devicemgr: support a devicemgr's key event generation functions 44/174244/4
authorJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 29 Mar 2018 06:03:59 +0000 (15:03 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 29 Mar 2018 10:51:19 +0000 (19:51 +0900)
Change-Id: Ia42f5cd8c9a8ca493ff0f34dcabe9925b64e98db

16 files changed:
Makefile.am
configure.ac
packaging/pepper.spec
pkgconfig/pepper-devicemgr.pc.in [new file with mode: 0644]
src/Makefile.am
src/bin/doctor/doctor.c
src/lib/devicemgr/Makefile.am [new file with mode: 0644]
src/lib/devicemgr/devicemgr-internal.h [new file with mode: 0644]
src/lib/devicemgr/devicemgr.c [new file with mode: 0644]
src/lib/devicemgr/devicemgr.h [new file with mode: 0644]
src/lib/devicemgr/pepper-devicemgr.c [new file with mode: 0644]
src/lib/devicemgr/pepper-devicemgr.h [new file with mode: 0644]
src/lib/xkb/pepper-xkb.h
src/lib/xkb/xkb.c
src/samples/sample-client.c
src/samples/sample-server.c

index 4eb2d30..22dcb2c 100644 (file)
@@ -12,6 +12,7 @@ pkgconfig_DATA += pkgconfig/pepper-tdm.pc
 endif
 pkgconfig_DATA += pkgconfig/pepper-fbdev.pc
 pkgconfig_DATA += pkgconfig/pepper-keyrouter.pc
+pkgconfig_DATA += pkgconfig/pepper-devicemgr.pc
 pkgconfig_DATA += pkgconfig/pepper-evdev.pc
 pkgconfig_DATA += pkgconfig/pepper-libinput.pc
 pkgconfig_DATA += pkgconfig/pepper-xkb.pc
index 89d51e0..86ea917 100644 (file)
@@ -97,6 +97,20 @@ AC_SUBST(PEPPER_XKB_CFLAGS)
 AC_SUBST(PEPPER_XKB_LIBS)
 AC_SUBST(PEPPER_XKB_REQUIRES)
 
+# pepper-devicemgr
+PEPPER_DEVICEMGR_REQUIRES="tizen-extension-server"
+PKG_CHECK_MODULES(PEPPER_DEVICEMGR, [$PEPPER_DEVICEMGR_REQUIRES])
+
+PEPPER_DEVICEMGR_DIR="-I\$(top_srcdir)/src/lib/devicemgr"
+PEPPER_DEVICEMGR_LIB="\$(top_srcdir)/src/lib/devicemgr/libpepper-devicemgr.la"
+
+PEPPER_DEVICEMGR_CFLAGS="$PEPPER_DIR $PEPPER_DEVICEMGR_CFLAGS $PEPPER_CFLAGS $PEPPER_DEVICEMGR_DIR $PEPPER_XKB_CFLAGS "
+PEPPER_DEVICEMGR_LIBS="$PEPPER_LIB $PEPPER_DEVICEMGR_LIBS $PEPPER_XKB_LIBS "
+
+AC_SUBST(PEPPER_DEVICEMGR_CFLAGS)
+AC_SUBST(PEPPER_DEVICEMGR_LIBS)
+AC_SUBST(PEPPER_DEVICEMGR_REQUIRES)
+
 # pepper-desktop-shell
 PEPPER_DESKTOP_SHELL_REQUIRES="pepper"
 
@@ -276,10 +290,10 @@ AC_SUBST(SAMPLES_LIBS)
 # doctor (headless server) and headless client samples
 DOCTOR_SERVER_REQUIRES="wayland-server libtbm"
 PKG_CHECK_MODULES(DOCTOR_SERVER, $[DOCTOR_SERVER_REQUIRES])
-DOCTOR_SERVER_CFLAGS="$PEPPER_DIR $PEPPER_EVDEV_DIR $PEPPER_KEYROUTER_DIR $DOCTOR_SERVER_CFLAGS"
+DOCTOR_SERVER_CFLAGS="$PEPPER_DIR $PEPPER_EVDEV_DIR $PEPPER_KEYROUTER_DIR $PEPPER_DEVICEMGR_DIR $DOCTOR_SERVER_CFLAGS"
 DOCTOR_SERVER_LIBS="$PEPPER_LIB $PEPPER_LIBS $DOCTOR_SERVER_LIBS"
 DOCTOR_SERVER_LIBS="$PEPPER_EVDEV_LIB $PEPPER_EVDEV_LIBS $DOCTOR_SERVER_LIBS"
-DOCTOR_SERVER_LIBS="$PEPPER_KEYROUTER_LIB $PEPPER_KEYROUTER_LIBS $DOCTOR_SERVER_LIBS"
+DOCTOR_SERVER_LIBS="$PEPPER_KEYROUTER_LIB $PEPPER_KEYROUTER_LIBS $PEPPER_DEVICEMGR_LIB $PEPPER_DEVICEMGR_LIBS $DOCTOR_SERVER_LIBS"
 
 AC_SUBST(DOCTOR_SERVER_CFLAGS)
 AC_SUBST(DOCTOR_SERVER_LIBS)
@@ -306,12 +320,12 @@ SAMPLE_SERVER_REQUIRES="wayland-server xkbcommon"
 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 $SAMPLE_SERVER_CFLAGS"
+SAMPLE_SERVER_CFLAGS="$PEPPER_EVDEV_DIR $PEPPER_KEYROUTER_DIR $PEPPER_DEVICEMGR_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 $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_XKB_LIB $PEPPER_XKB_LIBS $SAMPLE_SERVER_LIBS"
 
 AC_SUBST(SAMPLE_SERVER_CFLAGS)
@@ -346,6 +360,7 @@ Makefile
 src/Makefile
 src/lib/pepper/Makefile
 src/lib/keyrouter/Makefile
+src/lib/devicemgr/Makefile
 src/lib/evdev/Makefile
 src/lib/xkb/Makefile
 src/lib/libinput/Makefile
@@ -361,6 +376,7 @@ pkgconfig/pepper-render.pc
 pkgconfig/pepper-drm.pc
 pkgconfig/pepper-fbdev.pc
 pkgconfig/pepper-keyrouter.pc
+pkgconfig/pepper-devicemgr.pc
 pkgconfig/pepper-evdev.pc
 pkgconfig/pepper-xkb.pc
 pkgconfig/pepper-libinput.pc
index 448edf1..01796ec 100644 (file)
@@ -59,6 +59,21 @@ Requires: pepper-keyrouter = %{version}-%{release}
 %description keyrouter-devel
 This package includes keyrouter development module files.
 
+###### devicemgr
+%package devicemgr
+Summary: Keyrouter module for pepper package
+
+%description devicemgr
+This package includes devicemgr module files.
+
+###### devicemgr-devel
+%package devicemgr-devel
+Summary: Devicemgr development module for pepper package
+Requires: pepper-devicemgr = %{version}-%{release}
+
+%description devicemgr-devel
+This package includes devicemgr development module files.
+
 ###### evdev
 %package evdev
 Summary: evdev module for pepper package
@@ -198,7 +213,7 @@ This package includes wayland backend development module files.
 ###### doctor server
 %package doctor
 Summary: Doctor server for pepper package
-Requires: pepper pepper-keyrouter pepper-evdev
+Requires: pepper pepper-keyrouter pepper-devicemgr pepper-evdev
 Requires: libtbm
 
 %description doctor
@@ -212,7 +227,7 @@ Requires: pepper-fbdev
 Requires: pepper-tdm
 Requires: pepper-wayland pepper-x11
 Requires: pepper-libinput
-Requires: pepper-keyrouter pepper-evdev
+Requires: pepper-keyrouter pepper-evdev pepper-devicemgr
 Requires: pepper-xkb
 
 %description samples
@@ -263,6 +278,9 @@ install -m 0644 data/doctor/units/display_env.sh %{buildroot}%{_sysconfdir}/prof
 %post keyrouter -p /sbin/ldconfig
 %postun keyrouter -p /sbin/ldconfig
 
+%post devicemgr -p /sbin/ldconfig
+%postun devicemgr -p /sbin/ldconfig
+
 %post evdev -p /sbin/ldconfig
 %postun evdev -p /sbin/ldconfig
 
@@ -333,6 +351,20 @@ rm -f %{_unitdir_user}/basic.target.wants/display-user.service
 %{_libdir}/pkgconfig/pepper-keyrouter.pc
 %{_libdir}/libpepper-keyrouter.so
 
+%files devicemgr
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license COPYING
+%{_libdir}/libpepper-devicemgr.so.*
+
+%files devicemgr-devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_includedir}/pepper/devicemgr.h
+%{_includedir}/pepper/pepper-devicemgr.h
+%{_libdir}/pkgconfig/pepper-devicemgr.pc
+%{_libdir}/libpepper-devicemgr.so
+
 %files evdev
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
diff --git a/pkgconfig/pepper-devicemgr.pc.in b/pkgconfig/pepper-devicemgr.pc.in
new file mode 100644 (file)
index 0000000..6dabe41
--- /dev/null
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+libexecdir=@libexecdir@
+pkglibexecdir=${libexecdir}/@PACKAGE@
+
+Name: Pepper Devicemgr Library
+Description: Pepper devicemgr library header and library files
+Version: @PEPPER_DEVICEMGR_VERSION@
+
+Requires.private: @PEPPER_DEVICEMGR_REQUIRES@
+Cflags: -I${includedir}/pepper
+Libs: -L${libdir} -lpepper-devicemgr
index 89049d5..c9f9dbe 100644 (file)
@@ -1,5 +1,6 @@
 SUBDIRS = lib/pepper        \
           lib/keyrouter      \
