5 = keys that return objects =
6 - E_Client: the client associated with the object (E_Client*)
7 - comp_smart_obj: cw->smart_obj (Evas_Object*)
8 - comp_obj: cw (E_Comp_Object*)
10 = keys that are bool flags =
11 - client_restack: client needs a protocol-level restack
12 - comp_override: object is triggering a nocomp override to force compositing
13 - comp_ref: object has a ref from visibility animations
14 - comp_showing: object is currently running its show animation
15 - comp_hiding: object is currently running its hiding animation
16 - comp_object: object is a compositor-created object
17 - comp_object_skip: object has a name which prohibits theme shadows
18 - comp_object-to_del: list of objects which will be deleted when this object is deleted
19 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
20 - effect_running: object is animating by external module
23 #define UPDATE_MAX 512 // same as evas
24 #define FAILURE_MAX 2 // seems reasonable
25 #define SMART_NAME "e_comp_object"
26 #define INPUT_OBJ_SMART_NAME "input_object"
28 /* for non-util functions */
29 #define API_ENTRY E_Comp_Object *cw; \
30 cw = evas_object_smart_data_get(obj); \
31 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
33 /* for util functions (obj may or may not be E_Comp_Object */
34 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
37 CRI("YOU PASSED NULL! ARGH!"); \
40 cw = evas_object_smart_data_get(obj); \
41 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
43 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
45 /* enable for lots of client size info in console output */
47 # define e_util_size_debug_set(x, y)
50 /* enable along with display-specific damage INF calls to enable render tracing
54 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
56 #define RENDER_DEBUG(...)
59 typedef struct _E_Comp_Object
63 int x, y, w, h; // geometry
67 E_Comp_Object_Frame client_inset;
69 Eina_Stringshare *frame_theme;
70 Eina_Stringshare *frame_name;
71 Eina_Stringshare *visibility_effect; //effect when toggling visibility
73 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
75 Evas_Object *smart_obj; // smart object
76 Evas_Object *clip; // clipper over effect object
77 Evas_Object *input_obj; // input smart object
78 Evas_Object *obj; // composite object
79 Evas_Object *frame_object; // for client frames
80 Evas_Object *shobj; // shadow object
81 Evas_Object *effect_obj; // effects object
82 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
87 Evas_Object *transform_tranp_obj;// transform transp rect obj
88 Evas_Object *default_input_obj; // default input object
89 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
90 Eina_List *obj_mirror; // extra mirror objects
91 Eina_Tiler *updates; //render update regions
92 Eina_Tiler *pending_updates; //render update regions which are about to render
94 Evas_Native_Surface *ns; //for custom gl rendering
96 struct wl_listener buffer_destroy_listener;
98 unsigned int update_count; // how many updates have happened to this obj
100 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
102 unsigned int animating; // it's busy animating
103 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
104 unsigned int force_visible; //number of visible obj_mirror objects
105 Eina_Bool delete_pending : 1; // delete pending
106 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
107 Eina_Bool showing : 1; // object is currently in "show" animation
108 Eina_Bool hiding : 1; // object is currently in "hide" animation
109 Eina_Bool visible : 1; // is visible
111 Eina_Bool shaped : 1; // is shaped
112 Eina_Bool update : 1; // has updates to fetch
113 Eina_Bool redirected : 1; // has updates to fetch
114 Eina_Bool native : 1; // native
116 Eina_Bool nocomp : 1; // nocomp applied
117 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
118 Eina_Bool real_hid : 1; // last hide was a real window unmap
120 Eina_Bool effect_set : 1; //effect_obj has a valid group
121 Eina_Bool effect_running : 1; //effect_obj is playing an animation
122 Eina_Bool effect_clip : 1; //effect_obj is clipped
123 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
125 Eina_Bool updates_exist : 1;
126 Eina_Bool updates_full : 1; // entire object will be updated
128 Eina_Bool force_move : 1;
129 Eina_Bool frame_extends : 1; //frame may extend beyond object size
130 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
131 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
132 Eina_Bool user_alpha_set : 1;
133 Eina_Bool user_alpha : 1;
137 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
138 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
145 } indicator; //indicator object for internal client
149 Evas_Object *mask_obj;
152 int mask_x, mask_y, mask_w, mask_h;
155 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
157 tbm_surface_h tbm_surface;
158 E_Comp_Image_Filter image_filter;
159 Eina_Bool set_mouse_callbacks;
164 E_Comp_Wl_Buffer_Ref buffer_ref;
165 Eina_Bool pending_move_set;
166 int pending_move_x, pending_move_y;
167 Eina_Bool pending_resize_set;
168 int pending_resize_w, pending_resize_h;
169 } render_update_lock;
182 struct wl_signal lower;
183 struct wl_signal show;
184 struct wl_signal hide;
188 typedef struct _E_Input_Rect_Data
194 typedef struct _E_Input_Rect_Smart_Data
196 Eina_List *input_rect_data_list;
198 } E_Input_Rect_Smart_Data;
200 struct E_Comp_Object_Mover
203 E_Comp_Object_Mover_Cb func;
209 static Eina_Inlist *_e_comp_object_movers = NULL;
210 static Evas_Smart *_e_comp_smart = NULL;
211 static Evas_Smart *_e_comp_input_obj_smart = NULL;
213 static int _e_comp_object_hooks_delete = 0;
214 static int _e_comp_object_hooks_walking = 0;
216 static Eina_Inlist *_e_comp_object_hooks[] =
218 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
219 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
220 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
221 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
222 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
223 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
224 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
225 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
228 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
229 static int _e_comp_object_intercept_hooks_delete = 0;
230 static int _e_comp_object_intercept_hooks_walking = 0;
232 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
234 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
235 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
239 static Eina_Bool _damage_trace = EINA_FALSE;
240 static Eina_List *_damage_trace_objs = NULL;
241 static Eina_List *_damage_trace_post_objs = NULL;
243 /* sekrit functionzzz */
244 EINTERN void e_client_focused_set(E_Client *ec);
246 /* emitted every time a new noteworthy comp object is added */
247 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
249 /* ecore event define */
250 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
251 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
252 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
254 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
255 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
256 static void _e_comp_object_dim_update(E_Comp_Object *cw);
257 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
258 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
260 static E_Client *dim_client = NULL;
263 _e_comp_object_hooks_clean(void)
266 E_Comp_Object_Hook *ch;
269 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
270 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
272 if (!ch->delete_me) continue;
273 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
279 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
281 E_Comp_Object_Hook *ch;
282 Eina_Bool ret = EINA_TRUE;
284 if (e_object_is_del(E_OBJECT(ec)))
286 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
287 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
288 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
289 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
290 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
291 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
292 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
293 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
299 e_object_ref(E_OBJECT(ec));
300 _e_comp_object_hooks_walking++;
301 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
303 if (ch->delete_me) continue;
304 if (!(ch->func(ch->data, ec)))
310 _e_comp_object_hooks_walking--;
311 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
312 _e_comp_object_hooks_clean();
314 e_object_unref(E_OBJECT(ec));
319 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
321 _e_comp_object_intercept_hooks_clean(void)
324 E_Comp_Object_Intercept_Hook *ch;
327 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
328 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
330 if (!ch->delete_me) continue;
331 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
337 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
339 E_Comp_Object_Intercept_Hook *ch;
340 Eina_Bool ret = EINA_TRUE;
342 if (e_object_is_del(E_OBJECT(ec))) return ret;
343 e_object_ref(E_OBJECT(ec));
344 _e_comp_object_intercept_hooks_walking++;
345 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
347 if (ch->delete_me) continue;
348 if (!(ch->func(ch->data, ec)))
354 _e_comp_object_intercept_hooks_walking--;
355 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
356 _e_comp_object_intercept_hooks_clean();
358 e_object_unref(E_OBJECT(ec));
365 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
367 E_Event_Comp_Object *ev = event;
370 ec = evas_object_data_get(ev->comp_object, "E_Client");
374 e_object_unref(E_OBJECT(ec));
376 evas_object_unref(ev->comp_object);
381 _e_comp_object_event_add(Evas_Object *obj)
383 E_Event_Comp_Object *ev;
386 if (stopping) return;
387 ev = E_NEW(E_Event_Comp_Object, 1);
388 EINA_SAFETY_ON_NULL_RETURN(ev);
390 evas_object_ref(obj);
391 ev->comp_object = obj;
392 ec = evas_object_data_get(ev->comp_object, "E_Client");
396 e_object_ref(E_OBJECT(ec));
398 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
402 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
404 E_Event_Comp_Object *ev = event;
407 ec = evas_object_data_get(ev->comp_object, "E_Client");
411 e_object_unref(E_OBJECT(ec));
413 evas_object_unref(ev->comp_object);
418 _e_comp_object_event_simple(Evas_Object *obj, int type)
420 E_Event_Comp_Object *ev;
423 ev = E_NEW(E_Event_Comp_Object, 1);
426 evas_object_ref(obj);
427 ev->comp_object = obj;
428 ec = evas_object_data_get(ev->comp_object, "E_Client");
432 e_object_ref(E_OBJECT(ec));
434 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
436 /////////////////////////////////////
439 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
441 E_Comp_Object *cw = data;
443 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
447 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
452 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
455 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
456 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
460 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
462 E_Comp_Object *cw = data;
465 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
466 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
469 /////////////////////////////////////
472 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
476 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
477 if (cw->ec->input_only) return;
479 layer = evas_object_layer_get(obj);
481 if (cw->transform_bg_obj)
483 if (layer != evas_object_layer_get(cw->transform_bg_obj))
485 evas_object_layer_set(cw->transform_bg_obj, layer);
488 evas_object_stack_below(cw->transform_bg_obj, obj);
491 if (cw->transform_tranp_obj)
493 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
495 evas_object_layer_set(cw->transform_tranp_obj, layer);
498 evas_object_stack_below(cw->transform_tranp_obj, obj);
503 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
510 if (!map) return NULL;
512 e_map_util_points_populate_from_object_full(map, obj, 0);
513 e_map_util_points_color_set(map, 255, 255, 255, 255);
515 for (i = 0 ; i < 4 ; ++i)
520 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
521 e_map_point_coord_set(map, i, x, y, 1.0);
528 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
534 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
537 e_comp_object_map_set(obj, map);
538 e_comp_object_map_enable_set(obj, EINA_TRUE);
545 evas_object_map_enable_set(obj, EINA_FALSE);
550 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
561 e_comp_object_map_set(obj, map);
562 e_comp_object_map_enable_set(obj, EINA_TRUE);
569 evas_object_map_enable_set(obj, EINA_FALSE);
572 /////////////////////////////////////
574 static inline Eina_Bool
575 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
577 if (num > 1) return EINA_TRUE;
578 if ((rects[0].x == 0) && (rects[0].y == 0) &&
579 ((int)rects[0].w == w) && ((int)rects[0].h == h))
584 /////////////////////////////////////
586 /* add a client to the layer-client list */
588 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
590 g_rec_mutex_lock(&e_comp->ec_list_mutex);
593 e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
595 e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
596 if ((!above) && (!below))
599 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
600 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
601 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
603 e_comp->layers[cw->layer].clients_count++;
605 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
609 _e_comp_object_layers_remove(E_Comp_Object *cw)
611 g_rec_mutex_lock(&e_comp->ec_list_mutex);
613 if (cw->ec && e_comp->layers[cw->layer].clients)
615 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
616 e_comp->layers[cw->layer].clients_count--;
619 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
622 /////////////////////////////////////
624 _e_comp_object_alpha_set(E_Comp_Object *cw)
626 Eina_Bool alpha = cw->ec->argb;
628 if ((cw->external_content) &&
629 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
634 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
635 if (cw->user_alpha_set) alpha = cw->user_alpha;
637 evas_object_image_alpha_set(cw->obj, alpha);
641 _e_comp_object_shadow(E_Comp_Object *cw)
643 if (e_client_util_shadow_state_get(cw->ec))
644 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
646 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
647 if (cw->frame_object)
648 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
649 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
652 /* convert from the surface coordinates to the buffer coordinates */
654 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
656 E_Comp_Wl_Buffer_Viewport *vp;
657 E_Comp_Wl_Client_Data *cdata;
661 cdata = e_client_cdata_get(ec);
663 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
670 vp = &cdata->scaler.buffer_viewport;
671 transform = e_comp_wl_output_buffer_transform_get(ec);
673 e_pixmap_size_get(ec->pixmap, &bw, &bh);
675 /* for subsurface, it should be swap 90 and 270 */
676 if (e_comp_wl_subsurface_check(ec))
679 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
680 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
681 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
682 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
688 case WL_OUTPUT_TRANSFORM_NORMAL:
689 default: tx = sx, ty = sy; break;
690 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
691 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
692 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
693 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
694 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
695 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
696 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
699 tx *= vp->buffer.scale;
700 ty *= vp->buffer.scale;
707 _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh, int *dx, int *dy, int *dw, int *dh)
715 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
716 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
723 if (dw) *dw = MAX(x1, x2) - mx;
724 if (dh) *dh = MAX(y1, y2) - my;
728 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
729 int *dx, int *dy, int *dw, int *dh)
731 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
732 E_Util_Transform_Rect_Vertex sv, dv;
736 e_pixmap_size_get(ec->pixmap, &bw, &bh);
738 sv = e_util_transform_rect_to_vertices(&rect);
740 for (i = 0; i < 4; i++)
742 double x = 0.0, y = 0.0;
744 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
746 /* if evas decide coordinate is outside of map, it returns (0, 0)
747 in this case, full damage is added.
749 if ((i != 0) && (x == 0.0) && (y == 0.0))
752 dv.vertices[i].vertex[0] = x;
753 dv.vertices[i].vertex[1] = y;
754 dv.vertices[i].vertex[2] = 1.0;
755 dv.vertices[i].vertex[3] = 1.0;
758 rect = e_util_transform_vertices_to_rect(&dv);
760 if (dx) *dx = rect.x;
761 if (dy) *dy = rect.y;
762 if (dw) *dw = rect.w;
763 if (dh) *dh = rect.h;
777 _e_comp_object_map_damage_transform_get(E_Client *ec)
784 if (!e_client_transform_core_enable_get(ec))
787 m = e_client_map_get(ec);
791 e_pixmap_size_get(ec->pixmap, &bw, &bh);
792 if ((bw == 0) || (bh == 0))
805 e_map_point_coord_set(m2, 0, 0, 0, 0);
806 e_map_point_coord_set(m2, 1, bw, 0, 0);
807 e_map_point_coord_set(m2, 2, bw, bh, 0);
808 e_map_point_coord_set(m2, 3, 0, bh, 0);
810 for (i = 0; i < 4; i++)
814 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
815 e_map_point_image_uv_set(m2, i, map_x, map_y);
822 /////////////////////////////////////
824 /* handle evas mouse-in events on client object */
826 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
828 Evas_Event_Mouse_In *ev = event_info;
829 E_Comp_Object *cw = data;
831 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
834 /* handle evas mouse-out events on client object */
836 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
838 Evas_Event_Mouse_Out *ev = event_info;
839 E_Comp_Object *cw = data;
841 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
844 /* handle evas mouse wheel events on client object */
846 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
848 Evas_Event_Mouse_Wheel *ev = event_info;
849 E_Comp_Object *cw = data;
850 E_Binding_Event_Wheel ev2;
853 if (e_client_action_get()) return;
854 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
855 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
858 /* handle evas mouse down events on client object */
860 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
862 Evas_Event_Mouse_Down *ev = event_info;
863 E_Comp_Object *cw = data;
864 E_Binding_Event_Mouse_Button ev2;
867 if (e_client_action_get()) return;
868 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
869 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
872 /* handle evas mouse up events on client object */
874 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
876 Evas_Event_Mouse_Up *ev = event_info;
877 E_Comp_Object *cw = data;
878 E_Binding_Event_Mouse_Button ev2;
881 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
882 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
883 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
886 /* handle evas mouse movement events on client object */
888 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
890 Evas_Event_Mouse_Move *ev = event_info;
891 E_Comp_Object *cw = data;
894 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
895 e_client_mouse_move(cw->ec, &ev->cur.output);
897 /////////////////////////////////////
899 /* helper function for checking compositor themes based on user-defined matches */
901 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
903 if (((m->title) && (!ec->netwm.name)) ||
904 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
906 #if defined(__cplusplus) || defined(c_plusplus)
907 if (((m->clas) && (!ec->icccm.cpp_class)) ||
908 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
911 if (((m->clas) && (!ec->icccm.class)) ||
912 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
916 if (((m->role) && (!ec->icccm.window_role)) ||
917 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
923 if ((int)ec->netwm.type != m->primary_type)
926 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
929 if (m->borderless != 0)
933 if (e_client_util_borderless(ec))
935 if (!(((m->borderless == -1) && (!borderless)) ||
936 ((m->borderless == 1) && (borderless))))
943 if (((ec->icccm.transient_for != 0) ||
946 if (!(((m->dialog == -1) && (!dialog)) ||
947 ((m->dialog == 1) && (dialog))))
950 if (m->accepts_focus != 0)
952 int accepts_focus = 0;
954 if (ec->icccm.accepts_focus)
956 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
957 ((m->accepts_focus == 1) && (accepts_focus))))
966 if (!(((m->vkbd == -1) && (!vkbd)) ||
967 ((m->vkbd == 1) && (vkbd))))
972 if (!(((m->argb == -1) && (!ec->argb)) ||
973 ((m->argb == 1) && (ec->argb))))
976 if (m->fullscreen != 0)
978 int fullscreen = ec->fullscreen;
980 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
981 ((m->fullscreen == 1) && (fullscreen))))
988 if (ec->netwm.state.modal)
990 if (!(((m->modal == -1) && (!modal)) ||
991 ((m->modal == 1) && (modal))))
997 /* function for setting up a client's compositor frame theme (cw->shobj) */
999 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1003 Eina_List *list = NULL, *l;
1004 E_Input_Rect_Data *input_rect_data;
1005 E_Input_Rect_Smart_Data *input_rect_sd;
1007 Eina_Stringshare *reshadow_group = NULL;
1008 Eina_Bool focus = EINA_FALSE, urgent = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1009 Eina_Stringshare *name, *title;
1010 E_Comp_Config *conf = e_comp_config_get();
1012 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1013 /* match correct client type */
1014 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1015 name = cw->ec->icccm.name;
1016 title = cw->ec->icccm.title;
1017 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1018 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1020 /* skipping here is mostly a hack for systray because I hate it */
1023 EINA_LIST_FOREACH(list, l, m)
1025 if (((m->name) && (!name)) ||
1026 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1028 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1032 no_shadow = m->no_shadow;
1033 if (m->shadow_style)
1035 /* fast effects are just themes with "/fast" appended and shorter effect times */
1038 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1039 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1041 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1043 /* default to non-fast style if fast not available */
1046 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1047 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1049 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1051 if (ok && m->visibility_effect)
1052 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1059 if (skip || (cw->ec->e.state.video))
1061 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1063 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1066 if (conf->shadow_style)
1070 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1071 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1073 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1077 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1078 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1080 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1087 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1089 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1093 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1095 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1100 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1105 if (cw->ec->override)
1107 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1108 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1110 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1111 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1117 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1118 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1121 _e_comp_object_shadow(cw);
1124 if (focus || cw->ec->focused || cw->ec->override)
1125 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1127 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1128 if (urgent || cw->ec->urgent)
1129 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1131 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1133 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1135 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1136 /* visibility must always be enabled for re_manage clients to prevent
1137 * pop-in animations every time the user sees a persistent client again;
1138 * applying visibility for iconic clients prevents the client from getting
1141 if (cw->visible || cw->ec->re_manage)
1142 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1144 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1146 /* breaks animation counter */
1147 if (cw->frame_object)
1149 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1150 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1151 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1152 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1158 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1162 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1165 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1167 if (input_rect_data->obj)
1169 pass_event_flag = EINA_TRUE;
1175 if (cw->indicator.obj)
1177 Evas_Object *indicator;
1178 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1179 if (indicator != cw->indicator.obj)
1181 edje_object_part_unswallow(cw->shobj, indicator);
1182 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1183 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1187 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1188 evas_object_pass_events_set(cw->obj, pass_event_flag);
1193 /////////////////////////////////////////////
1196 _e_comp_object_animating_begin(E_Comp_Object *cw)
1199 if (cw->animating == 1)
1201 e_comp->animating++;
1203 e_object_ref(E_OBJECT(cw->ec));
1208 _e_comp_object_animating_end(E_Comp_Object *cw)
1217 if (cw->ec->launching)
1219 if (!cw->ec->extra_animating)
1221 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1222 cw->ec->launching = EINA_FALSE;
1223 if (cw->ec->first_mapped)
1225 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1226 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1229 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1233 e_comp->animating--;
1234 cw->showing = cw->hiding = 0;
1236 if (e_comp->animating == 0)
1237 e_comp_visibility_calculation_set(EINA_TRUE);
1238 /* remove ref from animation start, account for possibility of deletion from unref */
1239 return !!e_object_unref(E_OBJECT(cw->ec));
1245 /* handle the end of a compositor animation */
1247 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1249 E_Comp_Object *cw = data;
1251 /* visible clients which have never been sized are a bug */
1252 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1253 CRI("ACK! ec:%p", cw->ec);
1254 if (!_e_comp_object_animating_end(cw)) return;
1255 if (cw->animating) return;
1256 /* hide only after animation finishes to guarantee a full run of the animation */
1257 if (!cw->defer_hide) return;
1258 if ((!strcmp(emission, "e,action,hide,done")) ||
1259 (!strcmp(emission, "e,action,done")) ||
1260 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1262 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1263 evas_object_hide(cw->smart_obj);
1267 /* run a visibility compositor effect if available, return false if object is dead */
1269 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1275 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1276 if (!cw->effect_running)
1277 _e_comp_object_animating_begin(cw);
1278 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1279 return _e_comp_object_animating_end(cw);
1280 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1281 return _e_comp_object_animating_end(cw);
1283 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1286 zone = e_comp_zone_find_by_ec(cw->ec);
1288 zw = zone->w, zh = zone->h;
1293 zone = e_comp_object_util_zone_get(cw->smart_obj);
1294 if (!zone) zone = e_zone_current_get();
1301 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1302 cw->w, cw->h, zw, zh, x, y}, 8);
1303 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1304 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1307 /////////////////////////////////////////////
1309 /* create necessary objects for clients that e manages */
1311 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1313 if (cw->set_mouse_callbacks) return;
1314 if (!cw->smart_obj) return;
1316 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1317 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1318 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1319 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1320 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1321 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1323 cw->set_mouse_callbacks = EINA_TRUE;
1327 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1329 if (!cw->set_mouse_callbacks) return;
1330 if (!cw->smart_obj) return;
1332 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1333 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1334 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1335 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1336 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1337 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1339 cw->set_mouse_callbacks = EINA_FALSE;
1343 _e_comp_object_setup(E_Comp_Object *cw)
1345 cw->clip = evas_object_rectangle_add(e_comp->evas);
1346 evas_object_move(cw->clip, -9999, -9999);
1347 evas_object_resize(cw->clip, 999999, 999999);
1348 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1349 cw->effect_obj = edje_object_add(e_comp->evas);
1350 evas_object_move(cw->effect_obj, cw->x, cw->y);
1351 evas_object_clip_set(cw->effect_obj, cw->clip);
1352 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1353 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1354 cw->shobj = edje_object_add(e_comp->evas);
1355 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1356 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1357 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1359 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1360 if (cw->ec->override)
1362 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1363 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1364 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1366 else if (!cw->ec->input_only)
1368 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1369 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1370 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1372 cw->real_hid = !cw->ec->input_only;
1373 if (!cw->ec->input_only)
1375 e_util_size_debug_set(cw->effect_obj, 1);
1376 _e_comp_object_mouse_event_callback_set(cw);
1379 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1380 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1381 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1382 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1383 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1384 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1386 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1389 /////////////////////////////////////////////
1391 /* for fast path evas rendering; only called during render */
1393 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1395 E_Comp_Object *cw = data;
1396 E_Client *ec = cw->ec;
1398 int bx, by, bxx, byy;
1400 if (e_object_is_del(E_OBJECT(ec))) return;
1401 if (cw->external_content) return;
1402 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1403 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1406 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1407 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1409 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1411 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1412 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1416 bx = by = bxx = byy = 0;
1417 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1420 Edje_Message_Int_Set *msg;
1421 Edje_Message_Int msg2;
1422 Eina_Bool id = (bx || by || bxx || byy);
1424 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1430 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1432 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1436 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1437 e_comp_client_post_update_add(cw->ec);
1439 else if (e_comp_object_render(ec->frame))
1441 /* apply shape mask if necessary */
1442 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1443 e_comp_object_shape_apply(ec->frame);
1444 ec->shape_changed = 0;
1446 /* shaped clients get precise mouse events to handle transparent pixels */
1447 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1449 /* queue another render if client is still dirty; cannot refresh here. */
1450 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1451 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1453 if (cw->render_trace)
1455 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1461 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1463 E_Comp_Object *cw = data;
1464 E_Client *ec = cw->ec;
1466 if (e_object_is_del(E_OBJECT(ec))) return;
1467 if (cw->external_content) return;
1468 if (!e_comp->hwc) return;
1470 e_comp_client_render_list_add(cw->ec);
1472 if (!ec->hwc_window) return;
1474 e_hwc_windows_rendered_window_add(ec->hwc_window);
1477 /////////////////////////////////////////////
1480 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1482 E_Comp_Object *cw = data;
1485 if (cw->render_update_lock.lock)
1487 cw->render_update_lock.pending_move_x = x;
1488 cw->render_update_lock.pending_move_y = y;
1489 cw->render_update_lock.pending_move_set = EINA_TRUE;
1493 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1494 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1495 (cw->external_content))
1497 /* delay to move until the external content is unset */
1498 cw->ec->changes.pos = 1;
1503 if (cw->ec->move_after_resize)
1505 if ((x != cw->ec->x) || (y != cw->ec->y))
1507 if (!cw->ec->is_cursor)
1508 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1509 e_client_pos_set(cw->ec, x, y);
1510 cw->ec->changes.pos = 1;
1516 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1517 (cw->ec->manage_resize.resize_obj))
1519 e_client_pos_set(cw->ec, x, y);
1520 cw->ec->client.x = x + cw->client_inset.l;
1521 cw->ec->client.y = y + cw->client_inset.t;
1522 e_policy_visibility_client_defer_move(cw->ec);
1526 /* if frame_object does not exist, client_inset indicates CSD.
1527 * this means that ec->client matches cw->x/y, the opposite
1530 fx = (!cw->frame_object) * cw->client_inset.l;
1531 fy = (!cw->frame_object) * cw->client_inset.t;
1532 if ((cw->x == x + fx) && (cw->y == y + fy))
1534 if ((cw->ec->x != x) || (cw->ec->y != y))
1536 /* handle case where client tries to move to position and back very quickly */
1537 e_client_pos_set(cw->ec, x, y);
1538 cw->ec->client.x = x + cw->client_inset.l;
1539 cw->ec->client.y = y + cw->client_inset.t;
1543 if (!cw->ec->maximize_override)
1545 /* prevent moving in some directions while directionally maximized */
1546 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1548 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1551 ix = x + cw->client_inset.l;
1552 iy = y + cw->client_inset.t;
1553 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1554 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1555 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1557 /* prevent moving at all if move isn't allowed in current maximize state */
1558 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1559 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1562 zone = e_comp_zone_find_by_ec(cw->ec);
1565 cw->ec->changes.need_unmaximize = 1;
1566 cw->ec->saved.x = ix - zone->x;
1567 cw->ec->saved.y = iy - zone->y;
1568 cw->ec->saved.w = cw->ec->client.w;
1569 cw->ec->saved.h = cw->ec->client.h;
1573 /* only update during resize if triggered by resize */
1574 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1575 /* delay to move while surface waits paired commit serial*/
1576 if (e_client_pending_geometry_has(cw->ec))
1578 /* do nothing while waiting paired commit serial*/
1582 e_client_pos_set(cw->ec, x, y);
1583 if (cw->ec->new_client)
1585 /* don't actually do anything until first client idler loop */
1586 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1587 cw->ec->changes.pos = 1;
1592 /* only update xy position of client to avoid invalid
1593 * first damage region if it is not a new_client. */
1594 cw->ec->client.x = ix;
1595 cw->ec->client.y = iy;
1598 if (!cw->frame_object)
1600 evas_object_move(obj, x, y);
1605 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1607 E_Comp_Object *cw = data;
1608 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1611 if (cw->render_update_lock.lock)
1613 cw->render_update_lock.pending_resize_w = w;
1614 cw->render_update_lock.pending_resize_h = h;
1615 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1619 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1621 e_client_size_set(cw->ec, w, h);
1622 evas_object_resize(obj, w, h);
1626 /* if frame_object does not exist, client_inset indicates CSD.
1627 * this means that ec->client matches cw->w/h, the opposite
1630 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1631 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1632 if ((cw->w == w + fw) && (cw->h == h + fh))
1634 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1635 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1636 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1638 /* handle case where client tries to resize itself and back very quickly */
1639 e_client_size_set(cw->ec, w, h);
1640 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1641 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1642 evas_object_smart_callback_call(obj, "client_resize", NULL);
1646 /* guarantee that fullscreen is fullscreen */
1647 zone = e_comp_zone_find_by_ec(cw->ec);
1649 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1651 if (!e_client_transform_core_enable_get(cw->ec))
1654 /* calculate client size */
1655 iw = w - cw->client_inset.l - cw->client_inset.r;
1656 ih = h - cw->client_inset.t - cw->client_inset.b;
1657 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1659 /* prevent resizing while maximized depending on direction and config */
1660 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1662 Eina_Bool reject = EINA_FALSE;
1663 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1665 if (cw->ec->client.h != ih)
1667 cw->ec->saved.h = ih;
1668 cw->ec->saved.y = cw->ec->client.y - zone->y;
1669 reject = cw->ec->changes.need_unmaximize = 1;
1672 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1674 if (cw->ec->client.w != iw)
1676 cw->ec->saved.w = iw;
1677 cw->ec->saved.x = cw->ec->client.x - zone->x;
1678 reject = cw->ec->changes.need_unmaximize = 1;
1687 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1689 /* do nothing until client idler loops */
1690 if ((cw->ec->w != w) || (cw->ec->h != h))
1692 e_client_size_set(cw->ec, w, h);
1693 cw->ec->changes.size = 1;
1698 if (e_client_pending_geometry_has(cw->ec))
1700 /* do nothing while waiting paired commit serial*/
1704 e_client_size_set(cw->ec, w, h);
1706 cw->ec->client.w = iw;
1707 cw->ec->client.h = ih;
1708 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1710 /* The size of non-compositing window can be changed, so there is a
1711 * need to check that cw is H/W composited if cw is not redirected.
1712 * And of course we have to change size of evas object of H/W composited cw,
1713 * otherwise cw can't receive input events even if it is shown on the screen.
1715 Eina_Bool redirected = cw->redirected;
1717 redirected = e_comp_is_on_overlay(cw->ec);
1719 if ((!cw->ec->input_only) && (redirected) &&
1720 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1721 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1722 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1723 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1726 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1727 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1729 prev_w = cw->w, prev_h = cw->h;
1730 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1731 /* check shading and clamp to pixmap size for regular clients */
1732 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1733 (((w - fw != pw) || (h - fh != ph))))
1735 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1736 evas_object_smart_callback_call(obj, "client_resize", NULL);
1738 if (cw->frame_object || cw->ec->input_only)
1739 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1742 if ((cw->w == w) && (cw->h == h))
1744 /* going to be a noop resize which won't trigger smart resize */
1745 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1746 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1748 evas_object_resize(obj, w, h);
1752 evas_object_smart_callback_call(obj, "client_resize", NULL);
1755 if ((!cw->frame_object) && (!cw->ec->input_only))
1757 /* "just do it" for overrides */
1758 evas_object_resize(obj, w, h);
1760 if (!cw->ec->override)
1762 /* shape probably changed for non-overrides */
1763 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1764 cw->ec->need_shape_export |= cw->ec->shaped;
1765 if (cw->ec->shaped || cw->ec->shaped_input)
1769 /* this fixes positioning jiggles when using a resize mode
1770 * which also changes the client's position
1773 if (cw->frame_object)
1774 x = cw->x, y = cw->y;
1776 x = cw->ec->x, y = cw->ec->y;
1777 switch (cw->ec->resize_mode)
1779 case E_POINTER_RESIZE_BL:
1780 case E_POINTER_RESIZE_L:
1781 evas_object_move(obj, x + prev_w - cw->w, y);
1783 case E_POINTER_RESIZE_TL:
1784 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1786 case E_POINTER_RESIZE_T:
1787 case E_POINTER_RESIZE_TR:
1788 evas_object_move(obj, x, y + prev_h - cw->h);
1797 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1799 E_Comp_Object *cw = data;
1800 E_Comp_Wl_Client_Data *child_cdata;
1801 unsigned int l = e_comp_canvas_layer_map(layer);
1804 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1806 /* doing a compositor effect, follow directions */
1807 _e_comp_object_layer_set(obj, layer);
1808 if (layer == cw->ec->layer) //trying to put layer back
1812 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1813 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1814 if (cw->layer != l) goto layer_set;
1818 e_comp_render_queue();
1820 ec = e_client_above_get(cw->ec);
1821 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1822 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1823 ec = e_client_above_get(ec);
1824 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1826 ec = e_client_below_get(cw->ec);
1827 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1828 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1829 ec = e_client_below_get(ec);
1830 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1832 evas_object_stack_above(obj, ec->frame);
1837 if (ec && (cw->ec->parent == ec))
1839 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1840 evas_object_stack_above(obj, ec->frame);
1842 evas_object_stack_below(obj, ec->frame);
1845 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1851 if (cw->layer == l) return;
1852 if (e_comp_canvas_client_layer_map(layer) == 9999)
1853 return; //invalid layer for clients not doing comp effects
1854 if (cw->ec->fullscreen)
1856 cw->ec->saved.layer = layer;
1859 oldraise = e_config->transient.raise;
1861 /* clamp to valid client layer */
1862 layer = e_comp_canvas_client_layer_map_nearest(layer);
1863 cw->ec->layer = layer;
1864 if (e_config->transient.layer)
1867 Eina_List *list = eina_list_clone(cw->ec->transients);
1869 /* We need to set raise to one, else the child wont
1870 * follow to the new layer. It should be like this,
1871 * even if the user usually doesn't want to raise
1874 e_config->transient.raise = 1;
1875 EINA_LIST_FREE(list, child)
1877 child_cdata = e_client_cdata_get(child);
1878 if (child_cdata && !child_cdata->mapped)
1880 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1883 e_client_layer_set(child, layer);
1887 e_config->transient.raise = oldraise;
1889 _e_comp_object_layers_remove(cw);
1890 cw->layer = e_comp_canvas_layer_map(layer);
1891 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1892 //if (cw->ec->new_client)
1893 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1894 _e_comp_object_layer_set(obj, layer);
1895 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1896 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1897 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1899 /* can't stack a client above its own layer marker */
1900 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1902 if (!cw->visible) return;
1903 e_comp_render_queue();
1904 _e_comp_object_transform_obj_stack_update(obj);
1907 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1910 _e_comp_object_raise(Evas_Object *obj)
1912 evas_object_raise(obj);
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_RESTACK, ec);
1923 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1925 evas_object_lower(obj);
1927 if (evas_object_smart_smart_get(obj))
1929 E_Client *ec = e_comp_object_client_get(obj);
1932 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1933 wl_signal_emit_mutable(&cw->events.lower, NULL);
1939 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1941 evas_object_stack_above(obj, target);
1943 if (evas_object_smart_smart_get(obj))
1945 E_Client *ec = e_comp_object_client_get(obj);
1947 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1952 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1954 evas_object_stack_below(obj, target);
1956 if (evas_object_smart_smart_get(obj))
1958 E_Client *ec = e_comp_object_client_get(obj);
1960 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1965 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1967 evas_object_layer_set(obj, layer);
1969 if (evas_object_smart_smart_get(obj))
1971 E_Client *ec = e_comp_object_client_get(obj);
1973 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1978 _e_comp_object_is_pending(E_Client *ec)
1982 if (!ec) return EINA_FALSE;
1984 topmost = e_comp_wl_topmost_parent_get(ec);
1986 return (topmost) ? topmost->layer_pending : EINA_FALSE;
1990 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1992 E_Comp_Object *cw2 = NULL;
1995 Evas_Object *o = stack;
1996 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1998 /* We should consider topmost's layer_pending for subsurface */
1999 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2001 if (_e_comp_object_is_pending(cw->ec))
2002 e_comp_object_layer_update(cw->smart_obj,
2003 raising? stack : NULL,
2004 raising? NULL : stack);
2006 /* obey compositor effects! */
2007 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2008 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2009 stack_cb(cw->smart_obj, stack);
2010 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2011 evas_object_data_del(cw->smart_obj, "client_restack");
2015 cw2 = evas_object_data_get(o, "comp_obj");
2017 /* assume someone knew what they were doing during client init */
2018 if (cw->ec->new_client)
2019 layer = cw->ec->layer;
2020 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2021 layer = cw2->ec->layer;
2023 layer = evas_object_layer_get(stack);
2024 ecstack = e_client_below_get(cw->ec);
2025 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2027 evas_object_layer_set(cw->smart_obj, layer);
2028 /* we got our layer wrangled, return now! */
2029 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2032 /* check if we're stacking below another client */
2035 /* check for non-client layer object */
2036 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2038 /* find an existing client to use for layering
2039 * by walking up the object stack
2041 * this is guaranteed to be pretty quick since we'll either:
2042 * - run out of client layers
2043 * - find a stacking client
2045 o = evas_object_above_get(o);
2046 if ((!o) || (o == cw->smart_obj)) break;
2047 if (evas_object_layer_get(o) != layer)
2049 /* reached the top client layer somehow
2050 * use top client object
2052 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2055 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2056 * return here since the top client layer window
2061 ec = e_client_top_get();
2066 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2069 if (cw2 && cw->layer != cw2->layer)
2072 /* remove existing layers */
2073 _e_comp_object_layers_remove(cw);
2076 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2077 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2078 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2079 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2080 else //if no stacking objects found, either raise or lower
2081 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2084 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2086 /* find new object for stacking if cw2 is on state of layer_pending */
2087 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2089 E_Client *new_stack = NULL, *current_ec = NULL;
2090 current_ec = cw2->ec;
2093 while ((new_stack = e_client_below_get(current_ec)))
2095 current_ec = new_stack;
2096 if (new_stack == cw->ec) continue;
2097 if (new_stack->layer != cw2->ec->layer) break;
2098 if (!_e_comp_object_is_pending(new_stack)) break;
2100 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2101 stack = new_stack->frame;
2104 /* stack it above layer object */
2106 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2107 stack = e_comp->layers[below_layer].obj;
2112 while ((new_stack = e_client_above_get(current_ec)))
2114 current_ec = new_stack;
2115 if (new_stack == cw->ec) continue;
2116 if (new_stack->layer != cw2->ec->layer) break;
2117 if (!_e_comp_object_is_pending(new_stack)) break;
2119 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2120 stack = new_stack->frame;
2122 stack = e_comp->layers[cw2->layer].obj;
2126 /* set restack if stacking has changed */
2127 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2128 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2129 stack_cb(cw->smart_obj, stack);
2130 if (e_comp->layers[cw->layer].obj)
2131 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2133 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2135 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2136 evas_object_data_del(cw->smart_obj, "client_restack");
2137 if (!cw->visible) return;
2138 e_comp_render_queue();
2142 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2144 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2146 if (evas_object_below_get(obj) == above)
2148 e_comp_object_layer_update(obj, above, NULL);
2152 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2153 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2154 _e_comp_object_transform_obj_stack_update(obj);
2155 _e_comp_object_transform_obj_stack_update(above);
2160 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2162 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2163 if (evas_object_above_get(obj) == below)
2165 e_comp_object_layer_update(obj, NULL, below);
2169 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2170 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2171 if (evas_object_smart_smart_get(obj))
2172 _e_comp_object_transform_obj_stack_update(obj);
2173 if (evas_object_smart_smart_get(below))
2174 _e_comp_object_transform_obj_stack_update(below);
2179 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2181 E_Comp_Object *cw = data;
2184 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2186 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2188 if (cw->ec->layer_pending)
2189 e_comp_object_layer_update(obj, NULL, obj);
2191 _e_comp_object_lower(cw, obj);
2194 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2195 o = evas_object_below_get(obj);
2196 _e_comp_object_layers_remove(cw);
2197 /* prepend to client list since this client should be the first item now */
2198 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2199 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2200 evas_object_data_set(obj, "client_restack", (void*)1);
2201 _e_comp_object_lower(cw, obj);
2202 evas_object_data_del(obj, "client_restack");
2203 if (!cw->visible) goto end;
2204 e_comp_render_queue();
2205 _e_comp_object_transform_obj_stack_update(obj);
2212 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2214 E_Comp_Object *cw = data;
2218 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2220 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2222 if (cw->ec->layer_pending)
2224 int obj_layer = evas_object_layer_get(obj);
2225 if (cw->ec->layer != obj_layer)
2226 e_comp_object_layer_update(obj, NULL, NULL);
2229 _e_comp_object_raise(obj);
2232 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2233 o = evas_object_above_get(obj);
2234 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2236 /* still stack below override below the layer marker */
2237 for (op = o = e_comp->layers[cw->layer].obj;
2238 o && o != e_comp->layers[cw->layer - 1].obj;
2239 op = o, o = evas_object_below_get(o))
2241 if (evas_object_smart_smart_get(o))
2245 ec = e_comp_object_client_get(o);
2246 if (ec && (!ec->override)) break;
2249 _e_comp_object_stack_below(obj, op);
2250 e_client_focus_defer_set(cw->ec);
2252 if (!cw->visible) goto end;
2253 e_comp_render_queue();
2254 _e_comp_object_transform_obj_stack_update(obj);
2261 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2263 E_Comp_Object *cw = data;
2265 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2266 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2268 ELOGF("COMP", "Hide. intercepted", cw->ec);
2273 if (cw->ec->launching == EINA_TRUE)
2275 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2276 cw->ec->launching = EINA_FALSE;
2281 /* hidden flag = just do it */
2282 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2283 evas_object_hide(obj);
2285 wl_signal_emit_mutable(&cw->events.hide, NULL);
2290 if (cw->ec->input_only)
2292 /* input_only = who cares */
2293 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2294 evas_object_hide(obj);
2296 wl_signal_emit_mutable(&cw->events.hide, NULL);
2300 /* already hidden or currently animating */
2301 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2303 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2307 /* don't try hiding during shutdown */
2308 cw->defer_hide |= stopping;
2309 if (!cw->defer_hide)
2311 if ((!cw->ec->iconic) && (!cw->ec->override))
2312 /* unset delete requested so the client doesn't break */
2313 cw->ec->delete_requested = 0;
2314 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2316 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2317 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2320 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2323 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2325 _e_comp_object_animating_begin(cw);
2326 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2328 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2329 cw->defer_hide = !!cw->animating;
2331 e_comp_object_effect_set(obj, NULL);
2334 if (cw->animating) return;
2335 /* if we have no animations running, go ahead and hide */
2337 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2338 evas_object_hide(obj);
2340 wl_signal_emit_mutable(&cw->events.hide, NULL);
2344 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2346 E_Client *ec = cw->ec;
2349 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2351 if (ec->show_pending.count > 0)
2353 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2354 ec->show_pending.running = EINA_TRUE;
2358 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2359 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2361 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2366 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,
2367 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2368 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2371 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2374 if (ec->iconic && cw->animating)
2376 /* triggered during iconify animation */
2377 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2380 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2383 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2384 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2386 evas_object_move(cw->smart_obj, ec->x, ec->y);
2387 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2388 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2390 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2391 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2394 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2395 evas_object_show(cw->smart_obj);
2398 e_client_focus_defer_set(ec);
2402 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2406 pw = ec->client.w, ph = ec->client.h;
2408 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2410 ec->changes.visible = !ec->hidden;
2413 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2417 cw->updates = eina_tiler_new(pw, ph);
2420 ec->changes.visible = !ec->hidden;
2423 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2428 eina_tiler_tile_size_set(cw->updates, 1, 1);
2431 /* ignore until client idler first run */
2432 ec->changes.visible = !ec->hidden;
2435 ELOGF("COMP", "show_helper. return. new_client", ec);
2442 evas_object_move(cw->smart_obj, ec->x, ec->y);
2443 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2444 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2445 evas_object_show(cw->smart_obj);
2448 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2450 /* start_drag not received */
2451 ec->changes.visible = 1;
2454 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2457 /* re-set geometry */
2458 evas_object_move(cw->smart_obj, ec->x, ec->y);
2459 /* force resize in case it hasn't happened yet, or just to update size */
2460 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2461 if ((cw->w < 1) || (cw->h < 1))
2463 /* if resize didn't go through, try again */
2464 ec->visible = ec->changes.visible = 1;
2466 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2469 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2470 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2471 e_pixmap_clear(ec->pixmap);
2473 if (cw->real_hid && w && h)
2476 /* force comp theming in case it didn't happen already */
2477 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2478 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2479 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2482 /* only do the show if show is allowed */
2485 if (ec->internal) //internal clients render when they feel like it
2486 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2488 if (!e_client_is_iconified_by_client(ec)||
2489 e_policy_visibility_client_is_uniconic(ec))
2491 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2492 evas_object_show(cw->smart_obj);
2494 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2495 it is rendered in idle callback without native surface and
2496 compositor shows an empty frame if other objects aren't shown
2497 because job callback of e_comp called at the next loop.
2498 it causes a visual defect when windows are switched.
2502 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2503 e_comp_object_dirty(cw->smart_obj);
2504 e_comp_object_render(cw->smart_obj);
2509 wl_signal_emit_mutable(&cw->events.show, NULL);
2513 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2515 E_Comp_Object *cw = data;
2516 E_Client *ec = cw->ec;
2518 E_Input_Rect_Data *input_rect_data;
2519 E_Input_Rect_Smart_Data *input_rect_sd;
2522 if (ec->ignored) return;
2526 //INF("SHOW2 %p", ec);
2527 _e_comp_intercept_show_helper(cw);
2530 //INF("SHOW %p", ec);
2533 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2534 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2535 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2536 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2540 if ((!cw->obj) && (cw->external_content))
2542 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2546 _e_comp_object_setup(cw);
2549 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2550 cw->obj = evas_object_image_filled_add(e_comp->evas);
2551 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2552 e_util_size_debug_set(cw->obj, 1);
2553 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2554 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2555 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2556 evas_object_name_set(cw->obj, "cw->obj");
2557 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2559 _e_comp_object_alpha_set(cw);
2562 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2565 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2566 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2569 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2572 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2574 if (input_rect_data->obj)
2576 evas_object_geometry_set(input_rect_data->obj,
2577 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2578 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2579 input_rect_data->rect.w, input_rect_data->rect.h);
2586 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2588 _e_comp_intercept_show_helper(cw);
2592 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2594 E_Comp_Object *cw = data;
2598 /* note: this is here as it seems there are enough apps that do not even
2599 * expect us to emulate a look of focus but not actually set x input
2600 * focus as we do - so simply abort any focus set on such windows */
2601 /* be strict about accepting focus hint */
2602 /* be strict about accepting focus hint */
2603 if ((!ec->icccm.accepts_focus) &&
2604 (!ec->icccm.take_focus))
2608 if (e_client_focused_get() == ec)
2609 e_client_focused_set(NULL);
2611 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2612 evas_object_focus_set(obj, focus);
2616 if (focus && ec->lock_focus_out) return;
2617 if (e_object_is_del(E_OBJECT(ec)) && focus)
2618 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2620 /* filter focus setting based on current state */
2625 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2626 evas_object_focus_set(obj, focus);
2629 if ((ec->iconic) && (!ec->deskshow))
2631 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2633 /* don't focus an iconified window. that's silly! */
2634 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2635 e_client_uniconify(ec);
2636 e_client_focus_latest_set(ec);
2650 /* not yet visible, wait till the next time... */
2651 ec->want_focus = !ec->hidden;
2656 e_client_focused_set(ec);
2660 if (e_client_focused_get() == ec)
2661 e_client_focused_set(NULL);
2665 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2667 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2669 evas_object_focus_set(obj, focus);
2673 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2675 E_Comp_Object *cw = data;
2677 if (cw->transparent.set)
2679 cw->transparent.user_r = r;
2680 cw->transparent.user_g = g;
2681 cw->transparent.user_b = b;
2682 cw->transparent.user_a = a;
2684 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2686 cw->transparent.user_r,
2687 cw->transparent.user_g,
2688 cw->transparent.user_b,
2689 cw->transparent.user_a);
2693 evas_object_color_set(obj, r, g, b, a);
2696 ////////////////////////////////////////////////////
2699 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2701 int w, h, ox, oy, ow, oh;
2703 Eina_Bool pass_event_flag = EINA_FALSE;
2704 E_Input_Rect_Data *input_rect_data;
2705 E_Input_Rect_Smart_Data *input_rect_sd;
2707 if (cw->frame_object)
2709 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2710 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2711 /* set a fixed size, force edje calc, check size difference */
2712 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2713 edje_object_message_signal_process(cw->frame_object);
2714 edje_object_calc_force(cw->frame_object);
2715 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2716 cw->client_inset.l = ox;
2717 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2718 cw->client_inset.t = oy;
2719 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2720 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2721 evas_object_resize(cw->frame_object, w, h);
2725 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2728 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2730 if (input_rect_data->obj)
2732 pass_event_flag = EINA_TRUE;
2738 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2739 evas_object_pass_events_set(cw->obj, pass_event_flag);
2743 cw->client_inset.l = 0;
2744 cw->client_inset.r = 0;
2745 cw->client_inset.t = 0;
2746 cw->client_inset.b = 0;
2748 cw->client_inset.calc = !!cw->frame_object;
2752 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2754 E_Comp_Object *cw = data;
2758 /* - get current size
2760 * - readjust for new frame size
2763 w = cw->ec->w, h = cw->ec->h;
2764 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2766 _e_comp_object_frame_recalc(cw);
2768 if (!cw->ec->fullscreen)
2769 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2771 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2772 if (cw->ec->fullscreen)
2774 zone = e_comp_zone_find_by_ec(cw->ec);
2776 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2778 else if (cw->ec->new_client)
2780 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2781 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2782 evas_object_resize(cw->ec->frame, w, h);
2784 else if ((w != cw->ec->w) || (h != cw->ec->h))
2785 evas_object_resize(cw->ec->frame, w, h);
2789 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2791 E_Comp_Object *cw = data;
2793 _e_comp_object_shadow_setup(cw);
2794 if (cw->frame_object)
2796 _e_comp_object_shadow(cw);
2797 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2798 _e_comp_object_frame_recalc(cw);
2799 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2804 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2806 E_Comp_Object *cw = data;
2808 if (_e_comp_object_shadow_setup(cw))
2809 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2810 if (cw->frame_object)
2812 _e_comp_object_shadow(cw);
2813 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2814 _e_comp_object_frame_recalc(cw);
2815 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2820 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2822 E_Comp_Object *cw = data;
2824 if (cw->frame_object)
2826 _e_comp_object_shadow(cw);
2827 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2828 _e_comp_object_frame_recalc(cw);
2829 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2834 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2836 E_Comp_Object *cw = data;
2838 if (_e_comp_object_shadow_setup(cw))
2841 cw->ec->changes.size = 1;
2843 if (cw->frame_object)
2845 _e_comp_object_shadow(cw);
2846 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2847 _e_comp_object_frame_recalc(cw);
2848 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2853 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2855 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2859 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2861 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2865 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2867 E_Comp_Object *cw = data;
2869 if (!cw->ec) return; //NYI
2870 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2874 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2876 E_Comp_Object *cw = data;
2878 if (!cw->ec) return; //NYI
2879 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2883 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2885 e_comp_object_signal_emit(obj, "e,state,focused", "e");
2889 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2891 E_Comp_Object *cw = data;
2893 if (!e_object_is_del(E_OBJECT(cw->ec)))
2894 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2898 _e_comp_input_obj_smart_add(Evas_Object *obj)
2900 E_Input_Rect_Smart_Data *input_rect_sd;
2901 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2903 if (!input_rect_sd) return;
2904 evas_object_smart_data_set(obj, input_rect_sd);
2908 _e_comp_input_obj_smart_del(Evas_Object *obj)
2910 E_Input_Rect_Smart_Data *input_rect_sd;
2911 E_Input_Rect_Data *input_rect_data;
2913 input_rect_sd = evas_object_smart_data_get(obj);
2914 if (!input_rect_sd) return;
2916 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2918 if (input_rect_data->obj)
2920 evas_object_smart_member_del(input_rect_data->obj);
2921 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2923 E_FREE(input_rect_data);
2925 E_FREE(input_rect_sd);
2929 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2931 E_Input_Rect_Smart_Data *input_rect_sd;
2932 E_Input_Rect_Data *input_rect_data;
2936 input_rect_sd = evas_object_smart_data_get(obj);
2937 if (!input_rect_sd) return;
2939 cw = input_rect_sd->cw;
2940 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2942 if (input_rect_data->obj)
2944 evas_object_geometry_set(input_rect_data->obj,
2945 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2946 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2947 input_rect_data->rect.w, input_rect_data->rect.h);
2953 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2955 E_Input_Rect_Smart_Data *input_rect_sd;
2956 E_Input_Rect_Data *input_rect_data;
2960 input_rect_sd = evas_object_smart_data_get(obj);
2961 if (!input_rect_sd) return;
2963 cw = input_rect_sd->cw;
2964 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2966 if (input_rect_data->obj)
2968 evas_object_geometry_set(input_rect_data->obj,
2969 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2970 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2971 input_rect_data->rect.w, input_rect_data->rect.h);
2977 _e_comp_input_obj_smart_show(Evas_Object *obj)
2979 E_Input_Rect_Smart_Data *input_rect_sd;
2980 E_Input_Rect_Data *input_rect_data;
2983 input_rect_sd = evas_object_smart_data_get(obj);
2984 if (!input_rect_sd) return;
2986 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2988 if (input_rect_data->obj)
2990 evas_object_show(input_rect_data->obj);
2996 _e_comp_input_obj_smart_hide(Evas_Object *obj)
2998 E_Input_Rect_Smart_Data *input_rect_sd;
2999 E_Input_Rect_Data *input_rect_data;
3002 input_rect_sd = evas_object_smart_data_get(obj);
3003 if (!input_rect_sd) return;
3005 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3007 if (input_rect_data->obj)
3009 evas_object_hide(input_rect_data->obj);
3015 _e_comp_input_obj_smart_init(void)
3017 if (_e_comp_input_obj_smart) return;
3019 static const Evas_Smart_Class sc =
3021 INPUT_OBJ_SMART_NAME,
3022 EVAS_SMART_CLASS_VERSION,
3023 _e_comp_input_obj_smart_add,
3024 _e_comp_input_obj_smart_del,
3025 _e_comp_input_obj_smart_move,
3026 _e_comp_input_obj_smart_resize,
3027 _e_comp_input_obj_smart_show,
3028 _e_comp_input_obj_smart_hide,
3041 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3047 _e_comp_smart_add(Evas_Object *obj)
3051 cw = E_NEW(E_Comp_Object, 1);
3052 EINA_SAFETY_ON_NULL_RETURN(cw);
3054 wl_signal_init(&cw->events.lower);
3055 wl_signal_init(&cw->events.show);
3056 wl_signal_init(&cw->events.hide);
3058 cw->smart_obj = obj;
3059 cw->x = cw->y = cw->w = cw->h = -1;
3060 evas_object_smart_data_set(obj, cw);
3061 cw->opacity = 255.0;
3062 cw->external_content = 0;
3063 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3064 cw->transform_bg_color.r = 0;
3065 cw->transform_bg_color.g = 0;
3066 cw->transform_bg_color.b = 0;
3067 cw->transform_bg_color.a = 255;
3068 evas_object_data_set(obj, "comp_obj", cw);
3069 evas_object_move(obj, -1, -1);
3070 /* intercept ALL the callbacks! */
3071 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3072 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3073 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3074 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3075 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3076 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3077 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3078 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3079 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3080 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3081 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3083 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3084 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3085 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3086 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3088 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3089 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3091 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3092 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3094 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3096 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3097 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3101 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3104 evas_object_color_set(cw->clip, r, g, b, a);
3105 evas_object_smart_callback_call(obj, "color_set", NULL);
3110 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3113 evas_object_clip_set(cw->clip, clip);
3117 _e_comp_smart_clip_unset(Evas_Object *obj)
3120 evas_object_clip_unset(cw->clip);
3124 _e_comp_smart_hide(Evas_Object *obj)
3126 TRACE_DS_BEGIN(COMP:SMART HIDE);
3131 evas_object_hide(cw->clip);
3132 if (cw->input_obj) evas_object_hide(cw->input_obj);
3133 evas_object_hide(cw->effect_obj);
3134 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3135 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3136 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3143 /* unset native surface if current displaying buffer was destroied */
3144 if (!cw->buffer_destroy_listener.notify)
3146 Evas_Native_Surface *ns;
3147 ns = evas_object_image_native_surface_get(cw->obj);
3148 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3149 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3152 if (!cw->ec->input_only)
3154 edje_object_freeze(cw->effect_obj);
3155 edje_object_freeze(cw->shobj);
3156 edje_object_play_set(cw->shobj, 0);
3157 if (cw->frame_object)
3158 edje_object_play_set(cw->frame_object, 0);
3161 e_comp_render_queue(); //force nocomp recheck
3167 _e_comp_smart_show(Evas_Object *obj)
3175 if ((cw->w < 0) || (cw->h < 0))
3176 CRI("ACK! ec:%p", cw->ec);
3178 TRACE_DS_BEGIN(COMP:SMART SHOW);
3180 e_comp_object_map_update(obj);
3182 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3183 evas_object_show(tmp->frame);
3185 evas_object_show(cw->clip);
3186 if (cw->input_obj) evas_object_show(cw->input_obj);
3187 if (!cw->ec->input_only)
3189 edje_object_thaw(cw->effect_obj);
3190 edje_object_thaw(cw->shobj);
3191 edje_object_play_set(cw->shobj, 1);
3192 if (cw->frame_object)
3193 edje_object_play_set(cw->frame_object, 1);
3195 evas_object_show(cw->effect_obj);
3196 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3197 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3198 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3199 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3200 e_comp_render_queue();
3201 if (cw->ec->input_only)
3206 if (cw->ec->iconic && (!cw->ec->new_client))
3208 if (e_client_is_iconified_by_client(cw->ec))
3210 ELOGF("COMP", "Set launching flag..", cw->ec);
3211 cw->ec->launching = EINA_TRUE;
3214 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3216 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3219 ELOGF("COMP", "Set launching flag..", cw->ec);
3220 cw->ec->launching = EINA_TRUE;
3222 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3223 _e_comp_object_animating_begin(cw);
3224 if (!_e_comp_object_effect_visibility_start(cw, 1))
3230 /* ensure some random effect doesn't lock the client offscreen */
3234 e_comp_object_effect_set(obj, NULL);
3237 _e_comp_object_dim_update(cw);
3243 _e_comp_smart_del(Evas_Object *obj)
3249 if (cw->buffer_destroy_listener.notify)
3251 wl_list_remove(&cw->buffer_destroy_listener.link);
3252 cw->buffer_destroy_listener.notify = NULL;
3255 if (cw->tbm_surface)
3257 tbm_surface_internal_unref(cw->tbm_surface);
3258 cw->tbm_surface = NULL;
3261 if (cw->render_update_lock.buffer_ref.buffer)
3263 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3264 cw->ec, cw->render_update_lock.lock);
3265 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3268 e_comp_object_render_update_del(cw->smart_obj);
3269 E_FREE_FUNC(cw->updates, eina_tiler_free);
3270 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3277 EINA_LIST_FREE(cw->obj_mirror, o)
3279 evas_object_image_data_set(o, NULL);
3280 evas_object_freeze_events_set(o, 1);
3281 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3285 _e_comp_object_layers_remove(cw);
3286 l = evas_object_data_get(obj, "comp_object-to_del");
3287 E_FREE_LIST(l, evas_object_del);
3288 _e_comp_object_mouse_event_callback_unset(cw);
3289 evas_object_del(cw->clip);
3290 evas_object_del(cw->obj);
3291 evas_object_del(cw->shobj);
3292 evas_object_del(cw->effect_obj);
3293 evas_object_del(cw->frame_object);
3294 evas_object_del(cw->input_obj);
3295 evas_object_del(cw->mask.obj);
3296 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3297 evas_object_del(cw->transform_bg_obj);
3298 evas_object_del(cw->transform_tranp_obj);
3299 evas_object_del(cw->default_input_obj);
3300 eina_stringshare_del(cw->frame_theme);
3301 eina_stringshare_del(cw->frame_name);
3305 e_comp->animating--;
3307 e_object_unref(E_OBJECT(cw->ec));
3309 cw->ec->frame = NULL;
3314 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3318 cw->x = x, cw->y = y;
3319 evas_object_move(cw->effect_obj, x, y);
3320 evas_object_move(cw->default_input_obj, x, y);
3321 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3323 e_comp_object_map_update(obj);
3327 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3329 Eina_Bool first = EINA_FALSE;
3334 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3336 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3338 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3340 if (cw->w != w || cw->h != h)
3341 e_comp_object_map_update(obj);
3343 first = ((cw->w < 1) || (cw->h < 1));
3344 cw->w = w, cw->h = h;
3348 if (cw->frame_object)
3349 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3352 /* verify pixmap:object size */
3353 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3355 if ((ww != pw) || (hh != ph))
3356 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3358 evas_object_resize(cw->effect_obj, tw, th);
3359 evas_object_resize(cw->default_input_obj, w, h);
3361 evas_object_resize(cw->input_obj, w, h);
3363 evas_object_resize(cw->mask.obj, w, h);
3364 /* resize render update tiler */
3367 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3368 cw->updates_full = 0;
3369 if (cw->updates) eina_tiler_clear(cw->updates);
3373 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3374 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3382 e_comp_render_queue();
3388 _e_comp_smart_init(void)
3390 if (_e_comp_smart) return;
3392 static const Evas_Smart_Class sc =
3395 EVAS_SMART_CLASS_VERSION,
3399 _e_comp_smart_resize,
3402 _e_comp_smart_color_set,
3403 _e_comp_smart_clip_set,
3404 _e_comp_smart_clip_unset,
3414 _e_comp_smart = evas_smart_class_new(&sc);
3419 e_comp_object_init(void)
3421 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3422 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3423 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3424 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3428 e_comp_object_shutdown(void)
3434 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3436 API_ENTRY EINA_FALSE;
3437 return !!cw->force_visible;
3439 /////////////////////////////////////////////////////////
3442 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3445 Eina_Bool comp_object;
3447 comp_object = !!evas_object_data_get(obj, "comp_object");
3452 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3454 e_comp_render_queue();
3456 l = evas_object_data_get(obj, "comp_object-to_del");
3457 E_FREE_LIST(l, evas_object_del);
3461 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3463 if (e_comp_util_object_is_above_nocomp(obj) &&
3464 (!evas_object_data_get(obj, "comp_override")))
3466 evas_object_data_set(obj, "comp_override", (void*)1);
3467 e_comp_override_add();
3472 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3474 Eina_Bool ref = EINA_TRUE;
3475 if (evas_object_visible_get(obj))
3479 d = evas_object_data_del(obj, "comp_hiding");
3481 /* currently trying to hide */
3484 /* already visible */
3488 evas_object_show(obj);
3491 evas_object_ref(obj);
3492 evas_object_data_set(obj, "comp_ref", (void*)1);
3494 edje_object_signal_emit(obj, "e,state,visible", "e");
3495 evas_object_data_set(obj, "comp_showing", (void*)1);
3496 if (e_comp_util_object_is_above_nocomp(obj))
3498 evas_object_data_set(obj, "comp_override", (void*)1);
3499 e_comp_override_add();
3504 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3506 if (!evas_object_visible_get(obj)) return;
3507 /* already hiding */
3508 if (evas_object_data_get(obj, "comp_hiding")) return;
3509 if (!evas_object_data_del(obj, "comp_showing"))
3511 evas_object_ref(obj);
3512 evas_object_data_set(obj, "comp_ref", (void*)1);
3514 edje_object_signal_emit(obj, "e,state,hidden", "e");
3515 evas_object_data_set(obj, "comp_hiding", (void*)1);
3517 if (evas_object_data_del(obj, "comp_override"))
3518 e_comp_override_timed_pop();
3522 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3524 if (!e_util_strcmp(emission, "e,action,hide,done"))
3526 if (!evas_object_data_del(obj, "comp_hiding")) return;
3527 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3528 evas_object_hide(obj);
3529 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3532 evas_object_data_del(obj, "comp_showing");
3533 if (evas_object_data_del(obj, "comp_ref"))
3534 evas_object_unref(obj);
3538 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3544 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3548 E_API E_Comp_Object_Hook *
3549 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3551 E_Comp_Object_Hook *ch;
3553 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3554 ch = E_NEW(E_Comp_Object_Hook, 1);
3555 if (!ch) return NULL;
3556 ch->hookpoint = hookpoint;
3558 ch->data = (void*)data;
3559 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3564 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3567 if (_e_comp_object_hooks_walking == 0)
3569 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3573 _e_comp_object_hooks_delete++;
3576 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3577 E_API E_Comp_Object_Intercept_Hook *
3578 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3580 E_Comp_Object_Intercept_Hook *ch;
3582 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3583 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3584 if (!ch) return NULL;
3585 ch->hookpoint = hookpoint;
3587 ch->data = (void*)data;
3588 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3593 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3596 if (_e_comp_object_intercept_hooks_walking == 0)
3598 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3602 _e_comp_object_intercept_hooks_delete++;
3607 e_comp_object_util_add(Evas_Object *obj)
3611 E_Comp_Config *conf = e_comp_config_get();
3612 Eina_Bool skip = EINA_FALSE;
3618 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3620 name = evas_object_name_get(obj);
3621 vis = evas_object_visible_get(obj);
3622 o = edje_object_add(e_comp->evas);
3623 evas_object_data_set(o, "comp_object", (void*)1);
3625 skip = (!strncmp(name, "noshadow", 8));
3627 evas_object_data_set(o, "comp_object_skip", (void*)1);
3629 if (conf->shadow_style)
3631 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3632 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3635 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3636 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3637 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3639 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3641 evas_object_geometry_get(obj, &x, &y, &w, &h);
3642 evas_object_geometry_set(o, x, y, w, h);
3643 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3645 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3647 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3648 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3649 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3650 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3651 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3652 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3654 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3656 edje_object_part_swallow(o, "e.swallow.content", obj);
3658 _e_comp_object_event_add(o);
3661 evas_object_show(o);
3666 /* utility functions for deleting objects when their "owner" is deleted */
3668 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3673 EINA_SAFETY_ON_NULL_RETURN(to_del);
3674 l = evas_object_data_get(obj, "comp_object-to_del");
3675 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3676 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3677 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3681 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3686 EINA_SAFETY_ON_NULL_RETURN(to_del);
3687 l = evas_object_data_get(obj, "comp_object-to_del");
3689 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3692 /////////////////////////////////////////////////////////
3694 EINTERN Evas_Object *
3695 e_comp_object_client_add(E_Client *ec)
3700 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3701 if (ec->frame) return NULL;
3702 _e_comp_smart_init();
3703 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3704 cw = evas_object_smart_data_get(o);
3705 if (!cw) return NULL;
3706 evas_object_data_set(o, "E_Client", ec);
3709 evas_object_data_set(o, "comp_object", (void*)1);
3711 _e_comp_object_event_add(o);
3716 /* utility functions for getting client inset */
3718 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3721 if (!cw->client_inset.calc)
3727 if (ax) *ax = x - cw->client_inset.l;
3728 if (ay) *ay = y - cw->client_inset.t;
3732 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3735 if (!cw->client_inset.calc)
3741 if (ax) *ax = x + cw->client_inset.l;
3742 if (ay) *ay = y + cw->client_inset.t;
3746 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3749 if (!cw->client_inset.calc)
3755 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3756 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3760 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3763 if (!cw->client_inset.calc)
3769 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3770 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3774 e_comp_object_client_get(Evas_Object *obj)
3779 /* FIXME: remove this when eo is used */
3780 o = evas_object_data_get(obj, "comp_smart_obj");
3782 return e_comp_object_client_get(o);
3783 return cw ? cw->ec : NULL;
3787 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3790 if (cw->frame_extends)
3791 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3796 if (w) *w = cw->ec->w;
3797 if (h) *h = cw->ec->h;
3802 e_comp_object_util_zone_get(Evas_Object *obj)
3804 E_Zone *zone = NULL;
3808 zone = e_comp_zone_find_by_ec(cw->ec);
3813 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3814 zone = e_comp_zone_xy_get(x, y);
3820 e_comp_object_util_center(Evas_Object *obj)
3822 int x, y, w, h, ow, oh;
3827 zone = e_comp_object_util_zone_get(obj);
3828 EINA_SAFETY_ON_NULL_RETURN(zone);
3829 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3830 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3831 ow = cw->ec->w, oh = cw->ec->h;
3833 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3834 x = x + (w - ow) / 2;
3835 y = y + (h - oh) / 2;
3836 evas_object_move(obj, x, y);
3840 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3842 int x, y, w, h, ow, oh;
3845 EINA_SAFETY_ON_NULL_RETURN(on);
3846 evas_object_geometry_get(on, &x, &y, &w, &h);
3847 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3848 ow = cw->ec->w, oh = cw->ec->h;
3850 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3851 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3855 e_comp_object_util_fullscreen(Evas_Object *obj)
3860 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3863 evas_object_move(obj, 0, 0);
3864 evas_object_resize(obj, e_comp->w, e_comp->h);
3869 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3877 ow = cw->w, oh = cw->h;
3879 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3880 zone = e_comp_object_util_zone_get(obj);
3881 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3882 if (x) *x = zx + (zw - ow) / 2;
3883 if (y) *y = zy + (zh - oh) / 2;
3887 e_comp_object_input_objs_del(Evas_Object *obj)
3890 E_Input_Rect_Data *input_rect_data;
3891 E_Input_Rect_Smart_Data *input_rect_sd;
3896 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3897 if (!input_rect_sd) return;
3899 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3901 if (input_rect_data->obj)
3903 evas_object_smart_member_del(input_rect_data->obj);
3904 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3906 E_FREE(input_rect_data);
3911 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3914 E_Input_Rect_Data *input_rect_data = NULL;
3915 E_Input_Rect_Smart_Data *input_rect_sd;
3916 int client_w, client_h;
3918 if (cw->ec->client.w)
3919 client_w = cw->ec->client.w;
3921 client_w = cw->ec->w;
3923 if (cw->ec->client.h)
3924 client_h = cw->ec->client.h;
3926 client_h = cw->ec->h;
3928 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3932 _e_comp_input_obj_smart_init();
3933 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3934 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3935 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3938 input_rect_sd->cw = cw;
3941 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3944 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3945 if (input_rect_data)
3947 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3948 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3952 if ((input_rect_data) &&
3953 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3955 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3956 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3957 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3958 evas_object_clip_set(input_rect_data->obj, cw->clip);
3959 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3960 evas_object_geometry_set(input_rect_data->obj,
3961 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
3962 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
3963 evas_object_pass_events_set(cw->default_input_obj, 1);
3964 evas_object_pass_events_set(cw->obj, 1);
3967 evas_object_show(input_rect_data->obj);
3968 evas_object_show(cw->input_obj);
3973 evas_object_smart_member_del(cw->input_obj);
3974 E_FREE_FUNC(cw->input_obj, evas_object_del);
3975 evas_object_pass_events_set(cw->default_input_obj, 0);
3976 evas_object_pass_events_set(cw->obj, 0);
3981 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
3984 E_Input_Rect_Smart_Data *input_rect_sd;
3985 E_Input_Rect_Data *input_rect_data;
3988 if (!cw->input_obj) return;
3990 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3993 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3995 *list = eina_list_append(*list, &input_rect_data->rect);
4001 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4004 if (l) *l = cw->client_inset.l;
4005 if (r) *r = cw->client_inset.r;
4006 if (t) *t = cw->client_inset.t;
4007 if (b) *b = cw->client_inset.b;
4010 /* set geometry for CSD */
4012 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4018 if (cw->frame_object)
4019 CRI("ACK! ec:%p", cw->ec);
4020 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4021 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4022 calc = cw->client_inset.calc;
4023 cw->client_inset.calc = l || r || t || b;
4024 eina_stringshare_replace(&cw->frame_theme, "borderless");
4025 if (cw->client_inset.calc)
4027 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4028 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4029 e_client_size_set(cw->ec, tw, th);
4031 else if (cw->ec->maximized || cw->ec->fullscreen)
4033 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4034 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4036 if (!cw->ec->new_client)
4038 if (calc && cw->client_inset.calc)
4040 tx = cw->ec->x - (l - cw->client_inset.l);
4041 ty = cw->ec->y - (t - cw->client_inset.t);
4042 e_client_pos_set(cw->ec, tx, ty);
4044 cw->ec->changes.pos = cw->ec->changes.size = 1;
4047 cw->client_inset.l = l;
4048 cw->client_inset.r = r;
4049 cw->client_inset.t = t;
4050 cw->client_inset.b = b;
4054 e_comp_object_frame_allowed(Evas_Object *obj)
4056 API_ENTRY EINA_FALSE;
4057 return (cw->frame_object || (!cw->client_inset.calc));
4061 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4063 API_ENTRY EINA_FALSE;
4064 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4065 eina_stringshare_replace(&cw->frame_name, name);
4066 if (cw->frame_object)
4067 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4072 e_comp_object_frame_exists(Evas_Object *obj)
4074 API_ENTRY EINA_FALSE;
4075 return !!cw->frame_object;
4079 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4081 Evas_Object *o, *pbg;
4084 Eina_Stringshare *theme;
4086 API_ENTRY EINA_FALSE;
4088 if (!e_util_strcmp(cw->frame_theme, name))
4089 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4090 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4091 return _e_comp_object_shadow_setup(cw);
4092 pbg = cw->frame_object;
4093 theme = eina_stringshare_add(name);
4095 if (cw->frame_object)
4099 w = cw->ec->w, h = cw->ec->h;
4100 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4101 if ((cw->ec->w != w) || (cw->ec->h != h))
4103 cw->ec->changes.size = 1;
4106 E_FREE_FUNC(cw->frame_object, evas_object_del);
4107 if (!name) goto reshadow;
4109 o = edje_object_add(e_comp->evas);
4110 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4111 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4112 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4114 cw->frame_object = NULL;
4116 eina_stringshare_del(cw->frame_theme);
4117 cw->frame_theme = theme;
4122 if (theme != e_config->theme_default_border_style)
4124 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4125 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4129 ok = e_theme_edje_object_set(o, "base/theme/border",
4130 "e/widgets/border/default/border");
4131 if (ok && (theme == e_config->theme_default_border_style))
4133 /* Reset default border style to default */
4134 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4135 e_config_save_queue();
4142 cw->frame_object = o;
4143 eina_stringshare_del(cw->frame_theme);
4144 cw->frame_theme = theme;
4145 evas_object_name_set(o, "cw->frame_object");
4148 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4152 cw->ec->changes.icon = 1;
4158 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4163 _e_comp_object_shadow_setup(cw);
4166 int old_x, old_y, new_x = 0, new_y = 0;
4168 old_x = cw->x, old_y = cw->y;
4170 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4172 new_x = cw->ec->x, new_y = cw->ec->y;
4173 else if (cw->ec->placed || (!cw->ec->new_client))
4175 /* if no previous frame:
4176 * - reapply client_inset
4181 if (cw->ec->changes.size)
4189 zone = e_comp_zone_find_by_ec(cw->ec);
4192 x = cw->ec->client.x, y = cw->ec->client.y;
4193 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4194 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4196 new_x = x, new_y = y;
4199 if (old_x != new_x || old_y != new_y)
4201 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4202 cw->y = cw->x = -99999;
4203 evas_object_move(obj, new_x, new_y);
4207 if (cw->ec->maximized)
4209 cw->ec->changes.need_maximize = 1;
4212 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4213 if (cw->frame_object)
4215 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4218 cw->frame_extends = 0;
4219 evas_object_del(pbg);
4224 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4226 E_Comp_Object_Mover *prov;
4229 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4230 edje_object_signal_emit(cw->shobj, sig, src);
4231 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4232 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4233 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4235 /* start with highest priority callback first */
4236 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4238 if (!e_util_glob_match(sig, prov->sig)) continue;
4239 if (prov->func(prov->data, obj, sig)) break;
4244 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4246 /* FIXME: at some point I guess this should use eo to inherit
4247 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4248 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4251 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4255 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4258 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4262 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4265 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4269 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4272 Eina_Rectangle rect;
4275 if (cw->ec->input_only || (!cw->updates)) return;
4276 if (cw->nocomp) return;
4277 rect.x = x, rect.y = y;
4278 rect.w = w, rect.h = h;
4279 evas_object_smart_callback_call(obj, "damage", &rect);
4281 if (e_comp_is_on_overlay(cw->ec))
4283 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4284 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4285 * E module attempts to block screen update due to the particular policy.
4287 if (e_pixmap_resource_get(cw->ec->pixmap))
4288 cw->hwc_need_update = EINA_TRUE;
4291 /* ignore overdraw */
4292 if (cw->updates_full)
4294 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4295 e_comp_object_render_update_add(obj);
4297 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4298 evas_object_show(cw->smart_obj);
4302 /* clip rect to client surface */
4303 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4304 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4305 /* if rect is the total size of the client after clip, clear the updates
4306 * since this is guaranteed to be the whole region anyway
4308 eina_tiler_area_size_get(cw->updates, &tw, &th);
4309 if ((w > tw) || (h > th))
4311 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4312 eina_tiler_clear(cw->updates);
4313 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4315 tw = cw->ec->client.w, th = cw->ec->client.h;
4317 if ((!x) && (!y) && (w == tw) && (h == th))
4319 eina_tiler_clear(cw->updates);
4320 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4321 cw->updates_full = 1;
4322 cw->update_count = 0;
4325 if (cw->update_count > UPDATE_MAX)
4327 /* this is going to get really dumb, so just update the whole thing */
4328 eina_tiler_clear(cw->updates);
4329 cw->update_count = cw->updates_full = 1;
4330 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4331 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4335 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4336 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4338 cw->updates_exist = 1;
4339 e_comp_object_render_update_add(obj);
4341 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4342 evas_object_show(cw->smart_obj);
4346 e_comp_object_damage_exists(Evas_Object *obj)
4348 API_ENTRY EINA_FALSE;
4349 return cw->updates_exist;
4353 e_comp_object_render_update_add(Evas_Object *obj)
4357 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4358 if (cw->render_update_lock.lock) return;
4359 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4363 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4365 e_comp_render_queue();
4369 e_comp_object_render_update_del(Evas_Object *obj)
4373 if (cw->ec->input_only || (!cw->updates)) return;
4374 if (!cw->update) return;
4376 /* this gets called during comp animating to clear the update flag */
4377 if (e_comp->grabbed) return;
4378 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4379 if (!e_comp->updates)
4381 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4382 if (e_comp->render_animator)
4383 ecore_animator_freeze(e_comp->render_animator);
4388 e_comp_object_shape_apply(Evas_Object *obj)
4392 unsigned int i, *pix, *p;
4396 if (!cw->ec) return; //NYI
4397 if (cw->external_content) return;
4400 if ((cw->ec->shape_rects_num >= 1) &&
4401 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4406 ERR("BUGGER: shape with native surface? cw=%p", cw);
4409 evas_object_image_size_get(cw->obj, &w, &h);
4410 if ((w < 1) || (h < 1)) return;
4413 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4414 _e_comp_object_alpha_set(cw);
4415 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4416 evas_object_image_alpha_set(o, 1);
4418 p = pix = evas_object_image_data_get(cw->obj, 1);
4421 evas_object_image_data_set(cw->obj, pix);
4426 unsigned char *spix, *sp;
4428 spix = calloc(w * h, sizeof(unsigned char));
4430 for (i = 0; i < cw->ec->shape_rects_num; i++)
4434 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4435 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4436 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4437 sp = spix + (w * ry) + rx;
4438 for (py = 0; py < rh; py++)
4440 for (px = 0; px < rw; px++)
4448 for (py = 0; py < h; py++)
4450 for (px = 0; px < w; px++)
4452 unsigned int mask, imask;
4454 mask = ((unsigned int)(*sp)) << 24;
4456 imask |= imask >> 8;
4457 imask |= imask >> 8;
4458 *p = mask | (*p & imask);
4459 //if (*sp) *p = 0xff000000 | *p;
4460 //else *p = 0x00000000;
4469 for (py = 0; py < h; py++)
4471 for (px = 0; px < w; px++)
4475 evas_object_image_data_set(cw->obj, pix);
4476 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4477 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4479 evas_object_image_data_set(o, pix);
4480 evas_object_image_data_update_add(o, 0, 0, w, h);
4482 // don't need to fix alpha chanel as blending
4483 // should be totally off here regardless of
4484 // alpha channel content
4488 _e_comp_object_clear(E_Comp_Object *cw)
4493 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4495 if (cw->render_update_lock.lock) return;
4498 e_pixmap_clear(cw->ec->pixmap);
4500 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4501 evas_object_image_size_set(cw->obj, 1, 1);
4502 evas_object_image_data_set(cw->obj, NULL);
4503 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4505 evas_object_image_size_set(o, 1, 1);
4506 evas_object_image_data_set(o, NULL);
4509 e_comp_object_render_update_del(cw->smart_obj);
4513 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4517 API_ENTRY EINA_FALSE;
4519 if (cw->transparent.set == set)
4524 evas_object_color_get(obj, &r, &g, &b, &a);
4525 evas_object_color_set(obj, 0, 0, 0, 0);
4527 cw->transparent.user_r = r;
4528 cw->transparent.user_g = g;
4529 cw->transparent.user_b = b;
4530 cw->transparent.user_a = a;
4532 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4534 cw->transparent.user_r,
4535 cw->transparent.user_g,
4536 cw->transparent.user_b,
4537 cw->transparent.user_a);
4539 cw->transparent.set = EINA_TRUE;
4543 cw->transparent.set = EINA_FALSE;
4545 evas_object_color_set(obj,
4546 cw->transparent.user_r,
4547 cw->transparent.user_g,
4548 cw->transparent.user_b,
4549 cw->transparent.user_a);
4551 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4553 cw->transparent.user_r,
4554 cw->transparent.user_g,
4555 cw->transparent.user_b,
4556 cw->transparent.user_a);
4562 /* helper function to simplify toggling of redirection for display servers which support it */
4564 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4569 if (cw->redirected == set) return;
4570 cw->redirected = set;
4571 if (cw->external_content) return;
4573 e_comp_object_map_update(obj);
4577 if (cw->updates_exist)
4578 e_comp_object_render_update_add(obj);
4580 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4582 _e_comp_object_transparent_set(obj, EINA_FALSE);
4583 evas_object_smart_callback_call(obj, "redirected", NULL);
4587 _e_comp_object_clear(cw);
4588 _e_comp_object_transparent_set(obj, EINA_TRUE);
4589 evas_object_smart_callback_call(obj, "unredirected", NULL);
4594 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4597 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4599 if (cw->buffer_destroy_listener.notify)
4601 cw->buffer_destroy_listener.notify = NULL;
4602 wl_list_remove(&cw->buffer_destroy_listener.link);
4605 if (e_object_is_del(E_OBJECT(cw->ec)))
4607 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4612 /* if it's current displaying buffer, do not remove its content */
4613 if (!evas_object_visible_get(cw->ec->frame))
4614 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4619 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4624 if (cw->buffer_destroy_listener.notify)
4626 wl_list_remove(&cw->buffer_destroy_listener.link);
4627 cw->buffer_destroy_listener.notify = NULL;
4630 if (cw->tbm_surface)
4632 tbm_surface_internal_unref(cw->tbm_surface);
4633 cw->tbm_surface = NULL;
4638 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4640 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4641 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4643 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4645 tbm_surface_internal_ref(ns->data.tbm.buffer);
4646 cw->tbm_surface = ns->data.tbm.buffer;
4650 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4651 evas_object_image_native_surface_set(cw->obj, ns);
4655 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4657 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4658 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4659 evas_object_image_native_surface_set(o, ns);
4666 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4668 Evas_Native_Surface ns;
4671 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4672 if (cw->ec->input_only) return;
4673 if (cw->external_content) return;
4674 if (cw->render_update_lock.lock) return;
4677 memset(&ns, 0, sizeof(Evas_Native_Surface));
4681 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4682 set = (!cw->ec->shaped);
4684 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4688 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4692 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4695 if (cw->ec->input_only) return;
4698 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4699 _e_comp_object_alpha_set(cw);
4701 e_comp_object_native_surface_set(obj, cw->native);
4702 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4706 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4712 if (cw->blanked == set) return;
4714 _e_comp_object_alpha_set(cw);
4717 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4718 evas_object_image_data_set(cw->obj, NULL);
4722 e_comp_object_native_surface_set(obj, 1);
4723 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4727 _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)
4732 if (!_damage_trace) return;
4736 if (!evas_object_visible_get(cw->obj)) return;
4738 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4740 o = evas_object_rectangle_add(e_comp->evas);
4741 evas_object_layer_set(o, E_LAYER_MAX);
4742 evas_object_name_set(o, "damage_trace");
4743 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4744 evas_object_resize(o, dmg_w, dmg_h);
4745 evas_object_color_set(o, 0, 128, 0, 128);
4746 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4747 evas_object_pass_events_set(o, EINA_TRUE);
4748 evas_object_show(o);
4750 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4752 dmg_w, dmg_h, dmg_x, dmg_y,
4753 origin->w, origin->h, origin->x, origin->y);
4755 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4758 /* mark an object as dirty and setup damages */
4760 e_comp_object_dirty(Evas_Object *obj)
4763 Eina_Rectangle *rect;
4767 Eina_Bool dirty, visible;
4771 if (cw->external_content) return;
4772 if (!cw->redirected) return;
4773 if (cw->render_update_lock.lock)
4775 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4778 /* only actually dirty if pixmap is available */
4779 if (!e_pixmap_resource_get(cw->ec->pixmap))
4781 // e_pixmap_size_get returns last attached buffer size
4782 // eventhough it is destroyed
4783 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4786 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4787 visible = cw->visible;
4788 if (!dirty) w = h = 1;
4789 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4791 evas_object_image_data_set(cw->obj, NULL);
4792 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4793 evas_object_image_size_set(cw->obj, tw, th);
4794 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4795 if (cw->pending_updates)
4796 eina_tiler_area_size_set(cw->pending_updates, w, h);
4797 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4799 evas_object_image_pixels_dirty_set(o, dirty);
4801 evas_object_image_data_set(o, NULL);
4802 evas_object_image_size_set(o, tw, th);
4803 visible |= evas_object_visible_get(o);
4807 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4811 e_comp_object_native_surface_set(obj, 1);
4813 m = _e_comp_object_map_damage_transform_get(cw->ec);
4814 it = eina_tiler_iterator_new(cw->updates);
4815 EINA_ITERATOR_FOREACH(it, rect)
4817 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4818 * of evas engine and doesn't convert damage according to evas_map.
4819 * so damage of evas_object_image use surface coordinate.
4823 int damage_x, damage_y, damage_w, damage_h;
4825 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4826 &damage_x, &damage_y, &damage_w, &damage_h);
4827 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4828 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4832 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4833 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4836 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4837 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4838 if (cw->pending_updates)
4839 eina_tiler_rect_add(cw->pending_updates, rect);
4841 eina_iterator_free(it);
4842 if (m) e_map_free(m);
4843 if (cw->pending_updates)
4844 eina_tiler_clear(cw->updates);
4847 cw->pending_updates = cw->updates;
4848 cw->updates = eina_tiler_new(w, h);
4849 eina_tiler_tile_size_set(cw->updates, 1, 1);
4851 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4852 evas_object_smart_callback_call(obj, "dirty", NULL);
4853 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4854 /* force render if main object is hidden but mirrors are visible */
4855 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4856 e_comp_object_render(obj);
4860 e_comp_object_render(Evas_Object *obj)
4867 API_ENTRY EINA_FALSE;
4869 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4870 if (cw->ec->input_only) return EINA_TRUE;
4871 if (cw->external_content) return EINA_TRUE;
4872 if (cw->native) return EINA_FALSE;
4873 /* if comp object is not redirected state, comp object should not be set by newly committed data
4874 because image size of comp object is 1x1 and it should not be shown on canvas */
4875 if (!cw->redirected) return EINA_TRUE;
4876 if (cw->render_update_lock.lock)
4878 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4881 e_comp_object_render_update_del(obj);
4882 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4884 if (!cw->pending_updates)
4886 WRN("RENDER [%p]: NO RECTS!", cw->ec);
4887 evas_object_image_data_set(cw->obj, NULL);
4888 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4889 evas_object_image_data_set(o, NULL);
4893 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4895 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4897 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4900 e_pixmap_image_refresh(cw->ec->pixmap);
4901 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4904 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4905 e_pixmap_image_data_ref(cw->ec->pixmap);
4907 /* set pixel data */
4908 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4909 _e_comp_object_alpha_set(cw);
4910 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4912 evas_object_image_data_set(o, pix);
4913 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4914 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4917 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4919 e_comp_client_post_update_add(cw->ec);
4924 /* create a duplicate of an evas object */
4926 e_comp_object_util_mirror_add(Evas_Object *obj)
4930 unsigned int *pix = NULL;
4931 Eina_Bool argb = EINA_FALSE;
4936 cw = evas_object_data_get(obj, "comp_mirror");
4939 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4940 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4941 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4942 evas_object_image_alpha_set(o, 1);
4943 evas_object_image_source_set(o, obj);
4946 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4947 if (cw->external_content)
4949 ERR("%p of client %p is external content.", obj, cw->ec);
4952 o = evas_object_image_filled_add(evas_object_evas_get(obj));
4953 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4954 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4955 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4956 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4957 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4958 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4959 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4960 evas_object_data_set(o, "comp_mirror", cw);
4962 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4963 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4965 evas_object_image_size_set(o, tw, th);
4968 pix = evas_object_image_data_get(cw->obj, 0);
4974 evas_object_image_native_surface_set(o, cw->ns);
4977 Evas_Native_Surface ns;
4978 memset(&ns, 0, sizeof(Evas_Native_Surface));
4979 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
4980 evas_object_image_native_surface_set(o, &ns);
4985 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
4986 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
4988 (e_pixmap_image_exists(cw->ec->pixmap)))
4989 pix = e_pixmap_image_data_get(cw->ec->pixmap);
4991 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
4998 dirty = evas_object_image_pixels_dirty_get(cw->obj);
4999 evas_object_image_pixels_dirty_set(o, dirty);
5000 evas_object_image_data_set(o, pix);
5001 evas_object_image_data_set(cw->obj, pix);
5003 evas_object_image_data_update_add(o, 0, 0, tw, th);
5008 //////////////////////////////////////////////////////
5011 e_comp_object_effect_allowed_get(Evas_Object *obj)
5013 API_ENTRY EINA_FALSE;
5015 if (!cw->shobj) return EINA_FALSE;
5016 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5017 return !e_comp_config_get()->match.disable_borders;
5020 /* setup an api effect for a client */
5022 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5025 Eina_Stringshare *grp;
5026 E_Comp_Config *config;
5027 Eina_Bool loaded = EINA_FALSE;
5029 API_ENTRY EINA_FALSE;
5030 if (!cw->shobj) return EINA_FALSE; //input window
5032 if (!effect) effect = "none";
5033 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5035 config = e_comp_config_get();
5036 if ((config) && (config->effect_file))
5038 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5040 cw->effect_set = EINA_TRUE;
5047 edje_object_file_get(cw->effect_obj, NULL, &grp);
5048 cw->effect_set = !eina_streq(effect, "none");
5049 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5050 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5052 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5053 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5054 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5056 if (cw->effect_running)
5058 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5061 cw->effect_set = EINA_FALSE;
5062 return cw->effect_set;
5066 if (cw->effect_running)
5068 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5071 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5072 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5073 if (cw->effect_clip)
5075 evas_object_clip_unset(cw->clip);
5076 cw->effect_clip = 0;
5078 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5080 _e_comp_object_dim_update(cw);
5082 return cw->effect_set;
5085 /* set params for embryo scripts in effect */
5087 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5089 Edje_Message_Int_Set *msg;
5093 EINA_SAFETY_ON_NULL_RETURN(params);
5094 EINA_SAFETY_ON_FALSE_RETURN(count);
5095 if (!cw->effect_set) return;
5097 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5098 msg->count = (int)count;
5099 for (x = 0; x < count; x++)
5100 msg->val[x] = params[x];
5101 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5102 edje_object_message_signal_process(cw->effect_obj);
5106 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5108 Edje_Signal_Cb end_cb;
5110 E_Comp_Object *cw = data;
5112 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5113 cw->effect_running = 0;
5114 if (!_e_comp_object_animating_end(cw)) return;
5116 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5118 evas_object_data_del(cw->smart_obj, "effect_running");
5119 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5120 e_comp_visibility_calculation_set(EINA_TRUE);
5123 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5124 if (!end_cb) return;
5125 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5126 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5127 end_cb(end_data, cw->smart_obj, emission, source);
5130 /* clip effect to client's zone */
5132 e_comp_object_effect_clip(Evas_Object *obj)
5136 zone = e_comp_zone_find_by_ec(cw->ec);
5138 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5139 if (!cw->effect_clip_able) return;
5140 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5141 cw->effect_clip = 1;
5144 /* unclip effect from client's zone */
5146 e_comp_object_effect_unclip(Evas_Object *obj)
5149 if (!cw->effect_clip) return;
5150 evas_object_clip_unset(cw->smart_obj);
5151 cw->effect_clip = 0;
5154 /* start effect, running end_cb after */
5156 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5158 API_ENTRY EINA_FALSE;
5159 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5160 if (!cw->effect_set) return EINA_FALSE;
5162 if (cw->effect_running)
5164 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5167 e_comp_object_effect_clip(obj);
5168 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5170 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5171 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5172 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5173 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5175 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5176 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5178 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5179 _e_comp_object_animating_begin(cw);
5180 cw->effect_running = 1;
5184 /* stop a currently-running effect immediately */
5186 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5189 Edje_Signal_Cb end_cb_before = NULL;
5190 void *end_data_before = NULL;
5191 API_ENTRY EINA_FALSE;
5193 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5194 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5196 if (end_cb_before != end_cb) return EINA_TRUE;
5197 e_comp_object_effect_unclip(obj);
5198 if (cw->effect_clip)
5200 evas_object_clip_unset(cw->effect_obj);
5201 cw->effect_clip = 0;
5203 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5204 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5206 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5208 evas_object_data_del(cw->smart_obj, "effect_running");
5209 e_comp_visibility_calculation_set(EINA_TRUE);
5212 cw->effect_running = 0;
5213 ret = _e_comp_object_animating_end(cw);
5215 if ((ret) && (end_cb_before))
5217 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5218 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5225 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5227 return a->pri - b->pri;
5230 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5231 E_API E_Comp_Object_Mover *
5232 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5234 E_Comp_Object_Mover *prov;
5236 prov = E_NEW(E_Comp_Object_Mover, 1);
5237 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5238 prov->func = provider;
5239 prov->data = (void*)data;
5242 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5243 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5248 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5250 EINA_SAFETY_ON_NULL_RETURN(prov);
5251 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5256 e_comp_object_effect_object_get(Evas_Object *obj)
5260 return cw->effect_obj;
5264 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5266 API_ENTRY EINA_FALSE;
5267 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5268 if (!cw->effect_set) return EINA_FALSE;
5275 ////////////////////////////////////
5278 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5280 if (e_comp->autoclose.obj)
5282 e_comp_ungrab_input(0, 1);
5283 if (e_comp->autoclose.del_cb)
5284 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5285 else if (!already_del)
5287 evas_object_hide(e_comp->autoclose.obj);
5288 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5290 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5292 e_comp->autoclose.obj = NULL;
5293 e_comp->autoclose.data = NULL;
5294 e_comp->autoclose.del_cb = NULL;
5295 e_comp->autoclose.key_cb = NULL;
5296 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5300 _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)
5302 _e_comp_object_autoclose_cleanup(0);
5306 _e_comp_object_autoclose_setup(Evas_Object *obj)
5308 if (!e_comp->autoclose.rect)
5310 /* create rect just below autoclose object to catch mouse events */
5311 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5312 evas_object_move(e_comp->autoclose.rect, 0, 0);
5313 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5314 evas_object_show(e_comp->autoclose.rect);
5315 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5316 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5317 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5318 e_comp_grab_input(0, 1);
5320 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5321 evas_object_focus_set(obj, 1);
5325 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5327 _e_comp_object_autoclose_setup(obj);
5328 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5332 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5334 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5335 _e_comp_object_autoclose_cleanup(1);
5336 if (e_client_focused_get()) return;
5338 E_Zone *zone = e_zone_current_get();
5341 e_zone_focus_reset(zone);
5345 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5349 if (e_comp->autoclose.obj)
5351 if (e_comp->autoclose.obj == obj) return;
5352 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5353 e_comp->autoclose.obj = obj;
5354 e_comp->autoclose.del_cb = del_cb;
5355 e_comp->autoclose.key_cb = cb;
5356 e_comp->autoclose.data = (void*)data;
5357 if (evas_object_visible_get(obj))
5358 _e_comp_object_autoclose_setup(obj);
5360 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5361 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5364 e_comp->autoclose.obj = obj;
5365 e_comp->autoclose.del_cb = del_cb;
5366 e_comp->autoclose.key_cb = cb;
5367 e_comp->autoclose.data = (void*)data;
5368 if (evas_object_visible_get(obj))
5369 _e_comp_object_autoclose_setup(obj);
5371 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5372 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5376 e_comp_object_is_animating(Evas_Object *obj)
5380 return cw->animating;
5384 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5388 if ((cw->external_content) &&
5389 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5391 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5392 "But current external content is %d object for %p.",
5393 cw->content_type, cw->ec);
5397 cw->user_alpha_set = EINA_TRUE;
5398 cw->user_alpha = alpha;
5400 if (!cw->obj) return;
5402 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5404 evas_object_image_alpha_set(cw->obj, alpha);
5406 if ((!cw->native) && (!cw->external_content))
5407 evas_object_image_data_set(cw->obj, NULL);
5411 e_comp_object_alpha_get(Evas_Object *obj)
5413 API_ENTRY EINA_FALSE;
5415 return evas_object_image_alpha_get(cw->obj);
5419 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5421 Eina_Bool mask_set = EINA_FALSE;
5425 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5426 if (cw->ec->input_only) return;
5433 o = evas_object_rectangle_add(e_comp->evas);
5434 evas_object_color_set(o, 0, 0, 0, 0);
5435 evas_object_clip_set(o, cw->clip);
5436 evas_object_smart_member_add(o, obj);
5437 evas_object_move(o, 0, 0);
5438 evas_object_resize(o, cw->w, cw->h);
5439 /* save render op value to restore when clear a mask.
5441 * NOTE: DO NOT change the render op on ec->frame while mask object
5442 * is set. it will overwrite the changed op value. */
5443 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5444 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5445 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5446 if (cw->visible) evas_object_show(o);
5449 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5450 ELOGF("COMP", " |mask_obj", cw->ec);
5451 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5458 evas_object_smart_member_del(cw->mask.obj);
5459 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5461 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5462 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5468 e_comp_object_mask_has(Evas_Object *obj)
5470 API_ENTRY EINA_FALSE;
5472 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5476 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5481 if ((cw->external_content) &&
5482 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5484 WRN("Can set up size to ONLY evas \"image\" object. "
5485 "But current external content is %d object for %p.",
5486 cw->content_type, cw->ec);
5490 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5492 evas_object_image_size_set(cw->obj, tw, th);
5496 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5498 Eina_Bool transform_set = EINA_FALSE;
5500 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5501 if (cw->ec->input_only) return;
5503 transform_set = !!set;
5507 if (!cw->transform_bg_obj)
5509 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5510 evas_object_move(o, 0, 0);
5511 evas_object_resize(o, 1, 1);
5512 if (cw->transform_bg_color.a >= 255)
5513 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5515 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5516 evas_object_color_set(o,
5517 cw->transform_bg_color.r,
5518 cw->transform_bg_color.g,
5519 cw->transform_bg_color.b,
5520 cw->transform_bg_color.a);
5521 if (cw->visible) evas_object_show(o);
5523 cw->transform_bg_obj = o;
5524 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5526 _e_comp_object_transform_obj_stack_update(obj);
5530 if (cw->transform_bg_obj)
5532 evas_object_smart_member_del(cw->transform_bg_obj);
5533 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5539 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5543 cw->transform_bg_color.r = r;
5544 cw->transform_bg_color.g = g;
5545 cw->transform_bg_color.b = b;
5546 cw->transform_bg_color.a = a;
5548 if (cw->transform_bg_obj)
5550 evas_object_color_set(cw->transform_bg_obj,
5551 cw->transform_bg_color.r,
5552 cw->transform_bg_color.g,
5553 cw->transform_bg_color.b,
5554 cw->transform_bg_color.a);
5559 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5562 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5563 if (cw->ec->input_only) return;
5564 if (!cw->transform_bg_obj) return;
5566 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5570 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5573 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5574 if (cw->ec->input_only) return;
5575 if (!cw->transform_bg_obj) return;
5577 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5581 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5583 Eina_Bool transform_set = EINA_FALSE;
5585 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5586 if (cw->ec->input_only) return;
5588 transform_set = !!set;
5592 if (!cw->transform_tranp_obj)
5594 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5595 evas_object_move(o, 0, 0);
5596 evas_object_resize(o, 1, 1);
5597 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5598 evas_object_color_set(o, 0, 0, 0, 0);
5599 if (cw->visible) evas_object_show(o);
5601 cw->transform_tranp_obj = o;
5602 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5603 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5604 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5606 _e_comp_object_transform_obj_stack_update(obj);
5610 if (cw->transform_tranp_obj)
5612 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5613 evas_object_smart_member_del(cw->transform_tranp_obj);
5614 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5620 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5623 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5624 if (cw->ec->input_only) return;
5625 if (!cw->transform_tranp_obj) return;
5627 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5631 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5634 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5635 if (cw->ec->input_only) return;
5636 if (!cw->transform_tranp_obj) return;
5638 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5642 e_comp_object_layer_update(Evas_Object *obj,
5643 Evas_Object *above, Evas_Object *below)
5645 E_Comp_Object *cw2 = NULL;
5646 Evas_Object *o = NULL;
5651 if (cw->ec->layer_block) return;
5652 if ((above) && (below))
5654 ERR("Invalid layer update request! cw=%p", cw);
5662 layer = evas_object_layer_get(o);
5663 cw2 = evas_object_data_get(o, "comp_obj");
5666 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5668 o = evas_object_above_get(o);
5669 if ((!o) || (o == cw->smart_obj)) break;
5670 if (evas_object_layer_get(o) != layer)
5672 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5677 ec = e_client_top_get();
5678 if (ec) o = ec->frame;
5681 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5685 _e_comp_object_layers_remove(cw);
5688 if (cw2->layer > cw->layer)
5689 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5690 else if (cw2->layer == cw->layer)
5693 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5695 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5697 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5700 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5703 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5707 e_comp_object_layer_get(Evas_Object *obj)
5714 e_comp_object_content_set(Evas_Object *obj,
5715 Evas_Object *content,
5716 E_Comp_Object_Content_Type type)
5718 API_ENTRY EINA_FALSE;
5720 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5721 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5722 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5726 ERR("Can't set e.swallow.content to requested content. "
5727 "Previous comp object should not be changed at all.");
5731 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5733 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5734 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5736 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5737 type, content, cw->ec, cw->ec->pixmap);
5741 cw->external_content = EINA_TRUE;
5744 cw->content_type = type;
5745 e_util_size_debug_set(cw->obj, 1);
5746 evas_object_name_set(cw->obj, "cw->obj");
5747 _e_comp_object_alpha_set(cw);
5750 _e_comp_object_shadow_setup(cw);
5756 e_comp_object_content_unset(Evas_Object *obj)
5758 API_ENTRY EINA_FALSE;
5760 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5761 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5763 if (!cw->obj && !cw->ec->visible)
5765 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5769 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5771 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5777 if (cw->frame_object)
5778 edje_object_part_unswallow(cw->frame_object, cw->obj);
5780 edje_object_part_unswallow(cw->shobj, cw->obj);
5782 evas_object_del(cw->obj);
5783 evas_object_hide(cw->obj);
5787 cw->external_content = EINA_FALSE;
5788 if (cw->ec->is_cursor)
5791 DBG("%p is cursor surface..", cw->ec);
5792 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5794 evas_object_resize(cw->ec->frame, pw, ph);
5795 evas_object_hide(cw->ec->frame);
5800 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5801 cw->obj = evas_object_image_filled_add(e_comp->evas);
5802 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5803 e_util_size_debug_set(cw->obj, 1);
5804 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5805 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5806 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5807 evas_object_name_set(cw->obj, "cw->obj");
5808 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5809 _e_comp_object_alpha_set(cw);
5812 _e_comp_object_shadow_setup(cw);
5817 _e_comp_intercept_show_helper(cw);
5821 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5822 e_comp_object_dirty(cw->smart_obj);
5823 e_comp_object_render(cw->smart_obj);
5824 e_comp_object_render_update_add(obj);
5829 EINTERN Evas_Object *
5830 e_comp_object_content_get(Evas_Object *obj)
5834 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5836 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5838 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5845 E_API E_Comp_Object_Content_Type
5846 e_comp_object_content_type_get(Evas_Object *obj)
5848 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5850 return cw->content_type;
5854 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5857 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5858 E_Comp_Config *conf = e_comp_config_get();
5859 if (cw->ec->input_only) return;
5860 if (!conf->dim_rect_enable) return;
5862 cw->dim.mask_set = mask_set;
5868 if (!cw->dim.enable) return;
5869 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5873 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5875 Eina_Bool mask_set = EINA_FALSE;
5879 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5880 E_Comp_Config *conf = e_comp_config_get();
5881 if (cw->ec->input_only) return;
5882 if (!conf->dim_rect_enable) return;
5888 if (cw->dim.mask_obj)
5890 evas_object_smart_member_del(cw->dim.mask_obj);
5891 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5894 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);
5895 o = evas_object_rectangle_add(e_comp->evas);
5896 evas_object_color_set(o, 0, 0, 0, 0);
5897 evas_object_smart_member_add(o, obj);
5898 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5899 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5901 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5902 if (cw->visible) evas_object_show(o);
5904 cw->dim.mask_obj = o;
5905 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5907 evas_object_layer_set(cw->dim.mask_obj, 9998);
5911 if (cw->dim.mask_obj)
5913 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
5914 evas_object_smart_member_del(cw->dim.mask_obj);
5915 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5921 e_comp_object_dim_client_set(E_Client *ec)
5923 E_Comp_Config *conf = e_comp_config_get();
5925 if (!conf->dim_rect_enable) return ;
5926 if (dim_client == ec) return;
5928 Eina_Bool prev_dim = EINA_FALSE;
5929 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
5931 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5932 prev_dim = EINA_TRUE;
5934 if (prev_dim && dim_client->visible && ec)
5936 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5937 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5941 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5942 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5948 e_comp_object_dim_client_get(void)
5950 E_Comp_Config *conf = e_comp_config_get();
5952 if (!conf->dim_rect_enable ) return NULL;
5958 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
5961 char emit[32] = "\0";
5962 E_Comp_Config *conf = e_comp_config_get();
5965 if (!conf->dim_rect_enable) return;
5966 if (!cw->effect_obj) return;
5967 if (enable == cw->dim.enable) return;
5969 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
5970 if (noeffect || !conf->dim_rect_effect)
5972 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
5976 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
5979 cw->dim.enable = enable;
5981 if (cw->dim.mask_set && !enable)
5983 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5984 edje_object_signal_emit(cw->effect_obj, emit, "e");
5986 else if (cw->dim.mask_set && enable)
5988 edje_object_signal_emit(cw->effect_obj, emit, "e");
5989 e_comp_object_dim_mask_set(cw->ec->frame, enable);
5993 edje_object_signal_emit(cw->effect_obj, emit, "e");
5998 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6000 API_ENTRY EINA_FALSE;
6001 E_Comp_Config *conf = e_comp_config_get();
6003 if (!ec) return EINA_FALSE;
6004 if (!conf->dim_rect_enable) return EINA_FALSE;
6006 if (cw->dim.enable) return EINA_TRUE;
6012 _e_comp_object_dim_update(E_Comp_Object *cw)
6014 E_Comp_Config *conf = e_comp_config_get();
6017 if (!conf->dim_rect_enable) return;
6018 if (!cw->effect_obj) return;
6021 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6022 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6024 if (cw->dim.mask_set)
6026 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6032 e_comp_object_clear(Evas_Object *obj)
6036 _e_comp_object_clear(cw);
6040 e_comp_object_hwc_update_exists(Evas_Object *obj)
6042 API_ENTRY EINA_FALSE;
6043 return cw->hwc_need_update;
6048 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6051 cw->hwc_need_update = set;
6055 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6057 API_ENTRY EINA_FALSE;
6058 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6062 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6065 if (cw->indicator.obj != indicator)
6066 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6067 cw->indicator.obj = indicator;
6068 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6072 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6075 if (cw->indicator.obj != indicator) return;
6076 cw->indicator.obj = NULL;
6077 edje_object_part_unswallow(cw->shobj, indicator);
6081 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6084 Edje_Message_Int_Set *msg;
6086 if (!cw->indicator.obj) return;
6088 cw->indicator.w = w;
6089 cw->indicator.h = h;
6091 if (!cw->shobj) return;
6093 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6097 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6098 edje_object_message_signal_process(cw->shobj);
6101 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6103 e_comp_object_map_update(Evas_Object *obj)
6106 E_Client *ec = cw->ec;
6107 E_Comp_Wl_Client_Data *cdata;
6109 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6112 int l, remain = sizeof buffer;
6115 if (e_object_is_del(E_OBJECT(ec))) return;
6116 cdata = e_client_cdata_get(ec);
6119 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6120 * when new buffer is attached.
6122 if (!cdata->buffer_ref.buffer) return;
6124 if ((!cw->redirected) ||
6125 (e_client_video_hw_composition_check(ec)) ||
6126 (!e_comp_wl_output_buffer_transform_get(ec) &&
6127 cdata->scaler.buffer_viewport.buffer.scale == 1))
6129 if (evas_object_map_enable_get(cw->effect_obj))
6131 ELOGF("TRANSFORM", "map: disable", cw->ec);
6132 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6133 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6134 evas_object_resize(cw->effect_obj, tw, th);
6141 EINA_SAFETY_ON_NULL_RETURN(map);
6143 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6149 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6151 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6152 e_map_point_image_uv_set(map, 0, x, y);
6153 l = snprintf(p, remain, "%d,%d", x, y);
6154 p += l, remain -= l;
6156 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6157 e_map_point_image_uv_set(map, 1, x, y);
6158 l = snprintf(p, remain, " %d,%d", x, y);
6159 p += l, remain -= l;
6161 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6162 e_map_point_image_uv_set(map, 2, x, y);
6163 l = snprintf(p, remain, " %d,%d", x, y);
6164 p += l, remain -= l;
6166 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6167 e_map_point_image_uv_set(map, 3, x, y);
6168 l = snprintf(p, remain, " %d,%d", x, y);
6169 p += l, remain -= l;
6171 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6173 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6175 e_comp_object_map_set(cw->effect_obj, map);
6176 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6180 /* if there's screen rotation with comp mode, then ec->effect_obj and
6181 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6183 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6184 evas_object_resize(cw->effect_obj, tw, th);
6188 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6190 API_ENTRY EINA_FALSE;
6192 cw->render_trace = set;
6198 e_comp_object_native_usable_get(Evas_Object *obj)
6200 API_ENTRY EINA_FALSE;
6201 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6203 if (cw->ec->input_only) return EINA_FALSE;
6204 if (cw->external_content) return EINA_FALSE;
6205 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6207 /* just return true value, if it is normal case */
6208 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6211 Evas_Native_Surface *ns;
6212 ns = evas_object_image_native_surface_get(cw->obj);
6214 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6217 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6225 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6227 API_ENTRY EINA_FALSE;
6228 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6229 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6230 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6234 case E_COMP_IMAGE_FILTER_BLUR:
6235 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6237 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6238 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6240 case E_COMP_IMAGE_FILTER_INVERSE:
6241 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6243 case E_COMP_IMAGE_FILTER_NONE:
6245 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6249 cw->image_filter = filter;
6254 EINTERN E_Comp_Image_Filter
6255 e_comp_object_image_filter_get(Evas_Object *obj)
6257 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6258 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6259 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6260 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6262 return cw->image_filter;
6266 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6270 if (!_damage_trace) return;
6272 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6273 evas_object_del(obj);
6275 _damage_trace_post_objs = NULL;
6279 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6281 if (!_damage_trace) return;
6283 _damage_trace_post_objs = _damage_trace_objs;
6284 _damage_trace_objs = NULL;
6288 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6290 if (_damage_trace == onoff) return;
6294 evas_event_callback_add(e_comp->evas,
6295 EVAS_CALLBACK_RENDER_PRE,
6296 _e_comp_object_damage_trace_render_pre_cb,
6299 evas_event_callback_add(e_comp->evas,
6300 EVAS_CALLBACK_RENDER_POST,
6301 _e_comp_object_damage_trace_render_post_cb,
6308 EINA_LIST_FREE(_damage_trace_objs, obj)
6309 evas_object_del(obj);
6311 _damage_trace_objs = NULL;
6313 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6314 evas_object_del(obj);
6316 _damage_trace_post_objs = NULL;
6318 evas_event_callback_del(e_comp->evas,
6319 EVAS_CALLBACK_RENDER_PRE,
6320 _e_comp_object_damage_trace_render_pre_cb);
6322 evas_event_callback_del(e_comp->evas,
6323 EVAS_CALLBACK_RENDER_POST,
6324 _e_comp_object_damage_trace_render_post_cb);
6327 _damage_trace = onoff;
6331 e_comp_object_redirected_get(Evas_Object *obj)
6333 API_ENTRY EINA_FALSE;
6334 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6336 return cw->redirected;
6340 e_comp_object_color_visible_get(Evas_Object *obj)
6342 API_ENTRY EINA_FALSE;
6345 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6347 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6351 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6355 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6359 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6367 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6369 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6371 return e_map_set_to_comp_object(em, obj);
6375 e_comp_object_map_get(const Evas_Object *obj)
6377 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6379 return e_map_get_from_comp_object(obj);
6383 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6385 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6387 evas_object_map_enable_set(obj, enable);
6393 e_comp_object_render_update_lock(Evas_Object *obj)
6395 E_Comp_Wl_Buffer *buffer;
6396 struct wayland_tbm_client_queue *cqueue;
6398 API_ENTRY EINA_FALSE;
6400 if (cw->render_update_lock.lock == 0)
6402 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6404 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6405 if ((buffer) && (buffer->resource))
6407 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6409 wayland_tbm_server_client_queue_flush(cqueue);
6412 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6413 e_comp_object_render_update_del(obj);
6415 ELOGF("COMP", "Render update lock enabled", cw->ec);
6418 cw->render_update_lock.lock++;
6424 e_comp_object_render_update_unlock(Evas_Object *obj)
6428 if (cw->render_update_lock.lock == 0)
6431 cw->render_update_lock.lock--;
6433 if (cw->render_update_lock.lock == 0)
6436 if (cw->render_update_lock.pending_move_set)
6438 evas_object_move(obj,
6439 cw->render_update_lock.pending_move_x,
6440 cw->render_update_lock.pending_move_y);
6441 cw->render_update_lock.pending_move_x = 0;
6442 cw->render_update_lock.pending_move_y = 0;
6443 cw->render_update_lock.pending_move_set = EINA_FALSE;
6446 if (cw->render_update_lock.pending_resize_set)
6448 evas_object_resize(obj,
6449 cw->render_update_lock.pending_resize_w,
6450 cw->render_update_lock.pending_resize_h);
6451 cw->render_update_lock.pending_resize_w = 0;
6452 cw->render_update_lock.pending_resize_h = 0;
6453 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6456 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6458 if ((cw->ec->exp_iconify.buffer_flush) &&
6459 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6460 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6461 e_comp_object_clear(obj);
6463 e_comp_object_render_update_add(obj);
6465 ELOGF("COMP", "Render update lock disabled", cw->ec);
6470 e_comp_object_render_update_lock_get(Evas_Object *obj)
6472 API_ENTRY EINA_FALSE;
6474 if (cw->render_update_lock.lock > 0)
6481 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6485 if (cw->transparent.set)
6487 if (r) *r = cw->transparent.user_r;
6488 if (g) *g = cw->transparent.user_g;
6489 if (b) *b = cw->transparent.user_b;
6490 if (a) *a = cw->transparent.user_a;
6494 evas_object_color_get(obj, r, g, b, a);
6499 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6503 evas_object_render_op_set(cw->obj, op);
6506 EINTERN Evas_Render_Op
6507 e_comp_object_render_op_get(Evas_Object *obj)
6509 API_ENTRY EVAS_RENDER_BLEND;
6511 return evas_object_render_op_get(cw->obj);
6515 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6518 wl_signal_add(&cw->events.lower, listener);
6522 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6525 wl_signal_add(&cw->events.show, listener);
6529 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6532 wl_signal_add(&cw->events.hide, listener);