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