diff options
Diffstat (limited to 'src/xx.cpp')
-rw-r--r-- | src/xx.cpp | 77 |
1 files changed, 75 insertions, 2 deletions
@@ -2,7 +2,7 @@ #include "xprivate.h" #include "cvt.h" #include <QDebug> - +#include <QSocketNotifier> /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -36,10 +36,58 @@ static ScreenInfo initScreenInfo(const OutputInfo *oi, const ModeMap &om) ScreenSetup * ScreenSetup::_instance = nullptr; +static int errorHandlerX(Display*) +{ + exit(1); +} + ScreenSetup::ScreenSetup() : a(new XPrivate()) { - /* Get informations about Xserver */ + int event_base_return, error_base_return; + if (!XRRQueryExtension(a->_display, &event_base_return, &error_base_return)) { + qDebug() << "No XRANDR extension found"; + exit(1); + } updateScreenResources(); + //XSelectInput(a->_display, DefaultRootWindow(a->_display), StructureNotifyMask); + XRRSelectInput(a->_display, DefaultRootWindow(a->_display), RROutputChangeNotifyMask); + //XSync(a->_display, False); + XSetIOErrorHandler((XIOErrorHandler) errorHandlerX); + _socketNotifier = new QSocketNotifier(qintptr(ConnectionNumber(a->_display)), QSocketNotifier::Read); + connect(_socketNotifier, &QSocketNotifier::activated, [=](int) { + XEvent ev; + qDebug() << "Socket Event"; + while (XPending(a->_display) > 0) { + XNextEvent(a->_display, &ev); + if (ev.type - event_base_return != RRNotify) { + qDebug() << "Received unknown X event"; + continue; + } + qDebug() << "Got Change Event"; + XRROutputChangeNotifyEvent *oce = reinterpret_cast<XRROutputChangeNotifyEvent*>(&ev); + XRRScreenResources *sr = XRRGetScreenResources(oce->display, oce->window); + if (sr == nullptr) { + emit outputConfigChanged(ConnectionEvent::Unknown); + continue; + } + XRROutputInfo *oi = XRRGetOutputInfo(a->_display, sr, oce->output); + if (oi == nullptr) { + XRRFreeScreenResources(sr); + emit outputConfigChanged(ConnectionEvent::Unknown); + continue; + } + if (oi->connection == RR_Connected) { + emit outputConfigChanged(ConnectionEvent::Connected); + } else if (oi->connection == RR_Disconnected) { + emit outputConfigChanged(ConnectionEvent::Disconnected); + } else { + emit outputConfigChanged(ConnectionEvent::Unknown); + } + XRRFreeOutputInfo(oi); + XRRFreeScreenResources(sr); + } + }); + } @@ -337,11 +385,36 @@ ResolutionVector ScreenSetup::getCommonModes() const return ret; } +/** + * Return number of connected (no active) outputs according to last query + */ int ScreenSetup::getOutputCount() const { return a->_outputMap.size(); } +/** + * Query currently connected number of outputs + */ +int ScreenSetup::queryCurrentOutputCount() const +{ + auto sr = XRRGetScreenResourcesCurrent(a->_display, DefaultRootWindow(a->_display)); + if (sr == nullptr) + return 0; + int count = 0; + for (int i = 0; i < sr->noutput; ++i) { + XRROutputInfo* info = XRRGetOutputInfo(a->_display, sr, sr->outputs[i]); + if (info == nullptr) + continue; + if (info->connection != RR_Disconnected) { + count++; + } + XRRFreeOutputInfo(info); + } + XRRFreeScreenResources(sr); + return count; +} + const ResolutionVector &ScreenSetup::getVirtualResolutions() const { return a->_resolutions; |