From: Sung-Jin Park Date: Mon, 19 Jun 2017 02:32:22 +0000 (+0900) Subject: pepper & pepper-xkb : remove xkb dependency from pepper and add pepper-xkb X-Git-Tag: submit/tizen/20170628.060900~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6e8c9914cd486e0d39bdf6f7a53a3132fb0d9c5a;p=platform%2Fcore%2Fuifw%2Fpepper.git pepper & pepper-xkb : remove xkb dependency from pepper and add pepper-xkb Change-Id: I094529144338a2306c2fcc355c4de0d462818a51 Signed-off-by: Sung-Jin Park --- diff --git a/Makefile.am b/Makefile.am index 64f278c..4eb2d30 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,6 +14,7 @@ pkgconfig_DATA += pkgconfig/pepper-fbdev.pc pkgconfig_DATA += pkgconfig/pepper-keyrouter.pc pkgconfig_DATA += pkgconfig/pepper-evdev.pc pkgconfig_DATA += pkgconfig/pepper-libinput.pc +pkgconfig_DATA += pkgconfig/pepper-xkb.pc pkgconfig_DATA += pkgconfig/pepper-wayland.pc if ENABLE_X11 pkgconfig_DATA += pkgconfig/pepper-x11.pc diff --git a/configure.ac b/configure.ac index 3ffeafd..30a6054 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ fi AC_SUBST(GCC_CFLAGS) # pepper -PEPPER_REQUIRES="wayland-server xkbcommon" +PEPPER_REQUIRES="wayland-server" PKG_CHECK_MODULES(PEPPER, [$PEPPER_REQUIRES]) PKG_CHECK_MODULES([TBM], [libtbm wayland-tbm-server], [have_tbm=yes], [have_tbm=no]) if test x$have_tbm = xyes; then @@ -83,6 +83,20 @@ AC_SUBST(PEPPER_LIBINPUT_CFLAGS) AC_SUBST(PEPPER_LIBINPUT_LIBS) AC_SUBST(PEPPER_LIBINPUT_REQUIRES) +# pepper-xkb +PEPPER_XKB_REQUIRES="xkbcommon" +PKG_CHECK_MODULES(PEPPER_XKB, [$PEPPER_XKB_REQUIRES]) + +PEPPER_XKB_DIR="-I\$(top_srcdir)/src/lib/xkb" +PEPPER_XKB_LIB="\$(top_srcdir)/src/lib/xkb/libpepper-xkb.la" + +PEPPER_XKB_CFLAGS="$PEPPER_DIR $PEPPER_XKB_DIR $PEPPER_CFLAGS $PEPPER_XKB_CFLAGS" +PEPPER_XKB_LIBS="$PEPPER_LIB $PEPPER_XKB_LIBS" + +AC_SUBST(PEPPER_XKB_CFLAGS) +AC_SUBST(PEPPER_XKB_LIBS) +AC_SUBST(PEPPER_XKB_REQUIRES) + # pepper-desktop-shell PEPPER_DESKTOP_SHELL_REQUIRES="pepper" @@ -316,6 +330,7 @@ src/Makefile src/lib/pepper/Makefile src/lib/keyrouter/Makefile src/lib/evdev/Makefile +src/lib/xkb/Makefile src/lib/libinput/Makefile src/lib/desktop-shell/Makefile src/lib/render/Makefile @@ -330,6 +345,7 @@ pkgconfig/pepper-drm.pc pkgconfig/pepper-fbdev.pc pkgconfig/pepper-keyrouter.pc pkgconfig/pepper-evdev.pc +pkgconfig/pepper-xkb.pc pkgconfig/pepper-libinput.pc pkgconfig/pepper-wayland.pc pkgconfig/pepper-desktop-shell.pc diff --git a/packaging/pepper.spec b/packaging/pepper.spec index b1b86eb..056ffff 100644 --- a/packaging/pepper.spec +++ b/packaging/pepper.spec @@ -74,6 +74,21 @@ Requires: pepper-evdev = %{version}-%{release} %description evdev-devel This package includes evdev development module files. +###### xkb +%package xkb +Summary: xkb module for pepper package + +%description xkb +This package includes xkb module files. + +###### xkb-devel +%package xkb-devel +Summary: XKB development module for pepper package +Requires: pepper-xkb = %{version}-%{release} + +%description xkb-devel +This package includes xkb development module files. + ###### libinput %package libinput Summary: Libinput module for pepper package @@ -198,6 +213,7 @@ Requires: pepper-keyrouter pepper-evdev %description samples This package includes samples files. + ###### executing %prep @@ -257,7 +273,6 @@ make %{?_smp_mflags} %{_includedir}/pepper/pepper.h %{_includedir}/pepper/pepper-utils.h %{_includedir}/pepper/pepper-utils-pixman.h -%{_includedir}/pepper/pepper-utils-xkb.h %{_includedir}/pepper/pepper-output-backend.h %{_includedir}/pepper/pepper-input-backend.h %{_libdir}/pkgconfig/pepper.pc @@ -290,6 +305,19 @@ make %{?_smp_mflags} %{_libdir}/pkgconfig/pepper-evdev.pc %{_libdir}/libpepper-evdev.so +%files xkb +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license COPYING +%{_libdir}/libpepper-xkb.so.* + +%files xkb-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_includedir}/pepper/pepper-xkb.h +%{_libdir}/pkgconfig/pepper-xkb.pc +%{_libdir}/libpepper-xkb.so + %files libinput %manifest %{name}.manifest %defattr(-,root,root,-) diff --git a/pkgconfig/pepper-xkb.pc.in b/pkgconfig/pepper-xkb.pc.in new file mode 100644 index 0000000..3b62b43 --- /dev/null +++ b/pkgconfig/pepper-xkb.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +libexecdir=@libexecdir@ +pkglibexecdir=${libexecdir}/@PACKAGE@ + +Name: Pepper Evdev Backend Library +Description: Pepper xkb backend library header and library files +Version: @PEPPER_XKB_VERSION@ + +Requires.private: @PEPPER_XKB_REQUIRES@ +Cflags: -I${includedir}/pepper +Libs: -L${libdir} -lpepper-xkb diff --git a/src/Makefile.am b/src/Makefile.am index b918f09..89049d5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,6 +2,7 @@ SUBDIRS = lib/pepper \ lib/keyrouter \ lib/evdev \ lib/libinput \ + lib/xkb \ lib/desktop-shell \ lib/render \ lib/drm \ diff --git a/src/lib/pepper/Makefile.am b/src/lib/pepper/Makefile.am index 6606b06..858805a 100644 --- a/src/lib/pepper/Makefile.am +++ b/src/lib/pepper/Makefile.am @@ -3,7 +3,7 @@ lib_LTLIBRARIES = libpepper.la AM_CFLAGS = $(GCC_CFLAGS) libpepper_includedir=$(includedir)/pepper -libpepper_include_HEADERS = pepper.h pepper-utils.h pepper-utils-pixman.h pepper-utils-xkb.h pepper-output-backend.h pepper-input-backend.h +libpepper_include_HEADERS = pepper.h pepper-utils.h pepper-utils-pixman.h pepper-output-backend.h pepper-input-backend.h libpepper_la_CFLAGS = $(AM_CFLAGS) $(PEPPER_CFLAGS) libpepper_la_LIBADD = $(PEPPER_LIBS) -lm diff --git a/src/lib/pepper/keyboard.c b/src/lib/pepper/keyboard.c index 601a573..e5caabc 100644 --- a/src/lib/pepper/keyboard.c +++ b/src/lib/pepper/keyboard.c @@ -31,9 +31,9 @@ #include #include #include +#include #include "pepper-internal.h" -#include "pepper-utils-xkb.h" static void keyboard_release(struct wl_client *client, struct wl_resource *resource) @@ -74,9 +74,6 @@ update_keymap(pepper_keyboard_t *keyboard) if (keyboard->keymap_fd >= 0) close(keyboard->keymap_fd); - if (keyboard->xkb_info) - pepper_xkb_destroy((struct pepper_xkb_info *)keyboard->xkb_info); - keyboard->keymap_format = keyboard->pending.keymap_format; keyboard->keymap_fd = keyboard->pending.keymap_fd; keyboard->keymap_len = keyboard->pending.keymap_len; @@ -100,11 +97,6 @@ update_keymap(pepper_keyboard_t *keyboard) } keyboard->need_update_keymap = 0; - - if (keyboard->pending.xkb_info) { - keyboard->xkb_info = keyboard->pending.xkb_info; - keyboard->pending.xkb_info = NULL; - } } void @@ -136,12 +128,10 @@ pepper_keyboard_handle_event(pepper_keyboard_t *keyboard, uint32_t id, event->state); if (keyboard->need_update_keymap && keyboard->keys.size == 0) { + pepper_object_emit_event(&keyboard->base, + PEPPER_EVENT_KEYBOARD_KEYMAP_UPDATE, keyboard); update_keymap(keyboard); update_modifiers(keyboard); - } else { - if (keyboard->xkb_info) { - pepper_xkb_update_keyboard_modifier(keyboard->xkb_info, keyboard, event); - } } pepper_object_emit_event(&keyboard->base, PEPPER_EVENT_KEYBOARD_KEY, @@ -193,10 +183,6 @@ pepper_keyboard_destroy(pepper_keyboard_t *keyboard) close(keyboard->keymap_fd); if (keyboard->pending.keymap_fd >= 0) close(keyboard->pending.keymap_fd); - if (keyboard->xkb_info) - pepper_xkb_destroy((struct pepper_xkb_info *)keyboard->xkb_info); - if (keyboard->pending.xkb_info) - pepper_xkb_destroy((struct pepper_xkb_info *)keyboard->pending.xkb_info); wl_array_release(&keyboard->keys); free(keyboard); @@ -531,16 +517,9 @@ pepper_keyboard_get_grab_data(pepper_keyboard_t *keyboard) * * This function might send wl_pointer.keymap and wl_pointer.modifers events internally */ -PEPPER_API void +PEPPER_DEPRECATED void pepper_keyboard_set_keymap(pepper_keyboard_t *keyboard, - struct xkb_keymap *keymap) -{ - if (keyboard->pending.xkb_info) - pepper_xkb_destroy(keyboard->pending.xkb_info); - - keyboard->pending.xkb_info = pepper_xkb_create(keymap); - pepper_xkb_set_keyboard(keyboard->pending.xkb_info, keyboard); -} + void *keymap); /** * Set xkb keymap information for the given keyboard @@ -565,6 +544,8 @@ pepper_keyboard_set_keymap_info(pepper_keyboard_t *keyboard, keyboard->pending.keymap_format = keymap_format; if (keyboard->keys.size == 0) { + pepper_object_emit_event(&keyboard->base, + PEPPER_EVENT_KEYBOARD_KEYMAP_UPDATE, keyboard); update_keymap(keyboard); } else { keyboard->need_update_keymap = 1; @@ -595,3 +576,51 @@ pepper_keyboard_set_modifiers(pepper_keyboard_t *keyboard, if (!keyboard->need_update_keymap) update_modifiers(keyboard); } + +/** + * Get current xkb_info for the given keyboard + * + * @param keyboard keyboard object + */ +PEPPER_API void * +pepper_keyboard_get_xkb_info(pepper_keyboard_t *keyboard) +{ + return keyboard->xkb_info; +} + +/** + * Get pending xkb_info for the given keyboard + * + * @param keyboard keyboard object + */ +PEPPER_API void * +pepper_keyboard_get_pending_xkb_info(pepper_keyboard_t *keyboard) +{ + return keyboard->pending.xkb_info; +} + +/** + * Set xkb_info for the given keyboard + * + * @param keyboard keyboard object + * @param xkb_info xkb_info + */ +PEPPER_API void +pepper_keyboard_set_xkb_info(pepper_keyboard_t *keyboard, + void *xkb_info) +{ + keyboard->xkb_info = xkb_info; +} + +/** + * Set pending xkb_info for the given keyboard + * + * @param keyboard keyboard object + * @param xkb_info xkb_info + */ +PEPPER_API void +pepper_keyboard_set_pending_xkb_info(pepper_keyboard_t *keyboard, + void *xkb_info) +{ + keyboard->pending.xkb_info = xkb_info; +} diff --git a/src/lib/pepper/pepper-utils-xkb.h b/src/lib/pepper/pepper-utils-xkb.h deleted file mode 100644 index 76711cc..0000000 --- a/src/lib/pepper/pepper-utils-xkb.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -* Copyright © 2008-2012 Kristian Høgsberg -* Copyright © 2010-2012 Intel Corporation -* Copyright © 2011 Benjamin Franzke -* Copyright © 2012 Collabora, Ltd. -* Copyright © 2015 S-Core Corporation -* Copyright © 2015-2016 Samsung Electronics co., Ltd. All Rights Reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice (including the next -* paragraph) shall be included in all copies or substantial portions of the -* Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -* DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PEPPER_UTILS_XKB_H -#define PEPPER_UTILS_XKB_H - -#include -#include -#include -#include -#include - -struct pepper_xkb_info { - struct xkb_state *state; -}; - -static inline struct pepper_xkb_info * -pepper_xkb_create(struct xkb_keymap *keymap) -{ - struct pepper_xkb_info *info = NULL; - - if (!keymap) - return NULL; - - info = calloc(1, sizeof(struct pepper_xkb_info)); - info->state = xkb_state_new(keymap); - - return info; -} - -static inline void -pepper_xkb_destroy(struct pepper_xkb_info *info) -{ - xkb_state_unref(info->state); - free(info); -} - -static inline void -pepper_xkb_get_modifier(struct pepper_xkb_info *info, - uint32_t * depressed, - uint32_t * latched, - uint32_t * locked, uint32_t * group) -{ - if (depressed) - *depressed = xkb_state_serialize_mods(info->state, - XKB_STATE_MODS_DEPRESSED); - if (latched) - *latched = xkb_state_serialize_mods(info->state, - XKB_STATE_MODS_LATCHED); - if (locked) - *locked = xkb_state_serialize_mods(info->state, - XKB_STATE_MODS_LOCKED); - if (group) - *group = xkb_state_serialize_mods(info->state, - XKB_STATE_LAYOUT_EFFECTIVE); -} - -static inline void -pepper_xkb_set_keyboard(struct pepper_xkb_info *info, - pepper_keyboard_t * keyboard) -{ - struct xkb_keymap *keymap; - char *keymap_str = NULL; - int keymap_fd = -1; - uint32_t keymap_len; - char *keymap_map = NULL; - - uint32_t depressed = 0; - uint32_t latched = 0; - uint32_t locked = 0; - uint32_t group = 0; - - if (!info || !keyboard) - return; - - keymap = xkb_state_get_keymap(info->state); - if (!keymap) - return; - - keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); - if (!keymap_str) - goto err; - - keymap_len = strlen(keymap_str) + 1; - keymap_fd = pepper_create_anonymous_file(keymap_len); - if (keymap_fd < 0) - goto err; - - keymap_map = mmap(NULL, keymap_len, PROT_READ | PROT_WRITE, - MAP_SHARED, keymap_fd, 0); - if (!keymap_map) - goto err; - - strncpy(keymap_map, keymap_str, keymap_len); - pepper_keyboard_set_keymap_info(keyboard, - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - keymap_fd, keymap_len); - - pepper_xkb_get_modifier(info, &depressed, &latched, &locked, &group); - pepper_keyboard_set_modifiers(keyboard, depressed, latched, locked, - group); - - err: - if (keymap_str) - free(keymap_str); - - if (keymap_map) - munmap(keymap_map, keymap_len); - - if (keymap_fd >= 0) - close(keymap_fd); - - return; -} - -static inline void -pepper_xkb_update_keyboard_modifier(struct pepper_xkb_info *info, - pepper_keyboard_t * keyboard, - pepper_input_event_t * event) -{ - enum xkb_key_direction direction; - uint32_t depressed = 0; - uint32_t latched = 0; - uint32_t locked = 0; - uint32_t group = 0; - - if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) - direction = XKB_KEY_DOWN; - else - direction = XKB_KEY_UP; - - xkb_state_update_key(info->state, event->key + 8, direction); - - pepper_xkb_get_modifier(info, &depressed, &latched, &locked, &group); - pepper_keyboard_set_modifiers(keyboard, depressed, latched, locked, - group); -} - -#endif diff --git a/src/lib/pepper/pepper-utils.h b/src/lib/pepper/pepper-utils.h index e6b60b1..07d9faf 100644 --- a/src/lib/pepper/pepper-utils.h +++ b/src/lib/pepper/pepper-utils.h @@ -41,8 +41,10 @@ extern "C" { #if defined(__GNUC__) && __GNUC__ >= 4 # define PEPPER_API __attribute__ ((visibility("default"))) +# define PEPPER_DEPRECATED __attribute__ ((deprecated)) #else # define PEPPER_API +# define PEPPER_DEPRECATED #endif #define PEPPER_MAX(a, b) ((a) > (b) ? (a) : (b)) diff --git a/src/lib/pepper/pepper.h b/src/lib/pepper/pepper.h index 9bc52ed..3d8484e 100644 --- a/src/lib/pepper/pepper.h +++ b/src/lib/pepper/pepper.h @@ -36,7 +36,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -769,6 +768,15 @@ enum pepper_built_in_events { * - info : #pepper_input_event_t */ PEPPER_EVENT_TOUCH_CANCEL, + + /** + * Keymap update event. + * + * #pepper_keyboard_t + * - when : #pepper_keyboard_t emits keymap update event before updating keymap + * - info : #pepper_keyboard_t + */ + PEPPER_EVENT_KEYBOARD_KEYMAP_UPDATE, }; enum pepper_pointer_axis { @@ -1147,9 +1155,9 @@ pepper_keyboard_get_grab(pepper_keyboard_t *keyboard); PEPPER_API void * pepper_keyboard_get_grab_data(pepper_keyboard_t *keyboard); -PEPPER_API void +PEPPER_DEPRECATED void pepper_keyboard_set_keymap(pepper_keyboard_t *keyboard, - struct xkb_keymap *keymap); + void *keymap); PEPPER_API void pepper_keyboard_set_keymap_info(pepper_keyboard_t *keyboard, @@ -1162,6 +1170,18 @@ pepper_keyboard_set_modifiers(pepper_keyboard_t *keyboard, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group); +PEPPER_API void * +pepper_keyboard_get_xkb_info(pepper_keyboard_t *keyboard); + +PEPPER_API void * +pepper_keyboard_get_pending_xkb_info(pepper_keyboard_t *keyboard); + +PEPPER_API void +pepper_keyboard_set_xkb_info(pepper_keyboard_t *keyboard, void *xkb_info); + +PEPPER_API void +pepper_keyboard_set_pending_xkb_info(pepper_keyboard_t *keyboard, void *xkb_info); + /* Touch. */ struct pepper_touch_grab { void (*down)(pepper_touch_t *touch, void *data, uint32_t time, int32_t id, diff --git a/src/lib/xkb/Makefile.am b/src/lib/xkb/Makefile.am new file mode 100644 index 0000000..d23cd87 --- /dev/null +++ b/src/lib/xkb/Makefile.am @@ -0,0 +1,11 @@ +lib_LTLIBRARIES = libpepper-xkb.la + +AM_CFLAGS = $(GCC_CFLAGS) + +libpepper_xkb_includedir=$(includedir)/pepper +libpepper_xkb_include_HEADERS = pepper-xkb.h + +libpepper_xkb_la_CFLAGS = $(AM_CFLAGS) $(PEPPER_XKB_CFLAGS) +libpepper_xkb_la_LIBADD = $(PEPPER_XKB_LIBS) + +libpepper_xkb_la_SOURCES = xkb.c diff --git a/src/lib/xkb/pepper-xkb.h b/src/lib/xkb/pepper-xkb.h new file mode 100644 index 0000000..5da997f --- /dev/null +++ b/src/lib/xkb/pepper-xkb.h @@ -0,0 +1,54 @@ +/* +* Copyright © 2015-2017 Samsung Electronics co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PEPPER_XKB_H +#define PEPPER_XKB_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct xkb_rule_names pepper_xkb_rule_names; +typedef pepper_xkb_rule_names pepper_xkb_rule_names_t; +typedef struct pepper_xkb_info pepper_xkb_info_t; +typedef struct pepper_xkb pepper_xkb_t; + +PEPPER_API void +pepper_xkb_keyboard_set_keymap(pepper_xkb_t *xkb, + pepper_keyboard_t *keyboard, + pepper_xkb_rule_names_t *names); + +PEPPER_API pepper_xkb_t * +pepper_xkb_create(void); + +PEPPER_API void +pepper_xkb_destroy(pepper_xkb_t *xkb); + +#ifdef __cplusplus +} +#endif + +#endif /* PEPPER_XKB_H */ diff --git a/src/lib/xkb/xkb-internal.h b/src/lib/xkb/xkb-internal.h new file mode 100644 index 0000000..6448cfb --- /dev/null +++ b/src/lib/xkb/xkb-internal.h @@ -0,0 +1,44 @@ +/* +* Copyright © 2015-2017 Samsung Electronics co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PEPPER_XKB_INTERNAL_H +#define PEPPER_XKB_INTERNAL_H + +#include +#include + +struct pepper_xkb_info +{ + struct xkb_state *state; + struct xkb_context* context; + struct xkb_keymap* keymap; +}; + +struct pepper_xkb +{ + pepper_xkb_info_t *info; + pepper_event_listener_t *listener_key; + pepper_event_listener_t *listener_keymap_update; +}; + +#endif /* PEPPER_XKB_INTERNAL_H */ diff --git a/src/lib/xkb/xkb.c b/src/lib/xkb/xkb.c new file mode 100644 index 0000000..5bb0a9c --- /dev/null +++ b/src/lib/xkb/xkb.c @@ -0,0 +1,327 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void +pepper_xkb_info_destroy(pepper_xkb_info_t *info) +{ + if (!info) + return; + + xkb_keymap_unref(info->keymap); + xkb_state_unref(info->state); + xkb_context_unref(info->context); + + free(info); +} + +static struct xkb_keymap * +pepper_xkb_keymap_create(struct xkb_context* context, + pepper_xkb_rule_names_t *names) +{ + struct xkb_keymap* keymap; + + if (!context) + return NULL; + + keymap = xkb_map_new_from_names(context, names, XKB_KEYMAP_COMPILE_NO_FLAGS); + + return keymap; +} + +static void +pepper_xkb_get_modifier(pepper_xkb_info_t *info, + uint32_t * depressed, + uint32_t * latched, + uint32_t * locked, uint32_t * group) +{ + if (depressed) + *depressed = xkb_state_serialize_mods(info->state, + XKB_STATE_MODS_DEPRESSED); + if (latched) + *latched = xkb_state_serialize_mods(info->state, + XKB_STATE_MODS_LATCHED); + if (locked) + *locked = xkb_state_serialize_mods(info->state, + XKB_STATE_MODS_LOCKED); + if (group) + *group = xkb_state_serialize_mods(info->state, + XKB_STATE_LAYOUT_EFFECTIVE); +} + +static void +pepper_xkb_update_keyboard_modifier(pepper_xkb_info_t *info, + pepper_keyboard_t * keyboard, + pepper_input_event_t * event) +{ + enum xkb_key_direction direction; + uint32_t depressed = 0; + uint32_t latched = 0; + uint32_t locked = 0; + uint32_t group = 0; + + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) + direction = XKB_KEY_DOWN; + else + direction = XKB_KEY_UP; + + xkb_state_update_key(info->state, event->key + 8, direction); + + pepper_xkb_get_modifier(info, &depressed, &latched, &locked, &group); + pepper_keyboard_set_modifiers(keyboard, depressed, latched, locked, + group); +} + +static void +_pepper_xkb_handle_keyboard_key(pepper_event_listener_t *listener, + pepper_object_t *object, uint32_t id, void *info, void *data) +{ + pepper_xkb_info_t *xkb_info = NULL; + + PEPPER_CHECK(id == PEPPER_EVENT_KEYBOARD_KEY, return, "%d event will not be handled.\n", id); + PEPPER_CHECK(info, return, "Invalid event\n"); + PEPPER_CHECK(data, return, "Invalid data.\n"); + + pepper_input_event_t *event = (pepper_input_event_t *)info; + pepper_keyboard_t *keyboard = (pepper_keyboard_t *)data; + + xkb_info = pepper_keyboard_get_xkb_info(keyboard); + if (xkb_info) + pepper_xkb_update_keyboard_modifier(xkb_info, keyboard, event); +} + +static void +_pepper_xkb_handle_keymap_update(pepper_event_listener_t *listener, + pepper_object_t *object, uint32_t id, void *info, void *data) +{ + pepper_xkb_info_t *cur_xkb_info = NULL; + pepper_xkb_info_t *pending_xkb_info = NULL; + pepper_keyboard_t *keyboard = (pepper_keyboard_t *)info; + + PEPPER_CHECK(id == PEPPER_EVENT_KEYBOARD_KEYMAP_UPDATE, return, "%d event will not be handled.\n", id); + PEPPER_CHECK(info, return, "Invalid event\n"); + PEPPER_CHECK(data, return, "Invalid data.\n"); + + pending_xkb_info = pepper_keyboard_get_pending_xkb_info(keyboard); + + if (!pending_xkb_info) + { + PEPPER_ERROR("Pending xkb_info of a pepper keyboard is invalid !\n"); + return; + } + + /* destroy existing xkb information */ + cur_xkb_info = pepper_keyboard_get_xkb_info(keyboard); + + if (cur_xkb_info) + pepper_xkb_info_destroy(cur_xkb_info); + + /* update xkb information with pending xkb information */ + pepper_keyboard_set_xkb_info(keyboard, pending_xkb_info); + pepper_keyboard_set_pending_xkb_info(keyboard, NULL); +} + +static pepper_xkb_info_t * +pepper_xkb_create_with_names(pepper_xkb_rule_names_t *names) +{ + pepper_xkb_info_t *info = NULL; + + info = calloc(1, sizeof(struct pepper_xkb_info)); + + if (!info) + return NULL; + + info->context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!info->context) + goto err; + + info->keymap = pepper_xkb_keymap_create(info->context, names); + if (!info->keymap) + goto err; + + info->state = xkb_state_new(info->keymap); + if (!info->state) + goto err; + + return info; + +err: + xkb_keymap_unref(info->keymap); + xkb_state_unref(info->state); + xkb_context_unref(info->context); + free(info); + + return NULL; +} + +static pepper_xkb_info_t * +pepper_xkb_info_create_with_names(pepper_xkb_rule_names_t *names) +{ + pepper_xkb_rule_names_t *xkb_names = NULL; + pepper_xkb_rule_names_t default_names = { 0, }; + + if (names) + xkb_names = names; + else + { + /* set default names */ + default_names.rules = "evdev"; + default_names.model = "pc105"; + default_names.layout = "us"; + default_names.variant = NULL; + default_names.options = NULL; + + xkb_names = &default_names; + } + + return pepper_xkb_create_with_names(xkb_names); +} + +static void +pepper_xkb_set_keyboard(pepper_xkb_t *xkb, pepper_xkb_info_t *info, + pepper_keyboard_t * keyboard) +{ + struct xkb_keymap *keymap; + char *keymap_str = NULL; + int keymap_fd = -1; + uint32_t keymap_len; + char *keymap_map = NULL; + + uint32_t depressed = 0; + uint32_t latched = 0; + uint32_t locked = 0; + uint32_t group = 0; + + if (!xkb || !info || !keyboard) + return; + + keymap = xkb_state_get_keymap(info->state); + if (!keymap) + return; + + keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); + if (!keymap_str) + goto err; + + keymap_len = strlen(keymap_str) + 1; + keymap_fd = pepper_create_anonymous_file(keymap_len); + if (keymap_fd < 0) + goto err; + + keymap_map = mmap(NULL, keymap_len, PROT_READ | PROT_WRITE, + MAP_SHARED, keymap_fd, 0); + if (!keymap_map) + goto err; + + xkb->listener_key = pepper_object_add_event_listener((pepper_object_t *)keyboard, + PEPPER_EVENT_KEYBOARD_KEY, 0, + _pepper_xkb_handle_keyboard_key, keyboard); + + xkb->listener_keymap_update = pepper_object_add_event_listener((pepper_object_t *)keyboard, + PEPPER_EVENT_KEYBOARD_KEYMAP_UPDATE, 0, + _pepper_xkb_handle_keymap_update, keyboard); + + strncpy(keymap_map, keymap_str, keymap_len); + pepper_keyboard_set_keymap_info(keyboard, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + keymap_fd, keymap_len); + + pepper_xkb_get_modifier(info, &depressed, &latched, &locked, &group); + pepper_keyboard_set_modifiers(keyboard, depressed, latched, locked, + group); + + err: + if (keymap_str) + free(keymap_str); + + if (keymap_map) + munmap(keymap_map, keymap_len); + + if (keymap_fd >= 0) + close(keymap_fd); + + return; +} + +PEPPER_API void +pepper_xkb_keyboard_set_keymap(pepper_xkb_t *xkb, + pepper_keyboard_t *keyboard, + pepper_xkb_rule_names_t *names) +{ + pepper_xkb_info_t *pending_xkb_info = NULL; + + /* destroy existing pending xkb info */ + pending_xkb_info = pepper_keyboard_get_pending_xkb_info(keyboard); + + if (pending_xkb_info) + pepper_xkb_info_destroy(pending_xkb_info); + + /* create a new xkb info with given xkb rule names */ + pending_xkb_info = pepper_xkb_info_create_with_names(names); + pepper_keyboard_set_pending_xkb_info(keyboard, pending_xkb_info); + pepper_xkb_set_keyboard(xkb, pending_xkb_info, keyboard); +} + +PEPPER_API pepper_xkb_t * +pepper_xkb_create() +{ + pepper_xkb_t *xkb = NULL; + + xkb = calloc(1, sizeof(pepper_xkb_t)); + PEPPER_CHECK(xkb, return NULL, "[%s] Failed to allocate memory for pepper xkb...\n", __FUNCTION__); + + return xkb; +} + +PEPPER_API void +pepper_xkb_destroy(pepper_xkb_t *xkb) +{ + if (!xkb) + return; + + if (xkb->info) + { + pepper_xkb_info_destroy(xkb->info); + xkb->info = NULL; + } + + if (xkb->listener_key) + pepper_event_listener_remove(xkb->listener_key); + + if (xkb->listener_keymap_update) + pepper_event_listener_remove(xkb->listener_keymap_update); + + free(xkb); +} +