summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/exporter-int.h10
-rw-r--r--src/analysis/exporter.c92
-rw-r--r--src/analysis/exporter.h8
-rw-r--r--src/analysis/line_code.c84
-rw-r--r--src/arch/immediate.c91
-rw-r--r--src/arch/instruction.c60
-rw-r--r--src/arch/x86/operand.c206
-rw-r--r--src/arch/x86/registers.c33
-rw-r--r--src/glibext/Makefile.am5
-rw-r--r--src/glibext/gbufferline.c359
-rw-r--r--src/glibext/gbufferline.h86
-rw-r--r--src/glibext/gbuffersegment.c391
-rw-r--r--src/glibext/gbuffersegment.h65
-rw-r--r--src/glibext/gcodebuffer.c483
-rw-r--r--src/glibext/gcodebuffer.h102
-rw-r--r--src/gtkext/gtkblockview.c217
-rw-r--r--src/gtkext/gtkextstatusbar.c13
-rw-r--r--src/plugins/pglist.c2
18 files changed, 2184 insertions, 123 deletions
diff --git a/src/analysis/exporter-int.h b/src/analysis/exporter-int.h
index 3218bcf..421770e 100644
--- a/src/analysis/exporter-int.h
+++ b/src/analysis/exporter-int.h
@@ -33,6 +33,9 @@
typedef void (* add_text_fc) (GContentExporter *, GRenderingOptions *, MainRendering, FILE *);
/* Ajoute à un texte GTK le contenu de la ligne de rendu. */
+typedef void (* export_buffer_fc) (GContentExporter *, GBufferLine *, GRenderingOptions *);
+
+/* Ajoute à un texte GTK le contenu de la ligne de rendu. */
typedef void (* add_to_gtk_buffer_fc) (GContentExporter *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]);
/* Traduit une instruction en version humainement lisible. */
@@ -46,6 +49,7 @@ struct _GContentExporter
GObject parent; /* A laisser en premier */
add_text_fc add_text; /* Remplissage simple */
+ export_buffer_fc export_buffer; /* Constitution du texte GTK */
add_to_gtk_buffer_fc add_to_gtk_buffer; /* Constitution du texte GTK */
add_arch_to_gtk_buffer_fc add_arch_to_gtk_buffer; /* Constitution... */
@@ -58,6 +62,9 @@ struct _GContentExporterClass
{
GObjectClass parent; /* A laisser en premier */
+ PangoContext *context; /* Contexte graphique Pango */
+ PangoAttrList *attribs[RTT_COUNT]; /* Décorateurs pour tampons */
+
GtkTextTag *tags[RTT_COUNT]; /* Décorateurs pour les textes */
};
@@ -66,6 +73,9 @@ struct _GContentExporterClass
/* Ajoute du texte simple à un fichier ouvert en écriture. */
void g_content_exporter_insert_text(GContentExporter *, FILE *, const char *, size_t, RenderingTagType);
+/* Ajoute du texte à un tampon de code via l'instance spécifiée. */
+void g_content_exporter_insert_into_buffer(GContentExporter *, GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType);
+
/* Ajoute du texte à un texte GTK via l'instance spécifiée. */
void g_content_exporter_insert_with_gtk_tag(GContentExporter *, GtkTextBuffer *, GtkTextIter *, const char *, size_t, RenderingTagType);
diff --git a/src/analysis/exporter.c b/src/analysis/exporter.c
index e1e9160..5820fd6 100644
--- a/src/analysis/exporter.c
+++ b/src/analysis/exporter.c
@@ -46,9 +46,49 @@ G_DEFINE_TYPE(GContentExporter, g_content_exporter, G_TYPE_OBJECT);
static void g_content_exporter_class_init(GContentExporterClass *klass)
{
+ GdkScreen *screen; /* Ecran pour GDK */
+ PangoFontDescription *font_desc; /* Police de caractère */
GtkTextTagTable *table; /* Seule table globale valable */
GtkTextTag *tag;
+ /* Exportation vers un tampon de code */
+
+ screen = gdk_screen_get_default();
+
+ font_desc = pango_font_description_from_string("mono 10");
+
+ klass->context = gdk_pango_context_get_for_screen(screen);
+
+ pango_context_set_font_description(klass->context, font_desc);
+ pango_context_set_base_dir(klass->context, PANGO_DIRECTION_LTR);
+ pango_context_set_language(klass->context, gtk_get_default_language());
+
+ klass->attribs[RTT_RAW] = pango_attr_list_new();
+
+ klass->attribs[RTT_COMMENT] = pango_attr_list_new();
+
+ klass->attribs[RTT_RAW_CODE] = pango_attr_list_new();
+
+ klass->attribs[RTT_INSTRUCTION] = pango_attr_list_new();
+
+ klass->attribs[RTT_IMMEDIATE] = pango_attr_list_new();
+
+ klass->attribs[RTT_REGISTER] = pango_attr_list_new();
+
+ klass->attribs[RTT_HOOK] = pango_attr_list_new();
+
+ klass->attribs[RTT_SIGNS] = pango_attr_list_new();
+
+ klass->attribs[RTT_LTGT] = pango_attr_list_new();
+
+ klass->attribs[RTT_SEGMENT] = pango_attr_list_new();
+
+ klass->attribs[RTT_STRING] = pango_attr_list_new();
+
+ klass->attribs[RTT_VAR_NAME] = pango_attr_list_new();
+
+
+
/* Décorateurs GTK */
table = get_gtk_tag_table();
@@ -207,6 +247,36 @@ void g_content_exporter_insert_text(GContentExporter *exporter, FILE *stream, co
/******************************************************************************
* *
* Paramètres : exporter = instance sachant exporter son contenu. *
+* buffer = espace où placer ledit contenu. *
+* column = colonne de la ligne visée par l'insertion. *
+* text = texte à insérer dans l'existant. *
+* length = taille du texte à traiter. *
+* type = type de décorateur à utiliser. *
+* *
+* Description : Ajoute du texte à un tampon de code via l'instance spécifiée.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_content_exporter_insert_into_buffer(GContentExporter *exporter, GBufferLine *buffer, BufferLineColumn column, const char *text, size_t length, RenderingTagType type)
+{
+ GContentExporterClass *class; /* Stockage de briques de base */
+ GBufferSegment *segment; /* Portion de texte à ajouter */
+
+ class = G_CONTENT_EXPORTER_GET_CLASS(exporter);
+
+ segment = g_buffer_segment_new(class->context, class->attribs[type], text, length);
+ g_buffer_line_add_segment(buffer, column, segment);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : exporter = instance sachant exporter son contenu. *
* buffer = zone de texte à venir compléter. *
* iter = point d'insertion du nouveau texte. [OUT] *
* text = texte à insérer dans l'existant. *
@@ -260,6 +330,28 @@ void g_content_exporter_add_text(GContentExporter *exporter, GRenderingOptions *
/******************************************************************************
* *
+* Paramètres : exporter = instance sachant exporter son contenu. *
+* line = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_content_exporter_to_buffer(GContentExporter *exporter, GBufferLine *line, GRenderingOptions *options)
+{
+ if (exporter->export_buffer != NULL)
+ exporter->export_buffer(exporter, line, options);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : exporter = instance sachant exporter son contenu. *
* rendering = support effectif final des lignes de code. *
* buffer = zone de texte à venir compléter. *
diff --git a/src/analysis/exporter.h b/src/analysis/exporter.h
index 524d800..297fd99 100644
--- a/src/analysis/exporter.h
+++ b/src/analysis/exporter.h
@@ -31,11 +31,14 @@
#include "roptions.h"
+#include "../glibext/gbufferline.h"
/* Types de partie de rendu */
typedef enum _RenderingTagType
{
+ RTT_RAW, /* Contenu brut */
+
RTT_COMMENT, /* Commentaire */
RTT_RAW_CODE, /* Code binaire brut */
@@ -59,7 +62,7 @@ typedef enum _RenderingTagType
} RenderingTagType;
-#define RTT_NONE RTT_COUNT
+#define RTT_NONE RTT_RAW /* TODO : remme */
#define G_TYPE_CONTENT_EXPORTER g_content_exporter_get_type()
@@ -89,6 +92,9 @@ GtkTextTagTable *_get_gtk_tag_table(GtkTextTagTable *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
void g_content_exporter_add_text(GContentExporter *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+void g_content_exporter_to_buffer(GContentExporter *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu de l'instance spécifiée. */
void g_content_exporter_add_to_gtk_buffer(GContentExporter *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]);
diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c
index 7c80074..4761522 100644
--- a/src/analysis/line_code.c
+++ b/src/analysis/line_code.c
@@ -61,6 +61,9 @@ static void g_code_line_init(GCodeLine *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_code_line_add_text(GCodeLine *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_code_line_to_buffer(GCodeLine *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu de la ligne de code. */
static void g_code_line_add_to_gtk_buffer(GCodeLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]);
@@ -109,6 +112,7 @@ static void g_code_line_init(GCodeLine *line)
exporter_parent = G_CONTENT_EXPORTER(line);
exporter_parent->add_text = (add_text_fc)g_code_line_add_text;
+ exporter_parent->export_buffer = (export_buffer_fc)g_code_line_to_buffer;
exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_code_line_add_to_gtk_buffer;
line_parent = G_RENDERING_LINE(line);
@@ -121,7 +125,7 @@ static void g_code_line_init(GCodeLine *line)
/******************************************************************************
* *
-* Paramètres : line = ligne de représentation à actualiser. *
+* Paramètres : line = ligne de représentation à représenter. *
* options = options de rendu. *
* rendering = support effectif final des lignes de code. *
* stream = flux ouvert en écriture. *
@@ -184,7 +188,7 @@ static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, Ma
else
snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[bin_offset + i]);
}
-
+
g_content_exporter_insert_text(exporter, stream, bin_code, bin_len * 3 - 1, RTT_RAW_CODE);
free(bin_code);
@@ -212,6 +216,80 @@ static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, Ma
/******************************************************************************
* *
+* Paramètres : line = ligne de représentation à représenter. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_code_line_to_buffer(GCodeLine *line, GBufferLine *buffer, GRenderingOptions *options)
+{
+ GContentExporter *exporter; /* Autre vision de la ligne #1 */
+ GRenderingLine *basic; /* Autre vision de la ligne #2 */
+ MemoryDataSize msize; /* Taille du bus d'adresses */
+ char address[VMPA_MAX_SIZE]; /* Adresse au format texte */
+ size_t len; /* Taille de l'élément inséré */
+ const bin_t *content; /* Contenu binaire global */
+ off_t bin_offset; /* Début de l'instruction */
+ off_t bin_len; /* Taille d'instruction */
+ char *bin_code; /* Tampon du code binaire */
+ off_t i; /* Boucle de parcours */
+
+ exporter = G_CONTENT_EXPORTER(line);
+ basic = G_RENDERING_LINE(line);
+
+ /* Eventuelle adresse virtuelle ou physique */
+
+ msize = g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options));
+
+ len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ADDRESS, address, len, RTT_RAW);
+
+ /* Eventuel code brut */
+
+ content = g_binary_format_get_content(G_BIN_FORMAT(g_rendering_options_get_format(line->options)), NULL);
+ g_arch_instruction_get_location(line->instr, &bin_offset, &bin_len, NULL);
+
+ bin_code = (char *)calloc(bin_len * 3, sizeof(char));
+
+ for (i = 0; i < bin_len; i++)
+ {
+ if ((i + 1) < bin_len)
+ snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[bin_offset + i]);
+ else
+ snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[bin_offset + i]);
+ }
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_BINARY,
+ bin_code, bin_len * 3 - 1, RTT_RAW_CODE);
+
+ free(bin_code);
+
+ /* Instruction proprement dite */
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(line->instr), buffer, options);
+
+ /* Commentaire ? */
+
+ if (basic->comment != NULL)
+ {
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_COMMENTS, "; ", 2, RTT_COMMENT);
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_COMMENTS,
+ basic->comment, strlen(basic->comment), RTT_COMMENT);
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne de représentation à actualiser. *
* rendering = support effectif final des lignes de code. *
* buffer = zone de texte à venir compléter. *
@@ -282,7 +360,7 @@ static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering renderi
else
snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[bin_offset + i]);
}
-
+
g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter,
bin_code, bin_len * 3 - 1, RTT_RAW_CODE);
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index b9b8a6e..61dc5f5 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -85,11 +85,14 @@ static void g_imm_operand_class_init(GImmOperandClass *);
static void g_imm_operand_init(GImmOperand *);
/* Construit la chaîne de caractères correspondant à l'opérande. */
-static void g_imm_operand_to_string(const GImmOperand *, AsmSyntax, char [VMPA_MAX_SIZE]);
+static size_t g_imm_operand_to_string(const GImmOperand *, AsmSyntax, char [VMPA_MAX_SIZE]);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_imm_operand_add_text(const GImmOperand *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_imm_operand_to_buffer(const GImmOperand *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_imm_operand_add_to_gtk_buffer(const GImmOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -136,6 +139,7 @@ static void g_imm_operand_init(GImmOperand *operand)
parent = G_CONTENT_EXPORTER(operand);
parent->add_text = (add_text_fc)g_imm_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_imm_operand_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_imm_operand_add_to_gtk_buffer;
}
@@ -352,57 +356,59 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
* *
* Description : Construit la chaîne de caractères correspondant à l'opérande.*
* *
-* Retour : - *
+* Retour : Nombre de caractères utilisés. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[VMPA_MAX_SIZE])
+static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[VMPA_MAX_SIZE])
{
+ size_t result; /* Longueur à retourner */
+
switch (syntax)
{
case ASX_INTEL:
switch (operand->size)
{
case MDS_UNDEFINED:
- snprintf(value, VMPA_MAX_SIZE, "0x???");
+ result = snprintf(value, VMPA_MAX_SIZE, "0x???");
break;
case AOS_8_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);
break;
case AOS_16_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16);
break;
case AOS_32_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32);
break;
case AOS_64_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64);
break;
case AOS_8_BITS_SIGNED:
if (g_imm_operand_is_negative(operand))
- snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);
else
- snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);
break;
case AOS_16_BITS_SIGNED:
if (g_imm_operand_is_negative(operand))
- snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1);
else
- snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16);
break;
case AOS_32_BITS_SIGNED:
if (g_imm_operand_is_negative(operand))
- snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1);
else
- snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32);
break;
case AOS_64_BITS_SIGNED:
if (g_imm_operand_is_negative(operand))
- snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1);
else
- snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->signed_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->signed_imm.val64);
break;
}
break;
@@ -411,31 +417,31 @@ static void g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax
switch (operand->size)
{
case MDS_UNDEFINED:
- snprintf(value, VMPA_MAX_SIZE, "$0x???");
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x???");
break;
case AOS_8_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);
break;
case AOS_16_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16);
break;
case AOS_32_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32);
break;
case AOS_64_BITS_UNSIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64);
break;
case AOS_8_BITS_SIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
break;
case AOS_16_BITS_SIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1);
break;
case AOS_32_BITS_SIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1);
break;
case AOS_64_BITS_SIGNED:
- snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1);
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1);
break;
}
break;
@@ -445,6 +451,8 @@ static void g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax
}
+ return result;
+
}
@@ -466,11 +474,38 @@ static void g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax
static void g_imm_operand_add_text(const GImmOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream)
{
char value[VMPA_MAX_SIZE]; /* Chaîne à imprimer */
+ size_t len; /* Taille de l'élément inséré */
+
+ len = g_imm_operand_to_string(operand, g_rendering_options_get_syntax(options), value);
+
+ g_content_exporter_insert_text(G_CONTENT_EXPORTER(operand), stream, value, len, RTT_IMMEDIATE);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_imm_operand_to_buffer(const GImmOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ char value[VMPA_MAX_SIZE]; /* Chaîne à imprimer */
+ size_t len; /* Taille de l'élément inséré */
- g_imm_operand_to_string(operand, g_rendering_options_get_syntax(options), value);
+ len = g_imm_operand_to_string(operand, g_rendering_options_get_syntax(options), value);
- g_content_exporter_insert_text(G_CONTENT_EXPORTER(operand), stream,
- value, strlen(value), RTT_IMMEDIATE);
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
+ value, len, RTT_IMMEDIATE);
}
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index ee220a5..eb8ec28 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -41,6 +41,9 @@ static void g_arch_instruction_init(GArchInstruction *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_arch_instruction_add_text(const GArchInstruction *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_arch_instruction_to_buffer(const GArchInstruction *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'une instruction. */
static void g_arch_instruction_add_to_gtk_buffer(const GArchInstruction *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -87,6 +90,7 @@ static void g_arch_instruction_init(GArchInstruction *instr)
parent = G_CONTENT_EXPORTER(instr);
parent->add_text = (add_text_fc)g_arch_instruction_add_text;
+ parent->export_buffer = (export_buffer_fc)g_arch_instruction_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_arch_instruction_add_to_gtk_buffer;
}
@@ -109,7 +113,7 @@ static void g_arch_instruction_init(GArchInstruction *instr)
static void g_arch_instruction_add_text(const GArchInstruction *instr, GRenderingOptions *options, MainRendering rendering, FILE *stream)
{
- GContentExporter *exporter; /* Autre vision de la ligne */
+ GContentExporter *exporter; /* Autre vision de l'objet */
const char *key; /* Mot clef principal */
size_t klen; /* Taille de ce mot clef */
size_t i; /* Boucle de parcours */
@@ -148,6 +152,60 @@ static void g_arch_instruction_add_text(const GArchInstruction *instr, GRenderin
/******************************************************************************
* *
+* Paramètres : instr = instruction d'assemblage à représenter. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_to_buffer(const GArchInstruction *instr, GBufferLine *buffer, GRenderingOptions *options)
+{
+ GContentExporter *exporter; /* Autre vision de l'objet */
+ const char *key; /* Mot clef principal */
+ size_t klen; /* Taille de ce mot clef */
+ size_t i; /* Boucle de parcours */
+
+ exporter = G_CONTENT_EXPORTER(instr);
+
+ key = instr->get_text(instr,
+ g_rendering_options_get_format(options),
+ g_rendering_options_get_syntax(options));
+ klen = strlen(key);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY_HEAD,
+ key, klen, RTT_INSTRUCTION);
+
+ if (instr->operands_count > 0)
+ {
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(G_ARCH_INSTRUCTION(instr)->operands[0]),
+ buffer, options);
+
+ for (i = 1; i < instr->operands_count; i++)
+ {
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ ",", 1, RTT_NONE/* FIXME */);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ " ", 1, RTT_NONE);
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(G_ARCH_INSTRUCTION(instr)->operands[i]),
+ buffer, options);
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instruction à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index 7d6437a..0a571a7 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -92,6 +92,9 @@ static void g_x86_register_operand_init(GX86RegisterOperand *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_x86_register_operand_add_text(const GX86RegisterOperand *, GRenderingOptions *, MainRendering, FILE *);
+/*Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_x86_register_operand_to_buffer(const GX86RegisterOperand *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_x86_register_operand_add_to_gtk_buffer(const GX86RegisterOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -130,6 +133,9 @@ static void g_x86_mod_rm_operand_init(GX86ModRMOperand *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_x86_mod_rm_operand_add_text(const GX86ModRMOperand *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_x86_mod_rm_operand_to_buffer(const GX86ModRMOperand *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_x86_mod_rm_operand_add_to_gtk_buffer(const GX86ModRMOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -164,6 +170,9 @@ static void g_x86_relative_operand_init(GX86RelativeOperand *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_x86_relative_operand_add_text(const GX86RelativeOperand *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_x86_relative_operand_to_buffer(const GX86RelativeOperand *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_x86_relative_operand_add_to_gtk_buffer(const GX86RelativeOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -198,6 +207,9 @@ static void g_x86_moffs_operand_init(GX86MOffsOperand *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_x86_moffs_operand_add_text(const GX86MOffsOperand *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_x86_moffs_operand_to_buffer(const GX86MOffsOperand *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -233,6 +245,9 @@ static void g_x86_data_operand_init(GX86DataOperand *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_x86_data_operand_add_text(const GX86DataOperand *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_x86_data_operand_to_buffer(const GX86DataOperand *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_x86_data_operand_add_to_gtk_buffer(const GX86DataOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -330,6 +345,7 @@ static void g_x86_register_operand_init(GX86RegisterOperand *operand)
parent = G_CONTENT_EXPORTER(operand);
parent->add_text = (add_text_fc)g_x86_register_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_x86_register_operand_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_register_operand_add_to_gtk_buffer;
}
@@ -476,6 +492,27 @@ static void g_x86_register_operand_add_text(const GX86RegisterOperand *operand,
/******************************************************************************
* *
* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_register_operand_to_buffer(const GX86RegisterOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
* buffer = zone de texte à venir compléter. *
@@ -543,6 +580,7 @@ static void g_x86_mod_rm_operand_init(GX86ModRMOperand *operand)
parent = G_CONTENT_EXPORTER(operand);
parent->add_text = (add_text_fc)g_x86_mod_rm_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_x86_mod_rm_operand_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_mod_rm_operand_add_to_gtk_buffer;
}
@@ -732,6 +770,88 @@ static void g_x86_mod_rm_operand_add_text(const GX86ModRMOperand *operand, GRend
/******************************************************************************
* *
* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_mod_rm_operand_to_buffer(const GX86ModRMOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ GContentExporter *exporter; /* Autre vision de l'opérande */
+ char tmp[2]; /* Echelle en puissance de 2 */
+
+ exporter = G_CONTENT_EXPORTER(operand);
+
+ switch (g_rendering_options_get_syntax(options))
+ {
+ case ASX_INTEL:
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "[", 1, RTT_HOOK);
+
+ if (operand->scale > 0)
+ {
+ snprintf(tmp, 2, "%d", (int)pow(2, operand->scale));
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ tmp, 1, RTT_IMMEDIATE);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "*", 1, RTT_SIGNS);
+
+ }
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->index), buffer, options);
+
+ if (operand->base != NULL)
+ {
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "+", 1, RTT_SIGNS);
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->base), buffer, options);
+
+ }
+
+ if (operand->displacement != NULL)
+ {
+ if (g_imm_operand_is_negative(operand->displacement))
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "-", 1, RTT_SIGNS);
+ else
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "+", 1, RTT_SIGNS);
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->displacement), buffer, options);
+
+ }
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "]", 1, RTT_HOOK);
+
+ break;
+
+ case ASX_ATT:
+
+ /* TODO */
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY,
+ "[ModRM]", 7, RTT_HOOK);
+
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
* buffer = zone de texte à venir compléter. *
@@ -920,6 +1040,7 @@ static void g_x86_relative_operand_init(GX86RelativeOperand *operand)
parent = G_CONTENT_EXPORTER(operand);
parent->add_text = (add_text_fc)g_x86_relative_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_x86_relative_operand_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_relative_operand_add_to_gtk_buffer;
}
@@ -1004,6 +1125,27 @@ static void g_x86_relative_operand_add_text(const GX86RelativeOperand *operand,
/******************************************************************************
* *
* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_relative_operand_to_buffer(const GX86RelativeOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->immediate), buffer, options);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
* buffer = zone de texte à venir compléter. *
@@ -1091,6 +1233,7 @@ static void g_x86_moffs_operand_init(GX86MOffsOperand *operand)
parent = G_CONTENT_EXPORTER(operand);
parent->add_text = (add_text_fc)g_x86_moffs_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_x86_moffs_operand_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_moffs_operand_add_to_gtk_buffer;
}
@@ -1158,6 +1301,30 @@ static void g_x86_moffs_operand_add_text(const GX86MOffsOperand *operand, GRende
/******************************************************************************
* *
* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_moffs_operand_to_buffer(const GX86MOffsOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
+ "ds:", 3, RTT_SEGMENT);
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->offset), buffer, options);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
* buffer = zone de texte à venir compléter. *
@@ -1229,6 +1396,7 @@ static void g_x86_data_operand_init(GX86DataOperand *operand)
parent = G_CONTENT_EXPORTER(operand);
parent->add_text = (add_text_fc)g_x86_data_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_x86_data_operand_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_data_operand_add_to_gtk_buffer;
}
@@ -1299,6 +1467,44 @@ static void g_x86_data_operand_add_text(const GX86DataOperand *operand, GRenderi
/******************************************************************************
* *
* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_data_operand_to_buffer(const GX86DataOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ GContentExporter *exporter; /* Autre vision de l'opérande */
+
+ exporter = G_CONTENT_EXPORTER(operand);
+
+ if (operand->dest)
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
+ "es:", 3, RTT_SEGMENT);
+ else
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
+ "ds:", 3, RTT_SEGMENT);
+
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
+ "[", 1, RTT_HOOK);
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options);
+
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
+ "]", 1, RTT_HOOK);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
* buffer = zone de texte à venir compléter. *
diff --git a/src/arch/x86/registers.c b/src/arch/x86/registers.c
index 90346f7..8a61d09 100644
--- a/src/arch/x86/registers.c
+++ b/src/arch/x86/registers.c
@@ -115,6 +115,9 @@ static void g_x86_register_to_string(const GX86Register *, AsmSyntax, char [MAX_
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_x86_register_add_text(const GX86Register *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_x86_register_to_buffer(const GX86Register *, GBufferLine *, GRenderingOptions *);
+
/* Ajoute à un texte GTK le contenu d'un opérande. */
static void g_x86_register_add_to_gtk_buffer(const GX86Register *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);
@@ -161,6 +164,7 @@ static void g_x86_register_init(GX86Register *reg)
parent = G_CONTENT_EXPORTER(reg);
parent->add_text = (add_text_fc)g_x86_register_add_text;
+ parent->export_buffer = (export_buffer_fc)g_x86_register_to_buffer;
parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_register_add_to_gtk_buffer;
}
@@ -497,7 +501,7 @@ static void g_x86_register_to_string(const GX86Register *reg, AsmSyntax syntax,
/******************************************************************************
* *
-* Paramètres : operand = opérande à transcrire. *
+* Paramètres : reg = registre X86 à transcrire. *
* options = options de rendu. *
* rendering = support effectif final des lignes de code. *
* stream = flux ouvert en écriture. *
@@ -525,6 +529,33 @@ static void g_x86_register_add_text(const GX86Register *reg, GRenderingOptions *
/******************************************************************************
* *
+* Paramètres : reg = registre X86 à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_register_to_buffer(const GX86Register *reg, GBufferLine *buffer, GRenderingOptions *options)
+{
+ char key[MAX_REGNAME_LEN]; /* Mot clef principal */
+ size_t klen; /* Taille de ce mot clef */
+
+ g_x86_register_to_string(reg, g_rendering_options_get_syntax(options), key, &klen);
+
+ g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(reg), buffer, BLC_ASSEMBLY,
+ key, klen, RTT_REGISTER);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à transcrire. *
* format = format du binaire manipulé. *
* syntax = type de représentation demandée. *
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index 334b49a..7712965 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -3,7 +3,10 @@ noinst_LTLIBRARIES = libglibext.la
libglibext_la_SOURCES = \
delayed-int.h \
- delayed.h delayed.c
+ delayed.h delayed.c \
+ gbufferline.h gbufferline.c \
+ gbuffersegment.h gbuffersegment.c \
+ gcodebuffer.h gcodebuffer.c
libglibext_la_LDFLAGS =
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
new file mode 100644
index 0000000..bfb77bb
--- /dev/null
+++ b/src/glibext/gbufferline.c
@@ -0,0 +1,359 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gbufferline.c - représentation de fragments de texte en ligne
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 "gbufferline.h"
+
+
+
+
+#include <malloc.h> /* FIXME : à virer */
+
+
+
+/* Informations sur le contenu d'une colonne */
+typedef struct _buffer_line_column
+{
+ GBufferSegment **segments;
+ size_t count;
+
+ int max_width; /* Largeur max. de l'espace */
+
+} buffer_line_column;
+
+
+
+/* Réinitialise une colonne de ligne. */
+static void reset_column(buffer_line_column *);
+
+/* Fournit la quantité de pixels requise pour l'impression. */
+static gint get_column_width(buffer_line_column *);
+
+/* Ajoute un fragment de texte à une colonne de ligne. */
+static void add_segment_to_column(buffer_line_column *, GBufferSegment *);
+
+/* Imprime le contenu d'une colonne de ligne de texte. */
+static void draw_segments_of_column(buffer_line_column *, GdkDrawable *, GdkGC *, gint, gint);
+
+
+
+
+/* Représentation de fragments de texte en ligne (instance) */
+struct _GBufferLine
+{
+ GObject parent; /* A laisser en premier */
+
+ buffer_line_column columns[BLC_COUNT]; /* Répartition du texte */
+
+};
+
+/* Représentation de fragments de texte en ligne (classe) */
+struct _GBufferLineClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Procède à l'initialisation d'une classe de représentation. */
+static void g_buffer_line_class_init(GBufferLineClass *);
+
+/* Procède à l'initialisation d'une représentation de fragments. */
+static void g_buffer_line_init(GBufferLine *);
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : column = colonne de ligne à mettre à jour. *
+* *
+* Description : Réinitialise une colonne de ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void reset_column(buffer_line_column *column)
+{
+ column->max_width = -1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : column = colonne de ligne à consulter. *
+* *
+* Description : Fournit la quantité de pixels requise pour l'impression. *
+* *
+* Retour : Largeur requise par la colonne, en pixel. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gint get_column_width(buffer_line_column *column)
+{
+ size_t i;
+
+ if (column->max_width == -1)
+ {
+ column->max_width = 0;
+
+ for (i = 0; i < column->count; i++)
+ column->max_width += g_buffer_segment_get_width(column->segments[i]);
+
+ }
+
+ return column->max_width;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : column = colonne de ligne à venir compléter. *
+* segment = fragment de texte à ajouter à la colonne. *
+* *
+* Description : Ajoute un fragment de texte à une colonne de ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void add_segment_to_column(buffer_line_column *column, GBufferSegment *segment)
+{
+
+ /* FIXME : à remplacer */
+
+
+ column->segments = (GBufferSegment **)realloc(column->segments, ++column->count * sizeof(GBufferSegment *));
+
+
+ column->segments[column->count - 1] = segment;
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : column = colonne de ligne de texte à manipuler. *
+* drawable = surface de rendu où travailler. *
+* gc = contexte graphique à utiliser pour les pinceaux. *
+* x_init = abscisse du point d'impression de départ. *
+* y = ordonnée du point d'impression. *
+* *
+* Description : Imprime le contenu d'une colonne de ligne de texte. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void draw_segments_of_column(buffer_line_column *column, GdkDrawable *drawable, GdkGC *gc, gint x_init, gint y)
+{
+ gint x;
+ size_t i;
+
+ x = x_init;
+
+ for (i = 0; i < column->count; i++)
+ g_buffer_segment_draw(column->segments[i], drawable, gc, &x, y);
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Détermine le type de la représentation de fragments de texte en ligne. */
+G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de représentation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_line_class_init(GBufferLineClass *class)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une représentation de fragments.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_line_init(GBufferLine *line)
+{
+ unsigned int i; /* Boucle de parcours */
+
+ for (i = 0; i < BLC_COUNT; i++)
+ reset_column(&line->columns[i]);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une nouvelle représentation de fragments de texte. *
+* *
+* Retour : Composant GTK créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferLine *g_buffer_line_new(void)
+{
+ GBufferLine *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_BUFFER_LINE, NULL);
+ //result = g_new0(GBufferLine, 1);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne à venir compléter. *
+* index = index de la colonne visée par la procédure. *
+* segment = fragment de texte à ajouter à la colonne. *
+* *
+* Description : Ajoute un fragment de texte à une colonne de ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBufferSegment *segment)
+{
+ add_segment_to_column(&line->columns[index], segment);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne à venir compléter. *
+* index = index de la colonne visée par la procédure. *
+* *
+* Description : Fournit la largeur requise pour une colonne de ligne donnée. *
+* *
+* Retour : Largeur en pixel requise. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_line_get_width(GBufferLine *line, BufferLineColumn index)
+{
+ return get_column_width(&line->columns[index]);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne de texte à manipuler. *
+* drawable = surface de rendu où travailler. *
+* gc = contexte graphique à utiliser pour les pinceaux.*
+* max_widths = largeurs de colonne à respecter. *
+* x_init = abscisse du point d'impression de départ. *
+* y = ordonnée du point d'impression. *
+* *
+* Description : Imprime la ligne de texte représentée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_line_draw(GBufferLine *line, GdkDrawable *drawable, GdkGC *gc, const gint max_widths[BLC_COUNT], gint x_init, gint y)
+{
+ gint x; /* Point de départ d'impression*/
+ unsigned int i; /* Boucle de parcours */
+
+ x = x_init;
+
+ for (i = 0; i < BLC_COUNT; i++)
+ {
+ /* TODO : skip if... */
+
+ draw_segments_of_column(&line->columns[i], drawable, gc, x, y);
+ x += max_widths[i] + 23;
+
+ }
+
+}
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
new file mode 100644
index 0000000..4113c28
--- /dev/null
+++ b/src/glibext/gbufferline.h
@@ -0,0 +1,86 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gbufferline.h - prototypes pour la représentation de fragments de texte en ligne
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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/>.
+ */
+
+
+#ifndef _GLIBEXT_GBUFFERLINE_H
+#define _GLIBEXT_GBUFFERLINE_H
+
+
+#include <glib-object.h>
+
+
+#include "gbuffersegment.h"
+
+
+
+#define G_TYPE_BUFFER_LINE (g_buffer_line_get_type())
+#define G_BUFFER_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BUFFER_LINE, GBufferLine))
+#define G_BUFFER_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BUFFER_LINE, GBufferLineClass))
+#define G_IS_BUFFER_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BUFFER_LINE))
+#define G_IS_BUFFER_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BUFFER_LINE))
+#define G_BUFFER_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BUFFER_LINE, GBufferLineClass))
+
+
+
+/* Représentation de fragments de texte en ligne (instance) */
+typedef struct _GBufferLine GBufferLine;
+
+/* Représentation de fragments de texte en ligne (classe) */
+typedef struct _GBufferLineClass GBufferLineClass;
+
+
+/* Désignation des colonnes d'une ligne */
+typedef enum _BufferLineColumn
+{
+ BLC_ADDRESS, /* Adresse virtuelle */
+ BLC_BINARY, /* Contenu sous forme binaire */
+ BLC_ASSEMBLY_HEAD, /* Instruction pour assembleur */
+ BLC_ASSEMBLY, /* Code pour assembleur */
+ BLC_COMMENTS, /* Commentaires éventuels */
+
+ BLC_COUNT
+
+} BufferLineColumn;
+
+
+/* Accompagnement du dessin pour compléments */
+typedef void (* buffer_line_draw_fc) (GBufferLine *, GdkDrawable *, GdkGC *, gint, gint, void *);
+
+
+/* Détermine le type de la représentation de fragments de texte en ligne. */
+GType g_buffer_line_get_type(void);
+
+/* Crée une nouvelle représentation de fragments de texte. */
+GBufferLine *g_buffer_line_new(void);
+
+/* Ajoute un fragment de texte à une colonne de ligne. */
+void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *);
+
+/* Fournit la largeur requise pour une colonne de ligne donnée. */
+gint g_buffer_line_get_width(GBufferLine *, BufferLineColumn);
+
+/* Imprime la ligne de texte représentée. */
+void g_buffer_line_draw(GBufferLine *, GdkDrawable *, GdkGC *, const gint [BLC_COUNT], gint, gint);
+
+
+
+#endif /* _GLIBEXT_GBUFFERLINE_H */
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
new file mode 100644
index 0000000..bcafa97
--- /dev/null
+++ b/src/glibext/gbuffersegment.c
@@ -0,0 +1,391 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gbuffersegment.c - concentration d'un fragment de caractères aux propriétés communes
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 "gbuffersegment.h"
+
+
+#include <stdbool.h>
+
+
+
+
+
+
+/* Fragment de caractères aux propriétés communes (instance) */
+struct _GBufferSegment
+{
+ GObject parent; /* A laisser en premier */
+
+ PangoGlyphString *glyphs; /* Caractères traités */
+ PangoFont *font; /* Police utilisée à l'analyse */
+
+ PangoRectangle logical; /* Dimension du texte */
+
+};
+
+/* Fragment de caractères aux propriétés communes (classe) */
+struct _GBufferSegmentClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+ PangoGlyphString *ascii_glyphs; /* Caractères ASCII prêts */
+ PangoFont *ascii_font; /* Police utilisée pour ASCII */
+ bool ascii_ready; /* Utilisation possible ? */
+
+ bool ascii_init_done; /* Initialisation tentée ? */
+
+};
+
+
+/* Procède à l'initialisation d'une classe de fragment de texte. */
+static void g_buffer_segment_class_init(GBufferSegmentClass *);
+
+/* Procède à l'initialisation d'un fragment de texte. */
+static void g_buffer_segment_init(GBufferSegment *);
+
+
+
+
+
+
+
+
+
+
+static bool ascii_glyph_table_init(GBufferSegmentClass *class, PangoContext *context)
+{
+ gint i; /* Boucle de parcours */
+ char ascii_chars[128]; /* Table de caractères ASCII */
+ PangoAttrList *attribs; /* Liste d'attributs (vide) */
+ GList *list; /* Liste d'éléments distincts */
+
+ if (!class->ascii_init_done)
+ {
+ class->ascii_init_done = true;
+
+ /* Construction d'une chaîne adéquate */
+
+ for (i = 0; i < 128; ++i)
+ switch (i)
+ {
+ case 0 ... 31:
+ ascii_chars[i] = '?';
+ break;
+ case 32 ... 127:
+ ascii_chars[i] = i;
+ break;
+ default:
+ ascii_chars[i] = '?';
+ break;
+ }
+
+ /* Analyse de la chaîne créée */
+
+ attribs = pango_attr_list_new();
+ list = pango_itemize(context, ascii_chars, 0, 128, attribs, NULL);
+
+ class->ascii_ready = (list != NULL && list->next == NULL);
+
+ if (class->ascii_ready)
+ {
+ PangoItem *item;
+ int width;
+
+ item = (PangoItem *)list->data;
+ //width = gui.char_width * PANGO_SCALE;
+
+ /* Remember the shape engine used for ASCII. */
+ //default_shape_engine = item->analysis.shape_engine;
+
+ class->ascii_font = item->analysis.font;
+ g_object_ref(class->ascii_font);
+
+ class->ascii_glyphs = pango_glyph_string_new();
+
+ pango_shape(ascii_chars, 128, &item->analysis, class->ascii_glyphs);
+
+ class->ascii_ready = (class->ascii_glyphs->num_glyphs == 128);
+
+
+
+#if 0
+ for (i = 0; i < class->ascii_glyphs->num_glyphs; i++)
+ {
+ PangoGlyphGeometry *geom;
+
+ geom = &class->ascii_glyphs->glyphs[i].geometry;
+ //geom->x_offset += MAX(0, width - geom->width) / 2;
+ //geom->width = /*width*/8 * PANGO_SCALE;
+ }
+#endif
+
+ }
+
+ g_list_foreach(list, (GFunc)&pango_item_free, NULL);
+ g_list_free(list);
+
+ pango_attr_list_unref(attribs);
+
+ }
+
+ return class->ascii_ready;
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : context = contexte Pango pour l'analyse des caractères. *
+* attribs = propriétés de la zone de texte. *
+* text = chaîne de caractères à traiter. *
+* length = quantité de ces caractères. *
+* *
+* Description : Crée un nouveau fragment de texte avec des propriétés. *
+* *
+* Retour : Composant GTK créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *context, PangoAttrList *attribs, const char *text, size_t length)
+{
+ PangoGlyphString *glyphs; /* Caractères traités */
+
+ GList *item_list;
+ PangoItem *item;
+
+ PangoRectangle logical;
+
+
+ char *max;
+ char *iter;
+
+ GBufferSegmentClass *class;
+
+ size_t i;
+
+ PangoGlyphInfo *info;
+ gint *log_clusters;
+ PangoGlyphInfo *ref;
+
+ glyphs = pango_glyph_string_new();
+
+
+
+
+ /**
+ * Petite astuce empruntée à Vim...
+ * (cf. src/gui_gtk_x11.c, fonction gui_gtk2_draw_string()).
+ * On essaie de traiter à la main les morceaux de
+ * texte. Pour ceux en ASCII pur, le gain est non négligeable.
+ */
+
+ max = text + length;
+
+ for (iter = text; iter < max; iter++)
+ if (*iter & 0x80)
+ goto not_ascii;
+
+ class = G_BUFFER_SEGMENT_GET_CLASS(segment);
+
+ if (!ascii_glyph_table_init(class, context))
+ goto not_ascii;
+
+ pango_glyph_string_set_size(glyphs, length);
+
+ info = glyphs->glyphs;
+ log_clusters = glyphs->log_clusters;
+ ref = class->ascii_glyphs->glyphs;
+
+ for (i = 0; i < length; i++)
+ {
+ info[i] = ref[text[i]];
+ log_clusters[i] = i;
+ }
+
+ goto next;
+
+ not_ascii:
+
+ item_list = pango_itemize(context, text, 0, length, attribs, NULL);
+
+ /*
+ if (!(item_list != NULL && item_list->next == NULL))
+ printf("ouich\n");
+ */
+
+ item = (PangoItem *)item_list->data;
+ pango_shape(text, length, &item->analysis, glyphs);
+
+ //segment->font = item->analysis.font;/* TODO : ref ! */
+
+
+ next:
+
+
+ //pango_shape(text, length, &item->analysis, glyphs);
+
+
+ pango_glyph_string_extents(glyphs, class->ascii_font, NULL, &segment->logical);
+
+ segment->logical.y /= PANGO_SCALE;
+ segment->logical.width /= PANGO_SCALE;
+ segment->logical.height /= PANGO_SCALE;
+
+ segment->glyphs = glyphs;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Détermine le type du fragment de caractères aux propriétés communes. */
+G_DEFINE_TYPE(GBufferSegment, g_buffer_segment, G_TYPE_OBJECT);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de fragment de texte.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_segment_class_init(GBufferSegmentClass *class)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : segment = composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un fragment de texte. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_segment_init(GBufferSegment *segment)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : context = contexte Pango pour l'analyse des caractères. *
+* attribs = propriétés de la zone de texte. *
+* text = chaîne de caractères à traiter. *
+* length = quantité de ces caractères. *
+* *
+* Description : Crée un nouveau fragment de texte avec des propriétés. *
+* *
+* Retour : Composant GTK créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferSegment *g_buffer_segment_new(PangoContext *context, PangoAttrList *attribs, const char *text, size_t length)
+{
+ GBufferSegment *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_BUFFER_SEGMENT, NULL);
+ //result = g_new(GBufferSegment, 1);
+
+ g_buffer_segment_prepare(result, context, attribs, text, length);
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : segment = fragment de texte à consulter. *
+* *
+* Description : Fournit la quantité de pixels requise pour l'impression. *
+* *
+* Retour : Largeur requise par la colonne, en pixel. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_segment_get_width(const GBufferSegment *segment)
+{
+ return segment->logical.width;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : segment = fragment de texte à manipuler. *
+* drawable = surface de rendu où travailler. *
+* gc = contexte graphique à utiliser pour les pinceaux. *
+* x = abscisse du point d'impression (à maj). [OUT] *
+* y = ordonnée du point d'impression. *
+* *
+* Description : Imprime le fragment de texte représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_segment_draw(GBufferSegment *segment, GdkDrawable *drawable, GdkGC *gc, gint *x, gint y)
+{
+ gdk_draw_glyphs(drawable, gc, G_BUFFER_SEGMENT_GET_CLASS(segment)->ascii_font,
+ *x, y - segment->logical.y, segment->glyphs);
+
+ *x += segment->logical.width;
+
+}
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
new file mode 100644
index 0000000..28338b9
--- /dev/null
+++ b/src/glibext/gbuffersegment.h
@@ -0,0 +1,65 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gbuffersegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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/>.
+ */
+
+
+#ifndef _GLIBEXT_GBUFFERSEGMENT_H
+#define _GLIBEXT_GBUFFERSEGMENT_H
+
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+#include <pango/pango.h>
+
+
+
+#define G_TYPE_BUFFER_SEGMENT (g_buffer_segment_get_type())
+#define G_BUFFER_SEGMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BUFFER_SEGMENT, GBufferSegment))
+#define G_BUFFER_SEGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BUFFER_SEGMENT, GBufferSegmentClass))
+#define G_IS_BUFFER_SEGMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BUFFER_SEGMENT))
+#define G_IS_BUFFER_SEGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BUFFER_SEGMENT))
+#define G_BUFFER_SEGMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BUFFER_SEGMENT, GBufferSegmentClass))
+
+
+
+/* Fragment de caractères aux propriétés communes (instance) */
+typedef struct _GBufferSegment GBufferSegment;
+
+/* Fragment de caractères aux propriétés communes (classe) */
+typedef struct _GBufferSegmentClass GBufferSegmentClass;
+
+
+
+/* Détermine le type du fragment de caractères aux propriétés communes. */
+GType g_buffer_segment_get_type(void);
+
+/* Crée un nouveau fragment de texte avec des propriétés. */
+GBufferSegment *g_buffer_segment_new(PangoContext *, PangoAttrList *, const char *, size_t);
+
+/* Fournit la quantité de pixels requise pour l'impression. */
+gint g_buffer_segment_get_width(const GBufferSegment *);
+
+/* Imprime le fragment de texte représenté. */
+void g_buffer_segment_draw(GBufferSegment *, GdkDrawable *, GdkGC *, gint *, gint);
+
+
+
+#endif /* _GLIBEXT_GBUFFERSEGMENT_H */
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
new file mode 100644
index 0000000..fda2c01
--- /dev/null
+++ b/src/glibext/gcodebuffer.c
@@ -0,0 +1,483 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gcodebuffer.h - prototypes pour l'affichage d'un fragment de code d'assemblage
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 "gcodebuffer.h"
+
+
+#include <malloc.h>
+#include <sys/param.h>
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+/* Tampon pour code désassemblé (instance) */
+struct _GCodeBuffer
+{
+ GObject parent; /* A laisser en premier */
+
+ GBufferLine **lines; /* Liste des lignes intégrées */
+ size_t count; /* Quantité en cache */
+ size_t used; /* Quantité utilisée */
+
+};
+
+/* Tampon pour code désassemblé (classe) */
+struct _GCodeBufferClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Taille des allocations de masse */
+#define LINE_ALLOC_BULK 20
+
+
+/* Procède à l'initialisation d'une classe de tampon de code. */
+static void g_code_buffer_class_init(GCodeBufferClass *);
+
+/* Procède à l'initialisation d'un tampon pour code désassemblé. */
+static void g_code_buffer_init(GCodeBuffer *);
+
+
+
+/* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */
+
+
+/* Vue d'un tampon pour code désassemblé (instance) */
+struct _GBufferView
+{
+ GObject parent; /* A laisser en premier */
+
+ GCodeBuffer *buffer; /* Tampon de code visualisé */
+ size_t first; /* Première ligne intégrée */
+ size_t last; /* Dernière ligne intégrée */
+
+ gint line_height; /* Hauteur maximale des lignes */
+ gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */
+ gint left_margin; /* Marge gauche + espace */
+ gint left_text; /* Début d'impression du code */
+
+ buffer_line_draw_fc drawing_extra; /* Fonction d'accompagnement */
+ void *drawing_data; /* Donnée utilisateur */
+
+};
+
+/* Vue d'un tampon pour code désassemblé (classe) */
+struct _GBufferViewClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+#define WIDTHS_CACHED(view) ((view)->max_widths[0] != -1)
+
+
+/* Procède à l'initialisation d'une classe de vue de tampon. */
+static void g_buffer_view_class_init(GBufferViewClass *);
+
+/* Procède à l'initialisation d'une vue d'un tampon pour code. */
+static void g_buffer_view_init(GBufferView *);
+
+/* Réinitialise le cache des largeurs de colonne calculées. */
+static void g_buffer_view_reset_required_widths(GBufferView *);
+
+/* Calcule les dimensions requises par une visualisation. */
+static void g_buffer_view_compute_required_widths(GBufferView *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* TAMPON POUR CODE DESASSEMBLE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type du composant de tampon pour code désassemblé. */
+G_DEFINE_TYPE(GCodeBuffer, g_code_buffer, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de tampon de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_code_buffer_class_init(GCodeBufferClass *class)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un tampon pour code désassemblé.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_code_buffer_init(GCodeBuffer *buffer)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée un nouveau composant de tampon pour code désassemblé. *
+* *
+* Retour : Composant GTK créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GCodeBuffer *g_code_buffer_new(void)
+{
+ GCodeBuffer *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_CODE_BUFFER, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GTK à mettre à jour. *
+* *
+* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer)
+{
+ GBufferLine *result; /* Instance à retourner */
+
+ if (buffer->used == buffer->count)
+ {
+ buffer->count += LINE_ALLOC_BULK;
+ buffer->lines = (GBufferLine **)realloc(buffer->lines,
+ buffer->count * sizeof(GBufferLine *));
+ }
+
+ result = g_buffer_line_new();
+ buffer->lines[buffer->used++] = result;
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* VUE PARTICULIERE D'UN TAMPON DE CODE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type de la vue d'un tampon pour code désassemblé. */
+G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe de composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une classe de vue de tampon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_view_class_init(GBufferViewClass *class)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation d'une vue d'un tampon pour code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_view_init(GBufferView *buffer)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = tamon à représenter à l'écran. *
+* *
+* Description : Crée une nouvelle vue d'un tampon pour code désassemblé. *
+* *
+* Retour : Composant GTK créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
+{
+ GBufferView *result; /* Composant à retourner */
+
+ result = g_object_new(G_TYPE_BUFFER_VIEW, NULL);
+
+ result->buffer = buffer;
+ result->first = 0;
+ result->last = buffer->used;
+
+ g_buffer_view_reset_required_widths(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisation à consulter. *
+* *
+* Description : Réinitialise le cache des largeurs de colonne calculées. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_view_reset_required_widths(GBufferView *view)
+{
+ unsigned int i; /* Boucle de parcours */
+
+ for (i = 0; i < BLC_COUNT; i++)
+ view->max_widths[i] = -1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisation à consulter. *
+* *
+* Description : Calcule les dimensions requises par une visualisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_buffer_view_compute_required_widths(GBufferView *view)
+{
+ GBufferLine **lines; /* Liste des lignes à traiter */
+ size_t i; /* Boucle de parcours #1 */
+ unsigned int j; /* Boucle de parcours #2 */
+ gint width; /* Largeur d'une colonne */
+
+ lines = view->buffer->lines;
+
+ view->line_height = 17;
+
+ view->left_margin = 2 * view->line_height;
+ view->left_text = 2.5 * view->line_height;
+
+ for (i = view->first; i < view->last; i++)
+ for (j = 0; j < BLC_COUNT; j++)
+ {
+ width = g_buffer_line_get_width(lines[i], j);
+ view->max_widths[j] = MAX(view->max_widths[j], width);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisation à consulter. *
+* *
+* Description : Fournit la hauteur d'impression d'une ligne visualisée. *
+* *
+* Retour : Hauteur de ligne en pixel. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_view_get_line_height(GBufferView *view)
+{
+ if (!WIDTHS_CACHED(view))
+ g_buffer_view_compute_required_widths(view);
+
+ return view->line_height;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisation à consulter. *
+* width = largeur requise pour une pleine visualisation. [OUT]*
+* height = hauteur requise pour une pleine visualisation. [OUT]*
+* *
+* Description : Fournit les dimensions requises par une visualisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height)
+{
+ unsigned int i; /* Boucle de parcours */
+
+ *width = 0;
+ *height = view->line_height;
+
+ if (!WIDTHS_CACHED(view))
+ g_buffer_view_compute_required_widths(view);
+
+ for (i = 0; i < BLC_COUNT; i++)
+ *width += view->max_widths[i];
+
+ *height *= (view->last - view->first);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisation à mettre à jour. *
+* method = procédure à appeler à chaque dessin de ligne. *
+* data = donnée utilisateur à passer lors des appels. *
+* *
+* Description : Définit à une procédure à appeler lors des dessins de ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_view_define_extra_drawing(GBufferView *view, buffer_line_draw_fc method, void *data)
+{
+ view->drawing_extra = method;
+ view->drawing_data = data;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisation à représenter. *
+* event = informations liées à l'événement. *
+* gc = contexte graphique à utiliser pour les pinceaux. *
+* fake_x = abscisse réelle du point 0 à l'écran. *
+* fake_y = ordonnée réelle du point 0 à l'écran. *
+* *
+* Description : Imprime la visualisation du tempon de code désassemblé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, GdkGC *gc, gint fake_x, gint fake_y)
+{
+ GdkDrawable *drawable; /* Surface de dessin */
+ gint real_x; /* Abscisse réelle pour tampon */
+ gint real_y; /* Ordonnée réelle pour tampon */
+
+ size_t first; /* Première ligne visée */
+ size_t last; /* Dernière ligne visée + 1 */
+ gint y; /* Point de départ + décallage */
+
+
+ GBufferLine **lines; /* Liste des lignes à traiter */
+ size_t i; /* Boucle de parcours */
+
+
+ drawable = GDK_DRAWABLE(event->window);
+
+
+ real_x = fake_x + view->left_text;
+ real_y = fake_y + event->area.y;
+
+
+
+ first = (real_y / view->line_height);
+ last = first + (event->area.height / view->line_height);
+ if (event->area.height % view->line_height > 0) last++;
+
+ y = event->area.y - (real_y % view->line_height);
+
+
+
+ lines = view->buffer->lines;
+
+ for (i = first; i < last; i++)
+ {
+ /* TODO : skip if... */
+
+ if (view->drawing_extra != NULL)
+ view->drawing_extra(lines[i], drawable, gc, fake_x, y, view->drawing_data);
+
+ g_buffer_line_draw(lines[i], drawable, gc, view->max_widths, real_x, y);
+
+ y += view->line_height;
+
+ }
+
+}
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
new file mode 100644
index 0000000..9460530
--- /dev/null
+++ b/src/glibext/gcodebuffer.h
@@ -0,0 +1,102 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gcodebuffer.h - prototypes pour l'affichage d'un fragment de code d'assemblage
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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/>.
+ */
+
+
+#ifndef _GLIBEXT_GCODEBUFFER_H
+#define _GLIBEXT_GCODEBUFFER_H
+
+
+#include <glib-object.h>
+
+
+#include "gbufferline.h"
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+#define G_TYPE_CODE_BUFFER (g_code_buffer_get_type())
+#define G_CODE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GCodeBuffer))
+#define G_CODE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GCodeBufferClass))
+#define G_IS_CODE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_CODE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_CODE_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GCodeBufferClass))
+
+
+/* Tampon pour code désassemblé (instance) */
+typedef struct _GCodeBuffer GCodeBuffer;
+
+/* Tampon pour code désassemblé (classe) */
+typedef struct _GCodeBufferClass GCodeBufferClass;
+
+
+/* Détermine le type du composant de tampon pour code désassemblé. */
+GType g_code_buffer_get_type(void);
+
+/* Crée un nouveau composant de tampon pour code désassemblé. */
+GCodeBuffer *g_code_buffer_new(void);
+
+/* Ajoute une nouvelle ligne à un tampon pour code désassemblé. */
+GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *);
+
+
+
+/* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */
+
+
+#define G_TYPE_BUFFER_VIEW (g_buffer_view_get_type())
+#define G_BUFFER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BUFFER_VIEW, GBufferView))
+#define G_BUFFER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BUFFER_VIEW, GBufferViewClass))
+#define G_IS_BUFFER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BUFFER_VIEW))
+#define G_IS_BUFFER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BUFFER_VIEW))
+#define G_BUFFER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BUFFER_VIEW, GBufferViewClass))
+
+
+/* Vue d'un tampon pour code désassemblé (instance) */
+typedef struct _GBufferView GBufferView;
+
+/* Vue d'un tampon pour code désassemblé (classe) */
+typedef struct _GBufferViewClass GBufferViewClass;
+
+
+/* Détermine le type de la vue d'un tampon pour code désassemblé. */
+GType g_buffer_view_get_type(void);
+
+/* Crée une nouvelle vue d'un tampon pour code désassemblé. */
+GBufferView *g_buffer_view_new(GCodeBuffer *);
+
+/* Fournit la hauteur d'impression d'une ligne visualisée. */
+gint g_buffer_view_get_line_height(GBufferView *);
+
+/* Fournit les dimensions requises par une visualisation. */
+void g_buffer_view_get_size(GBufferView *, gint *, gint *);
+
+/* Définit à une procédure à appeler lors des dessins de ligne. */
+void g_buffer_view_define_extra_drawing(GBufferView *, buffer_line_draw_fc, void *);
+
+/* Imprime la visualisation du tempon de code désassemblé. */
+void g_buffer_view_draw(const GBufferView *, const GdkEventExpose *, GdkGC *, gint, gint);
+
+
+
+#endif /* _GLIBEXT_GCODEBUFFER_H */
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c
index a4f0d3e..2ea7ae2 100644
--- a/src/gtkext/gtkblockview.c
+++ b/src/gtkext/gtkblockview.c
@@ -36,8 +36,11 @@
#include "../analysis/exporter.h"
#include "../common/dllist.h"
#include "../glibext/delayed-int.h"
+#include "../glibext/gcodebuffer.h"
+#include "../glibext/gbuffersegment.h"
+
#ifndef _
# define _(str) str
@@ -104,6 +107,7 @@ struct _GtkBlockView
bool show_vaddress; /* Affichage des adresses ? */
bool show_code; /* Affichage du code brut ? */
+ GBufferView *buffer_view; /* Code sous forme de texte */
GtkTextBuffer *buffer; /* Code sous forme de texte */
GtkTextLayout *layout; /* Disposition du texte */
@@ -114,6 +118,12 @@ struct _GtkBlockView
const exe_format *format; /* Format du contenu bianire */
+
+
+ GCodeBuffer *_buffer; /* Code sous forme de texte */
+
+
+
};
struct _GtkBlockViewClass
@@ -205,6 +215,10 @@ static void gtk_block_view_size_allocate(GtkWidget *widget,
static gboolean gtk_block_view_button_press(GtkWidget *, GdkEventButton *event);
+
+/* Imprime d'éventuelles informations liées à une ligne. */
+static void gtk_block_view_draw_line_extra(GBufferLine *, GdkDrawable *, GdkGC *, gint, gint, void *);
+
/* Met à jour l'affichage de la vue sous forme de bloc. */
static gboolean gtk_block_view_expose(GtkWidget *, GdkEventExpose *);
@@ -308,11 +322,16 @@ static void g_delayed_insertion_process(GDelayedInsertion *insertion, GtkExtStat
vmpa_t start; /* Adresse de début de parcours*/
vmpa_t end; /* Adresse de fin de parcours */
guint id; /* Identifiant de statut */
+ GRenderingOptions *options; /* Options de rendu */
GRenderingLine *iter; /* Boucle de parcours */
GtkTextIter pos; /* Point d'insertion */
- GtkTextMark *mark; /* Marquage de ligne associée */
+ GBufferLine *line; /* Ligne de destination */
+ //GtkTextMark *mark; /* Marquage de ligne associée */
vmpa_t done; /* Quantité déjà parcourue */
+ clock_t _start, _end;
+ double cpu_time_used;
+
view = insertion->view;
lines = GTK_BIN_VIEW(view)->lines;
@@ -332,6 +351,10 @@ static void g_delayed_insertion_process(GDelayedInsertion *insertion, GtkExtStat
id = gtk_extended_status_bar_push(statusbar, _("Inserting lines..."), true);
+ options = g_openida_binary_get_options(GTK_BIN_VIEW(view)->binary);
+
+ _start = clock();
+
for (iter = lines;
iter != NULL;
iter = g_rendering_line_get_next_iter(lines, iter, last))
@@ -339,8 +362,16 @@ static void g_delayed_insertion_process(GDelayedInsertion *insertion, GtkExtStat
g_signal_connect(iter, "rendering-line-flags-changed",
G_CALLBACK(gtk_block_view_update_margin), view);
- gdk_threads_enter();
+ //gdk_threads_enter();
+ line = g_code_buffer_append_new_line(view->_buffer);
+
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(iter), line, options);
+ g_object_set_data(G_OBJECT(line), "line", iter);
+
+
+
+#if 0
if (iter != lines)
gtk_text_buffer_insert_with_tags(view->buffer, &pos, "\n", 1, NULL);
@@ -351,17 +382,33 @@ static void g_delayed_insertion_process(GDelayedInsertion *insertion, GtkExtStat
g_content_exporter_add_to_gtk_buffer(G_CONTENT_EXPORTER(iter), view->rendering,
view->buffer, &pos, insertion->lengths);
+#endif
+ /*
gdk_flush ();
gdk_threads_leave();
+ */
done = get_rendering_line_address(iter) + get_rendering_line_length(iter) - start;
gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / end);
}
+
+ _end = clock();
+
+ cpu_time_used = ((double) (_end - _start)) / (CLOCKS_PER_SEC / 1000);
+
+ printf(" ### TEMPS passé ::: %g ms (pid = %d)\n", cpu_time_used, getpid());
+
+
gtk_extended_status_bar_remove(statusbar, id);
+ view->buffer_view = g_buffer_view_new(view->_buffer);
+
+ g_buffer_view_define_extra_drawing(view->buffer_view, gtk_block_view_draw_line_extra, view);
+
+
}
@@ -550,6 +597,10 @@ static void gtk_block_view_init(GtkBlockView *view)
}
+
+ view->_buffer = g_code_buffer_new();
+
+
}
@@ -568,16 +619,11 @@ static void gtk_block_view_init(GtkBlockView *view)
static void gtk_block_view_realize(GtkWidget *widget)
{
GtkBinViewClass *parent_class; /* Version pure du parent */
- PangoFontDescription *font_desc;
parent_class = GTK_BIN_VIEW_CLASS(g_type_class_peek_parent(GTK_BLOCK_VIEW_GET_CLASS(widget)));
GTK_WIDGET_CLASS(parent_class)->realize(widget);
- font_desc = pango_font_description_from_string("mono 10");
- gtk_widget_modify_font(widget, font_desc);
- pango_font_description_free(font_desc);
-
}
@@ -596,8 +642,11 @@ static void gtk_block_view_realize(GtkWidget *widget)
static void gtk_block_view_size_request(GtkWidget *widget, GtkRequisition *requisition)
{
- gtk_text_layout_get_size(GTK_BLOCK_VIEW(widget)->layout,
- &requisition->width, &requisition->height);
+ g_buffer_view_get_size(GTK_BLOCK_VIEW(widget)->buffer_view,
+ &requisition->width, &requisition->height);
+
+ printf(" === size req :: (%d ; %d)\n",
+ requisition->width, requisition->height);
}
@@ -637,7 +686,7 @@ static void gtk_block_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
if (view->hadjustment == NULL || view->vadjustment == NULL)
return;
- gtk_text_layout_get_size(GTK_BLOCK_VIEW(view)->layout, &width, &height);
+ g_buffer_view_get_size(GTK_BLOCK_VIEW(view)->buffer_view, &width, &height);
gtk_bin_view_compute_allocation(view, &valloc);
@@ -786,6 +835,74 @@ static void gtk_block_view_compute_real_coord(GtkBlockView *view, gint *x, gint
/******************************************************************************
* *
+* Paramètres : line = ligne de texte à manipuler. *
+* drawable = surface de rendu où travailler. *
+* gc = contexte graphique à utiliser pour les pinceaux. *
+* x = abscisse du point d'impression décallé. *
+* y = ordonnée du point d'impression décallé. *
+* data = pointeur vers le composant GTK de support. *
+* *
+* Description : Imprime d'éventuelles informations liées à une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_block_view_draw_line_extra(GBufferLine *line, GdkDrawable *drawable, GdkGC *gc, gint x, gint y, void *data)
+{
+ GRenderingLine *rline; /* Ligne de rendu représentée */
+ GtkBlockViewClass *class; /* Classe contenant les images */
+ gint line_height; /* Hauteur d'une ligne */
+ RenderingLineFlag flags; /* Propriétés de la ligne */
+ int height; /* Hauteur de l'image */
+ GdkPixbuf *pixbuf; /* Données utiles au dessin */
+
+ rline = G_RENDERING_LINE(g_object_get_data(G_OBJECT(line), "line"));
+ class = GTK_BLOCK_VIEW_GET_CLASS(data);
+
+ line_height = g_buffer_view_get_line_height(GTK_BLOCK_VIEW(data)->buffer_view);
+
+ flags = g_rendering_line_get_flags(rline);
+
+ if (flags & RLF_RUNNING_BP)
+ pixbuf = class->stopped_pix;
+
+ else if (flags & RLF_BREAK_POINT)
+ pixbuf = class->breakpoint_pix;
+
+ else pixbuf = NULL;
+
+ if (pixbuf != NULL)
+ {
+ height = gdk_pixbuf_get_height(pixbuf);
+
+ gdk_draw_pixbuf(drawable, gc, pixbuf, 0, 0, x + 10,
+ y + (line_height - height) / 2,
+ gdk_pixbuf_get_width(pixbuf), height,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ }
+
+ /* Le point d'entrée prime */
+ if (flags & RLF_ENTRY_POINT)
+ {
+ pixbuf = class->entry_pix;
+ height = gdk_pixbuf_get_height(pixbuf);
+
+ gdk_draw_pixbuf(drawable, gc, pixbuf, 0, 0, x + 10,
+ y + (line_height - height) / 2,
+ gdk_pixbuf_get_width(pixbuf), height,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à redessiner. *
* event = informations liées à l'événement. *
* *
@@ -802,33 +919,18 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event)
GtkBlockView *view; /* Autre version du composant */
GtkBinView *bview; /* Autre version du composant */
GtkStyle *style; /* Style associé au composant */
+ GdkDrawable *drawable; /* Surface de dessin */
gint fake_x; /* Abscisse virtuelle */
gint fake_y; /* Ordonnée virtuelle */
GtkBinViewClass *parent_class; /* Version pure du parent */
- GtkTextIter iter; /* Point d'insertion */
- GdkRectangle rect; /* Zone d'un point */
- GtkTextMark *mark; /* Marquage de ligne associée */
- GRenderingLine *line; /* Ligne de rendu */
- RenderingLineFlag flags; /* Propriétés de la ligne */
- GdkPixbuf *pixbuf; /* Données utiles au dessin */
-
-
- //GdkGCValues values; /* Propriétés du contexte */
- //GdkColor white; /* Couleur du fond */
- //int width; /* Largeur de l'élément */
- //int height; /* Hauteur de l'élément */
- //int y; /* Ordonnée du haut d'une ligne*/
- //GRenderingLine *iter; /* Boucle de parcours */
-
-
- GList *child_exposes;
view = GTK_BLOCK_VIEW(widget);
-
widget = GTK_WIDGET(view);
bview = GTK_BIN_VIEW(widget);
- gdk_window_begin_paint_region(GDK_DRAWABLE(widget->window), event->region);
+ drawable = GDK_DRAWABLE(event->window);
+
+ gdk_window_begin_paint_region(drawable, event->region);
gdk_gc_set_clip_region(bview->gc, event->region);
@@ -842,12 +944,12 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event)
gdk_gc_set_foreground(bview->gc, &style->mid[GTK_WIDGET_STATE(widget)]);
- gdk_draw_rectangle(GDK_DRAWABLE(widget->window), bview->gc, TRUE,
+ gdk_draw_rectangle(drawable, bview->gc, TRUE,
fake_x, event->area.y, view->left_margin, event->area.y + event->area.height);
gdk_gc_set_foreground(bview->gc, &style->dark[GTK_WIDGET_STATE(widget)]);
- gdk_draw_line(GDK_DRAWABLE(widget->window), bview->gc,
+ gdk_draw_line(drawable, bview->gc,
fake_x + view->left_margin, event->area.y,
fake_x + view->left_margin, event->area.y + event->area.height);
@@ -857,58 +959,11 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event)
GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event);
- /* Informations individuelles des lignes */
-
- gtk_text_layout_get_line_at_y(view->layout, &iter, fake_y, NULL);
- gtk_text_layout_get_iter_location(view->layout, &iter, &rect);
-
- while (rect.y < (fake_y + event->area.height))
- {
- gtk_block_view_compute_real_coord(view, &rect.x, &rect.y);
-
- mark = gtk_text_iter_get_marks(&iter)->data;
-
- line = g_object_get_data(G_OBJECT(mark), "line");
- if (line == NULL) break;
-
- flags = g_rendering_line_get_flags(line);
-
- if (flags & RLF_RUNNING_BP)
- pixbuf = GTK_BLOCK_VIEW_GET_CLASS(view)->stopped_pix;
-
- else if (flags & RLF_BREAK_POINT)
- pixbuf = GTK_BLOCK_VIEW_GET_CLASS(view)->breakpoint_pix;
-
- else pixbuf = NULL;
-
- if (pixbuf != NULL)
- gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), bview->gc, pixbuf, 0, 0, fake_x + 10, rect.y,
- gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf),
- GDK_RGB_DITHER_NORMAL, 0, 0);
-
- /* Le point d'entrée prime */
- if (flags & RLF_ENTRY_POINT)
- {
- pixbuf = GTK_BLOCK_VIEW_GET_CLASS(view)->entry_pix;
-
- gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), bview->gc, pixbuf, 0, 0, fake_x + 10, rect.y,
- gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf),
- GDK_RGB_DITHER_NORMAL, 0, 0);
-
- }
-
- if (!gtk_text_layout_move_iter_to_next_line(view->layout, &iter)) break;
- gtk_text_layout_get_iter_location(view->layout, &iter, &rect);
-
- }
-
/* Impression du désassemblage */
- gtk_text_layout_draw(GTK_BLOCK_VIEW(bview)->layout, widget, GDK_DRAWABLE(widget->window),
- NULL, -fake_x + view->left_text, fake_y, event->area.x, event->area.y,
- event->area.width, event->area.height, &child_exposes);
+ g_buffer_view_draw(view->buffer_view, event, bview->gc, fake_x, fake_y);
- gdk_window_end_paint(GDK_DRAWABLE(widget->window));
+ gdk_window_end_paint(drawable);
return TRUE;
@@ -1160,7 +1215,7 @@ void gtk_block_view_recompute_size_request(GtkBlockView *view)
gint width; /* Largeur de l'objet actuelle */
gint height; /* Hauteur de l'objet actuelle */
- gtk_text_layout_get_size(view->layout, &width, &height);
+ g_buffer_view_get_size(view->buffer_view, &width, &height);
width += -view->left_text + 1;
height += 1;
diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c
index 79beda2..a177d18 100644
--- a/src/gtkext/gtkextstatusbar.c
+++ b/src/gtkext/gtkextstatusbar.c
@@ -174,20 +174,21 @@ void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, guint id, gdo
if (bar->msg_count == 0) return;
- gdk_threads_enter();
-
if (id == bar->msg_id[bar->msg_count - 1] && bar->is_progressive[bar->msg_count - 1])
{
+ if (value != 1.0 && value - gtk_progress_bar_get_fraction(bar->progress) < 0.01)
+ return;
+
g_snprintf(percent, 5, "%.0f%%", value * 100);
+ gdk_threads_enter();
+
gtk_progress_bar_set_fraction(bar->progress, value);
gtk_progress_bar_set_text(bar->progress, percent);
- }
+ gdk_threads_leave();
- gdk_flush ();
-
- gdk_threads_leave();
+ }
}
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index f242cba..8139e08 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -130,7 +130,7 @@ void browse_directory_for_plugins(plugins_list *list, const char *dir)
int ret; /* Bilan du parcours */
char *filename; /* Elément à ausculter */
GPluginModule *plugin; /* Greffon à intégrer ou pas */
-
+ return;
ret = scandir(dir, &namelist, filter_dirs_or_mods, alphasort);
if (ret < 0)
{