e_comp_object: add E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET
[platform/upstream/enlightenment.git] / src / bin / e_comp_object.c
1 #include "e_comp_object_intern.h"
2 #include "e_bindings_intern.h"
3 #include "e_utils_intern.h"
4 #ifdef REFACTOR_DESK_AREA
5 #else
6 #include "e_comp_canvas_intern.h"
7 #endif
8 #include "e_comp_cfdata_intern.h"
9 #include "e_comp_wl_subsurface_intern.h"
10 #include "e_comp_wl_tbm_intern.h"
11 #include "e_comp_intern.h"
12 #include "e_pixmap_intern.h"
13 #include "e_map_intern.h"
14 #include "e_hwc_window_intern.h"
15 #include "e_hwc_windows_intern.h"
16 #include "e_policy_visibility_intern.h"
17 #include "e_client_video_intern.h"
18 #include "e_client_intern.h"
19 #include "e_zone_intern.h"
20 #include "e_theme_intern.h"
21 #include "e_config_intern.h"
22
23 /* data keys:
24
25    = keys that return objects =
26    - E_Client: the client associated with the object (E_Client*)
27    - comp_smart_obj: cw->smart_obj (Evas_Object*)
28    - comp_obj: cw (E_Comp_Object*)
29
30    = keys that are bool flags =
31    - client_restack: client needs a protocol-level restack
32    - comp_override: object is triggering a nocomp override to force compositing
33    - comp_ref: object has a ref from visibility animations
34    - comp_showing: object is currently running its show animation
35    - comp_hiding: object is currently running its hiding animation
36    - comp_object: object is a compositor-created object
37    - comp_object_skip: object has a name which prohibits theme shadows
38    - comp_object-to_del: list of objects which will be deleted when this object is deleted
39    - comp_mirror: object is the result of e_comp_object_util_mirror_add()
40    - effect_running: object is animating by external module
41 */
42
43 #define UPDATE_MAX 512 // same as evas
44 #define FAILURE_MAX 2 // seems reasonable
45 #define SMART_NAME     "e_comp_object"
46 #define INPUT_OBJ_SMART_NAME "input_object"
47
48 /* for non-util functions */
49 #define API_ENTRY      E_Comp_Object *cw; \
50                        cw = evas_object_smart_data_get(obj); \
51                        if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
52
53 /* for util functions (obj may or may not be E_Comp_Object */
54 #define SOFT_ENTRY(...)      E_Comp_Object *cw; \
55                        if (!obj) \
56                          { \
57                             CRI("YOU PASSED NULL! ARGH!"); \
58                             return __VA_ARGS__; \
59                          } \
60                        cw = evas_object_smart_data_get(obj); \
61                        if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
62                          cw = NULL
63 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
64
65 /* enable for lots of client size info in console output */
66 #if 1
67 # define e_util_size_debug_set(x, y)
68 #endif
69
70 /* enable along with display-specific damage INF calls to enable render tracing
71  * SLOW!
72  */
73 #if 0
74 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
75 #else
76 #define RENDER_DEBUG(...)
77 #endif
78
79 typedef struct _E_Input_Rect_Data
80 {
81    Eina_Rectangle rect;
82    Evas_Object *obj;
83 } E_Input_Rect_Data;
84
85 typedef struct _E_Input_Rect_Smart_Data
86 {
87    Eina_List *input_rect_data_list;
88    E_Comp_Object *cw;
89 } E_Input_Rect_Smart_Data;
90
91 struct E_Comp_Object_Mover
92 {
93    EINA_INLIST;
94    E_Comp_Object_Mover_Cb func;
95    const char *sig;
96    void *data;
97    int pri;
98 };
99
100 static Eina_Inlist *_e_comp_object_movers = NULL;
101 static Evas_Smart *_e_comp_smart = NULL;
102 static Evas_Smart *_e_comp_input_obj_smart = NULL;
103
104 static int _e_comp_object_hooks_delete = 0;
105 static int _e_comp_object_hooks_walking = 0;
106
107 static Eina_Inlist *_e_comp_object_hooks[] =
108 {
109    [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
110    [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
111    [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
112    [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
113    [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
114    [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
115    [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
116    [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
117    [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET] = NULL,
118 };
119
120 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
121 static int _e_comp_object_intercept_hooks_delete = 0;
122 static int _e_comp_object_intercept_hooks_walking = 0;
123
124 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
125 {
126    [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
127    [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
128 };
129 #endif
130
131 static Eina_Bool _damage_trace = EINA_FALSE;
132 static Eina_List *_damage_trace_objs = NULL;
133 static Eina_List *_damage_trace_post_objs = NULL;
134
135 /* sekrit functionzzz */
136 EINTERN void e_client_focused_set(E_Client *ec);
137
138 /* emitted every time a new noteworthy comp object is added */
139 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
140
141 /* ecore event define */
142 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
143 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
144 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
145
146 static void           _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
147 static Eina_Bool      _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
148 static void           _e_comp_object_dim_update(E_Comp_Object *cw);
149 static void           _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
150 #ifdef REFACTOR_DESK_AREA
151 #else
152 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
153 static void _e_comp_object_raise(Evas_Object *obj);
154 static void  _e_comp_object_layer_set(Evas_Object *obj, short layer);
155 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
156 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
157 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
158 #endif
159
160 static E_Client       *dim_client = NULL;
161
162 static void
163 _e_comp_object_hooks_clean(void)
164 {
165    Eina_Inlist *l;
166    E_Comp_Object_Hook *ch;
167    unsigned int x;
168
169    for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
170      EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
171        {
172           if (!ch->delete_me) continue;
173           _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
174           free(ch);
175        }
176 }
177
178 static Eina_Bool
179 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
180 {
181    E_Comp_Object_Hook *ch;
182    Eina_Bool ret = EINA_TRUE;
183
184    if (e_object_is_del(E_OBJECT(ec)))
185      {
186         if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
187             (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
188             (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
189             (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
190             (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
191             (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
192             (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
193             (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET) &&
194             (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET)
195             )
196           {
197              return ret;
198           }
199      }
200    e_object_ref(E_OBJECT(ec));
201    _e_comp_object_hooks_walking++;
202    EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
203      {
204         if (ch->delete_me) continue;
205         if (!(ch->func(ch->data, ec)))
206           {
207              ret = EINA_FALSE;
208              break;
209           }
210      }
211    _e_comp_object_hooks_walking--;
212    if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
213      _e_comp_object_hooks_clean();
214
215    e_object_unref(E_OBJECT(ec));
216
217    return ret;
218 }
219
220 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
221 static void
222 _e_comp_object_intercept_hooks_clean(void)
223 {
224    Eina_Inlist *l;
225    E_Comp_Object_Intercept_Hook *ch;
226    unsigned int x;
227
228    for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
229      EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
230        {
231           if (!ch->delete_me) continue;
232           _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
233           free(ch);
234        }
235 }
236
237 static Eina_Bool
238 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
239 {
240    E_Comp_Object_Intercept_Hook *ch;
241    Eina_Bool ret = EINA_TRUE;
242
243    if (e_object_is_del(E_OBJECT(ec))) return ret;
244    e_object_ref(E_OBJECT(ec));
245    _e_comp_object_intercept_hooks_walking++;
246    EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
247      {
248         if (ch->delete_me) continue;
249         if (!(ch->func(ch->data, ec)))
250           {
251              ret = EINA_FALSE;
252              break;
253           }
254      }
255    _e_comp_object_intercept_hooks_walking--;
256    if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
257      _e_comp_object_intercept_hooks_clean();
258
259    e_object_unref(E_OBJECT(ec));
260
261    return ret;
262 }
263 #endif
264
265 static void
266 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
267 {
268    E_Event_Comp_Object *ev = event;
269    E_Client *ec;
270
271    ec = evas_object_data_get(ev->comp_object, "E_Client");
272    if (ec)
273      {
274         UNREFD(ec, 1);
275         e_object_unref(E_OBJECT(ec));
276      }
277    evas_object_unref(ev->comp_object);
278    free(ev);
279 }
280
281 static void
282 _e_comp_object_event_add(Evas_Object *obj)
283 {
284    E_Event_Comp_Object *ev;
285    E_Client *ec;
286
287    if (stopping) return;
288    ev = E_NEW(E_Event_Comp_Object, 1);
289    EINA_SAFETY_ON_NULL_RETURN(ev);
290
291    evas_object_ref(obj);
292    ev->comp_object = obj;
293    ec = evas_object_data_get(ev->comp_object, "E_Client");
294    if (ec)
295      {
296         REFD(ec, 1);
297         e_object_ref(E_OBJECT(ec));
298      }
299    ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
300 }
301
302 static void
303 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
304 {
305    E_Event_Comp_Object *ev = event;
306    E_Client *ec;
307
308    ec = evas_object_data_get(ev->comp_object, "E_Client");
309    if (ec)
310      {
311         UNREFD(ec, 1);
312         e_object_unref(E_OBJECT(ec));
313      }
314    evas_object_unref(ev->comp_object);
315    free(ev);
316 }
317
318 static void
319 _e_comp_object_event_simple(Evas_Object *obj, int type)
320 {
321    E_Event_Comp_Object *ev;
322    E_Client *ec;
323
324    ev = E_NEW(E_Event_Comp_Object, 1);
325    if (!ev) return;
326
327    evas_object_ref(obj);
328    ev->comp_object = obj;
329    ec = evas_object_data_get(ev->comp_object, "E_Client");
330    if (ec)
331      {
332         REFD(ec, 1);
333         e_object_ref(E_OBJECT(ec));
334      }
335    ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
336 }
337 /////////////////////////////////////
338
339 static void
340 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
341 {
342    E_Comp_Object *cw = data;
343
344    cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
345 }
346
347 static void
348 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
349 {
350    E_Comp_Object *cw = data;
351
352    if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
353      evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
354    cw->force_visible++;
355
356    if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
357      e_comp_hwc_client_end(cw->ec, __FUNCTION__);
358 }
359
360 static void
361 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
362 {
363    E_Comp_Object *cw = data;
364
365    cw->force_visible--;
366    if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
367      evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
368 }
369
370 /////////////////////////////////////
371
372 #ifdef REFACTOR_DESK_AREA
373 EINTERN void
374 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
375 #else
376 static void
377 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
378 #endif
379 {
380    int layer = 0;
381    API_ENTRY;
382    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
383    if (cw->ec->input_only) return;
384
385    layer = evas_object_layer_get(obj);
386
387    if (cw->transform_bg_obj)
388      {
389         if (layer != evas_object_layer_get(cw->transform_bg_obj))
390           {
391              evas_object_layer_set(cw->transform_bg_obj, layer);
392           }
393
394         evas_object_stack_below(cw->transform_bg_obj, obj);
395      }
396
397    if (cw->transform_tranp_obj)
398      {
399         if (layer != evas_object_layer_get(cw->transform_tranp_obj))
400           {
401              evas_object_layer_set(cw->transform_tranp_obj, layer);
402           }
403
404         evas_object_stack_below(cw->transform_tranp_obj, obj);
405      }
406 }
407
408 static E_Map *
409 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
410 {
411    E_Map *map;
412    int i;
413    int x, y;
414
415    map = e_map_new();
416    if (!map) return NULL;
417
418    e_map_util_points_populate_from_object_full(map, obj, 0);
419    e_map_util_points_color_set(map, 255, 255, 255, 255);
420
421    for (i = 0 ; i < 4 ; ++i)
422      {
423         x = 0;
424         y = 0;
425
426         e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
427         e_map_point_coord_set(map, i, x, y, 1.0);
428      }
429
430    return map;
431 }
432
433 static void
434 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
435 {
436    if (!obj) return;
437
438    if (vertices)
439      {
440         E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
441         if (map)
442           {
443              e_comp_object_map_set(obj, map);
444              e_comp_object_map_enable_set(obj, EINA_TRUE);
445
446              e_map_free(map);
447           }
448      }
449    else
450      {
451         evas_object_map_enable_set(obj, EINA_FALSE);
452      }
453 }
454
455 static void
456 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
457 {
458    if (!obj) return;
459
460    if (vertices)
461      {
462         E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
463         if (map)
464           {
465              e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
466
467              e_comp_object_map_set(obj, map);
468              e_comp_object_map_enable_set(obj, EINA_TRUE);
469
470              e_map_free(map);
471           }
472      }
473    else
474      {
475         evas_object_map_enable_set(obj, EINA_FALSE);
476      }
477 }
478 /////////////////////////////////////
479
480 static inline Eina_Bool
481 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
482 {
483    if (num > 1) return EINA_TRUE;
484    if ((rects[0].x == 0) && (rects[0].y == 0) &&
485        ((int)rects[0].w == w) && ((int)rects[0].h == h))
486      return EINA_FALSE;
487    return EINA_TRUE;
488 }
489
490 /////////////////////////////////////
491
492 /* add a client to the layer-client list */
493 #ifdef REFACTOR_DESK_AREA
494 #else
495 static void
496 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
497 {
498    g_rec_mutex_lock(&e_comp->ec_list_mutex);
499
500    if (above)
501     e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
502    else if (below)
503      e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
504    if ((!above) && (!below))
505      {
506         if (prepend)
507           e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
508         else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
509           e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
510      }
511    e_comp->layers[cw->layer].clients_count++;
512
513    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
514 }
515
516 static void
517 _e_comp_object_layers_remove(E_Comp_Object *cw)
518 {
519    g_rec_mutex_lock(&e_comp->ec_list_mutex);
520
521    if (cw->ec && e_comp->layers[cw->layer].clients)
522      {
523         e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
524         e_comp->layers[cw->layer].clients_count--;
525      }
526
527    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
528 }
529 #endif
530
531 /////////////////////////////////////
532 static void
533 _e_comp_object_alpha_set(E_Comp_Object *cw)
534 {
535    Eina_Bool alpha = cw->ec->argb;
536
537    if ((cw->external_content) &&
538        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
539      {
540         return;
541      }
542
543    if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
544    if (cw->user_alpha_set) alpha = cw->user_alpha;
545
546    evas_object_image_alpha_set(cw->obj, alpha);
547 }
548
549 static void
550 _e_comp_object_shadow(E_Comp_Object *cw)
551 {
552    if (e_client_util_shadow_state_get(cw->ec))
553      edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
554    else
555      edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
556    if (cw->frame_object)
557      edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
558    evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
559 }
560
561 /* convert from the surface coordinates to the buffer coordinates */
562 static void
563 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
564 {
565    E_Comp_Wl_Buffer_Viewport *vp;
566    E_Comp_Wl_Client_Data *cdata;
567    int transform;
568    int bw, bh, tx, ty;
569
570   cdata = e_client_cdata_get(ec);
571
572    if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
573      {
574         *dx = sx;
575         *dy = sy;
576         return;
577      }
578
579    vp = &cdata->scaler.buffer_viewport;
580    transform = e_comp_wl_output_buffer_transform_get(ec);
581
582    e_pixmap_size_get(ec->pixmap, &bw, &bh);
583
584    /* for subsurface, it should be swap 90 and 270 */
585    if (e_comp_wl_subsurface_check(ec))
586      switch (transform)
587        {
588         case WL_OUTPUT_TRANSFORM_90:          transform = WL_OUTPUT_TRANSFORM_270;         break;
589         case WL_OUTPUT_TRANSFORM_270:         transform = WL_OUTPUT_TRANSFORM_90;          break;
590         case WL_OUTPUT_TRANSFORM_FLIPPED_90:  transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
591         case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;  break;
592         default: break;
593        }
594
595    switch (transform)
596      {
597       case WL_OUTPUT_TRANSFORM_NORMAL:
598       default:                              tx = sx,      ty = sy;      break;
599       case WL_OUTPUT_TRANSFORM_90:          tx = sy,      ty = bw - sx; break;
600       case WL_OUTPUT_TRANSFORM_180:         tx = bw - sx, ty = bh - sy; break;
601       case WL_OUTPUT_TRANSFORM_270:         tx = bh - sy, ty = sx;      break;
602       case WL_OUTPUT_TRANSFORM_FLIPPED:     tx = bw - sx, ty = sy;      break;
603       case WL_OUTPUT_TRANSFORM_FLIPPED_90:  tx = sy,      ty = sx;      break;
604       case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx,      ty = bh - sy; break;
605       case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
606      }
607
608    tx *= vp->buffer.scale;
609    ty *= vp->buffer.scale;
610
611    *dx = tx;
612    *dy = ty;
613 }
614
615 static void
616 _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh, int *dx, int *dy, int *dw, int *dh)
617 {
618    int x1 = sx;
619    int y1 = sy;
620    int x2 = sx + sw;
621    int y2 = sy + sh;
622    int mx, my;
623
624    _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
625    _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
626
627    mx = MIN(x1, x2);
628    my = MIN(y1, y2);
629
630    if (dx) *dx = mx;
631    if (dy) *dy = my;
632    if (dw) *dw = MAX(x1, x2) - mx;
633    if (dh) *dh = MAX(y1, y2) - my;
634 }
635
636 static void
637 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
638                                          int *dx, int *dy, int *dw, int *dh)
639 {
640    E_Util_Transform_Rect rect = {sx, sy, sw, sh};
641    E_Util_Transform_Rect_Vertex sv, dv;
642    int bw, bh;
643    int i;
644
645    e_pixmap_size_get(ec->pixmap, &bw, &bh);
646
647    sv = e_util_transform_rect_to_vertices(&rect);
648
649    for (i = 0; i < 4; i++)
650      {
651         double x = 0.0, y = 0.0;
652
653         e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
654
655         /* if evas decide coordinate is outside of map, it returns (0, 0)
656            in this case, full damage is added.
657          */
658         if ((i != 0) && (x == 0.0) && (y == 0.0))
659           goto full;
660
661         dv.vertices[i].vertex[0] = x;
662         dv.vertices[i].vertex[1] = y;
663         dv.vertices[i].vertex[2] = 1.0;
664         dv.vertices[i].vertex[3] = 1.0;
665      }
666
667    rect = e_util_transform_vertices_to_rect(&dv);
668
669    if (dx) *dx = rect.x;
670    if (dy) *dy = rect.y;
671    if (dw) *dw = rect.w;
672    if (dh) *dh = rect.h;
673
674    return;
675
676 full:
677    if (dx) *dx = 0;
678    if (dy) *dy = 0;
679    if (dw) *dw = bw;
680    if (dh) *dh = bh;
681
682    return;
683 }
684
685 static E_Map *
686 _e_comp_object_map_damage_transform_get(E_Client *ec)
687 {
688    E_Map *m;
689    E_Map *m2 = NULL;
690    int bw, bh;
691    int i;
692
693    if (!e_client_transform_core_enable_get(ec))
694      return NULL;
695
696    m = e_client_map_get(ec);
697    if (!m)
698      return NULL;
699
700    e_pixmap_size_get(ec->pixmap, &bw, &bh);
701    if ((bw == 0) || (bh == 0))
702      {
703         e_map_free(m);
704         return NULL;
705      }
706
707    m2 = e_map_new();
708    if (!m2)
709      {
710         e_map_free(m);
711         return NULL;
712      }
713
714    e_map_point_coord_set(m2, 0, 0, 0, 0);
715    e_map_point_coord_set(m2, 1, bw, 0, 0);
716    e_map_point_coord_set(m2, 2, bw, bh, 0);
717    e_map_point_coord_set(m2, 3, 0, bh, 0);
718
719    for (i = 0; i < 4; i++)
720      {
721         int map_x, map_y;
722
723         e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
724         e_map_point_image_uv_set(m2, i, map_x, map_y);
725      }
726
727    e_map_free(m);
728    return m2;
729 }
730
731 /////////////////////////////////////
732
733 /* handle evas mouse-in events on client object */
734 static void
735 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
736 {
737    Evas_Event_Mouse_In *ev = event_info;
738    E_Comp_Object *cw = data;
739
740    e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
741 }
742
743 /* handle evas mouse-out events on client object */
744 static void
745 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
746 {
747    Evas_Event_Mouse_Out *ev = event_info;
748    E_Comp_Object *cw = data;
749
750    e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
751 }
752
753 /* handle evas mouse wheel events on client object */
754 static void
755 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
756 {
757    Evas_Event_Mouse_Wheel *ev = event_info;
758    E_Comp_Object *cw = data;
759    E_Binding_Event_Wheel ev2;
760
761    if (!cw->ec) return;
762    if (e_client_action_get()) return;
763    e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
764    e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
765 }
766
767 /* handle evas mouse down events on client object */
768 static void
769 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
770 {
771    Evas_Event_Mouse_Down *ev = event_info;
772    E_Comp_Object *cw = data;
773    E_Binding_Event_Mouse_Button ev2;
774
775    if (!cw->ec) return;
776    if (e_client_action_get()) return;
777    e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
778    e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
779 }
780
781 /* handle evas mouse up events on client object */
782 static void
783 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
784 {
785    Evas_Event_Mouse_Up *ev = event_info;
786    E_Comp_Object *cw = data;
787    E_Binding_Event_Mouse_Button ev2;
788
789    if (!cw->ec) return;
790    if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
791    e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
792    e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
793 }
794
795 /* handle evas mouse movement events on client object */
796 static void
797 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
798 {
799    Evas_Event_Mouse_Move *ev = event_info;
800    E_Comp_Object *cw = data;
801
802    if (!cw->ec) return;
803    if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
804    e_client_mouse_move(cw->ec, &ev->cur.output);
805 }
806 /////////////////////////////////////
807
808 /* helper function for checking compositor themes based on user-defined matches */
809 static Eina_Bool
810 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
811 {
812    if (((m->title) && (!ec->netwm.name)) ||
813        ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
814      return EINA_FALSE;
815 #if defined(__cplusplus) || defined(c_plusplus)
816    if (((m->clas) && (!ec->icccm.cpp_class)) ||
817        ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
818      return EINA_FALSE;
819 #else
820    if (((m->clas) && (!ec->icccm.class)) ||
821        ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
822      return EINA_FALSE;
823 #endif
824
825   if (((m->role) && (!ec->icccm.window_role)) ||
826        ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
827      return EINA_FALSE;
828    if (m->primary_type)
829      {
830         if (ec->netwm.type)
831           {
832              if ((int)ec->netwm.type != m->primary_type)
833                return EINA_FALSE;
834           }
835         else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
836           return EINA_FALSE;
837      }
838   if (m->borderless != 0)
839     {
840        int borderless = 0;
841
842        if (e_client_util_borderless(ec))
843          borderless = 1;
844        if (!(((m->borderless == -1) && (!borderless)) ||
845              ((m->borderless == 1) && (borderless))))
846          return EINA_FALSE;
847     }
848   if (m->dialog != 0)
849     {
850        int dialog = 0;
851
852        if (((ec->icccm.transient_for != 0) ||
853             (ec->dialog)))
854          dialog = 1;
855        if (!(((m->dialog == -1) && (!dialog)) ||
856              ((m->dialog == 1) && (dialog))))
857          return EINA_FALSE;
858     }
859   if (m->accepts_focus != 0)
860     {
861        int accepts_focus = 0;
862
863        if (ec->icccm.accepts_focus)
864          accepts_focus = 1;
865        if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
866              ((m->accepts_focus == 1) && (accepts_focus))))
867          return EINA_FALSE;
868     }
869   if (m->vkbd != 0)
870     {
871        int vkbd = 0;
872
873        if (ec->vkbd.vkbd)
874          vkbd = 1;
875        if (!(((m->vkbd == -1) && (!vkbd)) ||
876              ((m->vkbd == 1) && (vkbd))))
877          return EINA_FALSE;
878     }
879   if (m->argb != 0)
880     {
881        if (!(((m->argb == -1) && (!ec->argb)) ||
882              ((m->argb == 1) && (ec->argb))))
883          return EINA_FALSE;
884     }
885   if (m->fullscreen != 0)
886     {
887        int fullscreen = ec->fullscreen;
888
889        if (!(((m->fullscreen == -1) && (!fullscreen)) ||
890              ((m->fullscreen == 1) && (fullscreen))))
891          return EINA_FALSE;
892     }
893   if (m->modal != 0)
894     {
895        if (!(m->modal == -1))
896          return EINA_FALSE;
897     }
898   return EINA_TRUE;
899 }
900
901 /* function for setting up a client's compositor frame theme (cw->shobj) */
902 static Eina_Bool
903 _e_comp_object_shadow_setup(E_Comp_Object *cw)
904 {
905    int ok = 0;
906    char buf[4096];
907    Eina_List *list = NULL, *l;
908    E_Input_Rect_Data *input_rect_data;
909    E_Input_Rect_Smart_Data *input_rect_sd;
910    E_Comp_Match *m;
911    Eina_Stringshare *reshadow_group = NULL;
912    Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
913    Eina_Stringshare *name, *title;
914    E_Comp_Config *conf = e_comp_config_get();
915
916    edje_object_file_get(cw->shobj, NULL, &reshadow_group);
917    /* match correct client type */
918    list = cw->ec->override ? conf->match.overrides : conf->match.borders;
919    name = cw->ec->icccm.name;
920    title = cw->ec->icccm.title;
921    skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
922    fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
923
924    /* skipping here is mostly a hack for systray because I hate it */
925    if (!skip)
926      {
927         EINA_LIST_FOREACH(list, l, m)
928           {
929              if (((m->name) && (!name)) ||
930                  ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
931                continue;
932              if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
933
934              focus = m->focus;
935              no_shadow = m->no_shadow;
936              if (m->shadow_style)
937                {
938                   /* fast effects are just themes with "/fast" appended and shorter effect times */
939                   if (fast)
940                     {
941                        snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
942                        reshadow = ok = !e_util_strcmp(reshadow_group, buf);
943                        if (!ok)
944                          ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
945                     }
946                   /* default to non-fast style if fast not available */
947                   if (!ok)
948                     {
949                        snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
950                        reshadow = ok = !e_util_strcmp(reshadow_group, buf);
951                        if (!ok)
952                          ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
953                     }
954                   if (ok && m->visibility_effect)
955                     eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
956                   if (ok) break;
957                }
958           }
959      }
960    while (!ok)
961      {
962         if (skip || (cw->ec->e.state.video))
963           {
964              reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
965              if (!ok)
966                ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
967           }
968         if (ok) break;
969         if (conf->shadow_style)
970           {
971              if (fast)
972                {
973                   snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
974                   reshadow = ok = !e_util_strcmp(reshadow_group, buf);
975                   if (!ok)
976                     ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
977                }
978              if (!ok)
979                {
980                   snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
981                   reshadow = ok = !e_util_strcmp(reshadow_group, buf);
982                   if (!ok)
983                     ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
984                }
985           }
986         if (!ok)
987           {
988              if (fast)
989                {
990                   reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
991                   if (!ok)
992                     ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
993                }
994              if (!ok)
995                {
996                   reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
997                   if (!ok)
998                     ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
999                }
1000           }
1001         break;
1002      }
1003    /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1004    if (reshadow)
1005      {
1006         ;
1007      }
1008    if (cw->ec->override)
1009      {
1010         if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1011           edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1012         else
1013           edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1014         evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1015      }
1016    else
1017      {
1018         if (no_shadow)
1019           {
1020              edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1021              evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1022           }
1023         else
1024           _e_comp_object_shadow(cw);
1025      }
1026
1027    if (focus || cw->ec->focused || cw->ec->override)
1028      e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1029    else
1030      e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1031    if (cw->ec->sticky)
1032      e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1033    if (cw->ec->hung)
1034      e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1035    /* visibility must always be enabled for re_manage clients to prevent
1036     * pop-in animations every time the user sees a persistent client again;
1037     * applying visibility for iconic clients prevents the client from getting
1038     * stuck as hidden
1039     */
1040    if (cw->visible || cw->ec->re_manage)
1041      e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1042    else
1043      e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1044
1045    /* breaks animation counter */
1046    if (cw->frame_object)
1047      {
1048         edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1049         edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1050         edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1051         edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1052         no_shadow = 1;
1053      }
1054    else
1055      {
1056         no_shadow = 1;
1057         edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1058      }
1059    if (cw->input_obj)
1060      {
1061         input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1062         if (input_rect_sd)
1063           {
1064              EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1065                {
1066                   if (input_rect_data->obj)
1067                     {
1068                        pass_event_flag = EINA_TRUE;
1069                        break;
1070                     }
1071                }
1072           }
1073      }
1074    if (cw->indicator.obj)
1075      {
1076         Evas_Object *indicator;
1077         indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1078         if (indicator != cw->indicator.obj)
1079           {
1080              edje_object_part_unswallow(cw->shobj, indicator);
1081              edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1082              e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1083           }
1084      }
1085
1086    evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1087    evas_object_pass_events_set(cw->obj, pass_event_flag);
1088
1089    return EINA_TRUE;
1090 }
1091
1092 /////////////////////////////////////////////
1093
1094 static void
1095 _e_comp_object_animating_begin(E_Comp_Object *cw)
1096 {
1097    cw->animating++;
1098    if (cw->animating == 1)
1099      {
1100         e_comp->animating++;
1101         REFD(cw->ec, 2);
1102         e_object_ref(E_OBJECT(cw->ec));
1103      }
1104 }
1105
1106 static Eina_Bool
1107 _e_comp_object_animating_end(E_Comp_Object *cw)
1108 {
1109    if (cw->animating)
1110      {
1111         cw->animating--;
1112         if (!cw->animating)
1113           {
1114              if (cw->ec)
1115                {
1116                   if (cw->ec->launching)
1117                     {
1118                        if (!cw->ec->extra_animating)
1119                          {
1120                             ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1121                             cw->ec->launching = EINA_FALSE;
1122                             if (cw->ec->first_mapped)
1123                               {
1124                                  ELOGF("LAUNCH", "SHOW real win", cw->ec);
1125                                  e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1126                               }
1127
1128                             e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1129                          }
1130                     }
1131                }
1132              e_comp->animating--;
1133              cw->showing = cw->hiding = 0;
1134              UNREFD(cw->ec, 2);
1135              if (e_comp->animating == 0)
1136                e_comp_visibility_calculation_set(EINA_TRUE);
1137              /* remove ref from animation start, account for possibility of deletion from unref */
1138              return !!e_object_unref(E_OBJECT(cw->ec));
1139           }
1140      }
1141    return EINA_TRUE;
1142 }
1143
1144 /* handle the end of a compositor animation */
1145 static void
1146 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1147 {
1148    E_Comp_Object *cw = data;
1149
1150    /* visible clients which have never been sized are a bug */
1151    if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1152      CRI("ACK! ec:%p", cw->ec);
1153    if (!_e_comp_object_animating_end(cw)) return;
1154    if (cw->animating) return;
1155    /* hide only after animation finishes to guarantee a full run of the animation */
1156    if (!cw->defer_hide) return;
1157    if ((!strcmp(emission, "e,action,hide,done")) ||
1158        (!strcmp(emission, "e,action,done")) ||
1159        ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1160      {
1161         ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1162         evas_object_hide(cw->smart_obj);
1163      }
1164 }
1165
1166 /* run a visibility compositor effect if available, return false if object is dead */
1167 static Eina_Bool
1168 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1169 {
1170    E_Zone *zone;
1171    int x, y;
1172    int zw = 0, zh = 0;
1173
1174    if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1175    if (!cw->effect_running)
1176      _e_comp_object_animating_begin(cw);
1177    if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1178      return _e_comp_object_animating_end(cw);
1179    if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1180      return _e_comp_object_animating_end(cw);
1181
1182    evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1183    x -= cw->x;
1184    y -= cw->y;
1185    zone = e_comp_zone_find_by_ec(cw->ec);
1186    if (zone)
1187      zw = zone->w, zh = zone->h;
1188    else
1189      {
1190         E_Zone *zone;
1191
1192         zone = e_comp_object_util_zone_get(cw->smart_obj);
1193         if (!zone) zone = e_zone_current_get();
1194         if (zone)
1195           {
1196              zw = zone->w;
1197              zh = zone->h;
1198           }
1199      }
1200    e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1201       cw->w, cw->h, zw, zh, x, y}, 8);
1202    e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1203    e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1204    return EINA_TRUE;
1205 }
1206 /////////////////////////////////////////////
1207
1208 /* create necessary objects for clients that e manages */
1209 static void
1210 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1211 {
1212    if (cw->set_mouse_callbacks) return;
1213    if (!cw->smart_obj) return;
1214
1215    evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1216    evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1217    evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1218    evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1219    evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1220    evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1221
1222    cw->set_mouse_callbacks = EINA_TRUE;
1223 }
1224
1225 static void
1226 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1227 {
1228    if (!cw->set_mouse_callbacks) return;
1229    if (!cw->smart_obj) return;
1230
1231    evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1232    evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1233    evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1234    evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1235    evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1236    evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1237
1238    cw->set_mouse_callbacks = EINA_FALSE;
1239 }
1240
1241 static void
1242 _e_comp_object_setup(E_Comp_Object *cw)
1243 {
1244    cw->clip = evas_object_rectangle_add(e_comp->evas);
1245    evas_object_move(cw->clip, -9999, -9999);
1246    evas_object_resize(cw->clip, 999999, 999999);
1247    evas_object_smart_member_add(cw->clip, cw->smart_obj);
1248    cw->effect_obj = edje_object_add(e_comp->evas);
1249    evas_object_move(cw->effect_obj, cw->x, cw->y);
1250    evas_object_clip_set(cw->effect_obj, cw->clip);
1251    evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1252    e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1253    cw->shobj = edje_object_add(e_comp->evas);
1254    evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1255    edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1256    edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1257
1258    /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1259    if (cw->ec->override)
1260      {
1261         evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1262         evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1263         evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1264      }
1265    else if (!cw->ec->input_only)
1266      {
1267         evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1268         evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1269         evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1270      }
1271    cw->real_hid = !cw->ec->input_only;
1272    if (!cw->ec->input_only)
1273      {
1274         e_util_size_debug_set(cw->effect_obj, 1);
1275         _e_comp_object_mouse_event_callback_set(cw);
1276      }
1277
1278    cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1279    evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1280    evas_object_move(cw->default_input_obj, cw->x, cw->y);
1281    evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1282    evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1283    evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1284
1285    _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1286 }
1287
1288 /////////////////////////////////////////////
1289
1290 /* for fast path evas rendering; only called during render */
1291 static void
1292 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1293 {
1294    E_Comp_Object *cw = data;
1295    E_Client *ec = cw->ec;
1296    int pw, ph;
1297    int bx, by, bxx, byy;
1298
1299    if (e_object_is_del(E_OBJECT(ec))) return;
1300    if (cw->external_content) return;
1301    if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1302    e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1303    if (bxx && byy)
1304      {
1305         bxx = pw - (bx + bxx), byy = ph - (by + byy);
1306         evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1307      }
1308    else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1309      {
1310         bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1311         bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1312      }
1313    else
1314      {
1315         bx = by = bxx = byy = 0;
1316         evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1317      }
1318    {
1319       Edje_Message_Int_Set *msg;
1320       Edje_Message_Int msg2;
1321       Eina_Bool id = (bx || by || bxx || byy);
1322
1323       msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1324       msg->count = 4;
1325       msg->val[0] = bx;
1326       msg->val[1] = by;
1327       msg->val[2] = bxx;
1328       msg->val[3] = byy;
1329       edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1330       msg2.val = id;
1331       edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1332    }
1333    if (cw->native)
1334      {
1335         E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1336         e_comp_client_post_update_add(cw->ec);
1337      }
1338    else if (e_comp_object_render(ec->frame))
1339      {
1340         /* apply shape mask if necessary */
1341         if ((!cw->native) && (ec->shaped))
1342           e_comp_object_shape_apply(ec->frame);
1343      }
1344    /* shaped clients get precise mouse events to handle transparent pixels */
1345    evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1346
1347    /* queue another render if client is still dirty; cannot refresh here. */
1348    if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1349      e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1350
1351    if (cw->render_trace)
1352      {
1353         _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1354      }
1355 }
1356
1357
1358 static void
1359 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1360 {
1361    E_Comp_Object *cw = data;
1362    E_Client *ec = cw->ec;
1363
1364    if (e_object_is_del(E_OBJECT(ec))) return;
1365    if (cw->external_content) return;
1366    if (!e_comp->hwc) return;
1367
1368    e_comp_client_render_list_add(cw->ec);
1369
1370    if (!ec->hwc_window) return;
1371
1372    e_hwc_windows_rendered_window_add(ec->hwc_window);
1373 }
1374
1375 /////////////////////////////////////////////
1376
1377 static void
1378 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1379 {
1380    E_Comp_Object *cw = data;
1381    int ix, iy, fx, fy;
1382
1383    if (cw->render_update_lock.lock)
1384      {
1385         cw->render_update_lock.pending_move_x = x;
1386         cw->render_update_lock.pending_move_y = y;
1387         cw->render_update_lock.pending_move_set = EINA_TRUE;
1388         return;
1389      }
1390
1391    if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1392        (e_pixmap_usable_get(cw->ec->pixmap)) &&
1393        (cw->external_content))
1394      {
1395         /* delay to move until the external content is unset */
1396         cw->ec->changes.pos = 1;
1397         EC_CHANGED(cw->ec);
1398         return;
1399      }
1400
1401    if (cw->ec->move_after_resize)
1402      {
1403         if ((x != cw->ec->x) || (y != cw->ec->y))
1404           {
1405              if (!cw->ec->is_cursor)
1406                ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1407              e_client_pos_set(cw->ec, x, y);
1408              cw->ec->changes.pos = 1;
1409              EC_CHANGED(cw->ec);
1410           }
1411         return;
1412      }
1413
1414    if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1415        (cw->ec->manage_resize.resize_obj))
1416      {
1417         e_client_pos_set(cw->ec, x, y);
1418         cw->ec->client.x = x + cw->client_inset.l;
1419         cw->ec->client.y = y + cw->client_inset.t;
1420         e_policy_visibility_client_defer_move(cw->ec);
1421         return;
1422      }
1423
1424    /* if frame_object does not exist, client_inset indicates CSD.
1425     * this means that ec->client matches cw->x/y, the opposite
1426     * of SSD.
1427     */
1428    fx = (!cw->frame_object) * cw->client_inset.l;
1429    fy = (!cw->frame_object) * cw->client_inset.t;
1430    if ((cw->x == x + fx) && (cw->y == y + fy))
1431      {
1432         if ((cw->ec->x != x) || (cw->ec->y != y))
1433           {
1434              /* handle case where client tries to move to position and back very quickly */
1435              e_client_pos_set(cw->ec, x, y);
1436              cw->ec->client.x = x + cw->client_inset.l;
1437              cw->ec->client.y = y + cw->client_inset.t;
1438           }
1439         return;
1440      }
1441    if (!cw->ec->maximize_override)
1442      {
1443         /* prevent moving in some directions while directionally maximized */
1444         if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1445           y = cw->y;
1446         if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1447           x = cw->x;
1448      }
1449    ix = x + cw->client_inset.l;
1450    iy = y + cw->client_inset.t;
1451    if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1452        ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1453        ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1454      {
1455         /* prevent moving at all if move isn't allowed in current maximize state */
1456         if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1457         /* queue unmaximize if we are allowing move and update unmaximize geometry */
1458
1459         E_Zone *zone;
1460         zone = e_comp_zone_find_by_ec(cw->ec);
1461         if (!zone) return;
1462
1463         cw->ec->changes.need_unmaximize = 1;
1464         cw->ec->saved.x = ix - zone->x;
1465         cw->ec->saved.y = iy - zone->y;
1466         cw->ec->saved.w = cw->ec->client.w;
1467         cw->ec->saved.h = cw->ec->client.h;
1468         EC_CHANGED(cw->ec);
1469         return;
1470      }
1471    /* only update during resize if triggered by resize */
1472    if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1473    /* delay to move while surface waits paired commit serial*/
1474    if (e_client_pending_geometry_has(cw->ec))
1475      {
1476         /* do nothing while waiting paired commit serial*/
1477         return;
1478      }
1479
1480    e_client_pos_set(cw->ec, x, y);
1481    if (cw->ec->new_client)
1482      {
1483         /* don't actually do anything until first client idler loop */
1484         cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1485         cw->ec->changes.pos = 1;
1486         EC_CHANGED(cw->ec);
1487      }
1488    else
1489      {
1490         /* only update xy position of client to avoid invalid
1491          * first damage region if it is not a new_client. */
1492         cw->ec->client.x = ix;
1493         cw->ec->client.y = iy;
1494
1495         /* flip SSD->CSD */
1496         if (!cw->frame_object)
1497           x = ix, y = iy;
1498         evas_object_move(obj, x, y);
1499      }
1500 }
1501
1502 static void
1503 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1504 {
1505    E_Comp_Object *cw = data;
1506    int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1507    E_Zone *zone;
1508
1509    if (cw->render_update_lock.lock)
1510      {
1511         cw->render_update_lock.pending_resize_w = w;
1512         cw->render_update_lock.pending_resize_h = h;
1513         cw->render_update_lock.pending_resize_set = EINA_TRUE;
1514         return;
1515      }
1516
1517    if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1518      {
1519         e_client_size_set(cw->ec, w, h);
1520         evas_object_resize(obj, w, h);
1521         return;
1522      }
1523
1524    /* if frame_object does not exist, client_inset indicates CSD.
1525     * this means that ec->client matches cw->w/h, the opposite
1526     * of SSD.
1527     */
1528    fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1529    fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1530    if ((cw->w == w + fw) && (cw->h == h + fh))
1531      {
1532         if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1533             (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1534             (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1535           {
1536              /* handle case where client tries to resize itself and back very quickly */
1537              e_client_size_set(cw->ec, w, h);
1538              cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1539              cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1540              evas_object_smart_callback_call(obj, "client_resize", NULL);
1541           }
1542         return;
1543      }
1544    /* guarantee that fullscreen is fullscreen */
1545    zone = e_comp_zone_find_by_ec(cw->ec);
1546    if (!zone) return;
1547    if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1548      {
1549         if (!e_client_transform_core_enable_get(cw->ec))
1550           return;
1551      }
1552    /* calculate client size */
1553    iw = w - cw->client_inset.l - cw->client_inset.r;
1554    ih = h - cw->client_inset.t - cw->client_inset.b;
1555    if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1556      {
1557         /* prevent resizing while maximized depending on direction and config */
1558         if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1559
1560         Eina_Bool reject = EINA_FALSE;
1561         if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1562           {
1563              if (cw->ec->client.h != ih)
1564                {
1565                   cw->ec->saved.h = ih;
1566                   cw->ec->saved.y = cw->ec->client.y - zone->y;
1567                   reject = cw->ec->changes.need_unmaximize = 1;
1568                }
1569           }
1570         if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1571           {
1572              if (cw->ec->client.w != iw)
1573                {
1574                   cw->ec->saved.w = iw;
1575                   cw->ec->saved.x = cw->ec->client.x - zone->x;
1576                   reject = cw->ec->changes.need_unmaximize = 1;
1577                }
1578           }
1579         if (reject)
1580           {
1581              EC_CHANGED(cw->ec);
1582              return;
1583           }
1584      }
1585    if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1586      {
1587         /* do nothing until client idler loops */
1588         if ((cw->ec->w != w) || (cw->ec->h != h))
1589           {
1590              e_client_size_set(cw->ec, w, h);
1591              cw->ec->changes.size = 1;
1592              EC_CHANGED(cw->ec);
1593           }
1594         return;
1595      }
1596    if (e_client_pending_geometry_has(cw->ec))
1597      {
1598         /* do nothing while waiting paired commit serial*/
1599         return;
1600      }
1601
1602    e_client_size_set(cw->ec, w, h);
1603
1604    cw->ec->client.w = iw;
1605    cw->ec->client.h = ih;
1606    if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1607
1608    /* The size of non-compositing window can be changed, so there is a
1609     * need to check that cw is H/W composited if cw is not redirected.
1610     * And of course we have to change size of evas object of H/W composited cw,
1611     * otherwise cw can't receive input events even if it is shown on the screen.
1612     */
1613    Eina_Bool redirected = cw->redirected;
1614    if (!redirected)
1615      redirected = e_comp_is_on_overlay(cw->ec);
1616
1617    if ((!cw->ec->input_only) && (redirected) &&
1618        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1619        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1620        (e_pixmap_dirty_get(cw->ec->pixmap) ||
1621        (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1622      return;
1623
1624    if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1625        cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1626      pw = w, ph = h;
1627    prev_w = cw->w, prev_h = cw->h;
1628    e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1629    /* check shading and clamp to pixmap size for regular clients */
1630    if ((!cw->ec->input_only) && (!cw->ec->override) &&
1631        (((w - fw != pw) || (h - fh != ph))))
1632      {
1633         //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1634         evas_object_smart_callback_call(obj, "client_resize", NULL);
1635         /* flip for CSD */
1636         if (cw->frame_object || cw->ec->input_only)
1637           e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1638         else
1639           w = pw, h = ph;
1640         if ((cw->w == w) && (cw->h == h))
1641           {
1642              /* going to be a noop resize which won't trigger smart resize */
1643              RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1644              if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1645           }
1646         evas_object_resize(obj, w, h);
1647      }
1648    else
1649      {
1650         evas_object_smart_callback_call(obj, "client_resize", NULL);
1651
1652         /* flip for CSD */
1653         if ((!cw->frame_object) && (!cw->ec->input_only))
1654           w = pw, h = ph;
1655         /* "just do it" for overrides */
1656         evas_object_resize(obj, w, h);
1657      }
1658    if (!cw->ec->override)
1659      {
1660         /* shape probably changed for non-overrides */
1661         if (cw->ec->shaped)
1662           EC_CHANGED(cw->ec);
1663      }
1664
1665    /* this fixes positioning jiggles when using a resize mode
1666     * which also changes the client's position
1667     */
1668    cw->force_move = 1;
1669    if (cw->frame_object)
1670      x = cw->x, y = cw->y;
1671    else
1672      x = cw->ec->x, y = cw->ec->y;
1673    switch (cw->ec->resize_mode)
1674      {
1675       case E_POINTER_RESIZE_BL:
1676       case E_POINTER_RESIZE_L:
1677         evas_object_move(obj, x + prev_w - cw->w, y);
1678         break;
1679       case E_POINTER_RESIZE_TL:
1680         evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1681         break;
1682       case E_POINTER_RESIZE_T:
1683       case E_POINTER_RESIZE_TR:
1684         evas_object_move(obj, x, y + prev_h - cw->h);
1685         break;
1686       default:
1687         break;
1688      }
1689    cw->force_move = 0;
1690 }
1691
1692 static void
1693 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1694 {
1695 #ifdef REFACTOR_DESK_AREA
1696    E_Comp_Object *cw = data;
1697    E_Comp_Object_Data_Set_Layer layer_set_data;
1698
1699    layer_set_data.cw = cw;
1700    layer_set_data.layer = layer;
1701
1702    wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1703
1704    if (cw->visible)
1705      {
1706         e_comp_render_queue();
1707         e_comp_object_transform_obj_stack_update(obj);
1708      }
1709
1710 #else
1711    E_Comp_Object *cw = data;
1712    E_Comp_Wl_Client_Data *child_cdata;
1713    unsigned int l = e_comp_canvas_layer_map(layer);
1714    int oldraise;
1715
1716    if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1717      {
1718         /* doing a compositor effect, follow directions */
1719         _e_comp_object_layer_set(obj, layer);
1720         if (layer == cw->ec->layer) //trying to put layer back
1721           {
1722              E_Client *ec;
1723
1724              /* if ec->layer and layer are the same but the client is not belong to the given(l)
1725                  that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1726              if (cw->layer != l) goto layer_set;
1727
1728              if (cw->visible)
1729                {
1730                   e_comp_render_queue();
1731                }
1732              ec = e_client_above_get(cw->ec);
1733              /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1734              while ((ec) && (e_comp_wl_subsurface_check(ec)))
1735                ec = e_client_above_get(ec);
1736              if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1737                {
1738                   ec = e_client_below_get(cw->ec);
1739                   /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1740                   while ((ec) && (e_comp_wl_subsurface_check(ec)))
1741                     ec = e_client_below_get(ec);
1742                   if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1743                     {
1744                        evas_object_stack_above(obj, ec->frame);
1745                        return;
1746                     }
1747                   ec = NULL;
1748                }
1749              if (ec && (cw->ec->parent == ec))
1750                {
1751                   if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1752                     evas_object_stack_above(obj, ec->frame);
1753                   else
1754                     evas_object_stack_below(obj, ec->frame);
1755                }
1756              else
1757                evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1758           }
1759         return;
1760      }
1761
1762 layer_set:
1763    if (cw->layer == l) return;
1764    if (e_comp_canvas_client_layer_map(layer) == 9999)
1765      return; //invalid layer for clients not doing comp effects
1766    if (cw->ec->fullscreen)
1767      {
1768         cw->ec->saved.layer = layer;
1769         return;
1770      }
1771    oldraise = e_config->transient.raise;
1772
1773    /* clamp to valid client layer */
1774    layer = e_comp_canvas_client_layer_map_nearest(layer);
1775    cw->ec->layer = layer;
1776    if (e_config->transient.layer)
1777      {
1778         E_Client *child;
1779         Eina_List *list = eina_list_clone(cw->ec->transients);
1780
1781         /* We need to set raise to one, else the child wont
1782          * follow to the new layer. It should be like this,
1783          * even if the user usually doesn't want to raise
1784          * the transients.
1785          */
1786         e_config->transient.raise = 1;
1787         EINA_LIST_FREE(list, child)
1788           {
1789              child_cdata = e_client_cdata_get(child);
1790              if (child_cdata && !child_cdata->mapped)
1791                {
1792                   ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1793                   continue;
1794                }
1795              e_client_layer_set(child, layer);
1796           }
1797      }
1798
1799    e_config->transient.raise = oldraise;
1800
1801    _e_comp_object_layers_remove(cw);
1802    cw->layer = e_comp_canvas_layer_map(layer);
1803    _e_comp_object_layers_add(cw, NULL, NULL, 0);
1804    //if (cw->ec->new_client)
1805      //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1806    _e_comp_object_layer_set(obj, layer);
1807    if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1808    evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1809    if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1810      {
1811         /* can't stack a client above its own layer marker */
1812         CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1813      }
1814    if (!cw->visible) return;
1815    e_comp_render_queue();
1816    _e_comp_object_transform_obj_stack_update(obj);
1817 #endif
1818 }
1819
1820 #ifdef REFACTOR_DESK_AREA
1821 #else
1822 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1823 #endif
1824
1825 #ifdef REFACTOR_DESK_AREA
1826 EINTERN void
1827 e_comp_object_raise(Evas_Object *obj)
1828 #else
1829 static void
1830 _e_comp_object_raise(Evas_Object *obj)
1831 #endif
1832 {
1833    evas_object_raise(obj);
1834
1835    if (evas_object_smart_smart_get(obj))
1836      {
1837         E_Client *ec = e_comp_object_client_get(obj);
1838         if (ec)
1839           _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1840      }
1841 }
1842
1843 #ifdef REFACTOR_DESK_AREA
1844 EINTERN void
1845 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1846 #else
1847 static void
1848 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1849 #endif
1850 {
1851    evas_object_lower(obj);
1852
1853    if (evas_object_smart_smart_get(obj))
1854      {
1855         E_Client *ec = e_comp_object_client_get(obj);
1856         if (ec)
1857           {
1858              _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1859 #ifdef REFACTOR_DESK_AREA
1860              wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1861 #else
1862              wl_signal_emit_mutable(&cw->events.lower, NULL);
1863 #endif
1864           }
1865      }
1866 }
1867
1868 #ifdef REFACTOR_DESK_AREA
1869 EINTERN void
1870 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1871 #else
1872 static void
1873 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1874 #endif
1875 {
1876    evas_object_stack_above(obj, target);
1877
1878    if (evas_object_smart_smart_get(obj))
1879      {
1880         E_Client *ec = e_comp_object_client_get(obj);
1881         if (ec)
1882           _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1883      }
1884 }
1885
1886 #ifdef REFACTOR_DESK_AREA
1887 EINTERN void
1888 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1889 #else
1890 static void
1891 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1892 #endif
1893 {
1894    evas_object_stack_below(obj, target);
1895
1896    if (evas_object_smart_smart_get(obj))
1897      {
1898         E_Client *ec = e_comp_object_client_get(obj);
1899         if (ec)
1900           _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1901      }
1902 }
1903
1904 #ifdef REFACTOR_DESK_AREA
1905 EINTERN void
1906 e_comp_object_layer_set(Evas_Object *obj, short layer)
1907 #else
1908 static void
1909 _e_comp_object_layer_set(Evas_Object *obj, short layer)
1910 #endif
1911 {
1912    evas_object_layer_set(obj, layer);
1913
1914    if (evas_object_smart_smart_get(obj))
1915      {
1916         E_Client *ec = e_comp_object_client_get(obj);
1917         if (ec)
1918           _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
1919      }
1920 }
1921
1922 #ifdef REFACTOR_DESK_AREA
1923 #else
1924 static Eina_Bool
1925 _e_comp_object_is_pending(E_Client *ec)
1926 {
1927    E_Client *topmost;
1928
1929    if (!ec) return EINA_FALSE;
1930
1931    topmost = e_comp_wl_topmost_parent_get(ec);
1932
1933    return (topmost) ? topmost->layer_pending : EINA_FALSE;
1934 }
1935
1936 static void
1937 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
1938 {
1939    E_Comp_Object *cw2 = NULL;
1940    E_Client *ecstack;
1941    short layer;
1942    Evas_Object *o = stack;
1943 #ifdef REFACTOR_DESK_AREA
1944    Eina_Bool raising = stack_cb == e_comp_object_stack_above;
1945 #else
1946    Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
1947 #endif
1948
1949    /* We should consider topmost's layer_pending for subsurface */
1950    if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
1951      {
1952         if (_e_comp_object_is_pending(cw->ec))
1953           e_comp_object_layer_update(cw->smart_obj,
1954                                      raising? stack : NULL,
1955                                      raising? NULL : stack);
1956
1957         /* obey compositor effects! */
1958         if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1959           evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
1960         stack_cb(cw->smart_obj, stack);
1961         if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
1962           evas_object_data_del(cw->smart_obj, "client_restack");
1963         return;
1964      }
1965
1966    cw2 = evas_object_data_get(o, "comp_obj");
1967
1968    /* assume someone knew what they were doing during client init */
1969    if (cw->ec->new_client)
1970      layer = cw->ec->layer;
1971    else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
1972      layer = cw2->ec->layer;
1973    else
1974      layer = evas_object_layer_get(stack);
1975    ecstack = e_client_below_get(cw->ec);
1976    if (layer != e_comp_canvas_layer_map_to(cw->layer))
1977      {
1978         evas_object_layer_set(cw->smart_obj, layer);
1979         /* we got our layer wrangled, return now! */
1980         if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
1981      }
1982
1983    /* check if we're stacking below another client */
1984    while (!cw2)
1985      {
1986         /* check for non-client layer object */
1987         if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
1988           break;
1989         /* find an existing client to use for layering
1990          * by walking up the object stack
1991          *
1992          * this is guaranteed to be pretty quick since we'll either:
1993          * - run out of client layers
1994          * - find a stacking client
1995          */
1996         o = evas_object_above_get(o);
1997         if ((!o) || (o == cw->smart_obj)) break;
1998         if (evas_object_layer_get(o) != layer)
1999           {
2000              /* reached the top client layer somehow
2001               * use top client object
2002               */
2003              o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2004           }
2005         if (!o)
2006           /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2007            * return here since the top client layer window
2008            */
2009           {
2010              E_Client *ec;
2011
2012              ec = e_client_top_get();
2013              if (ec)
2014                o = ec->frame;
2015              //else //wat
2016           }
2017         if (o) cw2 = evas_object_data_get(o, "comp_obj");
2018      }
2019
2020    if (cw2 && cw->layer != cw2->layer)
2021      return;
2022
2023    /* remove existing layers */
2024    _e_comp_object_layers_remove(cw);
2025    if (cw2)
2026      {
2027         if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2028           _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2029         else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2030           _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2031         else //if no stacking objects found, either raise or lower
2032           _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2033      }
2034    else
2035      _e_comp_object_layers_add(cw, NULL, NULL, 0);
2036
2037    /* find new object for stacking if cw2 is on state of layer_pending */
2038    if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2039      {
2040         E_Client *new_stack = NULL, *current_ec = NULL;
2041         current_ec = cw2->ec;
2042         if (raising)
2043           {
2044              while ((new_stack = e_client_below_get(current_ec)))
2045                {
2046                   current_ec = new_stack;
2047                   if (new_stack == cw->ec) continue;
2048                   if (new_stack->layer != cw2->ec->layer) break;
2049                   if (!_e_comp_object_is_pending(new_stack)) break;
2050                }
2051              if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2052                stack = new_stack->frame;
2053              else
2054                {
2055                   /* stack it above layer object */
2056                   int below_layer;
2057                   below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2058                   stack = e_comp->layers[below_layer].obj;
2059                }
2060           }
2061         else
2062           {
2063              while ((new_stack = e_client_above_get(current_ec)))
2064                {
2065                   current_ec = new_stack;
2066                   if (new_stack == cw->ec) continue;
2067                   if (new_stack->layer != cw2->ec->layer) break;
2068                   if (!_e_comp_object_is_pending(new_stack)) break;
2069                }
2070              if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2071                stack = new_stack->frame;
2072              else
2073                stack = e_comp->layers[cw2->layer].obj;
2074           }
2075      }
2076
2077    /* set restack if stacking has changed */
2078    if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2079      evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2080    stack_cb(cw->smart_obj, stack);
2081    if (e_comp->layers[cw->layer].obj)
2082      if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2083        {
2084           CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2085        }
2086    if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2087      evas_object_data_del(cw->smart_obj, "client_restack");
2088    if (!cw->visible) return;
2089    e_comp_render_queue();
2090 }
2091 #endif
2092
2093 static void
2094 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2095 {
2096    EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2097
2098    TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2099
2100 #ifdef REFACTOR_DESK_AREA
2101    E_Comp_Object *cw = data;
2102    E_Comp_Object_Data_Stack_Above stack_above_data;
2103
2104    stack_above_data.cw = cw;
2105    stack_above_data.above_obj = above;
2106
2107    wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2108 #else
2109    if (evas_object_below_get(obj) == above)
2110      {
2111         e_comp_object_layer_update(obj, above, NULL);
2112         return;
2113      }
2114
2115    _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2116
2117    _e_comp_object_transform_obj_stack_update(obj);
2118    _e_comp_object_transform_obj_stack_update(above);
2119 #endif
2120
2121    TRACE_DS_END();
2122 }
2123
2124 static void
2125 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2126 {
2127    EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2128
2129    TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2130
2131 #ifdef REFACTOR_DESK_AREA
2132    E_Comp_Object *cw = data;
2133    E_Comp_Object_Data_Stack_Below stack_below_data;
2134
2135    stack_below_data.cw = cw;
2136    stack_below_data.below_obj = below;
2137
2138    wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2139
2140    if (!cw->visible)
2141      e_comp_render_queue();
2142 #else
2143    if (evas_object_above_get(obj) == below)
2144      {
2145         e_comp_object_layer_update(obj, NULL, below);
2146         return;
2147      }
2148
2149    _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2150
2151    if (evas_object_smart_smart_get(obj))
2152      _e_comp_object_transform_obj_stack_update(obj);
2153    if (evas_object_smart_smart_get(below))
2154      _e_comp_object_transform_obj_stack_update(below);
2155 #endif
2156
2157    TRACE_DS_END();
2158 }
2159
2160 static void
2161 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2162 {
2163    E_Comp_Object *cw = data;
2164
2165 #ifdef REFACTOR_DESK_AREA
2166 #else
2167    Evas_Object *o;
2168 #endif
2169
2170    TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2171
2172 #ifdef REFACTOR_DESK_AREA
2173    wl_signal_emit_mutable(&cw->events.lower, cw);
2174 #else
2175    if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2176      {
2177         if (cw->ec->layer_pending)
2178           e_comp_object_layer_update(obj, NULL, obj);
2179
2180 #ifdef REFACTOR_DESK_AREA
2181         e_comp_object_lower(cw, obj);
2182 #else
2183         _e_comp_object_lower(cw, obj);
2184 #endif
2185         goto end;
2186      }
2187    if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2188    o = evas_object_below_get(obj);
2189    _e_comp_object_layers_remove(cw);
2190    /* prepend to client list since this client should be the first item now */
2191    _e_comp_object_layers_add(cw, NULL, NULL, 1);
2192    if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2193    evas_object_data_set(obj, "client_restack", (void*)1);
2194 #ifdef REFACTOR_DESK_AREA
2195    e_comp_object_lower(cw, obj);
2196 #else
2197    _e_comp_object_lower(cw, obj);
2198 #endif
2199    evas_object_data_del(obj, "client_restack");
2200    if (!cw->visible) goto end;
2201    e_comp_render_queue();
2202 #ifdef REFACTOR_DESK_AREA
2203    e_comp_object_transform_obj_stack_update(obj);
2204 #else
2205    _e_comp_object_transform_obj_stack_update(obj);
2206 #endif
2207
2208 end:
2209 #endif
2210    TRACE_DS_END();
2211 }
2212
2213 static void
2214 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2215 {
2216    E_Comp_Object *cw = data;
2217 #ifdef REFACTOR_DESK_AREA
2218 #else
2219    Evas_Object *o;
2220    Evas_Object *op;
2221 #endif
2222
2223    TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2224
2225 #ifdef REFACTOR_DESK_AREA
2226    wl_signal_emit_mutable(&cw->events.raise, cw);
2227 #else
2228    if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2229      {
2230         if (cw->ec->layer_pending)
2231           {
2232              int obj_layer = evas_object_layer_get(obj);
2233              if (cw->ec->layer != obj_layer)
2234                e_comp_object_layer_update(obj, NULL, NULL);
2235           }
2236 #ifdef REFACTOR_DESK_AREA
2237         e_comp_object_raise(obj);
2238 #else
2239         _e_comp_object_raise(obj);
2240 #endif
2241         goto end;
2242      }
2243    if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2244    o = evas_object_above_get(obj);
2245    if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2246
2247    /* still stack below override below the layer marker */
2248    for (op = o = e_comp->layers[cw->layer].obj;
2249         o && o != e_comp->layers[cw->layer - 1].obj;
2250         op = o, o = evas_object_below_get(o))
2251      {
2252         if (evas_object_smart_smart_get(o))
2253           {
2254              E_Client *ec;
2255
2256              ec = e_comp_object_client_get(o);
2257              if (ec && (!ec->override)) break;
2258           }
2259      }
2260 #ifdef REFACTOR_DESK_AREA
2261    e_comp_object_stack_below(obj, op);
2262 #else
2263    _e_comp_object_stack_below(obj, op);
2264 #endif
2265    e_client_focus_defer_set(cw->ec);
2266
2267    if (!cw->visible) goto end;
2268    e_comp_render_queue();
2269 #ifdef REFACTOR_DESK_AREA
2270    e_comp_object_transform_obj_stack_update(obj);
2271 #else
2272    _e_comp_object_transform_obj_stack_update(obj);
2273 #endif
2274
2275 end:
2276 #endif
2277    TRACE_DS_END();
2278 }
2279
2280 static void
2281 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2282 {
2283    E_Comp_Object *cw = data;
2284
2285 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2286    if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2287      {
2288         ELOGF("COMP", "Hide. intercepted", cw->ec);
2289         return;
2290      }
2291 #endif
2292
2293    if (cw->ec->launching == EINA_TRUE)
2294      {
2295         ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2296         cw->ec->launching = EINA_FALSE;
2297      }
2298
2299    if (cw->ec->hidden)
2300      {
2301         /* hidden flag = just do it */
2302         ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2303         evas_object_hide(obj);
2304
2305         wl_signal_emit_mutable(&cw->events.hide, NULL);
2306
2307         return;
2308      }
2309
2310    if (cw->ec->input_only)
2311      {
2312         /* input_only = who cares */
2313         ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2314         evas_object_hide(obj);
2315
2316         wl_signal_emit_mutable(&cw->events.hide, NULL);
2317
2318         return;
2319      }
2320    /* already hidden or currently animating */
2321    if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2322      {
2323         ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2324         return;
2325      }
2326
2327    /* don't try hiding during shutdown */
2328    cw->defer_hide |= stopping;
2329    if (!cw->defer_hide)
2330      {
2331         if ((!cw->ec->iconic) && (!cw->ec->override))
2332           /* unset delete requested so the client doesn't break */
2333           cw->ec->delete_requested = 0;
2334         if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2335           {
2336              ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2337                    cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2338
2339              if (cw->ec->iconic)
2340                e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2341              else
2342                {
2343                   e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2344                   if (!cw->showing)
2345                     _e_comp_object_animating_begin(cw);
2346                   if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2347                }
2348              evas_object_smart_callback_call(obj, "hiding", cw->ec);
2349              cw->defer_hide = !!cw->animating;
2350              if (!cw->animating)
2351                e_comp_object_effect_set(obj, NULL);
2352           }
2353      }
2354    if (cw->animating) return;
2355    /* if we have no animations running, go ahead and hide */
2356    cw->defer_hide = 0;
2357    ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2358    evas_object_hide(obj);
2359
2360    wl_signal_emit_mutable(&cw->events.hide, NULL);
2361 }
2362
2363 static void
2364 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2365 {
2366    E_Client *ec = cw->ec;
2367    int w = 0, h = 0;
2368
2369    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2370
2371    if (ec->show_pending.count > 0)
2372      {
2373         ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2374         ec->show_pending.running = EINA_TRUE;
2375         return;
2376      }
2377
2378 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2379    if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2380      {
2381         ELOGF("COMP", "show_helper. intercepted", cw->ec);
2382         return;
2383      }
2384 #endif
2385
2386    ELOGF("COMP", "show_helper. cw(v:%d,a:%d,dh:%d,ct:%d,u:%p,s(%d,%d)), ec(i:%d(%d,%d),o:%d,g:%d,n:%d)", ec,
2387          cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2388          ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2389
2390    if (ec->sticky)
2391      e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2392    if (cw->visible)
2393      {
2394         if (ec->iconic && cw->animating)
2395           {
2396              /* triggered during iconify animation */
2397              e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2398              cw->defer_hide = 0;
2399           }
2400         ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2401         return;
2402      }
2403    if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2404        cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2405      {
2406         evas_object_move(cw->smart_obj, ec->x, ec->y);
2407         evas_object_resize(cw->smart_obj, ec->w, ec->h);
2408         e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2409
2410         if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2411           e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2412
2413         cw->real_hid = 0;
2414         ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2415         evas_object_show(cw->smart_obj);
2416
2417         if (!ec->iconic)
2418           e_client_focus_defer_set(ec);
2419
2420         return;
2421      }
2422    if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2423      {
2424         int pw, ph;
2425
2426         pw = ec->client.w, ph = ec->client.h;
2427         if ((!pw) || (!ph))
2428           if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2429             {
2430                ec->changes.visible = !ec->hidden;
2431                ec->visible = 1;
2432                EC_CHANGED(ec);
2433                ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2434                return;
2435             }
2436
2437         cw->updates = eina_tiler_new(pw, ph);
2438         if (!cw->updates)
2439           {
2440              ec->changes.visible = !ec->hidden;
2441              ec->visible = 1;
2442              EC_CHANGED(ec);
2443              ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2444              return;
2445           }
2446      }
2447    if (cw->updates)
2448      eina_tiler_tile_size_set(cw->updates, 1, 1);
2449    if (ec->new_client)
2450      {
2451         /* ignore until client idler first run */
2452         ec->changes.visible = !ec->hidden;
2453         ec->visible = 1;
2454         EC_CHANGED(ec);
2455         ELOGF("COMP", "show_helper. return. new_client", ec);
2456         return;
2457      }
2458    if (ec->input_only)
2459      {
2460         /* who cares */
2461         cw->real_hid = 0;
2462         evas_object_move(cw->smart_obj, ec->x, ec->y);
2463         evas_object_resize(cw->smart_obj, ec->w, ec->h);
2464         ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2465         evas_object_show(cw->smart_obj);
2466         return;
2467      }
2468    if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2469      {
2470         /* start_drag not received */
2471         ec->changes.visible = 1;
2472         ec->visible = 1;
2473         EC_CHANGED(ec);
2474         ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2475         return;
2476      }
2477    /* re-set geometry */
2478    evas_object_move(cw->smart_obj, ec->x, ec->y);
2479    /* force resize in case it hasn't happened yet, or just to update size */
2480    evas_object_resize(cw->smart_obj, ec->w, ec->h);
2481    if ((cw->w < 1) || (cw->h < 1))
2482      {
2483         /* if resize didn't go through, try again */
2484         ec->visible = ec->changes.visible = 1;
2485         EC_CHANGED(ec);
2486         ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2487         return;
2488      }
2489    /* if pixmap not available, clear pixmap since we're going to fetch it again */
2490    if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2491      e_pixmap_clear(ec->pixmap);
2492
2493    if (cw->real_hid && w && h)
2494      {
2495         cw->real_hid = 0;
2496         /* force comp theming in case it didn't happen already */
2497         e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2498         if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2499           e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2500      }
2501
2502    /* only do the show if show is allowed */
2503    if (!cw->real_hid)
2504      {
2505         if (ec->internal) //internal clients render when they feel like it
2506           e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2507
2508         if (!e_client_is_iconified_by_client(ec)||
2509             e_policy_visibility_client_is_uniconic(ec))
2510           {
2511              ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2512              evas_object_show(cw->smart_obj);
2513
2514              /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2515                 it is rendered in idle callback without native surface and
2516                 compositor shows an empty frame if other objects aren't shown
2517                 because job callback of e_comp called at the next loop.
2518                 it causes a visual defect when windows are switched.
2519               */
2520              if (cw->redirected)
2521                {
2522                   e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2523                   e_comp_object_dirty(cw->smart_obj);
2524                   e_comp_object_render(cw->smart_obj);
2525                }
2526           }
2527      }
2528
2529    wl_signal_emit_mutable(&cw->events.show, NULL);
2530 }
2531
2532 static void
2533 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2534 {
2535    E_Comp_Object *cw = data;
2536    E_Client *ec = cw->ec;
2537    Eina_List *l;
2538    E_Input_Rect_Data *input_rect_data;
2539    E_Input_Rect_Smart_Data *input_rect_sd;
2540    int tw, th;
2541
2542    if (ec->ignored) return;
2543
2544    if (cw->effect_obj)
2545      {
2546         //INF("SHOW2 %p", ec);
2547         _e_comp_intercept_show_helper(cw);
2548         return;
2549      }
2550    //INF("SHOW %p", ec);
2551    if (ec->input_only)
2552      {
2553         cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2554         evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2555         evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2556         evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2557      }
2558    else
2559      {
2560         if ((!cw->obj) && (cw->external_content))
2561           {
2562              ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2563              return;
2564           }
2565
2566         _e_comp_object_setup(cw);
2567         if (!cw->obj)
2568           {
2569              cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2570              cw->obj = evas_object_image_filled_add(e_comp->evas);
2571              evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2572              e_util_size_debug_set(cw->obj, 1);
2573              evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2574              evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2575              evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2576              evas_object_name_set(cw->obj, "cw->obj");
2577              evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2578           }
2579         _e_comp_object_alpha_set(cw);
2580
2581         cw->redirected = 1;
2582         evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2583      }
2584
2585    _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2586    evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2587    if (cw->input_obj)
2588      {
2589         input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2590         if (input_rect_sd)
2591           {
2592              EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2593                {
2594                   if (input_rect_data->obj)
2595                     {
2596                        evas_object_geometry_set(input_rect_data->obj,
2597                          cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2598                          cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2599                          input_rect_data->rect.w, input_rect_data->rect.h);
2600                     }
2601                }
2602           }
2603      }
2604
2605    if (cw->mask.obj)
2606      evas_object_resize(cw->mask.obj, cw->w, cw->h);
2607
2608    _e_comp_intercept_show_helper(cw);
2609 }
2610
2611 static void
2612 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2613 {
2614    E_Comp_Object *cw = data;
2615    E_Client *ec;
2616
2617    ec = cw->ec;
2618    /* note: this is here as it seems there are enough apps that do not even
2619     * expect us to emulate a look of focus but not actually set x input
2620     * focus as we do - so simply abort any focus set on such windows */
2621    /* be strict about accepting focus hint */
2622    /* be strict about accepting focus hint */
2623    if ((!ec->icccm.accepts_focus) &&
2624        (!ec->icccm.take_focus))
2625      {
2626         if (!focus)
2627           {
2628              if (e_client_focused_get() == ec)
2629                 e_client_focused_set(NULL);
2630
2631              ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2632              evas_object_focus_set(obj, focus);
2633           }
2634         return;
2635      }
2636    if (focus && ec->lock_focus_out) return;
2637    if (e_object_is_del(E_OBJECT(ec)) && focus)
2638      CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2639
2640    /* filter focus setting based on current state */
2641    if (focus)
2642      {
2643         if (ec->focused)
2644           {
2645              ELOGF("FOCUS", "FOCUS SET   | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2646              evas_object_focus_set(obj, focus);
2647              return;
2648           }
2649         if ((ec->iconic) && (!ec->deskshow))
2650           {
2651              if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2652                {
2653                   /* don't focus an iconified window. that's silly! */
2654                   ELOGF("FOCUS", "Do uniconify to set focus", ec);
2655                   e_client_uniconify(ec);
2656                   e_client_focus_latest_set(ec);
2657                   return;
2658                }
2659           }
2660         if (!ec->visible)
2661           {
2662              return;
2663           }
2664      }
2665
2666    if (focus)
2667      {
2668         if (!cw->visible)
2669           {
2670              /* not yet visible, wait till the next time... */
2671              ec->want_focus = !ec->hidden;
2672              if (ec->want_focus)
2673                EC_CHANGED(ec);
2674              return;
2675           }
2676         e_client_focused_set(ec);
2677      }
2678    else
2679      {
2680         if (e_client_focused_get() == ec)
2681           e_client_focused_set(NULL);
2682      }
2683
2684    if (focus)
2685      ELOGF("FOCUS", "FOCUS SET   | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2686    else
2687      ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2688
2689    evas_object_focus_set(obj, focus);
2690 }
2691
2692 static void
2693 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2694 {
2695    E_Comp_Object *cw = data;
2696
2697    if (cw->transparent.set)
2698      {
2699         cw->transparent.user_r = r;
2700         cw->transparent.user_g = g;
2701         cw->transparent.user_b = b;
2702         cw->transparent.user_a = a;
2703
2704         ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2705               cw->ec,
2706               cw->transparent.user_r,
2707               cw->transparent.user_g,
2708               cw->transparent.user_b,
2709               cw->transparent.user_a);
2710      }
2711    else
2712      {
2713         evas_object_color_set(obj, r, g, b, a);
2714      }
2715
2716    wl_signal_emit_mutable(&cw->events.color_set, NULL);
2717 }
2718 ////////////////////////////////////////////////////
2719
2720 static void
2721 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2722 {
2723    int w, h, ox, oy, ow, oh;
2724    Eina_List *l;
2725    Eina_Bool pass_event_flag = EINA_FALSE;
2726    E_Input_Rect_Data *input_rect_data;
2727    E_Input_Rect_Smart_Data *input_rect_sd;
2728
2729    if (cw->frame_object)
2730      {
2731         if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2732         evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2733         /* set a fixed size, force edje calc, check size difference */
2734         evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2735         edje_object_message_signal_process(cw->frame_object);
2736         edje_object_calc_force(cw->frame_object);
2737         edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2738         cw->client_inset.l = ox;
2739         cw->client_inset.r = MAX(w, 50) - (ox + ow);
2740         cw->client_inset.t = oy;
2741         cw->client_inset.b = MAX(h, 50) - (oy + oh);
2742         if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2743         evas_object_resize(cw->frame_object, w, h);
2744
2745         if (cw->input_obj)
2746           {
2747              input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2748              if (input_rect_sd)
2749                {
2750                   EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2751                     {
2752                        if (input_rect_data->obj)
2753                          {
2754                             pass_event_flag = EINA_TRUE;
2755                             break;
2756                          }
2757                     }
2758                }
2759           }
2760         evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2761         evas_object_pass_events_set(cw->obj, pass_event_flag);
2762      }
2763    else
2764      {
2765         cw->client_inset.l = 0;
2766         cw->client_inset.r = 0;
2767         cw->client_inset.t = 0;
2768         cw->client_inset.b = 0;
2769      }
2770    cw->client_inset.calc = !!cw->frame_object;
2771 }
2772
2773 static void
2774 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2775 {
2776    E_Comp_Object *cw = data;
2777    E_Zone *zone;
2778    int w, h, pw, ph;
2779
2780    /* - get current size
2781     * - calc new size
2782     * - readjust for new frame size
2783     */
2784
2785    w = cw->ec->w, h = cw->ec->h;
2786    e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2787
2788    _e_comp_object_frame_recalc(cw);
2789
2790    if (!cw->ec->fullscreen)
2791      e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2792
2793    evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2794    if (cw->ec->fullscreen)
2795      {
2796         zone = e_comp_zone_find_by_ec(cw->ec);
2797         if (!zone) return;
2798         evas_object_resize(cw->ec->frame, zone->w, zone->h);
2799      }
2800    else if (cw->ec->new_client)
2801      {
2802         if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2803         e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2804         evas_object_resize(cw->ec->frame, w, h);
2805      }
2806    else if ((w != cw->ec->w) || (h != cw->ec->h))
2807      evas_object_resize(cw->ec->frame, w, h);
2808 }
2809
2810 static void
2811 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2812 {
2813    E_Comp_Object *cw = data;
2814
2815    _e_comp_object_shadow_setup(cw);
2816    if (cw->frame_object)
2817      {
2818         _e_comp_object_shadow(cw);
2819         e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2820         _e_comp_object_frame_recalc(cw);
2821         evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2822      }
2823 }
2824
2825 static void
2826 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2827 {
2828    E_Comp_Object *cw = data;
2829
2830    if (_e_comp_object_shadow_setup(cw))
2831      e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2832    if (cw->frame_object)
2833      {
2834         _e_comp_object_shadow(cw);
2835         e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2836         _e_comp_object_frame_recalc(cw);
2837         evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2838      }
2839 }
2840
2841 static void
2842 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2843 {
2844    E_Comp_Object *cw = data;
2845
2846    if (cw->frame_object)
2847      {
2848         _e_comp_object_shadow(cw);
2849         e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2850         _e_comp_object_frame_recalc(cw);
2851         evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2852      }
2853 }
2854
2855 static void
2856 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2857 {
2858    E_Comp_Object *cw = data;
2859
2860    if (_e_comp_object_shadow_setup(cw))
2861      {
2862         EC_CHANGED(cw->ec);
2863         cw->ec->changes.size = 1;
2864      }
2865    if (cw->frame_object)
2866      {
2867         _e_comp_object_shadow(cw);
2868         e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2869         _e_comp_object_frame_recalc(cw);
2870         evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2871      }
2872 }
2873
2874 static void
2875 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2876 {
2877    e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2878 }
2879
2880 static void
2881 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2882 {
2883    e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2884 }
2885
2886 static void
2887 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2888 {
2889    E_Comp_Object *cw = data;
2890
2891    if (!cw->ec) return; //NYI
2892    e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2893 }
2894
2895 static void
2896 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2897 {
2898    E_Comp_Object *cw = data;
2899
2900    if (!cw->ec) return; //NYI
2901    e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2902 }
2903
2904 static void
2905 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2906 {
2907    e_comp_object_signal_emit(obj, "e,state,focused", "e");
2908 }
2909
2910 static void
2911 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2912 {
2913    E_Comp_Object *cw = data;
2914
2915    if (!e_object_is_del(E_OBJECT(cw->ec)))
2916      e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
2917 }
2918
2919 static void
2920 _e_comp_input_obj_smart_add(Evas_Object *obj)
2921 {
2922    E_Input_Rect_Smart_Data *input_rect_sd;
2923    input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
2924
2925    if (!input_rect_sd) return;
2926    evas_object_smart_data_set(obj, input_rect_sd);
2927 }
2928
2929 static void
2930 _e_comp_input_obj_smart_del(Evas_Object *obj)
2931 {
2932    E_Input_Rect_Smart_Data *input_rect_sd;
2933    E_Input_Rect_Data *input_rect_data;
2934
2935    input_rect_sd = evas_object_smart_data_get(obj);
2936    if (!input_rect_sd) return;
2937
2938    EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
2939      {
2940         if (input_rect_data->obj)
2941           {
2942              evas_object_smart_member_del(input_rect_data->obj);
2943              E_FREE_FUNC(input_rect_data->obj, evas_object_del);
2944           }
2945         E_FREE(input_rect_data);
2946      }
2947    E_FREE(input_rect_sd);
2948 }
2949
2950 static void
2951 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
2952 {
2953    E_Input_Rect_Smart_Data *input_rect_sd;
2954    E_Input_Rect_Data *input_rect_data;
2955    Eina_List *l;
2956    E_Comp_Object *cw;
2957
2958    input_rect_sd = evas_object_smart_data_get(obj);
2959    if (!input_rect_sd) return;
2960
2961    cw = input_rect_sd->cw;
2962    EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2963      {
2964         if (input_rect_data->obj)
2965           {
2966              evas_object_geometry_set(input_rect_data->obj,
2967                x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2968                y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2969                input_rect_data->rect.w, input_rect_data->rect.h);
2970           }
2971      }
2972 }
2973
2974 static void
2975 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
2976 {
2977    E_Input_Rect_Smart_Data *input_rect_sd;
2978    E_Input_Rect_Data *input_rect_data;
2979    Eina_List *l;
2980    E_Comp_Object *cw;
2981
2982    input_rect_sd = evas_object_smart_data_get(obj);
2983    if (!input_rect_sd) return;
2984
2985    cw = input_rect_sd->cw;
2986    EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2987      {
2988         if (input_rect_data->obj)
2989           {
2990              evas_object_geometry_set(input_rect_data->obj,
2991                cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2992                cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2993                input_rect_data->rect.w, input_rect_data->rect.h);
2994           }
2995      }
2996 }
2997
2998 static void
2999 _e_comp_input_obj_smart_show(Evas_Object *obj)
3000 {
3001    E_Input_Rect_Smart_Data *input_rect_sd;
3002    E_Input_Rect_Data *input_rect_data;
3003    Eina_List *l;
3004
3005    input_rect_sd = evas_object_smart_data_get(obj);
3006    if (!input_rect_sd) return;
3007
3008    EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3009      {
3010         if (input_rect_data->obj)
3011           {
3012              evas_object_show(input_rect_data->obj);
3013           }
3014      }
3015 }
3016
3017 static void
3018 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3019 {
3020    E_Input_Rect_Smart_Data *input_rect_sd;
3021    E_Input_Rect_Data *input_rect_data;
3022    Eina_List *l;
3023
3024    input_rect_sd = evas_object_smart_data_get(obj);
3025    if (!input_rect_sd) return;
3026
3027    EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3028      {
3029         if (input_rect_data->obj)
3030           {
3031              evas_object_hide(input_rect_data->obj);
3032           }
3033      }
3034 }
3035
3036 static void
3037 _e_comp_input_obj_smart_init(void)
3038 {
3039    if (_e_comp_input_obj_smart) return;
3040    {
3041       static const Evas_Smart_Class sc =
3042       {
3043          INPUT_OBJ_SMART_NAME,
3044          EVAS_SMART_CLASS_VERSION,
3045          _e_comp_input_obj_smart_add,
3046          _e_comp_input_obj_smart_del,
3047          _e_comp_input_obj_smart_move,
3048          _e_comp_input_obj_smart_resize,
3049          _e_comp_input_obj_smart_show,
3050          _e_comp_input_obj_smart_hide,
3051          NULL,
3052          NULL,
3053          NULL,
3054          NULL,
3055          NULL,
3056          NULL,
3057
3058          NULL,
3059          NULL,
3060          NULL,
3061          NULL
3062       };
3063       _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3064    }
3065 }
3066
3067
3068 static void
3069 _e_comp_smart_add(Evas_Object *obj)
3070 {
3071    E_Comp_Object *cw;
3072
3073    cw = E_NEW(E_Comp_Object, 1);
3074    EINA_SAFETY_ON_NULL_RETURN(cw);
3075
3076    wl_signal_init(&cw->events.lower);
3077 #ifdef REFACTOR_DESK_AREA
3078    wl_signal_init(&cw->events.lower_done);
3079    wl_signal_init(&cw->events.raise);
3080 #endif
3081    wl_signal_init(&cw->events.show);
3082    wl_signal_init(&cw->events.hide);
3083 #ifdef REFACTOR_DESK_AREA
3084    wl_signal_init(&cw->events.set_layer);
3085    wl_signal_init(&cw->events.stack_above);
3086    wl_signal_init(&cw->events.stack_below);
3087 #endif
3088    wl_signal_init(&cw->events.image_filter_set);
3089    wl_signal_init(&cw->events.render_op_set);
3090    wl_signal_init(&cw->events.content_type_set);
3091    wl_signal_init(&cw->events.color_set);
3092
3093    cw->smart_obj = obj;
3094    cw->x = cw->y = cw->w = cw->h = -1;
3095    evas_object_smart_data_set(obj, cw);
3096    cw->opacity = 255.0;
3097    cw->external_content = 0;
3098    cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3099    cw->transform_bg_color.r = 0;
3100    cw->transform_bg_color.g = 0;
3101    cw->transform_bg_color.b = 0;
3102    cw->transform_bg_color.a = 255;
3103    evas_object_data_set(obj, "comp_obj", cw);
3104    evas_object_move(obj, -1, -1);
3105    /* intercept ALL the callbacks! */
3106    evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3107    evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3108    evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3109    evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3110    evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3111    evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3112    evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3113    evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3114    evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3115    evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3116    evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3117
3118    evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3119    evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3120    evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3121    evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3122
3123    evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3124    evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3125
3126    evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3127    evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3128
3129    evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3130
3131    evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3132    evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3133 }
3134
3135 static void
3136 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3137 {
3138    INTERNAL_ENTRY;
3139    evas_object_color_set(cw->clip, r, g, b, a);
3140    evas_object_smart_callback_call(obj, "color_set", NULL);
3141 }
3142
3143
3144 static void
3145 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3146 {
3147    INTERNAL_ENTRY;
3148    evas_object_clip_set(cw->clip, clip);
3149 }
3150
3151 static void
3152 _e_comp_smart_clip_unset(Evas_Object *obj)
3153 {
3154    INTERNAL_ENTRY;
3155    evas_object_clip_unset(cw->clip);
3156 }
3157
3158 static void
3159 _e_comp_smart_hide(Evas_Object *obj)
3160 {
3161    TRACE_DS_BEGIN(COMP:SMART HIDE);
3162
3163    INTERNAL_ENTRY;
3164    cw->visible = 0;
3165    cw->hiding = 0;
3166    evas_object_hide(cw->clip);
3167    if (cw->input_obj) evas_object_hide(cw->input_obj);
3168    evas_object_hide(cw->effect_obj);
3169    if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3170    if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3171    if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3172    if (stopping)
3173      {
3174         TRACE_DS_END();
3175         return;
3176      }
3177
3178    /* unset native surface if current displaying buffer was destroied */
3179    if (!cw->buffer_destroy_listener.notify)
3180      {
3181         Evas_Native_Surface *ns;
3182         ns = evas_object_image_native_surface_get(cw->obj);
3183         if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3184           _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3185      }
3186
3187    if (!cw->ec->input_only)
3188      {
3189         edje_object_freeze(cw->effect_obj);
3190         edje_object_freeze(cw->shobj);
3191         edje_object_play_set(cw->shobj, 0);
3192         if (cw->frame_object)
3193           edje_object_play_set(cw->frame_object, 0);
3194      }
3195
3196    e_comp_render_queue(); //force nocomp recheck
3197
3198    TRACE_DS_END();
3199 }
3200
3201 static void
3202 _e_comp_smart_show(Evas_Object *obj)
3203 {
3204    E_Client *tmp;
3205    Eina_List *l;
3206
3207    INTERNAL_ENTRY;
3208    cw->defer_hide = 0;
3209    cw->visible = 1;
3210    if ((cw->w < 0) || (cw->h < 0))
3211      CRI("ACK! ec:%p", cw->ec);
3212
3213    TRACE_DS_BEGIN(COMP:SMART SHOW);
3214
3215    e_comp_object_map_update(obj);
3216
3217    EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3218      evas_object_show(tmp->frame);
3219
3220    evas_object_show(cw->clip);
3221    if (cw->input_obj) evas_object_show(cw->input_obj);
3222    if (!cw->ec->input_only)
3223      {
3224         edje_object_thaw(cw->effect_obj);
3225         edje_object_thaw(cw->shobj);
3226         edje_object_play_set(cw->shobj, 1);
3227         if (cw->frame_object)
3228           edje_object_play_set(cw->frame_object, 1);
3229      }
3230    evas_object_show(cw->effect_obj);
3231    if (cw->mask.obj) evas_object_show(cw->mask.obj);
3232    if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3233    if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3234    if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3235    e_comp_render_queue();
3236    if (cw->ec->input_only)
3237      {
3238         TRACE_DS_END();
3239         return;
3240      }
3241    if (cw->ec->iconic && (!cw->ec->new_client))
3242      {
3243         if (e_client_is_iconified_by_client(cw->ec))
3244           {
3245              ELOGF("COMP", "Set launching flag..", cw->ec);
3246              cw->ec->launching = EINA_TRUE;
3247           }
3248
3249         e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3250      }
3251    else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3252      {
3253         cw->showing = 1;
3254         ELOGF("COMP", "Set launching flag..", cw->ec);
3255         cw->ec->launching = EINA_TRUE;
3256
3257         e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3258         _e_comp_object_animating_begin(cw);
3259         if (!_e_comp_object_effect_visibility_start(cw, 1))
3260           {
3261              TRACE_DS_END();
3262              return;
3263           }
3264      }
3265    /* ensure some random effect doesn't lock the client offscreen */
3266    if (!cw->animating)
3267      {
3268         cw->showing = 0;
3269         e_comp_object_effect_set(obj, NULL);
3270      }
3271
3272    _e_comp_object_dim_update(cw);
3273
3274    TRACE_DS_END();
3275 }
3276
3277 static void
3278 _e_comp_smart_del(Evas_Object *obj)
3279 {
3280    Eina_List *l;
3281
3282    INTERNAL_ENTRY;
3283
3284    if (cw->buffer_destroy_listener.notify)
3285      {
3286         wl_list_remove(&cw->buffer_destroy_listener.link);
3287         cw->buffer_destroy_listener.notify = NULL;
3288      }
3289
3290    if (cw->tbm_surface)
3291      {
3292         tbm_surface_internal_unref(cw->tbm_surface);
3293         cw->tbm_surface = NULL;
3294      }
3295
3296    if (cw->render_update_lock.buffer_ref.buffer)
3297      {
3298         ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3299               cw->ec, cw->render_update_lock.lock);
3300         e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3301      }
3302
3303    e_comp_object_render_update_del(cw->smart_obj);
3304    E_FREE_FUNC(cw->updates, eina_tiler_free);
3305    E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3306    free(cw->ns);
3307
3308    if (cw->obj_mirror)
3309      {
3310         Evas_Object *o;
3311
3312         EINA_LIST_FREE(cw->obj_mirror, o)
3313           {
3314              evas_object_image_data_set(o, NULL);
3315              evas_object_freeze_events_set(o, 1);
3316              evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3317              evas_object_del(o);
3318           }
3319      }
3320 #ifdef REFACTOR_DESK_AREA
3321 #else
3322    _e_comp_object_layers_remove(cw);
3323 #endif
3324    l = evas_object_data_get(obj, "comp_object-to_del");
3325    E_FREE_LIST(l, evas_object_del);
3326    _e_comp_object_mouse_event_callback_unset(cw);
3327    evas_object_del(cw->clip);
3328    evas_object_del(cw->obj);
3329    evas_object_del(cw->shobj);
3330    evas_object_del(cw->effect_obj);
3331    evas_object_del(cw->frame_object);
3332    evas_object_del(cw->input_obj);
3333    evas_object_del(cw->mask.obj);
3334    if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3335    evas_object_del(cw->transform_bg_obj);
3336    evas_object_del(cw->transform_tranp_obj);
3337    evas_object_del(cw->default_input_obj);
3338    eina_stringshare_del(cw->frame_theme);
3339    eina_stringshare_del(cw->frame_name);
3340    if (cw->animating)
3341      {
3342         cw->animating = 0;
3343         e_comp->animating--;
3344         UNREFD(cw->ec, 2);
3345         e_object_unref(E_OBJECT(cw->ec));
3346      }
3347    cw->ec->frame = NULL;
3348    free(cw);
3349 }
3350
3351 static void
3352 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3353 {
3354    INTERNAL_ENTRY;
3355
3356    cw->x = x, cw->y = y;
3357    evas_object_move(cw->effect_obj, x, y);
3358    evas_object_move(cw->default_input_obj, x, y);
3359    if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3360
3361    e_comp_object_map_update(obj);
3362 }
3363
3364 static void
3365 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3366 {
3367    Eina_Bool first = EINA_FALSE;
3368    int tw, th;
3369
3370    INTERNAL_ENTRY;
3371
3372    if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3373
3374    TRACE_DS_BEGIN(COMP:SMART RESIZE);
3375
3376    _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3377
3378    if (cw->w != w || cw->h != h)
3379      e_comp_object_map_update(obj);
3380
3381    first = ((cw->w < 1) || (cw->h < 1));
3382    cw->w = w, cw->h = h;
3383
3384    int ww, hh, pw, ph;
3385
3386    if (cw->frame_object)
3387      e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3388    else
3389      ww = w, hh = h;
3390    /* verify pixmap:object size */
3391    if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3392      {
3393         if ((ww != pw) || (hh != ph))
3394           ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3395      }
3396    evas_object_resize(cw->effect_obj, tw, th);
3397    evas_object_resize(cw->default_input_obj, w, h);
3398    if (cw->input_obj)
3399      evas_object_resize(cw->input_obj, w, h);
3400    if (cw->mask.obj)
3401      evas_object_resize(cw->mask.obj, w, h);
3402    /* resize render update tiler */
3403    if (!first)
3404      {
3405         RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3406         cw->updates_full = 0;
3407         if (cw->updates) eina_tiler_clear(cw->updates);
3408      }
3409    else
3410      {
3411         RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3412         if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3413      }
3414
3415    if (!cw->visible)
3416      {
3417         TRACE_DS_END();
3418         return;
3419      }
3420    e_comp_render_queue();
3421
3422    TRACE_DS_END();
3423 }
3424
3425 static void
3426 _e_comp_smart_init(void)
3427 {
3428    if (_e_comp_smart) return;
3429    {
3430       static const Evas_Smart_Class sc =
3431       {
3432          SMART_NAME,
3433          EVAS_SMART_CLASS_VERSION,
3434          _e_comp_smart_add,
3435          _e_comp_smart_del,
3436          _e_comp_smart_move,
3437          _e_comp_smart_resize,
3438          _e_comp_smart_show,
3439          _e_comp_smart_hide,
3440          _e_comp_smart_color_set,
3441          _e_comp_smart_clip_set,
3442          _e_comp_smart_clip_unset,
3443          NULL,
3444          NULL,
3445          NULL,
3446
3447          NULL,
3448          NULL,
3449          NULL,
3450          NULL
3451       };
3452       _e_comp_smart = evas_smart_class_new(&sc);
3453    }
3454 }
3455
3456 EINTERN void
3457 e_comp_object_init(void)
3458 {
3459    E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3460    E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3461    E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3462    E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3463 }
3464
3465 EINTERN void
3466 e_comp_object_shutdown(void)
3467 {
3468
3469 }
3470
3471 EINTERN Eina_Bool
3472 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3473 {
3474    API_ENTRY EINA_FALSE;
3475    return !!cw->force_visible;
3476 }
3477 /////////////////////////////////////////////////////////
3478
3479 static void
3480 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3481 {
3482    Eina_List *l;
3483    Eina_Bool comp_object;
3484
3485    comp_object = !!evas_object_data_get(obj, "comp_object");
3486    if (comp_object)
3487      {
3488         Evas_Object *o;
3489
3490         o = edje_object_part_swallow_get(obj, "e.swallow.content");
3491         evas_object_del(o);
3492         e_comp_render_queue();
3493      }
3494    l = evas_object_data_get(obj, "comp_object-to_del");
3495    E_FREE_LIST(l, evas_object_del);
3496 }
3497
3498 static void
3499 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3500 {
3501    if (e_comp_util_object_is_above_nocomp(obj) &&
3502        (!evas_object_data_get(obj, "comp_override")))
3503      {
3504         evas_object_data_set(obj, "comp_override", (void*)1);
3505         e_comp_override_add();
3506      }
3507 }
3508
3509 static void
3510 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3511 {
3512    Eina_Bool ref = EINA_TRUE;
3513    if (evas_object_visible_get(obj))
3514      {
3515         void *d;
3516
3517         d = evas_object_data_del(obj, "comp_hiding");
3518         if (d)
3519           /* currently trying to hide */
3520           ref = EINA_FALSE;
3521         else
3522           /* already visible */
3523           return;
3524      }
3525
3526    evas_object_show(obj);
3527    if (ref)
3528      {
3529         evas_object_ref(obj);
3530         evas_object_data_set(obj, "comp_ref", (void*)1);
3531      }
3532    edje_object_signal_emit(obj, "e,state,visible", "e");
3533    evas_object_data_set(obj, "comp_showing", (void*)1);
3534    if (e_comp_util_object_is_above_nocomp(obj))
3535      {
3536         evas_object_data_set(obj, "comp_override", (void*)1);
3537         e_comp_override_add();
3538      }
3539 }
3540
3541 static void
3542 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3543 {
3544    if (!evas_object_visible_get(obj)) return;
3545    /* already hiding */
3546    if (evas_object_data_get(obj, "comp_hiding")) return;
3547    if (!evas_object_data_del(obj, "comp_showing"))
3548      {
3549         evas_object_ref(obj);
3550         evas_object_data_set(obj, "comp_ref", (void*)1);
3551      }
3552    edje_object_signal_emit(obj, "e,state,hidden", "e");
3553    evas_object_data_set(obj, "comp_hiding", (void*)1);
3554
3555    if (evas_object_data_del(obj, "comp_override"))
3556      e_comp_override_timed_pop();
3557 }
3558
3559 static void
3560 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3561 {
3562    if (!e_util_strcmp(emission, "e,action,hide,done"))
3563      {
3564         if (!evas_object_data_del(obj, "comp_hiding")) return;
3565         evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3566         evas_object_hide(obj);
3567         evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3568      }
3569    else
3570      evas_object_data_del(obj, "comp_showing");
3571    if (evas_object_data_del(obj, "comp_ref"))
3572      evas_object_unref(obj);
3573 }
3574
3575 static void
3576 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3577 {
3578    if (data)
3579      {
3580         int w, h;
3581
3582         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3583      }
3584 }
3585
3586 E_API E_Comp_Object_Hook *
3587 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3588 {
3589    E_Comp_Object_Hook *ch;
3590
3591    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3592    ch = E_NEW(E_Comp_Object_Hook, 1);
3593    if (!ch) return NULL;
3594    ch->hookpoint = hookpoint;
3595    ch->func = func;
3596    ch->data = (void*)data;
3597    _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3598    return ch;
3599 }
3600
3601 E_API void
3602 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3603 {
3604    ch->delete_me = 1;
3605    if (_e_comp_object_hooks_walking == 0)
3606      {
3607         _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3608         free(ch);
3609      }
3610    else
3611      _e_comp_object_hooks_delete++;
3612 }
3613
3614 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3615 E_API E_Comp_Object_Intercept_Hook *
3616 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3617 {
3618    E_Comp_Object_Intercept_Hook *ch;
3619
3620    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3621    ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3622    if (!ch) return NULL;
3623    ch->hookpoint = hookpoint;
3624    ch->func = func;
3625    ch->data = (void*)data;
3626    _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3627    return ch;
3628 }
3629
3630 E_API void
3631 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3632 {
3633    ch->delete_me = 1;
3634    if (_e_comp_object_intercept_hooks_walking == 0)
3635      {
3636         _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3637         free(ch);
3638      }
3639    else
3640      _e_comp_object_intercept_hooks_delete++;
3641 }
3642 #endif
3643
3644 E_API Evas_Object *
3645 e_comp_object_util_add(Evas_Object *obj)
3646 {
3647    Evas_Object *o;
3648    const char *name;
3649    E_Comp_Config *conf = e_comp_config_get();
3650    Eina_Bool skip = EINA_FALSE;
3651    char buf[1024];
3652    int ok = 0;
3653    int x, y, w, h;
3654    Eina_Bool vis;
3655
3656    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3657
3658    name = evas_object_name_get(obj);
3659    vis = evas_object_visible_get(obj);
3660    o = edje_object_add(e_comp->evas);
3661    evas_object_data_set(o, "comp_object", (void*)1);
3662    if (name)
3663      skip = (!strncmp(name, "noshadow", 8));
3664    if (skip)
3665      evas_object_data_set(o, "comp_object_skip", (void*)1);
3666
3667    if (conf->shadow_style)
3668      {
3669         snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3670         ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3671      }
3672    if (!ok)
3673      e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3674    if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3675      edje_object_signal_emit(o, "e,state,shadow,on", "e");
3676    else
3677      edje_object_signal_emit(o, "e,state,shadow,off", "e");
3678
3679    evas_object_geometry_get(obj, &x, &y, &w, &h);
3680    evas_object_geometry_set(o, x, y, w, h);
3681    evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3682
3683    edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3684
3685    evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3686    evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3687    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3688    evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3689    evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3690    evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3691
3692    e_comp_object_signal_emit(o, "e,state,hidden", "e");
3693
3694    edje_object_part_swallow(o, "e.swallow.content", obj);
3695
3696    _e_comp_object_event_add(o);
3697
3698    if (vis)
3699      evas_object_show(o);
3700
3701    return o;
3702 }
3703
3704 /* utility functions for deleting objects when their "owner" is deleted */
3705 EINTERN void
3706 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3707 {
3708    Eina_List *l;
3709
3710    SOFT_ENTRY();
3711    EINA_SAFETY_ON_NULL_RETURN(to_del);
3712    l = evas_object_data_get(obj, "comp_object-to_del");
3713    evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3714    evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3715    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3716 }
3717
3718 EINTERN void
3719 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3720 {
3721    Eina_List *l;
3722
3723    SOFT_ENTRY();
3724    EINA_SAFETY_ON_NULL_RETURN(to_del);
3725    l = evas_object_data_get(obj, "comp_object-to_del");
3726    if (l)
3727      evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3728 }
3729
3730 /////////////////////////////////////////////////////////
3731
3732 EINTERN Evas_Object *
3733 e_comp_object_client_add(E_Client *ec)
3734 {
3735    Evas_Object *o;
3736    E_Comp_Object *cw;
3737
3738    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3739    if (ec->frame) return NULL;
3740    _e_comp_smart_init();
3741    o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3742    cw = evas_object_smart_data_get(o);
3743    if (!cw) return NULL;
3744    evas_object_data_set(o, "E_Client", ec);
3745    cw->ec = ec;
3746    ec->frame = o;
3747    evas_object_data_set(o, "comp_object", (void*)1);
3748
3749    _e_comp_object_event_add(o);
3750
3751    return o;
3752 }
3753
3754 /* utility functions for getting client inset */
3755 E_API void
3756 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3757 {
3758    API_ENTRY;
3759    if (!cw->client_inset.calc)
3760      {
3761         if (ax) *ax = x;
3762         if (ay) *ay = y;
3763         return;
3764      }
3765    if (ax) *ax = x - cw->client_inset.l;
3766    if (ay) *ay = y - cw->client_inset.t;
3767 }
3768
3769 E_API void
3770 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3771 {
3772    API_ENTRY;
3773    if (!cw->client_inset.calc)
3774      {
3775         if (ax) *ax = x;
3776         if (ay) *ay = y;
3777         return;
3778      }
3779    if (ax) *ax = x + cw->client_inset.l;
3780    if (ay) *ay = y + cw->client_inset.t;
3781 }
3782
3783 E_API void
3784 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3785 {
3786    API_ENTRY;
3787    if (!cw->client_inset.calc)
3788      {
3789         if (aw) *aw = w;
3790         if (ah) *ah = h;
3791         return;
3792      }
3793    if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3794    if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3795 }
3796
3797 E_API void
3798 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3799 {
3800    API_ENTRY;
3801    if (!cw->client_inset.calc)
3802      {
3803         if (aw) *aw = w;
3804         if (ah) *ah = h;
3805         return;
3806      }
3807    if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3808    if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3809 }
3810
3811 E_API E_Client *
3812 e_comp_object_client_get(Evas_Object *obj)
3813 {
3814    Evas_Object *o;
3815
3816    SOFT_ENTRY(NULL);
3817    /* FIXME: remove this when eo is used */
3818    o = evas_object_data_get(obj, "comp_smart_obj");
3819    if (o)
3820      return e_comp_object_client_get(o);
3821    return cw ? cw->ec : NULL;
3822 }
3823
3824 EINTERN void
3825 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3826 {
3827    API_ENTRY;
3828    if (cw->frame_extends)
3829      edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3830    else
3831      {
3832         if (x) *x = 0;
3833         if (y) *y = 0;
3834         if (w) *w  = cw->ec->w;
3835         if (h) *h  = cw->ec->h;
3836      }
3837 }
3838
3839 EINTERN E_Zone *
3840 e_comp_object_util_zone_get(Evas_Object *obj)
3841 {
3842    E_Zone *zone = NULL;
3843
3844    SOFT_ENTRY(NULL);
3845    if (cw)
3846      zone = e_comp_zone_find_by_ec(cw->ec);
3847    if (!zone)
3848      {
3849         int x, y;
3850
3851         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3852         zone = e_comp_zone_xy_get(x, y);
3853      }
3854    return zone;
3855 }
3856
3857 EINTERN void
3858 e_comp_object_util_center(Evas_Object *obj)
3859 {
3860    int x, y, w, h, ow, oh;
3861    E_Zone *zone;
3862
3863    SOFT_ENTRY();
3864
3865    zone = e_comp_object_util_zone_get(obj);
3866    EINA_SAFETY_ON_NULL_RETURN(zone);
3867    e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3868    if (cw && (cw->ec->changes.size || cw->ec->new_client))
3869      ow = cw->ec->w, oh = cw->ec->h;
3870    else
3871      evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3872    x = x + (w - ow) / 2;
3873    y = y + (h - oh) / 2;
3874    evas_object_move(obj, x, y);
3875 }
3876
3877 EINTERN void
3878 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3879 {
3880    int x, y, w, h, ow, oh;
3881
3882    SOFT_ENTRY();
3883    EINA_SAFETY_ON_NULL_RETURN(on);
3884    evas_object_geometry_get(on, &x, &y, &w, &h);
3885    if (cw && (cw->ec->changes.size || cw->ec->new_client))
3886      ow = cw->ec->w, oh = cw->ec->h;
3887    else
3888      evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3889    evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3890 }
3891
3892 EINTERN void
3893 e_comp_object_util_fullscreen(Evas_Object *obj)
3894 {
3895    SOFT_ENTRY();
3896
3897    if (cw)
3898      e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3899    else
3900      {
3901         evas_object_move(obj, 0, 0);
3902         evas_object_resize(obj, e_comp->w, e_comp->h);
3903      }
3904 }
3905
3906 EINTERN void
3907 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
3908 {
3909    E_Zone *zone;
3910    int zx, zy, zw, zh;
3911    int ow, oh;
3912    SOFT_ENTRY();
3913
3914    if (cw)
3915      ow = cw->w, oh = cw->h;
3916    else
3917      evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3918    zone = e_comp_object_util_zone_get(obj);
3919    e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
3920    if (x) *x = zx + (zw - ow) / 2;
3921    if (y) *y = zy + (zh - oh) / 2;
3922 }
3923
3924 EINTERN void
3925 e_comp_object_input_objs_del(Evas_Object *obj)
3926 {
3927    API_ENTRY;
3928    E_Input_Rect_Data *input_rect_data;
3929    E_Input_Rect_Smart_Data *input_rect_sd;
3930
3931    if (!cw->input_obj)
3932      return;
3933
3934    input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3935    if (!input_rect_sd) return;
3936
3937    EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3938      {
3939         if (input_rect_data->obj)
3940           {
3941              evas_object_smart_member_del(input_rect_data->obj);
3942              E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3943           }
3944         E_FREE(input_rect_data);
3945      }
3946 }
3947
3948 E_API void
3949 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
3950 {
3951    API_ENTRY;
3952    E_Input_Rect_Data *input_rect_data = NULL;
3953    E_Input_Rect_Smart_Data *input_rect_sd;
3954    int client_w, client_h;
3955
3956    if (cw->ec->client.w)
3957      client_w = cw->ec->client.w;
3958    else
3959      client_w = cw->ec->w;
3960
3961    if (cw->ec->client.h)
3962      client_h = cw->ec->client.h;
3963    else
3964      client_h = cw->ec->h;
3965
3966    E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
3967
3968    if (!cw->input_obj)
3969      {
3970         _e_comp_input_obj_smart_init();
3971         cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
3972         evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
3973         input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3974
3975         if (input_rect_sd)
3976           input_rect_sd->cw = cw;
3977      }
3978
3979    input_rect_sd = evas_object_smart_data_get(cw->input_obj);
3980    if (input_rect_sd)
3981      {
3982         input_rect_data = E_NEW(E_Input_Rect_Data, 1);
3983         if (input_rect_data)
3984           {
3985              EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
3986              input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
3987           }
3988      }
3989
3990    if ((input_rect_data) &&
3991        (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
3992      {
3993         input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
3994         evas_object_name_set(input_rect_data->obj, "cw->input_obj");
3995         evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
3996         evas_object_clip_set(input_rect_data->obj, cw->clip);
3997         evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
3998         evas_object_geometry_set(input_rect_data->obj,
3999           cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4000           cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4001         evas_object_pass_events_set(cw->default_input_obj, 1);
4002         evas_object_pass_events_set(cw->obj, 1);
4003         if (cw->visible)
4004           {
4005              evas_object_show(input_rect_data->obj);
4006              evas_object_show(cw->input_obj);
4007           }
4008      }
4009    else
4010      {
4011         evas_object_smart_member_del(cw->input_obj);
4012         E_FREE_FUNC(cw->input_obj, evas_object_del);
4013         evas_object_pass_events_set(cw->default_input_obj, 0);
4014         evas_object_pass_events_set(cw->obj, 0);
4015      }
4016 }
4017
4018 E_API void
4019 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4020 {
4021    API_ENTRY;
4022    E_Input_Rect_Smart_Data *input_rect_sd;
4023    E_Input_Rect_Data *input_rect_data;
4024    Eina_List *l;
4025
4026    if (!cw->input_obj) return;
4027
4028    input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4029    if (input_rect_sd)
4030      {
4031         EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4032           {
4033              *list = eina_list_append(*list, &input_rect_data->rect);
4034           }
4035      }
4036 }
4037
4038 EINTERN void
4039 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4040 {
4041    API_ENTRY;
4042    if (l) *l = cw->client_inset.l;
4043    if (r) *r = cw->client_inset.r;
4044    if (t) *t = cw->client_inset.t;
4045    if (b) *b = cw->client_inset.b;
4046 }
4047
4048 /* set geometry for CSD */
4049 EINTERN void
4050 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4051 {
4052    Eina_Bool calc;
4053    int tx, ty, tw, th;
4054
4055    API_ENTRY;
4056    if (cw->frame_object)
4057      CRI("ACK! ec:%p", cw->ec);
4058    if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4059        (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4060    calc = cw->client_inset.calc;
4061    cw->client_inset.calc = l || r || t || b;
4062    eina_stringshare_replace(&cw->frame_theme, "borderless");
4063    if (cw->client_inset.calc)
4064      {
4065         tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4066         th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4067         e_client_size_set(cw->ec, tw, th);
4068      }
4069    else if (cw->ec->maximized || cw->ec->fullscreen)
4070      {
4071         cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4072         cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4073      }
4074    if (!cw->ec->new_client)
4075      {
4076         if (calc && cw->client_inset.calc)
4077           {
4078              tx = cw->ec->x - (l - cw->client_inset.l);
4079              ty = cw->ec->y - (t - cw->client_inset.t);
4080              e_client_pos_set(cw->ec, tx, ty);
4081           }
4082         cw->ec->changes.pos = cw->ec->changes.size = 1;
4083         EC_CHANGED(cw->ec);
4084      }
4085    cw->client_inset.l = l;
4086    cw->client_inset.r = r;
4087    cw->client_inset.t = t;
4088    cw->client_inset.b = b;
4089 }
4090
4091 EINTERN Eina_Bool
4092 e_comp_object_frame_allowed(Evas_Object *obj)
4093 {
4094    API_ENTRY EINA_FALSE;
4095    return (cw->frame_object || (!cw->client_inset.calc));
4096 }
4097
4098 EINTERN Eina_Bool
4099 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4100 {
4101    API_ENTRY EINA_FALSE;
4102    if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4103    eina_stringshare_replace(&cw->frame_name, name);
4104    if (cw->frame_object)
4105      edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4106    return EINA_TRUE;
4107 }
4108
4109 EINTERN Eina_Bool
4110 e_comp_object_frame_exists(Evas_Object *obj)
4111 {
4112    API_ENTRY EINA_FALSE;
4113    return !!cw->frame_object;
4114 }
4115
4116 EINTERN Eina_Bool
4117 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4118 {
4119    Evas_Object *o, *pbg;
4120    char buf[4096];
4121    int ok;
4122    Eina_Stringshare *theme;
4123
4124    API_ENTRY EINA_FALSE;
4125
4126    if (!e_util_strcmp(cw->frame_theme, name))
4127     return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4128    if (!e_util_strcmp(name, "COMP_RESHADOW"))
4129      return _e_comp_object_shadow_setup(cw);
4130    pbg = cw->frame_object;
4131    theme = eina_stringshare_add(name);
4132
4133    if (cw->frame_object)
4134      {
4135         int w, h;
4136
4137         w = cw->ec->w, h = cw->ec->h;
4138         e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4139         if ((cw->ec->w != w) || (cw->ec->h != h))
4140           {
4141              cw->ec->changes.size = 1;
4142              EC_CHANGED(cw->ec);
4143           }
4144         E_FREE_FUNC(cw->frame_object, evas_object_del);
4145         if (!name) goto reshadow;
4146      }
4147    o = edje_object_add(e_comp->evas);
4148    snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4149    ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4150    if ((!ok) && (!e_util_strcmp(name, "borderless")))
4151      {
4152         cw->frame_object = NULL;
4153         evas_object_del(o);
4154         eina_stringshare_del(cw->frame_theme);
4155         cw->frame_theme = theme;
4156         goto reshadow;
4157      }
4158    if (!ok)
4159      {
4160         if (theme != e_config->theme_default_border_style)
4161           {
4162              snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4163              ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4164           }
4165         if (!ok)
4166           {
4167              ok = e_theme_edje_object_set(o, "base/theme/border",
4168                                           "e/widgets/border/default/border");
4169              if (ok && (theme == e_config->theme_default_border_style))
4170                {
4171                   /* Reset default border style to default */
4172                   eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4173                   e_config_save_queue();
4174                }
4175           }
4176      }
4177
4178    if (ok)
4179      {
4180         cw->frame_object = o;
4181         eina_stringshare_del(cw->frame_theme);
4182         cw->frame_theme = theme;
4183         evas_object_name_set(o, "cw->frame_object");
4184
4185         if (cw->frame_name)
4186           edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4187
4188         if (!pbg)
4189           {
4190              cw->ec->changes.icon = 1;
4191              EC_CHANGED(cw->ec);
4192           }
4193      }
4194    else
4195      {
4196         CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4197         evas_object_del(o);
4198      }
4199 reshadow:
4200    if (cw->shobj)
4201      _e_comp_object_shadow_setup(cw);
4202    do
4203      {
4204         int old_x, old_y, new_x = 0, new_y = 0;
4205
4206         old_x = cw->x, old_y = cw->y;
4207
4208         _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4209         if (pbg)
4210           new_x = cw->ec->x, new_y = cw->ec->y;
4211         else if (cw->ec->placed || (!cw->ec->new_client))
4212           {
4213              /* if no previous frame:
4214               * - reapply client_inset
4215               * - clamp to zone
4216               */
4217              int x, y;
4218
4219              if (cw->ec->changes.size)
4220                {
4221                   x = cw->ec->x;
4222                   y = cw->ec->y;
4223                }
4224              else
4225                {
4226                   E_Zone *zone;
4227                   zone = e_comp_zone_find_by_ec(cw->ec);
4228                   if (!zone) break;
4229
4230                   x = cw->ec->client.x, y = cw->ec->client.y;
4231                   x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4232                   y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4233                }
4234              new_x = x, new_y = y;
4235           }
4236
4237         if (old_x != new_x || old_y != new_y)
4238           {
4239              /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4240              cw->y = cw->x = -99999;
4241              evas_object_move(obj, new_x, new_y);
4242           }
4243      } while (0);
4244
4245    if (cw->ec->maximized)
4246      {
4247         cw->ec->changes.need_maximize = 1;
4248         EC_CHANGED(cw->ec);
4249      }
4250    evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4251    if (cw->frame_object)
4252      {
4253         cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4254      }
4255    else
4256      cw->frame_extends = 0;
4257    evas_object_del(pbg);
4258    return EINA_TRUE;
4259 }
4260
4261 E_API void
4262 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4263 {
4264    E_Comp_Object_Mover *prov;
4265
4266    API_ENTRY;
4267    //INF("EMIT %p: %s %s", cw->ec, sig, src);
4268    edje_object_signal_emit(cw->shobj, sig, src);
4269    if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4270    if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4271        ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4272      return;
4273    /* start with highest priority callback first */
4274    EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4275      {
4276         if (!e_util_glob_match(sig, prov->sig)) continue;
4277         if (prov->func(prov->data, obj, sig)) break;
4278      }
4279 }
4280
4281 E_API void
4282 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4283 {
4284    /* FIXME: at some point I guess this should use eo to inherit
4285     * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4286     * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4287     */
4288    API_ENTRY;
4289    edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4290 }
4291
4292 E_API void
4293 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4294 {
4295    API_ENTRY;
4296    edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4297 }
4298
4299 E_API void
4300 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4301 {
4302    API_ENTRY;
4303    edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4304 }
4305
4306 E_API void
4307 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4308 {
4309    int tw, th;
4310    Eina_Rectangle rect;
4311    API_ENTRY;
4312
4313    if (cw->ec->input_only || (!cw->updates)) return;
4314    if (cw->nocomp) return;
4315    rect.x = x, rect.y = y;
4316    rect.w = w, rect.h = h;
4317    evas_object_smart_callback_call(obj, "damage", &rect);
4318
4319    if (e_comp_is_on_overlay(cw->ec))
4320      {
4321         /* It will not set hwc_need_update value if E modules already cleanup pixmap
4322         * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4323         * E module attempts to block screen update due to the particular policy.
4324         */
4325         if (e_pixmap_resource_get(cw->ec->pixmap))
4326           cw->hwc_need_update = EINA_TRUE;
4327      }
4328
4329    /* ignore overdraw */
4330    if (cw->updates_full)
4331      {
4332         RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4333         e_comp_object_render_update_add(obj);
4334
4335         if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4336           evas_object_show(cw->smart_obj);
4337
4338         return;
4339      }
4340    /* clip rect to client surface */
4341    RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4342    E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4343    /* if rect is the total size of the client after clip, clear the updates
4344     * since this is guaranteed to be the whole region anyway
4345     */
4346    eina_tiler_area_size_get(cw->updates, &tw, &th);
4347    if ((w > tw) || (h > th))
4348      {
4349         RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4350         eina_tiler_clear(cw->updates);
4351         eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4352         x = 0, y = 0;
4353         tw = cw->ec->client.w, th = cw->ec->client.h;
4354      }
4355    if ((!x) && (!y) && (w == tw) && (h == th))
4356      {
4357         eina_tiler_clear(cw->updates);
4358         RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4359         cw->updates_full = 1;
4360         cw->update_count = 0;
4361      }
4362    cw->update_count++;
4363    if (cw->update_count > UPDATE_MAX)
4364      {
4365         /* this is going to get really dumb, so just update the whole thing */
4366         eina_tiler_clear(cw->updates);
4367         cw->update_count = cw->updates_full = 1;
4368         eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4369         RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4370      }
4371    else
4372      {
4373         eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4374         RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4375      }
4376    cw->updates_exist = 1;
4377    e_comp_object_render_update_add(obj);
4378
4379    if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4380      evas_object_show(cw->smart_obj);
4381 }
4382
4383 EINTERN Eina_Bool
4384 e_comp_object_damage_exists(Evas_Object *obj)
4385 {
4386    API_ENTRY EINA_FALSE;
4387    return cw->updates_exist;
4388 }
4389
4390 EINTERN void
4391 e_comp_object_render_update_add(Evas_Object *obj)
4392 {
4393    API_ENTRY;
4394
4395    if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4396    if (cw->render_update_lock.lock) return;
4397    if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4398    if (!cw->update)
4399      {
4400         cw->update = 1;
4401         e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4402      }
4403    e_comp_render_queue();
4404 }
4405
4406 EINTERN void
4407 e_comp_object_render_update_del(Evas_Object *obj)
4408 {
4409    API_ENTRY;
4410
4411    if (cw->ec->input_only || (!cw->updates)) return;
4412    if (!cw->update) return;
4413    cw->update = 0;
4414    /* this gets called during comp animating to clear the update flag */
4415    if (e_comp->grabbed) return;
4416    e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4417    if (!e_comp->updates)
4418      {
4419         E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4420         if (e_comp->render_animator)
4421           ecore_animator_freeze(e_comp->render_animator);
4422      }
4423 }
4424
4425 EINTERN void
4426 e_comp_object_shape_apply(Evas_Object *obj)
4427 {
4428    Eina_List *l;
4429    Evas_Object *o;
4430    unsigned int i, *pix, *p;
4431    int w, h, px, py;
4432
4433    API_ENTRY;
4434    if (!cw->ec) return; //NYI
4435    if (cw->external_content) return;
4436    if (cw->ec->shaped)
4437      {
4438         if ((cw->ec->shape_rects_num >= 1) &&
4439             (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4440            return;
4441      }
4442    if (cw->native)
4443      {
4444         ERR("BUGGER: shape with native surface? cw=%p", cw);
4445         return;
4446      }
4447    evas_object_image_size_get(cw->obj, &w, &h);
4448    if ((w < 1) || (h < 1)) return;
4449
4450    if (cw->ec->shaped)
4451      _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4452    _e_comp_object_alpha_set(cw);
4453    EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4454       evas_object_image_alpha_set(o, 1);
4455
4456    p = pix = evas_object_image_data_get(cw->obj, 1);
4457    if (!pix)
4458      {
4459         evas_object_image_data_set(cw->obj, pix);
4460         return;
4461      }
4462    if (cw->ec->shaped)
4463      {
4464         unsigned char *spix, *sp;
4465
4466         spix = calloc(w * h, sizeof(unsigned char));
4467         if (!spix) return;
4468         for (i = 0; i < cw->ec->shape_rects_num; i++)
4469           {
4470              int rx, ry, rw, rh;
4471
4472              rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4473              rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4474              E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4475              sp = spix + (w * ry) + rx;
4476              for (py = 0; py < rh; py++)
4477                {
4478                   for (px = 0; px < rw; px++)
4479                     {
4480                        *sp = 0xff; sp++;
4481                     }
4482                   sp += w - rw;
4483                }
4484           }
4485         sp = spix;
4486         for (py = 0; py < h; py++)
4487           {
4488              for (px = 0; px < w; px++)
4489                {
4490                   unsigned int mask, imask;
4491
4492                   mask = ((unsigned int)(*sp)) << 24;
4493                   imask = mask >> 8;
4494                   imask |= imask >> 8;
4495                   imask |= imask >> 8;
4496                   *p = mask | (*p & imask);
4497                   //if (*sp) *p = 0xff000000 | *p;
4498                   //else *p = 0x00000000;
4499                   sp++;
4500                   p++;
4501                }
4502           }
4503         free(spix);
4504      }
4505    else
4506       {
4507          for (py = 0; py < h; py++)
4508            {
4509               for (px = 0; px < w; px++)
4510                 *p |= 0xff000000;
4511            }
4512       }
4513    evas_object_image_data_set(cw->obj, pix);
4514    evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4515    EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4516      {
4517         evas_object_image_data_set(o, pix);
4518         evas_object_image_data_update_add(o, 0, 0, w, h);
4519      }
4520 // don't need to fix alpha chanel as blending
4521 // should be totally off here regardless of
4522 // alpha channel content
4523 }
4524
4525 static void
4526 _e_comp_object_clear(E_Comp_Object *cw)
4527 {
4528    Eina_List *l;
4529    Evas_Object *o;
4530
4531    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4532
4533    if (cw->render_update_lock.lock) return;
4534
4535    if (cw->ec->pixmap)
4536      e_pixmap_clear(cw->ec->pixmap);
4537    if (cw->native)
4538      _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4539    evas_object_image_size_set(cw->obj, 1, 1);
4540    evas_object_image_data_set(cw->obj, NULL);
4541    EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4542      {
4543         evas_object_image_size_set(o, 1, 1);
4544         evas_object_image_data_set(o, NULL);
4545      }
4546    cw->native = 0;
4547    e_comp_object_render_update_del(cw->smart_obj);
4548 }
4549
4550 static Eina_Bool
4551 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4552 {
4553     int r, g, b, a;
4554
4555     API_ENTRY EINA_FALSE;
4556
4557     if (cw->transparent.set == set)
4558        return EINA_TRUE;
4559
4560     if (set)
4561       {
4562          evas_object_color_get(obj, &r, &g, &b, &a);
4563          evas_object_color_set(obj, 0, 0, 0, 0);
4564
4565          cw->transparent.user_r = r;
4566          cw->transparent.user_g = g;
4567          cw->transparent.user_b = b;
4568          cw->transparent.user_a = a;
4569
4570          ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4571                cw->ec,
4572                cw->transparent.user_r,
4573                cw->transparent.user_g,
4574                cw->transparent.user_b,
4575                cw->transparent.user_a);
4576
4577          cw->transparent.set = EINA_TRUE;
4578       }
4579     else
4580       {
4581          cw->transparent.set = EINA_FALSE;
4582
4583          evas_object_color_set(obj,
4584                                cw->transparent.user_r,
4585                                cw->transparent.user_g,
4586                                cw->transparent.user_b,
4587                                cw->transparent.user_a);
4588
4589          ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4590                cw->ec,
4591                cw->transparent.user_r,
4592                cw->transparent.user_g,
4593                cw->transparent.user_b,
4594                cw->transparent.user_a);
4595       }
4596
4597    return EINA_TRUE;
4598 }
4599
4600 /* helper function to simplify toggling of redirection for display servers which support it */
4601 EINTERN void
4602 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4603 {
4604    API_ENTRY;
4605
4606    set = !!set;
4607    if (cw->redirected == set) return;
4608    cw->redirected = set;
4609    if (cw->external_content) return;
4610
4611    e_comp_object_map_update(obj);
4612
4613    if (set)
4614      {
4615         if (cw->updates_exist)
4616           e_comp_object_render_update_add(obj);
4617         else
4618           e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4619
4620         _e_comp_object_transparent_set(obj, EINA_FALSE);
4621         evas_object_smart_callback_call(obj, "redirected", NULL);
4622      }
4623    else
4624      {
4625         _e_comp_object_clear(cw);
4626         _e_comp_object_transparent_set(obj, EINA_TRUE);
4627         evas_object_smart_callback_call(obj, "unredirected", NULL);
4628      }
4629 }
4630
4631 static void
4632 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4633 {
4634    E_Comp_Object *cw;
4635    cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4636
4637    if (cw->buffer_destroy_listener.notify)
4638      {
4639         cw->buffer_destroy_listener.notify = NULL;
4640         wl_list_remove(&cw->buffer_destroy_listener.link);
4641      }
4642
4643    if (e_object_is_del(E_OBJECT(cw->ec)))
4644      {
4645         if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4646           return;
4647      }
4648    else
4649      {
4650         /* if it's current displaying buffer, do not remove its content */
4651         if (!evas_object_visible_get(cw->ec->frame))
4652           _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4653      }
4654 }
4655
4656 static void
4657 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4658 {
4659    Eina_List *l;
4660    Evas_Object *o;
4661
4662    if (cw->buffer_destroy_listener.notify)
4663      {
4664         wl_list_remove(&cw->buffer_destroy_listener.link);
4665         cw->buffer_destroy_listener.notify = NULL;
4666      }
4667
4668    if (cw->tbm_surface)
4669      {
4670         tbm_surface_internal_unref(cw->tbm_surface);
4671         cw->tbm_surface = NULL;
4672      }
4673
4674    if (ns)
4675      {
4676         if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4677           {
4678              cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4679              wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4680           }
4681         else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4682           {
4683              tbm_surface_internal_ref(ns->data.tbm.buffer);
4684              cw->tbm_surface = ns->data.tbm.buffer;
4685           }
4686      }
4687
4688    TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4689    evas_object_image_native_surface_set(cw->obj, ns);
4690    TRACE_DS_END();
4691    if (with_mirror)
4692      {
4693         EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4694           {
4695              evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4696              TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4697              evas_object_image_native_surface_set(o, ns);
4698              TRACE_DS_END();
4699           }
4700      }
4701 }
4702
4703 EINTERN void
4704 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4705 {
4706    Evas_Native_Surface ns;
4707
4708    API_ENTRY;
4709    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4710    if (cw->ec->input_only) return;
4711    if (cw->external_content) return;
4712    if (cw->render_update_lock.lock) return;
4713    set = !!set;
4714
4715    memset(&ns, 0, sizeof(Evas_Native_Surface));
4716
4717    if (set)
4718      {
4719         /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4720         set = (!cw->ec->shaped);
4721         if (set)
4722           set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4723      }
4724    cw->native = set;
4725
4726    _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4727 }
4728
4729 EINTERN void
4730 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4731 {
4732    API_ENTRY;
4733    if (cw->ec->input_only) return;
4734    E_FREE(cw->ns);
4735    if (ns)
4736      cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4737    _e_comp_object_alpha_set(cw);
4738    if (cw->native)
4739      e_comp_object_native_surface_set(obj, cw->native);
4740    e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4741 }
4742
4743 EINTERN void
4744 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4745 {
4746    API_ENTRY;
4747
4748    set = !!set;
4749
4750    if (cw->blanked == set) return;
4751    cw->blanked = set;
4752    _e_comp_object_alpha_set(cw);
4753    if (set)
4754      {
4755         _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4756         evas_object_image_data_set(cw->obj, NULL);
4757         return;
4758      }
4759    if (cw->native)
4760      e_comp_object_native_surface_set(obj, 1);
4761    e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4762 }
4763
4764 static void
4765 _e_comp_object_damage_trace_rect_set(Evas_Object *obj, Eina_Rectangle *origin, int dmg_x, int dmg_y, int dmg_w, int dmg_h)
4766 {
4767    Evas_Object *o;
4768    int obj_x, obj_y;
4769
4770    if (!_damage_trace) return;
4771
4772    API_ENTRY;
4773
4774    if (!evas_object_visible_get(cw->obj)) return;
4775
4776    evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4777
4778    o = evas_object_rectangle_add(e_comp->evas);
4779    evas_object_layer_set(o, E_LAYER_MAX);
4780    evas_object_name_set(o, "damage_trace");
4781    evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4782    evas_object_resize(o, dmg_w, dmg_h);
4783    evas_object_color_set(o, 0, 128, 0, 128);
4784    evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4785    evas_object_pass_events_set(o, EINA_TRUE);
4786    evas_object_show(o);
4787
4788    ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4789          cw->ec,
4790          dmg_w, dmg_h, dmg_x, dmg_y,
4791          origin->w, origin->h, origin->x, origin->y);
4792
4793    _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4794 }
4795
4796 /* mark an object as dirty and setup damages */
4797 E_API void
4798 e_comp_object_dirty(Evas_Object *obj)
4799 {
4800    Eina_Iterator *it;
4801    Eina_Rectangle *rect;
4802    Eina_List *ll;
4803    Evas_Object *o;
4804    int w, h, tw, th;
4805    Eina_Bool dirty, visible;
4806    E_Map *m = NULL;
4807
4808    API_ENTRY;
4809    if (cw->external_content) return;
4810    if (!cw->redirected) return;
4811    if (cw->render_update_lock.lock)
4812      {
4813         ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4814         return;
4815      }
4816    /* only actually dirty if pixmap is available */
4817    if (!e_pixmap_resource_get(cw->ec->pixmap))
4818      {
4819         // e_pixmap_size_get returns last attached buffer size
4820         // eventhough it is destroyed
4821         ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4822         return;
4823      }
4824    dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4825    visible = cw->visible;
4826    if (!dirty) w = h = 1;
4827    evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4828    if (!dirty)
4829      evas_object_image_data_set(cw->obj, NULL);
4830    _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4831    evas_object_image_size_set(cw->obj, tw, th);
4832    if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4833    if (cw->pending_updates)
4834      eina_tiler_area_size_set(cw->pending_updates, w, h);
4835    EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4836      {
4837         evas_object_image_pixels_dirty_set(o, dirty);
4838         if (!dirty)
4839           evas_object_image_data_set(o, NULL);
4840         evas_object_image_size_set(o, tw, th);
4841         visible |= evas_object_visible_get(o);
4842      }
4843    if (!dirty)
4844      {
4845         ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4846         return;
4847      }
4848
4849    e_comp_object_native_surface_set(obj, 1);
4850
4851    m = _e_comp_object_map_damage_transform_get(cw->ec);
4852    it = eina_tiler_iterator_new(cw->updates);
4853    EINA_ITERATOR_FOREACH(it, rect)
4854      {
4855         /* evas converts damage according to rotation of ecore_evas in damage_region_set
4856          * of evas engine and doesn't convert damage according to evas_map.
4857          * so damage of evas_object_image use surface coordinate.
4858          */
4859         if (m)
4860           {
4861              int damage_x, damage_y, damage_w, damage_h;
4862
4863              _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4864                                                       &damage_x, &damage_y, &damage_w, &damage_h);
4865              evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4866              _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4867           }
4868         else
4869           {
4870              evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4871              _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4872           }
4873
4874         EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4875           evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4876         if (cw->pending_updates)
4877           eina_tiler_rect_add(cw->pending_updates, rect);
4878      }
4879    eina_iterator_free(it);
4880    if (m) e_map_free(m);
4881    if (cw->pending_updates)
4882      eina_tiler_clear(cw->updates);
4883    else
4884      {
4885         cw->pending_updates = cw->updates;
4886         cw->updates = eina_tiler_new(w, h);
4887         eina_tiler_tile_size_set(cw->updates, 1, 1);
4888      }
4889    cw->update_count = cw->updates_full = cw->updates_exist = 0;
4890    evas_object_smart_callback_call(obj, "dirty", NULL);
4891    if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4892    /* force render if main object is hidden but mirrors are visible */
4893    RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4894    e_comp_object_render(obj);
4895 }
4896
4897 E_API Eina_Bool
4898 e_comp_object_render(Evas_Object *obj)
4899 {
4900    Eina_List *l;
4901    Evas_Object *o;
4902    int pw, ph;
4903    unsigned int *pix;
4904
4905    API_ENTRY EINA_FALSE;
4906
4907    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4908    if (cw->ec->input_only) return EINA_TRUE;
4909    if (cw->external_content) return EINA_TRUE;
4910    if (cw->native) return EINA_FALSE;
4911    /* if comp object is not redirected state, comp object should not be set by newly committed data
4912       because image size of comp object is 1x1 and it should not be shown on canvas */
4913    if (!cw->redirected) return EINA_TRUE;
4914    if (cw->render_update_lock.lock)
4915      {
4916         ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4917         return EINA_TRUE;
4918      }
4919    e_comp_object_render_update_del(obj);
4920    if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
4921
4922    if (!cw->pending_updates)
4923      {
4924         WRN("RENDER [%p]: NO RECTS!", cw->ec);
4925         evas_object_image_data_set(cw->obj, NULL);
4926         EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4927           evas_object_image_data_set(o, NULL);
4928         return EINA_FALSE;
4929      }
4930
4931    evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
4932
4933    RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
4934
4935    pix = e_pixmap_image_data_get(cw->ec->pixmap);
4936    if (!pix)
4937      {
4938         e_pixmap_image_refresh(cw->ec->pixmap);
4939         pix = e_pixmap_image_data_get(cw->ec->pixmap);
4940      }
4941
4942    if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
4943      e_pixmap_image_data_ref(cw->ec->pixmap);
4944
4945    /* set pixel data */
4946    evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
4947    _e_comp_object_alpha_set(cw);
4948    EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4949      {
4950         evas_object_image_data_set(o, pix);
4951         evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
4952         evas_object_image_pixels_dirty_set(o, EINA_FALSE);
4953      }
4954
4955    E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
4956
4957    e_comp_client_post_update_add(cw->ec);
4958
4959    return EINA_TRUE;
4960 }
4961
4962 /* create a duplicate of an evas object */
4963 E_API Evas_Object *
4964 e_comp_object_util_mirror_add(Evas_Object *obj)
4965 {
4966    Evas_Object *o;
4967    int w, h, tw, th;
4968    unsigned int *pix = NULL;
4969    Eina_Bool argb = EINA_FALSE;
4970
4971    SOFT_ENTRY(NULL);
4972
4973    if (!cw)
4974      cw = evas_object_data_get(obj, "comp_mirror");
4975    if (!cw)
4976      {
4977         o = evas_object_image_filled_add(evas_object_evas_get(obj));
4978         evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4979         evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4980         evas_object_image_alpha_set(o, 1);
4981         evas_object_image_source_set(o, obj);
4982         return o;
4983      }
4984    if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
4985    if (cw->external_content)
4986      {
4987         ERR("%p of client %p is external content.", obj, cw->ec);
4988         return NULL;
4989      }
4990    o = evas_object_image_filled_add(evas_object_evas_get(obj));
4991    evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
4992    evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
4993    cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
4994    evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
4995    evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
4996    evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
4997    evas_object_data_set(o, "E_Client_Mirror", cw->ec);
4998    evas_object_data_set(o, "comp_mirror", cw);
4999
5000    evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5001    _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5002
5003    evas_object_image_size_set(o, tw, th);
5004
5005    if (cw->ec->shaped)
5006      pix = evas_object_image_data_get(cw->obj, 0);
5007    else
5008      {
5009         if (cw->native)
5010           {
5011              if (cw->ns)
5012                evas_object_image_native_surface_set(o, cw->ns);
5013              else
5014                {
5015                   Evas_Native_Surface ns;
5016                   memset(&ns, 0, sizeof(Evas_Native_Surface));
5017                   if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5018                     evas_object_image_native_surface_set(o, &ns);
5019                }
5020           }
5021         else
5022           {
5023              /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5024              argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5025              if ((argb) &&
5026                  (e_pixmap_image_exists(cw->ec->pixmap)))
5027                pix = e_pixmap_image_data_get(cw->ec->pixmap);
5028              else
5029                pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5030           }
5031      }
5032    if (pix)
5033      {
5034       Eina_Bool dirty;
5035
5036       dirty = evas_object_image_pixels_dirty_get(cw->obj);
5037       evas_object_image_pixels_dirty_set(o, dirty);
5038       evas_object_image_data_set(o, pix);
5039       evas_object_image_data_set(cw->obj, pix);
5040       if (dirty)
5041         evas_object_image_data_update_add(o, 0, 0, tw, th);
5042    }
5043    return o;
5044 }
5045
5046 //////////////////////////////////////////////////////
5047
5048 EINTERN Eina_Bool
5049 e_comp_object_effect_allowed_get(Evas_Object *obj)
5050 {
5051    API_ENTRY EINA_FALSE;
5052
5053    if (!cw->shobj) return EINA_FALSE;
5054    if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5055    return !e_comp_config_get()->match.disable_borders;
5056 }
5057
5058 /* setup an api effect for a client */
5059 E_API Eina_Bool
5060 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5061 {
5062    char buf[4096];
5063    Eina_Stringshare *grp;
5064    E_Comp_Config *config;
5065    Eina_Bool loaded = EINA_FALSE;
5066
5067    API_ENTRY EINA_FALSE;
5068    if (!cw->shobj) return EINA_FALSE; //input window
5069
5070    if (!effect) effect = "none";
5071    snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5072
5073    config = e_comp_config_get();
5074    if ((config) && (config->effect_file))
5075      {
5076         if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5077           {
5078              cw->effect_set = EINA_TRUE;
5079              loaded = EINA_TRUE;
5080           }
5081      }
5082
5083    if (!loaded)
5084      {
5085         edje_object_file_get(cw->effect_obj, NULL, &grp);
5086         cw->effect_set = !eina_streq(effect, "none");
5087         if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5088         if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5089           {
5090              snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5091              if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5092                if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5093                  {
5094                     if (cw->effect_running)
5095                       {
5096                          if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5097                            return EINA_FALSE;
5098                       }
5099                     cw->effect_set = EINA_FALSE;
5100                     return cw->effect_set;
5101                  }
5102           }
5103      }
5104    if (cw->effect_running)
5105      {
5106         if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5107           return EINA_FALSE;
5108      }
5109    ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5110    edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5111    if (cw->effect_clip)
5112      {
5113         evas_object_clip_unset(cw->clip);
5114         cw->effect_clip = 0;
5115      }
5116    cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5117
5118    _e_comp_object_dim_update(cw);
5119
5120    return cw->effect_set;
5121 }
5122
5123 /* set params for embryo scripts in effect */
5124 E_API void
5125 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5126 {
5127    Edje_Message_Int_Set *msg;
5128    unsigned int x;
5129
5130    API_ENTRY;
5131    EINA_SAFETY_ON_NULL_RETURN(params);
5132    EINA_SAFETY_ON_FALSE_RETURN(count);
5133    if (!cw->effect_set) return;
5134
5135    msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5136    msg->count = (int)count;
5137    for (x = 0; x < count; x++)
5138       msg->val[x] = params[x];
5139    edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5140    edje_object_message_signal_process(cw->effect_obj);
5141 }
5142
5143 static void
5144 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5145 {
5146    Edje_Signal_Cb end_cb;
5147    void *end_data;
5148    E_Comp_Object *cw = data;
5149
5150    edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5151    cw->effect_running = 0;
5152    if (!_e_comp_object_animating_end(cw)) return;
5153
5154    if (evas_object_data_get(cw->smart_obj, "effect_running"))
5155      {
5156         evas_object_data_del(cw->smart_obj, "effect_running");
5157         _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5158         e_comp_visibility_calculation_set(EINA_TRUE);
5159      }
5160
5161    end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5162    if (!end_cb) return;
5163    end_data = evas_object_data_get(obj, "_e_comp.end_data");
5164    _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5165    end_cb(end_data, cw->smart_obj, emission, source);
5166 }
5167
5168 /* clip effect to client's zone */
5169 EINTERN void
5170 e_comp_object_effect_clip(Evas_Object *obj)
5171 {
5172    API_ENTRY;
5173    E_Zone *zone;
5174    zone = e_comp_zone_find_by_ec(cw->ec);
5175    if (!zone) return;
5176    if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5177    if (!cw->effect_clip_able) return;
5178    evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5179    cw->effect_clip = 1;
5180 }
5181
5182 /* unclip effect from client's zone */
5183 EINTERN void
5184 e_comp_object_effect_unclip(Evas_Object *obj)
5185 {
5186    API_ENTRY;
5187    if (!cw->effect_clip) return;
5188    evas_object_clip_unset(cw->smart_obj);
5189    cw->effect_clip = 0;
5190 }
5191
5192 /* start effect, running end_cb after */
5193 E_API Eina_Bool
5194 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5195 {
5196    API_ENTRY EINA_FALSE;
5197    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5198    if (!cw->effect_set) return EINA_FALSE;
5199
5200    if (cw->effect_running)
5201      {
5202         e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5203      }
5204
5205    e_comp_object_effect_clip(obj);
5206    edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5207
5208    edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5209    evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5210    evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5211    evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5212
5213    _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5214    _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5215
5216    edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5217    _e_comp_object_animating_begin(cw);
5218    cw->effect_running = 1;
5219    return EINA_TRUE;
5220 }
5221
5222 /* stop a currently-running effect immediately */
5223 E_API Eina_Bool
5224 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5225 {
5226    int ret = 0;
5227    Edje_Signal_Cb end_cb_before = NULL;
5228    void *end_data_before = NULL;
5229    API_ENTRY EINA_FALSE;
5230
5231    end_cb_before   = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5232    end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5233
5234    if (end_cb_before != end_cb) return EINA_TRUE;
5235    e_comp_object_effect_unclip(obj);
5236    if (cw->effect_clip)
5237      {
5238         evas_object_clip_unset(cw->effect_obj);
5239         cw->effect_clip = 0;
5240      }
5241    edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5242    edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5243
5244    if (evas_object_data_get(cw->smart_obj, "effect_running"))
5245      {
5246         evas_object_data_del(cw->smart_obj, "effect_running");
5247         e_comp_visibility_calculation_set(EINA_TRUE);
5248      }
5249
5250    cw->effect_running = 0;
5251    ret = _e_comp_object_animating_end(cw);
5252
5253    if ((ret) && (end_cb_before))
5254      {
5255         _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5256         end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5257      }
5258
5259    return ret;
5260 }
5261
5262 static int
5263 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5264 {
5265    return a->pri - b->pri;
5266 }
5267
5268 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5269 E_API E_Comp_Object_Mover *
5270 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5271 {
5272    E_Comp_Object_Mover *prov;
5273
5274    prov = E_NEW(E_Comp_Object_Mover, 1);
5275    EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5276    prov->func = provider;
5277    prov->data = (void*)data;
5278    prov->pri = pri;
5279    prov->sig = sig;
5280    _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5281      (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5282    return prov;
5283 }
5284
5285 E_API void
5286 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5287 {
5288    EINA_SAFETY_ON_NULL_RETURN(prov);
5289    _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5290    free(prov);
5291 }
5292
5293 E_API Evas_Object *
5294 e_comp_object_effect_object_get(Evas_Object *obj)
5295 {
5296    API_ENTRY NULL;
5297
5298    return cw->effect_obj;
5299 }
5300
5301 E_API Eina_Bool
5302 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5303 {
5304    API_ENTRY EINA_FALSE;
5305    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5306    if (!cw->effect_set) return EINA_FALSE;
5307
5308    cw->hiding = set;
5309
5310    return EINA_TRUE;
5311 }
5312
5313 ////////////////////////////////////
5314
5315 static void
5316 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5317 {
5318    if (e_comp->autoclose.obj)
5319      {
5320         e_comp_ungrab_input(0, 1);
5321         if (e_comp->autoclose.del_cb)
5322           e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5323         else if (!already_del)
5324           {
5325              evas_object_hide(e_comp->autoclose.obj);
5326              E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5327           }
5328         E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5329      }
5330    e_comp->autoclose.obj = NULL;
5331    e_comp->autoclose.data = NULL;
5332    e_comp->autoclose.del_cb = NULL;
5333    e_comp->autoclose.key_cb = NULL;
5334    E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5335 }
5336
5337 static void
5338 _e_comp_object_autoclose_mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
5339 {
5340    _e_comp_object_autoclose_cleanup(0);
5341 }
5342
5343 static void
5344 _e_comp_object_autoclose_setup(Evas_Object *obj)
5345 {
5346    if (!e_comp->autoclose.rect)
5347      {
5348         /* create rect just below autoclose object to catch mouse events */
5349         e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5350         evas_object_move(e_comp->autoclose.rect, 0, 0);
5351         evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5352         evas_object_show(e_comp->autoclose.rect);
5353         evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5354         evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5355         evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5356         e_comp_grab_input(0, 1);
5357      }
5358    evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5359    evas_object_focus_set(obj, 1);
5360 }
5361
5362 static void
5363 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5364 {
5365    _e_comp_object_autoclose_setup(obj);
5366    evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5367 }
5368
5369 static void
5370 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5371 {
5372    evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5373    _e_comp_object_autoclose_cleanup(1);
5374    if (e_client_focused_get()) return;
5375
5376    E_Zone *zone = e_zone_current_get();
5377    if (!zone) return;
5378
5379    e_zone_focus_reset(zone);
5380 }
5381
5382 EINTERN void
5383 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5384 {
5385    SOFT_ENTRY();
5386
5387    if (e_comp->autoclose.obj)
5388      {
5389         if (e_comp->autoclose.obj == obj) return;
5390         evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5391         e_comp->autoclose.obj = obj;
5392         e_comp->autoclose.del_cb = del_cb;
5393         e_comp->autoclose.key_cb = cb;
5394         e_comp->autoclose.data = (void*)data;
5395         if (evas_object_visible_get(obj))
5396           _e_comp_object_autoclose_setup(obj);
5397         else
5398           evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5399         evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5400         return;
5401      }
5402    e_comp->autoclose.obj = obj;
5403    e_comp->autoclose.del_cb = del_cb;
5404    e_comp->autoclose.key_cb = cb;
5405    e_comp->autoclose.data = (void*)data;
5406    if (evas_object_visible_get(obj))
5407      _e_comp_object_autoclose_setup(obj);
5408    else
5409      evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5410    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5411 }
5412
5413 E_API unsigned int
5414 e_comp_object_is_animating(Evas_Object *obj)
5415 {
5416    API_ENTRY 0;
5417
5418    return cw->animating;
5419 }
5420
5421 E_API void
5422 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5423 {
5424    API_ENTRY;
5425
5426    if ((cw->external_content) &&
5427        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5428      {
5429         WRN("Can set up alpha value to ONLY evas \"image\" object. "
5430             "But current external content is %d object for %p.",
5431             cw->content_type, cw->ec);
5432         return;
5433      }
5434
5435    cw->user_alpha_set = EINA_TRUE;
5436    cw->user_alpha = alpha;
5437
5438    if (!cw->obj) return;
5439
5440    if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5441
5442    evas_object_image_alpha_set(cw->obj, alpha);
5443
5444    if ((!cw->native) && (!cw->external_content))
5445      evas_object_image_data_set(cw->obj, NULL);
5446 }
5447
5448 EINTERN Eina_Bool
5449 e_comp_object_alpha_get(Evas_Object *obj)
5450 {
5451    API_ENTRY EINA_FALSE;
5452
5453    return evas_object_image_alpha_get(cw->obj);
5454 }
5455
5456 E_API void
5457 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5458 {
5459    Eina_Bool mask_set = EINA_FALSE;
5460    Evas_Object *o;
5461
5462    API_ENTRY;
5463    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5464    if (cw->ec->input_only) return;
5465    mask_set = !!set;
5466
5467    if (mask_set)
5468      {
5469         if (!cw->mask.obj)
5470           {
5471              o = evas_object_rectangle_add(e_comp->evas);
5472              evas_object_color_set(o, 0, 0, 0, 0);
5473              evas_object_clip_set(o, cw->clip);
5474              evas_object_smart_member_add(o, obj);
5475              evas_object_move(o, 0, 0);
5476              evas_object_resize(o, cw->w, cw->h);
5477              /* save render op value to restore when clear a mask.
5478               *
5479               * NOTE: DO NOT change the render op on ec->frame while mask object
5480               * is set. it will overwrite the changed op value. */
5481              cw->mask.saved_render_op = evas_object_render_op_get(obj);
5482              evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5483              evas_object_render_op_set(o, EVAS_RENDER_COPY);
5484              if (cw->visible) evas_object_show(o);
5485
5486              cw->mask.obj = o;
5487              evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5488              ELOGF("COMP", "         |mask_obj", cw->ec);
5489              _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5490           }
5491      }
5492    else
5493      {
5494         if (cw->mask.obj)
5495           {
5496              evas_object_smart_member_del(cw->mask.obj);
5497              E_FREE_FUNC(cw->mask.obj, evas_object_del);
5498
5499              evas_object_render_op_set(obj, cw->mask.saved_render_op);
5500              _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5501           }
5502      }
5503 }
5504
5505 E_API Eina_Bool
5506 e_comp_object_mask_has(Evas_Object *obj)
5507 {
5508    API_ENTRY EINA_FALSE;
5509
5510    return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5511 }
5512
5513 EINTERN void
5514 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5515 {
5516    int tw, th;
5517    API_ENTRY;
5518
5519    if ((cw->external_content) &&
5520        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5521      {
5522         WRN("Can set up size to ONLY evas \"image\" object. "
5523             "But current external content is %d object for %p.",
5524             cw->content_type, cw->ec);
5525         return;
5526      }
5527
5528    _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5529
5530    evas_object_image_size_set(cw->obj, tw, th);
5531 }
5532
5533 E_API void
5534 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5535 {
5536    Eina_Bool transform_set = EINA_FALSE;
5537    API_ENTRY;
5538    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5539    if (cw->ec->input_only) return;
5540
5541    transform_set = !!set;
5542
5543    if (transform_set)
5544      {
5545         if (!cw->transform_bg_obj)
5546           {
5547              Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5548              evas_object_move(o, 0, 0);
5549              evas_object_resize(o, 1, 1);
5550              if (cw->transform_bg_color.a >= 255)
5551                evas_object_render_op_set(o, EVAS_RENDER_COPY);
5552              else
5553                evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5554              evas_object_color_set(o,
5555                                    cw->transform_bg_color.r,
5556                                    cw->transform_bg_color.g,
5557                                    cw->transform_bg_color.b,
5558                                    cw->transform_bg_color.a);
5559              if (cw->visible) evas_object_show(o);
5560
5561              cw->transform_bg_obj = o;
5562              evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5563           }
5564 #ifdef REFACTOR_DESK_AREA
5565         e_comp_object_transform_obj_stack_update(obj);
5566 #else
5567         _e_comp_object_transform_obj_stack_update(obj);
5568 #endif
5569      }
5570    else
5571      {
5572         if (cw->transform_bg_obj)
5573           {
5574              evas_object_smart_member_del(cw->transform_bg_obj);
5575              E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5576           }
5577      }
5578 }
5579
5580 E_API void
5581 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5582 {
5583    API_ENTRY;
5584
5585    cw->transform_bg_color.r = r;
5586    cw->transform_bg_color.g = g;
5587    cw->transform_bg_color.b = b;
5588    cw->transform_bg_color.a = a;
5589
5590    if (cw->transform_bg_obj)
5591      {
5592         evas_object_color_set(cw->transform_bg_obj,
5593                               cw->transform_bg_color.r,
5594                               cw->transform_bg_color.g,
5595                               cw->transform_bg_color.b,
5596                               cw->transform_bg_color.a);
5597      }
5598 }
5599
5600 EINTERN void
5601 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5602 {
5603    API_ENTRY;
5604    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5605    if (cw->ec->input_only) return;
5606    if (!cw->transform_bg_obj) return;
5607
5608    _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5609 }
5610
5611 EINTERN void
5612 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5613 {
5614    API_ENTRY;
5615    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5616    if (cw->ec->input_only) return;
5617    if (!cw->transform_bg_obj) return;
5618
5619    _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5620 }
5621
5622 E_API void
5623 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5624 {
5625    Eina_Bool transform_set = EINA_FALSE;
5626    API_ENTRY;
5627    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5628    if (cw->ec->input_only) return;
5629
5630    transform_set = !!set;
5631
5632    if (transform_set)
5633      {
5634         if (!cw->transform_tranp_obj)
5635           {
5636              Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5637              evas_object_move(o, 0, 0);
5638              evas_object_resize(o, 1, 1);
5639              evas_object_render_op_set(o, EVAS_RENDER_COPY);
5640              evas_object_color_set(o, 0, 0, 0, 0);
5641              if (cw->visible) evas_object_show(o);
5642
5643              cw->transform_tranp_obj = o;
5644              evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5645              ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5646              evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5647           }
5648 #ifdef REFACTOR_DESK_AREA
5649         e_comp_object_transform_obj_stack_update(obj);
5650 #else
5651         _e_comp_object_transform_obj_stack_update(obj);
5652 #endif
5653      }
5654    else
5655      {
5656         if (cw->transform_tranp_obj)
5657           {
5658              ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5659              evas_object_smart_member_del(cw->transform_tranp_obj);
5660              E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5661           }
5662      }
5663 }
5664
5665 EINTERN void
5666 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5667 {
5668    API_ENTRY;
5669    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5670    if (cw->ec->input_only) return;
5671    if (!cw->transform_tranp_obj) return;
5672
5673    _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5674 }
5675
5676 EINTERN void
5677 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5678 {
5679    API_ENTRY;
5680    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5681    if (cw->ec->input_only) return;
5682    if (!cw->transform_tranp_obj) return;
5683
5684    _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5685 }
5686
5687 #ifdef REFACTOR_DESK_AREA
5688 #else
5689 EINTERN void
5690 e_comp_object_layer_update(Evas_Object *obj,
5691                            Evas_Object *above, Evas_Object *below)
5692 {
5693    E_Comp_Object *cw2 = NULL;
5694    Evas_Object *o = NULL;
5695    short layer;
5696
5697    API_ENTRY;
5698
5699    if (cw->ec->layer_block) return;
5700    if ((above) && (below))
5701      {
5702         ERR("Invalid layer update request! cw=%p", cw);
5703         return;
5704      }
5705
5706    o = above?:below;
5707
5708    if (o)
5709      {
5710         layer = evas_object_layer_get(o);
5711         cw2 = evas_object_data_get(o, "comp_obj");
5712         while (!cw2)
5713           {
5714              if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5715
5716              o = evas_object_above_get(o);
5717              if ((!o) || (o == cw->smart_obj)) break;
5718              if (evas_object_layer_get(o) != layer)
5719                {
5720                   o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5721                }
5722              if (!o)
5723                {
5724                   E_Client *ec;
5725                   ec = e_client_top_get();
5726                   if (ec) o = ec->frame;
5727                }
5728
5729              if (o) cw2 = evas_object_data_get(o, "comp_obj");
5730           }
5731      }
5732
5733    _e_comp_object_layers_remove(cw);
5734    if (cw2)
5735      {
5736         if (cw2->layer > cw->layer)
5737           _e_comp_object_layers_add(cw, NULL, NULL, 0);
5738         else if (cw2->layer == cw->layer)
5739           {
5740              if (above)
5741                _e_comp_object_layers_add(cw, cw2, NULL, 0);
5742              else if (o == obj)
5743                _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5744              else if (below)
5745                _e_comp_object_layers_add(cw, NULL, cw2, 0);
5746           }
5747         else
5748           _e_comp_object_layers_add(cw, NULL, NULL, 1);
5749      }
5750    else
5751      _e_comp_object_layers_add(cw, NULL, NULL, 0);
5752 }
5753 #endif
5754
5755 EINTERN int
5756 e_comp_object_layer_get(Evas_Object *obj)
5757 {
5758    API_ENTRY -1;
5759    return cw->layer;
5760 }
5761
5762 E_API Eina_Bool
5763 e_comp_object_content_set(Evas_Object *obj,
5764                           Evas_Object *content,
5765                           E_Comp_Object_Content_Type type)
5766 {
5767    API_ENTRY EINA_FALSE;
5768
5769    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5770    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5771    EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5772
5773    if (cw->obj)
5774      {
5775         ERR("Can't set e.swallow.content to requested content. "
5776             "Previous comp object should not be changed at all.");
5777         return EINA_FALSE;
5778      }
5779
5780    if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5781
5782    if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5783        (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5784      {
5785         ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5786             type, content, cw->ec, cw->ec->pixmap);
5787         return EINA_FALSE;
5788      }
5789
5790    cw->external_content = EINA_TRUE;
5791
5792    cw->obj = content;
5793    cw->content_type = type;
5794    e_util_size_debug_set(cw->obj, 1);
5795    evas_object_name_set(cw->obj, "cw->obj");
5796    _e_comp_object_alpha_set(cw);
5797
5798    if (cw->shobj)
5799      _e_comp_object_shadow_setup(cw);
5800
5801    wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5802
5803    return EINA_TRUE;
5804 }
5805
5806 EINTERN Eina_Bool
5807 e_comp_object_content_unset(Evas_Object *obj)
5808 {
5809    API_ENTRY EINA_FALSE;
5810
5811    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5812    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5813
5814    if (!cw->obj && !cw->ec->visible)
5815      {
5816         ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5817         return EINA_TRUE;
5818      }
5819
5820    if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5821      {
5822         ELOGF("COMP", "has been set to internal image object already", cw->ec);
5823         return EINA_TRUE;
5824      }
5825
5826    if (cw->obj)
5827      {
5828         if (cw->frame_object)
5829           edje_object_part_unswallow(cw->frame_object, cw->obj);
5830         else if (cw->shobj)
5831           edje_object_part_unswallow(cw->shobj, cw->obj);
5832
5833         evas_object_del(cw->obj);
5834         evas_object_hide(cw->obj);
5835         cw->obj = NULL;
5836      }
5837
5838    cw->external_content = EINA_FALSE;
5839    if (cw->ec->is_cursor)
5840      {
5841         int pw, ph;
5842         DBG("%p is cursor surface..", cw->ec);
5843         if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5844           pw = ph = 1;
5845         evas_object_resize(cw->ec->frame, pw, ph);
5846         evas_object_hide(cw->ec->frame);
5847         return EINA_TRUE;
5848      }
5849
5850
5851    cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5852    cw->obj = evas_object_image_filled_add(e_comp->evas);
5853    evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5854    e_util_size_debug_set(cw->obj, 1);
5855    evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5856    evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5857    evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5858    evas_object_name_set(cw->obj, "cw->obj");
5859    evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5860    _e_comp_object_alpha_set(cw);
5861
5862    if (cw->shobj)
5863      _e_comp_object_shadow_setup(cw);
5864
5865    if (cw->visible)
5866      {
5867         cw->visible = 0;
5868         _e_comp_intercept_show_helper(cw);
5869         cw->visible = 1;
5870      }
5871
5872    e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5873    e_comp_object_dirty(cw->smart_obj);
5874    e_comp_object_render(cw->smart_obj);
5875    e_comp_object_render_update_add(obj);
5876
5877    wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5878
5879    return EINA_TRUE;
5880 }
5881
5882 EINTERN Evas_Object *
5883 e_comp_object_content_get(Evas_Object *obj)
5884 {
5885    API_ENTRY NULL;
5886
5887    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5888
5889    if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5890      {
5891         ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5892         return NULL;
5893      }
5894
5895    return cw->obj;
5896 }
5897
5898 E_API E_Comp_Object_Content_Type
5899 e_comp_object_content_type_get(Evas_Object *obj)
5900 {
5901    API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5902
5903    return cw->content_type;
5904 }
5905
5906 E_API void
5907 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5908 {
5909    API_ENTRY;
5910    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5911    E_Comp_Config *conf = e_comp_config_get();
5912    if (cw->ec->input_only) return;
5913    if (!conf->dim_rect_enable) return;
5914
5915    cw->dim.mask_set = mask_set;
5916    cw->dim.mask_x = x;
5917    cw->dim.mask_y = y;
5918    cw->dim.mask_w = w;
5919    cw->dim.mask_h = h;
5920
5921    if (!cw->dim.enable) return;
5922    e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5923 }
5924
5925 EINTERN void
5926 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
5927 {
5928    Eina_Bool mask_set = EINA_FALSE;
5929    Evas_Object *o;
5930
5931    API_ENTRY;
5932    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5933    E_Comp_Config *conf = e_comp_config_get();
5934    if (cw->ec->input_only) return;
5935    if (!conf->dim_rect_enable) return;
5936
5937    mask_set = !!set;
5938
5939    if (mask_set)
5940      {
5941         if (cw->dim.mask_obj)
5942           {
5943              evas_object_smart_member_del(cw->dim.mask_obj);
5944              E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5945           }
5946
5947         ELOGF("COMP", "DIM  |Mask applied on Dim rect mask_rect[%d %d %d %d]", cw->ec, cw->dim.mask_x, cw->dim.mask_y, cw->dim.mask_w, cw->dim.mask_h);
5948         o = evas_object_rectangle_add(e_comp->evas);
5949         evas_object_color_set(o, 0, 0, 0, 0);
5950         evas_object_smart_member_add(o, obj);
5951         evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
5952         evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
5953
5954         evas_object_render_op_set(o, EVAS_RENDER_COPY);
5955         if (cw->visible) evas_object_show(o);
5956
5957         cw->dim.mask_obj = o;
5958         evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
5959
5960         evas_object_layer_set(cw->dim.mask_obj, 9998);
5961      }
5962    else
5963      {
5964         if (cw->dim.mask_obj)
5965           {
5966              ELOGF("COMP", "DIM  |Mask on Dim rect Removed", cw->ec);
5967              evas_object_smart_member_del(cw->dim.mask_obj);
5968              E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
5969           }
5970      }
5971 }
5972
5973 E_API void
5974 e_comp_object_dim_client_set(E_Client *ec)
5975 {
5976    E_Comp_Config *conf = e_comp_config_get();
5977
5978    if (!conf->dim_rect_enable) return ;
5979    if (dim_client == ec) return;
5980
5981    Eina_Bool prev_dim = EINA_FALSE;
5982    ELOGF("COMP", "DIM  |Client Set %p -> %p", ec, dim_client, ec);
5983
5984    if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
5985       prev_dim = EINA_TRUE;
5986
5987    if (prev_dim && dim_client->visible && ec)
5988      {
5989         _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
5990         _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
5991      }
5992    else
5993      {
5994         if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
5995         if (ec)       _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
5996      }
5997    dim_client = ec;
5998 }
5999
6000 EINTERN E_Client *
6001 e_comp_object_dim_client_get(void)
6002 {
6003    E_Comp_Config *conf = e_comp_config_get();
6004
6005    if (!conf->dim_rect_enable ) return NULL;
6006
6007    return dim_client;
6008 }
6009
6010 static void
6011 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6012 {
6013    API_ENTRY;
6014    char emit[32] = "\0";
6015    E_Comp_Config *conf = e_comp_config_get();
6016
6017    if (!ec) return;
6018    if (!conf->dim_rect_enable) return;
6019    if (!cw->effect_obj) return;
6020    if (enable == cw->dim.enable) return;
6021
6022    ELOGF("COMP", "DIM  |set on Client [%d]", ec, enable);
6023    if (noeffect || !conf->dim_rect_effect)
6024      {
6025         strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6026      }
6027    else
6028      {
6029         strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6030      }
6031
6032    cw->dim.enable = enable;
6033
6034    if (cw->dim.mask_set && !enable)
6035      {
6036         e_comp_object_dim_mask_set(cw->ec->frame, enable);
6037         edje_object_signal_emit(cw->effect_obj, emit, "e");
6038      }
6039    else if (cw->dim.mask_set && enable)
6040      {
6041         edje_object_signal_emit(cw->effect_obj, emit, "e");
6042         e_comp_object_dim_mask_set(cw->ec->frame, enable);
6043      }
6044    else
6045      {
6046         edje_object_signal_emit(cw->effect_obj, emit, "e");
6047      }
6048 }
6049
6050 static Eina_Bool
6051 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6052 {
6053    API_ENTRY EINA_FALSE;
6054    E_Comp_Config *conf = e_comp_config_get();
6055
6056    if (!ec) return EINA_FALSE;
6057    if (!conf->dim_rect_enable) return EINA_FALSE;
6058
6059    if (cw->dim.enable) return EINA_TRUE;
6060
6061    return EINA_FALSE;
6062 }
6063
6064 static void
6065 _e_comp_object_dim_update(E_Comp_Object *cw)
6066 {
6067    E_Comp_Config *conf = e_comp_config_get();
6068
6069    if (!cw) return;
6070    if (!conf->dim_rect_enable) return;
6071    if (!cw->effect_obj) return;
6072    if (cw->dim.enable)
6073      {
6074         edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6075         ELOGF("COMP", "DIM  |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6076
6077         if (cw->dim.mask_set)
6078           {
6079              e_comp_object_dim_mask_set(cw->ec->frame,  cw->dim.mask_set);
6080           }
6081      }
6082 }
6083
6084 EINTERN void
6085 e_comp_object_clear(Evas_Object *obj)
6086 {
6087    API_ENTRY;
6088
6089    _e_comp_object_clear(cw);
6090 }
6091
6092 EINTERN Eina_Bool
6093 e_comp_object_hwc_update_exists(Evas_Object *obj)
6094 {
6095    API_ENTRY EINA_FALSE;
6096    return cw->hwc_need_update;
6097 }
6098
6099 // will remove out
6100 E_API void
6101 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6102 {
6103    API_ENTRY;
6104    cw->hwc_need_update = set;
6105 }
6106
6107 E_API Eina_Bool
6108 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6109 {
6110    API_ENTRY EINA_FALSE;
6111    return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6112 }
6113
6114 EINTERN void
6115 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6116 {
6117    API_ENTRY;
6118    if (cw->indicator.obj != indicator)
6119      edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6120    cw->indicator.obj = indicator;
6121    edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6122 }
6123
6124 EINTERN void
6125 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6126 {
6127    API_ENTRY;
6128    if (cw->indicator.obj != indicator) return;
6129    cw->indicator.obj = NULL;
6130    edje_object_part_unswallow(cw->shobj, indicator);
6131 }
6132
6133 EINTERN void
6134 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6135 {
6136    API_ENTRY;
6137    Edje_Message_Int_Set *msg;
6138
6139    if (!cw->indicator.obj) return;
6140
6141    cw->indicator.w = w;
6142    cw->indicator.h = h;
6143
6144    if (!cw->shobj) return;
6145
6146    msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6147    msg->count = 2;
6148    msg->val[0] = w;
6149    msg->val[1] = h;
6150    edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6151    edje_object_message_signal_process(cw->shobj);
6152 }
6153
6154 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6155 EINTERN void
6156 e_comp_object_map_update(Evas_Object *obj)
6157 {
6158    API_ENTRY;
6159    E_Client *ec = cw->ec;
6160    E_Comp_Wl_Client_Data *cdata;
6161    E_Map *map;
6162    int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6163    char buffer[128];
6164    char *p = buffer;
6165    int l, remain = sizeof buffer;
6166
6167    if (!ec) return;
6168    if (e_object_is_del(E_OBJECT(ec))) return;
6169    cdata = e_client_cdata_get(ec);
6170    if (!cdata) return;
6171
6172    /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6173     * when new buffer is attached.
6174     */
6175    if (!cdata->buffer_ref.buffer) return;
6176
6177    if ((!cw->redirected) ||
6178        (e_client_video_hw_composition_check(ec)) ||
6179        (!e_comp_wl_output_buffer_transform_get(ec) &&
6180         cdata->scaler.buffer_viewport.buffer.scale == 1))
6181      {
6182         if (evas_object_map_enable_get(cw->effect_obj))
6183           {
6184              ELOGF("TRANSFORM", "map: disable", cw->ec);
6185              evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6186              _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6187              evas_object_resize(cw->effect_obj, tw, th);
6188           }
6189
6190         return;
6191      }
6192
6193    map = e_map_new();
6194    EINA_SAFETY_ON_NULL_RETURN(map);
6195
6196    e_pixmap_size_get(ec->pixmap, &bw, &bh);
6197
6198    x1 = y1 = 0;
6199    x2 = bw;
6200    y2 = bh;
6201
6202    e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6203
6204    _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6205    e_map_point_image_uv_set(map, 0, x, y);
6206    l = snprintf(p, remain, "%d,%d", x, y);
6207    p += l, remain -= l;
6208
6209    _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6210    e_map_point_image_uv_set(map, 1, x, y);
6211    l = snprintf(p, remain, " %d,%d", x, y);
6212    p += l, remain -= l;
6213
6214    _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6215    e_map_point_image_uv_set(map, 2, x, y);
6216    l = snprintf(p, remain, " %d,%d", x, y);
6217    p += l, remain -= l;
6218
6219    _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6220    e_map_point_image_uv_set(map, 3, x, y);
6221    l = snprintf(p, remain, " %d,%d", x, y);
6222    p += l, remain -= l;
6223
6224    ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6225          cw->ec,
6226          ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6227
6228    e_comp_object_map_set(cw->effect_obj, map);
6229    e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6230
6231    e_map_free(map);
6232
6233    /* if there's screen rotation with comp mode, then ec->effect_obj and
6234     * ec->obj should rotate. if not, in evas_map, update region is clipped.
6235     */
6236    _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6237    evas_object_resize(cw->effect_obj, tw, th);
6238 }
6239
6240 EINTERN Eina_Bool
6241 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6242 {
6243    API_ENTRY EINA_FALSE;
6244
6245    cw->render_trace = set;
6246
6247    return EINA_TRUE;
6248 }
6249
6250 E_API Eina_Bool
6251 e_comp_object_native_usable_get(Evas_Object *obj)
6252 {
6253    API_ENTRY EINA_FALSE;
6254    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6255
6256    if (cw->ec->input_only) return EINA_FALSE;
6257    if (cw->external_content) return EINA_FALSE;
6258    if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6259
6260    /* just return true value, if it is normal case */
6261    if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6262
6263    /* abnormal case */
6264    Evas_Native_Surface *ns;
6265    ns = evas_object_image_native_surface_get(cw->obj);
6266
6267    /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6268    if (ns)
6269      {
6270         ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6271         return EINA_TRUE;
6272      }
6273
6274    return EINA_FALSE;
6275 }
6276
6277 EINTERN Eina_Bool
6278 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6279 {
6280    API_ENTRY EINA_FALSE;
6281    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6282    if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6283    if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6284
6285    if (cw->image_filter == filter) return EINA_TRUE;
6286
6287    switch (filter)
6288      {
6289       case E_COMP_IMAGE_FILTER_BLUR:
6290          efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6291          break;
6292       case E_COMP_IMAGE_FILTER_GRAYSCALE:
6293          efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6294          break;
6295       case E_COMP_IMAGE_FILTER_INVERSE:
6296          efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6297          break;
6298       case E_COMP_IMAGE_FILTER_NONE:
6299       default:
6300          efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6301          break;
6302      }
6303
6304    cw->image_filter = filter;
6305
6306    wl_signal_emit_mutable(&cw->events.image_filter_set, NULL);
6307
6308    return EINA_TRUE;
6309 }
6310
6311 EINTERN E_Comp_Image_Filter
6312 e_comp_object_image_filter_get(Evas_Object *obj)
6313 {
6314    API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6315    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6316    if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6317    if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6318
6319    return cw->image_filter;
6320 }
6321
6322 static void
6323 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6324 {
6325    Evas_Object *obj;
6326
6327    if (!_damage_trace) return;
6328
6329    EINA_LIST_FREE(_damage_trace_post_objs, obj)
6330      evas_object_del(obj);
6331
6332    _damage_trace_post_objs = NULL;
6333 }
6334
6335 static void
6336 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6337 {
6338    if (!_damage_trace) return;
6339
6340    _damage_trace_post_objs = _damage_trace_objs;
6341    _damage_trace_objs = NULL;
6342 }
6343
6344 EINTERN void
6345 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6346 {
6347    if (_damage_trace == onoff) return;
6348
6349    if (onoff)
6350      {
6351         evas_event_callback_add(e_comp->evas,
6352                                 EVAS_CALLBACK_RENDER_PRE,
6353                                 _e_comp_object_damage_trace_render_pre_cb,
6354                                 NULL);
6355
6356         evas_event_callback_add(e_comp->evas,
6357                                 EVAS_CALLBACK_RENDER_POST,
6358                                 _e_comp_object_damage_trace_render_post_cb,
6359                                 NULL);
6360      }
6361    else
6362      {
6363         Evas_Object *obj;
6364
6365         EINA_LIST_FREE(_damage_trace_objs, obj)
6366           evas_object_del(obj);
6367
6368         _damage_trace_objs = NULL;
6369
6370         EINA_LIST_FREE(_damage_trace_post_objs, obj)
6371           evas_object_del(obj);
6372
6373         _damage_trace_post_objs = NULL;
6374
6375         evas_event_callback_del(e_comp->evas,
6376                                 EVAS_CALLBACK_RENDER_PRE,
6377                                 _e_comp_object_damage_trace_render_pre_cb);
6378
6379         evas_event_callback_del(e_comp->evas,
6380                                 EVAS_CALLBACK_RENDER_POST,
6381                                 _e_comp_object_damage_trace_render_post_cb);
6382      }
6383
6384    _damage_trace = onoff;
6385 }
6386
6387 EINTERN Eina_Bool
6388 e_comp_object_redirected_get(Evas_Object *obj)
6389 {
6390    API_ENTRY EINA_FALSE;
6391    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6392
6393    return cw->redirected;
6394 }
6395
6396 EINTERN Eina_Bool
6397 e_comp_object_color_visible_get(Evas_Object *obj)
6398 {
6399    API_ENTRY EINA_FALSE;
6400    int a;
6401
6402    EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6403
6404    e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6405    if (a <= 0)
6406      return EINA_FALSE;
6407
6408    evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6409    if (a <= 0)
6410      return EINA_FALSE;
6411
6412    evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6413    if (a <= 0)
6414      return EINA_FALSE;
6415
6416    evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6417    if (a <= 0)
6418      return EINA_FALSE;
6419
6420    return EINA_TRUE;
6421 }
6422
6423 E_API Eina_Bool
6424 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6425 {
6426    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6427
6428    return e_map_set_to_comp_object(em, obj);
6429 }
6430
6431 EINTERN E_Map *
6432 e_comp_object_map_get(const Evas_Object *obj)
6433 {
6434    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6435
6436    return e_map_get_from_comp_object(obj);
6437 }
6438
6439 E_API Eina_Bool
6440 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6441 {
6442    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6443
6444    evas_object_map_enable_set(obj, enable);
6445
6446    return EINA_TRUE;
6447 }
6448
6449 E_API Eina_Bool
6450 e_comp_object_render_update_lock(Evas_Object *obj)
6451 {
6452    E_Comp_Wl_Buffer *buffer;
6453    struct wayland_tbm_client_queue *cqueue;
6454
6455    API_ENTRY EINA_FALSE;
6456
6457    if (cw->render_update_lock.lock == 0)
6458      {
6459         _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6460
6461         buffer = e_pixmap_resource_get(cw->ec->pixmap);
6462         if ((buffer) && (buffer->resource))
6463           {
6464              cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6465              if (cqueue)
6466                wayland_tbm_server_client_queue_flush(cqueue);
6467           }
6468
6469         e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6470         e_comp_object_render_update_del(obj);
6471
6472         ELOGF("COMP", "Render update lock enabled", cw->ec);
6473      }
6474
6475    cw->render_update_lock.lock++;
6476
6477    return EINA_TRUE;
6478 }
6479
6480 E_API void
6481 e_comp_object_render_update_unlock(Evas_Object *obj)
6482 {
6483    API_ENTRY;
6484
6485    if (cw->render_update_lock.lock == 0)
6486      return;
6487
6488    cw->render_update_lock.lock--;
6489
6490    if (cw->render_update_lock.lock == 0)
6491      {
6492
6493         if (cw->render_update_lock.pending_move_set)
6494           {
6495              evas_object_move(obj,
6496                               cw->render_update_lock.pending_move_x,
6497                               cw->render_update_lock.pending_move_y);
6498              cw->render_update_lock.pending_move_x = 0;
6499              cw->render_update_lock.pending_move_y = 0;
6500              cw->render_update_lock.pending_move_set = EINA_FALSE;
6501           }
6502
6503         if (cw->render_update_lock.pending_resize_set)
6504           {
6505              evas_object_resize(obj,
6506                                 cw->render_update_lock.pending_resize_w,
6507                                 cw->render_update_lock.pending_resize_h);
6508              cw->render_update_lock.pending_resize_w = 0;
6509              cw->render_update_lock.pending_resize_h = 0;
6510              cw->render_update_lock.pending_resize_set = EINA_FALSE;
6511           }
6512
6513         e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6514
6515         if ((cw->ec->exp_iconify.buffer_flush) &&
6516             (e_policy_visibility_client_is_iconic(cw->ec)) &&
6517             (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6518           e_comp_object_clear(obj);
6519         else
6520           e_comp_object_render_update_add(obj);
6521
6522         _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET, cw->ec);
6523
6524         ELOGF("COMP", "Render update lock disabled", cw->ec);
6525      }
6526 }
6527
6528 E_API Eina_Bool
6529 e_comp_object_render_update_lock_get(Evas_Object *obj)
6530 {
6531    API_ENTRY EINA_FALSE;
6532
6533    if (cw->render_update_lock.lock > 0)
6534      return EINA_TRUE;
6535
6536    return EINA_FALSE;
6537 }
6538
6539 E_API void
6540 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6541 {
6542    API_ENTRY;
6543
6544    if (cw->transparent.set)
6545      {
6546         if (r) *r = cw->transparent.user_r;
6547         if (g) *g = cw->transparent.user_g;
6548         if (b) *b = cw->transparent.user_b;
6549         if (a) *a = cw->transparent.user_a;
6550      }
6551    else
6552      {
6553         evas_object_color_get(obj, r, g, b, a);
6554      }
6555 }
6556
6557 EINTERN void
6558 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6559 {
6560    API_ENTRY;
6561
6562    evas_object_render_op_set(cw->obj, op);
6563
6564    wl_signal_emit_mutable(&cw->events.render_op_set, NULL);
6565 }
6566
6567 EINTERN Evas_Render_Op
6568 e_comp_object_render_op_get(Evas_Object *obj)
6569 {
6570    API_ENTRY EVAS_RENDER_BLEND;
6571
6572    return evas_object_render_op_get(cw->obj);
6573 }
6574
6575 EINTERN void
6576 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6577 {
6578    API_ENTRY;
6579    wl_signal_add(&cw->events.lower, listener);
6580 }
6581
6582 #ifdef REFACTOR_DESK_AREA
6583 EINTERN void
6584 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6585 {
6586    API_ENTRY;
6587    wl_signal_add(&cw->events.lower_done, listener);
6588 }
6589
6590 EINTERN void
6591 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6592 {
6593    API_ENTRY;
6594    wl_signal_add(&cw->events.raise, listener);
6595 }
6596 #endif
6597
6598 EINTERN void
6599 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6600 {
6601    API_ENTRY;
6602    wl_signal_add(&cw->events.show, listener);
6603 }
6604
6605 EINTERN void
6606 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6607 {
6608    API_ENTRY;
6609    wl_signal_add(&cw->events.hide, listener);
6610 }
6611
6612 #ifdef REFACTOR_DESK_AREA
6613 EINTERN void
6614 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6615 {
6616    API_ENTRY;
6617    wl_signal_add(&cw->events.set_layer, listener);
6618 }
6619
6620 EINTERN void
6621 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6622 {
6623    API_ENTRY;
6624    wl_signal_add(&cw->events.stack_above, listener);
6625 }
6626
6627 EINTERN void
6628 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6629 {
6630    API_ENTRY;
6631    wl_signal_add(&cw->events.stack_below, listener);
6632 }
6633 #endif
6634
6635 EINTERN void
6636 e_comp_object_image_filter_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6637 {
6638    API_ENTRY;
6639    wl_signal_add(&cw->events.image_filter_set, listener);
6640 }
6641
6642 EINTERN void
6643 e_comp_object_render_op_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6644 {
6645    API_ENTRY;
6646    wl_signal_add(&cw->events.render_op_set, listener);
6647 }
6648
6649 EINTERN void
6650 e_comp_object_content_type_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6651 {
6652    API_ENTRY;
6653    wl_signal_add(&cw->events.content_type_set, listener);
6654 }
6655
6656 EINTERN void
6657 e_comp_object_color_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6658 {
6659    API_ENTRY;
6660    wl_signal_add(&cw->events.color_set, listener);
6661 }