Re: Patch: ghex improvements.



Hi Michael,

Thanks heaps for looking over that - I appreciate it greatly!

I've made the changes you suggested (and a few minor ones), including
adding in a menu item to hide the thing (by default its visible,
though).

Jaka, Chema - Here is the new patch.

Cheers

David.
Index: src/ghex-ui.xml
===================================================================
RCS file: /cvs/gnome/ghex/src/ghex-ui.xml,v
retrieving revision 1.10
diff -u -r1.10 ghex-ui.xml
--- src/ghex-ui.xml	11 Nov 2002 13:35:38 -0000	1.10
+++ src/ghex-ui.xml	25 Sep 2003 02:02:59 -0000
@@ -38,6 +38,8 @@
 
 	<cmd name="CharacterTable" type="toggle" _label="Character Table..." _tip="Show the character table"/>
 
+	<cmd name="TypeDialog" type="toggle" _label="Type Conversion Dialog..." _tip="Show the type conversion dialog in the edit window"/>
+
 	<cmd name="EditUndo" _label="Undo" _tip="Undo the last action"
 	pixtype="stock" pixname="gtk-undo" accel="*Control*Z"/>
 
@@ -185,6 +187,8 @@
 	<menuitem name="CharacterTable" type="toggle" verb="" _label="Character _Table..."/>
 
 	<menuitem name="Converter" type="toggle" verb="" _label="_Base Converter"/>
+
+	<menuitem name="TypeDialog" type="toggle" verb="" _label="Type Conversion _Dialog"/>
 </submenu>
 
 <submenu name="Help" _label="_Help">
Index: src/ghex-window.c
===================================================================
RCS file: /cvs/gnome/ghex/src/ghex-window.c,v
retrieving revision 1.18
diff -u -r1.18 ghex-window.c
--- src/ghex-window.c	1 Sep 2003 15:41:43 -0000	1.18
+++ src/ghex-window.c	25 Sep 2003 02:03:02 -0000
@@ -238,6 +238,11 @@
                                                  win);
             win->gh = NULL;
         }
+        if (win->dialog)
+        {
+            g_object_unref (G_OBJECT(win->dialog));
+            win->dialog = NULL;
+        }
 
         window_list = g_list_remove(window_list, win);
 
@@ -406,6 +411,22 @@
         ghex_window_sync_char_table_item(win, atoi(state));
         return;
     }
+    else if (strcmp(path, "TypeDialog") == 0)
+    {
+        if (!win->dialog)
+            return;
+        if (state && atoi(state)) {
+            if (!GTK_WIDGET_VISIBLE(win->dialog_widget))
+            {
+                gtk_widget_show(win->dialog_widget);
+            }
+        }
+        else if (GTK_WIDGET_VISIBLE(win->dialog_widget))
+        {
+            gtk_widget_hide(GTK_WIDGET(win->dialog_widget));
+        }
+        return;
+    }
 	if (!state || !atoi (state) || (win->gh == NULL))
 		return;
 
@@ -465,12 +486,16 @@
                                       ghex_window_listener, win);
 	bonobo_ui_component_add_listener (uic, "CharacterTable",
                                       ghex_window_listener, win);
+	bonobo_ui_component_add_listener (uic, "TypeDialog",
+                                      ghex_window_listener, win);
     bonobo_ui_component_set_prop (uic, "/commands/Converter", "state",
                                   (converter && GTK_WIDGET_VISIBLE(converter->window))?"1":"0",
                                   NULL);
     bonobo_ui_component_set_prop (uic, "/commands/CharacterTable", "state",
                                   (char_table && GTK_WIDGET_VISIBLE(char_table))?"1":"0",
                                   NULL);
+    bonobo_ui_component_set_prop (uic, "/commands/TypeDialog", "state",
+                                  "1", NULL);
 	bonobo_ui_component_set_prop (uic, "/status", "hidden", "0", NULL);
 
     ghex_window_set_sensitivity(win);
