Skip to content

Commit

Permalink
Never crash when getting system layouts
Browse files Browse the repository at this point in the history
fixes #66
  • Loading branch information
tari01 committed Jul 18, 2024
1 parent 2da4c6e commit c158862
Show file tree
Hide file tree
Showing 2 changed files with 309 additions and 279 deletions.
289 changes: 151 additions & 138 deletions src/keyboard-lomiri.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,155 @@ static void onSourcesChanged (GSettings *pSettings, const gchar *sKey, gpointer
}
}

static void getSystemLayouts (gchar *sLocation, Keyboard *self)
{
gboolean bExists = g_file_test (sLocation, G_FILE_TEST_EXISTS);

if (!bExists)
{
return;
}

gchar *sFile = NULL;
GError *pError = NULL;
g_file_get_contents (sLocation, &sFile, NULL, &pError);

if (pError)
{
g_error_free (pError);

return;
}

GRegex *pRegex = NULL;
gboolean bDefaultLocation = g_str_equal (sLocation, "/etc/default/keyboard");

if (bDefaultLocation)
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *XKBLAYOUT *= *\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *XKBLAYOUT *= *\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}
else
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *Option +\"*XkbLayout\"* +\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *Option +\"*XkbLayout\"* +\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}

if (pError)
{
g_warning ("Panic: Failed to compile regex: %s", pError->message);
g_error_free (pError);
g_free(sFile);

return;
}

GMatchInfo *pMatchInfo = NULL;

#if GLIB_CHECK_VERSION(2, 73, 0)
gboolean bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo);
#else
gboolean bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo);
#endif

if (!bMatch)
{
g_regex_unref (pRegex);
g_free(sFile);

return;
}

gchar *sLayouts = g_match_info_fetch (pMatchInfo, 1);
GStrv lLayouts = g_strsplit (sLayouts, ",", -1);
g_free (sLayouts);
g_match_info_free (pMatchInfo);
g_regex_unref (pRegex);

if (bDefaultLocation)
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *XKBVARIANT *= *\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *XKBVARIANT *= *\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}
else
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *Option +\"*XkbVariant\"* +\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *Option +\"*XkbVariant\"* +\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}

if (pError)
{
g_warning ("Panic: Failed to compile regex: %s", pError->message);
g_error_free (pError);
g_free(sFile);

return;
}

#if GLIB_CHECK_VERSION(2, 73, 0)
bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo);
#else
bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo);
#endif

if (!bMatch)
{
g_regex_unref (pRegex);
g_free(sFile);

return;
}

gchar *sVariants = g_match_info_fetch (pMatchInfo, 1);
GStrv lVariants = g_strsplit (sVariants, ",", -1);
g_free (sVariants);
g_match_info_free (pMatchInfo);
g_regex_unref (pRegex);
g_free(sFile);
guint nLayouts = g_strv_length (lLayouts);

for (guint nLayout = 0; nLayout < nLayouts; nLayout++)
{
gchar *sId = NULL;
guint nVariantLength = 0;

if (lVariants && lVariants[nLayout])
{
nVariantLength = strlen (lVariants[nLayout]);
}

if (nVariantLength)
{
sId = g_strconcat (lLayouts[nLayout], "+", lVariants[nLayout], NULL);
}
else
{
sId = g_strdup (lLayouts[nLayout]);
}

self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId);
}

g_strfreev (lLayouts);
g_strfreev (lVariants);
}

static void keyboard_init(Keyboard *self)
{
self->pPrivate = keyboard_get_instance_private(self);
self->pPrivate->lLayoutRec = NULL;
self->pPrivate->lLayouts = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, freeLayout);

// Read all available layouts
Expand Down Expand Up @@ -446,152 +592,19 @@ static void keyboard_init(Keyboard *self)
else
{
// Get system layouts
gboolean bDefaultLocation = g_file_test ("/etc/default/keyboard", G_FILE_TEST_EXISTS);
gchar *sLocation = NULL;
getSystemLayouts ("/etc/default/keyboard", self);

if (bDefaultLocation)
{
sLocation = "/etc/default/keyboard";
}
else
if (!self->pPrivate->lLayoutRec)
{
sLocation = "/etc/X11/xorg.conf.d/00-keyboard.conf";
getSystemLayouts ("/etc/X11/xorg.conf.d/00-keyboard.conf", self);
}

gchar *sFile = NULL;
GError *pError = NULL;
g_file_get_contents (sLocation, &sFile, NULL, &pError);
GStrv lLayouts = NULL;
GStrv lVariants = NULL;

if (!pError)
if (!self->pPrivate->lLayoutRec)
{
GRegex *pRegex = NULL;

if (bDefaultLocation)
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *XKBLAYOUT *= *\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *XKBLAYOUT *= *\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}
else
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *Option +\"*XkbLayout\"* +\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *Option +\"*XkbLayout\"* +\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}

if (!pError)
{
GMatchInfo *pMatchInfo = NULL;

#if GLIB_CHECK_VERSION(2, 73, 0)
gboolean bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo);
#else
gboolean bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo);
#endif

if (bMatch)
{
gchar *sLayouts = g_match_info_fetch (pMatchInfo, 1);
lLayouts = g_strsplit (sLayouts, ",", -1);
g_free (sLayouts);
}
else
{
g_error ("PANIC: No system XkbLayout found");
}

g_match_info_free (pMatchInfo);
g_regex_unref (pRegex);
}
else
{
g_error ("PANIC: Failed to compile regex: %s", pError->message);
g_error_free (pError);
}

if (bDefaultLocation)
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *XKBVARIANT *= *\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *XKBVARIANT *= *\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}
else
{
#if GLIB_CHECK_VERSION(2, 73, 0)
pRegex = g_regex_new (" *Option +\"*XkbVariant\"* +\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError);
#else
pRegex = g_regex_new (" *Option +\"*XkbVariant\"* +\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError);
#endif
}

if (!pError)
{
GMatchInfo *pMatchInfo = NULL;

#if GLIB_CHECK_VERSION(2, 73, 0)
gboolean bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo);
#else
gboolean bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo);
#endif

if (bMatch)
{
gchar *sVariants = g_match_info_fetch (pMatchInfo, 1);
lVariants = g_strsplit (sVariants, ",", -1);
g_free (sVariants);
}

g_match_info_free (pMatchInfo);
g_regex_unref (pRegex);
}
else
{
g_error ("PANIC: Failed to compile regex: %s", pError->message);
g_error_free (pError);
}

g_free(sFile);
}
else
{
g_error ("PANIC: Failed to get %s contents: %s", sLocation, pError->message);
g_error_free (pError);
}

guint nLayouts = g_strv_length (lLayouts);

for (guint nLayout = 0; nLayout < nLayouts; nLayout++)
{
gchar *sId = NULL;
guint nVariantLength = 0;

if (lVariants && lVariants[nLayout])
{
nVariantLength = strlen (lVariants[nLayout]);
}

if (nVariantLength)
{
sId = g_strconcat (lLayouts[nLayout], "+", lVariants[nLayout], NULL);
}
else
{
sId = g_strdup (lLayouts[nLayout]);
}

gchar *sId = g_strdup ("us");
self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId);
}

g_strfreev (lLayouts);
g_strfreev (lVariants);
self->pPrivate->nLayout = 0;
//~ Get system layouts

Expand Down
Loading

0 comments on commit c158862

Please sign in to comment.