nkeynes@435: /** nkeynes@561: * $Id$ nkeynes@435: * nkeynes@435: * Action callbacks from the main window nkeynes@435: * nkeynes@435: * Copyright (c) 2005 Nathan Keynes. nkeynes@435: * nkeynes@435: * This program is free software; you can redistribute it and/or modify nkeynes@435: * it under the terms of the GNU General Public License as published by nkeynes@435: * the Free Software Foundation; either version 2 of the License, or nkeynes@435: * (at your option) any later version. nkeynes@435: * nkeynes@435: * This program is distributed in the hope that it will be useful, nkeynes@435: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@435: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@435: * GNU General Public License for more details. nkeynes@435: */ nkeynes@435: nkeynes@1041: #include nkeynes@1041: nkeynes@1041: #include "lxdream.h" nkeynes@450: #include "config.h" nkeynes@1041: #include "lxpaths.h" nkeynes@435: #include "dreamcast.h" nkeynes@435: #include "gdrom/gdrom.h" nkeynes@537: #include "gtkui/gtkui.h" nkeynes@455: #include "pvr2/pvr2.h" nkeynes@543: #include "loader.h" nkeynes@435: nkeynes@435: nkeynes@887: static void add_file_pattern( GtkFileChooser *chooser, const char *pattern, const char *patname ) nkeynes@435: { nkeynes@435: if( pattern != NULL ) { nkeynes@736: GtkFileFilter *filter = gtk_file_filter_new(); nkeynes@736: gtk_file_filter_add_pattern( filter, pattern ); nkeynes@736: gtk_file_filter_set_name( filter, patname ); nkeynes@736: gtk_file_chooser_add_filter( chooser, filter ); nkeynes@736: filter = gtk_file_filter_new(); nkeynes@736: gtk_file_filter_set_name( filter, _("All files") ); nkeynes@736: gtk_file_filter_add_pattern( filter, "*" ); nkeynes@736: gtk_file_chooser_add_filter( chooser, filter ); nkeynes@435: } nkeynes@435: } nkeynes@435: nkeynes@1034: gchar *open_file_dialog( const char *title, const char *pattern, const char *patname, nkeynes@1036: int initial_dir_key ) nkeynes@435: { nkeynes@435: GtkWidget *file; nkeynes@1034: gchar *filename = NULL; nkeynes@1036: nkeynes@435: file = gtk_file_chooser_dialog_new( title, NULL, nkeynes@736: GTK_FILE_CHOOSER_ACTION_OPEN, nkeynes@736: GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, nkeynes@736: GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, nkeynes@736: NULL ); nkeynes@435: add_file_pattern( GTK_FILE_CHOOSER(file), pattern, patname ); nkeynes@1036: if( initial_dir_key != -1 ) { nkeynes@1041: gchar *initial_path = get_absolute_path(get_gui_path(initial_dir_key)); nkeynes@1036: gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), initial_path ); nkeynes@1036: g_free(initial_path); nkeynes@1036: } nkeynes@435: gtk_window_set_modal( GTK_WINDOW(file), TRUE ); nkeynes@477: gtk_dialog_set_default_response( GTK_DIALOG(file), GTK_RESPONSE_ACCEPT ); nkeynes@477: int result = gtk_dialog_run( GTK_DIALOG(file) ); nkeynes@477: if( result == GTK_RESPONSE_ACCEPT ) { nkeynes@1034: filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ); nkeynes@1036: if( initial_dir_key != -1 ) { nkeynes@1036: gchar *end_path = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(file) ); nkeynes@1041: set_gui_path(initial_dir_key,end_path); nkeynes@1036: g_free(end_path); nkeynes@1036: } nkeynes@477: } nkeynes@477: gtk_widget_destroy(file); nkeynes@1034: nkeynes@1034: return filename; nkeynes@435: } nkeynes@435: nkeynes@1034: gchar *save_file_dialog( const char *title, const char *pattern, const char *patname, nkeynes@1124: const char *mandatory_ext, int initial_dir_key ) nkeynes@435: { nkeynes@435: GtkWidget *file; nkeynes@1072: gchar *filename = NULL; nkeynes@1036: nkeynes@435: file = gtk_file_chooser_dialog_new( title, NULL, nkeynes@736: GTK_FILE_CHOOSER_ACTION_SAVE, nkeynes@736: GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, nkeynes@736: GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, nkeynes@736: NULL ); nkeynes@435: add_file_pattern( GTK_FILE_CHOOSER(file), pattern, patname ); nkeynes@1036: if( initial_dir_key != -1 ) { nkeynes@1041: gchar *initial_path = get_absolute_path(get_gui_path(initial_dir_key)); nkeynes@1036: gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), initial_path ); nkeynes@1036: g_free(initial_path); nkeynes@1036: } nkeynes@435: gtk_window_set_modal( GTK_WINDOW(file), TRUE ); nkeynes@477: gtk_dialog_set_default_response( GTK_DIALOG(file), GTK_RESPONSE_ACCEPT ); nkeynes@477: int result = gtk_dialog_run( GTK_DIALOG(file) ); nkeynes@477: if( result == GTK_RESPONSE_ACCEPT ) { nkeynes@1034: filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ); nkeynes@1124: if( mandatory_ext ) { nkeynes@1124: int extlen = strlen(mandatory_ext); nkeynes@1124: int fnlen = strlen(filename); nkeynes@1124: if( fnlen < extlen || strcmp(filename + (fnlen - extlen), mandatory_ext) != 0 ) { nkeynes@1124: gchar *f2 = g_strdup_printf("%s%s",filename, mandatory_ext); nkeynes@1124: g_free(filename); nkeynes@1124: filename = f2; nkeynes@1124: } nkeynes@1124: } nkeynes@1036: if( initial_dir_key != -1 ) { nkeynes@1036: gchar *end_path = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(file) ); nkeynes@1041: set_gui_path(initial_dir_key,end_path); nkeynes@1036: g_free(end_path); nkeynes@1036: } nkeynes@477: } nkeynes@477: gtk_widget_destroy(file); nkeynes@1034: return filename; nkeynes@1034: } nkeynes@1034: nkeynes@1034: void open_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname, nkeynes@1036: int initial_dir_key ) nkeynes@1034: { nkeynes@1036: gchar *filename = open_file_dialog( title, pattern, patname, initial_dir_key ); nkeynes@1034: if( filename != NULL ) { nkeynes@1034: action( filename ); nkeynes@1034: g_free(filename); nkeynes@1034: } nkeynes@1034: } nkeynes@1034: nkeynes@1034: void save_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname, nkeynes@1124: const char *mandatory_ext, int initial_dir_key ) nkeynes@1034: { nkeynes@1124: gchar *filename = save_file_dialog( title, pattern, patname, mandatory_ext, initial_dir_key ); nkeynes@1034: if( filename != NULL ) { nkeynes@1034: action(filename); nkeynes@1034: g_free(filename); nkeynes@1034: } nkeynes@435: } nkeynes@435: nkeynes@435: void mount_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@1109: open_file_dialog_cb( "Open...", gtk_gui_gdrom_mount_image, NULL, NULL, CONFIG_DEFAULT_PATH ); nkeynes@435: } nkeynes@435: void reset_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@435: dreamcast_reset(); nkeynes@435: } nkeynes@435: nkeynes@435: void pause_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@435: dreamcast_stop(); nkeynes@435: } nkeynes@435: nkeynes@435: void resume_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@435: dreamcast_run(); nkeynes@435: } nkeynes@435: nkeynes@1109: gboolean gtk_gui_load_exec( const gchar *filename ) nkeynes@1109: { nkeynes@1109: ERROR err; nkeynes@1109: gboolean ok = file_load_exec(filename, &err); nkeynes@1109: if( !ok ) { nkeynes@1109: ERROR(err.msg); nkeynes@1109: } nkeynes@1109: return ok; nkeynes@1109: } nkeynes@1109: nkeynes@543: void load_binary_action_callback( GtkAction *action, gpointer user_data) nkeynes@543: { nkeynes@1109: open_file_dialog_cb( "Open Binary...", gtk_gui_load_exec, NULL, NULL, CONFIG_DEFAULT_PATH ); nkeynes@543: } nkeynes@543: nkeynes@477: void load_state_preview_callback( GtkFileChooser *chooser, gpointer user_data ) nkeynes@477: { nkeynes@477: GtkWidget *preview = GTK_WIDGET(user_data); nkeynes@477: gchar *filename = gtk_file_chooser_get_preview_filename(chooser); nkeynes@736: nkeynes@477: frame_buffer_t data = dreamcast_load_preview(filename); nkeynes@477: if( data != NULL ) { nkeynes@736: GdkPixbuf *pixbuf = gdk_pixbuf_new_from_frame_buffer(data); nkeynes@736: GdkPixbuf *scaled = gdk_pixbuf_scale_simple(pixbuf, 320, 240, nkeynes@736: GDK_INTERP_BILINEAR); nkeynes@736: g_object_unref(pixbuf); nkeynes@736: gtk_image_set_from_pixbuf( GTK_IMAGE(preview), scaled ); nkeynes@736: g_object_unref(scaled); nkeynes@736: gtk_widget_show(preview); nkeynes@477: } else { nkeynes@736: gtk_widget_hide(preview); nkeynes@477: } nkeynes@477: } nkeynes@477: nkeynes@435: void load_state_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@477: GtkWidget *file, *preview, *frame, *align; nkeynes@477: GtkRequisition size; nkeynes@1041: const gchar *dir = get_gui_path(CONFIG_SAVE_PATH); nkeynes@669: gchar *path = get_absolute_path(dir); nkeynes@508: file = gtk_file_chooser_dialog_new( _("Load state..."), NULL, nkeynes@736: GTK_FILE_CHOOSER_ACTION_OPEN, nkeynes@736: GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, nkeynes@736: GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, nkeynes@736: NULL ); nkeynes@508: add_file_pattern( GTK_FILE_CHOOSER(file), "*.dst", _("lxDream Save State (*.dst)") ); nkeynes@477: gtk_object_set_data( GTK_OBJECT(file), "file_action", action ); nkeynes@477: nkeynes@477: preview = gtk_image_new( ); nkeynes@477: nkeynes@477: frame = gtk_frame_new(NULL); nkeynes@477: gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_IN ); nkeynes@477: gtk_container_add( GTK_CONTAINER(frame), preview ); nkeynes@477: gtk_widget_show(frame); nkeynes@477: gtk_widget_size_request(frame, &size); nkeynes@477: gtk_widget_set_size_request(frame, size.width + 320, size.height + 240); nkeynes@477: align = gtk_alignment_new(0.5, 0.5, 0, 0 ); nkeynes@477: gtk_container_add( GTK_CONTAINER(align), frame ); nkeynes@477: gtk_widget_show( align ); nkeynes@477: gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(file), align); nkeynes@477: g_signal_connect( file, "update-preview", G_CALLBACK(load_state_preview_callback), nkeynes@736: preview ); nkeynes@630: gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), path ); nkeynes@477: gtk_window_set_modal( GTK_WINDOW(file), TRUE ); nkeynes@477: int result = gtk_dialog_run( GTK_DIALOG(file) ); nkeynes@477: if( result == GTK_RESPONSE_ACCEPT ) { nkeynes@736: gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ); nkeynes@1036: gchar *end_path = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(file) ); nkeynes@1041: set_gui_path(CONFIG_SAVE_PATH,end_path); nkeynes@1036: g_free(end_path); nkeynes@736: dreamcast_load_state( filename ); nkeynes@477: } nkeynes@477: gtk_widget_destroy(file); nkeynes@630: g_free(path); nkeynes@435: } nkeynes@477: nkeynes@435: void save_state_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@1124: save_file_dialog_cb( "Save state...", dreamcast_save_state, "*.dst", _("lxDream Save State (*.dst)"), ".dst", CONFIG_SAVE_PATH ); nkeynes@435: } nkeynes@1040: nkeynes@1040: void quick_state_action_callback( GtkRadioAction *action, GtkRadioAction *current, gpointer user_data) nkeynes@1040: { nkeynes@1040: gint val = gtk_radio_action_get_current_value(action); nkeynes@1040: dreamcast_set_quick_state(val); nkeynes@1040: } nkeynes@1040: nkeynes@1040: void quick_load_action_callback( GtkAction *action, gpointer user_data) nkeynes@1040: { nkeynes@1040: dreamcast_quick_load(); nkeynes@1040: } nkeynes@1040: nkeynes@1040: void quick_save_action_callback( GtkAction *action, gpointer user_data) nkeynes@1040: { nkeynes@1040: dreamcast_quick_save(); nkeynes@1040: } nkeynes@1040: nkeynes@1040: nkeynes@435: void about_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@736: nkeynes@435: GtkWidget *dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG, nkeynes@736: "name", APP_NAME, nkeynes@738: "version", lxdream_full_version, nkeynes@738: "copyright", lxdream_copyright, nkeynes@1017: "logo-icon-name", "lxdream", nkeynes@736: NULL); nkeynes@435: gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); nkeynes@447: gtk_dialog_run(GTK_DIALOG(dialog)); nkeynes@447: gtk_widget_destroy(dialog); nkeynes@736: nkeynes@435: } nkeynes@435: nkeynes@435: void exit_action_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@671: dreamcast_shutdown(); nkeynes@435: exit(0); nkeynes@435: } nkeynes@435: nkeynes@447: void path_settings_callback( GtkAction *action, gpointer user_data) nkeynes@447: { nkeynes@1072: gtk_configuration_panel_run( _("Path Settings"), lxdream_get_config_group(CONFIG_GROUP_GLOBAL) ); nkeynes@447: } nkeynes@447: nkeynes@435: void audio_settings_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@435: } nkeynes@435: nkeynes@455: void maple_settings_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@455: maple_dialog_run( ); nkeynes@435: } nkeynes@435: nkeynes@435: void network_settings_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@435: } nkeynes@435: nkeynes@435: void video_settings_callback( GtkAction *action, gpointer user_data) nkeynes@435: { nkeynes@435: } nkeynes@435: nkeynes@1015: void hotkey_settings_callback( GtkAction *action, gpointer user_data) nkeynes@1015: { nkeynes@1072: gtk_configuration_panel_run( _("Hotkey Settings"), lxdream_get_config_group(CONFIG_GROUP_HOTKEYS) ); nkeynes@1015: } nkeynes@1015: nkeynes@435: void fullscreen_toggle_callback( GtkToggleAction *action, gpointer user_data) nkeynes@435: { nkeynes@486: main_window_set_fullscreen(gtk_gui_get_main(), gtk_toggle_action_get_active(action)); nkeynes@435: } nkeynes@455: nkeynes@455: void debugger_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@455: gtk_gui_show_debugger(); nkeynes@455: } nkeynes@455: nkeynes@455: void debug_memory_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@738: gchar *title = g_strdup_printf( "%s :: %s", lxdream_package_name, _("Memory dump") ); nkeynes@508: dump_window_new( title ); nkeynes@508: g_free(title); nkeynes@455: } nkeynes@455: nkeynes@455: void debug_mmio_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@455: gtk_gui_show_mmio(); nkeynes@455: } nkeynes@455: nkeynes@455: void save_scene_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@1124: save_file_dialog_cb( _("Save next scene..."), pvr2_save_next_scene, "*.dsc", _("lxdream scene file (*.dsc)"), ".dsc", CONFIG_SAVE_PATH ); nkeynes@455: } nkeynes@455: nkeynes@480: int debug_window_get_selected_row( debug_window_t data ); nkeynes@480: nkeynes@455: void debug_step_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@455: debug_window_single_step(gtk_gui_get_debugger()); nkeynes@455: } nkeynes@455: nkeynes@455: void debug_runto_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@455: debug_window_t debug = gtk_gui_get_debugger(); nkeynes@455: int selected_row = debug_window_get_selected_row(debug); nkeynes@455: if( selected_row == -1 ) { nkeynes@508: WARN( _("No address selected, so can't run to it"), NULL ); nkeynes@455: } else { nkeynes@736: debug_window_set_oneshot_breakpoint( debug, selected_row ); nkeynes@736: dreamcast_run(); nkeynes@455: } nkeynes@455: } nkeynes@455: nkeynes@455: void debug_breakpoint_action_callback( GtkAction *action, gpointer user_data) nkeynes@455: { nkeynes@455: debug_window_t debug = gtk_gui_get_debugger(); nkeynes@455: int selected_row = debug_window_get_selected_row(debug); nkeynes@455: if( selected_row != -1 ) { nkeynes@736: debug_window_toggle_breakpoint( debug, selected_row ); nkeynes@455: } nkeynes@455: }