diff options
Diffstat (limited to 'src/service.c')
-rw-r--r-- | src/service.c | 185 |
1 files changed, 161 insertions, 24 deletions
diff --git a/src/service.c b/src/service.c index f4b086cc..123308c9 100644 --- a/src/service.c +++ b/src/service.c @@ -25,14 +25,19 @@ #define ICON_DEFAULT "input-keyboard" +#define HWKBD FALSE +#define OSK TRUE + 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 guint (*m_fnKeyboardGetNumLayouts)(Keyboard *pKeyboard, gboolean bOSK); static guint (*m_fnKeyboardGetLayoutIndex)(Keyboard *pKeyboard); -static void (*m_fnKeyboardGetLayout)(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription, gchar **pId); -static void (*m_fnKeyboardSetLayout)(Keyboard *pKeyboard, gint nLayout); +static void (*m_fnKeyboardGetLayout)(Keyboard *pKeyboard, gboolean bOSK, gint nLayout, gchar **pLanguage, gchar **pDescription, gchar **pId); +static void (*m_fnKeyboardSetLayout)(Keyboard *pKeyboard, gint nLayout, gboolean bOSK); +static gboolean (*m_fnKeyboardHasHardwareKeyboard)(Keyboard *pKeyboard); +static gboolean (*m_fnKeyboardHasSoftwareKeyboard)(Keyboard *pKeyboard); enum { @@ -77,6 +82,7 @@ struct _IndicatorKeyboardServicePrivate GSimpleAction *pSettingsAction; GSimpleAction *pDisplayAction; GSimpleAction *pLayoutAction; + GSimpleAction *pOSKLayoutAction; GMenu *pLayoutSection; Keyboard *pKeyboard; GSettings *pSettings; @@ -120,8 +126,9 @@ static GVariant* createHeaderState(IndicatorKeyboardService *self, int nProfile) } else { + gboolean bHardwareKeyboard = m_fnKeyboardHasHardwareKeyboard (self->pPrivate->pKeyboard); gchar *sLanguage; - m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, -1, &sLanguage, NULL, NULL); + m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, self->pPrivate->bLomiri && !bHardwareKeyboard, -1, &sLanguage, NULL, NULL); gchar *sIcon = g_strconcat("ayatana-indicator-keyboard-", sLanguage, NULL); g_free(sLanguage); @@ -148,20 +155,67 @@ static GVariant* createHeaderState(IndicatorKeyboardService *self, int nProfile) return g_variant_builder_end(&cBuilder); } -static GMenuModel* createLayoutSection(IndicatorKeyboardService *self) +static GMenuModel* createLayoutSection(IndicatorKeyboardService *self, gboolean bOSK) { self->pPrivate->pLayoutSection = g_menu_new(); + gboolean bCreate = TRUE; + + if (self->pPrivate->bLomiri) + { + if (!bOSK) + { + gboolean bHardwareKeyboard = m_fnKeyboardHasHardwareKeyboard (self->pPrivate->pKeyboard); + + if (bHardwareKeyboard) + { + g_menu_append (self->pPrivate->pLayoutSection, _("External Keyboard"), NULL); + } + else + { + bCreate = FALSE; + } + } + else if (bOSK) + { + gboolean bSoftwareKeyboard = m_fnKeyboardHasSoftwareKeyboard (self->pPrivate->pKeyboard); + g_menu_append (self->pPrivate->pLayoutSection, _("On-Screen Keyboard"), NULL); + + if (!bSoftwareKeyboard) + { + bCreate = FALSE; + } + } + } + else if (bOSK) + { + bCreate = FALSE; + } + if (!bCreate) + { + return G_MENU_MODEL(self->pPrivate->pLayoutSection); + } - guint nLayouts = m_fnKeyboardGetNumLayouts(self->pPrivate->pKeyboard); + guint nLayouts = m_fnKeyboardGetNumLayouts(self->pPrivate->pKeyboard, bOSK); for (guint nLayout = 0; nLayout < nLayouts; nLayout++) { gchar *sLanguage; gchar *sDescription; - m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, nLayout, &sLanguage, &sDescription, NULL); + m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, bOSK, nLayout, &sLanguage, &sDescription, NULL); 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)); + gchar *sAction = NULL; + + if (bOSK) + { + sAction = "indicator.osklayout"; + } + else + { + sAction = "indicator.layout"; + } + + g_menu_item_set_action_and_target_value(pItem, sAction, g_variant_new_byte(nLayout)); g_menu_item_set_attribute_value(pItem, "x-ayatana-layout", g_variant_new_byte(nLayout)); gchar *sIcon = g_strconcat("ayatana-indicator-keyboard-", sLanguage, NULL); g_free(sLanguage); @@ -184,11 +238,12 @@ static GMenuModel* createLayoutSection(IndicatorKeyboardService *self) return G_MENU_MODEL(self->pPrivate->pLayoutSection); } -static GMenuModel* createSettingsSection(IndicatorKeyboardService *self) +static GMenuModel* createSettingsSection(IndicatorKeyboardService *self, gboolean bOSK) { GMenu * pMenu = g_menu_new(); + gboolean bUbuntuTouch = ayatana_common_utils_is_ubuntutouch (); - if (self->pPrivate->bLomiri && (!ayatana_common_utils_is_ubuntutouch())) + if (self->pPrivate->bLomiri && bOSK && !bUbuntuTouch) { GMenuItem *pItem = g_menu_item_new (_("Always show OSK"), "indicator.osk(true)"); g_menu_item_set_attribute (pItem, "x-ayatana-type", "s", "org.ayatana.indicator.switch"); @@ -196,7 +251,33 @@ static GMenuModel* createSettingsSection(IndicatorKeyboardService *self) g_object_unref (pItem); } - g_menu_append(pMenu, _("Keyboard Settingsā¦"), "indicator.settings"); + gchar *sAction = NULL; + + if (self->pPrivate->bLomiri) + { + if (!bOSK) + { + gboolean bHardwareKeyboard = m_fnKeyboardHasHardwareKeyboard (self->pPrivate->pKeyboard); + + if (bHardwareKeyboard) + { + sAction = "indicator.settings"; + } + } + else if (bOSK) + { + sAction = "indicator.osksettings"; + } + } + else if (!bOSK) + { + sAction = "indicator.settings"; + } + + if (sAction) + { + g_menu_append(pMenu, _("Keyboard Settingsā¦"), sAction); + } return G_MENU_MODEL(pMenu); } @@ -204,7 +285,22 @@ static GMenuModel* createSettingsSection(IndicatorKeyboardService *self) static GMenuModel* createDisplaySection (IndicatorKeyboardService *self) { GMenu * pMenu = g_menu_new (); - g_menu_append (pMenu, _("Show Current Layout"), "indicator.display"); + gboolean bDisplay = TRUE; + + if (self->pPrivate->bLomiri) + { + gboolean bHardwareKeyboard = m_fnKeyboardHasHardwareKeyboard (self->pPrivate->pKeyboard); + + if (!bHardwareKeyboard) + { + bDisplay = FALSE; + } + } + + if (bDisplay) + { + g_menu_append (pMenu, _("Show Current Layout"), "indicator.display"); + } return G_MENU_MODEL (pMenu); } @@ -236,9 +332,12 @@ static void rebuildNow(IndicatorKeyboardService *self, guint nSections) if (nSections & SECTION_LAYOUTS) { - rebuildSection(pInfoDesktop->pSubmenu, 0, createLayoutSection(self)); - rebuildSection(pInfoPhone->pSubmenu, 0, createLayoutSection(self)); - rebuildSection(pInfoGreeter->pSubmenu, 0, createLayoutSection(self)); + rebuildSection(pInfoDesktop->pSubmenu, 0, createLayoutSection(self, HWKBD)); + rebuildSection(pInfoDesktop->pSubmenu, 3, createLayoutSection(self, OSK)); + rebuildSection(pInfoPhone->pSubmenu, 0, createLayoutSection(self, HWKBD)); + rebuildSection(pInfoPhone->pSubmenu, 2, createLayoutSection(self, OSK)); + rebuildSection(pInfoGreeter->pSubmenu, 0, createLayoutSection(self, HWKBD)); + rebuildSection(pInfoGreeter->pSubmenu, 1, createLayoutSection(self, OSK)); } if (nSections & SECTION_DISPLAY) @@ -248,8 +347,10 @@ static void rebuildNow(IndicatorKeyboardService *self, guint nSections) if (nSections & SECTION_SETTINGS) { - rebuildSection(pInfoDesktop->pSubmenu, 2, createSettingsSection(self)); - rebuildSection(pInfoPhone->pSubmenu, 2, createSettingsSection(self)); + rebuildSection(pInfoDesktop->pSubmenu, 2, createSettingsSection(self, HWKBD)); + rebuildSection(pInfoDesktop->pSubmenu, 4, createSettingsSection(self, OSK)); + rebuildSection(pInfoPhone->pSubmenu, 1, createSettingsSection(self, HWKBD)); + rebuildSection(pInfoPhone->pSubmenu, 3, createSettingsSection(self, OSK)); } } @@ -267,18 +368,23 @@ static void createMenu(IndicatorKeyboardService *self, int nProfile) // Build the sections if (nProfile == PROFILE_PHONE) { - lSections[nSection++] = createLayoutSection(self); - lSections[nSection++] = createSettingsSection(self); + lSections[nSection++] = createLayoutSection(self, HWKBD); + lSections[nSection++] = createSettingsSection(self, HWKBD); + lSections[nSection++] = createLayoutSection(self, OSK); + lSections[nSection++] = createSettingsSection(self, OSK); } else if (nProfile == PROFILE_DESKTOP) { - lSections[nSection++] = createLayoutSection(self); + lSections[nSection++] = createLayoutSection(self, HWKBD); lSections[nSection++] = createDisplaySection(self); - lSections[nSection++] = createSettingsSection(self); + lSections[nSection++] = createSettingsSection(self, HWKBD); + lSections[nSection++] = createLayoutSection(self, OSK); + lSections[nSection++] = createSettingsSection(self, OSK); } else if (nProfile == PROFILE_GREETER) { - lSections[nSection++] = createLayoutSection(self); + lSections[nSection++] = createLayoutSection(self, HWKBD); + lSections[nSection++] = createLayoutSection(self, OSK); } // Add sections to the submenu @@ -323,7 +429,14 @@ static void onLayoutSelected(GSimpleAction *pAction, GVariant *pVariant, gpointe { IndicatorKeyboardService *self = INDICATOR_KEYBOARD_SERVICE(pData); const guint8 nLayout = g_variant_get_byte(pVariant); - m_fnKeyboardSetLayout(self->pPrivate->pKeyboard, nLayout); + m_fnKeyboardSetLayout(self->pPrivate->pKeyboard, nLayout, HWKBD); +} + +static void onOSKLayoutSelected (GSimpleAction *pAction, GVariant *pVariant, gpointer pData) +{ + IndicatorKeyboardService *self = INDICATOR_KEYBOARD_SERVICE (pData); + const guint8 nLayout = g_variant_get_byte (pVariant); + m_fnKeyboardSetLayout (self->pPrivate->pKeyboard, nLayout, OSK); } static void onSettings(GSimpleAction *pAction, GVariant *pVariant, gpointer pData) @@ -340,6 +453,11 @@ static void onSettings(GSimpleAction *pAction, GVariant *pVariant, gpointer pDat } } +static void onOSKSettings(GSimpleAction *pAction, GVariant *pVariant, gpointer pData) +{ + ayatana_common_utils_open_url ("settings:///system/sw-keyboard-layouts"); +} + static void onDisplay (GSimpleAction *pAction, GVariant *pVariant, gpointer pData) { IndicatorKeyboardService *self = INDICATOR_KEYBOARD_SERVICE (pData); @@ -358,7 +476,7 @@ static void onDisplay (GSimpleAction *pAction, GVariant *pVariant, gpointer pDat { sProgram = "tecla"; - m_fnKeyboardGetLayout (self->pPrivate->pKeyboard, -1, NULL, NULL, &sArgs); + m_fnKeyboardGetLayout (self->pPrivate->pKeyboard, HWKBD, -1, NULL, NULL, &sArgs); } else { @@ -403,6 +521,14 @@ static void initActions(IndicatorKeyboardService *self) self->pPrivate->pLayoutAction = pAction; g_signal_connect(pAction, "activate", G_CALLBACK(onLayoutSelected), self); + if (self->pPrivate->bLomiri) + { + pAction = g_simple_action_new("osklayout", G_VARIANT_TYPE_BYTE); + g_action_map_add_action(G_ACTION_MAP(self->pPrivate->pActionGroup), G_ACTION(pAction)); + self->pPrivate->pOSKLayoutAction = pAction; + g_signal_connect(pAction, "activate", G_CALLBACK(onOSKLayoutSelected), self); + } + if (self->pPrivate->bLomiri && (!ayatana_common_utils_is_ubuntutouch())) { gboolean bOsk = g_settings_get_boolean (self->pPrivate->pLomiriSettings, "always-show-osk"); @@ -418,6 +544,14 @@ static void initActions(IndicatorKeyboardService *self) self->pPrivate->pSettingsAction = pAction; g_signal_connect(pAction, "activate", G_CALLBACK(onSettings), self); + if (self->pPrivate->bLomiri) + { + pAction = g_simple_action_new ("osksettings", NULL); + g_action_map_add_action(G_ACTION_MAP (self->pPrivate->pActionGroup), G_ACTION (pAction)); + self->pPrivate->pSettingsAction = pAction; + g_signal_connect (pAction, "activate", G_CALLBACK (onOSKSettings), self); + } + pAction = g_simple_action_new ("display", NULL); g_action_map_add_action (G_ACTION_MAP (self->pPrivate->pActionGroup), G_ACTION (pAction)); self->pPrivate->pDisplayAction = pAction; @@ -534,6 +668,7 @@ static void onDispose(GObject *pObject) g_clear_object (&self->pPrivate->pSettingsAction); g_clear_object (&self->pPrivate->pDisplayAction); g_clear_object (&self->pPrivate->pLayoutAction); + g_clear_object (&self->pPrivate->pOSKLayoutAction); for (int nProfile = 0; nProfile < N_PROFILES; ++nProfile) { @@ -589,6 +724,8 @@ static void indicator_keyboard_service_init(IndicatorKeyboardService *self) m_fnKeyboardGetLayoutIndex = dlsym(m_pLibHandle, "keyboard_GetLayoutIndex"); m_fnKeyboardGetLayout = dlsym(m_pLibHandle, "keyboard_GetLayout"); m_fnKeyboardSetLayout = dlsym(m_pLibHandle, "keyboard_SetLayout"); + m_fnKeyboardHasHardwareKeyboard = dlsym(m_pLibHandle, "keyboard_hasHardwareKeyboard"); + m_fnKeyboardHasSoftwareKeyboard = dlsym(m_pLibHandle, "keyboard_hasSoftwareKeyboard"); self->pPrivate = indicator_keyboard_service_get_instance_private(self); self->pPrivate->bLomiri = bLomiri; self->pPrivate->pCancellable = g_cancellable_new(); |