Logical reorderring of the GUI boot sequence. Also a little clean up in the OpenGL...
[dolphin.git] / Source / Core / DolphinWX / Src / Frame.cpp
blob2d027b15b72d4f05b73297adaaccf9d5736a93ee
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
19 // CFrame is the main parent window. Inside CFrame there is an m_Panel that is
20 // the parent for the rendering window (when we render to the main window). In
21 // Windows the rendering window is created by giving CreateWindow()
22 // m_Panel->GetHandle() as parent window and creating a new child window to
23 // m_Panel. The new child window handle that is returned by CreateWindow() can
24 // be accessed from Core::GetWindowHandle().
26 #include "Common.h" // Common
27 #include "FileUtil.h"
28 #include "Timer.h"
29 #include "Setup.h"
31 #include "Globals.h" // Local
32 #include "Frame.h"
33 #include "ConfigMain.h"
34 #include "PluginManager.h"
35 #include "MemcardManager.h"
36 #include "CheatsWindow.h"
37 #include "AboutDolphin.h"
38 #include "GameListCtrl.h"
39 #include "BootManager.h"
40 #include "ConsoleListener.h"
42 #include "ConfigManager.h" // Core
43 #include "Core.h"
44 #include "HW/DVDInterface.h"
45 #include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
46 #include "State.h"
47 #include "VolumeHandler.h"
49 #include <wx/datetime.h> // wxWidgets
51 #if defined HAVE_X11 && HAVE_X11
52 #include <X11/Xlib.h>
53 #endif
55 // Resources
57 extern "C" {
58 #include "../resources/Dolphin.c" // Dolphin icon
59 #include "../resources/toolbar_browse.c"
60 #include "../resources/toolbar_file_open.c"
61 #include "../resources/toolbar_fullscreen.c"
62 #include "../resources/toolbar_help.c"
63 #include "../resources/toolbar_pause.c"
64 #include "../resources/toolbar_play.c"
65 #include "../resources/toolbar_plugin_dsp.c"
66 #include "../resources/toolbar_plugin_gfx.c"
67 #include "../resources/toolbar_plugin_options.c"
68 #include "../resources/toolbar_plugin_pad.c"
69 #include "../resources/toolbar_refresh.c"
70 #include "../resources/toolbar_stop.c"
71 #include "../resources/Boomy.h" // Theme packages
72 #include "../resources/Vista.h"
73 #include "../resources/X-Plastik.h"
74 #include "../resources/KDE.h"
78 // Windows functions. Setting the cursor with wxSetCursor() did not work in
79 // this instance. Probably because it's somehow reset from the WndProc() in
80 // the child window
81 #ifdef _WIN32
82 // Declare a blank icon and one that will be the normal cursor
83 HCURSOR hCursor = NULL, hCursorBlank = NULL;
85 // Create the default cursor
86 void CreateCursor()
88 hCursor = LoadCursor( NULL, IDC_ARROW );
91 void MSWSetCursor(bool Show)
93 if(Show)
94 SetCursor(hCursor);
95 else
97 SetCursor(hCursorBlank);
98 //wxSetCursor(wxCursor(wxNullCursor));
102 // I could not use FindItemByHWND() instead of this, it crashed on that occation I used it */
103 HWND MSWGetParent_(HWND Parent)
105 return GetParent(Parent);
107 #endif
109 // ---------------
110 // The CPanel class to receive MSWWindowProc messages from the video plugin.
112 extern CFrame* main_frame;
115 BEGIN_EVENT_TABLE(CPanel, wxPanel)
116 END_EVENT_TABLE()
118 CPanel::CPanel(
119 wxWindow *parent,
120 wxWindowID id
122 : wxPanel(parent, id)
126 #ifdef _WIN32
127 WXLRESULT CPanel::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
129 switch (nMsg)
131 case WM_USER:
132 switch(wParam)
134 // Pause
135 case WM_USER_PAUSE:
136 main_frame->DoPause();
137 break;
139 // Stop
140 case WM_USER_STOP:
141 main_frame->DoStop();
142 break;
144 case WM_USER_CREATE:
145 main_frame->DoFullscreen(SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen);
146 break;
148 case WM_USER_SETCURSOR:
149 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
150 main_frame->RendererHasFocus() && Core::GetState() == Core::CORE_RUN)
151 MSWSetCursor(!SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor);
152 else
153 MSWSetCursor(true);
154 break;
156 case WIIMOTE_DISCONNECT:
157 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
159 if (main_frame->bNoWiimoteMsg)
160 main_frame->bNoWiimoteMsg = false;
161 else
163 int wiimote_idx = lParam;
164 int wiimote_num = wiimote_idx + 1;
165 //Auto reconnect if option is turned on.
166 //TODO: Make this only auto reconnect wiimotes that have the option activated.
167 SConfig::GetInstance().LoadSettingsWii();//Make sure we are using the newest settings.
168 if (SConfig::GetInstance().m_WiiAutoReconnect[wiimote_idx])
170 GetUsbPointer()->AccessWiiMote(wiimote_idx | 0x100)->Activate(true);
171 NOTICE_LOG(WIIMOTE, "Wiimote %i has been auto-reconnected...", wiimote_num);
173 else
175 // The Wiimote has been disconnected, we offer reconnect here.
176 wxMessageDialog *dlg = new wxMessageDialog(
177 this,
178 wxString::Format(wxT("Wiimote %i has been disconnected by system.\n")
179 wxT("Maybe this game doesn't support multi-wiimote,\n")
180 wxT("or maybe it is due to idle time out or other reason.\n\n")
181 wxT("Do you want to reconnect immediately?"), wiimote_num),
182 wxT("Reconnect Wiimote Confirm"),
183 wxYES_NO | wxSTAY_ON_TOP | wxICON_INFORMATION, //wxICON_QUESTION,
184 wxDefaultPosition);
186 if (dlg->ShowModal() == wxID_YES)
187 GetUsbPointer()->AccessWiiMote(wiimote_idx | 0x100)->Activate(true);
189 dlg->Destroy();
194 break;
195 default:
196 // By default let wxWidgets do what it normally does with this event
197 return wxPanel::MSWWindowProc(nMsg, wParam, lParam);
199 return 0;
201 #endif
203 CRenderFrame::CRenderFrame(wxFrame* parent, wxWindowID id, const wxString& title,
204 const wxPoint& pos, const wxSize& size, long style)
205 : wxFrame(parent, id, title, pos, size, style)
209 #ifdef _WIN32
210 WXLRESULT CRenderFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
212 switch (nMsg)
214 case WM_SYSCOMMAND:
215 switch (wParam)
217 case SC_SCREENSAVE:
218 case SC_MONITORPOWER:
219 if (Core::GetState() == Core::CORE_RUN)
220 break;
221 default:
222 return wxFrame::MSWWindowProc(nMsg, wParam, lParam);
224 break;
225 default:
226 // By default let wxWidgets do what it normally does with this event
227 return wxFrame::MSWWindowProc(nMsg, wParam, lParam);
229 return 0;
231 #endif
233 // event tables
234 // Notice that wxID_HELP will be processed for the 'About' menu and the toolbar
235 // help button.
237 const wxEventType wxEVT_HOST_COMMAND = wxNewEventType();
239 BEGIN_EVENT_TABLE(CFrame, CRenderFrame)
241 // Menu bar
242 EVT_MENU(wxID_OPEN, CFrame::OnOpen)
243 EVT_MENU(wxID_EXIT, CFrame::OnQuit)
244 EVT_MENU(IDM_HELPWEBSITE, CFrame::OnHelp)
245 EVT_MENU(IDM_HELPGOOGLECODE, CFrame::OnHelp)
246 EVT_MENU(IDM_HELPABOUT, CFrame::OnHelp)
247 EVT_MENU(wxID_REFRESH, CFrame::OnRefresh)
248 EVT_MENU(IDM_PLAY, CFrame::OnPlay)
249 EVT_MENU(IDM_STOP, CFrame::OnStop)
250 EVT_MENU(IDM_RESET, CFrame::OnReset)
251 EVT_MENU(IDM_RECORD, CFrame::OnRecord)
252 EVT_MENU(IDM_PLAYRECORD, CFrame::OnPlayRecording)
253 EVT_MENU(IDM_FRAMESTEP, CFrame::OnFrameStep)
254 EVT_MENU(IDM_LUA, CFrame::OnOpenLuaWindow)
255 EVT_MENU(IDM_SCREENSHOT, CFrame::OnScreenshot)
256 EVT_MENU(IDM_CONFIG_MAIN, CFrame::OnConfigMain)
257 EVT_MENU(IDM_CONFIG_GFX_PLUGIN, CFrame::OnPluginGFX)
258 EVT_MENU(IDM_CONFIG_DSP_PLUGIN, CFrame::OnPluginDSP)
259 EVT_MENU(IDM_CONFIG_PAD_PLUGIN, CFrame::OnPluginPAD)
260 EVT_MENU(IDM_CONFIG_WIIMOTE_PLUGIN, CFrame::OnPluginWiimote)
262 EVT_MENU(IDM_SAVE_PERSPECTIVE, CFrame::OnToolBar)
263 EVT_AUITOOLBAR_TOOL_DROPDOWN(IDM_SAVE_PERSPECTIVE, CFrame::OnDropDownToolbarItem)
264 EVT_MENU(IDM_EDIT_PERSPECTIVES, CFrame::OnToolBar)
265 EVT_AUITOOLBAR_TOOL_DROPDOWN(IDM_EDIT_PERSPECTIVES, CFrame::OnDropDownSettingsToolbar)
266 // Drop down
267 EVT_MENU(IDM_PERSPECTIVES_ADD_PANE, CFrame::OnToolBar)
268 EVT_MENU_RANGE(IDM_PERSPECTIVES_0, IDM_PERSPECTIVES_100, CFrame::OnSelectPerspective)
269 EVT_MENU(IDM_ADD_PERSPECTIVE, CFrame::OnDropDownToolbarSelect)
270 EVT_MENU(IDM_TAB_SPLIT, CFrame::OnDropDownToolbarSelect)
271 EVT_MENU(IDM_NO_DOCKING, CFrame::OnDropDownToolbarSelect)
272 // Drop down float
273 EVT_MENU(IDM_FLOAT_LOGWINDOW, CFrame::OnFloatWindow)
274 EVT_MENU(IDM_FLOAT_CONSOLEWINDOW, CFrame::OnFloatWindow)
275 EVT_MENU(IDM_FLOAT_CODEWINDOW, CFrame::OnFloatWindow)
276 EVT_MENU(IDM_FLOAT_REGISTERWINDOW, CFrame::OnFloatWindow)
277 EVT_MENU(IDM_FLOAT_BREAKPOINTWINDOW, CFrame::OnFloatWindow)
278 EVT_MENU(IDM_FLOAT_MEMORYWINDOW, CFrame::OnFloatWindow)
279 EVT_MENU(IDM_FLOAT_JITWINDOW, CFrame::OnFloatWindow)
280 EVT_MENU(IDM_FLOAT_SOUNDWINDOW, CFrame::OnFloatWindow)
281 EVT_MENU(IDM_FLOAT_VIDEOWINDOW, CFrame::OnFloatWindow)
283 EVT_MENU(IDM_NETPLAY, CFrame::OnNetPlay)
284 EVT_MENU(IDM_BROWSE, CFrame::OnBrowse)
285 EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
286 EVT_MENU(IDM_IMPORTSAVE, CFrame::OnImportSave)
287 EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow)
288 EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc)
289 EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu)
291 EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen)
292 EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore)
293 EVT_MENU(IDM_TOGGLE_SKIPIDLE, CFrame::OnToggleSkipIdle)
294 EVT_MENU(IDM_TOGGLE_TOOLBAR, CFrame::OnToggleToolbar)
295 EVT_MENU(IDM_TOGGLE_STATUSBAR, CFrame::OnToggleStatusbar)
296 EVT_MENU(IDM_LOGWINDOW, CFrame::OnToggleLogWindow)
297 EVT_MENU(IDM_CONSOLEWINDOW, CFrame::OnToggleConsole)
299 EVT_MENU(IDM_PURGECACHE, CFrame::GameListChanged)
301 EVT_MENU(IDM_LOADLASTSTATE, CFrame::OnLoadLastState)
302 EVT_MENU(IDM_UNDOLOADSTATE, CFrame::OnUndoLoadState)
303 EVT_MENU(IDM_UNDOSAVESTATE, CFrame::OnUndoSaveState)
304 EVT_MENU(IDM_LOADSTATEFILE, CFrame::OnLoadStateFromFile)
305 EVT_MENU(IDM_SAVESTATEFILE, CFrame::OnSaveStateToFile)
307 EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT8, CFrame::OnLoadState)
308 EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT8, CFrame::OnSaveState)
309 EVT_MENU_RANGE(IDM_FRAMESKIP0, IDM_FRAMESKIP9, CFrame::OnFrameSkip)
310 EVT_MENU_RANGE(IDM_DRIVE1, IDM_DRIVE24, CFrame::OnBootDrive)
311 EVT_MENU_RANGE(IDM_CONNECT_WIIMOTE1, IDM_CONNECT_WIIMOTE4, CFrame::OnConnectWiimote)
312 EVT_MENU_RANGE(IDM_LISTWAD, IDM_LISTDRIVES, CFrame::GameListChanged)
314 // Other
315 EVT_ACTIVATE(CFrame::OnActive)
316 EVT_CLOSE(CFrame::OnClose)
317 EVT_SIZE(CFrame::OnResize)
318 EVT_MOVE(CFrame::OnMove)
319 EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, CFrame::OnGameListCtrl_ItemActivated)
320 EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage)
321 #if wxUSE_TIMER
322 EVT_TIMER(wxID_ANY, CFrame::OnTimer)
323 #endif
325 EVT_AUI_PANE_CLOSE(CFrame::OnPaneClose)
326 EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, CFrame::OnNotebookPageClose)
327 EVT_AUINOTEBOOK_ALLOW_DND(wxID_ANY, CFrame::OnAllowNotebookDnD)
328 EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, CFrame::OnNotebookPageChanged)
329 EVT_AUINOTEBOOK_TAB_RIGHT_UP(wxID_ANY, CFrame::OnTab)
331 // Post events to child panels
332 EVT_MENU(wxID_ANY, CFrame::PostEvent)
333 EVT_TEXT(wxID_ANY, CFrame::PostEvent)
334 //EVT_MENU_HIGHLIGHT_ALL(CFrame::PostMenuEvent)
335 //EVT_UPDATE_UI(wxID_ANY, CFrame::PostUpdateUIEvent)
337 END_EVENT_TABLE()
339 // ---------------
340 // Creation and close, quit functions
342 CFrame::CFrame(wxFrame* parent,
343 wxWindowID id,
344 const wxString& title,
345 const wxPoint& pos,
346 const wxSize& size,
347 bool _UseDebugger,
348 bool ShowLogWindow,
349 long style)
350 : CRenderFrame(parent, id, title, pos, size, style)
351 , g_pCodeWindow(NULL)
352 , m_MenuBar(NULL)
353 , bRenderToMain(false), bNoWiimoteMsg(false)
354 , m_ToolBar(NULL), m_ToolBarDebug(NULL), m_ToolBarAui(NULL)
355 , bFloatLogWindow(false), bFloatConsoleWindow(false)
356 , m_pStatusBar(NULL), m_GameListCtrl(NULL), m_Panel(NULL)
357 , m_RenderFrame(NULL), m_RenderParent(NULL)
358 , m_LogWindow(NULL)
359 , UseDebugger(_UseDebugger), m_bEdit(false), m_bTabSplit(false), m_bNoDocking(false)
360 , m_bControlsCreated(false), m_bGameLoading(false), m_StopDlg(NULL)
361 #if wxUSE_TIMER
362 , m_timer(this)
363 #endif
366 if (ShowLogWindow) SConfig::GetInstance().m_InterfaceLogWindow = true;
368 // Give it a console early to show potential messages from this onward
369 ConsoleListener *Console = LogManager::GetInstance()->getConsoleListener();
370 if (SConfig::GetInstance().m_InterfaceConsole) Console->Open();
371 if (SConfig::GetInstance().m_InterfaceLogWindow) m_LogWindow = new CLogWindow(this, IDM_LOGWINDOW);
373 // Start debugging mazimized
374 if (UseDebugger) this->Maximize(true);
375 // Debugger class
376 if (UseDebugger)
378 g_pCodeWindow = new CCodeWindow(SConfig::GetInstance().m_LocalCoreStartupParameter, this, IDM_CODEWINDOW);
379 g_pCodeWindow->Hide();
380 g_pCodeWindow->Load();
383 // Create timer
384 #if wxUSE_TIMER
385 int TimesPerSecond = 10; // We don't need more than this
386 m_timer.Start( floor((double)(1000 / TimesPerSecond)) );
387 #endif
389 // Create toolbar bitmaps
390 InitBitmaps();
392 // Give it an icon
393 wxIcon IconTemp;
394 IconTemp.CopyFromBitmap(wxGetBitmapFromMemory(dolphin_ico32x32));
395 SetIcon(IconTemp);
397 // Give it a status bar
398 m_pStatusBar = CreateStatusBar(1, wxST_SIZEGRIP, ID_STATUSBAR);
399 if (!SConfig::GetInstance().m_InterfaceStatusbar)
400 m_pStatusBar->Hide();
402 // Give it a menu bar
403 CreateMenu();
405 // ---------------
406 // Main panel
407 // This panel is the parent for rendering and it holds the gamelistctrl
408 m_Panel = new CPanel(this, IDM_MPANEL);
410 m_GameListCtrl = new CGameListCtrl(m_Panel, LIST_CTRL,
411 wxDefaultPosition, wxDefaultSize,
412 wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT);
414 sizerPanel = new wxBoxSizer(wxHORIZONTAL);
415 sizerPanel->Add(m_GameListCtrl, 1, wxEXPAND | wxALL);
416 m_Panel->SetSizer(sizerPanel);
417 // ---------------
419 // Manager
420 // wxAUI_MGR_LIVE_RESIZE does not exist in the wxWidgets 2.8.9 that comes with Ubuntu 9.04
421 // Could just check for wxWidgets version if it becomes a problem.
422 m_Mgr = new wxAuiManager(this, wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
423 NOTEBOOK_STYLE = wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON | wxNO_BORDER;
424 TOOLBAR_STYLE = wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT /*wxAUI_TB_OVERFLOW overflow visible*/;
425 aNormalFile = wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_OTHER, wxSize(16,16));
427 if (g_pCodeWindow)
429 m_Mgr->AddPane(m_Panel, wxAuiPaneInfo().Name(wxT("Pane 0")).Caption(wxT("Pane 0")).Show());
431 else
433 m_Mgr->AddPane(m_Panel, wxAuiPaneInfo().Name(wxT("Pane 0")).Caption(wxT("Pane 0")).Hide());
434 m_Mgr->AddPane(CreateEmptyNotebook(), wxAuiPaneInfo().Name(wxT("Pane 1")).Caption(wxT("Logging")).Hide());
437 // Setup perspectives
438 if (g_pCodeWindow)
440 m_Mgr->GetPane(wxT("Pane 0")).CenterPane().PaneBorder(false);
441 AuiFullscreen = m_Mgr->SavePerspective();
442 m_Mgr->GetPane(wxT("Pane 0")).CenterPane().PaneBorder(true);
444 else
446 IniFile ini; int winpos;
447 ini.Load(File::GetUserPath(F_LOGGERCONFIG_IDX));
448 ini.Get("LogWindow", "pos", &winpos, 2);
450 m_Mgr->GetPane(wxT("Pane 0")).Show().PaneBorder(false).CaptionVisible(false).Layer(0).Center();
451 m_Mgr->GetPane(wxT("Pane 1")).Hide().PaneBorder(false).CaptionVisible(true).Layer(0)
452 .FloatingSize(wxSize(600, 350)).CloseButton(false).Direction(winpos);
453 AuiFullscreen = m_Mgr->SavePerspective();
456 // Create toolbar
457 RecreateToolbar();
458 if (!SConfig::GetInstance().m_InterfaceToolbar) DoToggleToolbar(false);
460 // Create list of available plugins for the configuration window
461 CPluginManager::GetInstance().ScanForPlugins();
463 // Setup perspectives
464 if (g_pCodeWindow)
466 // Load perspective
467 SaveLocal();
468 DoLoadPerspective();
470 else
472 SetSimplePaneSize();
473 if (SConfig::GetInstance().m_InterfaceLogWindow) DoToggleWindow(IDM_LOGWINDOW, true);
474 if (SConfig::GetInstance().m_InterfaceConsole) DoToggleWindow(IDM_CONSOLEWINDOW, true);
477 // Show window
478 Show();
480 // Commit
481 m_Mgr->Update();
483 // Create cursors
484 #ifdef _WIN32
485 CreateCursor();
486 #endif
488 // -------------------------
489 // Connect event handlers
491 m_Mgr->Connect(wxID_ANY, wxEVT_AUI_RENDER, // Resize
492 wxAuiManagerEventHandler(CFrame::OnManagerResize),
493 (wxObject*)0, this);
495 wxTheApp->Connect(wxID_ANY, wxEVT_LEFT_DCLICK,
496 wxMouseEventHandler(CFrame::OnDoubleClick),
497 (wxObject*)0, this);
498 // ----------
500 // Update controls
501 m_bControlsCreated = true;
502 UpdateGUI();
504 //if we are ever going back to optional iso caching:
505 //m_GameListCtrl->Update(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableIsoCache);
506 if (m_GameListCtrl) m_GameListCtrl->Update();
508 // If we are rerecording create the status bar now instead of later when a game starts
509 #ifdef RERECORDING
510 ModifyStatusBar();
511 // It's to early for the OnHostMessage(), we will update the status when Ctrl or Space is pressed
512 //Core::WriteStatus();
513 #endif
515 // Destructor
516 CFrame::~CFrame()
518 m_bControlsCreated = false;
520 drives.clear();
521 /* The statbar sample has this so I add this to, but I guess timer will be deleted after
522 this anyway */
523 #if wxUSE_TIMER
524 if (m_timer.IsRunning()) m_timer.Stop();
525 #endif
527 ClosePages();
529 delete m_Mgr;
532 bool CFrame::RendererIsFullscreen()
534 if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)
536 return m_RenderFrame->IsFullScreen();
538 return false;
541 void CFrame::OnQuit(wxCommandEvent& WXUNUSED (event))
543 Close(true);
546 #if defined HAVE_X11 && HAVE_X11
547 void CFrame::X11_SendClientEvent(const char *message,
548 int data1, int data2, int data3, int data4)
550 XEvent event;
551 Display *dpy = (Display *)Core::GetWindowHandle();
552 Window win = *(Window *)Core::GetXWindow();
554 // Init X event structure for client message
555 event.xclient.type = ClientMessage;
556 event.xclient.format = 32;
557 event.xclient.data.l[0] = XInternAtom(dpy, message, False);
558 event.xclient.data.l[1] = data1;
559 event.xclient.data.l[2] = data2;
560 event.xclient.data.l[3] = data3;
561 event.xclient.data.l[4] = data4;
563 // Send the event
564 if (!XSendEvent(dpy, win, False, False, &event))
565 ERROR_LOG(VIDEO, "Failed to send message %s to the emulator window.\n", message);
568 void X11_SendKeyEvent(int key)
570 XEvent event;
571 Display *dpy = (Display *)Core::GetWindowHandle();
572 Window win = *(Window *)Core::GetXWindow();
574 // Init X event structure for key press event
575 event.xkey.type = KeyPress;
576 // WARNING: This works for ASCII keys. If in the future other keys are needed
577 // convert with InputCommon::wxCharCodeWXToX from X11InputBase.cpp.
578 event.xkey.keycode = XKeysymToKeycode(dpy, key);
580 // Send the event
581 if (!XSendEvent(dpy, win, False, False, &event))
582 ERROR_LOG(VIDEO, "Failed to send key press event to the emulator window.\n");
584 #endif
586 // --------
587 // Events
588 void CFrame::OnActive(wxActivateEvent& event)
590 if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)
592 if (event.GetActive() && event.GetEventObject() == m_RenderFrame)
594 #ifdef _WIN32
595 ::SetFocus((HWND)m_RenderParent->GetHandle());
596 #else
597 m_RenderParent->SetFocus();
598 #endif
599 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
600 Core::GetState() == Core::CORE_RUN)
601 m_RenderParent->SetCursor(wxCURSOR_BLANK);
603 else
605 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
606 m_RenderParent->SetCursor(wxCURSOR_ARROW);
609 event.Skip();
612 void CFrame::OnClose(wxCloseEvent& event)
614 //Stop Dolphin from saving the minimized Xpos and Ypos
615 if(main_frame->IsIconized())
616 main_frame->Iconize(false);
618 // Don't forget the skip or the window won't be destroyed
619 event.Skip();
620 // Save GUI settings
621 if (g_pCodeWindow) Save();
622 // Uninit
623 m_Mgr->UnInit();
625 if (Core::GetState() != Core::CORE_UNINITIALIZED)
627 DoStop();
628 UpdateGUI();
632 // Post events
634 // Warning: This may cause an endless loop if the event is propagated back to its parent
635 void CFrame::PostEvent(wxCommandEvent& event)
637 if (g_pCodeWindow
638 && event.GetId() >= IDM_INTERPRETER && event.GetId() <= IDM_ADDRBOX
639 //&& event.GetId() != IDM_JITUNLIMITED
642 event.StopPropagation();
643 g_pCodeWindow->GetEventHandler()->AddPendingEvent(event);
645 else
646 event.Skip();
648 void CFrame::PostMenuEvent(wxMenuEvent& event)
650 if (g_pCodeWindow) g_pCodeWindow->GetEventHandler()->AddPendingEvent(event);
652 void CFrame::PostUpdateUIEvent(wxUpdateUIEvent& event)
654 if (g_pCodeWindow) g_pCodeWindow->GetEventHandler()->AddPendingEvent(event);
657 void CFrame::OnMove(wxMoveEvent& event)
659 event.Skip();
661 if (!IsMaximized() &&
662 !(SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && RendererIsFullscreen()))
664 SConfig::GetInstance().m_LocalCoreStartupParameter.iPosX = GetPosition().x;
665 SConfig::GetInstance().m_LocalCoreStartupParameter.iPosY = GetPosition().y;
669 void CFrame::OnResize(wxSizeEvent& event)
671 event.Skip();
672 if (!IsMaximized() &&
673 !(SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && RendererIsFullscreen()))
675 SConfig::GetInstance().m_LocalCoreStartupParameter.iWidth = GetSize().GetWidth();
676 SConfig::GetInstance().m_LocalCoreStartupParameter.iHeight = GetSize().GetHeight();
680 // Host messages
682 #ifdef _WIN32
683 WXLRESULT CFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
685 switch (nMsg)
687 case WM_SYSCOMMAND:
688 switch (wParam & 0xFFF0)
690 case SC_SCREENSAVE:
691 case SC_MONITORPOWER:
692 break;
693 default:
694 return wxFrame::MSWWindowProc(nMsg, wParam, lParam);
696 break;
697 default:
698 return wxFrame::MSWWindowProc(nMsg, wParam, lParam);
700 return 0;
702 #endif
704 #if wxUSE_TIMER
705 void CFrame::OnTimer(wxTimerEvent& WXUNUSED(event))
707 // Process events. Primarily to update the statusbar text.
708 if (wxGetApp().Pending())
709 wxGetApp().ProcessPendingEvents();
711 #endif
713 void CFrame::OnHostMessage(wxCommandEvent& event)
715 switch (event.GetId())
717 case IDM_UPDATEGUI:
718 UpdateGUI();
719 break;
721 case IDM_UPDATESTATUSBAR:
722 if (m_pStatusBar != NULL)
724 m_pStatusBar->SetStatusText(event.GetString(), event.GetInt());
726 break;
728 case IDM_UPDATETITLE:
729 if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && m_RenderFrame)
730 m_RenderFrame->SetTitle(event.GetString());
731 break;
733 case WM_USER_CREATE:
734 DoFullscreen(SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen);
735 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
736 m_RenderParent->SetCursor(wxCURSOR_BLANK);
737 break;
738 #if defined(HAVE_X11) && HAVE_X11
739 case WM_USER_STOP:
740 DoStop();
741 break;
742 #endif
746 void CFrame::OnCustomHostMessage(int Id)
748 wxWindow *Win;
750 switch(Id)
752 // Destroy windows
753 case AUDIO_DESTROY:
754 Win = GetWxWindow(wxT("Sound"));
755 if (Win)
757 DoRemovePage(Win, false);
759 CPluginManager::GetInstance().OpenDebug(
760 GetHandle(),
761 SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(),
762 PLUGIN_TYPE_DSP, false
765 //Win->Reparent(NULL);
766 //g_pCodeWindow->OnToggleDLLWindow(false, 0);
767 GetMenuBar()->FindItem(IDM_SOUNDWINDOW)->Check(false);
768 NOTICE_LOG(CONSOLE, "%s", Core::StopMessage(true, "Sound debugging window closed").c_str());
770 break;
772 case VIDEO_DESTROY:
773 break;
777 void CFrame::OnSizeRequest(int& x, int& y, int& width, int& height)
779 m_RenderParent->GetSize(&width, &height);
780 m_RenderParent->GetPosition(&x, &y);
783 bool CFrame::RendererHasFocus()
785 #ifdef _WIN32
786 // Why doesn't the "else" method below work in windows when called from
787 // Host_RendererHasFocus()?
788 if (m_RenderParent)
789 if (m_RenderParent->GetParent()->GetHWND() == GetForegroundWindow())
790 return true;
791 return false;
792 #else
793 return m_RenderParent && (m_RenderParent == wxWindow::FindFocus());
794 #endif
797 void CFrame::OnGameListCtrl_ItemActivated(wxListEvent& WXUNUSED (event))
799 // Show all platforms and regions if...
800 // 1. All platforms are set to hide
801 // 2. All Regions are set to hide
802 // Otherwise call BootGame to either...
803 // 1. Boot the selected iso
804 // 2. Boot the default or last loaded iso.
805 // 3. Call BrowseForDirectory if the gamelist is empty
806 if (!m_GameListCtrl->GetGameNames().size() &&
807 !((SConfig::GetInstance().m_ListGC &&
808 SConfig::GetInstance().m_ListWii &&
809 SConfig::GetInstance().m_ListWad) &&
810 (SConfig::GetInstance().m_ListJap &&
811 SConfig::GetInstance().m_ListUsa &&
812 SConfig::GetInstance().m_ListPal &&
813 SConfig::GetInstance().m_ListFrance &&
814 SConfig::GetInstance().m_ListItaly &&
815 SConfig::GetInstance().m_ListKorea &&
816 SConfig::GetInstance().m_ListTaiwan &&
817 SConfig::GetInstance().m_ListUnknown)))
819 SConfig::GetInstance().m_ListGC = SConfig::GetInstance().m_ListWii =
820 SConfig::GetInstance().m_ListWad = SConfig::GetInstance().m_ListJap =
821 SConfig::GetInstance().m_ListUsa = SConfig::GetInstance().m_ListPal =
822 SConfig::GetInstance().m_ListFrance = SConfig::GetInstance().m_ListItaly =
823 SConfig::GetInstance().m_ListKorea = SConfig::GetInstance().m_ListTaiwan =
824 SConfig::GetInstance().m_ListUnknown= true;
826 GetMenuBar()->FindItem(IDM_LISTGC)->Check(true);
827 GetMenuBar()->FindItem(IDM_LISTWII)->Check(true);
828 GetMenuBar()->FindItem(IDM_LISTWAD)->Check(true);
829 GetMenuBar()->FindItem(IDM_LISTJAP)->Check(true);
830 GetMenuBar()->FindItem(IDM_LISTUSA)->Check(true);
831 GetMenuBar()->FindItem(IDM_LISTPAL)->Check(true);
832 GetMenuBar()->FindItem(IDM_LISTFRANCE)->Check(true);
833 GetMenuBar()->FindItem(IDM_LISTITALY)->Check(true);
834 GetMenuBar()->FindItem(IDM_LISTKOREA)->Check(true);
835 GetMenuBar()->FindItem(IDM_LISTTAIWAN)->Check(true);
836 GetMenuBar()->FindItem(IDM_LIST_UNK)->Check(true);
838 m_GameListCtrl->Update();
840 else
841 // Game started by double click
842 BootGame(std::string(""));
845 bool IsHotkey(wxKeyEvent &event, int Id)
847 return (event.GetKeyCode() == SConfig::GetInstance().m_LocalCoreStartupParameter.iHotkey[Id] &&
848 event.GetModifiers() == SConfig::GetInstance().m_LocalCoreStartupParameter.iHotkeyModifier[Id]);
851 void CFrame::OnKeyDown(wxKeyEvent& event)
853 if(Core::GetState() != Core::CORE_UNINITIALIZED)
855 // Toggle fullscreen
856 if (IsHotkey(event, HK_FULLSCREEN))
857 DoFullscreen(!RendererIsFullscreen());
858 // Pause and Unpause
859 else if (IsHotkey(event, HK_PLAY_PAUSE))
860 DoPause();
861 // Stop
862 else if (IsHotkey(event, HK_STOP))
863 DoStop();
865 // Send the OSD hotkeys to the video plugin
866 if (event.GetKeyCode() >= '3' && event.GetKeyCode() <= '7' && event.GetModifiers() == wxMOD_NONE)
868 #ifdef _WIN32
869 PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode());
870 #elif defined(HAVE_X11) && HAVE_X11
871 X11_SendKeyEvent(event.GetKeyCode());
872 #endif
874 #ifdef _WIN32
875 // Send the freelook hotkeys to the video plugin
876 if ((event.GetKeyCode() == '0', '9', 'W', 'S', 'A', 'D', 'R')
877 && event.GetModifiers() == wxMOD_SHIFT)
878 PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode());
879 #endif
880 // state save and state load hotkeys
881 if (event.GetKeyCode() >= WXK_F1 && event.GetKeyCode() <= WXK_F8)
883 int slot_number = event.GetKeyCode() - WXK_F1 + 1;
884 if (event.GetModifiers() == wxMOD_NONE)
885 State_Load(slot_number);
886 else if (event.GetModifiers() == wxMOD_SHIFT)
887 State_Save(slot_number);
889 if (event.GetKeyCode() == WXK_F11 && event.GetModifiers() == wxMOD_NONE)
890 State_LoadLastSaved();
891 if (event.GetKeyCode() == WXK_F12)
893 if (event.GetModifiers() == wxMOD_NONE)
894 State_UndoSaveState();
895 else if (event.GetModifiers() == wxMOD_SHIFT)
896 State_UndoLoadState();
898 // screenshot hotkeys
899 if (event.GetKeyCode() == WXK_F9 && event.GetModifiers() == wxMOD_NONE)
900 Core::ScreenShot();
902 // Send the keyboard status to the Input plugin
903 CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down
905 else
906 event.Skip();
909 void CFrame::OnKeyUp(wxKeyEvent& event)
911 event.Skip();
913 if(Core::GetState() != Core::CORE_UNINITIALIZED)
914 CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 0); // 0 = Up
917 // ---------------
918 // Detect double click
920 void CFrame::OnDoubleClick(wxMouseEvent& event)
922 // Don't block the mouse click
923 event.Skip();
925 // Don't use this in Wii mode since we use the mouse as input to the game there
926 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) return;
928 // Only detect double clicks in the rendering window, and only use this when a game is running
929 if (! (Core::GetState() == Core::CORE_RUN && event.GetEventObject() == m_RenderParent)) return;
931 DoFullscreen(!RendererIsFullscreen());
935 // --------
936 // Functions
939 wxFrame * CFrame::CreateParentFrame(wxWindowID Id, const wxString& Title, wxWindow * Child)
941 wxFrame * Frame = new wxFrame(this, Id, Title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE);
943 Child->Reparent(Frame);
944 Child->Show();
946 wxBoxSizer * m_MainSizer = new wxBoxSizer(wxHORIZONTAL);
948 m_MainSizer->Add(Child, 1, wxEXPAND);
950 Frame->Connect(wxID_ANY, wxEVT_CLOSE_WINDOW,
951 wxCloseEventHandler(CFrame::OnFloatingPageClosed),
952 (wxObject*)0, this);
954 if (Id == IDM_CONSOLEWINDOW_PARENT)
956 Frame->Connect(wxID_ANY, wxEVT_SIZE,
957 wxSizeEventHandler(CFrame::OnFloatingPageSize),
958 (wxObject*)0, this);
961 // Main sizer
962 Frame->SetSizer( m_MainSizer );
963 // Minimum frame size
964 Frame->SetMinSize(wxSize(200, -1));
965 Frame->Show();
966 return Frame;
968 wxPanel* CFrame::CreateEmptyPanel(wxWindowID Id)
970 wxPanel* Panel = new wxPanel(this, Id);
971 return Panel;
973 wxAuiNotebook* CFrame::CreateEmptyNotebook()
975 wxAuiNotebook* NB = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, NOTEBOOK_STYLE);
976 return NB;
979 void CFrame::DoFullscreen(bool bF)
981 // Only switch this to fullscreen if we're rendering to main AND if we're running a game
982 // plus if a modal dialog is open, this will still process the keyboard events, and may cause
983 // the main window to become unresponsive, so we have to avoid that.
984 if ((Core::GetState() == Core::CORE_RUN) || (Core::GetState() == Core::CORE_PAUSE))
986 #if defined(HAVE_X11) && HAVE_X11
987 X11_SendClientEvent("TOGGLE_DISPLAYMODE", bF);
988 #elif defined(_WIN32)
989 PostMessage((HWND)Core::GetWindowHandle(), WM_USER, TOGGLE_DISPLAYMODE, bF);
990 #endif
991 m_RenderFrame->ShowFullScreen(bF);
992 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain)
994 if (bF)
996 // Save the current mode before going to fullscreen
997 AuiCurrent = m_Mgr->SavePerspective();
998 m_Mgr->LoadPerspective(AuiFullscreen, true);
1000 else
1002 // Restore saved perspective
1003 m_Mgr->LoadPerspective(AuiCurrent, true);
1006 else
1007 m_RenderFrame->Raise();
1011 // Debugging, show loose windows
1012 void CFrame::ListChildren()
1014 ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
1015 wxAuiNotebook * NB = NULL;
1017 Console->Log(LogTypes::LNOTICE, "--------------------------------------------------------------------\n");
1019 for (u32 i = 0; i < this->GetChildren().size(); i++)
1021 wxWindow * Win = this->GetChildren().Item(i)->GetData();
1022 Console->Log(LogTypes::LNOTICE, StringFromFormat(
1023 "%i: %s (%s) :: %s", i,
1024 (const char*)Win->GetName().mb_str(), (const char*)Win->GetLabel().mb_str(), (const char*)Win->GetParent()->GetName().mb_str()).c_str());
1025 //if (Win->GetName().IsSameAs(wxT("control")))
1026 if (Win->IsKindOf(CLASSINFO(wxAuiNotebook)))
1028 NB = (wxAuiNotebook*)Win;
1029 Console->Log(LogTypes::LNOTICE, StringFromFormat(" :: NB", (const char*)NB->GetName().mb_str()).c_str());
1031 else
1033 NB = NULL;
1035 Console->Log(LogTypes::LNOTICE, StringFromFormat("\n").c_str());
1037 Win = this->GetChildren().Item(i)->GetData();
1038 for (u32 j = 0; j < Win->GetChildren().size(); j++)
1040 Console->Log(LogTypes::LNOTICE, StringFromFormat(
1041 " %i.%i: %s (%s) :: %s", i, j,
1042 (const char*)Win->GetName().mb_str(), (const char*)Win->GetLabel().mb_str(), (const char*)Win->GetParent()->GetName().mb_str()).c_str());
1043 if (NB)
1045 if (j < NB->GetPageCount())
1046 Console->Log(LogTypes::LNOTICE, StringFromFormat(" :: %s", (const char*)NB->GetPage(j)->GetName().mb_str()).c_str());
1048 Console->Log(LogTypes::LNOTICE, StringFromFormat("\n").c_str());
1051 Win = this->GetChildren().Item(j)->GetData();
1052 for (int k = 0; k < Win->GetChildren().size(); k++)
1054 Console->Log(LogTypes::LNOTICE, StringFromFormat(
1055 " %i.%i.%i: %s (%s) :: %s\n", i, j, k,
1056 Win->GetName().mb_str(), Win->GetLabel().mb_str(), Win->GetParent()->GetName().mb_str()).c_str());
1062 Console->Log(LogTypes::LNOTICE, "--------------------------------------------------------------------\n");
1064 for (u32 i = 0; i < m_Mgr->GetAllPanes().GetCount(); i++)
1066 if (!m_Mgr->GetAllPanes().Item(i).window->IsKindOf(CLASSINFO(wxAuiNotebook))) continue;
1067 wxAuiNotebook * _NB = (wxAuiNotebook*)m_Mgr->GetAllPanes().Item(i).window;
1068 Console->Log(LogTypes::LNOTICE, StringFromFormat("%i: %s\n", i, (const char *)m_Mgr->GetAllPanes().Item(i).name.mb_str()).c_str());
1070 for (u32 j = 0; j < _NB->GetPageCount(); j++)
1072 Console->Log(LogTypes::LNOTICE, StringFromFormat("%i.%i: %s\n", i, j, (const char *)_NB->GetPageText(j).mb_str()).c_str());
1076 Console->Log(LogTypes::LNOTICE, "--------------------------------------------------------------------\n");
1079 void CFrame::ListTopWindows()
1081 wxWindowList::const_iterator i;
1082 int j = 0;
1083 const wxWindowList::const_iterator end = wxTopLevelWindows.end();
1085 for (i = wxTopLevelWindows.begin(); i != end; ++i)
1087 wxTopLevelWindow * const Win = wx_static_cast(wxTopLevelWindow *, *i);
1088 NOTICE_LOG(CONSOLE, "%i: %i %s", j, Win, (const char *)Win->GetTitle().mb_str());
1090 if ( win->ShouldPreventAppExit() )
1092 // there remains at least one important TLW, don't exit
1093 return false;
1096 j++;
1098 NOTICE_LOG(CONSOLE, "\n");