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 | |
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')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 62 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.h | 10 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/xcb_qpa_lib.pro | 3 |
3 files changed, 74 insertions, 1 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() diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 21f583ccf7..b9364758c4 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -53,6 +53,8 @@ #include <private/qfontengine_p.h> +#include <QtEdidSupport/private/qedidparser_p.h> + QT_BEGIN_NAMESPACE class QXcbConnection; @@ -147,6 +149,10 @@ public: QWindow *topLevelAt(const QPoint &point) const override; + QString manufacturer() const override; + QString model() const override; + QString serialNumber() const override; + QRect geometry() const override { return m_geometry; } QRect availableGeometry() const override {return m_availableGeometry;} int depth() const override { return screen()->root_depth; } @@ -206,6 +212,9 @@ public: private: void sendStartupMessage(const QByteArray &message) const; + QByteArray getOutputProperty(xcb_atom_t atom) const; + QByteArray getEdid() const; + QXcbVirtualDesktop *m_virtualDesktop; xcb_randr_output_t m_output; xcb_randr_crtc_t m_crtc; @@ -224,6 +233,7 @@ private: QXcbCursor *m_cursor; int m_refreshRate = 60; int m_pixelDensity = 1; + QEdidParser m_edid; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 76bb692590..b5cefa2726 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -5,7 +5,8 @@ DEFINES += QT_NO_FOREACH QT += \ core-private gui-private \ service_support-private theme_support-private \ - eventdispatcher_support-private fontdatabase_support-private + eventdispatcher_support-private fontdatabase_support-private \ + edid_support-private qtHaveModule(linuxaccessibility_support-private): \ QT += linuxaccessibility_support-private |