From eb957b75c0071db42967db0a5fa59170bdb0757c Mon Sep 17 00:00:00 2001 From: Robert Tari Date: Tue, 1 Mar 2022 03:48:30 +0100 Subject: Read layout information using libxkbcommon --- CMakeLists.txt | 2 +- src/keyboard-x11.c | 100 ++++++++++++++++++++++++++--------------------------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93671367..0f888526 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ add_definitions (-DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" -DLOCALEDIR="${CMAKE_INS find_package (PkgConfig REQUIRED) include (CheckIncludeFile) include (FindPkgConfig) -pkg_check_modules(SERVICE_DEPS REQUIRED glib-2.0>=2.36 gio-2.0>=2.36 libayatana-common>=0.9.3) +pkg_check_modules(SERVICE_DEPS REQUIRED glib-2.0>=2.36 gio-2.0>=2.36 libayatana-common>=0.9.3 xkbcommon>=1.0.3 xkbregistry>=1.0.3) pkg_check_modules(X11_DEPS REQUIRED x11>=1.6.7 libxklavier>=5.4) include_directories (SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS}) diff --git a/src/keyboard-x11.c b/src/keyboard-x11.c index 11c6d93f..f276f344 100644 --- a/src/keyboard-x11.c +++ b/src/keyboard-x11.c @@ -1,5 +1,5 @@ /* - * Copyright 2021 Robert Tari + * Copyright 2021-2022 Robert Tari * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -15,6 +15,7 @@ */ #include +#include #include #include "languages.h" #include "keyboard.h" @@ -38,6 +39,7 @@ struct _KeyboardPrivate guint nLayout; gint nXkbEventType; XklConfigRec *pConfigRec; + GSList *lLayoutRec; }; typedef KeyboardPrivate priv_t; @@ -52,14 +54,6 @@ typedef struct _Layout } Layout; -typedef struct _LayoutParser -{ - const gchar *sLayout; - const gchar *sLanguage; - Keyboard *pKeyboard; - -} LayoutParser; - typedef struct _Source { GSource cSource; @@ -158,37 +152,6 @@ static void freeLayout(gpointer pData) g_slice_free(Layout, pLayout); } -static void onParseLayouts(XklConfigRegistry *pRegistry, const XklConfigItem * pItem, gpointer pData) -{ - LayoutParser *pLayoutParser = (LayoutParser*)pData; - Layout *pLayout = g_slice_new0(Layout); - - if (pLayoutParser->sLayout) - { - pLayout->sId = g_strjoin("+", pLayoutParser->sLayout, pItem->name, NULL); - pLayout->sLanguage = g_strdup(lookupLanguage(pLayout->sId)); - pLayout->sDescription = g_strdup(pItem->description); - } - else - { - pLayout->sId = g_strdup(pItem->name); - pLayout->sLanguage = g_strdup(lookupLanguage(pLayout->sId)); - pLayout->sDescription = g_strdup(pItem->description); - } - - g_hash_table_replace(pLayoutParser->pKeyboard->pPrivate->lLayouts, pLayout->sId, pLayout); - - if (pLayoutParser->sLayout == NULL) - { - LayoutParser cLayoutParser; - cLayoutParser.sLayout = pItem->name; - cLayoutParser.pKeyboard = pLayoutParser->pKeyboard; - cLayoutParser.sLanguage = lookupLanguage(cLayoutParser.sLayout); - - xkl_config_registry_foreach_layout_variant(pRegistry, pItem->name, onParseLayouts, &cLayoutParser); - } -} - void keyboard_AddSource(Keyboard *pKeyboard) { XkbQueryExtension(pKeyboard->pPrivate->pDisplay, 0, &pKeyboard->pPrivate->nXkbEventType, 0, 0, 0); @@ -292,6 +255,52 @@ Keyboard* keyboard_new() static void keyboard_init(Keyboard *self) { self->pPrivate = keyboard_get_instance_private(self); + self->pPrivate->lLayouts = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, freeLayout); + + // Read all available layouts + struct rxkb_context *pContext = rxkb_context_new(RXKB_CONTEXT_LOAD_EXOTIC_RULES); + g_assert(pContext); + + if (!rxkb_context_include_path_append_default(pContext)) + { + g_warning("Failed to include default paths"); + } + + if (!rxkb_context_parse(pContext, "evdev")) + { + g_warning("Failed to parse XKB descriptions"); + } + + struct rxkb_layout *pRxkbLayout = rxkb_layout_first(pContext); + + while (pRxkbLayout != NULL) + { + const gchar *sLayout = rxkb_layout_get_name(pRxkbLayout); + const gchar *sVariant = rxkb_layout_get_variant(pRxkbLayout); + const gchar *sDescription = rxkb_layout_get_description(pRxkbLayout); + + Layout *pLayout = g_slice_new0(Layout); + + if (sVariant != NULL && strlen(sVariant) > 0) + { + pLayout->sId = g_strjoin("+", sLayout, sVariant, NULL); + pLayout->sLanguage = g_strdup(lookupLanguage(pLayout->sId)); + pLayout->sDescription = g_strdup(sDescription); + } + else + { + pLayout->sId = g_strdup(sLayout); + pLayout->sLanguage = g_strdup(lookupLanguage(pLayout->sId)); + pLayout->sDescription = g_strdup(sDescription); + } + + g_hash_table_replace(self->pPrivate->lLayouts, pLayout->sId, pLayout); + + pRxkbLayout = rxkb_layout_next(pRxkbLayout); + } + + rxkb_context_unref(pContext); + self->pPrivate->pDisplay = XOpenDisplay(NULL); g_assert(self->pPrivate->pDisplay); @@ -300,18 +309,7 @@ static void keyboard_init(Keyboard *self) g_assert(self->pPrivate->pEngine); - self->pPrivate->lLayouts = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, freeLayout); - XklConfigRegistry *pRegistry = xkl_config_registry_get_instance(self->pPrivate->pEngine); - xkl_config_registry_load(pRegistry, TRUE); - - LayoutParser cLayoutParser; - cLayoutParser.sLayout = NULL; - cLayoutParser.pKeyboard = self; - cLayoutParser.sLanguage = NULL; - xkl_config_registry_foreach_layout(pRegistry, onParseLayouts, &cLayoutParser); - xkl_engine_start_listen(self->pPrivate->pEngine, XKLL_TRACK_KEYBOARD_STATE); - self->pPrivate->pConfigRec = xkl_config_rec_new(); xkl_config_rec_get_from_server(self->pPrivate->pConfigRec, self->pPrivate->pEngine); XklState *pState = xkl_engine_get_current_state(self->pPrivate->pEngine); -- cgit v1.2.3 From aed21256148273068856ffa49e8587cdd88dbcd9 Mon Sep 17 00:00:00 2001 From: Robert Tari Date: Tue, 1 Mar 2022 03:51:36 +0100 Subject: debian/control: Add libxkbcommon build dependency --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index 2f401e8f..4fb0a703 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,8 @@ Build-Depends: cmake, libx11-dev (>=1.7.0), libxklavier-dev (>=5.4), libayatana-common-dev (>= 0.9.3), + libxkbcommon-dev (>=1.0.3), + libxkbregistry-dev (>=1.0.3), # for packaging debhelper (>= 10), dh-systemd | hello, -- cgit v1.2.3 From 801486c23db43749761843c277b83a523c1e8e89 Mon Sep 17 00:00:00 2001 From: Robert Tari Date: Tue, 1 Mar 2022 03:55:34 +0100 Subject: .build.yml: Add libxkbcommon build dependency --- .build.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/.build.yml b/.build.yml index 14243060..193bb849 100644 --- a/.build.yml +++ b/.build.yml @@ -16,6 +16,7 @@ requires: - glib2 - libx11 - libxklavier + - libxkbcommon # - libayatana-common debian: @@ -31,6 +32,8 @@ requires: - libglib2.0-dev - libx11-dev - libxklavier-dev + - libxkbcommon-dev + - libxkbregistry-dev - systemd # - libayatana-common-dev # For building libayatana-common: @@ -49,6 +52,21 @@ requires: - libxklavier-dev - systemd # - libayatana-common-dev +# - libxkbcommon-dev +# - libxkbregistry-dev +# For building libxkbcommon: + - meson + - pkg-config + - bison + - libxcb-xkb-dev + - libxml2-dev + - wayland-protocols + - libwayland-dev + - doxygen + - x11proto-dev + - xvfb + - flex + - graphviz variables: - 'CHECKERS=" @@ -83,6 +101,19 @@ before_scripts: - make install - cd - - rm -Rf libayatana-common-build/ + - + - if [ ${DISTRO_NAME} == "ubuntu" ]; then + - cd ${START_DIR} + - if [ ! -d libxkbcommon-build ]; then + - git clone --depth 1 https://github.com/xkbcommon/libxkbcommon.git libxkbcommon-build + - fi + - cd libxkbcommon-build + - meson setup build -Dprefix=/usr -Dlibdir=/usr/lib/x86_64-linux-gnu + - ninja -C build + - ninja -C build install + - cd - + - rm -Rf libxkbcommon-build/ + - fi build_scripts: - if [ ${DISTRO_NAME} == "debian" ];then -- cgit v1.2.3