aboutsummaryrefslogtreecommitdiff
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorRobert Tari <robert@tari.in>2021-09-07 01:25:17 +0200
committerRobert Tari <robert@tari.in>2021-09-13 22:30:14 +0200
commitd2758a873a848fc4113a4087d53446f73c6543cb (patch)
tree945d183caf2c627ef353d662536f712d29dd5c38 /src/keyboard.c
parentd42da41264e8e7a8939068791e9bb5038bdaf649 (diff)
downloadayatana-indicator-keyboard-d2758a873a848fc4113a4087d53446f73c6543cb.tar.gz
ayatana-indicator-keyboard-d2758a873a848fc4113a4087d53446f73c6543cb.tar.bz2
ayatana-indicator-keyboard-d2758a873a848fc4113a4087d53446f73c6543cb.zip
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
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c319
1 files changed, 0 insertions, 319 deletions
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 <robert@tari.in>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <X11/XKBlib.h>
-#include <libxklavier/xklavier.h>
-#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;
-}