@@ -566,15 +591,26 @@
 cursor_moved_cb(GtkHex *gtkhex, gpointer user_data)
 {
 	static gchar *cursor_pos, *format;
+    int i;
+    int current_pos;
+    HexDialogVal64 val;
 	GHexWindow *win = GHEX_WINDOW(user_data);
 
+    current_pos = gtk_hex_get_cursor(gtkhex);
+
 	if((format = g_strdup_printf(_("Offset: %s"), offset_fmt)) != NULL) {
-		if((cursor_pos = g_strdup_printf(format, gtk_hex_get_cursor(gtkhex))) != NULL) {
+		if((cursor_pos = g_strdup_printf(format, current_pos)) != NULL) {
 			ghex_window_show_status(win, cursor_pos);
             g_free(cursor_pos);
 		}
 		g_free(format);
 	}
+    for (i = 0; i < 8; i++)
+    {
+        /* returns  0 on buffer overflow, which is what we want */
+        val.v[i] = gtk_hex_get_byte(gtkhex, current_pos+i);
+    }
+    hex_dialog_updateview(win->dialog, &val);
 }
 
 gboolean
@@ -583,7 +619,9 @@
     gchar *full_path;
     HexDocument *doc;
     GtkWidget *gh;
+    GtkWidget *vbox;
     const GList *window_list;
+    gchar *state;
 
     g_return_val_if_fail(win != NULL, FALSE);
     g_return_val_if_fail(GHEX_IS_WINDOW(win), FALSE);
@@ -611,7 +649,24 @@
     g_signal_connect(G_OBJECT(gh), "cursor_moved",
                      G_CALLBACK(cursor_moved_cb), win);
     gtk_widget_show(gh);
-    
+
+    vbox = gtk_vbox_new(FALSE, 0);
+    gtk_widget_show(vbox);
+    gtk_box_pack_start(GTK_BOX(vbox), gh, TRUE, TRUE, GNOME_PAD);
+
+    win->dialog = hex_dialog_new();
+    win->dialog_widget = hex_dialog_getview(win->dialog);
+    gtk_box_pack_start(GTK_BOX(vbox), win->dialog_widget, FALSE, FALSE, GNOME_PAD);
+    state = bonobo_ui_component_get_prop (win->uic, "/commands/TypeDialog", "state", NULL);
+    if ((state && atoi(state)) || !state)
+    {
+      gtk_widget_show(win->dialog_widget);
+    }
+    else
+    {
+      gtk_widget_hide(win->dialog_widget);
+    }
+
     if(win->gh) {
         window_list = ghex_window_get_list();
         while(window_list) {
@@ -626,7 +681,7 @@
                                              ghex_window_doc_changed,
                                              win);
     }
-    bonobo_window_set_contents(BONOBO_WINDOW(win), gh);
+    bonobo_window_set_contents(BONOBO_WINDOW(win), vbox);
     win->gh = GTK_HEX(gh);
     win->changed = FALSE;
 
@@ -639,6 +694,8 @@
     ghex_window_sync_group_type(win);
     ghex_window_set_doc_name(win, win->gh->document->path_end);
     ghex_window_set_sensitivity(win);
+
+    gtk_signal_emit_by_name(GTK_OBJECT(gh), "cursor_moved");
    
     return TRUE;
 }
Index: src/ghex-window.h
===================================================================
RCS file: /cvs/gnome/ghex/src/ghex-window.h,v
retrieving revision 1.4
diff -u -r1.4 ghex-window.h
--- src/ghex-window.h	26 Oct 2002 17:51:02 -0000	1.4
+++ src/ghex-window.h	25 Sep 2003 02:03:03 -0000
@@ -44,6 +44,9 @@
     BonoboUIComponent *uic;
     gboolean changed, undo_sens, redo_sens;
 
+    HexDialog *dialog;
+    GtkWidget *dialog_widget;
+
     gchar **uris_to_open;
 };
 
Index: src/gtkhex.h
===================================================================
RCS file: /cvs/gnome/ghex/src/gtkhex.h,v
retrieving revision 1.21
diff -u -r1.21 gtkhex.h
--- src/gtkhex.h	6 Jan 2003 21:25:29 -0000	1.21
+++ src/gtkhex.h	25 Sep 2003 02:03:03 -0000
@@ -28,6 +28,7 @@
 #include <gdk/gdk.h>
 
 #include <hex-document.h>