+          lib/devicemgr     \
           lib/evdev         \
           lib/libinput      \
           lib/xkb           \
index 158fb6c..d542ba8 100644 (file)
@@ -4,6 +4,7 @@
 #include <pepper-keyrouter.h>
 #include <stdlib.h>
 #include <tbm_bufmgr.h>
+#include <pepper-devicemgr.h>
 
 /* basic pepper objects */
 pepper_seat_t *seat = NULL;
@@ -11,6 +12,7 @@ pepper_evdev_t *evdev = NULL;
 pepper_keyrouter_t *keyrouter = NULL;
 pepper_compositor_t *compositor = NULL;
 pepper_input_device_t *input_device = NULL;
+pepper_devicemgr_t *devicemgr = NULL;
 
 /* tbm buffer manager */
 tbm_bufmgr bufmgr;
@@ -205,6 +207,32 @@ _handle_input_device_remove(pepper_event_listener_t *listener, pepper_object_t *
                pepper_seat_remove_input_device(seat, device);
 }
 
+static void
+_pepper_devicemgr_keymap_add(pepper_list_t *list, const char *name, int keycode)
+{
+       pepper_devicemgr_keymap_data_t *data;
+
+       data = (pepper_devicemgr_keymap_data_t *)calloc(1, sizeof(pepper_devicemgr_keymap_data_t));
+       PEPPER_CHECK(data, return, "Failed to alloc memory\n");
+
+       strncpy(data->name, name, UINPUT_MAX_NAME_SIZE);
+       data->keycode = keycode;
+
+       pepper_list_init(&data->link);
+       pepper_list_insert(list, &data->link);
+}
+
+static void
+_pepper_devicemgr_keymap_set(pepper_devicemgr_t *pepper_devicemgr, pepper_list_t *list)
+{
+       pepper_list_init(list);
+       _pepper_devicemgr_keymap_add(list, "XF86Back", 166);
+       _pepper_devicemgr_keymap_add(list, "XF86Home", 147);
+       _pepper_devicemgr_keymap_add(list, "XF86Menu", 177);
+
+       pepper_devicemgr_keymap_set(pepper_devicemgr, list);
+}
+
 int main(int argc, char *argv[])
 {
        uint32_t caps = 0;
@@ -215,6 +243,8 @@ int main(int argc, char *argv[])
        const char* socket_name = NULL;
        const char* seat_name = NULL;
 
+       pepper_list_t keymap_list;
+
        socket_name = getenv("WAYLAND_DISPLAY");
 
        if (!socket_name)
@@ -262,6 +292,11 @@ int main(int argc, char *argv[])
        seat = pepper_compositor_add_seat(compositor, seat_name);
        PEPPER_CHECK(seat, goto shutdown_on_failure, "Failed to add seat !\n");
 
+       /* create pepper devicemgr */
+       devicemgr = pepper_devicemgr_create(compositor, seat);
+       PEPPER_CHECK(devicemgr, goto shutdown_on_failure, "Failed to create devicemgr !\n");
+       _pepper_devicemgr_keymap_set(devicemgr, &keymap_list);
+
        /* get capabilities for a default pepper input device*/
        if (getenv("WAYLAND_INPUT_KEYBOARD"))
                caps |= WL_SEAT_CAPABILITY_KEYBOARD;
@@ -327,6 +362,13 @@ shutdown:
                input_device = NULL;
        }
 
