diff options
author | Pier Luigi Fiorini <pierluigi.fiorini@liri.io> | 2017-01-06 20:11:22 +0100 |
---|---|---|
committer | Pier Luigi Fiorini <pierluigi.fiorini@liri.io> | 2017-05-04 08:10:31 +0000 |
commit | ec6c21717ae5e0b3ed16235dca6eb1b3db52f74d (patch) | |
tree | 5b7d50e7d0f8a9a064c84e0458401da247c04a39 /src/plugins/platforms/xcb/qxcbscreen.cpp | |
parent | b1debc11c118bb1e49a9e92a77194140255854fc (diff) |
xcb: Decode EDID blob
Retrieve and parse EDID blob.
Return screen product information from EDID.
[ChangeLog][Platform Specific Changes][Linux/XCB] Add screen product
information from EDID.
Change-Id: Ic54429cdc90c41342c37511bcaebce95c175f517
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbscreen.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 0fc872cf7e..0bc38869ac 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -428,6 +428,18 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe m_sizeMillimeters = m_virtualSizeMillimeters; m_cursor = new QXcbCursor(connection, this); + + // Parse EDID + if (m_edid.parse(getEdid())) + qCDebug(lcQpaScreen, "EDID data for output \"%s\": identifier '%s', manufacturer '%s', model '%s', serial '%s', physical size: %.2fx%.2f", + name().toLatin1().constData(), + m_edid.identifier.toLatin1().constData(), + m_edid.manufacturer.toLatin1().constData(), + m_edid.model.toLatin1().constData(), + m_edid.serialNumber.toLatin1().constData(), + m_edid.physicalSize.width(), m_edid.physicalSize.height()); + else + qCWarning(lcQpaScreen) << "Failed to parse EDID data for output" << name(); } QXcbScreen::~QXcbScreen() @@ -452,6 +464,21 @@ QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo) return name; } +QString QXcbScreen::manufacturer() const +{ + return m_edid.manufacturer; +} + +QString QXcbScreen::model() const +{ + return m_edid.model; +} + +QString QXcbScreen::serialNumber() const +{ + return m_edid.serialNumber; +} + QWindow *QXcbScreen::topLevelAt(const QPoint &p) const { xcb_window_t root = screen()->root; @@ -830,6 +857,41 @@ QXcbXSettings *QXcbScreen::xSettings() const return m_virtualDesktop->xSettings(); } +QByteArray QXcbScreen::getOutputProperty(xcb_atom_t atom) const +{ + QByteArray result; + + auto cookie = + xcb_randr_get_output_property(xcb_connection(), m_output, + atom, XCB_ATOM_ANY, 0, 100, false, false); + auto reply = xcb_randr_get_output_property_reply(xcb_connection(), cookie, nullptr); + if (reply->type == XCB_ATOM_INTEGER && reply->format == 8) { + quint8 *data = new quint8[reply->num_items]; + memcpy(data, xcb_randr_get_output_property_data(reply), reply->num_items); + result = QByteArray(reinterpret_cast<const char *>(data), reply->num_items); + delete[] data; + } + free(reply); + + return result; +} + +QByteArray QXcbScreen::getEdid() const +{ + // Try a bunch of atoms + xcb_atom_t atom = connection()->internAtom("EDID"); + QByteArray result = getOutputProperty(atom); + if (result.isEmpty()) { + atom = connection()->internAtom("EDID_DATA"); + result = getOutputProperty(atom); + } + if (result.isEmpty()) { + atom = connection()->internAtom("XFree86_DDC_EDID1_RAWDATA"); + result = getOutputProperty(atom); + } + return result; +} + static inline void formatRect(QDebug &debug, const QRect r) { debug << r.width() << 'x' << r.height() |