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