inotify: support a inotify functions 61/201961/5
authorjeon <jhyuni.kang@samsung.com>
Mon, 25 Mar 2019 10:18:04 +0000 (19:18 +0900)
committerjeon <jhyuni.kang@samsung.com>
Mon, 25 Mar 2019 11:05:15 +0000 (20:05 +0900)
  - sample-server: support hotplugged input devices
    using inotify and evdev

Change-Id: I85f7af8291ad7559b70da82c8ad31163ac072a9e

Makefile.am
configure.ac
packaging/pepper.spec
pkgconfig/pepper-inotify.pc.in [new file with mode: 0644]
src/Makefile.am
src/lib/inotify/Makefile.am [new file with mode: 0644]
src/lib/inotify/pepper-inotify-internal.h [new file with mode: 0644]
src/lib/inotify/pepper-inotify.c [new file with mode: 0644]
src/lib/inotify/pepper-inotify.h [new file with mode: 0644]
src/samples/sample-server.c

index 22dcb2c..c007542 100644 (file)
@@ -11,6 +11,7 @@ if ENABLE_TDM
 pkgconfig_DATA += pkgconfig/pepper-tdm.pc
 endif
 pkgconfig_DATA += pkgconfig/pepper-fbdev.pc
+pkgconfig_DATA += pkgconfig/pepper-inotify.pc
 pkgconfig_DATA += pkgconfig/pepper-keyrouter.pc
 pkgconfig_DATA += pkgconfig/pepper-devicemgr.pc
 pkgconfig_DATA += pkgconfig/pepper-evdev.pc
index 86ea917..ff6c3b3 100644 (file)
@@ -54,6 +54,19 @@ if test x$enable_socket_fd = xyes; then
     AC_DEFINE([ENABLE_SOCKET_FD], [1], [Use wl_display_add_socket_fd])
 fi
 
+# pepper-inotify
+PEPPER_INOTIFY_REQUIRES="pepper"
+
+PEPPER_INOTIFY_DIR="-I\$(top_srcdir)/src/lib/inotify"
+PEPPER_INOTIFY_LIB="\$(top_srcdir)/src/lib/inotify/libpepper-inotify.la"
+
+PEPPER_INOTIFY_CFLAGS="$PEPPER_DIR $PEPPER_INOTIFY_DIR $PEPPER_CFLAGS $PEPPER_INOTIFY_CFLAGS "
+PEPPER_INOTIFY_LIBS="$PEPPER_LIB $PEPPER_INOTIFY_LIBS "
+
+AC_SUBST(PEPPER_INOTIFY_CFLAGS)
+AC_SUBST(PEPPER_INOTIFY_LIBS)
+AC_SUBST(PEPPER_INOTIFY_REQUIRES)
+
 # pepper-keyrouter
 PEPPER_KEYROUTER_REQUIRES="tizen-extension-server"
 PKG_CHECK_MODULES(PEPPER_KEYROUTER, [$PEPPER_KEYROUTER_REQUIRES])
@@ -321,11 +334,13 @@ PKG_CHECK_MODULES(SAMPLE_SERVER, [$SAMPLE_SERVER_REQUIRES])
 
 SAMPLE_SERVER_CFLAGS="$PEPPER_DIR $SAMPLE_SERVER_CFLAGS"
 SAMPLE_SERVER_CFLAGS="$PEPPER_EVDEV_DIR $PEPPER_KEYROUTER_DIR $PEPPER_DEVICEMGR_DIR $SAMPLE_SERVER_CFLAGS"
+SAMPLE_SERVER_CFLAGS="$PEPPER_INOTIFY_DIR $SAMPLE_SERVER_CFLAGS"
 SAMPLE_SERVER_CFLAGS="$PEPPER_XKB_DIR $SAMPLE_SERVER_CFLAGS"
 
 SAMPLE_SERVER_LIBS="$PEPPER_LIB $SAMPLE_SERVER_LIBS"
 SAMPLE_SERVER_LIBS="$PEPPER_EVDEV_LIB $PEPPER_EVDEV_LIBS $SAMPLE_SERVER_LIBS"
 SAMPLE_SERVER_LIBS="$PEPPER_KEYROUTER_LIB $PEPPER_KEYROUTER_LIBS $PEPPER_DEVICEMGR_LIB $PEPPER_DEVICEMGR_LIBS $SAMPLE_SERVER_LIBS"
