6d32d3b427b9d74068dde2a1c45683a753d81ba5
[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 #include <pepper-evdev.h>
25 #include <pepper-input-backend.h>
26 #include <pepper-keyrouter.h>
27 #include <pepper-devicemgr.h>
28 #include <pepper-xkb.h>
29 #include <pepper-inotify.h>
30
31 typedef struct
32 {
33         pepper_compositor_t *compositor;
34         pepper_seat_t *seat;
35         pepper_evdev_t *evdev;
36         pepper_keyboard_t *keyboard;
37         pepper_input_device_t *default_device;
38         pepper_inotify_t *inotify;
39
40         pepper_view_t *focus_view;
41         pepper_view_t *top_view;
42
43         pepper_keyrouter_t *keyrouter;
44         pepper_devicemgr_t *devicemgr;
45         pepper_xkb_t *xkb;
46
47         pepper_event_listener_t *listener_seat_keyboard_key;
48         pepper_event_listener_t *listener_seat_keyboard_add;
49         pepper_event_listener_t *listener_seat_add;
50         pepper_event_listener_t *listener_input_device_add;
51
52         uint32_t ndevices;
53 } headless_input_t;
54
55 const static int KEY_INPUT = 0xdeadbeaf;
56
57 static void headless_input_init_event_listeners(headless_input_t *hi);
58 static void headless_input_deinit_event_listeners(headless_input_t *hi);
59
60 /* seat keyboard add event handler */
61 static void
62 _cb_handle_seat_keyboard_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
63 {
64         pepper_event_listener_t *h = NULL;
65         pepper_keyboard_t *keyboard = (pepper_keyboard_t *)info;
66         headless_input_t *hi = (headless_input_t *)data;
67
68         PEPPER_TRACE("[%s] keyboard added\n", __FUNCTION__);
69
70         /* FIXME: without a keymap, ecore wl2 based client must work properly. */
71         //pepper_keyboard_set_keymap_info(keyboard, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP, -1, 0);
72         pepper_xkb_keyboard_set_keymap(hi->xkb, keyboard, NULL);
73
74         pepper_keyrouter_set_keyboard(hi->keyrouter, keyboard);
75         h = pepper_object_add_event_listener((pepper_object_t *)keyboard, PEPPER_EVENT_KEYBOARD_KEY,
76                                                                 0, pepper_keyrouter_event_handler, hi->keyrouter);
77         PEPPER_CHECK(h, goto end, "Failed to add keyboard key listener.\n");
78         hi->listener_seat_keyboard_key = h;
79         hi->keyboard = keyboard;
80
81         return;
82
83 end:
84         headless_input_deinit_event_listeners(hi);
85 }
86
87 /* compositor input device add event handler */
88 static void
89 _cb_handle_input_device_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
90 {
91         pepper_input_device_t *device = (pepper_input_device_t *)info;
92         headless_input_t *hi = (headless_input_t *)data;
93
94         PEPPER_TRACE("[%s] input device added.\n", __FUNCTION__);
95
96         if (hi->seat)
97                 pepper_seat_add_input_device(hi->seat, device);
98 }
99
100 /* seat add event handler */
101 static void
102 _cb_handle_seat_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
103 {
104         pepper_event_listener_t *h = NULL;
105         pepper_seat_t *seat = (pepper_seat_t *)info;
106         headless_input_t *hi = (headless_input_t *)data;
107
108         PEPPER_TRACE("[%s] seat added. name:%s\n", __FUNCTION__, pepper_seat_get_name(seat));
109
110         h = pepper_object_add_event_listener((pepper_object_t *)seat, PEPPER_EVENT_SEAT_KEYBOARD_ADD,
111                                                                 0, _cb_handle_seat_keyboard_add, hi);
112         PEPPER_CHECK(h, goto end, "Failed to add seat keyboard add listener.\n");
113         hi->listener_seat_keyboard_add = h;
114
115         return;
116
117 end:
118         headless_input_deinit_event_listeners(hi);
119 }
120
121 static void
122 _cb_handle_inotify_event(uint32_t type, pepper_inotify_event_t *ev, void *data)
123 {
124         headless_input_t *hi = data;
125
126         PEPPER_CHECK(hi, return, "Invalid headless input\n");
127
128         switch (type)
129         {
130                 case PEPPER_INOTIFY_EVENT_TYPE_CREATE:
131                         pepper_evdev_device_path_add(hi->evdev, pepper_inotify_event_name_get(ev));
132                         break;
133                 case PEPPER_INOTIFY_EVENT_TYPE_REMOVE:
134                         pepper_evdev_device_path_remove(hi->evdev, pepper_inotify_event_name_get(ev));
135                         break;
136                 case PEPPER_INOTIFY_EVENT_TYPE_MODIFY:
137                         pepper_evdev_device_path_remove(hi->evdev, pepper_inotify_event_name_get(ev));
138                         pepper_evdev_device_path_add(hi->evdev, pepper_inotify_event_name_get(ev));
139                         break;
140                 default:
141                         break;
142         }
143 }
144
145 PEPPER_API void *
146 headless_input_get_keyrouter(pepper_compositor_t *compositor)
147 {
148         headless_input_t *hi;
149         hi = pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_INPUT);
150         PEPPER_CHECK(hi, return NULL, "input system is not initialized\n");
151
152         return hi->keyrouter;
153 }
154
155 PEPPER_API void *
156 headless_input_get_xkb(pepper_compositor_t *compositor)
157 {
158         headless_input_t *hi;
159         hi = pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_INPUT);
160         PEPPER_CHECK(hi, return NULL, "input system is not initialized\n");
161
162         return hi->xkb;
163 }
164
165 void
166 headless_input_set_focus_view(pepper_compositor_t *compositor, pepper_view_t *focus_view)
167 {
168         headless_input_t *hi;
169
170         hi = (headless_input_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_INPUT);
171         PEPPER_CHECK(hi, return, "Invalid headless input.\n");
172
173         if (hi->focus_view != focus_view)
174         {
175                 pepper_keyboard_send_leave(hi->keyboard, hi->focus_view);
176                 pepper_keyboard_set_focus(hi->keyboard, focus_view);
177                 pepper_keyboard_send_enter(hi->keyboard, focus_view);
178
179                 hi->focus_view = focus_view;
180         }
181
182         if (hi->keyrouter)
183                 pepper_keyrouter_set_focus_view(hi->keyrouter, focus_view);
184 }
185
186 void
187 headless_input_set_top_view(void *compositor, pepper_view_t *top_view)
188 {
189         headless_input_t *hi;
190
191         hi = (headless_input_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_INPUT);
192         PEPPER_CHECK(hi, return, "Invalid headless input.\n");
193
194         if (hi->top_view == top_view) return;
195
196         hi->top_view = top_view;
197
198         if (hi->keyrouter)
199                 pepper_keyrouter_set_top_view(hi->keyrouter, top_view);
200 }
201
202 static void
203 headless_input_init_event_listeners(headless_input_t *hi)
204 {
205         pepper_event_listener_t *h = NULL;
206         pepper_object_t *compositor = (pepper_object_t *)hi->compositor;
207
208         /* register event listeners */
209         h = pepper_object_add_event_listener((pepper_object_t *)compositor,
210                                                 PEPPER_EVENT_COMPOSITOR_SEAT_ADD, 0, _cb_handle_seat_add, hi);
211         PEPPER_CHECK(h, goto end, "Failed to add seat add listener.\n");
212         hi->listener_seat_add = h;
213
214         h = pepper_object_add_event_listener((pepper_object_t *)compositor,
215                                                 PEPPER_EVENT_COMPOSITOR_INPUT_DEVICE_ADD, 0, _cb_handle_input_device_add, hi);
216         PEPPER_CHECK(h, goto end, "Failed to add input device add listener.\n");
217         hi->listener_input_device_add = h;
218
219         return;
220
221 end:
222         PEPPER_ERROR("[%s] Failed to init listeners", __FUNCTION__);
223         headless_input_deinit_event_listeners(hi);
224 }
225
226 static void
227 headless_input_deinit_event_listeners(headless_input_t *hi)
228 {
229         pepper_event_listener_remove(hi->listener_seat_keyboard_key);
230         pepper_event_listener_remove(hi->listener_seat_keyboard_add);
231         pepper_event_listener_remove(hi->listener_seat_add);
232         pepper_event_listener_remove(hi->listener_input_device_add);
233
234         PEPPER_TRACE("[%s] event listeners have been removed.\n", __FUNCTION__);
235 }
236
237 static void
238 headless_input_deinit_input(headless_input_t *hi)
239 {
240         if (hi->inotify)
241         {
242                 pepper_inotify_destroy(hi->inotify);
243                 hi->inotify = NULL;
244         }
245
246         if (hi->default_device)
247         {
248                 pepper_input_device_destroy(hi->default_device);
249                 hi->default_device = NULL;
250         }
251
252         pepper_evdev_destroy(hi->evdev);
253
254         if (hi->seat)
255                 pepper_seat_destroy(hi->seat);
256
257         hi->seat = NULL;
258         hi->evdev = NULL;
259         hi->ndevices = 0;
260 }
261
262 static pepper_bool_t
263 headless_input_create_input_device(headless_input_t *hi, uint32_t caps)
264 {
265         pepper_input_device_t *input_device = NULL;
266
267         /* create a default pepper input device */
268         input_device = pepper_input_device_create(hi->compositor, caps, NULL, hi);
269         PEPPER_CHECK(input_device, return PEPPER_FALSE, "Failed to create a keyboard device !\n");
270
271         hi->default_device = input_device;
272         return PEPPER_TRUE;
273 }
274
275 static pepper_bool_t
276 headless_input_init_input(headless_input_t *hi)
277 {
278         uint32_t caps = 0;
279         uint32_t probed = 0;
280         pepper_bool_t res = PEPPER_FALSE;
281         pepper_evdev_t *evdev = NULL;
282         pepper_inotify_t *inotify = NULL;
283
284         /* create pepper evdev */
285         evdev = pepper_evdev_create(hi->compositor);
286         PEPPER_CHECK(evdev, goto end, "Failed to create evdev !\n");
287
288         hi->evdev = evdev;
289
290         /* probe evdev keyboard device(s) */
291         caps |= WL_SEAT_CAPABILITY_KEYBOARD;
292         probed = pepper_evdev_device_probe(evdev, caps);
293
294         if (!probed)
295         {
296                 PEPPER_TRACE("No evdev device has been probed. A default key device will be created.\n");
297
298                 res = headless_input_create_input_device(hi, caps);
299                 PEPPER_CHECK(res,  goto end, "Failed to create any input device(s) !\n");
300
301                 probed++;
302         }
303
304         hi->ndevices = probed;
305
306         PEPPER_TRACE("%d evdev device(s) has been found.\n", probed);
307
308         inotify = pepper_inotify_create(hi->compositor, _cb_handle_inotify_event, hi);
309         PEPPER_CHECK(inotify, goto end, "Failed to create inotify\n");
310
311         pepper_inotify_add(inotify, "/dev/input/");
312
313         hi->inotify = inotify;
314
315         return PEPPER_TRUE;
316
317 end:
318         pepper_evdev_destroy(evdev);
319
320         return PEPPER_FALSE;
321 }
322
323 static void
324 headless_input_init_modules(headless_input_t *hi)
325 {
326         const char *seat_name = NULL;
327         pepper_seat_t *seat = NULL;
328
329         pepper_keyrouter_t *keyrouter = NULL;
330         pepper_devicemgr_t *devicemgr = NULL;
331         pepper_xkb_t *xkb = NULL;
332
333         PEPPER_TRACE("[%s] ... begin\n", __FUNCTION__);
334
335         seat_name = getenv("XDG_SEAT");
336
337         if (!seat_name)
338                 seat_name = "seat0";
339
340         /* create a default seat (seat0) */
341         seat = pepper_compositor_add_seat(hi->compositor, seat_name);
342         PEPPER_CHECK(seat, goto end, "Failed to add seat (%s)!\n", seat_name);
343
344         hi->seat = seat;
345
346         /* create pepper xkb */
347         xkb = pepper_xkb_create();
348         PEPPER_CHECK(xkb, goto end, "Failed to create pepper_xkb !\n");
349
350         hi->xkb = xkb;
351
352         /* create pepper keyrouter */
353         keyrouter = pepper_keyrouter_create(hi->compositor);
354         PEPPER_CHECK(keyrouter, goto end, "Failed to create keyrouter !\n");
355
356         hi->keyrouter = keyrouter;
357
358         /* create pepper devicemgr */
359         devicemgr = pepper_devicemgr_create(hi->compositor, hi->seat);
360         PEPPER_CHECK(devicemgr, goto end, "Failed to create devicemgr !\n");
361         pepper_devicemgr_xkb_enable(devicemgr);
362
363         hi->devicemgr = devicemgr;
364
365         PEPPER_TRACE("[%s] ... done\n", __FUNCTION__);
366
367         return;
368 end:
369         if (hi->xkb)
370                 pepper_xkb_destroy(hi->xkb);
371         if (hi->keyrouter)
372                 pepper_keyrouter_destroy(hi->keyrouter);
373         if (hi->devicemgr)
374                 pepper_devicemgr_destroy(hi->devicemgr);
375         if (hi->seat)
376                 pepper_seat_destroy(hi->seat);
377
378         hi->xkb = NULL;
379         hi->keyrouter = NULL;
380         hi->devicemgr = NULL;
381         hi->seat = NULL;
382 }
383
384 static void
385 headless_input_deinit_modules(headless_input_t *hi)
386 {
387         if (hi->xkb)
388                 pepper_xkb_destroy(hi->xkb);
389         if (hi->keyrouter)
390                 pepper_keyrouter_destroy(hi->keyrouter);
391         if (hi->devicemgr)
392                 pepper_devicemgr_destroy(hi->devicemgr);
393
394         hi->xkb = NULL;
395         hi->keyrouter = NULL;
396         hi->devicemgr = NULL;
397 }
398
399 PEPPER_API void
400 headless_input_deinit(pepper_compositor_t * compositor)
401 {
402         headless_input_t *hi = NULL;
403
404         hi = (headless_input_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_INPUT);
405         PEPPER_CHECK(hi, return, "Failed to get headless input instance.\n");
406
407         headless_input_deinit_event_listeners(hi);
408         headless_input_deinit_modules(hi);
409         headless_input_deinit_input(hi);
410
411         pepper_object_set_user_data((pepper_object_t *)hi->compositor, &KEY_INPUT, NULL, NULL);
412         free(hi);
413 }
414
415 pepper_bool_t
416 headless_input_init(pepper_compositor_t *compositor)
417 {
418         headless_input_t *hi = NULL;
419         pepper_bool_t init = PEPPER_FALSE;
420
421         hi = (headless_input_t*)calloc(1, sizeof(headless_input_t));
422         PEPPER_CHECK(hi, goto error, "Failed to alloc for input\n");
423         hi->compositor = compositor;
424
425         headless_input_init_event_listeners(hi);
426         headless_input_init_modules(hi);
427         init = headless_input_init_input(hi);
428         PEPPER_CHECK(init, goto error, "headless_input_init_input() failed\n");
429
430         pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_INPUT, hi, NULL);
431
432         return PEPPER_TRUE;
433
434 error:
435         headless_input_deinit(compositor);
436
437         return PEPPER_FALSE;
438 }