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