From d2758a873a848fc4113a4087d53446f73c6543cb Mon Sep 17 00:00:00 2001 From: Robert Tari Date: Tue, 7 Sep 2021 01:25:17 +0200 Subject: Split X11 and Lomiri backends - CMakeLists.txt: Add separate dependencies for the X11 backend - src/keyboard.c: Fork into keyboard-x11.c and keyboard-lomiri.c - src/CMakeLists.txt: Build backend libraries - src/keyboard-lomiri.c: Add some mock defaults for Lomiri - src/service.c: Load appropriate backend during runtime - data/org.ayatana.indicator.keyboard: Move icon to leftmost position --- src/keyboard.c | 319 --------------------------------------------------------- 1 file changed, 319 deletions(-) delete mode 100644 src/keyboard.c (limited to 'src/keyboard.c') diff --git a/src/keyboard.c b/src/keyboard.c deleted file mode 100644 index 11c6d93f..00000000 --- a/src/keyboard.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2021 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 - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include -#include -#include "languages.h" -#include "keyboard.h" - -enum -{ - LAYOUT_CHANGED, - CONFIG_CHANGED, - LAST_SIGNAL -}; - -static guint m_lSignals[LAST_SIGNAL]; - -struct _KeyboardPrivate -{ - GPollFD cPollFD; - GSourceFuncs cSourceFuncs; - XklEngine *pEngine; - GHashTable *lLayouts; - Display *pDisplay; - guint nLayout; - gint nXkbEventType; - XklConfigRec *pConfigRec; -}; - -typedef KeyboardPrivate priv_t; - -G_DEFINE_TYPE_WITH_PRIVATE(Keyboard, keyboard, G_TYPE_OBJECT) - -typedef struct _Layout -{ - gchar *sId; - gchar *sLanguage; - gchar *sDescription; - -} Layout; - -typedef struct _LayoutParser -{ - const gchar *sLayout; - const gchar *sLanguage; - Keyboard *pKeyboard; - -} LayoutParser; - -typedef struct _Source -{ - GSource cSource; - Keyboard *pKeyboard; - -} Source; - -static gboolean onCheckEvent(Display *pDisplay, XEvent *pEvent, XPointer pData) -{ - gint *pXkbEventType = (gint*)pData; - - if (pEvent->type == *pXkbEventType) - { - XkbEvent *pXkbEvent = (XkbEvent*)pEvent; - - if (pXkbEvent->any.xkb_type == XkbStateNotify || pXkbEvent->any.xkb_type == XkbNamesNotify) - { - return TRUE; - } - } - - return FALSE; -} - -static gboolean onCheckSource(GSource *pSource) -{ - Keyboard *pKeyboard = ((Source*)pSource)->pKeyboard; - XEvent cEvent; - gboolean bEvent = XCheckIfEvent(pKeyboard->pPrivate->pDisplay, &cEvent, onCheckEvent, (XPointer)&pKeyboard->pPrivate->nXkbEventType); - - if (bEvent) - { - XklConfigRec *pConfigRec = xkl_config_rec_new(); - xkl_config_rec_get_from_server(pConfigRec, pKeyboard->pPrivate->pEngine); - gboolean bConfigChanged = FALSE; - gboolean bLayoutChanged = FALSE; - - if (!xkl_config_rec_equals(pKeyboard->pPrivate->pConfigRec, pConfigRec)) - { - gboolean bBadSignal = FALSE; - - if (g_strv_length(pKeyboard->pPrivate->pConfigRec->layouts) > g_strv_length(pConfigRec->layouts)) - { - // Pairing a Bluetooth device does this sometimes - if (pConfigRec->variants[0] == NULL) - { - bBadSignal = TRUE; - } - else - { - xkl_engine_lock_group(pKeyboard->pPrivate->pEngine, 0); - pKeyboard->pPrivate->nLayout = 0; - bLayoutChanged = TRUE; - } - } - - if (!bBadSignal) - { - xkl_config_rec_get_from_server(pKeyboard->pPrivate->pConfigRec, pKeyboard->pPrivate->pEngine); - bConfigChanged = TRUE; - } - } - - g_object_unref(pConfigRec); - pConfigRec = NULL; - - if (((XkbEvent*)&cEvent)->any.xkb_type == XkbStateNotify && !bConfigChanged && ((XkbEvent*)&cEvent)->state.group != pKeyboard->pPrivate->nLayout && ((XkbEvent*)&cEvent)->state.group < g_strv_length(pKeyboard->pPrivate->pConfigRec->layouts)) - { - pKeyboard->pPrivate->nLayout = ((XkbEvent*)&cEvent)->state.group; - bLayoutChanged = TRUE; - } - - if (bLayoutChanged) - { - g_signal_emit(pKeyboard, m_lSignals[LAYOUT_CHANGED], 0); - } - - if (bConfigChanged) - { - g_signal_emit(pKeyboard, m_lSignals[CONFIG_CHANGED], 0); - } - } - - return FALSE; -} - -static void freeLayout(gpointer pData) -{ - Layout *pLayout = pData; - - g_return_if_fail(pLayout != NULL); - - g_free(pLayout->sId); - g_free(pLayout->sLanguage); - g_free(pLayout->sDescription); - 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); - XkbSelectEventDetails(pKeyboard->pPrivate->pDisplay, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask); - - pKeyboard->pPrivate->cPollFD.fd = ConnectionNumber(pKeyboard->pPrivate->pDisplay); - pKeyboard->pPrivate->cPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR; - pKeyboard->pPrivate->cPollFD.revents = 0; - pKeyboard->pPrivate->cSourceFuncs.prepare = NULL; - pKeyboard->pPrivate->cSourceFuncs.check = onCheckSource; - pKeyboard->pPrivate->cSourceFuncs.dispatch = NULL; - pKeyboard->pPrivate->cSourceFuncs.finalize = NULL; - - GSource *pSource = g_source_new(&pKeyboard->pPrivate->cSourceFuncs, sizeof(Source)); - ((Source*)pSource)->pKeyboard = pKeyboard; - g_source_add_poll(pSource, &pKeyboard->pPrivate->cPollFD); - g_source_attach(pSource, NULL); -} - -guint keyboard_GetNumLayouts(Keyboard *pKeyboard) -{ - return g_strv_length(pKeyboard->pPrivate->pConfigRec->layouts); -} - -void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription) -{ - if (nLayout == -1) - { - nLayout = pKeyboard->pPrivate->nLayout; - } - - gchar *sLayout = pKeyboard->pPrivate->pConfigRec->layouts[nLayout]; - gchar *sVariant = pKeyboard->pPrivate->pConfigRec->variants[nLayout]; - gchar *sId; - - if (sVariant && strlen(sVariant)) - { - sId = g_strconcat(sLayout, "+", sVariant, NULL); - } - else - { - sId = g_strdup(sLayout); - } - - const Layout *pLayout; - g_hash_table_lookup_extended(pKeyboard->pPrivate->lLayouts, sId, NULL, (gpointer*)&pLayout); - - if (pLanguage != NULL) - { - *pLanguage = g_strdup(pLayout->sLanguage); - } - - if (pDescription != NULL) - { - *pDescription = g_strdup(pLayout->sDescription); - } - - g_free(sId); -} - -void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout) -{ - xkl_engine_lock_group(pKeyboard->pPrivate->pEngine, nLayout); - pKeyboard->pPrivate->nLayout = nLayout; - g_signal_emit(pKeyboard, m_lSignals[LAYOUT_CHANGED], 0); -} - -static void onDispose(GObject *pObject) -{ - Keyboard *self = G_KEYBOARD(pObject); - - if (self->pPrivate->lLayouts) - { - g_hash_table_destroy(self->pPrivate->lLayouts); - } - - if (self->pPrivate->pConfigRec) - { - g_object_unref(self->pPrivate->pConfigRec); - self->pPrivate->pConfigRec = NULL; - } - - G_OBJECT_CLASS(keyboard_parent_class)->dispose(pObject); -} - -static void keyboard_class_init(KeyboardClass *klass) -{ - GObjectClass *pClass = G_OBJECT_CLASS(klass); - pClass->dispose = onDispose; - m_lSignals[LAYOUT_CHANGED] = g_signal_new(KEYBOARD_LAYOUT_CHANGED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - m_lSignals[CONFIG_CHANGED] = g_signal_new(KEYBOARD_CONFIG_CHANGED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); -} - -Keyboard* keyboard_new() -{ - GObject *pObject = g_object_new(G_TYPE_KEYBOARD, NULL); - - return G_KEYBOARD(pObject); -} - -static void keyboard_init(Keyboard *self) -{ - self->pPrivate = keyboard_get_instance_private(self); - self->pPrivate->pDisplay = XOpenDisplay(NULL); - - g_assert(self->pPrivate->pDisplay); - - self->pPrivate->pEngine = xkl_engine_get_instance(self->pPrivate->pDisplay); - - 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); - self->pPrivate->nLayout = pState->group; -} -- cgit v1.2.3