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>
This commit is contained in:
Pier Luigi Fiorini 2017-01-06 20:11:22 +01:00
parent b1debc11c1
commit ec6c21717a
3 changed files with 74 additions and 1 deletions

View File

@ -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()

View File

@ -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

View File

@ -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