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 455:3080881d00d4
prev435:7a5d71e8560b
next457:af605fd32c0b
author nkeynes
date Sun Oct 21 05:21:35 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change More GUI WIP
file annotate diff log raw
nkeynes@2
     1
/**
nkeynes@455
     2
 * $Id: dump_win.c,v 1.5 2007-10-21 05:21:35 nkeynes Exp $
nkeynes@31
     3
 *
nkeynes@2
     4
 * Implements the memory dump window.
nkeynes@31
     5
 *
nkeynes@31
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@31
     7
 *
nkeynes@31
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@31
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@31
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@31
    11
 * (at your option) any later version.
nkeynes@31
    12
 *
nkeynes@31
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@31
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@31
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@31
    16
 * GNU General Public License for more details.
nkeynes@2
    17
 */
nkeynes@31
    18
nkeynes@2
    19
#include <gnome.h>
nkeynes@2
    20
#include <ctype.h>
nkeynes@2
    21
#include <assert.h>
nkeynes@2
    22
#include "mem.h"
nkeynes@435
    23
#include "gui/gtkui.h"
nkeynes@435
    24
#include "gui/debugif.h"
nkeynes@2
    25
nkeynes@2
    26
#define MAX_DUMP_SIZE 4096
nkeynes@2
    27
nkeynes@2
    28
#define DUMP_DATA_TAG 0xD4B9DA7A
nkeynes@2
    29
nkeynes@2
    30
typedef struct dump_data {
nkeynes@2
    31
    uint32_t _tag;
nkeynes@2
    32
    uint32_t start;
nkeynes@2
    33
    uint32_t end;
nkeynes@2
    34
    int flags;
nkeynes@430
    35
    unsigned char *data;
nkeynes@2
    36
nkeynes@2
    37
    GtkEntry *fromInput, *toInput;
nkeynes@2
    38
    GtkTextView *textArea;
nkeynes@2
    39
    GtkTextTag *changedTag;
nkeynes@2
    40
    GtkTextBuffer *textBuffer;
nkeynes@2
    41
    struct dump_data *next;
nkeynes@2
    42
} *dump_data_t;
nkeynes@2
    43
nkeynes@2
    44
static dump_data_t dump_list_head = NULL;
nkeynes@2
    45
nkeynes@455
    46
gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,
nkeynes@2
    47
                                   gpointer user_data );
nkeynes@455
    48
void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data );
nkeynes@455
    49
void dump_window_set_text( dump_data_t data, unsigned char *old_data, unsigned char *new_data );
nkeynes@2
    50
nkeynes@2
    51
nkeynes@455
    52
void dump_window_new( const gchar *title ) {
nkeynes@2
    53
    GtkWidget *win = create_dump_win();
nkeynes@2
    54
    GtkWidget *dump_view_button = (GtkWidget *)g_object_get_data(G_OBJECT(win), "dump_view_button");
nkeynes@2
    55
    dump_data_t data = malloc( sizeof(struct dump_data) );
nkeynes@2
    56
    data->_tag = DUMP_DATA_TAG;
nkeynes@2
    57
    data->fromInput = (GtkEntry *)g_object_get_data(G_OBJECT(win), "dump_from");
nkeynes@2
    58
    data->toInput = (GtkEntry *)g_object_get_data(G_OBJECT(win), "dump_to");
nkeynes@2
    59
    data->textArea = (GtkTextView *)g_object_get_data(G_OBJECT(win), "dump_text");
nkeynes@2
    60
    data->next = dump_list_head;
nkeynes@2
    61
    dump_list_head = data;
nkeynes@2
    62
    data->data = NULL;
nkeynes@2
    63
    data->start = 0;
nkeynes@2
    64
    data->end = 0;
nkeynes@2
    65
    gtk_entry_set_text( data->fromInput, "" );
nkeynes@2
    66
    gtk_entry_set_text( data->toInput, "" );
nkeynes@2
    67
    data->textBuffer = gtk_text_buffer_new(NULL);
nkeynes@2
    68
    data->changedTag = gtk_text_buffer_create_tag(data->textBuffer, "changed",
nkeynes@2
    69
                                                 "foreground", "blue",
nkeynes@2
    70
                                                  NULL);
nkeynes@2
    71
    gtk_text_view_set_buffer(data->textArea, data->textBuffer);
nkeynes@2
    72
    gtk_text_view_set_editable(data->textArea, FALSE);
nkeynes@435
    73
    gtk_widget_modify_font(GTK_WIDGET(data->textArea),gui_fixed_font);
nkeynes@2
    74
        
nkeynes@2
    75
    g_signal_connect ((gpointer) win, "delete_event",
nkeynes@455
    76
                      G_CALLBACK (on_dump_window_delete_event),
nkeynes@2
    77
                      data);
nkeynes@2
    78
    g_signal_connect ((gpointer) dump_view_button, "clicked",
nkeynes@455
    79
                      G_CALLBACK (on_dump_window_button_view_clicked),
nkeynes@2
    80
                      data);
nkeynes@2
    81
    gtk_widget_show( GTK_WIDGET(win) );
nkeynes@2
    82
}
nkeynes@2
    83
