diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/extstr.c | 32 | ||||
-rw-r--r-- | src/common/extstr.h | 4 | ||||
-rw-r--r-- | src/core/params.c | 3 | ||||
-rw-r--r-- | src/core/params.h | 1 | ||||
-rw-r--r-- | src/glibext/configuration.c | 3 | ||||
-rw-r--r-- | src/gtkext/Makefile.am | 3 | ||||
-rw-r--r-- | src/gtkext/theme.c | 106 | ||||
-rwxr-xr-x | src/gui/core/Makefile.am | 3 | ||||
-rw-r--r-- | src/gui/core/core.c | 8 | ||||
-rw-r--r-- | src/gui/core/theme.c | 260 | ||||
-rw-r--r-- | src/gui/core/theme.h (renamed from src/gtkext/theme.h) | 6 | ||||
-rw-r--r-- | src/main.c | 8 |
12 files changed, 317 insertions, 120 deletions
diff --git a/src/common/extstr.c b/src/common/extstr.c index cabc307..0b37606 100644 --- a/src/common/extstr.c +++ b/src/common/extstr.c @@ -368,3 +368,35 @@ char *ellipsis(char *input, size_t max) return result; } + + +/****************************************************************************** +* * +* Paramètres : str = chaîne à analyser. * +* suffix = chaîne à retrouver en extrémité éventuellement. * +* * +* Description : Détermine si une chaîne se termine par une autre. * +* * +* Retour : true si le suffixe a été identifié, ou false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool endswith(const char *str, const char *suffix) +{ + bool result; /* Bilan à faire remonter */ + size_t len; /* Taille de la chaîne soumise */ + size_t suflen; /* Taille du suffixe */ + + result = false; + + len = strlen(str); + suflen = strlen(suffix); + + if (len > suflen && strncmp(&str[len - suflen], suffix, suflen) == 0) + result = true; + + return result; + +} diff --git a/src/common/extstr.h b/src/common/extstr.h index 6eb3889..9b49563 100644 --- a/src/common/extstr.h +++ b/src/common/extstr.h @@ -26,6 +26,7 @@ #include <ctype.h> +#include <stdbool.h> #include <sys/types.h> @@ -60,6 +61,9 @@ char *escape_crlf(char *); /* Borne la taille d'une chaîne à une valeur donnée. */ char *ellipsis(char *, size_t); +/* Détermine si une chaîne se termine par une autre. */ +bool endswith(const char *, const char *); + #endif /* _COMMON_EXTSTR_H */ diff --git a/src/core/params.c b/src/core/params.c index 540ce48..b3f766e 100644 --- a/src/core/params.c +++ b/src/core/params.c @@ -138,6 +138,9 @@ bool load_main_config_parameters(void) param = g_generic_config_create_param(config, MPK_FORMAT_NO_NAME, CPT_BOOLEAN, false); if (param == NULL) return false; + param = g_generic_config_create_param(config, MPK_INTERNAL_THEME, CPT_STRING, "Adwaita"); + if (param == NULL) return false; + param = g_generic_config_create_param(config, MPK_TITLE_BAR, CPT_BOOLEAN, true); if (param == NULL) return false; diff --git a/src/core/params.h b/src/core/params.h index 281e617..2ec45cc 100644 --- a/src/core/params.h +++ b/src/core/params.h @@ -40,6 +40,7 @@ #define MPK_LOCAL_PORT "cdb.network.local.port" #define MPK_SERVER_BACKLOG "cdb.network.server.backlog" #define MPK_FORMAT_NO_NAME "format.symbols.use_phy_instead_of_virt" +#define MPK_INTERNAL_THEME "gui.editor.theme" #define MPK_TITLE_BAR "gui.editor.hide_titlebar" #define MPK_LAST_PROJECT "gui.editor.last_project" #define MPK_MAXIMIZED "gui.editor.start_maximized" diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c index 1dc7dc6..870bc72 100644 --- a/src/glibext/configuration.c +++ b/src/glibext/configuration.c @@ -1161,7 +1161,8 @@ GGenConfig *g_generic_config_new(const char *name) result = g_object_new(G_TYPE_GEN_CONFIG, NULL); - suffix = strdup("chrysalide/"); + suffix = strdup("chrysalide"); + suffix = stradd(suffix, G_DIR_SEPARATOR_S); suffix = stradd(suffix, name); suffix = stradd(suffix, ".xml"); diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index bdd0a31..f1bd18a 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -16,8 +16,7 @@ libgtkext_la_SOURCES = \ gtkstatusstack.h gtkstatusstack.c \ gtkviewpanel-int.h \ gtkviewpanel.h gtkviewpanel.c \ - support.h support.c \ - theme.h theme.c + support.h support.c libgtkext_la_LIBADD = \ graph/libgtkextgraph.la diff --git a/src/gtkext/theme.c b/src/gtkext/theme.c deleted file mode 100644 index fbaed3c..0000000 --- a/src/gtkext/theme.c +++ /dev/null @@ -1,106 +0,0 @@ - -/* 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 <config.h> - - - -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) -{ - GdkScreen *screen; /* Ecran(s) concerné(s) */ - const char **iter_f; /* Boucle de parcours #1 */ - bool done; /* Traitement d'un fichier */ - const char **iter_d; /* Boucle de parcours #2 */ - gchar *filename; /* Chemin d'accès constitué */ - GtkCssProvider *provider; /* Nouveau fournisseur CSS */ - - static const char *css_files[] = { - "portions.css", - "segments.css", - "icons.css", - NULL - }; - - screen = gdk_screen_get_default(); - - done = true; - - for (iter_f = css_files; *iter_f != NULL; iter_f++) - { - done = false; - - for (iter_d = _themes_directories; *iter_d != NULL && !done; iter_d++) - { - filename = g_strdup_printf("%s%s%s", *iter_d, G_DIR_SEPARATOR_S, *iter_f); - - if (g_file_test(filename, G_FILE_TEST_EXISTS)) - { - provider = gtk_css_provider_new(); - done = gtk_css_provider_load_from_path(provider, filename, NULL); - - if (done) - gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), - GTK_STYLE_PROVIDER_PRIORITY_USER); - - g_object_unref(G_OBJECT(provider)); - - } - - g_free(filename); - - } - - if (!done) - break; - - } - - return done; - -} 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/gtkext/theme.h b/src/gui/core/theme.h index 3c893a4..77341e3 100644 --- a/src/gtkext/theme.h +++ b/src/gui/core/theme.h @@ -22,8 +22,8 @@ */ -#ifndef _GTKEXT_THEME_H -#define _GTKEXT_THEME_H +#ifndef _GUI_CORE_THEME_H +#define _GUI_CORE_THEME_H #include <stdbool.h> @@ -36,4 +36,4 @@ bool load_extra_gtk_theme(void); -#endif /* _GTKEXT_THEME_H */ +#endif /* _GUI_CORE_THEME_H */ @@ -35,7 +35,6 @@ #include "core/params.h" #include "glibext/delayed.h" #include "glibext/gbinportion.h" -#include "gtkext/theme.h" #include "gui/editor.h" #include "gui/core/core.h" #include "gui/core/global.h" @@ -122,9 +121,6 @@ int main(int argc, char **argv) setlocale (LC_ALL, ""); gtk_init(&argc, &argv); - if (!load_extra_gtk_theme()) - return EXIT_FAILURE; - /* Initialisation du programme */ if (!load_all_basic_components()) return EXIT_FAILURE; @@ -170,6 +166,8 @@ int main(int argc, char **argv) editor = create_editor(); + if (editor == NULL) goto failed_to_load_editor; + gtk_widget_show_now(editor); init_work_queue(get_global_status()); @@ -237,6 +235,8 @@ int main(int argc, char **argv) //gtk_widget_destroy(editor); + failed_to_load_editor: + unload_all_basic_components(); return result; |