/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - main_gtk.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 Tillin9 * * Copyright (C) 2002 Blight * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* main_gtk.c - Handles the main window and 'glues' it with other windows */ #include #include #include #include #include // POSIX Thread library #include #include #include "main_gtk.h" #include "aboutdialog.h" #include "cheatdialog.h" #include "configdialog.h" #include "rombrowser.h" #include "romproperties.h" #include "../version.h" #include "../main.h" #include "../config.h" #include "../util.h" #include "../translate.h" #include "../savestates.h" #include "../plugin.h" #include "../rom.h" #ifdef DBG #include "debugger/registers.h" //temporary includes for the debugger menu #include "debugger/breakpoints.h" //these can be removed when the main gui #include "debugger/regTLB.h" //window no longer needs to know if each #include "debugger/memedit.h" //debugger window is open #include "debugger/varlist.h" #include "../../debugger/debugger.h" #endif /** function prototypes **/ static void callback_startEmulation(GtkWidget *widget, gpointer data); static void callback_stopEmulation(GtkWidget *widget, gpointer data); static void callback_openRom(GtkWidget *widget, gpointer data); static int create_mainWindow(void); /** globals **/ SMainWindow g_MainWindow; static pthread_t g_GuiThread = 0; // main gui thread /********************************************************************************************************* * GUI interfaces */ /** gui_init * Parse gui-specific arguments, remove them from argument list, * and create gtk gui in thread-safe manner, but do not display. */ void gui_init(int *argc, char ***argv) { // init multi-threading support g_thread_init(NULL); gdk_threads_init(); // save main gui thread handle g_GuiThread = pthread_self(); // call gtk to parse arguments gtk_init(argc, argv); create_mainWindow(); create_configDialog(); create_aboutDialog(); } /* gui_display * Display GUI components to the screen */ void gui_display(void) { gtk_widget_show_all(g_MainWindow.window); if(!(config_get_bool("ToolbarVisible",TRUE))) gtk_widget_hide(g_MainWindow.toolBar); if(!(config_get_bool("FilterVisible",TRUE))) gtk_widget_hide(g_MainWindow.filterBar); if(!(config_get_bool("StatusbarVisible",TRUE))) gtk_widget_hide(g_MainWindow.statusBarHBox); } /* gui_destroy * Better gui cleanup... */ void gui_destroy(void) { gtk_widget_destroy( g_MainWindow.window ); gtk_widget_destroy( g_AboutDialog.dialog ); gtk_widget_destroy( g_ConfigDialog.dialog ); gtk_widget_destroy( g_RomPropDialog.dialog ); } /* gui_main_loop * give control of thread to gtk */ void gui_main_loop(void) { gtk_main(); gui_destroy(); gdk_threads_leave(); } /* updaterombrowser() accesses g_romcahce.length and adds upto roms to the rombrowser. The clear * flag tells the GUI to clear the rombrowser. */ void updaterombrowser( unsigned int roms, unsigned short clear ) { pthread_t self = pthread_self(); //if we're calling from a thread other than the main gtk thread, take gdk lock if (!pthread_equal(self, g_GuiThread)) gdk_threads_enter(); rombrowser_refresh(roms, clear); gdk_threads_leave(); while(g_main_context_iteration(NULL, FALSE)); gdk_threads_enter(); if (!pthread_equal(self, g_GuiThread)) gdk_threads_leave(); return; } /* gui_message() uses messagetype to display either an informational message, for example to the * status bar, a yes / no confirmation dialogue, or an error dialogue. */ int gui_message(unsigned char messagetype, const char *format, ...) { if(!gui_enabled()) return 0; va_list ap; char buffer[2049]; pthread_t self = pthread_self(); gint response = 0; va_start(ap, format); vsnprintf(buffer, 2048, format, ap); buffer[2048] = '\0'; va_end(ap); // If we're calling from a thread other than the main gtk thread, take gdk lock. if(!pthread_equal(self, g_GuiThread)) gdk_threads_enter(); if(messagetype==0) { int counter; for( counter = 0; counter < strlen(buffer); ++counter ) { if(buffer[counter]=='\n') { buffer[counter]='\0'; break; } } gtk_statusbar_pop(GTK_STATUSBAR(g_MainWindow.statusBar), gtk_statusbar_get_context_id( GTK_STATUSBAR(g_MainWindow.statusBar), "status")); gtk_statusbar_push(GTK_STATUSBAR(g_MainWindow.statusBar), gtk_statusbar_get_context_id( GTK_STATUSBAR(g_MainWindow.statusBar), "status"), buffer); } else if(messagetype>0) { GtkWidget *dialog, *hbox, *label, *icon; hbox = gtk_hbox_new(FALSE, 5); GtkIconTheme *theme = gtk_icon_theme_get_default(); GdkPixbuf *pixbuf; if(messagetype==1) { dialog = gtk_dialog_new_with_buttons(tr("Error"), GTK_WINDOW(g_MainWindow.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL); if(check_icon_theme()) { pixbuf = gtk_icon_theme_load_icon(theme, "dialog-error", 32, 0, NULL); icon = gtk_image_new_from_pixbuf(pixbuf); } else icon = gtk_image_new_from_file(get_iconpath("32x32/dialog-error.png")); } else if(messagetype==2) { dialog = gtk_dialog_new_with_buttons(tr("Confirm"), GTK_WINDOW(g_MainWindow.window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_YES, GTK_RESPONSE_ACCEPT, GTK_STOCK_NO, GTK_RESPONSE_REJECT, NULL); if(check_icon_theme()) { pixbuf = gtk_icon_theme_load_icon(theme, "dialog-question", 32, 0, NULL); icon = gtk_image_new_from_pixbuf(pixbuf); } else icon = gtk_image_new_from_file(get_iconpath("32x32/dialog-question.png")); } gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0); label = gtk_label_new(buffer); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 5); gtk_widget_show_all(dialog); if(messagetype==1) { g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); } else if(messagetype==2) { response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } } gdk_threads_leave(); while(g_main_context_iteration(NULL, FALSE)); gdk_threads_enter(); if(!pthread_equal(self, g_GuiThread)) gdk_threads_leave(); return response == GTK_RESPONSE_ACCEPT; } /********************************************************************************************************* * callbacks */ /** rom **/ // open rom static void callback_openRom(GtkWidget *widget, gpointer data) { GtkWidget *file_chooser; GtkFileFilter *file_filter; if(g_EmulationThread) { if(!gui_message(2, tr("Emulation is running. Do you want to\nstop it and load a rom?"))) return; callback_stopEmulation( NULL, NULL ); } /* get rom file from user */ file_chooser = gtk_file_chooser_dialog_new(tr("Open Rom..."), GTK_WINDOW(g_MainWindow.window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); // add filter for rom file types file_filter = gtk_file_filter_new(); gtk_file_filter_set_name(file_filter, "N64 ROM (*.z64, *.v64, *.n64, *.gz, *.zip. *.bz2, *.lzma *.7z)"); gtk_file_filter_add_mime_type(file_filter, "application/x-gzip"); gtk_file_filter_add_mime_type(file_filter, "application/zip"); gtk_file_filter_add_mime_type(file_filter, "application/x-bzip2"); gtk_file_filter_add_mime_type(file_filter, "application/x-7z"); gtk_file_filter_add_pattern(file_filter, "*.[zZ]64"); gtk_file_filter_add_pattern(file_filter, "*.lzma"); gtk_file_filter_add_pattern(file_filter, "*.7z"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), file_filter); // add filter for "all files" file_filter = gtk_file_filter_new(); gtk_file_filter_set_name(file_filter, "All files (*.*)"); gtk_file_filter_add_pattern(file_filter, "*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), file_filter); if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser)); // hide dialog while rom is loading gtk_widget_hide(file_chooser); open_rom(filename, 0); g_free(filename); } gtk_widget_destroy (file_chooser); } // close rom static void callback_closeRom(GtkWidget *widget, gpointer data) { if(close_rom() == 0) { gtk_window_set_title( GTK_WINDOW(g_MainWindow.window), MUPEN_NAME " v" MUPEN_VERSION ); } } // reload windows void reload() { // recreate gui gtk_widget_destroy( g_MainWindow.window ); gtk_widget_destroy( g_AboutDialog.dialog ); gtk_widget_destroy( g_ConfigDialog.dialog ); gtk_widget_destroy( g_RomPropDialog.dialog ); create_mainWindow(); create_aboutDialog(); create_configDialog(); gtk_widget_show_all( g_MainWindow.window ); } // language selected static void callback_languageSelected(GtkWidget *widget, gpointer data) { const char *name; widget = data; // ToDo: find out why this is needed if( !GTK_CHECK_MENU_ITEM(widget)->active ) return; name = gtk_object_get_data( GTK_OBJECT(widget), "lang name" ); tr_set_language( name ); config_put_string( "Language", name ); reload(); g_romcache.rcstask = RCS_RESCAN; } /** emulation **/ // start/continue emulation static void callback_startEmulation(GtkWidget *widget, gpointer data) { if(!rom) { GList *list = NULL, *llist = NULL; cache_entry *entry; GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(g_MainWindow.romDisplay)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(g_MainWindow.romDisplay)); list = gtk_tree_selection_get_selected_rows (selection, &model); if(!list) //Nothing selected. { if(gui_message(2, tr("There is no Rom loaded. Do you want to load one?"))) callback_openRom(NULL, NULL); return; } else { llist = g_list_first(list); gtk_tree_model_get_iter(model, &iter,(GtkTreePath *) llist->data); gtk_tree_model_get(model, &iter, 22, &entry, -1); g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free(list); if(open_rom(entry->filename, entry->archivefile)==0) startEmulation(); else return; } } startEmulation(); } // pause/continue emulation static void callback_pauseContinueEmulation(GtkWidget *widget, gpointer data) { pauseContinueEmulation(); } // stop emulation static void callback_stopEmulation( GtkWidget *widget, gpointer data ) { stopEmulation(); } // Save State static void callback_Save( GtkWidget *widget, gpointer data ) { if( g_EmulationThread ) savestates_job |= SAVESTATE; } //Save As //Need to add default filename here... static void callback_SaveAs( GtkWidget *widget, gpointer data ) { if( g_EmulationThread ) { GtkWidget *file_chooser; file_chooser = gtk_file_chooser_dialog_new(tr("Save as..."), GTK_WINDOW(g_MainWindow.window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser)); savestates_select_filename( filename ); savestates_job |= SAVESTATE; g_free(filename); } gtk_widget_destroy (file_chooser); } else { error_message(tr("Emulation is not running.")); } } // Restore static void callback_Restore( GtkWidget *widget, gpointer data ) { if( g_EmulationThread ) savestates_job |= LOADSTATE; } // Load static void callback_Load( GtkWidget *widget, gpointer data ) { if( g_EmulationThread ) { GtkWidget *file_chooser; file_chooser = gtk_file_chooser_dialog_new(tr("Load..."), GTK_WINDOW(g_MainWindow.window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser)); savestates_select_filename( filename ); savestates_job |= LOADSTATE; g_free(filename); } gtk_widget_destroy (file_chooser); } else { error_message(tr("Emulation is not running.")); } } // user changed savestate slot static void cb_SaveSlotSelected(GtkMenuItem *item, int slot) { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))) { if(slot!=savestates_get_slot()) //Only actually change slot when not a GUI update. savestates_select_slot(slot); } } // user opened save slot menu. Make sure current save slot is selected. static void cb_UpdateSelectedSlot(GtkMenuItem *item, GSList *slots) { unsigned int i, slot; GtkWidget *slotItem = GTK_WIDGET(g_slist_nth_data(slots, savestates_get_slot())); for(i=0; idata; if(!strcasecmp(language, confLang)) lang_found = 1; } // if config file language is not supported, default to English if(!lang_found) { printf("Warning: Language \"%s\" unsupported, or maybe the language name has changed.\n", confLang); config_put_string("Language", "English"); confLang = config_get_string("Language", "English"); } // create menu item for each language list_foreach(langList, node) { language = (char *)node->data; fileLanguageItem = gtk_radio_menu_item_new_with_label( group, language ); gtk_object_set_data( GTK_OBJECT(fileLanguageItem), "lang name", language ); group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM(fileLanguageItem) ); if(!strcasecmp(language, confLang)) { gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(fileLanguageItem), 1 ); tr_set_language(language); } gtk_signal_connect_object(GTK_OBJECT(fileLanguageItem), "toggled", GTK_SIGNAL_FUNC(callback_languageSelected), NULL); gtk_menu_append(GTK_MENU(fileLanguageMenu), fileLanguageItem ); } // free language name list list_delete(&langList); // emulation menu emulationMenu = gtk_menu_new(); emulationMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Emulation")); gtk_menu_item_set_submenu( GTK_MENU_ITEM(emulationMenuItem), emulationMenu ); emulationStartItem = gtk_menu_item_new_with_mnemonic(tr("_Start")); emulationPauseContinueItem = gtk_menu_item_new_with_mnemonic(tr("_Pause")); gtk_widget_add_accelerator(emulationPauseContinueItem, "activate", g_MainWindow.accelGroup, GDK_Pause, 0, GTK_ACCEL_VISIBLE); emulationStopItem = gtk_menu_item_new_with_mnemonic(tr("S_top")); gtk_widget_add_accelerator(emulationStopItem, "activate", g_MainWindow.accelGroup, GDK_Escape, 0, GTK_ACCEL_VISIBLE); emulationSeparator1 = gtk_menu_item_new(); emulationSaveItem = gtk_menu_item_new_with_mnemonic(tr("Sa_ve State")); gtk_widget_add_accelerator(emulationSaveItem, "activate", g_MainWindow.accelGroup, GDK_F5, 0, GTK_ACCEL_VISIBLE); emulationSaveAsItem = gtk_menu_item_new_with_mnemonic(tr("Save State _as...")); emulationRestoreItem = gtk_menu_item_new_with_mnemonic(tr("_Restore State")); gtk_widget_add_accelerator(emulationRestoreItem, "activate", g_MainWindow.accelGroup, GDK_F7, 0, GTK_ACCEL_VISIBLE); emulationLoadItem = gtk_menu_item_new_with_mnemonic(tr("_Load State from...")); emulationSeparator2 = gtk_menu_item_new(); emulationSlotItem = gtk_menu_item_new_with_mnemonic(tr("_Current Save State Slot")); gtk_menu_append( GTK_MENU(emulationMenu), emulationStartItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationPauseContinueItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationStopItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationSeparator1 ); gtk_menu_append( GTK_MENU(emulationMenu), emulationSaveItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationSaveAsItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationRestoreItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationLoadItem ); gtk_menu_append( GTK_MENU(emulationMenu), emulationSeparator2 ); gtk_menu_append( GTK_MENU(emulationMenu), emulationSlotItem); g_signal_connect(emulationStartItem, "activate", G_CALLBACK(callback_startEmulation), NULL ); g_signal_connect(emulationPauseContinueItem, "activate", G_CALLBACK(callback_pauseContinueEmulation), NULL ); g_signal_connect(emulationStopItem, "activate", G_CALLBACK(callback_stopEmulation), NULL ); g_signal_connect(emulationSaveItem, "activate", G_CALLBACK(callback_Save), NULL ); g_signal_connect(emulationSaveAsItem, "activate", G_CALLBACK(callback_SaveAs), NULL ); g_signal_connect(emulationRestoreItem, "activate", G_CALLBACK(callback_Restore), NULL ); g_signal_connect(emulationLoadItem, "activate", G_CALLBACK(callback_Load), NULL ); // slot menu emulationSlotMenu = gtk_menu_new(); gtk_menu_item_set_submenu( GTK_MENU_ITEM(emulationSlotItem), emulationSlotMenu ); slotItem = gtk_radio_menu_item_new(NULL); char buffer[128]; for (i = 0; i < 10; ++i) { snprintf(buffer, 128, tr(" Slot _%d"), i); slotItem = gtk_radio_menu_item_new_with_mnemonic_from_widget(GTK_RADIO_MENU_ITEM(slotItem), buffer); g_object_set_data(G_OBJECT(slotItem), "slot_num", GUINT_TO_POINTER(i)); gtk_menu_append(GTK_MENU(emulationSlotMenu), slotItem); gtk_widget_add_accelerator(slotItem, "activate", g_MainWindow.accelUnsafe, GDK_0+i, 0, GTK_ACCEL_VISIBLE); g_signal_connect(slotItem, "activate", G_CALLBACK(cb_SaveSlotSelected), GUINT_TO_POINTER(i)); } // set callback so selected save state slot is updated in the menu everytime it's opened g_signal_connect(emulationSlotItem, "activate", G_CALLBACK(cb_UpdateSelectedSlot), gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(slotItem))); // options menu optionsMenu = gtk_menu_new(); optionsMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Options")); gtk_menu_item_set_submenu( GTK_MENU_ITEM(optionsMenuItem), optionsMenu ); optionsConfigureItem = gtk_menu_item_new_with_mnemonic(tr("_Configure...")); optionsSeparator1 = gtk_menu_item_new(); optionsVideoItem = gtk_menu_item_new_with_mnemonic(tr("_Video Settings...")); optionsAudioItem = gtk_menu_item_new_with_mnemonic(tr("_Audio Settings...")); optionsInputItem = gtk_menu_item_new_with_mnemonic(tr("_Input Settings...")); optionsRSPItem = gtk_menu_item_new_with_mnemonic(tr("_RSP Settings...")); optionsSeparator2 = gtk_menu_item_new(); optionsCheatsItem = gtk_menu_item_new_with_mnemonic(tr("C_heats...")); optionsFullScreenItem = gtk_menu_item_new_with_mnemonic(tr("_Full Screen")); gtk_widget_add_accelerator(optionsFullScreenItem, "activate", g_MainWindow.accelGroup, GDK_Return, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); gtk_menu_append( GTK_MENU(optionsMenu), optionsConfigureItem ); gtk_menu_append( GTK_MENU(optionsMenu), optionsSeparator1 ); gtk_menu_append( GTK_MENU(optionsMenu), optionsVideoItem ); gtk_menu_append( GTK_MENU(optionsMenu), optionsAudioItem ); gtk_menu_append( GTK_MENU(optionsMenu), optionsInputItem ); gtk_menu_append( GTK_MENU(optionsMenu), optionsRSPItem ); gtk_menu_append( GTK_MENU(optionsMenu), optionsSeparator2 ); gtk_menu_append( GTK_MENU(optionsMenu), optionsCheatsItem ); gtk_menu_append( GTK_MENU(optionsMenu), optionsFullScreenItem ); g_signal_connect(optionsConfigureItem, "activate", G_CALLBACK(callback_configure), NULL ); g_signal_connect(optionsVideoItem, "activate", G_CALLBACK(callback_configureVideo), NULL ); g_signal_connect(optionsAudioItem, "activate", G_CALLBACK(callback_configureAudio), NULL ); g_signal_connect(optionsInputItem, "activate", G_CALLBACK(callback_configureInput), NULL ); g_signal_connect(optionsRSPItem, "activate", G_CALLBACK(callback_configureRSP), NULL ); g_signal_connect(optionsCheatsItem, "activate", G_CALLBACK(cb_cheatDialog), NULL ); g_signal_connect(optionsFullScreenItem, "activate", G_CALLBACK(callback_fullScreen), NULL ); viewMenu = gtk_menu_new(); viewMenuItem = gtk_menu_item_new_with_mnemonic(tr("_View")); gtk_menu_item_set_submenu( GTK_MENU_ITEM(viewMenuItem), viewMenu ); viewToolbar = gtk_check_menu_item_new_with_mnemonic(tr(" _Toolbar")); viewFilter = gtk_check_menu_item_new_with_mnemonic(tr(" _Filter")); viewStatusbar = gtk_check_menu_item_new_with_mnemonic(tr(" _Statusbar")); if((i=config_get_bool("ToolbarVisible",2))==2) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewToolbar),TRUE); else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewToolbar),i); if((i=config_get_bool("FilterVisible",2))==2) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewFilter),TRUE); else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewFilter),i); if((i=config_get_bool("StatusBarVisible",2))==2) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewStatusbar),TRUE); else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewStatusbar),i); gtk_signal_connect_object( GTK_OBJECT(viewToolbar), "toggled", GTK_SIGNAL_FUNC(callback_toggle_toolbar), (gpointer)NULL ); gtk_signal_connect_object( GTK_OBJECT(viewFilter), "toggled", GTK_SIGNAL_FUNC(callback_toggle_filter), (gpointer)NULL ); gtk_signal_connect_object( GTK_OBJECT(viewStatusbar), "toggled", GTK_SIGNAL_FUNC(callback_toggle_statusbar), (gpointer)NULL ); gtk_menu_append( GTK_MENU(viewMenu), viewToolbar ); gtk_menu_append( GTK_MENU(viewMenu), viewFilter ); gtk_menu_append( GTK_MENU(viewMenu), viewStatusbar ); // debugger menu #ifdef DBG debuggerMenu = gtk_menu_new(); debuggerMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Debugger")); gtk_menu_item_set_submenu( GTK_MENU_ITEM(debuggerMenuItem), debuggerMenu ); debuggerEnableItem = gtk_check_menu_item_new_with_mnemonic(tr(" _Enable")); debuggerSeparator = gtk_menu_item_new(); debuggerRegistersShow = gtk_menu_item_new_with_mnemonic(tr("_Registers")); debuggerBreakpointsShow = gtk_menu_item_new_with_mnemonic(tr("_Breakpoints")); debuggerTLBShow = gtk_menu_item_new_with_mnemonic(tr("_TLB")); debuggerMemoryShow = gtk_menu_item_new_with_mnemonic(tr("_Memory")); debuggerVariablesShow = gtk_menu_item_new_with_mnemonic(tr("_Variables")); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerEnableItem ); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerSeparator ); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerRegistersShow ); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerBreakpointsShow ); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerTLBShow ); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerMemoryShow ); gtk_menu_append( GTK_MENU(debuggerMenu), debuggerVariablesShow ); if(g_DebuggerEnabled) gtk_check_menu_item_set_active( (GtkCheckMenuItem *) debuggerEnableItem, TRUE ); else { gtk_widget_set_sensitive( GTK_WIDGET(debuggerRegistersShow), FALSE); gtk_widget_set_sensitive( GTK_WIDGET(debuggerBreakpointsShow), FALSE); gtk_widget_set_sensitive( GTK_WIDGET(debuggerTLBShow), FALSE); gtk_widget_set_sensitive( GTK_WIDGET(debuggerMemoryShow), FALSE); gtk_widget_set_sensitive( GTK_WIDGET(debuggerVariablesShow), FALSE); } gtk_signal_connect( GTK_OBJECT(debuggerEnableItem), "toggled", GTK_SIGNAL_FUNC(callback_debuggerEnableToggled), (gpointer)NULL ); gtk_signal_connect( GTK_OBJECT(debuggerRegistersShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)1 ); gtk_signal_connect( GTK_OBJECT(debuggerBreakpointsShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)2 ); gtk_signal_connect( GTK_OBJECT(debuggerTLBShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)3 ); gtk_signal_connect( GTK_OBJECT(debuggerMemoryShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)4 ); gtk_signal_connect( GTK_OBJECT(debuggerVariablesShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)5 ); #endif // DBG // help menu helpMenu = gtk_menu_new(); helpMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Help")); gtk_menu_item_set_submenu( GTK_MENU_ITEM(helpMenuItem), helpMenu ); helpAboutItem = gtk_menu_item_new_with_mnemonic(tr("_About...")); gtk_menu_append( GTK_MENU(helpMenu), helpAboutItem ); gtk_signal_connect_object( GTK_OBJECT(helpAboutItem), "activate", GTK_SIGNAL_FUNC(callback_aboutMupen), (gpointer)NULL ); // add menus to menubar gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), fileMenuItem ); gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), emulationMenuItem ); gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), optionsMenuItem ); gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), viewMenuItem ); #ifdef DBG gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), debuggerMenuItem ); #endif gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), helpMenuItem ); return 0; } // toolbar static int create_toolBar( void ) { GtkWidget *openImage = NULL; GtkWidget *playImage = NULL; GtkWidget *pauseImage = NULL; GtkWidget *stopImage = NULL; GtkWidget *fullscreenImage = NULL; GtkWidget *configureImage = NULL; g_MainWindow.toolBar = gtk_toolbar_new(); gtk_toolbar_set_orientation( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_ORIENTATION_HORIZONTAL ); switch(config_get_number( "ToolbarStyle", 0 )) { case 0: gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_ICONS ); break; case 1: gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_TEXT ); break; case 2: gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_BOTH ); break; default: gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_ICONS ); } gtk_toolbar_set_tooltips( GTK_TOOLBAR(g_MainWindow.toolBar), TRUE ); // load icons from memory GtkIconTheme *theme = gtk_icon_theme_get_default(); GdkPixbuf *pixbuf; short size = config_get_number( "ToolbarSize", 22 ); if(check_icon_theme()) { pixbuf = gtk_icon_theme_load_icon(theme, "document-open", size, 0, NULL); openImage = gtk_image_new_from_pixbuf(pixbuf); pixbuf = gtk_icon_theme_load_icon(theme, "media-playback-start", size, 0, NULL); playImage = gtk_image_new_from_pixbuf(pixbuf); pixbuf = gtk_icon_theme_load_icon(theme, "media-playback-pause", size, 0, NULL); pauseImage = gtk_image_new_from_pixbuf(pixbuf); pixbuf = gtk_icon_theme_load_icon(theme, "media-playback-stop", size, 0, NULL); stopImage = gtk_image_new_from_pixbuf(pixbuf); pixbuf = gtk_icon_theme_load_icon(theme, "view-fullscreen", size, 0, NULL); fullscreenImage = gtk_image_new_from_pixbuf(pixbuf); pixbuf = gtk_icon_theme_load_icon(theme, "preferences-system", size, 0, NULL); configureImage = gtk_image_new_from_pixbuf(pixbuf); } else if(size==32) { openImage = gtk_image_new_from_file(get_iconpath("32x32/document-open.png")); playImage = gtk_image_new_from_file(get_iconpath("32x32/media-playback-start.png")); pauseImage = gtk_image_new_from_file(get_iconpath("32x32/media-playback-pause.png")); stopImage = gtk_image_new_from_file(get_iconpath("32x32/media-playback-stop.png")); fullscreenImage = gtk_image_new_from_file(get_iconpath("32x32/view-fullscreen.png")); configureImage = gtk_image_new_from_file(get_iconpath("32x32/preferences-system.png")); } else if(size==16) { openImage = gtk_image_new_from_file(get_iconpath("16x16/document-open.png")); playImage = gtk_image_new_from_file(get_iconpath("16x16/media-playback-start.png")); pauseImage = gtk_image_new_from_file(get_iconpath("16x16/media-playback-pause.png")); stopImage = gtk_image_new_from_file(get_iconpath("16x16/media-playback-stop.png")); fullscreenImage = gtk_image_new_from_file(get_iconpath("16x16/view-fullscreen.png")); configureImage = gtk_image_new_from_file(get_iconpath("16x16/preferences-system.png")); } else { openImage = gtk_image_new_from_file(get_iconpath("22x22/document-open.png")); playImage = gtk_image_new_from_file(get_iconpath("22x22/media-playback-start.png")); pauseImage = gtk_image_new_from_file(get_iconpath("22x22/media-playback-pause.png")); stopImage = gtk_image_new_from_file(get_iconpath("22x22/media-playback-stop.png")); fullscreenImage = gtk_image_new_from_file(get_iconpath("22x22/view-fullscreen.png")); configureImage = gtk_image_new_from_file(get_iconpath("22x22/preferences-system.png")); } // add icons to toolbar gtk_toolbar_append_item(GTK_TOOLBAR(g_MainWindow.toolBar),tr("Open"),tr("Open Rom"),"",openImage,GTK_SIGNAL_FUNC(callback_openRom),NULL); gtk_toolbar_append_space( GTK_TOOLBAR(g_MainWindow.toolBar) ); gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Start"),tr("Start Emulation"),"",playImage,GTK_SIGNAL_FUNC(callback_startEmulation),NULL); gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Pause"),tr("Pause/ Continue Emulation"),"",pauseImage,GTK_SIGNAL_FUNC(callback_pauseContinueEmulation),NULL ); gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Stop"),tr("Stop Emulation"),"",stopImage,GTK_SIGNAL_FUNC(callback_stopEmulation),NULL ); gtk_toolbar_append_space( GTK_TOOLBAR(g_MainWindow.toolBar) ); gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Configure"),tr("Configure"),"",configureImage,GTK_SIGNAL_FUNC(callback_configure),NULL ); gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Fullscreen"),tr("Fullscreen"),"",fullscreenImage,GTK_SIGNAL_FUNC(callback_fullScreen),NULL ); gtk_box_pack_start( GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.toolBar, FALSE, FALSE, 0 ); return 0; } // status bar static int create_statusBar( void ) { g_MainWindow.statusBarHBox = gtk_hbox_new( FALSE, 5 ); gtk_box_pack_end( GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.statusBarHBox, FALSE, FALSE, 0 ); g_MainWindow.statusBar = gtk_statusbar_new(); gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(g_MainWindow.statusBar), FALSE); gtk_box_pack_start( GTK_BOX(g_MainWindow.statusBarHBox), g_MainWindow.statusBar, TRUE , TRUE, 0 ); return 0; } // main window static int create_mainWindow( void ) { int i=config_get_number("RomSortType",16); if(i!=GTK_SORT_ASCENDING&&i!=GTK_SORT_DESCENDING) { g_MainWindow.romSortType = GTK_SORT_ASCENDING; config_put_number("RomSortType",GTK_SORT_ASCENDING); } else g_MainWindow.romSortType = i; i=config_get_number("RomSortColumn",17); if(i<0||i>16) { g_MainWindow.romSortColumn = 1; config_put_number("RomSortColumn",1); } else g_MainWindow.romSortColumn = i; gint width, height, xposition, yposition; width = config_get_number("MainWindowWidth",600); height = config_get_number("MainWindowHeight",400); xposition = config_get_number("MainWindowXPosition",0); yposition = config_get_number("MainWindowYPosition",0); GdkDisplay *display = gdk_display_get_default(); GdkScreen *screen = gdk_display_get_default_screen(display); gint screenwidth = gdk_screen_get_width(screen); gint screenheight = gdk_screen_get_height(screen); if(xposition>screenwidth) xposition = 0; if(yposition>screenheight) yposition = 0; if(width>screenwidth) width = 600; if(height>screenheight) height = 400; if((xposition+width)>screenwidth) xposition = screenwidth - width; if((yposition+height)>screenheight) yposition = screenheight - height; // window g_MainWindow.window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); gtk_window_set_title( GTK_WINDOW(g_MainWindow.window), MUPEN_NAME " v" MUPEN_VERSION ); gtk_window_set_default_size( GTK_WINDOW(g_MainWindow.window), width, height ); gtk_window_move( GTK_WINDOW(g_MainWindow.window), xposition, yposition ); GdkPixbuf *mupen64plus16, *mupen64plus32; mupen64plus16 = gdk_pixbuf_new_from_file( get_iconpath("16x16/mupen64plus.png"), NULL ); mupen64plus32 = gdk_pixbuf_new_from_file( get_iconpath("32x32/mupen64plus.png"), NULL ); GList *iconlist = NULL; iconlist = g_list_append( iconlist, mupen64plus16 ); iconlist = g_list_append( iconlist, mupen64plus16 ); gtk_window_set_icon_list( GTK_WINDOW(g_MainWindow.window), iconlist ); gtk_signal_connect(GTK_OBJECT(g_MainWindow.window), "delete_event", GTK_SIGNAL_FUNC(callback_mainWindowDeleteEvent), (gpointer)NULL); // toplevel vbox g_MainWindow.toplevelVBox = gtk_vbox_new( FALSE, 0 ); gtk_container_add( GTK_CONTAINER(g_MainWindow.window), g_MainWindow.toplevelVBox ); // menu create_menuBar(); // toolbar create_toolBar(); // Filter create_filter(); // rombrowser create_romBrowser(); // rom properties create_romPropDialog(); // statusbar create_statusBar(); return 0; } gboolean check_icon_theme() { GtkIconTheme *theme = gtk_icon_theme_get_default(); if(gtk_icon_theme_has_icon(theme, "document-open")&& gtk_icon_theme_has_icon(theme, "media-playback-start")&& gtk_icon_theme_has_icon(theme, "media-playback-pause")&& gtk_icon_theme_has_icon(theme, "media-playback-stop")&& gtk_icon_theme_has_icon(theme, "view-fullscreen")&& gtk_icon_theme_has_icon(theme, "preferences-system")&& gtk_icon_theme_has_icon(theme, "video-display")&& gtk_icon_theme_has_icon(theme, "audio-card")&& gtk_icon_theme_has_icon(theme, "input-gaming")&& gtk_icon_theme_has_icon(theme, "dialog-warning")&& gtk_icon_theme_has_icon(theme, "dialog-error")&& gtk_icon_theme_has_icon(theme, "dialog-question")) return TRUE; else return FALSE; }