filename | src/gtkui/gtk_dump.c |
changeset | 1065:bc1cc0c54917 |
prev | 561:533f6b478071 |
prev | 763:b3ce4448f200 |
author | nkeynes |
date | Fri Mar 02 23:49:10 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Android WIP: * Rename gui_jni.c to gui_android.c - now quite android specific. * Implement generic EGL driver with very minimal Java wrapper * Run emulation in separate thread, and implement simple queue for inter-thread communication. * Add menu/action-bar items for start + reset |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/gtkui/gtk_dump.c Fri Mar 02 23:49:10 2012 +10001.3 @@ -0,0 +1,256 @@1.4 +/**1.5 + * $Id$1.6 + *1.7 + * Implements the memory dump window.1.8 + *1.9 + * Copyright (c) 2005 Nathan Keynes.1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *1.16 + * This program is distributed in the hope that it will be useful,1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +1.22 +#include <ctype.h>1.23 +#include <assert.h>1.24 +#include <string.h>1.25 +#include <stdlib.h>1.26 +#include "mem.h"1.27 +#include "gtkui/gtkui.h"1.28 +1.29 +#define MAX_DUMP_SIZE 40961.30 +1.31 +#define DUMP_WINDOW_TAG 0xD4B9DA7A1.32 +1.33 +struct dump_window_info {1.34 + uint32_t _tag;1.35 + uint32_t start;1.36 + uint32_t end;1.37 + int flags;1.38 + unsigned char *data;1.39 +1.40 + GtkWidget *window;1.41 + GtkWidget *fromInput, *toInput;1.42 + GtkWidget *textArea;1.43 + GtkTextTag *changedTag;1.44 + GtkTextBuffer *textBuffer;1.45 + struct dump_window_info *next;1.46 +};1.47 +1.48 +static dump_window_t dump_list_head = NULL;1.49 +1.50 +gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,1.51 + gpointer user_data );1.52 +void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data );1.53 +void dump_window_set_text( dump_window_t data, unsigned char *old_data, unsigned char *new_data );1.54 +1.55 +1.56 +dump_window_t dump_window_new( const gchar *title )1.57 +{1.58 + GtkWidget *vbox3;1.59 + GtkWidget *hbox2;1.60 + GtkWidget *dump_view_button;1.61 + GtkWidget *scrolledwindow9;1.62 +1.63 + dump_window_t dump = g_malloc0( sizeof( struct dump_window_info ) );1.64 +1.65 + dump->_tag = DUMP_WINDOW_TAG;1.66 + dump->next = dump_list_head;1.67 + dump_list_head = dump;1.68 + dump->data = NULL;1.69 + dump->start = 0;1.70 + dump->end = 0;1.71 + dump->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);1.72 + gtk_window_set_title (GTK_WINDOW (dump->window), _("Memory dump"));1.73 +1.74 + vbox3 = gtk_vbox_new (FALSE, 0);1.75 + gtk_container_add (GTK_CONTAINER (dump->window), vbox3);1.76 +1.77 + hbox2 = gtk_hbox_new (FALSE, 0);1.78 + dump->fromInput = gtk_entry_new ();1.79 + gtk_entry_set_text( GTK_ENTRY(dump->fromInput), "" );1.80 + dump->toInput = gtk_entry_new ();1.81 + gtk_entry_set_text( GTK_ENTRY(dump->toInput), "" );1.82 + dump_view_button = gtk_button_new_with_mnemonic (_("View"));1.83 +1.84 + gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new(_(" From ")), FALSE, FALSE, 0);1.85 + gtk_box_pack_start (GTK_BOX (hbox2), dump->fromInput, FALSE, TRUE, 0);1.86 + gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new(_(" To ")), FALSE, FALSE, 0);1.87 + gtk_box_pack_start (GTK_BOX (hbox2), dump->toInput, FALSE, TRUE, 0);1.88 + gtk_box_pack_start (GTK_BOX (hbox2), dump_view_button, FALSE, FALSE, 0);1.89 + gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new (_(" ")), TRUE, TRUE, 0);1.90 + gtk_box_pack_start (GTK_BOX (vbox3), hbox2, FALSE, TRUE, 3);1.91 +1.92 + dump->textArea = gtk_text_view_new ();1.93 + dump->textBuffer = gtk_text_buffer_new(NULL);1.94 + dump->changedTag = gtk_text_buffer_create_tag(dump->textBuffer, "changed",1.95 + "foreground", "blue", NULL);1.96 + gtk_widget_modify_font(GTK_WIDGET(dump->textArea),gui_fixed_font);1.97 + gtk_text_view_set_editable(GTK_TEXT_VIEW(dump->textArea), FALSE);1.98 + gtk_text_view_set_buffer(GTK_TEXT_VIEW(dump->textArea), dump->textBuffer);1.99 + scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL);1.100 + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_SHADOW_IN);1.101 + gtk_container_add (GTK_CONTAINER (scrolledwindow9), dump->textArea);1.102 + gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow9, TRUE, TRUE, 0);1.103 +1.104 + g_signal_connect (dump->window, "delete_event",1.105 + G_CALLBACK (on_dump_window_delete_event),1.106 + dump);1.107 + g_signal_connect (dump_view_button, "clicked",1.108 + G_CALLBACK (on_dump_window_button_view_clicked),1.109 + dump);1.110 + gtk_widget_show_all( dump->window );1.111 +1.112 + return dump;1.113 +}1.114 +1.115 +void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value )1.116 +{1.117 + char buf[10];1.118 + sprintf( buf, "%08X", value );1.119 + gtk_entry_set_text( entry, buf );1.120 +}1.121 +1.122 +uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue )1.123 +{1.124 + const gchar *text = gtk_entry_get_text(entry);1.125 + if( text == NULL )1.126 + return defaultValue;1.127 + gchar *endptr;1.128 + uint32_t value = strtoul( text, &endptr, 16 );1.129 + if( text == endptr ) { /* invalid input */1.130 + value = defaultValue;1.131 + gtk_entry_set_hex_value( entry, value );1.132 + }1.133 + return value;1.134 +}1.135 +1.136 +gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,1.137 + gpointer user_data )1.138 +{1.139 + dump_window_t data = (dump_window_t)user_data;1.140 + if( data->data != NULL )1.141 + free( data->data );1.142 + dump_window_t node = dump_list_head;1.143 + if( node == data )1.144 + dump_list_head = data->next;1.145 + else {1.146 + while( node->next != data ) {1.147 + node = node->next;1.148 + assert( node != NULL );1.149 + }1.150 + node->next = data->next;1.151 + }1.152 + free( data );1.153 + return FALSE;1.154 +}1.155 +1.156 +void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data )1.157 +{1.158 + dump_window_t data = (dump_window_t)user_data;1.159 + uint32_t startVal, endVal;1.160 +1.161 + assert( data != NULL );1.162 + assert( data->_tag == DUMP_WINDOW_TAG );1.163 +1.164 + startVal = gtk_entry_get_hex_value(GTK_ENTRY(data->fromInput), data->start);1.165 + endVal = gtk_entry_get_hex_value(GTK_ENTRY(data->toInput), data->end);1.166 + if( startVal != data->start || endVal != data->end ) {1.167 + if( startVal > endVal ) {1.168 + int tmp = endVal;1.169 + endVal = startVal;1.170 + startVal = tmp;1.171 + }1.172 + if( endVal > startVal + MAX_DUMP_SIZE )1.173 + endVal = startVal + MAX_DUMP_SIZE;1.174 +1.175 + gtk_entry_set_hex_value(GTK_ENTRY(data->fromInput),startVal);1.176 + gtk_entry_set_hex_value(GTK_ENTRY(data->toInput),endVal);1.177 + data->start = startVal;1.178 + data->end = endVal;1.179 +1.180 + if( data->data != NULL ) {1.181 + free( data->data );1.182 + data->data = NULL;1.183 + }1.184 + if( startVal != endVal ) {1.185 + data->data = malloc( endVal - startVal );1.186 + mem_copy_from_sh4( data->data, startVal, endVal-startVal );1.187 + dump_window_set_text( data, data->data, data->data );1.188 + }1.189 + }1.190 +}1.191 +1.192 +void dump_window_update( dump_window_t data )1.193 +{1.194 + if( data->data == NULL )1.195 + return;1.196 + unsigned char tmp[data->end-data->start];1.197 + int length = data->end-data->start;1.198 + memcpy( tmp, data->data, length );1.199 + mem_copy_from_sh4( data->data, data->start, length );1.200 + dump_window_set_text( data, tmp, data->data );1.201 +}1.202 +1.203 +void dump_window_update_all( )1.204 +{1.205 + dump_window_t node = dump_list_head;1.206 + while( node != NULL ) {1.207 + dump_window_update(node);1.208 + node = node->next;1.209 + }1.210 +}1.211 +1.212 +void dump_window_set_text( dump_window_t data, unsigned char *old_data, unsigned char *new_data )1.213 +{1.214 + GtkTextBuffer *buf = data->textBuffer;1.215 + GtkTextTag *changedTag = data->changedTag;1.216 + GtkTextIter iter, endIter;1.217 + int i, j, offset;1.218 + /* Clear out the buffer */1.219 + gtk_text_buffer_get_start_iter(buf,&iter);1.220 + gtk_text_buffer_get_end_iter(buf,&endIter);1.221 + gtk_text_buffer_delete(buf,&iter,&endIter);1.222 + gtk_text_buffer_get_start_iter(buf,&iter);1.223 +1.224 + for( offset = 0, i=data->start; i<data->end; i+=16, offset+=16 ) {1.225 + char text[80];1.226 + sprintf(text, "%08X:", i );1.227 + gtk_text_buffer_insert( buf, &iter, text, 9 );1.228 + for( j=0; j<16; j++ ) {1.229 + if( j%4 == 0 )1.230 + gtk_text_buffer_insert( buf, &iter, " ", 1 );1.231 + if( i+j < data->end ) {1.232 + int oldVal = ((int)old_data[offset+j])&0xFF;1.233 + int newVal = ((int)new_data[offset+j])&0xFF;1.234 + sprintf(text, "%02X ", newVal);1.235 + if( oldVal == newVal )1.236 + gtk_text_buffer_insert( buf, &iter, text, 3 );1.237 + else1.238 + gtk_text_buffer_insert_with_tags( buf, &iter, text, 3,1.239 + changedTag, NULL );1.240 + } else {1.241 + gtk_text_buffer_insert( buf, &iter, " ", 3 );1.242 + }1.243 + }1.244 + gtk_text_buffer_insert( buf, &iter, " ", 2 );1.245 + for( j=0; j<16 && i+j < data->end; j++ ) {1.246 + int oldVal = ((int)old_data[offset+j])&0xFF;1.247 + int newVal = ((int)new_data[offset+j])&0xFF;1.248 + if( isprint(newVal) )1.249 + sprintf( text, "%c", newVal );1.250 + else strcpy( text, "." );1.251 + if( oldVal == newVal )1.252 + gtk_text_buffer_insert( buf, &iter, text, 1 );1.253 + else1.254 + gtk_text_buffer_insert_with_tags( buf, &iter, text, 1,1.255 + changedTag, NULL );1.256 + }1.257 + gtk_text_buffer_insert( buf, &iter, "\n", 1 );1.258 + }1.259 +}
.