815354063de806ee9ac72c89843a54bfb01bc17f
[platform/core/uifw/headless-server.git] / src / input / input.c
1 /*
2 * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #define USE_LIBDS
25
26 #ifdef USE_LIBDS
27 #include <stdlib.h>
28
29 #include <wayland-server.h>
30 #include <libds/log.h>
31 #include <libds/backend/libinput.h>
32 #include <libds/input_device.h>
33 #include <libds/keyboard.h>
34 #include <libds/seat.h>
35 #include <xkbcommon/xkbcommon.h>
36
37 #include "headless_server.h"
38
39 typedef struct headless_input headless_input_t;
40 typedef struct headless_keyboard headless_keyboard_t;
41
42 struct headless_input
43 {
44         headless_server_t *server;
45         headless_keyboard_t *keyboard;
46
47         struct ds_backend *backend;
48         struct ds_seat *seat;
49
50         struct wl_listener new_input;
51         struct wl_listener focus_change;
52 };
53
54 struct headless_keyboard
55 {
56         headless_input_t *input;
57
58         struct ds_input_device *dev;
59
60         struct wl_listener device_destroy;
61         struct wl_listener key;
62 };
63
64 static void handle_focus_change(struct wl_listener *listener, void *data);
65 static void handle_new_input(struct wl_listener *listener, void *data);
66 static headless_keyboard_t *create_keyboard(headless_input_t *input,
67                 struct ds_input_device *dev);
68 static void keyboard_destroy(headless_keyboard_t *keyboard);
69 static void keyboard_handle_destroy(struct wl_listener *listener, void *data);
70 static void keyboard_handle_key(struct wl_listener *listener, void *data);
71
72 headless_input_t *
73 headless_input_create(headless_server_t *server)
74 {
75         headless_input_t *input;
76
77         input = calloc(1, sizeof *input);
78         if (!input)
79                 return NULL;
80
81         input->server = server;
82
83         input->backend = ds_libinput_backend_create(server->display);
84         if (!input->backend) {
85                 ds_err("Could not create libinput backend");
86                 goto err_backend;
87         }
88
89         input->seat = ds_seat_create(server->display, "seat0");
90         if (!input->seat) {
91                 ds_err("Could not create ds_seat");
92                 goto err_seat;
93         }
94
95         input->new_input.notify = handle_new_input;
96         ds_backend_add_new_input_listener(input->backend, &input->new_input);
97
98         input->focus_change.notify = handle_focus_change;
99         wl_signal_add(&server->events.focus_change, &input->focus_change);
100
101         ds_backend_start(input->backend);
102
103         ds_inf("Created Headless input(%p)", input);
104
105         return input;
106
107 err_seat:
108         ds_backend_destroy(input->backend);
109 err_backend:
110         free(input);
111
112         return NULL;
113 }
114
115 void
116 headless_input_destroy(headless_input_t *input)
117 {
118         if (input->keyboard)
119                 keyboard_destroy(input->keyboard);
120
121         wl_list_remove(&input->focus_change.link);
122         wl_list_remove(&input->new_input.link);
123
124         ds_backend_destroy(input->backend);
125         free(input);
126 }
127
128 static void
129 handle_focus_change(struct wl_listener *listener, void *data)
130 {
131         headless_input_t *input;
132         headless_view_t *view = data;
133
134         input = wl_container_of(listener, input, focus_change);
135
136         if (view) {
137                 ds_seat_keyboard_notify_enter(input->seat, view->surface,
138                                 NULL, 0, NULL /* TODO */);
139         }
140         else {
141                 ds_seat_keyboard_notify_clear_focus(input->seat);
142         }
143 }
144
145 static void
146 handle_new_input(struct wl_listener *listener, void *data)
147 {
148         headless_input_t *input;
149         struct ds_input_device *dev = data;
150         enum ds_input_device_type dev_type;
151
152         input = wl_container_of(listener, input, new_input);
153
154         dev_type = ds_input_device_get_type(dev);
155
156         ds_inf("Input(%p): New input device(%p) type(%d)", input, dev, dev_type);
157
158         if (dev_type != DS_INPUT_DEVICE_KEYBOARD) {
159                 ds_inf("Not supported device: type(%d)", dev_type);
160                 return;
161         }
162
163         if (input->keyboard) {
164                 ds_inf("Already created keyboard device(%p)", input->keyboard);
165                 return;
166         }
167
168         input->keyboard = create_keyboard(input, dev);
169         if (!input->keyboard) {
170                 ds_err("Could not create keyboard");
171                 return;
172         }
173
174     ds_seat_set_keyboard(input->seat, dev);
175         ds_seat_set_capabilities(input->seat, WL_SEAT_CAPABILITY_KEYBOARD);
176 }
177
178 static headless_keyboard_t *
179 create_keyboard(headless_input_t *input, struct ds_input_device *dev)
180 {
181         headless_keyboard_t *keyboard;
182         struct ds_keyboard *ds_keyboard;
183         struct xkb_context *context;
184         struct xkb_keymap *keymap;
185
186         keyboard = calloc(1, sizeof *keyboard);
187         if (!keyboard) {
188                 ds_err("Could not allocate memory");
189                 return false;
190         }
191
192         keyboard->input = input;
193         keyboard->dev = dev;
194
195         keyboard->device_destroy.notify = keyboard_handle_destroy;
196         ds_input_device_add_destroy_listener(dev, &keyboard->device_destroy);
197
198         ds_keyboard = ds_input_device_get_keyboard(dev);
199
200         keyboard->key.notify = keyboard_handle_key;
201         ds_keyboard_add_key_listener(ds_keyboard, &keyboard->key);
202
203         context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
204         keymap = xkb_keymap_new_from_names(context, NULL,
205                         XKB_KEYMAP_COMPILE_NO_FLAGS);
206         ds_keyboard_set_keymap(ds_keyboard, keymap);
207         xkb_keymap_unref(keymap);
208         xkb_context_unref(context);
209
210         ds_inf("Input(%p): New keyboard(%p)", input, keyboard);
211
212         return keyboard;
213 }
214
215 static void
216 keyboard_destroy(headless_keyboard_t *keyboard)
217 {
218         ds_inf("Keyboard(%p) destroyed", keyboard);
219
220         wl_list_remove(&keyboard->key.link);
221         wl_list_remove(&keyboard->device_destroy.link);
222         free(keyboard);
223 }
224
225 static void
226 keyboard_handle_destroy(struct wl_listener *listener, void *data)
227 {
228         headless_keyboard_t *keyboard;
229
230         keyboard = wl_container_of(listener, keyboard, device_destroy);
231
232         keyboard->input->keyboard = NULL;
233
234         keyboard_destroy(keyboard);
235 }
236
237 static void
238 keyboard_handle_key(struct wl_listener *listener, void *data)
239 {
240         headless_keyboard_t *keyboard;
241         struct ds_event_keyboard_key *event = data;
242
243         keyboard = wl_container_of(listener, keyboard, key);
244
245         ds_inf("Keyboard(%p) key: keycode(%d), state(%d), time_msec(%d), "
246                         "update_state(%d)", keyboard, event->keycode, event->state,
247                         event->time_msec, event->update_state);
248
249         ds_seat_keyboard_notify_key(keyboard->input->seat, event->time_msec,
250                         event->keycode, event->state);
251 }
252 #else
253 #include <pepper-evdev.h>
254 #include <pepper-input-backend.h>
255 #include <pepper-keyrouter.h>
256 #include <pepper-devicemgr.h>
257 #include <pepper-xkb.h>
258 #include <pepper-inotify.h>
259
260 typedef struct
261 {
262         pepper_compositor_t *compositor;
263         pepper_seat_t *seat;
264         pepper_evdev_t *evdev;
265         pepper_keyboard_t *keyboard;
266         pepper_pointer_t *pointer;
267         pepper_touch_t *touch;
268         pepper_input_device_t *default_device;
269         pepper_inotify_t *inotify;
270
271         pepper_view_t *focus_view;
272         pepper_view_t *top_view;
273
274         pepper_keyrouter_t *keyrouter;
275         pepper_devicemgr_t *devicemgr;
276         pepper_xkb_t *xkb;
277
278         pepper_event_listener_t *listener_seat_keyboard_key;
279         pepper_event_listener_t *listener_seat_keyboard_add;
280         pepper_event_listener_t *listener_seat_pointer_event;
281         pepper_event_listener_t *listener_seat_pointer_add;
282         pepper_event_listener_t *listener_seat_touch_event;
283         pepper_event_listener_t *listener_seat_touch_add;
284         pepper_event_listener_t *listener_seat_add;
285         pepper_event_listener_t *listener_input_device_add;
286
287         uint32_t ndevices;
288 } headless_input_t;
289
290 const static int KEY_INPUT = 0xdeadbeaf;
291
292 static void headless_input_init_event_listeners(headless_input_t *hi);
293 static void headless_input_deinit_event_listeners(headless_input_t *hi);
294
295 /* pointer event handler */
296 static void
297 _handle_pointer_event(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
298 {
299         pepper_input_event_t *event;
300
301         PEPPER_CHECK((id >= PEPPER_EVENT_POINTER_MOTION && id <= PEPPER_EVENT_POINTER_AXIS), return, "unknown event %d !\n", id);
302         PEPPER_CHECK(info, return, "Invalid event !\n");
303         PEPPER_CHECK(data, return, "Invalid data !\n");
304
305         event = (pepper_input_event_t *)info;
306
307         /* TODO: */
308         (void) event;
309
310         switch (id)
311         {
312                 case PEPPER_EVENT_POINTER_MOTION:
313                         /* TODO: */
314                         PEPPER_TRACE("[%s] PEPPER_EVENT_POINTER_MOTION\n", __FUNCTION__);
315                         break;
316                 case PEPPER_EVENT_POINTER_MOTION_ABSOLUTE:
317                         /* TODO: */
318                         PEPPER_TRACE("[%s] PEPPER_EVENT_POINTER_MOTION_ABSOLUTE\n", __FUNCTION__);
319                         break;
320                 case PEPPER_EVENT_POINTER_BUTTON:
321                         /* TODO: */
322                         PEPPER_TRACE("[%s] PEPPER_EVENT_POINTER_BUTTON\n", __FUNCTION__);
323                         break;
324                 case PEPPER_EVENT_POINTER_AXIS:
325                         /* TODO: */
326                         PEPPER_TRACE("[%s] PEPPER_EVENT_POINTER_AXIS\n", __FUNCTION__);
327                         break;
328         }
329 }
330
331 /* touch event handler */
332 static void
333 _handle_touch_event(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
334 {
335         pepper_input_event_t *event;
336
337         PEPPER_CHECK((id >= PEPPER_EVENT_TOUCH_DOWN && id <= PEPPER_EVENT_TOUCH_CANCEL), return, "unknown event %d !\n", id);
338         PEPPER_CHECK(info, return, "Invalid event !\n");
339         PEPPER_CHECK(data, return, "Invalid data !\n");
340
341         event = (pepper_input_event_t *)info;
342
343         /* TODO: */
344         (void) event;
345
346         switch (id)
347         {
348                 case PEPPER_EVENT_TOUCH_DOWN:
349                         /* TODO: */
350                         PEPPER_TRACE("[%s] PEPPER_EVENT_TOUCH_DOWN\n", __FUNCTION__);
351                         break;
352                 case PEPPER_EVENT_TOUCH_UP:
353                         /* TODO: */
354                         PEPPER_TRACE("[%s] PEPPER_EVENT_TOUCH_UP\n", __FUNCTION__);
355                         break;
356                 case PEPPER_EVENT_TOUCH_MOTION:
357                         /* TODO: */
358                         PEPPER_TRACE("[%s] PEPPER_EVENT_TOUCH_MOTION\n", __FUNCTION__);
359                         break;
360                 case PEPPER_EVENT_TOUCH_FRAME:
361                         /* TODO: */
362                         PEPPER_TRACE("[%s] PEPPER_EVENT_TOUCH_FRAME\n", __FUNCTION__);
363                         break;
364                 case PEPPER_EVENT_TOUCH_CANCEL:
365                         /* TODO: */
366                         PEPPER_TRACE("[%s] PEPPER_EVENT_TOUCH_CANCEL\n", __FUNCTION__);
367                         break;
368         }
369 }
370
371 /* seat keyboard add event handler */
372 static void
373 _cb_handle_seat_keyboard_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
374 {
375         pepper_event_listener_t *h = NULL;
376         pepper_keyboard_t *keyboard = (pepper_keyboard_t *)info;
377         headless_input_t *hi = (headless_input_t *)data;
378
379         PEPPER_TRACE("[%s] keyboard added\n", __FUNCTION__);
380
381         /* FIXME: without a keymap, ecore wl2 based client must work properly. */
382         //pepper_keyboard_set_keymap_info(keyboard, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP, -1, 0);
383         pepper_xkb_keyboard_set_keymap(hi->xkb, keyboard, NULL);
384
385         pepper_keyrouter_set_keyboard(hi->keyrouter, keyboard);
386         h = pepper_object_add_event_listener((pepper_object_t *)keyboard, PEPPER_EVENT_KEYBOARD_KEY,
387                                                                 0, pepper_keyrouter_event_handler, hi->keyrouter);
388         PEPPER_CHECK(h, goto end, "Failed to add keyboard key listener.\n");
389         hi->listener_seat_keyboard_key = h;
390         hi->keyboard = keyboard;
391
392         return;
393
394 end:
395         headless_input_deinit_event_listeners(hi);
396 }
397
398 static void
399 _cb_handle_seat_pointer_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
400 {
401         pepper_event_listener_t *h = NULL;
402         pepper_pointer_t *pointer = (pepper_pointer_t *)info;
403         headless_input_t *hi = (headless_input_t *)data;
404
405         PEPPER_TRACE("[%s] pointer added\n", __FUNCTION__);
406
407         h = pepper_object_add_event_listener((pepper_object_t *)pointer,
408                                                                 PEPPER_EVENT_POINTER_MOTION
409                                                                 | PEPPER_EVENT_POINTER_MOTION_ABSOLUTE
410                                                                 | PEPPER_EVENT_POINTER_BUTTON
411                                                                 | PEPPER_EVENT_POINTER_AXIS,
412                                                                 0, _handle_pointer_event, hi->compositor);
413         PEPPER_CHECK(h, goto end, "Failed to add pointer listener.\n");
414         hi->listener_seat_pointer_event = h;
415         hi->pointer = pointer;
416
417         return;
418
419 end:
420         headless_input_deinit_event_listeners(hi);
421 }
422
423 static void
424 _cb_handle_seat_touch_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
425 {
426         pepper_event_listener_t *h = NULL;
427         pepper_touch_t *touch = (pepper_touch_t *)info;
428         headless_input_t *hi = (headless_input_t *)data;
429
430         PEPPER_TRACE("[%s] touch added\n", __FUNCTION__);
431
432         h = pepper_object_add_event_listener((pepper_object_t *)touch,
433                                                                 PEPPER_EVENT_TOUCH_DOWN
434                                                                 | PEPPER_EVENT_TOUCH_UP
435                                                                 | PEPPER_EVENT_TOUCH_MOTION
436                                                                 | PEPPER_EVENT_TOUCH_FRAME
437                                                                 | PEPPER_EVENT_TOUCH_CANCEL,
438                                                                 0, _handle_touch_event, hi->compositor);
439         PEPPER_CHECK(h, goto end, "Failed to add touch listener.\n");
440         hi->listener_seat_touch_event = h;
441         hi->touch = touch;
442
443         return;
444
445 end:
446         headless_input_deinit_event_listeners(hi);
447 }
448
449 /* compositor input device add event handler */
450 static void
451 _cb_handle_input_device_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
452 {
453         pepper_input_device_t *device = (pepper_input_device_t *)info;
454         headless_input_t *hi = (headless_input_t *)data;
455
456         PEPPER_TRACE("[%s] input device added.\n", __FUNCTION__);
457
458         if (hi->seat)
459                 pepper_seat_add_input_device(hi->seat, device);
460 }
461
462 /* seat add event handler */
463 static void
464 _cb_handle_seat_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
465 {
466         pepper_event_listener_t *key = NULL;
467         pepper_event_listener_t *pointer = NULL;
468         pepper_event_listener_t *touch = NULL;
469         pepper_seat_t *seat = (pepper_seat_t *)info;
470         headless_input_t *hi = (headless_input_t *)data;
471
472         PEPPER_TRACE("[%s] seat added. name:%s\n", __FUNCTION__, pepper_seat_get_name(seat));
473
474         key = pepper_object_add_event_listener((pepper_object_t *)seat, PEPPER_EVENT_SEAT_KEYBOARD_ADD,
475                                                                 0, _cb_handle_seat_keyboard_add, hi);
476
477         PEPPER_CHECK(key, goto end, "Failed to add seat keyboard add listener.\n");
478         hi->listener_seat_keyboard_add = key;
479
480         pointer = pepper_object_add_event_listener((pepper_object_t *)seat, PEPPER_EVENT_SEAT_POINTER_ADD,
481                                                                 0, _cb_handle_seat_pointer_add, hi);
482         PEPPER_CHECK(pointer, goto end, "Failed to add seat pointer add listener.\n");
483         hi->listener_seat_pointer_add = pointer;
484
485         touch = pepper_object_add_event_listener((pepper_object_t *)seat, PEPPER_EVENT_SEAT_TOUCH_ADD,
486                                                                 0, _cb_handle_seat_touch_add, hi);
487         PEPPER_CHECK(touch, goto end, "Failed to add seat touch add listener.\n");
488         hi->listener_seat_touch_add = touch;
489
490         return;
491
492 end:
493         headless_input_deinit_event_listeners(hi);
494 }
495
496 static void
497 _cb_handle_inotify_event(uint32_t type, pepper_inotify_event_t *ev, void *data)
498 {
499         headless_input_t *hi = data;
500
501         PEPPER_CHECK(hi, return, "Invalid headless input\n");
502
503         switch (type)
504         {
505                 case PEPPER_INOTIFY_EVENT_TYPE_CREATE:
506                         pepper_evdev_device_path_add(hi->evdev, pepper_inotify_event_name_get(ev));
507                         break;
508                 case PEPPER_INOTIFY_EVENT_TYPE_REMOVE:
509                         pepper_evdev_device_path_remove(hi->evdev, pepper_inotify_event_name_get(ev));
510                         break;
511                 case PEPPER_INOTIFY_EVENT_TYPE_MODIFY:
512                         pepper_evdev_device_path_remove(hi->evdev, pepper_inotify_event_name_get(ev));
513                         pepper_evdev_device_path_add(hi->evdev, pepper_inotify_event_name_get(ev));
514                         break;
515                 default:
516                         break;
517         }
518 }
519
520 PEPPER_API void *
521 headless_input_get_keyrouter(pepper_compositor_t *compositor)
522 {
523         headless_input_t *hi;
524         hi = pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_INPUT);
525         PEPPER_CHECK(hi, return NULL, "input system is not initialized\n");
526
527         return hi->keyrouter;
528 }
529
530 PEPPER_API void *
531 headless_input_get_xkb(pepper_compositor_t *compositor)
532 {
533         headless_input_t *hi;
534         hi = pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_INPUT);
535         PEPPER_CHECK(hi, return NULL, "input system is not initialized\n");
536
537         return hi->xkb;
538 }
539
540 void
541 headless_input_set_focus_view(pepper_compositor_t *compositor, pepper_view_t *focus_view)
542 {
543         headless_input_t *hi;
544
545         hi = (headless_input_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_INPUT);
546         PEPPER_CHECK(hi, return, "Invalid headless input.\n");
547
548         if (hi->focus_view != focus_view)
549         {
550                 pepper_keyboard_send_leave(hi->keyboard, hi->focus_view);
551                 pepper_keyboard_set_focus(hi->keyboard, focus_view);
552                 pepper_keyboard_send_enter(hi->keyboard, focus_view);
553
554                 hi->focus_view = focus_view;
555         }
556
557         if (hi->keyrouter)
558                 pepper_keyrouter_set_focus_view(hi->keyrouter, focus_view);
559 }
560
561 void
562 headless_input_set_top_view(void *compositor, pepper_view_t *top_view)
563 {
564         headless_input_t *hi;
565
566         hi = (headless_input_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_INPUT);
567         PEPPER_CHECK(hi, return, "Invalid headless input.\n");
568
569         if (hi->top_view == top_view) return;
570
571         hi->top_view = top_view;
572
573         if (hi->keyrouter)
574                 pepper_keyrouter_set_top_view(hi->keyrouter, top_view);
575 }
576
577 static void
578 headless_input_init_event_listeners(headless_input_t *hi)
579 {
580         pepper_event_listener_t *h = NULL;
581         pepper_object_t *compositor = (pepper_object_t *)hi->compositor;
582
583         /* register event listeners */
584         h = pepper_object_add_event_listener((pepper_object_t *)compositor,
585                                                 PEPPER_EVENT_COMPOSITOR_SEAT_ADD, 0, _cb_handle_seat_add, hi);
586         PEPPER_CHECK(h, goto end, "Failed to add seat add listener.\n");
587         hi->listener_seat_add = h;
588
589         h = pepper_object_add_event_listener((pepper_object_t *)compositor,
590                                                 PEPPER_EVENT_COMPOSITOR_INPUT_DEVICE_ADD, 0, _cb_handle_input_device_add, hi);
591         PEPPER_CHECK(h, goto end, "Failed to add input device add listener.\n");
592         hi->listener_input_device_add = h;
593
594         return;
595
596 end:
597         PEPPER_ERROR("[%s] Failed to init listeners", __FUNCTION__);
598         headless_input_deinit_event_listeners(hi);
599 }
600
601 static void
602 headless_input_deinit_event_listeners(headless_input_t *hi)
603 {
604         if(hi->listener_seat_keyboard_key)      pepper_event_listener_remove(hi->listener_seat_keyboard_key);
605         if(hi->listener_seat_keyboard_add)      pepper_event_listener_remove(hi->listener_seat_keyboard_add);
606         if(hi->listener_seat_pointer_add)       pepper_event_listener_remove(hi->listener_seat_pointer_add);
607         if(hi->listener_seat_pointer_event)     pepper_event_listener_remove(hi->listener_seat_pointer_event);
608         if(hi->listener_seat_touch_add)         pepper_event_listener_remove(hi->listener_seat_touch_add);
609         if(hi->listener_seat_touch_event)       pepper_event_listener_remove(hi->listener_seat_touch_event);
610         pepper_event_listener_remove(hi->listener_seat_add);
611         pepper_event_listener_remove(hi->listener_input_device_add);
612
613         PEPPER_TRACE("[%s] event listeners have been removed.\n", __FUNCTION__);
614 }
615
616 static void
617 headless_input_deinit_input(headless_input_t *hi)
618 {
619         if (hi->inotify)
620         {
621                 pepper_inotify_destroy(hi->inotify);
622                 hi->inotify = NULL;
623         }
624
625         if (hi->default_device)
626         {
627                 pepper_input_device_destroy(hi->default_device);
628                 hi->default_device = NULL;
629         }
630
631         pepper_evdev_destroy(hi->evdev);
632
633         if (hi->seat)
634                 pepper_seat_destroy(hi->seat);
635
636         hi->seat = NULL;
637         hi->evdev = NULL;
638         hi->ndevices = 0;
639 }
640
641 static pepper_bool_t
642 headless_input_create_input_device(headless_input_t *hi, uint32_t caps)
643 {
644         pepper_input_device_t *input_device = NULL;
645
646         /* create a default pepper input device */
647         input_device = pepper_input_device_create(hi->compositor, caps, NULL, hi);
648         PEPPER_CHECK(input_device, return PEPPER_FALSE, "Failed to create a keyboard device !\n");
649
650         hi->default_device = input_device;
651         return PEPPER_TRUE;
652 }
653
654 static pepper_bool_t
655 headless_input_init_input(headless_input_t *hi)
656 {
657         uint32_t caps = 0;
658         uint32_t probed = 0;
659         pepper_bool_t res = PEPPER_FALSE;
660         pepper_evdev_t *evdev = NULL;
661         pepper_inotify_t *inotify = NULL;
662
663         /* create pepper evdev */
664         evdev = pepper_evdev_create(hi->compositor);
665         PEPPER_CHECK(evdev, goto end, "Failed to create evdev !\n");
666
667         hi->evdev = evdev;
668
669         /* get capabilities for a default pepper input device*/
670         if (getenv("WAYLAND_INPUT_KEYBOARD"))
671                 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
672         if (getenv("WAYLAND_INPUT_POINTER"))
673                 caps |= WL_SEAT_CAPABILITY_POINTER;
674         if (getenv("WAYLAND_INPUT_TOUCH"))
675                 caps |= WL_SEAT_CAPABILITY_TOUCH;
676
677         if(!caps)
678                 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
679         probed = pepper_evdev_device_probe(evdev, caps);
680
681
682         if (!probed)
683         {
684                 PEPPER_TRACE("No evdev device has been probed. A default key device will be created.\n");
685
686                 res = headless_input_create_input_device(hi, caps);
687                 PEPPER_CHECK(res,  goto end, "Failed to create any input device(s) !\n");
688
689                 probed++;
690         }
691
692         hi->ndevices = probed;
693
694         PEPPER_TRACE("%d evdev device(s) has been found.\n", probed);
695
696         inotify = pepper_inotify_create(hi->compositor, _cb_handle_inotify_event, hi);
697         PEPPER_CHECK(inotify, goto end, "Failed to create inotify\n");
698
699         pepper_inotify_add(inotify, "/dev/input/");
700
701         hi->inotify = inotify;
702
703         return PEPPER_TRUE;
704
705 end:
706         pepper_evdev_destroy(evdev);
707
708         return PEPPER_FALSE;
709 }
710
711 static void
712 headless_input_init_modules(headless_input_t *hi)
713 {
714         const char *seat_name = NULL;
715         pepper_seat_t *seat = NULL;
716
717         pepper_keyrouter_t *keyrouter = NULL;
718         pepper_devicemgr_t *devicemgr = NULL;
719         pepper_xkb_t *xkb = NULL;
720
721         PEPPER_TRACE("[%s] ... begin\n", __FUNCTION__);
722
723         seat_name = getenv("XDG_SEAT");
724
725         if (!seat_name)
726                 seat_name = "seat0";
727
728         /* create a default seat (seat0) */
729         seat = pepper_compositor_add_seat(hi->compositor, seat_name);
730         PEPPER_CHECK(seat, goto end, "Failed to add seat (%s)!\n", seat_name);
731
732         hi->seat = seat;
733
734         /* create pepper xkb */
735         xkb = pepper_xkb_create();
736         PEPPER_CHECK(xkb, goto end, "Failed to create pepper_xkb !\n");
737
738         hi->xkb = xkb;
739
740         /* create pepper keyrouter */
741         keyrouter = pepper_keyrouter_create(hi->compositor);
742         PEPPER_CHECK(keyrouter, goto end, "Failed to create keyrouter !\n");
743
744         hi->keyrouter = keyrouter;
745
746         /* create pepper devicemgr */
747         devicemgr = pepper_devicemgr_create(hi->compositor, hi->seat);
748         PEPPER_CHECK(devicemgr, goto end, "Failed to create devicemgr !\n");
749         pepper_devicemgr_xkb_enable(devicemgr);
750
751         hi->devicemgr = devicemgr;
752
753         PEPPER_TRACE("[%s] ... done\n", __FUNCTION__);
754
755         return;
756 end:
757         if (hi->xkb)
758                 pepper_xkb_destroy(hi->xkb);
759         if (hi->keyrouter)
760                 pepper_keyrouter_destroy(hi->keyrouter);
761         if (hi->devicemgr)
762                 pepper_devicemgr_destroy(hi->devicemgr);
763         if (hi->seat)
764                 pepper_seat_destroy(hi->seat);
765
766         hi->xkb = NULL;
767         hi->keyrouter = NULL;
768         hi->devicemgr = NULL;
769         hi->seat = NULL;
770 }
771
772 static void
773 headless_input_deinit_modules(headless_input_t *hi)
774 {
775         if (hi->xkb)
776                 pepper_xkb_destroy(hi->xkb);
777         if (hi->keyrouter)
778                 pepper_keyrouter_destroy(hi->keyrouter);
779         if (hi->devicemgr)
780                 pepper_devicemgr_destroy(hi->devicemgr);
781
782         hi->xkb = NULL;
783         hi->keyrouter = NULL;
784         hi->devicemgr = NULL;
785 }
786
787 PEPPER_API void
788 headless_input_deinit(pepper_compositor_t * compositor)
789 {
790         headless_input_t *hi = NULL;
791
792         hi = (headless_input_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_INPUT);
793         PEPPER_CHECK(hi, return, "Failed to get headless input instance.\n");
794
795         headless_input_deinit_event_listeners(hi);
796         headless_input_deinit_modules(hi);
797         headless_input_deinit_input(hi);
798
799         pepper_object_set_user_data((pepper_object_t *)hi->compositor, &KEY_INPUT, NULL, NULL);
800         free(hi);
801 }
802
803 pepper_bool_t
804 headless_input_init(pepper_compositor_t *compositor)
805 {
806         headless_input_t *hi = NULL;
807         pepper_bool_t init = PEPPER_FALSE;
808
809         hi = (headless_input_t*)calloc(1, sizeof(headless_input_t));
810         PEPPER_CHECK(hi, goto error, "Failed to alloc for input\n");
811         hi->compositor = compositor;
812
813         headless_input_init_event_listeners(hi);
814         headless_input_init_modules(hi);
815         init = headless_input_init_input(hi);
816         PEPPER_CHECK(init, goto error, "headless_input_init_input() failed\n");
817
818         pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_INPUT, hi, NULL);
819
820         return PEPPER_TRUE;
821
822 error:
823         headless_input_deinit(compositor);
824
825         return PEPPER_FALSE;
826 }
827 #endif