summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-10-22 14:20:53 +0200
committerSimon Rettberg2019-10-22 14:20:53 +0200
commitfd688af424be0b953f7b7d1107d07ee668655868 (patch)
treeddf55760effec8ee11c489140ecae747e0776492
parentTry all possible modes for a given resolution (diff)
downloadbeamergui-fd688af424be0b953f7b7d1107d07ee668655868.tar.gz
beamergui-fd688af424be0b953f7b7d1107d07ee668655868.tar.xz
beamergui-fd688af424be0b953f7b7d1107d07ee668655868.zip
Improve Xlib error handling
-rw-r--r--src/xprivate.cpp67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/xprivate.cpp b/src/xprivate.cpp
index 1273e1e..bef9471 100644
--- a/src/xprivate.cpp
+++ b/src/xprivate.cpp
@@ -3,6 +3,10 @@
#include <QDebug>
#include <QRegularExpression>
+// Put this here as we need it in the static error handler
+static Display* __display;
+static XErrorHandler old_handler;
+
static double toVertRefresh(const XRRModeInfo *mode)
{
if (mode->hTotal > 0 && mode->vTotal > 0)
@@ -61,9 +65,15 @@ static int modeEqual(const XRRModeInfo *a, const XRRModeInfo *b)
static int errorHandler(Display *dpy, XErrorEvent *err)
{
- char buf[1000];
- XGetErrorText(dpy, err->error_code, buf, 1000);
- qDebug() << "**X11 error**" << buf;
+ if (dpy != __display) {
+ if (old_handler != nullptr) {
+ return old_handler(dpy, err);
+ }
+ } else {
+ char buf[1000];
+ XGetErrorText(dpy, err->error_code, buf, 1000);
+ qDebug() << "**X11 error**" << buf;
+ }
return 0;
}
@@ -75,12 +85,12 @@ XPrivate::XPrivate()
: _screenResources(nullptr)
{
// Get initial data (to be freed)
- _display = XOpenDisplay(nullptr);
+ __display = _display = XOpenDisplay(nullptr);
if (_display == nullptr) {
qFatal("Cannot open display");
::exit(1);
}
- XSetErrorHandler(errorHandler);
+ old_handler = XSetErrorHandler(errorHandler);
_EDID_ATOM = XInternAtom(_display, RR_PROPERTY_RANDR_EDID, False);
}
@@ -120,7 +130,7 @@ void XPrivate::updateScreenResources()
freeResources();
_screenResources = XRRGetScreenResourcesCurrent(_display, DefaultRootWindow(_display));
// Create the modemap
- qDebug() << "Modes";
+ qDebug() << "updateScreenResources: Modes";
for (int i = 0; i < _screenResources->nmode; ++i) {
_modeMap.insert(
_screenResources->modes[i].id,
@@ -145,7 +155,7 @@ void XPrivate::updateScreenResources()
*/
// Create crtcMap
- qDebug() << "CRTCs";
+ qDebug() << "updateScreenResources: CRTCs";
for (int i = 0; i < _screenResources->ncrtc; ++i) {
XRRCrtcInfo * info = XRRGetCrtcInfo(
_display,
@@ -160,7 +170,7 @@ void XPrivate::updateScreenResources()
}
// Create outputmap and connectedOutputMap
- qDebug() << "Outputs";
+ qDebug() << "updateScreenResources: Outputs";
QHash<RROutput, QString> tempMap;
QMap<Projector, int> typeCount;
for (int i = 0; i < _screenResources->noutput; ++i) {
@@ -234,7 +244,7 @@ void XPrivate::updateScreenResources()
return;
qSort(screens.begin(), screens.end(), xRectLessThan);
int endX = -0xffff;
- qDebug() << "From left to right";
+ qDebug() << "updateScreenResources: From left to right";
for (OutputInfo* output : screens) {
if (output->mode == nullptr) {
qDebug() << "(Ignoring" << output->outputName << "since it's disconnected)";
@@ -252,33 +262,37 @@ void XPrivate::updateScreenResources()
endX = output->crtc->x + int(output->mode->width);
}
}
- qDebug() << "Loaded.";
+ qDebug() << "updateScreenResources: Loaded.";
}
void XPrivate::addMissingEdidResolutions()
{
- XRRScreenResources *resptr = XRRGetScreenResourcesCurrent(_display, DefaultRootWindow(_display));
- for (int i = 0; i < resptr->noutput; ++i) {
- unsigned char prop[512];
- unsigned long edidLen = 512;
- if (!getEdid(resptr->outputs[i], prop, &edidLen))
- continue;
- if (edidLen < 128)
- continue;
- for (unsigned int j = 54; j < 125; j+= 18) {
- addMissingModesFromDtd(resptr, resptr->outputs[i], prop + j);
- }
- for (unsigned int j = 128; j < edidLen - 127; j += 128) {
- addMissingModesFromExtBlock(resptr, resptr->outputs[i], prop + j);
- }
- }
- XRRFreeScreenResources(resptr);
+ qDebug() << "addMissingEdidResolutions";
+ XRRScreenResources *resptr = XRRGetScreenResourcesCurrent(_display, DefaultRootWindow(_display));
+ if (resptr == nullptr)
+ return;
+ for (int i = 0; i < resptr->noutput; ++i) {
+ unsigned char prop[512];
+ unsigned long edidLen = 512;
+ if (!getEdid(resptr->outputs[i], prop, &edidLen))
+ continue;
+ if (edidLen < 128)
+ continue;
+ for (unsigned int j = 54; j < 125; j+= 18) {
+ addMissingModesFromDtd(resptr, resptr->outputs[i], prop + j);
+ }
+ for (unsigned int j = 128; j < edidLen - 127; j += 128) {
+ addMissingModesFromExtBlock(resptr, resptr->outputs[i], prop + j);
+ }
+ }
+ XRRFreeScreenResources(resptr);
}
bool XPrivate::getEdid(RROutput outputId, unsigned char *buffer, unsigned long *size)
{
int numProps = 0;
bool found = false;
+ qDebug() << "getEdid:" << outputId;
Atom* properties = XRRListOutputProperties(_display, outputId, &numProps);
for (int i = 0; i < numProps; ++i) {
if (properties[i] == _EDID_ATOM) {
@@ -351,6 +365,7 @@ void XPrivate::addMissingModesFromExtBlock(XRRScreenResources *res, RROutput out
dtdOffset = 128;
}
+ qDebug() << "addMissingModesFromExtBlock:" << outputId;
for (int i = dtdOffset; i < 128 - 17; i += 18) {
addMissingModesFromDtd(res, outputId, data + i);
}