/* Chrysalide - Outil d'analyse de fichiers binaires * app.c - fichier d'entrée du programme * * Copyright (C) 2024 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 #include #include #include #include #include "app.h" #include "common/io.h" #include "common/xdg.h" #include "core/logs.h" #include "gui/core/core.h" #include "gui/window.h" /* --------------------- DEFINITION D'APPLICATION PERSONNALISEE --------------------- */ /* Définition de l'application principale graphique (instance) */ struct _GtkChrysalideFramework { GtkApplication parent; /* A laisser en premier */ GtkApplicationWindow *main_window; /* Fenêtre principale */ }; /* Définition de l'application principale graphique (classe) */ struct _GtkChrysalideFrameworkClass { GtkApplicationClass parent; /* A laisser en premier */ }; /* Initialise la classe des applications majeures de Chrysalide. */ static void gtk_chrysalide_framework_class_init(GtkChrysalideFrameworkClass *); /* Initialise une application principale pour Chrysalide. */ static void gtk_chrysalide_framework_init(GtkChrysalideFramework *); /* Supprime toutes les références externes. */ static void gtk_chrysalide_framework_dispose(GtkChrysalideFramework *); /* Procède à la libération totale de la mémoire. */ static void gtk_chrysalide_framework_finalize(GtkChrysalideFramework *); /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ /* Réagit à l'activation de l'application. */ static void gtk_chrysalide_framework_activate(GApplication *); /* ---------------------- POINT D'ENTREE PRINCIPAL D'EXECUTION ---------------------- */ /* Installe au besoin une définition locale pour le système. */ static void ensure_wm_icon_and_name(void); /* ---------------------------------------------------------------------------------- */ /* DEFINITION D'APPLICATION PERSONNALISEE */ /* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour une application principale graphique de Chrysalide. */ G_DEFINE_TYPE(GtkChrysalideFramework, gtk_chrysalide_framework, GTK_TYPE_APPLICATION); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des applications majeures de Chrysalide.* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_chrysalide_framework_class_init(GtkChrysalideFrameworkClass *klass) { GObjectClass *object; /* Autre version de la classe */ GApplicationClass *app; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)gtk_chrysalide_framework_dispose; object->finalize = (GObjectFinalizeFunc)gtk_chrysalide_framework_finalize; app = G_APPLICATION_CLASS(klass); app->activate = gtk_chrysalide_framework_activate; } /****************************************************************************** * * * Paramètres : app = instance à initialiser. * * * * Description : Initialise une application principale pour Chrysalide. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_chrysalide_framework_init(GtkChrysalideFramework *app) { app->main_window = NULL; } /****************************************************************************** * * * Paramètres : app = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_chrysalide_framework_dispose(GtkChrysalideFramework *app) { g_clear_object(&app->main_window); G_OBJECT_CLASS(gtk_chrysalide_framework_parent_class)->dispose(G_OBJECT(app)); } /****************************************************************************** * * * Paramètres : app = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_chrysalide_framework_finalize(GtkChrysalideFramework *app) { G_OBJECT_CLASS(gtk_chrysalide_framework_parent_class)->finalize(G_OBJECT(app)); } /****************************************************************************** * * * Paramètres : - * * * * Description : Crée une nouvelle application principale pour Chrysalide. * * * * Retour : Mécanismes mis en place. * * * * Remarques : - * * * ******************************************************************************/ GtkChrysalideFramework *gtk_chrysalide_framework_new(void) { GtkChrysalideFramework *result; /* Instance à retourner */ result = g_object_new(GTK_TYPE_CHRYSALIDE_FRAMEWORK, "application-id", FRAMEWORK_WINDOW_ID, "flags", G_APPLICATION_DEFAULT_FLAGS, NULL); return result; } /* ---------------------------------------------------------------------------------- */ /* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : app = application concernée par l'événement. * * * * Description : Réagit à l'activation de l'application. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_chrysalide_framework_activate(GApplication *app) { GtkChrysalideFramework *real_app; /* Version réelle de l'instance*/ real_app = GTK_CHRYSALIDE_FRAMEWORK(app); real_app->main_window = gtk_framework_window_new(GTK_APPLICATION(app)); g_object_ref(G_OBJECT(real_app->main_window)); gtk_window_present(GTK_WINDOW(real_app->main_window)); } /* ---------------------------------------------------------------------------------- */ /* POINT D'ENTREE PRINCIPAL D'EXECUTION */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : - * * * * Description : Installe au besoin une définition locale pour le système. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void ensure_wm_icon_and_name(void) { GDesktopAppInfo *info; /* Information du système */ GKeyFile *kfile; /* Définition d'application */ unsigned long exec_path; /* Chemin du programme */ char *filename; /* Nom de fichier à écrire */ GBytes *res; /* Données brutes d'une image */ gsize size; /* Taille de ces données */ gconstpointer data; /* Pointeur vers les données */ int fd; /* Flux ouvert en écriture */ /* Evaluation du besoin */ info = g_desktop_app_info_new(FRAMEWORK_WINDOW_ID ".desktop"); /** * Si l'exécutable n'est pas valide (inconnu de $PATH), * la variable info n'est pas initialisée. */ if (info != NULL) { unref_object(info); goto done; } /* Mise en place d'une définition d'application */ exec_path = getauxval(AT_EXECFN); assert(exec_path != 0); kfile = g_key_file_new(); g_key_file_set_string(kfile, "Desktop Entry", "Name", "Chrysalide"); g_key_file_set_string(kfile, "Desktop Entry", "Comment[fr]", "Cadriciel de rétronception ciblant principalement les systèmes embarqués"); g_key_file_set_string(kfile, "Desktop Entry", "Comment", "Reverse Engineering Framework focused on embedded systems"); g_key_file_set_string(kfile, "Desktop Entry", "Type", "Application"); g_key_file_set_string(kfile, "Desktop Entry", "Exec", (const char *)exec_path); g_key_file_set_string(kfile, "Desktop Entry", "Icon", "chrysalide-logo"); g_key_file_set_string(kfile, "Desktop Entry", "StartupNotify", "true"); g_key_file_set_string(kfile, "Desktop Entry", "MimeType", "application/vnd.android.package-archive"); filename = get_xdg_data_dir("applications/re.chrysalide.framework.gui.desktop", true); g_key_file_save_to_file(kfile, filename, NULL); free(filename); g_key_file_free(kfile); /* Ecriture de l'image */ res = g_resources_lookup_data("/re/chrysalide/framework/images/chrysalide-logo.svg", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); assert(res != NULL); data = g_bytes_get_data(res, &size); filename = get_xdg_data_dir("icons/hicolor/scalable/apps/chrysalide-logo.svg", true); fd = open(filename, O_WRONLY | O_CREAT); if (fd == -1) LOG_ERROR_N("open"); else { safe_write(fd, data, size); close(fd); } free(filename); g_bytes_unref(res); /* Sortie */ done: ; } /****************************************************************************** * * * Paramètres : argc = nombre d'arguments dans la ligne de commande. * * argv = arguments de la ligne de commande. * * * * Description : Point d'entrée du programme. * * * * Retour : EXIT_SUCCESS si le prgm s'est déroulé sans encombres. * * * * Remarques : - * * * ******************************************************************************/ int main(int argc, char **argv) { int result; /* Bilan de l'exécution */ GtkChrysalideFramework *app; /* Gestion d'application GTK */ if (!load_gui_components(AGC_BUFFER_FEATURES | AGC_PANELS)) return EXIT_FAILURE; ensure_wm_icon_and_name(); app = gtk_chrysalide_framework_new(); result = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(G_OBJECT(app)); unload_gui_components(AGC_BUFFER_FEATURES | AGC_PANELS); return result; }