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