File indexing completed on 2024-11-10 04:57:29
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 SPDX-FileCopyrightText: 2021 Méven Car <meven.car@enioka.com> 0004 0005 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 #include "outputdevice_v2.h" 0008 0009 #include "display.h" 0010 #include "display_p.h" 0011 #include "utils/common.h" 0012 #include "utils/resource.h" 0013 0014 #include "core/output.h" 0015 0016 #include <QDebug> 0017 #include <QPointer> 0018 #include <QString> 0019 0020 #include "qwayland-server-kde-output-device-v2.h" 0021 0022 namespace KWin 0023 { 0024 0025 static const quint32 s_version = 6; 0026 0027 static QtWaylandServer::kde_output_device_v2::transform kwinTransformToOutputDeviceTransform(OutputTransform transform) 0028 { 0029 return static_cast<QtWaylandServer::kde_output_device_v2::transform>(transform.kind()); 0030 } 0031 0032 static QtWaylandServer::kde_output_device_v2::subpixel kwinSubPixelToOutputDeviceSubPixel(Output::SubPixel subPixel) 0033 { 0034 return static_cast<QtWaylandServer::kde_output_device_v2::subpixel>(subPixel); 0035 } 0036 0037 static uint32_t kwinCapabilitiesToOutputDeviceCapabilities(Output::Capabilities caps) 0038 { 0039 uint32_t ret = 0; 0040 if (caps & Output::Capability::Overscan) { 0041 ret |= QtWaylandServer::kde_output_device_v2::capability_overscan; 0042 } 0043 if (caps & Output::Capability::Vrr) { 0044 ret |= QtWaylandServer::kde_output_device_v2::capability_vrr; 0045 } 0046 if (caps & Output::Capability::RgbRange) { 0047 ret |= QtWaylandServer::kde_output_device_v2::capability_rgb_range; 0048 } 0049 if (caps & Output::Capability::HighDynamicRange) { 0050 ret |= QtWaylandServer::kde_output_device_v2::capability_high_dynamic_range; 0051 } 0052 if (caps & Output::Capability::WideColorGamut) { 0053 ret |= QtWaylandServer::kde_output_device_v2::capability_wide_color_gamut; 0054 } 0055 if (caps & Output::Capability::AutoRotation) { 0056 ret |= QtWaylandServer::kde_output_device_v2::capability_auto_rotate; 0057 } 0058 if (caps & Output::Capability::IccProfile) { 0059 ret |= QtWaylandServer::kde_output_device_v2::capability_icc_profile; 0060 } 0061 return ret; 0062 } 0063 0064 static QtWaylandServer::kde_output_device_v2::vrr_policy kwinVrrPolicyToOutputDeviceVrrPolicy(VrrPolicy policy) 0065 { 0066 return static_cast<QtWaylandServer::kde_output_device_v2::vrr_policy>(policy); 0067 } 0068 0069 static QtWaylandServer::kde_output_device_v2::rgb_range kwinRgbRangeToOutputDeviceRgbRange(Output::RgbRange range) 0070 { 0071 return static_cast<QtWaylandServer::kde_output_device_v2::rgb_range>(range); 0072 } 0073 0074 static QtWaylandServer::kde_output_device_v2::auto_rotate_policy kwinAutoRotationToOutputDeviceAutoRotation(Output::AutoRotationPolicy policy) 0075 { 0076 return static_cast<QtWaylandServer::kde_output_device_v2::auto_rotate_policy>(policy); 0077 } 0078 0079 class OutputDeviceV2InterfacePrivate : public QtWaylandServer::kde_output_device_v2 0080 { 0081 public: 0082 OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display, Output *handle); 0083 ~OutputDeviceV2InterfacePrivate() override; 0084 0085 void sendGeometry(Resource *resource); 0086 wl_resource *sendNewMode(Resource *resource, OutputDeviceModeV2Interface *mode); 0087 void sendCurrentMode(Resource *resource); 0088 void sendDone(Resource *resource); 0089 void sendUuid(Resource *resource); 0090 void sendEdid(Resource *resource); 0091 void sendEnabled(Resource *resource); 0092 void sendScale(Resource *resource); 0093 void sendEisaId(Resource *resource); 0094 void sendName(Resource *resource); 0095 void sendSerialNumber(Resource *resource); 0096 void sendCapabilities(Resource *resource); 0097 void sendOverscan(Resource *resource); 0098 void sendVrrPolicy(Resource *resource); 0099 void sendRgbRange(Resource *resource); 0100 void sendHighDynamicRange(Resource *resource); 0101 void sendSdrBrightness(Resource *resource); 0102 void sendWideColorGamut(Resource *resource); 0103 void sendAutoRotationPolicy(Resource *resource); 0104 void sendIccProfilePath(Resource *resource); 0105 void sendBrightnessMetadata(Resource *resource); 0106 void sendBrightnessOverrides(Resource *resource); 0107 void sendSdrGamutWideness(Resource *resource); 0108 0109 OutputDeviceV2Interface *q; 0110 QPointer<Display> m_display; 0111 Output *m_handle; 0112 QSize m_physicalSize; 0113 QPoint m_globalPosition; 0114 QString m_manufacturer = QStringLiteral("org.kde.kwin"); 0115 QString m_model = QStringLiteral("none"); 0116 qreal m_scale = 1.0; 0117 QString m_serialNumber; 0118 QString m_eisaId; 0119 QString m_name; 0120 subpixel m_subPixel = subpixel_unknown; 0121 transform m_transform = transform_normal; 0122 QList<OutputDeviceModeV2Interface *> m_modes; 0123 OutputDeviceModeV2Interface *m_currentMode = nullptr; 0124 QByteArray m_edid; 0125 bool m_enabled = true; 0126 QUuid m_uuid; 0127 uint32_t m_capabilities = 0; 0128 uint32_t m_overscan = 0; 0129 vrr_policy m_vrrPolicy = vrr_policy_automatic; 0130 rgb_range m_rgbRange = rgb_range_automatic; 0131 bool m_highDynamicRange = false; 0132 uint32_t m_sdrBrightness = 200; 0133 bool m_wideColorGamut = false; 0134 auto_rotate_policy m_autoRotation = auto_rotate_policy::auto_rotate_policy_in_tablet_mode; 0135 QString m_iccProfilePath; 0136 std::optional<double> m_maxPeakBrightness; 0137 std::optional<double> m_maxAverageBrightness; 0138 double m_minBrightness = 0; 0139 double m_sdrGamutWideness = 0; 0140 std::optional<double> m_maxPeakBrightnessOverride; 0141 std::optional<double> m_maxAverageBrightnessOverride; 0142 std::optional<double> m_minBrightnessOverride; 0143 0144 protected: 0145 void kde_output_device_v2_bind_resource(Resource *resource) override; 0146 void kde_output_device_v2_destroy_global() override; 0147 }; 0148 0149 class OutputDeviceModeV2InterfacePrivate : public QtWaylandServer::kde_output_device_mode_v2 0150 { 0151 public: 0152 struct ModeResource : Resource 0153 { 0154 OutputDeviceV2InterfacePrivate::Resource *output; 0155 }; 0156 0157 OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, std::shared_ptr<OutputMode> handle); 0158 ~OutputDeviceModeV2InterfacePrivate() override; 0159 0160 Resource *createResource(OutputDeviceV2InterfacePrivate::Resource *output); 0161 Resource *findResource(OutputDeviceV2InterfacePrivate::Resource *output) const; 0162 0163 void bindResource(wl_resource *resource); 0164 0165 static OutputDeviceModeV2InterfacePrivate *get(OutputDeviceModeV2Interface *mode) 0166 { 0167 return mode->d.get(); 0168 } 0169 0170 OutputDeviceModeV2Interface *q; 0171 std::weak_ptr<OutputMode> m_handle; 0172 QSize m_size; 0173 int m_refreshRate = 60000; 0174 bool m_preferred = false; 0175 0176 protected: 0177 Resource *kde_output_device_mode_v2_allocate() override; 0178 }; 0179 0180 OutputDeviceV2InterfacePrivate::OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display, Output *handle) 0181 : QtWaylandServer::kde_output_device_v2(*display, s_version) 0182 , q(q) 0183 , m_display(display) 0184 , m_handle(handle) 0185 { 0186 DisplayPrivate *displayPrivate = DisplayPrivate::get(display); 0187 displayPrivate->outputdevicesV2.append(q); 0188 } 0189 0190 OutputDeviceV2InterfacePrivate::~OutputDeviceV2InterfacePrivate() 0191 { 0192 if (m_display) { 0193 DisplayPrivate *displayPrivate = DisplayPrivate::get(m_display); 0194 displayPrivate->outputdevicesV2.removeOne(q); 0195 } 0196 } 0197 0198 OutputDeviceV2Interface::OutputDeviceV2Interface(Display *display, Output *handle, QObject *parent) 0199 : QObject(parent) 0200 , d(new OutputDeviceV2InterfacePrivate(this, display, handle)) 0201 { 0202 updateEnabled(); 0203 updateManufacturer(); 0204 updateEdid(); 0205 updateUuid(); 0206 updateModel(); 0207 updatePhysicalSize(); 0208 updateGlobalPosition(); 0209 updateScale(); 0210 updateTransform(); 0211 updateEisaId(); 0212 updateSerialNumber(); 0213 updateSubPixel(); 0214 updateOverscan(); 0215 updateCapabilities(); 0216 updateVrrPolicy(); 0217 updateRgbRange(); 0218 updateName(); 0219 updateModes(); 0220 updateHighDynamicRange(); 0221 updateSdrBrightness(); 0222 updateWideColorGamut(); 0223 updateAutoRotate(); 0224 updateIccProfilePath(); 0225 updateBrightnessMetadata(); 0226 updateBrightnessOverrides(); 0227 updateSdrGamutWideness(); 0228 0229 connect(handle, &Output::geometryChanged, 0230 this, &OutputDeviceV2Interface::updateGlobalPosition); 0231 connect(handle, &Output::scaleChanged, 0232 this, &OutputDeviceV2Interface::updateScale); 0233 connect(handle, &Output::enabledChanged, 0234 this, &OutputDeviceV2Interface::updateEnabled); 0235 connect(handle, &Output::transformChanged, 0236 this, &OutputDeviceV2Interface::updateTransform); 0237 connect(handle, &Output::currentModeChanged, 0238 this, &OutputDeviceV2Interface::updateCurrentMode); 0239 connect(handle, &Output::capabilitiesChanged, 0240 this, &OutputDeviceV2Interface::updateCapabilities); 0241 connect(handle, &Output::overscanChanged, 0242 this, &OutputDeviceV2Interface::updateOverscan); 0243 connect(handle, &Output::vrrPolicyChanged, 0244 this, &OutputDeviceV2Interface::updateVrrPolicy); 0245 connect(handle, &Output::modesChanged, 0246 this, &OutputDeviceV2Interface::updateModes); 0247 connect(handle, &Output::rgbRangeChanged, 0248 this, &OutputDeviceV2Interface::updateRgbRange); 0249 connect(handle, &Output::highDynamicRangeChanged, this, &OutputDeviceV2Interface::updateHighDynamicRange); 0250 connect(handle, &Output::sdrBrightnessChanged, this, &OutputDeviceV2Interface::updateSdrBrightness); 0251 connect(handle, &Output::wideColorGamutChanged, this, &OutputDeviceV2Interface::updateWideColorGamut); 0252 connect(handle, &Output::autoRotationPolicyChanged, this, &OutputDeviceV2Interface::updateAutoRotate); 0253 connect(handle, &Output::iccProfileChanged, this, &OutputDeviceV2Interface::updateIccProfilePath); 0254 connect(handle, &Output::brightnessMetadataChanged, this, &OutputDeviceV2Interface::updateBrightnessMetadata); 0255 connect(handle, &Output::brightnessMetadataChanged, this, &OutputDeviceV2Interface::updateBrightnessOverrides); 0256 connect(handle, &Output::sdrGamutWidenessChanged, this, &OutputDeviceV2Interface::updateSdrGamutWideness); 0257 } 0258 0259 OutputDeviceV2Interface::~OutputDeviceV2Interface() 0260 { 0261 d->globalRemove(); 0262 } 0263 0264 void OutputDeviceV2Interface::remove() 0265 { 0266 if (d->isGlobalRemoved()) { 0267 return; 0268 } 0269 0270 if (d->m_display) { 0271 DisplayPrivate *displayPrivate = DisplayPrivate::get(d->m_display); 0272 displayPrivate->outputdevicesV2.removeOne(this); 0273 } 0274 0275 d->globalRemove(); 0276 } 0277 0278 Output *OutputDeviceV2Interface::handle() const 0279 { 0280 return d->m_handle; 0281 } 0282 0283 void OutputDeviceV2InterfacePrivate::kde_output_device_v2_destroy_global() 0284 { 0285 delete q; 0286 } 0287 0288 void OutputDeviceV2InterfacePrivate::kde_output_device_v2_bind_resource(Resource *resource) 0289 { 0290 sendGeometry(resource); 0291 sendScale(resource); 0292 sendEisaId(resource); 0293 sendName(resource); 0294 sendSerialNumber(resource); 0295 0296 for (OutputDeviceModeV2Interface *mode : std::as_const(m_modes)) { 0297 sendNewMode(resource, mode); 0298 } 0299 sendCurrentMode(resource); 0300 sendUuid(resource); 0301 sendEdid(resource); 0302 sendEnabled(resource); 0303 sendCapabilities(resource); 0304 sendOverscan(resource); 0305 sendVrrPolicy(resource); 0306 sendRgbRange(resource); 0307 sendHighDynamicRange(resource); 0308 sendSdrBrightness(resource); 0309 sendWideColorGamut(resource); 0310 sendAutoRotationPolicy(resource); 0311 sendIccProfilePath(resource); 0312 sendBrightnessMetadata(resource); 0313 sendBrightnessOverrides(resource); 0314 sendSdrGamutWideness(resource); 0315 sendDone(resource); 0316 } 0317 0318 wl_resource *OutputDeviceV2InterfacePrivate::sendNewMode(Resource *resource, OutputDeviceModeV2Interface *mode) 0319 { 0320 auto privateMode = OutputDeviceModeV2InterfacePrivate::get(mode); 0321 // bind mode to client 0322 const auto modeResource = privateMode->createResource(resource); 0323 0324 send_mode(resource->handle, modeResource->handle); 0325 0326 privateMode->bindResource(modeResource->handle); 0327 0328 return modeResource->handle; 0329 } 0330 0331 void OutputDeviceV2InterfacePrivate::sendCurrentMode(Resource *outputResource) 0332 { 0333 const auto modeResource = OutputDeviceModeV2InterfacePrivate::get(m_currentMode)->findResource(outputResource); 0334 send_current_mode(outputResource->handle, modeResource->handle); 0335 } 0336 0337 void OutputDeviceV2InterfacePrivate::sendGeometry(Resource *resource) 0338 { 0339 send_geometry(resource->handle, 0340 m_globalPosition.x(), 0341 m_globalPosition.y(), 0342 m_physicalSize.width(), 0343 m_physicalSize.height(), 0344 m_subPixel, 0345 m_manufacturer, 0346 m_model, 0347 m_transform); 0348 } 0349 0350 void OutputDeviceV2InterfacePrivate::sendScale(Resource *resource) 0351 { 0352 send_scale(resource->handle, wl_fixed_from_double(m_scale)); 0353 } 0354 0355 void OutputDeviceV2InterfacePrivate::sendSerialNumber(Resource *resource) 0356 { 0357 send_serial_number(resource->handle, m_serialNumber); 0358 } 0359 0360 void OutputDeviceV2InterfacePrivate::sendEisaId(Resource *resource) 0361 { 0362 send_eisa_id(resource->handle, m_eisaId); 0363 } 0364 0365 void OutputDeviceV2InterfacePrivate::sendName(Resource *resource) 0366 { 0367 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_NAME_SINCE_VERSION) { 0368 send_name(resource->handle, m_name); 0369 } 0370 } 0371 0372 void OutputDeviceV2InterfacePrivate::sendDone(Resource *resource) 0373 { 0374 send_done(resource->handle); 0375 } 0376 0377 void OutputDeviceV2InterfacePrivate::sendEdid(Resource *resource) 0378 { 0379 send_edid(resource->handle, QString::fromStdString(m_edid.toBase64().toStdString())); 0380 } 0381 0382 void OutputDeviceV2InterfacePrivate::sendEnabled(Resource *resource) 0383 { 0384 send_enabled(resource->handle, m_enabled); 0385 } 0386 0387 void OutputDeviceV2InterfacePrivate::sendUuid(Resource *resource) 0388 { 0389 send_uuid(resource->handle, m_uuid.toString(QUuid::WithoutBraces)); 0390 } 0391 0392 void OutputDeviceV2InterfacePrivate::sendCapabilities(Resource *resource) 0393 { 0394 send_capabilities(resource->handle, m_capabilities); 0395 } 0396 0397 void OutputDeviceV2InterfacePrivate::sendOverscan(Resource *resource) 0398 { 0399 send_overscan(resource->handle, m_overscan); 0400 } 0401 0402 void OutputDeviceV2InterfacePrivate::sendVrrPolicy(Resource *resource) 0403 { 0404 send_vrr_policy(resource->handle, m_vrrPolicy); 0405 } 0406 0407 void OutputDeviceV2InterfacePrivate::sendRgbRange(Resource *resource) 0408 { 0409 send_rgb_range(resource->handle, m_rgbRange); 0410 } 0411 0412 void OutputDeviceV2InterfacePrivate::sendHighDynamicRange(Resource *resource) 0413 { 0414 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_HIGH_DYNAMIC_RANGE_SINCE_VERSION) { 0415 send_high_dynamic_range(resource->handle, m_highDynamicRange ? 1 : 0); 0416 } 0417 } 0418 0419 void OutputDeviceV2InterfacePrivate::sendSdrBrightness(Resource *resource) 0420 { 0421 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_SDR_BRIGHTNESS_SINCE_VERSION) { 0422 send_sdr_brightness(resource->handle, m_sdrBrightness); 0423 } 0424 } 0425 0426 void OutputDeviceV2InterfacePrivate::sendWideColorGamut(Resource *resource) 0427 { 0428 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_WIDE_COLOR_GAMUT_SINCE_VERSION) { 0429 send_wide_color_gamut(resource->handle, m_wideColorGamut ? 1 : 0); 0430 } 0431 } 0432 0433 void OutputDeviceV2InterfacePrivate::sendAutoRotationPolicy(Resource *resource) 0434 { 0435 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_SINCE_VERSION) { 0436 send_auto_rotate_policy(resource->handle, m_autoRotation); 0437 } 0438 } 0439 0440 void OutputDeviceV2InterfacePrivate::sendIccProfilePath(Resource *resource) 0441 { 0442 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_ICC_PROFILE_PATH_SINCE_VERSION) { 0443 send_icc_profile_path(resource->handle, m_iccProfilePath); 0444 } 0445 } 0446 0447 void OutputDeviceV2InterfacePrivate::sendBrightnessMetadata(Resource *resource) 0448 { 0449 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_METADATA_SINCE_VERSION) { 0450 send_brightness_metadata(resource->handle, std::round(m_maxPeakBrightness.value_or(0)), std::round(m_maxAverageBrightness.value_or(0)), std::round(m_minBrightness * 10'000)); 0451 } 0452 } 0453 0454 void OutputDeviceV2InterfacePrivate::sendBrightnessOverrides(Resource *resource) 0455 { 0456 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_OVERRIDES_SINCE_VERSION) { 0457 send_brightness_overrides(resource->handle, std::round(m_maxPeakBrightnessOverride.value_or(-1)), std::round(m_maxAverageBrightnessOverride.value_or(-1)), std::round(m_minBrightnessOverride.value_or(-0.000'1) * 10'000)); 0458 } 0459 } 0460 0461 void OutputDeviceV2InterfacePrivate::sendSdrGamutWideness(Resource *resource) 0462 { 0463 if (resource->version() >= KDE_OUTPUT_DEVICE_V2_SDR_GAMUT_WIDENESS_SINCE_VERSION) { 0464 send_sdr_gamut_wideness(resource->handle, std::clamp<uint32_t>(m_sdrGamutWideness * 10'000, 0, 10'000)); 0465 } 0466 } 0467 0468 void OutputDeviceV2Interface::updateGeometry() 0469 { 0470 const auto clientResources = d->resourceMap(); 0471 for (const auto &resource : clientResources) { 0472 d->sendGeometry(resource); 0473 d->sendDone(resource); 0474 } 0475 } 0476 0477 void OutputDeviceV2Interface::updatePhysicalSize() 0478 { 0479 d->m_physicalSize = d->m_handle->physicalSize(); 0480 } 0481 0482 void OutputDeviceV2Interface::updateGlobalPosition() 0483 { 0484 const QPoint arg = d->m_handle->geometry().topLeft(); 0485 if (d->m_globalPosition == arg) { 0486 return; 0487 } 0488 d->m_globalPosition = arg; 0489 updateGeometry(); 0490 } 0491 0492 void OutputDeviceV2Interface::updateManufacturer() 0493 { 0494 d->m_manufacturer = d->m_handle->manufacturer(); 0495 } 0496 0497 void OutputDeviceV2Interface::updateModel() 0498 { 0499 d->m_model = d->m_handle->model(); 0500 } 0501 0502 void OutputDeviceV2Interface::updateSerialNumber() 0503 { 0504 d->m_serialNumber = d->m_handle->serialNumber(); 0505 } 0506 0507 void OutputDeviceV2Interface::updateEisaId() 0508 { 0509 d->m_eisaId = d->m_handle->eisaId(); 0510 } 0511 0512 void OutputDeviceV2Interface::updateName() 0513 { 0514 d->m_name = d->m_handle->name(); 0515 } 0516 0517 void OutputDeviceV2Interface::updateSubPixel() 0518 { 0519 const auto arg = kwinSubPixelToOutputDeviceSubPixel(d->m_handle->subPixel()); 0520 if (d->m_subPixel != arg) { 0521 d->m_subPixel = arg; 0522 updateGeometry(); 0523 } 0524 } 0525 0526 void OutputDeviceV2Interface::updateTransform() 0527 { 0528 const auto arg = kwinTransformToOutputDeviceTransform(d->m_handle->transform()); 0529 if (d->m_transform != arg) { 0530 d->m_transform = arg; 0531 updateGeometry(); 0532 } 0533 } 0534 0535 void OutputDeviceV2Interface::updateScale() 0536 { 0537 const qreal scale = d->m_handle->scale(); 0538 if (qFuzzyCompare(d->m_scale, scale)) { 0539 return; 0540 } 0541 d->m_scale = scale; 0542 const auto clientResources = d->resourceMap(); 0543 for (const auto &resource : clientResources) { 0544 d->sendScale(resource); 0545 d->sendDone(resource); 0546 } 0547 } 0548 0549 void OutputDeviceV2Interface::updateModes() 0550 { 0551 const auto oldModes = d->m_modes; 0552 d->m_modes.clear(); 0553 d->m_currentMode = nullptr; 0554 0555 const auto clientResources = d->resourceMap(); 0556 const auto nativeModes = d->m_handle->modes(); 0557 0558 for (const std::shared_ptr<OutputMode> &mode : nativeModes) { 0559 OutputDeviceModeV2Interface *deviceMode = new OutputDeviceModeV2Interface(mode, this); 0560 d->m_modes.append(deviceMode); 0561 0562 if (d->m_handle->currentMode() == mode) { 0563 d->m_currentMode = deviceMode; 0564 } 0565 0566 for (auto resource : clientResources) { 0567 d->sendNewMode(resource, deviceMode); 0568 } 0569 } 0570 0571 for (auto resource : clientResources) { 0572 d->sendCurrentMode(resource); 0573 } 0574 0575 qDeleteAll(oldModes.crbegin(), oldModes.crend()); 0576 0577 for (auto resource : clientResources) { 0578 d->sendDone(resource); 0579 } 0580 } 0581 0582 void OutputDeviceV2Interface::updateCurrentMode() 0583 { 0584 for (OutputDeviceModeV2Interface *mode : std::as_const(d->m_modes)) { 0585 if (mode->handle().lock() == d->m_handle->currentMode()) { 0586 if (d->m_currentMode != mode) { 0587 d->m_currentMode = mode; 0588 const auto clientResources = d->resourceMap(); 0589 for (auto resource : clientResources) { 0590 d->sendCurrentMode(resource); 0591 d->sendDone(resource); 0592 } 0593 updateGeometry(); 0594 } 0595 return; 0596 } 0597 } 0598 } 0599 0600 void OutputDeviceV2Interface::updateEdid() 0601 { 0602 d->m_edid = d->m_handle->edid().raw(); 0603 const auto clientResources = d->resourceMap(); 0604 for (const auto &resource : clientResources) { 0605 d->sendEdid(resource); 0606 d->sendDone(resource); 0607 } 0608 } 0609 0610 void OutputDeviceV2Interface::updateEnabled() 0611 { 0612 bool enabled = d->m_handle->isEnabled(); 0613 if (d->m_enabled != enabled) { 0614 d->m_enabled = enabled; 0615 const auto clientResources = d->resourceMap(); 0616 for (const auto &resource : clientResources) { 0617 d->sendEnabled(resource); 0618 d->sendDone(resource); 0619 } 0620 } 0621 } 0622 0623 void OutputDeviceV2Interface::updateUuid() 0624 { 0625 const QUuid uuid = d->m_handle->uuid(); 0626 if (d->m_uuid != uuid) { 0627 d->m_uuid = uuid; 0628 const auto clientResources = d->resourceMap(); 0629 for (const auto &resource : clientResources) { 0630 d->sendUuid(resource); 0631 d->sendDone(resource); 0632 } 0633 } 0634 } 0635 0636 void OutputDeviceV2Interface::updateCapabilities() 0637 { 0638 const uint32_t cap = kwinCapabilitiesToOutputDeviceCapabilities(d->m_handle->capabilities()); 0639 if (d->m_capabilities != cap) { 0640 d->m_capabilities = cap; 0641 const auto clientResources = d->resourceMap(); 0642 for (const auto &resource : clientResources) { 0643 d->sendCapabilities(resource); 0644 d->sendDone(resource); 0645 } 0646 } 0647 } 0648 0649 void OutputDeviceV2Interface::updateOverscan() 0650 { 0651 const uint32_t overscan = d->m_handle->overscan(); 0652 if (d->m_overscan != overscan) { 0653 d->m_overscan = overscan; 0654 const auto clientResources = d->resourceMap(); 0655 for (const auto &resource : clientResources) { 0656 d->sendOverscan(resource); 0657 d->sendDone(resource); 0658 } 0659 } 0660 } 0661 0662 void OutputDeviceV2Interface::updateVrrPolicy() 0663 { 0664 const auto policy = kwinVrrPolicyToOutputDeviceVrrPolicy(d->m_handle->vrrPolicy()); 0665 if (d->m_vrrPolicy != policy) { 0666 d->m_vrrPolicy = policy; 0667 const auto clientResources = d->resourceMap(); 0668 for (const auto &resource : clientResources) { 0669 d->sendVrrPolicy(resource); 0670 d->sendDone(resource); 0671 } 0672 } 0673 } 0674 0675 void OutputDeviceV2Interface::updateRgbRange() 0676 { 0677 const auto rgbRange = kwinRgbRangeToOutputDeviceRgbRange(d->m_handle->rgbRange()); 0678 if (d->m_rgbRange != rgbRange) { 0679 d->m_rgbRange = rgbRange; 0680 const auto clientResources = d->resourceMap(); 0681 for (const auto &resource : clientResources) { 0682 d->sendRgbRange(resource); 0683 d->sendDone(resource); 0684 } 0685 } 0686 } 0687 0688 void OutputDeviceV2Interface::updateHighDynamicRange() 0689 { 0690 if (d->m_highDynamicRange != d->m_handle->highDynamicRange()) { 0691 d->m_highDynamicRange = d->m_handle->highDynamicRange(); 0692 const auto clientResources = d->resourceMap(); 0693 for (const auto &resource : clientResources) { 0694 d->sendHighDynamicRange(resource); 0695 d->sendDone(resource); 0696 } 0697 } 0698 } 0699 0700 void OutputDeviceV2Interface::updateSdrBrightness() 0701 { 0702 if (d->m_sdrBrightness != d->m_handle->sdrBrightness()) { 0703 d->m_sdrBrightness = d->m_handle->sdrBrightness(); 0704 const auto clientResources = d->resourceMap(); 0705 for (const auto &resource : clientResources) { 0706 d->sendSdrBrightness(resource); 0707 d->sendDone(resource); 0708 } 0709 } 0710 } 0711 0712 void OutputDeviceV2Interface::updateWideColorGamut() 0713 { 0714 if (d->m_wideColorGamut != d->m_handle->wideColorGamut()) { 0715 d->m_wideColorGamut = d->m_handle->wideColorGamut(); 0716 const auto clientResources = d->resourceMap(); 0717 for (const auto &resource : clientResources) { 0718 d->sendWideColorGamut(resource); 0719 d->sendDone(resource); 0720 } 0721 } 0722 } 0723 0724 void OutputDeviceV2Interface::updateAutoRotate() 0725 { 0726 const auto policy = kwinAutoRotationToOutputDeviceAutoRotation(d->m_handle->autoRotationPolicy()); 0727 if (d->m_autoRotation != policy) { 0728 d->m_autoRotation = policy; 0729 const auto clientResources = d->resourceMap(); 0730 for (const auto &resource : clientResources) { 0731 d->sendAutoRotationPolicy(resource); 0732 d->sendDone(resource); 0733 } 0734 } 0735 } 0736 0737 void OutputDeviceV2Interface::updateIccProfilePath() 0738 { 0739 if (d->m_iccProfilePath != d->m_handle->iccProfilePath()) { 0740 d->m_iccProfilePath = d->m_handle->iccProfilePath(); 0741 const auto clientResources = d->resourceMap(); 0742 for (const auto &resource : clientResources) { 0743 d->sendIccProfilePath(resource); 0744 d->sendDone(resource); 0745 } 0746 } 0747 } 0748 0749 void OutputDeviceV2Interface::updateBrightnessMetadata() 0750 { 0751 if (d->m_maxPeakBrightness != d->m_handle->maxPeakBrightness() || d->m_maxAverageBrightness != d->m_handle->maxAverageBrightness() || d->m_minBrightness != d->m_handle->minBrightness()) { 0752 d->m_maxPeakBrightness = d->m_handle->maxPeakBrightness(); 0753 d->m_maxAverageBrightness = d->m_handle->maxAverageBrightness(); 0754 d->m_minBrightness = d->m_handle->minBrightness(); 0755 const auto clientResources = d->resourceMap(); 0756 for (const auto &resource : clientResources) { 0757 d->sendBrightnessMetadata(resource); 0758 d->sendDone(resource); 0759 } 0760 } 0761 } 0762 0763 void OutputDeviceV2Interface::updateBrightnessOverrides() 0764 { 0765 if (d->m_maxPeakBrightnessOverride != d->m_handle->maxPeakBrightnessOverride() || d->m_maxAverageBrightnessOverride != d->m_handle->maxAverageBrightnessOverride() || d->m_minBrightnessOverride != d->m_handle->minBrightnessOverride()) { 0766 d->m_maxPeakBrightnessOverride = d->m_handle->maxPeakBrightnessOverride(); 0767 d->m_maxAverageBrightnessOverride = d->m_handle->maxAverageBrightnessOverride(); 0768 d->m_minBrightnessOverride = d->m_handle->minBrightnessOverride(); 0769 const auto clientResources = d->resourceMap(); 0770 for (const auto &resource : clientResources) { 0771 d->sendBrightnessOverrides(resource); 0772 d->sendDone(resource); 0773 } 0774 } 0775 } 0776 0777 void OutputDeviceV2Interface::updateSdrGamutWideness() 0778 { 0779 if (d->m_sdrGamutWideness != d->m_handle->sdrGamutWideness()) { 0780 d->m_sdrGamutWideness = d->m_handle->sdrGamutWideness(); 0781 const auto clientResources = d->resourceMap(); 0782 for (const auto &resource : clientResources) { 0783 d->sendSdrGamutWideness(resource); 0784 d->sendDone(resource); 0785 } 0786 } 0787 } 0788 0789 OutputDeviceV2Interface *OutputDeviceV2Interface::get(wl_resource *native) 0790 { 0791 if (auto devicePrivate = resource_cast<OutputDeviceV2InterfacePrivate *>(native); devicePrivate && !devicePrivate->isGlobalRemoved()) { 0792 return devicePrivate->q; 0793 } 0794 return nullptr; 0795 } 0796 0797 OutputDeviceModeV2InterfacePrivate::OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, std::shared_ptr<OutputMode> handle) 0798 : QtWaylandServer::kde_output_device_mode_v2() 0799 , q(q) 0800 , m_handle(handle) 0801 , m_size(handle->size()) 0802 , m_refreshRate(handle->refreshRate()) 0803 , m_preferred(handle->flags() & OutputMode::Flag::Preferred) 0804 { 0805 } 0806 0807 OutputDeviceModeV2Interface::OutputDeviceModeV2Interface(std::shared_ptr<OutputMode> handle, QObject *parent) 0808 : QObject(parent) 0809 , d(new OutputDeviceModeV2InterfacePrivate(this, handle)) 0810 { 0811 } 0812 0813 OutputDeviceModeV2Interface::~OutputDeviceModeV2Interface() = default; 0814 0815 OutputDeviceModeV2InterfacePrivate::~OutputDeviceModeV2InterfacePrivate() 0816 { 0817 const auto map = resourceMap(); 0818 for (Resource *resource : map) { 0819 send_removed(resource->handle); 0820 } 0821 } 0822 0823 OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::createResource(OutputDeviceV2InterfacePrivate::Resource *output) 0824 { 0825 const auto modeResource = static_cast<ModeResource *>(add(output->client(), output->version())); 0826 modeResource->output = output; 0827 return modeResource; 0828 } 0829 0830 OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::findResource(OutputDeviceV2InterfacePrivate::Resource *output) const 0831 { 0832 const auto resources = resourceMap(); 0833 for (const auto &resource : resources) { 0834 auto modeResource = static_cast<ModeResource *>(resource); 0835 if (modeResource->output == output) { 0836 return resource; 0837 } 0838 } 0839 return nullptr; 0840 } 0841 0842 OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::kde_output_device_mode_v2_allocate() 0843 { 0844 return new ModeResource; 0845 } 0846 0847 std::weak_ptr<OutputMode> OutputDeviceModeV2Interface::handle() const 0848 { 0849 return d->m_handle; 0850 } 0851 0852 void OutputDeviceModeV2InterfacePrivate::bindResource(wl_resource *resource) 0853 { 0854 send_size(resource, m_size.width(), m_size.height()); 0855 send_refresh(resource, m_refreshRate); 0856 0857 if (m_preferred) { 0858 send_preferred(resource); 0859 } 0860 } 0861 0862 OutputDeviceModeV2Interface *OutputDeviceModeV2Interface::get(wl_resource *native) 0863 { 0864 if (auto devicePrivate = resource_cast<OutputDeviceModeV2InterfacePrivate *>(native)) { 0865 return devicePrivate->q; 0866 } 0867 return nullptr; 0868 } 0869 0870 } 0871 0872 #include "moc_outputdevice_v2.cpp"