From 74c41986dbe4b12802f7cb7a46d987d5bb13fd1b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 2 Jan 2019 11:31:36 +0100 Subject: Don't skip over the 4 descriptors in base EDID block --- src/xprivate.cpp | 146 +++++++++++++++++++++++++++++-------------------------- src/xprivate.h | 3 +- 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(hactive); - m.height = static_cast(vactive); - m.dotClock = static_cast(pixclk) * 10ul * 1000ul; - m.hSyncStart= static_cast(hactive + hsyncoff); - m.hSyncEnd = static_cast(hactive + hsyncoff + hsyncwidth); - m.hTotal = static_cast(hactive + hblank); - m.hSkew = 0; - m.vSyncStart= static_cast(vactive + vsyncoff); - m.vSyncEnd = static_cast(vactive + vsyncoff + vsyncwidth); - m.vTotal = static_cast(vactive + vblank); - m.id = 0; - m.name = buf; - m.nameLength = static_cast(snprintf(buf, sizeof(buf), "%dx%d_%d", hactive, vactive, static_cast(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(hactive); + m.height = static_cast(vactive); + m.dotClock = static_cast(pixclk) * 10ul * 1000ul; + m.hSyncStart= static_cast(hactive + hsyncoff); + m.hSyncEnd = static_cast(hactive + hsyncoff + hsyncwidth); + m.hTotal = static_cast(hactive + hblank); + m.hSkew = 0; + m.vSyncStart= static_cast(vactive + vsyncoff); + m.vSyncEnd = static_cast(vactive + vsyncoff + vsyncwidth); + m.vTotal = static_cast(vactive + vblank); + m.id = 0; + m.name = buf; + m.nameLength = static_cast(snprintf(buf, sizeof(buf), "%dx%d_%d", hactive, vactive, static_cast(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); -- cgit v1.2.3-55-g7522