nkeynes@2
    84
nkeynes@435
    85
nkeynes@435
    86
uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue )
nkeynes@435
    87
{
nkeynes@435
    88
    const gchar *text = gtk_entry_get_text(entry);
nkeynes@435
    89
    if( text == NULL )
nkeynes@435
    90
        return defaultValue;
nkeynes@435
    91
    gchar *endptr;
nkeynes@435
    92
    uint32_t value = strtoul( text, &endptr, 16 );
nkeynes@435
    93
    if( text == endptr ) { /* invalid input */
nkeynes@435
    94
        value = defaultValue;
nkeynes@435
    95
        gtk_entry_set_hex_value( entry, value );
nkeynes@435
    96
    }
nkeynes@435
    97
    return value;
nkeynes@435
    98
}
nkeynes@435
    99
nkeynes@435
   100
void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value )
nkeynes@435
   101
{
nkeynes@435
   102
    char buf[10];
nkeynes@435
   103
    sprintf( buf, "%08X", value );
nkeynes@435
   104
    gtk_entry_set_text( entry, buf );
nkeynes@435
   105
}
nkeynes@435
   106
nkeynes@2
   107
        
nkeynes@455
   108
gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,
nkeynes@2
   109
                                   gpointer user_data )
nkeynes@2
   110
{
nkeynes@2
   111
    dump_data_t data = (dump_data_t)user_data;
nkeynes@2
   112
    if( data->data != NULL )
nkeynes@2
   113
        free( data->data );
nkeynes@2
   114
    dump_data_t node = dump_list_head;
nkeynes@2
   115
    if( node == data )
nkeynes@2
   116
        dump_list_head = data->next;
nkeynes@2
   117
    else {
nkeynes@2
   118
        while( node->next != data ) {
nkeynes@2
   119
            node = node->next;
nkeynes@2
   120
            assert( node != NULL );
nkeynes@2
   121
        }
nkeynes@2
   122
        node->next = data->next;
nkeynes@2
   123
    }
nkeynes@2
   124
    free( data );
nkeynes@2
   125
    return FALSE;
nkeynes@2
   126
}
nkeynes@2
   127
nkeynes@455
   128
void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data )
nkeynes@2
   129
{
nkeynes@2
   130
    dump_data_t data = (dump_data_t)user_data;
nkeynes@2
   131
    uint32_t startVal, endVal;
nkeynes@2
   132
nkeynes@2
   133
    assert( data != NULL );
nkeynes@2
   134
    assert( data->_tag == DUMP_DATA_TAG );
nkeynes@2
   135
    
nkeynes@2
   136
    startVal = gtk_entry_get_hex_value(data->fromInput, data->start);
nkeynes@2
   137
    endVal = gtk_entry_get_hex_value(data->toInput, data->end);
nkeynes@2
   138
    if( startVal != data->start || endVal != data->end ) {
nkeynes@2
   139
        if( startVal > endVal ) {
nkeynes@2
   140
            int tmp = endVal;
nkeynes@2
   141
            endVal = startVal;
nkeynes@2
   142
            startVal = tmp;
nkeynes@2
   143
        }
nkeynes@2
   144
        if( endVal > startVal + MAX_DUMP_SIZE )
nkeynes@2
   145
            endVal = startVal + MAX_DUMP_SIZE;
nkeynes@2
   146
nkeynes@2
   147
        gtk_entry_set_hex_value(data->fromInput,startVal);
nkeynes@2
   148
        gtk_entry_set_hex_value(data->toInput,endVal);
nkeynes@2
   149
        data->start = startVal;
nkeynes@2
   150
        data->end = endVal;
nkeynes@2
   151
nkeynes@2
   152
        if( data->data != NULL ) {
nkeynes@2
   153
            free( data->data );
nkeynes@2
   154
            data->data = NULL;
nkeynes@2
   155
        }
nkeynes@2
   156
        if( startVal != endVal ) {
nkeynes@2
   157
            data->data = malloc( endVal - startVal );
nkeynes@2
   158
            mem_copy_from_sh4( data->data, startVal, endVal-startVal );
nkeynes@455
   159
            dump_window_set_text( data, data->data, data->data );
nkeynes@2
   160
        }
nkeynes@2
   161
    }
nkeynes@2
   162
}
nkeynes@2
   163
