From d678f93e0ccbebc482e1ac52fbbc4d3c8f5b15c6 Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Thu, 29 Mar 2018 15:03:59 +0900 Subject: [PATCH] devicemgr: support a devicemgr's key event generation functions Change-Id: Ia42f5cd8c9a8ca493ff0f34dcabe9925b64e98db --- Makefile.am | 1 + configure.ac | 24 +- packaging/pepper.spec | 36 ++- pkgconfig/pepper-devicemgr.pc.in | 14 + src/Makefile.am | 1 + src/bin/doctor/doctor.c | 42 +++ src/lib/devicemgr/Makefile.am | 13 + src/lib/devicemgr/devicemgr-internal.h | 48 +++ src/lib/devicemgr/devicemgr.c | 160 +++++++++ src/lib/devicemgr/devicemgr.h | 50 +++ src/lib/devicemgr/pepper-devicemgr.c | 427 +++++++++++++++++++++++++ src/lib/devicemgr/pepper-devicemgr.h | 40 +++ src/lib/xkb/pepper-xkb.h | 3 + src/lib/xkb/xkb.c | 51 +++ src/samples/sample-client.c | 89 +++++- src/samples/sample-server.c | 37 +++ 16 files changed, 1028 insertions(+), 8 deletions(-) create mode 100644 pkgconfig/pepper-devicemgr.pc.in create mode 100644 src/lib/devicemgr/Makefile.am create mode 100644 src/lib/devicemgr/devicemgr-internal.h create mode 100644 src/lib/devicemgr/devicemgr.c create mode 100644 src/lib/devicemgr/devicemgr.h create mode 100644 src/lib/devicemgr/pepper-devicemgr.c create mode 100644 src/lib/devicemgr/pepper-devicemgr.h diff --git a/Makefile.am b/Makefile.am index 4eb2d30..22dcb2c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.ac b/configure.ac index 89d51e0..86ea917 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/packaging/pepper.spec b/packaging/pepper.spec index 448edf1..01796ec 100644 --- a/packaging/pepper.spec +++ b/packaging/pepper.spec @@ -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 index 0000000..6dabe41 --- /dev/null +++ b/pkgconfig/pepper-devicemgr.pc.in @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 89049d5..c9f9dbe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = lib/pepper \ lib/keyrouter \ + lib/devicemgr \ lib/evdev \ lib/libinput \ lib/xkb \ diff --git a/src/bin/doctor/doctor.c b/src/bin/doctor/doctor.c index 158fb6c..d542ba8 100644 --- a/src/bin/doctor/doctor.c +++ b/src/bin/doctor/doctor.c @@ -4,6 +4,7 @@ #include #include #include +#include /* 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 index 0000000..153941c --- /dev/null +++ b/src/lib/devicemgr/Makefile.am @@ -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 index 0000000..a8dc8d4 --- /dev/null +++ b/src/lib/devicemgr/devicemgr-internal.h @@ -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 +#include +#include +#include +#include + +#include +#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 index 0000000..6378f2d --- /dev/null +++ b/src/lib/devicemgr/devicemgr.c @@ -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 + +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 index 0000000..56f54cb --- /dev/null +++ b/src/lib/devicemgr/devicemgr.h @@ -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 + +#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 index 0000000..799fbaa --- /dev/null +++ b/src/lib/devicemgr/pepper-devicemgr.c @@ -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 +#ifdef _F_DEVICEMGR_XKB +#include +#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 index 0000000..ad04169 --- /dev/null +++ b/src/lib/devicemgr/pepper-devicemgr.h @@ -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 + +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); diff --git a/src/lib/xkb/pepper-xkb.h b/src/lib/xkb/pepper-xkb.h index 5da997f..81faecc 100644 --- a/src/lib/xkb/pepper-xkb.h +++ b/src/lib/xkb/pepper-xkb.h @@ -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 diff --git a/src/lib/xkb/xkb.c b/src/lib/xkb/xkb.c index 5bb0a9c..2ad4090 100644 --- a/src/lib/xkb/xkb.c +++ b/src/lib/xkb/xkb.c @@ -33,6 +33,57 @@ #include #include +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) { diff --git a/src/samples/sample-client.c b/src/samples/sample-client.c index ecf4ff2..144b475 100644 --- a/src/samples/sample-client.c +++ b/src/samples/sample-client.c @@ -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,12 +689,50 @@ 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) { @@ -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) diff --git a/src/samples/sample-server.c b/src/samples/sample-server.c index 641681d..86e569a 100644 --- a/src/samples/sample-server.c +++ b/src/samples/sample-server.c @@ -32,6 +32,7 @@ #include #include #include +#include /* 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) -- 2.34.1