nkeynes@30: /** nkeynes@43: * $Id: gui.c,v 1.9 2005-12-26 11:47:15 nkeynes Exp $ nkeynes@30: * nkeynes@30: * Top-level GUI (GTK2) module. nkeynes@30: * nkeynes@30: * Copyright (c) 2005 Nathan Keynes. nkeynes@30: * nkeynes@30: * This program is free software; you can redistribute it and/or modify nkeynes@30: * it under the terms of the GNU General Public License as published by nkeynes@30: * the Free Software Foundation; either version 2 of the License, or nkeynes@30: * (at your option) any later version. nkeynes@30: * nkeynes@30: * This program is distributed in the hope that it will be useful, nkeynes@30: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@30: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@30: * GNU General Public License for more details. nkeynes@30: */ nkeynes@30: nkeynes@1: #include nkeynes@1: #include nkeynes@1: #include nkeynes@1: #include nkeynes@27: #include "dream.h" nkeynes@18: #include "dreamcast.h" nkeynes@1: #include "mem.h" nkeynes@30: #include "sh4/sh4dasm.h" nkeynes@30: #include "aica/armdasm.h" nkeynes@27: #include "gui/gui.h" nkeynes@1: nkeynes@1: #define REGISTER_FONT "-*-fixed-medium-r-normal--12-*-*-*-*-*-iso8859-1" nkeynes@1: nkeynes@1: GdkColor clrNormal, clrChanged, clrError, clrWarn, clrPC, clrDebug, clrTrace; nkeynes@43: GdkColor clrBreak, clrTempBreak, clrWhite; nkeynes@1: PangoFontDescription *fixed_list_font; nkeynes@1: nkeynes@27: debug_info_t main_debug; nkeynes@27: nkeynes@27: nkeynes@18: void open_file_callback(GtkWidget *btn, gint result, gpointer user_data); nkeynes@1: nkeynes@27: void gtk_gui_init( void ); nkeynes@27: void gtk_gui_update( void ); nkeynes@28: void gtk_gui_start( void ); nkeynes@28: void gtk_gui_stop( void ); nkeynes@30: uint32_t gtk_gui_run_slice( uint32_t nanosecs ); nkeynes@27: nkeynes@27: struct dreamcast_module gtk_gui_module = { "Debugger", gtk_gui_init, nkeynes@28: gtk_gui_update, gtk_gui_start, nkeynes@27: gtk_gui_run_slice, nkeynes@28: gtk_gui_stop, nkeynes@27: NULL, NULL }; nkeynes@27: nkeynes@27: const cpu_desc_t cpu_descs[4] = { &sh4_cpu_desc, &arm_cpu_desc, &armt_cpu_desc, NULL }; nkeynes@27: nkeynes@27: nkeynes@27: void gtk_gui_init() { nkeynes@2: GdkColormap *map; nkeynes@27: GtkWidget *debug_win; nkeynes@27: nkeynes@2: clrNormal.red = clrNormal.green = clrNormal.blue = 0; nkeynes@2: clrChanged.red = clrChanged.green = 64*256; nkeynes@2: clrChanged.blue = 154*256; nkeynes@2: clrError.red = 65535; nkeynes@2: clrError.green = clrError.blue = 64*256; nkeynes@2: clrPC.red = 32*256; nkeynes@2: clrPC.green = 170*256; nkeynes@2: clrPC.blue = 52*256; nkeynes@2: clrWarn = clrChanged; nkeynes@2: clrTrace.red = 156*256; nkeynes@2: clrTrace.green = 78*256; nkeynes@2: clrTrace.blue = 201*256; nkeynes@2: clrDebug = clrPC; nkeynes@43: clrBreak.red = 65535; nkeynes@43: clrBreak.green = clrBreak.blue = 192*256; nkeynes@43: clrTempBreak.red = clrTempBreak.green = 128*256; nkeynes@43: clrTempBreak.blue = 32*256; nkeynes@43: clrWhite.red = clrWhite.green = clrWhite.blue = 65535; nkeynes@1: nkeynes@2: map = gdk_colormap_new(gdk_visual_get_best(), TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrNormal, TRUE, TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrChanged, TRUE, TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrError, TRUE, TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrWarn, TRUE, TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrPC, TRUE, TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrDebug, TRUE, TRUE); nkeynes@2: gdk_colormap_alloc_color(map, &clrTrace, TRUE, TRUE); nkeynes@43: gdk_colormap_alloc_color(map, &clrBreak, TRUE, TRUE); nkeynes@43: gdk_colormap_alloc_color(map, &clrTempBreak, TRUE, TRUE); nkeynes@43: gdk_colormap_alloc_color(map, &clrWhite, TRUE, TRUE); nkeynes@2: fixed_list_font = pango_font_description_from_string("Courier 10"); nkeynes@27: debug_win = create_debug_win (); nkeynes@27: main_debug = init_debug_win(debug_win, cpu_descs); nkeynes@27: init_mmr_win(); nkeynes@27: nkeynes@27: gtk_widget_show (debug_win); nkeynes@27: nkeynes@2: } nkeynes@2: nkeynes@28: /** nkeynes@28: * Hook called when DC starts running. Just disables the run/step buttons nkeynes@28: * and enables the stop button. nkeynes@28: */ nkeynes@28: void gtk_gui_start( void ) nkeynes@28: { nkeynes@28: debug_win_set_running( main_debug, TRUE ); nkeynes@28: } nkeynes@28: nkeynes@28: /** nkeynes@28: * Hook called when DC stops running. Enables the run/step buttons nkeynes@28: * and disables the stop button. nkeynes@28: */ nkeynes@28: void gtk_gui_stop( void ) nkeynes@28: { nkeynes@28: debug_win_set_running( main_debug, FALSE ); nkeynes@28: gtk_gui_update(); nkeynes@28: } nkeynes@28: nkeynes@30: uint32_t gtk_gui_run_slice( uint32_t nanosecs ) nkeynes@23: { nkeynes@23: while( gtk_events_pending() ) nkeynes@23: gtk_main_iteration(); nkeynes@23: update_icount(main_debug); nkeynes@30: return nanosecs; nkeynes@23: } nkeynes@23: nkeynes@27: void gtk_gui_update(void) { nkeynes@9: update_registers(main_debug); nkeynes@9: update_icount(main_debug); nkeynes@1: update_mmr_win(); nkeynes@2: dump_win_update_all(); nkeynes@1: } nkeynes@1: nkeynes@18: void open_file_callback(GtkWidget *btn, gint result, gpointer user_data) { nkeynes@18: GtkFileChooser *file = GTK_FILE_CHOOSER(user_data); nkeynes@18: if( result == GTK_RESPONSE_ACCEPT ) { nkeynes@18: gchar *filename =gtk_file_chooser_get_filename( nkeynes@18: GTK_FILE_CHOOSER(file) ); nkeynes@18: file_callback_t action = (file_callback_t)gtk_object_get_data( GTK_OBJECT(file), "file_action" ); nkeynes@18: gtk_widget_destroy(GTK_WIDGET(file)); nkeynes@18: action( filename ); nkeynes@18: g_free(filename); nkeynes@18: } else { nkeynes@18: gtk_widget_destroy(GTK_WIDGET(file)); nkeynes@18: } nkeynes@1: } nkeynes@1: nkeynes@18: static void add_file_pattern( GtkFileChooser *chooser, char *pattern, char *patname ) nkeynes@18: { nkeynes@18: if( pattern != NULL ) { nkeynes@18: GtkFileFilter *filter = gtk_file_filter_new(); nkeynes@18: gtk_file_filter_add_pattern( filter, pattern ); nkeynes@18: gtk_file_filter_set_name( filter, patname ); nkeynes@18: gtk_file_chooser_add_filter( chooser, filter ); nkeynes@18: filter = gtk_file_filter_new(); nkeynes@18: gtk_file_filter_set_name( filter, "All files" ); nkeynes@18: gtk_file_filter_add_pattern( filter, "*" ); nkeynes@18: gtk_file_chooser_add_filter( chooser, filter ); nkeynes@18: } nkeynes@1: } nkeynes@1: nkeynes@18: void open_file_dialog( char *title, file_callback_t action, char *pattern, char *patname ) nkeynes@1: { nkeynes@1: GtkWidget *file; nkeynes@1: nkeynes@18: file = gtk_file_chooser_dialog_new( title, NULL, nkeynes@18: GTK_FILE_CHOOSER_ACTION_OPEN, nkeynes@18: GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, nkeynes@18: GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, nkeynes@18: NULL ); nkeynes@18: add_file_pattern( GTK_FILE_CHOOSER(file), pattern, patname ); nkeynes@18: g_signal_connect( GTK_OBJECT(file), "response", nkeynes@18: GTK_SIGNAL_FUNC(open_file_callback), file ); nkeynes@18: gtk_object_set_data( GTK_OBJECT(file), "file_action", action ); nkeynes@18: gtk_widget_show( file ); nkeynes@18: } nkeynes@18: nkeynes@18: void save_file_dialog( char *title, file_callback_t action, char *pattern, char *patname ) nkeynes@18: { nkeynes@18: GtkWidget *file; nkeynes@18: nkeynes@18: file = gtk_file_chooser_dialog_new( title, NULL, nkeynes@18: GTK_FILE_CHOOSER_ACTION_SAVE, nkeynes@18: GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, nkeynes@18: GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, nkeynes@18: NULL ); nkeynes@18: add_file_pattern( GTK_FILE_CHOOSER(file), pattern, patname ); nkeynes@18: g_signal_connect( GTK_OBJECT(file), "response", nkeynes@18: GTK_SIGNAL_FUNC(open_file_callback), file ); nkeynes@18: gtk_object_set_data( GTK_OBJECT(file), "file_action", action ); nkeynes@1: gtk_widget_show( file ); nkeynes@1: } nkeynes@1: nkeynes@2: uint32_t gtk_entry_get_hex_value( GtkEntry *entry, uint32_t defaultValue ) nkeynes@1: { nkeynes@2: gchar *text = gtk_entry_get_text(entry); nkeynes@2: if( text == NULL ) nkeynes@2: return defaultValue; nkeynes@2: gchar *endptr; nkeynes@2: uint32_t value = strtoul( text, &endptr, 16 ); nkeynes@2: if( text == endptr ) { /* invalid input */ nkeynes@2: value = defaultValue; nkeynes@2: gtk_entry_set_hex_value( entry, value ); nkeynes@2: } nkeynes@2: return value; nkeynes@1: } nkeynes@1: nkeynes@2: void gtk_entry_set_hex_value( GtkEntry *entry, uint32_t value ) nkeynes@1: { nkeynes@2: char buf[10]; nkeynes@2: sprintf( buf, "%08X", value ); nkeynes@2: gtk_entry_set_text( entry, buf ); nkeynes@1: }