summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorGlenn Rice <glennricster@gmail.com>2010-03-15 23:25:11 +0000
committerGlenn Rice <glennricster@gmail.com>2010-03-15 23:25:11 +0000
commit2015d252f02f422cd92c10c2a0aad4417ca2656e (patch)
tree8035f5a242cb0c18ba9773436773b76d0b4777c4 /Source/Core
parentc5d4c2c1b1c6ac669f2573b5ae84fa946f0db243 (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.cpp71
-rw-r--r--Source/Core/DolphinWX/Src/Frame.cpp108
-rw-r--r--Source/Core/DolphinWX/Src/Frame.h3
-rw-r--r--Source/Core/DolphinWX/Src/FrameTools.cpp21
-rw-r--r--Source/Core/DolphinWX/Src/Main.cpp2
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:
{