diff --git a/stepmania/src/archutils/Unix/X11Helper.cpp b/stepmania/src/archutils/Unix/X11Helper.cpp index 2277fd6d50..a7f5c42cee 100644 --- a/stepmania/src/archutils/Unix/X11Helper.cpp +++ b/stepmania/src/archutils/Unix/X11Helper.cpp @@ -1,13 +1,18 @@ #include "X11Helper.h" +#include + #include // Display, Window #include "RageDisplay.h" // RageDisplay -vector pCBacks; // Callbacks for the rendering thread -Display *pDpy; // Running X connection -Window *pWin; // Current window -unsigned short int pCt = 0; // Number of subsystems using the X connection +vector pCBacks; // Callbacks for the rendering + // thread +list pMasks; // Currently open masks +Display *pDpy; // Running X connection +Window *pWin; // Current window +unsigned short int pCt = 0; // Number of subsystems using + // the X connection bool X11Helper::Go() { @@ -26,19 +31,75 @@ Display *X11Helper::Dpy() return pDpy; } +static bool pApplyMasks() +{ + int i; + long finalMask; + + i = 0; + while(i < pMasks.size() ) + { + finalMask |= pMasks[i]; + i++; + } + + if(XSelectInput(pDpy, pWin, finalMask) == 0) { return false; } + + return true; +} + +bool X11Helper::OpenMask(long mask) +{ + pMasks.push_back(mask); + return pApplyMasks(); +} + +bool X11Helper::CloseMask(long mask) +{ + int i; + + i = 0; + while(true) + { + if(pMasks[i] == mask) + { + pMasks.erase(i); + break; + } + i++; + if(i > pMasks.size()-1) { return false; } + } + + return pApplyMasks(); +} + bool X11Helper::MakeWindow(int screenNum, int depth, Visual *visual int width=64, int height=64) { + int i; + if(dpy == NULL) { return false; } XSetWindowAttributes winAttribs; winAttribs.border_pixel = 0; - winAttribs.event_mask = StructureNotifyMask; + + // XXX: Error catching/handling? winAttribs.colormap = XCreateColorMap(pDpy, RootWindow(pDpy, screenNum), visual, AllocNone); - pWin = XCreateWindow(pDpy, RootWindow(pDpy, screenNum), 0, 0, width, height + pWin = XCreateWindow(pDpy, RootWindow(pDpy, screenNum), 0, 0, width, + height, 0, depth, InputOutput, visual, + CWBorderPixel | CWColorMap | CWEventMask, &winAttribs); + + i = 0; + while(i < pCBacks.size() ) + { + pCBacks[i](pWin); + i++; + } + + return pApplyMasks(); } bool X11Helper::Callback(Callback_t cb) @@ -55,7 +116,10 @@ void X11Helper::Stop() if(pCt == 0) { XCloseDisplay(pDpy); + pMasks.clear(); } + + return true; } /* diff --git a/stepmania/src/archutils/Unix/X11Helper.h b/stepmania/src/archutils/Unix/X11Helper.h index b7002fcdd1..cb213f8a9a 100644 --- a/stepmania/src/archutils/Unix/X11Helper.h +++ b/stepmania/src/archutils/Unix/X11Helper.h @@ -8,9 +8,11 @@ namespace X11Helper { + // All functions in here that return a bool return true on success, and + // false on failure. + // Create the connection, if necessary; otherwise do some important // internal session-tracking stuff (so you should call this anyway). - // True on success, false failure. bool Go(); // Get the current Display (connection). Behavior is undefined if you @@ -19,26 +21,28 @@ namespace X11Helper // (Re)create the window on the screen of this number with this depth, // this visual type, this width (optional -- you can resize the window - // in your callback later), and this height (optional). Returns true on - // success, false on failure. + // in your callback later), and this height (optional). bool MakeWindow(int screenNum, int depth, Visual *visual, int width=64, int height=64); // Callback type. typedef void (*Callback_t)(Window*); - // TODO: We need to manage event masks here, to keep the InputHandler - // and LowLevelWindow code separate. - + // Unmask one X event type mask thingy (XSelectInput() arg 3) on the + // current window. Masked/unmasked events will carry between windows. + bool OpenMask(long mask); + + // (Re)mask one X event type mask thingy (XSelectInput() arg 3) on the + // current window. Masked/unmasked events will carry between windows. + bool CloseMask(long mask); + // Register a callback for new windows (including the initial window). // This callback will be called with 0 if I try to create a new window, - // but fail. Returns false if for some really messed up reason it fails - // (shouldn't happen), false otherwise + // but fail. bool Callback(Callback_t cb); // Destroy the connection, if appropriate; otherwise do some important // internal session-tracking stuff (so you should call it anyway). - // True success, false failure. void Stop(); }