diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | data/org.ayatana.indicator.keyboard | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 40 | ||||
-rw-r--r-- | src/keyboard-lomiri.c | 93 | ||||
-rw-r--r-- | src/keyboard-x11.c (renamed from src/keyboard.c) | 0 | ||||
-rw-r--r-- | src/keyboard.h | 2 | ||||
-rw-r--r-- | src/languages.h | 2 | ||||
-rw-r--r-- | src/service.c | 56 |
8 files changed, 171 insertions, 27 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a9053180..de69c452 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,8 @@ 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 x11>=1.6.7 libxklavier>=5.4 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) +pkg_check_modules(X11_DEPS REQUIRED x11>=1.6.7 libxklavier>=5.4) include_directories (SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS}) # custom targets diff --git a/data/org.ayatana.indicator.keyboard b/data/org.ayatana.indicator.keyboard index 0af4084a..30e235d3 100644 --- a/data/org.ayatana.indicator.keyboard +++ b/data/org.ayatana.indicator.keyboard @@ -5,7 +5,7 @@ Position=-10 [phone] ObjectPath=/org/ayatana/indicator/keyboard/phone -Position=25 +Position=1000 [desktop] ObjectPath=/org/ayatana/indicator/keyboard/desktop diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6efa4677..e4ca3439 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,28 +1,30 @@ -cmake_minimum_required(VERSION 2.8.12) -set (SERVICE_LIB "ayatanaindicatorkeyboardservice") -set (SERVICE_EXEC "ayatana-indicator-keyboard-service") +cmake_minimum_required(VERSION 3.13) -add_definitions(-DG_LOG_DOMAIN="ayatana-indicator-keyboard") +# libayatana-keyboard-backend-x11.so -# handwritten sources -set(SERVICE_MANUAL_SOURCES keyboard.c service.c) +add_library("ayatana-keyboard-x11" SHARED keyboard-x11.c) +target_link_libraries("ayatana-keyboard-x11" ${SERVICE_DEPS_LIBRARIES} ${X11_DEPS_LIBRARIES}) +set_target_properties("ayatana-keyboard-x11" PROPERTIES VERSION 0.0.0 SOVERSION 0) +install(TARGETS "ayatana-keyboard-x11" DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) -# generated sources -set(SERVICE_GENERATED_SOURCES) +# libayatana-keyboard-backend-lomiri.so -# add the bin dir to our include path so the code can find the generated header files -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_library("ayatana-keyboard-lomiri" SHARED keyboard-lomiri.c) +target_link_libraries("ayatana-keyboard-lomiri" ${SERVICE_DEPS_LIBRARIES}) +set_target_properties("ayatana-keyboard-lomiri" PROPERTIES VERSION 0.0.0 SOVERSION 0) +install(TARGETS "ayatana-keyboard-lomiri" DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) -# add warnings/coverage info on handwritten files but not the autogenerated ones... -set_source_files_properties(${SERVICE_MANUAL_SOURCES} PROPERTIES COMPILE_FLAGS "${C_WARNING_ARGS} -g -std=c99") +# libayatanaindicatorkeyboardservice.a -# the service library for tests to link against (basically, everything except main()) -add_library(${SERVICE_LIB} STATIC ${SERVICE_MANUAL_SOURCES} ${SERVICE_GENERATED_SOURCES}) +add_definitions(-DG_LOG_DOMAIN="ayatana-indicator-keyboard") +set_source_files_properties(service.c PROPERTIES COMPILE_FLAGS "-std=c99") +add_library("ayatanaindicatorkeyboardservice" STATIC service.c) include_directories(${CMAKE_SOURCE_DIR}) link_directories(${SERVICE_DEPS_LIBRARY_DIRS}) -# the executable: lib + main() -add_executable (${SERVICE_EXEC} main.c) -set_source_files_properties(${SERVICE_SOURCES} main.c PROPERTIES COMPILE_FLAGS "${C_WARNING_ARGS} -std=c99") -target_link_libraries (${SERVICE_EXEC} ${SERVICE_LIB} ${SERVICE_DEPS_LIBRARIES}) -install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) +# ayatana-indicator-keyboard-service + +add_executable("ayatana-indicator-keyboard-service" main.c) +set_source_files_properties(service.c main.c PROPERTIES COMPILE_FLAGS "-std=c99") +target_link_libraries("ayatana-indicator-keyboard-service" "ayatanaindicatorkeyboardservice" "${SERVICE_DEPS_LIBRARIES} -ldl") +install(TARGETS "ayatana-indicator-keyboard-service" RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") diff --git a/src/keyboard-lomiri.c b/src/keyboard-lomiri.c new file mode 100644 index 00000000..0ae0b4a2 --- /dev/null +++ b/src/keyboard-lomiri.c @@ -0,0 +1,93 @@ +/* + * 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 <glib-object.h> +#include "languages.h" +#include "keyboard.h" + +enum +{ + LAYOUT_CHANGED, + CONFIG_CHANGED, + LAST_SIGNAL +}; + +static guint m_lSignals[LAST_SIGNAL]; + +struct _KeyboardPrivate +{ + guint nLayout; +}; + +typedef KeyboardPrivate priv_t; + +G_DEFINE_TYPE_WITH_PRIVATE(Keyboard, keyboard, G_TYPE_OBJECT) + +void keyboard_AddSource(Keyboard *pKeyboard) +{ + return; +} + +guint keyboard_GetNumLayouts(Keyboard *pKeyboard) +{ + return 1; +} + +void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription) +{ + if (nLayout == -1) + { + nLayout = pKeyboard->pPrivate->nLayout; + } + + *pLanguage = g_strdup("En"); + + if (pDescription != NULL) + { + *pDescription = g_strdup("English"); + } +} + +void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout) +{ + g_signal_emit(pKeyboard, m_lSignals[LAYOUT_CHANGED], 0); +} + +static void onDispose(GObject *pObject) +{ + 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->nLayout = 0; +} diff --git a/src/keyboard.c b/src/keyboard-x11.c index 11c6d93f..11c6d93f 100644 --- a/src/keyboard.c +++ b/src/keyboard-x11.c diff --git a/src/keyboard.h b/src/keyboard.h index 24c4aa19..20ae9dac 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -17,6 +17,8 @@ #ifndef __KEYBOARD_H__ #define __KEYBOARD_H__ +#include <glib.h> + G_BEGIN_DECLS #define KEYBOARD_LAYOUT_CHANGED "layout-changed" diff --git a/src/languages.h b/src/languages.h index bd121000..f3c1a7ea 100644 --- a/src/languages.h +++ b/src/languages.h @@ -14,6 +14,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <glib.h> + gchar *LANGUAGES[] = { "Ap", //APL diff --git a/src/service.c b/src/service.c index afeed80f..ac94f0b5 100644 --- a/src/service.c +++ b/src/service.c @@ -17,12 +17,19 @@ #include <glib/gi18n.h> #include <gio/gio.h> #include <ayatana/common/utils.h> +#include <dlfcn.h> #include "service.h" #define BUS_NAME "org.ayatana.indicator.keyboard" #define BUS_PATH "/org/ayatana/indicator/keyboard" static guint m_nSignal = 0; +static void *m_pLibHandle = NULL; +static Keyboard* (*m_fnKeyboardNew)(); +static void (*m_fnKeyboardAddSource)(Keyboard *pKeyboard); +static guint (*m_fnKeyboardGetNumLayouts)(Keyboard *pKeyboard); +static void (*m_fnKeyboardGetLayout)(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription); +static void (*m_fnKeyboardSetLayout)(Keyboard *pKeyboard, gint nLayout); enum { @@ -81,7 +88,7 @@ static GVariant* createHeaderState(IndicatorKeyboardService *self) g_variant_builder_add(&cBuilder, "{sv}", "visible", g_variant_new_boolean(TRUE)); gchar *sLanguage; - keyboard_GetLayout(self->pPrivate->pKeyboard, -1, &sLanguage, NULL); + m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, -1, &sLanguage, NULL); gchar *sIcon = g_strconcat("ayatana-indicator-keyboard-", sLanguage, NULL); g_free(sLanguage); @@ -110,13 +117,13 @@ static GMenuModel* createDesktopLayoutSection(IndicatorKeyboardService *self, in { self->pPrivate->pLayoutSection = g_menu_new(); - guint nLayouts = keyboard_GetNumLayouts(self->pPrivate->pKeyboard); + guint nLayouts = m_fnKeyboardGetNumLayouts(self->pPrivate->pKeyboard); for (guint nLayout = 0; nLayout < nLayouts; nLayout++) { gchar *sLanguage; gchar *sDescription; - keyboard_GetLayout(self->pPrivate->pKeyboard, nLayout, &sLanguage, &sDescription); + m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, nLayout, &sLanguage, &sDescription); GMenuItem *pItem = g_menu_item_new(sDescription, NULL); g_free(sDescription); g_menu_item_set_action_and_target_value(pItem, "indicator.layout", g_variant_new_byte(nLayout)); @@ -251,7 +258,7 @@ static void onLayoutSelected(GSimpleAction *pAction, GVariant *pVariant, gpointe { IndicatorKeyboardService *self = INDICATOR_KEYBOARD_SERVICE(pData); const guint8 nLayout = g_variant_get_byte(pVariant); - keyboard_SetLayout(self->pPrivate->pKeyboard, nLayout); + m_fnKeyboardSetLayout(self->pPrivate->pKeyboard, nLayout); } static void onSettings(GSimpleAction *pAction, GVariant *pVariant, gpointer pUserData) @@ -387,14 +394,51 @@ static void onDispose(GObject *pObject) g_clear_object (&self->pPrivate->pActionGroup); g_clear_object (&self->pPrivate->pConnection); + if (m_pLibHandle) + { + dlclose(m_pLibHandle); + m_pLibHandle = NULL; + } + G_OBJECT_CLASS(indicator_keyboard_service_parent_class)->dispose(pObject); } static void indicator_keyboard_service_init(IndicatorKeyboardService *self) { + gchar *sLib = "libayatana-keyboard-x11.so"; + GFile *pFile = g_file_new_for_path("/usr/lib/maliit/plugins/liblomiri-keyboard-plugin.so"); + gboolean bExists = g_file_query_exists(pFile, NULL); + g_object_unref(pFile); + + if (bExists) + { + sLib = "libayatana-keyboard-lomiri.so"; + } + + m_pLibHandle = dlopen(sLib, RTLD_NOW); + + if (!m_pLibHandle) + { + g_error("%s", dlerror()); + } + + m_fnKeyboardNew = dlsym(m_pLibHandle, "keyboard_new"); + + gchar *sError = dlerror(); + + if (sError != NULL) + { + g_error("%s", sError); + } + + m_fnKeyboardAddSource = dlsym(m_pLibHandle, "keyboard_AddSource"); + m_fnKeyboardGetNumLayouts = dlsym(m_pLibHandle, "keyboard_GetNumLayouts"); + m_fnKeyboardGetLayout = dlsym(m_pLibHandle, "keyboard_GetLayout"); + m_fnKeyboardSetLayout = dlsym(m_pLibHandle, "keyboard_SetLayout"); + self->pPrivate = indicator_keyboard_service_get_instance_private(self); self->pPrivate->pCancellable = g_cancellable_new(); - self->pPrivate->pKeyboard = keyboard_new(); + self->pPrivate->pKeyboard = m_fnKeyboardNew(); g_signal_connect(self->pPrivate->pKeyboard, KEYBOARD_LAYOUT_CHANGED, G_CALLBACK(onLayoutChanged), self); g_signal_connect(self->pPrivate->pKeyboard, KEYBOARD_CONFIG_CHANGED, G_CALLBACK(onConfigChanged), self); initActions(self); @@ -424,5 +468,5 @@ IndicatorKeyboardService *indicator_keyboard_service_new() void indicator_keyboard_service_AddKeyboardSource(IndicatorKeyboardService *self) { - keyboard_AddSource(self->pPrivate->pKeyboard); + m_fnKeyboardAddSource(self->pPrivate->pKeyboard); } |