From ec6c21717ae5e0b3ed16235dca6eb1b3db52f74d Mon Sep 17 00:00:00 2001 From: Pier Luigi Fiorini Date: Fri, 6 Jan 2017 20:11:22 +0100 Subject: 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 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbscreen.cpp | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src/plugins/platforms/xcb/qxcbscreen.cpp') 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(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() -- cgit v1.2.3