aboutsummaryrefslogtreecommitdiffstats
path: root/hex.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2004-03-28 11:31:57 +0000
committerkraxel <kraxel>2004-03-28 11:31:57 +0000
commite9e9684117719204929821028ba9dbb7915ea119 (patch)
tree6dd2d71940b33a9f960945335e9124ef4fea9fe7 /hex.c
downloadfbida-e9e9684117719204929821028ba9dbb7915ea119.tar.gz
Initial revision
Diffstat (limited to 'hex.c')
-rw-r--r--hex.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/hex.c b/hex.c
new file mode 100644
index 0000000..b648233
--- /dev/null
+++ b/hex.c
@@ -0,0 +1,141 @@
+/*
+ * file viewer (hex dump)
+ * quick & dirty for now, handling xxl files doesn't work very well ...
+ *
+ * (c) 2001 Gerd Knorr <kraxel@bytesex.org>
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include <X11/Xlib.h>
+#include <X11/Intrinsic.h>
+#include <Xm/Xm.h>
+#include <Xm/Form.h>
+#include <Xm/Label.h>
+#include <Xm/RowColumn.h>
+#include <Xm/PushB.h>
+#include <Xm/ScrolledW.h>
+#include <Xm/SelectioB.h>
+
+#include "RegEdit.h"
+#include "hex.h"
+
+extern Display *dpy;
+extern Widget app_shell;
+
+/*----------------------------------------------------------------------*/
+
+static Widget hex_dlg, hex_label;
+
+static void
+hex_destroy(Widget widget, XtPointer clientdata, XtPointer call_data)
+{
+ XtDestroyWidget(hex_dlg);
+ hex_dlg = NULL;
+}
+
+static XmString
+hexify(int addr,unsigned char *data, int bytes)
+{
+ XmString xmpage,xmchunk;
+ char line[120];
+ int len,y,i;
+
+ xmpage = XmStringGenerate("", NULL, XmMULTIBYTE_TEXT, NULL);
+ for (y = 0; y < bytes; y += 16) {
+ /* hexify line */
+ len = sprintf(line,"%04x ",addr+y);
+ for (i = 0; i < 16; i++) {
+ if (y+i < bytes)
+ len += sprintf(line+len,"%02x ",data[y+i]);
+ else
+ len += sprintf(line+len," ");
+ if (3 == i%4)
+ len += sprintf(line+len," ");
+ }
+ for (i = 0; i < 16; i++) {
+ if (y+i < bytes)
+ if (isprint(data[y+i]))
+ len += sprintf(line+len,"%c",data[y+i]);
+ else
+ len += sprintf(line+len,".");
+ else
+ len += sprintf(line+len," ");
+ }
+ len += sprintf(line+len,"\n");
+ /* add last chunk for line */
+ xmchunk = XmStringGenerate(line, NULL, XmMULTIBYTE_TEXT, NULL);
+ xmpage = XmStringConcatAndFree(xmpage, xmchunk);
+ }
+ return xmpage;
+}
+
+/* guess whenever we have ascii or binary data */
+static int
+is_binary(unsigned char *data, int bytes)
+{
+ int i, bin;
+
+ bin = 0;
+ for (i = 0; i < 64 && i < bytes; i++) {
+ if (!isprint(data[i]) &&
+ data[i] != '\t' &&
+ data[i] != '\n')
+ bin = 1;
+ }
+ return bin;
+}
+
+void
+hex_display(char *filename)
+{
+ Widget view;
+ XmString xmpage,chunk;
+ unsigned char data[32768+1];
+ int chars;
+ FILE *fp;
+
+ /* build dialog */
+ if (!hex_dlg) {
+ hex_dlg = XmCreatePromptDialog(app_shell,"hex",NULL,0);
+ XmdRegisterEditres(XtParent(hex_dlg));
+ XtUnmanageChild(XmSelectionBoxGetChild(hex_dlg,
+ XmDIALOG_SELECTION_LABEL));
+ XtUnmanageChild(XmSelectionBoxGetChild(hex_dlg,XmDIALOG_HELP_BUTTON));
+ XtUnmanageChild(XmSelectionBoxGetChild(hex_dlg,
+ XmDIALOG_CANCEL_BUTTON));
+ XtUnmanageChild(XmSelectionBoxGetChild(hex_dlg,XmDIALOG_TEXT));
+ XtAddCallback(hex_dlg,XmNokCallback,hex_destroy,NULL);
+ view = XmCreateScrolledWindow(hex_dlg,"view",NULL,0);
+ XtManageChild(view);
+ hex_label = XtVaCreateManagedWidget("label", xmLabelWidgetClass,
+ view, NULL);
+ }
+ XtManageChild(hex_dlg);
+
+ /* read the file (32k max) */
+ fp = fopen(filename,"r");
+ memset(data,0,sizeof(data));
+ chars = fread(data, 1, sizeof(data)-1, fp);
+ if (is_binary(data,chars)) {
+ xmpage = hexify(0, data, chars);
+ if (sizeof(data)-1 == chars) {
+ chunk = XmStringGenerate("[ ... ]\n",NULL,
+ XmMULTIBYTE_TEXT, NULL);
+ xmpage = XmStringConcatAndFree(xmpage,chunk);
+ }
+ } else {
+ xmpage = XmStringGenerate(data, NULL, XmMULTIBYTE_TEXT, NULL);
+ if (sizeof(data)-1 == chars) {
+ chunk = XmStringGenerate("\n[ ... ]\n",NULL,
+ XmMULTIBYTE_TEXT, NULL);
+ xmpage = XmStringConcatAndFree(xmpage,chunk);
+ }
+ }
+ XtVaSetValues(hex_label,XmNlabelString,xmpage,NULL);
+ XmStringFree(xmpage);
+ XtVaSetValues(XtParent(hex_dlg),XmNtitle,filename,NULL);
+ fclose(fp);
+}