mirror of https://github.com/PCSX2/pcsx2.git
GregMiscellaneous: zzogl: rework fullscreen (to be friend with the WM). Note: it is not crash free for the moment.
* use alt-enter to toggle the fullscreen mode. (toggle quickly multiple time to crash it...) I suspect need of XLockDisplay & XUnlockDisplay * escape: will quit for both mode Not yet done: * good support of fullscreen conf flag. Which is wrong for the moment. (actually may be a source of crash) * Better support of widescreen screen git-svn-id: http://pcsx2.googlecode.com/svn/branches/GregMiscellaneous@3731 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
5e8f776adb
commit
0845dffb5b
|
@ -50,8 +50,8 @@ class GLWindow
|
||||||
|
|
||||||
bool CreateVisual();
|
bool CreateVisual();
|
||||||
void GetGLXVersion();
|
void GetGLXVersion();
|
||||||
void GetGLXVidModeVersion();
|
|
||||||
void GetWindowSize();
|
void GetWindowSize();
|
||||||
|
void UpdateGrabKey();
|
||||||
#endif
|
#endif
|
||||||
bool fullScreen, doubleBuffered;
|
bool fullScreen, doubleBuffered;
|
||||||
s32 x, y;
|
s32 x, y;
|
||||||
|
@ -61,6 +61,10 @@ class GLWindow
|
||||||
void SwapGLBuffers();
|
void SwapGLBuffers();
|
||||||
bool ReleaseContext();
|
bool ReleaseContext();
|
||||||
|
|
||||||
|
#ifdef GL_X11_WINDOW
|
||||||
|
void ToggleFullscreen();
|
||||||
|
#endif
|
||||||
|
|
||||||
bool CreateWindow(void *pDisplay);
|
bool CreateWindow(void *pDisplay);
|
||||||
void CloseWindow();
|
void CloseWindow();
|
||||||
bool DisplayWindow(int _width, int _height);
|
bool DisplayWindow(int _width, int _height);
|
||||||
|
@ -68,6 +72,7 @@ class GLWindow
|
||||||
void ResizeCheck();
|
void ResizeCheck();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern GLWindow GLWin;
|
extern GLWindow GLWin;
|
||||||
|
|
||||||
#endif // GLWIN_H_INCLUDED
|
#endif // GLWIN_H_INCLUDED
|
||||||
|
|
|
@ -59,22 +59,15 @@ void GLWindow::CloseWindow()
|
||||||
conf.x = x;
|
conf.x = x;
|
||||||
conf.y = y;
|
conf.y = y;
|
||||||
SaveConfig();
|
SaveConfig();
|
||||||
|
if (!glDisplay) return;
|
||||||
|
|
||||||
/* switch back to original desktop resolution if we were in fullscreen */
|
/* switch back to original desktop resolution if we were in fullscreen */
|
||||||
if (glDisplay != NULL)
|
if (fullScreen)
|
||||||
{
|
ToggleFullscreen();
|
||||||
if (fullScreen)
|
|
||||||
{
|
|
||||||
XF86VidModeSwitchToMode(glDisplay, glScreen, &deskMode);
|
|
||||||
XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glDisplay != NULL)
|
XSync(glDisplay, False);
|
||||||
{
|
XCloseDisplay(glDisplay);
|
||||||
XCloseDisplay(glDisplay);
|
glDisplay = NULL;
|
||||||
glDisplay = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLWindow::CreateVisual()
|
bool GLWindow::CreateVisual()
|
||||||
|
@ -123,11 +116,15 @@ bool GLWindow::CreateVisual()
|
||||||
|
|
||||||
void GLWindow::GetWindowSize()
|
void GLWindow::GetWindowSize()
|
||||||
{
|
{
|
||||||
|
if (!glDisplay or !glWindow) return;
|
||||||
|
|
||||||
unsigned int borderDummy;
|
unsigned int borderDummy;
|
||||||
Window winDummy;
|
Window winDummy;
|
||||||
|
s32 xDummy;
|
||||||
|
s32 yDummy;
|
||||||
|
|
||||||
XGetGeometry(glDisplay, glWindow, &winDummy, &x, &y, &width, &height, &borderDummy, &depth);
|
XGetGeometry(glDisplay, glWindow, &winDummy, &xDummy, &yDummy, &width, &height, &borderDummy, &depth);
|
||||||
ZZLog::Error_Log("Depth %d", depth);
|
ZZLog::Error_Log("Resolution %dx%d. Depth %d bpp. Position (%d,%d)", width, height, depth, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLWindow::GetGLXVersion()
|
void GLWindow::GetGLXVersion()
|
||||||
|
@ -139,13 +136,58 @@ void GLWindow::GetGLXVersion()
|
||||||
ZZLog::Error_Log("glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
|
ZZLog::Error_Log("glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLWindow::GetGLXVidModeVersion()
|
void GLWindow::UpdateGrabKey() {
|
||||||
|
if (fullScreen) {
|
||||||
|
XGrabPointer(glDisplay, glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, glWindow, None, CurrentTime);
|
||||||
|
XGrabKeyboard(glDisplay, glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
} else {
|
||||||
|
XUngrabPointer(glDisplay, CurrentTime);
|
||||||
|
XUngrabKeyboard(glDisplay, CurrentTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _NET_WM_STATE_REMOVE 0
|
||||||
|
#define _NET_WM_STATE_ADD 1
|
||||||
|
#define _NET_WM_STATE_TOGGLE 2
|
||||||
|
|
||||||
|
void GLWindow::ToggleFullscreen()
|
||||||
{
|
{
|
||||||
int vidModeMajorVersion, vidModeMinorVersion;
|
if (!glDisplay or !glWindow) return;
|
||||||
|
|
||||||
XF86VidModeQueryVersion(glDisplay, &vidModeMajorVersion, &vidModeMinorVersion);
|
u32 mask = SubstructureRedirectMask | SubstructureNotifyMask;
|
||||||
|
// Setup a new event structure
|
||||||
|
XClientMessageEvent cme;
|
||||||
|
|
||||||
|
cme.type = ClientMessage;
|
||||||
|
cme.send_event = True;
|
||||||
|
cme.display = glDisplay;
|
||||||
|
cme.window = glWindow;
|
||||||
|
cme.message_type = XInternAtom(glDisplay, "_NET_WM_STATE", False);
|
||||||
|
cme.format = 32;
|
||||||
|
cme.data.l[0] = _NET_WM_STATE_TOGGLE;
|
||||||
|
cme.data.l[1] = (u32)XInternAtom(glDisplay, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
|
cme.data.l[2] = 0;
|
||||||
|
cme.data.l[3] = 0;
|
||||||
|
|
||||||
|
// send the event
|
||||||
|
if (!XSendEvent(glDisplay, RootWindow(glDisplay, vi->screen), False, mask, (XEvent*)(&cme)))
|
||||||
|
ZZLog::Error_Log("Failed to send event: toggle fullscreen");
|
||||||
|
else
|
||||||
|
fullScreen = (!fullScreen);
|
||||||
|
|
||||||
|
// Apply the change
|
||||||
|
XSync(glDisplay, False);
|
||||||
|
|
||||||
|
// update info structure
|
||||||
|
GetWindowSize();
|
||||||
|
|
||||||
|
// Grab key if needed
|
||||||
|
UpdateGrabKey();
|
||||||
|
|
||||||
|
// Hide the cursor in the right bottom corner
|
||||||
|
if(fullScreen)
|
||||||
|
XWarpPointer(glDisplay, None, glWindow, 0, 0, 0, 0, width, height);
|
||||||
|
|
||||||
ZZLog::Error_Log("XF86VidModeExtension-Version %d.%d.", vidModeMajorVersion, vidModeMinorVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLWindow::DisplayWindow(int _width, int _height)
|
bool GLWindow::DisplayWindow(int _width, int _height)
|
||||||
|
@ -167,95 +209,43 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
||||||
|
|
||||||
attr.colormap = cmap;
|
attr.colormap = cmap;
|
||||||
attr.border_pixel = 0;
|
attr.border_pixel = 0;
|
||||||
attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
|
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
|
||||||
|
StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask | FocusChangeMask ;
|
||||||
|
|
||||||
GetGLXVersion();
|
GetGLXVersion();
|
||||||
|
|
||||||
if (fullScreen)
|
glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen),
|
||||||
{
|
0, 0, _width, _height, 0, vi->depth, InputOutput, vi->visual,
|
||||||
int dpyWidth, dpyHeight;
|
CWBorderPixel | CWColormap | CWEventMask,
|
||||||
int modeNum = 0, bestMode = 0;
|
&attr);
|
||||||
XF86VidModeModeInfo **modes = NULL;
|
|
||||||
|
|
||||||
GetGLXVidModeVersion();
|
/* Allow to kill properly the window */
|
||||||
|
Atom wmDelete = XInternAtom(glDisplay, "WM_DELETE_WINDOW", True);
|
||||||
|
XSetWMProtocols(glDisplay, glWindow, &wmDelete, 1);
|
||||||
|
|
||||||
XF86VidModeGetAllModeLines(glDisplay, glScreen, &modeNum, &modes);
|
// Set icon name
|
||||||
|
XSetIconName(glDisplay, glWindow, "ZZogl-pg");
|
||||||
|
|
||||||
if (modeNum > 0 && modes != NULL)
|
// Draw the window
|
||||||
{
|
XMapRaised(glDisplay, glWindow);
|
||||||
/* save desktop-resolution before switching modes */
|
XSync(glDisplay, false);
|
||||||
deskMode = *modes[0];
|
|
||||||
|
|
||||||
/* look for mode with requested resolution */
|
|
||||||
|
|
||||||
for (int i = 0; i < modeNum; i++)
|
|
||||||
{
|
|
||||||
if ((modes[i]->hdisplay == _width) && (modes[i]->vdisplay == _height))
|
|
||||||
{
|
|
||||||
bestMode = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XF86VidModeSwitchToMode(glDisplay, glScreen, modes[bestMode]);
|
|
||||||
|
|
||||||
XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0);
|
|
||||||
dpyWidth = modes[bestMode]->hdisplay;
|
|
||||||
dpyHeight = modes[bestMode]->vdisplay;
|
|
||||||
ZZLog::Error_Log("Resolution %dx%d.", dpyWidth, dpyHeight);
|
|
||||||
XFree(modes);
|
|
||||||
|
|
||||||
/* create a fullscreen window */
|
|
||||||
attr.override_redirect = True;
|
|
||||||
glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen),
|
|
||||||
0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
|
|
||||||
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
|
|
||||||
&attr);
|
|
||||||
XWarpPointer(glDisplay, None, glWindow, 0, 0, 0, 0, 0, 0);
|
|
||||||
XMapRaised(glDisplay, glWindow);
|
|
||||||
XGrabKeyboard(glDisplay, glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
||||||
XGrabPointer(glDisplay, glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, glWindow, None, CurrentTime);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ZZLog::Error_Log("Failed to start fullscreen. If you received the \n"
|
|
||||||
"\"XFree86-VidModeExtension\" extension is missing, add\n"
|
|
||||||
"Load \"extmod\"\n"
|
|
||||||
"to your X configuration file (under the Module Section)");
|
|
||||||
fullScreen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fullScreen)
|
|
||||||
{
|
|
||||||
// create a window in window mode
|
|
||||||
glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen),
|
|
||||||
0, 0, _width, _height, 0, vi->depth, InputOutput, vi->visual,
|
|
||||||
CWBorderPixel | CWColormap | CWEventMask, &attr);
|
|
||||||
|
|
||||||
// only set window title and handle wm_delete_events if in windowed mode
|
|
||||||
Atom wmDelete;
|
|
||||||
wmDelete = XInternAtom(glDisplay, "WM_DELETE_WINDOW", True);
|
|
||||||
XSetWMProtocols(glDisplay, glWindow, &wmDelete, 1);
|
|
||||||
|
|
||||||
XSetStandardProperties(glDisplay, glWindow, "ZZOgl-PG", "ZZOgl-PG", None, NULL, 0, NULL);
|
|
||||||
XMapRaised(glDisplay, glWindow);
|
|
||||||
XMoveWindow(glDisplay, glWindow, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect the glx-context to the window
|
// connect the glx-context to the window
|
||||||
glXMakeCurrent(glDisplay, glWindow, context);
|
glXMakeCurrent(glDisplay, glWindow, context);
|
||||||
|
|
||||||
GetWindowSize();
|
|
||||||
|
|
||||||
if (glXIsDirect(glDisplay, context))
|
if (glXIsDirect(glDisplay, context))
|
||||||
ZZLog::Error_Log("You have Direct Rendering!");
|
ZZLog::Error_Log("You have Direct Rendering!");
|
||||||
else
|
else
|
||||||
ZZLog::Error_Log("No Direct Rendering possible!");
|
ZZLog::Error_Log("No Direct Rendering possible!");
|
||||||
|
|
||||||
// better for pad plugin key input (thc)
|
if (fullScreen) {
|
||||||
XSelectInput(glDisplay, glWindow, ExposureMask | KeyPressMask | KeyReleaseMask |
|
ToggleFullscreen();
|
||||||
ButtonPressMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask |
|
} else {
|
||||||
FocusChangeMask);
|
// Restore the window position
|
||||||
|
XMoveWindow(glDisplay, glWindow, x, y);
|
||||||
|
GetWindowSize();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -267,16 +257,16 @@ void GLWindow::SwapGLBuffers()
|
||||||
|
|
||||||
void GLWindow::SetTitle(char *strtitle)
|
void GLWindow::SetTitle(char *strtitle)
|
||||||
{
|
{
|
||||||
if (!conf.fullscreen())
|
if (!fullScreen)
|
||||||
{
|
{
|
||||||
XTextProperty prop;
|
XTextProperty prop;
|
||||||
memset(&prop, 0, sizeof(prop));
|
memset(&prop, 0, sizeof(prop));
|
||||||
char* ptitle = strtitle;
|
|
||||||
|
|
||||||
|
char* ptitle = strtitle;
|
||||||
if (XStringListToTextProperty(&ptitle, 1, &prop))
|
if (XStringListToTextProperty(&ptitle, 1, &prop))
|
||||||
XSetWMName(glDisplay, glWindow, &prop);
|
XSetWMName(glDisplay, glWindow, &prop);
|
||||||
|
|
||||||
XFree(prop.value);
|
XFree(prop.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,14 +283,17 @@ void GLWindow::ResizeCheck()
|
||||||
height = event.xconfigure.height;
|
height = event.xconfigure.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((event.xconfigure.x != x) || (event.xconfigure.y != y))
|
if (!fullScreen) {
|
||||||
{
|
if ((event.xconfigure.x != x) || (event.xconfigure.y != y))
|
||||||
// Fixme; x&y occassionally gives values near the top left corner rather then the real values,
|
{
|
||||||
// causing the window to change positions when adjusting ZZOgl's settings.
|
// Fixme; x&y occassionally gives values near the top left corner rather then the real values,
|
||||||
x = event.xconfigure.x;
|
// causing the window to change positions when adjusting ZZOgl's settings.
|
||||||
y = event.xconfigure.y;
|
x = event.xconfigure.x;
|
||||||
}
|
y = event.xconfigure.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -53,10 +53,7 @@ void CALLBACK GSkeyEvent(keyEvent *ev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XK_Escape:
|
case XK_Escape:
|
||||||
if (conf.fullscreen())
|
GSclose();
|
||||||
{
|
|
||||||
GSclose();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XK_Shift_L:
|
case XK_Shift_L:
|
||||||
|
@ -69,6 +66,10 @@ void CALLBACK GSkeyEvent(keyEvent *ev)
|
||||||
case XK_Alt_R:
|
case XK_Alt_R:
|
||||||
bAlt = true;
|
bAlt = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case XK_Return:
|
||||||
|
if (bAlt)
|
||||||
|
GLWin.ToggleFullscreen();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue