summaryrefslogtreecommitdiff
path: root/src/gui/core
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-11-09 01:49:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-11-09 01:49:49 (GMT)
commit2df715e74d6600ed0a5688a43f6ecd873957326a (patch)
treefeeb09b609a1fea8ae4441a83107767007ccba37 /src/gui/core
parente5808e7df6eb36ff8e150e57e8691a0b05222844 (diff)
Loaded GTK CSS extensions from files in a given theme directory.
Diffstat (limited to 'src/gui/core')
-rwxr-xr-xsrc/gui/core/Makefile.am3
-rw-r--r--src/gui/core/core.c8
-rw-r--r--src/gui/core/theme.c260
-rw-r--r--src/gui/core/theme.h39
4 files changed, 306 insertions, 4 deletions
diff --git a/src/gui/core/Makefile.am b/src/gui/core/Makefile.am
index 75b342f..85aaacf 100755
--- a/src/gui/core/Makefile.am
+++ b/src/gui/core/Makefile.am
@@ -4,7 +4,8 @@ noinst_LTLIBRARIES = libguicore.la
libguicore_la_SOURCES = \
core.h core.c \
global.h global.c \
- panels.h panels.c
+ panels.h panels.c \
+ theme.h theme.c
libguicore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS)
diff --git a/src/gui/core/core.c b/src/gui/core/core.c
index 4f84127..7d75167 100644
--- a/src/gui/core/core.c
+++ b/src/gui/core/core.c
@@ -27,6 +27,7 @@
#include "panels.h"
+#include "theme.h"
#include "../../core/params.h"
#include "../../glibext/linesegment.h"
@@ -48,13 +49,14 @@ bool load_all_gui_components(GObject *ref)
{
bool result; /* Bilan à retourner */
+ load_main_panels(ref);
+
+ load_extra_gtk_theme();
+
result = load_segment_rendering_parameters();
result &= init_segment_content_hash_table();
- if (result)
- load_main_panels(ref);
-
return result;
}
diff --git a/src/gui/core/theme.c b/src/gui/core/theme.c
new file mode 100644
index 0000000..7e81497
--- /dev/null
+++ b/src/gui/core/theme.c
@@ -0,0 +1,260 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * theme.c - prototypes pour l'ajout d'extensions au thème GTK
+ *
+ * Copyright (C) 2009-2012 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "theme.h"
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#include <config.h>
+#include <i18n.h>
+
+
+#include "../panels/log.h"
+#include "../../common/extstr.h"
+#include "../../common/xdg.h"
+#include "../../core/params.h"
+
+
+
+/* Parcourt tous les répertoires connus pour trouver un thème. */
+static bool browse_themes_directories(GdkScreen *, const char *, gboolean);
+
+/* Parcourt un répertoire donné à la recherche d'un thème. */
+static bool look_for_named_theme(GdkScreen *, const char *, const char *, gboolean);
+
+
+/* Répertoires de recherche */
+static const char *_themes_directories[] = {
+
+ PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "themes",
+ PACKAGE_DATA_DIR G_DIR_SEPARATOR_S "themes",
+ NULL
+
+};
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Charge le thème GTK pour les composants spécifiques. *
+* *
+* Retour : true ou false selon le bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_extra_gtk_theme(void)
+{
+ bool result; /* Bilan à faire remonter */
+ const char *name; /* Nom du thème recherché */
+ GdkScreen *screen; /* Ecran(s) concerné(s) */
+ GtkSettings *settings; /* Propriétés du système */
+ gboolean dark; /* Envie d'un thème sombre ? */
+
+ result = false;
+
+ if (!g_generic_config_get_value(get_main_configuration(), MPK_INTERNAL_THEME, &name))
+ goto legt_done;
+
+ screen = gdk_screen_get_default();
+
+ settings = gtk_settings_get_for_screen(screen);
+
+ g_object_get(settings, "gtk-application-prefer-dark-theme", &dark, NULL);
+
+ if (dark)
+ result = browse_themes_directories(screen, name, true);
+
+ if (!result)
+ result = browse_themes_directories(screen, name, false);
+
+ legt_done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : screen = écran concerné par les éventuels chargements. *
+* name = nom du thème recherché, et donc de son répertoire. *
+* dark = indique une préférence pour la variante foncée. *
+* *
+* Description : Parcourt tous les répertoires connus pour trouver un thème. *
+* *
+* Retour : true si un élément de thème a pu être chargé, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool browse_themes_directories(GdkScreen *screen, const char *name, gboolean dark)
+{
+ bool result; /* Bilan à faire remonter */
+ char *suffix; /* Fin du répertoire personnel */
+ char *owndir; /* Thèmes personnels ? */
+ const char **iter; /* Boucle de parcours */
+
+ result = false;
+
+ /* Répertoire de l'utilisateur en premier ! */
+
+ suffix = strdup("chrysalide");
+ suffix = stradd(suffix, G_DIR_SEPARATOR_S);
+ suffix = stradd(suffix, "themes");
+
+ owndir = get_xdg_config_dir(suffix);
+
+ free(suffix);
+
+ if (owndir != NULL)
+ {
+ result = look_for_named_theme(screen, owndir, name, dark);
+
+ free(owndir);
+
+ }
+
+ /* Parcours des autres répertoires classiques au besoin */
+
+ for (iter = _themes_directories; *iter != NULL && !result; iter++)
+ result = look_for_named_theme(screen, *iter, name, dark);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : screen = écran concerné par les éventuels chargements. *
+* dirname = chemin du répertoire où effectuer des recherches. *
+* name = nom du thème recherché, et donc de son répertoire. *
+* dark = indique une préférence pour la variante foncée. *
+* *
+* Description : Parcourt un répertoire donné à la recherche d'un thème. *
+* *
+* Retour : true si un élément de thème a pu être chargé, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const char *name, gboolean dark)
+{
+ bool result; /* Bilan à faire remonter */
+ char *path; /* Chemin d'accès à essayer */
+ int ret; /* Bilan d'un appel */
+ int dirfd; /* Canal de lecture */
+ struct dirent **namelist; /* Liste des trouvailles */
+ int count; /* Nombre de fichiers trouvés */
+ int i; /* Boucle de parcours */
+ char *filename; /* Chemin d'accès constitué */
+ GtkCssProvider *provider; /* Nouveau fournisseur CSS */
+ GError *error; /* Relevé d'éventuelles erreurs*/
+
+ result = false;
+
+ ret = asprintf(&path, "%s" G_DIR_SEPARATOR_S "%s", dirname, name);
+ if (ret == -1) goto lfnt_done;
+
+ dirfd = open(path, O_RDONLY | O_DIRECTORY);
+ if (dirfd == -1) goto lfnt_not_found;
+
+ int keep_dark_css_only(const struct dirent *entry)
+ {
+ return (entry->d_type == DT_REG
+ && endswith(entry->d_name, "-dark.css") ? 1 : 0);
+
+ }
+
+ int keep_css_only(const struct dirent *entry)
+ {
+ return (entry->d_type == DT_REG
+ && endswith(entry->d_name, ".css")
+ && !endswith(entry->d_name, "-dark.css") ? 1 : 0);
+
+ }
+
+ count = scandirat(dirfd, ".", &namelist, dark ? keep_dark_css_only : keep_css_only, alphasort);
+
+ for (i = 0; i < count; i++)
+ {
+ ret = asprintf(&filename, "%s%s%s", path, G_DIR_SEPARATOR_S, namelist[i]->d_name);
+ if (ret == -1) continue;
+
+ provider = gtk_css_provider_new();
+
+ error = NULL;
+
+ gtk_css_provider_load_from_path(provider, filename, &error);
+
+ if (error == NULL)
+ {
+ log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), filename);
+
+ gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ result = true;
+
+ }
+ else
+ {
+ log_variadic_message(LMT_ERROR, _("Failed to load CSS definitions from '%s'"), filename);
+ g_error_free(error);
+ }
+
+ g_object_unref(G_OBJECT(provider));
+
+ free(filename);
+
+ }
+
+ if (count > 0)
+ free(namelist);
+
+ close(dirfd);
+
+ lfnt_not_found:
+
+ free(path);
+
+ lfnt_done:
+
+ return result;
+
+}
diff --git a/src/gui/core/theme.h b/src/gui/core/theme.h
new file mode 100644
index 0000000..77341e3
--- /dev/null
+++ b/src/gui/core/theme.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * theme.h - prototypes pour l'ajout d'extensions au thème GTK
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _GUI_CORE_THEME_H
+#define _GUI_CORE_THEME_H
+
+
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+
+
+/* Charge le thème GTK pour les composants spécifiques. */
+bool load_extra_gtk_theme(void);
+
+
+
+#endif /* _GUI_CORE_THEME_H */