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
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
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"
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
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
%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
%description samples
This package includes samples files.
+
###### executing
%prep
%{_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
%{_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,-)
--- /dev/null
+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
lib/keyrouter \
lib/evdev \
lib/libinput \
+ lib/xkb \
lib/desktop-shell \
lib/render \
lib/drm \
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
#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)
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;
}
keyboard->need_update_keymap = 0;
-
- if (keyboard->pending.xkb_info) {
- keyboard->xkb_info = keyboard->pending.xkb_info;
- keyboard->pending.xkb_info = NULL;
- }
}
void
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,
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);
*
* 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
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;
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;
+}
+++ /dev/null
-/*
-* 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
#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))
#include <time.h>
#include <linux/input.h>
-#include <xkbcommon/xkbcommon.h>
#ifdef __cplusplus
extern "C" {
* - 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 {
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,
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,
--- /dev/null
+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
--- /dev/null
+/*
+* 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 */
--- /dev/null
+/*
+* 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 */
--- /dev/null
+/*
+* 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);
+}
+