+#include <hex-dialog.h>
 
 #ifdef __cplusplus
 extern "C" {
Index: src/hex-document.h
===================================================================
RCS file: /cvs/gnome/ghex/src/hex-document.h,v
retrieving revision 1.19
diff -u -r1.19 hex-document.h
--- src/hex-document.h	21 Feb 2003 20:13:28 -0000	1.19
+++ src/hex-document.h	25 Sep 2003 02:03:03 -0000
@@ -31,7 +31,7 @@
 #define HEX_DOCUMENT_TYPE          (hex_document_get_type())
 #define HEX_DOCUMENT(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, hex_document_get_type (), HexDocument)
 #define HEX_DOCUMENT_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, hex_document_get_type (), HexDocumentClass)
-#define IS_HEX_DOCUMENT(obj)       G_CHECK_INSTANCE_TYPE (obj, hex_document_get_type ())
+#define IS_HEX_DOCUMENT(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, hex_document_get_type ())
 
 typedef struct _HexDocument       HexDocument;
 typedef struct _HexDocumentClass  HexDocumentClass;
--- /dev/null	2003-08-28 21:02:17.000000000 +1000
+++ src/hex-dialog.c	2003-09-25 10:59:54.000000000 +1000
@@ -0,0 +1,616 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copright (c) David Hammerton 2003
+ * David Hammerton <crazney crazney net>
+ *
+ *  GHex 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 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  GHex 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 GHex; see the file COPYING.
+ *  If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib-object.h>
+
+#include <gtkhex.h>
+#include <gnome.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <string.h>
+
+static void hex_dialog_class_init     (HexDialogClass *);
+static void hex_dialog_init           (HexDialog *);
+static void hex_dialog_destroy        (GtkObject *);
+
+void hex_dialog_updateview(HexDialog *dialog, HexDialogVal64 *val);
+
+/* conversion functions */
+char *HexConvert_S8(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_US8(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_S16(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_US16(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_S32(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_US32(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_32float(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_64float(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_hex(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_oct(HexDialogVal64 *val, HexConversionProperties *prop);
+char *HexConvert_bin(HexDialogVal64 *val, HexConversionProperties *prop);
+
+static struct {
+    char *name;
+    char *(*conv_function)(HexDialogVal64 *val, HexConversionProperties *prop);
+} HexDialogEntries[ENTRY_MAX] = {
+    "Signed 8 bit:", HexConvert_S8,
+    "Unsigned 8 bit:", HexConvert_US8,
+    "Signed 16 bit:", HexConvert_S16,
+    "Unsigned 16 bit:", HexConvert_US16,
+    "Signed 32 bit:", HexConvert_S32,
+    "Unsigned 32 bit:", HexConvert_US32,
+    "32 bit float:", HexConvert_32float,
+    "64 bit float:", HexConvert_64float,
+    "Hexadecimal:", HexConvert_hex,
+    "Octal:", HexConvert_oct,
+    "Binary:", HexConvert_bin
+};
+
+
+
+GType hex_dialog_get_type ()
+{
+    static GtkType doc_type = 0;
+
+    if (doc_type == 0)
+    {
+        static const GTypeInfo doc_info =
+        {
+            sizeof (HexDialogClass),
+            NULL,       /* base_init */
+            NULL,       /* base_finalize */
+            (GClassInitFunc) hex_dialog_class_init,
+            NULL,       /* class_finalize */
+            NULL,       /* class_data */
+            sizeof (HexDialog),
+            0,
+            (GInstanceInitFunc) hex_dialog_init
+        };
+
+        doc_type = g_type_register_static (G_TYPE_OBJECT,
+                                           "HexDialog",
+                                           &doc_info,
+                                           0);
+    }
+    return doc_type;
+}
+
+static void hex_dialog_init (HexDialog *dialog)
+{
+    int i;
+    for (i = 0; i < ENTRY_MAX; i++)
+        dialog->entry[i] = NULL;
+    dialog->config_endian = NULL;
+    dialog->config_hex = NULL;
+    dialog->properties.endian = LITTLE;
+    dialog->properties.hexHint = FALSE;
+    dialog->properties.streamBitsHint = 8;
+    for (i = 0; i < 8; i++)
+        dialog->val.v[i] = 0;
+}
+
+static void hex_dialog_class_init (HexDialogClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+}
+
+HexDialog *hex_dialog_new()
+{
+    HexDialog *dialog;
+
+    dialog = HEX_DIALOG(g_object_new(HEX_DIALOG_TYPE, NULL));
+    g_return_val_if_fail (dialog != NULL, NULL);
+
+    return dialog;
+}
+
+static void create_dialog_prop(HexDialogEntryTypes type,
+                               HexDialog *dialog, GtkWidget *table,
+                               gint xpos, gint ypos)
+{
+    GtkWidget *label;
+
+    label = gtk_label_new(HexDialogEntries[type].name);
+    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+    gtk_table_attach_defaults(GTK_TABLE(table), label, xpos, xpos+1, ypos, ypos+1);
+    gtk_widget_show(label);
+
+    dialog->entry[type] = gtk_entry_new();
+    gtk_editable_set_editable(GTK_EDITABLE(dialog->entry[type]), FALSE);
+    gtk_table_attach_defaults(GTK_TABLE(table), dialog->entry[type], xpos+1,
+                              xpos+2, ypos, ypos+1);
+    gtk_widget_show(dialog->entry[type]);
+}
+
+static void config_toggled_cb(GtkToggleButton *togglebutton, gpointer user_data)
+{
+    HexDialog *dialog = HEX_DIALOG(user_data);
+    dialog->properties.endian = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->config_endian)) ?
+                                LITTLE : BIG;
+    dialog->properties.hexHint = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->config_hex));
+    hex_dialog_updateview(dialog, NULL);
+}
+
+static void config_spinchange_cb(GtkSpinButton *spinbutton, gpointer user_data)
+{
+    HexDialog *dialog = HEX_DIALOG(user_data);
+    dialog->properties.streamBitsHint = (guchar)gtk_spin_button_get_value(spinbutton);
+    hex_dialog_updateview(dialog, NULL);
+}
+
+GtkWidget *hex_dialog_getview(HexDialog *dialog)
+{
+
+    GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
+    GtkWidget *hbox;
+    GtkWidget *table = gtk_table_new(4, 6, FALSE);
+    GtkWidget *label;
+    GtkAdjustment *adjuster;
+    GtkWidget *spin;
+    gtk_widget_show(table);
+    gtk_widget_show(vbox);
+
+    gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, FALSE, GNOME_PAD_SMALL);
+
+    gtk_table_set_row_spacings(GTK_TABLE(table), GNOME_PAD_SMALL);
+    gtk_table_set_col_spacings(GTK_TABLE(table), GNOME_PAD_SMALL);
+
+    create_dialog_prop(S8, dialog, table, 0, 0);
+    create_dialog_prop(US8, dialog, table, 0, 1);
+    create_dialog_prop(S16, dialog, table, 0, 2);
+    create_dialog_prop(US16, dialog, table, 0, 3);
+
+    create_dialog_prop(S32, dialog, table, 2, 0);
+    create_dialog_prop(US32, dialog, table, 2, 1);
+    create_dialog_prop(FLOAT32, dialog, table, 2, 2);
+    create_dialog_prop(FLOAT64, dialog, table, 2, 3);
+
+    create_dialog_prop(HEX, dialog, table, 4, 0);
+    create_dialog_prop(OCT, dialog, table, 4, 1);
+    create_dialog_prop(BIN, dialog, table, 4, 2);
+
+    hbox = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, GNOME_PAD_SMALL);
+    gtk_widget_show(hbox);
+
+    dialog->config_endian = gtk_check_button_new_with_label("Show little endian decoding");
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->config_endian), TRUE);
+    g_signal_connect(G_OBJECT(dialog->config_endian), "toggled",
+                     G_CALLBACK(config_toggled_cb), dialog);
+    gtk_widget_show(dialog->config_endian);
+    gtk_box_pack_start(GTK_BOX(hbox), dialog->config_endian, TRUE, FALSE, GNOME_PAD_SMALL);
+
+    dialog->config_hex = gtk_check_button_new_with_label("Show unsigned and float as hexadecimal");
+    g_signal_connect(G_OBJECT(dialog->config_hex), "toggled",
+                     G_CALLBACK(config_toggled_cb), dialog);
+    gtk_widget_show(dialog->config_hex);
+    gtk_box_pack_start(GTK_BOX(hbox), dialog->config_hex, TRUE, FALSE, GNOME_PAD_SMALL);
+
+    label = gtk_label_new("Stream Length:");
+    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+    gtk_table_attach_defaults(GTK_TABLE(table), label, 4, 5, 3, 4);
+    gtk_widget_show(label);
+
+    adjuster = (GtkAdjustment *)gtk_adjustment_new(8.0, 1.0, 32.0, 1.0, 8.0, 8.0);
+    spin = gtk_spin_button_new(adjuster, 1.0, 0);
+    g_signal_connect(G_OBJECT(spin), "value-changed",
+                     G_CALLBACK(config_spinchange_cb), dialog);
+    gtk_table_attach_defaults(GTK_TABLE(table), spin, 5, 6, 3, 4);
+    gtk_widget_show(spin);
+
+    return vbox;
+}
+
+static void update_dialog_prop(HexDialogEntryTypes type,
+                               HexDialog *dialog, HexDialogVal64 *val)
+{
+    char *buf;
+    if (HexDialogEntries[type].conv_function)
+        buf = HexDialogEntries[type].conv_function(val, &dialog->properties);
+    else
+        buf = "FIXME: no conversion function";
+    gtk_entry_set_text(GTK_ENTRY(dialog->entry[type]), buf);
+}
+
+/* if val is NULL, uses the previous used val */
+void hex_dialog_updateview(HexDialog *dialog, HexDialogVal64 *val)
+{
+    int i;
+    if (val)
+    {
+        for (i = 0; i < 8; i++)
+        {
+            dialog->val.v[i] = val->v[i];
+        }
+    }
+    for (i = 0; i < ENTRY_MAX; i++)
+    {
+        update_dialog_prop(i, dialog, &dialog->val);
+    }
+}
+
+/* used for conversions, this can be global, since it need not be
+ * reentrant */
+#define CONV_BUFSIZE 64
+static char convbuffer[CONV_BUFSIZE];
+
+/* conversion functions */
+
+/* the conversion functions are slow on purpose, we interpret
+ * all bits manually in order to allow for the future possibility
+ * of different byte sizes.
+ * also makes it endian safe (i think)
+ */
+
+unsigned int pow2(int p)
+{
+    unsigned int i = 0, r = 1;
+    for (i = 0; i < p; i++)
+        r*=2;
+    return r;
+}
+
+double fpow10(int p)
+{
+    return pow(10, p);
+}
+
+double fpow2(int p)
+{
+    return pow(2.0, p);
+}
+
+char *HexConvert_S8(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    int i, local = 0;
+    for (i = 0; i < 7; i++)
+        local += ((val->v[0] >> i) & 0x1) * pow2(i);
+    if ((val->v[0] >> 7) & 0x1)
+        local  = -(pow2(7) - local);
+    snprintf(convbuffer, sizeof(convbuffer), "%d", local);
+    return convbuffer;
+}
+
+char *HexConvert_US8(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    int i, local = 0;
+    for (i = 0; i < 8; i++)
+        local += ((val->v[0] >> i) & 0x1) * pow2(i);
+
+    if (!prop->hexHint)
+        snprintf(convbuffer, sizeof(convbuffer), "%u", local);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "0x%02X", local);
+    return convbuffer;
+}
+
+char *HexConvert_S16(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    guchar in[2];
+    int i, local = 0;
+    if (prop->endian == LITTLE)
+    {
+        in[0] = val->v[0];
+        in[1] = val->v[1];
+    }
+    else
+    {
+        in[0] = val->v[1];
+        in[1] = val->v[0];
+    }
+    for (i = 0; i < 8; i++)
+        local += ((in[0] >> i) & 0x1) * pow2(i);
+    for (i = 0; i < 7; i++)
+        local += ((in[1] >> i) & 0x1) * pow2(i + 8);
+    if ((in[1] >> 7) & 0x1)
+        local  = -(pow2(15) - local);
+    snprintf(convbuffer, sizeof(convbuffer), "%d", local);
+    return convbuffer;
+}
+
+char *HexConvert_US16(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    guchar in[2];
+    int i, local = 0;
+    if (prop->endian == LITTLE)
+    {
+        in[0] = val->v[0];
+        in[1] = val->v[1];
+    }
+    else
+    {
+        in[0] = val->v[1];
+        in[1] = val->v[0];
+    }
+    for (i = 0; i < 8; i++)
+        local += ((in[0] >> i) & 0x1) * pow2(i);
+    for (i = 0; i < 8; i++)
+        local += ((in[1] >> i) & 0x1) * pow2(i + 8);
+
+    if (!prop->hexHint)
+        snprintf(convbuffer, sizeof(convbuffer), "%u", local);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "0x%04X", local);
+
+    return convbuffer;
+}
+
+char *HexConvert_S32(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    guchar in[4];
+    int i, local = 0;
+    if (prop->endian == LITTLE)
+    {
+        in[0] = val->v[0];
+        in[1] = val->v[1];
+        in[2] = val->v[2];
+        in[3] = val->v[3];
+    }
+    else
+    {
+        in[0] = val->v[3];
+        in[1] = val->v[2];
+        in[2] = val->v[1];
+        in[3] = val->v[0];
+    }
+    for (i = 0; i < 8; i++)
+        local += ((in[0] >> i) & 0x1) * pow2(i);
+    for (i = 0; i < 8; i++)
+        local += ((in[1] >> i) & 0x1) * pow2(i + 8);
+    for (i = 0; i < 8; i++)
+        local += ((in[2] >> i) & 0x1) * pow2(i + 16);
+    for (i = 0; i < 7; i++)
+        local += ((in[3] >> i) & 0x1) * pow2(i + 24);
+    if ((in[3] >> 7) & 0x1)
+        local  = -(pow2(31) - local);
+    snprintf(convbuffer, sizeof(convbuffer), "%d", local);
+    return convbuffer;
+}
+
+char *HexConvert_US32(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    guchar in[4];
+    unsigned int i, local = 0;
+    if (prop->endian == LITTLE)
+    {
+        in[0] = val->v[0];
+        in[1] = val->v[1];
+        in[2] = val->v[2];
+        in[3] = val->v[3];
+    }
+    else
+    {
+        in[0] = val->v[3];
+        in[1] = val->v[2];
+        in[2] = val->v[1];
+        in[3] = val->v[0];
+    }
+    for (i = 0; i < 8; i++)
+        local += ((in[0] >> i) & 0x1) * pow2(i);
+    for (i = 0; i < 8; i++)
+        local += ((in[1] >> i) & 0x1) * pow2(i + 8);
+    for (i = 0; i < 8; i++)
+        local += ((in[2] >> i) & 0x1) * pow2(i + 16);
+    for (i = 0; i < 8; i++)
+        local += ((in[3] >> i) & 0x1) * pow2(i + 24);
+
+    if (!prop->hexHint)
+        snprintf(convbuffer, sizeof(convbuffer), "%u", local);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "0x%08X", local);
+    return convbuffer;
+}
+
+/* for floats we just cast them, can't be bothered
+ * interpretting them properly
+ */
+char *HexConvert_32float(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    union
+    {
+        guchar c[4];
+        float f;
+    } in;
+
+    float local = 0.0;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    if (prop->endian == LITTLE)
+#else
+    if (prop->endian == BIG)
+#endif
+    {
+        in.c[0] = val->v[0];
+        in.c[1] = val->v[1];
+        in.c[2] = val->v[2];
+        in.c[3] = val->v[3];
+    }
+    else
+    {
+        in.c[0] = val->v[3];
+        in.c[1] = val->v[2];
+        in.c[2] = val->v[1];
+        in.c[3] = val->v[0];
+    }
+
+    local = in.f;
+
+    if (!prop->hexHint)
+        snprintf(convbuffer, sizeof(convbuffer), "%e", local);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "%A", local);
+    return convbuffer;
+}
+
+char *HexConvert_64float(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    union
+    {
+        guchar c[8];
+        double f;
+    } in;
+
+    double local = 0.0;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    if (prop->endian == LITTLE)
+#else
+    if (prop->endian == BIG)
+#endif
+    {
+        in.c[0] = val->v[0];
+        in.c[1] = val->v[1];
+        in.c[2] = val->v[2];
+        in.c[3] = val->v[3];
+        in.c[4] = val->v[4];
+        in.c[5] = val->v[5];
+        in.c[6] = val->v[6];
+        in.c[7] = val->v[7];
+    }
+    else
+    {
+        in.c[0] = val->v[3];
+        in.c[1] = val->v[2];
+        in.c[2] = val->v[1];
+        in.c[3] = val->v[0];
+        in.c[4] = val->v[7];
+        in.c[5] = val->v[6];
+        in.c[6] = val->v[5];
+        in.c[7] = val->v[4];
+    }
+
+    local = in.f;
+
+    if (!prop->hexHint)
+        snprintf(convbuffer, sizeof(convbuffer), "%e", local);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "%A", local);
+    return convbuffer;
+}
+
+/* these three care not for endianness, they take the input as a stream */
+char *HexConvert_hex(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    int i;
+    int local = 0;
+
+    int v[4];
+
+    v[0] = (prop->streamBitsHint >= 8) ? 8 : prop->streamBitsHint;
+    v[1] = (prop->streamBitsHint >= 16) ? 8 : prop->streamBitsHint - 8;
+    if (v[1] < 0) v[1] = 0;
+    v[2] = (prop->streamBitsHint >= 24) ? 8 : prop->streamBitsHint - 16;
+    if (v[2] < 0) v[2] = 0;
+    v[3] = prop->streamBitsHint - 24;
+    if (v[3] < 0) v[3] = 0;
+
+    for (i = 0; i < v[0]; i++)
+        local += ((val->v[0] >> i) & 0x1) * pow2(i);
+    for (i = 0; i < v[1]; i++)
+        local += ((val->v[1] >> i) & 0x1) * pow2(i + 8);
+    for (i = 0; i < v[2]; i++)
+        local += ((val->v[2] >> i) & 0x1) * pow2(i + 16);
+    for (i = 0; i < v[3]; i++)
+        local += ((val->v[3] >> i) & 0x1) * pow2(i + 24);
+
+    if (v[3])
+        snprintf(convbuffer, sizeof(convbuffer), "%02X %02X %02X %02X",
+                 (local & 0x000000ff),  (local & 0x0000ff00) >> 8,
+                 (local & 0x00ff0000) >> 16, (local & 0xff000000) >> 24);
+    else if (v[2])
+        snprintf(convbuffer, sizeof(convbuffer), "%02X %02X %02X",
+                 (local & 0x000000ff),  (local & 0x0000ff00) >> 8,
+                 (local & 0x00ff0000) >> 16);
+    else if (v[1])
+        snprintf(convbuffer, sizeof(convbuffer), "%02X %02X",
+                 (local & 0x000000ff),  (local & 0x0000ff00) >> 8);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "%02X",
+                 (local & 0x000000ff));
+
+    return convbuffer;
+}
+
+char *HexConvert_oct(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    int i;
+    int local = 0;
+
+    int v[4];
+
+    v[0] = (prop->streamBitsHint >= 8) ? 8 : prop->streamBitsHint;
+    v[1] = (prop->streamBitsHint >= 16) ? 8 : prop->streamBitsHint - 8;
+    if (v[1] < 0) v[1] = 0;
+    v[2] = (prop->streamBitsHint >= 24) ? 8 : prop->streamBitsHint - 16;
+    if (v[2] < 0) v[2] = 0;
+    v[3] = prop->streamBitsHint - 24;
+    if (v[3] < 0) v[3] = 0;
+
+    for (i = 0; i < v[0]; i++)
+        local += ((val->v[0] >> i) & 0x1) * pow2(i);
+    for (i = 0; i < v[1]; i++)
+        local += ((val->v[1] >> i) & 0x1) * pow2(i + 8);
+    for (i = 0; i < v[2]; i++)
+        local += ((val->v[2] >> i) & 0x1) * pow2(i + 16);
+    for (i = 0; i < v[3]; i++)
+        local += ((val->v[3] >> i) & 0x1) * pow2(i + 24);
+
+    if (v[3])
+        snprintf(convbuffer, sizeof(convbuffer), "%03o %03o %03o %03o",
+                 (local & 0x000000ff),  (local & 0x0000ff00) >> 8,
+                 (local & 0x00ff0000) >> 16, (local & 0xff000000) >> 24);
+    else if (v[2])
+        snprintf(convbuffer, sizeof(convbuffer), "%03o %03o %03o",
+                 (local & 0x000000ff),  (local & 0x0000ff00) >> 8,
+                 (local & 0x00ff0000) >> 16);
+    else if (v[1])
+        snprintf(convbuffer, sizeof(convbuffer), "%03o %03o",
+                 (local & 0x000000ff),  (local & 0x0000ff00) >> 8);
+    else
+        snprintf(convbuffer, sizeof(convbuffer), "%03o",
+                 (local & 0x000000ff));
+
+    return convbuffer;
+}
+
+char *HexConvert_bin(HexDialogVal64 *val, HexConversionProperties *prop)
+{
+    int i;
+
+    g_return_if_fail(prop->streamBitsHint <= 32);
+    convbuffer[0] = '\0';
+
+    for (i = 0; i < prop->streamBitsHint; i++)
+    {
+        int v = i < 8 ? 0 :
+                i < 16 ? 1 :
+                i < 24 ? 2 :
+                3;
+        int shift = 7 - ((v == 0) ? i : (i % (v * 8)));
+        convbuffer[i] = (val->v[v] >> shift & 0x1) ? '1' : '0';
+    }
+    convbuffer[i] = '\0';
+    return convbuffer;
+}
+
+
--- /dev/null	2003-08-28 21:02:17.000000000 +1000
+++ src/hex-dialog.h	2003-09-23 18:48:06.000000000 +1000
@@ -0,0 +1,93 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copright (c) David Hammerton 2003
+ * David Hammerton <crazney crazney net>
+ *
+ *  GHex 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 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  GHex 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 GHex; see the file COPYING.
+ *  If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __HEX_DIALOG_H__
+#define __HEX_DIALOG_H__
+
+#include <glib-object.h>
+
+#define HEX_DIALOG_TYPE           (hex_dialog_get_type())
+#define HEX_DIALOG(obj)           G_TYPE_CHECK_INSTANCE_CAST (obj, hex_dialog_get_type (), HexDialog)
+#define HEX_DIALOG_CLASS(klass)   G_TYPE_CHECK_CLASS_CAST (klass, hex_dialog_get_type (), HexDialogClass)
+#define IS_HEX_DIALOG(obj)        G_TYPE_CHECK_INSTANCE_TYPE (obj, hex_dialog_get_type ())
+
+
+typedef struct _HexDialog       HexDialog;
+typedef struct _HexDialogClass  HexDialogClass;
+
+typedef enum
+{
+    S8 = 0,
+    US8,
+    S16,
+    US16,
+    S32,
+    US32,
+    FLOAT32,
+    FLOAT64,
+    HEX,
+    OCT,
+    BIN,
+    ENTRY_MAX
+} HexDialogEntryTypes;
+
+typedef struct
+{
+    guchar v[8];
+} HexDialogVal64;
+
+typedef enum
+{
+    LITTLE,
+    BIG
+} HexEndian;
+
+typedef struct
+{
+    HexEndian endian;
+    gboolean hexHint;        /* only some functions use the Hint parameter */
+    guchar streamBitsHint;
+} HexConversionProperties;
+
+struct _HexDialog
+{
+    GObject gobject;
+
+    GtkWidget *entry[ENTRY_MAX];
+    GtkWidget *config_endian;
+    GtkWidget *config_hex;
+    HexConversionProperties properties;
+    HexDialogVal64 val;
+};
+
+struct _HexDialogClass
+{
+    GObjectClass parent_class;
+};
+
+GType        hex_dialog_get_type();
+HexDialog    *hex_dialog_new();
+GtkWidget    *hex_dialog_getview(HexDialog *);
+void         hex_dialog_updateview(HexDialog *dialog, HexDialogVal64 *val);
+
+
+#endif /* __HEX_DIALOG_H__ */
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]