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