Search
lxdream.org :: lxdream/src/gtkui/gtk_debug.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/gtkui/gtk_debug.c
changeset 763:b3ce4448f200
prev755:ab873907b00e
next887:8b3ee741c9d7
author nkeynes
date Tue Jul 22 04:40:55 2008 +0000 (12 years ago)
permissions -rw-r--r--
last change Rename GTK UI files to follow the same scheme as the cocoa ones
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/gtkui/gtk_debug.c Tue Jul 22 04:40:55 2008 +0000
1.3 @@ -0,0 +1,454 @@
1.4 +/**
1.5 + * $Id$
1.6 + * This file is responsible for the main debugger gui frame.
1.7 + *
1.8 + * Copyright (c) 2005 Nathan Keynes.
1.9 + *
1.10 + * This program is free software; you can redistribute it and/or modify
1.11 + * it under the terms of the GNU General Public License as published by
1.12 + * the Free Software Foundation; either version 2 of the License, or
1.13 + * (at your option) any later version.
1.14 + *
1.15 + * This program is distributed in the hope that it will be useful,
1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.18 + * GNU General Public License for more details.
1.19 + */
1.20 +#include <stdlib.h>
1.21 +#include <stdarg.h>
1.22 +#include <stdio.h>
1.23 +#include <string.h>
1.24 +#include <math.h>
1.25 +#include <gdk/gdkkeysyms.h>
1.26 +#include "mem.h"
1.27 +#include "cpu.h"
1.28 +#include "dreamcast.h"
1.29 +#include "gtkui/gtkui.h"
1.30 +#include "sh4/sh4dasm.h"
1.31 +#include "aica/armdasm.h"
1.32 +
1.33 +GdkColor *msg_colors[] = { &gui_colour_error, &gui_colour_error, &gui_colour_warn,
1.34 + &gui_colour_normal,&gui_colour_debug, &gui_colour_trace };
1.35 +
1.36 +const cpu_desc_t cpu_list[4] = { &sh4_cpu_desc, &arm_cpu_desc, &armt_cpu_desc, NULL };
1.37 +
1.38 +void init_register_list( debug_window_t data );
1.39 +uint32_t row_to_address( debug_window_t data, int row );
1.40 +int address_to_row( debug_window_t data, uint32_t address );
1.41 +void set_disassembly_pc( debug_window_t data, unsigned int pc, gboolean select );
1.42 +void set_disassembly_region( debug_window_t data, unsigned int page );
1.43 +void set_disassembly_cpu( debug_window_t data, const gchar *cpu );
1.44 +
1.45 +void on_mode_field_changed ( GtkEditable *editable, gpointer user_data);
1.46 +gboolean on_page_field_key_press_event( GtkWidget * widget, GdkEventKey *event,
1.47 + gpointer user_data);
1.48 +void on_jump_pc_btn_clicked( GtkButton *button, gpointer user_data);
1.49 +void on_disasm_list_select_row (GtkCList *clist, gint row, gint column,
1.50 + GdkEvent *event, gpointer user_data);
1.51 +void on_disasm_list_unselect_row (GtkCList *clist, gint row, gint column,
1.52 + GdkEvent *event, gpointer user_data);
1.53 +gboolean on_debug_delete_event(GtkWidget *widget, GdkEvent event, gpointer user_data);
1.54 +
1.55 +struct debug_window_info {
1.56 + int disasm_from;
1.57 + int disasm_to;
1.58 + int disasm_pc;
1.59 + const struct cpu_desc_struct *cpu;
1.60 + const cpu_desc_t *cpu_list;
1.61 + GtkCList *regs_list;
1.62 + GtkCList *disasm_list;
1.63 + GtkEntry *page_field;
1.64 + GtkWidget *window;
1.65 + GtkWidget *statusbar;
1.66 + char saved_regs[0];
1.67 +};
1.68 +
1.69 +debug_window_t debug_window_new( const gchar *title, GtkWidget *menubar,
1.70 + GtkWidget *toolbar, GtkAccelGroup *accel_group )
1.71 +{
1.72 + debug_window_t data = g_malloc0( sizeof(struct debug_window_info) + cpu_list[0]->regs_size );
1.73 + GtkWidget *vbox;
1.74 +
1.75 + data->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1.76 + gtk_window_set_default_size (GTK_WINDOW (data->window), 700, 480);
1.77 + gtk_window_set_title( GTK_WINDOW(data->window), title );
1.78 + gtk_window_add_accel_group (GTK_WINDOW (data->window), accel_group);
1.79 +
1.80 + gtk_toolbar_set_style( GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS );
1.81 +
1.82 + data->statusbar = gtk_statusbar_new();
1.83 +
1.84 + GtkWidget *hpaned = gtk_hpaned_new ();
1.85 + gtk_paned_set_position (GTK_PANED (hpaned), 500);
1.86 +
1.87 + GtkWidget *disasm_box = gtk_vbox_new(FALSE,0);
1.88 + gtk_paned_pack1 (GTK_PANED (hpaned), disasm_box, TRUE, TRUE);
1.89 +
1.90 + GtkWidget *hbox1 = gtk_hbox_new (FALSE, 0);
1.91 + gtk_box_pack_start (GTK_BOX (disasm_box), hbox1, FALSE, FALSE, 3);
1.92 + gtk_box_pack_start (GTK_BOX (hbox1), gtk_label_new (_("Page")), FALSE, FALSE, 4);
1.93 +
1.94 + data->page_field = GTK_ENTRY(gtk_entry_new ());
1.95 + gtk_box_pack_start (GTK_BOX (hbox1), GTK_WIDGET(data->page_field), FALSE, TRUE, 0);
1.96 +
1.97 + GtkWidget *jump_pc_btn = gtk_button_new_with_mnemonic (_(" Jump to PC "));
1.98 + gtk_box_pack_start (GTK_BOX (hbox1), jump_pc_btn, FALSE, FALSE, 4);
1.99 +
1.100 + gtk_box_pack_start (GTK_BOX (hbox1), gtk_label_new(_("Mode")), FALSE, FALSE, 5);
1.101 +
1.102 + GtkWidget *mode_box = gtk_combo_new ();
1.103 + gtk_box_pack_start (GTK_BOX (hbox1), mode_box, FALSE, FALSE, 0);
1.104 + GList *mode_box_items = NULL;
1.105 + mode_box_items = g_list_append (mode_box_items, (gpointer) _("SH4"));
1.106 + mode_box_items = g_list_append (mode_box_items, (gpointer) _("ARM7"));
1.107 + mode_box_items = g_list_append (mode_box_items, (gpointer) _("ARM7T"));
1.108 + gtk_combo_set_popdown_strings (GTK_COMBO (mode_box), mode_box_items);
1.109 + g_list_free (mode_box_items);
1.110 +
1.111 + GtkWidget *mode_field = GTK_COMBO (mode_box)->entry;
1.112 + gtk_editable_set_editable (GTK_EDITABLE (mode_field), FALSE);
1.113 +
1.114 + GtkWidget *disasm_scroll = gtk_scrolled_window_new (NULL, NULL);
1.115 + gtk_box_pack_start (GTK_BOX (disasm_box), disasm_scroll, TRUE, TRUE, 0);
1.116 + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (disasm_scroll), GTK_SHADOW_IN);
1.117 + data->disasm_list = GTK_CLIST(gtk_clist_new (4));
1.118 + gtk_clist_set_column_width (GTK_CLIST (data->disasm_list), 0, 80);
1.119 + gtk_clist_set_column_width (GTK_CLIST (data->disasm_list), 2, 80);
1.120 + gtk_clist_set_column_width (GTK_CLIST (data->disasm_list), 3, 80);
1.121 + gtk_clist_set_column_width( data->disasm_list, 1, 16 );
1.122 + gtk_clist_column_titles_hide (GTK_CLIST (data->disasm_list));
1.123 + gtk_container_add (GTK_CONTAINER (disasm_scroll), GTK_WIDGET(data->disasm_list));
1.124 +
1.125 + GtkWidget *reg_scroll = gtk_scrolled_window_new (NULL, NULL);
1.126 + gtk_paned_pack2 (GTK_PANED (hpaned), reg_scroll, FALSE, TRUE);
1.127 + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (reg_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1.128 + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (reg_scroll), GTK_SHADOW_IN);
1.129 +
1.130 + data->regs_list = GTK_CLIST(gtk_clist_new (2));
1.131 + gtk_container_add (GTK_CONTAINER (reg_scroll), GTK_WIDGET(data->regs_list));
1.132 + gtk_clist_set_column_width (GTK_CLIST (data->regs_list), 0, 80);
1.133 + gtk_clist_set_column_width (GTK_CLIST (data->regs_list), 1, 80);
1.134 + gtk_clist_column_titles_hide (GTK_CLIST (data->regs_list));
1.135 + gtk_widget_modify_font( GTK_WIDGET(data->regs_list), gui_fixed_font );
1.136 +
1.137 + vbox = gtk_vbox_new(FALSE, 0);
1.138 + gtk_container_add( GTK_CONTAINER(data->window), vbox );
1.139 + gtk_box_pack_start( GTK_BOX(vbox), menubar, FALSE, FALSE, 0 );
1.140 + gtk_box_pack_start( GTK_BOX(vbox), toolbar, FALSE, FALSE, 0 );
1.141 + gtk_box_pack_start( GTK_BOX(vbox), hpaned, TRUE, TRUE, 0 );
1.142 + gtk_box_pack_start( GTK_BOX(vbox), data->statusbar, FALSE, FALSE, 0 );
1.143 +
1.144 + g_signal_connect ((gpointer) data->page_field, "key_press_event",
1.145 + G_CALLBACK (on_page_field_key_press_event),
1.146 + data);
1.147 + g_signal_connect ((gpointer) jump_pc_btn, "clicked",
1.148 + G_CALLBACK (on_jump_pc_btn_clicked),
1.149 + data);
1.150 + g_signal_connect ((gpointer) mode_field, "changed",
1.151 + G_CALLBACK (on_mode_field_changed),
1.152 + data);
1.153 + g_signal_connect ((gpointer) data->disasm_list, "select_row",
1.154 + G_CALLBACK (on_disasm_list_select_row),
1.155 + data);
1.156 + g_signal_connect ((gpointer) data->disasm_list, "unselect_row",
1.157 + G_CALLBACK (on_disasm_list_unselect_row),
1.158 + data);
1.159 + g_signal_connect ((gpointer) data->window, "delete_event",
1.160 + G_CALLBACK (on_debug_delete_event),
1.161 + data);
1.162 +
1.163 + data->disasm_from = -1;
1.164 + data->disasm_to = -1;
1.165 + data->disasm_pc = -1;
1.166 + data->cpu = cpu_list[0];
1.167 + data->cpu_list = cpu_list;
1.168 +
1.169 + init_register_list( data );
1.170 + gtk_object_set_data( GTK_OBJECT(data->window), "debug_data", data );
1.171 + set_disassembly_pc( data, *data->cpu->pc, FALSE );
1.172 + debug_window_set_running( data, FALSE );
1.173 +
1.174 + gtk_widget_show_all( data->window );
1.175 + return data;
1.176 +}
1.177 +
1.178 +void debug_window_show( debug_window_t data, gboolean show )
1.179 +{
1.180 + if( show ) {
1.181 + gtk_widget_show( data->window );
1.182 + } else {
1.183 + gtk_widget_hide( data->window );
1.184 + }
1.185 +}
1.186 +
1.187 +int debug_window_get_selected_row( debug_window_t data )
1.188 +{
1.189 + if( data->disasm_list->selection == NULL ) {
1.190 + return -1;
1.191 + } else {
1.192 + return GPOINTER_TO_INT(data->disasm_list->selection->data);
1.193 + }
1.194 +}
1.195 +
1.196 +void init_register_list( debug_window_t data )
1.197 +{
1.198 + int i;
1.199 + char buf[20];
1.200 + char *arr[2];
1.201 +
1.202 + gtk_clist_clear( data->regs_list );
1.203 + arr[1] = buf;
1.204 + for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
1.205 + arr[0] = data->cpu->regs_info[i].name;
1.206 + if( data->cpu->regs_info->type == REG_INT )
1.207 + sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );
1.208 + else
1.209 + sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );
1.210 + gtk_clist_append( data->regs_list, arr );
1.211 + }
1.212 +}
1.213 +
1.214 +/*
1.215 + * Check for changed registers and update the display
1.216 + */
1.217 +void debug_window_update( debug_window_t data )
1.218 +{
1.219 + int i;
1.220 + for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
1.221 + if( data->cpu->regs_info[i].type == REG_INT ) {
1.222 + /* Yes this _is_ probably fairly evil */
1.223 + if( *((uint32_t *)data->cpu->regs_info[i].value) !=
1.224 + *((uint32_t *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
1.225 + char buf[20];
1.226 + sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );
1.227 + gtk_clist_set_text( data->regs_list, i, 1, buf );
1.228 + gtk_clist_set_foreground( data->regs_list, i, &gui_colour_changed );
1.229 + } else {
1.230 + gtk_clist_set_foreground( data->regs_list, i, &gui_colour_normal );
1.231 + }
1.232 + } else {
1.233 + if( *((float *)data->cpu->regs_info[i].value) !=
1.234 + *((float *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
1.235 + char buf[20];
1.236 + sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );
1.237 + gtk_clist_set_text( data->regs_list, i, 1, buf );
1.238 + gtk_clist_set_foreground( data->regs_list, i, &gui_colour_changed );
1.239 + } else {
1.240 + gtk_clist_set_foreground( data->regs_list, i, &gui_colour_normal );
1.241 + }
1.242 + }
1.243 + }
1.244 +
1.245 + set_disassembly_pc( data, *data->cpu->pc, TRUE );
1.246 + memcpy( data->saved_regs, data->cpu->regs, data->cpu->regs_size );
1.247 +}
1.248 +
1.249 +void set_disassembly_region( debug_window_t data, unsigned int page )
1.250 +{
1.251 + uint32_t i, posn, next;
1.252 + char buf[80];
1.253 + char addr[10];
1.254 + char opcode[16] = "";
1.255 + char *arr[4] = { addr, " ", opcode, buf };
1.256 + unsigned int from = page & 0xFFFFF000;
1.257 + unsigned int to = from + 4096;
1.258 +
1.259 + gtk_clist_clear(data->disasm_list);
1.260 +
1.261 + sprintf( addr, "%08X", from );
1.262 + gtk_entry_set_text( data->page_field, addr );
1.263 +
1.264 + if( !data->cpu->is_valid_page_func( from ) ) {
1.265 + arr[3] = _("This page is currently unmapped");
1.266 + gtk_clist_append( data->disasm_list, arr );
1.267 + gtk_clist_set_foreground( data->disasm_list, 0, &gui_colour_error );
1.268 + } else {
1.269 + for( i=from; i<to; i = next ) {
1.270 + next = data->cpu->disasm_func( i, buf, sizeof(buf), opcode );
1.271 + sprintf( addr, "%08X", i );
1.272 + posn = gtk_clist_append( data->disasm_list, arr );
1.273 + if( buf[0] == '?' )
1.274 + gtk_clist_set_foreground( data->disasm_list, posn, &gui_colour_warn );
1.275 + if( data->cpu->get_breakpoint != NULL ) {
1.276 + int type = data->cpu->get_breakpoint( i );
1.277 + switch(type) {
1.278 + case BREAK_ONESHOT:
1.279 + gtk_clist_set_background( data->disasm_list, posn, &gui_colour_temp_break );
1.280 + break;
1.281 + case BREAK_KEEP:
1.282 + gtk_clist_set_background( data->disasm_list, posn, &gui_colour_break );
1.283 + break;
1.284 + }
1.285 + }
1.286 + }
1.287 + if( data->disasm_pc != -1 && data->disasm_pc >= from && data->disasm_pc < to )
1.288 + gtk_clist_set_foreground( data->disasm_list, address_to_row(data, data->disasm_pc),
1.289 + &gui_colour_pc );
1.290 + }
1.291 +
1.292 + if( page != from ) { /* not a page boundary */
1.293 + gtk_clist_moveto( data->disasm_list, (page-from)>>1, 0, 0.5, 0.0 );
1.294 + }
1.295 + data->disasm_from = from;
1.296 + data->disasm_to = to;
1.297 +}
1.298 +
1.299 +void jump_to_disassembly( debug_window_t data, unsigned int addr, gboolean select )
1.300 +{
1.301 + int row;
1.302 +
1.303 + if( addr < data->disasm_from || addr >= data->disasm_to )
1.304 + set_disassembly_region(data,addr);
1.305 +
1.306 + row = address_to_row( data, addr );
1.307 + if(select) {
1.308 + gtk_clist_select_row( data->disasm_list, row, 0 );
1.309 + }
1.310 + if( gtk_clist_row_is_visible( data->disasm_list, row ) != GTK_VISIBILITY_FULL ){
1.311 + gtk_clist_moveto( data->disasm_list, row, 0, 0.5, 0.0 );
1.312 + }
1.313 +}
1.314 +
1.315 +void jump_to_pc( debug_window_t data, gboolean select )
1.316 +{
1.317 + jump_to_disassembly( data, *data->cpu->pc, select );
1.318 +}
1.319 +
1.320 +void set_disassembly_pc( debug_window_t data, unsigned int pc, gboolean select )
1.321 +{
1.322 + int row;
1.323 +
1.324 + jump_to_disassembly( data, pc, select );
1.325 + if( data->disasm_pc != -1 && data->disasm_pc >= data->disasm_from &&
1.326 + data->disasm_pc < data->disasm_to )
1.327 + gtk_clist_set_foreground( data->disasm_list,
1.328 + (data->disasm_pc - data->disasm_from) / data->cpu->instr_size,
1.329 + &gui_colour_normal );
1.330 + row = address_to_row( data, pc );
1.331 + gtk_clist_set_foreground( data->disasm_list, row, &gui_colour_pc );
1.332 + data->disasm_pc = pc;
1.333 +}
1.334 +
1.335 +void set_disassembly_cpu( debug_window_t data, const gchar *cpu )
1.336 +{
1.337 + int i;
1.338 + for( i=0; data->cpu_list[i] != NULL; i++ ) {
1.339 + if( strcmp( data->cpu_list[i]->name, cpu ) == 0 ) {
1.340 + if( data->cpu != data->cpu_list[i] ) {
1.341 + data->cpu = data->cpu_list[i];
1.342 + data->disasm_from = data->disasm_to = -1; /* Force reload */
1.343 + set_disassembly_pc( data, *data->cpu->pc, FALSE );
1.344 + init_register_list( data );
1.345 + }
1.346 + return;
1.347 + }
1.348 + }
1.349 +}
1.350 +
1.351 +void debug_window_toggle_breakpoint( debug_window_t data, int row )
1.352 +{
1.353 + uint32_t pc = row_to_address( data, row );
1.354 + int oldType = data->cpu->get_breakpoint( pc );
1.355 + if( oldType != BREAK_NONE ) {
1.356 + data->cpu->clear_breakpoint( pc, oldType );
1.357 + gtk_clist_set_background( data->disasm_list, row, &gui_colour_white );
1.358 + } else {
1.359 + data->cpu->set_breakpoint( pc, BREAK_KEEP );
1.360 + gtk_clist_set_background( data->disasm_list, row, &gui_colour_break );
1.361 + }
1.362 +}
1.363 +
1.364 +void debug_window_set_oneshot_breakpoint( debug_window_t data, int row )
1.365 +{
1.366 + uint32_t pc = row_to_address( data, row );
1.367 + data->cpu->clear_breakpoint( pc, BREAK_ONESHOT );
1.368 + data->cpu->set_breakpoint( pc, BREAK_ONESHOT );
1.369 + gtk_clist_set_background( data->disasm_list, row, &gui_colour_temp_break );
1.370 +}
1.371 +
1.372 +/**
1.373 + * Execute a single instruction using the current CPU mode.
1.374 + */
1.375 +void debug_window_single_step( debug_window_t data )
1.376 +{
1.377 + data->cpu->step_func();
1.378 + gtk_gui_update();
1.379 +}
1.380 +
1.381 +uint32_t row_to_address( debug_window_t data, int row ) {
1.382 + return data->cpu->instr_size * row + data->disasm_from;
1.383 +}
1.384 +
1.385 +int address_to_row( debug_window_t data, uint32_t address ) {
1.386 + if( data->disasm_from > address || data->disasm_to <= address )
1.387 + return -1;
1.388 + return (address - data->disasm_from) / data->cpu->instr_size;
1.389 +}
1.390 +
1.391 +debug_window_t get_debug_info( GtkWidget *widget ) {
1.392 +
1.393 + GtkWidget *win = gtk_widget_get_toplevel(widget);
1.394 + debug_window_t data = (debug_window_t)gtk_object_get_data( GTK_OBJECT(win), "debug_data" );
1.395 + return data;
1.396 +}
1.397 +
1.398 +void debug_window_set_running( debug_window_t data, gboolean isRunning )
1.399 +{
1.400 + if( data != NULL ) {
1.401 + gtk_gui_enable_action( "SingleStep", !isRunning );
1.402 + gtk_gui_enable_action( "RunTo", !isRunning && dreamcast_can_run() );
1.403 + }
1.404 +}
1.405 +
1.406 +void on_mode_field_changed ( GtkEditable *editable, gpointer user_data)
1.407 +{
1.408 + const gchar *text = gtk_entry_get_text( GTK_ENTRY(editable) );
1.409 + set_disassembly_cpu( gtk_gui_get_debugger(), text );
1.410 +}
1.411 +
1.412 +
1.413 +gboolean on_page_field_key_press_event( GtkWidget * widget, GdkEventKey *event,
1.414 + gpointer user_data)
1.415 +{
1.416 + if( event->keyval == GDK_Return || event->keyval == GDK_Linefeed ) {
1.417 + debug_window_t data = get_debug_info(widget);
1.418 + const gchar *text = gtk_entry_get_text( GTK_ENTRY(widget) );
1.419 + gchar *endptr;
1.420 + unsigned int val = strtoul( text, &endptr, 16 );
1.421 + if( text == endptr ) { /* invalid input */
1.422 + char buf[10];
1.423 + sprintf( buf, "%08X", row_to_address(data,0) );
1.424 + gtk_entry_set_text( GTK_ENTRY(widget), buf );
1.425 + } else {
1.426 + set_disassembly_region(data, val);
1.427 + }
1.428 + }
1.429 + return FALSE;
1.430 +}
1.431 +
1.432 +
1.433 +void on_jump_pc_btn_clicked( GtkButton *button, gpointer user_data)
1.434 +{
1.435 + debug_window_t data = get_debug_info( GTK_WIDGET(button) );
1.436 + jump_to_pc( data, TRUE );
1.437 +}
1.438 +
1.439 +void on_disasm_list_select_row (GtkCList *clist, gint row, gint column,
1.440 + GdkEvent *event, gpointer user_data)
1.441 +{
1.442 + gtk_gui_enable_action( "SetBreakpoint", TRUE );
1.443 + gtk_gui_enable_action( "RunTo", dreamcast_can_run() );
1.444 +}
1.445 +
1.446 +void on_disasm_list_unselect_row (GtkCList *clist, gint row, gint column,
1.447 + GdkEvent *event, gpointer user_data)
1.448 +{
1.449 + gtk_gui_enable_action( "SetBreakpoint", FALSE );
1.450 + gtk_gui_enable_action( "RunTo", FALSE );
1.451 +}
1.452 +
1.453 +gboolean on_debug_delete_event(GtkWidget *widget, GdkEvent event, gpointer user_data)
1.454 +{
1.455 + gtk_widget_hide( widget );
1.456 + return TRUE;
1.457 +}
.