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
This commit is contained in:
parent
c5d4c2c1b1
commit
2015d252f0
|
@ -29,11 +29,6 @@
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
|
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "CPUDetect.h"
|
#include "CPUDetect.h"
|
||||||
|
@ -252,47 +247,6 @@ void Stop() // - Hammertime!
|
||||||
g_EmuThread = 0;
|
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.
|
// Create the CPU thread. which would be a CPU + Video thread in Single Core mode.
|
||||||
|
|
||||||
THREAD_RETURN CpuThread(void *pArg)
|
THREAD_RETURN CpuThread(void *pArg)
|
||||||
|
@ -368,6 +322,9 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
VideoInitialize.pScheduleEvent_Threadsafe = CoreTiming::ScheduleEvent_Threadsafe;
|
VideoInitialize.pScheduleEvent_Threadsafe = CoreTiming::ScheduleEvent_Threadsafe;
|
||||||
// This is first the m_Panel handle, then it is updated to have the new window handle
|
// This is first the m_Panel handle, then it is updated to have the new window handle
|
||||||
VideoInitialize.pWindowHandle = _CoreParameter.hMainWindow;
|
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.pLog = Callback_VideoLog;
|
||||||
VideoInitialize.pSysMessage = Host_SysMessage;
|
VideoInitialize.pSysMessage = Host_SysMessage;
|
||||||
VideoInitialize.pRequestWindowSize = NULL; //Callback_VideoRequestWindowSize;
|
VideoInitialize.pRequestWindowSize = NULL; //Callback_VideoRequestWindowSize;
|
||||||
|
@ -388,7 +345,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
// Under linux, this is an X11 Display, not a HWND!
|
// Under linux, this is an X11 Display, not a HWND!
|
||||||
g_pWindowHandle = (HWND)VideoInitialize.pWindowHandle;
|
g_pWindowHandle = (HWND)VideoInitialize.pWindowHandle;
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
g_pXWindow = (Window *)VideoInitialize.pXWindow;
|
g_pXWindow = (void *)VideoInitialize.pXWindow;
|
||||||
#endif
|
#endif
|
||||||
Callback_PeekMessages = VideoInitialize.pPeekMessages;
|
Callback_PeekMessages = VideoInitialize.pPeekMessages;
|
||||||
g_pUpdateFPSDisplay = VideoInitialize.pUpdateFPSDisplay;
|
g_pUpdateFPSDisplay = VideoInitialize.pUpdateFPSDisplay;
|
||||||
|
@ -417,6 +374,9 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
PADInitialize.hWnd = g_pWindowHandle;
|
PADInitialize.hWnd = g_pWindowHandle;
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
PADInitialize.pXWindow = g_pXWindow;
|
PADInitialize.pXWindow = g_pXWindow;
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2
|
||||||
|
PADInitialize.pPanel = VideoInitialize.pPanel;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
PADInitialize.pLog = Callback_PADLog;
|
PADInitialize.pLog = Callback_PADLog;
|
||||||
// This is may be needed to avoid a SDL problem
|
// This is may be needed to avoid a SDL problem
|
||||||
|
@ -429,6 +389,9 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
SWiimoteInitialize WiimoteInitialize;
|
SWiimoteInitialize WiimoteInitialize;
|
||||||
WiimoteInitialize.hWnd = g_pWindowHandle;
|
WiimoteInitialize.hWnd = g_pWindowHandle;
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2
|
||||||
|
WiimoteInitialize.pPanel = VideoInitialize.pPanel;
|
||||||
|
#endif
|
||||||
WiimoteInitialize.pXWindow = g_pXWindow;
|
WiimoteInitialize.pXWindow = g_pXWindow;
|
||||||
#endif
|
#endif
|
||||||
WiimoteInitialize.ISOId = Ascii2Hex(_CoreParameter.m_strUniqueID);
|
WiimoteInitialize.ISOId = Ascii2Hex(_CoreParameter.m_strUniqueID);
|
||||||
|
@ -459,10 +422,6 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
|
|
||||||
// Spawn the CPU thread
|
// Spawn the CPU thread
|
||||||
Common::Thread *cpuThread = NULL;
|
Common::Thread *cpuThread = NULL;
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
|
||||||
Common::Thread *xEventThread = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ENTER THE VIDEO THREAD LOOP
|
// ENTER THE VIDEO THREAD LOOP
|
||||||
if (_CoreParameter.bCPUThread)
|
if (_CoreParameter.bCPUThread)
|
||||||
{
|
{
|
||||||
|
@ -471,9 +430,6 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
|
|
||||||
Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent
|
Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent
|
||||||
cpuThread = new Common::Thread(CpuThread, pArg);
|
cpuThread = new Common::Thread(CpuThread, pArg);
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
|
||||||
xEventThread = new Common::Thread(XEventThread, pArg);
|
|
||||||
#endif
|
|
||||||
Common::SetCurrentThreadName("Video thread");
|
Common::SetCurrentThreadName("Video thread");
|
||||||
|
|
||||||
if (g_pUpdateFPSDisplay != NULL)
|
if (g_pUpdateFPSDisplay != NULL)
|
||||||
|
@ -508,9 +464,6 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
{
|
{
|
||||||
if (Callback_PeekMessages)
|
if (Callback_PeekMessages)
|
||||||
Callback_PeekMessages();
|
Callback_PeekMessages();
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
|
||||||
ProcessXEvents();
|
|
||||||
#endif
|
|
||||||
Common::SleepCurrentThread(20);
|
Common::SleepCurrentThread(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,11 +770,15 @@ void Callback_KeyPress(int key, bool shift, bool control)
|
||||||
State_UndoLoadState();
|
State_UndoLoadState();
|
||||||
}
|
}
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
if (key == 0)
|
||||||
|
Host_Message(WM_USER_CREATE);
|
||||||
// 0x1b == VK_ESCAPE
|
// 0x1b == VK_ESCAPE
|
||||||
if (key == 0x1b)
|
if (key == 0x1b)
|
||||||
Host_Message(WM_USER_STOP);
|
Host_Message(WM_USER_STOP);
|
||||||
if (key == 0x1c)
|
if (key == 0x1c)
|
||||||
Host_Message(WM_USER_PAUSE);
|
Host_Message(WM_USER_PAUSE);
|
||||||
|
if (key == 0x1d)
|
||||||
|
Host_Message(TOGGLE_FULLSCREEN);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -523,7 +523,7 @@ void CFrame::OnQuit(wxCommandEvent& WXUNUSED (event))
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HAVE_X11 && HAVE_X11
|
#if defined HAVE_X11 && HAVE_X11
|
||||||
void X11_SendEvent(const char *message)
|
void CFrame::X11_SendClientEvent(const char *message)
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
Display *dpy = (Display *)Core::GetWindowHandle();
|
Display *dpy = (Display *)Core::GetWindowHandle();
|
||||||
|
@ -536,9 +536,24 @@ void X11_SendEvent(const char *message)
|
||||||
|
|
||||||
// Send the event
|
// Send the event
|
||||||
if (!XSendEvent(dpy, win, False, False, &event))
|
if (!XSendEvent(dpy, win, False, False, &event))
|
||||||
{
|
|
||||||
ERROR_LOG(VIDEO, "Failed to send message %s to the emulator window.\n", message);
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -547,8 +562,13 @@ void X11_SendEvent(const char *message)
|
||||||
void CFrame::OnActive(wxActivateEvent& event)
|
void CFrame::OnActive(wxActivateEvent& event)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
#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))
|
if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)
|
||||||
X11_SendEvent("WINDOW_REFOCUS");
|
{
|
||||||
|
if (event.GetActive())
|
||||||
|
X11_SendClientEvent("FOCUSIN");
|
||||||
|
else
|
||||||
|
X11_SendClientEvent("FOCUSOUT");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
@ -618,7 +638,7 @@ void CFrame::OnResizeAll(wxSizeEvent& event)
|
||||||
event.Skip();
|
event.Skip();
|
||||||
#if defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
#if defined(HAVE_X11) && HAVE_X11 && defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)
|
if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE)
|
||||||
X11_SendEvent("MAIN_RESIZED");
|
X11_SendClientEvent("RESIZE");
|
||||||
#endif
|
#endif
|
||||||
//wxWindow * Win = (wxWindow*)event.GetEventObject();
|
//wxWindow * Win = (wxWindow*)event.GetEventObject();
|
||||||
//NOTICE_LOG(CONSOLE, "OnResizeAll: %i", (HWND)Win->GetHWND());
|
//NOTICE_LOG(CONSOLE, "OnResizeAll: %i", (HWND)Win->GetHWND());
|
||||||
|
@ -675,11 +695,17 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
case WM_USER_CREATE:
|
||||||
|
bRenderToMain = true;
|
||||||
|
break;
|
||||||
|
case TOGGLE_FULLSCREEN:
|
||||||
|
DoFullscreen(!IsFullScreen());
|
||||||
|
break;
|
||||||
case WM_USER_STOP:
|
case WM_USER_STOP:
|
||||||
main_frame->DoStop();
|
DoStop();
|
||||||
break;
|
break;
|
||||||
case WM_USER_PAUSE:
|
case WM_USER_PAUSE:
|
||||||
main_frame->DoPause();
|
DoPause();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -787,8 +813,14 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode());
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Send the keyboard status to the Input plugin
|
// Send the keyboard status to the Input plugin
|
||||||
if(Core::GetState() != Core::CORE_UNINITIALIZED)
|
if(Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||||
CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down
|
CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down
|
||||||
|
@ -938,14 +970,12 @@ wxAuiNotebook* CFrame::CreateEmptyNotebook()
|
||||||
|
|
||||||
void CFrame::DoFullscreen(bool bF)
|
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
|
// 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
|
// 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.
|
// 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))
|
||||||
|
{
|
||||||
|
if (bRenderToMain)
|
||||||
{
|
{
|
||||||
ShowFullScreen(bF);
|
ShowFullScreen(bF);
|
||||||
|
|
||||||
|
@ -961,13 +991,13 @@ void CFrame::DoFullscreen(bool bF)
|
||||||
m_Mgr->LoadPerspective(AuiCurrent, true);
|
m_Mgr->LoadPerspective(AuiCurrent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
// Show the cursor again, in case it was hidden
|
// Show the cursor again, in case it was hidden
|
||||||
if (IsFullScreen())
|
if (IsFullScreen())
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
MSWSetCursor(true);
|
MSWSetCursor(true);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
else // Post the message to the separate rendering window which will then handle it.
|
else // Post the message to the separate rendering window which will then handle it.
|
||||||
|
@ -975,8 +1005,12 @@ void CFrame::DoFullscreen(bool bF)
|
||||||
BringWindowToTop((HWND)Core::GetWindowHandle());
|
BringWindowToTop((HWND)Core::GetWindowHandle());
|
||||||
PostMessage((HWND)Core::GetWindowHandle(), WM_USER, TOGGLE_FULLSCREEN, 0);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Debugging, show loose windows
|
// Debugging, show loose windows
|
||||||
void CFrame::ListChildren()
|
void CFrame::ListChildren()
|
||||||
|
|
|
@ -303,6 +303,9 @@ class CFrame : public wxFrame
|
||||||
|
|
||||||
void OnGameListCtrl_ItemActivated(wxListEvent& event);
|
void OnGameListCtrl_ItemActivated(wxListEvent& event);
|
||||||
void DoFullscreen(bool _F);
|
void DoFullscreen(bool _F);
|
||||||
|
#if defined HAVE_X11 && HAVE_X11
|
||||||
|
void X11_SendClientEvent(const char *message);
|
||||||
|
#endif
|
||||||
|
|
||||||
// MenuBar
|
// MenuBar
|
||||||
// File - Drive
|
// File - Drive
|
||||||
|
|
|
@ -629,17 +629,12 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
|
||||||
wxThread::Sleep(20);
|
wxThread::Sleep(20);
|
||||||
g_pCodeWindow->JumpToAddress(PC);
|
g_pCodeWindow->JumpToAddress(PC);
|
||||||
g_pCodeWindow->Update();
|
g_pCodeWindow->Update();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Core::GetState() == Core::CORE_RUN)
|
|
||||||
Core::SetState(Core::CORE_PAUSE);
|
|
||||||
else
|
|
||||||
Core::SetState(Core::CORE_RUN);
|
|
||||||
}
|
|
||||||
// Update toolbar with Play/Pause status
|
// Update toolbar with Play/Pause status
|
||||||
UpdateGUI();
|
UpdateGUI();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
DoPause();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
// Core is uninitialized, start the game
|
// Core is uninitialized, start the game
|
||||||
StartGame(std::string(""));
|
StartGame(std::string(""));
|
||||||
|
@ -692,9 +687,19 @@ void CFrame::OnScreenshot(wxCommandEvent& WXUNUSED (event))
|
||||||
void CFrame::DoPause()
|
void CFrame::DoPause()
|
||||||
{
|
{
|
||||||
if (Core::GetState() == Core::CORE_RUN)
|
if (Core::GetState() == Core::CORE_RUN)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
X11_SendClientEvent("PAUSE");
|
||||||
|
#endif
|
||||||
Core::SetState(Core::CORE_PAUSE);
|
Core::SetState(Core::CORE_PAUSE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
X11_SendClientEvent("RESUME");
|
||||||
|
#endif
|
||||||
Core::SetState(Core::CORE_RUN);
|
Core::SetState(Core::CORE_RUN);
|
||||||
|
}
|
||||||
UpdateGUI();
|
UpdateGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -533,6 +533,8 @@ void Host_Message(int Id)
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
switch(Id)
|
switch(Id)
|
||||||
{
|
{
|
||||||
|
case WM_USER_CREATE:
|
||||||
|
case TOGGLE_FULLSCREEN:
|
||||||
case WM_USER_STOP:
|
case WM_USER_STOP:
|
||||||
case WM_USER_PAUSE:
|
case WM_USER_PAUSE:
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,9 @@ typedef struct
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
#if defined HAVE_X11 && HAVE_X11
|
#if defined HAVE_X11 && HAVE_X11
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2
|
||||||
|
void *pPanel;
|
||||||
|
#endif
|
||||||
void *pXWindow;
|
void *pXWindow;
|
||||||
#endif
|
#endif
|
||||||
TLog pLog;
|
TLog pLog;
|
||||||
|
|
|
@ -72,6 +72,9 @@ typedef struct
|
||||||
{
|
{
|
||||||
void *pWindowHandle;
|
void *pWindowHandle;
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2
|
||||||
|
void *pPanel;
|
||||||
|
#endif
|
||||||
void *pXWindow;
|
void *pXWindow;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@ typedef struct
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
#if defined HAVE_X11 && HAVE_X11
|
#if defined HAVE_X11 && HAVE_X11
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2
|
||||||
|
void *pPanel;
|
||||||
|
#endif
|
||||||
void *pXWindow;
|
void *pXWindow;
|
||||||
#endif
|
#endif
|
||||||
u32 ISOId;
|
u32 ISOId;
|
||||||
|
|
|
@ -658,12 +658,14 @@ bool IsFocus()
|
||||||
return false;
|
return false;
|
||||||
#elif defined HAVE_X11 && HAVE_X11
|
#elif defined HAVE_X11 && HAVE_X11
|
||||||
Window GLWin = *(Window *)g_PADInitialize->pXWindow;
|
Window GLWin = *(Window *)g_PADInitialize->pXWindow;
|
||||||
|
bool bFocus = False;
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
bFocus = (wxPanel *)g_PADInitialize->pPanel == wxWindow::FindFocus();
|
||||||
|
#endif
|
||||||
Window FocusWin;
|
Window FocusWin;
|
||||||
int Revert;
|
int Revert;
|
||||||
XGetInputFocus(GCdisplay, &FocusWin, &Revert);
|
XGetInputFocus(GCdisplay, &FocusWin, &Revert);
|
||||||
XWindowAttributes WinAttribs;
|
return (GLWin == FocusWin || bFocus);
|
||||||
XGetWindowAttributes (GCdisplay, GLWin, &WinAttribs);
|
|
||||||
return (GLWin != 0 && (GLWin == FocusWin || WinAttribs.override_redirect));
|
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -118,43 +118,61 @@ void UpdateFPSDisplay(const char *text)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
|
THREAD_RETURN XEventThread(void *pArg);
|
||||||
|
|
||||||
|
void X11_EWMH_Fullscreen(int action)
|
||||||
|
{
|
||||||
|
assert(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD
|
||||||
|
|| action == _NET_WM_STATE_TOGGLE);
|
||||||
|
|
||||||
|
// Init X event structure for _NET_WM_STATE_FULLSCREEN client message
|
||||||
|
XEvent event;
|
||||||
|
event.xclient.type = ClientMessage;
|
||||||
|
event.xclient.message_type = XInternAtom(GLWin.dpy, "_NET_WM_STATE", False);
|
||||||
|
event.xclient.window = GLWin.win;
|
||||||
|
event.xclient.format = 32;
|
||||||
|
event.xclient.data.l[0] = action;
|
||||||
|
event.xclient.data.l[1] = XInternAtom(GLWin.dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
|
|
||||||
|
// Send the event
|
||||||
|
if (!XSendEvent(GLWin.dpy, DefaultRootWindow(GLWin.dpy), False,
|
||||||
|
SubstructureRedirectMask | SubstructureNotifyMask, &event))
|
||||||
|
ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode.\n");
|
||||||
|
}
|
||||||
|
|
||||||
void CreateXWindow (void)
|
void CreateXWindow (void)
|
||||||
{
|
{
|
||||||
Atom wmProtocols[2];
|
Atom wmProtocols[3];
|
||||||
Window parent = RootWindow(GLWin.dpy, GLWin.vi->screen);
|
Window parent;
|
||||||
GLWin.x = 0;
|
|
||||||
GLWin.y = 0;
|
|
||||||
|
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
wxMutexGuiEnter();
|
wxMutexGuiEnter();
|
||||||
#endif
|
#endif
|
||||||
if (GLWin.fs)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
if (GLWin.fullSize >= 0)
|
if (GLWin.fs
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
&& !g_Config.RenderToMainframe
|
||||||
|
#endif
|
||||||
|
)
|
||||||
XRRSetScreenConfig(GLWin.dpy, GLWin.screenConfig, RootWindow(GLWin.dpy, GLWin.screen),
|
XRRSetScreenConfig(GLWin.dpy, GLWin.screenConfig, RootWindow(GLWin.dpy, GLWin.screen),
|
||||||
GLWin.fullSize, GLWin.screenRotation, CurrentTime);
|
GLWin.fullSize, GLWin.screenRotation, CurrentTime);
|
||||||
#endif
|
#endif
|
||||||
GLWin.attr.override_redirect = True;
|
|
||||||
GLWin.width = GLWin.fullWidth;
|
|
||||||
GLWin.height = GLWin.fullHeight;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GLWin.attr.override_redirect = False;
|
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
if (g_Config.RenderToMainframe)
|
if (g_Config.RenderToMainframe)
|
||||||
{
|
{
|
||||||
GLWin.panel->GetSize((int *)&GLWin.width, (int *)&GLWin.height);
|
GLWin.panel->GetSize((int *)&GLWin.width, (int *)&GLWin.height);
|
||||||
GLWin.panel->GetPosition(&GLWin.x, &GLWin.y);
|
GLWin.panel->GetPosition(&GLWin.x, &GLWin.y);
|
||||||
parent = GDK_WINDOW_XID(GTK_WIDGET(GLWin.panel->GetHandle())->window);
|
parent = GDK_WINDOW_XID(GTK_WIDGET(GLWin.panel->GetHandle())->window);
|
||||||
|
GLWin.panel->SetFocus();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
GLWin.x = 0;
|
||||||
|
GLWin.y = 0;
|
||||||
GLWin.width = GLWin.winWidth;
|
GLWin.width = GLWin.winWidth;
|
||||||
GLWin.height = GLWin.winHeight;
|
GLWin.height = GLWin.winHeight;
|
||||||
}
|
parent = RootWindow(GLWin.dpy, GLWin.vi->screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Control window size and picture scaling
|
// Control window size and picture scaling
|
||||||
|
@ -164,28 +182,18 @@ void CreateXWindow (void)
|
||||||
// create the window
|
// create the window
|
||||||
GLWin.win = XCreateWindow(GLWin.dpy, parent,
|
GLWin.win = XCreateWindow(GLWin.dpy, parent,
|
||||||
GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual,
|
GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual,
|
||||||
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &GLWin.attr);
|
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
|
||||||
wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
|
wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
|
||||||
wmProtocols[1] = XInternAtom(GLWin.dpy, "WM_TAKE_FOCUS", True);
|
wmProtocols[1] = XInternAtom(GLWin.dpy, "_NET_WM_STATE", False);
|
||||||
XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 2);
|
wmProtocols[2] = XInternAtom(GLWin.dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
|
XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 3);
|
||||||
XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL);
|
XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL);
|
||||||
XMapRaised(GLWin.dpy, GLWin.win);
|
XMapRaised(GLWin.dpy, GLWin.win);
|
||||||
if (GLWin.fs)
|
|
||||||
{
|
|
||||||
XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
||||||
XGrabPointer(GLWin.dpy, GLWin.win, True, NULL,
|
|
||||||
GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
|
|
||||||
}
|
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
|
||||||
if (GLWin.fs || g_Config.RenderToMainframe)
|
|
||||||
#else
|
|
||||||
if (GLWin.fs)
|
|
||||||
#endif
|
|
||||||
XSetInputFocus(GLWin.dpy, GLWin.win, RevertToPointerRoot, CurrentTime);
|
|
||||||
XSync(GLWin.dpy, True);
|
XSync(GLWin.dpy, True);
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
wxMutexGuiLeave();
|
wxMutexGuiLeave();
|
||||||
#endif
|
#endif
|
||||||
|
GLWin.xEventThread = new Common::Thread(XEventThread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyXWindow(void)
|
void DestroyXWindow(void)
|
||||||
|
@ -200,25 +208,189 @@ void DestroyXWindow(void)
|
||||||
/* switch back to original desktop resolution if we were in fullscreen */
|
/* switch back to original desktop resolution if we were in fullscreen */
|
||||||
if( GLWin.fs )
|
if( GLWin.fs )
|
||||||
{
|
{
|
||||||
XUngrabKeyboard (GLWin.dpy, CurrentTime);
|
|
||||||
XUngrabPointer (GLWin.dpy, CurrentTime);
|
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
if (GLWin.fullSize >= 0)
|
|
||||||
XRRSetScreenConfig(GLWin.dpy, GLWin.screenConfig, RootWindow(GLWin.dpy, GLWin.screen),
|
XRRSetScreenConfig(GLWin.dpy, GLWin.screenConfig, RootWindow(GLWin.dpy, GLWin.screen),
|
||||||
GLWin.deskSize, GLWin.screenRotation, CurrentTime);
|
GLWin.deskSize, GLWin.screenRotation, CurrentTime);
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
if (!g_Config.RenderToMainframe)
|
||||||
|
#endif
|
||||||
|
X11_EWMH_Fullscreen(_NET_WM_STATE_REMOVE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
XUndefineCursor(GLWin.dpy, GLWin.win);
|
XUndefineCursor(GLWin.dpy, GLWin.win);
|
||||||
XUnmapWindow(GLWin.dpy, GLWin.win);
|
XUnmapWindow(GLWin.dpy, GLWin.win);
|
||||||
XSync(GLWin.dpy, True);
|
GLWin.win = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleFullscreenMode (void)
|
void ToggleFullscreenMode (void)
|
||||||
{
|
{
|
||||||
DestroyXWindow();
|
|
||||||
GLWin.fs = !GLWin.fs;
|
GLWin.fs = !GLWin.fs;
|
||||||
CreateXWindow();
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
OpenGL_MakeCurrent();
|
if (GLWin.fs)
|
||||||
|
XRRSetScreenConfig(GLWin.dpy, GLWin.screenConfig, RootWindow(GLWin.dpy, GLWin.screen),
|
||||||
|
GLWin.fullSize, GLWin.screenRotation, CurrentTime);
|
||||||
|
else
|
||||||
|
XRRSetScreenConfig(GLWin.dpy, GLWin.screenConfig, RootWindow(GLWin.dpy, GLWin.screen),
|
||||||
|
GLWin.deskSize, GLWin.screenRotation, CurrentTime);
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
if (!g_Config.RenderToMainframe)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
X11_EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
|
||||||
|
XRaiseWindow(GLWin.dpy, GLWin.win);
|
||||||
|
XSetInputFocus(GLWin.dpy, GLWin.win, RevertToPointerRoot, CurrentTime);
|
||||||
|
}
|
||||||
|
XSync(GLWin.dpy, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
THREAD_RETURN XEventThread(void *pArg)
|
||||||
|
{
|
||||||
|
bool bPaused = False;
|
||||||
|
while (GLWin.win)
|
||||||
|
{
|
||||||
|
XEvent event;
|
||||||
|
KeySym key;
|
||||||
|
int num_events;
|
||||||
|
for (num_events = XPending(GLWin.dpy);num_events > 0;num_events--) {
|
||||||
|
XNextEvent(GLWin.dpy, &event);
|
||||||
|
switch(event.type) {
|
||||||
|
case KeyPress:
|
||||||
|
key = XLookupKeysym((XKeyEvent*)&event, 0);
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case XK_F1: case XK_F2: case XK_F3: case XK_F4: case XK_F5: case XK_F6:
|
||||||
|
case XK_F7: case XK_F8: case XK_F9: case XK_F11: case XK_F12:
|
||||||
|
g_VideoInitialize.pKeyPress(key - 0xff4e,
|
||||||
|
event.xkey.state & ShiftMask,
|
||||||
|
event.xkey.state & ControlMask);
|
||||||
|
break;
|
||||||
|
case XK_Escape:
|
||||||
|
if (GLWin.fs && !bPaused)
|
||||||
|
{
|
||||||
|
printf("toggling fullscreen\n");
|
||||||
|
ToggleFullscreenMode();
|
||||||
|
}
|
||||||
|
g_VideoInitialize.pKeyPress(0x1c, False, False);
|
||||||
|
break;
|
||||||
|
case XK_Return:
|
||||||
|
if (event.xkey.state & Mod1Mask)
|
||||||
|
ToggleFullscreenMode();
|
||||||
|
break;
|
||||||
|
case XK_3:
|
||||||
|
OSDChoice = 1;
|
||||||
|
// Toggle native resolution
|
||||||
|
if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
|
||||||
|
g_Config.bNativeResolution = true;
|
||||||
|
else if (g_Config.bNativeResolution && Renderer::AllowCustom())
|
||||||
|
{ g_Config.bNativeResolution = false; if (Renderer::Allow2x()) {g_Config.b2xResolution = true;} }
|
||||||
|
else if (Renderer::AllowCustom())
|
||||||
|
g_Config.b2xResolution = false;
|
||||||
|
break;
|
||||||
|
case XK_4:
|
||||||
|
OSDChoice = 2;
|
||||||
|
// Toggle aspect ratio
|
||||||
|
g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
|
||||||
|
break;
|
||||||
|
case XK_5:
|
||||||
|
OSDChoice = 3;
|
||||||
|
// Toggle EFB copy
|
||||||
|
if (g_Config.bEFBCopyDisable || g_Config.bCopyEFBToTexture)
|
||||||
|
{
|
||||||
|
g_Config.bEFBCopyDisable = !g_Config.bEFBCopyDisable;
|
||||||
|
g_Config.bCopyEFBToTexture = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XK_6:
|
||||||
|
OSDChoice = 4;
|
||||||
|
g_Config.bDisableFog = !g_Config.bDisableFog;
|
||||||
|
break;
|
||||||
|
case XK_7:
|
||||||
|
OSDChoice = 5;
|
||||||
|
g_Config.bDisableLighting = !g_Config.bDisableLighting;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FocusIn:
|
||||||
|
if (g_Config.bHideCursor && !bPaused
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
&& !g_Config.RenderToMainframe
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
XDefineCursor(GLWin.dpy, GLWin.win, GLWin.blankCursor);
|
||||||
|
break;
|
||||||
|
case FocusOut:
|
||||||
|
if (g_Config.bHideCursor && !bPaused
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
&& !g_Config.RenderToMainframe
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
XUndefineCursor(GLWin.dpy, GLWin.win);
|
||||||
|
break;
|
||||||
|
case ConfigureNotify:
|
||||||
|
Window winDummy;
|
||||||
|
unsigned int borderDummy;
|
||||||
|
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
|
||||||
|
&GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
|
||||||
|
s_backbuffer_width = GLWin.width;
|
||||||
|
s_backbuffer_height = GLWin.height;
|
||||||
|
// Save windowed mode size for return from fullscreen
|
||||||
|
if (!GLWin.fs)
|
||||||
|
{
|
||||||
|
GLWin.winWidth = GLWin.width;
|
||||||
|
GLWin.winHeight = GLWin.height;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClientMessage:
|
||||||
|
if ((ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False))
|
||||||
|
g_VideoInitialize.pKeyPress(0x1b, False, False);
|
||||||
|
if ((ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "TOGGLE_FULLSCREEN", False))
|
||||||
|
ToggleFullscreenMode();
|
||||||
|
if (g_Config.bHideCursor &&
|
||||||
|
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "PAUSE", False))
|
||||||
|
{
|
||||||
|
bPaused = True;
|
||||||
|
XUndefineCursor(GLWin.dpy, GLWin.win);
|
||||||
|
}
|
||||||
|
if (g_Config.bHideCursor &&
|
||||||
|
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "RESUME", False))
|
||||||
|
{
|
||||||
|
bPaused = False;
|
||||||
|
XDefineCursor(GLWin.dpy, GLWin.win, GLWin.blankCursor);
|
||||||
|
}
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
if (g_Config.RenderToMainframe &&
|
||||||
|
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "RESIZE", False))
|
||||||
|
{
|
||||||
|
GLWin.panel->GetSize((int *)&GLWin.width, (int *)&GLWin.height);
|
||||||
|
GLWin.panel->GetPosition(&GLWin.x, &GLWin.y);
|
||||||
|
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height);
|
||||||
|
}
|
||||||
|
if (g_Config.RenderToMainframe &&
|
||||||
|
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "FOCUSIN", False))
|
||||||
|
{
|
||||||
|
GLWin.panel->SetFocus();
|
||||||
|
if (g_Config.bHideCursor)
|
||||||
|
XDefineCursor(GLWin.dpy, GLWin.win, GLWin.blankCursor);
|
||||||
|
}
|
||||||
|
if (g_Config.RenderToMainframe && g_Config.bHideCursor &&
|
||||||
|
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "FOCUSOUT", False))
|
||||||
|
XUndefineCursor(GLWin.dpy, GLWin.win);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Common::SleepCurrentThread(20);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -396,7 +568,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
|
|
||||||
GLWin.dpy = XOpenDisplay(0);
|
GLWin.dpy = XOpenDisplay(0);
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
GLWin.panel = (wxPanel *)g_VideoInitialize.pWindowHandle;
|
GLWin.panel = (wxPanel *)g_VideoInitialize.pPanel;
|
||||||
#endif
|
#endif
|
||||||
g_VideoInitialize.pWindowHandle = (Display *)GLWin.dpy;
|
g_VideoInitialize.pWindowHandle = (Display *)GLWin.dpy;
|
||||||
GLWin.screen = DefaultScreen(GLWin.dpy);
|
GLWin.screen = DefaultScreen(GLWin.dpy);
|
||||||
|
@ -426,9 +598,11 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
exit(0); // TODO: Don't bring down entire Emu
|
exit(0); // TODO: Don't bring down entire Emu
|
||||||
}
|
}
|
||||||
// Create a color map and set the event masks
|
// Create a color map and set the event masks
|
||||||
GLWin.attr.colormap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, GLWin.vi->screen), GLWin.vi->visual, AllocNone);
|
GLWin.attr.colormap = XCreateColormap(GLWin.dpy,
|
||||||
|
RootWindow(GLWin.dpy, GLWin.vi->screen), GLWin.vi->visual, AllocNone);
|
||||||
GLWin.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
|
GLWin.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
|
||||||
StructureNotifyMask | ResizeRedirectMask;
|
StructureNotifyMask | ResizeRedirectMask;
|
||||||
|
GLWin.attr.background_pixel = BlackPixel(GLWin.dpy, GLWin.screen);
|
||||||
GLWin.attr.border_pixel = 0;
|
GLWin.attr.border_pixel = 0;
|
||||||
XkbSetDetectableAutoRepeat(GLWin.dpy, True, NULL);
|
XkbSetDetectableAutoRepeat(GLWin.dpy, True, NULL);
|
||||||
|
|
||||||
|
@ -483,6 +657,11 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
GLWin.fullHeight = DisplayHeight(GLWin.dpy, GLWin.screen);
|
GLWin.fullHeight = DisplayHeight(GLWin.dpy, GLWin.screen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
if (g_Config.RenderToMainframe)
|
||||||
|
g_VideoInitialize.pKeyPress(0, False, False);
|
||||||
|
#endif
|
||||||
|
|
||||||
CreateXWindow();
|
CreateXWindow();
|
||||||
g_VideoInitialize.pXWindow = (Window *) &GLWin.win;
|
g_VideoInitialize.pXWindow = (Window *) &GLWin.win;
|
||||||
|
|
||||||
|
@ -525,6 +704,19 @@ bool OpenGL_MakeCurrent()
|
||||||
ERROR_LOG(VIDEO, "no Direct Rendering possible!");
|
ERROR_LOG(VIDEO, "no Direct Rendering possible!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GLWin.fs)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
if (g_Config.RenderToMainframe)
|
||||||
|
{
|
||||||
|
GLWin.fs = False;
|
||||||
|
g_VideoInitialize.pKeyPress(0x1d, False, False);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
X11_EWMH_Fullscreen(_NET_WM_STATE_ADD);
|
||||||
|
}
|
||||||
|
|
||||||
// Hide the cursor now
|
// Hide the cursor now
|
||||||
if (g_Config.bHideCursor)
|
if (g_Config.bHideCursor)
|
||||||
XDefineCursor (GLWin.dpy, GLWin.win, GLWin.blankCursor);
|
XDefineCursor (GLWin.dpy, GLWin.win, GLWin.blankCursor);
|
||||||
|
@ -581,134 +773,6 @@ void OpenGL_Update()
|
||||||
s_backbuffer_height = height;
|
s_backbuffer_height = height;
|
||||||
|
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
// We just check all of our events here
|
|
||||||
XEvent event;
|
|
||||||
KeySym key;
|
|
||||||
int num_events;
|
|
||||||
for (num_events = XPending(GLWin.dpy);num_events > 0;num_events--) {
|
|
||||||
XNextEvent(GLWin.dpy, &event);
|
|
||||||
switch(event.type) {
|
|
||||||
case KeyPress:
|
|
||||||
key = XLookupKeysym((XKeyEvent*)&event, 0);
|
|
||||||
switch (key)
|
|
||||||
{
|
|
||||||
case XK_F4:
|
|
||||||
if(event.xkey.state & Mod1Mask)
|
|
||||||
{
|
|
||||||
g_VideoInitialize.pKeyPress(0x1b, False, False);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XK_F1: case XK_F2: case XK_F3: case XK_F5:
|
|
||||||
case XK_F6: case XK_F7: case XK_F8: case XK_F9:
|
|
||||||
g_VideoInitialize.pKeyPress(key - 0xff4e,
|
|
||||||
event.xkey.state & ShiftMask,
|
|
||||||
event.xkey.state & ControlMask);
|
|
||||||
break;
|
|
||||||
case XK_Escape:
|
|
||||||
if (GLWin.fs)
|
|
||||||
{
|
|
||||||
ToggleFullscreenMode();
|
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
|
||||||
if (!g_Config.RenderToMainframe)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
XEvent mapevent;
|
|
||||||
do {
|
|
||||||
XMaskEvent(GLWin.dpy, StructureNotifyMask, &mapevent);
|
|
||||||
} while ((mapevent.type != MapNotify) || (mapevent.xmap.event != GLWin.win));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_VideoInitialize.pKeyPress(0x1c, False, False);
|
|
||||||
break;
|
|
||||||
case XK_Return:
|
|
||||||
if (event.xkey.state & Mod1Mask)
|
|
||||||
ToggleFullscreenMode();
|
|
||||||
break;
|
|
||||||
case XK_3:
|
|
||||||
OSDChoice = 1;
|
|
||||||
// Toggle native resolution
|
|
||||||
if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
|
|
||||||
g_Config.bNativeResolution = true;
|
|
||||||
else if (g_Config.bNativeResolution && Renderer::AllowCustom())
|
|
||||||
{ g_Config.bNativeResolution = false; if (Renderer::Allow2x()) {g_Config.b2xResolution = true;} }
|
|
||||||
else if (Renderer::AllowCustom())
|
|
||||||
g_Config.b2xResolution = false;
|
|
||||||
break;
|
|
||||||
case XK_4:
|
|
||||||
OSDChoice = 2;
|
|
||||||
// Toggle aspect ratio
|
|
||||||
g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
|
|
||||||
break;
|
|
||||||
case XK_5:
|
|
||||||
OSDChoice = 3;
|
|
||||||
// Toggle EFB copy
|
|
||||||
if (g_Config.bEFBCopyDisable || g_Config.bCopyEFBToTexture)
|
|
||||||
{
|
|
||||||
g_Config.bEFBCopyDisable = !g_Config.bEFBCopyDisable;
|
|
||||||
g_Config.bCopyEFBToTexture = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case XK_6:
|
|
||||||
OSDChoice = 4;
|
|
||||||
g_Config.bDisableFog = !g_Config.bDisableFog;
|
|
||||||
break;
|
|
||||||
case XK_7:
|
|
||||||
OSDChoice = 5;
|
|
||||||
g_Config.bDisableLighting = !g_Config.bDisableLighting;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FocusIn:
|
|
||||||
if (g_Config.bHideCursor)
|
|
||||||
XDefineCursor(GLWin.dpy, GLWin.win, GLWin.blankCursor);
|
|
||||||
break;
|
|
||||||
case FocusOut:
|
|
||||||
if (g_Config.bHideCursor && !GLWin.fs)
|
|
||||||
XUndefineCursor(GLWin.dpy, GLWin.win);
|
|
||||||
break;
|
|
||||||
case ConfigureNotify:
|
|
||||||
Window winDummy;
|
|
||||||
unsigned int borderDummy;
|
|
||||||
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
|
|
||||||
&GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
|
|
||||||
s_backbuffer_width = GLWin.width;
|
|
||||||
s_backbuffer_height = GLWin.height;
|
|
||||||
// Save windowed mode size for return from fullscreen
|
|
||||||
if (!GLWin.fs)
|
|
||||||
{
|
|
||||||
GLWin.winWidth = GLWin.width;
|
|
||||||
GLWin.winHeight = GLWin.height;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClientMessage:
|
|
||||||
if ((ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False))
|
|
||||||
g_VideoInitialize.pKeyPress(0x1b, False, False);
|
|
||||||
if ((ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "TOGGLE_FULLSCREEN", False))
|
|
||||||
ToggleFullscreenMode();
|
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
|
||||||
if (g_Config.RenderToMainframe && !GLWin.fs &&
|
|
||||||
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "MAIN_RESIZED", False))
|
|
||||||
{
|
|
||||||
GLWin.panel->GetSize((int *)&GLWin.width, (int *)&GLWin.height);
|
|
||||||
GLWin.panel->GetPosition(&GLWin.x, &GLWin.y);
|
|
||||||
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height);
|
|
||||||
}
|
|
||||||
if (g_Config.RenderToMainframe && !GLWin.fs &&
|
|
||||||
(ulong) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "WINDOW_REFOCUS", False))
|
|
||||||
XSetInputFocus(GLWin.dpy, GLWin.win, RevertToPointerRoot, CurrentTime);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,6 +812,9 @@ void OpenGL_Shutdown()
|
||||||
}
|
}
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
DestroyXWindow();
|
DestroyXWindow();
|
||||||
|
if (GLWin.xEventThread)
|
||||||
|
GLWin.xEventThread->WaitForDeath();
|
||||||
|
GLWin.xEventThread = NULL;
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
if (GLWin.fullSize >= 0)
|
if (GLWin.fullSize >= 0)
|
||||||
XRRFreeScreenConfigInfo(GLWin.screenConfig);
|
XRRFreeScreenConfigInfo(GLWin.screenConfig);
|
||||||
|
|
|
@ -31,14 +31,14 @@
|
||||||
#include <GLew/gl.h>
|
#include <GLew/gl.h>
|
||||||
#include <GLew/glext.h>
|
#include <GLew/glext.h>
|
||||||
|
|
||||||
#else // linux basic definitions
|
#else // linux and apple basic definitions
|
||||||
|
|
||||||
#if defined(USE_WX) && USE_WX
|
#if defined(USE_WX) && USE_WX
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "wx/wx.h"
|
#include "wx/wx.h"
|
||||||
#include "wx/glcanvas.h"
|
#include "wx/glcanvas.h"
|
||||||
|
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
#define I_NEED_OS2_H // HAXXOR
|
|
||||||
#include <GL/glxew.h>
|
#include <GL/glxew.h>
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
#if defined(HAVE_GTK2) && HAVE_GTK2 // Needed for render to main
|
#if defined(HAVE_GTK2) && HAVE_GTK2 // Needed for render to main
|
||||||
|
@ -46,9 +46,23 @@
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#include "Thread.h"
|
||||||
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#endif // XRANDR
|
||||||
|
// EWMH state actions, see
|
||||||
|
// http://freedesktop.org/wiki/Specifications/wm-spec?action=show&redirect=Standards%2Fwm-spec
|
||||||
|
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||||
|
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||||
|
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
|
||||||
|
|
||||||
#elif defined(USE_SDL) && USE_SDL
|
#elif defined(USE_SDL) && USE_SDL
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#elif defined(HAVE_COCOA) && HAVE_COCOA
|
#elif defined(HAVE_COCOA) && HAVE_COCOA
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "cocoaGL.h"
|
#include "cocoaGL.h"
|
||||||
|
@ -70,15 +84,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
|
||||||
#include <X11/extensions/Xrandr.h>
|
|
||||||
#endif // XRANDR
|
|
||||||
#endif // X11
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -102,6 +107,7 @@ typedef struct {
|
||||||
Bool doubleBuffered;
|
Bool doubleBuffered;
|
||||||
int fullWidth, fullHeight;
|
int fullWidth, fullHeight;
|
||||||
int winWidth, winHeight;
|
int winWidth, winHeight;
|
||||||
|
Common::Thread *xEventThread;
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
XRRScreenConfiguration *screenConfig;
|
XRRScreenConfiguration *screenConfig;
|
||||||
Rotation screenRotation;
|
Rotation screenRotation;
|
||||||
|
|
|
@ -397,12 +397,14 @@ bool IsFocus()
|
||||||
return false;
|
return false;
|
||||||
#elif defined HAVE_X11 && HAVE_X11
|
#elif defined HAVE_X11 && HAVE_X11
|
||||||
Window GLWin = *(Window *)g_WiimoteInitialize.pXWindow;
|
Window GLWin = *(Window *)g_WiimoteInitialize.pXWindow;
|
||||||
|
bool bFocus = False;
|
||||||
|
#if defined(HAVE_GTK2) && HAVE_GTK2 && defined(wxGTK)
|
||||||
|
bFocus = (wxPanel *)g_WiimoteInitialize.pPanel == wxWindow::FindFocus();
|
||||||
|
#endif
|
||||||
Window FocusWin;
|
Window FocusWin;
|
||||||
int Revert;
|
int Revert;
|
||||||
XGetInputFocus(WMdisplay, &FocusWin, &Revert);
|
XGetInputFocus(WMdisplay, &FocusWin, &Revert);
|
||||||
XWindowAttributes WinAttribs;
|
return (GLWin == FocusWin || bFocus);
|
||||||
XGetWindowAttributes (WMdisplay, GLWin, &WinAttribs);
|
|
||||||
return (GLWin != 0 && (GLWin == FocusWin || WinAttribs.override_redirect));
|
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue