diff options
| -rw-r--r-- | ChangeLog | 34 | ||||
| -rw-r--r-- | src/analysis/exporter-int.h | 10 | ||||
| -rw-r--r-- | src/analysis/exporter.c | 92 | ||||
| -rw-r--r-- | src/analysis/exporter.h | 8 | ||||
| -rw-r--r-- | src/analysis/line_code.c | 84 | ||||
| -rw-r--r-- | src/arch/immediate.c | 91 | ||||
| -rw-r--r-- | src/arch/instruction.c | 60 | ||||
| -rw-r--r-- | src/arch/x86/operand.c | 206 | ||||
| -rw-r--r-- | src/arch/x86/registers.c | 33 | ||||
| -rw-r--r-- | src/glibext/Makefile.am | 5 | ||||
| -rw-r--r-- | src/glibext/gbufferline.c | 359 | ||||
| -rw-r--r-- | src/glibext/gbufferline.h | 86 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.c | 391 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.h | 65 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.c | 483 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.h | 102 | ||||
| -rw-r--r-- | src/gtkext/gtkblockview.c | 217 | ||||
| -rw-r--r-- | src/gtkext/gtkextstatusbar.c | 13 | ||||
| -rw-r--r-- | src/plugins/pglist.c | 2 | 
19 files changed, 2218 insertions, 123 deletions
@@ -1,3 +1,37 @@ +10-04-11  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/exporter.c: +	* src/analysis/exporter.h: +	* src/analysis/exporter-int.h: +	* src/analysis/line_code.c: +	* src/arch/immediate.c: +	* src/arch/instruction.c: +	* src/arch/x86/operand.c: +	* src/arch/x86/registers.c: +	Export content into the new display buffer format (line of code only). + +	* src/glibext/gbufferline.c: +	* src/glibext/gbufferline.h: +	* src/glibext/gbuffersegment.c: +	* src/glibext/gbuffersegment.h: +	* src/glibext/gcodebuffer.c: +	* src/glibext/gcodebuffer.h: +	New entries: provide a faster than GTK display buffer. + +	* src/glibext/Makefile.am: +	Add the gbufferline.[ch], gbuffersegment.[ch] and gcodebuffer.[ch] +	files to libglibext_la_SOURCES. + +	* src/gtkext/gtkblockview.c: +	Display the view using the new internal display buffer. + +	* src/gtkext/gtkextstatusbar.c: +	Improve the processing time: skip all cases which don't change +	the progress status enough (< 1%). + +	* src/plugins/pglist.c: +	Disable all plugins (again). +  10-04-05  Cyrille Bagard <nocbos@gmail.com>  	* configure.ac: 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)      {  | 
