summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-01-02 11:31:36 +0100
committerSimon Rettberg2019-01-02 11:31:36 +0100
commit74c41986dbe4b12802f7cb7a46d987d5bb13fd1b (patch)
treeddf84033868526dd835a89ffcd76d58ee17a3e2d
parentActually call the function... (diff)
downloadbeamergui-74c41986dbe4b12802f7cb7a46d987d5bb13fd1b.tar.gz
beamergui-74c41986dbe4b12802f7cb7a46d987d5bb13fd1b.tar.xz
beamergui-74c41986dbe4b12802f7cb7a46d987d5bb13fd1b.zip
Don't skip over the 4 descriptors in base EDID block
-rw-r--r--src/xprivate.cpp146
-rw-r--r--src/xprivate.h3
2 files changed, 79 insertions, 70 deletions
diff --git a/src/xprivate.cpp b/src/xprivate.cpp
index 4be7098..2cba1b0 100644
--- a/src/xprivate.cpp
+++ b/src/xprivate.cpp
@@ -247,10 +247,13 @@ void XPrivate::addMissingEdidResolutions()
unsigned long edidLen = 512;
if (!getEdid(resptr->outputs[i], prop, &edidLen))
continue;
- if (edidLen < 256)
+ 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) {
- addMissingModesFromEdid(resptr, resptr->outputs[i], prop + j);
+ addMissingModesFromExtBlock(resptr, resptr->outputs[i], prop + j);
}
}
XRRFreeScreenResources(resptr);
@@ -319,7 +322,7 @@ bool XPrivate::readEdid(OutputInfo* output)
return true;
}
-void XPrivate::addMissingModesFromEdid(XRRScreenResources *res, RROutput outputId, unsigned char *data)
+void XPrivate::addMissingModesFromExtBlock(XRRScreenResources *res, RROutput outputId, unsigned char *data)
{
if (data[0] != 2) // Not type 2, skip
return;
@@ -332,79 +335,84 @@ void XPrivate::addMissingModesFromEdid(XRRScreenResources *res, RROutput outputI
dtdOffset = 128;
}
- int hactive, vactive, pixclk, hsyncoff, hsyncwidth, hblank, vsyncoff, vsyncwidth, vblank;
for (int i = dtdOffset; i < 128 - 17; i += 18) {
- if (data[i] == 0 && data[i + 1] == 0)
- continue;
- hactive = data[i+2] + ((data[i+4] & 0xf0) << 4);
- hblank = data[i+3] + ((data[i+4] & 0x0f) << 8);
- vactive = data[i+5] + ((data[i+7] & 0xf0) << 4);
- vblank = data[i+6] + ((data[i+7] & 0x0f) << 8);
- pixclk = (data[i+1] << 8) | (data[i]); // 10kHz
- hsyncoff = data[i+8] | ((data[i+11] & 0xC0) << 2);
- hsyncwidth = data[i+9] | ((data[i+11] & 0x30) << 4);
- vsyncoff = ((data[i+10] & 0xf0) >> 4) | ((data[i+11] & 0x0C) << 2);
- vsyncwidth = (data[i+10] & 0x0f) | ((data[i+11] & 0x03) << 4);
- char buf[100];
- XRRModeInfo m;
- memset(&m, 0, sizeof(m));
- m.width = static_cast<unsigned int>(hactive);
- m.height = static_cast<unsigned int>(vactive);
- m.dotClock = static_cast<unsigned long>(pixclk) * 10ul * 1000ul;
- m.hSyncStart= static_cast<unsigned int>(hactive + hsyncoff);
- m.hSyncEnd = static_cast<unsigned int>(hactive + hsyncoff + hsyncwidth);
- m.hTotal = static_cast<unsigned int>(hactive + hblank);
- m.hSkew = 0;
- m.vSyncStart= static_cast<unsigned int>(vactive + vsyncoff);
- m.vSyncEnd = static_cast<unsigned int>(vactive + vsyncoff + vsyncwidth);
- m.vTotal = static_cast<unsigned int>(vactive + vblank);
- m.id = 0;
- m.name = buf;
- m.nameLength = static_cast<unsigned int>(snprintf(buf, sizeof(buf), "%dx%d_%d", hactive, vactive, static_cast<int>(m.dotClock / (m.hTotal * m.vTotal))));
- if (m.nameLength > sizeof(buf)) {
- m.nameLength = sizeof(buf);
- }
- if ((data[i+17] & 0x18) == 0x18) {
- // Digital Separate
- if (data[i+17] & 0x04) {
- m.modeFlags |= RR_VSyncPositive;
- } else {
- m.modeFlags |= RR_VSyncNegative;
- }
- if (data[i+17] & 0x02) {
- m.modeFlags |= RR_HSyncPositive;
- } else {
- m.modeFlags |= RR_HSyncNegative;
- }
- } else if ((data[i+17] & 0x18) == 0x10) {
- // Digital Composite
- if (data[i+17] & 0x02) {
- m.modeFlags |= RR_HSyncPositive;
- } else {
- m.modeFlags |= RR_HSyncNegative;
- }
- m.modeFlags |= RR_VSyncNegative; // Default? Clarify...
+ addMissingModesFromDtd(res, outputId, data + i);
+ }
+}
+
+void XPrivate::addMissingModesFromDtd(XRRScreenResources *res, RROutput outputId, unsigned char *data)
+{
+ if (data[0] == 0 && data[1] == 0)
+ return;
+ int hactive, vactive, pixclk, hsyncoff, hsyncwidth, hblank, vsyncoff, vsyncwidth, vblank;
+ hactive = data[2] + ((data[4] & 0xf0) << 4);
+ hblank = data[3] + ((data[4] & 0x0f) << 8);
+ vactive = data[5] + ((data[7] & 0xf0) << 4);
+ vblank = data[6] + ((data[7] & 0x0f) << 8);
+ pixclk = (data[1] << 8) | (data[0]); // 10kHz
+ hsyncoff = data[8] | ((data[11] & 0xC0) << 2);
+ hsyncwidth = data[9] | ((data[11] & 0x30) << 4);
+ vsyncoff = ((data[10] & 0xf0) >> 4) | ((data[11] & 0x0C) << 2);
+ vsyncwidth = (data[10] & 0x0f) | ((data[11] & 0x03) << 4);
+ char buf[100];
+ XRRModeInfo m;
+ memset(&m, 0, sizeof(m));
+ m.width = static_cast<unsigned int>(hactive);
+ m.height = static_cast<unsigned int>(vactive);
+ m.dotClock = static_cast<unsigned long>(pixclk) * 10ul * 1000ul;
+ m.hSyncStart= static_cast<unsigned int>(hactive + hsyncoff);
+ m.hSyncEnd = static_cast<unsigned int>(hactive + hsyncoff + hsyncwidth);
+ m.hTotal = static_cast<unsigned int>(hactive + hblank);
+ m.hSkew = 0;
+ m.vSyncStart= static_cast<unsigned int>(vactive + vsyncoff);
+ m.vSyncEnd = static_cast<unsigned int>(vactive + vsyncoff + vsyncwidth);
+ m.vTotal = static_cast<unsigned int>(vactive + vblank);
+ m.id = 0;
+ m.name = buf;
+ m.nameLength = static_cast<unsigned int>(snprintf(buf, sizeof(buf), "%dx%d_%d", hactive, vactive, static_cast<int>(m.dotClock / (m.hTotal * m.vTotal))));
+ if (m.nameLength > sizeof(buf)) {
+ m.nameLength = sizeof(buf);
+ }
+ if ((data[17] & 0x18) == 0x18) {
+ // Digital Separate
+ if (data[17] & 0x04) {
+ m.modeFlags |= RR_VSyncPositive;
} else {
- m.modeFlags |= RR_VSyncNegative | RR_HSyncNegative; // ...
- }
- if (data[i+17] & 0x80) {
- m.modeFlags |= RR_Interlace;
+ m.modeFlags |= RR_VSyncNegative;
}
- // See if we should add this mode
- RRMode modeId = 0;
- for (int mode = 0; mode < res->nmode; ++mode) {
- if (modeEqual(&res->modes[mode], &m)) {
- modeId = res->modes[mode].id;
- break;
- }
+ if (data[17] & 0x02) {
+ m.modeFlags |= RR_HSyncPositive;
+ } else {
+ m.modeFlags |= RR_HSyncNegative;
}
- if (modeId == 0) {
- modeId = XRRCreateMode(_display, DefaultRootWindow(_display), &m);
+ } else if ((data[17] & 0x18) == 0x10) {
+ // Digital Composite
+ if (data[17] & 0x02) {
+ m.modeFlags |= RR_HSyncPositive;
+ } else {
+ m.modeFlags |= RR_HSyncNegative;
}
- if (modeId != 0) {
- XRRAddOutputMode(_display, outputId, modeId);
+ m.modeFlags |= RR_VSyncNegative; // Default? Clarify...
+ } else {
+ m.modeFlags |= RR_VSyncNegative | RR_HSyncNegative; // ...
+ }
+ if (data[17] & 0x80) {
+ m.modeFlags |= RR_Interlace;
+ }
+ // See if we should add this mode
+ RRMode modeId = 0;
+ for (int mode = 0; mode < res->nmode; ++mode) {
+ if (modeEqual(&res->modes[mode], &m)) {
+ modeId = res->modes[mode].id;
+ break;
}
}
+ if (modeId == 0) {
+ modeId = XRRCreateMode(_display, DefaultRootWindow(_display), &m);
+ }
+ if (modeId != 0) {
+ XRRAddOutputMode(_display, outputId, modeId);
+ }
}
void XPrivate::setScreenSize(const QSize &size)
diff --git a/src/xprivate.h b/src/xprivate.h
index 28234ac..3bc6067 100644
--- a/src/xprivate.h
+++ b/src/xprivate.h
@@ -47,7 +47,8 @@ public:
void addMissingEdidResolutions();
bool getEdid(RROutput outputId, unsigned char *buffer, unsigned long *size);
bool readEdid(OutputInfo* output);
- void addMissingModesFromEdid(XRRScreenResources *res, RROutput outputId, unsigned char *data);
+ void addMissingModesFromExtBlock(XRRScreenResources *res, RROutput outputId, unsigned char *data);
+ void addMissingModesFromDtd(XRRScreenResources *res, RROutput outputId, unsigned char *data);
void disconnectAllCrtcs();
XRRModeInfo* getPreferredMode(OutputInfo *oi, XRRModeInfo *fallback = nullptr) const;
void setScreenSize(const QSize &size);