filename | src/gtkui/dump_win.c |
changeset | 669:ab344e42bca9 |
prev | 561:533f6b478071 |
next | 736:a02d1475ccfd |
author | nkeynes |
date | Thu Jun 19 04:40:37 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Refactor the gd-rom list management out of the GUI (devices, recent files, etc). Add gd-rom list to the cocoa UI. |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * Implements the memory dump window.
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include <ctype.h>
20 #include <assert.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <glib/gi18n.h>
24 #include "mem.h"
25 #include "gtkui/gtkui.h"
27 #define MAX_DUMP_SIZE 4096
29 #define DUMP_WINDOW_TAG 0xD4B9DA7A
31 struct dump_window_info {
32 uint32_t _tag;
33 uint32_t start;
34 uint32_t end;
35 int flags;
36 unsigned char *data;
38 GtkWidget *window;
39 GtkWidget *fromInput, *toInput;
40 GtkWidget *textArea;
41 GtkTextTag *changedTag;
42 GtkTextBuffer *textBuffer;
43 struct dump_window_info *next;
44 };
46 static dump_window_t dump_list_head = NULL;
48 gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,
49 gpointer user_data );
50 void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data );
51 void dump_window_set_text( dump_window_t data, unsigned char *old_data, unsigned char *new_data );
54 dump_window_t dump_window_new( const gchar *title )
55 {
56 GtkWidget *vbox3;
57 GtkWidget *hbox2;
58 GtkWidget *dump_view_button;
59 GtkWidget *scrolledwindow9;
61 dump_window_t dump = g_malloc0( sizeof( struct dump_window_info ) );
63 dump->_tag = DUMP_WINDOW_TAG;
64 dump->next = dump_list_head;
65 dump_list_head = dump;
66 dump->data = NULL;
67 dump->start = 0;
68 dump->end = 0;
69 dump->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
70 gtk_window_set_title (GTK_WINDOW (dump->window), _("Memory dump"));
72 vbox3 = gtk_vbox_new (FALSE, 0);
73 gtk_container_add (GTK_CONTAINER (dump->window), vbox3);
75 hbox2 = gtk_hbox_new (FALSE, 0);
76 dump->fromInput = gtk_entry_new ();
77 gtk_entry_set_text( GTK_ENTRY(dump->fromInput), "" );
78 dump->toInput = gtk_entry_new ();
79 gtk_entry_set_text( GTK_ENTRY(dump->toInput), "" );
80 dump_view_button = gtk_button_new_with_mnemonic (_("View"));
82 gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new(_(" From ")), FALSE, FALSE, 0);
83 gtk_box_pack_start (GTK_BOX (hbox2), dump->fromInput, FALSE, TRUE, 0);
84 gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new(_(" To ")), FALSE, FALSE, 0);
85 gtk_box_pack_start (GTK_BOX (hbox2), dump->toInput, FALSE, TRUE, 0);
86 gtk_box_pack_start (GTK_BOX (hbox2), dump_view_button, FALSE, FALSE, 0);
87 gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new (_(" ")), TRUE, TRUE, 0);
88 gtk_box_pack_start (GTK_BOX (vbox3), hbox2, FALSE, TRUE, 3);
90 dump->textArea = gtk_text_view_new ();
91 dump->textBuffer = gtk_text_buffer_new(NULL);
92 dump->changedTag = gtk_text_buffer_create_tag(dump->textBuffer, "changed",
93 "foreground", "blue", NULL);
94 gtk_widget_modify_font(GTK_WIDGET(dump->textArea),gui_fixed_font);
95 gtk_text_view_set_editable(GTK_TEXT_VIEW(dump->textArea), FALSE);
96 gtk_text_view_set_buffer(GTK_TEXT_VIEW(dump->textArea), dump->textBuffer);
97 scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL);
98 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_SHADOW_IN);
99 gtk_container_add (GTK_CONTAINER (scrolledwindow9), dump->textArea);
100 gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow9, TRUE, TRUE, 0);
102 g_signal_connect (dump->window, "delete_event",
103 G_CALLBACK (on_dump_window_delete_event),
104 dump);
105 g_signal_connect (dump_view_button, "clicked",
106 G_CALLBACK (on_dump_window_button_view_clicked),
107 dump);
108 gtk_widget_show_all( dump->window );
110 return dump;
111 }
113 void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value )
114 {
115 char buf[10];
116 sprintf( buf, "%08X", value );
117 gtk_entry_set_text( entry, buf );
118 }
120 uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue )
121 {
122 const gchar *text = gtk_entry_get_text(entry);
123 if( text == NULL )
124 return defaultValue;
125 gchar *endptr;
126 uint32_t value = strtoul( text, &endptr, 16 );
127 if( text == endptr ) { /* invalid input */
128 value = defaultValue;
129 gtk_entry_set_hex_value( entry, value );
130 }
131 return value;
132 }
134 gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,
135 gpointer user_data )
136 {
137 dump_window_t data = (dump_window_t)user_data;
138 if( data->data != NULL )
139 free( data->data );
140 dump_window_t node = dump_list_head;
141 if( node == data )
142 dump_list_head = data->next;
143 else {
144 while( node->next != data ) {
145 node = node->next;
146 assert( node != NULL );
147 }
148 node->next = data->next;
149 }
150 free( data );
151 return FALSE;
152 }
154 void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data )
155 {
156 dump_window_t data = (dump_window_t)user_data;
157 uint32_t startVal, endVal;
159 assert( data != NULL );
160 assert( data->_tag == DUMP_WINDOW_TAG );
162 startVal = gtk_entry_get_hex_value(GTK_ENTRY(data->fromInput), data->start);
163 endVal = gtk_entry_get_hex_value(GTK_ENTRY(data->toInput), data->end);
164 if( startVal != data->start || endVal != data->end ) {
165 if( startVal > endVal ) {
166 int tmp = endVal;
167 endVal = startVal;
168 startVal = tmp;
169 }
170 if( endVal > startVal + MAX_DUMP_SIZE )
171 endVal = startVal + MAX_DUMP_SIZE;
173 gtk_entry_set_hex_value(GTK_ENTRY(data->fromInput),startVal);
174 gtk_entry_set_hex_value(GTK_ENTRY(data->toInput),endVal);
175 data->start = startVal;
176 data->end = endVal;
178 if( data->data != NULL ) {
179 free( data->data );
180 data->data = NULL;
181 }
182 if( startVal != endVal ) {
183 data->data = malloc( endVal - startVal );
184 mem_copy_from_sh4( data->data, startVal, endVal-startVal );
185 dump_window_set_text( data, data->data, data->data );
186 }
187 }
188 }
190 void dump_window_update( dump_window_t data )
191 {
192 if( data->data == NULL )
193 return;
194 unsigned char tmp[data->end-data->start];
195 int length = data->end-data->start;
196 memcpy( tmp, data->data, length );
197 mem_copy_from_sh4( data->data, data->start, length );
198 dump_window_set_text( data, tmp, data->data );
199 }
201 void dump_window_update_all( )
202 {
203 dump_window_t node = dump_list_head;
204 while( node != NULL ) {
205 dump_window_update(node);
206 node = node->next;
207 }
208 }
210 void dump_window_set_text( dump_window_t data, unsigned char *old_data, unsigned char *new_data )
211 {
212 GtkTextBuffer *buf = data->textBuffer;
213 GtkTextTag *changedTag = data->changedTag;
214 GtkTextIter iter, endIter;
215 int i, j, offset;
216 /* Clear out the buffer */
217 gtk_text_buffer_get_start_iter(buf,&iter);
218 gtk_text_buffer_get_end_iter(buf,&endIter);
219 gtk_text_buffer_delete(buf,&iter,&endIter);
220 gtk_text_buffer_get_start_iter(buf,&iter);
222 for( offset = 0, i=data->start; i<data->end; i+=16, offset+=16 ) {
223 char text[80];
224 sprintf(text, "%08X:", i );
225 gtk_text_buffer_insert( buf, &iter, text, 9 );
226 for( j=0; j<16; j++ ) {
227 if( j%4 == 0 )
228 gtk_text_buffer_insert( buf, &iter, " ", 1 );
229 if( i+j < data->end ) {
230 int oldVal = ((int)old_data[offset+j])&0xFF;
231 int newVal = ((int)new_data[offset+j])&0xFF;
232 sprintf(text, "%02X ", newVal);
233 if( oldVal == newVal )
234 gtk_text_buffer_insert( buf, &iter, text, 3 );
235 else
236 gtk_text_buffer_insert_with_tags( buf, &iter, text, 3,
237 changedTag, NULL );
238 } else {
239 gtk_text_buffer_insert( buf, &iter, " ", 3 );
240 }
241 }
242 gtk_text_buffer_insert( buf, &iter, " ", 2 );
243 for( j=0; j<16 && i+j < data->end; j++ ) {
244 int oldVal = ((int)old_data[offset+j])&0xFF;
245 int newVal = ((int)new_data[offset+j])&0xFF;
246 if( isprint(newVal) )
247 sprintf( text, "%c", newVal );
248 else strcpy( text, "." );
249 if( oldVal == newVal )
250 gtk_text_buffer_insert( buf, &iter, text, 1 );
251 else
252 gtk_text_buffer_insert_with_tags( buf, &iter, text, 1,
253 changedTag, NULL );
254 }
255 gtk_text_buffer_insert( buf, &iter, "\n", 1 );
256 }
257 }
.