diff options
Diffstat (limited to 'src/gui/core/items.c')
-rw-r--r-- | src/gui/core/items.c | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/src/gui/core/items.c b/src/gui/core/items.c new file mode 100644 index 0000000..923a565 --- /dev/null +++ b/src/gui/core/items.c @@ -0,0 +1,374 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * items.c - manipulation de l'ensemble des composants graphiques actifs + * + * Copyright (C) 2017 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "items.h" + + +#include "global.h" +#include "../editem-int.h" +#include "../../analysis/db/items/move.h" + + + +/* Liste des éléments enregistrés */ +static GEditorItem *_editem_list = NULL; + + +/* Suit les changements de focus des panneaux d'affichage. */ +static gboolean notify_view_panel_focus_change(GtkDisplayPanel *, GdkEventFocus *, gpointer); + +/* Lance une procédure de déplacement de la position courante. */ +static void start_moving_to_address_in_view_panel(GtkDisplayPanel *, const vmpa2t *, gpointer); + +/* Suit les changements de position dans du code d'assembleur. */ +static void track_caret_address_on_view_panel(GtkDisplayPanel *, const vmpa2t *, gpointer); + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède à l'enregistrement d'un élément reactif de l'éditeur.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_editor_item(GEditorItem *item) +{ + editem_list_add_tail(item, &_editem_list); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = nouvelle instance de binaire analysé. * +* * +* Description : Lance une actualisation du fait d'un changement de binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void change_editor_items_current_binary(GLoadedBinary *binary) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + set_current_binary(binary); + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->update_binary != NULL) + klass->update_binary(iter, binary); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant d'affichage concerné par l'opération. * +* event = informations liées à l'événement. * +* unused = adresse non utilisée ici. * +* * +* Description : Suit les changements de focus des panneaux d'affichage. * +* * +* Retour : FALSE pour continuer la propagation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean notify_view_panel_focus_change(GtkDisplayPanel *panel, GdkEventFocus *event, gpointer unused) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->notify_focus != NULL) + klass->notify_focus(iter, event->in ? panel : NULL); + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant d'affichage parcouru. * +* addr = adresse de destination du curseur souhaitée. * +* unused = adresse non utilisée ici. * +* * +* Description : Lance une procédure de déplacement de la position courante. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void start_moving_to_address_in_view_panel(GtkDisplayPanel *panel, const vmpa2t *addr, gpointer unused) +{ + const vmpa2t *src; /* Position courante de curseur*/ + GDbMove *move; /* Déplacement à organiser */ + GLoadedBinary *binary; /* Binaire en cours d'étude */ + + src = gtk_display_panel_get_caret_location(panel); + + /* S'il n'y a pas de passif, pas besoin d'historique */ + if (src == NULL) + gtk_display_panel_scroll_to_address(panel, addr, SPT_CENTER); + + else + { + move = g_db_move_new(src, addr); + + binary = gtk_display_panel_get_binary(panel); + g_loaded_binary_add_to_collection(binary, G_DB_ITEM(move)); + g_object_unref(G_OBJECT(binary)); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant d'affichage parcouru. * +* addr = nouvelle adresse du curseur courant. * +* unused = adresse non utilisée ici. * +* * +* Description : Suit les changements de position dans du code d'assembleur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void track_caret_address_on_view_panel(GtkDisplayPanel *panel, const vmpa2t *addr, gpointer unused) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->track_caret != NULL) + klass->track_caret(iter, panel, addr); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = nouveau panneau d'affichage actif. * +* * +* Description : Lance une actualisation du fait d'un changement de vue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void change_editor_items_current_view(GtkDisplayPanel *panel) +{ + GtkDisplayPanel *view; /* Affichage actif */ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + GObject *caret; /* Support du curseur actif */ + + /* Suivi des affichages */ + + view = get_current_view(); + + if (view != NULL) + { + g_signal_handlers_disconnect_by_func(view, G_CALLBACK(notify_view_panel_focus_change), NULL); + g_signal_handlers_disconnect_by_func(view, G_CALLBACK(notify_view_panel_focus_change), NULL); + + g_object_unref(view); + + } + + set_current_view(panel); + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->update_view != NULL) + klass->update_view(iter, panel); + + } + + if (panel != NULL) + { + g_signal_connect(panel, "focus-in-event", G_CALLBACK(notify_view_panel_focus_change), NULL); + g_signal_connect(panel, "focus-out-event", G_CALLBACK(notify_view_panel_focus_change), NULL); + } + + /* Suivi du curseur */ + + caret = get_caret_instance(); + + if (caret != NULL) + { + g_signal_handlers_disconnect_by_func(caret, + G_CALLBACK(start_moving_to_address_in_view_panel), + NULL); + g_signal_handlers_disconnect_by_func(caret, + G_CALLBACK(track_caret_address_on_view_panel), + NULL); + + set_caret_instance(NULL); + g_object_unref(caret); + + } + + if (panel != NULL) + { + g_signal_connect(panel, "move-request", + G_CALLBACK(start_moving_to_address_in_view_panel), + NULL); + + g_signal_connect(panel, "caret-moved", + G_CALLBACK(track_caret_address_on_view_panel), + NULL); + + caret = G_OBJECT(panel); + + g_object_ref(caret); + set_caret_instance(caret); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : panel = nouveau panneau d'affichage actif. * +* * +* Description : Lance une actualisation du fait d'un changement de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void change_editor_items_current_view_content(GtkDisplayPanel *panel) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->update_content != NULL) + klass->update_content(iter, panel); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire contenant l'adresse à représenter. * +* addr = adresse mémoire à mettre en avant. * +* source = composant à l'origine du changement. * +* * +* Description : Concentre l'attention de l'ensemble sur une adresse donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void focus_address_in_editor_items(GLoadedBinary *binary, const vmpa2t *addr, GEditorItem *source) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->focus_addr != NULL && iter != source) + klass->focus_addr(iter, binary, addr); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : project = projet concerné par l'évolution. * +* * +* Description : Lance une actualisation relative à l'étendue du projet. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_project_area(GStudyProject *project) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->update_project != NULL) + klass->update_project(iter, project); + + } + +} |