/* Chrysalide - Outil d'analyse de fichiers binaires * hexview.c - affichage de contenus de binaire * * Copyright (C) 2016-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 Chrysalide. If not, see . */ #include "hexview.h" #include "area.h" /* Composant d'affichage générique (instance) */ struct _GtkHexView { GtkWidget parent; /* A laisser en premier */ GtkWidget *offsets; /* Affichage des positions */ GtkWidget *hex; /* Affichage des octets brut */ GtkWidget *ascii; /* Affichage des imprimables */ }; /* Composant d'affichage générique (classe) */ struct _GtkHexViewClass { GtkWidgetClass parent; /* A laisser en premier */ }; /* Procède à l'initialisation de l'afficheur générique. */ static void gtk_hex_view_class_init(GtkHexViewClass *); /* Procède à l'initialisation de l'afficheur générique. */ static void gtk_hex_view_init(GtkHexView *); /* Supprime toutes les références externes. */ static void gtk_hex_view_dispose(GtkHexView *); /* Procède à la libération totale de la mémoire. */ static void gtk_hex_view_finalize(GtkHexView *); void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot); void demo_measure (GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum_size, int *natural_size, int *minimum_baseline, int *natural_baseline); /* Détermine le type du composant d'affichage générique. */ G_DEFINE_TYPE(GtkHexView, gtk_hex_view, GTK_TYPE_WIDGET); /****************************************************************************** * * * Paramètres : class = classe GTK à initialiser. * * * * Description : Procède à l'initialisation de l'afficheur générique. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_hex_view_class_init(GtkHexViewClass *class) { GObjectClass *object; /* Plus haut niveau équivalent */ GtkWidgetClass *widget; /* Classe de haut niveau */ object = G_OBJECT_CLASS(class); object->dispose = (GObjectFinalizeFunc/* ! */)gtk_hex_view_dispose; object->finalize = (GObjectFinalizeFunc)gtk_hex_view_finalize; widget = GTK_WIDGET_CLASS(class); gtk_widget_class_set_css_name(widget, "GtkHexView"); gtk_widget_class_set_layout_manager_type(widget, GTK_TYPE_BOX_LAYOUT); g_type_ensure(GTK_TYPE_COMPOSING_AREA); gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/hexview.ui"); gtk_widget_class_bind_template_child(widget, GtkHexView, offsets); gtk_widget_class_bind_template_child(widget, GtkHexView, hex); gtk_widget_class_bind_template_child(widget, GtkHexView, ascii); //widget->snapshot = demo_snapshot; //widget->measure = demo_measure; /* */ /* widget->destroy = gtk_hex_view_destroy; widget->realize = gtk_hex_view_realize; widget->size_allocate = gtk_hex_view_size_allocate; widget->get_preferred_height = gtk_hex_view_get_preferred_height; widget->get_preferred_width = gtk_hex_view_get_preferred_width; */ } /****************************************************************************** * * * Paramètres : view = composant GTK à initialiser. * * * * Description : Procède à l'initialisation de l'afficheur générique. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_hex_view_init(GtkHexView *view) { gtk_widget_init_template(GTK_WIDGET(view)); g_object_set(G_OBJECT(view->offsets), "width-request", 30, NULL); g_object_set(G_OBJECT(view->ascii), "width-request", 230, NULL); g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->offsets), demo_snapshot, GTK_WIDGET(view)); g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->hex), demo_snapshot, GTK_WIDGET(view)); g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->ascii), demo_snapshot, GTK_WIDGET(view)); } /****************************************************************************** * * * Paramètres : view = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_hex_view_dispose(GtkHexView *view) { gtk_widget_dispose_template(GTK_WIDGET(view), GTK_TYPE_HEX_VIEW); G_OBJECT_CLASS(gtk_hex_view_parent_class)->dispose(G_OBJECT(view)); } /****************************************************************************** * * * Paramètres : view = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_hex_view_finalize(GtkHexView *view) { G_OBJECT_CLASS(gtk_hex_view_parent_class)->finalize(G_OBJECT(view)); } void demo_measure (GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum_size, int *natural_size, int *minimum_baseline, int *natural_baseline) { printf("set size\n"); *minimum_size = 100; *natural_size = 200; } void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) { GdkRGBA red, green, yellow, blue; float w, h; gdk_rgba_parse (&red, "red"); gdk_rgba_parse (&green, "green"); gdk_rgba_parse (&yellow, "yellow"); gdk_rgba_parse (&blue, "blue"); w = gtk_widget_get_width (widget) / 2.0; h = gtk_widget_get_height (widget) / 2.0; gtk_snapshot_append_color (snapshot, &red, &GRAPHENE_RECT_INIT(0, 0, w, h)); gtk_snapshot_append_color (snapshot, &green, &GRAPHENE_RECT_INIT(w, 0, w, h)); gtk_snapshot_append_color (snapshot, &yellow, &GRAPHENE_RECT_INIT(0, h, w, h)); gtk_snapshot_append_color (snapshot, &blue, &GRAPHENE_RECT_INIT(w, h, w, h)); /* printf("[widget] CSS name: %s\n", gtk_widget_get_css_name(widget)); char **iter; iter = gtk_widget_get_css_classes(widget); while (*iter) printf("[widget] CSS classes: %s\n", *iter); */ } #if 0 /****************************************************************************** * * * Paramètres : widget = composant GTK à examiner. * * minimum = largeur minimale à préciser ou NULL. [OUT] * * natural = largeur idéale à préciser ou NULL. [OUT] * * * * Description : Fournit la largeur idéale pour le composant d'affichage. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_hex_view_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural) { GtkHexView *panel; /* Autre version du composant */ gint req; /* Dimension requise */ panel = GTK_HEX_VIEW(widget); GTK_HEX_VIEW_GET_CLASS(widget)->compute_size(panel, &req, NULL); req *= panel->scale; if (minimum != NULL) *minimum = req; if (natural != NULL) *natural = req; } /****************************************************************************** * * * Paramètres : panel = composant GTK à venir consulter. * * cr = contexte graphique associé à l'événement. * * * * Description : Dessine si besoin est une bordure autour du composant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void gtk_hex_view_draw_border(GtkHexView *panel, cairo_t *cr) { GtkWidget *widget; /* Autre version du composant */ GtkStyleContext *context; /* Contexte du thème actuel */ GdkRGBA color; /* Couleur de thème récupérée */ GtkRequisition req; /* Taille allouée à l'élément */ GtkAllocation area; /* Emplacement à considérer */ if (panel->show_border) { widget = GTK_WIDGET(panel); gtk_widget_get_preferred_size(widget, NULL, &req); context = gtk_widget_get_style_context(widget); gtk_style_context_save(context); gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); gtk_style_context_get(gtk_widget_get_style_context(widget), gtk_widget_get_state_flags(widget), GTK_STYLE_PROPERTY_COLOR, &color, NULL); cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); cairo_set_line_width(cr, 1.0); gtk_widget_get_preferred_size(GTK_WIDGET(panel), NULL, &req); area.x = 0; area.y = 0; area.width = req.width; area.height = req.height; gtk_hex_view_define_border_path(panel, cr, &area); cairo_stroke(cr); gtk_style_context_restore(context); } } #endif