nkeynes@455
   164
void dump_window_update( dump_data_t data )
nkeynes@2
   165
{
nkeynes@2
   166
    if( data->data == NULL )
nkeynes@2
   167
        return;
nkeynes@430
   168
    unsigned char tmp[data->end-data->start];
nkeynes@2
   169
    int length = data->end-data->start;
nkeynes@2
   170
    memcpy( tmp, data->data, length );
nkeynes@2
   171
    mem_copy_from_sh4( data->data, data->start, length );
nkeynes@455
   172
    dump_window_set_text( data, tmp, data->data );
nkeynes@2
   173
}
nkeynes@2
   174
nkeynes@455
   175
void dump_window_update_all( )
nkeynes@2
   176
{
nkeynes@2
   177
    dump_data_t node = dump_list_head;
nkeynes@2
   178
    while( node != NULL ) {
nkeynes@455
   179
        dump_window_update(node);
nkeynes@2
   180
        node = node->next;
nkeynes@2
   181
    }
nkeynes@2
   182
}
nkeynes@2
   183
nkeynes@455
   184
void dump_window_set_text( dump_data_t data, unsigned char *old_data, unsigned char *new_data )
nkeynes@2
   185
{
nkeynes@2
   186
    GtkTextBuffer *buf = data->textBuffer;
nkeynes@2
   187
    GtkTextTag *changedTag = data->changedTag;
nkeynes@2
   188
    GtkTextIter iter, endIter;
nkeynes@2
   189
    int i, j, offset;
nkeynes@2
   190
    /* Clear out the buffer */
nkeynes@2
   191
    gtk_text_buffer_get_start_iter(buf,&iter);
nkeynes@2
   192
    gtk_text_buffer_get_end_iter(buf,&endIter);
nkeynes@2
   193
    gtk_text_buffer_delete(buf,&iter,&endIter);
nkeynes@2
   194
    gtk_text_buffer_get_start_iter(buf,&iter);
nkeynes@2
   195
    
nkeynes@2
   196
    for( offset = 0, i=data->start; i<data->end; i+=16, offset+=16 ) {
nkeynes@2
   197
        char text[80];
nkeynes@2
   198
        sprintf(text, "%08X:", i );
nkeynes@2
   199
        gtk_text_buffer_insert( buf, &iter, text, 9 );
nkeynes@2
   200
        for( j=0; j<16; j++ ) {
nkeynes@2
   201
            if( j%4 == 0 )
nkeynes@2
   202
                gtk_text_buffer_insert( buf, &iter, " ", 1 );
nkeynes@2
   203
            if( i+j < data->end ) {
nkeynes@2
   204
                int oldVal = ((int)old_data[offset+j])&0xFF;
nkeynes@2
   205
                int newVal = ((int)new_data[offset+j])&0xFF;
nkeynes@2
   206
                sprintf(text, "%02X ", newVal);
nkeynes@2
   207
                if( oldVal == newVal )
nkeynes@2
   208
                    gtk_text_buffer_insert( buf, &iter, text, 3 );
nkeynes@2
   209
                else
nkeynes@2
   210
                    gtk_text_buffer_insert_with_tags( buf, &iter, text, 3,
nkeynes@2
   211
                                                      changedTag, NULL );
nkeynes@2
   212
            } else {
nkeynes@2
   213
                gtk_text_buffer_insert( buf, &iter, "   ", 3 );
nkeynes@2
   214
            }
nkeynes@2
   215
        }
nkeynes@2
   216
        gtk_text_buffer_insert( buf, &iter, "  ", 2 );
nkeynes@2
   217
        for( j=0; j<16 && i+j < data->end; j++ ) {
nkeynes@2
   218
            int oldVal = ((int)old_data[offset+j])&0xFF;
nkeynes@2
   219
            int newVal = ((int)new_data[offset+j])&0xFF;
nkeynes@2
   220
            if( isprint(newVal) )
nkeynes@2
   221
                sprintf( text, "%c", newVal );
nkeynes@2
   222
            else strcpy( text, "." );
nkeynes@2
   223
            if( oldVal == newVal )
nkeynes@2
   224
                gtk_text_buffer_insert( buf, &iter, text, 1 );
nkeynes@2
   225
            else
nkeynes@2
   226
                gtk_text_buffer_insert_with_tags( buf, &iter, text, 1,
nkeynes@2
   227
                                                  changedTag, NULL );
nkeynes@2
   228
        }
nkeynes@2
   229
        gtk_text_buffer_insert( buf, &iter, "\n", 1 );
nkeynes@2
   230
    }
nkeynes@2
   231
}
.