diff --git a/stepmania/src/arch/InputHandler/InputHandler_X11.cpp b/stepmania/src/arch/InputHandler/InputHandler_X11.cpp index 39cb82b697..605001b917 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_X11.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_X11.cpp @@ -126,9 +126,12 @@ void InputHandler_X11::Update(float fDeltaTime) Display *display = X11Helper::Dpy(); Window window = X11Helper::Win(); XEvent event; - if (window) - while(XCheckTypedWindowEvent(display, window, KeyPress, &event) - || XCheckTypedWindowEvent(display, window, KeyRelease, &event) ) + + if (X11Helper::Win) + while(XCheckTypedWindowEvent(X11Helper::Dpy, + X11Helper::Win, KeyPress, &event) + || XCheckTypedWindowEvent(X11Helper::Dpy, + X11Helper::Win, KeyRelease, &event) ) { LOG->Trace("key: sym %i, key %i, state %i", XLookupKeysym(&event.xkey,0), XSymToKeySym(XLookupKeysym(&event.xkey,0)), diff --git a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp index f5e8a1e7a5..b19bc66c3f 100644 --- a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp +++ b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp @@ -21,7 +21,7 @@ LowLevelWindow_X11::LowLevelWindow_X11() { RageException::Throw("Failed to establish a connection with the X server."); } - g_X11Display = X11Helper::Dpy(); + g_X11Display = X11Helper::Dpy; } LowLevelWindow_X11::~LowLevelWindow_X11() @@ -39,15 +39,12 @@ void *LowLevelWindow_X11::GetProcAddress(CString s) CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &bNewDeviceOut) { - int i; - int bpppc; // Bits per pixel per channel - int visAttribs[11]; - XVisualInfo *xvi; - XEvent ev; XSizeHints hints; - GLXContext ctxt; + XEvent ev; stack otherEvs; + int i; + // XXX: LLW_SDL allows the window to be resized. Do we really want to? hints.flags = PMinSize | PMaxSize | PBaseSize; hints.min_width = hints.max_width = hints.base_width = p.width; @@ -57,39 +54,53 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b if(!windowIsOpen || p.bpp != CurrentParams.bpp) { + int visAttribs[32]; + XVisualInfo *xvi; + GLXContext ctxt; + // Different depth, or we didn't make a window before. New context. bNewDeviceOut = true; - - bpppc = (int) ceil(p.bpp / 4.0); - visAttribs[0] = GLX_RGBA; - visAttribs[1] = GLX_DOUBLEBUFFER; - visAttribs[2] = GLX_RED_SIZE; visAttribs[3] = bpppc; - visAttribs[4] = GLX_GREEN_SIZE; visAttribs[5] = bpppc; - visAttribs[6] = GLX_BLUE_SIZE; visAttribs[7] = bpppc; - visAttribs[8] = GLX_ALPHA_SIZE; visAttribs[9] = p.bpp - - (bpppc * 3); - // Alpha gets however many bits are left... - visAttribs[10] = None; + i = 0; + ASSERT(p.bpp == 16 || p.bpp == 32); + if(p.bpp == 32) + { + visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 8; + visAttribs[i++] = GLX_GREEN_SIZE; visAttribs[i++] = 8; + visAttribs[i++] = GLX_BLUE_SIZE; visAttribs[i++] = 8; + } + else + { + visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 5; + visAttribs[i++] = GLX_GREEN_SIZE; visAttribs[i++] = 6; + visAttribs[i++] = GLX_BLUE_SIZE; visAttribs[i++] = 5; + } - xvi = glXChooseVisual(X11Helper::Dpy(), - DefaultScreen(X11Helper::Dpy() ), visAttribs); + visAttribs[i++] = GLX_DEPTH_SIZE; visAttribs[i++] = 16; + visAttribs[i++] = GLX_RGBA; + visAttribs[i++] = GLX_DOUBLEBUFFER; + + visAttribs[i++] = None; + + xvi = glXChooseVisual(X11Helper::Dpy, + DefaultScreen(X11Helper::Dpy), visAttribs); if(!xvi) { return "No visual available for that depth."; } - if(!X11Helper::MakeWindow(xvi->screen, xvi->depth, xvi->visual, - p.width, p.height) ) + // Taking a hint from SDL. + + if(!X11Helper::MakeWindow(xvi->screen, xvi->depth, xvi->visual) ) { return "Failed to create the window."; } windowIsOpen = true; - ctxt = glXCreateContext(X11Helper::Dpy(), xvi, NULL, True); + ctxt = glXCreateContext(X11Helper::Dpy, xvi, NULL, True); - glXMakeCurrent(X11Helper::Dpy(), X11Helper::Win(), ctxt); + glXMakeCurrent(X11Helper::Dpy, X11Helper::Win, ctxt); } else @@ -99,12 +110,12 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b bNewDeviceOut = false; // Remap the window to work around possible buggy WMs and/or // X servers - XUnmapWindow(X11Helper::Dpy(), X11Helper::Win() ); + XUnmapWindow(X11Helper::Dpy, X11Helper::Win); } - XSetWMNormalHints(X11Helper::Dpy(), X11Helper::Win(), &hints); + XSetWMNormalHints(X11Helper::Dpy, X11Helper::Win, &hints); - XMapWindow(X11Helper::Dpy(), X11Helper::Win() ); + XMapWindow(X11Helper::Dpy, X11Helper::Win); // HACK: Wait for the MapNotify event, without spinning and // eating CPU unnecessarily, and without smothering other @@ -113,7 +124,7 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b // after MapNotify arrives. while(true) { - XNextEvent(X11Helper::Dpy(), &ev); + XNextEvent(X11Helper::Dpy, &ev); if(ev.type == MapNotify) { break; @@ -125,7 +136,7 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b } while(!otherEvs.empty() ) { - XPutBackEvent(X11Helper::Dpy(), &otherEvs.top() ); + XPutBackEvent(X11Helper::Dpy, &otherEvs.top() ); otherEvs.pop(); } @@ -138,7 +149,11 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b void LowLevelWindow_X11::SwapBuffers() { - glXSwapBuffers(X11Helper::Dpy(), X11Helper::Win() ); + glXSwapBuffers(X11Helper::Dpy, X11Helper::Win); + // XXX HACK: I added this sleep on a strange hunch while trying to find + // the source of crippling performance issues, and suddenly + // those performance issues simply stopped... + usleep(10000); // Allows up to ~100fps } /* diff --git a/stepmania/src/archutils/Unix/X11Helper.cpp b/stepmania/src/archutils/Unix/X11Helper.cpp index 3309f52475..f6572b0e83 100644 --- a/stepmania/src/archutils/Unix/X11Helper.cpp +++ b/stepmania/src/archutils/Unix/X11Helper.cpp @@ -7,18 +7,20 @@ #include "RageLog.h" // LOG #include "RageDisplay.h" // RageDisplay +#include "RageThreads.h" // Don't make me list everything... vector pMasks; // Currently open masks -Display *pDpy = NULL; // Running X connection bool pHaveWin = false; // Do we have a window? -Window pWin; // Current window unsigned short int pCt = 0; // Number of subsystems // using the X connection +Display *X11Helper::Dpy = NULL; +Window X11Helper::Win; + int protoErrorCallback(Display *d, XErrorEvent *err) { - char errText[1024]; - XGetErrorText(d, err->error_code, errText, 1024); + char errText[512]; + XGetErrorText(d, err->error_code, errText, 512); LOG->Warn("X11 Protocol error %s (%d) has occurred, caused by request %d,%d, resource ID %d", errText, err->error_code, err->request_code, err->minor_code, err->resourceid); @@ -32,11 +34,14 @@ int protoFatalCallback(Display *d) bool X11Helper::Go() { + int i; + if(pCt == 0) { - pDpy = XOpenDisplay(0); - if(pDpy == NULL) { return false; } + Dpy = XOpenDisplay(0); + if(Dpy == NULL) { return false; } + XSetIOErrorHandler(&protoFatalCallback); XSetErrorHandler(&protoErrorCallback); } pCt++; @@ -44,21 +49,13 @@ bool X11Helper::Go() return true; } -Display *X11Helper::Dpy() -{ - return pDpy; -} - -Window& X11Helper::Win() -{ - return pWin; -} - static bool pApplyMasks() { unsigned int i; long finalMask; + LOG->Trace("X11Helper: Reapplying event masks."); + i = 0; while(i < pMasks.size() ) { @@ -66,7 +63,10 @@ static bool pApplyMasks() i++; } - if(XSelectInput(pDpy, pWin, finalMask) == 0) { return false; } + if(XSelectInput(X11Helper::Dpy, X11Helper::Win, finalMask) == 0) { return false; } + + // Sync, so that the event mask applies now. + XSync(X11Helper::Dpy, false); return true; } @@ -114,9 +114,9 @@ bool X11Helper::MakeWindow(int screenNum, int depth, Visual *visual, int width, { vector::iterator i; - if(pDpy == NULL) { return false; } + if(pCt == 0) { return false; } - if(pHaveWin) { XDestroyWindow(pDpy, pWin); pHaveWin = false; } + if(pHaveWin) { XDestroyWindow(Dpy, Win); pHaveWin = false; } XSetWindowAttributes winAttribs; @@ -131,10 +131,10 @@ bool X11Helper::MakeWindow(int screenNum, int depth, Visual *visual, int width, // XXX: Error catching/handling? - winAttribs.colormap = XCreateColormap(pDpy, RootWindow(pDpy, screenNum), + winAttribs.colormap = XCreateColormap(Dpy, RootWindow(Dpy, screenNum), visual, AllocNone); - pWin = XCreateWindow(pDpy, RootWindow(pDpy, screenNum), 0, 0, width, + Win = XCreateWindow(Dpy, RootWindow(Dpy, screenNum), 0, 0, width, height, 0, depth, InputOutput, visual, CWBorderPixel | CWColormap | CWEventMask, &winAttribs); @@ -149,7 +149,7 @@ void X11Helper::Stop() if(pCt == 0) { - XCloseDisplay(pDpy); + XCloseDisplay(Dpy); pMasks.clear(); } }