diff options
| author | Glenn Rice <glennricster@gmail.com> | 2010-03-15 23:25:11 +0000 |
|---|---|---|
| committer | Glenn Rice <glennricster@gmail.com> | 2010-03-15 23:25:11 +0000 |
| commit | 2015d252f02f422cd92c10c2a0aad4417ca2656e (patch) | |
| tree | 8035f5a242cb0c18ba9773436773b76d0b4777c4 /Source/Core | |
| parent | c5d4c2c1b1c6ac669f2573b5ae84fa946f0db243 (diff) | |
Rewrite of fullscreen toggling in linux. This goes back to using the EWMH specifications. I wasn't using it right before, but now it should work on all EWMH compliant window managers (like KDE, Metacity, Compiz, etc). Since this doesn't need an override redirect Alt-Tab works even in fullscreen mode. This also allows for some other nice things to be done.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5199 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Src/Core.cpp | 71 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/Frame.cpp | 108 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/Frame.h | 3 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/FrameTools.cpp | 21 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/Main.cpp | 2 |
5 files changed, 103 insertions, 102 deletions
diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 7abb4612fd..45333463f5 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -29,11 +29,6 @@ #include "MathUtil.h" #include "MemoryUtil.h" -#if defined(HAVE_X11) && HAVE_X11 -#include <X11/Xlib.h> -#include <X11/keysym.h> -#endif - #include "Console.h" #include "Core.h" #include "CPUDetect.h" @@ -252,47 +247,6 @@ void Stop() // - Hammertime! g_EmuThread = 0; } -#if defined(HAVE_X11) && HAVE_X11 -void ProcessXEvents(void) -{ - if (GetState() == CORE_PAUSE) - { - Display *dpy = (Display *)g_pWindowHandle; - XEvent event; - KeySym key; - int num_events; - for (num_events = XPending(dpy);num_events > 0;num_events--) - { - XNextEvent(dpy, &event); - switch(event.type) { - case KeyPress: - key = XLookupKeysym((XKeyEvent*)&event, 0); - if (key == XK_Escape) - Host_Message(WM_USER_PAUSE); - case ClientMessage: - if ((ulong) event.xclient.data.l[0] == XInternAtom(dpy, "WM_DELETE_WINDOW", False)) - Host_Message(WM_USER_STOP); - if ((ulong) event.xclient.data.l[0] == XInternAtom(dpy, "WINDOW_REFOCUS", False)) - XSetInputFocus(dpy, *(Window *)g_pXWindow, RevertToPointerRoot, CurrentTime); - break; - default: - break; - } - } - } -} - -THREAD_RETURN XEventThread(void *pArg) -{ - while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) - { - ProcessXEvents(); - Common::SleepCurrentThread(200); - } - return 0; -} -#endif - // Create the CPU thread. which would be a CPU + Video thread in Single Core mode. THREAD_RETURN CpuThread(void *pArg) @@ -368,6 +322,9 @@ THREAD_RETURN EmuThread(void *pArg) VideoInitialize.pScheduleEvent_Threadsafe = CoreTiming::ScheduleEvent_Threadsafe; // This is first the m_Panel handle, then it is updated to have the new window handle VideoInitialize.pWindowHandle = _CoreParameter.hMainWindow; +#if defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 + VideoInitialize.pPanel = _CoreParameter.hMainWindow; +#endif VideoInitialize.pLog = Callback_VideoLog; VideoInitialize.pSysMessage = Host_SysMessage; VideoInitialize.pRequestWindowSize = NULL; //Callback_VideoRequestWindowSize; @@ -388,7 +345,7 @@ THREAD_RETURN EmuThread(void *pArg) // Under linux, this is an X11 Display, not a HWND! g_pWindowHandle = (HWND)VideoInitialize.pWindowHandle; #if defined(HAVE_X11) && HAVE_X11 - g_pXWindow = (Window *)VideoInitialize.pXWindow; + g_pXWindow = (void *)VideoInitialize.pXWindow; #endif Callback_PeekMessages = VideoInitialize.pPeekMessages; g_pUpdateFPSDisplay = VideoInitialize.pUpdateFPSDisplay; @@ -417,6 +374,9 @@ THREAD_RETURN EmuThread(void *pArg) PADInitialize.hWnd = g_pWindowHandle; #if defined(HAVE_X11) && HAVE_X11 PADInitialize.pXWindow = g_pXWindow; +#if defined(HAVE_GTK2) && HAVE_GTK2 + PADInitialize.pPanel = VideoInitialize.pPanel; +#endif #endif PADInitialize.pLog = Callback_PADLog; // This is may be needed to avoid a SDL problem @@ -429,6 +389,9 @@ THREAD_RETURN EmuThread(void *pArg) SWiimoteInitialize WiimoteInitialize; WiimoteInitialize.hWnd = g_pWindowHandle; #if defined(HAVE_X11) && HAVE_X11 +#if defined(HAVE_GTK2) && HAVE_GTK2 + WiimoteInitialize.pPanel = VideoInitialize.pPanel; +#endif WiimoteInitialize.pXWindow = g_pXWindow; #endif WiimoteInitialize.ISOId = Ascii2Hex(_CoreParameter.m_strUniqueID); @@ -459,10 +422,6 @@ THREAD_RETURN EmuThread(void *pArg) // Spawn the CPU thread Common::Thread *cpuThread = NULL; -#if defined(HAVE_X11) && HAVE_X11 - Common::Thread *xEventThread = NULL; -#endif - // ENTER THE VIDEO THREAD LOOP if (_CoreParameter.bCPUThread) { @@ -471,9 +430,6 @@ THREAD_RETURN EmuThread(void *pArg) Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent cpuThread = new Common::Thread(CpuThread, pArg); -#if defined(HAVE_X11) && HAVE_X11 - xEventThread = new Common::Thread(XEventThread, pArg); -#endif Common::SetCurrentThreadName("Video thread"); if (g_pUpdateFPSDisplay != NULL) @@ -508,9 +464,6 @@ THREAD_RETURN EmuThread(void *pArg) { if (Callback_PeekMessages) Callback_PeekMessages(); -#if defined(HAVE_X11) && HAVE_X11 - ProcessXEvents(); -#endif Common::SleepCurrentThread(20); } @@ -817,11 +770,15 @@ void Callback_KeyPress(int key, bool shift, bool control) State_UndoLoadState(); } #if defined(HAVE_X11) && HAVE_X11 + if (key == 0) + Host_Message(WM_USER_CREATE); // 0x1b == VK_ESCAPE if (key == 0x1b) Host_Message(WM_USER_STOP); if (key == 0x1c) Host_Message(WM_USER_PAUSE); + if (key == 0x1d) + Host_Message(TOGGLE_FULLSCREEN); #endif } diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index ea38e45bfa..333c5d4f46 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -523,7 +523,7 @@ void CFrame::OnQuit(wxCommandEvent& WXUNUSED (event)) } #if defined HAVE_X11 && HAVE_X11 -void X11_SendEvent(const char *message) +void CFrame::X11_SendClientEvent(const char *message) { XEvent event; Display *dpy = (Display *)Core::GetWindowHandle(); @@ -536,9 +536,24 @@ void X11_SendEvent(const char *message) // Send the event if (!XSendEvent(dpy, win, False, False, &event)) - { ERROR_LOG(VIDEO, "Failed to send message %s to the emulator window.\n", message); - } +} + +void X11_SendKeyEvent(int key) +{ + XEvent event; + Display *dpy = (Display *)Core::GetWindowHandle(); + Window win = *(Window *)Core::GetXWindow(); + + // Init X event structure for key press event + event.xkey.type = KeyPress; + // WARNING: This works for '3' to '7'. If in the future other keys are needed + // convert with InputCommon::wxCharCodeWXToX from X11InputBase.cpp. + event.xkey.keycode = XKeysymToKeycode(dpy, key); + + // Send the event + if (!XSendEvent(dpy, win, False, False, &event)) + ERROR_LOG(VIDEO, "Failed to send key press event to the emulator window.\n"); } #endif @@ -547,8 +562,13 @@ void X11_SendEvent(const char *message) void CFrame::OnActive(wxActivateEvent& event) { #if defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK) - if (event.GetActive() && (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)) - X11_SendEvent("WINDOW_REFOCUS"); + if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE) + { + if (event.GetActive()) + X11_SendClientEvent("FOCUSIN"); + else + X11_SendClientEvent("FOCUSOUT"); + } #endif event.Skip(); } @@ -618,7 +638,7 @@ void CFrame::OnResizeAll(wxSizeEvent& event) event.Skip(); #if defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK) if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE) - X11_SendEvent("MAIN_RESIZED"); + X11_SendClientEvent("RESIZE"); #endif //wxWindow * Win = (wxWindow*)event.GetEventObject(); //NOTICE_LOG(CONSOLE, "OnResizeAll: %i", (HWND)Win->GetHWND()); @@ -675,11 +695,17 @@ void CFrame::OnHostMessage(wxCommandEvent& event) } break; #if defined(HAVE_X11) && HAVE_X11 + case WM_USER_CREATE: + bRenderToMain = true; + break; + case TOGGLE_FULLSCREEN: + DoFullscreen(!IsFullScreen()); + break; case WM_USER_STOP: - main_frame->DoStop(); + DoStop(); break; case WM_USER_PAUSE: - main_frame->DoPause(); + DoPause(); break; #endif } @@ -787,8 +813,14 @@ void CFrame::OnKeyDown(wxKeyEvent& event) { PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode()); } +#elif defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK) + if (event.GetKeyCode() >= '3' && event.GetKeyCode() <= '7') // Send this to the video plugin + { + X11_SendKeyEvent(event.GetKeyCode()); + } #endif + // Send the keyboard status to the Input plugin if(Core::GetState() != Core::CORE_UNINITIALIZED) CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down @@ -938,44 +970,46 @@ wxAuiNotebook* CFrame::CreateEmptyNotebook() void CFrame::DoFullscreen(bool bF) { -#if defined HAVE_X11 && HAVE_X11 - if ((Core::GetState() == Core::CORE_RUN)) - X11_SendEvent("TOGGLE_FULLSCREEN"); -#endif // Only switch this to fullscreen if we're rendering to main AND if we're running a game // plus if a modal dialog is open, this will still process the keyboard events, and may cause // the main window to become unresponsive, so we have to avoid that. - if ((bRenderToMain && Core::GetState() == Core::CORE_RUN)) + if ((Core::GetState() == Core::CORE_RUN) || (Core::GetState() == Core::CORE_PAUSE)) { - ShowFullScreen(bF); - - if (bF) - { - // Save the current mode before going to fullscreen - AuiCurrent = m_Mgr->SavePerspective(); - m_Mgr->LoadPerspective(AuiFullscreen, true); - } - else + if (bRenderToMain) { - // Restore saved perspective - m_Mgr->LoadPerspective(AuiCurrent, true); - } + ShowFullScreen(bF); - // Show the cursor again, in case it was hidden - if (IsFullScreen()) - { - #ifdef _WIN32 - MSWSetCursor(true); - #endif + if (bF) + { + // Save the current mode before going to fullscreen + AuiCurrent = m_Mgr->SavePerspective(); + m_Mgr->LoadPerspective(AuiFullscreen, true); + } + else + { + // Restore saved perspective + m_Mgr->LoadPerspective(AuiCurrent, true); + } + +#ifdef _WIN32 + // Show the cursor again, in case it was hidden + if (IsFullScreen()) + { + MSWSetCursor(true); + } +#endif } - } #ifdef _WIN32 - else // Post the message to the separate rendering window which will then handle it. - { - BringWindowToTop((HWND)Core::GetWindowHandle()); - PostMessage((HWND)Core::GetWindowHandle(), WM_USER, TOGGLE_FULLSCREEN, 0); - } + else // Post the message to the separate rendering window which will then handle it. + { + BringWindowToTop((HWND)Core::GetWindowHandle()); + PostMessage((HWND)Core::GetWindowHandle(), WM_USER, TOGGLE_FULLSCREEN, 0); + } +#elif defined HAVE_X11 && HAVE_X11 + else // Send the event to the separate rendering window which will then handle it. + X11_SendClientEvent("TOGGLE_FULLSCREEN"); #endif + } } // Debugging, show loose windows diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h index 5d0656a477..c4e21c1a06 100644 --- a/Source/Core/DolphinWX/Src/Frame.h +++ b/Source/Core/DolphinWX/Src/Frame.h @@ -303,6 +303,9 @@ class CFrame : public wxFrame void OnGameListCtrl_ItemActivated(wxListEvent& event); void DoFullscreen(bool _F); +#if defined HAVE_X11 && HAVE_X11 + void X11_SendClientEvent(const char *message); +#endif // MenuBar // File - Drive diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 50d710ed49..6c7aca9b7e 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -629,16 +629,11 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event)) wxThread::Sleep(20); g_pCodeWindow->JumpToAddress(PC); g_pCodeWindow->Update(); + // Update toolbar with Play/Pause status + UpdateGUI(); } else - { - if (Core::GetState() == Core::CORE_RUN) - Core::SetState(Core::CORE_PAUSE); - else - Core::SetState(Core::CORE_RUN); - } - // Update toolbar with Play/Pause status - UpdateGUI(); + DoPause(); } else // Core is uninitialized, start the game @@ -692,9 +687,19 @@ void CFrame::OnScreenshot(wxCommandEvent& WXUNUSED (event)) void CFrame::DoPause() { if (Core::GetState() == Core::CORE_RUN) + { +#if defined(HAVE_X11) && HAVE_X11 + X11_SendClientEvent("PAUSE"); +#endif Core::SetState(Core::CORE_PAUSE); + } else + { +#if defined(HAVE_X11) && HAVE_X11 + X11_SendClientEvent("RESUME"); +#endif Core::SetState(Core::CORE_RUN); + } UpdateGUI(); } diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index 87ff3a7b6b..a8a9e600c0 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -533,6 +533,8 @@ void Host_Message(int Id) #if defined(HAVE_X11) && HAVE_X11 switch(Id) { + case WM_USER_CREATE: + case TOGGLE_FULLSCREEN: case WM_USER_STOP: case WM_USER_PAUSE: { |
