File indexing completed on 2024-06-16 05:05:12

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
0006     SPDX-FileCopyrightText: 2021-2022 Xaver Hugl <xaver.hugl@gmail.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "drm_property.h"
0012 #include "drm_gpu.h"
0013 #include "drm_logging.h"
0014 #include "drm_object.h"
0015 #include <cerrno>
0016 
0017 namespace KWin
0018 {
0019 
0020 DrmProperty::DrmProperty(DrmObject *obj, const QByteArray &name, const QList<QByteArray> &enumNames)
0021     : m_obj(obj)
0022     , m_propName(name)
0023     , m_enumNames(enumNames)
0024 {
0025 }
0026 
0027 bool DrmProperty::setPropertyLegacy(uint64_t value)
0028 {
0029     if (m_current == value) {
0030         return true;
0031     } else if (drmModeObjectSetProperty(m_obj->gpu()->fd(), m_obj->id(), m_obj->type(), m_propId, value) == 0) {
0032         m_current = value;
0033         return true;
0034     } else {
0035         return false;
0036     }
0037 }
0038 
0039 void DrmProperty::update(DrmPropertyList &propertyList)
0040 {
0041     if (const auto opt = propertyList.takeProperty(m_propName)) {
0042         const auto &[prop, value] = *opt;
0043         m_propId = prop->prop_id;
0044         m_current = value;
0045         m_immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
0046         m_isBlob = prop->flags & DRM_MODE_PROP_BLOB;
0047         m_isBitmask = prop->flags & DRM_MODE_PROP_BITMASK;
0048         if (prop->flags & DRM_MODE_PROP_RANGE) {
0049             Q_ASSERT(prop->count_values > 1);
0050             m_minValue = prop->values[0];
0051             m_maxValue = prop->values[1];
0052         }
0053         m_enumToPropertyMap.clear();
0054         m_propertyToEnumMap.clear();
0055         // bitmasks need translation too, not just enums
0056         if (prop->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
0057             for (int i = 0; i < prop->count_enums; i++) {
0058                 struct drm_mode_property_enum *en = &prop->enums[i];
0059                 int j = m_enumNames.indexOf(QByteArray(en->name));
0060                 if (j >= 0) {
0061                     if (m_isBitmask) {
0062                         m_enumToPropertyMap[1 << j] = 1 << en->value;
0063                         m_propertyToEnumMap[1 << en->value] = 1 << j;
0064                     } else {
0065                         m_enumToPropertyMap[j] = en->value;
0066                         m_propertyToEnumMap[en->value] = j;
0067                     }
0068                 }
0069             }
0070         }
0071         if (m_immutable && m_isBlob) {
0072             if (m_current != 0) {
0073                 m_immutableBlob.reset(drmModeGetPropertyBlob(m_obj->gpu()->fd(), m_current));
0074                 if (m_immutableBlob && (!m_immutableBlob->data || !m_immutableBlob->length)) {
0075                     m_immutableBlob.reset();
0076                 }
0077             } else {
0078                 m_immutableBlob.reset();
0079             }
0080         }
0081     } else {
0082         m_propId = 0;
0083         m_immutableBlob.reset();
0084         m_enumToPropertyMap.clear();
0085         m_propertyToEnumMap.clear();
0086     }
0087 }
0088 
0089 uint64_t DrmProperty::value() const
0090 {
0091     return m_current;
0092 }
0093 
0094 bool DrmProperty::hasAllEnums() const
0095 {
0096     return m_enumToPropertyMap.count() == m_enumNames.count();
0097 }
0098 
0099 uint32_t DrmProperty::propId() const
0100 {
0101     return m_propId;
0102 }
0103 
0104 const QByteArray &DrmProperty::name() const
0105 {
0106     return m_propName;
0107 }
0108 
0109 bool DrmProperty::isImmutable() const
0110 {
0111     return m_immutable;
0112 }
0113 
0114 bool DrmProperty::isBitmask() const
0115 {
0116     return m_isBitmask;
0117 }
0118 
0119 uint64_t DrmProperty::minValue() const
0120 {
0121     return m_minValue;
0122 }
0123 
0124 uint64_t DrmProperty::maxValue() const
0125 {
0126     return m_maxValue;
0127 }
0128 
0129 drmModePropertyBlobRes *DrmProperty::immutableBlob() const
0130 {
0131     return m_immutableBlob.get();
0132 }
0133 
0134 DrmObject *DrmProperty::drmObject() const
0135 {
0136     return m_obj;
0137 }
0138 
0139 bool DrmProperty::isValid() const
0140 {
0141     return m_propId != 0;
0142 }
0143 }