--- /dev/null
+#include "DSXkb.h"
+#include "DSXkbPrivate.h"
+
+namespace display_server
+{
+
+DSXkbPrivate::DSXkbPrivate(DSXkb *p_ptr)
+ : DSObjectPrivate(p_ptr), __p_ptr(p_ptr),
+ __xkb_state(nullptr), __xkb_keymap(nullptr), __xkb_context(nullptr),
+ __depressed(0), __latched(0), __locked(0), __group(0)
+{
+}
+
+DSXkbPrivate::~DSXkbPrivate()
+{
+ xkb_state_unref(__xkb_state);
+ xkb_keymap_unref(__xkb_keymap);
+ xkb_context_unref(__xkb_context);
+}
+
+bool DSXkbPrivate::makeKeymap()
+{
+ DS_GET_PUB(DSXkb);
+
+ __xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ if (!__xkb_context)
+ {
+ DSLOG_ERR("DSXkb", "Failed to xkb_context_new()..\n");
+ return false;
+ }
+
+ struct ::xkb_rule_names names = { pub->__rules.c_str(), pub->__model.c_str(), pub->__layout.c_str(), pub->__variant.c_str(), pub->__options.c_str() };
+
+ __xkb_keymap = xkb_map_new_from_names(__xkb_context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!__xkb_keymap)
+ {
+ DSLOG_ERR("DSXkb", "Failed to xkb_map_new_from_names()..\n");
+ xkb_context_unref(__xkb_context);
+ return false;
+ }
+
+ __xkb_state = xkb_state_new(__xkb_keymap);
+ if (!__xkb_state)
+ {
+ DSLOG_ERR("DSXkb", "Failed to xkb_state_new()..\n");
+ xkb_keymap_unref(__xkb_keymap);
+ xkb_context_unref(__xkb_context);
+ return false;
+ }
+
+ return true;
+}
+
+void DSXkbPrivate::updateModifier(int keycode, bool pressed)
+{
+ enum xkb_key_direction direction;
+
+ if (pressed)
+ direction = XKB_KEY_DOWN;
+ else
+ direction = XKB_KEY_UP;
+
+ xkb_state_update_key(__xkb_state, keycode, direction);
+
+ __depressed = xkb_state_serialize_mods(__xkb_state, XKB_STATE_MODS_DEPRESSED);
+ __latched = xkb_state_serialize_mods(__xkb_state, XKB_STATE_MODS_LATCHED);
+ __locked = xkb_state_serialize_mods(__xkb_state, XKB_STATE_MODS_LOCKED);
+ __group = xkb_state_serialize_mods(__xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
+}
+
+uint32_t DSXkbPrivate::getModifierDePressed()
+{
+ return __depressed;
+}
+
+uint32_t DSXkbPrivate::getModifierLatched()
+{
+ return __latched;
+}
+
+uint32_t DSXkbPrivate::getModifierLocked()
+{
+ return __locked;
+}
+
+uint32_t DSXkbPrivate::getModifierGroup()
+{
+ return __group;
+}
+
+std::string DSXkbPrivate::getKeyname(int keycode)
+{
+ int nsyms;
+ const xkb_keysym_t *syms;
+ xkb_keysym_t sym = XKB_KEY_NoSymbol;
+ char key[256] = {0, };
+ std::string keyname;
+
+ nsyms = xkb_key_get_syms(__xkb_state, keycode, &syms);
+ if (nsyms == 1) sym = syms[0];
+
+ if (sym == XKB_KEY_NoSymbol)
+ {
+ snprintf(key, sizeof(key), "Keycode-%u", keycode);
+ }
+ else
+ {
+ /* get the keyname for this sym */
+ xkb_keysym_get_name(sym, key, sizeof(key));
+ }
+
+ if (key[0] == '\0')
+ {
+ snprintf(key, sizeof(key), "Keycode-%u", keycode);
+ }
+
+ keyname = key;
+ return keyname;
+}
+
+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;
+ }
+ }
+}
+
+int DSXkbPrivate::getKeycode(std::string keyname)
+{
+ xkb_keysym_t keysym = 0x0;
+ xkb_keycode_t keycode = 0;
+
+ if (keyname.compare("Keycode-") == 0)
+ {
+ keycode = std::stoi(keyname);
+ }
+ else
+ {
+ keysym = xkb_keysym_from_name(keyname.c_str(), XKB_KEYSYM_NO_FLAGS);
+ keycode_map found_keycodes = {0,};
+ found_keycodes.keysym = keysym;
+ xkb_keymap_key_for_each(__xkb_keymap, find_keycode, &found_keycodes);
+
+ keycode = found_keycodes.keycode;
+ }
+
+ return keycode;
+}
+
+
+DSXkb::DSXkb(DSSeat *seat)
+ : DS_INIT_PRIVATE_PTR(DSXkb),
+ __seat(seat),
+ __rules("evdev"), __model("pc105"), __layout("us"), __variant(""), __options("")
+{
+ DS_GET_PRIV(DSXkb);
+
+ priv->makeKeymap();
+}
+
+DSXkb::DSXkb(DSSeat *seat, std::string rules, std::string model, std::string layout, std::string variant, std::string options)
+ : DS_INIT_PRIVATE_PTR(DSXkb),
+ __seat(seat),
+ __rules(rules), __model(model), __layout(layout), __variant(variant), __options(options)
+{
+ DS_GET_PRIV(DSXkb);
+
+ priv->makeKeymap();
+}
+
+DSXkb::~DSXkb()
+{
+}
+
+void DSXkb::updateModifier(int keycode, bool pressed)
+{
+ DS_GET_PRIV(DSXkb);
+
+ priv->updateModifier(keycode, pressed);
+}
+
+uint32_t DSXkb::getModifierDePressed()
+{
+ DS_GET_PRIV(DSXkb);
+
+ return priv->getModifierDePressed();
+}
+
+uint32_t DSXkb::getModifierLatched()
+{
+ DS_GET_PRIV(DSXkb);
+
+ return priv->getModifierLatched();
+}
+
+uint32_t DSXkb::getModifierLocked()
+{
+ DS_GET_PRIV(DSXkb);
+
+ return priv->getModifierLocked();
+}
+
+uint32_t DSXkb::getModifierGroup()
+{
+ DS_GET_PRIV(DSXkb);
+
+ return priv->getModifierGroup();
+}
+
+std::string DSXkb::getKeyname(int keycode)
+{
+ DS_GET_PRIV(DSXkb);
+
+ return priv->getKeyname(keycode);
+}
+
+int DSXkb::getKeycode(std::string keyname)
+{
+ DS_GET_PRIV(DSXkb);
+
+ return priv->getKeycode(keyname);
+}
+
+} // namespace display_server
--- /dev/null
+#ifndef __DS_XKB_PRIVATE_H__
+#define __DS_XKB_PRIVATE_H__
+
+#include <DSCore.h>
+#include <DSSeat.h>
+#include "DSXkb.h"
+
+#include <xkbcommon/xkbcommon.h>
+
+namespace display_server
+{
+
+class DSXkbPrivate : public DSObjectPrivate
+{
+DS_PIMPL_USE_PUBLIC(DSXkb);
+public:
+ DSXkbPrivate() = delete;
+ DSXkbPrivate(DSXkb *p_ptr);
+ ~DSXkbPrivate();
+
+ bool makeKeymap();
+ void updateModifier(int keycode, bool pressed);
+ xkb_mod_mask_t getModifierDePressed();
+ xkb_mod_mask_t getModifierLatched();
+ xkb_mod_mask_t getModifierLocked();
+ xkb_mod_mask_t getModifierGroup();
+
+ std::string getKeyname(int keycode);
+ int getKeycode(std::string keyname);
+
+private:
+ struct ::xkb_state *__xkb_state;
+ struct ::xkb_keymap *__xkb_keymap;
+ struct ::xkb_context *__xkb_context;
+
+ xkb_mod_mask_t __depressed;
+ xkb_mod_mask_t __latched;
+ xkb_mod_mask_t __locked;
+ xkb_mod_mask_t __group;
+};
+
+}
+
+#endif
'DSClient/DSClientPrivate.h',
'DSClient/DSClient.h',
'DSClient/DSClient.cpp',
+ 'DSXkb/DSXkbPrivate.h',
+ 'DSXkb/DSXkb.h',
+ 'DSXkb/DSXkb.cpp',
]
libds_wayland_srcs = [
wayland_dep = dependency('wayland-server')
libinput_dep = dependency('libinput')
libudev_dep = dependency('libudev')
+xkbcommon_dep = dependency('xkbcommon')
tizen_ext_dep = dependency('tizen-extension-server')
xdg_shell_unstable_v6_dep = dependency('xdg-shell-unstable-v6-server')
'./DSWindowShell',
'./DSZone',
'./DSClient',
+ './DSXkb',
)
libds_lib = shared_library(
'ds',
libds_srcs,
- dependencies : [dlog_dep, libtdm_dep, wayland_dep, tizen_ext_deps, ecore_dep, ecore_evas_dep, libinput_dep, libudev_dep],
+ dependencies : [dlog_dep, libtdm_dep, wayland_dep, tizen_ext_deps, ecore_dep, ecore_evas_dep, libinput_dep, libudev_dep, xkbcommon_dep],
include_directories : [libds_include_dirs],
version : meson.project_version(),
install : true
libds_static_lib = static_library(
'ds',
libds_srcs,
- dependencies : [dlog_dep, libtdm_dep, wayland_dep, tizen_ext_deps, ecore_dep, ecore_evas_dep, libinput_dep, libudev_dep],
+ dependencies : [dlog_dep, libtdm_dep, wayland_dep, tizen_ext_deps, ecore_dep, ecore_evas_dep, libinput_dep, libudev_dep, xkbcommon_dep],
include_directories : [libds_include_dirs],
install : true
)
--- /dev/null
+#include "libds-tests.h"
+#include "DSXkb.h"
+
+using namespace display_server;
+
+class DSXkbTest : public ::testing::Test
+{
+public:
+ void SetUp(void) override
+ {}
+ void TearDown(void) override
+ {}
+};
+
+TEST_F(DSXkbTest, NewDSXkb)
+{
+ DSSeat *seat = new DSSeat;
+ DSXkb *xkb = new DSXkb(seat);
+ EXPECT_TRUE(xkb != nullptr);
+
+ delete xkb;
+ delete seat;
+}
+
+TEST_F(DSXkbTest, GetKeyname)
+{
+ DSSeat *seat = new DSSeat;
+ DSXkb *xkb = new DSXkb(seat);
+ EXPECT_TRUE(xkb != nullptr);
+
+ std::string keyname = xkb->getKeyname(166);
+
+ EXPECT_TRUE(!keyname.empty());
+
+ delete xkb;
+ delete seat;
+}
+
+TEST_F(DSXkbTest, GetKeycode)
+{
+ DSSeat *seat = new DSSeat;
+ DSXkb *xkb = new DSXkb(seat);
+ EXPECT_TRUE(xkb != nullptr);
+
+ int keycode = xkb->getKeycode("XF86Back");
+
+ EXPECT_TRUE(keycode > 8);
+
+ delete xkb;
+ delete seat;
+}