e_input: move kbd structure to e_comp_input_intern.h
[platform/upstream/enlightenment.git] / src / bin / e_comp_wl.c
1
2 #include "e_comp_wl_intern.h"
3 #include "e_main_intern.h"
4 #include "e_foreign_intern.h"
5 #include "e_wtz_shell_intern.h"
6 #include "e_client_intern.h"
7 #include "e_appinfo_intern.h"
8 #include "e_blender_intern.h"
9 #include "e_utils_intern.h"
10 #include "e_scale_intern.h"
11 #include "e_comp_canvas_intern.h"
12 #include "e_comp_screen_intern.h"
13 #include "e_comp_wl_capture_intern.h"
14 #include "e_comp_wl_data_intern.h"
15 #include "e_comp_wl_input_intern.h"
16 #include "e_comp_wl_renderer_intern.h"
17 #include "e_comp_wl_rsm_intern.h"
18 #include "e_comp_wl_screenshooter_intern.h"
19 #include "e_comp_wl_shell_intern.h"
20 #include "e_comp_wl_subsurface_intern.h"
21 #include "e_comp_wl_tbm_intern.h"
22 #include "e_comp_wl_viewport_intern.h"
23 #include "e_comp_intern.h"
24 #include "e_input_intern.h"
25 #include "e_keyrouter_intern.h"
26 #include "e_error_intern.h"
27 #include "e_pointer_intern.h"
28 #include "e_presentation_time_intern.h"
29 #include "e_grabinput_intern.h"
30 #include "e_env_intern.h"
31 #include "e_dnd_intern.h"
32 #include "e_policy_visibility_intern.h"
33 #include "e_compositor_intern.h"
34 #include "e_client_video_intern.h"
35 #include "e_comp_wl_video_intern.h"
36 #include "e_comp_object_intern.h"
37 #include "e_desk_intern.h"
38 #include "e_zone_intern.h"
39 #include "e_hints_intern.h"
40 #include "e_comp_input_intern.h"
41 #include "e_blur_intern.h"
42
43 #include <tizen-extension-server-protocol.h>
44 #include <relative-pointer-unstable-v1-server-protocol.h>
45 #include <pointer-constraints-unstable-v1-server-protocol.h>
46
47 #include <wayland-tbm-server.h>
48 #include <glib.h>
49 #include <libds/log.h>
50 #include <libds/single_pixel_buffer_v1.h>
51 #include <Evas_GL.h>
52
53  #include <ctype.h>
54  #include <sys/resource.h>
55
56 /* handle include for printing uint64_t */
57 #define __STDC_FORMAT_MACROS
58 #include <inttypes.h>
59
60 #define E_COM_WL_PREPARE_GAP_LOG_TIME 2000
61
62 /* Resource Data Mapping: (wl_resource_get_user_data)
63  *
64  * wl_surface == e_pixmap
65  * wl_region == eina_tiler
66  * wl_subsurface == e_client
67  *
68  */
69
70 typedef struct _E_Comp_Data E_Comp_Data;
71
72 struct _E_Comp_Data
73 {
74    E_Comp_Wl_Data base;
75    struct wl_listener client_created;
76 };
77
78 static void _e_comp_wl_move_resize_init(void);
79
80 static Eina_Bool _e_comp_wl_cursor_timer_control(Evas_Callback_Type type, E_Client *ec);
81
82 /* local variables */
83 typedef struct _E_Comp_Wl_Key_Data
84 {
85    uint32_t key;
86    Ecore_Device *dev;
87 } E_Comp_Wl_Key_Data;
88
89 struct _E_Comp_Wl_Evas_Gl
90 {
91    Evas_GL *gl;
92    Evas_GL_Config *glcfg;
93    Evas_GL_Context *glctx;
94    Evas_GL_Surface *glsfc;
95    Evas_GL_API *glapi;
96 };
97
98 static Eina_List *handlers = NULL;
99 static E_Client *cursor_timer_ec = NULL;
100 static Eina_Bool need_send_released = EINA_FALSE;
101 static Eina_Bool need_send_motion = EINA_TRUE;
102
103 static GMutex connection_mutex;
104
105 static int _e_comp_wl_hooks_delete = 0;
106 static int _e_comp_wl_hooks_walking = 0;
107
108 static int _e_comp_wl_pid_hooks_delete = 0;
109 static int _e_comp_wl_pid_hooks_walking = 0;
110
111 static int _e_comp_wl_intercept_hooks_delete = 0;
112 static int _e_comp_wl_intercept_hooks_walking = 0;
113
114 static Eina_Inlist *_e_comp_wl_hooks[] =
115 {
116    [E_COMP_WL_HOOK_SHELL_SURFACE_READY] = NULL,
117    [E_COMP_WL_HOOK_SUBSURFACE_CREATE] = NULL,
118    [E_COMP_WL_HOOK_SUBSURFACE_COMMIT_TO_CACHE] = NULL,
119    [E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT] = NULL,
120    [E_COMP_WL_HOOK_BUFFER_CHANGE] = NULL,
121    [E_COMP_WL_HOOK_CLIENT_REUSE] = NULL,
122    [E_COMP_WL_HOOK_BUFFER_SIZE_CHANGE] = NULL,
123    [E_COMP_WL_HOOK_DEL] = NULL,
124    [E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE] = NULL,
125    [E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT] = NULL,
126    [E_COMP_WL_HOOK_CLIENT_BEFORE_SURFACE_COMMIT] = NULL,
127 };
128
129 static Eina_Inlist *_e_comp_wl_pid_hooks[] =
130 {
131    [E_COMP_WL_PID_HOOK_CONNECTED_CLIENT_CREATE] = NULL,
132 };
133
134 static Eina_Inlist *_e_comp_wl_intercept_hooks[] =
135 {
136    [E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_IN] = NULL,
137    [E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_OUT] = NULL,
138    [E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_MOVE] = NULL,
139    [E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_WHEEL] = NULL,
140    [E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_DOWN] = NULL,
141    [E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_UP] = NULL,
142 };
143
144 static Eina_List *hooks = NULL;
145
146 /* local functions */
147 static void
148 _e_comp_wl_hooks_clean(void)
149 {
150    Eina_Inlist *l;
151    E_Comp_Wl_Hook *ch;
152    unsigned int x;
153    for (x = 0; x < E_COMP_WL_HOOK_LAST; x++)
154      EINA_INLIST_FOREACH_SAFE(_e_comp_wl_hooks[x], l, ch)
155        {
156           if (!ch->delete_me) continue;
157           _e_comp_wl_hooks[x] = eina_inlist_remove(_e_comp_wl_hooks[x], EINA_INLIST_GET(ch));
158          free(ch);
159        }
160 }
161
162 static void
163 _e_comp_wl_hook_call(E_Comp_Wl_Hook_Point hookpoint, E_Client *ec)
164 {
165    E_Comp_Wl_Hook *ch;
166
167    e_object_ref(E_OBJECT(ec));
168    _e_comp_wl_hooks_walking++;
169    EINA_INLIST_FOREACH(_e_comp_wl_hooks[hookpoint], ch)
170      {
171         if (ch->delete_me) continue;
172         ch->func(ch->data, ec);
173         if ((hookpoint != E_COMP_WL_HOOK_DEL) &&
174             (e_object_is_del(E_OBJECT(ec))))
175           break;
176      }
177    _e_comp_wl_hooks_walking--;
178    if ((_e_comp_wl_hooks_walking == 0) && (_e_comp_wl_hooks_delete > 0))
179      _e_comp_wl_hooks_clean();
180    e_object_unref(E_OBJECT(ec));
181 }
182
183 static void
184 _e_comp_wl_pid_hooks_clean(void)
185 {
186    Eina_Inlist *l;
187    E_Comp_Wl_Pid_Hook *ch;
188    unsigned int x;
189    for (x = 0; x < E_COMP_WL_PID_HOOK_LAST; x++)
190      EINA_INLIST_FOREACH_SAFE(_e_comp_wl_pid_hooks[x], l, ch)
191        {
192           if (!ch->delete_me) continue;
193           _e_comp_wl_pid_hooks[x] = eina_inlist_remove(_e_comp_wl_pid_hooks[x], EINA_INLIST_GET(ch));
194          free(ch);
195        }
196 }
197
198 static void
199 _e_comp_wl_pid_hook_call(E_Comp_Wl_Pid_Hook_Point hookpoint, pid_t pid)
200 {
201    E_Comp_Wl_Pid_Hook *ch;
202
203    _e_comp_wl_pid_hooks_walking++;
204    EINA_INLIST_FOREACH(_e_comp_wl_pid_hooks[hookpoint], ch)
205      {
206         if (ch->delete_me) continue;
207         ch->func(ch->data, pid);
208      }
209    _e_comp_wl_pid_hooks_walking--;
210    if ((_e_comp_wl_pid_hooks_walking == 0) && (_e_comp_wl_pid_hooks_delete > 0))
211      _e_comp_wl_pid_hooks_clean();
212 }
213
214 static void
215 _e_comp_wl_intercept_hooks_clean(void)
216 {
217    Eina_Inlist *l;
218    E_Comp_Wl_Intercept_Hook *ch;
219    unsigned int x;
220    for (x = 0; x < E_COMP_WL_INTERCEPT_HOOK_LAST; x++)
221      EINA_INLIST_FOREACH_SAFE(_e_comp_wl_intercept_hooks[x], l, ch)
222        {
223           if (!ch->delete_me) continue;
224           _e_comp_wl_intercept_hooks[x] = eina_inlist_remove(_e_comp_wl_intercept_hooks[x], EINA_INLIST_GET(ch));
225          free(ch);
226        }
227 }
228
229 static Eina_Bool
230 _e_comp_wl_intercept_hook_call(E_Comp_Wl_Intercept_Hook_Point hookpoint, E_Client *ec)
231 {
232    E_Comp_Wl_Intercept_Hook *ch;
233    Eina_Bool res = EINA_TRUE, ret = EINA_TRUE;
234
235    e_object_ref(E_OBJECT(ec));
236    _e_comp_wl_intercept_hooks_walking++;
237    EINA_INLIST_FOREACH(_e_comp_wl_intercept_hooks[hookpoint], ch)
238      {
239         if (ch->delete_me) continue;
240         res = ch->func(ch->data, ec);
241         if (!res) ret = EINA_FALSE;
242         if (e_object_is_del(E_OBJECT(ec)))
243           break;
244      }
245    _e_comp_wl_intercept_hooks_walking--;
246    if ((_e_comp_wl_intercept_hooks_walking == 0) && (_e_comp_wl_intercept_hooks_delete > 0))
247      _e_comp_wl_intercept_hooks_clean();
248    e_object_unref(E_OBJECT(ec));
249
250    return ret;
251 }
252
253
254 static void
255 _e_comp_wl_configure_send(E_Client *ec, Eina_Bool edges, Eina_Bool send_size)
256 {
257    int w, h;
258
259    if (send_size)
260      {
261         if (e_comp_object_frame_exists(ec->frame))
262           w = ec->client.w, h = ec->client.h;
263         else
264           w = ec->w, h = ec->h;
265      }
266    else
267      {
268         // Width and Height are -1 means that we don't consider size value
269         w = h = -1;
270      }
271
272    e_client_shell_configure_send(ec, edges * e_comp_wl->resize.edges, w, h);
273 }
274
275 static void
276 _e_comp_wl_focus_check(void)
277 {
278    E_Client *ec;
279
280    if (stopping) return;
281    ec = e_client_focused_get();
282    if (!ec)
283      e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);
284 }
285
286 static Eina_Bool
287 _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
288 {
289    /* dispatch pending wayland events */
290    wl_event_loop_dispatch(e_comp_wl->wl.loop, 0);
291
292    return ECORE_CALLBACK_RENEW;
293 }
294
295 void
296 e_comp_wl_display_flush()
297 {
298    if (e_comp_wl && e_comp_wl->wl.disp)
299      {
300         if (e_config->key_input_ttrace_enable)
301           {
302              TRACE_INPUT_BEGIN(wl_display_flush_clients);
303              ELOGF("INPUT", "wl_display_flush_clients|B|", NULL);
304           }
305
306         g_mutex_lock(&connection_mutex);
307         wl_display_flush_clients(e_comp_wl->wl.disp);
308         g_mutex_unlock(&connection_mutex);
309
310         if (e_config->key_input_ttrace_enable)
311           {
312              TRACE_INPUT_END();
313              ELOGF("INPUT", "wl_display_flush_clients|E|", NULL);
314           }
315      }
316 }
317
318 EINTERN void
319 e_comp_wl_connection_lock()
320 {
321    e_input_boost_lock(&connection_mutex);
322 }
323
324 EINTERN void
325 e_comp_wl_connection_unlock()
326 {
327    e_input_boost_unlock(&connection_mutex);
328 }
329
330 void
331 e_comp_wl_focused_client_flush()
332 {
333    E_Client *focused_ec;
334    if (!(e_comp_wl && e_comp_wl->wl.disp)) return;
335
336    e_input_boost_lock(&connection_mutex);
337    focused_ec = e_client_focused_get();
338
339    if (focused_ec)
340      {
341         struct wl_client *wc;
342         struct wl_resource *surface = e_comp_wl_client_surface_get(focused_ec);
343         if (!surface)
344           {
345             e_input_boost_unlock(&connection_mutex);
346             return;
347           }
348
349         wc = wl_resource_get_client(surface);
350         wl_client_flush(wc);
351      }
352
353    e_input_boost_unlock(&connection_mutex);
354 }
355
356 static void
357 _e_comp_wl_cb_prepare(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
358 {
359    double gap_time;
360
361    if (e_comp_wl->idle_exiter_timestamp > 0.0)
362      {
363         gap_time = (ecore_time_get() * 1000) - e_comp_wl->idle_exiter_timestamp;
364         if (gap_time > E_COM_WL_PREPARE_GAP_LOG_TIME)
365           {
366              ELOGF("E_COMP", "prepare gap time: %lfms",
367                    NULL, gap_time);
368           }
369      }
370
371    e_comp_wl->idle_exiter_timestamp = 0.0;
372
373    wl_event_loop_dispatch_idle(e_comp_wl->wl.loop);
374
375    /* flush pending client events */
376    e_comp_wl_display_flush();
377
378    TRACE_DS_ASYNC_END((intptr_t)&e_comp_wl->idle_exiter_timestamp,
379                       IDLE_EXITER~CB_PREPARE);
380
381    // _e_comp_wl_cb_prepare() function is called before idle state in ecore_main_loop.
382    // idle state means that epoll() or select() is called in ecore_main_loop.
383    e_main_hook_call(E_MAIN_HOOK_LOOP_BEFORE_IDLE_ENTER);
384 }
385
386 static void
387 _e_comp_wl_cb_awake(void *data)
388 {
389    e_comp_wl->idle_exiter_timestamp = ecore_time_get() * 1000;
390
391    TRACE_DS_ASYNC_BEGIN((intptr_t)&e_comp_wl->idle_exiter_timestamp,
392                         IDLE_EXITER~CB_PREPARE);
393
394    // _e_comp_wl_cb_awake() function is called after idle state in ecore_main_loop.
395    // ecore_main_loop awake due to returning from epoll() or select()
396    e_main_hook_call(E_MAIN_HOOK_LOOP_AFTER_IDLE_EXIT);
397 }
398
399 E_API enum wl_output_transform
400 e_comp_wl_output_buffer_transform_get(E_Client *ec)
401 {
402    E_Comp_Wl_Buffer_Viewport *vp;
403    E_Comp_Wl_Buffer *buffer;
404    enum wl_output_transform transform, rotation;
405
406    if (!ec) return WL_OUTPUT_TRANSFORM_NORMAL;
407    if (e_object_is_del(E_OBJECT(ec))) return WL_OUTPUT_TRANSFORM_NORMAL;
408    if (!ec->comp_data) return WL_OUTPUT_TRANSFORM_NORMAL;
409
410    vp = &ec->comp_data->scaler.buffer_viewport;
411    if (e_comp_wl_subsurface_check(ec))
412      return vp->buffer.transform;
413
414    buffer = ec->comp_data->buffer_ref.buffer;
415
416    if (!buffer ||
417        (buffer->type != E_COMP_WL_BUFFER_TYPE_NATIVE && buffer->type != E_COMP_WL_BUFFER_TYPE_TBM))
418      return vp->buffer.transform;
419
420    rotation = buffer->transform;
421    if (rotation == 0)
422      return vp->buffer.transform;
423
424    /* ignore the flip value when calculating transform because the screen rotation
425     * functionality doesn't consider the flip output transform currently
426     */
427    transform = (4 + (vp->buffer.transform & 0x3) - rotation) & 0x3;
428
429    DBG("ec(%p) window rotation(%d) buffer_transform(%d) : transform(%d)",
430        ec, rotation, vp->buffer.transform, transform);
431
432    return transform;
433 }
434
435 EINTERN enum wl_output_transform
436 e_comp_wl_output_pending_buffer_transform_get(E_Client *ec)
437 {
438    E_Comp_Wl_Buffer_Viewport *vp;
439    E_Comp_Wl_Buffer *buffer;
440    enum wl_output_transform transform, rotation;
441
442    if (!ec) return WL_OUTPUT_TRANSFORM_NORMAL;
443    if (e_object_is_del(E_OBJECT(ec))) return WL_OUTPUT_TRANSFORM_NORMAL;
444    if (!ec->comp_data) return WL_OUTPUT_TRANSFORM_NORMAL;
445
446    vp = &ec->comp_data->pending.buffer_viewport;
447    if (e_comp_wl_subsurface_check(ec))
448      return vp->buffer.transform;
449
450    buffer = ec->comp_data->pending.buffer;
451
452    if (!buffer ||
453        (buffer->type != E_COMP_WL_BUFFER_TYPE_NATIVE && buffer->type != E_COMP_WL_BUFFER_TYPE_TBM))
454      return vp->buffer.transform;
455
456    rotation = buffer->transform;
457    if (rotation == 0)
458      return vp->buffer.transform;
459
460    /* ignore the flip value when calculating transform because the screen rotation
461     * functionality doesn't consider the flip output transform currently
462     */
463    transform = (4 + (vp->buffer.transform & 0x3) - rotation) & 0x3;
464
465    DBG("ec(%p) window rotation(%d) buffer_transform(%d) : transform(%d)",
466        ec, rotation, vp->buffer.transform, transform);
467
468    return transform;
469 }
470
471 E_API void
472 e_comp_wl_map_size_cal_from_buffer(E_Client *ec)
473 {
474    E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
475    E_Comp_Wl_Buffer *buffer;
476    int32_t width, height;
477
478    buffer = e_pixmap_resource_get(ec->pixmap);
479    if (!buffer)
480      {
481         ec->comp_data->width_from_buffer = 0;
482         ec->comp_data->height_from_buffer = 0;
483         return;
484      }
485
486    switch (e_comp_wl_output_buffer_transform_get(ec))
487      {
488       case WL_OUTPUT_TRANSFORM_90:
489       case WL_OUTPUT_TRANSFORM_270:
490       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
491       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
492         width = buffer->h / vp->buffer.scale;
493         height = buffer->w / vp->buffer.scale;
494         break;
495       default:
496         width = buffer->w / vp->buffer.scale;
497         height = buffer->h / vp->buffer.scale;
498         break;
499      }
500
501    ec->comp_data->width_from_buffer = width;
502    ec->comp_data->height_from_buffer = height;
503 }
504
505 E_API void
506 e_comp_wl_map_size_cal_from_viewport(E_Client *ec)
507 {
508    E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
509    int32_t width, height;
510
511    width = ec->comp_data->width_from_buffer;
512    height = ec->comp_data->height_from_buffer;
513
514    if (width == 0 && height == 0) return;
515
516    if (width != 0 && vp->surface.width != -1)
517      {
518         ec->comp_data->width_from_viewport = vp->surface.width;
519         ec->comp_data->height_from_viewport = vp->surface.height;
520         return;
521      }
522
523    if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1))
524      {
525         int32_t w = wl_fixed_to_int(wl_fixed_from_int(1) - 1 + vp->buffer.src_width);
526         int32_t h = wl_fixed_to_int(wl_fixed_from_int(1) - 1 + vp->buffer.src_height);
527         ec->comp_data->width_from_viewport = w ?: 1;
528         ec->comp_data->height_from_viewport = h ?: 1;
529         return;
530      }
531
532    ec->comp_data->width_from_viewport = width;
533    ec->comp_data->height_from_viewport = height;
534 }
535
536 E_API E_Client*
537 e_comp_wl_topmost_parent_get(E_Client *ec)
538 {
539    E_Client *parent;
540
541    if (!e_comp_wl_subsurface_check(ec))
542      return ec;
543
544    parent = e_comp_wl_subsurface_parent_get(ec);
545    while (parent)
546      {
547         if (!e_comp_wl_subsurface_check(parent))
548           return parent;
549
550         parent = e_comp_wl_subsurface_parent_get(parent);
551      }
552
553    return ec;
554 }
555
556 E_API void
557 e_comp_wl_map_apply(E_Client *ec)
558 {
559    E_Comp_Wl_Buffer_Viewport *vp;
560    E_Comp_Wl_Subsurf_Data *sdata;
561    E_Comp_Wl_Client_Data *cdata;
562    int x1, y1, x2, y2, x, y;
563    int dx = 0, dy = 0;
564    Eina_Bool zoom_animating = EINA_FALSE;
565
566    if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec))) return;
567
568    e_comp_object_map_update(ec->frame);
569
570    cdata = ec->comp_data;
571    vp = &cdata->scaler.buffer_viewport;
572    if ((vp->buffer.src_width == wl_fixed_from_int(-1)) &&
573        (!cdata->viewport_transform))
574      return;
575
576    if (e_comp_wl_subsurface_check(ec))
577      {
578         e_comp_wl_subsurface_global_coord_get(ec, &dx, &dy);
579
580         sdata = ec->comp_data->sub.data;
581         if (sdata->remote_surface.offscreen_parent)
582           {
583              E_Client *offscreen_parent = sdata->remote_surface.offscreen_parent;
584              Eina_Rectangle *rect;
585              Eina_List *l;
586
587              EINA_LIST_FOREACH(offscreen_parent->comp_data->remote_surface.regions, l, rect)
588                {
589                   /* TODO: If there are one more regions, it means that provider's offscreen
590                    * is displayed by one more remote_surfaces. Have to consider it later. At
591                    * this time, just consider only one remote_surface.
592                    */
593                   dx += rect->x;
594                   dy += rect->y;
595                   break;
596                }
597           }
598      }
599    else
600      {
601         dx = ec->x;
602         dy = ec->y;
603      }
604
605    evas_object_geometry_get(ec->frame, &x, &y, NULL, NULL);
606    if (x != dx || y != dy)
607      evas_object_move(ec->frame, dx, dy);
608
609    if (!cdata->viewport_transform)
610      {
611         cdata->viewport_transform = e_util_transform_new();
612         e_util_transform_role_set(cdata->viewport_transform, "viewport_transform");
613         e_client_transform_core_add(ec, cdata->viewport_transform);
614      }
615
616    e_util_transform_viewport_set(cdata->viewport_transform, dx, dy,
617                                  ec->comp_data->width_from_viewport,
618                                  ec->comp_data->height_from_viewport);
619
620    if (vp->buffer.src_width == wl_fixed_from_int(-1))
621      {
622         x1 = 0;
623         y1 = 0;
624         x2 = cdata->width_from_buffer;
625         y2 = cdata->height_from_buffer;
626      }
627    else
628      {
629         x1 = wl_fixed_to_int(vp->buffer.src_x);
630         y1 = wl_fixed_to_int(vp->buffer.src_y);
631         x2 = wl_fixed_to_int(vp->buffer.src_x + vp->buffer.src_width);
632         y2 = wl_fixed_to_int(vp->buffer.src_y + vp->buffer.src_height);
633      }
634
635    e_util_transform_texcoord_set(cdata->viewport_transform, 0, x1, y1);
636    e_util_transform_texcoord_set(cdata->viewport_transform, 1, x2, y1);
637    e_util_transform_texcoord_set(cdata->viewport_transform, 2, x2, y2);
638    e_util_transform_texcoord_set(cdata->viewport_transform, 3, x1, y2);
639
640    E_Desk *desk;
641    desk = e_comp_desk_find_by_ec(ec);
642    if (desk)
643      zoom_animating = e_desk_zoom_is_animating(desk);
644
645    ELOGF("TRANSFORM", "viewport map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d), zoom_animating: %d",
646          ec, ec->x, ec->y, ec->comp_data->width_from_viewport,
647          ec->comp_data->height_from_viewport, x1, y1, x2, y1, x2, y2, x1, y2, zoom_animating);
648
649    /* workaround:: when the desk zoom is doing their animation,
650       the transform core update can override animation's zoom boundary.
651       so, don't doing transform core update while desk zoom animation */
652    if (!zoom_animating)
653      e_client_transform_core_update(ec);
654
655 }
656
657 EINTERN void
658 e_comp_wl_map_inv_coord_get(E_Client *ec, int x, int y, int *mx, int *my)
659 {
660    E_Map *map;
661    E_Map *map2;
662    int map_c = 0, map_x = 0, map_y = 0;
663    double inv_x = 0.0, inv_y = 0.0;
664
665    EINA_SAFETY_ON_NULL_RETURN(ec);
666
667    map = e_client_map_get(ec);
668    map_c = e_map_count_get(map);
669
670    if (!map || map_c <= 0)
671      {
672         *mx = x;
673         *my = y;
674         e_map_free(map);
675         return;
676      }
677
678    map2 = e_map_new();
679
680    e_map_point_coord_set(map2, 0, ec->x, ec->y, 0);
681    e_map_point_coord_set(map2, 1, ec->x + ec->w, ec->y, 0);
682    e_map_point_coord_set(map2, 2, ec->x + ec->w, ec->y + ec->h, 0);
683    e_map_point_coord_set(map2, 3, ec->x, ec->y + ec->h, 0);
684
685    for (int i = 0; i < map_c; i++)
686      {
687         e_map_point_coord_get(map, i, &map_x, &map_y, NULL);
688         e_map_point_image_uv_set(map2, i, map_x, map_y);
689      }
690    e_map_coords_get(map2, (double)x, (double)y, &inv_x, &inv_y, 0);
691
692    *mx = lround(inv_x);
693    *my = lround(inv_y);
694
695    e_map_free(map);
696    e_map_free(map2);
697 }
698
699 static void
700 _e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
701 {
702    E_Client *ec, *tmp;
703    Eina_List *l;
704    E_Client *topmost;
705
706    if (!(ec = data)) return;
707    if (e_object_is_del(data)) return;
708
709    if (!ec->override) e_hints_window_visible_set(ec);
710
711    if ((!ec->override) && (!ec->re_manage) && (!ec->comp_data->reparented) &&
712        (!ec->comp_data->need_reparent))
713      {
714         ec->comp_data->need_reparent = EINA_TRUE;
715         ec->visible = EINA_TRUE;
716      }
717    if (!e_client_util_ignored_get(ec))
718      {
719         ec->take_focus = !starting;
720         EC_CHANGED(ec);
721      }
722
723    if (!ec->comp_data->need_reparent)
724      {
725         if ((ec->hidden) || (ec->iconic))
726           {
727              evas_object_hide(ec->frame);
728 //             e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
729           }
730         else
731           evas_object_show(ec->frame);
732      }
733
734    EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp)
735      evas_object_show(tmp->frame);
736
737    topmost = e_comp_wl_topmost_parent_get(ec);
738    if (topmost == ec && (ec->comp_data->sub.list || ec->comp_data->sub.below_list))
739      e_comp_wl_subsurface_show(ec);
740
741    if (ec->comp_data->sub.below_obj)
742      evas_object_show(ec->comp_data->sub.below_obj);
743 }
744
745 static void
746 _e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
747 {
748    E_Client *ec, *tmp;
749    Eina_List *l;
750    E_Client *topmost;
751
752    if (!(ec = data)) return;
753    if (e_object_is_del(E_OBJECT(ec))) return;
754
755    /* Uncommonly some clients's final buffer can be skipped if the client
756     * requests unmap of its surface right after wl_surface@commit.
757     * So if this client evas object is hidden state and client is already
758     * unmmapped, we can consider to clear pixmap image here mandatorily.
759     */
760    if (!ec->comp_data->mapped)
761      e_pixmap_image_clear(ec->pixmap, 1);
762
763    EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp)
764      evas_object_hide(tmp->frame);
765
766    topmost = e_comp_wl_topmost_parent_get(ec);
767    if (topmost == ec && (ec->comp_data->sub.list || ec->comp_data->sub.below_list))
768      e_comp_wl_subsurface_hide(ec);
769
770    if (ec->comp_data->sub.below_obj)
771      evas_object_hide(ec->comp_data->sub.below_obj);
772
773    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_unmap_signal, ec);
774 }
775
776 static void
777 _e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
778 {
779    E_Client *ec;
780    E_Client *subc;
781    Eina_List *l;
782    int x = 0 , y = 0;
783
784    if (!(ec = data)) return;
785    if (e_object_is_del(E_OBJECT(ec))) return;
786
787    EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
788      {
789         if (!e_comp_wl_subsurface_check(subc)) continue;
790         e_comp_wl_subsurface_global_coord_get(subc, &x, &y);
791         evas_object_move(subc->frame, x, y);
792
793         E_Comp_Wl_Client_Data *cdata = subc->comp_data;
794         if (cdata->viewport_transform)
795           e_comp_wl_map_apply(subc);
796      }
797
798    EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
799      {
800         if (!e_comp_wl_subsurface_check(subc)) continue;
801         e_comp_wl_subsurface_global_coord_get(subc, &x, &y);
802         evas_object_move(subc->frame, x, y);
803
804         E_Comp_Wl_Client_Data *cdata = subc->comp_data;
805         if (cdata->viewport_transform)
806           e_comp_wl_map_apply(subc);
807      }
808
809    if (ec->comp_data->sub.below_obj)
810      {
811         evas_object_move(ec->comp_data->sub.below_obj, ec->x, ec->y);
812         e_comp_wl_subsurface_bg_rectangle_map_apply(ec);
813      }
814 }
815
816 static void
817 _e_comp_wl_send_touch_cancel(E_Client *ec)
818 {
819    Eina_List *l;
820    struct wl_resource *res;
821    struct wl_client *wc;
822    E_Comp_Config *comp_conf = NULL;
823
824    if (!ec) return;
825    if (e_object_is_del(E_OBJECT(ec))) return;
826    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
827
828    if (!surface) return;
829    if ((ec->ignored) && (!ec->remote_surface.provider)) return;
830
831    wc = wl_resource_get_client(surface);
832
833    comp_conf = e_comp_config_get();
834
835    EINA_LIST_FOREACH(e_comp->wl_comp_data->touch.resources, l, res)
836      {
837         if (wl_resource_get_client(res) != wc) continue;
838         if (!e_comp_wl_input_touch_check(res)) continue;
839
840         if (comp_conf && comp_conf->input_log_enable)
841            ELOGF("Touch", "Cancel name:%20s", ec, e_client_util_name_get(ec));
842
843         wl_touch_send_cancel(res);
844      }
845 }
846
847 static void
848 _e_comp_wl_touch_cancel(void)
849 {
850    E_Client *ec;
851
852    ec = e_comp_wl->ptr.ec ? e_comp_wl->ptr.ec : e_comp_wl->touch.faked_ec;
853    if (!ec) return;
854    if (!e_comp_wl->touch.pressed) return;
855
856    _e_comp_wl_send_touch_cancel(ec);
857 }
858
859 static E_Devicemgr_Input_Device *
860 _e_comp_wl_device_last_device_get(Ecore_Device_Class dev_class)
861 {
862    E_Devicemgr_Input_Device *last_kbd = NULL;
863    switch (dev_class)
864      {
865       case ECORE_DEVICE_CLASS_MOUSE:
866          return e_devicemgr->last_device_ptr;
867       case ECORE_DEVICE_CLASS_KEYBOARD:
868          last_kbd = atomic_load(&e_devicemgr->last_device_kbd);
869          return last_kbd;
870       case ECORE_DEVICE_CLASS_TOUCH:
871          return e_devicemgr->last_device_touch;
872       default:
873          return NULL;;
874      }
875    return NULL;
876 }
877
878 static void
879 _e_comp_wl_device_last_device_set(Ecore_Device_Class dev_class, E_Devicemgr_Input_Device *device)
880 {
881    switch (dev_class)
882      {
883       case ECORE_DEVICE_CLASS_MOUSE:
884          e_devicemgr->last_device_ptr = device;
885          break;
886       case ECORE_DEVICE_CLASS_KEYBOARD:
887          atomic_store(&e_devicemgr->last_device_kbd, device);
888          break;
889       case ECORE_DEVICE_CLASS_TOUCH:
890          e_devicemgr->last_device_touch = device;
891          break;
892       default:
893          break;
894      }
895 }
896
897 static E_Devicemgr_Input_Device *
898 _e_comp_wl_device_client_last_device_get(E_Client *ec, Ecore_Device_Class dev_class)
899 {
900    E_Devicemgr_Input_Device *last_kbd = NULL;
901
902    switch (dev_class)
903      {
904       case ECORE_DEVICE_CLASS_MOUSE:
905          return ec->comp_data->last_device_ptr;
906       case ECORE_DEVICE_CLASS_KEYBOARD:
907          last_kbd = atomic_load(&ec->comp_data->last_device_kbd);
908          return last_kbd;
909       case ECORE_DEVICE_CLASS_TOUCH:
910          return ec->comp_data->last_device_touch;
911       default:
912          return NULL;;
913      }
914    return NULL;
915 }
916
917 static void
918 _e_comp_wl_device_client_last_device_set(E_Client *ec, Ecore_Device_Class dev_class, E_Devicemgr_Input_Device *device)
919 {
920    switch (dev_class)
921      {
922       case ECORE_DEVICE_CLASS_MOUSE:
923          ec->comp_data->last_device_ptr = device;
924          break;
925       case ECORE_DEVICE_CLASS_KEYBOARD:
926          atomic_store(&ec->comp_data->last_device_kbd, device);
927          break;
928       case ECORE_DEVICE_CLASS_TOUCH:
929          ec->comp_data->last_device_touch = device;
930          break;
931       default:
932          break;
933      }
934 }
935
936 static void
937 _e_comp_wl_device_send_event_device(E_Client *ec, Evas_Device *dev, uint32_t timestamp)
938 {
939    E_Devicemgr_Input_Device *last_device, *ec_last_device, *input_dev;
940    struct wl_resource *dev_res;
941    const char *dev_name;
942    Ecore_Device_Class dev_class;
943    struct wl_client *wc;
944    uint32_t serial;
945    Eina_List *l, *ll;
946
947    EINA_SAFETY_ON_NULL_RETURN(dev);
948
949    if (!ec) return;
950    if (ec->cur_mouse_action || e_comp_wl->drag)
951      return;
952    if (e_object_is_del(E_OBJECT(ec))) return;
953    if ((ec->ignored) && (!ec->remote_surface.provider)) return;
954    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
955    if (!surface) return;
956
957    dev_class = (Ecore_Device_Class)evas_device_class_get(dev);
958    dev_name = evas_device_description_get(dev);
959    last_device = _e_comp_wl_device_last_device_get(dev_class);
960    ec_last_device = _e_comp_wl_device_client_last_device_get(ec, dev_class);
961
962    serial = wl_display_next_serial(e_comp_wl->wl.disp);
963    wc = wl_resource_get_client(surface);
964    g_rec_mutex_lock(&e_devicemgr->device_list_mutex);
965    EINA_LIST_FOREACH(e_devicemgr->device_list, l, input_dev)
966      {
967         if (!eina_streq(input_dev->identifier, dev_name) || (input_dev->clas != dev_class)) continue;
968         if ((!last_device) || (last_device != input_dev) || (!ec_last_device) || (ec_last_device != input_dev))
969           {
970              _e_comp_wl_device_last_device_set(dev_class, input_dev);
971              _e_comp_wl_device_client_last_device_set(ec, dev_class, input_dev);
972
973              EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
974                {
975                   if (wl_resource_get_client(dev_res) != wc) continue;
976                   tizen_input_device_send_event_device(dev_res, serial, input_dev->identifier, timestamp);
977                }
978           }
979      }
980    g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
981 }
982
983 static void
984 _e_comp_wl_device_send_last_event_device(E_Client *ec, Ecore_Device_Class dev_class, uint32_t timestamp)
985 {
986    E_Devicemgr_Input_Device *last_device;
987    struct wl_resource *dev_res;
988    struct wl_client *wc;
989    uint32_t serial;
990    Eina_List *l;
991
992    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
993    if (!surface) return;
994
995    last_device = _e_comp_wl_device_last_device_get(dev_class);
996    if (!last_device) return;
997
998    _e_comp_wl_device_client_last_device_set(ec, dev_class, last_device);
999
1000    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1001    wc = wl_resource_get_client(surface);
1002    EINA_LIST_FOREACH(last_device->resources, l, dev_res)
1003      {
1004         if (wl_resource_get_client(dev_res) != wc) continue;
1005         tizen_input_device_send_event_device(dev_res, serial, last_device->identifier, timestamp);
1006      }
1007 }
1008
1009 static void
1010 _e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Device *dev, uint32_t serial)
1011 {
1012    E_Devicemgr_Input_Device *input_dev;
1013    struct wl_resource *dev_res;
1014    const char *dev_name;
1015    Eina_List *l, *ll;
1016
1017    EINA_SAFETY_ON_NULL_RETURN(dev);
1018
1019    dev_name = ecore_device_identifier_get(dev);
1020
1021    g_rec_mutex_lock(&e_devicemgr->device_list_mutex);
1022    EINA_LIST_FOREACH(e_devicemgr->device_list, l, input_dev)
1023      {
1024         if (!eina_streq(input_dev->identifier, dev_name) ||
1025             (input_dev->clas != ecore_device_class_get(dev))) continue;
1026         _e_comp_wl_device_last_device_set(ecore_device_class_get(dev), input_dev);
1027
1028         EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
1029           {
1030              if (wl_resource_get_client(dev_res) != wc) continue;
1031              tizen_input_device_send_event_device(dev_res, serial, input_dev->identifier, timestamp);
1032           }
1033      }
1034    g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
1035 }
1036
1037 static void
1038 _e_comp_wl_send_event_e_device(struct wl_client *wc, uint32_t timestamp, E_Device *dev, uint32_t serial)
1039 {
1040    E_Devicemgr_Input_Device *input_dev;
1041    struct wl_resource *dev_res;
1042    const char *dev_name;
1043    Eina_List *l, *ll;
1044
1045    EINA_SAFETY_ON_NULL_RETURN(dev);
1046
1047    dev_name = e_device_identifier_get(dev);
1048
1049    g_rec_mutex_lock(&e_devicemgr->device_list_mutex);
1050    EINA_LIST_FOREACH(e_devicemgr->device_list, l, input_dev)
1051      {
1052         if (!eina_streq(input_dev->identifier, dev_name) ||
1053             (input_dev->clas != e_device_class_get(dev))) continue;
1054         _e_comp_wl_device_last_device_set(e_device_class_get(dev), input_dev);
1055
1056         EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
1057           {
1058              if (wl_resource_get_client(dev_res) != wc) continue;
1059              tizen_input_device_send_event_device(dev_res, serial, input_dev->identifier, timestamp);
1060           }
1061      }
1062    g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
1063 }
1064
1065 static void
1066 _e_comp_wl_cursor_reload(E_Client *ec)
1067 {
1068    struct wl_resource *res;
1069    struct wl_client *wc;
1070    Eina_List *l;
1071    E_Map *map;
1072    uint32_t serial;
1073    int cx, cy, px, py;
1074
1075    if (e_comp->pointer && e_comp->pointer->o_ptr &&
1076        !evas_object_visible_get(e_comp->pointer->o_ptr))
1077      e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
1078
1079    if (!ec) return;
1080    if (e_object_is_del(E_OBJECT(ec))) return;
1081    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1082    if (!surface) return;
1083    if (ec->pointer_enter_sent) return;
1084
1085    px = wl_fixed_to_int(e_comp_wl->ptr.x);
1086    py = wl_fixed_to_int(e_comp_wl->ptr.y);
1087
1088    if (e_client_transform_core_enable_get(ec))
1089      {
1090         double dx = 0.0, dy = 0.0;
1091         map = e_client_map_get(ec);
1092         e_map_coords_get(map, (double)px, (double)py, &dx, &dy, 0);
1093         px = (int)dx;
1094         py = (int)dy;
1095         e_map_free(map);
1096      }
1097
1098    cx = px - ec->client.x;
1099    cy = py - ec->client.y;
1100
1101    wc = wl_resource_get_client(surface);
1102    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1103    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
1104      {
1105         if (!e_comp_wl_input_pointer_check(res)) continue;
1106         if (wl_resource_get_client(res) != wc) continue;
1107         wl_pointer_send_enter(res, serial, surface,
1108                               wl_fixed_from_int(cx), wl_fixed_from_int(cy));
1109         ec->pointer_enter_sent = EINA_TRUE;
1110      }
1111    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mousein_signal, ec);
1112 }
1113
1114 static Eina_Bool
1115 _e_comp_wl_cursor_timer(void *data)
1116 {
1117    E_Client *ec = data;
1118
1119    ELOGF("Mouse", "Cursor hide timer expired after %d sec.", ec, e_config->cursor_timer_interval);
1120    if (e_comp_wl->relative_ptr.activated) return ECORE_CALLBACK_CANCEL;
1121
1122    e_comp_wl_cursor_hide(ec);
1123
1124    return ECORE_CALLBACK_CANCEL;
1125 }
1126
1127 static void
1128 _e_comp_wl_device_send_axis(const char *dev_name, Evas_Device_Class dev_class, E_Client *ec, enum tizen_input_device_axis_type axis_type, double value)
1129 {
1130    E_Devicemgr_Input_Device *input_dev;
1131    struct wl_resource *dev_res;
1132    struct wl_client *wc;
1133    Eina_List *l, *ll;
1134    wl_fixed_t f_value;
1135
1136    if (!ec) return;
1137    if (ec->cur_mouse_action) return;
1138    if (e_object_is_del(E_OBJECT(ec))) return;
1139    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1140    if (!surface) return;
1141
1142    f_value = wl_fixed_from_double(value);
1143    wc = wl_resource_get_client(surface);
1144
1145    g_rec_mutex_lock(&e_devicemgr->device_list_mutex);
1146    EINA_LIST_FOREACH(e_devicemgr->device_list, l, input_dev)
1147      {
1148         if ((strcmp(input_dev->identifier, dev_name)) || (input_dev->clas != (Ecore_Device_Class)dev_class)) continue;
1149         EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
1150           {
1151              if (wl_resource_get_client(dev_res) != wc) continue;
1152              tizen_input_device_send_axis(dev_res, axis_type, f_value);
1153           }
1154      }
1155    g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
1156 }
1157
1158 static void
1159 _e_comp_wl_device_renew_axis(const char *dev_name, Evas_Device_Class dev_class, E_Client *ec, unsigned int idx, double radius_x, double radius_y, double pressure, double angle)
1160 {
1161    if (idx >= e_input_touch_max_count_get()) return;
1162
1163    _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_X, radius_x);
1164    e_devicemgr->multi[idx].radius_x = radius_x;
1165    _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_Y, radius_y);
1166    e_devicemgr->multi[idx].radius_y = radius_y;
1167    _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_PRESSURE, pressure);
1168    e_devicemgr->multi[idx].pressure = pressure;
1169    _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_ANGLE, angle);
1170    e_devicemgr->multi[idx].angle = angle;
1171 }
1172
1173 static void
1174 _e_comp_wl_device_handle_axes(const char *dev_name, Evas_Device_Class dev_class, E_Client *ec, unsigned int idx, double radius_x, double radius_y, double pressure, double angle)
1175 {
1176    if (idx >= e_input_touch_max_count_get()) return;
1177
1178    if (e_devicemgr->multi[idx].radius_x != radius_x)
1179      {
1180         _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_X, radius_x);
1181         e_devicemgr->multi[idx].radius_x = radius_x;
1182      }
1183    if (e_devicemgr->multi[idx].radius_y != radius_y)
1184      {
1185         _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_Y, radius_y);
1186         e_devicemgr->multi[idx].radius_y = radius_y;
1187      }
1188    if (e_devicemgr->multi[idx].pressure != pressure)
1189      {
1190         _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_PRESSURE, pressure);
1191         e_devicemgr->multi[idx].pressure = pressure;
1192      }
1193    if (e_devicemgr->multi[idx].angle != angle)
1194      {
1195         _e_comp_wl_device_send_axis(dev_name, dev_class, ec, TIZEN_INPUT_DEVICE_AXIS_TYPE_ANGLE, angle);
1196         e_devicemgr->multi[idx].angle = angle;
1197      }
1198 }
1199
1200 static Eina_Bool
1201 _e_comp_wl_cursor_timer_control(Evas_Callback_Type type, E_Client *ec)
1202 {
1203    Eina_Bool ret = EINA_TRUE;
1204    switch (type)
1205      {
1206         case EVAS_CALLBACK_MOUSE_IN:
1207           ret = _e_comp_wl_intercept_hook_call(E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_IN, ec);
1208           if (!ret) break;
1209
1210           if (e_comp_wl->ptr.hide_tmr)
1211             {
1212                ecore_timer_del(e_comp_wl->ptr.hide_tmr);
1213                cursor_timer_ec = ec;
1214                e_comp_wl->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
1215             }
1216           else
1217             {
1218                if (e_pointer_is_hidden(e_comp->pointer))
1219                  ret = EINA_FALSE;
1220             }
1221           break;
1222
1223         case EVAS_CALLBACK_MOUSE_OUT:
1224           ret = _e_comp_wl_intercept_hook_call(E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_OUT, ec);
1225           if (!ret) break;
1226
1227           if (!e_comp_wl->ptr.hide_tmr && e_pointer_is_hidden(e_comp->pointer))
1228             ret = EINA_FALSE;
1229           break;
1230
1231         case EVAS_CALLBACK_MOUSE_MOVE:
1232           ret = _e_comp_wl_intercept_hook_call(E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_MOVE, ec);
1233           if (!ret) break;
1234
1235           if (e_pointer_is_hidden(e_comp->pointer) || !ec->pointer_enter_sent)
1236             _e_comp_wl_cursor_reload(ec);
1237           break;
1238
1239         case EVAS_CALLBACK_MOUSE_WHEEL:
1240           ret = _e_comp_wl_intercept_hook_call(E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_WHEEL, ec);
1241           if (!ret) break;
1242
1243           if (e_pointer_is_hidden(e_comp->pointer) || !ec->pointer_enter_sent)
1244             _e_comp_wl_cursor_reload(ec);
1245           break;
1246
1247         case EVAS_CALLBACK_MOUSE_DOWN:
1248           ret = _e_comp_wl_intercept_hook_call(E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_DOWN, ec);
1249           if (!ret) break;
1250
1251           if (e_comp_wl->ptr.hide_tmr)
1252             {
1253                ecore_timer_del(e_comp_wl->ptr.hide_tmr);
1254                e_comp_wl->ptr.hide_tmr = NULL;
1255             }
1256           cursor_timer_ec = NULL;
1257
1258           if (e_pointer_is_hidden(e_comp->pointer) || !ec->pointer_enter_sent)
1259             _e_comp_wl_cursor_reload(ec);
1260           break;
1261
1262         case EVAS_CALLBACK_MOUSE_UP:
1263           ret = _e_comp_wl_intercept_hook_call(E_COMP_WL_INTERCEPT_HOOK_CURSOR_TIMER_MOUSE_UP, ec);
1264           break;
1265
1266         default:
1267           break;
1268      }
1269
1270    return ret;
1271 }
1272
1273 static Eina_Bool
1274 _e_comp_wl_check_cursor_timer_needed(E_Client *ec)
1275 {
1276    if (ec->has_cursor_unset)
1277      return EINA_FALSE;
1278
1279    if (!e_config->show_cursor)
1280      return EINA_FALSE;
1281
1282    if (!e_config->use_cursor_timer)
1283      return EINA_FALSE;
1284
1285    return EINA_TRUE;
1286 }
1287
1288 static void
1289 _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
1290 {
1291    E_Client *ec;
1292    Evas_Event_Mouse_In *ev;
1293    struct wl_resource *res;
1294    struct wl_client *wc;
1295    Eina_List *l;
1296    uint32_t serial;
1297    E_Comp_Config *comp_conf;
1298    E_Client *prev_ptr_ec;
1299
1300    ev = event;
1301
1302    e_comp_wl->ptr.x = wl_fixed_from_int(ev->output.x);
1303    e_comp_wl->ptr.y = wl_fixed_from_int(ev->output.y);
1304
1305    if (!(ec = data)) return;
1306    if (e_object_is_del(E_OBJECT(ec))) return;
1307    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1308    if (!surface) return;
1309
1310    prev_ptr_ec = e_comp_wl->ptr.ec;
1311    if (prev_ptr_ec)
1312      {
1313         ELOGF("Mouse", "In (prev_ptr_ec: %p pointer_enter_sent: %d)", ec, prev_ptr_ec, prev_ptr_ec->pointer_enter_sent);
1314         prev_ptr_ec->pointer_enter_sent = EINA_FALSE;
1315      }
1316
1317    e_comp_wl->ptr.ec = ec;
1318
1319    comp_conf = e_comp_config_get();
1320    if (comp_conf && comp_conf->input_log_enable)
1321      ELOGF("Mouse", "In  (obj: %p, time: %d, canvas(%d, %d) output(%d, %d), name:%20s)",
1322            ec, obj, ev->timestamp, ev->canvas.x, ev->canvas.y, ev->output.x, ev->output.y,
1323            e_client_util_name_get(ec));
1324
1325    if (_e_comp_wl_check_cursor_timer_needed(ec))
1326      {
1327         if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_IN, ec))
1328           return;
1329      }
1330
1331    if (!eina_list_count(e_comp_wl->ptr.resources)) return;
1332    wc = wl_resource_get_client(surface);
1333    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1334    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
1335      {
1336         if (!e_comp_wl_input_pointer_check(res)) continue;
1337         if (wl_resource_get_client(res) != wc) continue;
1338
1339         _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, ev->timestamp);
1340
1341         wl_pointer_send_enter(res, serial, surface,
1342                               wl_fixed_from_int(ev->canvas.x - ec->client.x),
1343                               wl_fixed_from_int(ev->canvas.y - ec->client.y));
1344         ec->pointer_enter_sent = EINA_TRUE;
1345      }
1346
1347    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mousein_signal, ec);
1348 }
1349
1350 static void
1351 _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
1352 {
1353    E_Client *ec;
1354    Evas_Event_Mouse_Out *ev;
1355    struct wl_resource *res;
1356    struct wl_client *wc;
1357    Eina_List *l;
1358    uint32_t serial;
1359    Eina_Bool inside_check;
1360    E_Comp_Config *comp_conf;
1361
1362    ev = event;
1363
1364    if (!(ec = data)) return;
1365    inside_check = E_INSIDE(ev->canvas.x, ev->canvas.y,
1366                           ec->client.x, ec->client.y, ec->client.w, ec->client.h);
1367    if (ec->cur_mouse_action && inside_check) return;
1368    if (e_object_is_del(E_OBJECT(e_comp))) return;
1369    if (e_comp_wl->ptr.ec == ec)
1370      e_comp_wl->ptr.ec = NULL;
1371    if (e_object_is_del(E_OBJECT(ec))) return;
1372
1373    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1374    if (!surface) return;
1375
1376    comp_conf = e_comp_config_get();
1377    if (comp_conf && comp_conf->input_log_enable)
1378      ELOGF("Mouse", "Out (obj: %p, time: %d, canvas(%d, %d) output(%d, %d), name:%20s)",
1379            ec, obj, ev->timestamp, ev->canvas.x, ev->canvas.y, ev->output.x, ev->output.y,
1380            e_client_util_name_get(ec));
1381
1382    if (_e_comp_wl_check_cursor_timer_needed(ec))
1383      {
1384         if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_OUT, ec))
1385           return;
1386      }
1387
1388    if (!eina_list_count(e_comp_wl->ptr.resources)) return;
1389
1390    wc = wl_resource_get_client(surface);
1391    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1392    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
1393      {
1394         if (!e_comp_wl_input_pointer_check(res)) continue;
1395         if (wl_resource_get_client(res) != wc) continue;
1396         if (ec->pointer_enter_sent == EINA_FALSE) continue;
1397
1398         _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, ev->timestamp);
1399
1400         wl_pointer_send_leave(res, serial, surface);
1401         ec->pointer_enter_sent = EINA_FALSE;
1402      }
1403    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mouseout_signal, ec);
1404 }
1405
1406 static void
1407 _e_comp_wl_send_touch(E_Client *ec, int idx, int canvas_x, int canvas_y, uint32_t timestamp, Eina_Bool pressed)
1408 {
1409    Eina_List *l;
1410    struct wl_client *wc;
1411    struct wl_resource *res;
1412    wl_fixed_t x, y;
1413    uint32_t serial;
1414    E_Comp_Config *comp_conf = NULL;
1415
1416    if (!ec) return;
1417    if (e_object_is_del(E_OBJECT(ec))) return;
1418    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1419    if (!surface) return;
1420
1421    wc = wl_resource_get_client(surface);
1422    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1423
1424    if (pressed)
1425      {
1426         x = wl_fixed_from_int(canvas_x - ec->client.x);
1427         y = wl_fixed_from_int(canvas_y - ec->client.y);
1428      }
1429
1430    comp_conf = e_comp_config_get();
1431
1432    EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
1433      {
1434         if (wl_resource_get_client(res) != wc) continue;
1435         if (!e_comp_wl_input_touch_check(res)) continue;
1436         TRACE_INPUT_BEGIN(_e_comp_wl_send_touch);
1437         if (pressed)
1438           {
1439              if (comp_conf && comp_conf->input_log_enable)
1440                ELOGF("Touch", "Down (id: %d, time: %d, x:%d, y:%d, name:%20s)", ec, idx, timestamp, canvas_x - ec->client.x, canvas_y - ec->client.y, e_client_util_name_get(ec));
1441
1442              wl_touch_send_down(res, serial, timestamp, surface, idx, x, y); //id 0 for the 1st finger
1443           }
1444         else
1445           {
1446              if (comp_conf && comp_conf->input_log_enable)
1447                ELOGF("Touch", "Up (id: %d, time: %d, x:%d, y:%d, name:%20s)\n", ec, idx, timestamp, canvas_x - ec->client.x, canvas_y - ec->client.y, e_client_util_name_get(ec));
1448
1449              wl_touch_send_up(res, serial, timestamp, idx);
1450           }
1451         TRACE_INPUT_END();
1452      }
1453 }
1454
1455 static void
1456 _e_comp_wl_send_touch_move(E_Client *ec, int idx, int canvas_x, int canvas_y, uint32_t timestamp)
1457 {
1458    Eina_List *l;
1459    struct wl_client *wc;
1460    struct wl_resource *res;
1461    wl_fixed_t x, y;
1462
1463    if (!ec) return;
1464    if (ec->cur_mouse_action) return;
1465    if (e_object_is_del(E_OBJECT(ec))) return;
1466    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1467    if (!surface) return;
1468
1469    wc = wl_resource_get_client(surface);
1470
1471    x = wl_fixed_from_int(canvas_x - ec->client.x);
1472    y = wl_fixed_from_int(canvas_y - ec->client.y);
1473
1474    EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
1475      {
1476         if (wl_resource_get_client(res) != wc) continue;
1477         if (!e_comp_wl_input_touch_check(res)) continue;
1478         wl_touch_send_motion(res, timestamp, idx, x, y);
1479      }
1480 }
1481
1482 static void
1483 _e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
1484 {
1485    struct wl_resource *res;
1486    struct wl_client *wc;
1487    Eina_List *l;
1488
1489    if (!ec) return;
1490    if (ec->cur_mouse_action) return;
1491    if (e_object_is_del(E_OBJECT(ec))) return;
1492    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1493    if (!surface) return;
1494
1495    wc = wl_resource_get_client(surface);
1496    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
1497      {
1498         if (!e_comp_wl_input_pointer_check(res)) continue;
1499         if (wl_resource_get_client(res) != wc) continue;
1500         wl_pointer_send_motion(res, timestamp,
1501                                wl_fixed_from_int(x - ec->client.x),
1502                                wl_fixed_from_int(y - ec->client.y));
1503      }
1504 }
1505
1506 static void
1507 _e_comp_wl_cursor_move_timer_control(E_Client *ec)
1508 {
1509    if (e_comp_wl->ptr.hide_tmr)
1510      {
1511         if (cursor_timer_ec == ec)
1512           {
1513              ecore_timer_interval_set(e_comp_wl->ptr.hide_tmr, e_config->cursor_timer_interval);
1514              ecore_timer_reset(e_comp_wl->ptr.hide_tmr);
1515           }
1516         else
1517           {
1518              ecore_timer_del(e_comp_wl->ptr.hide_tmr);
1519              cursor_timer_ec = ec;
1520              e_comp_wl->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
1521           }
1522      }
1523    else
1524      {
1525         cursor_timer_ec = ec;
1526         e_comp_wl->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
1527      }
1528 }
1529
1530 static void
1531 _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
1532 {
1533    E_Client *ec;
1534    Evas_Event_Mouse_Move *ev;
1535    Evas_Device *dev = NULL;
1536    const char *dev_name;
1537    E_Comp_Config *comp_conf;
1538
1539    ev = event;
1540
1541    e_comp->wl_comp_data->ptr.x = wl_fixed_from_int(ev->cur.canvas.x);
1542    e_comp->wl_comp_data->ptr.y = wl_fixed_from_int(ev->cur.canvas.y);
1543
1544    if (!(ec = data)) return;
1545    if (e_object_is_del(E_OBJECT(ec))) return;
1546    if ((ec->ignored) && (!ec->remote_surface.provider)) return;
1547    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1548    if (!surface) return;
1549
1550    if ((!need_send_motion) && (!need_send_released) && (e_client_visibility_get(ec) == E_VISIBILITY_FULLY_OBSCURED)) return;
1551
1552    dev = ev->dev;
1553    dev_name = evas_device_description_get(dev);
1554
1555    comp_conf = e_comp_config_get();
1556    if (comp_conf && comp_conf->input_log_enable)
1557      ELOGF("Mouse", "Move (obj: %p, time: %d, canvas(%d, %d), output(%d, %d), name:%20s) (dev:%s)",
1558            ec, obj, ev->timestamp, ev->cur.canvas.x, ev->cur.canvas.y, ev->cur.output.x, ev->cur.output.y,
1559            e_client_util_name_get(ec), dev_name);
1560
1561    if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
1562      {
1563         if (!e_comp_wl->drag_client)
1564           {
1565              e_comp_wl->touch.faked_ec = ec;
1566              if (e_comp_wl->touch.pressed & (1 << 0))
1567                {
1568                   _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1569                   if (dev_name)
1570                     _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
1571                                                   ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
1572                   _e_comp_wl_send_touch_move(ec, 0, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
1573                }
1574           }
1575
1576         e_pointer_touch_move(e_comp->pointer, ev->cur.output.x, ev->cur.output.y);
1577      }
1578    else
1579      {
1580         if (!e_comp_wl->drag_client)
1581           {
1582              if (_e_comp_wl_check_cursor_timer_needed(ec))
1583                {
1584                   if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_MOVE, ec))
1585                     return;
1586                }
1587
1588              _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1589              _e_comp_wl_send_mouse_move(ec, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
1590
1591              if (!need_send_released) // set cursor's hide_tmr only when mouse button is not pressed
1592                {
1593                   if (_e_comp_wl_check_cursor_timer_needed(ec))
1594                     _e_comp_wl_cursor_move_timer_control(ec);
1595                }
1596           }
1597
1598         e_pointer_mouse_move(e_comp->pointer, ev->cur.output.x, ev->cur.output.y);
1599      }
1600 }
1601
1602 static void
1603 _e_comp_wl_evas_handle_mouse_button_to_touch(E_Client *ec, uint32_t timestamp, int canvas_x, int canvas_y, Eina_Bool flag)
1604 {
1605    if (ec->cur_mouse_action || e_comp_wl->drag) return;
1606    if (e_object_is_del(E_OBJECT(ec))) return;
1607    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1608    if (!surface) return;
1609    if ((ec->ignored) && (!ec->remote_surface.provider)) return;
1610
1611    e_comp_wl->ptr.button = BTN_LEFT;
1612
1613    _e_comp_wl_send_touch(ec, 0, canvas_x, canvas_y, timestamp, flag);
1614 }
1615
1616 static void
1617 _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
1618 {
1619    E_Client *ec = data;
1620    Evas_Event_Mouse_Down *ev = event;
1621    Evas_Device *dev = NULL;
1622    const Evas_Device *seat_dev;
1623    const char *dev_name, *seat_name;
1624    E_Comp_Config *comp_conf = NULL;
1625
1626    if (!ec) return;
1627    if (e_object_is_del(E_OBJECT(ec))) return;
1628
1629    dev = ev->dev;
1630    dev_name = evas_device_description_get(dev);
1631
1632    seat_dev = evas_device_parent_get(dev);
1633    seat_name = evas_device_name_get(seat_dev);
1634
1635    comp_conf = e_comp_config_get();
1636    if (comp_conf && comp_conf->input_log_enable)
1637      ELOGF("Touch", "Down (obj: %p, button: %d, time: %d, x:%d, y:%d, name:%20s) (dev:%s, seat:%s)",
1638            ec, obj, ev->button, ev->timestamp, ev->output.x, ev->output.y, e_client_util_name_get(ec),
1639            dev_name, seat_name);
1640
1641    _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1642
1643    if (dev &&  (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
1644      {
1645         e_comp_wl->touch.faked_ec = ec;
1646
1647         if (dev_name)
1648           _e_comp_wl_device_renew_axis(dev_name, evas_device_class_get(dev),
1649                                         ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
1650         _e_comp_wl_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_TRUE);
1651
1652         e_pointer_touch_move(e_comp->pointer, ev->output.x, ev->output.y);
1653         e_comp_wl->touch.pressed |= (1 << 0);
1654      }
1655    else
1656      {
1657         if (_e_comp_wl_check_cursor_timer_needed(ec))
1658           {
1659              if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_DOWN, ec))
1660                return;
1661           }
1662
1663         e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
1664                                            WL_POINTER_BUTTON_STATE_PRESSED);
1665
1666         e_pointer_mouse_move(e_comp->pointer, ev->output.x, ev->output.y);
1667      }
1668
1669    need_send_released = EINA_TRUE;
1670 }
1671
1672 static void
1673 _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event)
1674 {
1675    E_Client *ec = data;
1676    Evas_Event_Mouse_Up *ev = event;
1677    Evas_Device *dev = NULL;
1678    const Evas_Device *seat_dev;
1679    const char *dev_name, *seat_name;;
1680    Evas_Event_Flags flags;
1681    E_Comp_Config *comp_conf = NULL;
1682
1683    if (!ec) return;
1684    if (ec->cur_mouse_action) return;
1685    if (e_object_is_del(E_OBJECT(ec))) return;
1686
1687    if (!need_send_released)
1688      {
1689         need_send_motion = EINA_TRUE;
1690      }
1691
1692    dev = ev->dev;
1693    dev_name = evas_device_description_get(dev);
1694
1695    seat_dev = evas_device_parent_get(dev);
1696    seat_name = evas_device_name_get(seat_dev);
1697    flags = evas_event_default_flags_get(evas);
1698
1699    comp_conf = e_comp_config_get();
1700    if (comp_conf && comp_conf->input_log_enable)
1701      ELOGF("Touch", "Up (obj: %p, button: %d, flag: 0x%x, time: %d, x:%d, y:%d, name:%20s) (dev:%s, seat:%s)",
1702            ec, obj, ev->button, flags, ev->timestamp, ev->output.x, ev->output.y, e_client_util_name_get(ec),
1703            dev_name, seat_name);
1704
1705    if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
1706      {
1707         e_comp_wl->touch.pressed &= ~(1 << 0);
1708
1709         if (!e_comp_wl->touch.pressed && e_comp_wl->touch.faked_ec)
1710           e_comp_wl->touch.faked_ec = NULL;
1711      }
1712
1713    if (flags & EVAS_EVENT_FLAG_ON_HOLD) goto finish;
1714
1715    _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1716
1717    if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
1718      {
1719         if (dev_name)
1720           _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
1721                                         ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
1722         _e_comp_wl_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_FALSE);
1723      }
1724    else
1725      {
1726         if (_e_comp_wl_check_cursor_timer_needed(ec))
1727           {
1728              if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_UP, ec))
1729                return;
1730           }
1731
1732         e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
1733                                            WL_POINTER_BUTTON_STATE_RELEASED);
1734
1735         if (_e_comp_wl_check_cursor_timer_needed(ec))
1736           _e_comp_wl_cursor_move_timer_control(ec);
1737      }
1738
1739 finish:
1740    need_send_released = EINA_FALSE;
1741 }
1742
1743 static void
1744 _e_comp_wl_mouse_wheel_send(E_Client *ec, int direction, int z, int timestamp)
1745 {
1746    struct wl_resource *res;
1747    struct wl_client *wc;
1748    Eina_List *l;
1749    uint32_t axis, dir;
1750
1751    if (direction == 0)
1752      axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
1753    else
1754      axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
1755
1756    if (z < 0)
1757      dir = -wl_fixed_from_int(abs(z));
1758    else
1759      dir = wl_fixed_from_int(z);
1760
1761    if (!ec) return;
1762    if (e_object_is_del(E_OBJECT(ec))) return;
1763    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1764    if (!surface) return;
1765
1766    wc = wl_resource_get_client(surface);
1767    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
1768      {
1769         if (!e_comp_wl_input_pointer_check(res)) continue;
1770         if (wl_resource_get_client(res) != wc) continue;
1771         wl_pointer_send_axis(res, timestamp, axis, dir);
1772      }
1773 }
1774
1775 static void
1776 _e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
1777 {
1778    E_Client *ec;
1779    Evas_Event_Mouse_Wheel *ev;
1780
1781    ev = event;
1782    if (!(ec = data)) return;
1783    if (ec->cur_mouse_action) return;
1784    if (e_object_is_del(E_OBJECT(ec))) return;
1785    if ((ec->ignored) && (!ec->remote_surface.provider)) return;
1786    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1787    if (!surface) return;
1788
1789    if (!eina_list_count(e_comp_wl->ptr.resources))
1790      return;
1791
1792    if (_e_comp_wl_check_cursor_timer_needed(ec))
1793       {
1794          if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_WHEEL, ec))
1795            return;
1796       }
1797
1798    _e_comp_wl_device_send_event_device(ec, ev->dev, ev->timestamp);
1799
1800    _e_comp_wl_mouse_wheel_send(ec, ev->direction, ev->z, ev->timestamp);
1801
1802    if (!need_send_released) // set cursor's hide_tmr only when mouse button is not pressed
1803      {
1804         if (_e_comp_wl_check_cursor_timer_needed(ec))
1805           _e_comp_wl_cursor_move_timer_control(ec);
1806      }
1807 }
1808
1809 static void
1810 _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
1811 {
1812    E_Client *ec = data;
1813    Evas_Event_Multi_Down *ev = event;
1814    Evas_Device *dev = NULL;
1815    const Evas_Device *seat_dev;
1816    const char *dev_name, *seat_name;
1817    Evas_Device_Class dev_class;
1818    E_Comp_Config *comp_conf = NULL;
1819
1820    if (!ec) return;
1821    if (e_object_is_del(E_OBJECT(ec))) return;
1822    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1823    if (!surface) return;
1824
1825    /* Do not deliver emulated single touch events to client */
1826    if (ev->device == 0) return;
1827
1828    dev = ev->dev;
1829    dev_name = evas_device_description_get(dev);
1830    e_comp_wl->touch.faked_ec = ec;
1831
1832    seat_dev = evas_device_parent_get(dev);
1833    seat_name = evas_device_name_get(seat_dev);
1834
1835    comp_conf = e_comp_config_get();
1836    if (comp_conf && comp_conf->input_log_enable)
1837      ELOGF("Touch", "Down (obj: %p, idx: %d, time: %d, x:%d, y:%d, name:%20s) (dev:%s, seat:%s)",
1838            ec, obj, ev->device, ev->timestamp, ev->output.x, ev->output.y, e_client_util_name_get(ec),
1839            dev_name, seat_name);
1840
1841    if (dev && dev_name)
1842      {
1843         dev_class = evas_device_class_get(dev);
1844         _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1845         _e_comp_wl_device_renew_axis(dev_name, dev_class, ec, ev->device, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
1846      }
1847
1848    _e_comp_wl_send_touch(ec, ev->device, ev->canvas.x, ev->canvas.y, ev->timestamp, EINA_TRUE);
1849    e_comp_wl->touch.pressed |= (1 << ev->device);
1850 }
1851
1852 static void
1853 _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED, void *event)
1854 {
1855    E_Client *ec = data;
1856    Evas_Event_Multi_Up *ev = event;
1857    Evas_Device *dev = NULL;
1858    const Evas_Device *seat_dev;
1859    const char *dev_name, *seat_name;
1860    Evas_Device_Class dev_class;
1861    Evas_Event_Flags flags;
1862    E_Comp_Config *comp_conf = NULL;
1863
1864    if (!ec) return;
1865    if (e_object_is_del(E_OBJECT(ec))) return;
1866    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1867    if (!surface) return;
1868
1869    /* Do not deliver emulated single touch events to client */
1870    if (ev->device == 0) return;
1871
1872    flags = evas_event_default_flags_get(evas);
1873
1874    e_comp_wl->touch.pressed &= ~(1 << ev->device);
1875    if (!e_comp_wl->touch.pressed && e_comp_wl->touch.faked_ec)
1876      e_comp_wl->touch.faked_ec = NULL;
1877
1878    if (flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1879
1880    dev = ev->dev;
1881    dev_name = evas_device_description_get(dev);
1882
1883    seat_dev = evas_device_parent_get(dev);
1884    seat_name = evas_device_name_get(seat_dev);
1885
1886    comp_conf = e_comp_config_get();
1887    if (comp_conf && comp_conf->input_log_enable)
1888      ELOGF("Touch", "Up (obj: %p, idx: %d, flag: 0x%x, time: %d, x:%d, y:%d, name:%20s) (dev:%s, seat:%s)",
1889            ec, obj, ev->device, flags, ev->timestamp, ev->output.x, ev->output.y, e_client_util_name_get(ec),
1890            dev_name, seat_name);
1891
1892    if (dev && dev_name)
1893      {
1894         dev_class = evas_device_class_get(dev);
1895         _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1896         _e_comp_wl_device_handle_axes(dev_name, dev_class, ec, ev->device, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
1897      }
1898
1899    _e_comp_wl_send_touch(ec, ev->device, 0, 0, ev->timestamp, EINA_FALSE);
1900 }
1901
1902 static void
1903 _e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
1904 {
1905    E_Client *ec = data;
1906    Evas_Event_Multi_Move *ev = event;
1907    Evas_Device *dev = NULL;
1908    const char *dev_name;
1909    Evas_Device_Class dev_class;
1910
1911    if (!ec) return;
1912    if (e_object_is_del(E_OBJECT(ec))) return;
1913    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1914    if (!surface) return;
1915
1916    /* Do not deliver emulated single touch events to client */
1917    if (ev->device == 0) return;
1918
1919    e_comp_wl->touch.faked_ec = ec;
1920
1921    if (e_comp_wl->touch.pressed & (1 << ev->device))
1922      {
1923         dev = ev->dev;
1924         if (dev && (dev_name = evas_device_description_get(dev)))
1925           {
1926              dev_class = evas_device_class_get(dev);
1927              _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
1928              _e_comp_wl_device_handle_axes(dev_name, dev_class, ec, ev->device, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
1929           }
1930
1931         _e_comp_wl_send_touch_move(ec, ev->device, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
1932      }
1933 }
1934
1935 static void
1936 _e_comp_wl_client_priority_adjust(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_child, Eina_Bool do_child)
1937 {
1938    Eina_List *files;
1939    char *file, buff[PATH_MAX];
1940    FILE *f;
1941    int pid2, ppid;
1942    int num_read;
1943    int n;
1944
1945    if (use_adj)
1946      n = (getpriority(PRIO_PROCESS, pid) + adj);
1947    else
1948      n = set;
1949
1950    setpriority(PRIO_PROCESS, pid, n);
1951
1952    if (adj_child)
1953      use_adj = EINA_TRUE;
1954
1955    if (!do_child) return;
1956
1957    files = ecore_file_ls("/proc");
1958    EINA_LIST_FREE(files, file)
1959       {
1960          if (!isdigit(file[0]))
1961            continue;
1962
1963          snprintf(buff, sizeof(buff), "/proc/%s/stat", file);
1964          if ((f = fopen(buff, "r")))
1965            {
1966               pid2 = -1;
1967               ppid = -1;
1968               num_read = fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid);
1969               fclose(f);
1970               if (num_read == 2 && ppid == pid)
1971                 _e_comp_wl_client_priority_adjust(pid2, set,
1972                                                   adj, use_adj,
1973                                                   adj_child, do_child);
1974            }
1975
1976          free(file);
1977       }
1978 }
1979
1980 static void
1981 _e_comp_wl_client_priority_raise(E_Client *ec)
1982 {
1983    if (!e_config->priority_control) return;
1984    if (ec->netwm.pid <= 0) return;
1985    if (ec->netwm.pid == getpid()) return;
1986    _e_comp_wl_client_priority_adjust(ec->netwm.pid,
1987                                      e_config->priority - 1, -1,
1988                                      EINA_FALSE, EINA_TRUE, EINA_FALSE);
1989 }
1990
1991 static void
1992 _e_comp_wl_client_priority_normal(E_Client *ec)
1993 {
1994    if (!e_config->priority_control) return;
1995    if (ec->netwm.pid <= 0) return;
1996    if (ec->netwm.pid == getpid()) return;
1997    _e_comp_wl_client_priority_adjust(ec->netwm.pid, e_config->priority, 1,
1998                                      EINA_FALSE, EINA_TRUE, EINA_FALSE);
1999 }
2000
2001 static void
2002 _e_comp_wl_input_thread_send_keys()
2003 {
2004    uint32_t serial;
2005    E_Comp_Wl_Key_Data *k;
2006    struct wl_resource *res;
2007    Eina_List *l;
2008    double t;
2009
2010    if (!e_comp_input_key->kbd.focused)
2011      {
2012         return;
2013      }
2014
2015    serial = wl_display_next_serial(e_comp_wl->wl.disp);
2016    t = ecore_time_unix_get();
2017
2018    EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
2019      {
2020         wl_array_for_each(k, &e_comp_input_key->kbd.keys)
2021           {
2022              _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial);
2023              wl_keyboard_send_key(res, serial, t,
2024                                   k->key, WL_KEYBOARD_KEY_STATE_PRESSED);
2025           }
2026      }
2027 }
2028
2029 static Eina_Bool
2030 _e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
2031 {
2032    if (!ec) return EINA_FALSE;
2033    if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
2034    if (!ec->comp_data) return EINA_FALSE;
2035
2036    ec->comp_data->on_focus_timer = NULL;
2037
2038    e_input_thread_safe_call(_e_comp_wl_input_thread_send_keys, NULL, 0);
2039
2040    return EINA_FALSE;
2041 }
2042
2043 static void
2044 _e_comp_wl_input_thread_focus_in(void *data)
2045 {
2046    struct wl_resource *surface = NULL;
2047    memcpy(&surface, data, sizeof(struct wl_resource *));
2048    struct wl_resource *res;
2049    struct wl_client *wc;
2050    Eina_List *l;
2051
2052    wc = wl_resource_get_client(surface);
2053
2054    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
2055      {
2056         if (wl_resource_get_client(res) == wc)
2057           {
2058              if (!eina_list_data_find(e_comp_input_key->kbd.focused, res))
2059                e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
2060           }
2061      }
2062
2063    if (!e_comp_input_key->kbd.focused)
2064      {
2065         return;
2066      }
2067
2068    e_comp_input_key->kbd.focus = surface;
2069    e_comp_wl_input_keyboard_enter_send(surface);
2070    e_comp_wl_data_device_keyboard_focus_set();
2071 }
2072
2073 /* It is called in the following cases:
2074  *  When a normal ec->frame has focus.
2075  *  Or launching image ec is replaced to the real ec.
2076  */
2077 EINTERN void
2078 e_comp_wl_feed_focus_in(E_Client *ec)
2079 {
2080    E_Client *focused;
2081
2082    if (!ec) return;
2083    if (e_object_is_del(E_OBJECT(ec))) return;
2084    if (ec->iconic) return;
2085
2086    /* block spurious focus events */
2087    focused = e_client_focused_get();
2088    if ((focused) && (ec != focused)) return;
2089
2090    /* raise client priority */
2091    _e_comp_wl_client_priority_raise(ec);
2092
2093    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
2094    if (!surface) return;
2095
2096    INF("send focus in request to input thread. resource %p\n", surface);
2097    e_input_thread_safe_call(_e_comp_wl_input_thread_focus_in, (void *)&surface, sizeof(struct wl_resource *));
2098
2099    ec->comp_data->on_focus_timer =
2100       ecore_timer_add(((e_config->xkb.delay_held_key_input_to_focus)/1000.0),
2101                       (Ecore_Task_Cb)_e_comp_wl_evas_cb_focus_in_timer, ec);
2102    int rotation = ec->e.state.rot.ang.curr;
2103    e_pointer_rotation_set(e_comp->pointer, rotation);
2104 }
2105
2106 static void
2107 _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2108 {
2109    E_Client *ec;
2110    if (!(ec = data)) return;
2111    e_comp_wl_feed_focus_in(ec);
2112 }
2113
2114 static void
2115 _e_comp_wl_input_thread_focus_out(void *data)
2116 {
2117    struct wl_resource *surface = NULL;
2118    struct wl_resource *res;
2119    uint32_t serial;
2120    E_Comp_Wl_Key_Data *k;
2121    Eina_List *l, *ll;
2122    double t;
2123
2124    memcpy(&surface, data, sizeof(struct wl_resource *));
2125
2126    /* update keyboard modifier state */
2127    wl_array_for_each(k, &e_comp_input_key->kbd.keys)
2128       e_comp_wl_input_keyboard_state_update(k->key, EINA_FALSE);
2129
2130    if (!surface) return;
2131
2132    if (!eina_list_count(e_comp_input_key->kbd.resources))
2133      {
2134         return;
2135      }
2136
2137    /* send keyboard_leave to all keyboard resources */
2138    serial = wl_display_next_serial(e_comp_wl->wl.disp);
2139    t = ecore_time_unix_get();
2140
2141    EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
2142      {
2143         wl_array_for_each(k, &e_comp_input_key->kbd.keys)
2144           {
2145              _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial);
2146               wl_keyboard_send_key(res, serial, t,
2147                                    k->key, WL_KEYBOARD_KEY_STATE_RELEASED);
2148           }
2149         wl_keyboard_send_leave(res, serial, surface);
2150         e_comp_input_key->kbd.focused =
2151            eina_list_remove_list(e_comp_input_key->kbd.focused, l);
2152      }
2153 }
2154
2155 static void
2156 _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2157 {
2158    E_Client *ec;
2159    if (!(ec = data)) return;
2160
2161    if (!ec->comp_data) return;
2162
2163    E_FREE_FUNC(ec->comp_data->on_focus_timer, ecore_timer_del);
2164
2165    /* lower client priority */
2166    if (!e_object_is_del(data))
2167      _e_comp_wl_client_priority_normal(ec);
2168
2169    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
2170    INF("send focus out request to input thread. resource %p\n", surface);
2171    e_input_thread_safe_call(_e_comp_wl_input_thread_focus_out, (void *)&surface, sizeof(struct wl_resource *));
2172 }
2173
2174 static void
2175 _e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2176 {
2177    E_Client *ec;
2178
2179    if (!(ec = data)) return;
2180
2181    if (!ec->comp_data->shell.configure_send) return;
2182
2183    /* TODO: calculate x, y with transfrom object */
2184    if ((e_client_util_resizing_get(ec)) && (!ec->transformed) && (e_comp_wl->resize.edges))
2185      {
2186         int w, h;
2187
2188         w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w;
2189         h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h;
2190         if (e_comp_object_frame_exists(ec->frame))
2191           e_comp_object_frame_wh_unadjust(ec->frame, w, h, &w, &h);
2192
2193         switch (ec->resize_mode)
2194           {
2195            case E_POINTER_RESIZE_TL:
2196            case E_POINTER_RESIZE_L:
2197            case E_POINTER_RESIZE_BL:
2198              w += ec->mouse.last_down[ec->moveinfo.down.button - 1].mx -
2199                ec->mouse.current.mx;
2200              break;
2201            case E_POINTER_RESIZE_TR:
2202            case E_POINTER_RESIZE_R:
2203            case E_POINTER_RESIZE_BR:
2204              w += ec->mouse.current.mx - ec->mouse.last_down[ec->moveinfo.down.button - 1].mx;
2205              break;
2206            default:
2207              break;;
2208           }
2209         switch (ec->resize_mode)
2210           {
2211            case E_POINTER_RESIZE_TL:
2212            case E_POINTER_RESIZE_T:
2213            case E_POINTER_RESIZE_TR:
2214              h += ec->mouse.last_down[ec->moveinfo.down.button - 1].my -
2215                ec->mouse.current.my;
2216              break;
2217            case E_POINTER_RESIZE_BL:
2218            case E_POINTER_RESIZE_B:
2219            case E_POINTER_RESIZE_BR:
2220              h += ec->mouse.current.my - ec->mouse.last_down[ec->moveinfo.down.button - 1].my;
2221              break;
2222            default:
2223              break;
2224           }
2225         w = E_CLAMP(w, 1, w);
2226         h = E_CLAMP(h, 1, h);
2227         e_client_resize_limit(ec, &w, &h);
2228
2229         e_client_shell_configure_send(ec, e_comp_wl->resize.edges, w, h);
2230      }
2231    else if ((!ec->fullscreen) && (!ec->maximized) &&
2232             (!ec->comp_data->maximize_pre))
2233      {
2234         int pw = 0;
2235         int ph = 0;
2236         e_pixmap_size_get(ec->pixmap, &pw, &ph);
2237         if ((pw != ec->w) || (ph != ec->h))
2238           {
2239              _e_comp_wl_configure_send(ec, 1, 1);
2240           }
2241      }
2242
2243    if (ec->comp_data->sub.below_obj)
2244      e_comp_wl_subsurface_bg_rectangle_map_apply(ec);
2245 }
2246
2247 static void
2248 _e_comp_wl_evas_cb_maximize_pre(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2249 {
2250    E_Client *ec = data;
2251
2252    ec->comp_data->maximize_pre = 1;
2253 }
2254
2255 static void
2256 _e_comp_wl_evas_cb_maximize_done(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2257 {
2258    E_Client *ec = data;
2259    int w, h;
2260
2261    if (e_object_is_del(E_OBJECT(ec))) return;
2262
2263    e_client_maximized_geometry_get(ec, NULL, NULL, &w, &h);
2264    e_client_shell_configure_send(ec, 0, w, h);
2265
2266    ec->comp_data->maximize_pre = 0;
2267 }
2268
2269 static void
2270 _e_comp_wl_evas_cb_unmaximize_pre(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2271 {
2272    E_Client *ec = data;
2273
2274    ec->comp_data->maximize_pre = 1;
2275 }
2276
2277 static void
2278 _e_comp_wl_evas_cb_unmaximize_done(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2279 {
2280    E_Client *ec = data;
2281
2282    if (e_object_is_del(E_OBJECT(ec))) return;
2283
2284    /* check for wayland pixmap */
2285
2286    if (ec->comp_data->shell.configure_send)
2287      _e_comp_wl_configure_send(ec, 0, 0);
2288
2289    ec->comp_data->maximize_pre = 0;
2290 }
2291
2292 static void
2293 _e_comp_wl_evas_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2294 {
2295    E_Client *ec = data;
2296
2297    if (e_object_is_del(E_OBJECT(ec))) return;
2298
2299    /* check for wayland pixmap */
2300
2301    if (ec->comp_data->shell.configure_send)
2302      _e_comp_wl_configure_send(ec, 0, 1);
2303
2304    ec->comp_data->maximize_pre = 0;
2305 }
2306
2307 static void
2308 _e_comp_wl_evas_cb_unfullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2309 {
2310    E_Client *ec = data;
2311
2312    if (e_object_is_del(E_OBJECT(ec))) return;
2313
2314    /* check for wayland pixmap */
2315
2316    if (ec->comp_data->shell.configure_send)
2317      _e_comp_wl_configure_send(ec, 0, 0);
2318
2319    ec->comp_data->maximize_pre = 0;
2320 }
2321
2322 static void
2323 _e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2324 {
2325    E_Client *ec;
2326
2327    if (!(ec = data)) return;
2328
2329    e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
2330
2331    e_object_del(E_OBJECT(ec));
2332
2333    _e_comp_wl_focus_check();
2334
2335    /* TODO: Delete request send ??
2336     * NB: No such animal wrt wayland */
2337 }
2338
2339 static void
2340 _e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2341 {
2342    E_Client *ec;
2343
2344    if (!(ec = data)) return;
2345
2346    e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
2347    if (ec->comp_data)
2348      {
2349         if (ec->comp_data->reparented)
2350           e_client_comp_hidden_set(ec, EINA_TRUE);
2351      }
2352
2353    evas_object_pass_events_set(ec->frame, EINA_TRUE);
2354    if (ec->visible) evas_object_hide(ec->frame);
2355    if (!ec->internal) e_object_del(E_OBJECT(ec));
2356
2357    _e_comp_wl_focus_check();
2358 }
2359
2360 static void
2361 _e_comp_wl_evas_cb_ping(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2362 {
2363    E_Client *ec;
2364
2365    if (!(ec = data)) return;
2366
2367    e_client_shell_ping(ec);
2368 }
2369
2370 static void
2371 _e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUSED)
2372 {
2373    E_Client *ec;
2374    int a = 0;
2375
2376    if (!(ec = data)) return;
2377    evas_object_color_get(obj, NULL, NULL, NULL, &a);
2378    if (ec->netwm.opacity == a) return;
2379    ec->netwm.opacity = a;
2380    ec->netwm.opacity_changed = EINA_TRUE;
2381 }
2382
2383 static void
2384 _e_comp_wl_buffer_damage_set(E_Comp_Wl_Buffer *buffer, Eina_List *buffer_damages)
2385 {
2386    Eina_Rectangle *damage_rect = NULL;
2387    Eina_Rectangle *dmg = NULL;
2388    Eina_List *l = NULL;
2389
2390    if (buffer->type != E_COMP_WL_BUFFER_TYPE_NATIVE &&
2391        buffer->type != E_COMP_WL_BUFFER_TYPE_TBM)
2392      return;
2393
2394    if (!buffer->tbm_surface) return;
2395
2396    if (buffer_damages)
2397      {
2398         EINA_LIST_FOREACH(buffer_damages, l, dmg)
2399           {
2400              if (!damage_rect)
2401                {
2402                   damage_rect = eina_rectangle_new(dmg->x, dmg->y, dmg->w, dmg->h);
2403                   EINA_SAFETY_ON_FALSE_RETURN(damage_rect);
2404                }
2405              else
2406                eina_rectangle_union(damage_rect, dmg);
2407           }
2408      }
2409    else
2410      {
2411         damage_rect = eina_rectangle_new(0, 0, buffer->w, buffer->h);
2412         EINA_SAFETY_ON_FALSE_RETURN(damage_rect);
2413      }
2414
2415    tbm_surface_internal_set_damage(buffer->tbm_surface,
2416                                    damage_rect->x,
2417                                    damage_rect->y,
2418                                    damage_rect->w,
2419                                    damage_rect->h);
2420
2421    eina_rectangle_free(damage_rect);
2422 }
2423
2424 static void
2425 _e_comp_wl_client_evas_init(E_Client *ec)
2426 {
2427    if (!ec || !ec->comp_data) return;
2428    if (ec->comp_data->evas_init) return;
2429
2430    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,        _e_comp_wl_evas_cb_show,        ec);
2431    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,        _e_comp_wl_evas_cb_hide,        ec);
2432    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE,        _e_comp_wl_evas_cb_move,        ec);
2433
2434
2435    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_IN,    EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_in,    ec);
2436    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_OUT,   EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_out,   ec);
2437    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_MOVE,  EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_move,  ec);
2438    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_DOWN,  EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_down,  ec);
2439    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_UP,    EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_up,    ec);
2440    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_wheel, ec);
2441
2442    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MULTI_DOWN, EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_multi_down, ec);
2443    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MULTI_UP,   EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_multi_up,   ec);
2444    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MULTI_MOVE, EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_multi_move, ec);
2445
2446    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_FOCUS_IN,    EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_focus_in,    ec);
2447    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT,   EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_focus_out,   ec);
2448
2449    if (!ec->override)
2450      {
2451         evas_object_smart_callback_add(ec->frame, "client_resize",   _e_comp_wl_evas_cb_resize,          ec);
2452         evas_object_smart_callback_add(ec->frame, "maximize_pre",    _e_comp_wl_evas_cb_maximize_pre,    ec);
2453         evas_object_smart_callback_add(ec->frame, "maximize_done",   _e_comp_wl_evas_cb_maximize_done,   ec);
2454         evas_object_smart_callback_add(ec->frame, "unmaximize_pre",  _e_comp_wl_evas_cb_unmaximize_pre,  ec);
2455         evas_object_smart_callback_add(ec->frame, "unmaximize_done", _e_comp_wl_evas_cb_unmaximize_done, ec);
2456         evas_object_smart_callback_add(ec->frame, "fullscreen",      _e_comp_wl_evas_cb_fullscreen,      ec);
2457         evas_object_smart_callback_add(ec->frame, "unfullscreen",    _e_comp_wl_evas_cb_unfullscreen,    ec);
2458      }
2459
2460    /* setup delete/kill callbacks */
2461    evas_object_smart_callback_add(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request, ec);
2462    evas_object_smart_callback_add(ec->frame, "kill_request",   _e_comp_wl_evas_cb_kill_request,   ec);
2463
2464    /* setup ping callback */
2465    evas_object_smart_callback_add(ec->frame, "ping",           _e_comp_wl_evas_cb_ping,           ec);
2466    evas_object_smart_callback_add(ec->frame, "color_set",      _e_comp_wl_evas_cb_color_set,      ec);
2467
2468    ec->comp_data->evas_init = EINA_TRUE;
2469 }
2470
2471 static void
2472 _e_comp_wl_client_evas_deinit(E_Client *ec)
2473 {
2474    if (!ec || !ec->comp_data) return;
2475    if (!ec->comp_data->evas_init) return;
2476
2477    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_SHOW, _e_comp_wl_evas_cb_show);
2478    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_HIDE, _e_comp_wl_evas_cb_hide);
2479    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOVE, _e_comp_wl_evas_cb_move);
2480
2481    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOUSE_IN,    _e_comp_wl_evas_cb_mouse_in);
2482    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOUSE_OUT,   _e_comp_wl_evas_cb_mouse_out);
2483    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOUSE_MOVE,  _e_comp_wl_evas_cb_mouse_move);
2484    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOUSE_DOWN,  _e_comp_wl_evas_cb_mouse_down);
2485    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOUSE_UP,    _e_comp_wl_evas_cb_mouse_up);
2486    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_wl_evas_cb_mouse_wheel);
2487
2488    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MULTI_DOWN, _e_comp_wl_evas_cb_multi_down);
2489    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MULTI_UP,   _e_comp_wl_evas_cb_multi_up);
2490    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_MULTI_MOVE, _e_comp_wl_evas_cb_multi_move);
2491
2492    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_FOCUS_IN,  _e_comp_wl_evas_cb_focus_in);
2493    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_FOCUS_OUT, _e_comp_wl_evas_cb_focus_out);
2494
2495    if (!ec->override)
2496      {
2497         evas_object_smart_callback_del(ec->frame, "client_resize",   _e_comp_wl_evas_cb_resize);
2498         evas_object_smart_callback_del(ec->frame, "maximize_pre",    _e_comp_wl_evas_cb_maximize_pre);
2499         evas_object_smart_callback_del(ec->frame, "maximize_done",   _e_comp_wl_evas_cb_maximize_done);
2500         evas_object_smart_callback_del(ec->frame, "unmaximize_pre",  _e_comp_wl_evas_cb_unmaximize_pre);
2501         evas_object_smart_callback_del(ec->frame, "unmaximize_done", _e_comp_wl_evas_cb_unmaximize_done);
2502         evas_object_smart_callback_del(ec->frame, "fullscreen",      _e_comp_wl_evas_cb_fullscreen);
2503         evas_object_smart_callback_del(ec->frame, "unfullscreen",    _e_comp_wl_evas_cb_unfullscreen);
2504      }
2505
2506    evas_object_smart_callback_del(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request);
2507    evas_object_smart_callback_del(ec->frame, "kill_request",   _e_comp_wl_evas_cb_kill_request);
2508
2509    evas_object_smart_callback_del(ec->frame, "ping",           _e_comp_wl_evas_cb_ping);
2510    evas_object_smart_callback_del(ec->frame, "color_set",      _e_comp_wl_evas_cb_color_set);
2511
2512    ec->comp_data->evas_init = EINA_FALSE;
2513 }
2514
2515 static Eina_Bool
2516 _e_comp_wl_cb_randr_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
2517 {
2518    Eina_List *l;
2519    E_Output *eout;
2520    E_Comp_Screen *e_comp_screen;
2521    unsigned int transform = WL_OUTPUT_TRANSFORM_NORMAL;
2522
2523    if (!e_comp) return ECORE_CALLBACK_RENEW;
2524    if (!e_comp->e_comp_screen) return ECORE_CALLBACK_RENEW;
2525    e_comp_screen = e_comp->e_comp_screen;
2526
2527    EINA_LIST_FOREACH(e_comp_screen->outputs, l, eout)
2528      {
2529         if (!eout->config.enabled)
2530           {
2531              e_comp_wl_output_remove(eout->id);
2532              continue;
2533           }
2534
2535         switch (eout->config.rotation)
2536           {
2537            case 90:
2538              transform = WL_OUTPUT_TRANSFORM_90;
2539              break;
2540            case 180:
2541              transform = WL_OUTPUT_TRANSFORM_180;
2542              break;
2543            case 270:
2544              transform = WL_OUTPUT_TRANSFORM_270;
2545              break;
2546            case 0:
2547            default:
2548              transform = WL_OUTPUT_TRANSFORM_NORMAL;
2549              break;
2550           }
2551
2552         if (!e_comp_wl_output_init(eout->id, eout->info.name,
2553                                    eout->info.screen,
2554                                    eout->config.geom.x, eout->config.geom.y,
2555                                    eout->config.geom.w, eout->config.geom.h,
2556                                    eout->info.size.w, eout->info.size.h,
2557                                    eout->config.mode.refresh, 0, transform))
2558           ERR("Could not initialize screen %s", eout->info.name);
2559      }
2560
2561    return ECORE_CALLBACK_RENEW;
2562 }
2563
2564 static Eina_Bool
2565 _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Comp_Object *ev)
2566 {
2567    E_Client *ec;
2568
2569    /* try to get the client from the object */
2570    if (!(ec = e_comp_object_client_get(ev->comp_object)))
2571      return ECORE_CALLBACK_RENEW;
2572
2573    /* check for client being deleted */
2574    if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_RENEW;
2575
2576    /* check for wayland pixmap */
2577    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL)
2578      return ECORE_CALLBACK_RENEW;
2579
2580    /* if we have not setup evas callbacks for this client, do it */
2581    if (!ec->comp_data->evas_init) _e_comp_wl_client_evas_init(ec);
2582
2583    return ECORE_CALLBACK_RENEW;
2584 }
2585
2586 static Eina_Bool
2587 _e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev)
2588 {
2589    int ec_x, ec_y;
2590
2591    e_comp_wl->ptr.x = wl_fixed_from_int(ev->x);
2592    e_comp_wl->ptr.y = wl_fixed_from_int(ev->y);
2593
2594    if (e_comp_wl->selection.target &&
2595        e_comp_wl->drag)
2596      {
2597         struct wl_resource *res;
2598         int x, y;
2599         E_Client *ec = NULL;
2600         E_Client *legacy_target = e_comp_wl->selection.target;
2601         int device_id = e_comp_wl_data_current_device_id_get();
2602
2603         if (device_id < 0)
2604           {
2605              e_comp_wl_data_current_device_id_set(ev->multi.device);
2606           }
2607         else if (device_id != ev->multi.device)
2608           {
2609              return ECORE_CALLBACK_RENEW;
2610           }
2611
2612         ec = e_client_under_position_input_get(legacy_target->desk, ev->x, ev->y);
2613         EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_RENEW);
2614
2615         struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
2616         EINA_SAFETY_ON_NULL_RETURN_VAL(surface, ECORE_CALLBACK_RENEW);
2617
2618         res = e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
2619         EINA_SAFETY_ON_NULL_RETURN_VAL(res, ECORE_CALLBACK_RENEW);
2620
2621         if ((e_comp_wl->drag_offer != wl_resource_get_user_data(res)) &&
2622             (ec != legacy_target))
2623           {
2624              e_comp_wl_data_device_send_leave(legacy_target);
2625              e_comp_wl_data_device_send_enter(ec);
2626           }
2627
2628         if (e_comp_wl->drag)
2629           e_drag_move(e_comp_wl->drag, ev->x, ev->y);
2630
2631         if (e_client_transform_core_enable_get(ec))
2632           {
2633              int trans_x, trans_y;
2634              e_client_transform_core_input_transform(ec, ev->x, ev->y, &trans_x, &trans_y);
2635              x = trans_x - ec->client.x;
2636              y = trans_y - ec->client.y;
2637           }
2638         else
2639           {
2640              e_client_geometry_get(ec, &ec_x, &ec_y, NULL, NULL);
2641              x = ev->x - ec_x;
2642              y = ev->y - ec_y;
2643           }
2644
2645         wl_data_device_send_motion(res, ev->timestamp, wl_fixed_from_int(x), wl_fixed_from_int(y));
2646      }
2647
2648    return ECORE_CALLBACK_RENEW;
2649 }
2650
2651 static Eina_Bool
2652 _e_comp_wl_cb_mouse_relative_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Relative_Move *ev)
2653 {
2654    E_Client *ec;
2655    struct wl_resource *surface;
2656    struct wl_resource *res;
2657    struct wl_client *wc;
2658    Eina_List *l;
2659    E_Comp_Config *comp_conf;
2660
2661    ec = e_comp_wl->ptr_constraints.ec;
2662    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_RENEW);
2663
2664    surface = e_comp_wl_client_surface_get(ec);
2665    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, ECORE_CALLBACK_RENEW);
2666
2667    wc = wl_resource_get_client(surface);
2668
2669    comp_conf = e_comp_config_get();
2670
2671    EINA_LIST_FOREACH(e_comp_wl->relative_ptr.resources, l, res)
2672      {
2673         if (!e_comp_wl_input_relative_pointer_check(res)) continue;
2674         if (wl_resource_get_client(res) != wc) continue;
2675
2676         if (comp_conf && comp_conf->input_log_enable)
2677           ELOGF("Mouse", "Relative Move (time: %d, dx:%d dy:%d, unaccel(%d, %d) name:%20s)",
2678                 ec, ev->timestamp, ev->dx, ev->dy, ev->dx_unaccel, ev->dy_unaccel,
2679                 e_client_util_name_get(ec));
2680
2681         zwp_relative_pointer_v1_send_relative_motion(res,
2682                                                      0,
2683                                                      (uint32_t)(ev->timestamp),
2684                                                      wl_fixed_from_int(ev->dx),
2685                                                      wl_fixed_from_int(ev->dy),
2686                                                      wl_fixed_from_int(ev->dx_unaccel),
2687                                                      wl_fixed_from_int(ev->dy_unaccel));
2688      }
2689
2690    return ECORE_CALLBACK_DONE;
2691 }
2692
2693 static Eina_Bool
2694 _e_comp_wl_cb_mouse_button_cancel(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Button *ev)
2695 {
2696    _e_comp_wl_touch_cancel();
2697
2698    return ECORE_CALLBACK_PASS_ON;
2699 }
2700
2701 static Eina_Bool
2702 _e_comp_wl_cb_zone_display_state_change(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Zone_Display_State_Change *ev)
2703 {
2704    if (!ev) return ECORE_CALLBACK_PASS_ON;
2705
2706    E_Zone *zone = ev->zone;
2707
2708    E_OBJECT_CHECK_RETURN(zone, ECORE_CALLBACK_PASS_ON);
2709    E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, ECORE_CALLBACK_PASS_ON);
2710
2711    if (!e_zone_is_displaying(zone))
2712      _e_comp_wl_touch_cancel();
2713
2714    return ECORE_CALLBACK_PASS_ON;
2715 }
2716
2717 static Eina_Bool
2718 _e_comp_wl_cb_client_rot_change_begin(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Rotation_Change_Begin *ev)
2719 {
2720    E_Client *ec = ev->ec;
2721    E_Comp_Wl_Buffer_Viewport *vp;
2722
2723    if (!ec) return ECORE_CALLBACK_PASS_ON;
2724    if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
2725    if (!ec->comp_data) return ECORE_CALLBACK_PASS_ON;
2726    if (e_comp_wl_subsurface_check(ec)) return ECORE_CALLBACK_PASS_ON;
2727    if (ec->e.state.rot.ang.next < 0) return ECORE_CALLBACK_PASS_ON;
2728
2729    vp = &ec->comp_data->scaler.buffer_viewport;
2730    vp->wait_for_transform_change = ((360 + ec->e.state.rot.ang.next - ec->e.state.rot.ang.curr) % 360) / 90;
2731
2732    DBG("ec(%p) wait_for_transform_change(%d)", ec, vp->wait_for_transform_change);
2733
2734    return ECORE_CALLBACK_PASS_ON;
2735 }
2736
2737 static Eina_Bool
2738 _e_comp_wl_cb_client_rot_change_cancel(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Rotation_Change_Cancel *ev)
2739 {
2740    E_Client *ec = ev->ec;
2741    E_Comp_Wl_Buffer_Viewport *vp;
2742
2743    if (!ec) return ECORE_CALLBACK_PASS_ON;
2744    if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
2745    if (!ec->comp_data) return ECORE_CALLBACK_PASS_ON;
2746    if (e_comp_wl_subsurface_check(ec)) return ECORE_CALLBACK_PASS_ON;
2747
2748    vp = &ec->comp_data->scaler.buffer_viewport;
2749    vp->wait_for_transform_change = 0;
2750
2751    DBG("ec(%p) wait_for_transform_change(%d) reset", ec, vp->wait_for_transform_change);
2752
2753    return ECORE_CALLBACK_PASS_ON;
2754 }
2755
2756 static Eina_Bool
2757 _e_comp_wl_cb_client_rot_change_end(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Rotation_Change_End *ev EINA_UNUSED)
2758 {
2759    E_Client *focused_ec;
2760    int rotation;
2761
2762    focused_ec = e_client_focused_get();
2763    if (!focused_ec) return ECORE_CALLBACK_PASS_ON;
2764
2765    rotation = focused_ec->e.state.rot.ang.curr;
2766    e_pointer_rotation_set(e_comp->pointer, rotation);
2767
2768    return ECORE_CALLBACK_PASS_ON;
2769 }
2770
2771 static void
2772 _e_comp_wl_surface_state_size_update(E_Client *ec, E_Comp_Wl_Surface_State *state)
2773 {
2774    int prev_w, prev_h;
2775    Eina_Rectangle *window;
2776
2777    prev_w = state->bw;
2778    prev_h = state->bh;
2779
2780    if (!e_pixmap_size_get(ec->pixmap, &state->bw, &state->bh)) return;
2781
2782    if ((prev_w != state->bw) ||
2783        (prev_h != state->bh))
2784      {
2785         ec->changes.buf_size = EINA_TRUE;
2786      }
2787
2788    if (e_comp_object_frame_exists(ec->frame)) return;
2789    window = &ec->comp_data->shell.window;
2790    if ((!ec->borderless) && /* FIXME temporarily added this check code
2791                              * to prevent updating E_Client's size by frame */
2792        (window->x || window->y || window->w || window->h))
2793      {
2794         e_comp_object_frame_geometry_set(ec->frame,
2795                                          -window->x,
2796                                          (window->x + window->w) - state->bw,
2797                                          -window->y,
2798                                          (window->y + window->h) - state->bh);
2799      }
2800    else
2801      e_comp_object_frame_geometry_set(ec->frame, 0, 0, 0, 0);
2802 }
2803
2804 static void
2805 _e_comp_wl_surface_state_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
2806 {
2807    E_Comp_Wl_Surface_State *state;
2808
2809    state =
2810      container_of(listener, E_Comp_Wl_Surface_State, buffer_destroy_listener);
2811    state->buffer = NULL;
2812 }
2813
2814 static void
2815 _e_comp_wl_surface_state_init(E_Comp_Wl_Surface_State *state, int w, int h)
2816 {
2817    state->new_attach = EINA_FALSE;
2818    state->buffer = NULL;
2819    state->buffer_destroy_listener.notify =
2820      _e_comp_wl_surface_state_cb_buffer_destroy;
2821    state->sx = state->sy = 0;
2822
2823    state->input = eina_tiler_new(w, h);
2824    eina_tiler_tile_size_set(state->input, 1, 1);
2825
2826    state->opaque = eina_tiler_new(w, h);
2827    eina_tiler_tile_size_set(state->opaque, 1, 1);
2828
2829    state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
2830    state->buffer_viewport.buffer.scale = 1;
2831    state->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
2832    state->buffer_viewport.surface.width = -1;
2833    state->buffer_viewport.changed = 0;
2834
2835    e_presentation_time_container_init(&state->presentation_container);
2836 }
2837
2838 static void
2839 _e_comp_wl_surface_state_finish(E_Comp_Wl_Surface_State *state)
2840 {
2841    struct wl_resource *cb;
2842    Eina_Rectangle *dmg;
2843
2844    EINA_LIST_FREE(state->frames, cb)
2845      wl_resource_destroy(cb);
2846
2847    EINA_LIST_FREE(state->damages, dmg)
2848      eina_rectangle_free(dmg);
2849
2850    EINA_LIST_FREE(state->buffer_damages, dmg)
2851      eina_rectangle_free(dmg);
2852
2853    if (state->opaque) eina_tiler_free(state->opaque);
2854    state->opaque = NULL;
2855
2856    if (state->input) eina_tiler_free(state->input);
2857    state->input = NULL;
2858
2859    if (state->buffer) wl_list_remove(&state->buffer_destroy_listener.link);
2860    state->buffer = NULL;
2861
2862    e_presentation_time_container_finish(&state->presentation_container);
2863 }
2864
2865 static void
2866 _e_comp_wl_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer)
2867 {
2868    if (state->buffer == buffer) return;
2869    if (state->buffer)
2870      wl_list_remove(&state->buffer_destroy_listener.link);
2871    state->buffer = buffer;
2872    if (state->buffer)
2873      wl_signal_add(&state->buffer->destroy_signal,
2874                    &state->buffer_destroy_listener);
2875 }
2876
2877 static void
2878 _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
2879 {
2880    Eina_Rectangle *dmg;
2881    Eina_Bool placed = EINA_TRUE;
2882    int x = 0, y = 0;
2883    int w, h;
2884    int nw, nh;
2885    E_Comp_Wl_Buffer *buffer;
2886    struct wl_resource *cb;
2887    Eina_List *l, *ll;
2888    E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
2889    E_Comp_Wl_Buffer_Viewport *vp = &cdata->scaler.buffer_viewport;
2890    E_Zone *zone;
2891
2892    if (ec->ignored)
2893      {
2894         if ((ec->internal) ||
2895             (cdata->shell.surface && state->new_attach))
2896           {
2897              EC_CHANGED(ec);
2898              ec->new_client = 1;
2899              e_comp->new_clients++;
2900              ELOGF("COMP", "Unignore", ec);
2901              e_client_unignore(ec);
2902           }
2903      }
2904
2905    /* buffer transform */
2906    if (vp->buffer.transform != state->buffer_viewport.buffer.transform)
2907      {
2908         E_Output *eout;
2909         int transform_change = (4 + state->buffer_viewport.buffer.transform - vp->buffer.transform) & 0x3;
2910
2911         /* when buffer is transformed, we have to apply the new evas-map */
2912         state->buffer_viewport.changed = EINA_TRUE;
2913
2914         ELOGF("TRANSFORM", "buffer_transform changed: old(%d) new(%d)",
2915               ec,
2916               vp->buffer.transform, state->buffer_viewport.buffer.transform);
2917
2918         if (transform_change == vp->wait_for_transform_change)
2919           vp->wait_for_transform_change = 0;
2920
2921         // TODO: This logic has to move to e_comp_hwc or e_hwc_window and it is
2922         //       triggered by E_CLIENT_HOOK calls at those file.
2923         zone = e_comp_zone_find_by_ec(ec);
2924         if (zone)
2925           {
2926              eout = e_output_find(zone->output_id);
2927              if (eout && eout->hwc)
2928                {
2929                   if (e_hwc_policy_get(eout->hwc) == E_HWC_POLICY_PLANES)
2930                     {
2931                        if (e_comp_is_on_overlay(ec))
2932                          e_comp_hwc_client_end(ec, __FUNCTION__);
2933                     }
2934                }
2935           }
2936      }
2937
2938    /* assign a new buffer_vieport to cdata->scaler.buffer_viewport */
2939    cdata->scaler.buffer_viewport = state->buffer_viewport;
2940
2941    if (state->new_attach)
2942      {
2943         e_comp_wl_surface_attach(ec, state->buffer);
2944      }
2945
2946    /* emit a apply_viewport signal when the information of viewport and buffer is ready */
2947    wl_signal_emit(&cdata->apply_viewport_signal, &cdata->surface);
2948
2949    _e_comp_wl_surface_state_buffer_set(state, NULL);
2950
2951    if ((state->new_attach) ||
2952        (state->buffer_viewport.changed))
2953      {
2954         _e_comp_wl_surface_state_size_update(ec, state);
2955         e_comp_wl_map_size_cal_from_viewport(ec);
2956
2957         /* update the position */
2958         if (ec->changes.pos)
2959           {
2960              e_comp_object_frame_xy_unadjust(ec->frame,
2961                                              ec->x, ec->y,
2962                                              &x, &y);
2963           }
2964         else
2965           {
2966              x = ec->client.x;
2967              y = ec->client.y;
2968           }
2969
2970         if (ec->new_client) placed = ec->placed;
2971
2972         if (!ec->lock_client_size)
2973           {
2974              w = ec->w;
2975              h = ec->h;
2976
2977              ec->client.w = state->bw;
2978              ec->client.h = state->bh;
2979
2980              e_comp_object_frame_wh_adjust(ec->frame,
2981                                            ec->client.w, ec->client.h,
2982                                            &nw, &nh);
2983              e_client_size_set(ec, nw, nh);
2984
2985              if ((w != ec->w) || (h != ec->h))
2986                {
2987                   ec->changes.size = 1;
2988                   EC_CHANGED(ec);
2989                }
2990           }
2991
2992         if (ec->changes.buf_size)
2993           {
2994              ELOGF("COMP", "Buffer size is changed. size(%d,%d)", ec, state->bw, state->bh);
2995              _e_comp_wl_hook_call(E_COMP_WL_HOOK_BUFFER_SIZE_CHANGE, ec);
2996              ec->changes.buf_size = EINA_FALSE;
2997
2998              if (ec->move_after_resize)
2999                {
3000                   ELOGF("POSSIZE", "Unset move_after_resize. ec_geo(%d,%d,%dx%d)", ec, ec->x, ec->y, ec->w, ec->h);
3001                   ec->move_after_resize = EINA_FALSE;
3002                }
3003           }
3004      }
3005
3006    /* map or unmap ec */
3007    Eina_Bool pixmap_usable = e_pixmap_usable_get(ec->pixmap);
3008    Eina_Bool hide_by_request = e_client_hide_by_request_get(ec);
3009    if (!pixmap_usable || hide_by_request)
3010      {
3011         /* unmap ec */
3012         if (cdata->mapped)
3013           {
3014              ELOGF("COMP", "Unmap. pixmap_usable:%d", ec, pixmap_usable);
3015
3016              e_client_hide(ec);
3017           }
3018
3019         if ((cdata->sub.below_obj) &&
3020             (evas_object_visible_get(cdata->sub.below_obj)))
3021           {
3022              evas_object_hide(cdata->sub.below_obj);
3023           }
3024      }
3025    else
3026      {
3027         /* map ec */
3028         e_client_show(ec);
3029
3030         if ((cdata->sub.below_obj) &&
3031             (!evas_object_visible_get(cdata->sub.below_obj)) &&
3032             (evas_object_visible_get(ec->frame)))
3033           {
3034              evas_object_show(cdata->sub.below_obj);
3035           }
3036      }
3037
3038    if ((state->new_attach) ||
3039        (state->buffer_viewport.changed))
3040      {
3041         if ((e_comp_wl->drag) &&
3042             (e_comp_wl->drag_client) &&
3043             (e_comp_wl->drag_client == ec))
3044           {
3045              e_drag_reference_point_set(e_comp_wl->drag, state->sx, state->sy);
3046
3047              e_drag_move(e_comp_wl->drag,
3048                          e_comp_wl->drag->x,
3049                          e_comp_wl->drag->y);
3050
3051              e_drag_resize(e_comp_wl->drag,
3052                            state->bw, state->bh);
3053           }
3054         else if ((cdata->shell.surface) &&
3055                  (cdata->shell.configure))
3056           {
3057              e_comp_wl_commit_sync_configure(ec);
3058           }
3059         else if (!e_client_video_hw_composition_check(ec))
3060           {
3061              e_client_util_move_resize_without_frame(ec, x, y, ec->w, ec->h);
3062           }
3063
3064         if (ec->new_client)
3065           {
3066              ec->placed = placed;
3067              ec->want_focus |= ec->icccm.accepts_focus && (!ec->override);
3068           }
3069      }
3070
3071    if (cdata->scaler.buffer_viewport.changed)
3072      e_comp_wl_map_apply(ec);
3073
3074    /* resize transform object */
3075    if (ec->transformed)
3076      e_client_transform_update(ec);
3077
3078    state->sx = 0;
3079    state->sy = 0;
3080    state->new_attach = EINA_FALSE;
3081
3082    EINA_LIST_FOREACH_SAFE(cdata->frames, l, ll, cb)
3083      {
3084         wl_callback_send_done(cb, (unsigned int)(ecore_loop_time_get() * 1000));
3085         wl_resource_destroy(cb);
3086      }
3087
3088    /* insert state frame callbacks into comp_data->frames
3089     * NB: This clears state->frames list */
3090    cdata->frames = eina_list_merge(cdata->frames,
3091                                            state->frames);
3092    state->frames = NULL;
3093
3094    e_presentation_time_container_feedback_discard(&cdata->presentation_container);
3095    e_presentation_time_container_feedback_merge(&cdata->presentation_container,
3096                                                 &state->presentation_container);
3097
3098    buffer = e_pixmap_resource_get(ec->pixmap);
3099
3100    /* put state damages into surface */
3101    if (ec->frame)
3102      {
3103         /* FIXME: workaround for bad wayland egl driver which doesn't send damage request */
3104         if (!eina_list_count(state->damages) && !eina_list_count(state->buffer_damages))
3105           {
3106              if ((cdata->buffer_ref.buffer) &&
3107                  ((cdata->buffer_ref.buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE) ||
3108                   (cdata->buffer_ref.buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)))
3109                {
3110                   e_comp_object_damage(ec->frame,
3111                                        0, 0,
3112                                        cdata->buffer_ref.buffer->w,
3113                                        cdata->buffer_ref.buffer->h);
3114                }
3115           }
3116         else
3117           {
3118              Eina_List *damages = NULL;
3119
3120              if (buffer)
3121                _e_comp_wl_buffer_damage_set(buffer, state->buffer_damages);
3122
3123              if (eina_list_count(state->buffer_damages))
3124                {
3125                   EINA_LIST_FREE(state->buffer_damages, dmg)
3126                     {
3127                        if (buffer)
3128                          e_comp_wl_rect_convert_inverse(buffer->w, buffer->h,
3129                                                         e_comp_wl_output_buffer_transform_get(ec),
3130                                                         vp->buffer.scale,
3131                                                         dmg->x, dmg->y, dmg->w, dmg->h,
3132                                                         &dmg->x, &dmg->y, &dmg->w, &dmg->h);
3133                        damages = eina_list_append(damages, dmg);
3134                     }
3135                }
3136
3137              EINA_LIST_FREE(state->damages, dmg)
3138                damages = eina_list_append(damages, dmg);
3139
3140              EINA_LIST_FREE(damages, dmg)
3141                {
3142                   /* not creating damage for ec that shows a underlay video */
3143                   if (state->buffer_viewport.changed ||
3144                       !e_comp->wl_comp_data->available_hw_accel.underlay ||
3145                       !buffer || buffer->type != E_COMP_WL_BUFFER_TYPE_VIDEO)
3146                     e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h);
3147
3148                   eina_rectangle_free(dmg);
3149                }
3150           }
3151      }
3152
3153    /* put state opaque into surface */
3154    e_pixmap_image_opaque_set(ec->pixmap, 0, 0, 0, 0);
3155    if (state->opaque)
3156      {
3157         Eina_Rectangle *rect;
3158         Eina_Iterator *itr;
3159
3160         itr = eina_tiler_iterator_new(state->opaque);
3161         EINA_ITERATOR_FOREACH(itr, rect)
3162           {
3163              Eina_Rectangle r;
3164
3165              EINA_RECTANGLE_SET(&r, rect->x, rect->y, rect->w, rect->h);
3166              E_RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h, 0, 0, state->bw, state->bh);
3167              e_pixmap_image_opaque_set(ec->pixmap, r.x, r.y, r.w, r.h);
3168              break;
3169           }
3170
3171         eina_iterator_free(itr);
3172      }
3173
3174    /* put state input into surface */
3175    if ((state->input) &&
3176        (!eina_tiler_empty(state->input)) &&
3177        ec->first_mapped)
3178      {
3179         Eina_Tiler *src, *tmp;
3180         int sw = ec->w;
3181         int sh = ec->h;
3182
3183         tmp = eina_tiler_new(sw, sh);
3184         eina_tiler_tile_size_set(tmp, 1, 1);
3185
3186         eina_tiler_rect_add(tmp,
3187                             &(Eina_Rectangle){0, 0, sw, sh});
3188
3189         if ((src = eina_tiler_intersection(state->input, tmp)))
3190           {
3191              Eina_Rectangle *rect;
3192              Eina_Iterator *itr;
3193
3194              e_comp_object_input_objs_del(ec->frame);
3195              itr = eina_tiler_iterator_new(src);
3196              EINA_ITERATOR_FOREACH(itr, rect)
3197                {
3198                   ELOGF("COMP", "Set Input Area x:%d, y:%d, w:%d, h:%d, ec(%dx%d), state(%dx%d)",
3199                         ec, rect->x, rect->y, rect->w, rect->h,
3200                         ec->w, ec->h, state->bw, state->bh);
3201                   e_comp_object_input_area_set(ec->frame,
3202                                                rect->x, rect->y,
3203                                                rect->w, rect->h);
3204                }
3205
3206              eina_iterator_free(itr);
3207              eina_tiler_free(src);
3208           }
3209         else
3210           e_comp_object_input_area_set(ec->frame, 0, 0, ec->w, ec->h);
3211
3212         eina_tiler_free(tmp);
3213
3214         /* clear input tiler */
3215         eina_tiler_clear(state->input);
3216      }
3217
3218    e_comp_wl_subsurface_check_below_bg_rectangle(ec);
3219
3220    if ((cdata->video_client) &&
3221        ((buffer) &&
3222         (buffer->type == E_COMP_WL_BUFFER_TYPE_VIDEO)) &&
3223        (e_comp->wl_comp_data->available_hw_accel.underlay))
3224      {
3225         e_pixmap_image_clear(ec->pixmap, 1);
3226      }
3227
3228    state->buffer_viewport.changed = 0;
3229
3230    wl_signal_emit(&cdata->state_commit_signal, &cdata->surface);
3231
3232    if (buffer &&
3233        ec->exp_iconify.buffer_flush &&
3234        e_policy_visibility_client_is_iconic(ec))
3235      {
3236         e_pixmap_buffer_clear(ec->pixmap, EINA_FALSE);
3237      }
3238 }
3239
3240 static void
3241 _e_comp_wl_surface_render_stop(E_Client *ec)
3242 {
3243    /* FIXME: this may be fine after e_pixmap can create textures for wl clients? */
3244    //if ((!ec->internal) && (!e_comp_gl_get()))
3245      ec->dead = 1;
3246
3247    /* check if internal animation is running */
3248    if (e_comp_object_is_animating(ec->frame)) return;
3249    /* check if external animation is running */
3250    if (evas_object_data_get(ec->frame, "effect_running")) return;
3251
3252    evas_object_hide(ec->frame);
3253 }
3254
3255 EINTERN void
3256 e_comp_wl_client_surface_finish(E_Client *ec)
3257 {
3258    struct wl_resource *res, *surface;
3259    struct wl_client *surface_client = NULL;
3260    Eina_List *l, *ll;
3261
3262    surface = e_comp_wl_client_surface_get(ec);
3263
3264    if (surface)
3265      surface_client = wl_resource_get_client(surface);
3266
3267    if (surface_client &&
3268        (ec == e_client_focused_get()))
3269      {
3270         EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
3271           {
3272              if (wl_resource_get_client(res) ==
3273                  surface_client)
3274                e_comp_input_key->kbd.focused =
3275                   eina_list_remove_list(e_comp_input_key->kbd.focused, l);
3276
3277           }
3278      }
3279
3280    e_comp_wl_client_surface_set(ec, NULL);
3281
3282    ec->comp_data->wl_surface = NULL;
3283    e_pixmap_win_id_del(ec->pixmap);
3284
3285    _e_comp_wl_surface_render_stop(ec);
3286    e_object_del(E_OBJECT(ec));
3287 }
3288
3289 static void
3290 _e_comp_wl_pname_get(pid_t pid, char *name, int size)
3291 {
3292    if (!name) return;
3293
3294    FILE *h;
3295    char proc[512], pname[512];
3296    size_t len;
3297
3298    snprintf(proc, 512,"/proc/%d/cmdline", pid);
3299
3300    h = fopen(proc, "r");
3301    if (h)
3302      {
3303         len = fread(pname, sizeof(char), 512, h);
3304         if (len > 0)
3305           pname[len - 1] = '\0';
3306         else
3307           strncpy(pname, "NO NAME", sizeof(pname));
3308
3309         fclose(h);
3310      }
3311    else
3312      {
3313         strncpy(pname, "NO NAME", sizeof(pname));
3314      }
3315
3316    strncpy(name, pname, size);
3317 }
3318
3319 static void
3320 _e_comp_wl_pname_print(pid_t pid)
3321 {
3322    FILE *h;
3323    char proc[512], pname[512];
3324    size_t len;
3325
3326    snprintf(proc, 512,"/proc/%d/cmdline", pid);
3327
3328    h = fopen(proc, "r");
3329    if (!h) return;
3330
3331    len = fread(pname, sizeof(char), 512, h);
3332    if (len > 0)
3333      pname[len - 1] = '\0';
3334    else
3335      strncpy(pname, "NO NAME", sizeof(pname));
3336
3337    fclose(h);
3338
3339    ELOGF("COMP", "         |%s", NULL, pname);
3340 }
3341
3342
3343 static void
3344 _e_comp_wl_connected_client_cb_destroy(struct wl_listener *listener, void *data)
3345 {
3346    struct wl_client *client = data;
3347    E_Comp_Connected_Client_Info *cinfo;
3348    E_Appinfo *eai;
3349
3350    cinfo = wl_container_of(listener, cinfo, destroy);
3351
3352    ELOGF("WL_CLIENT", "DESTROY  |client:%8p|%d|%d|%d",
3353          NULL, client, cinfo->pid, cinfo->uid, cinfo->gid);
3354
3355    eai = e_appinfo_find_with_pid(cinfo->pid);
3356    if (e_appinfo_owner_get(eai) == E_APPINFO_OWNER_SERVER)
3357      e_appinfo_del(eai);
3358
3359    e_comp->connected_clients = eina_list_remove(e_comp->connected_clients, cinfo);
3360
3361    wl_list_remove(&cinfo->destroy.link);
3362    eina_stringshare_del(cinfo->name);
3363    free(cinfo);
3364 }
3365
3366 static void
3367 _e_comp_wl_connected_client_create(struct wl_client *client, char *name, pid_t pid, uid_t uid, gid_t gid)
3368 {
3369    E_Comp_Connected_Client_Info *cinfo;
3370
3371    cinfo = E_NEW(E_Comp_Connected_Client_Info, 1);
3372    EINA_SAFETY_ON_NULL_RETURN(cinfo);
3373
3374    cinfo->name = eina_stringshare_add(name);
3375    cinfo->pid = pid;
3376    cinfo->uid = uid;
3377    cinfo->gid = gid;
3378    cinfo->destroy.notify = _e_comp_wl_connected_client_cb_destroy;
3379    wl_client_add_destroy_listener(client, &cinfo->destroy);
3380    e_comp->connected_clients = eina_list_append(e_comp->connected_clients, cinfo);
3381
3382    _e_comp_wl_pid_hook_call(E_COMP_WL_PID_HOOK_CONNECTED_CLIENT_CREATE, pid);
3383 }
3384
3385 static void
3386 _e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
3387 {
3388    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
3389
3390    /* send configure */
3391    if (ec->comp_data->shell.configure_send)
3392      {
3393         if (ec->comp_data->shell.surface)
3394           _e_comp_wl_configure_send(ec, 0, 0);
3395      }
3396
3397    e_comp_input_key->kbd.focus = ec->comp_data->surface;
3398 }
3399
3400 static void
3401 _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
3402 {
3403    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
3404
3405    /* send configure */
3406    if (ec->comp_data->shell.configure_send)
3407      {
3408         if (ec->comp_data->shell.surface)
3409           _e_comp_wl_configure_send(ec, 0, 0);
3410      }
3411
3412    _e_comp_wl_focus_check();
3413
3414    if (e_comp_input_key->kbd.focus == ec->comp_data->surface)
3415      e_comp_input_key->kbd.focus = NULL;
3416 }
3417
3418 static void
3419 _e_comp_wl_client_cb_resize_begin(void *data EINA_UNUSED, E_Client *ec)
3420 {
3421    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
3422    if (ec->keyboard_resizing) return;
3423
3424    /* do nothing currently */
3425    ;
3426 }
3427
3428 static void
3429 _e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
3430 {
3431    if (e_object_is_del(E_OBJECT(ec))) return;
3432    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
3433
3434    e_comp_wl->resize.edges = 0;
3435    e_comp_wl->resize.resource = NULL;
3436 }
3437
3438 static void
3439 _e_comp_wl_client_cb_move_end(void *data EINA_UNUSED, E_Client *ec)
3440 {
3441    if (e_object_is_del(E_OBJECT(ec))) return;
3442    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
3443 }
3444
3445 static void
3446 _e_comp_wl_output_info_send(E_Comp_Wl_Output *output, struct wl_resource *resource, pid_t pid, int res_w, int res_h)
3447 {
3448    int phys_w, phys_h;
3449    int ratio_w, ratio_h;
3450
3451    phys_w = output->phys_width;
3452    phys_h = output->phys_height;
3453
3454    if (e_config->configured_output_resolution.use)
3455      {
3456         // change the configured physical size(mm) of the output
3457         if (output->w != res_w)
3458           {
3459              ratio_w = res_w / output->w;
3460              phys_w = (int)((float)output->phys_width * (float)ratio_w);
3461           }
3462
3463         if (output->h != res_h)
3464           {
3465              ratio_h = res_h / output->h;
3466              phys_h = (int)((float)output->phys_height * (float)ratio_h);
3467           }
3468
3469         ELOGF("COMP_WL", "\tSend Configured Output (pid:%d)", NULL, pid);
3470      }
3471
3472    ELOGF("COMP_WL", "\t    Output Resolution: res(%d, %d) phy_size(%d, %d) (pid:%d).",
3473          NULL, res_w, res_h, phys_w, phys_h, pid);
3474
3475    if (wl_resource_get_version(resource) >= WL_OUTPUT_SCALE_SINCE_VERSION)
3476      wl_output_send_scale(resource, output->scale);
3477
3478    wl_output_send_geometry(resource, output->x, output->y,
3479                            phys_w, phys_h,
3480                            output->subpixel, output->make ?: "",
3481                            output->model ?: "", output->transform);
3482
3483    wl_output_send_mode(resource,  WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
3484                        res_w, res_h, output->refresh);
3485
3486    if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
3487      wl_output_send_done(resource);
3488 }
3489
3490 static void
3491 _e_comp_wl_cb_output_unbind(struct wl_resource *resource)
3492 {
3493    E_Comp_Wl_Output *output;
3494
3495    if (!(output = wl_resource_get_user_data(resource))) return;
3496
3497    output->resources = eina_list_remove(output->resources, resource);
3498 }
3499
3500 static void
3501 _e_comp_wl_cb_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
3502 {
3503    E_Comp_Wl_Output *output;
3504    struct wl_resource *resource;
3505    E_Appinfo *eai = NULL;
3506    pid_t pid = 0;
3507    int res_w, res_h;
3508
3509    if (!(output = data)) return;
3510
3511    resource =
3512      wl_resource_create(client, &wl_output_interface, version, id);
3513    if (!resource)
3514      {
3515         wl_client_post_no_memory(client);
3516         return;
3517      }
3518
3519    ELOGF("COMP_WL", "Bound Output: %s", NULL, output->id);
3520    ELOGF("COMP_WL", "\tOutput Geom: %d %d %d %d", NULL, output->x, output->y, output->w, output->h);
3521
3522    output->resources = eina_list_append(output->resources, resource);
3523
3524    wl_resource_set_implementation(resource, NULL, output,
3525                                   _e_comp_wl_cb_output_unbind);
3526    wl_resource_set_user_data(resource, output);
3527
3528    // set the configured_output_resolution as a resolution of the wl_output if the use is set.
3529    if (e_config->configured_output_resolution.use)
3530      {
3531         wl_client_get_credentials(client, &pid, NULL, NULL);
3532         if (pid <= 0)
3533           {
3534              res_w = e_config->configured_output_resolution.w;
3535              res_h = e_config->configured_output_resolution.h;
3536              goto send_info;
3537           }
3538
3539         eai = e_appinfo_find_with_pid(pid);
3540         if (!eai)
3541           {
3542              res_w = e_config->configured_output_resolution.w;
3543              res_h = e_config->configured_output_resolution.h;
3544              goto send_info;
3545           }
3546
3547         if (!e_appinfo_base_output_resolution_get(eai, &res_w, &res_h))
3548           {
3549              res_w = e_config->configured_output_resolution.w;
3550              res_h = e_config->configured_output_resolution.h;
3551              goto send_info;
3552           }
3553
3554         ELOGF("COMP_WL", "Get base_screen_resolution. (pid:%d).", NULL, pid);
3555      }
3556    else
3557      {
3558         res_w = output->w;
3559         res_h = output->h;
3560      }
3561
3562 send_info:
3563    _e_comp_wl_output_info_send(output, resource, pid, res_w, res_h);
3564 }
3565
3566 static void
3567 _e_comp_wl_gl_init(void *data EINA_UNUSED)
3568 {
3569    Evas *evas = NULL;
3570    Evas_GL *evasgl = NULL;
3571    Evas_GL_API *glapi = NULL;
3572    Evas_GL_Context *ctx = NULL;
3573    Evas_GL_Surface *sfc = NULL;
3574    Evas_GL_Config *cfg = NULL;
3575    Eina_Bool res;
3576    E_Comp_Wl_Evas_Gl *evas_gl = NULL;
3577
3578    if (!e_comp_gl_get()) return;
3579
3580    evas_gl = E_NEW(E_Comp_Wl_Evas_Gl, 1);
3581    EINA_SAFETY_ON_NULL_RETURN(evas_gl);
3582
3583    /* create dummy evas gl to bind wayland display of enlightenment to egl display */
3584    e_main_ts_begin("\tE_Comp_Wl_GL Init");
3585
3586    /* if wl_drm module doesn't call e_comp_canvas_init yet,
3587     * then we should get evas from ecore_evas.
3588     */
3589    if (e_comp->evas)
3590      evas = e_comp->evas;
3591    else
3592      evas = ecore_evas_get(e_comp->ee);
3593
3594    evasgl = evas_gl_new(evas);
3595    EINA_SAFETY_ON_NULL_GOTO(evasgl, err);
3596
3597    glapi = evas_gl_api_get(evasgl);
3598    EINA_SAFETY_ON_NULL_GOTO(glapi, err);
3599    EINA_SAFETY_ON_NULL_GOTO(glapi->evasglBindWaylandDisplay, err);
3600
3601    cfg = evas_gl_config_new();
3602    EINA_SAFETY_ON_NULL_GOTO(cfg, err);
3603
3604    sfc = evas_gl_surface_create(evasgl, cfg, 1, 1);
3605    EINA_SAFETY_ON_NULL_GOTO(sfc, err);
3606
3607    ctx = evas_gl_context_create(evasgl, NULL);
3608    EINA_SAFETY_ON_NULL_GOTO(ctx, err);
3609
3610    res = evas_gl_make_current(evasgl, sfc, ctx);
3611    EINA_SAFETY_ON_FALSE_GOTO(res, err);
3612
3613    res = glapi->evasglBindWaylandDisplay(evasgl, e_comp_wl->wl.disp);
3614    EINA_SAFETY_ON_FALSE_GOTO(res, err);
3615
3616    evas_gl_config_free(cfg);
3617
3618    evas_gl->gl = evasgl;
3619    evas_gl->glapi = glapi;
3620    evas_gl->glsfc = sfc;
3621    evas_gl->glctx = ctx;
3622
3623    e_comp_wl->evas_gl = evas_gl;
3624
3625    /* for native surface */
3626    e_comp->gl = 1;
3627
3628    e_main_ts_end("\tE_Comp_Wl_GL Init Done");
3629
3630    return;
3631
3632 err:
3633    evas_gl_config_free(cfg);
3634    evas_gl_make_current(evasgl, NULL, NULL);
3635    evas_gl_context_destroy(evasgl, ctx);
3636    evas_gl_surface_destroy(evasgl, sfc);
3637    evas_gl_free(evasgl);
3638    free(evas_gl);
3639 }
3640
3641 // FIXME
3642 #if 0
3643 static void
3644 _e_comp_wl_gl_popup_cb_close(void *data,
3645                              Evas_Object *obj EINA_UNUSED,
3646                              void *event_info EINA_UNUSED)
3647 {
3648    evas_object_del(data);
3649 }
3650
3651 static void
3652 _e_comp_wl_gl_popup_cb_focus(void *data,
3653                              Evas_Object *obj EINA_UNUSED,
3654                              void *event_info EINA_UNUSED)
3655 {
3656    elm_object_focus_set(data, EINA_TRUE);
3657 }
3658 #endif
3659
3660 static Eina_Bool
3661 _e_comp_wl_gl_idle(void *data)
3662 {
3663    if (!e_comp->gl)
3664      {
3665         /* show warning window to notify failure of gl init */
3666         // TODO: yigl
3667 #if 0
3668         Evas_Object *win, *bg, *popup, *btn;
3669
3670         win = elm_win_add(NULL, "compositor warning", ELM_WIN_BASIC);
3671         elm_win_title_set(win, "Compositor Warning");
3672         elm_win_autodel_set(win, EINA_TRUE);
3673         elm_win_borderless_set(win, EINA_TRUE);
3674         elm_win_role_set(win, "notification-low");
3675         elm_win_alpha_set(win, EINA_TRUE);
3676
3677         bg = evas_object_rectangle_add(evas_object_evas_get(win));
3678         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3679         elm_win_resize_object_add(win, bg);
3680         evas_object_color_set(bg, 125, 125, 125, 125);
3681         evas_object_show(bg);
3682
3683         popup = elm_popup_add(win);
3684         elm_object_text_set(popup,
3685                             _( "Your screen does not support OpenGL.<br>"
3686                                "Falling back to software engine."));
3687         elm_object_part_text_set(popup, "title,text", "Compositor Warning");
3688
3689         btn = elm_button_add(popup);
3690         elm_object_text_set(btn, "Close");
3691         elm_object_part_content_set(popup, "button1", btn);
3692         evas_object_show(btn);
3693
3694         evas_object_smart_callback_add(win, "focus,in", _e_comp_wl_gl_popup_cb_focus, popup);
3695         evas_object_smart_callback_add(btn, "unpressed", _e_comp_wl_gl_popup_cb_close, win);
3696
3697         evas_object_show(popup);
3698         evas_object_show(win);
3699 #endif
3700      }
3701
3702    return ECORE_CALLBACK_CANCEL;
3703 }
3704
3705 static void
3706 _e_comp_wl_cb_client_created(struct wl_listener *listener, void *data)
3707 {
3708    struct wl_client *client = data;
3709    pid_t pid = 0;
3710    uid_t uid = 0;
3711    gid_t gid = 0;
3712    char name[512];
3713
3714    wl_client_get_credentials(client, &pid, &uid, &gid);
3715
3716    ELOGF("COMP", "WL_CLIENT|client:%8p|%d|%d|%d", NULL, client, pid, uid, gid);
3717
3718    _e_comp_wl_pname_print(pid);
3719    _e_comp_wl_pname_get(pid, name, sizeof(name));
3720    _e_comp_wl_connected_client_create(client, name, pid, uid, gid);
3721 }
3722
3723 static void
3724 _e_comp_wl_ds_log_handler(enum ds_log_level level, const char *fmt, va_list args)
3725 {
3726    char buf[1024] = {0, };
3727
3728    vsnprintf(buf, 1024, fmt, args);
3729    switch (level)
3730      {
3731       case DS_DBG:
3732          DBG("[libds] %s", buf);
3733          break;
3734       case DS_INF:
3735          INF("[libds] %s", buf);
3736          break;
3737       case DS_ERR:
3738          ERR("[libds] %s", buf);
3739          break;
3740       default:
3741          break;
3742      }
3743 }
3744
3745 static Eina_Bool
3746 _e_comp_wl_display_create(void)
3747 {
3748    E_Comp_Data *comp;
3749    E_Comp_Wl_Data *wl_cdata;
3750    const char *name;
3751    int fd = 0;
3752    Eina_Bool res;
3753
3754    /* create new compositor data */
3755    if (!(comp = E_NEW(E_Comp_Data, 1)))
3756      {
3757         ERR("Could not create compositor data: %m");
3758         return EINA_FALSE;
3759      }
3760    wl_cdata = &comp->base;
3761
3762    /* set compositor wayland data */
3763    e_comp_wl = e_comp->wl_comp_data = wl_cdata;
3764
3765    g_mutex_init(&connection_mutex);
3766
3767    /* try to create a wayland display */
3768    if (!(wl_cdata->wl.disp = wl_display_create()))
3769      {
3770         ERR("Could not create a Wayland display: %m");
3771         goto disp_err;
3772      }
3773
3774    /* try to setup wayland socket */
3775    if (!(name = wl_display_add_socket_auto(wl_cdata->wl.disp)))
3776      {
3777         ERR("Could not create Wayland display socket: %m");
3778         PRCTL("[Winsys] Could not create Wayland display socket: /run/wayland-0");
3779         goto sock_err;
3780      }
3781
3782    res = e_comp_socket_init(name);
3783    EINA_SAFETY_ON_FALSE_GOTO(res, sock_err);
3784    PRCTL("[Winsys] change permission and create sym link for %s", name);
3785
3786    /* set wayland display environment variable */
3787    e_env_set("WAYLAND_DISPLAY", name);
3788
3789    /* wl_cdata->output.transform = WL_OUTPUT_TRANSFORM_NORMAL; */
3790    /* wl_cdata->output.scale = e_scale; */
3791
3792    ds_log_init(DS_DBG, _e_comp_wl_ds_log_handler);
3793
3794    if (!e_compositor_init(wl_cdata->wl.disp))
3795      {
3796         ERR("Failed to initialize compositor");
3797         goto comp_err;
3798      }
3799
3800    comp->client_created.notify = _e_comp_wl_cb_client_created;
3801    wl_display_add_client_created_listener(comp->base.wl.disp, &comp->client_created);
3802
3803    if (!e_comp_wl_subsurfaces_init())
3804      {
3805         ERR("Failed to init_subsurfaces");
3806         goto subsurfaces_err;
3807      }
3808
3809    /* initialize shm mechanism */
3810    wl_display_init_shm(wl_cdata->wl.disp);
3811
3812    /* _e_comp_wl_cb_randr_change(NULL, 0, NULL); */
3813
3814    /* try to init data manager */
3815    if (!e_comp_wl_data_manager_init())
3816      {
3817         ERR("Could not initialize data manager");
3818         goto data_err;
3819      }
3820
3821    /* try to init input */
3822    if (!e_comp_wl_input_init())
3823      {
3824         ERR("Could not initialize input");
3825         goto input_err;
3826      }
3827
3828    if (e_comp_gl_get())
3829      _e_comp_wl_gl_init(NULL);
3830
3831    /* get the wayland display loop */
3832    wl_cdata->wl.loop = wl_display_get_event_loop(wl_cdata->wl.disp);
3833
3834    /* get the file descriptor of the wayland event loop */
3835    fd = wl_event_loop_get_fd(wl_cdata->wl.loop);
3836
3837    /* create a listener for wayland main loop events */
3838    wl_cdata->fd_hdlr =
3839      ecore_main_fd_handler_add(fd, (ECORE_FD_READ | ECORE_FD_ERROR),
3840                                _e_comp_wl_cb_read, wl_cdata, NULL, NULL);
3841    ecore_main_fd_handler_prepare_callback_set(wl_cdata->fd_hdlr,
3842                                               _e_comp_wl_cb_prepare, wl_cdata);
3843
3844    /* add awake handler */
3845    ecore_main_awake_handler_add(_e_comp_wl_cb_awake, NULL);
3846
3847    return EINA_TRUE;
3848
3849 input_err:
3850    e_comp_wl_data_manager_shutdown();
3851 data_err:
3852    e_comp_wl_subsurfaces_shutdown();
3853 subsurfaces_err:
3854    wl_list_remove(&comp->client_created.link);
3855 comp_err:
3856    e_env_unset("WAYLAND_DISPLAY");
3857 sock_err:
3858    wl_display_destroy(wl_cdata->wl.disp);
3859 disp_err:
3860    g_mutex_clear(&connection_mutex);
3861    free(comp);
3862    return EINA_FALSE;
3863 }
3864
3865 static void
3866 _e_comp_wl_gl_shutdown(void)
3867 {
3868    if (!e_comp_wl->evas_gl) return;
3869
3870    e_comp_wl->evas_gl->glapi->evasglUnbindWaylandDisplay(e_comp_wl->evas_gl->gl, e_comp_wl->wl.disp);
3871
3872    evas_gl_make_current(e_comp_wl->evas_gl->gl, NULL, NULL);
3873    evas_gl_context_destroy(e_comp_wl->evas_gl->gl, e_comp_wl->evas_gl->glctx);
3874    evas_gl_surface_destroy(e_comp_wl->evas_gl->gl, e_comp_wl->evas_gl->glsfc);
3875    evas_gl_free(e_comp_wl->evas_gl->gl);
3876
3877    E_FREE(e_comp_wl->evas_gl);
3878 }
3879
3880 /* public functions */
3881
3882 /**
3883  * Creates and initializes a Wayland compositor with ecore.
3884  * Registers callback handlers for keyboard and mouse activity
3885  * and other client events.
3886  *
3887  * @returns true on success, false if initialization failed.
3888  */
3889 EINTERN Eina_Bool
3890 e_comp_wl_init(void)
3891 {
3892    TRACE_DS_BEGIN(COMP_WL:INIT);
3893
3894    /* try to create a wayland compositor */
3895    if (!_e_comp_wl_display_create())
3896      {
3897         e_error_message_show(_("Enlightenment cannot create a Wayland Compositor!\n"));
3898         TRACE_DS_END();
3899         return EINA_FALSE;
3900      }
3901
3902    e_comp_wl_shell_init();
3903    e_wtz_shell_init();
3904 #ifdef HAVE_WAYLAND_TBM
3905    e_comp_wl_tbm_init();
3906 #endif
3907    e_comp_wl_remote_surface_init();
3908
3909    e_pixmap_init();
3910
3911    e_comp_wl_screenshooter_init();
3912
3913    if (!e_comp_wl_video_init())
3914      ELOGF("COMP", "Failed to initialize the e_comp_wl_video", NULL);
3915
3916    e_comp_wl_viewport_init();
3917    e_comp_wl_capture_init();
3918    e_comp_wl_renderer_init();
3919    _e_comp_wl_move_resize_init();
3920    e_presentation_time_init();
3921    ds_single_pixel_buffer_manager_v1_create(e_comp_wl->wl.disp);
3922    e_blender_init();
3923    e_blur_manager_init();
3924
3925    if (!e_foreign_global_init(e_comp_wl->wl.disp))
3926      ELOGF("COMP", "Failed to initialize the e_foreign global", NULL);
3927
3928    /* add event handlers to catch E events */
3929    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREEN_CHANGE,            _e_comp_wl_cb_randr_change,        NULL);
3930    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD,         _e_comp_wl_cb_comp_object_add,     NULL);
3931    E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_MOVE,          _e_comp_wl_cb_mouse_move,          NULL);
3932    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_RELATIVE_MOVE,  _e_comp_wl_cb_mouse_relative_move, NULL);
3933    E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_CANCEL, _e_comp_wl_cb_mouse_button_cancel, NULL);
3934    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_comp_wl_cb_zone_display_state_change, NULL);
3935    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN, _e_comp_wl_cb_client_rot_change_begin, NULL);
3936    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL, _e_comp_wl_cb_client_rot_change_cancel, NULL);
3937    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_END, _e_comp_wl_cb_client_rot_change_end, NULL);
3938
3939    /* add hooks to catch e_client events */
3940    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_FOCUS_SET,    _e_comp_wl_client_cb_focus_set,    NULL);
3941    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_FOCUS_UNSET,  _e_comp_wl_client_cb_focus_unset,  NULL);
3942    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_RESIZE_BEGIN, _e_comp_wl_client_cb_resize_begin, NULL);
3943    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_RESIZE_END,   _e_comp_wl_client_cb_resize_end,   NULL);
3944    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_MOVE_END,     _e_comp_wl_client_cb_move_end,     NULL);
3945
3946    TRACE_DS_END();
3947    return EINA_TRUE;
3948 }
3949
3950 EINTERN void
3951 e_comp_wl_deferred_job(void)
3952 {
3953    ecore_idle_enterer_add(_e_comp_wl_gl_idle, NULL);
3954 }
3955
3956 /* internal functions */
3957 EINTERN void
3958 e_comp_wl_shutdown(void)
3959 {
3960    E_Comp_Data *comp = (E_Comp_Data *)e_comp_wl;
3961
3962    e_comp_wl_subsurfaces_shutdown();
3963    /* free handlers */
3964    E_FREE_LIST(handlers, ecore_event_handler_del);
3965    E_FREE_LIST(hooks, e_client_hook_del);
3966    _e_comp_wl_gl_shutdown();
3967
3968    e_presentation_time_shutdown();
3969    e_comp_wl_renderer_shutdown();
3970    e_comp_wl_capture_shutdown();
3971    e_comp_wl_viewport_shutdown();
3972    e_comp_wl_video_shutdown();
3973    e_comp_wl_screenshooter_shutdown();
3974
3975    e_comp_wl_remote_surface_shutdown();
3976
3977    e_pixmap_shutdown();
3978
3979    e_wtz_shell_shutdown();
3980    e_comp_wl_shell_shutdown();
3981    e_comp_wl_input_shutdown();
3982
3983    wl_list_remove(&comp->client_created.link);
3984
3985    /* delete awake handler */
3986    ecore_main_awake_handler_del(_e_comp_wl_cb_awake);
3987
3988    e_comp_wl = NULL;
3989    e_comp->wl_comp_data = NULL;
3990    free(comp);
3991    // TODO: yigl
3992 #if 0
3993    E_Comp_Wl_Output *output;
3994
3995    if (e_comp_wl->screenshooter.global)
3996      wl_global_destroy(e_comp_wl->screenshooter.global);
3997
3998    EINA_LIST_FREE(e_comp_wl->outputs, output)
3999      {
4000         if (output->id) eina_stringshare_del(output->id);
4001         if (output->make) eina_stringshare_del(output->make);
4002         if (output->model) eina_stringshare_del(output->model);
4003         free(output);
4004      }
4005
4006    /* delete fd handler */
4007    if (e_comp_wl->fd_hdlr) ecore_main_fd_handler_del(e_comp_wl->fd_hdlr);
4008
4009    E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
4010    cursor_timer_ec = NULL;
4011
4012    /* free allocated data structure */
4013    free(e_comp_wl);
4014 #endif
4015 }
4016
4017 static void
4018 e_comp_wl_surface_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
4019 {
4020    e_object_unref(E_OBJECT(ev->ec));
4021    free(ev);
4022 }
4023
4024 EINTERN void
4025 e_comp_wl_surface_attach(E_Client *ec, E_Comp_Wl_Buffer *buffer)
4026 {
4027    E_Event_Client *ev;
4028    ev = E_NEW(E_Event_Client, 1);
4029    if (!ev) return;
4030
4031    e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, buffer);
4032
4033    /* set usable early because shell module checks this */
4034    if (ec->comp_data->shell.surface || e_comp_wl_subsurface_check(ec))
4035      e_pixmap_usable_set(ec->pixmap, (buffer != NULL));
4036
4037    e_pixmap_resource_set(ec->pixmap, buffer);
4038    e_pixmap_dirty(ec->pixmap);
4039    e_pixmap_refresh(ec->pixmap);
4040
4041    e_comp_wl_map_size_cal_from_buffer(ec);
4042    _e_comp_wl_surface_state_size_update(ec, &ec->comp_data->pending);
4043
4044    /* wm-policy module uses it */
4045    _e_comp_wl_hook_call(E_COMP_WL_HOOK_BUFFER_CHANGE, ec);
4046
4047    ev->ec = ec;
4048    e_object_ref(E_OBJECT(ec));
4049    ecore_event_add(E_EVENT_CLIENT_BUFFER_CHANGE, ev,
4050                    (Ecore_End_Cb)e_comp_wl_surface_event_simple_free, NULL);
4051 }
4052
4053 EINTERN Eina_Bool
4054 e_comp_wl_surface_commit(E_Client *ec)
4055 {
4056    Eina_Bool ignored;
4057    int x = 0, y = 0;
4058
4059    _e_comp_wl_surface_state_commit(ec, &ec->comp_data->pending);
4060    if (!e_comp_object_damage_exists(ec->frame))
4061      {
4062         if ((ec->comp_data->video_client) ||
4063             (!e_client_video_hw_composition_check(ec)))
4064           e_pixmap_image_clear(ec->pixmap, 1);
4065      }
4066
4067    ignored = ec->ignored;
4068
4069    if (e_comp_wl_subsurface_order_commit(ec))
4070      {
4071         E_Client *topmost = e_comp_wl_topmost_parent_get(ec);
4072         e_comp_wl_subsurface_restack(topmost);
4073         e_comp_wl_subsurface_restack_bg_rectangle(topmost);
4074      }
4075
4076    ec->ignored = ignored;
4077
4078    if (ec->is_cursor && ec->visible)
4079      {
4080         /* ignore cursor changes during resize/move I guess */
4081         if (!e_client_action_get())
4082           {
4083              if (e_comp->pointer)
4084                {
4085                   x = e_comp->pointer->hot.x;
4086                   y = e_comp->pointer->hot.y;
4087                }
4088              e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
4089           }
4090      }
4091    return EINA_TRUE;
4092 }
4093
4094 static E_Comp_Wl_Output *
4095 _e_comp_wl_output_get(Eina_List *outputs, const char *id)
4096 {
4097    Eina_List *l;
4098    E_Comp_Wl_Output *output;
4099
4100    EINA_LIST_FOREACH(outputs, l, output)
4101      {
4102        if (!strcmp(output->id, id))
4103          return output;
4104      }
4105
4106    return NULL;
4107 }
4108
4109 /**
4110  * Initializes information about one display output.
4111  *
4112  * Adds or updates the given data about a single display output,
4113  * with an id matching the provided id.
4114  *
4115  * @param id         identification of output to be added or changed
4116  * @param make       manufacturer name of the display output
4117  * @param model      model name of the display output
4118  * @param x          output's top left corner x coordinate
4119  * @param y          output's top left corner y coordinate
4120  * @param w          output's width in pixels
4121  * @param h          output's height in pixels
4122  * @param pw         output's physical width in millimeters
4123  * @param ph         output's physical height in millimeters
4124  * @param refresh    output's refresh rate in mHz
4125  * @param subpixel   output's subpixel layout
4126  * @param transform  output's rotation and/or mirror transformation
4127  *
4128  * @returns True if a display output object could be added or updated
4129  */
4130 EINTERN Eina_Bool
4131 e_comp_wl_output_init(const char *id, const char *make, const char *model,
4132                       int x, int y, int w, int h, int pw, int ph,
4133                       unsigned int refresh, unsigned int subpixel,
4134                       unsigned int transform)
4135 {
4136    E_Comp_Wl_Output *output;
4137    Eina_List *l2;
4138    struct wl_resource *resource;
4139
4140    /* retrieve named output; or create it if it doesn't exist */
4141    output = _e_comp_wl_output_get(e_comp_wl->outputs, id);
4142    if (!output)
4143      {
4144         if (!(output = E_NEW(E_Comp_Wl_Output, 1))) return EINA_FALSE;
4145
4146         if (id) output->id = eina_stringshare_add(id);
4147         if (make)
4148           output->make = eina_stringshare_add(make);
4149         else
4150           output->make = eina_stringshare_add("unknown");
4151         if (model)
4152           output->model = eina_stringshare_add(model);
4153         else
4154           output->model = eina_stringshare_add("unknown");
4155
4156         e_comp_wl->outputs = eina_list_append(e_comp_wl->outputs, output);
4157
4158         output->global =
4159           wl_global_create(e_comp_wl->wl.disp, &wl_output_interface,
4160                            2, output, _e_comp_wl_cb_output_bind);
4161
4162         output->resources = NULL;
4163         output->scale = e_scale;
4164      }
4165
4166    /* update the output details */
4167    output->x = x;
4168    output->y = y;
4169    output->w = w;
4170    output->h = h;
4171    output->phys_width = pw;
4172    output->phys_height = ph;
4173    output->refresh = refresh;
4174    output->subpixel = subpixel;
4175    output->transform = transform;
4176
4177    if (output->scale <= 0)
4178      output->scale = e_scale;
4179
4180    /* if we have bound resources, send updates */
4181    EINA_LIST_FOREACH(output->resources, l2, resource)
4182      {
4183         wl_output_send_geometry(resource,
4184                                 output->x, output->y,
4185                                 output->phys_width,
4186                                 output->phys_height,
4187                                 output->subpixel,
4188                                 output->make ?: "", output->model ?: "",
4189                                 output->transform);
4190
4191         if (wl_resource_get_version(resource) >= WL_OUTPUT_SCALE_SINCE_VERSION)
4192           wl_output_send_scale(resource, output->scale);
4193
4194         wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
4195                             output->w, output->h, output->refresh);
4196
4197         if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
4198           wl_output_send_done(resource);
4199      }
4200
4201    return EINA_TRUE;
4202 }
4203
4204 EINTERN void
4205 e_comp_wl_output_remove(const char *id)
4206 {
4207    E_Comp_Wl_Output *output;
4208
4209    output = _e_comp_wl_output_get(e_comp_wl->outputs, id);
4210    if (output)
4211      {
4212         e_comp_wl->outputs = eina_list_remove(e_comp_wl->outputs, output);
4213
4214         /* wl_global_destroy(output->global); */
4215
4216         /* eina_stringshare_del(output->id); */
4217         /* eina_stringshare_del(output->make); */
4218         /* eina_stringshare_del(output->model); */
4219
4220         /* free(output); */
4221      }
4222 }
4223
4224 static void
4225 _e_comp_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, enum wl_keyboard_key_state state, Eina_List *key_list, E_Client *ec)
4226 {
4227    struct wl_resource *res;
4228    Eina_List *l;
4229    uint32_t serial, keycode;
4230    struct wl_client *wc = NULL;
4231    E_Comp_Config *comp_conf = NULL;
4232    const char *device_name = NULL;
4233
4234    keycode = (ev->keycode - 8);
4235
4236    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4237
4238    comp_conf = e_comp_config_get();
4239
4240    if (ec && ec->comp_data)
4241      {
4242         struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4243
4244         if (surface)
4245           wc = wl_resource_get_client(surface);
4246      }
4247
4248    if (e_config->key_input_ttrace_enable)
4249      {
4250         TRACE_INPUT_BEGIN(wl_keyboard_send_key:%s:%s, (state ? "PRESS" : "RELEASE"), ev->keyname);
4251         ELOGF("INPUT", "wl_keyboard_send_key:%s:%s|B|", NULL, (state ? "PRESS" : "RELEASE"), ev->keyname);
4252      }
4253
4254    EINA_LIST_FOREACH(key_list, l, res)
4255      {
4256         if (wl_resource_get_client(res) != wc) continue;
4257
4258         TRACE_INPUT_BEGIN(_e_comp_wl_key_send);
4259         if (!e_input_thread_mode_get())
4260           {
4261              _e_comp_wl_send_event_device(wc, ev->timestamp, ev->dev, serial);
4262              device_name = ecore_device_name_get(ev->dev);
4263           }
4264         else
4265           {
4266              if (dev)
4267                {
4268                   _e_comp_wl_send_event_e_device(wc, ev->timestamp, dev, serial);
4269                   device_name = e_device_name_get(dev);
4270                }
4271           }
4272
4273         if (comp_conf && comp_conf->input_log_enable)
4274           ELOGF("Key", "Send Key %s (time: %d, device: %s)", ec, (state ? "Down" : "Up"), ev->timestamp, device_name);
4275
4276         wl_keyboard_send_key(res, serial, ev->timestamp,
4277                              keycode, state);
4278         TRACE_INPUT_END();
4279      }
4280
4281    if (e_config->key_input_ttrace_enable)
4282      {
4283         TRACE_INPUT_END();
4284         ELOGF("INPUT", "wl_keyboard_send_key|E|", NULL);
4285      }
4286 }
4287
4288 EINTERN Eina_Bool
4289 e_comp_wl_key_down(Ecore_Event_Key *ev, E_Device *dev)
4290 {
4291    E_Client *ec = NULL;
4292    uint32_t keycode;
4293    E_Comp_Wl_Key_Data *end, *k;
4294
4295    if (ev->window != e_comp->ee_win)
4296      {
4297         return EINA_FALSE;
4298      }
4299
4300    keycode = (ev->keycode - 8);
4301    if (!(e_comp_wl = e_comp->wl_comp_data))
4302      {
4303         return EINA_FALSE;
4304      }
4305
4306 #ifndef E_RELEASE_BUILD
4307    if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
4308        ((ev->modifiers & ECORE_EVENT_MODIFIER_ALT) ||
4309        (ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) &&
4310        eina_streq(ev->key, "BackSpace"))
4311      {
4312         exit(0);
4313      }
4314 #endif
4315
4316    end = (E_Comp_Wl_Key_Data *)e_comp_input_key->kbd.keys.data + (e_comp_input_key->kbd.keys.size / sizeof(*k));
4317
4318    for (k = e_comp_input_key->kbd.keys.data; k < end; k++)
4319      {
4320         /* ignore server-generated key repeats */
4321         if (k->key == keycode)
4322           {
4323              return EINA_FALSE;
4324           }
4325      }
4326
4327    if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
4328      {
4329         ec = e_client_focused_get();
4330         struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4331         if (ec && ec->comp_data && surface)
4332           {
4333              if (e_comp_input_key->kbd.focused)
4334                {
4335                   _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_input_key->kbd.focused, ec);
4336
4337                   /* A key only sent to clients is added to the list */
4338                   e_comp_input_key->kbd.keys.size = (const char *)end - (const char *)e_comp_input_key->kbd.keys.data;
4339
4340                   if (!(k = wl_array_add(&e_comp_input_key->kbd.keys, sizeof(*k))))
4341                     {
4342                        DBG("wl_array_add: Out of memory\n");
4343                        return EINA_FALSE;
4344                     }
4345                   k->key = keycode;
4346                   k->dev = ev->dev;
4347                }
4348           }
4349      }
4350
4351    /* update modifier state */
4352    e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
4353
4354    return !!ec;
4355 }
4356
4357 EINTERN Eina_Bool
4358 e_comp_wl_key_up(Ecore_Event_Key *ev, E_Device *dev)
4359 {
4360    E_Client *ec = NULL;
4361    uint32_t keycode, delivered_key;
4362    E_Comp_Wl_Key_Data *end, *k;
4363
4364    if (ev->window != e_comp->ee_win)
4365      {
4366         return EINA_FALSE;
4367      }
4368
4369    keycode = (ev->keycode - 8);
4370    delivered_key = 0;
4371    if (!(e_comp_wl = e_comp->wl_comp_data))
4372      {
4373         return EINA_FALSE;
4374      }
4375
4376    end = (E_Comp_Wl_Key_Data *)e_comp_input_key->kbd.keys.data + (e_comp_input_key->kbd.keys.size / sizeof(*k));
4377    for (k = e_comp_input_key->kbd.keys.data; k < end; k++)
4378      {
4379         if (k->key == keycode)
4380           {
4381              *k = *--end;
4382              delivered_key = 1;
4383           }
4384      }
4385
4386    e_comp_input_key->kbd.keys.size =
4387      (const char *)end - (const char *)e_comp_input_key->kbd.keys.data;
4388
4389    /* If a key down event have been sent to clients, send a key up event to client for garantee key event sequence pair. (down/up) */
4390    if ((delivered_key) ||
4391        ((!e_client_action_get()) && (!e_comp->input_key_grabs)))
4392      {
4393         ec = e_client_focused_get();
4394
4395         if (e_comp_input_key->kbd.focused)
4396           {
4397              _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_input_key->kbd.focused, ec);
4398           }
4399      }
4400
4401    /* update modifier state */
4402    e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE);
4403
4404    return !!ec;
4405 }
4406
4407 EINTERN Eina_Bool
4408 e_comp_wl_key_process(Ecore_Event_Key *ev, E_Device *dev, int type)
4409 {
4410    Eina_Bool res = EINA_FALSE;
4411
4412    if (type == ECORE_EVENT_KEY_DOWN)
4413      {
4414         res = e_comp_wl_key_down(ev, dev);
4415      }
4416    else if (type == ECORE_EVENT_KEY_UP)
4417      {
4418         res = e_comp_wl_key_up(ev, dev);
4419      }
4420
4421    return res;
4422 }
4423
4424 EINTERN Eina_Bool
4425 e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t button_id, uint32_t state)
4426 {
4427    Eina_List *l;
4428    struct wl_client *wc;
4429    uint32_t serial, btn;
4430    struct wl_resource *res;
4431    E_Comp_Config *comp_conf = NULL;
4432
4433    if (ec->cur_mouse_action || e_comp_wl->drag)
4434      return EINA_FALSE;
4435    if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
4436    if ((ec->ignored) && (!ec->remote_surface.provider)) return EINA_FALSE;
4437
4438    switch (button_id)
4439      {
4440       case 1:  btn = BTN_LEFT;   break;
4441       case 2:  btn = BTN_MIDDLE; break;
4442       case 3:  btn = BTN_RIGHT;  break;
4443       default: btn = button_id;  break;
4444      }
4445
4446    e_comp_wl->ptr.button = btn;
4447    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4448    if (!surface) return EINA_FALSE;
4449
4450    if (!eina_list_count(e_comp_wl->ptr.resources))
4451      return EINA_TRUE;
4452
4453    wc = wl_resource_get_client(surface);
4454    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4455
4456    comp_conf = e_comp_config_get();
4457
4458    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
4459      {
4460         if (wl_resource_get_client(res) != wc) continue;
4461         if (!e_comp_wl_input_pointer_check(res)) continue;
4462         TRACE_INPUT_BEGIN(e_comp_wl_evas_handle_mouse_button);
4463
4464         if (comp_conf && comp_conf->input_log_enable)
4465           ELOGF("Mouse", "Button %s (btn: %d, time: %d)", ec, (state ? "Down" : "Up"), btn, timestamp);
4466
4467         wl_pointer_send_button(res, serial, timestamp, btn, state);
4468         TRACE_INPUT_END();
4469      }
4470    return EINA_TRUE;
4471 }
4472
4473 E_API void
4474 e_comp_wl_touch_cancel(void)
4475 {
4476    _e_comp_wl_touch_cancel();
4477 }
4478
4479 E_API E_Comp_Wl_Hook *
4480 e_comp_wl_hook_add(E_Comp_Wl_Hook_Point hookpoint, E_Comp_Wl_Hook_Cb func, const void *data)
4481 {
4482    E_Comp_Wl_Hook *ch;
4483
4484    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_WL_HOOK_LAST, NULL);
4485    ch = E_NEW(E_Comp_Wl_Hook, 1);
4486    if (!ch) return NULL;
4487    ch->hookpoint = hookpoint;
4488    ch->func = func;
4489    ch->data = (void*)data;
4490    _e_comp_wl_hooks[hookpoint] = eina_inlist_append(_e_comp_wl_hooks[hookpoint], EINA_INLIST_GET(ch));
4491    return ch;
4492 }
4493
4494 E_API void
4495 e_comp_wl_hook_del(E_Comp_Wl_Hook *ch)
4496 {
4497    ch->delete_me = 1;
4498    if (_e_comp_wl_hooks_walking == 0)
4499      {
4500         _e_comp_wl_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_wl_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
4501         free(ch);
4502      }
4503    else
4504      _e_comp_wl_hooks_delete++;
4505 }
4506
4507 E_API E_Comp_Wl_Pid_Hook *
4508 e_comp_wl_pid_hook_add(E_Comp_Wl_Pid_Hook_Point hookpoint, E_Comp_Wl_Pid_Hook_Cb func, const void *data)
4509 {
4510    E_Comp_Wl_Pid_Hook *ch;
4511
4512    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_WL_PID_HOOK_LAST, NULL);
4513
4514    ch = E_NEW(E_Comp_Wl_Pid_Hook, 1);
4515    EINA_SAFETY_ON_NULL_RETURN_VAL(ch, NULL);
4516
4517    ch->hookpoint = hookpoint;
4518    ch->func = func;
4519    ch->data = (void*)data;
4520    _e_comp_wl_pid_hooks[hookpoint] = eina_inlist_append(_e_comp_wl_pid_hooks[hookpoint], EINA_INLIST_GET(ch));
4521
4522    return ch;
4523 }
4524
4525 E_API void
4526 e_comp_wl_pid_hook_del(E_Comp_Wl_Pid_Hook *ch)
4527 {
4528    ch->delete_me = 1;
4529    if (_e_comp_wl_pid_hooks_walking == 0)
4530      {
4531         _e_comp_wl_pid_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_wl_pid_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
4532         free(ch);
4533      }
4534    else
4535      _e_comp_wl_pid_hooks_delete++;
4536 }
4537
4538 E_API E_Comp_Wl_Intercept_Hook *
4539 e_comp_wl_intercept_hook_add(E_Comp_Wl_Intercept_Hook_Point hookpoint, E_Comp_Wl_Intercept_Hook_Cb func, const void *data)
4540 {
4541    E_Comp_Wl_Intercept_Hook *ch;
4542
4543    EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_WL_INTERCEPT_HOOK_LAST, NULL);
4544    ch = E_NEW(E_Comp_Wl_Intercept_Hook, 1);
4545    if (!ch) return NULL;
4546    ch->hookpoint = hookpoint;
4547    ch->func = func;
4548    ch->data = (void*)data;
4549    _e_comp_wl_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_wl_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
4550    return ch;
4551 }
4552
4553 E_API void
4554 e_comp_wl_intercept_hook_del(E_Comp_Wl_Intercept_Hook *ch)
4555 {
4556    ch->delete_me = 1;
4557    if (_e_comp_wl_intercept_hooks_walking == 0)
4558      {
4559         _e_comp_wl_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_wl_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
4560         free(ch);
4561      }
4562    else
4563      _e_comp_wl_intercept_hooks_delete++;
4564 }
4565
4566 EINTERN void
4567 e_comp_wl_shell_surface_ready(E_Client *ec)
4568 {
4569    if (!ec) return;
4570
4571    _e_comp_wl_hook_call(E_COMP_WL_HOOK_SHELL_SURFACE_READY, ec);
4572 }
4573
4574 E_API void
4575 e_comp_wl_input_cursor_timer_enable_set(Eina_Bool enabled)
4576 {
4577    e_config->use_cursor_timer = !!enabled;
4578
4579    if (e_config->use_cursor_timer)
4580      {
4581         if (!e_pointer_is_hidden(e_comp->pointer))
4582           {
4583              _e_comp_wl_cursor_move_timer_control(e_comp_wl->ptr.ec);
4584           }
4585      }
4586    else
4587      {
4588         if (e_comp_wl->ptr.hide_tmr)
4589           {
4590              ecore_timer_del(e_comp_wl->ptr.hide_tmr);
4591              e_comp_wl->ptr.hide_tmr = NULL;
4592           }
4593         cursor_timer_ec = NULL;
4594
4595         if (e_comp_wl->ptr.ec && e_comp_wl->ptr.ec->has_cursor_unset)
4596           return;
4597
4598         if (e_pointer_is_hidden(e_comp->pointer))
4599           {
4600              _e_comp_wl_cursor_reload(e_comp_wl->ptr.ec);
4601           }
4602      }
4603 }
4604
4605 EINTERN void
4606 e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Device *dev, uint32_t serial)
4607 {
4608    EINA_SAFETY_ON_NULL_RETURN(wc);
4609    EINA_SAFETY_ON_NULL_RETURN(dev);
4610
4611    _e_comp_wl_send_event_device(wc, timestamp, dev, serial);
4612 }
4613
4614 EINTERN void
4615 e_comp_wl_send_event_e_device(struct wl_client *wc, uint32_t timestamp, E_Device *dev, uint32_t serial)
4616 {
4617    EINA_SAFETY_ON_NULL_RETURN(wc);
4618    EINA_SAFETY_ON_NULL_RETURN(dev);
4619
4620    _e_comp_wl_send_event_e_device(wc, timestamp, dev, serial);
4621 }
4622
4623 EINTERN Eina_Bool
4624 e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, void *dev, uint32_t time)
4625 {
4626    struct wl_resource *res;
4627    struct wl_client *wc;
4628    Eina_List *l;
4629    uint32_t serial, wl_keycode;
4630    enum wl_keyboard_key_state state;
4631    E_Comp_Config *comp_conf = NULL;
4632    const char *dev_name = NULL;
4633
4634    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4635    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4636    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4637
4638    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4639    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4640
4641    wl_keycode = keycode - 8;
4642    EINA_SAFETY_ON_TRUE_RETURN_VAL(wl_keycode <= 0, EINA_FALSE);
4643
4644    wc = wl_resource_get_client(surface);
4645    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4646    if (!time) time = e_util_timestamp_get();
4647    if (pressed) state = WL_KEYBOARD_KEY_STATE_PRESSED;
4648    else state = WL_KEYBOARD_KEY_STATE_RELEASED;
4649
4650    comp_conf = e_comp_config_get();
4651    e_keyrouter_event_surface_send(ec, keycode);
4652
4653    if (e_config->key_input_ttrace_enable)
4654      {
4655         TRACE_INPUT_BEGIN(wl_keyboard_send_key:%s:%d, (state ? "PRESS" : "RELEASE"), keycode);
4656         ELOGF("INPUT", "wl_keyboard_send_key:%s:%d|B|", NULL, (state ? "PRESS" : "RELEASE"), keycode);
4657      }
4658
4659    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
4660      {
4661         if (wl_resource_get_client(res) != wc) continue;
4662         if (!e_input_thread_mode_get())
4663           {
4664              if (dev)
4665                {
4666                   _e_comp_wl_send_event_device(wc, time, (Ecore_Device *)dev, serial);
4667                   dev_name = ecore_device_name_get((Ecore_Device *)dev);
4668                }
4669              else
4670                {
4671                   _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_KEYBOARD, time);
4672                }
4673           }
4674         else
4675           {
4676              if (dev)
4677                {
4678                   e_comp_wl_send_event_e_device(wc, time, (E_Device *)dev, serial);
4679                   dev_name = e_device_name_get(dev);
4680                }
4681           }
4682
4683         if (comp_conf && comp_conf->input_log_enable)
4684           ELOGF("Key", "Send Key %s (keycode: %d, time: %d, device: %s)", ec, (state ? "Down" : "Up"), wl_keycode, time,
4685                 dev_name);
4686
4687         wl_keyboard_send_key(res, serial, time,
4688                              wl_keycode, state);
4689      }
4690
4691    if (e_config->key_input_ttrace_enable)
4692      {
4693         TRACE_INPUT_END();
4694         ELOGF("INPUT", "wl_keyboard_send_key|E|", NULL);
4695      }
4696
4697    return EINA_TRUE;
4698 }
4699
4700 EINTERN Eina_Bool
4701 e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time)
4702 {
4703    struct wl_resource *res;
4704    struct wl_client *wc;
4705    Eina_List *l;
4706    uint32_t serial, wl_keycode, cancel_keycode;
4707    E_Comp_Config *comp_conf = NULL;
4708    struct xkb_keymap *keymap = NULL;
4709
4710    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4711    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4712    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4713
4714    keymap = e_comp_input_key->xkb.keymap;
4715    EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, EINA_FALSE);
4716
4717    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4718    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4719
4720    cancel_keycode = e_comp_wl_input_keymap_keyname_to_keycode("Cancel");
4721    if (cancel_keycode == XKB_KEYCODE_INVALID)
4722      {
4723         ELOGF("Key", "Failed to send key cancel for %d key, Cancel key is not supported\n", ec, keycode);
4724         return EINA_FALSE;
4725      }
4726
4727    EINA_SAFETY_ON_TRUE_RETURN_VAL(cancel_keycode < 8, EINA_FALSE);
4728
4729    cancel_keycode = cancel_keycode - 8;
4730
4731    wl_keycode = keycode - 8;
4732    EINA_SAFETY_ON_TRUE_RETURN_VAL(wl_keycode <= 0, EINA_FALSE);
4733
4734    wc = wl_resource_get_client(surface);
4735    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4736    if (!time) time = e_util_timestamp_get();
4737
4738    comp_conf = e_comp_config_get();
4739    e_keyrouter_event_surface_send(ec, keycode);
4740
4741    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
4742      {
4743         if (wl_resource_get_client(res) != wc) continue;
4744         if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
4745         else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_KEYBOARD, time);
4746
4747         if (comp_conf && comp_conf->input_log_enable)
4748           ELOGF("Key", "Send Key Cancel (time: %d)", ec, time);
4749         wl_keyboard_send_key(res, serial, time,
4750                              cancel_keycode, WL_KEYBOARD_KEY_STATE_PRESSED);
4751         wl_keyboard_send_key(res, serial, time,
4752                              wl_keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
4753         wl_keyboard_send_key(res, serial, time,
4754                              cancel_keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
4755      }
4756
4757    return EINA_TRUE;
4758 }
4759
4760
4761 EINTERN Eina_Bool
4762 e_comp_wl_touch_send(E_Client *ec, int idx, int x, int y, Eina_Bool pressed, Ecore_Device *dev, double radius_x, double radius_y, double pressure, double angle, uint32_t time)
4763 {
4764    struct wl_client *wc;
4765    uint32_t serial;
4766    E_Devicemgr_Input_Device *device = NULL;
4767
4768    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4769    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4770    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4771
4772    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4773    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4774
4775    if (!dev) device = _e_comp_wl_device_last_device_get(ECORE_DEVICE_CLASS_TOUCH);
4776
4777    wc = wl_resource_get_client(surface);
4778    if (!time) time = e_util_timestamp_get();
4779    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4780
4781    if (dev)
4782      {
4783         _e_comp_wl_send_event_device(wc, time, dev, serial);
4784         _e_comp_wl_device_handle_axes(ecore_device_identifier_get(dev), ECORE_DEVICE_CLASS_TOUCH, ec, idx, radius_x, radius_y, pressure, angle);
4785      }
4786    else if (device)
4787      {
4788         _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_TOUCH, time);
4789         _e_comp_wl_device_handle_axes(device->identifier, device->clas, ec, idx, radius_x, radius_y, pressure, angle);
4790      }
4791
4792    x = x + ec->client.x;
4793    y = y + ec->client.y;
4794
4795    _e_comp_wl_send_touch(ec, idx, x, y, time, pressed);
4796
4797    return EINA_TRUE;
4798 }
4799
4800 EINTERN Eina_Bool
4801 e_comp_wl_touch_update_send(E_Client *ec, int idx, int x, int y, Ecore_Device *dev, double radius_x, double radius_y, double pressure, double angle, uint32_t time)
4802 {
4803    E_Devicemgr_Input_Device *device;
4804    uint32_t serial;
4805    struct wl_client *wc;
4806
4807    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4808    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4809    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4810
4811    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4812    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4813
4814    if (!dev) device = _e_comp_wl_device_last_device_get(ECORE_DEVICE_CLASS_TOUCH);
4815
4816    wc = wl_resource_get_client(surface);
4817    if (!time) time = e_util_timestamp_get();
4818    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4819
4820    if (dev)
4821      {
4822         _e_comp_wl_send_event_device(wc, time, dev, serial);
4823         _e_comp_wl_device_handle_axes(ecore_device_identifier_get(dev), ECORE_DEVICE_CLASS_TOUCH, ec, idx, radius_x, radius_y, pressure, angle);
4824      }
4825    else if (device)
4826      {
4827         _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_TOUCH, time);
4828         _e_comp_wl_device_handle_axes(device->identifier, device->clas, ec, idx, radius_x, radius_y, pressure, angle);
4829      }
4830
4831    x = x + ec->client.x;
4832    y = y + ec->client.y;
4833
4834    _e_comp_wl_send_touch_move(ec, idx, x, y, time);
4835
4836    return EINA_TRUE;
4837 }
4838
4839 EINTERN Eina_Bool
4840 e_comp_wl_touch_cancel_send(E_Client *ec)
4841 {
4842    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4843    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4844    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4845
4846    _e_comp_wl_send_touch_cancel(ec);
4847
4848    return EINA_TRUE;
4849 }
4850
4851 EINTERN Eina_Bool
4852 e_comp_wl_mouse_button_send(E_Client *ec, int buttons, Eina_Bool pressed, Ecore_Device *dev, uint32_t time)
4853 {
4854    uint32_t serial;
4855    struct wl_client *wc;
4856
4857    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4858    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4859    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4860
4861    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4862    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4863
4864    wc = wl_resource_get_client(surface);
4865    if (!time) time = e_util_timestamp_get();
4866    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4867
4868    if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
4869    else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
4870
4871    if (pressed)
4872      e_comp_wl_evas_handle_mouse_button(ec, time, buttons,
4873                                           WL_POINTER_BUTTON_STATE_PRESSED);
4874    else
4875      e_comp_wl_evas_handle_mouse_button(ec, time, buttons,
4876                                           WL_POINTER_BUTTON_STATE_RELEASED);
4877
4878    return EINA_TRUE;
4879 }
4880
4881 EINTERN Eina_Bool
4882 e_comp_wl_mouse_move_send(E_Client *ec, int x, int y, Ecore_Device *dev, uint32_t time)
4883 {
4884    uint32_t serial;
4885    struct wl_client *wc;
4886
4887    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4888    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4889    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4890
4891    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4892    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4893
4894    wc = wl_resource_get_client(surface);
4895    if (!time) time = e_util_timestamp_get();
4896    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4897
4898    if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
4899    else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
4900
4901    x = x + ec->client.x;
4902    y = y + ec->client.y;
4903
4904    _e_comp_wl_send_mouse_move(ec, x, y, time);
4905
4906    return EINA_TRUE;
4907 }
4908
4909 EINTERN Eina_Bool
4910 e_comp_wl_mouse_wheel_send(E_Client *ec, int direction, int z, Ecore_Device *dev, uint32_t time)
4911 {
4912    uint32_t serial;
4913    struct wl_client *wc;
4914
4915    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4916    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4917    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4918
4919    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4920    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4921
4922    wc = wl_resource_get_client(surface);
4923    if (!time) time = e_util_timestamp_get();
4924    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4925
4926    if (_e_comp_wl_check_cursor_timer_needed(ec))
4927       {
4928          if (!_e_comp_wl_cursor_timer_control(EVAS_CALLBACK_MOUSE_WHEEL, ec))
4929            return EINA_TRUE;
4930       }
4931
4932    if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
4933    else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
4934
4935    _e_comp_wl_mouse_wheel_send(ec, direction, z, time);
4936
4937    if (!need_send_released) // set cursor's hide_tmr only when mouse button is not pressed
4938      {
4939         if (_e_comp_wl_check_cursor_timer_needed(ec))
4940           _e_comp_wl_cursor_move_timer_control(ec);
4941      }
4942
4943    return EINA_TRUE;
4944 }
4945
4946 EINTERN Eina_Bool
4947 e_comp_wl_mouse_in_send(E_Client *ec, int x, int y, Ecore_Device *dev, uint32_t time)
4948 {
4949    uint32_t serial;
4950    struct wl_client *wc;
4951    struct wl_resource *res;
4952    Eina_List *l;
4953
4954    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4955    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4956
4957    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4958    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4959
4960    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4961    EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
4962
4963    if (!eina_list_count(e_comp_wl->ptr.resources)) return EINA_FALSE;
4964    wc = wl_resource_get_client(surface);
4965    serial = wl_display_next_serial(e_comp_wl->wl.disp);
4966    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
4967      {
4968         if (!e_comp_wl_input_pointer_check(res)) continue;
4969         if (wl_resource_get_client(res) != wc) continue;
4970
4971         if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
4972         else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
4973
4974         wl_pointer_send_enter(res, serial, surface,
4975                               wl_fixed_from_int(x),
4976                               wl_fixed_from_int(y));
4977         ec->pointer_enter_sent = EINA_TRUE;
4978      }
4979    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mousein_signal, ec);
4980
4981    return EINA_TRUE;
4982 }
4983
4984 EINTERN Eina_Bool
4985 e_comp_wl_mouse_out_send(E_Client *ec, Ecore_Device *dev, uint32_t time)
4986 {
4987    uint32_t serial;
4988    struct wl_client *wc;
4989    struct wl_resource *res;
4990    Eina_List *l;
4991
4992    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
4993    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
4994    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
4995    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
4996    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
4997    EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
4998
4999    if (!eina_list_count(e_comp_wl->ptr.resources)) return EINA_FALSE;
5000    wc = wl_resource_get_client(surface);
5001    serial = wl_display_next_serial(e_comp_wl->wl.disp);
5002    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
5003      {
5004         if (!e_comp_wl_input_pointer_check(res)) continue;
5005         if (wl_resource_get_client(res) != wc) continue;
5006
5007         if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
5008         else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
5009
5010         wl_pointer_send_leave(res, serial, surface);
5011         ec->pointer_enter_sent = EINA_FALSE;
5012      }
5013    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mouseout_signal, ec);
5014
5015    return EINA_TRUE;
5016 }
5017
5018 EINTERN void
5019 e_comp_wl_mouse_in_renew(E_Client *ec, int buttons, int x, int y, void *data, Evas_Modifier *modifiers, Evas_Lock *locks, unsigned int timestamp, Evas_Event_Flags event_flags, Evas_Device *dev, Evas_Object *event_src)
5020 {
5021    Evas_Event_Mouse_In ev_in;
5022
5023    if (!ec) return;
5024    if (ec->pointer_enter_sent) return;
5025
5026    ev_in.buttons = buttons;
5027
5028    ev_in.output.x = x;
5029    ev_in.output.y = y;
5030    ev_in.canvas.x = x;
5031    ev_in.canvas.y = y;
5032
5033    ev_in.data = data;
5034    ev_in.modifiers = modifiers;
5035    ev_in.locks = locks;
5036    ev_in.timestamp = timestamp;
5037    ev_in.event_flags = event_flags;
5038
5039    ev_in.dev = dev;
5040    ev_in.event_src = event_src;
5041
5042    _e_comp_wl_evas_cb_mouse_in((void *)ec, NULL, NULL, &ev_in);
5043 }
5044
5045 EINTERN void
5046 e_comp_wl_mouse_out_renew(E_Client *ec, int buttons, int x, int y, void *data, Evas_Modifier *modifiers, Evas_Lock *locks, unsigned int timestamp, Evas_Event_Flags event_flags, Evas_Device *dev, Evas_Object *event_src)
5047 {
5048    Evas_Event_Mouse_Out ev_out;
5049
5050    if (!ec) return;
5051    if (!ec->pointer_enter_sent) return;
5052
5053    ev_out.buttons = buttons;
5054
5055    ev_out.output.x = x;
5056    ev_out.output.y = y;
5057    ev_out.canvas.x = x;
5058    ev_out.canvas.y = y;
5059
5060    ev_out.data = data;
5061    ev_out.modifiers = modifiers;
5062    ev_out.locks = locks;
5063    ev_out.timestamp = timestamp;
5064    ev_out.event_flags = event_flags;
5065
5066    ev_out.dev = dev;
5067    ev_out.event_src = event_src;
5068
5069    _e_comp_wl_evas_cb_mouse_out((void *)ec, NULL, NULL, &ev_out);
5070 }
5071
5072 EINTERN Eina_Bool
5073 e_comp_wl_cursor_hide(E_Client *ec)
5074 {
5075    struct wl_resource *res;
5076    struct wl_client *wc;
5077    Eina_List *l;
5078    uint32_t serial;
5079
5080    e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
5081
5082    if (e_comp_wl->ptr.hide_tmr)
5083      {
5084         ecore_timer_del(e_comp_wl->ptr.hide_tmr);
5085         e_comp_wl->ptr.hide_tmr = NULL;
5086      }
5087    cursor_timer_ec = NULL;
5088
5089    if (!ec) return EINA_FALSE;
5090    if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
5091    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
5092    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
5093
5094    wc = wl_resource_get_client(surface);
5095    serial = wl_display_next_serial(e_comp_wl->wl.disp);
5096    EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
5097      {
5098         if (!e_comp_wl_input_pointer_check(res)) continue;
5099         if (wl_resource_get_client(res) != wc) continue;
5100         if (ec->pointer_enter_sent == EINA_FALSE) continue;
5101         wl_pointer_send_leave(res, serial, surface);
5102         ec->pointer_enter_sent = EINA_FALSE;
5103      }
5104
5105    return EINA_TRUE;
5106 }
5107
5108 /* surface to buffer
5109  *   - width    : surface width
5110  *   - height   : surface height
5111  *   - transform: buffer transform
5112  *   - scale    : buffer scale
5113  * screen to output
5114  *   - width    : screen width
5115  *   - height   : screen height
5116  *   - transform: output transform
5117  *   - scale    : output scale
5118  */
5119 static E_Util_Transform_Matrix
5120 _e_comp_wl_buffer_coord_get(int width, int height, int transform, int scale)
5121 {
5122    E_Util_Transform_Matrix m;
5123
5124    e_util_transform_matrix_load_identity(&m);
5125
5126    if (transform & 0x4)
5127      {
5128         e_util_transform_matrix_translate(&m, -((double)width / 2), 0, 0);
5129         e_util_transform_matrix_flip_x(&m);
5130         e_util_transform_matrix_translate(&m, (double)width / 2, 0, 0);
5131      }
5132
5133    switch (transform & 0x3)
5134      {
5135       case WL_OUTPUT_TRANSFORM_90:
5136         e_util_transform_matrix_translate(&m, -width, 0, 0);
5137         e_util_transform_matrix_rotation_z(&m, 270);
5138         break;
5139       case WL_OUTPUT_TRANSFORM_180:
5140         e_util_transform_matrix_translate(&m, -width, -height, 0);
5141         e_util_transform_matrix_rotation_z(&m, 180);
5142         break;
5143       case WL_OUTPUT_TRANSFORM_270:
5144         e_util_transform_matrix_translate(&m, 0, -height, 0);
5145         e_util_transform_matrix_rotation_z(&m, 90);
5146         break;
5147       default:
5148         break;
5149      }
5150
5151    e_util_transform_matrix_scale(&m, scale, scale, 1);
5152
5153    return m;
5154 }
5155
5156 /* surface to buffer
5157  *   - surface width, surface height, buffer transform, buffer scale
5158  * screen to output
5159  *   - screen width, screen height, output transform, output scale
5160  */
5161 EINTERN void
5162 e_comp_wl_pos_convert(int width, int height, int transform, int scale, int sx, int sy, int *bx, int *by)
5163 {
5164    E_Util_Transform_Matrix m;
5165    E_Util_Transform_Vertex v;
5166
5167    m = _e_comp_wl_buffer_coord_get(width, height, transform, scale);
5168
5169    e_util_transform_vertex_init(&v, sx, sy, 0.0, 1.0);
5170    v = e_util_transform_matrix_multiply_vertex(&m, &v);
5171    e_util_transform_vertex_pos_round_get(&v, bx, by, NULL, NULL);
5172 }
5173
5174 /* buffer to screen
5175  *   - buffer width, buffer height, buffer transform, buffer scale
5176  */
5177 EINTERN void
5178 e_comp_wl_pos_convert_inverse(int width, int height, int transform, int scale, int bx, int by, int *sx, int *sy)
5179 {
5180    E_Util_Transform_Matrix m;
5181    E_Util_Transform_Vertex v;
5182    int tw, th;
5183
5184    if (transform != 0 || scale > 1)
5185      {
5186         tw = ((transform % 2) ? height : width) / scale;
5187         th = ((transform % 2) ? width : height) / scale;
5188      }
5189    else
5190      {
5191         tw = width;
5192         th = height;
5193      }
5194
5195    m = _e_comp_wl_buffer_coord_get(tw, th, transform, scale);
5196    m = e_util_transform_matrix_inverse_get(&m);
5197
5198    e_util_transform_vertex_init(&v, bx, by, 0.0, 1.0);
5199    v = e_util_transform_matrix_multiply_vertex(&m, &v);
5200    e_util_transform_vertex_pos_round_get(&v, sx, sy, NULL, NULL);
5201 }
5202
5203 /* surface to buffer
5204  *   - surface width, surface height, buffer transform, buffer scale
5205  * screen to output
5206  *   - screen width, screen height, output transform, output scale
5207  */
5208 EINTERN void
5209 e_comp_wl_rect_convert(int width, int height, int transform, int scale,
5210                        int sx, int sy, int sw, int sh, int *bx, int *by, int *bw, int *bh)
5211 {
5212    E_Util_Transform_Matrix m;
5213    E_Util_Transform_Rect sr = {sx, sy, sw, sh};
5214    E_Util_Transform_Rect_Vertex sv;
5215
5216    m = _e_comp_wl_buffer_coord_get(width, height, transform, scale);
5217
5218    sv = e_util_transform_rect_to_vertices(&sr);
5219    sv = e_util_transform_matrix_multiply_rect_vertex(&m, &sv);
5220    sr = e_util_transform_vertices_to_rect(&sv);
5221
5222    if (bx) *bx = sr.x;
5223    if (by) *by = sr.y;
5224    if (bw) *bw = sr.w;
5225    if (bh) *bh = sr.h;
5226 }
5227
5228 /* buffer to screen
5229  *   - buffer width, buffer height, buffer transform, buffer scale
5230  */
5231 EINTERN void
5232 e_comp_wl_rect_convert_inverse(int width, int height, int transform, int scale,
5233                                int bx, int by, int bw, int bh, int *sx, int *sy, int *sw, int *sh)
5234 {
5235    E_Util_Transform_Matrix m;
5236    E_Util_Transform_Rect br = {bx, by, bw, bh};
5237    E_Util_Transform_Rect_Vertex bv;
5238    int tw, th;
5239
5240    if (transform != 0 || scale > 1)
5241      {
5242         tw = ((transform % 2) ? height : width) / scale;
5243         th = ((transform % 2) ? width : height) / scale;
5244      }
5245    else
5246      {
5247         tw = width;
5248         th = height;
5249      }
5250
5251    m = _e_comp_wl_buffer_coord_get(tw, th, transform, scale);
5252    m = e_util_transform_matrix_inverse_get(&m);
5253
5254    bv = e_util_transform_rect_to_vertices(&br);
5255    bv = e_util_transform_matrix_multiply_rect_vertex(&m, &bv);
5256    br = e_util_transform_vertices_to_rect(&bv);
5257
5258    if (sx) *sx = br.x;
5259    if (sy) *sy = br.y;
5260    if (sw) *sw = br.w;
5261    if (sh) *sh = br.h;
5262 }
5263
5264 EINTERN E_Comp_Wl_Output*
5265 e_comp_wl_output_find(E_Client *ec)
5266 {
5267    Eina_List *l;
5268    E_Comp_Wl_Output *output;
5269
5270    if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec))) return NULL;
5271
5272    EINA_LIST_FOREACH(e_comp_wl->outputs, l, output)
5273      {
5274         if (output->transform % 2)
5275           {
5276              if (ec->x < output->y || ec->x >= (output->y + output->h) ||
5277                  ec->y < output->x || ec->y >= (output->x + output->w))
5278                continue;
5279           }
5280         else
5281           {
5282              if (ec->x < output->x || ec->x >= (output->x + output->w) ||
5283                  ec->y < output->y || ec->y >= (output->y + output->h))
5284                continue;
5285           }
5286
5287         return output;
5288      }
5289
5290    return NULL;
5291 }
5292
5293 EINTERN Eina_Array *
5294 e_comp_wl_output_find_all(E_Client *ec)
5295 {
5296    E_Comp_Wl_Output *output;
5297    Eina_Array *outputs;
5298    Eina_List *l;
5299
5300    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
5301
5302    outputs = eina_array_new(4);
5303    if (!outputs)
5304      return NULL;
5305
5306    EINA_LIST_FOREACH(e_comp_wl->outputs, l, output)
5307      {
5308         if (E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
5309                          output->x, output->y, output->w, output->h))
5310           {
5311              eina_array_push(outputs, output);
5312           }
5313      }
5314
5315    if (eina_array_count(outputs) == 0)
5316      {
5317         eina_array_free(outputs);
5318         return NULL;
5319      }
5320
5321    return outputs;
5322 }
5323
5324 // --------------------------------------------------------
5325 // tizen_move_resize
5326 // --------------------------------------------------------
5327 EINTERN Eina_Bool
5328 e_comp_wl_commit_sync_client_geometry_add(E_Client *ec,
5329                                           uint32_t serial,
5330                                           int32_t x,
5331                                           int32_t y,
5332                                           int32_t w,
5333                                           int32_t h)
5334 {
5335    E_Client_Pending_Geometry *geo;
5336
5337    if (!ec) goto ret;
5338    if (e_object_is_del(E_OBJECT(ec))) goto ret;
5339    if (ec->fullscreen || ec->maximized) goto err;
5340
5341    geo = E_NEW(E_Client_Pending_Geometry, 1);
5342    if (!geo) goto err;
5343
5344    geo->serial = serial;
5345    geo->x = x;
5346    geo->y = y;
5347    geo->w = w;
5348    geo->h = h;
5349
5350    ec->surface_sync.pending_geometry = eina_list_append(ec->surface_sync.pending_geometry, geo);
5351    ec->surface_sync.wait_commit = EINA_TRUE;
5352
5353    return EINA_TRUE;
5354
5355 err:
5356    ELOGF("POSSIZE", "Could not add geometry(new:%d full:%d max:%d)", ec, ec->new_client, ec->fullscreen, ec->maximized);
5357
5358 ret:
5359    return EINA_FALSE;
5360 }
5361
5362 EINTERN Eina_Bool
5363 e_comp_wl_commit_sync_configure(E_Client *ec)
5364 {
5365    Eina_List *l;
5366    E_Client_Pending_Geometry *geo;
5367    int bw, bh;
5368    Eina_Bool match_size = EINA_FALSE;
5369
5370    struct
5371      {
5372         int x, y, w, h;
5373      } config;
5374
5375    if (!ec || !ec->frame) goto ret;
5376    if (e_object_is_del(E_OBJECT(ec))) goto ret;
5377
5378    bw = bh = 0;
5379    config.x = ec->x; config.y = ec->y; config.w = ec->w; config.h = ec->h;
5380    if (!e_pixmap_size_get(ec->pixmap, &bw, &bh)) goto err;
5381
5382    if (eina_list_count(ec->surface_sync.pending_geometry))
5383      {
5384         Eina_List *ll = NULL;
5385         EINA_LIST_REVERSE_FOREACH_SAFE(ec->surface_sync.pending_geometry, l, ll, geo)
5386           {
5387              if (match_size)
5388                {
5389                   ec->surface_sync.pending_geometry = eina_list_remove(ec->surface_sync.pending_geometry, geo);
5390                   E_FREE(geo);
5391                   continue;
5392                }
5393
5394              if ((geo->w == bw) && (geo->h == bh))
5395                {
5396                   match_size = EINA_TRUE;
5397                   config.w = geo->w;
5398                   config.h = geo->h;
5399                   config.x = geo->x;
5400                   config.y = geo->y;
5401                   ec->surface_sync.pending_geometry = eina_list_remove(ec->surface_sync.pending_geometry, geo);
5402                   E_FREE(geo);
5403                }
5404           }
5405
5406         if (match_size)
5407           {
5408              if ((config.w != ec->w) || (config.h != ec->h))
5409                {
5410                   e_client_size_set(ec, config.w, config.h);
5411                   ec->changes.size = EINA_TRUE;
5412                   EC_CHANGED(ec);
5413                }
5414
5415              // FIXME: The geometry of the client would be better to be calculated
5416              //        at e_desk or at e_desk_area. So the position(x,y) of the client
5417              //        should be calcuated at the e_desk or at the e_desk_area.
5418              E_Desk *desk;
5419              desk = e_comp_desk_find_by_ec(ec);
5420              if (desk)
5421                {
5422                   ec->client.x = desk->geom.x + config.x;
5423                   ec->client.y = desk->geom.y + config.y;
5424                }
5425              else
5426                {
5427                   ec->client.x = config.x;
5428                   ec->client.y = config.y;
5429                }
5430
5431              if ((ec->client.x != ec->x) || (ec->client.y != ec->y))
5432                {
5433                   e_client_pos_set(ec, ec->client.x, ec->client.y);
5434                   ec->placed = 1;
5435                   ec->changes.pos = 1;
5436                   EC_CHANGED(ec);
5437                }
5438
5439              ELOGF("POSSIZE", "Configure pending geometry (%d,%d,%dx%d)", ec, ec->x, ec->y, ec->w, ec->h);
5440           }
5441      }
5442
5443    // cw interceptor(move,resize) won't work if wait_commit is TRUE
5444    ec->surface_sync.wait_commit = EINA_FALSE;
5445
5446    e_client_shell_configure(ec, ec->x, ec->y, ec->w, ec->h);
5447
5448    // rollback wait_commit if there are pending requests remained
5449    if (eina_list_count(ec->surface_sync.pending_geometry))
5450      ec->surface_sync.wait_commit = EINA_TRUE;
5451
5452    return EINA_TRUE;
5453
5454 err:
5455    ELOGF("POSSIZE", "Could not configure geometry (%d,%d - %dx%d) bw:%d bh:%d", ec, ec->x, ec->y, ec->w, ec->h, bw, bh);
5456
5457 ret:
5458    return EINA_FALSE;
5459 }
5460
5461 static void
5462 _tz_move_resize_iface_cb_destroy(struct wl_client *client EINA_UNUSED,
5463                                  struct wl_resource *res_moveresize)
5464 {
5465    wl_resource_destroy(res_moveresize);
5466 }
5467
5468 static void
5469 _tz_move_resize_iface_cb_set_geometry(struct wl_client *client EINA_UNUSED,
5470                                       struct wl_resource *res_moveresize,
5471                                       struct wl_resource *surface,
5472                                       uint32_t serial,
5473                                       int32_t x,
5474                                       int32_t y,
5475                                       int32_t w,
5476                                       int32_t h)
5477 {
5478    /* to be implemented */
5479    E_Client *ec;
5480    Eina_Bool pending;
5481    int cur_w = 0, cur_h = 0;
5482
5483    ec = e_client_from_surface_resource(surface);
5484    if (!ec) return;
5485
5486    pending = e_client_pending_geometry_has(ec);
5487    e_client_geometry_get(ec, NULL, NULL, &cur_w, &cur_h);
5488    ELOGF("POSSIZE", "Request move_resize geometry_set. geo(%d,%d,%dx%d) cur(%dx%d). pend:%d", ec, x, y, w, h, cur_w, cur_h, pending);
5489
5490    if (!pending)
5491      {
5492         if ((cur_w == w) && (cur_h == h))
5493           {
5494              e_client_pos_set(ec, x, y);
5495              ec->changes.pos = 1;
5496              EC_CHANGED(ec);
5497              return;
5498           }
5499      }
5500
5501    if (!e_comp_wl_commit_sync_client_geometry_add(ec, serial, x, y, w, h)) goto err;
5502    return;
5503
5504 err:
5505    ELOGF("POSSIZE", "Could not add set_geometry request(serial:%d, %d,%d - %dx%d)", ec, serial, x, y, w, h);
5506 }
5507
5508 static const struct tizen_move_resize_interface _tz_move_resize_iface =
5509 {
5510    _tz_move_resize_iface_cb_destroy,
5511    _tz_move_resize_iface_cb_set_geometry,
5512 };
5513
5514 static void
5515 _tz_moveresize_cb_bind(struct wl_client *client,
5516                        void *data EINA_UNUSED,
5517                        uint32_t ver,
5518                        uint32_t id)
5519 {
5520    struct wl_resource *res_moveresize;
5521
5522    res_moveresize = wl_resource_create(client,
5523                                        &tizen_move_resize_interface,
5524                                        ver,
5525                                        id);
5526    EINA_SAFETY_ON_NULL_GOTO(res_moveresize, err);
5527
5528
5529    wl_resource_set_implementation(res_moveresize,
5530                                   &_tz_move_resize_iface,
5531                                   NULL,
5532                                   NULL);
5533    return;
5534
5535 err:
5536    ERR("Could not create tizen_move_resize_interface res: %m");
5537    wl_client_post_no_memory(client);
5538 }
5539
5540 static void
5541 _e_comp_wl_move_resize_init(void)
5542 {
5543    if (!e_comp_wl) return;
5544    if (!e_comp_wl->wl.disp) return;
5545
5546    if (!wl_global_create(e_comp_wl->wl.disp,
5547                          &tizen_move_resize_interface,
5548                          1,
5549                          NULL,
5550                          _tz_moveresize_cb_bind))
5551      {
5552         ERR("Could not create tizen_move_resize_interface to wayland globals: %m");
5553      }
5554
5555    return;
5556 }
5557
5558 EINTERN Eina_Bool
5559 e_comp_wl_pid_output_configured_resolution_send(pid_t pid, int w, int h)
5560 {
5561    E_Comp_Wl_Output *output;
5562    pid_t output_pid = 0;
5563    Eina_List *l = NULL, *l2 = NULL;
5564    struct wl_resource *resource = NULL;
5565
5566    if (!e_config->configured_output_resolution.use) return EINA_TRUE;
5567
5568    EINA_SAFETY_ON_TRUE_RETURN_VAL(pid <= 0, EINA_FALSE);
5569    EINA_SAFETY_ON_TRUE_RETURN_VAL(w < 0, EINA_FALSE);
5570    EINA_SAFETY_ON_TRUE_RETURN_VAL(h < 0, EINA_FALSE);
5571
5572    EINA_LIST_FOREACH(e_comp_wl->outputs, l, output)
5573      {
5574         /* if we have bound resources, send updates */
5575         EINA_LIST_FOREACH(output->resources, l2, resource)
5576           {
5577              wl_client_get_credentials(wl_resource_get_client(resource), &output_pid, NULL, NULL);
5578              if (output_pid != pid) continue;
5579
5580              ELOGF("COMP_WL", "\tSend Configured Output AGAIN ~!!!!! (pid:%d)", NULL, pid);
5581
5582              // send output information to the client
5583              _e_comp_wl_output_info_send(output, resource, pid, w, h);
5584           }
5585      }
5586
5587    return EINA_TRUE;
5588 }
5589
5590 EINTERN void
5591 e_comp_wl_surface_state_init(E_Comp_Wl_Surface_State *state, int w, int h)
5592 {
5593    _e_comp_wl_surface_state_init(state, w, h);
5594 }
5595
5596 EINTERN void
5597 e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
5598 {
5599    _e_comp_wl_surface_state_commit(ec, state);
5600 }
5601
5602 EINTERN void
5603 e_comp_wl_hook_call(E_Comp_Wl_Hook_Point hookpoint, E_Client *ec)
5604 {
5605    _e_comp_wl_hook_call(hookpoint, ec);
5606 }
5607
5608 EINTERN void
5609 e_comp_wl_surface_state_finish(E_Comp_Wl_Surface_State *state)
5610 {
5611    _e_comp_wl_surface_state_finish(state);
5612 }
5613
5614 EINTERN void
5615 e_comp_wl_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer)
5616 {
5617    _e_comp_wl_surface_state_buffer_set(state, buffer);
5618 }
5619
5620 static void
5621 buffer_transform(int width, int height, uint32_t transform, int32_t scale,
5622                  int sx, int sy, int *dx, int *dy)
5623 {
5624    switch (transform)
5625      {
5626       case WL_OUTPUT_TRANSFORM_NORMAL:
5627       default:
5628          *dx = sx, *dy = sy;
5629          break;
5630       case WL_OUTPUT_TRANSFORM_FLIPPED:
5631          *dx = width - sx, *dy = sy;
5632          break;
5633       case WL_OUTPUT_TRANSFORM_90:
5634          *dx = height - sy, *dy = sx;
5635          break;
5636       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
5637          *dx = height - sy, *dy = width - sx;
5638          break;
5639       case WL_OUTPUT_TRANSFORM_180:
5640          *dx = width - sx, *dy = height - sy;
5641          break;
5642       case WL_OUTPUT_TRANSFORM_FLIPPED_180:
5643          *dx = sx, *dy = height - sy;
5644          break;
5645       case WL_OUTPUT_TRANSFORM_270:
5646          *dx = sy, *dy = width - sx;
5647          break;
5648       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
5649          *dx = sy, *dy = sx;
5650          break;
5651      }
5652
5653    *dx *= scale;
5654    *dy *= scale;
5655 }
5656
5657 static void
5658 _buffer_viewport_get(E_Comp_Wl_Buffer_Viewport *vp, int bw, int bh, Eina_Rectangle *out)
5659 {
5660    int x1, y1, x2, y2;
5661    int tx1, ty1, tx2, ty2;
5662    int width_from_buffer, height_from_buffer;
5663
5664    switch (vp->buffer.transform)
5665      {
5666       case WL_OUTPUT_TRANSFORM_90:
5667       case WL_OUTPUT_TRANSFORM_270:
5668       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
5669       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
5670          width_from_buffer = bh / vp->buffer.scale;
5671          height_from_buffer = bw / vp->buffer.scale;
5672          break;
5673       default:
5674          width_from_buffer = bw / vp->buffer.scale;
5675          height_from_buffer = bh / vp->buffer.scale;
5676          break;
5677      }
5678
5679    if (vp->buffer.src_width == wl_fixed_from_int(-1))
5680      {
5681         x1 = 0.0;
5682         y1 = 0.0;
5683         x2 = width_from_buffer;
5684         y2 = height_from_buffer;
5685      }
5686    else
5687      {
5688         x1 = wl_fixed_to_int(vp->buffer.src_x);
5689         y1 = wl_fixed_to_int(vp->buffer.src_y);
5690         x2 = wl_fixed_to_int(vp->buffer.src_x + vp->buffer.src_width);
5691         y2 = wl_fixed_to_int(vp->buffer.src_y + vp->buffer.src_height);
5692      }
5693
5694    buffer_transform(width_from_buffer, height_from_buffer,
5695                     vp->buffer.transform, vp->buffer.scale, x1, y1, &tx1, &ty1);
5696    buffer_transform(width_from_buffer, height_from_buffer,
5697                     vp->buffer.transform, vp->buffer.scale, x2, y2, &tx2, &ty2);
5698
5699    out->x = (tx1 <= tx2) ? tx1 : tx2;
5700    out->y = (ty1 <= ty2) ? ty1 : ty2;
5701    out->w = (tx1 <= tx2) ? tx2 - tx1 : tx1 - tx2;
5702    out->h = (ty1 <= ty2) ? ty2 - ty1 : ty1 - ty2;
5703 }
5704
5705 /**
5706  * Convert given four coordinates to elements of rectangle
5707  * @in   p[4]        Coordinates to be converted
5708  * @out  rect        x, y, width, and height
5709  *       transform   Angle which represents TDM_TRANSFORM of rectangle
5710  * @return EINA_FALSE in following case, otherwise EINA_TRUE.
5711  *   1. The given coordinates are not represented by rectangle.
5712  *   2. All angles except for 0, 90, 180, 270.
5713  */
5714 static Eina_Bool
5715 _coords_to_rectangle_convert(Evas_Point p[4], Eina_Rectangle *rect, uint *rotation)
5716 {
5717    Eina_Bool ret = EINA_FALSE;
5718
5719    if ((p[0].y == p[1].y) && (p[1].x == p[2].x) && (p[2].y == p[3].y) && (p[3].x == p[0].x))
5720      {
5721         /* 0 or 180 */
5722         if ((p[0].x < p[2].x) && (p[0].y < p[2].y))
5723           {
5724              if (rotation)
5725                *rotation = TDM_TRANSFORM_NORMAL;
5726
5727              if (rect)
5728                EINA_RECTANGLE_SET(rect, p[0].x, p[0].y, p[2].x - p[0].x, p[2].y - p[0].y);
5729
5730              ret = EINA_TRUE;
5731           }
5732         else if ((p[0].x > p[2].x) && (p[0].y > p[2].y))
5733           {
5734              if (rotation)
5735                *rotation = TDM_TRANSFORM_180;
5736
5737              if (rect)
5738                EINA_RECTANGLE_SET(rect, p[2].x, p[2].y, p[0].x - p[2].x, p[0].y - p[2].y);
5739
5740              ret = EINA_TRUE;
5741           }
5742      }
5743    else if ((p[0].x == p[1].x) && (p[1].y == p[2].y) && (p[2].x == p[3].x) && (p[3].y == p[0].y))
5744      {
5745         /* 90 or 270 */
5746         if ((p[0].x > p[2].x) && (p[0].y < p[2].y))
5747           {
5748              if (rotation)
5749                *rotation = TDM_TRANSFORM_90;
5750
5751              if (rect)
5752                EINA_RECTANGLE_SET(rect, p[2].x, p[0].y, p[0].x - p[2].x, p[2].y - p[0].y);
5753
5754              ret = EINA_TRUE;
5755           }
5756         else if ((p[0].x < p[2].x) && (p[0].y > p[2].y))
5757           {
5758              if (rotation)
5759                *rotation = TDM_TRANSFORM_270;
5760
5761              if (rect)
5762                EINA_RECTANGLE_SET(rect, p[0].x, p[2].y, p[2].x - p[0].x, p[0].y - p[2].y);
5763
5764              ret = EINA_TRUE;
5765           }
5766      }
5767
5768    return ret;
5769 }
5770
5771 static Eina_Bool
5772 _output_viewport_get_from_evas_map(E_Map *m, Eina_Rectangle *out, unsigned int *rotation)
5773 {
5774    Evas_Point p[4];
5775    int i;
5776
5777    for (i = 0; i < 4; i++)
5778      e_map_point_coord_get(m, i, &p[i].x, &p[i].y, NULL);
5779
5780    if (!_coords_to_rectangle_convert(p, out, rotation))
5781      {
5782         DBG("Cannot convert given coords to rectangle.\n"
5783             "p1(%d %d) p2(%d %d) p3(%d %d) p4(%d %d)",
5784             p[0].x, p[0].y, p[1].x, p[1].y,
5785             p[2].x, p[2].y, p[3].x, p[3].y);
5786         return EINA_FALSE;
5787      }
5788
5789    return EINA_TRUE;
5790 }
5791
5792 static unsigned int
5793 _transform_merge_with_rotation(enum wl_output_transform transform, unsigned int rotation)
5794 {
5795    int trans_rotation, flip;
5796
5797    trans_rotation = transform & 0x3;
5798    flip = transform & 0x4;
5799
5800    return (flip + (trans_rotation + rotation) % 4);
5801 }
5802
5803 static void
5804 _e_comp_wl_surface_output_viewport_get(E_Client *ec, Eina_Rectangle *out)
5805 {
5806    if (!out)
5807      return;
5808
5809    if (!ec->comp_data)
5810      return;
5811
5812    if (e_comp_wl_subsurface_check(ec))
5813      e_comp_wl_subsurface_global_coord_get(ec, &out->x, &out->y);
5814    else
5815      {
5816         out->x = ec->x;
5817         out->y = ec->y;
5818      }
5819
5820    out->w = ec->comp_data->width_from_viewport;
5821    out->w = (out->w + 1) & ~1;
5822    out->h = ec->comp_data->height_from_viewport;
5823
5824    e_comp_object_frame_xy_unadjust(ec->frame, out->x, out->y, &out->x, &out->y);
5825    e_comp_object_frame_wh_unadjust(ec->frame, out->w, out->h, &out->w, &out->h);
5826 }
5827
5828 EINTERN Eina_Bool
5829 e_comp_wl_surface_viewport_get(E_Client *ec, Eina_Rectangle *buffer_viewport, Eina_Rectangle *output_viewport, unsigned int *transform)
5830 {
5831    E_Comp_Wl_Buffer *buffer;
5832    E_Comp_Wl_Buffer_Viewport *vp;
5833    E_Map *m;
5834    enum wl_output_transform buffer_transform;
5835    unsigned int rotation;
5836    Eina_Bool res = EINA_FALSE;
5837
5838    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
5839
5840    if (e_object_is_del(E_OBJECT(ec)))
5841      return EINA_FALSE;
5842
5843    vp = &ec->comp_data->scaler.buffer_viewport;
5844
5845    if (buffer_viewport)
5846      {
5847         buffer = ec->comp_data->buffer_ref.buffer;
5848         /* Getting a viewport of buffer needs geometry of buffer. */
5849         if (!buffer)
5850           return EINA_FALSE;
5851
5852         _buffer_viewport_get(vp, buffer->w, buffer->h, buffer_viewport);
5853      }
5854
5855    if ((output_viewport) || (transform))
5856      {
5857         m = e_client_map_get(ec);
5858         if (m)
5859           res = _output_viewport_get_from_evas_map(m, output_viewport, &rotation);
5860         else
5861           _e_comp_wl_surface_output_viewport_get(ec, output_viewport);
5862         e_map_free(m);
5863
5864         if (transform)
5865           {
5866              buffer_transform = e_comp_wl_output_buffer_transform_get(ec);
5867              /* NOTE Merge transform value from evas_map with E_Comp_Wl_Buffer_Viewport's one.
5868               * Since buffer.transform isn't applied using evas_map,
5869               * it has to be taken into account here to apply buffer.transform
5870               * and rotation of e_client_transform together. */
5871              if (res)
5872                *transform = _transform_merge_with_rotation(buffer_transform, rotation);
5873              else
5874                *transform = (unsigned int)buffer_transform;
5875           }
5876      }
5877
5878    return EINA_TRUE;
5879 }
5880
5881 EINTERN Eina_Bool
5882 e_comp_wl_surface_role_set(E_Client *ec, const char *role_name, struct wl_resource *error_resource, uint32_t error_code)
5883 {
5884    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
5885    EINA_SAFETY_ON_NULL_RETURN_VAL(role_name, EINA_FALSE);
5886
5887    /* Must be called with valid comp_data */
5888    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
5889
5890    if ((ec->comp_data->role_name == NULL) ||
5891        (ec->comp_data->role_name == role_name) ||
5892        (strcmp(ec->comp_data->role_name, role_name) == 0))
5893      {
5894         ec->comp_data->role_name = role_name;
5895         return EINA_TRUE;
5896      }
5897
5898    if (error_resource)
5899      {
5900         wl_resource_post_error(error_resource, error_code,
5901                                "Cannot assign role %s to wl_surface@%d,"
5902                                " already has role %s\n",
5903                                role_name,
5904                                ec->comp_data->wl_surface ?
5905                                wl_resource_get_id(ec->comp_data->wl_surface) : -1,
5906                                ec->comp_data->role_name);
5907      }
5908
5909    return EINA_FALSE;
5910 }
5911
5912 EINTERN const char *
5913 e_comp_wl_surface_role_get(E_Client *ec)
5914 {
5915    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
5916    return ec->comp_data ? ec->comp_data->role_name : NULL;
5917 }
5918
5919 EINTERN struct wl_resource *
5920 e_comp_wl_client_surface_get(E_Client *ec)
5921 {
5922    struct wl_resource *surface = NULL;
5923    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
5924    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, NULL);
5925
5926    g_mutex_lock(&ec->comp_data->surface_mutex);
5927    surface = ec->comp_data->surface;
5928    g_mutex_unlock(&ec->comp_data->surface_mutex);
5929
5930    return surface;
5931 }
5932
5933 EINTERN void e_comp_wl_client_surface_set(E_Client *ec, struct wl_resource *surface)
5934 {
5935    EINA_SAFETY_ON_NULL_RETURN(ec);
5936    EINA_SAFETY_ON_NULL_RETURN(ec->comp_data);
5937
5938    g_mutex_lock(&ec->comp_data->surface_mutex);
5939    ec->comp_data->surface = surface;
5940    g_mutex_unlock(&ec->comp_data->surface_mutex);
5941 }
5942
5943 EINTERN E_Client *
5944 e_comp_wl_util_client_from_surface_resource(struct wl_resource *surface_resource)
5945 {
5946    return e_compositor_util_client_from_surface_resource(surface_resource);
5947 }
5948
5949 EINTERN void
5950 e_comp_wl_client_surface_pending_buffer_set(E_Client *ec, E_Comp_Wl_Buffer *buffer, int32_t sx, int32_t sy)
5951 {
5952    if (!ec->comp_data->mapped)
5953      {
5954         if (ec->comp_data->shell.surface &&
5955             !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
5956           {
5957              ELOGF("COMP", "Current unmapped. ATTACH buffer:%p", ec, buffer);
5958           }
5959      }
5960
5961    if (!buffer)
5962      {
5963         if (ec->comp_data->mapped)
5964           {
5965              /* will be unmapped. so run capture */
5966              e_comp_wl_remote_surface_image_save(ec);
5967           }
5968      }
5969
5970    _e_comp_wl_surface_state_buffer_set(&ec->comp_data->pending, buffer);
5971
5972    ec->comp_data->pending.sx = sx;
5973    ec->comp_data->pending.sy = sy;
5974    ec->comp_data->pending.new_attach = EINA_TRUE;
5975
5976    e_client_fps_update(ec);
5977 }
5978
5979 EINTERN void
5980 e_comp_wl_client_surface_pending_opaque_region_set(E_Client *ec, Eina_Tiler *region)
5981 {
5982    if (ec->comp_data->pending.opaque)
5983      eina_tiler_clear(ec->comp_data->pending.opaque);
5984
5985    if (region)
5986      {
5987         eina_tiler_union(ec->comp_data->pending.opaque, region);
5988
5989         if (!eina_tiler_empty(ec->comp_data->pending.opaque))
5990           {
5991              if (ec->argb)
5992                {
5993                   ec->argb = EINA_FALSE;
5994                   ELOGF("COMP", "Set argb:%d", ec, ec->argb);
5995                   EC_CHANGED(ec);
5996                   _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, ec);
5997                   e_comp_object_alpha_set(ec->frame, EINA_FALSE);
5998                }
5999           }
6000      }
6001    else
6002      {
6003         if (!ec->argb)
6004           {
6005              ec->argb = EINA_TRUE;
6006              ELOGF("COMP", "Set argb:%d", ec, ec->argb);
6007              EC_CHANGED(ec);
6008              _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE, ec);
6009              e_comp_object_alpha_set(ec->frame, EINA_TRUE);
6010           }
6011      }
6012 }
6013
6014 EINTERN void
6015 e_comp_wl_client_surface_pending_input_region_set(E_Client *ec, Eina_Tiler *region)
6016 {
6017    if (ec->comp_data->pending.input)
6018      eina_tiler_clear(ec->comp_data->pending.input);
6019
6020    if (region)
6021      {
6022         if (eina_tiler_empty(region))
6023           {
6024              ELOGF("COMP", "         |unset input rect", NULL);
6025              e_comp_object_input_objs_del(ec->frame);
6026              e_comp_object_input_area_set(ec->frame, -1, -1, 1, 1);
6027           }
6028         else
6029           eina_tiler_union(ec->comp_data->pending.input, region);
6030      }
6031    else
6032      {
6033         eina_tiler_rect_add(ec->comp_data->pending.input,
6034                             &(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
6035      }
6036 }
6037
6038 EINTERN void
6039 e_comp_wl_client_surface_pending_frame_callback_add(E_Client *ec, struct wl_resource *callback_resource)
6040 {
6041    ec->comp_data->pending.frames = eina_list_prepend(ec->comp_data->pending.frames, callback_resource);
6042 }
6043
6044 EINTERN void
6045 e_comp_wl_client_surface_frame_callback_remove(E_Client *ec, struct wl_resource *callback_resource)
6046 {
6047    E_Comp_Wl_Subsurf_Data *sdata;
6048
6049    if (!ec->comp_data)
6050      return;
6051
6052    if (ec->comp_data->frames)
6053      {
6054         ec->comp_data->frames =
6055            eina_list_remove(ec->comp_data->frames, callback_resource);
6056      }
6057
6058    if (ec->comp_data->pending.frames)
6059      {
6060         ec->comp_data->pending.frames =
6061            eina_list_remove(ec->comp_data->pending.frames, callback_resource);
6062      }
6063
6064    sdata = ec->comp_data->sub.data;
6065    if ((sdata) && (sdata->cached.frames))
6066      {
6067         sdata->cached.frames =
6068            eina_list_remove(sdata->cached.frames, callback_resource);
6069      }
6070 }
6071
6072 EINTERN void
6073 e_comp_wl_client_surface_pending_commit(E_Client *ec)
6074 {
6075    if (e_object_is_del(E_OBJECT(ec))) return;
6076
6077    if (e_comp_wl_remote_surface_commit(ec)) return;
6078
6079    e_comp_wl_surface_commit(ec);
6080
6081    _e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT, ec);
6082 }
6083
6084 static void
6085 _e_comp_wl_client_subsurface_set(E_Client *ec, E_Comp_Wl_Subsurf_Data *sub)
6086 {
6087    e_comp_wl_client_surface_set(ec, ec->comp_data->wl_surface);
6088    ec->comp_data->sub.data = sub;
6089
6090    /* set subsurface client properties */
6091    ec->borderless = EINA_TRUE;
6092    ec->argb = EINA_TRUE;
6093    ELOGF("SUBSURFACE", "Set argb:%d", ec, ec->argb);
6094    ec->lock_border = EINA_TRUE;
6095    ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
6096    ec->netwm.state.skip_taskbar = EINA_TRUE;
6097    ec->netwm.state.skip_pager = EINA_TRUE;
6098    ec->border_size = 0;
6099    ec->lock_user_location = 0;
6100    ec->lock_client_location = 0;
6101    ec->lock_user_size = 0;
6102    ec->lock_client_size = 0;
6103    ec->lock_client_stacking = 0;
6104    ec->lock_user_maximize = 0;
6105    ec->lock_client_maximize = 0;
6106    ec->changes.need_maximize = 0;
6107    ec->maximized = E_MAXIMIZE_NONE;
6108    EC_CHANGED(ec);
6109
6110    ec->new_client = ec->netwm.ping = EINA_TRUE;
6111    e_comp->new_clients++;
6112    e_client_unignore(ec);
6113
6114    /* Delete 'below_obj' if it was created before 'E_Client' becomes subsurface.
6115     * It's not for subsurface. */
6116    E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del);
6117 }
6118
6119 static void
6120 _e_comp_wl_client_subsurface_parent_set(E_Client *ec, E_Client *parent)
6121 {
6122    E_Comp_Wl_Subsurf_Data *sub = ec->comp_data->sub.data;
6123    E_Layer layer;
6124
6125    ELOGF("COMP", "         |subsurface_parent:%p", ec, parent);
6126
6127    sub->parent = parent;
6128
6129    if (parent->frame)
6130      {
6131         layer = e_client_layer_get(parent);
6132         if (layer > E_LAYER_BOTTOM)
6133           e_client_layer_set(ec, layer);
6134      }
6135
6136    if (parent->comp_data)
6137      {
6138         /* append this client to the parents subsurface list */
6139         parent->comp_data->sub.list_pending =
6140            eina_list_append(parent->comp_data->sub.list_pending, ec);
6141         parent->comp_data->sub.list_changed = EINA_TRUE;
6142      }
6143 }
6144
6145 EINTERN void
6146 e_comp_wl_client_subsurface_parent_unset(E_Client *ec)
6147 {
6148    E_Comp_Wl_Subsurf_Data *sub = ec->comp_data->sub.data;
6149    E_Client *parent = sub->parent;
6150
6151    parent->comp_data->sub.list =
6152       eina_list_remove(parent->comp_data->sub.list, ec);
6153    parent->comp_data->sub.list_pending =
6154       eina_list_remove(parent->comp_data->sub.list_pending, ec);
6155    parent->comp_data->sub.below_list =
6156       eina_list_remove(parent->comp_data->sub.below_list, ec);
6157    parent->comp_data->sub.below_list_pending =
6158       eina_list_remove(parent->comp_data->sub.below_list_pending, ec);
6159
6160    sub->parent = NULL;
6161 }
6162
6163 EINTERN void
6164 e_comp_wl_client_subsurface_init(E_Client *ec, struct wl_resource *subsurface_resource, E_Comp_Wl_Subsurf_Data *sub, E_Client *parent, E_Client *offscreen_parent)
6165 {
6166    sub->resource = subsurface_resource;
6167    sub->cached_buffer_ref.buffer = NULL;
6168    sub->synchronized = EINA_TRUE;
6169    sub->parent = parent;
6170    sub->remote_surface.offscreen_parent = offscreen_parent;
6171    if (offscreen_parent)
6172      ELOGF("SUBSURFACE", "         |offscreen_parent:%p", ec, offscreen_parent);
6173
6174    _e_comp_wl_surface_state_init(&sub->cached, ec->w, ec->h);
6175
6176    _e_comp_wl_client_subsurface_set(ec, sub);
6177    _e_comp_wl_client_subsurface_parent_set(ec, parent);
6178
6179    e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_CREATE, ec);
6180 }
6181
6182 EINTERN void
6183 e_comp_wl_client_subsurface_finish(E_Client *ec)
6184 {
6185    E_Comp_Wl_Subsurf_Data *sub = ec->comp_data->sub.data;
6186
6187    if (sub->parent)
6188      e_comp_wl_client_subsurface_parent_unset(ec);
6189
6190    e_comp_wl_surface_state_finish(&sub->cached);
6191    e_comp_wl_buffer_reference(&sub->cached_buffer_ref, NULL);
6192
6193    ec->comp_data->sub.data = NULL;
6194 }
6195
6196 EINTERN void
6197 e_comp_wl_client_evas_init(E_Client *ec)
6198 {
6199    EINA_SAFETY_ON_NULL_RETURN(ec);
6200
6201    _e_comp_wl_client_evas_init(ec);
6202 }
6203
6204 EINTERN void
6205 e_comp_wl_client_evas_deinit(E_Client *ec)
6206 {
6207    EINA_SAFETY_ON_NULL_RETURN(ec);
6208
6209    _e_comp_wl_client_evas_deinit(ec);
6210 }
6211
6212 EINTERN void
6213 e_comp_wl_focus_check(void)
6214 {
6215    _e_comp_wl_focus_check();
6216 }
6217
6218 EINTERN Eina_Bool
6219 e_comp_wl_client_subsurface_cyclic_reference_check(E_Client *ec, E_Client *parent)
6220 {
6221    while (parent)
6222      {
6223         if (ec == parent)
6224           return EINA_TRUE;
6225
6226         if ((parent->comp_data) && (parent->comp_data->sub.data))
6227           parent = parent->comp_data->sub.data->parent;
6228         else
6229           break;
6230      }
6231
6232    return EINA_FALSE;
6233 }