pepper & pepper-xkb : remove xkb dependency from pepper and add pepper-xkb 93/134493/4
authorSung-Jin Park <sj76.park@samsung.com>
Mon, 19 Jun 2017 02:32:22 +0000 (11:32 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Mon, 19 Jun 2017 07:23:54 +0000 (16:23 +0900)
Change-Id: I094529144338a2306c2fcc355c4de0d462818a51
Signed-off-by: Sung-Jin Park <sj76.park@samsung.com>
14 files changed:
Makefile.am
configure.ac
packaging/pepper.spec
pkgconfig/pepper-xkb.pc.in [new file with mode: 0644]
src/Makefile.am
src/lib/pepper/Makefile.am
src/lib/pepper/keyboard.c
src/lib/pepper/pepper-utils-xkb.h [deleted file]
src/lib/pepper/pepper-utils.h
src/lib/pepper/pepper.h
src/lib/xkb/Makefile.am [new file with mode: 0644]
src/lib/xkb/pepper-xkb.h [new file with mode: 0644]
src/lib/xkb/xkb-internal.h [new file with mode: 0644]
src/lib/xkb/xkb.c [new file with mode: 0644]

index 64f278cd4e39581c4d57e603501e4435a0e783e2..4eb2d30de5f2913619a53da79964a3853e968fa0 100644 (file)
@@ -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
index 3ffeafdce9b1ec7a34a4105a239301c92e5d278d..30a605486e7ac30aee2fdee5a931377e18368b87 100644 (file)
@@ -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
index b1b86eb13cae9b36efe3ba0562369fe48bad5324..056ffffe2729c2f3385bcd321d2cd369b341dcd5 100644 (file)
@@ -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 (file)
index 0000000..3b62b43
--- /dev/null
@@ -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
index b918f09d1d26629e2147477d2a16d859c3997206..89049d5dc1149423179be4b66e7163628eca7375 100644 (file)
@@ -2,6 +2,7 @@ SUBDIRS = lib/pepper        \
           lib/keyrouter      \
           lib/evdev         \
           lib/libinput      \
+          lib/xkb           \
           lib/desktop-shell \
           lib/render        \
           lib/drm           \
index 6606b06438433cc136056cb9cca078078acf4e83..858805a45ace0f368899a326849f0213d3f97429 100644 (file)
@@ -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
index 601a573a2800b4f8c371c9ca0fde8dd046c89bb2..e5caabcadb95404e02141e6b9cadbcc82375f331 100644 (file)
@@ -31,9 +31,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <stdio.h>
 
 #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 (file)
index 76711cc..0000000
+++ /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 <unistd.h>
-#include <sys/mman.h>
-#include <pepper.h>
-#include <pepper-utils.h>
-#include <xkbcommon/xkbcommon.h>
-
-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
index e6b60b1c6ead08a273949e7e2972e09e028218e5..07d9fafa6e88fb674d908b3a643e35d191017723 100644 (file)
@@ -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))
index 9bc52ed3126ee3eb02eddb31e326b6bfdfba7374..3d8484e50845e4e6353c011e0713f2d428a5b36d 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <time.h>
 #include <linux/input.h>
-#include <xkbcommon/xkbcommon.h>
 
 #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 (file)
index 0000000..d23cd87
--- /dev/null
@@ -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 (file)
index 0000000..5da997f
--- /dev/null
@@ -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 <pepper.h>
+#include <xkbcommon/xkbcommon.h>
+
+#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 (file)
index 0000000..6448cfb
--- /dev/null
@@ -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 <pepper-xkb.h>
+#include <xkbcommon/xkbcommon.h>
+
+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 (file)
index 0000000..5bb0a9c
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/mman.h>
+
+#include <pepper-utils.h>
+#include <xkb-internal.h>
+
+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);
+}
+