summaryrefslogtreecommitdiffstats
path: root/src/xx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xx.cpp')
-rw-r--r--src/xx.cpp77
1 files changed, 75 insertions, 2 deletions
diff --git a/src/xx.cpp b/src/xx.cpp
index 2a8cdc5..d9c05d6 100644
--- a/src/xx.cpp
+++ b/src/xx.cpp
@@ -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;