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