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 457:af605fd32c0b
prev455:3080881d00d4
next484:e2c1476f4c67
author nkeynes
date Wed Oct 24 21:23:22 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Fix long standing texcache management bug (invalidate palette was not placing
the invalidated entries on the free list).
view annotate diff log raw
     1 /**
     2  * $Id: dump_win.c,v 1.6 2007-10-21 11:38:02 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"
    25 #define MAX_DUMP_SIZE 4096
    27 #define DUMP_WINDOW_TAG 0xD4B9DA7A
    29 struct dump_window_info {
    30     uint32_t _tag;
    31     uint32_t start;
    32     uint32_t end;
    33     int flags;
    34     unsigned char *data;
    36     GtkWidget *window;
    37     GtkWidget *fromInput, *toInput;
    38     GtkWidget *textArea;
    39     GtkTextTag *changedTag;
    40     GtkTextBuffer *textBuffer;
    41     struct dump_window_info *next;
    42 };
    44 static dump_window_t dump_list_head = NULL;
    46 gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,
    47                                    gpointer user_data );
    48 void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data );
    49 void dump_window_set_text( dump_window_t data, unsigned char *old_data, unsigned char *new_data );
    52 dump_window_t dump_window_new( const gchar *title )
    53 {
    54     GtkWidget *vbox3;
    55     GtkWidget *hbox2;
    56     GtkWidget *dump_view_button;
    57     GtkWidget *scrolledwindow9;
    59     dump_window_t dump = g_malloc0( sizeof( struct dump_window_info ) );
    61     dump->_tag = DUMP_WINDOW_TAG;
    62     dump->next = dump_list_head;
    63     dump_list_head = dump;
    64     dump->data = NULL;
    65     dump->start = 0;
    66     dump->end = 0;
    67     dump->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    68     gtk_window_set_title (GTK_WINDOW (dump->window), _("Memory dump"));
    70     vbox3 = gtk_vbox_new (FALSE, 0);
    71     gtk_container_add (GTK_CONTAINER (dump->window), vbox3);
    73     hbox2 = gtk_hbox_new (FALSE, 0);
    74     dump->fromInput = gtk_entry_new ();
    75     gtk_entry_set_text( GTK_ENTRY(dump->fromInput), "" );
    76     dump->toInput = gtk_entry_new ();
    77     gtk_entry_set_text( GTK_ENTRY(dump->toInput), "" );
    78     dump_view_button = gtk_button_new_with_mnemonic (_("View"));
    80     gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new(_(" From ")), FALSE, FALSE, 0);
    81     gtk_box_pack_start (GTK_BOX (hbox2), dump->fromInput, FALSE, TRUE, 0);
    82     gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new(_(" To ")), FALSE, FALSE, 0);
    83     gtk_box_pack_start (GTK_BOX (hbox2), dump->toInput, FALSE, TRUE, 0);
    84     gtk_box_pack_start (GTK_BOX (hbox2), dump_view_button, FALSE, FALSE, 0);
    85     gtk_box_pack_start (GTK_BOX (hbox2), gtk_label_new (_("   ")), TRUE, TRUE, 0);
    86     gtk_box_pack_start (GTK_BOX (vbox3), hbox2, FALSE, TRUE, 3);
    88     dump->textArea = gtk_text_view_new ();
    89     dump->textBuffer = gtk_text_buffer_new(NULL);
    90     dump->changedTag = gtk_text_buffer_create_tag(dump->textBuffer, "changed",
    91 						  "foreground", "blue", NULL);
    92     gtk_widget_modify_font(GTK_WIDGET(dump->textArea),gui_fixed_font);
    93     gtk_text_view_set_editable(GTK_TEXT_VIEW(dump->textArea), FALSE);
    94     gtk_text_view_set_buffer(GTK_TEXT_VIEW(dump->textArea), dump->textBuffer);
    95     scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL);
    96     gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_SHADOW_IN);
    97     gtk_container_add (GTK_CONTAINER (scrolledwindow9), dump->textArea);
    98     gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow9, TRUE, TRUE, 0);
   100     g_signal_connect (dump->window, "delete_event",
   101                       G_CALLBACK (on_dump_window_delete_event),
   102                       dump);
   103     g_signal_connect (dump_view_button, "clicked",
   104                       G_CALLBACK (on_dump_window_button_view_clicked),
   105                       dump);
   106     gtk_widget_show_all( dump->window );
   108     return dump;
   109 }
   111 void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value )
   112 {
   113     char buf[10];
   114     sprintf( buf, "%08X", value );
   115     gtk_entry_set_text( entry, buf );
   116 }
   118 uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue )
   119 {
   120     const gchar *text = gtk_entry_get_text(entry);
   121     if( text == NULL )
   122         return defaultValue;
   123     gchar *endptr;
   124     uint32_t value = strtoul( text, &endptr, 16 );
   125     if( text == endptr ) { /* invalid input */
   126         value = defaultValue;
   127         gtk_entry_set_hex_value( entry, value );
   128     }
   129     return value;
   130 }
   132 gboolean on_dump_window_delete_event( GtkWidget *widget, GdkEvent *event,
   133                                    gpointer user_data )
   134 {
   135     dump_window_t data = (dump_window_t)user_data;
   136     if( data->data != NULL )
   137         free( data->data );
   138     dump_window_t node = dump_list_head;
   139     if( node == data )
   140         dump_list_head = data->next;
   141     else {
   142         while( node->next != data ) {
   143             node = node->next;
   144             assert( node != NULL );
   145         }
   146         node->next = data->next;
   147     }
   148     free( data );
   149     return FALSE;
   150 }
   152 void on_dump_window_button_view_clicked( GtkWidget *widget, gpointer user_data )
   153 {
   154     dump_window_t data = (dump_window_t)user_data;
   155     uint32_t startVal, endVal;
   157     assert( data != NULL );
   158     assert( data->_tag == DUMP_WINDOW_TAG );
   160     startVal = gtk_entry_get_hex_value(GTK_ENTRY(data->fromInput), data->start);
   161     endVal = gtk_entry_get_hex_value(GTK_ENTRY(data->toInput), data->end);
   162     if( startVal != data->start || endVal != data->end ) {
   163         if( startVal > endVal ) {
   164             int tmp = endVal;
   165             endVal = startVal;
   166             startVal = tmp;
   167         }
   168         if( endVal > startVal + MAX_DUMP_SIZE )
   169             endVal = startVal + MAX_DUMP_SIZE;
   171         gtk_entry_set_hex_value(GTK_ENTRY(data->fromInput),startVal);
   172 	gtk_entry_set_hex_value(GTK_ENTRY(data->toInput),endVal);
   173         data->start = startVal;
   174         data->end = endVal;
   176         if( data->data != NULL ) {
   177             free( data->data );
   178             data->data = NULL;
   179         }
   180         if( startVal != endVal ) {
   181             data->data = malloc( endVal - startVal );
   182             mem_copy_from_sh4( data->data, startVal, endVal-startVal );
   183             dump_window_set_text( data, data->data, data->data );
   184         }
   185     }
   186 }
   188 void dump_window_update( dump_window_t data )
   189 {
   190     if( data->data == NULL )
   191         return;
   192     unsigned char tmp[data->end-data->start];
   193     int length = data->end-data->start;
   194     memcpy( tmp, data->data, length );
   195     mem_copy_from_sh4( data->data, data->start, length );
   196     dump_window_set_text( data, tmp, data->data );
   197 }
   199 void dump_window_update_all( )
   200 {
   201     dump_window_t node = dump_list_head;
   202     while( node != NULL ) {
   203         dump_window_update(node);
   204         node = node->next;
   205     }
   206 }
   208 void dump_window_set_text( dump_window_t data, unsigned char *old_data, unsigned char *new_data )
   209 {
   210     GtkTextBuffer *buf = data->textBuffer;
   211     GtkTextTag *changedTag = data->changedTag;
   212     GtkTextIter iter, endIter;
   213     int i, j, offset;
   214     /* Clear out the buffer */
   215     gtk_text_buffer_get_start_iter(buf,&iter);
   216     gtk_text_buffer_get_end_iter(buf,&endIter);
   217     gtk_text_buffer_delete(buf,&iter,&endIter);
   218     gtk_text_buffer_get_start_iter(buf,&iter);
   220     for( offset = 0, i=data->start; i<data->end; i+=16, offset+=16 ) {
   221         char text[80];
   222         sprintf(text, "%08X:", i );
   223         gtk_text_buffer_insert( buf, &iter, text, 9 );
   224         for( j=0; j<16; j++ ) {
   225             if( j%4 == 0 )
   226                 gtk_text_buffer_insert( buf, &iter, " ", 1 );
   227             if( i+j < data->end ) {
   228                 int oldVal = ((int)old_data[offset+j])&0xFF;
   229                 int newVal = ((int)new_data[offset+j])&0xFF;
   230                 sprintf(text, "%02X ", newVal);
   231                 if( oldVal == newVal )
   232                     gtk_text_buffer_insert( buf, &iter, text, 3 );
   233                 else
   234                     gtk_text_buffer_insert_with_tags( buf, &iter, text, 3,
   235                                                       changedTag, NULL );
   236             } else {
   237                 gtk_text_buffer_insert( buf, &iter, "   ", 3 );
   238             }
   239         }
   240         gtk_text_buffer_insert( buf, &iter, "  ", 2 );
   241         for( j=0; j<16 && i+j < data->end; j++ ) {
   242             int oldVal = ((int)old_data[offset+j])&0xFF;
   243             int newVal = ((int)new_data[offset+j])&0xFF;
   244             if( isprint(newVal) )
   245                 sprintf( text, "%c", newVal );
   246             else strcpy( text, "." );
   247             if( oldVal == newVal )
   248                 gtk_text_buffer_insert( buf, &iter, text, 1 );
   249             else
   250                 gtk_text_buffer_insert_with_tags( buf, &iter, text, 1,
   251                                                   changedTag, NULL );
   252         }
   253         gtk_text_buffer_insert( buf, &iter, "\n", 1 );
   254     }
   255 }
.