#include "clientGUIUtils.h" #include #include struct BlankScreen_Sysdep { Display *dpy; Window win; XEvent ev; int scr; bool locked; QString lockMsg; int blackColor, whiteColor; int offX, offY; }; BlankScreen::BlankScreen() { _sysdep = new BlankScreen_Sysdep; _sysdep->dpy = XOpenDisplay(NULL); _sysdep->scr = DefaultScreen(_sysdep->dpy); assert(_sysdep->dpy); _sysdep->blackColor = BlackPixel(_sysdep->dpy, DefaultScreen(_sysdep->dpy)); _sysdep->whiteColor = WhitePixel(_sysdep->dpy, DefaultScreen(_sysdep->dpy)); // win = XCreateSimpleWindow(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), 0, 0, 200, 100, 0, blackColor, whiteColor); _sysdep->win = XCreateSimpleWindow(_sysdep->dpy, RootWindow(_sysdep->dpy, _sysdep->scr), 10, 10, 200, 200, 1, WhitePixel(_sysdep->dpy, _sysdep->scr), BlackPixel(_sysdep->dpy, _sysdep->scr)); XSelectInput(_sysdep->dpy, _sysdep->win, ExposureMask | KeyPressMask); _sysdep->locked = false; _sysdep->offX = _sysdep->offY = 0; } BlankScreen::~BlankScreen() { delete _sysdep; } void BlankScreen::draw(bool force) { if (_sysdep->locked)// no need to draw if we're not showing the window { XWindowAttributes xwa; XGetWindowAttributes(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), &xwa); int hx = (xwa.width)>>2, hy = (xwa.height)>>2; if (XCheckTypedEvent(_sysdep->dpy, Expose, &_sysdep->ev) || force ) { hx += _sysdep->offX; hy += _sysdep->offY; GC gcc = XCreateGC(_sysdep->dpy, _sysdep->win, 0, NULL); XSetForeground(_sysdep->dpy, gcc, _sysdep->whiteColor); // XClearArea(_sysdep->dpy, _sysdep->win, 0, 0, xwa.width, xwa.height, false); if (_sysdep->lockMsg.size() > 0) { char *msg = const_cast(_sysdep->lockMsg.toUtf8().data()); XDrawString(_sysdep->dpy, _sysdep->win, gcc/*DefaultGC(dpy, scr)*/, hx, hy, msg, strlen(msg)); } else { } } } } bool BlankScreen::lock() { #define lock_test if (_sysdep->locked) return _sysdep->locked; // We want to get MapNotify events XSelectInput(_sysdep->dpy, _sysdep->win, StructureNotifyMask); // "Map" the window (that is, make it appear on the screen) XMapWindow(_sysdep->dpy, _sysdep->win); // Create a "Graphics Context" //GC gc = XCreateGC(dpy, win, 0, NULL); XEvent xev; Atom wm_state = XInternAtom(_sysdep->dpy, "_NET_WM_STATE", False); Atom fullscreen = XInternAtom(_sysdep->dpy, "_NET_WM_STATE_FULLSCREEN", False); memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.xclient.window = _sysdep->win; xev.xclient.message_type = wm_state; xev.xclient.format = 32; xev.xclient.data.l[0] = 1; xev.xclient.data.l[1] = fullscreen; xev.xclient.data.l[2] = 0; XSendEvent(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), False, SubstructureNotifyMask, &xev); // Wait for the MapNotify event for (;;) { XEvent e; XNextEvent(_sysdep->dpy, &e); if (e.type == MapNotify) break; } //Flush it! //XFlush(_sysdep->dpy); #ifndef lock_test // load the locked cursor, so people dont think they can click anything // TODO: Use some kind of invisible cursor instead of the wait-cursor Cursor _sysdep->locked_cur = XCreateFontCursor(_sysdep->dpy, XC_watch); XDefineCursor(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy),_sysdep->locked_cur); #endif // grabbing of keyboard and mouse and hide the cursor XGrabKeyboard(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, 0, GrabModeAsync, GrabModeAsync, None, NULL, CurrentTime); if (!_sysdep->locked) ConsoleLog writeLine(QString("Locked")); // see header for more information on this switch return _sysdep->locked = true; } bool BlankScreen::lock_inputs() { // grabbing of keyboard and mouse and hide the cursor XGrabKeyboard(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, 0, GrabModeAsync, GrabModeAsync, None, NULL, CurrentTime); return true; } bool BlankScreen::unlock() { if (_sysdep->dpy) { int retval = -1; //reset cursor to arrow (no *real* default here...) Cursor normal_cur = XCreateFontCursor(_sysdep->dpy, XC_arrow); XDefineCursor(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), normal_cur); // ungrabbing of keyboard and mouse XUngrabPointer(_sysdep->dpy, CurrentTime); XUngrabKeyboard(_sysdep->dpy, CurrentTime); retval = XUnmapWindow(_sysdep->dpy,_sysdep->win); if (retval == BadWindow) ConsoleLog writeError(QString("Bad window while unmapping. Badwindow: ").append(int2String(retval))); XFlush(_sysdep->dpy); } if (_sysdep->locked) ConsoleLog writeLine(QString("Unlocked")); _sysdep->lockMsg.clear(); return !(_sysdep->locked = false); } static Display* _dpy = 0; Display* X11Info::display() { if(!_dpy) { _dpy = XOpenDisplay(0); } return _dpy; }