Move fullscreen display resolution control to the GUI with the rest of the fullscreen toggling code. This removes redundancy of code that was in several places through the various video plugins. Unfortunately it means the fullscreen resolution setting also had to be moved to the main configuration dialog. I am sure that will meet some resistance.

Also added a window size setting for windowed mode.

Also pulled some X11 specific code out into a separate file.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5395 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Glenn Rice
2010-04-22 04:28:34 +00:00
parent 8eb21d1bac
commit 140332c02e
30 changed files with 634 additions and 556 deletions

View File

@ -33,15 +33,9 @@
#endif
#if defined HAVE_X11 && HAVE_X11
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include "X11InputBase.h"
#include "State.h"
// 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 */
#include "X11Utils.h"
#endif
#if defined(HAVE_COCOA) && HAVE_COCOA
@ -71,52 +65,6 @@ void Host_NotifyMapLoaded(){}
void Host_ShowJitResults(unsigned int address){}
#if defined(HAVE_X11) && HAVE_X11
void X11_SendClientEvent(const char *message,
int data1 = 0, int data2 = 0, int data3 = 0, int data4 = 0)
{
XEvent event;
Display *dpy = (Display *)Core::GetWindowHandle();
Window win = *(Window *)Core::GetXWindow();
// Init X event structure for client message
event.xclient.type = ClientMessage;
event.xclient.format = 32;
event.xclient.data.l[0] = XInternAtom(dpy, message, False);
event.xclient.data.l[1] = data1;
event.xclient.data.l[2] = data2;
event.xclient.data.l[3] = data3;
event.xclient.data.l[4] = data4;
// 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_EWMH_Fullscreen(int action)
{
_assert_(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD
|| action == _NET_WM_STATE_TOGGLE);
Display *dpy = (Display *)Core::GetWindowHandle();
Window win = *(Window *)Core::GetXWindow();
// Init X event structure for _NET_WM_STATE_FULLSCREEN client message
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.message_type = XInternAtom(dpy, "_NET_WM_STATE", False);
event.xclient.window = win;
event.xclient.format = 32;
event.xclient.data.l[0] = action;
event.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
// Send the event
if (!XSendEvent(dpy, DefaultRootWindow(dpy), False,
SubstructureRedirectMask | SubstructureNotifyMask, &event))
ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode.\n");
}
#endif
Common::Event updateMainFrameEvent;
void Host_Message(int Id)
{
@ -188,6 +136,133 @@ void Host_SysMessage(const char *fmt, ...)
void Host_SetWiiMoteConnectionState(int _State) {}
#if defined(HAVE_X11) && HAVE_X11
void X11_MainLoop()
{
bool fullscreen = SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen;
while (Core::GetState() == Core::CORE_UNINITIALIZED)
updateMainFrameEvent.Wait();
Display *dpy = XOpenDisplay(0);
Window win = *(Window *)Core::GetXWindow();
XSelectInput(dpy, win, KeyPressMask | KeyReleaseMask | FocusChangeMask);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
X11Utils::XRRConfiguration *XRRConfig = new X11Utils::XRRConfiguration(dpy, win);
#endif
Cursor blankCursor = NULL;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
{
// make a blank cursor
Pixmap Blank;
XColor DummyColor;
char ZeroData[1] = {0};
Blank = XCreateBitmapFromData (dpy, win, ZeroData, 1, 1);
blankCursor = XCreatePixmapCursor(dpy, Blank, Blank, &DummyColor, &DummyColor, 0, 0);
XFreePixmap (dpy, Blank);
XDefineCursor(dpy, win, blankCursor);
}
if (fullscreen)
{
X11Utils::EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(True);
#endif
}
// The actual loop
while (running)
{
XEvent event;
KeySym key;
for (int 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)
{
if (Core::GetState() == Core::CORE_RUN)
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XUndefineCursor(dpy, win);
Core::SetState(Core::CORE_PAUSE);
}
else
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XDefineCursor(dpy, win, blankCursor);
Core::SetState(Core::CORE_RUN);
}
}
else if ((key == XK_Return) && (event.xkey.state & Mod1Mask))
{
fullscreen = !fullscreen;
X11Utils::EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(fullscreen);
#endif
}
else if (key >= XK_F1 && key <= XK_F8)
{
int slot_number = key - XK_F1 + 1;
if (event.xkey.state & ShiftMask)
State_Save(slot_number);
else
State_Load(slot_number);
}
else if (key == XK_F9)
Core::ScreenShot();
else if (key == XK_F11)
State_LoadLastSaved();
else if (key == XK_F12)
{
if (event.xkey.state & ShiftMask)
State_UndoLoadState();
else
State_UndoSaveState();
}
break;
case FocusIn:
rendererHasFocus = true;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
Core::GetState() != Core::CORE_PAUSE)
XDefineCursor(dpy, win, blankCursor);
break;
case FocusOut:
rendererHasFocus = false;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XUndefineCursor(dpy, win);
break;
}
}
if (!fullscreen)
{
Window winDummy;
unsigned int borderDummy, depthDummy;
XGetGeometry(dpy, win, &winDummy,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
&borderDummy, &depthDummy);
}
usleep(100000);
}
#if defined(HAVE_XRANDR) && HAVE_XRANDR
delete XRRConfig;
#endif
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XFreeCursor(dpy, blankCursor);
XCloseDisplay(dpy);
Core::Stop();
}
#endif
//for cocoa we need to hijack the main to get event
#if defined(HAVE_COCOA) && HAVE_COCOA
@ -322,112 +397,7 @@ int main(int argc, char* argv[])
if (BootManager::BootCore(bootFile)) //no use running the loop when booting fails
{
#if defined(HAVE_X11) && HAVE_X11
bool fullscreen = SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen;
printf("gopt here\n");
while (Core::GetState() == Core::CORE_UNINITIALIZED)
updateMainFrameEvent.Wait();
Display *dpy = XOpenDisplay(0);
Window win = *(Window *)Core::GetXWindow();
XSelectInput(dpy, win, KeyPressMask | KeyReleaseMask | FocusChangeMask);
Cursor blankCursor = NULL;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
{
// make a blank cursor
Pixmap Blank;
XColor DummyColor;
char ZeroData[1] = {0};
Blank = XCreateBitmapFromData (dpy, win, ZeroData, 1, 1);
blankCursor = XCreatePixmapCursor(dpy, Blank, Blank, &DummyColor, &DummyColor, 0, 0);
XFreePixmap (dpy, Blank);
XDefineCursor(dpy, win, blankCursor);
}
if (fullscreen)
{
X11_SendClientEvent("TOGGLE_DISPLAYMODE", fullscreen);
X11_EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
}
while (running)
{
XEvent event;
KeySym key;
for (int 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)
{
if (Core::GetState() == Core::CORE_RUN)
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XUndefineCursor(dpy, win);
Core::SetState(Core::CORE_PAUSE);
}
else
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XDefineCursor(dpy, win, blankCursor);
Core::SetState(Core::CORE_RUN);
}
}
else if ((key == XK_Return) && (event.xkey.state & Mod1Mask))
{
fullscreen = !fullscreen;
X11_SendClientEvent("TOGGLE_DISPLAYMODE", fullscreen);
X11_EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
}
else if (key >= XK_F1 && key <= XK_F8)
{
int slot_number = key - XK_F1 + 1;
if (event.xkey.state & ShiftMask)
State_Save(slot_number);
else
State_Load(slot_number);
}
else if (key == XK_F9)
Core::ScreenShot();
else if (key == XK_F11)
State_LoadLastSaved();
else if (key == XK_F12)
{
if (event.xkey.state & ShiftMask)
State_UndoLoadState();
else
State_UndoSaveState();
}
break;
case FocusIn:
rendererHasFocus = true;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
Core::GetState() != Core::CORE_PAUSE)
XDefineCursor(dpy, win, blankCursor);
break;
case FocusOut:
rendererHasFocus = false;
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XUndefineCursor(dpy, win);
break;
}
}
if (!fullscreen)
{
Window winDummy;
unsigned int borderDummy, depthDummy;
XGetGeometry(dpy, win, &winDummy,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos,
&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
&borderDummy, &depthDummy);
}
usleep(100000);
}
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
XFreeCursor(dpy, blankCursor);
XCloseDisplay(dpy);
Core::Stop();
X11_MainLoop();
#else
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
updateMainFrameEvent.Wait();