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,
117 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET] = NULL,
120 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
121 static int _e_comp_object_intercept_hooks_delete = 0;
122 static int _e_comp_object_intercept_hooks_walking = 0;
124 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
126 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
127 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
131 static Eina_Bool _damage_trace = EINA_FALSE;
132 static Eina_List *_damage_trace_objs = NULL;
133 static Eina_List *_damage_trace_post_objs = NULL;
135 /* sekrit functionzzz */
136 EINTERN void e_client_focused_set(E_Client *ec);
138 /* emitted every time a new noteworthy comp object is added */
139 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
141 /* ecore event define */
142 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
143 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
144 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
146 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
147 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
148 static void _e_comp_object_dim_update(E_Comp_Object *cw);
149 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
150 #ifdef REFACTOR_DESK_AREA
152 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
153 static void _e_comp_object_raise(Evas_Object *obj);
154 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
155 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
156 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
157 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
160 static E_Client *dim_client = NULL;
163 _e_comp_object_hooks_clean(void)
166 E_Comp_Object_Hook *ch;
169 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
170 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
172 if (!ch->delete_me) continue;
173 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
179 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
181 E_Comp_Object_Hook *ch;
182 Eina_Bool ret = EINA_TRUE;
184 if (e_object_is_del(E_OBJECT(ec)))
186 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
187 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
188 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
189 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
190 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
191 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
192 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
193 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET) &&
194 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET)
200 e_object_ref(E_OBJECT(ec));
201 _e_comp_object_hooks_walking++;
202 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
204 if (ch->delete_me) continue;
205 if (!(ch->func(ch->data, ec)))
211 _e_comp_object_hooks_walking--;
212 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
213 _e_comp_object_hooks_clean();
215 e_object_unref(E_OBJECT(ec));
220 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
222 _e_comp_object_intercept_hooks_clean(void)
225 E_Comp_Object_Intercept_Hook *ch;
228 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
229 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
231 if (!ch->delete_me) continue;
232 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
238 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
240 E_Comp_Object_Intercept_Hook *ch;
241 Eina_Bool ret = EINA_TRUE;
243 if (e_object_is_del(E_OBJECT(ec))) return ret;
244 e_object_ref(E_OBJECT(ec));
245 _e_comp_object_intercept_hooks_walking++;
246 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
248 if (ch->delete_me) continue;
249 if (!(ch->func(ch->data, ec)))
255 _e_comp_object_intercept_hooks_walking--;
256 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
257 _e_comp_object_intercept_hooks_clean();
259 e_object_unref(E_OBJECT(ec));
266 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
268 E_Event_Comp_Object *ev = event;
271 ec = evas_object_data_get(ev->comp_object, "E_Client");
275 e_object_unref(E_OBJECT(ec));
277 evas_object_unref(ev->comp_object);
282 _e_comp_object_event_add(Evas_Object *obj)
284 E_Event_Comp_Object *ev;
287 if (stopping) return;
288 ev = E_NEW(E_Event_Comp_Object, 1);
289 EINA_SAFETY_ON_NULL_RETURN(ev);
291 evas_object_ref(obj);
292 ev->comp_object = obj;
293 ec = evas_object_data_get(ev->comp_object, "E_Client");
297 e_object_ref(E_OBJECT(ec));
299 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
303 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
305 E_Event_Comp_Object *ev = event;
308 ec = evas_object_data_get(ev->comp_object, "E_Client");
312 e_object_unref(E_OBJECT(ec));
314 evas_object_unref(ev->comp_object);
319 _e_comp_object_event_simple(Evas_Object *obj, int type)
321 E_Event_Comp_Object *ev;
324 ev = E_NEW(E_Event_Comp_Object, 1);
327 evas_object_ref(obj);
328 ev->comp_object = obj;
329 ec = evas_object_data_get(ev->comp_object, "E_Client");
333 e_object_ref(E_OBJECT(ec));
335 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
337 /////////////////////////////////////
340 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
342 E_Comp_Object *cw = data;
344 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
348 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
350 E_Comp_Object *cw = data;
352 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
353 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
356 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
357 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
361 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
363 E_Comp_Object *cw = data;
366 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
367 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
370 /////////////////////////////////////
372 #ifdef REFACTOR_DESK_AREA
374 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
377 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
382 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
383 if (cw->ec->input_only) return;
385 layer = evas_object_layer_get(obj);
387 if (cw->transform_bg_obj)
389 if (layer != evas_object_layer_get(cw->transform_bg_obj))
391 evas_object_layer_set(cw->transform_bg_obj, layer);
394 evas_object_stack_below(cw->transform_bg_obj, obj);
397 if (cw->transform_tranp_obj)
399 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
401 evas_object_layer_set(cw->transform_tranp_obj, layer);
404 evas_object_stack_below(cw->transform_tranp_obj, obj);
409 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
416 if (!map) return NULL;
418 e_map_util_points_populate_from_object_full(map, obj, 0);
419 e_map_util_points_color_set(map, 255, 255, 255, 255);
421 for (i = 0 ; i < 4 ; ++i)
426 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
427 e_map_point_coord_set(map, i, x, y, 1.0);
434 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
440 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
443 e_comp_object_map_set(obj, map);
444 e_comp_object_map_enable_set(obj, EINA_TRUE);
451 evas_object_map_enable_set(obj, EINA_FALSE);
456 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
462 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
465 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
467 e_comp_object_map_set(obj, map);
468 e_comp_object_map_enable_set(obj, EINA_TRUE);
475 evas_object_map_enable_set(obj, EINA_FALSE);
478 /////////////////////////////////////
480 static inline Eina_Bool
481 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
483 if (num > 1) return EINA_TRUE;
484 if ((rects[0].x == 0) && (rects[0].y == 0) &&
485 ((int)rects[0].w == w) && ((int)rects[0].h == h))
490 /////////////////////////////////////
492 /* add a client to the layer-client list */
493 #ifdef REFACTOR_DESK_AREA
496 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
498 g_rec_mutex_lock(&e_comp->ec_list_mutex);
501 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));
503 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));
504 if ((!above) && (!below))
507 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
508 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
509 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
511 e_comp->layers[cw->layer].clients_count++;
513 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
517 _e_comp_object_layers_remove(E_Comp_Object *cw)
519 g_rec_mutex_lock(&e_comp->ec_list_mutex);
521 if (cw->ec && e_comp->layers[cw->layer].clients)
523 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
524 e_comp->layers[cw->layer].clients_count--;
527 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
531 /////////////////////////////////////
533 _e_comp_object_alpha_set(E_Comp_Object *cw)
535 Eina_Bool alpha = cw->ec->argb;
537 if ((cw->external_content) &&
538 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
543 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
544 if (cw->user_alpha_set) alpha = cw->user_alpha;
546 evas_object_image_alpha_set(cw->obj, alpha);
550 _e_comp_object_shadow(E_Comp_Object *cw)
552 if (e_client_util_shadow_state_get(cw->ec))
553 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
555 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
556 if (cw->frame_object)
557 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
558 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
561 /* convert from the surface coordinates to the buffer coordinates */
563 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
565 E_Comp_Wl_Buffer_Viewport *vp;
566 E_Comp_Wl_Client_Data *cdata;
570 cdata = e_client_cdata_get(ec);
572 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
579 vp = &cdata->scaler.buffer_viewport;
580 transform = e_comp_wl_output_buffer_transform_get(ec);
582 e_pixmap_size_get(ec->pixmap, &bw, &bh);
584 /* for subsurface, it should be swap 90 and 270 */
585 if (e_comp_wl_subsurface_check(ec))
588 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
589 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
590 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
591 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
597 case WL_OUTPUT_TRANSFORM_NORMAL:
598 default: tx = sx, ty = sy; break;
599 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
600 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
601 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
602 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
603 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
604 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
605 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
608 tx *= vp->buffer.scale;
609 ty *= vp->buffer.scale;
616 _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)
624 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
625 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
632 if (dw) *dw = MAX(x1, x2) - mx;
633 if (dh) *dh = MAX(y1, y2) - my;
637 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
638 int *dx, int *dy, int *dw, int *dh)
640 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
641 E_Util_Transform_Rect_Vertex sv, dv;
645 e_pixmap_size_get(ec->pixmap, &bw, &bh);
647 sv = e_util_transform_rect_to_vertices(&rect);
649 for (i = 0; i < 4; i++)
651 double x = 0.0, y = 0.0;
653 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
655 /* if evas decide coordinate is outside of map, it returns (0, 0)
656 in this case, full damage is added.
658 if ((i != 0) && (x == 0.0) && (y == 0.0))
661 dv.vertices[i].vertex[0] = x;
662 dv.vertices[i].vertex[1] = y;
663 dv.vertices[i].vertex[2] = 1.0;
664 dv.vertices[i].vertex[3] = 1.0;
667 rect = e_util_transform_vertices_to_rect(&dv);
669 if (dx) *dx = rect.x;
670 if (dy) *dy = rect.y;
671 if (dw) *dw = rect.w;
672 if (dh) *dh = rect.h;
686 _e_comp_object_map_damage_transform_get(E_Client *ec)
693 if (!e_client_transform_core_enable_get(ec))
696 m = e_client_map_get(ec);
700 e_pixmap_size_get(ec->pixmap, &bw, &bh);
701 if ((bw == 0) || (bh == 0))
714 e_map_point_coord_set(m2, 0, 0, 0, 0);
715 e_map_point_coord_set(m2, 1, bw, 0, 0);
716 e_map_point_coord_set(m2, 2, bw, bh, 0);
717 e_map_point_coord_set(m2, 3, 0, bh, 0);
719 for (i = 0; i < 4; i++)
723 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
724 e_map_point_image_uv_set(m2, i, map_x, map_y);
731 /////////////////////////////////////
733 /* handle evas mouse-in events on client object */
735 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
737 Evas_Event_Mouse_In *ev = event_info;
738 E_Comp_Object *cw = data;
740 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
743 /* handle evas mouse-out events on client object */
745 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
747 Evas_Event_Mouse_Out *ev = event_info;
748 E_Comp_Object *cw = data;
750 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
753 /* handle evas mouse wheel events on client object */
755 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
757 Evas_Event_Mouse_Wheel *ev = event_info;
758 E_Comp_Object *cw = data;
759 E_Binding_Event_Wheel ev2;
762 if (e_client_action_get()) return;
763 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
764 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
767 /* handle evas mouse down events on client object */
769 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
771 Evas_Event_Mouse_Down *ev = event_info;
772 E_Comp_Object *cw = data;
773 E_Binding_Event_Mouse_Button ev2;
776 if (e_client_action_get()) return;
777 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
778 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
781 /* handle evas mouse up events on client object */
783 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
785 Evas_Event_Mouse_Up *ev = event_info;
786 E_Comp_Object *cw = data;
787 E_Binding_Event_Mouse_Button ev2;
790 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
791 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
792 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
795 /* handle evas mouse movement events on client object */
797 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
799 Evas_Event_Mouse_Move *ev = event_info;
800 E_Comp_Object *cw = data;
803 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
804 e_client_mouse_move(cw->ec, &ev->cur.output);
806 /////////////////////////////////////
808 /* helper function for checking compositor themes based on user-defined matches */
810 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
812 if (((m->title) && (!ec->netwm.name)) ||
813 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
815 #if defined(__cplusplus) || defined(c_plusplus)
816 if (((m->clas) && (!ec->icccm.cpp_class)) ||
817 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
820 if (((m->clas) && (!ec->icccm.class)) ||
821 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
825 if (((m->role) && (!ec->icccm.window_role)) ||
826 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
832 if ((int)ec->netwm.type != m->primary_type)
835 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
838 if (m->borderless != 0)
842 if (e_client_util_borderless(ec))
844 if (!(((m->borderless == -1) && (!borderless)) ||
845 ((m->borderless == 1) && (borderless))))
852 if (((ec->icccm.transient_for != 0) ||
855 if (!(((m->dialog == -1) && (!dialog)) ||
856 ((m->dialog == 1) && (dialog))))
859 if (m->accepts_focus != 0)
861 int accepts_focus = 0;
863 if (ec->icccm.accepts_focus)
865 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
866 ((m->accepts_focus == 1) && (accepts_focus))))
875 if (!(((m->vkbd == -1) && (!vkbd)) ||
876 ((m->vkbd == 1) && (vkbd))))
881 if (!(((m->argb == -1) && (!ec->argb)) ||
882 ((m->argb == 1) && (ec->argb))))
885 if (m->fullscreen != 0)
887 int fullscreen = ec->fullscreen;
889 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
890 ((m->fullscreen == 1) && (fullscreen))))
895 if (!(m->modal == -1))
901 /* function for setting up a client's compositor frame theme (cw->shobj) */
903 _e_comp_object_shadow_setup(E_Comp_Object *cw)
907 Eina_List *list = NULL, *l;
908 E_Input_Rect_Data *input_rect_data;
909 E_Input_Rect_Smart_Data *input_rect_sd;
911 Eina_Stringshare *reshadow_group = NULL;
912 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
913 Eina_Stringshare *name, *title;
914 E_Comp_Config *conf = e_comp_config_get();
916 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
917 /* match correct client type */
918 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
919 name = cw->ec->icccm.name;
920 title = cw->ec->icccm.title;
921 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
922 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
924 /* skipping here is mostly a hack for systray because I hate it */
927 EINA_LIST_FOREACH(list, l, m)
929 if (((m->name) && (!name)) ||
930 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
932 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
935 no_shadow = m->no_shadow;
938 /* fast effects are just themes with "/fast" appended and shorter effect times */
941 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
942 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
944 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
946 /* default to non-fast style if fast not available */
949 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
950 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
952 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
954 if (ok && m->visibility_effect)
955 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
962 if (skip || (cw->ec->e.state.video))
964 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
966 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
969 if (conf->shadow_style)
973 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
974 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
976 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
980 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
981 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
983 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
990 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
992 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
996 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
998 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1003 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1008 if (cw->ec->override)
1010 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1011 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1013 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1014 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1020 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1021 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1024 _e_comp_object_shadow(cw);
1027 if (focus || cw->ec->focused || cw->ec->override)
1028 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1030 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1032 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1034 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1035 /* visibility must always be enabled for re_manage clients to prevent
1036 * pop-in animations every time the user sees a persistent client again;
1037 * applying visibility for iconic clients prevents the client from getting
1040 if (cw->visible || cw->ec->re_manage)
1041 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1043 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1045 /* breaks animation counter */
1046 if (cw->frame_object)
1048 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1049 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1050 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1051 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1057 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1061 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1064 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1066 if (input_rect_data->obj)
1068 pass_event_flag = EINA_TRUE;
1074 if (cw->indicator.obj)
1076 Evas_Object *indicator;
1077 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1078 if (indicator != cw->indicator.obj)
1080 edje_object_part_unswallow(cw->shobj, indicator);
1081 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1082 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1086 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1087 evas_object_pass_events_set(cw->obj, pass_event_flag);
1092 /////////////////////////////////////////////
1095 _e_comp_object_animating_begin(E_Comp_Object *cw)
1098 if (cw->animating == 1)
1100 e_comp->animating++;
1102 e_object_ref(E_OBJECT(cw->ec));
1107 _e_comp_object_animating_end(E_Comp_Object *cw)
1116 if (cw->ec->launching)
1118 if (!cw->ec->extra_animating)
1120 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1121 cw->ec->launching = EINA_FALSE;
1122 if (cw->ec->first_mapped)
1124 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1125 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1128 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1132 e_comp->animating--;
1133 cw->showing = cw->hiding = 0;
1135 if (e_comp->animating == 0)
1136 e_comp_visibility_calculation_set(EINA_TRUE);
1137 /* remove ref from animation start, account for possibility of deletion from unref */
1138 return !!e_object_unref(E_OBJECT(cw->ec));
1144 /* handle the end of a compositor animation */
1146 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1148 E_Comp_Object *cw = data;
1150 /* visible clients which have never been sized are a bug */
1151 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1152 CRI("ACK! ec:%p", cw->ec);
1153 if (!_e_comp_object_animating_end(cw)) return;
1154 if (cw->animating) return;
1155 /* hide only after animation finishes to guarantee a full run of the animation */
1156 if (!cw->defer_hide) return;
1157 if ((!strcmp(emission, "e,action,hide,done")) ||
1158 (!strcmp(emission, "e,action,done")) ||
1159 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1161 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1162 evas_object_hide(cw->smart_obj);
1166 /* run a visibility compositor effect if available, return false if object is dead */
1168 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1174 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1175 if (!cw->effect_running)
1176 _e_comp_object_animating_begin(cw);
1177 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1178 return _e_comp_object_animating_end(cw);
1179 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1180 return _e_comp_object_animating_end(cw);
1182 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1185 zone = e_comp_zone_find_by_ec(cw->ec);
1187 zw = zone->w, zh = zone->h;
1192 zone = e_comp_object_util_zone_get(cw->smart_obj);
1193 if (!zone) zone = e_zone_current_get();
1200 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1201 cw->w, cw->h, zw, zh, x, y}, 8);
1202 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1203 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1206 /////////////////////////////////////////////
1208 /* create necessary objects for clients that e manages */
1210 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1212 if (cw->set_mouse_callbacks) return;
1213 if (!cw->smart_obj) return;
1215 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1216 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1217 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1218 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1219 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1220 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1222 cw->set_mouse_callbacks = EINA_TRUE;
1226 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1228 if (!cw->set_mouse_callbacks) return;
1229 if (!cw->smart_obj) return;
1231 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1232 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1233 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1234 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1235 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1236 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1238 cw->set_mouse_callbacks = EINA_FALSE;
1242 _e_comp_object_setup(E_Comp_Object *cw)
1244 cw->clip = evas_object_rectangle_add(e_comp->evas);
1245 evas_object_move(cw->clip, -9999, -9999);
1246 evas_object_resize(cw->clip, 999999, 999999);
1247 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1248 cw->effect_obj = edje_object_add(e_comp->evas);
1249 evas_object_move(cw->effect_obj, cw->x, cw->y);
1250 evas_object_clip_set(cw->effect_obj, cw->clip);
1251 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1252 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1253 cw->shobj = edje_object_add(e_comp->evas);
1254 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1255 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1256 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1258 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1259 if (cw->ec->override)
1261 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1262 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1263 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1265 else if (!cw->ec->input_only)
1267 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1268 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1269 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1271 cw->real_hid = !cw->ec->input_only;
1272 if (!cw->ec->input_only)
1274 e_util_size_debug_set(cw->effect_obj, 1);
1275 _e_comp_object_mouse_event_callback_set(cw);
1278 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1279 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1280 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1281 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1282 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1283 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1285 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1288 /////////////////////////////////////////////
1290 /* for fast path evas rendering; only called during render */
1292 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1294 E_Comp_Object *cw = data;
1295 E_Client *ec = cw->ec;
1297 int bx, by, bxx, byy;
1299 if (e_object_is_del(E_OBJECT(ec))) return;
1300 if (cw->external_content) return;
1301 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1302 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1305 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1306 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1308 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1310 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1311 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1315 bx = by = bxx = byy = 0;
1316 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1319 Edje_Message_Int_Set *msg;
1320 Edje_Message_Int msg2;
1321 Eina_Bool id = (bx || by || bxx || byy);
1323 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1329 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1331 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1335 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1336 e_comp_client_post_update_add(cw->ec);
1338 else if (e_comp_object_render(ec->frame))
1340 /* apply shape mask if necessary */
1341 if ((!cw->native) && (ec->shaped))
1342 e_comp_object_shape_apply(ec->frame);
1344 /* shaped clients get precise mouse events to handle transparent pixels */
1345 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1347 /* queue another render if client is still dirty; cannot refresh here. */
1348 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1349 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1351 if (cw->render_trace)
1353 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1359 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1361 E_Comp_Object *cw = data;
1362 E_Client *ec = cw->ec;
1364 if (e_object_is_del(E_OBJECT(ec))) return;
1365 if (cw->external_content) return;
1366 if (!e_comp->hwc) return;
1368 e_comp_client_render_list_add(cw->ec);
1370 if (!ec->hwc_window) return;
1372 e_hwc_windows_rendered_window_add(ec->hwc_window);
1375 /////////////////////////////////////////////
1378 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1380 E_Comp_Object *cw = data;
1383 if (cw->render_update_lock.lock)
1385 cw->render_update_lock.pending_move_x = x;
1386 cw->render_update_lock.pending_move_y = y;
1387 cw->render_update_lock.pending_move_set = EINA_TRUE;
1391 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1392 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1393 (cw->external_content))
1395 /* delay to move until the external content is unset */
1396 cw->ec->changes.pos = 1;
1401 if (cw->ec->move_after_resize)
1403 if ((x != cw->ec->x) || (y != cw->ec->y))
1405 if (!cw->ec->is_cursor)
1406 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1407 e_client_pos_set(cw->ec, x, y);
1408 cw->ec->changes.pos = 1;
1414 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1415 (cw->ec->manage_resize.resize_obj))
1417 e_client_pos_set(cw->ec, x, y);
1418 cw->ec->client.x = x + cw->client_inset.l;
1419 cw->ec->client.y = y + cw->client_inset.t;
1420 e_policy_visibility_client_defer_move(cw->ec);
1424 /* if frame_object does not exist, client_inset indicates CSD.
1425 * this means that ec->client matches cw->x/y, the opposite
1428 fx = (!cw->frame_object) * cw->client_inset.l;
1429 fy = (!cw->frame_object) * cw->client_inset.t;
1430 if ((cw->x == x + fx) && (cw->y == y + fy))
1432 if ((cw->ec->x != x) || (cw->ec->y != y))
1434 /* handle case where client tries to move to position and back very quickly */
1435 e_client_pos_set(cw->ec, x, y);
1436 cw->ec->client.x = x + cw->client_inset.l;
1437 cw->ec->client.y = y + cw->client_inset.t;
1441 if (!cw->ec->maximize_override)
1443 /* prevent moving in some directions while directionally maximized */
1444 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1446 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1449 ix = x + cw->client_inset.l;
1450 iy = y + cw->client_inset.t;
1451 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1452 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1453 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1455 /* prevent moving at all if move isn't allowed in current maximize state */
1456 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1457 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1460 zone = e_comp_zone_find_by_ec(cw->ec);
1463 cw->ec->changes.need_unmaximize = 1;
1464 cw->ec->saved.x = ix - zone->x;
1465 cw->ec->saved.y = iy - zone->y;
1466 cw->ec->saved.w = cw->ec->client.w;
1467 cw->ec->saved.h = cw->ec->client.h;
1471 /* only update during resize if triggered by resize */
1472 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1473 /* delay to move while surface waits paired commit serial*/
1474 if (e_client_pending_geometry_has(cw->ec))
1476 /* do nothing while waiting paired commit serial*/
1480 e_client_pos_set(cw->ec, x, y);
1481 if (cw->ec->new_client)
1483 /* don't actually do anything until first client idler loop */
1484 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1485 cw->ec->changes.pos = 1;
1490 /* only update xy position of client to avoid invalid
1491 * first damage region if it is not a new_client. */
1492 cw->ec->client.x = ix;
1493 cw->ec->client.y = iy;
1496 if (!cw->frame_object)
1498 evas_object_move(obj, x, y);
1503 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1505 E_Comp_Object *cw = data;
1506 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1509 if (cw->render_update_lock.lock)
1511 cw->render_update_lock.pending_resize_w = w;
1512 cw->render_update_lock.pending_resize_h = h;
1513 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1517 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1519 e_client_size_set(cw->ec, w, h);
1520 evas_object_resize(obj, w, h);
1524 /* if frame_object does not exist, client_inset indicates CSD.
1525 * this means that ec->client matches cw->w/h, the opposite
1528 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1529 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1530 if ((cw->w == w + fw) && (cw->h == h + fh))
1532 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1533 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1534 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1536 /* handle case where client tries to resize itself and back very quickly */
1537 e_client_size_set(cw->ec, w, h);
1538 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1539 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1540 evas_object_smart_callback_call(obj, "client_resize", NULL);
1544 /* guarantee that fullscreen is fullscreen */
1545 zone = e_comp_zone_find_by_ec(cw->ec);
1547 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1549 if (!e_client_transform_core_enable_get(cw->ec))
1552 /* calculate client size */
1553 iw = w - cw->client_inset.l - cw->client_inset.r;
1554 ih = h - cw->client_inset.t - cw->client_inset.b;
1555 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1557 /* prevent resizing while maximized depending on direction and config */
1558 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1560 Eina_Bool reject = EINA_FALSE;
1561 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1563 if (cw->ec->client.h != ih)
1565 cw->ec->saved.h = ih;
1566 cw->ec->saved.y = cw->ec->client.y - zone->y;
1567 reject = cw->ec->changes.need_unmaximize = 1;
1570 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1572 if (cw->ec->client.w != iw)
1574 cw->ec->saved.w = iw;
1575 cw->ec->saved.x = cw->ec->client.x - zone->x;
1576 reject = cw->ec->changes.need_unmaximize = 1;
1585 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1587 /* do nothing until client idler loops */
1588 if ((cw->ec->w != w) || (cw->ec->h != h))
1590 e_client_size_set(cw->ec, w, h);
1591 cw->ec->changes.size = 1;
1596 if (e_client_pending_geometry_has(cw->ec))
1598 /* do nothing while waiting paired commit serial*/
1602 e_client_size_set(cw->ec, w, h);
1604 cw->ec->client.w = iw;
1605 cw->ec->client.h = ih;
1606 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1608 /* The size of non-compositing window can be changed, so there is a
1609 * need to check that cw is H/W composited if cw is not redirected.
1610 * And of course we have to change size of evas object of H/W composited cw,
1611 * otherwise cw can't receive input events even if it is shown on the screen.
1613 Eina_Bool redirected = cw->redirected;
1615 redirected = e_comp_is_on_overlay(cw->ec);
1617 if ((!cw->ec->input_only) && (redirected) &&
1618 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1619 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1620 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1621 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1624 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1625 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1627 prev_w = cw->w, prev_h = cw->h;
1628 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1629 /* check shading and clamp to pixmap size for regular clients */
1630 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1631 (((w - fw != pw) || (h - fh != ph))))
1633 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1634 evas_object_smart_callback_call(obj, "client_resize", NULL);
1636 if (cw->frame_object || cw->ec->input_only)
1637 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1640 if ((cw->w == w) && (cw->h == h))
1642 /* going to be a noop resize which won't trigger smart resize */
1643 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1644 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1646 evas_object_resize(obj, w, h);
1650 evas_object_smart_callback_call(obj, "client_resize", NULL);
1653 if ((!cw->frame_object) && (!cw->ec->input_only))
1655 /* "just do it" for overrides */
1656 evas_object_resize(obj, w, h);
1658 if (!cw->ec->override)
1660 /* shape probably changed for non-overrides */
1665 /* this fixes positioning jiggles when using a resize mode
1666 * which also changes the client's position
1669 if (cw->frame_object)
1670 x = cw->x, y = cw->y;
1672 x = cw->ec->x, y = cw->ec->y;
1673 switch (cw->ec->resize_mode)
1675 case E_POINTER_RESIZE_BL:
1676 case E_POINTER_RESIZE_L:
1677 evas_object_move(obj, x + prev_w - cw->w, y);
1679 case E_POINTER_RESIZE_TL:
1680 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1682 case E_POINTER_RESIZE_T:
1683 case E_POINTER_RESIZE_TR:
1684 evas_object_move(obj, x, y + prev_h - cw->h);
1693 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1695 #ifdef REFACTOR_DESK_AREA
1696 E_Comp_Object *cw = data;
1697 E_Comp_Object_Data_Set_Layer layer_set_data;
1699 layer_set_data.cw = cw;
1700 layer_set_data.layer = layer;
1702 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1706 e_comp_render_queue();
1707 e_comp_object_transform_obj_stack_update(obj);
1711 E_Comp_Object *cw = data;
1712 E_Comp_Wl_Client_Data *child_cdata;
1713 unsigned int l = e_comp_canvas_layer_map(layer);
1716 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1718 /* doing a compositor effect, follow directions */
1719 _e_comp_object_layer_set(obj, layer);
1720 if (layer == cw->ec->layer) //trying to put layer back
1724 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1725 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1726 if (cw->layer != l) goto layer_set;
1730 e_comp_render_queue();
1732 ec = e_client_above_get(cw->ec);
1733 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1734 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1735 ec = e_client_above_get(ec);
1736 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1738 ec = e_client_below_get(cw->ec);
1739 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1740 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1741 ec = e_client_below_get(ec);
1742 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1744 evas_object_stack_above(obj, ec->frame);
1749 if (ec && (cw->ec->parent == ec))
1751 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1752 evas_object_stack_above(obj, ec->frame);
1754 evas_object_stack_below(obj, ec->frame);
1757 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1763 if (cw->layer == l) return;
1764 if (e_comp_canvas_client_layer_map(layer) == 9999)
1765 return; //invalid layer for clients not doing comp effects
1766 if (cw->ec->fullscreen)
1768 cw->ec->saved.layer = layer;
1771 oldraise = e_config->transient.raise;
1773 /* clamp to valid client layer */
1774 layer = e_comp_canvas_client_layer_map_nearest(layer);
1775 cw->ec->layer = layer;
1776 if (e_config->transient.layer)
1779 Eina_List *list = eina_list_clone(cw->ec->transients);
1781 /* We need to set raise to one, else the child wont
1782 * follow to the new layer. It should be like this,
1783 * even if the user usually doesn't want to raise
1786 e_config->transient.raise = 1;
1787 EINA_LIST_FREE(list, child)
1789 child_cdata = e_client_cdata_get(child);
1790 if (child_cdata && !child_cdata->mapped)
1792 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1795 e_client_layer_set(child, layer);
1799 e_config->transient.raise = oldraise;
1801 _e_comp_object_layers_remove(cw);
1802 cw->layer = e_comp_canvas_layer_map(layer);
1803 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1804 //if (cw->ec->new_client)
1805 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1806 _e_comp_object_layer_set(obj, layer);
1807 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1808 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1809 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1811 /* can't stack a client above its own layer marker */
1812 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1814 if (!cw->visible) return;
1815 e_comp_render_queue();
1816 _e_comp_object_transform_obj_stack_update(obj);
1820 #ifdef REFACTOR_DESK_AREA
1822 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1825 #ifdef REFACTOR_DESK_AREA
1827 e_comp_object_raise(Evas_Object *obj)
1830 _e_comp_object_raise(Evas_Object *obj)
1833 evas_object_raise(obj);
1835 if (evas_object_smart_smart_get(obj))
1837 E_Client *ec = e_comp_object_client_get(obj);
1839 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1843 #ifdef REFACTOR_DESK_AREA
1845 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1848 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1851 evas_object_lower(obj);
1853 if (evas_object_smart_smart_get(obj))
1855 E_Client *ec = e_comp_object_client_get(obj);
1858 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1859 #ifdef REFACTOR_DESK_AREA
1860 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1862 wl_signal_emit_mutable(&cw->events.lower, NULL);
1868 #ifdef REFACTOR_DESK_AREA
1870 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1873 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1876 evas_object_stack_above(obj, target);
1878 if (evas_object_smart_smart_get(obj))
1880 E_Client *ec = e_comp_object_client_get(obj);
1882 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1886 #ifdef REFACTOR_DESK_AREA
1888 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1891 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1894 evas_object_stack_below(obj, target);
1896 if (evas_object_smart_smart_get(obj))
1898 E_Client *ec = e_comp_object_client_get(obj);
1900 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1904 #ifdef REFACTOR_DESK_AREA
1906 e_comp_object_layer_set(Evas_Object *obj, short layer)
1909 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1912 evas_object_layer_set(obj, layer);
1914 if (evas_object_smart_smart_get(obj))
1916 E_Client *ec = e_comp_object_client_get(obj);
1918 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1922 #ifdef REFACTOR_DESK_AREA
1925 _e_comp_object_is_pending(E_Client *ec)
1929 if (!ec) return EINA_FALSE;
1931 topmost = e_comp_wl_topmost_parent_get(ec);
1933 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1937 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1939 E_Comp_Object *cw2 = NULL;
1942 Evas_Object *o = stack;
1943 #ifdef REFACTOR_DESK_AREA
1944 Eina_Bool raising = stack_cb == e_comp_object_stack_above;
1946 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1949 /* We should consider topmost's layer_pending for subsurface */
1950 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
1952 if (_e_comp_object_is_pending(cw->ec))
1953 e_comp_object_layer_update(cw->smart_obj,
1954 raising? stack : NULL,
1955 raising? NULL : stack);
1957 /* obey compositor effects! */
1958 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1959 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
1960 stack_cb(cw->smart_obj, stack);
1961 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1962 evas_object_data_del(cw->smart_obj, "client_restack");
1966 cw2 = evas_object_data_get(o, "comp_obj");
1968 /* assume someone knew what they were doing during client init */
1969 if (cw->ec->new_client)
1970 layer = cw->ec->layer;
1971 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
1972 layer = cw2->ec->layer;
1974 layer = evas_object_layer_get(stack);
1975 ecstack = e_client_below_get(cw->ec);
1976 if (layer != e_comp_canvas_layer_map_to(cw->layer))
1978 evas_object_layer_set(cw->smart_obj, layer);
1979 /* we got our layer wrangled, return now! */
1980 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
1983 /* check if we're stacking below another client */
1986 /* check for non-client layer object */
1987 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
1989 /* find an existing client to use for layering
1990 * by walking up the object stack
1992 * this is guaranteed to be pretty quick since we'll either:
1993 * - run out of client layers
1994 * - find a stacking client
1996 o = evas_object_above_get(o);
1997 if ((!o) || (o == cw->smart_obj)) break;
1998 if (evas_object_layer_get(o) != layer)
2000 /* reached the top client layer somehow
2001 * use top client object
2003 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2006 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2007 * return here since the top client layer window
2012 ec = e_client_top_get();
2017 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2020 if (cw2 && cw->layer != cw2->layer)
2023 /* remove existing layers */
2024 _e_comp_object_layers_remove(cw);
2027 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2028 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2029 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2030 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2031 else //if no stacking objects found, either raise or lower
2032 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2035 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2037 /* find new object for stacking if cw2 is on state of layer_pending */
2038 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2040 E_Client *new_stack = NULL, *current_ec = NULL;
2041 current_ec = cw2->ec;
2044 while ((new_stack = e_client_below_get(current_ec)))
2046 current_ec = new_stack;
2047 if (new_stack == cw->ec) continue;
2048 if (new_stack->layer != cw2->ec->layer) break;
2049 if (!_e_comp_object_is_pending(new_stack)) break;
2051 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2052 stack = new_stack->frame;
2055 /* stack it above layer object */
2057 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2058 stack = e_comp->layers[below_layer].obj;
2063 while ((new_stack = e_client_above_get(current_ec)))
2065 current_ec = new_stack;
2066 if (new_stack == cw->ec) continue;
2067 if (new_stack->layer != cw2->ec->layer) break;
2068 if (!_e_comp_object_is_pending(new_stack)) break;
2070 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2071 stack = new_stack->frame;
2073 stack = e_comp->layers[cw2->layer].obj;
2077 /* set restack if stacking has changed */
2078 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2079 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2080 stack_cb(cw->smart_obj, stack);
2081 if (e_comp->layers[cw->layer].obj)
2082 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2084 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2086 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2087 evas_object_data_del(cw->smart_obj, "client_restack");
2088 if (!cw->visible) return;
2089 e_comp_render_queue();
2094 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2096 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2098 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2100 #ifdef REFACTOR_DESK_AREA
2101 E_Comp_Object *cw = data;
2102 E_Comp_Object_Data_Stack_Above stack_above_data;
2104 stack_above_data.cw = cw;
2105 stack_above_data.above_obj = above;
2107 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2109 if (evas_object_below_get(obj) == above)
2111 e_comp_object_layer_update(obj, above, NULL);
2115 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2117 _e_comp_object_transform_obj_stack_update(obj);
2118 _e_comp_object_transform_obj_stack_update(above);
2125 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2127 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2129 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2131 #ifdef REFACTOR_DESK_AREA
2132 E_Comp_Object *cw = data;
2133 E_Comp_Object_Data_Stack_Below stack_below_data;
2135 stack_below_data.cw = cw;
2136 stack_below_data.below_obj = below;
2138 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2141 e_comp_render_queue();
2143 if (evas_object_above_get(obj) == below)
2145 e_comp_object_layer_update(obj, NULL, below);
2149 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2151 if (evas_object_smart_smart_get(obj))
2152 _e_comp_object_transform_obj_stack_update(obj);
2153 if (evas_object_smart_smart_get(below))
2154 _e_comp_object_transform_obj_stack_update(below);
2161 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2163 E_Comp_Object *cw = data;
2165 #ifdef REFACTOR_DESK_AREA
2170 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2172 #ifdef REFACTOR_DESK_AREA
2173 wl_signal_emit_mutable(&cw->events.lower, cw);
2175 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2177 if (cw->ec->layer_pending)
2178 e_comp_object_layer_update(obj, NULL, obj);
2180 #ifdef REFACTOR_DESK_AREA
2181 e_comp_object_lower(cw, obj);
2183 _e_comp_object_lower(cw, obj);
2187 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2188 o = evas_object_below_get(obj);
2189 _e_comp_object_layers_remove(cw);
2190 /* prepend to client list since this client should be the first item now */
2191 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2192 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2193 evas_object_data_set(obj, "client_restack", (void*)1);
2194 #ifdef REFACTOR_DESK_AREA
2195 e_comp_object_lower(cw, obj);
2197 _e_comp_object_lower(cw, obj);
2199 evas_object_data_del(obj, "client_restack");
2200 if (!cw->visible) goto end;
2201 e_comp_render_queue();
2202 #ifdef REFACTOR_DESK_AREA
2203 e_comp_object_transform_obj_stack_update(obj);
2205 _e_comp_object_transform_obj_stack_update(obj);
2214 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2216 E_Comp_Object *cw = data;
2217 #ifdef REFACTOR_DESK_AREA
2223 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2225 #ifdef REFACTOR_DESK_AREA
2226 wl_signal_emit_mutable(&cw->events.raise, cw);
2228 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2230 if (cw->ec->layer_pending)
2232 int obj_layer = evas_object_layer_get(obj);
2233 if (cw->ec->layer != obj_layer)
2234 e_comp_object_layer_update(obj, NULL, NULL);
2236 #ifdef REFACTOR_DESK_AREA
2237 e_comp_object_raise(obj);
2239 _e_comp_object_raise(obj);
2243 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2244 o = evas_object_above_get(obj);
2245 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2247 /* still stack below override below the layer marker */
2248 for (op = o = e_comp->layers[cw->layer].obj;
2249 o && o != e_comp->layers[cw->layer - 1].obj;
2250 op = o, o = evas_object_below_get(o))
2252 if (evas_object_smart_smart_get(o))
2256 ec = e_comp_object_client_get(o);
2257 if (ec && (!ec->override)) break;
2260 #ifdef REFACTOR_DESK_AREA
2261 e_comp_object_stack_below(obj, op);
2263 _e_comp_object_stack_below(obj, op);
2265 e_client_focus_defer_set(cw->ec);
2267 if (!cw->visible) goto end;
2268 e_comp_render_queue();
2269 #ifdef REFACTOR_DESK_AREA
2270 e_comp_object_transform_obj_stack_update(obj);
2272 _e_comp_object_transform_obj_stack_update(obj);
2281 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2283 E_Comp_Object *cw = data;
2285 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2286 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2288 ELOGF("COMP", "Hide. intercepted", cw->ec);
2293 if (cw->ec->launching == EINA_TRUE)
2295 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2296 cw->ec->launching = EINA_FALSE;
2301 /* hidden flag = just do it */
2302 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2303 evas_object_hide(obj);
2305 wl_signal_emit_mutable(&cw->events.hide, NULL);
2310 if (cw->ec->input_only)
2312 /* input_only = who cares */
2313 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2314 evas_object_hide(obj);
2316 wl_signal_emit_mutable(&cw->events.hide, NULL);
2320 /* already hidden or currently animating */
2321 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2323 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2327 /* don't try hiding during shutdown */
2328 cw->defer_hide |= stopping;
2329 if (!cw->defer_hide)
2331 if ((!cw->ec->iconic) && (!cw->ec->override))
2332 /* unset delete requested so the client doesn't break */
2333 cw->ec->delete_requested = 0;
2334 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2336 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2337 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2340 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2343 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2345 _e_comp_object_animating_begin(cw);
2346 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2348 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2349 cw->defer_hide = !!cw->animating;
2351 e_comp_object_effect_set(obj, NULL);
2354 if (cw->animating) return;
2355 /* if we have no animations running, go ahead and hide */
2357 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2358 evas_object_hide(obj);
2360 wl_signal_emit_mutable(&cw->events.hide, NULL);
2364 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2366 E_Client *ec = cw->ec;
2369 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2371 if (ec->show_pending.count > 0)
2373 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2374 ec->show_pending.running = EINA_TRUE;
2378 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2379 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2381 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2386 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,
2387 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2388 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2391 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2394 if (ec->iconic && cw->animating)
2396 /* triggered during iconify animation */
2397 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2400 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2403 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2404 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2406 evas_object_move(cw->smart_obj, ec->x, ec->y);
2407 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2408 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2410 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2411 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2414 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2415 evas_object_show(cw->smart_obj);
2418 e_client_focus_defer_set(ec);
2422 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2426 pw = ec->client.w, ph = ec->client.h;
2428 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2430 ec->changes.visible = !ec->hidden;
2433 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2437 cw->updates = eina_tiler_new(pw, ph);
2440 ec->changes.visible = !ec->hidden;
2443 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2448 eina_tiler_tile_size_set(cw->updates, 1, 1);
2451 /* ignore until client idler first run */
2452 ec->changes.visible = !ec->hidden;
2455 ELOGF("COMP", "show_helper. return. new_client", ec);
2462 evas_object_move(cw->smart_obj, ec->x, ec->y);
2463 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2464 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2465 evas_object_show(cw->smart_obj);
2468 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2470 /* start_drag not received */
2471 ec->changes.visible = 1;
2474 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2477 /* re-set geometry */
2478 evas_object_move(cw->smart_obj, ec->x, ec->y);
2479 /* force resize in case it hasn't happened yet, or just to update size */
2480 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2481 if ((cw->w < 1) || (cw->h < 1))
2483 /* if resize didn't go through, try again */
2484 ec->visible = ec->changes.visible = 1;
2486 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2489 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2490 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2491 e_pixmap_clear(ec->pixmap);
2493 if (cw->real_hid && w && h)
2496 /* force comp theming in case it didn't happen already */
2497 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2498 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2499 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2502 /* only do the show if show is allowed */
2505 if (ec->internal) //internal clients render when they feel like it
2506 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2508 if (!e_client_is_iconified_by_client(ec)||
2509 e_policy_visibility_client_is_uniconic(ec))
2511 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2512 evas_object_show(cw->smart_obj);
2514 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2515 it is rendered in idle callback without native surface and
2516 compositor shows an empty frame if other objects aren't shown
2517 because job callback of e_comp called at the next loop.
2518 it causes a visual defect when windows are switched.
2522 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2523 e_comp_object_dirty(cw->smart_obj);
2524 e_comp_object_render(cw->smart_obj);
2529 wl_signal_emit_mutable(&cw->events.show, NULL);
2533 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2535 E_Comp_Object *cw = data;
2536 E_Client *ec = cw->ec;
2538 E_Input_Rect_Data *input_rect_data;
2539 E_Input_Rect_Smart_Data *input_rect_sd;
2542 if (ec->ignored) return;
2546 //INF("SHOW2 %p", ec);
2547 _e_comp_intercept_show_helper(cw);
2550 //INF("SHOW %p", ec);
2553 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2554 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2555 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2556 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2560 if ((!cw->obj) && (cw->external_content))
2562 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2566 _e_comp_object_setup(cw);
2569 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2570 cw->obj = evas_object_image_filled_add(e_comp->evas);
2571 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2572 e_util_size_debug_set(cw->obj, 1);
2573 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2574 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2575 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2576 evas_object_name_set(cw->obj, "cw->obj");
2577 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2579 _e_comp_object_alpha_set(cw);
2582 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2585 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2586 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2589 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2592 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2594 if (input_rect_data->obj)
2596 evas_object_geometry_set(input_rect_data->obj,
2597 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2598 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2599 input_rect_data->rect.w, input_rect_data->rect.h);
2606 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2608 _e_comp_intercept_show_helper(cw);
2612 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2614 E_Comp_Object *cw = data;
2618 /* note: this is here as it seems there are enough apps that do not even
2619 * expect us to emulate a look of focus but not actually set x input
2620 * focus as we do - so simply abort any focus set on such windows */
2621 /* be strict about accepting focus hint */
2622 /* be strict about accepting focus hint */
2623 if ((!ec->icccm.accepts_focus) &&
2624 (!ec->icccm.take_focus))
2628 if (e_client_focused_get() == ec)
2629 e_client_focused_set(NULL);
2631 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2632 evas_object_focus_set(obj, focus);
2636 if (focus && ec->lock_focus_out) return;
2637 if (e_object_is_del(E_OBJECT(ec)) && focus)
2638 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2640 /* filter focus setting based on current state */
2645 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2646 evas_object_focus_set(obj, focus);
2649 if ((ec->iconic) && (!ec->deskshow))
2651 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2653 /* don't focus an iconified window. that's silly! */
2654 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2655 e_client_uniconify(ec);
2656 e_client_focus_latest_set(ec);
2670 /* not yet visible, wait till the next time... */
2671 ec->want_focus = !ec->hidden;
2676 e_client_focused_set(ec);
2680 if (e_client_focused_get() == ec)
2681 e_client_focused_set(NULL);
2685 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2687 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2689 evas_object_focus_set(obj, focus);
2693 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2695 E_Comp_Object *cw = data;
2697 if (cw->transparent.set)
2699 cw->transparent.user_r = r;
2700 cw->transparent.user_g = g;
2701 cw->transparent.user_b = b;
2702 cw->transparent.user_a = a;
2704 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2706 cw->transparent.user_r,
2707 cw->transparent.user_g,
2708 cw->transparent.user_b,
2709 cw->transparent.user_a);
2713 evas_object_color_set(obj, r, g, b, a);
2716 wl_signal_emit_mutable(&cw->events.color_set, NULL);
2718 ////////////////////////////////////////////////////
2721 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2723 int w, h, ox, oy, ow, oh;
2725 Eina_Bool pass_event_flag = EINA_FALSE;
2726 E_Input_Rect_Data *input_rect_data;
2727 E_Input_Rect_Smart_Data *input_rect_sd;
2729 if (cw->frame_object)
2731 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2732 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2733 /* set a fixed size, force edje calc, check size difference */
2734 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2735 edje_object_message_signal_process(cw->frame_object);
2736 edje_object_calc_force(cw->frame_object);
2737 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2738 cw->client_inset.l = ox;
2739 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2740 cw->client_inset.t = oy;
2741 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2742 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2743 evas_object_resize(cw->frame_object, w, h);
2747 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2750 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2752 if (input_rect_data->obj)
2754 pass_event_flag = EINA_TRUE;
2760 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2761 evas_object_pass_events_set(cw->obj, pass_event_flag);
2765 cw->client_inset.l = 0;
2766 cw->client_inset.r = 0;
2767 cw->client_inset.t = 0;
2768 cw->client_inset.b = 0;
2770 cw->client_inset.calc = !!cw->frame_object;
2774 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2776 E_Comp_Object *cw = data;
2780 /* - get current size
2782 * - readjust for new frame size
2785 w = cw->ec->w, h = cw->ec->h;
2786 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2788 _e_comp_object_frame_recalc(cw);
2790 if (!cw->ec->fullscreen)
2791 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2793 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2794 if (cw->ec->fullscreen)
2796 zone = e_comp_zone_find_by_ec(cw->ec);
2798 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2800 else if (cw->ec->new_client)
2802 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2803 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2804 evas_object_resize(cw->ec->frame, w, h);
2806 else if ((w != cw->ec->w) || (h != cw->ec->h))
2807 evas_object_resize(cw->ec->frame, w, h);
2811 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2813 E_Comp_Object *cw = data;
2815 _e_comp_object_shadow_setup(cw);
2816 if (cw->frame_object)
2818 _e_comp_object_shadow(cw);
2819 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2820 _e_comp_object_frame_recalc(cw);
2821 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2826 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2828 E_Comp_Object *cw = data;
2830 if (_e_comp_object_shadow_setup(cw))
2831 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2832 if (cw->frame_object)
2834 _e_comp_object_shadow(cw);
2835 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2836 _e_comp_object_frame_recalc(cw);
2837 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2842 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2844 E_Comp_Object *cw = data;
2846 if (cw->frame_object)
2848 _e_comp_object_shadow(cw);
2849 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2850 _e_comp_object_frame_recalc(cw);
2851 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2856 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2858 E_Comp_Object *cw = data;
2860 if (_e_comp_object_shadow_setup(cw))
2863 cw->ec->changes.size = 1;
2865 if (cw->frame_object)
2867 _e_comp_object_shadow(cw);
2868 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2869 _e_comp_object_frame_recalc(cw);
2870 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2875 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2877 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2881 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2883 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2887 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2889 E_Comp_Object *cw = data;
2891 if (!cw->ec) return; //NYI
2892 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2896 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2898 E_Comp_Object *cw = data;
2900 if (!cw->ec) return; //NYI
2901 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2905 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2907 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2911 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2913 E_Comp_Object *cw = data;
2915 if (!e_object_is_del(E_OBJECT(cw->ec)))
2916 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2920 _e_comp_input_obj_smart_add(Evas_Object *obj)
2922 E_Input_Rect_Smart_Data *input_rect_sd;
2923 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2925 if (!input_rect_sd) return;
2926 evas_object_smart_data_set(obj, input_rect_sd);
2930 _e_comp_input_obj_smart_del(Evas_Object *obj)
2932 E_Input_Rect_Smart_Data *input_rect_sd;
2933 E_Input_Rect_Data *input_rect_data;
2935 input_rect_sd = evas_object_smart_data_get(obj);
2936 if (!input_rect_sd) return;
2938 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2940 if (input_rect_data->obj)
2942 evas_object_smart_member_del(input_rect_data->obj);
2943 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2945 E_FREE(input_rect_data);
2947 E_FREE(input_rect_sd);
2951 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2953 E_Input_Rect_Smart_Data *input_rect_sd;
2954 E_Input_Rect_Data *input_rect_data;
2958 input_rect_sd = evas_object_smart_data_get(obj);
2959 if (!input_rect_sd) return;
2961 cw = input_rect_sd->cw;
2962 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2964 if (input_rect_data->obj)
2966 evas_object_geometry_set(input_rect_data->obj,
2967 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2968 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2969 input_rect_data->rect.w, input_rect_data->rect.h);
2975 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2977 E_Input_Rect_Smart_Data *input_rect_sd;
2978 E_Input_Rect_Data *input_rect_data;
2982 input_rect_sd = evas_object_smart_data_get(obj);
2983 if (!input_rect_sd) return;
2985 cw = input_rect_sd->cw;
2986 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2988 if (input_rect_data->obj)
2990 evas_object_geometry_set(input_rect_data->obj,
2991 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2992 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2993 input_rect_data->rect.w, input_rect_data->rect.h);
2999 _e_comp_input_obj_smart_show(Evas_Object *obj)
3001 E_Input_Rect_Smart_Data *input_rect_sd;
3002 E_Input_Rect_Data *input_rect_data;
3005 input_rect_sd = evas_object_smart_data_get(obj);
3006 if (!input_rect_sd) return;
3008 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3010 if (input_rect_data->obj)
3012 evas_object_show(input_rect_data->obj);
3018 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3020 E_Input_Rect_Smart_Data *input_rect_sd;
3021 E_Input_Rect_Data *input_rect_data;
3024 input_rect_sd = evas_object_smart_data_get(obj);
3025 if (!input_rect_sd) return;
3027 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3029 if (input_rect_data->obj)
3031 evas_object_hide(input_rect_data->obj);
3037 _e_comp_input_obj_smart_init(void)
3039 if (_e_comp_input_obj_smart) return;
3041 static const Evas_Smart_Class sc =
3043 INPUT_OBJ_SMART_NAME,
3044 EVAS_SMART_CLASS_VERSION,
3045 _e_comp_input_obj_smart_add,
3046 _e_comp_input_obj_smart_del,
3047 _e_comp_input_obj_smart_move,
3048 _e_comp_input_obj_smart_resize,
3049 _e_comp_input_obj_smart_show,
3050 _e_comp_input_obj_smart_hide,
3063 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3069 _e_comp_smart_add(Evas_Object *obj)
3073 cw = E_NEW(E_Comp_Object, 1);
3074 EINA_SAFETY_ON_NULL_RETURN(cw);
3076 wl_signal_init(&cw->events.lower);
3077 #ifdef REFACTOR_DESK_AREA
3078 wl_signal_init(&cw->events.lower_done);
3079 wl_signal_init(&cw->events.raise);
3081 wl_signal_init(&cw->events.show);
3082 wl_signal_init(&cw->events.hide);
3083 #ifdef REFACTOR_DESK_AREA
3084 wl_signal_init(&cw->events.set_layer);
3085 wl_signal_init(&cw->events.stack_above);
3086 wl_signal_init(&cw->events.stack_below);
3088 wl_signal_init(&cw->events.image_filter_set);
3089 wl_signal_init(&cw->events.render_op_set);
3090 wl_signal_init(&cw->events.content_type_set);
3091 wl_signal_init(&cw->events.color_set);
3093 cw->smart_obj = obj;
3094 cw->x = cw->y = cw->w = cw->h = -1;
3095 evas_object_smart_data_set(obj, cw);
3096 cw->opacity = 255.0;
3097 cw->external_content = 0;
3098 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3099 cw->transform_bg_color.r = 0;
3100 cw->transform_bg_color.g = 0;
3101 cw->transform_bg_color.b = 0;
3102 cw->transform_bg_color.a = 255;
3103 evas_object_data_set(obj, "comp_obj", cw);
3104 evas_object_move(obj, -1, -1);
3105 /* intercept ALL the callbacks! */
3106 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3107 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3108 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3109 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3110 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3111 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3112 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3113 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3114 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3115 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3116 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3118 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3119 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3120 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3121 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3123 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3124 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3126 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3127 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3129 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3131 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3132 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3136 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3139 evas_object_color_set(cw->clip, r, g, b, a);
3140 evas_object_smart_callback_call(obj, "color_set", NULL);
3145 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3148 evas_object_clip_set(cw->clip, clip);
3152 _e_comp_smart_clip_unset(Evas_Object *obj)
3155 evas_object_clip_unset(cw->clip);
3159 _e_comp_smart_hide(Evas_Object *obj)
3161 TRACE_DS_BEGIN(COMP:SMART HIDE);
3166 evas_object_hide(cw->clip);
3167 if (cw->input_obj) evas_object_hide(cw->input_obj);
3168 evas_object_hide(cw->effect_obj);
3169 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3170 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3171 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3178 /* unset native surface if current displaying buffer was destroied */
3179 if (!cw->buffer_destroy_listener.notify)
3181 Evas_Native_Surface *ns;
3182 ns = evas_object_image_native_surface_get(cw->obj);
3183 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3184 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3187 if (!cw->ec->input_only)
3189 edje_object_freeze(cw->effect_obj);
3190 edje_object_freeze(cw->shobj);
3191 edje_object_play_set(cw->shobj, 0);
3192 if (cw->frame_object)
3193 edje_object_play_set(cw->frame_object, 0);
3196 e_comp_render_queue(); //force nocomp recheck
3202 _e_comp_smart_show(Evas_Object *obj)
3210 if ((cw->w < 0) || (cw->h < 0))
3211 CRI("ACK! ec:%p", cw->ec);
3213 TRACE_DS_BEGIN(COMP:SMART SHOW);
3215 e_comp_object_map_update(obj);
3217 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3218 evas_object_show(tmp->frame);
3220 evas_object_show(cw->clip);
3221 if (cw->input_obj) evas_object_show(cw->input_obj);
3222 if (!cw->ec->input_only)
3224 edje_object_thaw(cw->effect_obj);
3225 edje_object_thaw(cw->shobj);
3226 edje_object_play_set(cw->shobj, 1);
3227 if (cw->frame_object)
3228 edje_object_play_set(cw->frame_object, 1);
3230 evas_object_show(cw->effect_obj);
3231 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3232 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3233 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3234 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3235 e_comp_render_queue();
3236 if (cw->ec->input_only)
3241 if (cw->ec->iconic && (!cw->ec->new_client))
3243 if (e_client_is_iconified_by_client(cw->ec))
3245 ELOGF("COMP", "Set launching flag..", cw->ec);
3246 cw->ec->launching = EINA_TRUE;
3249 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3251 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3254 ELOGF("COMP", "Set launching flag..", cw->ec);
3255 cw->ec->launching = EINA_TRUE;
3257 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3258 _e_comp_object_animating_begin(cw);
3259 if (!_e_comp_object_effect_visibility_start(cw, 1))
3265 /* ensure some random effect doesn't lock the client offscreen */
3269 e_comp_object_effect_set(obj, NULL);
3272 _e_comp_object_dim_update(cw);
3278 _e_comp_smart_del(Evas_Object *obj)
3284 if (cw->buffer_destroy_listener.notify)
3286 wl_list_remove(&cw->buffer_destroy_listener.link);
3287 cw->buffer_destroy_listener.notify = NULL;
3290 if (cw->tbm_surface)
3292 tbm_surface_internal_unref(cw->tbm_surface);
3293 cw->tbm_surface = NULL;
3296 if (cw->render_update_lock.buffer_ref.buffer)
3298 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3299 cw->ec, cw->render_update_lock.lock);
3300 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3303 e_comp_object_render_update_del(cw->smart_obj);
3304 E_FREE_FUNC(cw->updates, eina_tiler_free);
3305 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3312 EINA_LIST_FREE(cw->obj_mirror, o)
3314 evas_object_image_data_set(o, NULL);
3315 evas_object_freeze_events_set(o, 1);
3316 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3320 #ifdef REFACTOR_DESK_AREA
3322 _e_comp_object_layers_remove(cw);
3324 l = evas_object_data_get(obj, "comp_object-to_del");
3325 E_FREE_LIST(l, evas_object_del);
3326 _e_comp_object_mouse_event_callback_unset(cw);
3327 evas_object_del(cw->clip);
3328 evas_object_del(cw->obj);
3329 evas_object_del(cw->shobj);
3330 evas_object_del(cw->effect_obj);
3331 evas_object_del(cw->frame_object);
3332 evas_object_del(cw->input_obj);
3333 evas_object_del(cw->mask.obj);
3334 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3335 evas_object_del(cw->transform_bg_obj);
3336 evas_object_del(cw->transform_tranp_obj);
3337 evas_object_del(cw->default_input_obj);
3338 eina_stringshare_del(cw->frame_theme);
3339 eina_stringshare_del(cw->frame_name);
3343 e_comp->animating--;
3345 e_object_unref(E_OBJECT(cw->ec));
3347 cw->ec->frame = NULL;
3352 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3356 cw->x = x, cw->y = y;
3357 evas_object_move(cw->effect_obj, x, y);
3358 evas_object_move(cw->default_input_obj, x, y);
3359 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3361 e_comp_object_map_update(obj);
3365 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3367 Eina_Bool first = EINA_FALSE;
3372 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3374 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3376 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3378 if (cw->w != w || cw->h != h)
3379 e_comp_object_map_update(obj);
3381 first = ((cw->w < 1) || (cw->h < 1));
3382 cw->w = w, cw->h = h;
3386 if (cw->frame_object)
3387 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3390 /* verify pixmap:object size */
3391 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3393 if ((ww != pw) || (hh != ph))
3394 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3396 evas_object_resize(cw->effect_obj, tw, th);
3397 evas_object_resize(cw->default_input_obj, w, h);
3399 evas_object_resize(cw->input_obj, w, h);
3401 evas_object_resize(cw->mask.obj, w, h);
3402 /* resize render update tiler */
3405 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3406 cw->updates_full = 0;
3407 if (cw->updates) eina_tiler_clear(cw->updates);
3411 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3412 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3420 e_comp_render_queue();
3426 _e_comp_smart_init(void)
3428 if (_e_comp_smart) return;
3430 static const Evas_Smart_Class sc =
3433 EVAS_SMART_CLASS_VERSION,
3437 _e_comp_smart_resize,
3440 _e_comp_smart_color_set,
3441 _e_comp_smart_clip_set,
3442 _e_comp_smart_clip_unset,
3452 _e_comp_smart = evas_smart_class_new(&sc);
3457 e_comp_object_init(void)
3459 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3460 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3461 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3462 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3466 e_comp_object_shutdown(void)
3472 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3474 API_ENTRY EINA_FALSE;
3475 return !!cw->force_visible;
3477 /////////////////////////////////////////////////////////
3480 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3483 Eina_Bool comp_object;
3485 comp_object = !!evas_object_data_get(obj, "comp_object");
3490 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3492 e_comp_render_queue();
3494 l = evas_object_data_get(obj, "comp_object-to_del");
3495 E_FREE_LIST(l, evas_object_del);
3499 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3501 if (e_comp_util_object_is_above_nocomp(obj) &&
3502 (!evas_object_data_get(obj, "comp_override")))
3504 evas_object_data_set(obj, "comp_override", (void*)1);
3505 e_comp_override_add();
3510 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3512 Eina_Bool ref = EINA_TRUE;
3513 if (evas_object_visible_get(obj))
3517 d = evas_object_data_del(obj, "comp_hiding");
3519 /* currently trying to hide */
3522 /* already visible */
3526 evas_object_show(obj);
3529 evas_object_ref(obj);
3530 evas_object_data_set(obj, "comp_ref", (void*)1);
3532 edje_object_signal_emit(obj, "e,state,visible", "e");
3533 evas_object_data_set(obj, "comp_showing", (void*)1);
3534 if (e_comp_util_object_is_above_nocomp(obj))
3536 evas_object_data_set(obj, "comp_override", (void*)1);
3537 e_comp_override_add();
3542 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3544 if (!evas_object_visible_get(obj)) return;
3545 /* already hiding */
3546 if (evas_object_data_get(obj, "comp_hiding")) return;
3547 if (!evas_object_data_del(obj, "comp_showing"))
3549 evas_object_ref(obj);
3550 evas_object_data_set(obj, "comp_ref", (void*)1);
3552 edje_object_signal_emit(obj, "e,state,hidden", "e");
3553 evas_object_data_set(obj, "comp_hiding", (void*)1);
3555 if (evas_object_data_del(obj, "comp_override"))
3556 e_comp_override_timed_pop();
3560 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3562 if (!e_util_strcmp(emission, "e,action,hide,done"))
3564 if (!evas_object_data_del(obj, "comp_hiding")) return;
3565 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3566 evas_object_hide(obj);
3567 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3570 evas_object_data_del(obj, "comp_showing");
3571 if (evas_object_data_del(obj, "comp_ref"))
3572 evas_object_unref(obj);
3576 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3582 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3586 E_API E_Comp_Object_Hook *
3587 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3589 E_Comp_Object_Hook *ch;
3591 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3592 ch = E_NEW(E_Comp_Object_Hook, 1);
3593 if (!ch) return NULL;
3594 ch->hookpoint = hookpoint;
3596 ch->data = (void*)data;
3597 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3602 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3605 if (_e_comp_object_hooks_walking == 0)
3607 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3611 _e_comp_object_hooks_delete++;
3614 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3615 E_API E_Comp_Object_Intercept_Hook *
3616 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3618 E_Comp_Object_Intercept_Hook *ch;
3620 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3621 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3622 if (!ch) return NULL;
3623 ch->hookpoint = hookpoint;
3625 ch->data = (void*)data;
3626 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3631 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3634 if (_e_comp_object_intercept_hooks_walking == 0)
3636 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3640 _e_comp_object_intercept_hooks_delete++;
3645 e_comp_object_util_add(Evas_Object *obj)
3649 E_Comp_Config *conf = e_comp_config_get();
3650 Eina_Bool skip = EINA_FALSE;
3656 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3658 name = evas_object_name_get(obj);
3659 vis = evas_object_visible_get(obj);
3660 o = edje_object_add(e_comp->evas);
3661 evas_object_data_set(o, "comp_object", (void*)1);
3663 skip = (!strncmp(name, "noshadow", 8));
3665 evas_object_data_set(o, "comp_object_skip", (void*)1);
3667 if (conf->shadow_style)
3669 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3670 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3673 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3674 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3675 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3677 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3679 evas_object_geometry_get(obj, &x, &y, &w, &h);
3680 evas_object_geometry_set(o, x, y, w, h);
3681 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3683 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3685 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3686 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3687 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3688 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3689 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3690 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3692 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3694 edje_object_part_swallow(o, "e.swallow.content", obj);
3696 _e_comp_object_event_add(o);
3699 evas_object_show(o);
3704 /* utility functions for deleting objects when their "owner" is deleted */
3706 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3711 EINA_SAFETY_ON_NULL_RETURN(to_del);
3712 l = evas_object_data_get(obj, "comp_object-to_del");
3713 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3714 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3715 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3719 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3724 EINA_SAFETY_ON_NULL_RETURN(to_del);
3725 l = evas_object_data_get(obj, "comp_object-to_del");
3727 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3730 /////////////////////////////////////////////////////////
3732 EINTERN Evas_Object *
3733 e_comp_object_client_add(E_Client *ec)
3738 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3739 if (ec->frame) return NULL;
3740 _e_comp_smart_init();
3741 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3742 cw = evas_object_smart_data_get(o);
3743 if (!cw) return NULL;
3744 evas_object_data_set(o, "E_Client", ec);
3747 evas_object_data_set(o, "comp_object", (void*)1);
3749 _e_comp_object_event_add(o);
3754 /* utility functions for getting client inset */
3756 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3759 if (!cw->client_inset.calc)
3765 if (ax) *ax = x - cw->client_inset.l;
3766 if (ay) *ay = y - cw->client_inset.t;
3770 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3773 if (!cw->client_inset.calc)
3779 if (ax) *ax = x + cw->client_inset.l;
3780 if (ay) *ay = y + cw->client_inset.t;
3784 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3787 if (!cw->client_inset.calc)
3793 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3794 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3798 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3801 if (!cw->client_inset.calc)
3807 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3808 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3812 e_comp_object_client_get(Evas_Object *obj)
3817 /* FIXME: remove this when eo is used */
3818 o = evas_object_data_get(obj, "comp_smart_obj");
3820 return e_comp_object_client_get(o);
3821 return cw ? cw->ec : NULL;
3825 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3828 if (cw->frame_extends)
3829 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3834 if (w) *w = cw->ec->w;
3835 if (h) *h = cw->ec->h;
3840 e_comp_object_util_zone_get(Evas_Object *obj)
3842 E_Zone *zone = NULL;
3846 zone = e_comp_zone_find_by_ec(cw->ec);
3851 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3852 zone = e_comp_zone_xy_get(x, y);
3858 e_comp_object_util_center(Evas_Object *obj)
3860 int x, y, w, h, ow, oh;
3865 zone = e_comp_object_util_zone_get(obj);
3866 EINA_SAFETY_ON_NULL_RETURN(zone);
3867 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3868 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3869 ow = cw->ec->w, oh = cw->ec->h;
3871 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3872 x = x + (w - ow) / 2;
3873 y = y + (h - oh) / 2;
3874 evas_object_move(obj, x, y);
3878 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3880 int x, y, w, h, ow, oh;
3883 EINA_SAFETY_ON_NULL_RETURN(on);
3884 evas_object_geometry_get(on, &x, &y, &w, &h);
3885 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3886 ow = cw->ec->w, oh = cw->ec->h;
3888 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3889 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3893 e_comp_object_util_fullscreen(Evas_Object *obj)
3898 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3901 evas_object_move(obj, 0, 0);
3902 evas_object_resize(obj, e_comp->w, e_comp->h);
3907 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3915 ow = cw->w, oh = cw->h;
3917 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3918 zone = e_comp_object_util_zone_get(obj);
3919 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3920 if (x) *x = zx + (zw - ow) / 2;
3921 if (y) *y = zy + (zh - oh) / 2;
3925 e_comp_object_input_objs_del(Evas_Object *obj)
3928 E_Input_Rect_Data *input_rect_data;
3929 E_Input_Rect_Smart_Data *input_rect_sd;
3934 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3935 if (!input_rect_sd) return;
3937 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3939 if (input_rect_data->obj)
3941 evas_object_smart_member_del(input_rect_data->obj);
3942 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3944 E_FREE(input_rect_data);
3949 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3952 E_Input_Rect_Data *input_rect_data = NULL;
3953 E_Input_Rect_Smart_Data *input_rect_sd;
3954 int client_w, client_h;
3956 if (cw->ec->client.w)
3957 client_w = cw->ec->client.w;
3959 client_w = cw->ec->w;
3961 if (cw->ec->client.h)
3962 client_h = cw->ec->client.h;
3964 client_h = cw->ec->h;
3966 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3970 _e_comp_input_obj_smart_init();
3971 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3972 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3973 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3976 input_rect_sd->cw = cw;
3979 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3982 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3983 if (input_rect_data)
3985 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3986 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3990 if ((input_rect_data) &&
3991 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3993 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3994 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3995 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3996 evas_object_clip_set(input_rect_data->obj, cw->clip);
3997 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3998 evas_object_geometry_set(input_rect_data->obj,
3999 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4000 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4001 evas_object_pass_events_set(cw->default_input_obj, 1);
4002 evas_object_pass_events_set(cw->obj, 1);
4005 evas_object_show(input_rect_data->obj);
4006 evas_object_show(cw->input_obj);
4011 evas_object_smart_member_del(cw->input_obj);
4012 E_FREE_FUNC(cw->input_obj, evas_object_del);
4013 evas_object_pass_events_set(cw->default_input_obj, 0);
4014 evas_object_pass_events_set(cw->obj, 0);
4019 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4022 E_Input_Rect_Smart_Data *input_rect_sd;
4023 E_Input_Rect_Data *input_rect_data;
4026 if (!cw->input_obj) return;
4028 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4031 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4033 *list = eina_list_append(*list, &input_rect_data->rect);
4039 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4042 if (l) *l = cw->client_inset.l;
4043 if (r) *r = cw->client_inset.r;
4044 if (t) *t = cw->client_inset.t;
4045 if (b) *b = cw->client_inset.b;
4048 /* set geometry for CSD */
4050 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4056 if (cw->frame_object)
4057 CRI("ACK! ec:%p", cw->ec);
4058 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4059 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4060 calc = cw->client_inset.calc;
4061 cw->client_inset.calc = l || r || t || b;
4062 eina_stringshare_replace(&cw->frame_theme, "borderless");
4063 if (cw->client_inset.calc)
4065 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4066 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4067 e_client_size_set(cw->ec, tw, th);
4069 else if (cw->ec->maximized || cw->ec->fullscreen)
4071 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4072 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4074 if (!cw->ec->new_client)
4076 if (calc && cw->client_inset.calc)
4078 tx = cw->ec->x - (l - cw->client_inset.l);
4079 ty = cw->ec->y - (t - cw->client_inset.t);
4080 e_client_pos_set(cw->ec, tx, ty);
4082 cw->ec->changes.pos = cw->ec->changes.size = 1;
4085 cw->client_inset.l = l;
4086 cw->client_inset.r = r;
4087 cw->client_inset.t = t;
4088 cw->client_inset.b = b;
4092 e_comp_object_frame_allowed(Evas_Object *obj)
4094 API_ENTRY EINA_FALSE;
4095 return (cw->frame_object || (!cw->client_inset.calc));
4099 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4101 API_ENTRY EINA_FALSE;
4102 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4103 eina_stringshare_replace(&cw->frame_name, name);
4104 if (cw->frame_object)
4105 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4110 e_comp_object_frame_exists(Evas_Object *obj)
4112 API_ENTRY EINA_FALSE;
4113 return !!cw->frame_object;
4117 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4119 Evas_Object *o, *pbg;
4122 Eina_Stringshare *theme;
4124 API_ENTRY EINA_FALSE;
4126 if (!e_util_strcmp(cw->frame_theme, name))
4127 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4128 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4129 return _e_comp_object_shadow_setup(cw);
4130 pbg = cw->frame_object;
4131 theme = eina_stringshare_add(name);
4133 if (cw->frame_object)
4137 w = cw->ec->w, h = cw->ec->h;
4138 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4139 if ((cw->ec->w != w) || (cw->ec->h != h))
4141 cw->ec->changes.size = 1;
4144 E_FREE_FUNC(cw->frame_object, evas_object_del);
4145 if (!name) goto reshadow;
4147 o = edje_object_add(e_comp->evas);
4148 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4149 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4150 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4152 cw->frame_object = NULL;
4154 eina_stringshare_del(cw->frame_theme);
4155 cw->frame_theme = theme;
4160 if (theme != e_config->theme_default_border_style)
4162 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4163 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4167 ok = e_theme_edje_object_set(o, "base/theme/border",
4168 "e/widgets/border/default/border");
4169 if (ok && (theme == e_config->theme_default_border_style))
4171 /* Reset default border style to default */
4172 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4173 e_config_save_queue();
4180 cw->frame_object = o;
4181 eina_stringshare_del(cw->frame_theme);
4182 cw->frame_theme = theme;
4183 evas_object_name_set(o, "cw->frame_object");
4186 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4190 cw->ec->changes.icon = 1;
4196 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4201 _e_comp_object_shadow_setup(cw);
4204 int old_x, old_y, new_x = 0, new_y = 0;
4206 old_x = cw->x, old_y = cw->y;
4208 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4210 new_x = cw->ec->x, new_y = cw->ec->y;
4211 else if (cw->ec->placed || (!cw->ec->new_client))
4213 /* if no previous frame:
4214 * - reapply client_inset
4219 if (cw->ec->changes.size)
4227 zone = e_comp_zone_find_by_ec(cw->ec);
4230 x = cw->ec->client.x, y = cw->ec->client.y;
4231 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4232 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4234 new_x = x, new_y = y;
4237 if (old_x != new_x || old_y != new_y)
4239 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4240 cw->y = cw->x = -99999;
4241 evas_object_move(obj, new_x, new_y);
4245 if (cw->ec->maximized)
4247 cw->ec->changes.need_maximize = 1;
4250 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4251 if (cw->frame_object)
4253 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4256 cw->frame_extends = 0;
4257 evas_object_del(pbg);
4262 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4264 E_Comp_Object_Mover *prov;
4267 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4268 edje_object_signal_emit(cw->shobj, sig, src);
4269 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4270 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4271 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4273 /* start with highest priority callback first */
4274 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4276 if (!e_util_glob_match(sig, prov->sig)) continue;
4277 if (prov->func(prov->data, obj, sig)) break;
4282 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4284 /* FIXME: at some point I guess this should use eo to inherit
4285 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4286 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4289 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4293 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4296 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4300 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4303 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4307 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4310 Eina_Rectangle rect;
4313 if (cw->ec->input_only || (!cw->updates)) return;
4314 if (cw->nocomp) return;
4315 rect.x = x, rect.y = y;
4316 rect.w = w, rect.h = h;
4317 evas_object_smart_callback_call(obj, "damage", &rect);
4319 if (e_comp_is_on_overlay(cw->ec))
4321 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4322 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4323 * E module attempts to block screen update due to the particular policy.
4325 if (e_pixmap_resource_get(cw->ec->pixmap))
4326 cw->hwc_need_update = EINA_TRUE;
4329 /* ignore overdraw */
4330 if (cw->updates_full)
4332 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4333 e_comp_object_render_update_add(obj);
4335 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4336 evas_object_show(cw->smart_obj);
4340 /* clip rect to client surface */
4341 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4342 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4343 /* if rect is the total size of the client after clip, clear the updates
4344 * since this is guaranteed to be the whole region anyway
4346 eina_tiler_area_size_get(cw->updates, &tw, &th);
4347 if ((w > tw) || (h > th))
4349 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4350 eina_tiler_clear(cw->updates);
4351 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4353 tw = cw->ec->client.w, th = cw->ec->client.h;
4355 if ((!x) && (!y) && (w == tw) && (h == th))
4357 eina_tiler_clear(cw->updates);
4358 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4359 cw->updates_full = 1;
4360 cw->update_count = 0;
4363 if (cw->update_count > UPDATE_MAX)
4365 /* this is going to get really dumb, so just update the whole thing */
4366 eina_tiler_clear(cw->updates);
4367 cw->update_count = cw->updates_full = 1;
4368 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4369 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4373 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4374 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4376 cw->updates_exist = 1;
4377 e_comp_object_render_update_add(obj);
4379 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4380 evas_object_show(cw->smart_obj);
4384 e_comp_object_damage_exists(Evas_Object *obj)
4386 API_ENTRY EINA_FALSE;
4387 return cw->updates_exist;
4391 e_comp_object_render_update_add(Evas_Object *obj)
4395 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4396 if (cw->render_update_lock.lock) return;
4397 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4401 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4403 e_comp_render_queue();
4407 e_comp_object_render_update_del(Evas_Object *obj)
4411 if (cw->ec->input_only || (!cw->updates)) return;
4412 if (!cw->update) return;
4414 /* this gets called during comp animating to clear the update flag */
4415 if (e_comp->grabbed) return;
4416 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4417 if (!e_comp->updates)
4419 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4420 if (e_comp->render_animator)
4421 ecore_animator_freeze(e_comp->render_animator);
4426 e_comp_object_shape_apply(Evas_Object *obj)
4430 unsigned int i, *pix, *p;
4434 if (!cw->ec) return; //NYI
4435 if (cw->external_content) return;
4438 if ((cw->ec->shape_rects_num >= 1) &&
4439 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4444 ERR("BUGGER: shape with native surface? cw=%p", cw);
4447 evas_object_image_size_get(cw->obj, &w, &h);
4448 if ((w < 1) || (h < 1)) return;
4451 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4452 _e_comp_object_alpha_set(cw);
4453 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4454 evas_object_image_alpha_set(o, 1);
4456 p = pix = evas_object_image_data_get(cw->obj, 1);
4459 evas_object_image_data_set(cw->obj, pix);
4464 unsigned char *spix, *sp;
4466 spix = calloc(w * h, sizeof(unsigned char));
4468 for (i = 0; i < cw->ec->shape_rects_num; i++)
4472 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4473 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4474 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4475 sp = spix + (w * ry) + rx;
4476 for (py = 0; py < rh; py++)
4478 for (px = 0; px < rw; px++)
4486 for (py = 0; py < h; py++)
4488 for (px = 0; px < w; px++)
4490 unsigned int mask, imask;
4492 mask = ((unsigned int)(*sp)) << 24;
4494 imask |= imask >> 8;
4495 imask |= imask >> 8;
4496 *p = mask | (*p & imask);
4497 //if (*sp) *p = 0xff000000 | *p;
4498 //else *p = 0x00000000;
4507 for (py = 0; py < h; py++)
4509 for (px = 0; px < w; px++)
4513 evas_object_image_data_set(cw->obj, pix);
4514 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4515 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4517 evas_object_image_data_set(o, pix);
4518 evas_object_image_data_update_add(o, 0, 0, w, h);
4520 // don't need to fix alpha chanel as blending
4521 // should be totally off here regardless of
4522 // alpha channel content
4526 _e_comp_object_clear(E_Comp_Object *cw)
4531 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4533 if (cw->render_update_lock.lock) return;
4536 e_pixmap_clear(cw->ec->pixmap);
4538 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4539 evas_object_image_size_set(cw->obj, 1, 1);
4540 evas_object_image_data_set(cw->obj, NULL);
4541 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4543 evas_object_image_size_set(o, 1, 1);
4544 evas_object_image_data_set(o, NULL);
4547 e_comp_object_render_update_del(cw->smart_obj);
4551 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4555 API_ENTRY EINA_FALSE;
4557 if (cw->transparent.set == set)
4562 evas_object_color_get(obj, &r, &g, &b, &a);
4563 evas_object_color_set(obj, 0, 0, 0, 0);
4565 cw->transparent.user_r = r;
4566 cw->transparent.user_g = g;
4567 cw->transparent.user_b = b;
4568 cw->transparent.user_a = a;
4570 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4572 cw->transparent.user_r,
4573 cw->transparent.user_g,
4574 cw->transparent.user_b,
4575 cw->transparent.user_a);
4577 cw->transparent.set = EINA_TRUE;
4581 cw->transparent.set = EINA_FALSE;
4583 evas_object_color_set(obj,
4584 cw->transparent.user_r,
4585 cw->transparent.user_g,
4586 cw->transparent.user_b,
4587 cw->transparent.user_a);
4589 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4591 cw->transparent.user_r,
4592 cw->transparent.user_g,
4593 cw->transparent.user_b,
4594 cw->transparent.user_a);
4600 /* helper function to simplify toggling of redirection for display servers which support it */
4602 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4607 if (cw->redirected == set) return;
4608 cw->redirected = set;
4609 if (cw->external_content) return;
4611 e_comp_object_map_update(obj);
4615 if (cw->updates_exist)
4616 e_comp_object_render_update_add(obj);
4618 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4620 _e_comp_object_transparent_set(obj, EINA_FALSE);
4621 evas_object_smart_callback_call(obj, "redirected", NULL);
4625 _e_comp_object_clear(cw);
4626 _e_comp_object_transparent_set(obj, EINA_TRUE);
4627 evas_object_smart_callback_call(obj, "unredirected", NULL);
4632 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4635 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4637 if (cw->buffer_destroy_listener.notify)
4639 cw->buffer_destroy_listener.notify = NULL;
4640 wl_list_remove(&cw->buffer_destroy_listener.link);
4643 if (e_object_is_del(E_OBJECT(cw->ec)))
4645 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4650 /* if it's current displaying buffer, do not remove its content */
4651 if (!evas_object_visible_get(cw->ec->frame))
4652 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4657 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4662 if (cw->buffer_destroy_listener.notify)
4664 wl_list_remove(&cw->buffer_destroy_listener.link);
4665 cw->buffer_destroy_listener.notify = NULL;
4668 if (cw->tbm_surface)
4670 tbm_surface_internal_unref(cw->tbm_surface);
4671 cw->tbm_surface = NULL;
4676 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4678 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4679 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4681 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4683 tbm_surface_internal_ref(ns->data.tbm.buffer);
4684 cw->tbm_surface = ns->data.tbm.buffer;
4688 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4689 evas_object_image_native_surface_set(cw->obj, ns);
4693 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4695 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4696 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4697 evas_object_image_native_surface_set(o, ns);
4704 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4706 Evas_Native_Surface ns;
4709 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4710 if (cw->ec->input_only) return;
4711 if (cw->external_content) return;
4712 if (cw->render_update_lock.lock) return;
4715 memset(&ns, 0, sizeof(Evas_Native_Surface));
4719 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4720 set = (!cw->ec->shaped);
4722 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4726 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4730 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4733 if (cw->ec->input_only) return;
4736 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4737 _e_comp_object_alpha_set(cw);
4739 e_comp_object_native_surface_set(obj, cw->native);
4740 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4744 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4750 if (cw->blanked == set) return;
4752 _e_comp_object_alpha_set(cw);
4755 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4756 evas_object_image_data_set(cw->obj, NULL);
4760 e_comp_object_native_surface_set(obj, 1);
4761 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4765 _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)
4770 if (!_damage_trace) return;
4774 if (!evas_object_visible_get(cw->obj)) return;
4776 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4778 o = evas_object_rectangle_add(e_comp->evas);
4779 evas_object_layer_set(o, E_LAYER_MAX);
4780 evas_object_name_set(o, "damage_trace");
4781 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4782 evas_object_resize(o, dmg_w, dmg_h);
4783 evas_object_color_set(o, 0, 128, 0, 128);
4784 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4785 evas_object_pass_events_set(o, EINA_TRUE);
4786 evas_object_show(o);
4788 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4790 dmg_w, dmg_h, dmg_x, dmg_y,
4791 origin->w, origin->h, origin->x, origin->y);
4793 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4796 /* mark an object as dirty and setup damages */
4798 e_comp_object_dirty(Evas_Object *obj)
4801 Eina_Rectangle *rect;
4805 Eina_Bool dirty, visible;
4809 if (cw->external_content) return;
4810 if (!cw->redirected) return;
4811 if (cw->render_update_lock.lock)
4813 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4816 /* only actually dirty if pixmap is available */
4817 if (!e_pixmap_resource_get(cw->ec->pixmap))
4819 // e_pixmap_size_get returns last attached buffer size
4820 // eventhough it is destroyed
4821 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4824 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4825 visible = cw->visible;
4826 if (!dirty) w = h = 1;
4827 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4829 evas_object_image_data_set(cw->obj, NULL);
4830 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4831 evas_object_image_size_set(cw->obj, tw, th);
4832 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4833 if (cw->pending_updates)
4834 eina_tiler_area_size_set(cw->pending_updates, w, h);
4835 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4837 evas_object_image_pixels_dirty_set(o, dirty);
4839 evas_object_image_data_set(o, NULL);
4840 evas_object_image_size_set(o, tw, th);
4841 visible |= evas_object_visible_get(o);
4845 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4849 e_comp_object_native_surface_set(obj, 1);
4851 m = _e_comp_object_map_damage_transform_get(cw->ec);
4852 it = eina_tiler_iterator_new(cw->updates);
4853 EINA_ITERATOR_FOREACH(it, rect)
4855 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4856 * of evas engine and doesn't convert damage according to evas_map.
4857 * so damage of evas_object_image use surface coordinate.
4861 int damage_x, damage_y, damage_w, damage_h;
4863 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4864 &damage_x, &damage_y, &damage_w, &damage_h);
4865 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4866 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4870 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4871 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4874 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4875 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4876 if (cw->pending_updates)
4877 eina_tiler_rect_add(cw->pending_updates, rect);
4879 eina_iterator_free(it);
4880 if (m) e_map_free(m);
4881 if (cw->pending_updates)
4882 eina_tiler_clear(cw->updates);
4885 cw->pending_updates = cw->updates;
4886 cw->updates = eina_tiler_new(w, h);
4887 eina_tiler_tile_size_set(cw->updates, 1, 1);
4889 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4890 evas_object_smart_callback_call(obj, "dirty", NULL);
4891 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4892 /* force render if main object is hidden but mirrors are visible */
4893 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4894 e_comp_object_render(obj);
4898 e_comp_object_render(Evas_Object *obj)
4905 API_ENTRY EINA_FALSE;
4907 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4908 if (cw->ec->input_only) return EINA_TRUE;
4909 if (cw->external_content) return EINA_TRUE;
4910 if (cw->native) return EINA_FALSE;
4911 /* if comp object is not redirected state, comp object should not be set by newly committed data
4912 because image size of comp object is 1x1 and it should not be shown on canvas */
4913 if (!cw->redirected) return EINA_TRUE;
4914 if (cw->render_update_lock.lock)
4916 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4919 e_comp_object_render_update_del(obj);
4920 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4922 if (!cw->pending_updates)
4924 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4925 evas_object_image_data_set(cw->obj, NULL);
4926 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4927 evas_object_image_data_set(o, NULL);
4931 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4933 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4935 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4938 e_pixmap_image_refresh(cw->ec->pixmap);
4939 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4942 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4943 e_pixmap_image_data_ref(cw->ec->pixmap);
4945 /* set pixel data */
4946 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4947 _e_comp_object_alpha_set(cw);
4948 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4950 evas_object_image_data_set(o, pix);
4951 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4952 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4955 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4957 e_comp_client_post_update_add(cw->ec);
4962 /* create a duplicate of an evas object */
4964 e_comp_object_util_mirror_add(Evas_Object *obj)
4968 unsigned int *pix = NULL;
4969 Eina_Bool argb = EINA_FALSE;
4974 cw = evas_object_data_get(obj, "comp_mirror");
4977 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4978 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4979 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4980 evas_object_image_alpha_set(o, 1);
4981 evas_object_image_source_set(o, obj);
4984 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4985 if (cw->external_content)
4987 ERR("%p of client %p is external content.", obj, cw->ec);
4990 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4991 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4992 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4993 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4994 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4995 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4996 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4997 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4998 evas_object_data_set(o, "comp_mirror", cw);
5000 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5001 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5003 evas_object_image_size_set(o, tw, th);
5006 pix = evas_object_image_data_get(cw->obj, 0);
5012 evas_object_image_native_surface_set(o, cw->ns);
5015 Evas_Native_Surface ns;
5016 memset(&ns, 0, sizeof(Evas_Native_Surface));
5017 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5018 evas_object_image_native_surface_set(o, &ns);
5023 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5024 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5026 (e_pixmap_image_exists(cw->ec->pixmap)))
5027 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5029 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5036 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5037 evas_object_image_pixels_dirty_set(o, dirty);
5038 evas_object_image_data_set(o, pix);
5039 evas_object_image_data_set(cw->obj, pix);
5041 evas_object_image_data_update_add(o, 0, 0, tw, th);
5046 //////////////////////////////////////////////////////
5049 e_comp_object_effect_allowed_get(Evas_Object *obj)
5051 API_ENTRY EINA_FALSE;
5053 if (!cw->shobj) return EINA_FALSE;
5054 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5055 return !e_comp_config_get()->match.disable_borders;
5058 /* setup an api effect for a client */
5060 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5063 Eina_Stringshare *grp;
5064 E_Comp_Config *config;
5065 Eina_Bool loaded = EINA_FALSE;
5067 API_ENTRY EINA_FALSE;
5068 if (!cw->shobj) return EINA_FALSE; //input window
5070 if (!effect) effect = "none";
5071 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5073 config = e_comp_config_get();
5074 if ((config) && (config->effect_file))
5076 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5078 cw->effect_set = EINA_TRUE;
5085 edje_object_file_get(cw->effect_obj, NULL, &grp);
5086 cw->effect_set = !eina_streq(effect, "none");
5087 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5088 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5090 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5091 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5092 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5094 if (cw->effect_running)
5096 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5099 cw->effect_set = EINA_FALSE;
5100 return cw->effect_set;
5104 if (cw->effect_running)
5106 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5109 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5110 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5111 if (cw->effect_clip)
5113 evas_object_clip_unset(cw->clip);
5114 cw->effect_clip = 0;
5116 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5118 _e_comp_object_dim_update(cw);
5120 return cw->effect_set;
5123 /* set params for embryo scripts in effect */
5125 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5127 Edje_Message_Int_Set *msg;
5131 EINA_SAFETY_ON_NULL_RETURN(params);
5132 EINA_SAFETY_ON_FALSE_RETURN(count);
5133 if (!cw->effect_set) return;
5135 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5136 msg->count = (int)count;
5137 for (x = 0; x < count; x++)
5138 msg->val[x] = params[x];
5139 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5140 edje_object_message_signal_process(cw->effect_obj);
5144 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5146 Edje_Signal_Cb end_cb;
5148 E_Comp_Object *cw = data;
5150 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5151 cw->effect_running = 0;
5152 if (!_e_comp_object_animating_end(cw)) return;
5154 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5156 evas_object_data_del(cw->smart_obj, "effect_running");
5157 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5158 e_comp_visibility_calculation_set(EINA_TRUE);
5161 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5162 if (!end_cb) return;
5163 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5164 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5165 end_cb(end_data, cw->smart_obj, emission, source);
5168 /* clip effect to client's zone */
5170 e_comp_object_effect_clip(Evas_Object *obj)
5174 zone = e_comp_zone_find_by_ec(cw->ec);
5176 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5177 if (!cw->effect_clip_able) return;
5178 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5179 cw->effect_clip = 1;
5182 /* unclip effect from client's zone */
5184 e_comp_object_effect_unclip(Evas_Object *obj)
5187 if (!cw->effect_clip) return;
5188 evas_object_clip_unset(cw->smart_obj);
5189 cw->effect_clip = 0;
5192 /* start effect, running end_cb after */
5194 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5196 API_ENTRY EINA_FALSE;
5197 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5198 if (!cw->effect_set) return EINA_FALSE;
5200 if (cw->effect_running)
5202 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5205 e_comp_object_effect_clip(obj);
5206 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5208 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5209 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5210 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5211 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5213 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5214 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5216 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5217 _e_comp_object_animating_begin(cw);
5218 cw->effect_running = 1;
5222 /* stop a currently-running effect immediately */
5224 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5227 Edje_Signal_Cb end_cb_before = NULL;
5228 void *end_data_before = NULL;
5229 API_ENTRY EINA_FALSE;
5231 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5232 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5234 if (end_cb_before != end_cb) return EINA_TRUE;
5235 e_comp_object_effect_unclip(obj);
5236 if (cw->effect_clip)
5238 evas_object_clip_unset(cw->effect_obj);
5239 cw->effect_clip = 0;
5241 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5242 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5244 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5246 evas_object_data_del(cw->smart_obj, "effect_running");
5247 e_comp_visibility_calculation_set(EINA_TRUE);
5250 cw->effect_running = 0;
5251 ret = _e_comp_object_animating_end(cw);
5253 if ((ret) && (end_cb_before))
5255 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5256 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5263 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5265 return a->pri - b->pri;
5268 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5269 E_API E_Comp_Object_Mover *
5270 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5272 E_Comp_Object_Mover *prov;
5274 prov = E_NEW(E_Comp_Object_Mover, 1);
5275 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5276 prov->func = provider;
5277 prov->data = (void*)data;
5280 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5281 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5286 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5288 EINA_SAFETY_ON_NULL_RETURN(prov);
5289 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5294 e_comp_object_effect_object_get(Evas_Object *obj)
5298 return cw->effect_obj;
5302 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5304 API_ENTRY EINA_FALSE;
5305 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5306 if (!cw->effect_set) return EINA_FALSE;
5313 ////////////////////////////////////
5316 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5318 if (e_comp->autoclose.obj)
5320 e_comp_ungrab_input(0, 1);
5321 if (e_comp->autoclose.del_cb)
5322 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5323 else if (!already_del)
5325 evas_object_hide(e_comp->autoclose.obj);
5326 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5328 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5330 e_comp->autoclose.obj = NULL;
5331 e_comp->autoclose.data = NULL;
5332 e_comp->autoclose.del_cb = NULL;
5333 e_comp->autoclose.key_cb = NULL;
5334 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5338 _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)
5340 _e_comp_object_autoclose_cleanup(0);
5344 _e_comp_object_autoclose_setup(Evas_Object *obj)
5346 if (!e_comp->autoclose.rect)
5348 /* create rect just below autoclose object to catch mouse events */
5349 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5350 evas_object_move(e_comp->autoclose.rect, 0, 0);
5351 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5352 evas_object_show(e_comp->autoclose.rect);
5353 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5354 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5355 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5356 e_comp_grab_input(0, 1);
5358 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5359 evas_object_focus_set(obj, 1);
5363 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5365 _e_comp_object_autoclose_setup(obj);
5366 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5370 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5372 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5373 _e_comp_object_autoclose_cleanup(1);
5374 if (e_client_focused_get()) return;
5376 E_Zone *zone = e_zone_current_get();
5379 e_zone_focus_reset(zone);
5383 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5387 if (e_comp->autoclose.obj)
5389 if (e_comp->autoclose.obj == obj) return;
5390 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5391 e_comp->autoclose.obj = obj;
5392 e_comp->autoclose.del_cb = del_cb;
5393 e_comp->autoclose.key_cb = cb;
5394 e_comp->autoclose.data = (void*)data;
5395 if (evas_object_visible_get(obj))
5396 _e_comp_object_autoclose_setup(obj);
5398 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5399 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5402 e_comp->autoclose.obj = obj;
5403 e_comp->autoclose.del_cb = del_cb;
5404 e_comp->autoclose.key_cb = cb;
5405 e_comp->autoclose.data = (void*)data;
5406 if (evas_object_visible_get(obj))
5407 _e_comp_object_autoclose_setup(obj);
5409 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5410 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5414 e_comp_object_is_animating(Evas_Object *obj)
5418 return cw->animating;
5422 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5426 if ((cw->external_content) &&
5427 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5429 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5430 "But current external content is %d object for %p.",
5431 cw->content_type, cw->ec);
5435 cw->user_alpha_set = EINA_TRUE;
5436 cw->user_alpha = alpha;
5438 if (!cw->obj) return;
5440 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5442 evas_object_image_alpha_set(cw->obj, alpha);
5444 if ((!cw->native) && (!cw->external_content))
5445 evas_object_image_data_set(cw->obj, NULL);
5449 e_comp_object_alpha_get(Evas_Object *obj)
5451 API_ENTRY EINA_FALSE;
5453 return evas_object_image_alpha_get(cw->obj);
5457 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5459 Eina_Bool mask_set = EINA_FALSE;
5463 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5464 if (cw->ec->input_only) return;
5471 o = evas_object_rectangle_add(e_comp->evas);
5472 evas_object_color_set(o, 0, 0, 0, 0);
5473 evas_object_clip_set(o, cw->clip);
5474 evas_object_smart_member_add(o, obj);
5475 evas_object_move(o, 0, 0);
5476 evas_object_resize(o, cw->w, cw->h);
5477 /* save render op value to restore when clear a mask.
5479 * NOTE: DO NOT change the render op on ec->frame while mask object
5480 * is set. it will overwrite the changed op value. */
5481 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5482 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5483 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5484 if (cw->visible) evas_object_show(o);
5487 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5488 ELOGF("COMP", " |mask_obj", cw->ec);
5489 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5496 evas_object_smart_member_del(cw->mask.obj);
5497 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5499 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5500 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5506 e_comp_object_mask_has(Evas_Object *obj)
5508 API_ENTRY EINA_FALSE;
5510 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5514 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5519 if ((cw->external_content) &&
5520 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5522 WRN("Can set up size to ONLY evas \"image\" object. "
5523 "But current external content is %d object for %p.",
5524 cw->content_type, cw->ec);
5528 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5530 evas_object_image_size_set(cw->obj, tw, th);
5534 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5536 Eina_Bool transform_set = EINA_FALSE;
5538 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5539 if (cw->ec->input_only) return;
5541 transform_set = !!set;
5545 if (!cw->transform_bg_obj)
5547 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5548 evas_object_move(o, 0, 0);
5549 evas_object_resize(o, 1, 1);
5550 if (cw->transform_bg_color.a >= 255)
5551 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5553 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5554 evas_object_color_set(o,
5555 cw->transform_bg_color.r,
5556 cw->transform_bg_color.g,
5557 cw->transform_bg_color.b,
5558 cw->transform_bg_color.a);
5559 if (cw->visible) evas_object_show(o);
5561 cw->transform_bg_obj = o;
5562 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5564 #ifdef REFACTOR_DESK_AREA
5565 e_comp_object_transform_obj_stack_update(obj);
5567 _e_comp_object_transform_obj_stack_update(obj);
5572 if (cw->transform_bg_obj)
5574 evas_object_smart_member_del(cw->transform_bg_obj);
5575 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5581 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5585 cw->transform_bg_color.r = r;
5586 cw->transform_bg_color.g = g;
5587 cw->transform_bg_color.b = b;
5588 cw->transform_bg_color.a = a;
5590 if (cw->transform_bg_obj)
5592 evas_object_color_set(cw->transform_bg_obj,
5593 cw->transform_bg_color.r,
5594 cw->transform_bg_color.g,
5595 cw->transform_bg_color.b,
5596 cw->transform_bg_color.a);
5601 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5604 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5605 if (cw->ec->input_only) return;
5606 if (!cw->transform_bg_obj) return;
5608 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5612 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5615 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5616 if (cw->ec->input_only) return;
5617 if (!cw->transform_bg_obj) return;
5619 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5623 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5625 Eina_Bool transform_set = EINA_FALSE;
5627 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5628 if (cw->ec->input_only) return;
5630 transform_set = !!set;
5634 if (!cw->transform_tranp_obj)
5636 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5637 evas_object_move(o, 0, 0);
5638 evas_object_resize(o, 1, 1);
5639 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5640 evas_object_color_set(o, 0, 0, 0, 0);
5641 if (cw->visible) evas_object_show(o);
5643 cw->transform_tranp_obj = o;
5644 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5645 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5646 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5648 #ifdef REFACTOR_DESK_AREA
5649 e_comp_object_transform_obj_stack_update(obj);
5651 _e_comp_object_transform_obj_stack_update(obj);
5656 if (cw->transform_tranp_obj)
5658 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5659 evas_object_smart_member_del(cw->transform_tranp_obj);
5660 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5666 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5669 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5670 if (cw->ec->input_only) return;
5671 if (!cw->transform_tranp_obj) return;
5673 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5677 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5680 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5681 if (cw->ec->input_only) return;
5682 if (!cw->transform_tranp_obj) return;
5684 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5687 #ifdef REFACTOR_DESK_AREA
5690 e_comp_object_layer_update(Evas_Object *obj,
5691 Evas_Object *above, Evas_Object *below)
5693 E_Comp_Object *cw2 = NULL;
5694 Evas_Object *o = NULL;
5699 if (cw->ec->layer_block) return;
5700 if ((above) && (below))
5702 ERR("Invalid layer update request! cw=%p", cw);
5710 layer = evas_object_layer_get(o);
5711 cw2 = evas_object_data_get(o, "comp_obj");
5714 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5716 o = evas_object_above_get(o);
5717 if ((!o) || (o == cw->smart_obj)) break;
5718 if (evas_object_layer_get(o) != layer)
5720 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5725 ec = e_client_top_get();
5726 if (ec) o = ec->frame;
5729 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5733 _e_comp_object_layers_remove(cw);
5736 if (cw2->layer > cw->layer)
5737 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5738 else if (cw2->layer == cw->layer)
5741 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5743 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5745 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5748 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5751 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5756 e_comp_object_layer_get(Evas_Object *obj)
5763 e_comp_object_content_set(Evas_Object *obj,
5764 Evas_Object *content,
5765 E_Comp_Object_Content_Type type)
5767 API_ENTRY EINA_FALSE;
5769 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5770 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5771 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5775 ERR("Can't set e.swallow.content to requested content. "
5776 "Previous comp object should not be changed at all.");
5780 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5782 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5783 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5785 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5786 type, content, cw->ec, cw->ec->pixmap);
5790 cw->external_content = EINA_TRUE;
5793 cw->content_type = type;
5794 e_util_size_debug_set(cw->obj, 1);
5795 evas_object_name_set(cw->obj, "cw->obj");
5796 _e_comp_object_alpha_set(cw);
5799 _e_comp_object_shadow_setup(cw);
5801 wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5807 e_comp_object_content_unset(Evas_Object *obj)
5809 API_ENTRY EINA_FALSE;
5811 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5812 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5814 if (!cw->obj && !cw->ec->visible)
5816 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5820 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5822 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5828 if (cw->frame_object)
5829 edje_object_part_unswallow(cw->frame_object, cw->obj);
5831 edje_object_part_unswallow(cw->shobj, cw->obj);
5833 evas_object_del(cw->obj);
5834 evas_object_hide(cw->obj);
5838 cw->external_content = EINA_FALSE;
5839 if (cw->ec->is_cursor)
5842 DBG("%p is cursor surface..", cw->ec);
5843 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5845 evas_object_resize(cw->ec->frame, pw, ph);
5846 evas_object_hide(cw->ec->frame);
5851 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5852 cw->obj = evas_object_image_filled_add(e_comp->evas);
5853 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5854 e_util_size_debug_set(cw->obj, 1);
5855 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5856 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5857 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5858 evas_object_name_set(cw->obj, "cw->obj");
5859 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5860 _e_comp_object_alpha_set(cw);
5863 _e_comp_object_shadow_setup(cw);
5868 _e_comp_intercept_show_helper(cw);
5872 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5873 e_comp_object_dirty(cw->smart_obj);
5874 e_comp_object_render(cw->smart_obj);
5875 e_comp_object_render_update_add(obj);
5877 wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5882 EINTERN Evas_Object *
5883 e_comp_object_content_get(Evas_Object *obj)
5887 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5889 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5891 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5898 E_API E_Comp_Object_Content_Type
5899 e_comp_object_content_type_get(Evas_Object *obj)
5901 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5903 return cw->content_type;
5907 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5910 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5911 E_Comp_Config *conf = e_comp_config_get();
5912 if (cw->ec->input_only) return;
5913 if (!conf->dim_rect_enable) return;
5915 cw->dim.mask_set = mask_set;
5921 if (!cw->dim.enable) return;
5922 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5926 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5928 Eina_Bool mask_set = EINA_FALSE;
5932 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5933 E_Comp_Config *conf = e_comp_config_get();
5934 if (cw->ec->input_only) return;
5935 if (!conf->dim_rect_enable) return;
5941 if (cw->dim.mask_obj)
5943 evas_object_smart_member_del(cw->dim.mask_obj);
5944 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5947 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);
5948 o = evas_object_rectangle_add(e_comp->evas);
5949 evas_object_color_set(o, 0, 0, 0, 0);
5950 evas_object_smart_member_add(o, obj);
5951 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5952 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5954 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5955 if (cw->visible) evas_object_show(o);
5957 cw->dim.mask_obj = o;
5958 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5960 evas_object_layer_set(cw->dim.mask_obj, 9998);
5964 if (cw->dim.mask_obj)
5966 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5967 evas_object_smart_member_del(cw->dim.mask_obj);
5968 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5974 e_comp_object_dim_client_set(E_Client *ec)
5976 E_Comp_Config *conf = e_comp_config_get();
5978 if (!conf->dim_rect_enable) return ;
5979 if (dim_client == ec) return;
5981 Eina_Bool prev_dim = EINA_FALSE;
5982 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5984 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5985 prev_dim = EINA_TRUE;
5987 if (prev_dim && dim_client->visible && ec)
5989 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5990 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5994 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5995 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6001 e_comp_object_dim_client_get(void)
6003 E_Comp_Config *conf = e_comp_config_get();
6005 if (!conf->dim_rect_enable ) return NULL;
6011 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6014 char emit[32] = "\0";
6015 E_Comp_Config *conf = e_comp_config_get();
6018 if (!conf->dim_rect_enable) return;
6019 if (!cw->effect_obj) return;
6020 if (enable == cw->dim.enable) return;
6022 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6023 if (noeffect || !conf->dim_rect_effect)
6025 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6029 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6032 cw->dim.enable = enable;
6034 if (cw->dim.mask_set && !enable)
6036 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6037 edje_object_signal_emit(cw->effect_obj, emit, "e");
6039 else if (cw->dim.mask_set && enable)
6041 edje_object_signal_emit(cw->effect_obj, emit, "e");
6042 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6046 edje_object_signal_emit(cw->effect_obj, emit, "e");
6051 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6053 API_ENTRY EINA_FALSE;
6054 E_Comp_Config *conf = e_comp_config_get();
6056 if (!ec) return EINA_FALSE;
6057 if (!conf->dim_rect_enable) return EINA_FALSE;
6059 if (cw->dim.enable) return EINA_TRUE;
6065 _e_comp_object_dim_update(E_Comp_Object *cw)
6067 E_Comp_Config *conf = e_comp_config_get();
6070 if (!conf->dim_rect_enable) return;
6071 if (!cw->effect_obj) return;
6074 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6075 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6077 if (cw->dim.mask_set)
6079 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6085 e_comp_object_clear(Evas_Object *obj)
6089 _e_comp_object_clear(cw);
6093 e_comp_object_hwc_update_exists(Evas_Object *obj)
6095 API_ENTRY EINA_FALSE;
6096 return cw->hwc_need_update;
6101 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6104 cw->hwc_need_update = set;
6108 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6110 API_ENTRY EINA_FALSE;
6111 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6115 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6118 if (cw->indicator.obj != indicator)
6119 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6120 cw->indicator.obj = indicator;
6121 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6125 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6128 if (cw->indicator.obj != indicator) return;
6129 cw->indicator.obj = NULL;
6130 edje_object_part_unswallow(cw->shobj, indicator);
6134 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6137 Edje_Message_Int_Set *msg;
6139 if (!cw->indicator.obj) return;
6141 cw->indicator.w = w;
6142 cw->indicator.h = h;
6144 if (!cw->shobj) return;
6146 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6150 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6151 edje_object_message_signal_process(cw->shobj);
6154 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6156 e_comp_object_map_update(Evas_Object *obj)
6159 E_Client *ec = cw->ec;
6160 E_Comp_Wl_Client_Data *cdata;
6162 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6165 int l, remain = sizeof buffer;
6168 if (e_object_is_del(E_OBJECT(ec))) return;
6169 cdata = e_client_cdata_get(ec);
6172 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6173 * when new buffer is attached.
6175 if (!cdata->buffer_ref.buffer) return;
6177 if ((!cw->redirected) ||
6178 (e_client_video_hw_composition_check(ec)) ||
6179 (!e_comp_wl_output_buffer_transform_get(ec) &&
6180 cdata->scaler.buffer_viewport.buffer.scale == 1))
6182 if (evas_object_map_enable_get(cw->effect_obj))
6184 ELOGF("TRANSFORM", "map: disable", cw->ec);
6185 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6186 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6187 evas_object_resize(cw->effect_obj, tw, th);
6194 EINA_SAFETY_ON_NULL_RETURN(map);
6196 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6202 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6204 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6205 e_map_point_image_uv_set(map, 0, x, y);
6206 l = snprintf(p, remain, "%d,%d", x, y);
6207 p += l, remain -= l;
6209 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6210 e_map_point_image_uv_set(map, 1, x, y);
6211 l = snprintf(p, remain, " %d,%d", x, y);
6212 p += l, remain -= l;
6214 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6215 e_map_point_image_uv_set(map, 2, x, y);
6216 l = snprintf(p, remain, " %d,%d", x, y);
6217 p += l, remain -= l;
6219 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6220 e_map_point_image_uv_set(map, 3, x, y);
6221 l = snprintf(p, remain, " %d,%d", x, y);
6222 p += l, remain -= l;
6224 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6226 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6228 e_comp_object_map_set(cw->effect_obj, map);
6229 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6233 /* if there's screen rotation with comp mode, then ec->effect_obj and
6234 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6236 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6237 evas_object_resize(cw->effect_obj, tw, th);
6241 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6243 API_ENTRY EINA_FALSE;
6245 cw->render_trace = set;
6251 e_comp_object_native_usable_get(Evas_Object *obj)
6253 API_ENTRY EINA_FALSE;
6254 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6256 if (cw->ec->input_only) return EINA_FALSE;
6257 if (cw->external_content) return EINA_FALSE;
6258 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6260 /* just return true value, if it is normal case */
6261 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6264 Evas_Native_Surface *ns;
6265 ns = evas_object_image_native_surface_get(cw->obj);
6267 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6270 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6278 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6280 API_ENTRY EINA_FALSE;
6281 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6282 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6283 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6285 if (cw->image_filter == filter) return EINA_TRUE;
6289 case E_COMP_IMAGE_FILTER_BLUR:
6290 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6292 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6293 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6295 case E_COMP_IMAGE_FILTER_INVERSE:
6296 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6298 case E_COMP_IMAGE_FILTER_NONE:
6300 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6304 cw->image_filter = filter;
6306 wl_signal_emit_mutable(&cw->events.image_filter_set, NULL);
6311 EINTERN E_Comp_Image_Filter
6312 e_comp_object_image_filter_get(Evas_Object *obj)
6314 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6315 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6316 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6317 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6319 return cw->image_filter;
6323 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6327 if (!_damage_trace) return;
6329 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6330 evas_object_del(obj);
6332 _damage_trace_post_objs = NULL;
6336 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6338 if (!_damage_trace) return;
6340 _damage_trace_post_objs = _damage_trace_objs;
6341 _damage_trace_objs = NULL;
6345 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6347 if (_damage_trace == onoff) return;
6351 evas_event_callback_add(e_comp->evas,
6352 EVAS_CALLBACK_RENDER_PRE,
6353 _e_comp_object_damage_trace_render_pre_cb,
6356 evas_event_callback_add(e_comp->evas,
6357 EVAS_CALLBACK_RENDER_POST,
6358 _e_comp_object_damage_trace_render_post_cb,
6365 EINA_LIST_FREE(_damage_trace_objs, obj)
6366 evas_object_del(obj);
6368 _damage_trace_objs = NULL;
6370 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6371 evas_object_del(obj);
6373 _damage_trace_post_objs = NULL;
6375 evas_event_callback_del(e_comp->evas,
6376 EVAS_CALLBACK_RENDER_PRE,
6377 _e_comp_object_damage_trace_render_pre_cb);
6379 evas_event_callback_del(e_comp->evas,
6380 EVAS_CALLBACK_RENDER_POST,
6381 _e_comp_object_damage_trace_render_post_cb);
6384 _damage_trace = onoff;
6388 e_comp_object_redirected_get(Evas_Object *obj)
6390 API_ENTRY EINA_FALSE;
6391 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6393 return cw->redirected;
6397 e_comp_object_color_visible_get(Evas_Object *obj)
6399 API_ENTRY EINA_FALSE;
6402 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6404 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6408 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6412 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6416 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6424 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6426 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6428 return e_map_set_to_comp_object(em, obj);
6432 e_comp_object_map_get(const Evas_Object *obj)
6434 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6436 return e_map_get_from_comp_object(obj);
6440 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6442 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6444 evas_object_map_enable_set(obj, enable);
6450 e_comp_object_render_update_lock(Evas_Object *obj)
6452 E_Comp_Wl_Buffer *buffer;
6453 struct wayland_tbm_client_queue *cqueue;
6455 API_ENTRY EINA_FALSE;
6457 if (cw->render_update_lock.lock == 0)
6459 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6461 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6462 if ((buffer) && (buffer->resource))
6464 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6466 wayland_tbm_server_client_queue_flush(cqueue);
6469 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6470 e_comp_object_render_update_del(obj);
6472 ELOGF("COMP", "Render update lock enabled", cw->ec);
6475 cw->render_update_lock.lock++;
6481 e_comp_object_render_update_unlock(Evas_Object *obj)
6485 if (cw->render_update_lock.lock == 0)
6488 cw->render_update_lock.lock--;
6490 if (cw->render_update_lock.lock == 0)
6493 if (cw->render_update_lock.pending_move_set)
6495 evas_object_move(obj,
6496 cw->render_update_lock.pending_move_x,
6497 cw->render_update_lock.pending_move_y);
6498 cw->render_update_lock.pending_move_x = 0;
6499 cw->render_update_lock.pending_move_y = 0;
6500 cw->render_update_lock.pending_move_set = EINA_FALSE;
6503 if (cw->render_update_lock.pending_resize_set)
6505 evas_object_resize(obj,
6506 cw->render_update_lock.pending_resize_w,
6507 cw->render_update_lock.pending_resize_h);
6508 cw->render_update_lock.pending_resize_w = 0;
6509 cw->render_update_lock.pending_resize_h = 0;
6510 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6513 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6515 if ((cw->ec->exp_iconify.buffer_flush) &&
6516 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6517 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6518 e_comp_object_clear(obj);
6520 e_comp_object_render_update_add(obj);
6522 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET, cw->ec);
6524 ELOGF("COMP", "Render update lock disabled", cw->ec);
6529 e_comp_object_render_update_lock_get(Evas_Object *obj)
6531 API_ENTRY EINA_FALSE;
6533 if (cw->render_update_lock.lock > 0)
6540 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6544 if (cw->transparent.set)
6546 if (r) *r = cw->transparent.user_r;
6547 if (g) *g = cw->transparent.user_g;
6548 if (b) *b = cw->transparent.user_b;
6549 if (a) *a = cw->transparent.user_a;
6553 evas_object_color_get(obj, r, g, b, a);
6558 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6562 evas_object_render_op_set(cw->obj, op);
6564 wl_signal_emit_mutable(&cw->events.render_op_set, NULL);
6567 EINTERN Evas_Render_Op
6568 e_comp_object_render_op_get(Evas_Object *obj)
6570 API_ENTRY EVAS_RENDER_BLEND;
6572 return evas_object_render_op_get(cw->obj);
6576 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6579 wl_signal_add(&cw->events.lower, listener);
6582 #ifdef REFACTOR_DESK_AREA
6584 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6587 wl_signal_add(&cw->events.lower_done, listener);
6591 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6594 wl_signal_add(&cw->events.raise, listener);
6599 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6602 wl_signal_add(&cw->events.show, listener);
6606 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6609 wl_signal_add(&cw->events.hide, listener);
6612 #ifdef REFACTOR_DESK_AREA
6614 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6617 wl_signal_add(&cw->events.set_layer, listener);
6621 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6624 wl_signal_add(&cw->events.stack_above, listener);
6628 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6631 wl_signal_add(&cw->events.stack_below, listener);
6636 e_comp_object_image_filter_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6639 wl_signal_add(&cw->events.image_filter_set, listener);
6643 e_comp_object_render_op_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6646 wl_signal_add(&cw->events.render_op_set, listener);
6650 e_comp_object_content_type_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6653 wl_signal_add(&cw->events.content_type_set, listener);
6657 e_comp_object_color_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6660 wl_signal_add(&cw->events.color_set, listener);