Search
lxdream.org :: lxdream/src/gui/dump_win.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gui/dump_win.c
changeset 435:7a5d71e8560b
prev430:467519b050f4
next455:3080881d00d4
author nkeynes
date Wed Oct 17 11:26:45 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Split config management out to config.[ch]
Manage config filename
Check home dir + sysconfdir for conf file
Initial work on a path settings dialog
view annotate diff log raw
     1 /**
     2  * $Id: dump_win.c,v 1.4 2007-10-10 11:02:04 nkeynes Exp $
     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 <gnome.h>
    20 #include <ctype.h>
    21 #include <assert.h>
    22 #include "mem.h"
    23 #include "gui/gtkui.h"
    24 #include "gui/debugif.h"
    26 #define MAX_DUMP_SIZE 4096
    28 #define DUMP_DATA_TAG 0xD4B9DA7A
    30 typedef struct dump_data {
    31     uint32_t _tag;
    32     uint32_t start;
    33     uint32_t end;
    34     int flags;
    35     unsigned char *data;
    37     GtkEntry *fromInput, *toInput;
    38     GtkTextView *textArea;
    39     GtkTextTag *changedTag;
    40     GtkTextBuffer *textBuffer;
    41     struct dump_data *next;
    42 } *dump_data_t;
    44 static dump_data_t dump_list_head = NULL;
    46 gboolean on_dump_win_delete_event( GtkWidget *widget, GdkEvent *event,
    47                                    gpointer user_data );
    48 void on_dump_win_button_view_clicked( GtkWidget *widget, gpointer user_data );
    49 void dump_win_set_text( dump_data_t data, unsigned char *old_data, unsigned char *new_data );
    52 void dump_window_new( void ) {
    53     GtkWidget *win = create_dump_win();
    54     GtkWidget *dump_view_button = (GtkWidget *)g_object_get_data(G_OBJECT(win), "dump_view_button");
    55     dump_data_t data = malloc( sizeof(struct dump_data) );
    56     data->_tag = DUMP_DATA_TAG;
    57     data->fromInput = (GtkEntry *)g_object_get_data(G_OBJECT(win), "dump_from");
    58     data->toInput = (GtkEntry *)g_object_get_data(G_OBJECT(win), "dump_to");
    59     data->textArea = (GtkTextView *)g_object_get_data(G_OBJECT(win), "dump_text");
    60     data->next = dump_list_head;
    61     dump_list_head = data;
    62     data->data = NULL;
    63     data->start = 0;
    64     data->end = 0;
    65     gtk_entry_set_text( data->fromInput, "" );
    66     gtk_entry_set_text( data->toInput, "" );
    67     data->textBuffer = gtk_text_buffer_new(NULL);
    68     data->changedTag = gtk_text_buffer_create_tag(data->textBuffer, "changed",
    69                                                  "foreground", "blue",
    70                                                   NULL);
    71     gtk_text_view_set_buffer(data->textArea, data->textBuffer);
    72     gtk_text_view_set_editable(data->textArea, FALSE);
    73     gtk_widget_modify_font(GTK_WIDGET(data->textArea),gui_fixed_font);
    75     g_signal_connect ((gpointer) win, "delete_event",
    76                       G_CALLBACK (on_dump_win_delete_event),
    77                       data);
    78     g_signal_connect ((gpointer) dump_view_button, "clicked",
    79                       G_CALLBACK (on_dump_win_button_view_clicked),
    80                       data);
    81     gtk_widget_show( GTK_WIDGET(win) );
    82 }
    86 uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue )
    87 {
    88     const gchar *text = gtk_entry_get_text(entry);
    89     if( text == NULL )
    90         return defaultValue;
    91     gchar *endptr;
    92     uint32_t value = strtoul( text, &endptr, 16 );
    93     if( text == endptr ) { /* invalid input */
    94         value = defaultValue;
    95         gtk_entry_set_hex_value( entry, value );
    96     }
    97     return value;
    98 }
   100 void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value )
   101 {
   102     char buf[10];
   103     sprintf( buf, "%08X", value );
   104     gtk_entry_set_text( entry, buf );
   105 }
   108 gboolean on_dump_win_delete_event( GtkWidget *widget, GdkEvent *event,
   109                                    gpointer user_data )
   110 {
   111     dump_data_t data = (dump_data_t)user_data;
   112     if( data->data != NULL )
   113         free( data->data );
   114     dump_data_t node = dump_list_head;
   115     if( node == data )
   116         dump_list_head = data->next;
   117     else {
   118         while( node->next != data ) {
   119             node = node->next;
   120             assert( node != NULL );
   121         }
   122         node->next = data->next;
   123     }
   124     free( data );
   125     return FALSE;
   126 }
   128 void on_dump_win_button_view_clicked( GtkWidget *widget, gpointer user_data )
   129 {
   130     dump_data_t data = (dump_data_t)user_data;
   131     uint32_t startVal, endVal;
   133     assert( data != NULL );
   134     assert( data->_tag == DUMP_DATA_TAG );
   136     startVal = gtk_entry_get_hex_value(data->fromInput, data->start);
   137     endVal = gtk_entry_get_hex_value(data->toInput, data->end);
   138     if( startVal != data->start || endVal != data->end ) {
   139         if( startVal > endVal ) {
   140             int tmp = endVal;
   141             endVal = startVal;
   142             startVal = tmp;
   143         }
   144         if( endVal > startVal + MAX_DUMP_SIZE )
   145             endVal = startVal + MAX_DUMP_SIZE;
   147         gtk_entry_set_hex_value(data->fromInput,startVal);
   148         gtk_entry_set_hex_value(data->toInput,endVal);
   149         data->start = startVal;
   150         data->end = endVal;
   152         if( data->data != NULL ) {
   153             free( data->data );
   154             data->data = NULL;
   155         }
   156         if( startVal != endVal ) {
   157             data->data = malloc( endVal - startVal );
   158             mem_copy_from_sh4( data->data, startVal, endVal-startVal );
   159             dump_win_set_text( data, data->data, data->data );
   160         }
   161     }
   162 }
   164 void dump_win_update( dump_data_t data )
   165 {
   166     if( data->data == NULL )
   167         return;
   168     unsigned char tmp[data->end-data->start];
   169     int length = data->end-data->start;
   170     memcpy( tmp, data->data, length );
   171     mem_copy_from_sh4( data->data, data->start, length );
   172     dump_win_set_text( data, tmp, data->data );
   173 }
   175 void dump_win_update_all( )
   176 {
   177     dump_data_t node = dump_list_head;
   178     while( node != NULL ) {
   179         dump_win_update(node);
   180         node = node->next;
   181     }
   182 }
   184 void dump_win_set_text( dump_data_t data, unsigned char *old_data, unsigned char *new_data )
   185 {
   186     GtkTextBuffer *buf = data->textBuffer;
   187     GtkTextTag *changedTag = data->changedTag;
   188     GtkTextIter iter, endIter;
   189     int i, j, offset;
   190     /* Clear out the buffer */
   191     gtk_text_buffer_get_start_iter(buf,&iter);
   192     gtk_text_buffer_get_end_iter(buf,&endIter);
   193     gtk_text_buffer_delete(buf,&iter,&endIter);
   194     gtk_text_buffer_get_start_iter(buf,&iter);
   196     for( offset = 0, i=data->start; i<data->end; i+=16, offset+=16 ) {
   197         char text[80];
   198         sprintf(text, "%08X:", i );
   199         gtk_text_buffer_insert( buf, &iter, text, 9 );
   200         for( j=0; j<16; j++ ) {
   201             if( j%4 == 0 )
   202                 gtk_text_buffer_insert( buf, &iter, " ", 1 );
   203             if( i+j < data->end ) {
   204                 int oldVal = ((int)old_data[offset+j])&0xFF;
   205                 int newVal = ((int)new_data[offset+j])&0xFF;
   206                 sprintf(text, "%02X ", newVal);
   207                 if( oldVal == newVal )
   208                     gtk_text_buffer_insert( buf, &iter, text, 3 );
   209                 else
   210                     gtk_text_buffer_insert_with_tags( buf, &iter, text, 3,
   211                                                       changedTag, NULL );
   212             } else {
   213                 gtk_text_buffer_insert( buf, &iter, "   ", 3 );
   214             }
   215         }
   216         gtk_text_buffer_insert( buf, &iter, "  ", 2 );
   217         for( j=0; j<16 && i+j < data->end; j++ ) {
   218             int oldVal = ((int)old_data[offset+j])&0xFF;
   219             int newVal = ((int)new_data[offset+j])&0xFF;
   220             if( isprint(newVal) )
   221                 sprintf( text, "%c", newVal );
   222             else strcpy( text, "." );
   223             if( oldVal == newVal )
   224                 gtk_text_buffer_insert( buf, &iter, text, 1 );
   225             else
   226                 gtk_text_buffer_insert_with_tags( buf, &iter, text, 1,
   227                                                   changedTag, NULL );
   228         }
   229         gtk_text_buffer_insert( buf, &iter, "\n", 1 );
   230     }
   231 }
.