159254b993725551d03978c8ea195b1d80fd0b1e
[platform/upstream/enlightenment.git] / src / bin / e_comp_wl.c
1 #include "e.h"
2 #include "e_comp_wl.h"
3 #include <sys/mman.h>
4
5 /* compositor function prototypes */
6 static void _seat_send_updated_caps(struct wl_seat *seat);
7 static void _move_resources(struct wl_list *dest, struct wl_list *src);
8 static void _move_resources_for_client(struct wl_list *dest, struct wl_list *src, struct wl_client *client);
9
10 static struct wl_resource *_find_resource_for_surface(struct wl_list *list, struct wl_resource *surface);
11
12 static void _default_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y);
13 static void _default_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y);
14 static void _default_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp, uint32_t button, uint32_t state_w);
15
16 static void _default_grab_touch_down(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy);
17 static void _default_grab_touch_up(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id);
18 static void _default_grab_touch_motion(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy);
19
20 static void _data_offer_accept(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *mime_type);
21 static void _data_offer_receive(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type, int32_t fd);
22 static void _data_offer_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource);
23
24 static void _destroy_data_offer(struct wl_resource *resource);
25 static void _destroy_offer_data_source(struct wl_listener *listener, void *data EINA_UNUSED);
26
27 static void _create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id);
28 static void _get_data_device(struct wl_client *client, struct wl_resource *manager_resource EINA_UNUSED, uint32_t id, struct wl_resource *seat_resource);
29
30 static void _current_surface_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
31 static void _bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id);
32
33 static void _default_grab_key(struct wl_keyboard_grab *grab, uint32_t timestamp, uint32_t key, uint32_t state);
34 static void _default_grab_modifiers(struct wl_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group);
35
36 static void _data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource EINA_UNUSED, struct wl_resource *icon_resource, uint32_t serial EINA_UNUSED);
37 static void _data_device_set_selection(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *source_resource, uint32_t serial);
38 static void _destroy_data_device_icon(struct wl_listener *listener, void *data EINA_UNUSED);
39
40 static void _destroy_selection_data_source(struct wl_listener *listener, void *data EINA_UNUSED);
41 static void _data_source_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *type);
42 static void _data_source_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource);
43 static void _destroy_data_source(struct wl_resource *resource);
44 static void _destroy_data_device_source(struct wl_listener *listener, void *data EINA_UNUSED);
45 static void _data_device_end_drag_grab(struct wl_seat *seat);
46
47 static void _drag_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp EINA_UNUSED, uint32_t button, uint32_t state_w);
48 static void _drag_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y);
49
50 static void _destroy_drag_focus(struct wl_listener *listener, void *data EINA_UNUSED);
51 static void _drag_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y);
52
53 static void _client_source_accept(struct wl_data_source *source, uint32_t timestamp EINA_UNUSED, const char *mime_type);
54 static void _client_source_send(struct wl_data_source *source, const char *mime_type, int32_t fd);
55 static void _client_source_cancel(struct wl_data_source *source);
56
57 static void _e_comp_wl_cb_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id);
58 static Eina_Bool _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSED);
59 static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED);
60 static Eina_Bool _e_comp_wl_cb_module_idle(void *data EINA_UNUSED);
61 static Eina_Bool _e_comp_wl_cb_keymap_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
62
63 /* compositor interface prototypes */
64 static void _e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id);
65 static void _e_comp_wl_cb_surface_destroy(struct wl_resource *resource);
66 static void _e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id);
67 static void _e_comp_wl_cb_region_destroy(struct wl_resource *resource);
68
69 /* input function prototypes */
70 static Eina_Bool _e_comp_wl_input_init(void);
71 static void _e_comp_wl_input_shutdown(void);
72 static void _e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id);
73 static void _e_comp_wl_input_cb_unbind(struct wl_resource *resource);
74 static struct xkb_keymap *_e_comp_wl_input_keymap_get(void);
75 static int _e_comp_wl_input_keymap_fd_get(off_t size);
76 static E_Wayland_Keyboard_Info *_e_comp_wl_input_keyboard_info_get(struct xkb_keymap *keymap);
77
78 /* input interface prototypes */
79 static void _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
80 static void _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
81 static void _e_comp_wl_input_cb_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
82
83 /* pointer function prototypes */
84 static void _e_comp_wl_pointer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
85 static void _e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
86 static void _e_comp_wl_pointer_unmap(E_Wayland_Surface *ews);
87
88 /* pointer interface prototypes */
89 static void _e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y);
90 static void _e_comp_wl_pointer_cb_release(struct wl_client *client, struct wl_resource *resource);
91
92 /* keyboard interface prototypes */
93 static void _e_comp_wl_keyboard_cb_release(struct wl_client *client, struct wl_resource *resource);
94
95 /* touch interface prototypes */
96 static void _e_comp_wl_touch_cb_release(struct wl_client *client, struct wl_resource *resource);
97
98 /* region interface prototypes */
99 static void _e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource);
100 static void _e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h);
101 static void _e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h);
102
103 /* surface function prototypes */
104 static void _e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
105 static void _e_comp_wl_surface_cb_frame_destroy(struct wl_resource *resource);
106 static void _e_comp_wl_surface_buffer_reference(E_Wayland_Buffer_Reference *ref, E_Wayland_Buffer *buffer);
107 static void _e_comp_wl_surface_buffer_reference_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
108 static E_Wayland_Buffer *_e_comp_wl_surface_buffer_resource(struct wl_resource *resource);
109 static void _e_comp_wl_surface_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
110
111 /* surface interface prototypes */
112 static void _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource);
113 static void _e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int x, int y);
114 static void _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h);
115 static void _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, unsigned int callback);
116 static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource);
117 static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource);
118 static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource);
119 static void _e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int transform EINA_UNUSED);
120 static void _e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int scale EINA_UNUSED);
121
122 /* local wayland interfaces */
123 static const struct wl_compositor_interface _e_compositor_interface = 
124 {
125    _e_comp_wl_cb_surface_create,
126    _e_comp_wl_cb_region_create
127 };
128
129 static const struct wl_seat_interface _e_input_interface = 
130 {
131    _e_comp_wl_input_cb_pointer_get,
132    _e_comp_wl_input_cb_keyboard_get,
133    _e_comp_wl_input_cb_touch_get,
134 };
135
136 static const struct wl_pointer_interface _e_pointer_interface = 
137 {
138    _e_comp_wl_pointer_cb_cursor_set,
139    _e_comp_wl_pointer_cb_release
140 };
141
142 static const struct wl_keyboard_interface _e_keyboard_interface = 
143 {
144    _e_comp_wl_keyboard_cb_release
145 };
146
147 static const struct wl_touch_interface _e_touch_interface = 
148 {
149    _e_comp_wl_touch_cb_release
150 };
151
152 static const struct wl_region_interface _e_region_interface = 
153 {
154    _e_comp_wl_region_cb_destroy,
155    _e_comp_wl_region_cb_add,
156    _e_comp_wl_region_cb_subtract
157 };
158
159 static const struct wl_surface_interface _e_surface_interface = 
160 {
161    _e_comp_wl_surface_cb_destroy,
162    _e_comp_wl_surface_cb_attach,
163    _e_comp_wl_surface_cb_damage,
164    _e_comp_wl_surface_cb_frame,
165    _e_comp_wl_surface_cb_opaque_region_set,
166    _e_comp_wl_surface_cb_input_region_set,
167    _e_comp_wl_surface_cb_commit,
168    _e_comp_wl_surface_cb_buffer_transform_set,
169    _e_comp_wl_surface_cb_buffer_scale_set
170 };
171
172 static const struct wl_pointer_grab_interface _e_pointer_grab_interface = 
173 {
174    _default_grab_focus,
175    _default_grab_motion,
176    _default_grab_button
177 };
178
179 static const struct wl_keyboard_grab_interface _e_default_keyboard_grab_interface = 
180 {
181    _default_grab_key,
182    _default_grab_modifiers,
183 };
184
185 static const struct wl_data_offer_interface _e_data_offer_interface = 
186 {
187    _data_offer_accept,
188    _data_offer_receive,
189    _data_offer_destroy,
190 };
191
192 static const struct wl_data_device_manager_interface _e_manager_interface = 
193 {
194    _create_data_source,
195    _get_data_device
196 };
197
198 static const struct wl_data_device_interface _e_data_device_interface = 
199 {
200    _data_device_start_drag,
201    _data_device_set_selection,
202 };
203
204 static const struct wl_touch_grab_interface _e_default_touch_grab_interface = 
205 {
206    _default_grab_touch_down,
207    _default_grab_touch_up,
208    _default_grab_touch_motion
209 };
210
211 static struct wl_data_source_interface _e_data_source_interface = 
212 {
213    _data_source_offer,
214    _data_source_destroy
215 };
216
217 static const struct wl_pointer_grab_interface _e_drag_grab_interface = 
218 {
219    _drag_grab_focus,
220    _drag_grab_motion,
221    _drag_grab_button,
222 };
223
224 /* local variables */
225 static Ecore_Idler *_module_idler = NULL;
226
227 /* external variables */
228 EAPI E_Wayland_Compositor *_e_wl_comp;
229
230 /* external functions */
231 EINTERN Eina_Bool 
232 e_comp_wl_init(void)
233 {
234    int fd = 0;
235
236    /* try to allocate space for a new compositor */
237    if (!(_e_wl_comp = E_NEW(E_Wayland_Compositor, 1)))
238      return EINA_FALSE;
239
240    /* try to create a wayland display */
241    if (!(_e_wl_comp->wl.display = wl_display_create()))
242      {
243         ERR("Could not create a Wayland Display: %m");
244         goto err;
245      }
246
247    /* init compositor signals */
248    wl_signal_init(&_e_wl_comp->signals.destroy);
249    wl_signal_init(&_e_wl_comp->signals.activate);
250    wl_signal_init(&_e_wl_comp->signals.kill);
251    wl_signal_init(&_e_wl_comp->signals.seat);
252
253    /* try to add compositor to the displays globals */
254    if (!wl_global_create(_e_wl_comp->wl.display, &wl_compositor_interface, 3, 
255                          _e_wl_comp, _e_comp_wl_cb_bind))
256      {
257         ERR("Could not add compositor to globals: %m");
258         goto err;
259      }
260
261    /* init data device manager */
262    wl_data_device_manager_init(_e_wl_comp->wl.display);
263
264    /* try to init shm mechanism */
265    if (wl_display_init_shm(_e_wl_comp->wl.display) < 0)
266      ERR("Could not initialize SHM: %m");
267
268 #ifdef HAVE_WAYLAND_EGL
269    /* try to get the egl display
270     * 
271     * NB: This is interesting....if we try to eglGetDisplay and pass in the 
272     * wayland display, then EGL fails due to XCB not owning the event queue.
273     * If we pass it a NULL, it inits just fine */
274    _e_wl_comp->egl.display = eglGetDisplay((EGLNativeDisplayType)ecore_x_display_get());
275    if (_e_wl_comp->egl.display == EGL_NO_DISPLAY)
276      ERR("Could not get EGL display: %m");
277    else
278      {
279         EGLint major, minor;
280
281         /* try to initialize egl */
282         if (!eglInitialize(_e_wl_comp->egl.display, &major, &minor))
283           {
284              ERR("Could not initialize EGL: %m");
285              eglTerminate(_e_wl_comp->egl.display);
286           }
287         else
288           {
289              EGLint n;
290              EGLint attribs[] = 
291                {
292                   EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 
293                   EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, 
294                   EGL_ALPHA_SIZE, 1, EGL_RENDERABLE_TYPE, 
295                   EGL_OPENGL_ES2_BIT, EGL_NONE
296                };
297              /* const char *exts; */
298
299              if ((!eglChooseConfig(_e_wl_comp->egl.display, attribs, 
300                                    &_e_wl_comp->egl.config, 1, &n) || (n == 0)))
301                {
302                   ERR("Could not choose EGL config: %m");
303                   eglTerminate(_e_wl_comp->egl.display);
304                }
305
306              /* if (!eglBindAPI(EGL_OPENGL_ES_API)) */
307              /*   { */
308              /*      ERR("Could not bind EGL API: %m"); */
309              /*      eglTerminate(_e_wl_comp->egl.display); */
310              /*   } */
311
312              /* exts = (const char *)eglQueryString(_e_wl_comp->egl.display, EGL_EXTENSIONS); */
313              /* if (!exts) */
314              /*   { */
315              /*      ERR("Could not get EGL Extensions: %m"); */
316              /*      eglTerminate(_e_wl_comp->egl.display); */
317              /*   } */
318              /* else */
319              /*   { */
320              /*      if (strstr(exts, "EGL_WL_bind_wayland_display")) */
321              /*        { */
322              /*           _e_wl_comp->egl.bind_display =  */
323              /*             (void *)eglGetProcAddress("eglBindWaylandDisplayWL"); */
324              /*           _e_wl_comp->egl.unbind_display =  */
325              /*             (void *)eglGetProcAddress("eglUnbindWaylandDisplayWL"); */
326              /*        } */
327              /*   } */
328
329              /* if (_e_wl_comp->egl.bind_display) */
330              /*   { */
331              /*      EGLBoolean ret; */
332
333              /*      ret = _e_wl_comp->egl.bind_display(_e_wl_comp->egl.display,  */
334              /*                                         _e_wl_comp->wl.display); */
335              /*      if (!ret) */
336              /*        { */
337              /*           ERR("Could not bind EGL Wayland Display: %m"); */
338              /*           _e_wl_comp->egl.bound = EINA_FALSE; */
339              /*        } */
340              /*      else */
341              /*        _e_wl_comp->egl.bound = EINA_TRUE; */
342              /*   } */
343           }
344      }
345 #endif
346
347    /* try to initialize input */
348    if (!_e_comp_wl_input_init())
349      {
350         ERR("Could not initialize input: %m");
351         goto err;
352      }
353
354    /* setup keymap_change event handler */
355    _e_wl_comp->kbd_handler = 
356      ecore_event_handler_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, 
357                              _e_comp_wl_cb_keymap_changed, NULL);
358
359    /* get the displays event loop */
360    _e_wl_comp->wl.loop = wl_display_get_event_loop(_e_wl_comp->wl.display);
361
362    /* get the event loop's file descriptor so we can listen on it */
363    fd = wl_event_loop_get_fd(_e_wl_comp->wl.loop);
364
365    /* add the fd to E's main loop */
366    _e_wl_comp->fd_handler = 
367      ecore_main_fd_handler_add(fd, ECORE_FD_READ, 
368                                _e_comp_wl_cb_read, NULL, NULL, NULL);
369
370    /* add an idler for flushing clients */
371    _e_wl_comp->idler = ecore_idle_enterer_add(_e_comp_wl_cb_idle, NULL);
372
373    /* TODO: event handlers ?? */
374
375    /* try to add a display socket */
376    if (wl_display_add_socket(_e_wl_comp->wl.display, NULL) < 0)
377      {
378         ERR("Could not add a Wayland Display socket: %m");
379         goto err;
380      }
381
382    /* add an idler for deferred shell module loading */
383    _module_idler = ecore_idler_add(_e_comp_wl_cb_module_idle, NULL);
384
385    /* return success */
386    return EINA_TRUE;
387
388 err:
389    /* remove kbd handler */
390    if (_e_wl_comp->kbd_handler) 
391      ecore_event_handler_del(_e_wl_comp->kbd_handler);
392
393    /* remove the module idler */
394    if (_module_idler) ecore_idler_del(_module_idler);
395
396 #ifdef HAVE_WAYLAND_EGL
397    /* unbind wayland display */
398    if (_e_wl_comp->egl.bound)
399      _e_wl_comp->egl.unbind_display(_e_wl_comp->egl.display, _e_wl_comp->wl.display);
400
401    /* terminate the egl display */
402    if (_e_wl_comp->egl.display) eglTerminate(_e_wl_comp->egl.display);
403
404    eglReleaseThread();
405 #endif
406
407    /* if we have a display, destroy it */
408    if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display);
409
410    /* free the compositor */
411    E_FREE(_e_wl_comp);
412
413    /* return failure */
414    return EINA_FALSE;
415 }
416
417 EINTERN void 
418 e_comp_wl_shutdown(void)
419 {
420    E_Module *mod = NULL;
421
422    if (_e_wl_comp)
423      {
424         /* remove the idler */
425         if (_e_wl_comp->idler) ecore_idler_del(_e_wl_comp->idler);
426
427         /* remove the fd handler */
428         if (_e_wl_comp->fd_handler)
429           ecore_main_fd_handler_del(_e_wl_comp->fd_handler);
430
431         /* shutdown input */
432         _e_comp_wl_input_shutdown();
433
434 #ifdef HAVE_WAYLAND_EGL
435         /* unbind wayland display */
436         if (_e_wl_comp->egl.bound)
437           _e_wl_comp->egl.unbind_display(_e_wl_comp->egl.display, _e_wl_comp->wl.display);
438
439         /* terminate the egl display */
440         if (_e_wl_comp->egl.display) eglTerminate(_e_wl_comp->egl.display);
441
442         eglReleaseThread();
443 #endif
444
445         /* if we have a display, destroy it */
446         if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display);
447
448         /* free the compositor */
449         E_FREE(_e_wl_comp);
450      }
451
452    /* disable the loaded shell module */
453    /* TODO: we should have a config variable somewhere to store which 
454     * shell we want to unload (tablet, mobile, etc) */
455    if ((mod = e_module_find("wl_desktop_shell")))
456      e_module_disable(mod);
457 }
458
459 EAPI void 
460 wl_seat_init(struct wl_seat *seat)
461 {
462    memset(seat, 0, sizeof *seat);
463
464    wl_signal_init(&seat->destroy_signal);
465
466    seat->selection_data_source = NULL;
467    wl_list_init(&seat->base_resource_list);
468    wl_signal_init(&seat->selection_signal);
469    wl_list_init(&seat->drag_resource_list);
470    wl_signal_init(&seat->drag_icon_signal);
471 }
472
473 EAPI void 
474 wl_seat_release(struct wl_seat *seat)
475 {
476    /* if (seat->pointer) */
477    /*   { */
478    /*      if (seat->pointer->focus) */
479    /*        wl_list_remove(&seat->pointer->focus_listener.link); */
480    /*   } */
481
482    /* if (seat->keyboard) */
483    /*   { */
484    /*      if (seat->keyboard->focus) */
485    /*        wl_list_remove(&seat->keyboard->focus_listener.link); */
486    /*   } */
487
488    /* if (seat->touch) */
489    /*   { */
490    /*      if (seat->touch->focus) */
491    /*        wl_list_remove(&seat->touch->focus_listener.link); */
492    /*   } */
493
494    wl_signal_emit(&seat->destroy_signal, seat);
495 }
496
497 EAPI void 
498 wl_seat_set_pointer(struct wl_seat *seat, struct wl_pointer *pointer)
499 {
500    if (pointer && (seat->pointer || pointer->seat)) return; /* XXX: error? */
501    if (!pointer && !seat->pointer) return;
502
503    seat->pointer = pointer;
504    if (pointer) pointer->seat = seat;
505
506    _seat_send_updated_caps(seat);
507 }
508
509 EAPI void 
510 wl_seat_set_keyboard(struct wl_seat *seat, struct wl_keyboard *keyboard)
511 {
512    if (keyboard && (seat->keyboard || keyboard->seat)) return; /* XXX: error? */
513    if (!keyboard && !seat->keyboard) return;
514
515    seat->keyboard = keyboard;
516    if (keyboard) keyboard->seat = seat;
517
518    _seat_send_updated_caps(seat);
519 }
520
521 EAPI void 
522 wl_seat_set_touch(struct wl_seat *seat, struct wl_touch *touch)
523 {
524    if (touch && (seat->touch || touch->seat)) return; /* XXX: error? */
525    if (!touch && !seat->touch) return;
526
527    seat->touch = touch;
528    if (touch) touch->seat = seat;
529
530    _seat_send_updated_caps(seat);
531 }
532
533 EAPI void 
534 wl_pointer_init(struct wl_pointer *pointer)
535 {
536    memset(pointer, 0, sizeof *pointer);
537    wl_list_init(&pointer->resource_list);
538    wl_list_init(&pointer->focus_resource_list);
539    pointer->default_grab.interface = &_e_pointer_grab_interface;
540    pointer->default_grab.pointer = pointer;
541    pointer->grab = &pointer->default_grab;
542    wl_signal_init(&pointer->focus_signal);
543
544    pointer->x = wl_fixed_from_int(100);
545    pointer->y = wl_fixed_from_int(100);
546 }
547
548 EAPI void 
549 wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_resource *surface, wl_fixed_t sx, wl_fixed_t sy)
550 {
551    struct wl_keyboard *kbd = pointer->seat->keyboard;
552    struct wl_resource *res;
553    struct wl_list *lst;
554    uint32_t serial;
555
556    lst = &pointer->focus_resource_list;
557    if ((!wl_list_empty(lst)) && (pointer->focus != surface))
558      {
559         serial = wl_display_next_serial(_e_wl_comp->wl.display);
560         wl_resource_for_each(res, lst)
561           wl_pointer_send_leave(res, serial, pointer->focus);
562
563         _move_resources(&pointer->resource_list, lst);
564      }
565
566    if ((_find_resource_for_surface(&pointer->resource_list, surface)) && 
567        (pointer->focus != surface))
568      {
569         struct wl_client *client;
570
571         client = wl_resource_get_client(surface);
572         _move_resources_for_client(lst, &pointer->resource_list, client);
573
574         wl_resource_for_each(res, lst)
575           wl_pointer_send_enter(res, serial, surface, sx, sy);
576
577         pointer->focus_serial = serial;
578      }
579
580    if ((kbd) && (surface) && (kbd->focus != pointer->focus))
581      {
582         struct wl_client *client;
583
584         client = wl_resource_get_client(surface);
585
586         wl_resource_for_each(res, &kbd->resource_list)
587           {
588              if (wl_resource_get_client(res) == client)
589                wl_keyboard_send_modifiers(res, serial,
590                                           kbd->modifiers.mods_depressed,
591                                           kbd->modifiers.mods_latched,
592                                           kbd->modifiers.mods_locked,
593                                           kbd->modifiers.group);
594           }
595      }
596
597    pointer->focus = surface;
598    pointer->default_grab.focus = surface;
599    wl_signal_emit(&pointer->focus_signal, pointer);
600 }
601
602 EAPI void 
603 wl_pointer_start_grab(struct wl_pointer *pointer, struct wl_pointer_grab *grab)
604 {
605    const struct wl_pointer_grab_interface *interface;
606
607    pointer->grab = grab;
608    interface = pointer->grab->interface;
609    grab->pointer = pointer;
610
611    if (pointer->current)
612      interface->focus(pointer->grab, pointer->current,
613                        pointer->current_x, pointer->current_y);
614 }
615
616 EAPI void 
617 wl_pointer_end_grab(struct wl_pointer *pointer)
618 {
619    const struct wl_pointer_grab_interface *interface;
620
621    pointer->grab = &pointer->default_grab;
622    interface = pointer->grab->interface;
623    interface->focus(pointer->grab, pointer->current,
624                     pointer->current_x, pointer->current_y);
625 }
626
627 EAPI void 
628 wl_keyboard_init(struct wl_keyboard *keyboard)
629 {
630    memset(keyboard, 0, sizeof *keyboard);
631    wl_list_init(&keyboard->resource_list);
632    wl_array_init(&keyboard->keys);
633    wl_list_init(&keyboard->focus_resource_list);
634    keyboard->default_grab.interface = &_e_default_keyboard_grab_interface;
635    keyboard->default_grab.keyboard = keyboard;
636    keyboard->grab = &keyboard->default_grab;
637    wl_signal_init(&keyboard->focus_signal);
638 }
639
640 EAPI void 
641 wl_keyboard_set_focus(struct wl_keyboard *keyboard, struct wl_resource *surface)
642 {
643    struct wl_resource *res;
644    struct wl_list *lst;
645    uint32_t serial;
646
647    lst = &keyboard->focus_resource_list;
648
649    if ((!wl_list_empty(lst)) && (keyboard->focus != surface))
650      {
651         serial = wl_display_next_serial(_e_wl_comp->wl.display);
652
653         wl_resource_for_each(res, lst)
654           wl_keyboard_send_leave(res, serial, keyboard->focus);
655
656         _move_resources(&keyboard->resource_list, lst);
657      }
658
659    if ((_find_resource_for_surface(&keyboard->resource_list, surface)) && 
660        (keyboard->focus != surface))
661      {       
662         struct wl_client *client;
663
664         client = wl_resource_get_client(surface);
665         serial = wl_display_next_serial(_e_wl_comp->wl.display);
666
667         _move_resources_for_client(lst, &keyboard->resource_list, client);
668
669         wl_resource_for_each(res, lst)
670           {
671              wl_keyboard_send_modifiers(res, serial,
672                                         keyboard->modifiers.mods_depressed,
673                                         keyboard->modifiers.mods_latched,
674                                         keyboard->modifiers.mods_locked,
675                                         keyboard->modifiers.group);
676              wl_keyboard_send_enter(res, serial, surface, &keyboard->keys);
677           }
678
679         keyboard->focus_serial = serial;
680      }
681
682    keyboard->focus = surface;
683    wl_signal_emit(&keyboard->focus_signal, keyboard);
684 }
685
686 EAPI void 
687 wl_keyboard_start_grab(struct wl_keyboard *device, struct wl_keyboard_grab *grab)
688 {
689    device->grab = grab;
690    grab->keyboard = device;
691 }
692
693 EAPI void 
694 wl_keyboard_end_grab(struct wl_keyboard *keyboard)
695 {
696    keyboard->grab = &keyboard->default_grab;
697 }
698
699 EAPI void 
700 wl_touch_init(struct wl_touch *touch)
701 {
702    memset(touch, 0, sizeof *touch);
703    wl_list_init(&touch->resource_list);
704    wl_list_init(&touch->focus_resource_list);
705    touch->default_grab.interface = &_e_default_touch_grab_interface;
706    touch->default_grab.touch = touch;
707    touch->grab = &touch->default_grab;
708    wl_signal_init(&touch->focus_signal);
709 }
710
711 EAPI void 
712 wl_touch_start_grab(struct wl_touch *device, struct wl_touch_grab *grab)
713 {
714    device->grab = grab;
715    grab->touch = device;
716 }
717
718 EAPI void 
719 wl_touch_end_grab(struct wl_touch *touch)
720 {
721    touch->grab = &touch->default_grab;
722 }
723
724 EAPI void 
725 wl_data_device_set_keyboard_focus(struct wl_seat *seat)
726 {
727    struct wl_resource *data_device, *focus, *offer;
728    struct wl_data_source *source;
729
730    if (!seat->keyboard) return;
731
732    focus = seat->keyboard->focus;
733    if (!focus) return;
734
735    data_device = 
736      wl_resource_find_for_client(&seat->drag_resource_list, 
737                                  wl_resource_get_client(focus));
738    if (!data_device) return;
739
740    source = seat->selection_data_source;
741    if (source) 
742      {
743         offer = wl_data_source_send_offer(source, data_device);
744         wl_data_device_send_selection(data_device, offer);
745      }
746 }
747
748 EAPI int 
749 wl_data_device_manager_init(struct wl_display *display)
750 {
751    if (!wl_global_create(display, &wl_data_device_manager_interface, 1, 
752                          NULL, _bind_manager))
753      return -1;
754    return 0;
755 }
756
757 EAPI struct wl_resource *
758 wl_data_source_send_offer(struct wl_data_source *source, struct wl_resource *target)
759 {
760    struct wl_data_offer *offer;
761    char **p;
762
763    offer = malloc(sizeof *offer);
764    if (offer == NULL) return NULL;
765
766    offer->resource = 
767      wl_resource_create(wl_resource_get_client(target),
768                         &wl_data_offer_interface, 1, 0);
769    if (!offer->resource)
770      {
771         free(offer);
772         return NULL;
773      }
774
775    wl_resource_set_implementation(offer->resource, &_e_data_offer_interface, 
776                                   offer, _destroy_data_offer);
777
778    offer->source = source;
779    offer->source_destroy_listener.notify = _destroy_offer_data_source;
780    wl_signal_add(&source->destroy_signal,
781                  &offer->source_destroy_listener);
782
783    wl_data_device_send_data_offer(target, offer->resource);
784
785    wl_array_for_each(p, &source->mime_types)
786      wl_data_offer_send_offer(offer->resource, *p);
787
788    return offer->resource;
789 }
790
791 EAPI void
792 wl_seat_set_selection(struct wl_seat *seat, struct wl_data_source *source, uint32_t serial)
793 {
794    struct wl_resource *data_device, *offer;
795    struct wl_resource *focus = NULL;
796
797    if (seat->selection_data_source &&
798        seat->selection_serial - serial < UINT32_MAX / 2)
799      return;
800
801    if (seat->selection_data_source) 
802      {
803         seat->selection_data_source->cancel(seat->selection_data_source);
804         wl_list_remove(&seat->selection_data_source_listener.link);
805         seat->selection_data_source = NULL;
806      }
807
808    seat->selection_data_source = source;
809    seat->selection_serial = serial;
810    if (seat->keyboard)
811      focus = seat->keyboard->focus;
812    if (focus) 
813      {
814         data_device = 
815           wl_resource_find_for_client(&seat->drag_resource_list, 
816                                       wl_resource_get_client(focus));
817         if (data_device && source) 
818           {
819              offer = wl_data_source_send_offer(seat->selection_data_source,
820                                                data_device);
821              wl_data_device_send_selection(data_device, offer);
822           }
823         else if (data_device) 
824           {
825              wl_data_device_send_selection(data_device, NULL);
826           }
827      }
828
829    wl_signal_emit(&seat->selection_signal, seat);
830    if (source) 
831      {
832         seat->selection_data_source_listener.notify =
833           _destroy_selection_data_source;
834         wl_signal_add(&source->destroy_signal,
835                       &seat->selection_data_source_listener);
836      }
837 }
838
839 EAPI unsigned int 
840 e_comp_wl_time_get(void)
841 {
842    struct timeval tm;
843
844    gettimeofday(&tm, NULL);
845    return (tm.tv_sec * 1000 + tm.tv_usec / 1000);
846 }
847
848 EAPI void 
849 e_comp_wl_input_modifiers_update(unsigned int serial)
850 {
851    struct wl_keyboard *kbd;
852    struct wl_keyboard_grab *grab;
853    unsigned int pressed = 0, latched = 0, locked = 0, group = 0;
854    Eina_Bool changed = EINA_FALSE;
855
856    /* check for valid keyboard */
857    if (!(kbd = _e_wl_comp->input->wl.seat.keyboard)) 
858      return;
859
860    /* try to get the current keyboard's grab interface. 
861     * Fallback to the default grab */
862    if (!(grab = kbd->grab)) grab = &kbd->default_grab;
863
864    pressed = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, 
865                                       XKB_STATE_DEPRESSED);
866    latched = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, 
867                                       XKB_STATE_LATCHED);
868    locked = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, 
869                                      XKB_STATE_LOCKED);
870    group = xkb_state_serialize_group(_e_wl_comp->input->xkb.state, 
871                                      XKB_STATE_EFFECTIVE);
872
873    if ((pressed != kbd->modifiers.mods_depressed) || 
874        (latched != kbd->modifiers.mods_latched) || 
875        (locked != kbd->modifiers.mods_locked) || 
876        (group != kbd->modifiers.group))
877      changed = EINA_TRUE;
878
879    kbd->modifiers.mods_depressed = pressed;
880    kbd->modifiers.mods_latched = latched;
881    kbd->modifiers.mods_locked = locked;
882    kbd->modifiers.group = group;
883
884    /* TODO: update leds ? */
885
886    if (changed)
887      grab->interface->modifiers(grab, serial, 
888                                 kbd->modifiers.mods_depressed, 
889                                 kbd->modifiers.mods_latched, 
890                                 kbd->modifiers.mods_locked,
891                                 kbd->modifiers.group);
892 }
893
894 /* local functions */
895 static void
896 _seat_send_updated_caps(struct wl_seat *seat)
897 {
898    struct wl_resource *res;
899    enum wl_seat_capability caps = 0;
900
901    if (seat->pointer)
902      caps |= WL_SEAT_CAPABILITY_POINTER;
903    if (seat->keyboard)
904      caps |= WL_SEAT_CAPABILITY_KEYBOARD;
905    if (seat->touch)
906      caps |= WL_SEAT_CAPABILITY_TOUCH;
907
908    wl_resource_for_each(res, &seat->base_resource_list)
909      wl_seat_send_capabilities(res, caps);
910 }
911
912 static void 
913 _move_resources(struct wl_list *dest, struct wl_list *src)
914 {
915    wl_list_insert_list(dest, src);
916    wl_list_init(src);
917 }
918
919 static void 
920 _move_resources_for_client(struct wl_list *dest, struct wl_list *src, struct wl_client *client)
921 {
922    struct wl_resource *res, *tmp;
923
924    wl_resource_for_each_safe(res, tmp, src)
925      {
926         if (wl_resource_get_client(res) == client)
927           {
928              wl_list_remove(wl_resource_get_link(res));
929              wl_list_insert(dest, wl_resource_get_link(res));
930           }
931      }
932 }
933
934 static struct wl_resource *
935 _find_resource_for_surface(struct wl_list *list, struct wl_resource *surface)
936 {
937    if (!surface) return NULL;
938
939    return wl_resource_find_for_client(list, wl_resource_get_client(surface));
940 }
941
942 static void
943 _default_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y)
944 {
945    struct wl_pointer *pointer = grab->pointer;
946
947    if (pointer->button_count > 0) return;
948
949    wl_pointer_set_focus(pointer, surface, x, y);
950 }
951
952 static void
953 _default_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y)
954 {
955    struct wl_list *lst;
956    struct wl_resource *res;
957
958    lst = &grab->pointer->focus_resource_list;
959    wl_resource_for_each(res, lst)
960      wl_pointer_send_motion(res, timestamp, x, y);
961 }
962
963 static void
964 _default_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp, uint32_t button, uint32_t state_w)
965 {
966    struct wl_pointer *pointer = grab->pointer;
967    struct wl_list *lst;
968    struct wl_resource *res;
969    enum wl_pointer_button_state state = state_w;
970
971    lst = &pointer->focus_resource_list;
972    if (!wl_list_empty(lst))
973      {
974         uint32_t serial;
975
976         serial = wl_display_next_serial(_e_wl_comp->wl.display);
977
978         wl_resource_for_each(res, lst)
979           {
980              switch (button)
981                {
982                 case BTN_LEFT:
983                 case BTN_MIDDLE:
984                 case BTN_RIGHT:
985                   wl_pointer_send_button(res, serial, timestamp, 
986                                          button, state_w);
987                   break;
988                 case 4:
989                   if (state_w)
990                     wl_pointer_send_axis(res, timestamp, 
991                                          WL_POINTER_AXIS_VERTICAL_SCROLL, 
992                                          -wl_fixed_from_int(1));
993                   break;
994                 case 5:
995                   if (state_w)
996                     wl_pointer_send_axis(res, timestamp, 
997                                          WL_POINTER_AXIS_VERTICAL_SCROLL, 
998                                          wl_fixed_from_int(1));
999                   break;
1000                 case 6:
1001                   if (state_w)
1002                     wl_pointer_send_axis(res, timestamp, 
1003                                          WL_POINTER_AXIS_HORIZONTAL_SCROLL, 
1004                                          -wl_fixed_from_int(1));
1005                   break;
1006                 case 7:
1007                   if (state_w)
1008                     wl_pointer_send_axis(res, timestamp, 
1009                                          WL_POINTER_AXIS_HORIZONTAL_SCROLL, 
1010                                          wl_fixed_from_int(1));
1011                   break;
1012                }
1013           }
1014      }
1015
1016    if (pointer->button_count == 0 &&
1017        state == WL_POINTER_BUTTON_STATE_RELEASED)
1018      wl_pointer_set_focus(pointer, pointer->current,
1019                           pointer->current_x, pointer->current_y);
1020 }
1021
1022 static void 
1023 _default_grab_touch_down(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1024 {
1025    struct wl_resource *res;
1026    struct wl_list *lst;
1027    struct wl_touch *touch = grab->touch;
1028
1029    lst = &touch->focus_resource_list;
1030    if (!wl_list_empty(lst) && (touch->focus))
1031      {
1032         uint32_t serial;
1033
1034         serial = wl_display_next_serial(_e_wl_comp->wl.display);
1035         wl_resource_for_each(res, lst)
1036           wl_touch_send_down(res, serial, timestamp,
1037                              touch->focus, touch_id, sx, sy);
1038      }
1039 }
1040
1041 static void 
1042 _default_grab_touch_up(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id)
1043 {
1044    struct wl_resource *res;
1045    struct wl_list *lst;
1046    struct wl_touch *touch = grab->touch;
1047
1048    lst = &touch->focus_resource_list;
1049    if (!wl_list_empty(lst) && (touch->focus))
1050      {
1051         uint32_t serial;
1052
1053         serial = wl_display_next_serial(_e_wl_comp->wl.display);
1054         wl_resource_for_each(res, lst)
1055           wl_touch_send_up(res, serial, timestamp, touch_id);
1056      }
1057 }
1058
1059 static void 
1060 _default_grab_touch_motion(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1061 {
1062    struct wl_resource *res;
1063    struct wl_list *lst;
1064    struct wl_touch *touch = grab->touch;
1065
1066    lst = &touch->focus_resource_list;
1067    wl_resource_for_each(res, lst)
1068      wl_touch_send_motion(res, timestamp, touch_id, sx, sy);
1069 }
1070
1071 static void
1072 _data_offer_accept(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *mime_type)
1073 {
1074    struct wl_data_offer *offer;
1075
1076    offer = wl_resource_get_user_data(resource);
1077
1078    if (offer->source)
1079      offer->source->accept(offer->source, serial, mime_type);
1080 }
1081
1082 static void
1083 _data_offer_receive(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type, int32_t fd)
1084 {
1085    struct wl_data_offer *offer;
1086
1087    offer = wl_resource_get_user_data(resource);
1088
1089    if (offer->source)
1090      offer->source->send(offer->source, mime_type, fd);
1091    else
1092      close(fd);
1093 }
1094
1095 static void
1096 _data_offer_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1097 {
1098    wl_resource_destroy(resource);
1099 }
1100
1101 static void
1102 _destroy_data_offer(struct wl_resource *resource)
1103 {
1104    struct wl_data_offer *offer;
1105
1106    offer = wl_resource_get_user_data(resource);
1107
1108    if (offer->source)
1109      wl_list_remove(&offer->source_destroy_listener.link);
1110    free(offer);
1111 }
1112
1113 static void
1114 _destroy_offer_data_source(struct wl_listener *listener, void *data EINA_UNUSED)
1115 {
1116    struct wl_data_offer *offer;
1117
1118    offer = container_of(listener, struct wl_data_offer,
1119                         source_destroy_listener);
1120    offer->source = NULL;
1121 }
1122
1123 static void
1124 _create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id)
1125 {
1126    struct wl_data_source *source;
1127
1128    source = malloc(sizeof *source);
1129    if (source == NULL) 
1130      {
1131         wl_resource_post_no_memory(resource);
1132         return;
1133      }
1134
1135    wl_signal_init(&source->destroy_signal);
1136    source->accept = _client_source_accept;
1137    source->send = _client_source_send;
1138    source->cancel = _client_source_cancel;
1139
1140    wl_array_init(&source->mime_types);
1141
1142    source->resource = 
1143      wl_resource_create(client, &wl_data_source_interface, 1, id);
1144
1145    wl_resource_set_implementation(source->resource, 
1146                                   &_e_data_source_interface, source, 
1147                                   _destroy_data_source);
1148 }
1149
1150 static void 
1151 _unbind_data_device(struct wl_resource *resource)
1152 {
1153    wl_list_remove(wl_resource_get_link(resource));
1154 }
1155
1156 static void
1157 _get_data_device(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource)
1158 {
1159    struct wl_seat *seat;
1160    struct wl_resource *resource;
1161
1162    seat = wl_resource_get_user_data(seat_resource);
1163
1164    resource = 
1165      wl_resource_create(client, &wl_data_device_interface, 1, id);
1166    if (!resource)
1167      {
1168         wl_resource_post_no_memory(manager_resource);
1169         return;
1170      }
1171
1172    wl_list_insert(&seat->drag_resource_list, wl_resource_get_link(resource));
1173
1174    wl_resource_set_implementation(resource, &_e_data_device_interface, seat, 
1175                                   _unbind_data_device);
1176
1177 }
1178
1179 static void
1180 _current_surface_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
1181 {
1182    struct wl_pointer *pointer =
1183      container_of(listener, struct wl_pointer, current_listener);
1184    pointer->current = NULL;
1185 }
1186
1187 static void
1188 _bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
1189 {
1190    struct wl_resource *res;
1191
1192    res = wl_resource_create(client, &wl_data_device_manager_interface, 1, id);
1193    if (!res)
1194      {
1195         wl_client_post_no_memory(client);
1196         return;
1197      }
1198
1199    wl_resource_set_implementation(res, &_e_manager_interface, NULL, NULL);
1200 }
1201
1202 static void
1203 _default_grab_key(struct wl_keyboard_grab *grab, uint32_t timestamp, uint32_t key, uint32_t state)
1204 {
1205    struct wl_keyboard *keyboard = grab->keyboard;
1206    struct wl_resource *res;
1207    struct wl_list *lst;
1208
1209    lst = &keyboard->focus_resource_list;
1210    if (!wl_list_empty(lst))
1211      {
1212         uint32_t serial;
1213
1214         serial = wl_display_next_serial(_e_wl_comp->wl.display);
1215         wl_resource_for_each(res, lst)
1216           wl_keyboard_send_key(res, serial, timestamp, key, state);
1217      }
1218 }
1219
1220 static void
1221 _default_grab_modifiers(struct wl_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
1222 {
1223    struct wl_keyboard *keyboard = grab->keyboard;
1224    struct wl_pointer *pointer = keyboard->seat->pointer;
1225    struct wl_resource *res;
1226    struct wl_list *lst;
1227
1228    lst = &keyboard->focus_resource_list;
1229    wl_resource_for_each(res, lst)
1230      wl_keyboard_send_modifiers(res, serial, mods_depressed, mods_latched,
1231                                 mods_locked, group);
1232
1233    if (pointer && pointer->focus && pointer->focus != keyboard->focus) 
1234      {
1235         struct wl_client *client;
1236
1237         lst = &keyboard->resource_list;
1238         client = wl_resource_get_client(pointer->focus);
1239         wl_resource_for_each(res, lst)
1240           {
1241              if (wl_resource_get_client(res) == client)
1242                wl_keyboard_send_modifiers(res, serial, mods_depressed, 
1243                                           mods_latched, mods_locked, group);
1244           }
1245      }
1246 }
1247
1248 static void
1249 _data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t serial EINA_UNUSED)
1250 {
1251    struct wl_seat *seat;
1252
1253    seat = wl_resource_get_user_data(resource);
1254
1255    if ((seat->pointer->button_count == 0) || 
1256        (seat->pointer->grab_serial != serial) || 
1257        (seat->pointer->focus != wl_resource_get_user_data(origin_resource)))
1258      return;
1259
1260    seat->drag_grab.interface = &_e_drag_grab_interface;
1261    seat->drag_client = client;
1262    seat->drag_data_source = NULL;
1263
1264    if (source_resource) 
1265      {
1266         struct wl_data_source *source;
1267
1268         source = wl_resource_get_user_data(source_resource);
1269         seat->drag_data_source = source;
1270         seat->drag_data_source_listener.notify =
1271           _destroy_data_device_source;
1272         wl_signal_add(&source->destroy_signal,
1273                       &seat->drag_data_source_listener);
1274        }
1275
1276    if (icon_resource) 
1277      {
1278         E_Wayland_Surface *icon;
1279
1280         icon = wl_resource_get_user_data(icon_resource);
1281
1282         seat->drag_surface = icon->wl.surface;
1283         seat->drag_icon_listener.notify = _destroy_data_device_icon;
1284         wl_signal_add(&icon->wl.destroy_signal,
1285                       &seat->drag_icon_listener);
1286         /* wl_signal_emit(&seat->drag_icon_signal, icon_resource); */
1287      }
1288
1289    wl_pointer_set_focus(seat->pointer, NULL,
1290                         wl_fixed_from_int(0), wl_fixed_from_int(0));
1291    wl_pointer_start_grab(seat->pointer, &seat->drag_grab);
1292 }
1293
1294 static void
1295 _data_device_set_selection(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *source_resource, uint32_t serial)
1296 {
1297    struct wl_data_source *source;
1298    struct wl_seat *seat;
1299
1300    if (!(seat = wl_resource_get_user_data(resource))) return;
1301    source = wl_resource_get_user_data(source_resource);
1302
1303    wl_seat_set_selection(seat, source, serial);
1304 }
1305
1306 static void
1307 _destroy_data_device_icon(struct wl_listener *listener, void *data EINA_UNUSED)
1308 {
1309    struct wl_seat *seat = 
1310      container_of(listener, struct wl_seat, drag_icon_listener);
1311
1312    seat->drag_surface = NULL;
1313 }
1314
1315 static void
1316 _destroy_selection_data_source(struct wl_listener *listener, void *data EINA_UNUSED)
1317 {
1318    struct wl_seat *seat = 
1319      container_of(listener, struct wl_seat, selection_data_source_listener);
1320    struct wl_resource *data_device;
1321    struct wl_resource *focus = NULL;
1322
1323    seat->selection_data_source = NULL;
1324
1325    if (seat->keyboard)
1326      focus = seat->keyboard->focus;
1327
1328    if (focus)
1329      {
1330         data_device = 
1331           wl_resource_find_for_client(&seat->drag_resource_list,
1332                                     wl_resource_get_client(focus));
1333         if (data_device)
1334           wl_data_device_send_selection(data_device, NULL);
1335      }
1336
1337    wl_signal_emit(&seat->selection_signal, seat);
1338 }
1339
1340 static void
1341 _destroy_data_device_source(struct wl_listener *listener, void *data EINA_UNUSED)
1342 {
1343    struct wl_seat *seat = 
1344      container_of(listener, struct wl_seat, drag_data_source_listener);
1345    _data_device_end_drag_grab(seat);
1346 }
1347
1348 static void
1349 _data_source_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *type)
1350 {
1351    struct wl_data_source *source;
1352    char **p;
1353
1354    source = wl_resource_get_user_data(resource);
1355    p = wl_array_add(&source->mime_types, sizeof *p);
1356    if (p) *p = strdup(type);
1357
1358    if (!p || !*p) wl_resource_post_no_memory(resource);
1359 }
1360
1361 static void
1362 _data_source_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1363 {
1364    wl_resource_destroy(resource);
1365 }
1366
1367 static void
1368 _destroy_data_source(struct wl_resource *resource)
1369 {
1370    struct wl_data_source *source;
1371    char **p;
1372
1373    source = wl_resource_get_user_data(resource);
1374
1375    wl_signal_emit(&source->destroy_signal, source);
1376
1377    wl_array_for_each(p, &source->mime_types)
1378      free(*p);
1379
1380    wl_array_release(&source->mime_types);
1381
1382    source->resource = NULL;
1383 }
1384
1385 static void
1386 _data_device_end_drag_grab(struct wl_seat *seat)
1387 {
1388    if (seat->drag_surface) 
1389      {
1390         seat->drag_surface = NULL;
1391         wl_signal_emit(&seat->drag_icon_signal, NULL);
1392         wl_list_remove(&seat->drag_icon_listener.link);
1393      }
1394
1395    _drag_grab_focus(&seat->drag_grab, NULL,
1396                     wl_fixed_from_int(0), wl_fixed_from_int(0));
1397    wl_pointer_end_grab(seat->pointer);
1398    seat->drag_data_source = NULL;
1399    seat->drag_client = NULL;
1400 }
1401
1402 static void
1403 _drag_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp EINA_UNUSED, uint32_t button, uint32_t state_w)
1404 {
1405    struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab);
1406    enum wl_pointer_button_state state = state_w;
1407
1408    if (seat->drag_focus_resource &&
1409        seat->pointer->grab_button == button &&
1410        state == WL_POINTER_BUTTON_STATE_RELEASED)
1411      wl_data_device_send_drop(seat->drag_focus_resource);
1412
1413    if (seat->pointer->button_count == 0 &&
1414        state == WL_POINTER_BUTTON_STATE_RELEASED) 
1415      {
1416         if (seat->drag_data_source)
1417           wl_list_remove(&seat->drag_data_source_listener.link);
1418
1419         _data_device_end_drag_grab(seat);
1420      }
1421 }
1422
1423 static void
1424 _drag_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y)
1425 {
1426    struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab);
1427
1428    if (seat->drag_focus_resource)
1429      wl_data_device_send_motion(seat->drag_focus_resource,
1430                                 timestamp, x, y);
1431 }
1432
1433 static void
1434 _destroy_drag_focus(struct wl_listener *listener, void *data EINA_UNUSED)
1435 {
1436    struct wl_seat *seat =
1437      container_of(listener, struct wl_seat, drag_focus_listener);
1438
1439    seat->drag_focus_resource = NULL;
1440 }
1441
1442 static void
1443 _drag_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y)
1444 {
1445    struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab);
1446    struct wl_resource *resource, *offer = NULL;
1447    struct wl_display *display;
1448    uint32_t serial;
1449    E_Wayland_Surface *ews;
1450
1451    if (seat->drag_focus_resource) 
1452      {
1453         wl_data_device_send_leave(seat->drag_focus_resource);
1454         wl_list_remove(&seat->drag_focus_listener.link);
1455         seat->drag_focus_resource = NULL;
1456         seat->drag_focus = NULL;
1457      }
1458
1459    if (!surface) return;
1460
1461    if (!seat->drag_data_source &&
1462        wl_resource_get_client(surface) != seat->drag_client)
1463      return;
1464
1465    resource = 
1466      wl_resource_find_for_client(&seat->drag_resource_list, 
1467                                  wl_resource_get_client(surface));
1468    if (!resource) return;
1469
1470    display = wl_client_get_display(wl_resource_get_client(resource));
1471    serial = wl_display_next_serial(display);
1472
1473    if (seat->drag_data_source)
1474      offer = wl_data_source_send_offer(seat->drag_data_source,
1475                                        resource);
1476
1477    wl_data_device_send_enter(resource, serial, surface, x, y, offer);
1478
1479    ews = wl_resource_get_user_data(surface);
1480
1481    seat->drag_focus = surface;
1482    seat->drag_focus_listener.notify = _destroy_drag_focus;
1483    wl_signal_add(&ews->wl.destroy_signal, &seat->drag_focus_listener);
1484    seat->drag_focus_resource = resource;
1485    grab->focus = surface;
1486 }
1487
1488 static void
1489 _client_source_accept(struct wl_data_source *source, uint32_t timestamp EINA_UNUSED, const char *mime_type)
1490 {
1491    wl_data_source_send_target(source->resource, mime_type);
1492 }
1493
1494 static void
1495 _client_source_send(struct wl_data_source *source, const char *mime_type, int32_t fd)
1496 {
1497    wl_data_source_send_send(source->resource, mime_type, fd);
1498    close(fd);
1499 }
1500
1501 static void
1502 _client_source_cancel(struct wl_data_source *source)
1503 {
1504    wl_data_source_send_cancelled(source->resource);
1505 }
1506
1507 static void 
1508 _e_comp_wl_cb_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id)
1509 {
1510    E_Wayland_Compositor *comp;
1511    struct wl_resource *res;
1512
1513    if (!(comp = data)) return;
1514
1515    res = 
1516      wl_resource_create(client, &wl_compositor_interface, MIN(version, 3), id);
1517    if (res)
1518      wl_resource_set_implementation(res, &_e_compositor_interface, comp, NULL);
1519 }
1520
1521 static Eina_Bool 
1522 _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSED)
1523 {
1524    /* flush any events before we sleep */
1525    wl_display_flush_clients(_e_wl_comp->wl.display);
1526    wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0);
1527
1528    return ECORE_CALLBACK_RENEW;
1529 }
1530
1531 static Eina_Bool 
1532 _e_comp_wl_cb_idle(void *data EINA_UNUSED)
1533 {
1534    if ((_e_wl_comp) && (_e_wl_comp->wl.display))
1535      {
1536         /* flush any clients before we idle */
1537         wl_display_flush_clients(_e_wl_comp->wl.display);
1538      }
1539
1540    return ECORE_CALLBACK_RENEW;
1541 }
1542
1543 static Eina_Bool 
1544 _e_comp_wl_cb_module_idle(void *data EINA_UNUSED)
1545 {
1546    E_Module *mod = NULL;
1547
1548    /* if we are still in the process of loading modules, then we will wait */
1549    if (e_module_loading_get()) return ECORE_CALLBACK_RENEW;
1550
1551    /* try to find the shell module, and create it if not found
1552     * 
1553     * TODO: we should have a config variable somewhere to store which 
1554     * shell we want to load (tablet, mobile, etc) */
1555    if (!(mod = e_module_find("wl_desktop_shell")))
1556      mod = e_module_new("wl_desktop_shell");
1557
1558    /* if we have the module now, load it */
1559    if (mod) 
1560      {
1561         e_module_enable(mod);
1562         _module_idler = NULL;
1563
1564         /* flush any pending events
1565          * 
1566          * NB: This advertises out any globals so it needs to be deferred 
1567          * until after the shell has been loaded */
1568         wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0);
1569
1570         return ECORE_CALLBACK_CANCEL;
1571      }
1572
1573    return ECORE_CALLBACK_RENEW;
1574 }
1575
1576 static Eina_Bool 
1577 _e_comp_wl_cb_keymap_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1578 {
1579    struct xkb_keymap *keymap;
1580
1581    /* try to fetch the keymap */
1582    if (!(keymap = _e_comp_wl_input_keymap_get())) 
1583      return ECORE_CALLBACK_PASS_ON;
1584
1585    /* destroy keyboard */
1586    if (_e_wl_comp->input->xkb.info)
1587      {
1588         /* if we have a keymap, unreference it */
1589         if (_e_wl_comp->input->xkb.info->keymap)
1590           xkb_map_unref(_e_wl_comp->input->xkb.info->keymap);
1591
1592         /* if we have a keymap mmap'd area, unmap it */
1593         if (_e_wl_comp->input->xkb.info->area)
1594           munmap(_e_wl_comp->input->xkb.info->area, 
1595                  _e_wl_comp->input->xkb.info->size);
1596
1597         /* if we created an fd for keyboard input, close it */
1598         if (_e_wl_comp->input->xkb.info->fd) 
1599           close(_e_wl_comp->input->xkb.info->fd);
1600
1601         /* free the allocated keyboard info structure */
1602         E_FREE(_e_wl_comp->input->xkb.info);
1603      }
1604
1605    /* unreference the xkb state we created */
1606    if (_e_wl_comp->input->xkb.state) 
1607      xkb_state_unref(_e_wl_comp->input->xkb.state);
1608
1609    /* unreference the xkb context we created */
1610    if (_e_wl_comp->xkb.context)
1611      xkb_context_unref(_e_wl_comp->xkb.context);
1612
1613    /* create the xkb context */
1614    _e_wl_comp->xkb.context = xkb_context_new(0);
1615
1616    /* try to fetch the keymap */
1617 //   if ((keymap = _e_comp_wl_input_keymap_get()))
1618      {
1619         /* try to create new keyboard info */
1620         _e_wl_comp->input->xkb.info = 
1621           _e_comp_wl_input_keyboard_info_get(keymap);
1622
1623         /* create new xkb state */
1624         _e_wl_comp->input->xkb.state = xkb_state_new(keymap);
1625
1626         /* unreference the keymap */
1627         xkb_map_unref(keymap);
1628      }
1629
1630    /* check for valid keyboard */
1631    if (!_e_wl_comp->input->wl.keyboard_resource) 
1632      return ECORE_CALLBACK_PASS_ON;
1633
1634    /* send the current keymap to the keyboard object */
1635    wl_keyboard_send_keymap(_e_wl_comp->input->wl.keyboard_resource, 
1636                            WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, 
1637                            _e_wl_comp->input->xkb.info->fd, 
1638                            _e_wl_comp->input->xkb.info->size);
1639
1640    return ECORE_CALLBACK_PASS_ON;
1641 }
1642
1643 /* compositor interface functions */
1644 static void 
1645 _e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id)
1646 {
1647    E_Wayland_Surface *ews = NULL;
1648
1649    /* try to allocate space for a new surface */
1650    if (!(ews = E_NEW(E_Wayland_Surface, 1)))
1651      {
1652         wl_resource_post_no_memory(resource);
1653         return;
1654      }
1655
1656    ews->wl.client = client;
1657    ews->pixmap = e_pixmap_new(E_PIXMAP_TYPE_WL, ews);
1658    e_pixmap_parent_window_set(ews->pixmap, ews);
1659    e_pixmap_usable_set(ews->pixmap, 1);
1660    /* initialize the destroy signal */
1661    wl_signal_init(&ews->wl.destroy_signal);
1662
1663    /* initialize the link */
1664    wl_list_init(&ews->wl.link);
1665
1666    /* initialize the lists of frames */
1667    wl_list_init(&ews->wl.frames);
1668    wl_list_init(&ews->pending.frames);
1669
1670    ews->wl.surface = NULL;
1671
1672    /* set destroy function for pending buffers */
1673    ews->pending.buffer_destroy.notify = 
1674      _e_comp_wl_surface_cb_pending_buffer_destroy;
1675
1676    /* initialize regions */
1677    pixman_region32_init(&ews->region.opaque);
1678    pixman_region32_init(&ews->region.damage);
1679    pixman_region32_init(&ews->region.clip);
1680    pixman_region32_init_rect(&ews->region.input, INT32_MIN, INT32_MIN, 
1681                              UINT32_MAX, UINT32_MAX);
1682
1683    /* initialize pending regions */
1684    pixman_region32_init(&ews->pending.opaque);
1685    pixman_region32_init(&ews->pending.damage);
1686    pixman_region32_init_rect(&ews->pending.input, INT32_MIN, INT32_MIN, 
1687                              UINT32_MAX, UINT32_MAX);
1688
1689    ews->wl.surface = 
1690      wl_resource_create(client, &wl_surface_interface, 
1691                         wl_resource_get_version(resource), id);
1692    wl_resource_set_implementation(ews->wl.surface, &_e_surface_interface, 
1693                                   ews, _e_comp_wl_cb_surface_destroy);
1694
1695    /* add this surface to the list of surfaces */
1696    _e_wl_comp->surfaces = eina_inlist_append(_e_wl_comp->surfaces, EINA_INLIST_GET(ews));
1697 }
1698
1699 static void 
1700 _e_comp_wl_cb_surface_destroy(struct wl_resource *resource)
1701 {
1702    E_Wayland_Surface *ews = NULL;
1703    E_Wayland_Surface_Frame_Callback *cb = NULL, *ncb = NULL;
1704    struct wl_pointer *pointer;
1705
1706    /* try to get the surface from this resource */
1707    if (!(ews = wl_resource_get_user_data(resource)))
1708      return;
1709
1710    pointer = &_e_wl_comp->input->wl.pointer;
1711    if (pointer->focus == resource)
1712      {
1713         wl_pointer_set_focus(pointer, NULL,
1714                              wl_fixed_from_int(0), wl_fixed_from_int(0));
1715
1716         _e_wl_comp->input->pointer.surface = NULL;
1717      }
1718
1719    /* if this surface is mapped, unmap it */
1720    if (ews->mapped)
1721      {
1722         if (ews->unmap) ews->unmap(ews);
1723      }
1724    if (ews->buffer_reference.buffer)
1725      ews->buffer_reference.buffer->ews = NULL;
1726    if (ews->pending.buffer)
1727      ews->pending.buffer->ews = NULL;
1728
1729    /* loop any pending surface frame callbacks and destroy them */
1730    wl_list_for_each_safe(cb, ncb, &ews->pending.frames, wl.link)
1731      wl_resource_destroy(cb->wl.resource);
1732
1733    /* clear any pending regions */
1734    pixman_region32_fini(&ews->pending.damage);
1735    pixman_region32_fini(&ews->pending.opaque);
1736    pixman_region32_fini(&ews->pending.input);
1737
1738    /* remove the pending buffer from the list */
1739    if (ews->pending.buffer)
1740      wl_list_remove(&ews->pending.buffer_destroy.link);
1741
1742    /* dereference any existing buffers */
1743    _e_comp_wl_surface_buffer_reference(&ews->buffer_reference, NULL);
1744
1745    /* clear any active regions */
1746    pixman_region32_fini(&ews->region.damage);
1747    pixman_region32_fini(&ews->region.opaque);
1748    pixman_region32_fini(&ews->region.input);
1749    pixman_region32_fini(&ews->region.clip);
1750
1751    /* loop any active surface frame callbacks and destroy them */
1752    wl_list_for_each_safe(cb, ncb, &ews->wl.frames, wl.link)
1753      wl_resource_destroy(cb->wl.resource);
1754
1755    e_pixmap_parent_window_set(ews->pixmap, NULL);
1756    e_pixmap_free(ews->pixmap);
1757
1758    /* remove this surface from the compositor's list of surfaces */
1759    _e_wl_comp->surfaces = eina_inlist_remove(_e_wl_comp->surfaces, EINA_INLIST_GET(ews));
1760
1761    /* free the allocated surface structure */
1762    free(ews);
1763 }
1764
1765 static void 
1766 _e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id)
1767 {
1768    E_Wayland_Region *ewr = NULL;
1769
1770    /* try to allocate space for a new region */
1771    if (!(ewr = E_NEW_RAW(E_Wayland_Region, 1)))
1772      {
1773         wl_resource_post_no_memory(resource);
1774         return;
1775      }
1776
1777    pixman_region32_init(&ewr->region);
1778
1779    ewr->wl.resource = 
1780      wl_resource_create(client, &wl_region_interface, 
1781                         wl_resource_get_version(resource), id);
1782    wl_resource_set_implementation(ewr->wl.resource, &_e_region_interface, ewr, 
1783                                   _e_comp_wl_cb_region_destroy);
1784 }
1785
1786 static void 
1787 _e_comp_wl_cb_region_destroy(struct wl_resource *resource)
1788 {
1789    E_Wayland_Region *ewr = NULL;
1790
1791    /* try to get the region from this resource */
1792    if (!(ewr = wl_resource_get_user_data(resource)))
1793      return;
1794
1795    /* tell pixman we are finished with this region */
1796    pixman_region32_fini(&ewr->region);
1797
1798    /* free the allocated region structure */
1799    E_FREE(ewr);
1800 }
1801
1802 /* input functions */
1803 static Eina_Bool 
1804 _e_comp_wl_input_init(void)
1805 {
1806    struct xkb_keymap *keymap;
1807
1808    /* try to allocate space for a new compositor */
1809    if (!(_e_wl_comp->input = E_NEW(E_Wayland_Input, 1)))
1810      return EINA_FALSE;
1811
1812    /* initialize the seat */
1813    wl_seat_init(&_e_wl_comp->input->wl.seat);
1814
1815    /* try to add this input to the diplay's list of globals */
1816    if (!wl_global_create(_e_wl_comp->wl.display, &wl_seat_interface, 2, 
1817                          _e_wl_comp->input, _e_comp_wl_input_cb_bind))
1818      {
1819         ERR("Could not add Input to Wayland Display Globals: %m");
1820         goto err;
1821      }
1822
1823    _e_wl_comp->input->pointer.surface = NULL;
1824    _e_wl_comp->input->pointer.surface_destroy.notify = 
1825      _e_comp_wl_pointer_cb_destroy;
1826    _e_wl_comp->input->pointer.hot.x = 16;
1827    _e_wl_comp->input->pointer.hot.y = 16;
1828
1829    /* initialize wayland pointer */
1830    wl_pointer_init(&_e_wl_comp->input->wl.pointer);
1831
1832    /* tell the seat about this pointer */
1833    wl_seat_set_pointer(&_e_wl_comp->input->wl.seat, 
1834                        &_e_wl_comp->input->wl.pointer);
1835
1836    /* set flag to indicate we have a pointer */
1837    _e_wl_comp->input->has_pointer = EINA_TRUE;
1838
1839    /* create the xkb context */
1840    _e_wl_comp->xkb.context = xkb_context_new(0);
1841
1842    /* try to fetch the keymap */
1843    if ((keymap = _e_comp_wl_input_keymap_get()))
1844      {
1845         /* try to create new keyboard info */
1846         _e_wl_comp->input->xkb.info = 
1847           _e_comp_wl_input_keyboard_info_get(keymap);
1848
1849         /* create new xkb state */
1850         _e_wl_comp->input->xkb.state = xkb_state_new(keymap);
1851
1852         /* unreference the keymap */
1853         xkb_map_unref(keymap);
1854      }
1855
1856    /* initialize the keyboard */
1857    wl_keyboard_init(&_e_wl_comp->input->wl.keyboard);
1858
1859    /* tell the seat about this keyboard */
1860    wl_seat_set_keyboard(&_e_wl_comp->input->wl.seat, 
1861                         &_e_wl_comp->input->wl.keyboard);
1862
1863    /* set flag to indicate we have a keyboard */
1864    _e_wl_comp->input->has_keyboard = EINA_TRUE;
1865
1866    wl_list_init(&_e_wl_comp->input->wl.link);
1867
1868    /* append this input to the list */
1869    _e_wl_comp->seats = eina_list_append(_e_wl_comp->seats, _e_wl_comp->input);
1870
1871    /* emit a signal saying that input has been initialized */
1872    wl_signal_emit(&_e_wl_comp->signals.seat, _e_wl_comp->input);
1873
1874    /* return success */
1875    return EINA_TRUE;
1876
1877 err:
1878    /* release the wl_seat */
1879    wl_seat_release(&_e_wl_comp->input->wl.seat);
1880
1881    /* free the allocated input structure */
1882    E_FREE(_e_wl_comp->input);
1883
1884    /* return failure */
1885    return EINA_FALSE;
1886 }
1887
1888 static void 
1889 _e_comp_wl_input_shutdown(void)
1890 {
1891    /* safety check */
1892    if (!_e_wl_comp->input) return;
1893
1894    /* destroy keyboard */
1895    if (_e_wl_comp->input->xkb.info)
1896      {
1897         /* if we have a keymap, unreference it */
1898         if (_e_wl_comp->input->xkb.info->keymap)
1899           xkb_map_unref(_e_wl_comp->input->xkb.info->keymap);
1900
1901         /* if we have a keymap mmap'd area, unmap it */
1902         if (_e_wl_comp->input->xkb.info->area)
1903           munmap(_e_wl_comp->input->xkb.info->area, 
1904                  _e_wl_comp->input->xkb.info->size);
1905
1906         /* if we created an fd for keyboard input, close it */
1907         if (_e_wl_comp->input->xkb.info->fd) 
1908           close(_e_wl_comp->input->xkb.info->fd);
1909
1910         /* free the allocated keyboard info structure */
1911         E_FREE(_e_wl_comp->input->xkb.info);
1912      }
1913
1914    /* unreference the xkb state we created */
1915    if (_e_wl_comp->input->xkb.state) 
1916      xkb_state_unref(_e_wl_comp->input->xkb.state);
1917
1918    /* unreference the xkb context we created */
1919    if (_e_wl_comp->xkb.context)
1920      xkb_context_unref(_e_wl_comp->xkb.context);
1921
1922    /* TODO: destroy pointer surface
1923     * 
1924     * NB: Currently, we do not create one */
1925
1926    wl_list_remove(&_e_wl_comp->input->wl.link);
1927
1928    /* release the seat */
1929    wl_seat_release(&_e_wl_comp->input->wl.seat);
1930
1931    /* free the allocated input structure */
1932    E_FREE(_e_wl_comp->input);
1933 }
1934
1935 static void 
1936 _e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id)
1937 {
1938    struct wl_seat *seat = NULL;
1939    struct wl_resource *resource = NULL;
1940    enum wl_seat_capability caps = 0;
1941
1942    /* try to cast data to our seat */
1943    if (!(seat = data)) return;
1944
1945    /* add the seat object to the client */
1946    resource = 
1947      wl_resource_create(client, &wl_seat_interface, MIN(version, 2), id);
1948
1949    wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
1950
1951    wl_resource_set_implementation(resource, &_e_input_interface, data, 
1952                                   _e_comp_wl_input_cb_unbind);
1953
1954    /* set capabilities based on seat */
1955    if (seat->pointer) caps |= WL_SEAT_CAPABILITY_POINTER;
1956    if (seat->keyboard) caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1957    if (seat->touch) caps |= WL_SEAT_CAPABILITY_TOUCH;
1958
1959    /* inform the resource about the seat capabilities */
1960    wl_seat_send_capabilities(resource, caps);
1961 }
1962
1963 static void 
1964 _e_comp_wl_input_cb_unbind(struct wl_resource *resource)
1965 {
1966    /* remove the link */
1967    wl_list_remove(wl_resource_get_link(resource));
1968 }
1969
1970 static struct xkb_keymap *
1971 _e_comp_wl_input_keymap_get(void)
1972 {
1973    E_Config_XKB_Layout *kbd_layout;
1974    struct xkb_keymap *keymap;
1975    struct xkb_rule_names names;
1976
1977    memset(&names, 0, sizeof(names));
1978
1979    if ((kbd_layout = e_xkb_layout_get()))
1980      {
1981         names.model = strdup(kbd_layout->model);
1982         names.layout = strdup(kbd_layout->name);
1983      }
1984
1985    /* if we are running under X11, try to get the xkb rule names atom */
1986    if (getenv("DISPLAY"))
1987      {
1988         Ecore_X_Atom rules = 0;
1989         Ecore_X_Window root = 0;
1990         int len = 0;
1991         unsigned char *data;
1992
1993         /* TODO: FIXME: NB:
1994          * 
1995          * The below commented out code is for using the "already" configured 
1996          * E xkb settings in the wayland clients. The only Major problem with 
1997          * that is: That the E_Config_XKB_Layout does not define a 
1998          * 'RULES' which we need ....
1999          * 
2000          */
2001
2002         root = ecore_x_window_root_first_get();
2003         rules = ecore_x_atom_get("_XKB_RULES_NAMES");
2004         ecore_x_window_prop_property_get(root, rules, ECORE_X_ATOM_STRING, 
2005                                          1024, &data, &len);
2006
2007         if ((data) && (len > 0))
2008           {
2009              names.rules = strdup((const char *)data);
2010              data += strlen((const char *)data) + 1;
2011              if (!names.model)
2012                names.model = strdup((const char *)data);
2013              data += strlen((const char *)data) + 1;
2014              if (!names.layout)
2015                names.layout = strdup((const char *)data);
2016           }
2017      }
2018
2019    printf("Keymap\n");
2020    printf("\tRules: %s\n", names.rules);
2021    printf("\tModel: %s\n", names.model);
2022    printf("\tLayout: %s\n", names.layout);
2023
2024    keymap = xkb_map_new_from_names(_e_wl_comp->xkb.context, &names, 0);
2025
2026    free((char *)names.rules);
2027    free((char *)names.model);
2028    free((char *)names.layout);
2029
2030    return keymap;
2031 }
2032
2033 static int 
2034 _e_comp_wl_input_keymap_fd_get(off_t size)
2035 {
2036    char tmp[PATH_MAX];
2037    const char *path;
2038    int fd = 0;
2039    long flags;
2040
2041    if (!(path = getenv("XDG_RUNTIME_DIR")))
2042      return -1;
2043
2044    strcpy(tmp, path);
2045    strcat(tmp, "/e-wl-keymap-XXXXXX");
2046
2047    if ((fd = mkstemp(tmp)) < 0)
2048      return -1;
2049
2050    /* TODO: really should error check the returns here */
2051
2052    flags = fcntl(fd, F_GETFD);
2053    fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2054
2055    if (ftruncate(fd, size) < 0)
2056      {
2057         close(fd);
2058         return -1;
2059      }
2060
2061    unlink(tmp);
2062    return fd;
2063 }
2064
2065 static E_Wayland_Keyboard_Info *
2066 _e_comp_wl_input_keyboard_info_get(struct xkb_keymap *keymap)
2067 {
2068    E_Wayland_Keyboard_Info *info = NULL;
2069    char *tmp;
2070
2071    /* try to allocate space for the keyboard info structure */
2072    if (!(info = E_NEW(E_Wayland_Keyboard_Info, 1)))
2073      return NULL;
2074
2075    if (!(info->keymap = xkb_map_ref(keymap)))
2076      {
2077         E_FREE(info);
2078         return NULL;
2079      }
2080
2081    /* init modifiers */
2082    info->mod_shift = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
2083    info->mod_caps = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
2084    info->mod_ctrl = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
2085    info->mod_alt = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
2086    info->mod_super = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
2087
2088    /* try to get a string of this keymap */
2089    if (!(tmp = xkb_map_get_as_string(keymap)))
2090      {
2091         printf("Could not get keymap as string\n");
2092         E_FREE(info);
2093         return NULL;
2094      }
2095
2096    info->size = strlen(tmp) + 1;
2097
2098    /* try to create an fd we can listen on for input */
2099    info->fd = _e_comp_wl_input_keymap_fd_get(info->size);
2100    if (info->fd < 0)
2101      {
2102         printf("Could not create keymap fd\n");
2103         E_FREE(info);
2104         return NULL;
2105      }
2106
2107    info->area = 
2108      mmap(NULL, info->size, PROT_READ | PROT_WRITE, MAP_SHARED, info->fd, 0);
2109
2110    /* TODO: error check mmap */
2111
2112    if ((info->area) && (tmp))
2113      {
2114         strcpy(info->area, tmp);
2115         free(tmp);
2116      }
2117
2118    return info;
2119 }
2120
2121 /* input interface functions */
2122 static void 
2123 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
2124 {
2125    E_Wayland_Input *input = NULL;
2126    struct wl_resource *ptr = NULL;
2127
2128    /* try to cast the resource data to our input structure */
2129    if (!(input = wl_resource_get_user_data(resource)))
2130      return;
2131
2132    /* check that input has a pointer */
2133    if (!input->has_pointer) return;
2134
2135    /* add a pointer object to the client */
2136    ptr = wl_resource_create(client, &wl_pointer_interface, 
2137                             wl_resource_get_version(resource), id);
2138    wl_list_insert(&input->wl.seat.pointer->resource_list, 
2139                   wl_resource_get_link(ptr));
2140    wl_resource_set_implementation(ptr, &_e_pointer_interface, 
2141                                   input, _e_comp_wl_input_cb_unbind);
2142
2143    /* if the pointer has a focused surface, set it */
2144    if ((input->wl.seat.pointer->focus) && 
2145        (wl_resource_get_client(input->wl.seat.pointer->focus) == client))
2146      {
2147         /* tell pointer which surface is focused */
2148         wl_list_remove(wl_resource_get_link(ptr));
2149         wl_list_insert(&input->wl.seat.pointer->focus_resource_list, 
2150                        wl_resource_get_link(ptr));
2151
2152         wl_pointer_send_enter(ptr, input->wl.seat.pointer->focus_serial, 
2153                               input->wl.seat.pointer->focus, 
2154                               input->wl.seat.pointer->x, 
2155                               input->wl.seat.pointer->y);
2156      }
2157 }
2158
2159 static void 
2160 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
2161 {
2162    E_Wayland_Input *input = NULL;
2163    struct wl_resource *kbd = NULL;
2164
2165    /* try to cast the resource data to our input structure */
2166    if (!(input = wl_resource_get_user_data(resource)))
2167      return;
2168
2169    /* check that input has a keyboard */
2170    if (!input->has_keyboard) return;
2171
2172    /* add a keyboard object to the client */
2173    kbd = wl_resource_create(client, &wl_keyboard_interface, 
2174                             wl_resource_get_version(resource), id);
2175    wl_list_insert(&input->wl.seat.keyboard->resource_list, 
2176                   wl_resource_get_link(kbd));
2177    wl_resource_set_implementation(kbd, &_e_keyboard_interface, input, 
2178                                   _e_comp_wl_input_cb_unbind);
2179
2180    /* send the current keymap to the keyboard object */
2181    wl_keyboard_send_keymap(kbd, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, 
2182                            input->xkb.info->fd, input->xkb.info->size);
2183
2184    if (((input->wl.seat.keyboard) && (input->wl.seat.keyboard->focus) && 
2185         (wl_resource_get_client(input->wl.seat.keyboard->focus) == client)) || 
2186        ((input->wl.seat.pointer) && (input->wl.seat.pointer->focus) && 
2187            (wl_resource_get_client(input->wl.seat.pointer->focus) == client)))
2188      {
2189         wl_keyboard_send_modifiers(kbd, input->wl.seat.keyboard->focus_serial,
2190                                    input->wl.seat.keyboard->modifiers.mods_depressed,
2191                                    input->wl.seat.keyboard->modifiers.mods_latched,
2192                                    input->wl.seat.keyboard->modifiers.mods_locked,
2193                                    input->wl.seat.keyboard->modifiers.group);
2194      }
2195
2196    /* test if keyboard has a focused client */
2197    if ((input->wl.seat.keyboard->focus) && 
2198        (wl_resource_get_client(input->wl.seat.keyboard->focus) == client))
2199      {
2200         wl_list_remove(wl_resource_get_link(kbd));
2201         wl_list_insert(&input->wl.seat.keyboard->focus_resource_list, 
2202                        wl_resource_get_link(kbd));
2203         wl_keyboard_send_enter(kbd, input->wl.seat.keyboard->focus_serial, 
2204                                input->wl.seat.keyboard->focus, 
2205                                &input->wl.seat.keyboard->keys);
2206
2207         if (input->wl.seat.keyboard->focus_resource_list.prev == 
2208             wl_resource_get_link(kbd))
2209           {
2210              /* update the keyboard focus in the data device */
2211              wl_data_device_set_keyboard_focus(&input->wl.seat);
2212           }
2213      }
2214
2215    input->wl.keyboard_resource = kbd;
2216 }
2217
2218 static void 
2219 _e_comp_wl_input_cb_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
2220 {
2221    E_Wayland_Input *input = NULL;
2222    struct wl_resource *tch = NULL;
2223
2224    /* try to cast the resource data to our input structure */
2225    if (!(input = wl_resource_get_user_data(resource)))
2226      return;
2227
2228    /* check that input has a touch */
2229    if (!input->has_touch) return;
2230
2231    /* add a touch object to the client */
2232    tch = wl_resource_create(client, &wl_touch_interface, 
2233                             wl_resource_get_version(resource), id);
2234    if ((input->wl.seat.touch->focus) && 
2235        (wl_resource_get_client(input->wl.seat.touch->focus) == client))
2236      {
2237         wl_list_insert(&input->wl.seat.touch->resource_list, 
2238                        wl_resource_get_link(tch));
2239      }
2240    else
2241      wl_list_insert(&input->wl.seat.touch->focus_resource_list, 
2242                     wl_resource_get_link(tch));
2243
2244    wl_resource_set_implementation(tch, &_e_touch_interface, input, 
2245                                   _e_comp_wl_input_cb_unbind);
2246 }
2247
2248 /* pointer functions */
2249 static void 
2250 _e_comp_wl_pointer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
2251 {
2252    E_Wayland_Input *input = NULL;
2253
2254    /* try to get the input from this listener */
2255    if (!(input = container_of(listener, E_Wayland_Input, pointer.surface_destroy)))
2256      return;
2257
2258    input->pointer.surface = NULL;
2259 }
2260
2261 static void 
2262 _e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
2263 {
2264    E_Wayland_Input *input = NULL;
2265    E_Wayland_Surface *focus = NULL;
2266
2267    /* safety check */
2268    if (!ews) return;
2269
2270    /* see if this surface has 'input' */
2271    if (!(input = ews->input)) return;
2272
2273    input->pointer.hot.x -= x;
2274    input->pointer.hot.y -= y;
2275
2276    /* configure the surface geometry */
2277    ews->geometry.x = x;
2278    ews->geometry.h = h;
2279    ews->geometry.w = w;
2280    ews->geometry.h = h;
2281    ews->geometry.changed = EINA_TRUE;
2282
2283    /* tell pixman we are finished with this region */
2284    pixman_region32_fini(&ews->pending.input);
2285
2286    /* reinitalize the pending input region */
2287    pixman_region32_init(&ews->pending.input);
2288
2289    /* do we have a focused surface ? */
2290    if (!input->wl.seat.pointer->focus) return;
2291
2292    if ((focus = wl_resource_get_user_data(input->wl.seat.pointer->focus)))
2293      {
2294         /* NB: Ideally, I wanted to use the e_pointer methods here so that 
2295          * the cursor would match the E theme, however Wayland currently 
2296          * provides NO Method to get the cursor name :( so we are stuck 
2297          * using the pixels from their cursor surface */
2298
2299         /* is it mapped ? */
2300         if ((focus->mapped) && (focus->ec))
2301           {
2302              Ecore_Window win;
2303
2304              /* try to get the ecore_window */
2305 #warning CURSOR BROKEN
2306 #if 0
2307              if ((win = ecore_evas_window_get(focus->ee)))
2308                {
2309                   E_Wayland_Buffer_Reference *ref;
2310                   struct wl_shm_buffer *shm_buffer;
2311                   void *pixels;
2312
2313                   ref = &ews->buffer_reference;
2314
2315                   shm_buffer = wl_shm_buffer_get(ref->buffer->wl.resource);
2316
2317                   /* grab the pixels from the cursor surface */
2318                   if ((pixels = wl_shm_buffer_get_data(shm_buffer)))
2319                     {
2320                        Ecore_X_Cursor cur;
2321
2322                        /* create the new X cursor with this image */
2323                        cur = ecore_x_cursor_new(win, pixels, w, h,
2324                                                 input->pointer.hot.x, 
2325                                                 input->pointer.hot.y);
2326
2327                        /* set the cursor on this window */
2328                        ecore_x_window_cursor_set(win, cur);
2329
2330                        /* free the cursor */
2331                        ecore_x_cursor_free(cur);
2332                     }
2333                   else
2334                     ecore_x_window_cursor_set(win, 0);
2335                }
2336 #endif
2337           }
2338      }
2339 }
2340
2341 static void 
2342 _e_comp_wl_pointer_unmap(E_Wayland_Surface *ews)
2343 {
2344    E_Wayland_Input *input = NULL;
2345
2346    /* safety check */
2347    if (!ews) return;
2348
2349    if (!(input = ews->input)) return;
2350
2351    wl_list_remove(&input->pointer.surface_destroy.link);
2352
2353    if (input->pointer.surface)
2354      input->pointer.surface->configure = NULL;
2355
2356    input->pointer.surface = NULL;
2357 }
2358
2359 /* pointer interface functions */
2360 static void 
2361 _e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y)
2362 {
2363    E_Wayland_Input *input = NULL;
2364    E_Wayland_Surface *ews = NULL;
2365
2366    /* try to cast the resource data to our input structure */
2367    if (!(input = wl_resource_get_user_data(resource)))
2368      return;
2369
2370    /* if we were passed in a surface, try to cast it to our structure */
2371    if (surface_resource) ews = wl_resource_get_user_data(surface_resource);
2372
2373    /* if this input has no pointer, get out */
2374    if (!input->has_pointer) return;
2375
2376    /* if the input has no current focus, get out */
2377    if (!input->wl.seat.pointer->focus) 
2378      {
2379         /* if we have an existing pointer surface, unmap it */
2380         if (input->pointer.surface) 
2381           {
2382              /* call the unmap function */
2383              if (input->pointer.surface->unmap)
2384                input->pointer.surface->unmap(input->pointer.surface);
2385           }
2386
2387         input->pointer.surface = NULL;
2388
2389         return;
2390      }
2391
2392    if (wl_resource_get_client(input->wl.seat.pointer->focus) != client) return;
2393    if ((input->wl.seat.pointer->focus_serial - serial) > (UINT32_MAX / 2))
2394      return;
2395
2396    /* is the passed in surface the same as our pointer surface ? */
2397    if ((ews) && (ews != input->pointer.surface))
2398      {
2399         if (ews->configure)
2400           {
2401              wl_resource_post_error(ews->wl.surface, 
2402                                     WL_DISPLAY_ERROR_INVALID_OBJECT, 
2403                                     "Surface already configured");
2404              return;
2405           }
2406      }
2407
2408    /* if we have an existing pointer surface, unmap it */
2409    if (input->pointer.surface) 
2410      {
2411         /* call the unmap function */
2412         if (input->pointer.surface->unmap)
2413           input->pointer.surface->unmap(input->pointer.surface);
2414      }
2415
2416    input->pointer.surface = ews;
2417
2418    /* if we don't have a pointer surface, we are done here */
2419    if (!ews) return;
2420
2421    /* set the destroy listener */
2422    wl_signal_add(&ews->wl.destroy_signal, 
2423                  &input->pointer.surface_destroy);
2424
2425    /* set some properties on this surface */
2426    ews->unmap = _e_comp_wl_pointer_unmap;
2427    ews->configure = _e_comp_wl_pointer_configure;
2428    ews->input = input;
2429
2430    /* update input structure with new values */
2431    input->pointer.hot.x = x;
2432    input->pointer.hot.y = y;
2433
2434    if (&ews->buffer_reference)
2435      {
2436         E_Wayland_Buffer *buf;
2437
2438         if ((buf = ews->buffer_reference.buffer))
2439           {
2440              Evas_Coord bw = 0, bh = 0;
2441
2442              bw = buf->w;
2443              bh = buf->h;
2444
2445              /* configure the pointer surface */
2446              _e_comp_wl_pointer_configure(ews, 0, 0, bw, bh);
2447           }
2448      }
2449 }
2450
2451 static void 
2452 _e_comp_wl_pointer_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2453 {
2454    wl_resource_destroy(resource);
2455 }
2456
2457 /* keyboard interface functions */
2458 static void 
2459 _e_comp_wl_keyboard_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2460 {
2461    wl_resource_destroy(resource);
2462 }
2463
2464 /* touch interface functions */
2465 static void 
2466 _e_comp_wl_touch_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2467 {
2468    wl_resource_destroy(resource);
2469 }
2470
2471 /* region interface functions */
2472 static void 
2473 _e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2474 {
2475    wl_resource_destroy(resource);
2476 }
2477
2478 static void 
2479 _e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h)
2480 {
2481    E_Wayland_Region *ewr = NULL;
2482
2483    /* try to cast the resource data to our region structure */
2484    if (!(ewr = wl_resource_get_user_data(resource))) return;
2485
2486    /* tell pixman to union this region with any previous one */
2487    pixman_region32_union_rect(&ewr->region, &ewr->region, x, y, w, h);
2488 }
2489
2490 static void 
2491 _e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h)
2492 {
2493    E_Wayland_Region *ewr = NULL;
2494    pixman_region32_t region;
2495
2496    /* try to cast the resource data to our region structure */
2497    if (!(ewr = wl_resource_get_user_data(resource))) return;
2498
2499    /* ask pixman to create a new temporary rect */
2500    pixman_region32_init_rect(&region, x, y, w, h);
2501
2502    /* ask pixman to subtract this temp rect from the existing region */
2503    pixman_region32_subtract(&ewr->region, &ewr->region, &region);
2504
2505    /* tell pixman we are finished with the temporary rect */
2506    pixman_region32_fini(&region);
2507 }
2508
2509 /* surface functions */
2510 static void 
2511 _e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
2512 {
2513    E_Wayland_Surface *ews = NULL;
2514
2515    /* try to get the surface from this listener */
2516    if (!(ews = container_of(listener, E_Wayland_Surface, 
2517                             pending.buffer_destroy)))
2518      return;
2519
2520    /* set surface pending buffer to null */
2521    ews->pending.buffer = NULL;
2522 }
2523
2524 static void 
2525 _e_comp_wl_surface_cb_frame_destroy(struct wl_resource *resource)
2526 {
2527    E_Wayland_Surface_Frame_Callback *cb = NULL;
2528
2529    /* try to cast the resource data to our surface frame callback structure */
2530    if (!(cb = wl_resource_get_user_data(resource))) return;
2531
2532    wl_list_remove(&cb->wl.link);
2533
2534    /* free the allocated callback structure */
2535    E_FREE(cb);
2536 }
2537
2538 static void 
2539 _e_comp_wl_surface_buffer_reference(E_Wayland_Buffer_Reference *ref, E_Wayland_Buffer *buffer)
2540 {
2541    if ((ref->buffer) && (buffer != ref->buffer))
2542      {
2543         ref->buffer->busy_count--;
2544         if (ref->buffer->busy_count == 0)
2545           wl_resource_queue_event(ref->buffer->wl.resource, WL_BUFFER_RELEASE);
2546         wl_list_remove(&ref->destroy_listener.link);
2547      }
2548
2549    if ((buffer) && (buffer != ref->buffer))
2550      {
2551         buffer->busy_count++;
2552         wl_signal_add(&buffer->wl.destroy_signal, &ref->destroy_listener);
2553      }
2554
2555    //INF("CURRENT BUFFER SWAP");
2556    ref->buffer = buffer;
2557    ref->destroy_listener.notify = 
2558      _e_comp_wl_surface_buffer_reference_cb_destroy;
2559 }
2560
2561 static void 
2562 _e_comp_wl_surface_buffer_reference_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
2563 {
2564    E_Wayland_Buffer_Reference *ref;
2565
2566    /* try to get the surface from this listener */
2567    ref = container_of(listener, E_Wayland_Buffer_Reference, destroy_listener);
2568    if (!ref) return;
2569
2570    /* set referenced buffer to null */
2571    ref->buffer = NULL;
2572 }
2573
2574 static E_Wayland_Buffer *
2575 _e_comp_wl_surface_buffer_resource(struct wl_resource *resource)
2576 {
2577    E_Wayland_Buffer *buffer;
2578    struct wl_listener *listener;
2579
2580    listener = 
2581      wl_resource_get_destroy_listener(resource, 
2582                                       _e_comp_wl_surface_buffer_cb_destroy);
2583    if (listener)
2584      buffer = container_of(listener, E_Wayland_Buffer, wl.destroy_listener);
2585    else
2586      {
2587         buffer = E_NEW_RAW(E_Wayland_Buffer, 1);
2588         memset(buffer, 0, sizeof(*buffer));
2589         buffer->wl.resource = resource;
2590         wl_signal_init(&buffer->wl.destroy_signal);
2591         buffer->wl.destroy_listener.notify = 
2592           _e_comp_wl_surface_buffer_cb_destroy;
2593         wl_resource_add_destroy_listener(resource, 
2594                                          &buffer->wl.destroy_listener);
2595      }
2596
2597    return buffer;
2598 }
2599
2600 static void 
2601 _e_comp_wl_surface_buffer_cb_destroy(struct wl_listener *listener, void *data)
2602 {
2603    E_Wayland_Buffer *buffer;
2604
2605    buffer = container_of(listener, E_Wayland_Buffer, wl.destroy_listener);
2606    wl_signal_emit(&buffer->wl.destroy_signal, buffer);
2607    if (buffer->ews && buffer->ews->pixmap && (e_pixmap_resource_get(buffer->ews->pixmap) == data))
2608      {
2609         if (buffer->ews->ec)
2610           {
2611              INF("DESTROYED CURRENT BUFFER: %s", e_pixmap_dirty_get(buffer->ews->pixmap) ? "DIRTY" : "CLEAN");
2612              e_pixmap_usable_set(buffer->ews->pixmap, 0);
2613              if (!e_pixmap_image_exists(buffer->ews->pixmap))
2614                {
2615                   e_pixmap_image_refresh(buffer->ews->pixmap);
2616                }
2617              
2618              e_pixmap_image_clear(buffer->ews->pixmap, 0);
2619              e_comp_object_damage(buffer->ews->ec->frame, 0, 0, buffer->ews->ec->client.w, buffer->ews->ec->client.h);
2620              e_comp_object_render(buffer->ews->ec->frame);
2621              e_comp_object_render_update_del(buffer->ews->ec->frame);
2622           }
2623      }
2624    E_FREE(buffer);
2625 }
2626
2627 /* surface interface functionss */
2628 static void 
2629 _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2630 {
2631    wl_resource_destroy(resource);
2632 }
2633
2634 static void 
2635 _e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int x, int y)
2636 {
2637    E_Wayland_Surface *ews = NULL;
2638    E_Wayland_Buffer *buffer = NULL;
2639
2640    /* try to cast the resource data to our surface structure */
2641    if (!(ews = wl_resource_get_user_data(resource))) return;
2642
2643    if (buffer_resource) 
2644      {
2645         buffer = _e_comp_wl_surface_buffer_resource(buffer_resource);
2646         if (ews->ec && (!ews->buffer_reference.buffer))
2647           {
2648              e_pixmap_usable_set(ews->pixmap, 1);
2649           }
2650      }
2651
2652    /* reference any existing buffers */
2653    _e_comp_wl_surface_buffer_reference(&ews->buffer_reference, buffer);
2654    //INF("ATTACHED NEW BUFFER");
2655    e_pixmap_dirty(ews->pixmap);
2656    //if (ews->ec)
2657      //e_comp_object_damage(ews->ec->frame, 0, 0, ews->ec->client.w, ews->ec->client.h);
2658      
2659
2660    /* if we are setting a null buffer, then unmap the surface */
2661    if (buffer)
2662      buffer->ews = ews;
2663    else
2664      {
2665         if (ews->mapped)
2666           {
2667              if (ews->unmap) ews->unmap(ews);
2668           }
2669      }
2670
2671    /* if we already have a pending buffer, remove the listener */
2672    if (ews->pending.buffer)
2673      wl_list_remove(&ews->pending.buffer_destroy.link);
2674
2675    /* set some pending values */
2676    ews->pending.x = x;
2677    ews->pending.y = y;
2678    ews->pending.buffer = buffer;
2679 //   if (buffer)
2680    ews->pending.new_buffer = EINA_TRUE;
2681
2682    /* if we were given a buffer, initialize the destroy signal */
2683    if (buffer)
2684      wl_signal_add(&buffer->wl.destroy_signal, &ews->pending.buffer_destroy);
2685 }
2686
2687 static void 
2688 _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h)
2689 {
2690    E_Wayland_Surface *ews = NULL;
2691
2692    /* try to cast the resource data to our surface structure */
2693    if (!(ews = wl_resource_get_user_data(resource))) return;
2694    e_pixmap_image_clear(ews->pixmap, 1);
2695
2696    /* tell pixman to add this damage to pending */
2697    pixman_region32_union_rect(&ews->pending.damage, &ews->pending.damage, 
2698                               x, y, w, h);
2699 }
2700
2701 static void 
2702 _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, unsigned int callback)
2703 {
2704    E_Wayland_Surface *ews = NULL;
2705    E_Wayland_Surface_Frame_Callback *cb = NULL;
2706
2707    /* try to cast the resource data to our surface structure */
2708    if (!(ews = wl_resource_get_user_data(resource))) return;
2709
2710    /* try to allocate space for a new frame callback */
2711    if (!(cb = E_NEW(E_Wayland_Surface_Frame_Callback, 1)))
2712      {
2713         wl_resource_post_no_memory(resource);
2714         return;
2715      }
2716
2717    cb->wl.resource = 
2718      wl_resource_create(client, &wl_callback_interface, 1, callback);
2719    wl_resource_set_implementation(cb->wl.resource, NULL, cb, 
2720                                   _e_comp_wl_surface_cb_frame_destroy);
2721
2722    /* add this callback to the surface list of pending frames */
2723    wl_list_insert(ews->pending.frames.prev, &cb->wl.link);
2724 }
2725
2726 static void 
2727 _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource)
2728 {
2729    E_Wayland_Surface *ews = NULL;
2730
2731    /* try to cast the resource data to our surface structure */
2732    if (!(ews = wl_resource_get_user_data(resource))) return;
2733
2734    if (region_resource)
2735      {
2736         E_Wayland_Region *ewr = NULL;
2737
2738         /* copy this region to the pending opaque region */
2739         if ((ewr = wl_resource_get_user_data(region_resource)))
2740           pixman_region32_copy(&ews->pending.opaque, &ewr->region);
2741      }
2742    else
2743      {
2744         /* tell pixman we are finished with this region */
2745         pixman_region32_fini(&ews->pending.opaque);
2746
2747         /* reinitalize the pending opaque region */
2748         pixman_region32_init(&ews->pending.opaque);
2749      }
2750 }
2751
2752 static void 
2753 _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource)
2754 {
2755    E_Wayland_Surface *ews = NULL;
2756
2757    /* try to cast the resource data to our surface structure */
2758    if (!(ews = wl_resource_get_user_data(resource))) return;
2759
2760    if (region_resource)
2761      {
2762         E_Wayland_Region *ewr = NULL;
2763
2764         /* copy this region to the pending input region */
2765         if ((ewr = wl_resource_get_user_data(region_resource)))
2766           pixman_region32_copy(&ews->pending.input, &ewr->region);
2767      }
2768    else
2769      {
2770         /* tell pixman we are finished with this region */
2771         pixman_region32_fini(&ews->pending.input);
2772
2773         /* reinitalize the pending input region */
2774         pixman_region32_init_rect(&ews->pending.input, INT32_MIN, INT32_MIN, 
2775                                   UINT32_MAX, UINT32_MAX);
2776      }
2777 }
2778
2779 static void 
2780 _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2781 {
2782    E_Wayland_Surface *ews = NULL;
2783    Evas_Coord bw = 0, bh = 0;
2784    pixman_region32_t opaque;
2785    pixman_box32_t *rects;
2786    int n = 0;
2787
2788    /* FIXME */
2789
2790    /* try to cast the resource data to our surface structure */
2791    if (!(ews = wl_resource_get_user_data(resource))) return;
2792
2793    /* if we have a pending buffer or a new pending buffer, attach it */
2794    if ((ews->pending.buffer) || (ews->pending.new_buffer))
2795      {
2796         /* reference the pending buffer */
2797         _e_comp_wl_surface_buffer_reference(&ews->buffer_reference, 
2798                                             ews->pending.buffer);
2799
2800         /* if the pending buffer is NULL, unmap the surface */
2801         if (ews->pending.buffer)
2802           ews->pending.buffer->ews = ews;
2803         else
2804           {
2805              if (ews->mapped)
2806                {
2807                   if (ews->unmap) ews->unmap(ews);
2808                }
2809           }
2810      }
2811    e_pixmap_dirty(ews->pixmap);
2812    e_pixmap_refresh(ews->pixmap);
2813    e_pixmap_size_get(ews->pixmap, &bw, &bh);
2814
2815    /* if we have a new pending buffer, call configure */
2816    if ((ews->configure) && (ews->pending.new_buffer))
2817 //     ews->configure(ews, ews->pending.x, ews->pending.y, bw, bh);
2818      ews->configure(ews, ews->geometry.x, ews->geometry.y, bw, bh);
2819
2820    if (ews->pending.buffer)
2821      wl_list_remove(&ews->pending.buffer_destroy.link);
2822
2823    /* set some pending values */
2824    ews->pending.buffer = NULL;
2825    ews->pending.x = 0;
2826    ews->pending.y = 0;
2827    ews->pending.new_buffer = EINA_FALSE;
2828
2829    /* set surface damage */
2830    pixman_region32_union(&ews->region.damage, &ews->region.damage, 
2831                          &ews->pending.damage);
2832    pixman_region32_intersect_rect(&ews->region.damage, &ews->region.damage, 
2833                                   0, 0, ews->geometry.w, ews->geometry.h);
2834
2835    /* empty any pending damage */
2836    pixman_region32_fini(&ews->pending.damage);
2837    pixman_region32_init(&ews->pending.damage);
2838
2839    /* get the extent of the damage region */
2840    if (ews->ec)
2841      {
2842         rects = pixman_region32_rectangles(&ews->region.damage, &n);
2843         while (n--)
2844           {
2845              pixman_box32_t *r;
2846
2847              r = &rects[n];
2848
2849              /* send damages to the image */
2850              e_comp_object_damage(ews->ec->frame, r->x1, r->y1, r->x2, r->y2);
2851           }
2852      }
2853
2854    /* tell pixman we are finished with this region */
2855    /* pixman_region32_fini(&ews->region.damage); */
2856
2857    /* reinitalize the damage region */
2858    /* pixman_region32_init(&ews->region.damage); */
2859
2860    /* calculate new opaque region */
2861    pixman_region32_init_rect(&opaque, 0, 0, ews->geometry.w, ews->geometry.h);
2862    pixman_region32_intersect(&opaque, &opaque, &ews->pending.opaque);
2863
2864    /* if new opaque region is not equal to the current one, then update */
2865    if (!pixman_region32_equal(&opaque, &ews->region.opaque))
2866      {
2867         pixman_region32_copy(&ews->region.opaque, &opaque);
2868         ews->geometry.changed = EINA_TRUE;
2869      }
2870
2871    /* tell pixman we are done with this temporary region */
2872    pixman_region32_fini(&opaque);
2873
2874    /* clear any existing input region */
2875    pixman_region32_fini(&ews->region.input);
2876
2877    /* initialize a new input region */
2878    pixman_region32_init_rect(&ews->region.input, 0, 0, 
2879                              ews->geometry.w, ews->geometry.h);
2880
2881    /* put pending input region into new input region */
2882    pixman_region32_intersect(&ews->region.input, &ews->region.input, 
2883                              &ews->pending.input);
2884
2885    /* check for valid input region */
2886 //   if (pixman_region32_not_empty(&ews->region.input))
2887      {
2888         /* get the extent of the input region */
2889         rects = pixman_region32_extents(&ews->region.input);
2890
2891         /* update the smart object's input region */
2892         if (ews->ec)
2893           e_comp_object_input_area_set(ews->ec->frame, rects->x1, rects->y1, 
2894                                        rects->x2, rects->y2); 
2895      }
2896
2897    /* put any pending frame callbacks into active list */
2898    wl_list_insert_list(&ews->wl.frames, &ews->pending.frames);
2899
2900    /* clear list of pending frame callbacks */
2901    wl_list_init(&ews->pending.frames);
2902
2903    ews->updates = 1;
2904
2905    _e_wl_comp->surfaces = eina_inlist_promote(_e_wl_comp->surfaces, EINA_INLIST_GET(ews));
2906
2907    /* TODO: schedule repaint ?? */
2908 }
2909
2910 static void 
2911 _e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int transform EINA_UNUSED)
2912 {
2913
2914 }
2915
2916 static void 
2917 _e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int scale EINA_UNUSED)
2918 {
2919
2920 }