+SAMPLE_SERVER_LIBS="$PEPPER_INOTIFY_LIB $PEPPER_INOTIFY_LIBS $SAMPLE_SERVER_LIBS"
 SAMPLE_SERVER_LIBS="$PEPPER_XKB_LIB $PEPPER_XKB_LIBS $SAMPLE_SERVER_LIBS"
 
 AC_SUBST(SAMPLE_SERVER_CFLAGS)
@@ -359,6 +374,7 @@ AC_CONFIG_FILES([
 Makefile
 src/Makefile
 src/lib/pepper/Makefile
+src/lib/inotify/Makefile
 src/lib/keyrouter/Makefile
 src/lib/devicemgr/Makefile
 src/lib/evdev/Makefile
@@ -375,6 +391,7 @@ pkgconfig/pepper.pc
 pkgconfig/pepper-render.pc
 pkgconfig/pepper-drm.pc
 pkgconfig/pepper-fbdev.pc
+pkgconfig/pepper-inotify.pc
 pkgconfig/pepper-keyrouter.pc
 pkgconfig/pepper-devicemgr.pc
 pkgconfig/pepper-evdev.pc
index dd564f0..ba521e6 100644 (file)
@@ -44,6 +44,21 @@ Requires: %{name} = %{version}-%{release}
 %description devel
 This package includes developer files common to all packages.
 
+###### pepper-inotify
+%package inotify
+Summary: inotify module for pepper package
+
+%description inotify
+This package includes inotify module files.
+
+###### inotify-devel
+%package inotify-devel
+Summary: Inotify development module for pepper package
+Requires: pepper-inotify = %{version}-%{release}
+
+%description inotify-devel
+This package includes inotify development module files.
+
 ###### keyrouter
 %package keyrouter
 Summary: Keyrouter module for pepper package
@@ -227,7 +242,7 @@ Requires: pepper-fbdev
 Requires: pepper-tdm
 Requires: pepper-wayland pepper-x11
 Requires: pepper-libinput
-Requires: pepper-keyrouter pepper-evdev pepper-devicemgr
+Requires: pepper-keyrouter pepper-evdev pepper-devicemgr pepper-inotify
 Requires: pepper-xkb
 
 %description samples
@@ -275,6 +290,9 @@ install -m 0644 data/doctor/units/display_env.sh %{buildroot}%{_sysconfdir}/prof
 %post -n %{name} -p /sbin/ldconfig
 %postun -n %{name} -p /sbin/ldconfig
 
+%post inotify -p /sbin/ldconfig
+%postun inotify -p /sbin/ldconfig
+
 %post keyrouter -p /sbin/ldconfig
 %postun keyrouter -p /sbin/ldconfig
 
@@ -337,6 +355,19 @@ rm -f %{_unitdir_user}/basic.target.wants/display-user.service
 %{_libdir}/pkgconfig/pepper.pc
 %{_libdir}/libpepper.so
 
+%files inotify
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license COPYING
+%{_libdir}/libpepper-inotify.so.*
+
+%files inotify-devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_includedir}/pepper/pepper-inotify.h
+%{_libdir}/pkgconfig/pepper-inotify.pc
+%{_libdir}/libpepper-inotify.so
+
 %files keyrouter
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
diff --git a/pkgconfig/pepper-inotify.pc.in b/pkgconfig/pepper-inotify.pc.in
new file mode 100644 (file)
index 0000000..8c21f6f
--- /dev/null
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+libexecdir=@libexecdir@
+pkglibexecdir=${libexecdir}/@PACKAGE@
+
+Name: Pepper Inotify Library
+Description: Pepper inotify library header and library files
+Version: @PEPPER_INOTIFY_VERSION@
+
+Requires.private: @PEPPER_INOTIFY_REQUIRES@
+Cflags: -I${includedir}/pepper
+Libs: -L${libdir} -lpepper-inotify
index c9f9dbe..800689f 100644 (file)
@@ -8,7 +8,8 @@ SUBDIRS = lib/pepper        \
           lib/render        \
           lib/drm           \
           lib/fbdev         \
-          lib/wayland
+          lib/wayland       \
+          lib/inotify
 
 if ENABLE_TDM
 SUBDIRS += lib/tdm
diff --git a/src/lib/inotify/Makefile.am b/src/lib/inotify/Makefile.am
new file mode 100644 (file)
index 0000000..4a9b768
--- /dev/null
@@ -0,0 +1,11 @@
+lib_LTLIBRARIES = libpepper-inotify.la
+
+AM_CFLAGS = $(GCC_CFLAGS)
+
+libpepper_inotify_includedir=$(includedir)/pepper
+libpepper_inotify_include_HEADERS = pepper-inotify.h
+
+libpepper_inotify_la_CFLAGS = $(AM_CFLAGS) $(PEPPER_INOTIFY_CFLAGS)
+libpepper_inotify_la_LIBADD = $(PEPPER_INOTIFY_LIBS)
+
+libpepper_inotify_la_SOURCES = pepper-inotify.c
diff --git a/src/lib/inotify/pepper-inotify-internal.h b/src/lib/inotify/pepper-inotify-internal.h
new file mode 100644 (file)
index 0000000..56f3f83
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+* Copyright © 2015-2017 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef PEPPER_INOTIFY_INTERNAL_H
+#define PEPPER_INOTIFY_INTERNAL_H
+
+#include <pepper.h>
+#include <pepper-inotify.h>
+
+#define MAX_PATH_LEN 64
+
+struct pepper_inotify_event
+{
+       pepper_inotify_t *inotify;
+
+       char *name;
+       pepper_bool_t is_dir;
+};
+
+struct pepper_inotify_watch
+{
+       pepper_inotify_t *inotify;
+       struct wl_event_source *event_source;
+       int wd;
+       char path[MAX_PATH_LEN];
+
+       pepper_list_t link;
+};
+
+struct pepper_inotify
+{
+       pepper_compositor_t *compositor;
+       struct wl_display *display;
+       struct wl_event_loop *event_loop;
+
+       struct {
+               pepper_inotify_event_cb_t cb;
+               void *data;
+       } callback;
+
+       int fd;
+
+       pepper_list_t watched_list;
+};
+
+#endif /* PEPPER_INOTIFY_INTERNAL_H */
diff --git a/src/lib/inotify/pepper-inotify.c b/src/lib/inotify/pepper-inotify.c
new file mode 100644 (file)
index 0000000..6960dd0
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+* Copyright © 2015-2017 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <linux/input.h>
+#include <sys/inotify.h>
+
+#include <pepper-inotify-internal.h>
+
+static void
+_inotify_event_post(pepper_inotify_t *inotify, pepper_inotify_event_type_t type, const char *name, pepper_bool_t is_dir)
+{
+       pepper_inotify_event_t ev;
+
+       PEPPER_CHECK(inotify->callback.cb, return, "Current inotify has no callback");
+
+       ev.inotify = inotify;
+
+       ev.name = (char *)name;
+       ev.is_dir = is_dir;
+
+       inotify->callback.cb(type, &ev, inotify->callback.data);
+}
+
+static void
+_inotify_event_process(struct inotify_event *ev, pepper_inotify_watch_t *watch)
+{
+       if (!ev->len) return;
+
+       if (ev->mask & IN_CREATE) {
+               _inotify_event_post(watch->inotify, PEPPER_INOTIFY_EVENT_TYPE_CREATE,
+                                       ev->name, (ev->mask & IN_ISDIR) ? PEPPER_TRUE : PEPPER_FALSE);
+       }
+       else if (ev->mask & IN_DELETE) {
+               _inotify_event_post(watch->inotify, PEPPER_INOTIFY_EVENT_TYPE_REMOVE,
+                                       ev->name, (ev->mask & IN_ISDIR) ? PEPPER_TRUE : PEPPER_FALSE);
+       }
+       else if (ev->mask & IN_MODIFY) {
+               _inotify_event_post(watch->inotify, PEPPER_INOTIFY_EVENT_TYPE_MODIFY,
+                                       ev->name, (ev->mask & IN_ISDIR) ? PEPPER_TRUE : PEPPER_FALSE);
+       }
+}
+
+static int
+_inotify_fd_read(int fd, uint32_t mask, void *data)
+{
+       uint32_t i;
+       int nread;
+       char buf[128];
+       struct inotify_event ev[32];
+       pepper_inotify_watch_t *watch_data = data;
+
+       PEPPER_CHECK(!(mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)),
+                       return 0,
+                       "[%s] With the given fd, there is an error or it's been hung-up.\n",
+                       __FUNCTION__);
+
+       if (!(mask & WL_EVENT_READABLE))
+               return 0;
+
+       nread = read(fd, &ev, sizeof(ev));
+       PEPPER_CHECK(nread >= 0, return 0,
+                       "Failed on reading given fd. (error : %s, fd:%d)\n",
+                       strerror_r(errno, buf, 128), fd);
+
+       for (i = 0 ; i < (nread / sizeof(ev[0])); i++) {
+               if (ev[i].wd == watch_data->wd)
+                       _inotify_event_process(&ev[i], watch_data);
+       }
+
+       return 0;
+}
+
+PEPPER_API char *
+pepper_inotify_event_name_get(pepper_inotify_event_t *ev)
+{
+       PEPPER_CHECK(ev, return PEPPER_INOTIFY_EVENT_TYPE_NONE,
+                       "Invalid inotify event\n");
+
+       return ev->name;
+}
+
+PEPPER_API pepper_bool_t
+pepper_inotify_event_is_directory(pepper_inotify_event_t *ev)
+{
+       PEPPER_CHECK(ev, return PEPPER_INOTIFY_EVENT_TYPE_NONE,
+                       "Invalid inotify event\n");
+
+       return ev->is_dir;
+}
+
+PEPPER_API pepper_bool_t
+pepper_inotify_add(pepper_inotify_t *inotify, const char *path)
+{
+       pepper_inotify_watch_t *watch_data;
+       char buf[128];
+
+       PEPPER_CHECK(inotify, return PEPPER_FALSE, "Invalid pepper_inotify_t object\n");
+       PEPPER_CHECK(path, return PEPPER_FALSE, "Invalid path\n");
+
+       watch_data = (pepper_inotify_watch_t *)calloc(1, sizeof(pepper_inotify_watch_t));
+       PEPPER_CHECK(watch_data, return PEPPER_FALSE,
+               "Failed to allocate pepper_inotify_watch_t\n");
+
+       watch_data->inotify = inotify;
+
+       watch_data->wd = inotify_add_watch(inotify->fd, path,
+                       IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_MOVE_SELF);
+       PEPPER_CHECK(watch_data->wd >= 0, goto failed,
+                       "Failed to add watch for %s\n", path, strerror_r(errno, buf, 128));
+
+       strncpy(watch_data->path, path, MAX_PATH_LEN - 1);
+
+       watch_data->event_source = wl_event_loop_add_fd(inotify->event_loop, inotify->fd,
+                       WL_EVENT_READABLE, _inotify_fd_read, watch_data);
+       PEPPER_CHECK(watch_data->event_source, goto failed,
+                       "Failed to add fd as an event source.\n");
+
+       pepper_list_insert(&inotify->watched_list, &watch_data->link);
+
+       return PEPPER_TRUE;
+
+failed:
+       if (watch_data->event_source)
+               wl_event_source_remove(watch_data->event_source);
+       if (watch_data->wd)
+               inotify_rm_watch(inotify->fd, watch_data->wd);
+
+       return PEPPER_FALSE;
+}
+
+PEPPER_API void
+pepper_inotify_del(pepper_inotify_t *inotify, const char *path)
+{
+       pepper_inotify_watch_t *watch_data, *watch_data_tmp;
+
+       PEPPER_CHECK(inotify, return, "Invalid pepper_inotify_t object\n");
+       PEPPER_CHECK(path, return, "Invalid path\n");
+
+       if (!pepper_list_empty(&inotify->watched_list))
+       {
+               pepper_list_for_each_safe(watch_data, watch_data_tmp, &inotify->watched_list, link)
+               {
+                       if (!strncmp(watch_data->path, path, MAX_PATH_LEN - 1))
+                       {
+                               if (watch_data->wd)
+                                       inotify_rm_watch(inotify->fd, watch_data->wd);
+                               if (watch_data->event_source)
+                                       wl_event_source_remove(watch_data->event_source);
+                               pepper_list_remove(&watch_data->link);
+                               free(watch_data);
+                               break;
+                       }
+               }
+       }
+}
+
+PEPPER_API pepper_inotify_t *
+pepper_inotify_create(pepper_compositor_t *compositor, pepper_inotify_event_cb_t cb, void *data)
+{
+       pepper_inotify_t *inotify;
+
+       PEPPER_CHECK(compositor, return NULL, "Invalid compositor object\n");
+
+       inotify = (pepper_inotify_t *)calloc(1, sizeof(pepper_inotify_t));
+       PEPPER_CHECK(inotify, return NULL, "Failed to allocate pepper_inotify_t\n");
+
+       inotify->display = pepper_compositor_get_display(compositor);
+       PEPPER_CHECK(inotify->display, goto failed, "Invaild wl_display\n");
+
+       inotify->event_loop = wl_display_get_event_loop(inotify->display);
+       PEPPER_CHECK(inotify->event_loop, goto failed, "Invaild wl_event_loop\n");
+
+       inotify->fd = inotify_init();
+       PEPPER_CHECK(inotify->fd >= 0, goto failed, "Failed to init inotify. fd: %d\n", inotify->fd);
+
+       inotify->callback.cb = cb;
+       inotify->callback.data = data;
+
+       pepper_list_init(&inotify->watched_list);
+
+       return inotify;
+
+failed:
+       if (inotify) {
+               if (inotify->fd)
+                       close(inotify->fd);
+               free(inotify);
+       }
+       return NULL;
+}
+
+PEPPER_API void
+pepper_inotify_destroy(pepper_inotify_t *inotify)
+{
+       pepper_inotify_watch_t *watch_data, *watch_data_tmp;
+
+       PEPPER_CHECK(inotify, return, "Invalid pepper_inotify_t object\n");
+
+       if (!pepper_list_empty(&inotify->watched_list))
+       {
+               pepper_list_for_each_safe(watch_data, watch_data_tmp, &inotify->watched_list, link)
+               {
+                       if (watch_data->wd)
+                               inotify_rm_watch(inotify->fd, watch_data->wd);
+                       if (watch_data->event_source)
+                               wl_event_source_remove(watch_data->event_source);
+
+                       pepper_list_remove(&watch_data->link);
+                       free(watch_data);
+               }
+
+               pepper_list_remove(&inotify->watched_list);
+       }
+
+       if (inotify->fd)
+               close(inotify->fd);
+
+       free(inotify);
+       inotify = NULL;
+}
+
diff --git a/src/lib/inotify/pepper-inotify.h b/src/lib/inotify/pepper-inotify.h
new file mode 100644 (file)
index 0000000..36364fb
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+* Copyright © 2015-2017 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef PEPPER_INOTIFY_H
+#define PEPPER_INOTIFY_H
+
+#include <pepper.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct pepper_inotify pepper_inotify_t;
+typedef struct pepper_inotify_watch pepper_inotify_watch_t;
+typedef struct pepper_inotify_event pepper_inotify_event_t;
+
+typedef void (*pepper_inotify_event_cb_t)(uint32_t type, pepper_inotify_event_t *ev, void *data);
+
+typedef enum pepper_inotify_event_type
+{
+       PEPPER_INOTIFY_EVENT_TYPE_NONE,
+       PEPPER_INOTIFY_EVENT_TYPE_CREATE,
+       PEPPER_INOTIFY_EVENT_TYPE_REMOVE,
+       PEPPER_INOTIFY_EVENT_TYPE_MODIFY
+} pepper_inotify_event_type_t;
+
+PEPPER_API pepper_bool_t
+pepper_inotify_add(pepper_inotify_t *inotify, const char *path);
+
+PEPPER_API void
+pepper_inotify_del(pepper_inotify_t *inotify, const char *path);
+
+PEPPER_API pepper_inotify_t *
+pepper_inotify_create(pepper_compositor_t *compositor, pepper_inotify_event_cb_t cb, void *data);
+
+PEPPER_API void
+pepper_inotify_destroy(pepper_inotify_t *inotify);
+
+PEPPER_API pepper_inotify_event_type_t
+pepper_inotify_event_type_get(pepper_inotify_event_t *ev);
+
+PEPPER_API char *
+pepper_inotify_event_name_get(pepper_inotify_event_t *ev);
+
+PEPPER_API pepper_bool_t
+pepper_inotify_event_is_directory(pepper_inotify_event_t *ev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEPPER_INOTIFY_H */
index 86e569a..23c3632 100644 (file)
@@ -33,6 +33,7 @@
 #include <pepper-keyrouter.h>
 #include <pepper-input-backend.h>
 #include <pepper-devicemgr.h>
+#include <pepper-inotify.h>
 
 /* basic pepper objects */
 pepper_xkb_t *xkb = NULL;
@@ -41,6 +42,7 @@ pepper_evdev_t *evdev = NULL;
 pepper_keyrouter_t *keyrouter = NULL;
 pepper_input_device_t *input_device = NULL;
 pepper_devicemgr_t *devicemgr = NULL;
+pepper_inotify_t *inotify = NULL;
 
 /* event listeners */
 pepper_event_listener_t *listener_seat_add = NULL;
@@ -162,6 +164,28 @@ _pepper_devicemgr_keymap_set(pepper_devicemgr_t *pepper_devicemgr, pepper_list_t
        pepper_devicemgr_keymap_set(pepper_devicemgr, list);
 }
 
+static void
+_handle_pepper_inotify_event(uint32_t type, pepper_inotify_event_t *ev, void *data)
+{
+       pepper_evdev_t *evdev = data;
+
+       switch (type)
+       {
+               case PEPPER_INOTIFY_EVENT_TYPE_CREATE:
+                       pepper_evdev_device_path_add(evdev, pepper_inotify_event_name_get(ev));
+                       break;
+               case PEPPER_INOTIFY_EVENT_TYPE_REMOVE:
+                       pepper_evdev_device_path_remove(evdev, pepper_inotify_event_name_get(ev));
+                       break;
+               case PEPPER_INOTIFY_EVENT_TYPE_MODIFY:
+                       pepper_evdev_device_path_remove(evdev, pepper_inotify_event_name_get(ev));
+                       pepper_evdev_device_path_add(evdev, pepper_inotify_event_name_get(ev));
+                       break;
+               default:
+                       break;
+       }
+}
+
 int
 main(int argc, char **argv)
 {
@@ -249,6 +273,11 @@ main(int argc, char **argv)
        if (!probed)
                PEPPER_TRACE("No evdev devices have been probed.\n");
 
+       inotify = pepper_inotify_create(compositor, _handle_pepper_inotify_event, evdev);
+       PEPPER_CHECK(inotify, ;, "Failed to create inotify\n");
+
+       pepper_inotify_add(inotify, "/dev/input/");
+
        /* Enter main loop. */
        wl_display_run(display);