File indexing completed on 2024-11-10 04:56:30
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 }