+       /* destroy devicemgr */
+       if (devicemgr)
+       {
+               pepper_devicemgr_destroy(devicemgr);
+               devicemgr = NULL;
+       }
+
        /* destroy seat */
        if (seat)
        {
diff --git a/src/lib/devicemgr/Makefile.am b/src/lib/devicemgr/Makefile.am
new file mode 100644 (file)
index 0000000..153941c
--- /dev/null
@@ -0,0 +1,13 @@
+lib_LTLIBRARIES = libpepper-devicemgr.la
+
+AM_CFLAGS = $(GCC_CFLAGS)
+
+libpepper_devicemgr_includedir=$(includedir)/pepper
+libpepper_devicemgr_include_HEADERS = devicemgr.h pepper-devicemgr.h
+
+libpepper_devicemgr_la_CFLAGS = $(AM_CFLAGS) $(PEPPER_DEVICEMGR_CFLAGS)
+libpepper_devicemgr_la_LIBADD = $(PEPPER_DEVICEMGR_LIBS)
+
+libpepper_devicemgr_la_SOURCES = devicemgr-internal.h \
+                                 devicemgr.c \
+                                 pepper-devicemgr.c
diff --git a/src/lib/devicemgr/devicemgr-internal.h b/src/lib/devicemgr/devicemgr-internal.h
new file mode 100644 (file)
index 0000000..a8dc8d4
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+* 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 DEVICEMGR_INTERNAL_H
+#define DEVICEMGR_INTERNAL_H
+
+#include <unistd.h>
+#include <config.h>
+#include <fcntl.h>
+#include <linux/uinput.h>
+#include <linux/input.h>
+
+#include <pepper-input-backend.h>
+#include "devicemgr.h"
+
+struct devicemgr_device {
+       char name[UINPUT_MAX_NAME_SIZE + 1];
+       pepper_input_device_t *input_device;
+       pepper_keyboard_t *kbd;
+};
+
+struct devicemgr {
+       pepper_compositor_t *compositor;
+       pepper_seat_t *seat;
+       devicemgr_device_t *keyboard;
+};
+
+#endif /* DEVICEMGR_INTERNAL_H */
diff --git a/src/lib/devicemgr/devicemgr.c b/src/lib/devicemgr/devicemgr.c
new file mode 100644 (file)
index 0000000..6378f2d
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+* 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.
+*/
+
+#include "devicemgr-internal.h"
+#include <tizen-extension-server-protocol.h>
+
+static void
+_devicemgr_generate_key(pepper_keyboard_t *keyboard, int keycode, int pressed)
+{
+       pepper_input_event_t event;
+       struct timeval time;
+       unsigned int timestamp;
+
+       gettimeofday(&time, NULL);
+       timestamp = time.tv_sec * 1000 + time.tv_usec / 1000;
+
+       event.time = timestamp;
+       event.key = keycode - 8;
+       event.state = pressed ? PEPPER_KEY_STATE_PRESSED : PEPPER_KEY_STATE_RELEASED;
+
+       pepper_object_emit_event((pepper_object_t *)keyboard,
+                                                               PEPPER_EVENT_KEYBOARD_KEY, &event);
+}
+
+PEPPER_API int
+devicemgr_input_generator_generate_key(devicemgr_t *devicemgr, int keycode, pepper_bool_t pressed)
+{
+       PEPPER_CHECK(devicemgr,
+               return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES,
+               "Invalid devicemgr structure.\n");
+       PEPPER_CHECK(devicemgr->keyboard && devicemgr->keyboard->kbd,
+               return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES,
+               "Keyboard device is not initialized\n");
+
+       _devicemgr_generate_key(devicemgr->keyboard->kbd, keycode, pressed);
+
+       return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+}
+
+PEPPER_API void
+devicemgr_input_generator_keyboard_set(devicemgr_t *devicemgr, pepper_keyboard_t *keyboard)
+{
+       PEPPER_CHECK(devicemgr, return, "Invalid devicemgr structure.\n");
+       PEPPER_CHECK(devicemgr->keyboard, return, "input generator is not initialized yet.\n");
+       if (devicemgr->keyboard->kbd) return;
+       devicemgr->keyboard->kbd = keyboard;
+}
+
+PEPPER_API void
+devicemgr_input_generator_keyboard_unset(devicemgr_t *devicemgr, pepper_keyboard_t *keyboard)
+{
+       PEPPER_CHECK(devicemgr, return, "Invalid devicemgr structure.\n");
+       devicemgr->keyboard->kbd = NULL;
+}
+
+
+static pepper_bool_t
+_devicemgr_input_generator_keyboard_create(devicemgr_t *devicemgr, const char *name)
+{
+       if (devicemgr->keyboard->kbd) return PEPPER_TRUE;
+
+       devicemgr->keyboard->input_device = pepper_input_device_create(devicemgr->compositor, WL_SEAT_CAPABILITY_KEYBOARD, NULL, NULL);
+       PEPPER_CHECK(devicemgr->keyboard->input_device, return PEPPER_FALSE, "Failed to create input device !\n");
+
+       return PEPPER_TRUE;
+}
+
+PEPPER_API int
+devicemgr_input_generator_init(devicemgr_t *devicemgr, unsigned int clas, const char *name)
+{
+       int ret;
+
+       PEPPER_CHECK(devicemgr, return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES, "Invalid devicemgr structure.\n");
+
+       if (strlen(devicemgr->keyboard->name) > 0) return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+
+       ret = _devicemgr_input_generator_keyboard_create(devicemgr, name);
+       PEPPER_CHECK(ret == PEPPER_TRUE, return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES, "Failed to create keyboard device: %s\n", name);
+       strncpy(devicemgr->keyboard->name, name, UINPUT_MAX_NAME_SIZE);
+
+       return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+}
+
+static void
+_devicemgr_input_generator_keyboard_close(devicemgr_t *devicemgr)
+{
+       if (!devicemgr->keyboard->input_device) return;
+       pepper_input_device_destroy(devicemgr->keyboard->input_device);
+}
+
+PEPPER_API int
+devicemgr_input_generator_deinit(devicemgr_t *devicemgr)
+{
+       PEPPER_CHECK(devicemgr, return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES, "Invalid devicemgr structure.\n");
+
+       if (!devicemgr->keyboard) return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+
+       _devicemgr_input_generator_keyboard_close(devicemgr);
+       memset(devicemgr->keyboard->name, 0, UINPUT_MAX_NAME_SIZE);
+
+       return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+}
+
+PEPPER_API devicemgr_t *
+devicemgr_create(pepper_compositor_t *compositor, pepper_seat_t *seat)
+{
+       devicemgr_t *devicemgr = NULL;
+
+       PEPPER_CHECK(seat, return NULL, "Invalid seat\n");
+
+       devicemgr = (devicemgr_t *)calloc(1, sizeof(devicemgr_t));
+       PEPPER_CHECK(devicemgr, return NULL, "devicemgr allocation failed.\n");
+
+       devicemgr->keyboard = (devicemgr_device_t *)calloc(1, sizeof(devicemgr_device_t));
+       PEPPER_CHECK(devicemgr->keyboard, goto failed, "Failed to allocate device");
+
+       devicemgr->compositor = compositor;
+       devicemgr->seat = seat;
+
+       return devicemgr;
+
+failed:
+       if (devicemgr) free(devicemgr);
+       return NULL;
+}
+
+PEPPER_API void
+devicemgr_destroy(devicemgr_t *devicemgr)
+{
+       PEPPER_CHECK(devicemgr, return, "Invalid devicemgr resource.\n");
+
+       if (devicemgr->keyboard) {
+               _devicemgr_input_generator_keyboard_close(devicemgr);
+               free(devicemgr->keyboard);
+               devicemgr->keyboard = NULL;
+       }
+
+       free(devicemgr);
+       devicemgr = NULL;
+}
diff --git a/src/lib/devicemgr/devicemgr.h b/src/lib/devicemgr/devicemgr.h
new file mode 100644 (file)
index 0000000..56f54cb
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+* 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 DEVICEMGR_H
+#define DEVICEMGR_H
+
+#include <pepper.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct devicemgr devicemgr_t;
+typedef struct devicemgr_device devicemgr_device_t;
+
+PEPPER_API devicemgr_t *devicemgr_create(pepper_compositor_t *compositor, pepper_seat_t *seat);
+PEPPER_API void devicemgr_destroy(devicemgr_t *devicemgr);
+PEPPER_API int devicemgr_input_generator_init(devicemgr_t *devicemgr, unsigned int clas, const char *name);
+PEPPER_API int devicemgr_input_generator_deinit(devicemgr_t *devicemgr);
+PEPPER_API int devicemgr_input_generator_generate_key(devicemgr_t *devicemgr, int keycode, pepper_bool_t pressed);
+
+PEPPER_API void devicemgr_input_generator_keyboard_set(devicemgr_t *devicemgr, pepper_keyboard_t *keyboard);
+PEPPER_API void devicemgr_input_generator_keyboard_unset(devicemgr_t *devicemgr, pepper_keyboard_t *keyboard);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DEVICEMGR_H */
+
diff --git a/src/lib/devicemgr/pepper-devicemgr.c b/src/lib/devicemgr/pepper-devicemgr.c
new file mode 100644 (file)
index 0000000..799fbaa
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+* 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.
+*/
+
+#include "pepper-devicemgr.h"
+#include "pepper-internal.h"
+#include <tizen-extension-server-protocol.h>
+#ifdef _F_DEVICEMGR_XKB
+#include <pepper-xkb.h>
+#endif
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+typedef struct pepper_devicemgr_resource pepper_devicemgr_resource_t;
+
+struct pepper_devicemgr {
+       struct wl_global *global;
+       struct wl_display *display;
+       pepper_compositor_t *compositor;
+       pepper_seat_t *seat;
+#ifdef _F_DEVICEMGR_XKB
+       pepper_xkb_info_t *xkb_info;
+#else
+       pepper_list_t *keymap_list;
+#endif
+
+       pepper_event_listener_t *listener_seat_keyboard_add;
+       pepper_event_listener_t *listener_keyboard_keymap_update;
+
+       pepper_list_t resources;
+
+       devicemgr_t *devicemgr;
+       int ref;
+};
+
+struct pepper_devicemgr_resource {
+       struct wl_resource *resource;
+       pepper_bool_t init;
+       pepper_list_t link;
+};
+
+#ifdef _F_DEVICEMGR_XKB
+static void
+_pepper_devicemgr_handle_keyboard_keymap_update(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
+{
+       pepper_keyboard_t *keyboard = (pepper_keyboard_t *)info;
+       pepper_devicemgr_t *pepper_devicemgr = (pepper_devicemgr_t *)data;
+
+       pepper_devicemgr->xkb_info = keyboard->xkb_info;
+}
+#endif
+
+static void
+_pepper_devicemgr_handle_seat_keyboard_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data)
+{
+       pepper_keyboard_t *keyboard = (pepper_keyboard_t *)info;
+       pepper_devicemgr_t *pepper_devicemgr = (pepper_devicemgr_t *)data;
+
+       devicemgr_input_generator_keyboard_set(pepper_devicemgr->devicemgr, keyboard);
+#ifdef _F_DEVICEMGR_XKB
+       pepper_devicemgr->xkb_info = keyboard->xkb_info;
+
+       pepper_devicemgr->listener_keyboard_keymap_update =
+               pepper_object_add_event_listener((pepper_object_t *)keyboard,
+                       PEPPER_EVENT_KEYBOARD_KEYMAP_UPDATE, 0,
+                       _pepper_devicemgr_handle_keyboard_keymap_update, pepper_devicemgr);
+#endif
+}
+
+static void
+_pepper_devicemgr_cb_block_events(struct wl_client *client, struct wl_resource *resource,
+                             uint32_t serial, uint32_t clas, uint32_t duration)
+{
+       tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+}
+
+static void
+_pepper_devicemgr_cb_unblock_events(struct wl_client *client, struct wl_resource *resource,
+                             uint32_t serial)
+{
+       tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+}
+
+static int
+_pepper_devicemgr_init_generator(pepper_devicemgr_t *pepper_devicemgr, struct wl_resource *resource, uint32_t clas, const char *name)
+{
+       int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+       pepper_devicemgr_resource_t *rdata;
+
+       ret = devicemgr_input_generator_init(pepper_devicemgr->devicemgr, clas, name);
+       PEPPER_CHECK(ret == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE, return ret, "Failed to init input generator\n");
+
+       pepper_list_for_each(rdata, &pepper_devicemgr->resources, link) {
+               if (rdata->resource == resource) {
+                       if (rdata->init == PEPPER_FALSE) {
+                               rdata->init = PEPPER_TRUE;
+                               pepper_devicemgr->ref++;
+                       }
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int
+_pepper_devicemgr_deinit_generator(pepper_devicemgr_t *pepper_devicemgr, struct wl_resource *resource)
+{
+       int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+       pepper_devicemgr_resource_t *rdata;
+
+       pepper_list_for_each(rdata, &pepper_devicemgr->resources, link) {
+               if (rdata->resource == resource) {
+                       if (rdata->init == PEPPER_TRUE) {
+                               rdata->init = PEPPER_FALSE;
+                               pepper_devicemgr->ref--;
+                               if (pepper_devicemgr->ref < 0) pepper_devicemgr->ref = 0;
+                       }
+                       break;
+               }
+       }
+
+       if (pepper_devicemgr->ref <= 0) {
+               ret = devicemgr_input_generator_deinit(pepper_devicemgr->devicemgr);
+               PEPPER_CHECK(ret == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE, return ret, "Failed to init input generator\n");
+       }
+
+       return ret;
+}
+
+static void
+_pepper_devicemgr_cb_init_generator(struct wl_client *client, struct wl_resource *resource, uint32_t clas)
+{
+       pepper_devicemgr_t *pepper_devicemgr;
+       int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+
+       pepper_devicemgr = wl_resource_get_user_data(resource);
+       PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n");
+       PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n");
+
+       ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
+       PEPPER_CHECK(clas == TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, goto failed,
+               "only support keyboard device. (requested: 0x%x)\n", clas);
+
+       ret = _pepper_devicemgr_init_generator(pepper_devicemgr, resource, clas, "Input Generator");
+       PEPPER_CHECK(ret == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE, goto failed, "Failed to init input generator\n");
+
+failed:
+       tizen_input_device_manager_send_error(resource, ret);
+}
+
+static void
+_pepper_devicemgr_cb_init_generator_with_name(struct wl_client *client, struct wl_resource *resource, uint32_t clas, const char *name)
+{
+       pepper_devicemgr_t *pepper_devicemgr;
+       int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+
+       pepper_devicemgr = wl_resource_get_user_data(resource);
+       PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n");
+       PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n");
+
+       ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
+       PEPPER_CHECK(clas == TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, goto failed,
+               "only support keyboard device. (requested: 0x%x)\n", clas);
+
+       ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
+       PEPPER_CHECK(name, goto failed, "no name for device\n");
+
+       ret = _pepper_devicemgr_init_generator(pepper_devicemgr, resource, clas, name);
+       PEPPER_CHECK(ret == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE, goto failed, "Failed to init input generator\n");
+
+failed:
+       tizen_input_device_manager_send_error(resource, ret);
+}
+
+static void
+_pepper_devicemgr_cb_deinit_generator(struct wl_client *client, struct wl_resource *resource, uint32_t clas)
+{
+       pepper_devicemgr_t *pepper_devicemgr;
+       int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+
+       pepper_devicemgr = wl_resource_get_user_data(resource);
+       PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n");
+       PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n");
+
+       ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
+       PEPPER_CHECK(clas == TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, goto failed,
+               "only support keyboard device. (requested: 0x%x)\n", clas);
+
+       ret = _pepper_devicemgr_deinit_generator(pepper_devicemgr, resource);
+       PEPPER_CHECK(ret == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE, goto failed, "Failed to init input generator\n");
+
+failed:
+       tizen_input_device_manager_send_error(resource, ret);
+}
+
+PEPPER_API void
+pepper_devicemgr_keymap_set(pepper_devicemgr_t *pepper_devicemgr, pepper_list_t *list)
+{
+       PEPPER_CHECK(pepper_devicemgr || list, return, "Please insert correct data\n");
+       if (pepper_devicemgr->keymap_list) return;
+
+       pepper_devicemgr->keymap_list = list;
+}
+
+static int
+_pepper_devicemgr_keyname_to_keycode(pepper_list_t *list, const char *name)
+{
+       pepper_devicemgr_keymap_data_t *data;
+
+       if (!strncmp(name, "Keycode-", sizeof("Keycode-")-1)) {
+               return atoi(name + 8);
+       }
+       else if (!pepper_list_empty(list)) {
+               pepper_list_for_each(data, list, link) {
+                       if (data) {
+                               if (!strncmp(data->name, name, UINPUT_MAX_NAME_SIZE)) {
+                                       return data->keycode;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static void
+_pepper_devicemgr_cb_generate_key(struct wl_client *client, struct wl_resource *resource,
+                                const char *keyname, uint32_t pressed)
+{
+       pepper_devicemgr_t *pepper_devicemgr;
+       int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+       int keycode = 0;
+
+       pepper_devicemgr = wl_resource_get_user_data(resource);
+       PEPPER_CHECK(pepper_devicemgr, goto failed, "pepper_devicemgr is not set\n");
+       PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "devicemgr is not created\n");
+
+#ifdef _F_DEVICEMGR_XKB
+       if (pepper_devicemgr->xkb_info) {
+               keycode = pepper_xkb_info_keyname_to_keycode(pepper_devicemgr->xkb_info, keyname);
+       } else
+#else
+       keycode = _pepper_devicemgr_keyname_to_keycode(pepper_devicemgr->keymap_list, keyname);
+#endif
+
+       ret = devicemgr_input_generator_generate_key(pepper_devicemgr->devicemgr, keycode, pressed);
+       PEPPER_CHECK(ret == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE, goto failed, "Failed to generate key(name: %s, code: %d), ret: %d\n", keyname, keycode, ret);
+
+failed:
+       tizen_input_device_manager_send_error(resource, ret);
+}
+
+static void
+_pepper_devicemgr_cb_generate_pointer(struct wl_client *client, struct wl_resource *resource,
+                                    uint32_t type, uint32_t x, uint32_t y, uint32_t button)
+{
+       tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+}
+
+static void
+_pepper_devicemgr_cb_generate_touch(struct wl_client *client, struct wl_resource *resource,
+                                   uint32_t type, uint32_t x, uint32_t y, uint32_t finger)
+{
+       tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+}
+
+static void
+_pepper_devicemgr_cb_pointer_warp(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y)
+{
+       tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+}
+
+static void
+_pepper_devicemgr_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+
+static const struct tizen_input_device_manager_interface _pepper_devmgr_implementation = {
+   _pepper_devicemgr_cb_block_events,
+   _pepper_devicemgr_cb_unblock_events,
+   _pepper_devicemgr_cb_init_generator,
+   _pepper_devicemgr_cb_deinit_generator,
+   _pepper_devicemgr_cb_generate_key,
+   _pepper_devicemgr_cb_generate_pointer,
+   _pepper_devicemgr_cb_generate_touch,
+   _pepper_devicemgr_cb_pointer_warp,
+   _pepper_devicemgr_cb_init_generator_with_name,
+   _pepper_devicemgr_cb_destroy,
+};
+
+/* tizen_devicemgr global object bind function */
+static void
+_pepper_devicemgr_cb_unbind(struct wl_resource *resource)
+{
+       pepper_devicemgr_t *pepper_devicemgr;
+
+       pepper_devicemgr = wl_resource_get_user_data(resource);
+       PEPPER_CHECK(pepper_devicemgr, return, "Invalid pepper_devicemgr_t\n");
+
+       _pepper_devicemgr_deinit_generator(pepper_devicemgr, resource);
+}
+
+static void
+_pepper_devicemgr_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+       struct wl_resource *resource;
+       pepper_devicemgr_resource_t *rdata;
+       pepper_devicemgr_t *pepper_devicemgr;
+
+       pepper_devicemgr = (pepper_devicemgr_t *)data;
+       PEPPER_CHECK(client, return, "Invalid client\n");
+       PEPPER_CHECK(pepper_devicemgr, return, "Invalid pepper_devicemgr_t\n");
+
+       resource = wl_resource_create(client, &tizen_input_device_manager_interface, 2, id);
+       if (!resource) {
+               PEPPER_ERROR("Failed to create resource ! (version :%d, id:%d)", version, id);
+               wl_client_post_no_memory(client);
+               return;
+       }
+
+       rdata = (pepper_devicemgr_resource_t *)calloc(1, sizeof(pepper_devicemgr_resource_t));
+       if (!rdata) {
+               PEPPER_ERROR("Failed to allocate memory !\n");
+
+               wl_resource_destroy(resource);
+               wl_client_post_no_memory(client);
+               return;
+       }
+
+       rdata->resource = resource;
+       pepper_list_init(&rdata->link);
+       pepper_list_insert(&pepper_devicemgr->resources, &rdata->link);
+
+       wl_resource_set_implementation(resource, &_pepper_devmgr_implementation,
+                                      pepper_devicemgr, _pepper_devicemgr_cb_unbind);
+}
+
+PEPPER_API pepper_devicemgr_t *
+pepper_devicemgr_create(pepper_compositor_t *compositor, pepper_seat_t *seat)
+{
+       struct wl_display *display = NULL;
+       struct wl_global *global = NULL;
+       pepper_devicemgr_t *pepper_devicemgr;
+
+       PEPPER_CHECK(compositor, return PEPPER_FALSE, "Invalid compositor\n");
+
+       display = pepper_compositor_get_display(compositor);
+       PEPPER_CHECK(display, return PEPPER_FALSE, "Failed to get wl_display from compositor\n");
+
+       pepper_devicemgr = (pepper_devicemgr_t *)calloc(1, sizeof(pepper_devicemgr_t));
+       PEPPER_CHECK(pepper_devicemgr, return PEPPER_FALSE, "Failed to allocate memory for devicemgr\n");
+       pepper_devicemgr->display = display;
+       pepper_devicemgr->compositor = compositor;
+       pepper_devicemgr->seat = seat;
+
+       pepper_devicemgr->listener_seat_keyboard_add = pepper_object_add_event_listener((pepper_object_t *)pepper_devicemgr->seat,
+               PEPPER_EVENT_SEAT_KEYBOARD_ADD,
+               0, _pepper_devicemgr_handle_seat_keyboard_add, pepper_devicemgr);
+
+       pepper_list_init(&pepper_devicemgr->resources);
+
+       global = wl_global_create(display, &tizen_input_device_manager_interface, 2, pepper_devicemgr, _pepper_devicemgr_cb_bind);
+       PEPPER_CHECK(global, goto failed, "Failed to create wl_global for tizen_devicemgr\n");
+
+       pepper_devicemgr->devicemgr = devicemgr_create(compositor, seat);
+       PEPPER_CHECK(pepper_devicemgr->devicemgr, goto failed, "Failed to create devicemgr\n");
+
+       return pepper_devicemgr;
+
+failed:
+       if (pepper_devicemgr) {
+               if (pepper_devicemgr->devicemgr) {
+                       devicemgr_destroy(pepper_devicemgr->devicemgr);
+                       pepper_devicemgr->devicemgr = NULL;
+               }
+               free(pepper_devicemgr);
+       }
+
+       return NULL;
+}
+
+PEPPER_API void
+pepper_devicemgr_destroy(pepper_devicemgr_t *pepper_devicemgr)
+{
+       pepper_devicemgr_resource_t *rdata, *rtmp;
+
+       PEPPER_CHECK(pepper_devicemgr, return, "Pepper devicemgr is not initialized\n");
+
+       pepper_list_for_each_safe(rdata, rtmp, &pepper_devicemgr->resources, link) {
+               wl_resource_destroy(rdata->resource);
+               pepper_list_remove(&rdata->link);
+               free(rdata);
+       }
+
+       if (pepper_devicemgr->devicemgr) {
+               devicemgr_destroy(pepper_devicemgr->devicemgr);
+               pepper_devicemgr->devicemgr = NULL;
+       }
+
+       if (pepper_devicemgr->global)
+               wl_global_destroy(pepper_devicemgr->global);
+
+       free(pepper_devicemgr);
+       pepper_devicemgr = NULL;
+}
diff --git a/src/lib/devicemgr/pepper-devicemgr.h b/src/lib/devicemgr/pepper-devicemgr.h
new file mode 100644 (file)
index 0000000..ad04169
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+* 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.
+*/
+
+#include "devicemgr.h"
+#include <linux/uinput.h>
+
+typedef struct pepper_devicemgr pepper_devicemgr_t;
+
+typedef struct pepper_devicemgr_keymap_data
+{
+       char name[UINPUT_MAX_NAME_SIZE + 1];
+       int keycode;
+
+       pepper_list_t link;
+} pepper_devicemgr_keymap_data_t;
+
+PEPPER_API pepper_devicemgr_t *pepper_devicemgr_create(pepper_compositor_t *compositor, pepper_seat_t *seat);
+PEPPER_API void pepper_devicemgr_destroy(pepper_devicemgr_t *pepper_devicemgr);
+
+PEPPER_API void pepper_devicemgr_keymap_set(pepper_devicemgr_t *pepper_devicemgr, pepper_list_t *list);
index 5da997f..81faecc 100644 (file)
@@ -47,6 +47,9 @@ pepper_xkb_create(void);
 PEPPER_API void
 pepper_xkb_destroy(pepper_xkb_t *xkb);
 
+PEPPER_API int
+pepper_xkb_info_keyname_to_keycode(pepper_xkb_info_t *xkb_info, const char *keyname);
+
 #ifdef __cplusplus
 }
 #endif
index 5bb0a9c..2ad4090 100644 (file)
 #include <pepper-utils.h>
 #include <xkb-internal.h>
 
+typedef struct _keycode_map{
+    xkb_keysym_t keysym;
+    xkb_keycode_t keycode;
+} keycode_map;
+
+static void
+find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
+{
+       keycode_map *found_keycodes = (keycode_map *)data;
+       xkb_keysym_t keysym = found_keycodes->keysym;
+       int nsyms = 0;
+       const xkb_keysym_t *syms_out = NULL;
+
+       if (found_keycodes->keycode) return;
+
+       nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
+       if (nsyms && syms_out) {
+               if (*syms_out == keysym) {
+                       found_keycodes->keycode = key;
+               }
+       }
+}
+
+static void
+_pepper_xkb_keycode_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym, xkb_keycode_t *keycode)
+{
+       keycode_map found_keycodes = {0,};
+       found_keycodes.keysym = keysym;
+       xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
+
+       *keycode = found_keycodes.keycode;
+}
+
+PEPPER_API int
+pepper_xkb_info_keyname_to_keycode(pepper_xkb_info_t *xkb_info, const char *keyname)
+{
+       xkb_keysym_t keysym = 0x0;
+       xkb_keycode_t keycode = 0;
+
+       PEPPER_CHECK(xkb_info, return -1, "pepper xkb is not set\n");
+
+       if (!strncmp(keyname, "Keycode-", sizeof("Keycode-")-1)) {
+               keycode = atoi(keyname+8);
+       } else {
+               keysym = xkb_keysym_from_name(keyname, XKB_KEYSYM_NO_FLAGS);
+               _pepper_xkb_keycode_from_keysym(xkb_info->keymap, keysym, &keycode);
+       }
+
+       return keycode;
+}
+
 static void
 pepper_xkb_info_destroy(pepper_xkb_info_t *info)
 {
index ecf4ff2..144b475 100644 (file)
@@ -41,6 +41,7 @@ struct sample_client
        struct wl_compositor *compositor;
        struct wl_registry *registry;
        struct tizen_keyrouter *keyrouter;
+       struct tizen_input_device_manager *devicemgr;
        struct wl_seat *seat;
        struct wl_keyboard *keyboard;
        struct wl_pointer *pointer;
@@ -471,8 +472,30 @@ keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t
        (void) time;
        (void) key;
        (void) state;
+       sample_client_t *client = data;
+       static int pressed = 1;
 
        TRACE("... serial=%d, time=%d, key=%d, state=%d\n", serial, time, key, state);
+       if (state == 0)
+       {
+               if (key == 123)
+               {
+                       tizen_input_device_manager_init_generator(client->devicemgr, TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD);
+               }
+               else if (key == 122)
+               {
+                       tizen_input_device_manager_deinit_generator(client->devicemgr, TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD);
+               }
+               else if (key == 177)
+               {
+                       tizen_input_device_manager_generate_key(client->devicemgr, "XF86Back", pressed);
+                       pressed = !pressed;
+               }
+               else if (key == 147)
+               {
+                       tizen_input_device_manager_destroy(client->devicemgr);
+               }
+       }
 }
 
 static void
@@ -589,6 +612,11 @@ global_registry_add(void * data, struct wl_registry * registry, uint32_t id, con
                client->keyrouter = wl_registry_bind(client->registry, id, &tizen_keyrouter_interface, 1);
                if (client->keyrouter) TRACE("[PID:%d] Succeed to bind tizen_keyrouter_interface !\n", client->pid);
        }
+       else if (0 == strncmp(interface, "tizen_input_device_manager", 12))
+       {
+               client->devicemgr = wl_registry_bind(client->registry, id, &tizen_input_device_manager_interface, 2);
+               if (client->devicemgr) TRACE("[PID:%d] Succeed to bind tizen_input_device_manager_interface !\n", client->pid);
+       }
        else if (0 == strncmp(interface, "xdg_shell", 9))
        {
                client->shell = wl_registry_bind(client->registry, id, &xdg_shell_interface, 1);
@@ -661,13 +689,51 @@ keygrab_notify_list(void *data, struct tizen_keyrouter *tizen_keyrouter, struct
        TRACE("... list\n");
 }
 
-
 static struct tizen_keyrouter_listener keyrouter_listener = {
        keygrab_notify,
        keygrab_notify_list
 };
 
 static void
+_cb_device_add(void *data, struct tizen_input_device_manager *tizen_input_device_manager, uint32_t serial, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
+{
+   ;
+}
+
+static void
+_cb_device_remove(void *data, struct tizen_input_device_manager *tizen_input_device_manager,
+               uint32_t serial ,
+               const char *identifier ,
+               struct tizen_input_device *device ,
+               struct wl_seat *seat )
+{
+   ;
+}
+
+static void
+_cb_error(void *data,
+          struct tizen_input_device_manager *tizen_input_device_manager,
+          uint32_t errorcode)
+{
+       TRACE("... error=%d\n", errorcode);
+}
+
+static void
+_cb_block_expired(void *data,
+                  struct tizen_input_device_manager *tizen_input_device_manager)
+{
+   ;
+}
+
+struct tizen_input_device_manager_listener devicemgr_listener =
+{
+   _cb_device_add,
+   _cb_device_remove,
+   _cb_error,
+   _cb_block_expired
+};
+
+static void
 do_keygrab(sample_client_t *client, const char *keyname, uint32_t mode)
 {
        xkb_keysym_t keysym = 0x0;
@@ -695,14 +761,18 @@ int main(int argc, char **argv)
 
        const char *use_xdg_shell = NULL;
        const char *use_keyrouter = NULL;
+       const char *use_devicemgr = NULL;
 
        use_xdg_shell = getenv("USE_XDG_SHELL");
        use_keyrouter = getenv("USE_KEYROUTER");
+       use_devicemgr = getenv("USE_DEVICEMGR");
 
        if (!use_xdg_shell)
                TRACE("* Note : XDG SHELL can be initialized by setting USE_XDG_SHELL environment variable !\n");
        if (!use_keyrouter)
                TRACE("* Note : tizen_keyrouter interface can be initialized by setting USE_KEYROUTER environment variable !\n");
+       if (!use_devicemgr)
+               TRACE("* Note : tizen_input_device_manager interface can be initialized by setting USE_DEVICEMGR environment variable !\n");
 
        client = calloc(1, sizeof(sample_client_t));
        ERROR_CHECK(client, goto shutdown, "Failed to allocate memory for sample client !\n");
@@ -730,6 +800,9 @@ int main(int argc, char **argv)
        if (use_xdg_shell)
                ERROR_CHECK(client->shell, goto shutdown, "[PID:%d] Failed to bind to the xdg shell interface !\n", client->pid);
 
+       if (use_devicemgr)
+               ERROR_CHECK(client->devicemgr, goto shutdown, "[PID:%d] Failed to bind to the devicemgr interface !\n", client->pid);
+
        client->surface = wl_compositor_create_surface(client->compositor);
        ERROR_CHECK(client->surface, goto shutdown, "[PID:%d] can't create surface\n", client->pid);
 
@@ -746,13 +819,25 @@ int main(int argc, char **argv)
 
        if (use_keyrouter)
        {
-               if (0 > tizen_keyrouter_add_listener(client->keyrouter, &keyrouter_listener, NULL))
+               if (0 > tizen_keyrouter_add_listener(client->keyrouter, &keyrouter_listener, client))
                {
                        TRACE("[PID:%d] Failed on tizen_keyrouter_add_listener !\n", client->pid);
                        return 0;
                }
 
+               do_keygrab(client, "XF86Menu", TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
+               do_keygrab(client, "XF86AudioRaiseVolume", TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
+               do_keygrab(client, "XF86AudioLowerVolume", TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
                do_keygrab(client, "XF86Home", TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
+               do_keygrab(client, "XF86Back", TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
+       }
+       if (use_devicemgr)
+       {
+               if (0 > tizen_input_device_manager_add_listener(client->devicemgr, &devicemgr_listener, client))
+               {
+                       TRACE("[PID:%d] Failed on tizen_input_device_manager_add_listener !\n", client->pid);
+                       return 0;
+               }
        }
 
        while (wl_display_dispatch(client->display) != -1)
index 641681d..86e569a 100644 (file)
@@ -32,6 +32,7 @@
 #include <pepper-evdev.h>
 #include <pepper-keyrouter.h>
 #include <pepper-input-backend.h>
+#include <pepper-devicemgr.h>
 
 /* basic pepper objects */
 pepper_xkb_t *xkb = NULL;
@@ -39,6 +40,7 @@ pepper_seat_t *seat = NULL;
 pepper_evdev_t *evdev = NULL;
 pepper_keyrouter_t *keyrouter = NULL;
 pepper_input_device_t *input_device = NULL;
+pepper_devicemgr_t *devicemgr = NULL;
 
 /* event listeners */
 pepper_event_listener_t *listener_seat_add = NULL;
@@ -134,6 +136,32 @@ _handle_input_device_remove(pepper_event_listener_t *listener, pepper_object_t *
                pepper_seat_remove_input_device(seat, device);
 }
 
+static void
+_pepper_devicemgr_keymap_add(pepper_list_t *list, const char *name, int keycode)
+{
+       pepper_devicemgr_keymap_data_t *data;
+
+       data = (pepper_devicemgr_keymap_data_t *)calloc(1, sizeof(pepper_devicemgr_keymap_data_t));
+       PEPPER_CHECK(data, return, "Failed to alloc memory\n");
+
+       strncpy(data->name, name, UINPUT_MAX_NAME_SIZE);
+       data->keycode = keycode;
+
+       pepper_list_init(&data->link);
+       pepper_list_insert(list, &data->link);
+}
+
+static void
+_pepper_devicemgr_keymap_set(pepper_devicemgr_t *pepper_devicemgr, pepper_list_t *list)
+{
+       pepper_list_init(list);
+       _pepper_devicemgr_keymap_add(list, "XF86Back", 166);
+       _pepper_devicemgr_keymap_add(list, "XF86Home", 147);
+       _pepper_devicemgr_keymap_add(list, "XF86Menu", 177);
+
+       pepper_devicemgr_keymap_set(pepper_devicemgr, list);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -142,6 +170,7 @@ main(int argc, char **argv)
        struct wl_display   *display;
        pepper_compositor_t *compositor;
        const char* socket_name = NULL;
+       pepper_list_t keymap_list;
 
        if (!getenv("XDG_RUNTIME_DIR"))
                setenv("XDG_RUNTIME_DIR", "/run", 1);
@@ -201,6 +230,12 @@ main(int argc, char **argv)
        seat = pepper_compositor_add_seat(compositor, "seat0");
        PEPPER_CHECK(seat, goto shutdown_on_failure, "Failed to add seat !\n");
 
+       /* create pepper devicemgr */
+       devicemgr = pepper_devicemgr_create(compositor, seat);
+       PEPPER_CHECK(devicemgr, goto shutdown_on_failure, "Failed to create devicemgr !\n");
+
+       _pepper_devicemgr_keymap_set(devicemgr, &keymap_list);
+
        /* set keyboard capability by default */
        caps = WL_SEAT_CAPABILITY_KEYBOARD;
 
@@ -233,6 +268,8 @@ shutdown_on_failure:
 
        if (keyrouter)
                pepper_keyrouter_destroy(keyrouter);
+       if (devicemgr)
+               pepper_devicemgr_destroy(devicemgr);
        if (evdev)
                pepper_evdev_destroy(evdev);
        if (input_device)