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