platforms/drm: Fix handling of missing EDID
drmModeGetPropertyBlob() may return null and we should handle that. In addition to that, m_conn is not initialized in DrmConnector so kwin will crash whenever the connector info is accessed.
This commit is contained in:
parent
53f7bda7d2
commit
75e7562953
4 changed files with 19 additions and 23 deletions
|
@ -51,6 +51,9 @@ bool DrmObject::initProps(const QVector<PropertyDefinition> &&vector, uint32_t o
|
|||
drmModePropertyBlobRes *blob = nullptr;
|
||||
if (prop->flags & DRM_MODE_PROP_BLOB) {
|
||||
blob = drmModeGetPropertyBlob(fd(), properties->prop_values[i]);
|
||||
if (!blob) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
qCDebug(KWIN_DRM, "Found property %s with value %lu", def.name.data(), properties->prop_values[i]);
|
||||
m_props[j] = new Property(prop.data(), properties->prop_values[i], def.enumNames, blob);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "drm_object_connector.h"
|
||||
#include "drm_pointer.h"
|
||||
#include "logging.h"
|
||||
#include "edid.h"
|
||||
|
||||
#include <main.h>
|
||||
// frameworks
|
||||
|
@ -20,13 +19,10 @@ namespace KWin
|
|||
|
||||
DrmConnector::DrmConnector(uint32_t connector_id, int fd)
|
||||
: DrmObject(connector_id, fd)
|
||||
, m_conn(drmModeGetConnector(fd, connector_id))
|
||||
{
|
||||
DrmScopedPointer<drmModeConnector> con(drmModeGetConnector(fd, connector_id));
|
||||
if (!con) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < con->count_encoders; ++i) {
|
||||
m_encoders << con->encoders[i];
|
||||
for (int i = 0; i < m_conn->count_encoders; ++i) {
|
||||
m_encoders << m_conn->encoders[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,8 +51,8 @@ bool DrmConnector::init()
|
|||
|
||||
// parse edid
|
||||
if (auto edidProp = m_props[static_cast<uint32_t>(PropertyIndex::Edid)]) {
|
||||
m_edid.reset(new Edid(edidProp->blob()->data, edidProp->blob()->length));
|
||||
if (!m_edid->isValid()) {
|
||||
m_edid = Edid(edidProp->blob()->data, edidProp->blob()->length);
|
||||
if (!m_edid.isValid()) {
|
||||
qCWarning(KWIN_DRM, "Couldn't parse EDID for connector with id %d", id());
|
||||
}
|
||||
deleteProp(PropertyIndex::Edid);
|
||||
|
@ -65,21 +61,21 @@ bool DrmConnector::init()
|
|||
}
|
||||
|
||||
// check the physical size
|
||||
if (m_edid->physicalSize().isEmpty()) {
|
||||
if (m_edid.physicalSize().isEmpty()) {
|
||||
m_physicalSize = QSize(m_conn->mmWidth, m_conn->mmHeight);
|
||||
} else {
|
||||
m_physicalSize = m_edid->physicalSize();
|
||||
m_physicalSize = m_edid.physicalSize();
|
||||
}
|
||||
|
||||
// the size might be completely borked. E.g. Samsung SyncMaster 2494HS reports 160x90 while in truth it's 520x292
|
||||
// as this information is used to calculate DPI info, it's going to result in everything being huge
|
||||
const QByteArray unknown = QByteArrayLiteral("unknown");
|
||||
KConfigGroup group = kwinApp()->config()->group("EdidOverwrite").group(m_edid->eisaId().isEmpty() ? unknown : m_edid->eisaId())
|
||||
.group(m_edid->monitorName().isEmpty() ? unknown : m_edid->monitorName())
|
||||
.group(m_edid->serialNumber().isEmpty() ? unknown : m_edid->serialNumber());
|
||||
KConfigGroup group = kwinApp()->config()->group("EdidOverwrite").group(m_edid.eisaId().isEmpty() ? unknown : m_edid.eisaId())
|
||||
.group(m_edid.monitorName().isEmpty() ? unknown : m_edid.monitorName())
|
||||
.group(m_edid.serialNumber().isEmpty() ? unknown : m_edid.serialNumber());
|
||||
if (group.hasKey("PhysicalSize")) {
|
||||
const QSize overwriteSize = group.readEntry("PhysicalSize", m_physicalSize);
|
||||
qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid->eisaId() << "/" << m_edid->monitorName() << "/" << m_edid->serialNumber() << " from " << m_physicalSize << "to " << overwriteSize;
|
||||
qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid.eisaId() << "/" << m_edid.monitorName() << "/" << m_edid.serialNumber() << " from " << m_physicalSize << "to " << overwriteSize;
|
||||
m_physicalSize = overwriteSize;
|
||||
}
|
||||
|
||||
|
@ -125,7 +121,7 @@ QString DrmConnector::connectorName() const
|
|||
|
||||
QString DrmConnector::modelName() const
|
||||
{
|
||||
return connectorName() + m_edid->nameString();
|
||||
return connectorName() + m_edid.nameString();
|
||||
}
|
||||
|
||||
bool DrmConnector::isInternal() const
|
||||
|
|
|
@ -12,12 +12,11 @@
|
|||
#include <QSize>
|
||||
|
||||
#include "drm_object.h"
|
||||
#include "edid.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Edid;
|
||||
|
||||
class DrmConnector : public DrmObject
|
||||
{
|
||||
public:
|
||||
|
@ -53,8 +52,8 @@ public:
|
|||
return m_props[static_cast<uint32_t>(PropertyIndex::Dpms)];
|
||||
}
|
||||
|
||||
Edid *edid() const {
|
||||
return m_edid.get();
|
||||
const Edid *edid() const {
|
||||
return &m_edid;
|
||||
}
|
||||
|
||||
QString connectorName() const;
|
||||
|
@ -66,8 +65,7 @@ public:
|
|||
private:
|
||||
DrmScopedPointer<drmModeConnector> m_conn;
|
||||
QVector<uint32_t> m_encoders;
|
||||
|
||||
QScopedPointer<Edid> m_edid;
|
||||
Edid m_edid;
|
||||
QSize m_physicalSize = QSize(-1, -1);
|
||||
|
||||
};
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "drm_backend.h"
|
||||
#include "drm_object_crtc.h"
|
||||
#include "drm_object_connector.h"
|
||||
#include "edid.h"
|
||||
|
||||
#include "composite.h"
|
||||
#include "cursor.h"
|
||||
|
|
Loading…
Reference in a new issue