#include "clientGUIUtils.h"
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
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<char*>(_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;
}