summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbscreen.cpp
diff options
context:
space:
mode:
authorPier Luigi Fiorini <pierluigi.fiorini@liri.io>2017-01-06 20:11:22 +0100
committerPier Luigi Fiorini <pierluigi.fiorini@liri.io>2017-05-04 08:10:31 +0000
commitec6c21717ae5e0b3ed16235dca6eb1b3db52f74d (patch)
tree5b7d50e7d0f8a9a064c84e0458401da247c04a39 /src/plugins/platforms/xcb/qxcbscreen.cpp
parentb1debc11c118bb1e49a9e92a77194140255854fc (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.cpp62
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()