pepper-evdev: fix to refer to event source only when it's valid
[platform/core/uifw/pepper.git] / src / lib / evdev / evdev.c
1 /*
2 * Copyright © 2015-2017 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 _GNU_SOURCE
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <stdint.h>
33 #include <dirent.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <linux/input.h>
37
38 #include <evdev-internal.h>
39 #include <pepper-input-backend.h>
40
41 #ifdef EVENT_MAX
42 #undef EVENT_MAX
43 #endif
44 #define EVENT_MAX 32
45
46 #ifndef LONG_BITS
47 #define LONG_BITS (sizeof(long) * 8)
48 #endif
49
50 #ifndef NLONGS
51 #define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
52 #endif
53
54 static void
55 _evdev_keyboard_event_post(pepper_input_device_t *device, uint32_t keycode, int state, uint32_t time)
56 {
57         pepper_input_event_t event;
58
59         event.time = time;
60         event.key = keycode;
61         event.state = state ? PEPPER_KEY_STATE_PRESSED : PEPPER_KEY_STATE_RELEASED;
62
63         pepper_object_emit_event((pepper_object_t *)device,
64                                                                 PEPPER_EVENT_INPUT_DEVICE_KEYBOARD_KEY, &event);
65 }
66
67 static void
68 _evdev_keyboard_event_flush(pepper_evdev_t *evdev)
69 {
70         evdev_key_event_t *event = NULL;
71         evdev_key_event_t *tmp = NULL;
72
73         pepper_list_for_each_safe(event, tmp, &evdev->key_event_queue, link)
74         {
75                 _evdev_keyboard_event_post(event->device, event->keycode, event->state, event->time);
76                 pepper_list_remove(&event->link);
77                 free(event);
78         }
79 }
80
81 static void
82 _evdev_keyboard_event_queue(uint32_t keycode, int state, uint32_t time, evdev_device_info_t *device_info)
83 {
84         evdev_key_event_t *event = NULL;
85         pepper_evdev_t *evdev = device_info->evdev;
86
87         event = (evdev_key_event_t *)calloc(1, sizeof(evdev_key_event_t));
88         PEPPER_CHECK(event, return, "[%s] Failed to allocate memory for key event.\n", __FUNCTION__);
89
90         event->keycode = keycode;
91         event->state = state;
92         event->time = time;
93         event->device = device_info->device;
94
95         pepper_list_insert(&evdev->key_event_queue, &event->link);
96 }
97
98 static void
99 _evdev_keyboard_event_process(struct input_event *ev, evdev_device_info_t *device_info)
100 {
101          uint32_t timestamp;
102
103         /* FIXME : need to think about using current time vs. time within event from kernel */
104         timestamp = ev->time.tv_sec * 1000 + ev->time.tv_usec / 1000;
105
106         switch (ev->type)
107         {
108                 case EV_KEY:
109                         _evdev_keyboard_event_queue((uint32_t)ev->code, ev->value, timestamp, device_info);
110                         break;
111
112                 case EV_SYN:
113                         _evdev_keyboard_event_flush(device_info->evdev);
114                         break;
115
116                 default:
117                         break;
118         }
119 }
120
121 static int
122 _evdev_keyboard_event_fd_read(int fd, uint32_t mask, void *data)
123 {
124         uint32_t i;
125         int nread;
126         struct input_event ev[EVENT_MAX];
127         evdev_device_info_t *device_info = (evdev_device_info_t *)data;
128
129         if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR))
130         {
131                 PEPPER_ERROR("With the given fd(%d, mask:0x%x), there is an error or it's been hung-up. (errno:%m)\n", fd, mask);
132                 PEPPER_ERROR("The event source will be disabled and the fd(%d) will be closed.\n", device_info->fd);
133
134                 if (device_info->event_source)
135                 {
136                         wl_event_source_fd_update(device_info->event_source, (uint32_t)0);
137                         wl_event_source_remove(device_info->event_source);
138                 }
139                 return 0;
140         }
141
142         if (!(mask & WL_EVENT_READABLE))
143                 return 0;
144
145         nread = read(fd, &ev, sizeof(ev));
146         PEPPER_CHECK(nread>=0, return 0, "[%s] Failed on reading given fd. (error msg : %m, fd:%d)\n",
147                                         __FUNCTION__, fd);
148
149         for (i = 0 ; i < (nread / sizeof(ev[0])); i++)
150         {
151                 _evdev_keyboard_event_process(&ev[i], device_info);
152         }
153
154         return 0;
155 }
156
157 static int
158 bit_is_set(const unsigned long *array, int bit)
159 {
160     return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
161 }
162
163 static void
164 _evdev_device_configure(evdev_device_info_t *device_info)
165 {
166         int rc;
167         unsigned long bits[NLONGS(EV_CNT)] = {0, };
168         unsigned long key_bits[NLONGS(KEY_CNT)] = {0, };
169         unsigned long found = 0, i;
170         char device_name[256] = {0, };
171
172         rc = ioctl(device_info->fd, EVIOCGBIT(0, sizeof(bits)), bits);
173         PEPPER_CHECK(rc >= 0, return, "Failed to get event bits\n");
174
175         if (bit_is_set(bits, EV_KEY)) {
176                 rc = ioctl(device_info->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits);
177                 if (rc >= 0) {
178                         for (i = 0; i < BTN_MISC / BITS_PER_LONG; ++i) {
179                                 found |= key_bits[i];
180                                 if (found) break;
181                         }
182                         if (!found) {
183                                 for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) {
184                                         if (bit_is_set(key_bits, i)) {
185                                                 found = 1;
186                                                 break;
187                                         }
188                                 }
189                         }
190
191                         if (found) device_info->caps |= WL_SEAT_CAPABILITY_KEYBOARD;
192                 } else
193                         PEPPER_ERROR("Failed to get key bits\n");
194         }
195
196         if (bit_is_set(bits, EV_REL)) {
197                 rc = ioctl(device_info->fd, EVIOCGNAME(sizeof(device_name) - 1), device_name);
198                 if (rc >= 0) {
199                         if (strcasestr(device_name, "mouse"))
200                                 device_info->caps |= WL_SEAT_CAPABILITY_POINTER;
201                 } else
202                         PEPPER_ERROR("Failed to get device name\n");
203         }
204 }
205
206 static int
207 _evdev_keyboard_device_open(pepper_evdev_t *evdev, const char *path)
208 {
209         int fd;
210         char device_path[32];
211         uint32_t event_mask;
212         evdev_device_info_t *device_info = NULL;
213         pepper_input_device_t *device = NULL;
214
215         PEPPER_CHECK(path, return 0, "[%s] Given path is NULL.\n", __FUNCTION__);
216
217         snprintf(device_path, sizeof(device_path), "/dev/input/%s", path);
218
219         fd = open(device_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
220         PEPPER_CHECK(fd >= 0, return 0, "[%s] Failed to open given path of device.\n", __FUNCTION__);
221
222         device_info = (evdev_device_info_t *)calloc(1, sizeof(evdev_device_info_t));
223         PEPPER_CHECK(device_info, goto error, "[%s] Failed to allocate memory for device info...\n", __FUNCTION__);
224
225         device_info->fd = fd;
226         device_info->evdev = evdev;
227         strncpy(device_info->path, path, MAX_PATH_LEN - 1);
228
229         _evdev_device_configure(device_info);
230         if (device_info->caps != WL_SEAT_CAPABILITY_KEYBOARD) goto error;
231
232         device = pepper_input_device_create(evdev->compositor, WL_SEAT_CAPABILITY_KEYBOARD, NULL, NULL);
233         PEPPER_CHECK(device, goto error, "[%s] Failed to create pepper input device.\n", __FUNCTION__);
234
235         device_info->device = device;
236         event_mask = WL_EVENT_READABLE;
237         device_info->event_source = wl_event_loop_add_fd(evdev->event_loop,
238                         fd, event_mask, _evdev_keyboard_event_fd_read, device_info);
239         PEPPER_CHECK(device_info->event_source, goto error, "[%s] Failed to add fd as an event source...\n", __FUNCTION__);
240
241         pepper_list_insert(&evdev->device_list, &device_info->link);
242
243         return 1;
244
245 error:
246         if (device)
247         {
248                 pepper_input_device_destroy(device);
249                 device = NULL;
250         }
251
252         if (device_info)
253         {
254                 if (device_info->event_source)
255                         wl_event_source_remove(device_info->event_source);
256
257                 free(device_info);
258                 device_info = NULL;
259         }
260
261         if (fd >=0)
262                 close(fd);
263
264         return 0;
265 }
266
267 static void
268 _evdev_keyboard_device_close(pepper_evdev_t *evdev, const char *path)
269 {
270         evdev_device_info_t *device_info = NULL;
271
272         evdev_device_info_t *tmp = NULL;
273
274         PEPPER_CHECK(path, return, "[%s] Given path is NULL.\n", __FUNCTION__);
275
276         pepper_list_for_each_safe(device_info, tmp, &evdev->device_list, link) {
277                 if (!strncmp(path, device_info->path, MAX_PATH_LEN)) {
278                         pepper_input_device_destroy(device_info->device);
279                         wl_event_source_remove(device_info->event_source);
280                         close(device_info->fd);
281
282                         pepper_list_remove(&device_info->link);
283                         free(device_info);
284
285                         break;
286                 }
287         }
288 }
289
290
291 PEPPER_API pepper_bool_t
292 pepper_evdev_device_path_add(pepper_evdev_t *evdev, const char *path)
293 {
294         int res = 0;
295
296         PEPPER_CHECK(evdev, return PEPPER_FALSE, "Invalid evdev structure.\n");
297         PEPPER_CHECK(path, return PEPPER_FALSE, "Invalid path.\n");
298
299         if (!strncmp(path, "event", 5)) {
300                 res = _evdev_keyboard_device_open(evdev, path);
301         } else {
302                 PEPPER_ERROR("Invalid path to open: %s\n", path);
303         }
304
305         if (res) return PEPPER_TRUE;
306         return PEPPER_FALSE;
307 }
308
309 PEPPER_API void
310 pepper_evdev_device_path_remove(pepper_evdev_t *evdev, const char *path)
311 {
312         PEPPER_CHECK(evdev, return, "Invalid evdev structure.\n");
313         PEPPER_CHECK(path, return, "Invalid path.\n");
314
315         if (!strncmp(path, "event", 5)) {
316                 _evdev_keyboard_device_close(evdev, path);
317         } else {
318                 PEPPER_ERROR("Invalid path to close: %s\n", path);
319         }
320 }
321
322 PEPPER_API uint32_t
323 pepper_evdev_device_probe(pepper_evdev_t *evdev, uint32_t caps)
324 {
325         uint32_t probed = 0;
326
327         DIR *dir_info = NULL;
328         struct dirent *dir_entry = NULL;
329
330         /* Probe event device nodes under /dev/input */
331         dir_info = opendir("/dev/input/");
332
333         if (dir_info)
334         {
335                 while ((dir_entry = readdir(dir_info)))
336                 {
337                         if (!strncmp(dir_entry->d_name, "event", 5))
338                         {
339                                 if (caps & WL_SEAT_CAPABILITY_KEYBOARD)
340                                         probed += _evdev_keyboard_device_open(evdev, dir_entry->d_name);
341                         }
342                 }
343
344                 closedir(dir_info);
345                 dir_info = NULL;
346         }
347
348         return probed;
349 }
350
351 PEPPER_API pepper_evdev_t *
352 pepper_evdev_create(pepper_compositor_t *compositor)
353 {
354         pepper_evdev_t *evdev = NULL;
355
356         evdev = (pepper_evdev_t *)calloc(1, sizeof(pepper_evdev_t));
357         PEPPER_CHECK(evdev, return NULL, "[%s] Failed to allocate memory for pepper evdev...\n", __FUNCTION__);
358
359         evdev->compositor = compositor;
360         evdev->display = pepper_compositor_get_display(compositor);
361         evdev->event_loop = wl_display_get_event_loop(evdev->display);
362
363         pepper_list_init(&evdev->device_list);
364         pepper_list_init(&evdev->key_event_queue);
365
366         return evdev;
367 }
368
369 PEPPER_API void
370 pepper_evdev_destroy(pepper_evdev_t *evdev)
371 {
372         evdev_device_info_t *device_info = NULL;
373         evdev_device_info_t *tmp = NULL;
374
375         if (!evdev)
376                 return;
377
378         /* clean-up/destroy key event queue */
379         if (!pepper_list_empty(&evdev->key_event_queue))
380         {
381                 _evdev_keyboard_event_flush(evdev);
382                 pepper_list_remove(&evdev->key_event_queue);
383         }
384
385         /* clean-up/destory device list */
386         if (!pepper_list_empty(&evdev->device_list))
387         {
388                 pepper_list_for_each_safe(device_info, tmp, &evdev->device_list, link)
389                 {
390                         if (device_info->device)
391                                 pepper_input_device_destroy(device_info->device);
392                         if (device_info->event_source)
393                                 wl_event_source_remove(device_info->event_source);
394                         if (device_info->fd)
395                                 close(device_info->fd);
396
397                         pepper_list_remove(&device_info->link);
398                         free(device_info);
399                 }
400
401                 pepper_list_remove(&evdev->device_list);
402         }
403
404         free(evdev);
405 }
406