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;
77 Eina_Stringshare *frame_theme;
78 Eina_Stringshare *frame_name;
79 Eina_Stringshare *visibility_effect; //effect when toggling visibility
81 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
83 Evas_Object *smart_obj; // smart object
84 Evas_Object *clip; // clipper over effect object
85 Evas_Object *input_obj; // input smart object
86 Evas_Object *obj; // composite object
87 Evas_Object *frame_object; // for client frames
88 Evas_Object *shobj; // shadow object
89 Evas_Object *effect_obj; // effects object
90 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
95 Evas_Object *transform_tranp_obj;// transform transp rect obj
96 Evas_Object *default_input_obj; // default input object
97 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
98 Eina_List *obj_mirror; // extra mirror objects
99 Eina_Tiler *updates; //render update regions
100 Eina_Tiler *pending_updates; //render update regions which are about to render
102 Evas_Native_Surface *ns; //for custom gl rendering
104 struct wl_listener buffer_destroy_listener;
106 unsigned int update_count; // how many updates have happened to this obj
108 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
110 unsigned int animating; // it's busy animating
111 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
112 unsigned int force_visible; //number of visible obj_mirror objects
113 Eina_Bool delete_pending : 1; // delete pending
114 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
115 Eina_Bool showing : 1; // object is currently in "show" animation
116 Eina_Bool hiding : 1; // object is currently in "hide" animation
117 Eina_Bool visible : 1; // is visible
119 Eina_Bool shaped : 1; // is shaped
120 Eina_Bool update : 1; // has updates to fetch
121 Eina_Bool redirected : 1; // has updates to fetch
122 Eina_Bool native : 1; // native
124 Eina_Bool nocomp : 1; // nocomp applied
125 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
126 Eina_Bool real_hid : 1; // last hide was a real window unmap
128 Eina_Bool effect_set : 1; //effect_obj has a valid group
129 Eina_Bool effect_running : 1; //effect_obj is playing an animation
130 Eina_Bool effect_clip : 1; //effect_obj is clipped
131 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
133 Eina_Bool updates_exist : 1;
134 Eina_Bool updates_full : 1; // entire object will be updated
136 Eina_Bool force_move : 1;
137 Eina_Bool frame_extends : 1; //frame may extend beyond object size
138 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
139 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
140 Eina_Bool user_alpha_set : 1;
141 Eina_Bool user_alpha : 1;
145 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
146 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
153 } indicator; //indicator object for internal client
157 Evas_Object *mask_obj;
160 int mask_x, mask_y, mask_w, mask_h;
163 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
165 tbm_surface_h tbm_surface;
166 E_Comp_Image_Filter image_filter;
167 Eina_Bool set_mouse_callbacks;
172 E_Comp_Wl_Buffer_Ref buffer_ref;
173 Eina_Bool pending_move_set;
174 int pending_move_x, pending_move_y;
175 Eina_Bool pending_resize_set;
176 int pending_resize_w, pending_resize_h;
177 } render_update_lock;
189 typedef struct _E_Input_Rect_Data
195 typedef struct _E_Input_Rect_Smart_Data
197 Eina_List *input_rect_data_list;
199 } E_Input_Rect_Smart_Data;
201 struct E_Comp_Object_Mover
204 E_Comp_Object_Mover_Cb func;
210 static Eina_Inlist *_e_comp_object_movers = NULL;
211 static Evas_Smart *_e_comp_smart = NULL;
212 static Evas_Smart *_e_comp_input_obj_smart = NULL;
214 static int _e_comp_object_hooks_delete = 0;
215 static int _e_comp_object_hooks_walking = 0;
217 static Eina_Inlist *_e_comp_object_hooks[] =
219 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
220 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
221 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
222 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
223 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
224 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
225 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
226 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
227 //#ifdef REFACTOR_FOCUS_POLICY
228 [E_COMP_OBJECT_HOOK_LOWER] = NULL,
232 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
233 static int _e_comp_object_intercept_hooks_delete = 0;
234 static int _e_comp_object_intercept_hooks_walking = 0;
236 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
238 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
239 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
243 static Eina_Bool _damage_trace = EINA_FALSE;
244 static Eina_List *_damage_trace_objs = NULL;
245 static Eina_List *_damage_trace_post_objs = NULL;
247 /* sekrit functionzzz */
248 EINTERN void e_client_focused_set(E_Client *ec);
250 /* emitted every time a new noteworthy comp object is added */
251 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
253 /* ecore event define */
254 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
255 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
256 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
258 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
259 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
260 static void _e_comp_object_dim_update(E_Comp_Object *cw);
261 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
262 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
264 static E_Client *dim_client = NULL;
267 _e_comp_object_hooks_clean(void)
270 E_Comp_Object_Hook *ch;
273 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
274 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
276 if (!ch->delete_me) continue;
277 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
283 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
285 E_Comp_Object_Hook *ch;
286 Eina_Bool ret = EINA_TRUE;
288 if (e_object_is_del(E_OBJECT(ec)))
290 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
291 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
292 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
293 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
294 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
295 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
296 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
297 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
298 #ifdef REFACTOR_FOCUS_POLICY
299 && (hookpoint != E_COMP_OBJECT_HOOK_LOWER)
306 e_object_ref(E_OBJECT(ec));
307 _e_comp_object_hooks_walking++;
308 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
310 if (ch->delete_me) continue;
311 if (!(ch->func(ch->data, ec)))
317 _e_comp_object_hooks_walking--;
318 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
319 _e_comp_object_hooks_clean();
321 e_object_unref(E_OBJECT(ec));
326 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
328 _e_comp_object_intercept_hooks_clean(void)
331 E_Comp_Object_Intercept_Hook *ch;
334 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
335 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
337 if (!ch->delete_me) continue;
338 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
344 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
346 E_Comp_Object_Intercept_Hook *ch;
347 Eina_Bool ret = EINA_TRUE;
349 if (e_object_is_del(E_OBJECT(ec))) return ret;
350 e_object_ref(E_OBJECT(ec));
351 _e_comp_object_intercept_hooks_walking++;
352 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
354 if (ch->delete_me) continue;
355 if (!(ch->func(ch->data, ec)))
361 _e_comp_object_intercept_hooks_walking--;
362 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
363 _e_comp_object_intercept_hooks_clean();
365 e_object_unref(E_OBJECT(ec));
372 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
374 E_Event_Comp_Object *ev = event;
377 ec = evas_object_data_get(ev->comp_object, "E_Client");
381 e_object_unref(E_OBJECT(ec));
383 evas_object_unref(ev->comp_object);
388 _e_comp_object_event_add(Evas_Object *obj)
390 E_Event_Comp_Object *ev;
393 if (stopping) return;
394 ev = E_NEW(E_Event_Comp_Object, 1);
395 EINA_SAFETY_ON_NULL_RETURN(ev);
397 evas_object_ref(obj);
398 ev->comp_object = obj;
399 ec = evas_object_data_get(ev->comp_object, "E_Client");
403 e_object_ref(E_OBJECT(ec));
405 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
409 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
411 E_Event_Comp_Object *ev = event;
414 ec = evas_object_data_get(ev->comp_object, "E_Client");
418 e_object_unref(E_OBJECT(ec));
420 evas_object_unref(ev->comp_object);
425 _e_comp_object_event_simple(Evas_Object *obj, int type)
427 E_Event_Comp_Object *ev;
430 ev = E_NEW(E_Event_Comp_Object, 1);
433 evas_object_ref(obj);
434 ev->comp_object = obj;
435 ec = evas_object_data_get(ev->comp_object, "E_Client");
439 e_object_ref(E_OBJECT(ec));
441 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
443 /////////////////////////////////////
446 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
448 E_Comp_Object *cw = data;
450 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
454 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
456 E_Comp_Object *cw = data;
458 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
459 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
462 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
463 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
467 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
469 E_Comp_Object *cw = data;
472 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
473 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
476 /////////////////////////////////////
479 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
483 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
484 if (cw->ec->input_only) return;
486 layer = evas_object_layer_get(obj);
488 if (cw->transform_bg_obj)
490 if (layer != evas_object_layer_get(cw->transform_bg_obj))
492 evas_object_layer_set(cw->transform_bg_obj, layer);
495 evas_object_stack_below(cw->transform_bg_obj, obj);
498 if (cw->transform_tranp_obj)
500 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
502 evas_object_layer_set(cw->transform_tranp_obj, layer);
505 evas_object_stack_below(cw->transform_tranp_obj, obj);
510 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
517 if (!map) return NULL;
519 e_map_util_points_populate_from_object_full(map, obj, 0);
520 e_map_util_points_color_set(map, 255, 255, 255, 255);
522 for (i = 0 ; i < 4 ; ++i)
527 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
528 e_map_point_coord_set(map, i, x, y, 1.0);
535 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
541 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
544 e_comp_object_map_set(obj, map);
545 e_comp_object_map_enable_set(obj, EINA_TRUE);
552 evas_object_map_enable_set(obj, EINA_FALSE);
557 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
563 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
566 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
568 e_comp_object_map_set(obj, map);
569 e_comp_object_map_enable_set(obj, EINA_TRUE);
576 evas_object_map_enable_set(obj, EINA_FALSE);
579 /////////////////////////////////////
581 static inline Eina_Bool
582 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
584 if (num > 1) return EINA_TRUE;
585 if ((rects[0].x == 0) && (rects[0].y == 0) &&
586 ((int)rects[0].w == w) && ((int)rects[0].h == h))
591 /////////////////////////////////////
593 /* add a client to the layer-client list */
595 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
597 E_Comp_Object *layer_cw = NULL;
599 /* try to get the internal data for the layer;
600 * will return NULL for fake layers (eg. wayland)
602 if (e_comp->layers[cw->layer].obj)
604 if (evas_object_smart_smart_get(e_comp->layers[cw->layer].obj))
605 layer_cw = evas_object_smart_data_get(e_comp->layers[cw->layer].obj);
607 if (layer_cw == cw) layer_cw = NULL;
609 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));
611 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));
612 if ((!above) && (!below))
615 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
617 e_comp->layers[cw->layer].clients = eina_inlist_prepend_relative(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(layer_cw->ec));
618 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
619 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
621 e_comp->layers[cw->layer].clients_count++;
622 #ifndef E_RELEASE_BUILD
625 E_Client *below_ec = e_client_below_get(cw->ec);
628 if (e_comp->layers[cw->layer].obj == below_ec->frame)
629 CRI("ACK! ec:%p", cw->ec);
636 _e_comp_object_layers_remove(E_Comp_Object *cw)
638 if (cw->ec && e_comp->layers[cw->layer].clients)
640 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
641 e_comp->layers[cw->layer].clients_count--;
644 e_comp->layers[cw->layer].objs = eina_inlist_remove(e_comp->layers[cw->layer].objs, EINA_INLIST_GET(cw));
645 e_comp->layers[cw->layer].objs_count--;
649 /////////////////////////////////////
651 _e_comp_object_alpha_set(E_Comp_Object *cw)
653 Eina_Bool alpha = cw->ec->argb;
655 if ((cw->external_content) &&
656 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
661 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
662 if (cw->user_alpha_set) alpha = cw->user_alpha;
664 evas_object_image_alpha_set(cw->obj, alpha);
668 _e_comp_object_shadow(E_Comp_Object *cw)
670 if (e_client_util_shadow_state_get(cw->ec))
671 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
673 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
674 if (cw->frame_object)
675 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
676 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
679 /* convert from the surface coordinates to the buffer coordinates */
681 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
683 E_Comp_Wl_Buffer_Viewport *vp;
684 E_Comp_Wl_Client_Data *cdata;
688 cdata = e_client_cdata_get(ec);
690 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
697 vp = &cdata->scaler.buffer_viewport;
698 transform = e_comp_wl_output_buffer_transform_get(ec);
700 e_pixmap_size_get(ec->pixmap, &bw, &bh);
702 /* for subsurface, it should be swap 90 and 270 */
703 if (e_comp_wl_subsurface_check(ec))
706 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
707 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
708 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
709 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
715 case WL_OUTPUT_TRANSFORM_NORMAL:
716 default: tx = sx, ty = sy; break;
717 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
718 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
719 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
720 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
721 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
722 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
723 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
726 tx *= vp->buffer.scale;
727 ty *= vp->buffer.scale;
734 _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)
742 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
743 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
750 if (dw) *dw = MAX(x1, x2) - mx;
751 if (dh) *dh = MAX(y1, y2) - my;
755 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
756 int *dx, int *dy, int *dw, int *dh)
758 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
759 E_Util_Transform_Rect_Vertex sv, dv;
763 e_pixmap_size_get(ec->pixmap, &bw, &bh);
765 sv = e_util_transform_rect_to_vertices(&rect);
767 for (i = 0; i < 4; i++)
769 double x = 0.0, y = 0.0;
771 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
773 /* if evas decide coordinate is outside of map, it returns (0, 0)
774 in this case, full damage is added.
776 if ((i != 0) && (x == 0.0) && (y == 0.0))
779 dv.vertices[i].vertex[0] = x;
780 dv.vertices[i].vertex[1] = y;
781 dv.vertices[i].vertex[2] = 1.0;
782 dv.vertices[i].vertex[3] = 1.0;
785 rect = e_util_transform_vertices_to_rect(&dv);
787 if (dx) *dx = rect.x;
788 if (dy) *dy = rect.y;
789 if (dw) *dw = rect.w;
790 if (dh) *dh = rect.h;
804 _e_comp_object_map_damage_transform_get(E_Client *ec)
811 if (!evas_object_map_enable_get(ec->frame))
814 m = e_client_map_get(ec);
818 e_pixmap_size_get(ec->pixmap, &bw, &bh);
819 if ((bw == 0) || (bh == 0))
832 e_map_point_coord_set(m2, 0, 0, 0, 0);
833 e_map_point_coord_set(m2, 1, bw, 0, 0);
834 e_map_point_coord_set(m2, 2, bw, bh, 0);
835 e_map_point_coord_set(m2, 3, 0, bh, 0);
837 for (i = 0; i < 4; i++)
841 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
842 e_map_point_image_uv_set(m2, i, map_x, map_y);
849 /////////////////////////////////////
851 /* handle evas mouse-in events on client object */
853 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
855 Evas_Event_Mouse_In *ev = event_info;
856 E_Comp_Object *cw = data;
858 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
861 /* handle evas mouse-out events on client object */
863 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
865 Evas_Event_Mouse_Out *ev = event_info;
866 E_Comp_Object *cw = data;
868 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
871 /* handle evas mouse wheel events on client object */
873 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
875 Evas_Event_Mouse_Wheel *ev = event_info;
876 E_Comp_Object *cw = data;
877 E_Binding_Event_Wheel ev2;
880 if (e_client_action_get()) return;
881 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
882 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
885 /* handle evas mouse down events on client object */
887 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
889 Evas_Event_Mouse_Down *ev = event_info;
890 E_Comp_Object *cw = data;
891 E_Binding_Event_Mouse_Button ev2;
894 if (e_client_action_get()) return;
895 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
896 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
899 /* handle evas mouse up events on client object */
901 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
903 Evas_Event_Mouse_Up *ev = event_info;
904 E_Comp_Object *cw = data;
905 E_Binding_Event_Mouse_Button ev2;
908 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
909 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
910 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
913 /* handle evas mouse movement events on client object */
915 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
917 Evas_Event_Mouse_Move *ev = event_info;
918 E_Comp_Object *cw = data;
921 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
922 e_client_mouse_move(cw->ec, &ev->cur.output);
924 /////////////////////////////////////
926 /* helper function for checking compositor themes based on user-defined matches */
928 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
930 if (((m->title) && (!ec->netwm.name)) ||
931 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
933 #if defined(__cplusplus) || defined(c_plusplus)
934 if (((m->clas) && (!ec->icccm.cpp_class)) ||
935 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
938 if (((m->clas) && (!ec->icccm.class)) ||
939 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
943 if (((m->role) && (!ec->icccm.window_role)) ||
944 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
950 if ((int)ec->netwm.type != m->primary_type)
953 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
956 if (m->borderless != 0)
960 if (e_client_util_borderless(ec))
962 if (!(((m->borderless == -1) && (!borderless)) ||
963 ((m->borderless == 1) && (borderless))))
970 if (((ec->icccm.transient_for != 0) ||
973 if (!(((m->dialog == -1) && (!dialog)) ||
974 ((m->dialog == 1) && (dialog))))
977 if (m->accepts_focus != 0)
979 int accepts_focus = 0;
981 if (ec->icccm.accepts_focus)
983 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
984 ((m->accepts_focus == 1) && (accepts_focus))))
993 if (!(((m->vkbd == -1) && (!vkbd)) ||
994 ((m->vkbd == 1) && (vkbd))))
999 if (!(((m->argb == -1) && (!ec->argb)) ||
1000 ((m->argb == 1) && (ec->argb))))
1003 if (m->fullscreen != 0)
1005 int fullscreen = ec->fullscreen;
1007 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1008 ((m->fullscreen == 1) && (fullscreen))))
1015 if (ec->netwm.state.modal)
1017 if (!(((m->modal == -1) && (!modal)) ||
1018 ((m->modal == 1) && (modal))))
1024 /* function for setting up a client's compositor frame theme (cw->shobj) */
1026 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1030 Eina_List *list = NULL, *l;
1031 E_Input_Rect_Data *input_rect_data;
1032 E_Input_Rect_Smart_Data *input_rect_sd;
1034 Eina_Stringshare *reshadow_group = NULL;
1035 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;
1036 Eina_Stringshare *name, *title;
1037 E_Comp_Config *conf = e_comp_config_get();
1039 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1040 /* match correct client type */
1041 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1042 name = cw->ec->icccm.name;
1043 title = cw->ec->icccm.title;
1044 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1045 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1047 /* skipping here is mostly a hack for systray because I hate it */
1050 EINA_LIST_FOREACH(list, l, m)
1052 if (((m->name) && (!name)) ||
1053 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1055 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1059 no_shadow = m->no_shadow;
1060 if (m->shadow_style)
1062 /* fast effects are just themes with "/fast" appended and shorter effect times */
1065 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1066 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1068 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1070 /* default to non-fast style if fast not available */
1073 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1074 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1076 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1078 if (ok && m->visibility_effect)
1079 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1086 if (skip || (cw->ec->e.state.video))
1088 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1090 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1093 if (conf->shadow_style)
1097 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1098 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1100 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1104 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1105 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1107 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1114 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1116 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1120 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1122 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1127 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1132 if (cw->ec->override)
1134 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1135 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1137 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1138 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1144 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1145 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1148 _e_comp_object_shadow(cw);
1151 if (focus || cw->ec->focused || cw->ec->override)
1152 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1154 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1155 if (urgent || cw->ec->urgent)
1156 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1158 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1160 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
1162 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1165 /* visibility must always be enabled for re_manage clients to prevent
1166 * pop-in animations every time the user sees a persistent client again;
1167 * applying visibility for iconic clients prevents the client from getting
1170 if (cw->visible || cw->ec->re_manage)
1171 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1173 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1175 /* breaks animation counter */
1176 if (cw->frame_object)
1178 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1179 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1181 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1187 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1191 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1194 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1196 if (input_rect_data->obj)
1198 pass_event_flag = EINA_TRUE;
1204 if (cw->indicator.obj)
1206 Evas_Object *indicator;
1207 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1208 if (indicator != cw->indicator.obj)
1210 edje_object_part_unswallow(cw->shobj, indicator);
1211 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1212 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1216 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1217 evas_object_pass_events_set(cw->obj, pass_event_flag);
1222 /////////////////////////////////////////////
1225 _e_comp_object_animating_begin(E_Comp_Object *cw)
1228 if (cw->animating == 1)
1230 e_comp->animating++;
1232 e_object_ref(E_OBJECT(cw->ec));
1237 _e_comp_object_animating_end(E_Comp_Object *cw)
1246 if (cw->ec->launching)
1248 if (!cw->ec->extra_animating)
1250 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1251 cw->ec->launching = EINA_FALSE;
1252 if (cw->ec->first_mapped)
1254 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1255 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1258 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1262 e_comp->animating--;
1263 cw->showing = cw->hiding = 0;
1265 if (e_comp->animating == 0)
1266 e_comp_visibility_calculation_set(EINA_TRUE);
1267 /* remove ref from animation start, account for possibility of deletion from unref */
1268 return !!e_object_unref(E_OBJECT(cw->ec));
1274 /* handle the end of a compositor animation */
1276 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1278 E_Comp_Object *cw = data;
1280 /* visible clients which have never been sized are a bug */
1281 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1282 CRI("ACK! ec:%p", cw->ec);
1283 if (!_e_comp_object_animating_end(cw)) return;
1284 if (cw->animating) return;
1285 /* hide only after animation finishes to guarantee a full run of the animation */
1286 if (!cw->defer_hide) return;
1287 if ((!strcmp(emission, "e,action,hide,done")) ||
1288 (!strcmp(emission, "e,action,done")) ||
1289 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1291 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1292 evas_object_hide(cw->smart_obj);
1296 /* run a visibility compositor effect if available, return false if object is dead */
1298 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1304 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1305 if (!cw->effect_running)
1306 _e_comp_object_animating_begin(cw);
1307 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1308 return _e_comp_object_animating_end(cw);
1309 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1310 return _e_comp_object_animating_end(cw);
1312 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1315 zone = e_comp_zone_find_by_ec(cw->ec);
1317 zw = zone->w, zh = zone->h;
1322 zone = e_comp_object_util_zone_get(cw->smart_obj);
1323 if (!zone) zone = e_zone_current_get();
1330 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1331 cw->w, cw->h, zw, zh, x, y}, 8);
1332 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1333 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1336 /////////////////////////////////////////////
1338 /* create necessary objects for clients that e manages */
1340 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1342 if (cw->set_mouse_callbacks) return;
1343 if (!cw->smart_obj) return;
1345 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1346 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1347 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1348 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1349 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1350 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1352 cw->set_mouse_callbacks = EINA_TRUE;
1356 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1358 if (!cw->set_mouse_callbacks) return;
1359 if (!cw->smart_obj) return;
1361 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1362 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1363 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1364 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1365 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1366 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1368 cw->set_mouse_callbacks = EINA_FALSE;
1372 _e_comp_object_setup(E_Comp_Object *cw)
1374 cw->clip = evas_object_rectangle_add(e_comp->evas);
1375 evas_object_move(cw->clip, -9999, -9999);
1376 evas_object_resize(cw->clip, 999999, 999999);
1377 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1378 cw->effect_obj = edje_object_add(e_comp->evas);
1379 evas_object_move(cw->effect_obj, cw->x, cw->y);
1380 evas_object_clip_set(cw->effect_obj, cw->clip);
1381 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1382 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1383 cw->shobj = edje_object_add(e_comp->evas);
1384 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1385 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1386 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1388 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1389 if (cw->ec->override)
1391 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1392 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1393 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1395 else if (!cw->ec->input_only)
1397 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1398 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1399 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1401 cw->real_hid = !cw->ec->input_only;
1402 if (!cw->ec->input_only)
1404 e_util_size_debug_set(cw->effect_obj, 1);
1405 _e_comp_object_mouse_event_callback_set(cw);
1408 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1409 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1410 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1411 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1412 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1413 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1415 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1418 /////////////////////////////////////////////
1420 /* for fast path evas rendering; only called during render */
1422 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1424 E_Comp_Object *cw = data;
1425 E_Client *ec = cw->ec;
1427 int bx, by, bxx, byy;
1429 if (e_object_is_del(E_OBJECT(ec))) return;
1430 if (cw->external_content) return;
1431 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1432 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1435 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1436 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1438 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1440 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1441 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1445 bx = by = bxx = byy = 0;
1446 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1449 Edje_Message_Int_Set *msg;
1450 Edje_Message_Int msg2;
1451 Eina_Bool id = (bx || by || bxx || byy);
1453 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1459 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1461 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1465 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1466 e_comp_client_post_update_add(cw->ec);
1468 else if (e_comp_object_render(ec->frame))
1470 /* apply shape mask if necessary */
1471 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1472 e_comp_object_shape_apply(ec->frame);
1473 ec->shape_changed = 0;
1475 /* shaped clients get precise mouse events to handle transparent pixels */
1476 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1478 /* queue another render if client is still dirty; cannot refresh here. */
1479 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1480 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1482 if (cw->render_trace)
1484 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1490 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1492 E_Comp_Object *cw = data;
1493 E_Client *ec = cw->ec;
1495 if (e_object_is_del(E_OBJECT(ec))) return;
1496 if (cw->external_content) return;
1497 if (!e_comp->hwc) return;
1499 e_comp_client_render_list_add(cw->ec);
1501 if (!ec->hwc_window) return;
1503 e_hwc_windows_rendered_window_add(ec->hwc_window);
1506 /////////////////////////////////////////////
1509 _e_comp_object_client_pending_resize_add(E_Client *ec,
1512 unsigned int serial)
1514 E_Client_Pending_Resize *pnd;
1516 pnd = E_NEW(E_Client_Pending_Resize, 1);
1520 pnd->serial = serial;
1521 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1525 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1527 E_Comp_Object *cw = data;
1530 if (cw->render_update_lock.lock)
1532 cw->render_update_lock.pending_move_x = x;
1533 cw->render_update_lock.pending_move_y = y;
1534 cw->render_update_lock.pending_move_set = EINA_TRUE;
1538 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1539 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1540 (cw->external_content))
1542 /* delay to move until the external content is unset */
1543 cw->ec->changes.pos = 1;
1548 if (cw->ec->move_after_resize)
1550 if ((x != cw->ec->x) || (y != cw->ec->y))
1552 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1553 e_client_pos_set(cw->ec, x, y);
1554 cw->ec->changes.pos = 1;
1560 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1561 (cw->ec->manage_resize.resize_obj))
1563 e_client_pos_set(cw->ec, x, y);
1564 cw->ec->client.x = x + cw->client_inset.l;
1565 cw->ec->client.y = y + cw->client_inset.t;
1566 e_policy_visibility_client_defer_move(cw->ec);
1570 /* if frame_object does not exist, client_inset indicates CSD.
1571 * this means that ec->client matches cw->x/y, the opposite
1574 fx = (!cw->frame_object) * cw->client_inset.l;
1575 fy = (!cw->frame_object) * cw->client_inset.t;
1576 if ((cw->x == x + fx) && (cw->y == y + fy))
1578 if ((cw->ec->x != x) || (cw->ec->y != y))
1580 /* handle case where client tries to move to position and back very quickly */
1581 e_client_pos_set(cw->ec, x, y);
1582 cw->ec->client.x = x + cw->client_inset.l;
1583 cw->ec->client.y = y + cw->client_inset.t;
1587 if (!cw->ec->maximize_override)
1589 /* prevent moving in some directions while directionally maximized */
1590 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1592 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1595 ix = x + cw->client_inset.l;
1596 iy = y + cw->client_inset.t;
1597 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1598 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1599 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1601 /* prevent moving at all if move isn't allowed in current maximize state */
1602 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1603 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1604 if ((!cw->ec->shading) && (!cw->ec->shaded))
1607 zone = e_comp_zone_find_by_ec(cw->ec);
1610 cw->ec->changes.need_unmaximize = 1;
1611 cw->ec->saved.x = ix - zone->x;
1612 cw->ec->saved.y = iy - zone->y;
1613 cw->ec->saved.w = cw->ec->client.w;
1614 cw->ec->saved.h = cw->ec->client.h;
1620 /* only update during resize if triggered by resize */
1621 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1622 /* delay to move while surface waits paired commit serial*/
1623 if (e_client_pending_geometry_has(cw->ec))
1625 /* do nothing while waiting paired commit serial*/
1629 e_client_pos_set(cw->ec, x, y);
1630 if (cw->ec->new_client)
1632 /* don't actually do anything until first client idler loop */
1633 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1634 cw->ec->changes.pos = 1;
1639 /* only update xy position of client to avoid invalid
1640 * first damage region if it is not a new_client. */
1641 if (!cw->ec->shading)
1643 cw->ec->client.x = ix;
1644 cw->ec->client.y = iy;
1647 if (!cw->frame_object)
1649 evas_object_move(obj, x, y);
1654 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1656 E_Comp_Object *cw = data;
1657 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1660 if (cw->render_update_lock.lock)
1662 cw->render_update_lock.pending_resize_w = w;
1663 cw->render_update_lock.pending_resize_h = h;
1664 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1668 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1670 e_client_size_set(cw->ec, w, h);
1671 evas_object_resize(obj, w, h);
1675 /* if frame_object does not exist, client_inset indicates CSD.
1676 * this means that ec->client matches cw->w/h, the opposite
1679 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1680 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1681 if ((cw->w == w + fw) && (cw->h == h + fh))
1683 if (cw->ec->shading || cw->ec->shaded) return;
1684 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1685 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1686 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1688 /* handle case where client tries to resize itself and back very quickly */
1689 e_client_size_set(cw->ec, w, h);
1690 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1691 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1692 evas_object_smart_callback_call(obj, "client_resize", NULL);
1696 /* guarantee that fullscreen is fullscreen */
1697 zone = e_comp_zone_find_by_ec(cw->ec);
1699 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1701 /* calculate client size */
1702 iw = w - cw->client_inset.l - cw->client_inset.r;
1703 ih = h - cw->client_inset.t - cw->client_inset.b;
1704 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1706 /* prevent resizing while maximized depending on direction and config */
1707 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1708 if ((!cw->ec->shading) && (!cw->ec->shaded))
1710 Eina_Bool reject = EINA_FALSE;
1711 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1713 if (cw->ec->client.h != ih)
1715 cw->ec->saved.h = ih;
1716 cw->ec->saved.y = cw->ec->client.y - zone->y;
1717 reject = cw->ec->changes.need_unmaximize = 1;
1720 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1722 if (cw->ec->client.w != iw)
1724 cw->ec->saved.w = iw;
1725 cw->ec->saved.x = cw->ec->client.x - zone->x;
1726 reject = cw->ec->changes.need_unmaximize = 1;
1736 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1738 /* do nothing until client idler loops */
1739 if ((cw->ec->w != w) || (cw->ec->h != h))
1741 e_client_size_set(cw->ec, w, h);
1742 cw->ec->changes.size = 1;
1747 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1748 ((cw->ec->w != w) || (cw->ec->h != h)))
1751 /* netwm sync resizes queue themselves and then trigger later on */
1752 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1754 if (e_client_pending_geometry_has(cw->ec))
1756 /* do nothing while waiting paired commit serial*/
1760 e_client_size_set(cw->ec, w, h);
1761 if ((!cw->ec->shading) && (!cw->ec->shaded))
1763 /* client geom never changes when shading since the client is never altered */
1764 cw->ec->client.w = iw;
1765 cw->ec->client.h = ih;
1766 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1769 /* The size of non-compositing window can be changed, so there is a
1770 * need to check that cw is H/W composited if cw is not redirected.
1771 * And of course we have to change size of evas object of H/W composited cw,
1772 * otherwise cw can't receive input events even if it is shown on the screen.
1774 Eina_Bool redirected = cw->redirected;
1776 redirected = e_comp_is_on_overlay(cw->ec);
1778 if ((!cw->ec->input_only) && (redirected) &&
1779 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1780 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1781 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1782 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1785 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1786 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1788 prev_w = cw->w, prev_h = cw->h;
1789 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1790 /* check shading and clamp to pixmap size for regular clients */
1791 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1792 (((w - fw != pw) || (h - fh != ph))))
1794 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1795 evas_object_smart_callback_call(obj, "client_resize", NULL);
1797 if (cw->frame_object || cw->ec->input_only)
1798 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1801 if ((cw->w == w) && (cw->h == h))
1803 /* going to be a noop resize which won't trigger smart resize */
1804 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1805 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1807 evas_object_resize(obj, w, h);
1811 evas_object_smart_callback_call(obj, "client_resize", NULL);
1814 if ((!cw->frame_object) && (!cw->ec->input_only))
1816 /* "just do it" for overrides */
1817 evas_object_resize(obj, w, h);
1819 if (!cw->ec->override)
1821 /* shape probably changed for non-overrides */
1822 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1823 cw->ec->need_shape_export |= cw->ec->shaped;
1824 if (cw->ec->shaped || cw->ec->shaped_input)
1828 /* this fixes positioning jiggles when using a resize mode
1829 * which also changes the client's position
1832 if (cw->frame_object)
1833 x = cw->x, y = cw->y;
1835 x = cw->ec->x, y = cw->ec->y;
1836 switch (cw->ec->resize_mode)
1838 case E_POINTER_RESIZE_BL:
1839 case E_POINTER_RESIZE_L:
1840 evas_object_move(obj, x + prev_w - cw->w, y);
1842 case E_POINTER_RESIZE_TL:
1843 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1845 case E_POINTER_RESIZE_T:
1846 case E_POINTER_RESIZE_TR:
1847 evas_object_move(obj, x, y + prev_h - cw->h);
1856 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1858 E_Comp_Object *cw = data;
1859 E_Comp_Wl_Client_Data *child_cdata;
1860 unsigned int l = e_comp_canvas_layer_map(layer);
1863 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1865 /* doing a compositor effect, follow directions */
1866 _e_comp_object_layer_set(obj, layer);
1867 if (layer == cw->ec->layer) //trying to put layer back
1871 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1872 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1873 if (cw->layer != l) goto layer_set;
1877 e_comp_render_queue();
1879 ec = e_client_above_get(cw->ec);
1880 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1881 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1882 ec = e_client_above_get(ec);
1883 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1885 ec = e_client_below_get(cw->ec);
1886 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1887 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1888 ec = e_client_below_get(ec);
1889 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1891 evas_object_stack_above(obj, ec->frame);
1896 if (ec && (cw->ec->parent == ec))
1898 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1899 evas_object_stack_above(obj, ec->frame);
1901 evas_object_stack_below(obj, ec->frame);
1904 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1910 if (cw->layer == l) return;
1911 if (e_comp_canvas_client_layer_map(layer) == 9999)
1912 return; //invalid layer for clients not doing comp effects
1913 if (cw->ec->fullscreen)
1915 cw->ec->saved.layer = layer;
1918 oldraise = e_config->transient.raise;
1920 /* clamp to valid client layer */
1921 layer = e_comp_canvas_client_layer_map_nearest(layer);
1922 cw->ec->layer = layer;
1923 if (e_config->transient.layer)
1926 Eina_List *list = eina_list_clone(cw->ec->transients);
1928 /* We need to set raise to one, else the child wont
1929 * follow to the new layer. It should be like this,
1930 * even if the user usually doesn't want to raise
1933 e_config->transient.raise = 1;
1934 EINA_LIST_FREE(list, child)
1936 child_cdata = e_client_cdata_get(child);
1937 if (child_cdata && !child_cdata->mapped)
1939 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1942 e_client_layer_set(child, layer);
1946 e_config->transient.raise = oldraise;
1948 _e_comp_object_layers_remove(cw);
1949 cw->layer = e_comp_canvas_layer_map(layer);
1950 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1951 //if (cw->ec->new_client)
1952 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1953 _e_comp_object_layer_set(obj, layer);
1954 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1955 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1956 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1958 /* can't stack a client above its own layer marker */
1959 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1961 if (!cw->visible) return;
1962 e_comp_render_queue();
1963 _e_comp_object_transform_obj_stack_update(obj);
1966 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1969 _e_comp_object_raise(Evas_Object *obj)
1971 evas_object_raise(obj);
1973 if (evas_object_smart_smart_get(obj))
1975 E_Client *ec = e_comp_object_client_get(obj);
1977 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1982 _e_comp_object_lower(Evas_Object *obj)
1984 evas_object_lower(obj);
1986 if (evas_object_smart_smart_get(obj))
1988 E_Client *ec = e_comp_object_client_get(obj);
1990 #ifdef REFACTOR_FOCUS_POLICY
1992 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1993 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LOWER, ec);
1996 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2002 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2004 evas_object_stack_above(obj, target);
2006 if (evas_object_smart_smart_get(obj))
2008 E_Client *ec = e_comp_object_client_get(obj);
2010 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2015 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2017 evas_object_stack_below(obj, target);
2019 if (evas_object_smart_smart_get(obj))
2021 E_Client *ec = e_comp_object_client_get(obj);
2023 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2028 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2030 evas_object_layer_set(obj, layer);
2032 if (evas_object_smart_smart_get(obj))
2034 E_Client *ec = e_comp_object_client_get(obj);
2036 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2041 _e_comp_object_is_pending(E_Client *ec)
2045 if (!ec) return EINA_FALSE;
2047 topmost = e_comp_wl_topmost_parent_get(ec);
2049 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2053 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2055 E_Comp_Object *cw2 = NULL;
2058 Evas_Object *o = stack;
2059 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2061 /* We should consider topmost's layer_pending for subsurface */
2062 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2064 if (_e_comp_object_is_pending(cw->ec))
2065 e_comp_object_layer_update(cw->smart_obj,
2066 raising? stack : NULL,
2067 raising? NULL : stack);
2069 /* obey compositor effects! */
2070 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2071 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2072 stack_cb(cw->smart_obj, stack);
2073 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2074 evas_object_data_del(cw->smart_obj, "client_restack");
2078 cw2 = evas_object_data_get(o, "comp_obj");
2080 /* assume someone knew what they were doing during client init */
2081 if (cw->ec->new_client)
2082 layer = cw->ec->layer;
2083 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2084 layer = cw2->ec->layer;
2086 layer = evas_object_layer_get(stack);
2087 ecstack = e_client_below_get(cw->ec);
2088 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2090 /* some FOOL is trying to restack a layer marker */
2091 if (cw->smart_obj == e_comp->layers[cw->layer].obj) return;
2092 evas_object_layer_set(cw->smart_obj, layer);
2093 /* we got our layer wrangled, return now! */
2094 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2097 /* check if we're stacking below another client */
2100 /* check for non-client layer object */
2101 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2103 /* find an existing client to use for layering
2104 * by walking up the object stack
2106 * this is guaranteed to be pretty quick since we'll either:
2107 * - run out of client layers
2108 * - find a stacking client
2110 o = evas_object_above_get(o);
2111 if ((!o) || (o == cw->smart_obj)) break;
2112 if (evas_object_layer_get(o) != layer)
2114 /* reached the top client layer somehow
2115 * use top client object
2117 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2120 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2121 * return here since the top client layer window
2126 ec = e_client_top_get();
2131 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2134 if (cw2 && cw->layer != cw2->layer)
2137 /* remove existing layers */
2138 _e_comp_object_layers_remove(cw);
2141 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2142 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2143 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2144 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2145 else //if no stacking objects found, either raise or lower
2146 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2149 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2151 /* find new object for stacking if cw2 is on state of layer_pending */
2152 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2154 E_Client *new_stack = NULL, *current_ec = NULL;
2155 current_ec = cw2->ec;
2158 while ((new_stack = e_client_below_get(current_ec)))
2160 current_ec = new_stack;
2161 if (new_stack == cw->ec) continue;
2162 if (new_stack->layer != cw2->ec->layer) break;
2163 if (!_e_comp_object_is_pending(new_stack)) break;
2165 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2166 stack = new_stack->frame;
2169 /* stack it above layer object */
2171 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2172 stack = e_comp->layers[below_layer].obj;
2177 while ((new_stack = e_client_above_get(current_ec)))
2179 current_ec = new_stack;
2180 if (new_stack == cw->ec) continue;
2181 if (new_stack->layer != cw2->ec->layer) break;
2182 if (!_e_comp_object_is_pending(new_stack)) break;
2184 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2185 stack = new_stack->frame;
2187 stack = e_comp->layers[cw2->layer].obj;
2191 /* set restack if stacking has changed */
2192 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2193 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2194 stack_cb(cw->smart_obj, stack);
2195 if (e_comp->layers[cw->layer].obj)
2196 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2198 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2200 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2201 evas_object_data_del(cw->smart_obj, "client_restack");
2202 if (!cw->visible) return;
2203 e_comp_render_queue();
2207 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2209 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2211 if (evas_object_below_get(obj) == above)
2213 e_comp_object_layer_update(obj, above, NULL);
2217 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2218 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2219 _e_comp_object_transform_obj_stack_update(obj);
2220 _e_comp_object_transform_obj_stack_update(above);
2225 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2227 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2228 if (evas_object_above_get(obj) == below)
2230 e_comp_object_layer_update(obj, NULL, below);
2234 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2235 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2236 if (evas_object_smart_smart_get(obj))
2237 _e_comp_object_transform_obj_stack_update(obj);
2238 if (evas_object_smart_smart_get(below))
2239 _e_comp_object_transform_obj_stack_update(below);
2244 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2246 E_Comp_Object *cw = data;
2249 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2251 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2253 if (cw->ec->layer_pending)
2254 e_comp_object_layer_update(obj, NULL, obj);
2256 _e_comp_object_lower(obj);
2259 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2260 o = evas_object_below_get(obj);
2261 _e_comp_object_layers_remove(cw);
2262 /* prepend to client list since this client should be the first item now */
2263 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2264 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2265 if (obj == e_comp->layers[cw->layer].obj) goto end; //never lower a layer marker!
2266 evas_object_data_set(obj, "client_restack", (void*)1);
2267 _e_comp_object_lower(obj);
2268 evas_object_data_del(obj, "client_restack");
2269 if (!cw->visible) goto end;
2270 e_comp_render_queue();
2271 _e_comp_object_transform_obj_stack_update(obj);
2274 #ifdef REFACTOR_FOCUS_POLICY
2275 // This code executes E_COMP_OBJECT_HOOK_LOWER callback at e_focus_policy_history.c
2277 if (!cw->ec->post_lower)
2278 e_client_focus_stack_lower(cw->ec);
2284 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2286 E_Comp_Object *cw = data;
2289 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2291 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2293 if (cw->ec->layer_pending)
2295 int obj_layer = evas_object_layer_get(obj);
2296 if (cw->ec->layer != obj_layer)
2297 e_comp_object_layer_update(obj, NULL, NULL);
2300 _e_comp_object_raise(obj);
2303 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2304 o = evas_object_above_get(obj);
2306 E_Client *ecabove = e_client_above_get(cw->ec);
2307 if (ecabove && (ecabove->frame == e_comp->layers[cw->layer].obj) &&
2308 (ecabove->frame == o)) goto end; //highest below marker
2310 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2311 if (obj == e_comp->layers[cw->layer].obj) //never raise a non-layer marker!
2312 _e_comp_object_raise(obj);
2317 /* still stack below override below the layer marker */
2318 for (op = o = e_comp->layers[cw->layer].obj;
2319 o && o != e_comp->layers[cw->layer - 1].obj;
2320 op = o, o = evas_object_below_get(o))
2322 if (evas_object_smart_smart_get(o))
2326 ec = e_comp_object_client_get(o);
2327 if (ec && (!ec->override)) break;
2330 _e_comp_object_stack_below(obj, op);
2331 e_client_focus_defer_set(cw->ec);
2333 if (!cw->visible) goto end;
2334 e_comp_render_queue();
2335 _e_comp_object_transform_obj_stack_update(obj);
2342 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2344 E_Comp_Object *cw = data;
2346 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2347 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2349 ELOGF("COMP", "Hide. intercepted", cw->ec);
2354 if (cw->ec->launching == EINA_TRUE)
2356 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2357 cw->ec->launching = EINA_FALSE;
2362 /* hidden flag = just do it */
2363 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2364 evas_object_hide(obj);
2368 if (cw->ec->input_only)
2370 /* input_only = who cares */
2371 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2372 evas_object_hide(obj);
2375 /* already hidden or currently animating */
2376 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2378 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2382 /* don't try hiding during shutdown */
2383 cw->defer_hide |= stopping;
2384 if (!cw->defer_hide)
2386 if ((!cw->ec->iconic) && (!cw->ec->override))
2387 /* unset delete requested so the client doesn't break */
2388 cw->ec->delete_requested = 0;
2389 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2391 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2392 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2395 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2398 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2400 _e_comp_object_animating_begin(cw);
2401 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2403 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2404 cw->defer_hide = !!cw->animating;
2406 e_comp_object_effect_set(obj, NULL);
2409 if (cw->animating) return;
2410 /* if we have no animations running, go ahead and hide */
2412 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2413 evas_object_hide(obj);
2417 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2419 E_Client *ec = cw->ec;
2422 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2424 if (ec->show_pending.count > 0)
2426 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2427 ec->show_pending.running = EINA_TRUE;
2431 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2432 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2434 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2439 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,
2440 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2441 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2444 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2447 if (ec->iconic && cw->animating)
2449 /* triggered during iconify animation */
2450 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2453 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2456 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2457 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2459 evas_object_move(cw->smart_obj, ec->x, ec->y);
2460 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2461 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2463 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2464 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2467 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2468 evas_object_show(cw->smart_obj);
2471 e_client_focus_defer_set(ec);
2475 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2479 pw = ec->client.w, ph = ec->client.h;
2481 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2483 ec->changes.visible = !ec->hidden;
2486 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2490 cw->updates = eina_tiler_new(pw, ph);
2493 ec->changes.visible = !ec->hidden;
2496 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2501 eina_tiler_tile_size_set(cw->updates, 1, 1);
2504 /* ignore until client idler first run */
2505 ec->changes.visible = !ec->hidden;
2508 ELOGF("COMP", "show_helper. return. new_client", ec);
2515 evas_object_move(cw->smart_obj, ec->x, ec->y);
2516 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2517 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2518 evas_object_show(cw->smart_obj);
2521 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2523 /* start_drag not received */
2524 ec->changes.visible = 1;
2527 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2530 /* re-set geometry */
2531 evas_object_move(cw->smart_obj, ec->x, ec->y);
2532 /* force resize in case it hasn't happened yet, or just to update size */
2533 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2534 if ((cw->w < 1) || (cw->h < 1))
2536 /* if resize didn't go through, try again */
2537 ec->visible = ec->changes.visible = 1;
2539 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2542 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2543 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2544 e_pixmap_clear(ec->pixmap);
2546 if (cw->real_hid && w && h)
2549 /* force comp theming in case it didn't happen already */
2550 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2551 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2552 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2555 /* only do the show if show is allowed */
2558 if (ec->internal) //internal clients render when they feel like it
2559 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2561 if (!e_client_is_iconified_by_client(ec)||
2562 e_policy_visibility_client_is_uniconic(ec))
2564 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2565 evas_object_show(cw->smart_obj);
2567 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2568 it is rendered in idle callback without native surface and
2569 compositor shows an empty frame if other objects aren't shown
2570 because job callback of e_comp called at the next loop.
2571 it causes a visual defect when windows are switched.
2575 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2576 e_comp_object_dirty(cw->smart_obj);
2577 e_comp_object_render(cw->smart_obj);
2581 e_policy_visibility_client_is_uniconic(ec))
2583 if (ec->exp_iconify.not_raise &&
2584 e_client_check_above_focused(ec))
2585 e_client_focus_stack_append_current_focused(ec);
2587 e_client_focus_defer_set(ec);
2594 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2596 E_Comp_Object *cw = data;
2597 E_Client *ec = cw->ec;
2599 E_Input_Rect_Data *input_rect_data;
2600 E_Input_Rect_Smart_Data *input_rect_sd;
2603 if (ec->ignored) return;
2607 //INF("SHOW2 %p", ec);
2608 _e_comp_intercept_show_helper(cw);
2611 //INF("SHOW %p", ec);
2614 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2615 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2616 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2617 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2621 if ((!cw->obj) && (cw->external_content))
2623 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2627 _e_comp_object_setup(cw);
2630 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2631 cw->obj = evas_object_image_filled_add(e_comp->evas);
2632 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2633 e_util_size_debug_set(cw->obj, 1);
2634 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2635 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2636 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2637 evas_object_name_set(cw->obj, "cw->obj");
2638 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2640 _e_comp_object_alpha_set(cw);
2643 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2646 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2647 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2650 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2653 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2655 if (input_rect_data->obj)
2657 evas_object_geometry_set(input_rect_data->obj,
2658 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2659 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2660 input_rect_data->rect.w, input_rect_data->rect.h);
2667 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2669 _e_comp_intercept_show_helper(cw);
2673 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2675 E_Comp_Object *cw = data;
2679 /* note: this is here as it seems there are enough apps that do not even
2680 * expect us to emulate a look of focus but not actually set x input
2681 * focus as we do - so simply abort any focus set on such windows */
2682 /* be strict about accepting focus hint */
2683 /* be strict about accepting focus hint */
2684 if ((!ec->icccm.accepts_focus) &&
2685 (!ec->icccm.take_focus))
2689 if (e_client_focused_get() == ec)
2690 e_client_focused_set(NULL);
2692 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2693 evas_object_focus_set(obj, focus);
2697 if (focus && ec->lock_focus_out) return;
2698 if (e_object_is_del(E_OBJECT(ec)) && focus)
2699 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2701 /* filter focus setting based on current state */
2706 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2707 evas_object_focus_set(obj, focus);
2710 if ((ec->iconic) && (!ec->deskshow))
2712 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2714 /* don't focus an iconified window. that's silly! */
2715 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2716 e_client_uniconify(ec);
2717 e_client_focus_latest_set(ec);
2725 if ((!ec->sticky) && (ec->desk) && (!ec->desk->visible))
2727 if (ec->desk->animate_count) return;
2728 e_desk_show(ec->desk);
2729 if (!ec->desk->visible) return;
2737 /* not yet visible, wait till the next time... */
2738 ec->want_focus = !ec->hidden;
2743 e_client_focused_set(ec);
2747 if (e_client_focused_get() == ec)
2748 e_client_focused_set(NULL);
2752 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2754 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2756 evas_object_focus_set(obj, focus);
2760 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2762 E_Comp_Object *cw = data;
2764 if (cw->transparent.set)
2766 cw->transparent.user_r = r;
2767 cw->transparent.user_g = g;
2768 cw->transparent.user_b = b;
2769 cw->transparent.user_a = a;
2771 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2773 cw->transparent.user_r,
2774 cw->transparent.user_g,
2775 cw->transparent.user_b,
2776 cw->transparent.user_a);
2780 evas_object_color_set(obj, r, g, b, a);
2783 ////////////////////////////////////////////////////
2786 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2788 int w, h, ox, oy, ow, oh;
2790 Eina_Bool pass_event_flag = EINA_FALSE;
2791 E_Input_Rect_Data *input_rect_data;
2792 E_Input_Rect_Smart_Data *input_rect_sd;
2794 if (cw->frame_object)
2796 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2797 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2798 /* set a fixed size, force edje calc, check size difference */
2799 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2800 edje_object_message_signal_process(cw->frame_object);
2801 edje_object_calc_force(cw->frame_object);
2802 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2803 cw->client_inset.l = ox;
2804 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2805 cw->client_inset.t = oy;
2806 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2807 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2808 evas_object_resize(cw->frame_object, w, h);
2812 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2815 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2817 if (input_rect_data->obj)
2819 pass_event_flag = EINA_TRUE;
2825 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2826 evas_object_pass_events_set(cw->obj, pass_event_flag);
2830 cw->client_inset.l = 0;
2831 cw->client_inset.r = 0;
2832 cw->client_inset.t = 0;
2833 cw->client_inset.b = 0;
2835 cw->client_inset.calc = !!cw->frame_object;
2839 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2841 E_Comp_Object *cw = data;
2845 /* - get current size
2847 * - readjust for new frame size
2850 w = cw->ec->w, h = cw->ec->h;
2851 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2853 _e_comp_object_frame_recalc(cw);
2855 if (!cw->ec->fullscreen)
2856 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2858 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2859 if (cw->ec->shading || cw->ec->shaded) return;
2860 if (cw->ec->fullscreen)
2862 zone = e_comp_zone_find_by_ec(cw->ec);
2864 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2866 else if (cw->ec->new_client)
2868 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2869 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2870 evas_object_resize(cw->ec->frame, w, h);
2872 else if ((w != cw->ec->w) || (h != cw->ec->h))
2873 evas_object_resize(cw->ec->frame, w, h);
2877 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2879 E_Comp_Object *cw = data;
2881 if (!cw->ec) return; //NYI
2882 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2884 cw->shade.x = cw->x;
2885 cw->shade.y = cw->y;
2886 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2890 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2892 E_Comp_Object *cw = data;
2894 if (!cw->ec) return; //NYI
2895 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2897 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2901 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2903 E_Comp_Object *cw = data;
2905 if (!cw->ec) return; //NYI
2906 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2908 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2912 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2914 E_Comp_Object *cw = data;
2916 if (!cw->ec) return; //NYI
2917 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2919 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2923 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2925 E_Comp_Object *cw = data;
2927 _e_comp_object_shadow_setup(cw);
2928 if (cw->frame_object)
2930 _e_comp_object_shadow(cw);
2931 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2932 _e_comp_object_frame_recalc(cw);
2933 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2938 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2940 E_Comp_Object *cw = data;
2942 if (_e_comp_object_shadow_setup(cw))
2943 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2944 if (cw->frame_object)
2946 _e_comp_object_shadow(cw);
2947 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2948 _e_comp_object_frame_recalc(cw);
2949 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2954 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2956 E_Comp_Object *cw = data;
2958 if (cw->frame_object)
2960 _e_comp_object_shadow(cw);
2961 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2962 _e_comp_object_frame_recalc(cw);
2963 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2968 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2970 E_Comp_Object *cw = data;
2972 if (_e_comp_object_shadow_setup(cw))
2975 cw->ec->changes.size = 1;
2977 if (cw->frame_object)
2979 _e_comp_object_shadow(cw);
2980 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2981 _e_comp_object_frame_recalc(cw);
2982 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2987 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2989 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2993 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2995 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2999 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3001 E_Comp_Object *cw = data;
3003 if (!cw->ec) return; //NYI
3004 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
3008 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3010 E_Comp_Object *cw = data;
3012 if (!cw->ec) return; //NYI
3013 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3017 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3019 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3023 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3025 E_Comp_Object *cw = data;
3027 if (!e_object_is_del(E_OBJECT(cw->ec)))
3028 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3032 _e_comp_input_obj_smart_add(Evas_Object *obj)
3034 E_Input_Rect_Smart_Data *input_rect_sd;
3035 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3037 if (!input_rect_sd) return;
3038 evas_object_smart_data_set(obj, input_rect_sd);
3042 _e_comp_input_obj_smart_del(Evas_Object *obj)
3044 E_Input_Rect_Smart_Data *input_rect_sd;
3045 E_Input_Rect_Data *input_rect_data;
3047 input_rect_sd = evas_object_smart_data_get(obj);
3048 if (!input_rect_sd) return;
3050 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3052 if (input_rect_data->obj)
3054 evas_object_smart_member_del(input_rect_data->obj);
3055 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3057 E_FREE(input_rect_data);
3059 E_FREE(input_rect_sd);
3063 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3065 E_Input_Rect_Smart_Data *input_rect_sd;
3066 E_Input_Rect_Data *input_rect_data;
3070 input_rect_sd = evas_object_smart_data_get(obj);
3071 if (!input_rect_sd) return;
3073 cw = input_rect_sd->cw;
3074 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3076 if (input_rect_data->obj)
3078 evas_object_geometry_set(input_rect_data->obj,
3079 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3080 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3081 input_rect_data->rect.w, input_rect_data->rect.h);
3087 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3089 E_Input_Rect_Smart_Data *input_rect_sd;
3090 E_Input_Rect_Data *input_rect_data;
3094 input_rect_sd = evas_object_smart_data_get(obj);
3095 if (!input_rect_sd) return;
3097 cw = input_rect_sd->cw;
3098 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3100 if (input_rect_data->obj)
3102 evas_object_geometry_set(input_rect_data->obj,
3103 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3104 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3105 input_rect_data->rect.w, input_rect_data->rect.h);
3111 _e_comp_input_obj_smart_show(Evas_Object *obj)
3113 E_Input_Rect_Smart_Data *input_rect_sd;
3114 E_Input_Rect_Data *input_rect_data;
3117 input_rect_sd = evas_object_smart_data_get(obj);
3118 if (!input_rect_sd) return;
3120 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3122 if (input_rect_data->obj)
3124 evas_object_show(input_rect_data->obj);
3130 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3132 E_Input_Rect_Smart_Data *input_rect_sd;
3133 E_Input_Rect_Data *input_rect_data;
3136 input_rect_sd = evas_object_smart_data_get(obj);
3137 if (!input_rect_sd) return;
3139 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3141 if (input_rect_data->obj)
3143 evas_object_hide(input_rect_data->obj);
3149 _e_comp_input_obj_smart_init(void)
3151 if (_e_comp_input_obj_smart) return;
3153 static const Evas_Smart_Class sc =
3155 INPUT_OBJ_SMART_NAME,
3156 EVAS_SMART_CLASS_VERSION,
3157 _e_comp_input_obj_smart_add,
3158 _e_comp_input_obj_smart_del,
3159 _e_comp_input_obj_smart_move,
3160 _e_comp_input_obj_smart_resize,
3161 _e_comp_input_obj_smart_show,
3162 _e_comp_input_obj_smart_hide,
3175 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3181 _e_comp_smart_add(Evas_Object *obj)
3185 cw = E_NEW(E_Comp_Object, 1);
3186 EINA_SAFETY_ON_NULL_RETURN(cw);
3188 cw->smart_obj = obj;
3189 cw->x = cw->y = cw->w = cw->h = -1;
3190 evas_object_smart_data_set(obj, cw);
3191 cw->opacity = 255.0;
3192 cw->external_content = 0;
3193 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3194 cw->transform_bg_color.r = 0;
3195 cw->transform_bg_color.g = 0;
3196 cw->transform_bg_color.b = 0;
3197 cw->transform_bg_color.a = 255;
3198 evas_object_data_set(obj, "comp_obj", cw);
3199 evas_object_move(obj, -1, -1);
3200 /* intercept ALL the callbacks! */
3201 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3202 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3203 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3204 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3205 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3206 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3207 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3208 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3209 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3210 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3211 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3213 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3214 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3215 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3216 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3218 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3219 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3220 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3221 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3223 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3224 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3226 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3227 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3229 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3231 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3232 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3236 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3239 evas_object_color_set(cw->clip, r, g, b, a);
3240 evas_object_smart_callback_call(obj, "color_set", NULL);
3245 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3248 evas_object_clip_set(cw->clip, clip);
3252 _e_comp_smart_clip_unset(Evas_Object *obj)
3255 evas_object_clip_unset(cw->clip);
3259 _e_comp_smart_hide(Evas_Object *obj)
3261 TRACE_DS_BEGIN(COMP:SMART HIDE);
3266 evas_object_hide(cw->clip);
3267 if (cw->input_obj) evas_object_hide(cw->input_obj);
3268 evas_object_hide(cw->effect_obj);
3269 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3270 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3271 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3278 /* unset native surface if current displaying buffer was destroied */
3279 if (!cw->buffer_destroy_listener.notify)
3281 Evas_Native_Surface *ns;
3282 ns = evas_object_image_native_surface_get(cw->obj);
3283 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3284 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3287 if (!cw->ec->input_only)
3289 edje_object_freeze(cw->effect_obj);
3290 edje_object_freeze(cw->shobj);
3291 edje_object_play_set(cw->shobj, 0);
3292 if (cw->frame_object)
3293 edje_object_play_set(cw->frame_object, 0);
3295 /* ensure focus-out */
3296 if (cw->ec->focused &&
3297 (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK))
3299 ELOGF("FOCUS", "focus unset | smart_hide", cw->ec);
3300 e_client_frame_focus_set(cw->ec, EINA_FALSE);
3301 e_client_focus_defer_unset(cw->ec);
3303 e_comp_render_queue(); //force nocomp recheck
3309 _e_comp_smart_show(Evas_Object *obj)
3317 if ((cw->w < 0) || (cw->h < 0))
3318 CRI("ACK! ec:%p", cw->ec);
3320 TRACE_DS_BEGIN(COMP:SMART SHOW);
3322 e_comp_object_map_update(obj);
3324 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3325 evas_object_show(tmp->frame);
3327 evas_object_show(cw->clip);
3328 if (cw->input_obj) evas_object_show(cw->input_obj);
3329 if (!cw->ec->input_only)
3331 edje_object_thaw(cw->effect_obj);
3332 edje_object_thaw(cw->shobj);
3333 edje_object_play_set(cw->shobj, 1);
3334 if (cw->frame_object)
3335 edje_object_play_set(cw->frame_object, 1);
3337 evas_object_show(cw->effect_obj);
3338 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3339 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3340 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3341 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3342 e_comp_render_queue();
3343 if (cw->ec->input_only)
3348 if (cw->ec->iconic && (!cw->ec->new_client))
3350 if (e_client_is_iconified_by_client(cw->ec))
3352 ELOGF("COMP", "Set launching flag..", cw->ec);
3353 cw->ec->launching = EINA_TRUE;
3356 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3358 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3361 ELOGF("COMP", "Set launching flag..", cw->ec);
3362 cw->ec->launching = EINA_TRUE;
3364 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3365 _e_comp_object_animating_begin(cw);
3366 if (!_e_comp_object_effect_visibility_start(cw, 1))
3372 /* ensure some random effect doesn't lock the client offscreen */
3376 e_comp_object_effect_set(obj, NULL);
3379 _e_comp_object_dim_update(cw);
3385 _e_comp_smart_del(Evas_Object *obj)
3391 if (cw->buffer_destroy_listener.notify)
3393 wl_list_remove(&cw->buffer_destroy_listener.link);
3394 cw->buffer_destroy_listener.notify = NULL;
3397 if (cw->tbm_surface)
3399 tbm_surface_internal_unref(cw->tbm_surface);
3400 cw->tbm_surface = NULL;
3403 if (cw->render_update_lock.buffer_ref.buffer)
3405 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3406 cw->ec, cw->render_update_lock.lock);
3407 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3410 e_comp_object_render_update_del(cw->smart_obj);
3411 E_FREE_FUNC(cw->updates, eina_tiler_free);
3412 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3419 EINA_LIST_FREE(cw->obj_mirror, o)
3421 evas_object_image_data_set(o, NULL);
3422 evas_object_freeze_events_set(o, 1);
3423 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3427 _e_comp_object_layers_remove(cw);
3428 l = evas_object_data_get(obj, "comp_object-to_del");
3429 E_FREE_LIST(l, evas_object_del);
3430 _e_comp_object_mouse_event_callback_unset(cw);
3431 evas_object_del(cw->clip);
3432 evas_object_del(cw->effect_obj);
3433 evas_object_del(cw->shobj);
3434 evas_object_del(cw->frame_object);
3435 evas_object_del(cw->input_obj);
3436 evas_object_del(cw->obj);
3437 evas_object_del(cw->mask.obj);
3438 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3439 evas_object_del(cw->transform_bg_obj);
3440 evas_object_del(cw->transform_tranp_obj);
3441 evas_object_del(cw->default_input_obj);
3442 eina_stringshare_del(cw->frame_theme);
3443 eina_stringshare_del(cw->frame_name);
3447 e_comp->animating--;
3449 e_object_unref(E_OBJECT(cw->ec));
3451 cw->ec->frame = NULL;
3456 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3460 cw->x = x, cw->y = y;
3461 evas_object_move(cw->effect_obj, x, y);
3462 evas_object_move(cw->default_input_obj, x, y);
3463 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3465 e_comp_object_map_update(obj);
3469 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3471 Eina_Bool first = EINA_FALSE;
3476 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3478 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3480 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3482 if (cw->w != w || cw->h != h)
3483 e_comp_object_map_update(obj);
3485 first = ((cw->w < 1) || (cw->h < 1));
3486 cw->w = w, cw->h = h;
3487 if ((!cw->ec->shading) && (!cw->ec->shaded))
3491 if (cw->frame_object)
3492 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3495 /* verify pixmap:object size */
3496 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3498 if ((ww != pw) || (hh != ph))
3499 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3501 evas_object_resize(cw->effect_obj, tw, th);
3502 evas_object_resize(cw->default_input_obj, w, h);
3504 evas_object_resize(cw->input_obj, w, h);
3506 evas_object_resize(cw->mask.obj, w, h);
3507 /* resize render update tiler */
3510 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3511 cw->updates_full = 0;
3512 if (cw->updates) eina_tiler_clear(cw->updates);
3516 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3517 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3522 evas_object_resize(cw->effect_obj, tw, th);
3523 evas_object_resize(cw->default_input_obj, w, h);
3530 e_comp_render_queue();
3536 _e_comp_smart_init(void)
3538 if (_e_comp_smart) return;
3540 static const Evas_Smart_Class sc =
3543 EVAS_SMART_CLASS_VERSION,
3547 _e_comp_smart_resize,
3550 _e_comp_smart_color_set,
3551 _e_comp_smart_clip_set,
3552 _e_comp_smart_clip_unset,
3562 _e_comp_smart = evas_smart_class_new(&sc);
3567 e_comp_object_init(void)
3569 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3570 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3571 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3572 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3576 e_comp_object_shutdown(void)
3582 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3584 API_ENTRY EINA_FALSE;
3585 return !!cw->force_visible;
3587 /////////////////////////////////////////////////////////
3590 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3593 Eina_Bool comp_object;
3595 comp_object = !!evas_object_data_get(obj, "comp_object");
3600 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3602 e_comp_render_queue();
3604 l = evas_object_data_get(obj, "comp_object-to_del");
3605 E_FREE_LIST(l, evas_object_del);
3609 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3611 if (e_comp_util_object_is_above_nocomp(obj) &&
3612 (!evas_object_data_get(obj, "comp_override")))
3614 evas_object_data_set(obj, "comp_override", (void*)1);
3615 e_comp_override_add();
3620 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3622 Eina_Bool ref = EINA_TRUE;
3623 if (evas_object_visible_get(obj))
3627 d = evas_object_data_del(obj, "comp_hiding");
3629 /* currently trying to hide */
3632 /* already visible */
3636 evas_object_show(obj);
3639 evas_object_ref(obj);
3640 evas_object_data_set(obj, "comp_ref", (void*)1);
3642 edje_object_signal_emit(obj, "e,state,visible", "e");
3643 evas_object_data_set(obj, "comp_showing", (void*)1);
3644 if (e_comp_util_object_is_above_nocomp(obj))
3646 evas_object_data_set(obj, "comp_override", (void*)1);
3647 e_comp_override_add();
3652 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3654 if (!evas_object_visible_get(obj)) return;
3655 /* already hiding */
3656 if (evas_object_data_get(obj, "comp_hiding")) return;
3657 if (!evas_object_data_del(obj, "comp_showing"))
3659 evas_object_ref(obj);
3660 evas_object_data_set(obj, "comp_ref", (void*)1);
3662 edje_object_signal_emit(obj, "e,state,hidden", "e");
3663 evas_object_data_set(obj, "comp_hiding", (void*)1);
3665 if (evas_object_data_del(obj, "comp_override"))
3666 e_comp_override_timed_pop();
3670 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3672 if (!e_util_strcmp(emission, "e,action,hide,done"))
3674 if (!evas_object_data_del(obj, "comp_hiding")) return;
3675 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3676 evas_object_hide(obj);
3677 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3680 evas_object_data_del(obj, "comp_showing");
3681 if (evas_object_data_del(obj, "comp_ref"))
3682 evas_object_unref(obj);
3686 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3692 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3696 E_API E_Comp_Object_Hook *
3697 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3699 E_Comp_Object_Hook *ch;
3701 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3702 ch = E_NEW(E_Comp_Object_Hook, 1);
3703 if (!ch) return NULL;
3704 ch->hookpoint = hookpoint;
3706 ch->data = (void*)data;
3707 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3712 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3715 if (_e_comp_object_hooks_walking == 0)
3717 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3721 _e_comp_object_hooks_delete++;
3724 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3725 E_API E_Comp_Object_Intercept_Hook *
3726 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3728 E_Comp_Object_Intercept_Hook *ch;
3730 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3731 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3732 if (!ch) return NULL;
3733 ch->hookpoint = hookpoint;
3735 ch->data = (void*)data;
3736 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3741 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3744 if (_e_comp_object_intercept_hooks_walking == 0)
3746 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3750 _e_comp_object_intercept_hooks_delete++;
3755 e_comp_object_util_add(Evas_Object *obj)
3759 E_Comp_Config *conf = e_comp_config_get();
3760 Eina_Bool skip = EINA_FALSE;
3766 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3768 name = evas_object_name_get(obj);
3769 vis = evas_object_visible_get(obj);
3770 o = edje_object_add(e_comp->evas);
3771 evas_object_data_set(o, "comp_object", (void*)1);
3773 skip = (!strncmp(name, "noshadow", 8));
3775 evas_object_data_set(o, "comp_object_skip", (void*)1);
3777 if (conf->shadow_style)
3779 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3780 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3783 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3784 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3785 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3787 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3789 evas_object_geometry_get(obj, &x, &y, &w, &h);
3790 evas_object_geometry_set(o, x, y, w, h);
3791 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3793 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3795 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3796 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3797 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3798 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3799 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3800 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3802 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3804 edje_object_part_swallow(o, "e.swallow.content", obj);
3806 _e_comp_object_event_add(o);
3809 evas_object_show(o);
3814 /* utility functions for deleting objects when their "owner" is deleted */
3816 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3821 EINA_SAFETY_ON_NULL_RETURN(to_del);
3822 l = evas_object_data_get(obj, "comp_object-to_del");
3823 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3824 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3825 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3829 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3834 EINA_SAFETY_ON_NULL_RETURN(to_del);
3835 l = evas_object_data_get(obj, "comp_object-to_del");
3837 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3840 /////////////////////////////////////////////////////////
3842 EINTERN Evas_Object *
3843 e_comp_object_client_add(E_Client *ec)
3848 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3849 if (ec->frame) return NULL;
3850 _e_comp_smart_init();
3851 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3852 cw = evas_object_smart_data_get(o);
3853 if (!cw) return NULL;
3854 evas_object_data_set(o, "E_Client", ec);
3857 evas_object_data_set(o, "comp_object", (void*)1);
3859 _e_comp_object_event_add(o);
3864 /* utility functions for getting client inset */
3866 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3869 if (!cw->client_inset.calc)
3875 if (ax) *ax = x - cw->client_inset.l;
3876 if (ay) *ay = y - cw->client_inset.t;
3880 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3883 if (!cw->client_inset.calc)
3889 if (ax) *ax = x + cw->client_inset.l;
3890 if (ay) *ay = y + cw->client_inset.t;
3894 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3897 if (!cw->client_inset.calc)
3903 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3904 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3908 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3911 if (!cw->client_inset.calc)
3917 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3918 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3922 e_comp_object_client_get(Evas_Object *obj)
3927 /* FIXME: remove this when eo is used */
3928 o = evas_object_data_get(obj, "comp_smart_obj");
3930 return e_comp_object_client_get(o);
3931 return cw ? cw->ec : NULL;
3935 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3938 if (cw->frame_extends)
3939 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3944 if (w) *w = cw->ec->w;
3945 if (h) *h = cw->ec->h;
3950 e_comp_object_util_zone_get(Evas_Object *obj)
3952 E_Zone *zone = NULL;
3956 zone = e_comp_zone_find_by_ec(cw->ec);
3961 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3962 zone = e_comp_zone_xy_get(x, y);
3968 e_comp_object_util_center(Evas_Object *obj)
3970 int x, y, w, h, ow, oh;
3975 zone = e_comp_object_util_zone_get(obj);
3976 EINA_SAFETY_ON_NULL_RETURN(zone);
3977 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3978 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3979 ow = cw->ec->w, oh = cw->ec->h;
3981 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3982 x = x + (w - ow) / 2;
3983 y = y + (h - oh) / 2;
3984 evas_object_move(obj, x, y);
3988 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3990 int x, y, w, h, ow, oh;
3993 EINA_SAFETY_ON_NULL_RETURN(on);
3994 evas_object_geometry_get(on, &x, &y, &w, &h);
3995 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3996 ow = cw->ec->w, oh = cw->ec->h;
3998 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3999 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
4003 e_comp_object_util_fullscreen(Evas_Object *obj)
4008 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4011 evas_object_move(obj, 0, 0);
4012 evas_object_resize(obj, e_comp->w, e_comp->h);
4017 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4025 ow = cw->w, oh = cw->h;
4027 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4028 zone = e_comp_object_util_zone_get(obj);
4029 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4030 if (x) *x = zx + (zw - ow) / 2;
4031 if (y) *y = zy + (zh - oh) / 2;
4035 e_comp_object_input_objs_del(Evas_Object *obj)
4038 E_Input_Rect_Data *input_rect_data;
4039 E_Input_Rect_Smart_Data *input_rect_sd;
4044 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4045 if (!input_rect_sd) return;
4047 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4049 if (input_rect_data->obj)
4051 evas_object_smart_member_del(input_rect_data->obj);
4052 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4054 E_FREE(input_rect_data);
4059 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4062 E_Input_Rect_Data *input_rect_data = NULL;
4063 E_Input_Rect_Smart_Data *input_rect_sd;
4064 int client_w, client_h;
4066 if (cw->ec->client.w)
4067 client_w = cw->ec->client.w;
4069 client_w = cw->ec->w;
4071 if (cw->ec->client.h)
4072 client_h = cw->ec->client.h;
4074 client_h = cw->ec->h;
4076 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4080 _e_comp_input_obj_smart_init();
4081 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4082 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4083 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4086 input_rect_sd->cw = cw;
4089 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4092 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4093 if (input_rect_data)
4095 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4096 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4100 if ((input_rect_data) &&
4101 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4103 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4104 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4105 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4106 evas_object_clip_set(input_rect_data->obj, cw->clip);
4107 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4108 evas_object_geometry_set(input_rect_data->obj,
4109 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4110 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4111 evas_object_pass_events_set(cw->default_input_obj, 1);
4112 evas_object_pass_events_set(cw->obj, 1);
4115 evas_object_show(input_rect_data->obj);
4116 evas_object_show(cw->input_obj);
4121 evas_object_smart_member_del(cw->input_obj);
4122 E_FREE_FUNC(cw->input_obj, evas_object_del);
4123 evas_object_pass_events_set(cw->default_input_obj, 0);
4124 evas_object_pass_events_set(cw->obj, 0);
4129 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4132 E_Input_Rect_Smart_Data *input_rect_sd;
4133 E_Input_Rect_Data *input_rect_data;
4136 if (!cw->input_obj) return;
4138 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4141 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4143 *list = eina_list_append(*list, &input_rect_data->rect);
4149 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4152 if (l) *l = cw->client_inset.l;
4153 if (r) *r = cw->client_inset.r;
4154 if (t) *t = cw->client_inset.t;
4155 if (b) *b = cw->client_inset.b;
4158 /* set geometry for CSD */
4160 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4166 if (cw->frame_object)
4167 CRI("ACK! ec:%p", cw->ec);
4168 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4169 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4170 calc = cw->client_inset.calc;
4171 cw->client_inset.calc = l || r || t || b;
4172 eina_stringshare_replace(&cw->frame_theme, "borderless");
4173 if (cw->client_inset.calc)
4175 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4176 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4177 e_client_size_set(cw->ec, tw, th);
4179 else if (cw->ec->maximized || cw->ec->fullscreen)
4181 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4182 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4184 if (!cw->ec->new_client)
4186 if (calc && cw->client_inset.calc)
4188 tx = cw->ec->x - (l - cw->client_inset.l);
4189 ty = cw->ec->y - (t - cw->client_inset.t);
4190 e_client_pos_set(cw->ec, tx, ty);
4192 cw->ec->changes.pos = cw->ec->changes.size = 1;
4195 cw->client_inset.l = l;
4196 cw->client_inset.r = r;
4197 cw->client_inset.t = t;
4198 cw->client_inset.b = b;
4202 e_comp_object_frame_allowed(Evas_Object *obj)
4204 API_ENTRY EINA_FALSE;
4205 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4209 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4211 API_ENTRY EINA_FALSE;
4212 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4213 eina_stringshare_replace(&cw->frame_name, name);
4214 if (cw->frame_object)
4215 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4220 e_comp_object_frame_exists(Evas_Object *obj)
4222 API_ENTRY EINA_FALSE;
4223 return !!cw->frame_object;
4227 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4229 Evas_Object *o, *pbg;
4232 Eina_Stringshare *theme;
4234 API_ENTRY EINA_FALSE;
4236 if (!e_util_strcmp(cw->frame_theme, name))
4237 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4238 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4239 return _e_comp_object_shadow_setup(cw);
4240 pbg = cw->frame_object;
4241 theme = eina_stringshare_add(name);
4243 if (cw->frame_object)
4247 w = cw->ec->w, h = cw->ec->h;
4248 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4249 if ((cw->ec->w != w) || (cw->ec->h != h))
4251 cw->ec->changes.size = 1;
4254 E_FREE_FUNC(cw->frame_object, evas_object_del);
4255 if (!name) goto reshadow;
4257 o = edje_object_add(e_comp->evas);
4258 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4259 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4260 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4262 cw->frame_object = NULL;
4264 eina_stringshare_del(cw->frame_theme);
4265 cw->frame_theme = theme;
4270 if (theme != e_config->theme_default_border_style)
4272 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4273 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4277 ok = e_theme_edje_object_set(o, "base/theme/border",
4278 "e/widgets/border/default/border");
4279 if (ok && (theme == e_config->theme_default_border_style))
4281 /* Reset default border style to default */
4282 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4283 e_config_save_queue();
4290 cw->frame_object = o;
4291 eina_stringshare_del(cw->frame_theme);
4292 cw->frame_theme = theme;
4293 evas_object_name_set(o, "cw->frame_object");
4296 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4300 cw->ec->changes.icon = 1;
4306 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4311 _e_comp_object_shadow_setup(cw);
4314 int old_x, old_y, new_x = 0, new_y = 0;
4316 old_x = cw->x, old_y = cw->y;
4318 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4320 new_x = cw->ec->x, new_y = cw->ec->y;
4321 else if (cw->ec->placed || (!cw->ec->new_client))
4323 /* if no previous frame:
4324 * - reapply client_inset
4329 if (cw->ec->changes.size)
4337 zone = e_comp_zone_find_by_ec(cw->ec);
4340 x = cw->ec->client.x, y = cw->ec->client.y;
4341 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4342 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4344 new_x = x, new_y = y;
4347 if (old_x != new_x || old_y != new_y)
4349 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4350 cw->y = cw->x = -99999;
4351 evas_object_move(obj, new_x, new_y);
4355 if (cw->ec->maximized)
4357 cw->ec->changes.need_maximize = 1;
4360 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4361 if (cw->frame_object)
4363 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4366 cw->frame_extends = 0;
4367 evas_object_del(pbg);
4372 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4374 E_Comp_Object_Mover *prov;
4377 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4378 edje_object_signal_emit(cw->shobj, sig, src);
4379 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4380 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4381 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4383 /* start with highest priority callback first */
4384 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4386 if (!e_util_glob_match(sig, prov->sig)) continue;
4387 if (prov->func(prov->data, obj, sig)) break;
4392 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4394 /* FIXME: at some point I guess this should use eo to inherit
4395 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4396 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4399 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4403 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4406 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4410 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4413 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4417 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4420 Eina_Rectangle rect;
4423 if (cw->ec->input_only || (!cw->updates)) return;
4424 if (cw->nocomp) return;
4425 rect.x = x, rect.y = y;
4426 rect.w = w, rect.h = h;
4427 evas_object_smart_callback_call(obj, "damage", &rect);
4429 if (e_comp_is_on_overlay(cw->ec))
4431 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4432 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4433 * E module attempts to block screen update due to the particular policy.
4435 if (e_pixmap_resource_get(cw->ec->pixmap))
4436 cw->hwc_need_update = EINA_TRUE;
4439 /* ignore overdraw */
4440 if (cw->updates_full)
4442 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4443 e_comp_object_render_update_add(obj);
4445 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4446 evas_object_show(cw->smart_obj);
4450 /* clip rect to client surface */
4451 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4452 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4453 /* if rect is the total size of the client after clip, clear the updates
4454 * since this is guaranteed to be the whole region anyway
4456 eina_tiler_area_size_get(cw->updates, &tw, &th);
4457 if ((w > tw) || (h > th))
4459 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4460 eina_tiler_clear(cw->updates);
4461 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4463 tw = cw->ec->client.w, th = cw->ec->client.h;
4465 if ((!x) && (!y) && (w == tw) && (h == th))
4467 eina_tiler_clear(cw->updates);
4468 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4469 cw->updates_full = 1;
4470 cw->update_count = 0;
4473 if (cw->update_count > UPDATE_MAX)
4475 /* this is going to get really dumb, so just update the whole thing */
4476 eina_tiler_clear(cw->updates);
4477 cw->update_count = cw->updates_full = 1;
4478 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4479 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4483 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4484 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4486 cw->updates_exist = 1;
4487 e_comp_object_render_update_add(obj);
4489 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4490 evas_object_show(cw->smart_obj);
4494 e_comp_object_damage_exists(Evas_Object *obj)
4496 API_ENTRY EINA_FALSE;
4497 return cw->updates_exist;
4501 e_comp_object_render_update_add(Evas_Object *obj)
4505 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4506 if (cw->render_update_lock.lock) return;
4507 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4511 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4513 e_comp_render_queue();
4517 e_comp_object_render_update_del(Evas_Object *obj)
4521 if (cw->ec->input_only || (!cw->updates)) return;
4522 if (!cw->update) return;
4524 /* this gets called during comp animating to clear the update flag */
4525 if (e_comp->grabbed) return;
4526 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4527 if (!e_comp->updates)
4529 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4530 if (e_comp->render_animator)
4531 ecore_animator_freeze(e_comp->render_animator);
4536 e_comp_object_shape_apply(Evas_Object *obj)
4540 unsigned int i, *pix, *p;
4544 if (!cw->ec) return; //NYI
4545 if (cw->external_content) return;
4548 if ((cw->ec->shape_rects_num >= 1) &&
4549 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4554 ERR("BUGGER: shape with native surface? cw=%p", cw);
4557 evas_object_image_size_get(cw->obj, &w, &h);
4558 if ((w < 1) || (h < 1)) return;
4561 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4562 _e_comp_object_alpha_set(cw);
4563 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4564 evas_object_image_alpha_set(o, 1);
4566 p = pix = evas_object_image_data_get(cw->obj, 1);
4569 evas_object_image_data_set(cw->obj, pix);
4574 unsigned char *spix, *sp;
4576 spix = calloc(w * h, sizeof(unsigned char));
4578 for (i = 0; i < cw->ec->shape_rects_num; i++)
4582 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4583 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4584 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4585 sp = spix + (w * ry) + rx;
4586 for (py = 0; py < rh; py++)
4588 for (px = 0; px < rw; px++)
4596 for (py = 0; py < h; py++)
4598 for (px = 0; px < w; px++)
4600 unsigned int mask, imask;
4602 mask = ((unsigned int)(*sp)) << 24;
4604 imask |= imask >> 8;
4605 imask |= imask >> 8;
4606 *p = mask | (*p & imask);
4607 //if (*sp) *p = 0xff000000 | *p;
4608 //else *p = 0x00000000;
4617 for (py = 0; py < h; py++)
4619 for (px = 0; px < w; px++)
4623 evas_object_image_data_set(cw->obj, pix);
4624 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4625 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4627 evas_object_image_data_set(o, pix);
4628 evas_object_image_data_update_add(o, 0, 0, w, h);
4630 // don't need to fix alpha chanel as blending
4631 // should be totally off here regardless of
4632 // alpha channel content
4636 _e_comp_object_clear(E_Comp_Object *cw)
4641 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4643 if (cw->render_update_lock.lock) return;
4646 e_pixmap_clear(cw->ec->pixmap);
4648 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4649 evas_object_image_size_set(cw->obj, 1, 1);
4650 evas_object_image_data_set(cw->obj, NULL);
4651 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4653 evas_object_image_size_set(o, 1, 1);
4654 evas_object_image_data_set(o, NULL);
4657 e_comp_object_render_update_del(cw->smart_obj);
4661 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4665 API_ENTRY EINA_FALSE;
4667 if (cw->transparent.set == set)
4672 evas_object_color_get(obj, &r, &g, &b, &a);
4673 evas_object_color_set(obj, 0, 0, 0, 0);
4675 cw->transparent.user_r = r;
4676 cw->transparent.user_g = g;
4677 cw->transparent.user_b = b;
4678 cw->transparent.user_a = a;
4680 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4682 cw->transparent.user_r,
4683 cw->transparent.user_g,
4684 cw->transparent.user_b,
4685 cw->transparent.user_a);
4687 cw->transparent.set = EINA_TRUE;
4691 cw->transparent.set = EINA_FALSE;
4693 evas_object_color_set(obj,
4694 cw->transparent.user_r,
4695 cw->transparent.user_g,
4696 cw->transparent.user_b,
4697 cw->transparent.user_a);
4699 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4701 cw->transparent.user_r,
4702 cw->transparent.user_g,
4703 cw->transparent.user_b,
4704 cw->transparent.user_a);
4710 /* helper function to simplify toggling of redirection for display servers which support it */
4712 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4717 if (cw->redirected == set) return;
4718 cw->redirected = set;
4719 if (cw->external_content) return;
4721 e_comp_object_map_update(obj);
4725 if (cw->updates_exist)
4726 e_comp_object_render_update_add(obj);
4728 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4730 _e_comp_object_transparent_set(obj, EINA_FALSE);
4731 evas_object_smart_callback_call(obj, "redirected", NULL);
4735 _e_comp_object_clear(cw);
4736 _e_comp_object_transparent_set(obj, EINA_TRUE);
4737 evas_object_smart_callback_call(obj, "unredirected", NULL);
4742 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4745 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4747 if (cw->buffer_destroy_listener.notify)
4749 cw->buffer_destroy_listener.notify = NULL;
4750 wl_list_remove(&cw->buffer_destroy_listener.link);
4753 if (e_object_is_del(E_OBJECT(cw->ec)))
4755 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4760 /* if it's current displaying buffer, do not remove its content */
4761 if (!evas_object_visible_get(cw->ec->frame))
4762 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4767 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4772 if (cw->buffer_destroy_listener.notify)
4774 wl_list_remove(&cw->buffer_destroy_listener.link);
4775 cw->buffer_destroy_listener.notify = NULL;
4778 if (cw->tbm_surface)
4780 tbm_surface_internal_unref(cw->tbm_surface);
4781 cw->tbm_surface = NULL;
4786 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4788 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4789 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4791 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4793 tbm_surface_internal_ref(ns->data.tbm.buffer);
4794 cw->tbm_surface = ns->data.tbm.buffer;
4798 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4799 evas_object_image_native_surface_set(cw->obj, ns);
4803 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4805 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4806 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4807 evas_object_image_native_surface_set(o, ns);
4814 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4816 Evas_Native_Surface ns;
4819 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4820 if (cw->ec->input_only) return;
4821 if (cw->external_content) return;
4822 if (cw->render_update_lock.lock) return;
4825 memset(&ns, 0, sizeof(Evas_Native_Surface));
4829 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4830 set = (!cw->ec->shaped);
4832 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4836 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4840 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4843 if (cw->ec->input_only) return;
4846 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4847 _e_comp_object_alpha_set(cw);
4849 e_comp_object_native_surface_set(obj, cw->native);
4850 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4854 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4860 if (cw->blanked == set) return;
4862 _e_comp_object_alpha_set(cw);
4865 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4866 evas_object_image_data_set(cw->obj, NULL);
4870 e_comp_object_native_surface_set(obj, 1);
4871 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4875 _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)
4880 if (!_damage_trace) return;
4884 if (!evas_object_visible_get(cw->obj)) return;
4886 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4888 o = evas_object_rectangle_add(e_comp->evas);
4889 evas_object_layer_set(o, E_LAYER_MAX);
4890 evas_object_name_set(o, "damage_trace");
4891 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4892 evas_object_resize(o, dmg_w, dmg_h);
4893 evas_object_color_set(o, 0, 128, 0, 128);
4894 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4895 evas_object_pass_events_set(o, EINA_TRUE);
4896 evas_object_show(o);
4898 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4900 dmg_w, dmg_h, dmg_x, dmg_y,
4901 origin->w, origin->h, origin->x, origin->y);
4903 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4906 /* mark an object as dirty and setup damages */
4908 e_comp_object_dirty(Evas_Object *obj)
4911 Eina_Rectangle *rect;
4915 Eina_Bool dirty, visible;
4919 if (cw->external_content) return;
4920 if (!cw->redirected) return;
4921 if (cw->render_update_lock.lock)
4923 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4926 /* only actually dirty if pixmap is available */
4927 if (!e_pixmap_resource_get(cw->ec->pixmap))
4929 // e_pixmap_size_get returns last attached buffer size
4930 // eventhough it is destroyed
4931 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4934 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4935 visible = cw->visible;
4936 if (!dirty) w = h = 1;
4937 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4939 evas_object_image_data_set(cw->obj, NULL);
4940 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4941 evas_object_image_size_set(cw->obj, tw, th);
4942 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4943 if (cw->pending_updates)
4944 eina_tiler_area_size_set(cw->pending_updates, w, h);
4945 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4947 evas_object_image_pixels_dirty_set(o, dirty);
4949 evas_object_image_data_set(o, NULL);
4950 evas_object_image_size_set(o, tw, th);
4951 visible |= evas_object_visible_get(o);
4955 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4959 e_comp_object_native_surface_set(obj, 1);
4961 m = _e_comp_object_map_damage_transform_get(cw->ec);
4962 it = eina_tiler_iterator_new(cw->updates);
4963 EINA_ITERATOR_FOREACH(it, rect)
4965 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4966 * of evas engine and doesn't convert damage according to evas_map.
4967 * so damage of evas_object_image use surface coordinate.
4971 int damage_x, damage_y, damage_w, damage_h;
4973 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4974 &damage_x, &damage_y, &damage_w, &damage_h);
4975 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4976 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4980 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4981 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4984 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4985 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4986 if (cw->pending_updates)
4987 eina_tiler_rect_add(cw->pending_updates, rect);
4989 eina_iterator_free(it);
4990 if (m) e_map_free(m);
4991 if (cw->pending_updates)
4992 eina_tiler_clear(cw->updates);
4995 cw->pending_updates = cw->updates;
4996 cw->updates = eina_tiler_new(w, h);
4997 eina_tiler_tile_size_set(cw->updates, 1, 1);
4999 cw->update_count = cw->updates_full = cw->updates_exist = 0;
5000 evas_object_smart_callback_call(obj, "dirty", NULL);
5001 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
5002 /* force render if main object is hidden but mirrors are visible */
5003 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
5004 e_comp_object_render(obj);
5008 e_comp_object_render(Evas_Object *obj)
5015 API_ENTRY EINA_FALSE;
5017 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5018 if (cw->ec->input_only) return EINA_TRUE;
5019 if (cw->external_content) return EINA_TRUE;
5020 if (cw->native) return EINA_FALSE;
5021 /* if comp object is not redirected state, comp object should not be set by newly committed data
5022 because image size of comp object is 1x1 and it should not be shown on canvas */
5023 if (!cw->redirected) return EINA_TRUE;
5024 if (cw->render_update_lock.lock)
5026 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5029 e_comp_object_render_update_del(obj);
5030 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5032 if (!cw->pending_updates)
5034 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5035 evas_object_image_data_set(cw->obj, NULL);
5036 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5037 evas_object_image_data_set(o, NULL);
5041 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5043 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5045 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5048 e_pixmap_image_refresh(cw->ec->pixmap);
5049 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5052 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5053 e_pixmap_image_data_ref(cw->ec->pixmap);
5055 /* set pixel data */
5056 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5057 _e_comp_object_alpha_set(cw);
5058 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5060 evas_object_image_data_set(o, pix);
5061 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5062 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5065 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5067 e_comp_client_post_update_add(cw->ec);
5072 /* create a duplicate of an evas object */
5074 e_comp_object_util_mirror_add(Evas_Object *obj)
5078 unsigned int *pix = NULL;
5079 Eina_Bool argb = EINA_FALSE;
5084 cw = evas_object_data_get(obj, "comp_mirror");
5087 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5088 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5089 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5090 evas_object_image_alpha_set(o, 1);
5091 evas_object_image_source_set(o, obj);
5094 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5095 if (cw->external_content)
5097 ERR("%p of client %p is external content.", obj, cw->ec);
5100 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5101 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5102 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5103 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5104 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5105 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5106 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5107 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5108 evas_object_data_set(o, "comp_mirror", cw);
5110 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5111 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5113 evas_object_image_size_set(o, tw, th);
5116 pix = evas_object_image_data_get(cw->obj, 0);
5122 evas_object_image_native_surface_set(o, cw->ns);
5125 Evas_Native_Surface ns;
5126 memset(&ns, 0, sizeof(Evas_Native_Surface));
5127 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5128 evas_object_image_native_surface_set(o, &ns);
5133 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5134 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5136 (e_pixmap_image_exists(cw->ec->pixmap)))
5137 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5139 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5146 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5147 evas_object_image_pixels_dirty_set(o, dirty);
5148 evas_object_image_data_set(o, pix);
5149 evas_object_image_data_set(cw->obj, pix);
5151 evas_object_image_data_update_add(o, 0, 0, tw, th);
5156 //////////////////////////////////////////////////////
5159 e_comp_object_effect_allowed_get(Evas_Object *obj)
5161 API_ENTRY EINA_FALSE;
5163 if (!cw->shobj) return EINA_FALSE;
5164 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5165 return !e_comp_config_get()->match.disable_borders;
5168 /* setup an api effect for a client */
5170 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5173 Eina_Stringshare *grp;
5174 E_Comp_Config *config;
5175 Eina_Bool loaded = EINA_FALSE;
5177 API_ENTRY EINA_FALSE;
5178 if (!cw->shobj) return EINA_FALSE; //input window
5180 if (!effect) effect = "none";
5181 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5183 config = e_comp_config_get();
5184 if ((config) && (config->effect_file))
5186 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5188 cw->effect_set = EINA_TRUE;
5195 edje_object_file_get(cw->effect_obj, NULL, &grp);
5196 cw->effect_set = !eina_streq(effect, "none");
5197 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5198 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5200 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5201 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5202 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5204 if (cw->effect_running)
5206 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5209 cw->effect_set = EINA_FALSE;
5210 return cw->effect_set;
5214 if (cw->effect_running)
5216 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5219 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5220 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5221 if (cw->effect_clip)
5223 evas_object_clip_unset(cw->clip);
5224 cw->effect_clip = 0;
5226 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5228 _e_comp_object_dim_update(cw);
5230 return cw->effect_set;
5233 /* set params for embryo scripts in effect */
5235 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5237 Edje_Message_Int_Set *msg;
5241 EINA_SAFETY_ON_NULL_RETURN(params);
5242 EINA_SAFETY_ON_FALSE_RETURN(count);
5243 if (!cw->effect_set) return;
5245 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5246 msg->count = (int)count;
5247 for (x = 0; x < count; x++)
5248 msg->val[x] = params[x];
5249 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5250 edje_object_message_signal_process(cw->effect_obj);
5254 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5256 Edje_Signal_Cb end_cb;
5258 E_Comp_Object *cw = data;
5260 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5261 cw->effect_running = 0;
5262 if (!_e_comp_object_animating_end(cw)) return;
5264 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5266 evas_object_data_del(cw->smart_obj, "effect_running");
5267 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5268 e_comp_visibility_calculation_set(EINA_TRUE);
5271 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5272 if (!end_cb) return;
5273 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5274 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5275 end_cb(end_data, cw->smart_obj, emission, source);
5278 /* clip effect to client's zone */
5280 e_comp_object_effect_clip(Evas_Object *obj)
5284 zone = e_comp_zone_find_by_ec(cw->ec);
5286 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5287 if (!cw->effect_clip_able) return;
5288 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5289 cw->effect_clip = 1;
5292 /* unclip effect from client's zone */
5294 e_comp_object_effect_unclip(Evas_Object *obj)
5297 if (!cw->effect_clip) return;
5298 evas_object_clip_unset(cw->smart_obj);
5299 cw->effect_clip = 0;
5302 /* start effect, running end_cb after */
5304 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5306 API_ENTRY EINA_FALSE;
5307 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5308 if (!cw->effect_set) return EINA_FALSE;
5310 if (cw->effect_running)
5312 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5315 e_comp_object_effect_clip(obj);
5316 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5318 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5319 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5320 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5321 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5323 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5324 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5326 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5327 _e_comp_object_animating_begin(cw);
5328 cw->effect_running = 1;
5332 /* stop a currently-running effect immediately */
5334 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5337 Edje_Signal_Cb end_cb_before = NULL;
5338 void *end_data_before = NULL;
5339 API_ENTRY EINA_FALSE;
5341 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5342 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5344 if (end_cb_before != end_cb) return EINA_TRUE;
5345 e_comp_object_effect_unclip(obj);
5346 if (cw->effect_clip)
5348 evas_object_clip_unset(cw->effect_obj);
5349 cw->effect_clip = 0;
5351 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5352 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5354 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5356 evas_object_data_del(cw->smart_obj, "effect_running");
5357 e_comp_visibility_calculation_set(EINA_TRUE);
5360 cw->effect_running = 0;
5361 ret = _e_comp_object_animating_end(cw);
5363 if ((ret) && (end_cb_before))
5365 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5366 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5373 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5375 return a->pri - b->pri;
5378 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5379 E_API E_Comp_Object_Mover *
5380 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5382 E_Comp_Object_Mover *prov;
5384 prov = E_NEW(E_Comp_Object_Mover, 1);
5385 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5386 prov->func = provider;
5387 prov->data = (void*)data;
5390 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5391 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5396 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5398 EINA_SAFETY_ON_NULL_RETURN(prov);
5399 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5404 e_comp_object_effect_object_get(Evas_Object *obj)
5408 return cw->effect_obj;
5412 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5414 API_ENTRY EINA_FALSE;
5415 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5416 if (!cw->effect_set) return EINA_FALSE;
5423 ////////////////////////////////////
5426 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5428 if (e_comp->autoclose.obj)
5430 e_comp_ungrab_input(0, 1);
5431 if (e_comp->autoclose.del_cb)
5432 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5433 else if (!already_del)
5435 evas_object_hide(e_comp->autoclose.obj);
5436 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5438 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5440 e_comp->autoclose.obj = NULL;
5441 e_comp->autoclose.data = NULL;
5442 e_comp->autoclose.del_cb = NULL;
5443 e_comp->autoclose.key_cb = NULL;
5444 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5448 _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)
5450 _e_comp_object_autoclose_cleanup(0);
5454 _e_comp_object_autoclose_setup(Evas_Object *obj)
5456 if (!e_comp->autoclose.rect)
5458 /* create rect just below autoclose object to catch mouse events */
5459 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5460 evas_object_move(e_comp->autoclose.rect, 0, 0);
5461 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5462 evas_object_show(e_comp->autoclose.rect);
5463 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5464 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5465 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5466 e_comp_grab_input(0, 1);
5468 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5469 evas_object_focus_set(obj, 1);
5473 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5475 _e_comp_object_autoclose_setup(obj);
5476 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5480 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5482 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5483 _e_comp_object_autoclose_cleanup(1);
5484 if (e_client_focused_get()) return;
5485 if (e_config->focus_policy != E_FOCUS_MOUSE)
5490 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5494 if (e_comp->autoclose.obj)
5496 if (e_comp->autoclose.obj == obj) return;
5497 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5498 e_comp->autoclose.obj = obj;
5499 e_comp->autoclose.del_cb = del_cb;
5500 e_comp->autoclose.key_cb = cb;
5501 e_comp->autoclose.data = (void*)data;
5502 if (evas_object_visible_get(obj))
5503 _e_comp_object_autoclose_setup(obj);
5505 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5506 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5509 e_comp->autoclose.obj = obj;
5510 e_comp->autoclose.del_cb = del_cb;
5511 e_comp->autoclose.key_cb = cb;
5512 e_comp->autoclose.data = (void*)data;
5513 if (evas_object_visible_get(obj))
5514 _e_comp_object_autoclose_setup(obj);
5516 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5517 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5521 e_comp_object_is_animating(Evas_Object *obj)
5525 return cw->animating;
5529 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5533 if ((cw->external_content) &&
5534 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5536 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5537 "But current external content is %d object for %p.",
5538 cw->content_type, cw->ec);
5542 cw->user_alpha_set = EINA_TRUE;
5543 cw->user_alpha = alpha;
5545 if (!cw->obj) return;
5547 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5549 evas_object_image_alpha_set(cw->obj, alpha);
5551 if ((!cw->native) && (!cw->external_content))
5552 evas_object_image_data_set(cw->obj, NULL);
5556 e_comp_object_alpha_get(Evas_Object *obj)
5558 API_ENTRY EINA_FALSE;
5560 return evas_object_image_alpha_get(cw->obj);
5564 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5566 Eina_Bool mask_set = EINA_FALSE;
5570 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5571 if (cw->ec->input_only) return;
5578 o = evas_object_rectangle_add(e_comp->evas);
5579 evas_object_color_set(o, 0, 0, 0, 0);
5580 evas_object_clip_set(o, cw->clip);
5581 evas_object_smart_member_add(o, obj);
5582 evas_object_move(o, 0, 0);
5583 evas_object_resize(o, cw->w, cw->h);
5584 /* save render op value to restore when clear a mask.
5586 * NOTE: DO NOT change the render op on ec->frame while mask object
5587 * is set. it will overwrite the changed op value. */
5588 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5589 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5590 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5591 if (cw->visible) evas_object_show(o);
5594 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5595 ELOGF("COMP", " |mask_obj", cw->ec);
5596 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5603 evas_object_smart_member_del(cw->mask.obj);
5604 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5606 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5607 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5613 e_comp_object_mask_has(Evas_Object *obj)
5615 API_ENTRY EINA_FALSE;
5617 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5621 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5626 if ((cw->external_content) &&
5627 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5629 WRN("Can set up size to ONLY evas \"image\" object. "
5630 "But current external content is %d object for %p.",
5631 cw->content_type, cw->ec);
5635 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5637 evas_object_image_size_set(cw->obj, tw, th);
5641 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5643 Eina_Bool transform_set = EINA_FALSE;
5645 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5646 if (cw->ec->input_only) return;
5648 transform_set = !!set;
5652 if (!cw->transform_bg_obj)
5654 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5655 evas_object_move(o, 0, 0);
5656 evas_object_resize(o, 1, 1);
5657 if (cw->transform_bg_color.a >= 255)
5658 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5660 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5661 evas_object_color_set(o,
5662 cw->transform_bg_color.r,
5663 cw->transform_bg_color.g,
5664 cw->transform_bg_color.b,
5665 cw->transform_bg_color.a);
5666 if (cw->visible) evas_object_show(o);
5668 cw->transform_bg_obj = o;
5669 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5671 _e_comp_object_transform_obj_stack_update(obj);
5675 if (cw->transform_bg_obj)
5677 evas_object_smart_member_del(cw->transform_bg_obj);
5678 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5684 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5688 cw->transform_bg_color.r = r;
5689 cw->transform_bg_color.g = g;
5690 cw->transform_bg_color.b = b;
5691 cw->transform_bg_color.a = a;
5693 if (cw->transform_bg_obj)
5695 evas_object_color_set(cw->transform_bg_obj,
5696 cw->transform_bg_color.r,
5697 cw->transform_bg_color.g,
5698 cw->transform_bg_color.b,
5699 cw->transform_bg_color.a);
5704 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5707 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5708 if (cw->ec->input_only) return;
5709 if (!cw->transform_bg_obj) return;
5711 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5715 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5718 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5719 if (cw->ec->input_only) return;
5720 if (!cw->transform_bg_obj) return;
5722 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5726 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5728 Eina_Bool transform_set = EINA_FALSE;
5730 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5731 if (cw->ec->input_only) return;
5733 transform_set = !!set;
5737 if (!cw->transform_tranp_obj)
5739 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5740 evas_object_move(o, 0, 0);
5741 evas_object_resize(o, 1, 1);
5742 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5743 evas_object_color_set(o, 0, 0, 0, 0);
5744 if (cw->visible) evas_object_show(o);
5746 cw->transform_tranp_obj = o;
5747 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5749 _e_comp_object_transform_obj_stack_update(obj);
5753 if (cw->transform_tranp_obj)
5755 evas_object_smart_member_del(cw->transform_tranp_obj);
5756 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5762 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5765 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5766 if (cw->ec->input_only) return;
5767 if (!cw->transform_tranp_obj) return;
5769 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5773 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5776 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5777 if (cw->ec->input_only) return;
5778 if (!cw->transform_tranp_obj) return;
5780 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5784 e_comp_object_layer_update(Evas_Object *obj,
5785 Evas_Object *above, Evas_Object *below)
5787 E_Comp_Object *cw2 = NULL;
5788 Evas_Object *o = NULL;
5793 if (cw->ec->layer_block) return;
5794 if ((above) && (below))
5796 ERR("Invalid layer update request! cw=%p", cw);
5804 layer = evas_object_layer_get(o);
5805 cw2 = evas_object_data_get(o, "comp_obj");
5808 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5810 o = evas_object_above_get(o);
5811 if ((!o) || (o == cw->smart_obj)) break;
5812 if (evas_object_layer_get(o) != layer)
5814 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5819 ec = e_client_top_get();
5820 if (ec) o = ec->frame;
5823 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5827 _e_comp_object_layers_remove(cw);
5830 if (cw2->layer > cw->layer)
5831 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5832 else if (cw2->layer == cw->layer)
5835 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5837 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5839 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5842 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5845 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5849 e_comp_object_layer_get(Evas_Object *obj)
5856 e_comp_object_content_set(Evas_Object *obj,
5857 Evas_Object *content,
5858 E_Comp_Object_Content_Type type)
5860 API_ENTRY EINA_FALSE;
5862 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5863 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5864 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5868 ERR("Can't set e.swallow.content to requested content. "
5869 "Previous comp object should not be changed at all.");
5873 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5875 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5876 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5878 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5879 type, content, cw->ec, cw->ec->pixmap);
5883 cw->external_content = EINA_TRUE;
5886 cw->content_type = type;
5887 e_util_size_debug_set(cw->obj, 1);
5888 evas_object_name_set(cw->obj, "cw->obj");
5889 _e_comp_object_alpha_set(cw);
5892 _e_comp_object_shadow_setup(cw);
5898 e_comp_object_content_unset(Evas_Object *obj)
5900 API_ENTRY EINA_FALSE;
5902 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5903 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5905 if (!cw->obj && !cw->ec->visible)
5907 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5911 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5913 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5919 if (cw->frame_object)
5920 edje_object_part_unswallow(cw->frame_object, cw->obj);
5922 edje_object_part_unswallow(cw->shobj, cw->obj);
5924 evas_object_del(cw->obj);
5925 evas_object_hide(cw->obj);
5929 cw->external_content = EINA_FALSE;
5930 if (cw->ec->is_cursor)
5933 DBG("%p is cursor surface..", cw->ec);
5934 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5936 evas_object_resize(cw->ec->frame, pw, ph);
5937 evas_object_hide(cw->ec->frame);
5942 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5943 cw->obj = evas_object_image_filled_add(e_comp->evas);
5944 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5945 e_util_size_debug_set(cw->obj, 1);
5946 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5947 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5948 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5949 evas_object_name_set(cw->obj, "cw->obj");
5950 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5951 _e_comp_object_alpha_set(cw);
5954 _e_comp_object_shadow_setup(cw);
5959 _e_comp_intercept_show_helper(cw);
5963 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5964 e_comp_object_dirty(cw->smart_obj);
5965 e_comp_object_render(cw->smart_obj);
5966 e_comp_object_render_update_add(obj);
5971 EINTERN Evas_Object *
5972 e_comp_object_content_get(Evas_Object *obj)
5976 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5978 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5980 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5987 E_API E_Comp_Object_Content_Type
5988 e_comp_object_content_type_get(Evas_Object *obj)
5990 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5992 return cw->content_type;
5996 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5999 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6000 E_Comp_Config *conf = e_comp_config_get();
6001 if (cw->ec->input_only) return;
6002 if (!conf->dim_rect_enable) return;
6004 cw->dim.mask_set = mask_set;
6010 if (!cw->dim.enable) return;
6011 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6015 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6017 Eina_Bool mask_set = EINA_FALSE;
6021 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6022 E_Comp_Config *conf = e_comp_config_get();
6023 if (cw->ec->input_only) return;
6024 if (!conf->dim_rect_enable) return;
6030 if (cw->dim.mask_obj)
6032 evas_object_smart_member_del(cw->dim.mask_obj);
6033 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6036 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);
6037 o = evas_object_rectangle_add(e_comp->evas);
6038 evas_object_color_set(o, 0, 0, 0, 0);
6039 evas_object_smart_member_add(o, obj);
6040 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6041 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6043 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6044 if (cw->visible) evas_object_show(o);
6046 cw->dim.mask_obj = o;
6047 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6049 evas_object_layer_set(cw->dim.mask_obj, 9998);
6053 if (cw->dim.mask_obj)
6055 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6056 evas_object_smart_member_del(cw->dim.mask_obj);
6057 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6063 e_comp_object_dim_client_set(E_Client *ec)
6065 E_Comp_Config *conf = e_comp_config_get();
6067 if (!conf->dim_rect_enable) return ;
6068 if (dim_client == ec) return;
6070 Eina_Bool prev_dim = EINA_FALSE;
6071 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6073 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6074 prev_dim = EINA_TRUE;
6076 if (prev_dim && dim_client->visible && ec)
6078 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6079 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6083 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6084 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6090 e_comp_object_dim_client_get(void)
6092 E_Comp_Config *conf = e_comp_config_get();
6094 if (!conf->dim_rect_enable ) return NULL;
6100 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6103 char emit[32] = "\0";
6104 E_Comp_Config *conf = e_comp_config_get();
6107 if (!conf->dim_rect_enable) return;
6108 if (!cw->effect_obj) return;
6109 if (enable == cw->dim.enable) return;
6111 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6112 if (noeffect || !conf->dim_rect_effect)
6114 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6118 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6121 cw->dim.enable = enable;
6123 if (cw->dim.mask_set && !enable)
6125 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6126 edje_object_signal_emit(cw->effect_obj, emit, "e");
6128 else if (cw->dim.mask_set && enable)
6130 edje_object_signal_emit(cw->effect_obj, emit, "e");
6131 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6135 edje_object_signal_emit(cw->effect_obj, emit, "e");
6140 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6142 API_ENTRY EINA_FALSE;
6143 E_Comp_Config *conf = e_comp_config_get();
6145 if (!ec) return EINA_FALSE;
6146 if (!conf->dim_rect_enable) return EINA_FALSE;
6148 if (cw->dim.enable) return EINA_TRUE;
6154 _e_comp_object_dim_update(E_Comp_Object *cw)
6156 E_Comp_Config *conf = e_comp_config_get();
6159 if (!conf->dim_rect_enable) return;
6160 if (!cw->effect_obj) return;
6163 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6164 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6166 if (cw->dim.mask_set)
6168 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6174 e_comp_object_clear(Evas_Object *obj)
6178 _e_comp_object_clear(cw);
6182 e_comp_object_hwc_update_exists(Evas_Object *obj)
6184 API_ENTRY EINA_FALSE;
6185 return cw->hwc_need_update;
6190 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6193 cw->hwc_need_update = set;
6197 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6199 API_ENTRY EINA_FALSE;
6200 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6204 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6207 if (cw->indicator.obj != indicator)
6208 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6209 cw->indicator.obj = indicator;
6210 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6214 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6217 if (cw->indicator.obj != indicator) return;
6218 cw->indicator.obj = NULL;
6219 edje_object_part_unswallow(cw->shobj, indicator);
6223 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6226 Edje_Message_Int_Set *msg;
6228 if (!cw->indicator.obj) return;
6230 cw->indicator.w = w;
6231 cw->indicator.h = h;
6233 if (!cw->shobj) return;
6235 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6239 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6240 edje_object_message_signal_process(cw->shobj);
6243 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6245 e_comp_object_map_update(Evas_Object *obj)
6248 E_Client *ec = cw->ec;
6249 E_Comp_Wl_Client_Data *cdata;
6251 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6254 int l, remain = sizeof buffer;
6257 if (e_object_is_del(E_OBJECT(ec))) return;
6258 cdata = e_client_cdata_get(ec);
6261 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6262 * when new buffer is attached.
6264 if (!cdata->buffer_ref.buffer) return;
6266 if ((!cw->redirected) ||
6267 (e_client_video_hw_composition_check(ec)) ||
6268 (!e_comp_wl_output_buffer_transform_get(ec) &&
6269 cdata->scaler.buffer_viewport.buffer.scale == 1))
6271 if (evas_object_map_enable_get(cw->effect_obj))
6273 ELOGF("TRANSFORM", "map: disable", cw->ec);
6274 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6275 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6276 evas_object_resize(cw->effect_obj, tw, th);
6283 EINA_SAFETY_ON_NULL_RETURN(map);
6285 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6291 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6293 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6294 e_map_point_image_uv_set(map, 0, x, y);
6295 l = snprintf(p, remain, "%d,%d", x, y);
6296 p += l, remain -= l;
6298 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6299 e_map_point_image_uv_set(map, 1, x, y);
6300 l = snprintf(p, remain, " %d,%d", x, y);
6301 p += l, remain -= l;
6303 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6304 e_map_point_image_uv_set(map, 2, x, y);
6305 l = snprintf(p, remain, " %d,%d", x, y);
6306 p += l, remain -= l;
6308 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6309 e_map_point_image_uv_set(map, 3, x, y);
6310 l = snprintf(p, remain, " %d,%d", x, y);
6311 p += l, remain -= l;
6313 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6315 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6317 e_comp_object_map_set(cw->effect_obj, map);
6318 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6322 /* if there's screen rotation with comp mode, then ec->effect_obj and
6323 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6325 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6326 evas_object_resize(cw->effect_obj, tw, th);
6330 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6332 API_ENTRY EINA_FALSE;
6334 cw->render_trace = set;
6340 e_comp_object_native_usable_get(Evas_Object *obj)
6342 API_ENTRY EINA_FALSE;
6343 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6345 if (cw->ec->input_only) return EINA_FALSE;
6346 if (cw->external_content) return EINA_FALSE;
6347 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6349 /* just return true value, if it is normal case */
6350 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6353 Evas_Native_Surface *ns;
6354 ns = evas_object_image_native_surface_get(cw->obj);
6356 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6359 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6367 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6369 API_ENTRY EINA_FALSE;
6370 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6371 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6372 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6376 case E_COMP_IMAGE_FILTER_BLUR:
6377 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6379 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6380 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6382 case E_COMP_IMAGE_FILTER_INVERSE:
6383 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6385 case E_COMP_IMAGE_FILTER_NONE:
6387 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6391 cw->image_filter = filter;
6396 EINTERN E_Comp_Image_Filter
6397 e_comp_object_image_filter_get(Evas_Object *obj)
6399 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6400 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6401 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6402 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6404 return cw->image_filter;
6408 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6412 if (!_damage_trace) return;
6414 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6415 evas_object_del(obj);
6417 _damage_trace_post_objs = NULL;
6421 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6423 if (!_damage_trace) return;
6425 _damage_trace_post_objs = _damage_trace_objs;
6426 _damage_trace_objs = NULL;
6430 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6432 if (_damage_trace == onoff) return;
6436 evas_event_callback_add(e_comp->evas,
6437 EVAS_CALLBACK_RENDER_PRE,
6438 _e_comp_object_damage_trace_render_pre_cb,
6441 evas_event_callback_add(e_comp->evas,
6442 EVAS_CALLBACK_RENDER_POST,
6443 _e_comp_object_damage_trace_render_post_cb,
6450 EINA_LIST_FREE(_damage_trace_objs, obj)
6451 evas_object_del(obj);
6453 _damage_trace_objs = NULL;
6455 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6456 evas_object_del(obj);
6458 _damage_trace_post_objs = NULL;
6460 evas_event_callback_del(e_comp->evas,
6461 EVAS_CALLBACK_RENDER_PRE,
6462 _e_comp_object_damage_trace_render_pre_cb);
6464 evas_event_callback_del(e_comp->evas,
6465 EVAS_CALLBACK_RENDER_POST,
6466 _e_comp_object_damage_trace_render_post_cb);
6469 _damage_trace = onoff;
6473 e_comp_object_redirected_get(Evas_Object *obj)
6475 API_ENTRY EINA_FALSE;
6476 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6478 return cw->redirected;
6482 e_comp_object_color_visible_get(Evas_Object *obj)
6484 API_ENTRY EINA_FALSE;
6487 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6489 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6493 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6497 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6501 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6509 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6511 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6513 return e_map_set_to_comp_object(em, obj);
6517 e_comp_object_map_get(const Evas_Object *obj)
6519 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6521 return e_map_get_from_comp_object(obj);
6525 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6527 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6529 evas_object_map_enable_set(obj, enable);
6535 e_comp_object_render_update_lock(Evas_Object *obj)
6537 E_Comp_Wl_Buffer *buffer;
6538 struct wayland_tbm_client_queue *cqueue;
6540 API_ENTRY EINA_FALSE;
6542 if (cw->render_update_lock.lock == 0)
6544 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6546 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6547 if ((buffer) && (buffer->resource))
6549 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6551 wayland_tbm_server_client_queue_flush(cqueue);
6554 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6555 e_comp_object_render_update_del(obj);
6557 ELOGF("COMP", "Render update lock enabled", cw->ec);
6560 cw->render_update_lock.lock++;
6566 e_comp_object_render_update_unlock(Evas_Object *obj)
6570 if (cw->render_update_lock.lock == 0)
6573 cw->render_update_lock.lock--;
6575 if (cw->render_update_lock.lock == 0)
6578 if (cw->render_update_lock.pending_move_set)
6580 evas_object_move(obj,
6581 cw->render_update_lock.pending_move_x,
6582 cw->render_update_lock.pending_move_y);
6583 cw->render_update_lock.pending_move_x = 0;
6584 cw->render_update_lock.pending_move_y = 0;
6585 cw->render_update_lock.pending_move_set = EINA_FALSE;
6588 if (cw->render_update_lock.pending_resize_set)
6590 evas_object_resize(obj,
6591 cw->render_update_lock.pending_resize_w,
6592 cw->render_update_lock.pending_resize_h);
6593 cw->render_update_lock.pending_resize_w = 0;
6594 cw->render_update_lock.pending_resize_h = 0;
6595 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6598 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6600 if ((cw->ec->exp_iconify.buffer_flush) &&
6601 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6602 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6603 e_comp_object_clear(obj);
6605 e_comp_object_render_update_add(obj);
6607 ELOGF("COMP", "Render update lock disabled", cw->ec);
6612 e_comp_object_render_update_lock_get(Evas_Object *obj)
6614 API_ENTRY EINA_FALSE;
6616 if (cw->render_update_lock.lock > 0)
6623 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6627 if (cw->transparent.set)
6629 if (r) *r = cw->transparent.user_r;
6630 if (g) *g = cw->transparent.user_g;
6631 if (b) *b = cw->transparent.user_b;
6632 if (a) *a = cw->transparent.user_a;
6636 evas_object_color_get(obj, r, g, b, a);
6641 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6645 evas_object_render_op_set(cw->obj, op);
6648 EINTERN Evas_Render_Op
6649 e_comp_object_render_op_get(Evas_Object *obj)
6651 API_ENTRY EVAS_RENDER_BLEND;
6653 return evas_object_render_op_get(cw->obj);