From 872aa556302576a4dbe9e93d6012f6df60ea30ae Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Sun, 22 Oct 2023 14:52:13 +0200 Subject: [PATCH] allow setting the icc profile through the output management protocol --- src/backends/drm/drm_output.cpp | 2 +- src/core/output.cpp | 3 +++ src/core/output.h | 2 ++ src/wayland/outputdevice_v2.cpp | 29 ++++++++++++++++++++++++++++- src/wayland/outputdevice_v2.h | 1 + src/wayland/outputmanagement_v2.cpp | 13 ++++++++++++- 6 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 8cd19dd197..aedfeb4139 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -43,7 +43,7 @@ DrmOutput::DrmOutput(const std::shared_ptr &conn) m_pipeline->setOutput(this); m_renderLoop->setRefreshRate(m_pipeline->mode()->refreshRate()); - Capabilities capabilities = Capability::Dpms; + Capabilities capabilities = Capability::Dpms | Capability::IccProfile; State initialState; if (conn->overscan.isValid() || conn->underscan.isValid()) { diff --git a/src/core/output.cpp b/src/core/output.cpp index 41d92d954e..bf77a6c107 100644 --- a/src/core/output.cpp +++ b/src/core/output.cpp @@ -418,6 +418,9 @@ void Output::setState(const State &state) if (oldState.iccProfile != state.iccProfile) { Q_EMIT iccProfileChanged(); } + if (oldState.iccProfilePath != state.iccProfilePath) { + Q_EMIT iccProfilePathChanged(); + } if (oldState.enabled != state.enabled) { Q_EMIT enabledChanged(); } diff --git a/src/core/output.h b/src/core/output.h index 05ae7a924e..8fc4960063 100644 --- a/src/core/output.h +++ b/src/core/output.h @@ -135,6 +135,7 @@ public: HighDynamicRange = 1 << 4, WideColorGamut = 1 << 5, AutoRotation = 1 << 6, + IccProfile = 1 << 7, }; Q_DECLARE_FLAGS(Capabilities, Capability) @@ -380,6 +381,7 @@ Q_SIGNALS: void highDynamicRangeChanged(); void autoRotationPolicyChanged(); void iccProfileChanged(); + void iccProfilePathChanged(); protected: struct Information diff --git a/src/wayland/outputdevice_v2.cpp b/src/wayland/outputdevice_v2.cpp index 03b116671d..eacd31722a 100644 --- a/src/wayland/outputdevice_v2.cpp +++ b/src/wayland/outputdevice_v2.cpp @@ -22,7 +22,7 @@ namespace KWin { -static const quint32 s_version = 4; +static const quint32 s_version = 5; static QtWaylandServer::kde_output_device_v2::transform kwinTransformToOutputDeviceTransform(OutputTransform transform) { @@ -55,6 +55,9 @@ static uint32_t kwinCapabilitiesToOutputDeviceCapabilities(Output::Capabilities if (caps & Output::Capability::AutoRotation) { ret |= QtWaylandServer::kde_output_device_v2::capability_auto_rotate; } + if (caps & Output::Capability::IccProfile) { + ret |= QtWaylandServer::kde_output_device_v2::capability_icc_profile; + } return ret; } @@ -98,6 +101,7 @@ public: void sendSdrBrightness(Resource *resource); void sendWideColorGamut(Resource *resource); void sendAutoRotationPolicy(Resource *resource); + void sendIccProfilePath(Resource *resource); OutputDeviceV2Interface *q; QPointer m_display; @@ -125,6 +129,7 @@ public: uint32_t m_sdrBrightness = 200; bool m_wideColorGamut = false; auto_rotate_policy m_autoRotation = auto_rotate_policy::auto_rotate_policy_in_tablet_mode; + QString m_iccProfilePath; protected: void kde_output_device_v2_bind_resource(Resource *resource) override; @@ -206,6 +211,7 @@ OutputDeviceV2Interface::OutputDeviceV2Interface(Display *display, Output *handl updateSdrBrightness(); updateWideColorGamut(); updateAutoRotate(); + updateIccProfilePath(); connect(handle, &Output::geometryChanged, this, &OutputDeviceV2Interface::updateGlobalPosition); @@ -231,6 +237,7 @@ OutputDeviceV2Interface::OutputDeviceV2Interface(Display *display, Output *handl connect(handle, &Output::sdrBrightnessChanged, this, &OutputDeviceV2Interface::updateSdrBrightness); connect(handle, &Output::wideColorGamutChanged, this, &OutputDeviceV2Interface::updateWideColorGamut); connect(handle, &Output::autoRotationPolicyChanged, this, &OutputDeviceV2Interface::updateAutoRotate); + connect(handle, &Output::iccProfileChanged, this, &OutputDeviceV2Interface::updateIccProfilePath); } OutputDeviceV2Interface::~OutputDeviceV2Interface() @@ -285,6 +292,7 @@ void OutputDeviceV2InterfacePrivate::kde_output_device_v2_bind_resource(Resource sendSdrBrightness(resource); sendWideColorGamut(resource); sendAutoRotationPolicy(resource); + sendIccProfilePath(resource); sendDone(resource); } @@ -410,6 +418,13 @@ void OutputDeviceV2InterfacePrivate::sendAutoRotationPolicy(Resource *resource) } } +void OutputDeviceV2InterfacePrivate::sendIccProfilePath(Resource *resource) +{ + if (resource->version() >= KDE_OUTPUT_DEVICE_V2_ICC_PROFILE_PATH_SINCE_VERSION) { + send_icc_profile_path(resource->handle, m_iccProfilePath); + } +} + void OutputDeviceV2Interface::updateGeometry() { const auto clientResources = d->resourceMap(); @@ -679,6 +694,18 @@ void OutputDeviceV2Interface::updateAutoRotate() } } +void OutputDeviceV2Interface::updateIccProfilePath() +{ + if (d->m_iccProfilePath != d->m_handle->iccProfilePath()) { + d->m_iccProfilePath = d->m_handle->iccProfilePath(); + const auto clientResources = d->resourceMap(); + for (const auto &resource : clientResources) { + d->sendIccProfilePath(resource); + d->sendDone(resource); + } + } +} + OutputDeviceV2Interface *OutputDeviceV2Interface::get(wl_resource *native) { if (auto devicePrivate = resource_cast(native); devicePrivate && !devicePrivate->isGlobalRemoved()) { diff --git a/src/wayland/outputdevice_v2.h b/src/wayland/outputdevice_v2.h index 674380260f..6bdfa87f05 100644 --- a/src/wayland/outputdevice_v2.h +++ b/src/wayland/outputdevice_v2.h @@ -73,6 +73,7 @@ private: void updateSdrBrightness(); void updateWideColorGamut(); void updateAutoRotate(); + void updateIccProfilePath(); std::unique_ptr d; }; diff --git a/src/wayland/outputmanagement_v2.cpp b/src/wayland/outputmanagement_v2.cpp index 346307a25b..4f8c7ce507 100644 --- a/src/wayland/outputmanagement_v2.cpp +++ b/src/wayland/outputmanagement_v2.cpp @@ -23,7 +23,7 @@ namespace KWin { -static const quint32 s_version = 5; +static const quint32 s_version = 6; class OutputManagementV2InterfacePrivate : public QtWaylandServer::kde_output_management_v2 { @@ -63,6 +63,7 @@ protected: void kde_output_configuration_v2_set_sdr_brightness(Resource *resource, wl_resource *outputdevice, uint32_t sdr_brightness) override; void kde_output_configuration_v2_set_wide_color_gamut(Resource *resource, wl_resource *outputdevice, uint32_t enable_wcg) override; void kde_output_configuration_v2_set_auto_rotate_policy(Resource *resource, wl_resource *outputdevice, uint32_t auto_rotation_policy) override; + void kde_output_configuration_v2_set_icc_profile_path(Resource *resource, wl_resource *outputdevice, const QString &profile_path) override; }; OutputManagementV2InterfacePrivate::OutputManagementV2InterfacePrivate(Display *display) @@ -284,6 +285,16 @@ void OutputConfigurationV2Interface::kde_output_configuration_v2_set_auto_rotate } } +void OutputConfigurationV2Interface::kde_output_configuration_v2_set_icc_profile_path(Resource *resource, wl_resource *outputdevice, const QString &profile_path) +{ + if (invalid) { + return; + } + if (OutputDeviceV2Interface *output = OutputDeviceV2Interface::get(outputdevice)) { + config.changeSet(output->handle())->iccProfilePath = profile_path; + } +} + void OutputConfigurationV2Interface::kde_output_configuration_v2_destroy(Resource *resource) { wl_resource_destroy(resource->handle);