diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2370a5d47..f99b90255f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -146,7 +146,6 @@ target_sources(kwin PRIVATE was_user_interaction_x11_filter.cpp wayland_server.cpp waylandoutput.cpp - waylandoutputdevicev2.cpp waylandshellintegration.cpp waylandwindow.cpp window.cpp diff --git a/src/platform.cpp b/src/platform.cpp index c042dde54e..e6b80bad90 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -140,19 +140,6 @@ bool Platform::applyOutputChanges(const OutputConfiguration &config) return true; } -Output *Platform::findOutput(const QUuid &uuid) const -{ - const auto outs = outputs(); - auto it = std::find_if(outs.constBegin(), outs.constEnd(), - [uuid](Output *output) { - return output->uuid() == uuid; - }); - if (it != outs.constEnd()) { - return *it; - } - return nullptr; -} - Output *Platform::findOutput(const QString &name) const { const auto candidates = outputs(); diff --git a/src/platform.h b/src/platform.h index cd1f07c8e0..53932af1f6 100644 --- a/src/platform.h +++ b/src/platform.h @@ -287,7 +287,6 @@ public: } virtual Outputs outputs() const = 0; - Output *findOutput(const QUuid &uuid) const; Output *findOutput(const QString &name) const; /** diff --git a/src/wayland/outputdevice_v2_interface.cpp b/src/wayland/outputdevice_v2_interface.cpp index 570a16d335..868b682dc0 100644 --- a/src/wayland/outputdevice_v2_interface.cpp +++ b/src/wayland/outputdevice_v2_interface.cpp @@ -11,26 +11,62 @@ #include "utils.h" #include "utils/common.h" +#include "output.h" + #include #include #include -#include - #include "qwayland-server-kde-output-device-v2.h" +using namespace KWin; + namespace KWaylandServer { + static const quint32 s_version = 2; +static QtWaylandServer::kde_output_device_v2::transform kwinTransformToOutputDeviceTransform(Output::Transform transform) +{ + return static_cast(transform); +} + +static QtWaylandServer::kde_output_device_v2::subpixel kwinSubPixelToOutputDeviceSubPixel(Output::SubPixel subPixel) +{ + return static_cast(subPixel); +} + +static uint32_t kwinCapabilitiesToOutputDeviceCapabilities(Output::Capabilities caps) +{ + uint32_t ret = 0; + if (caps & Output::Capability::Overscan) { + ret |= QtWaylandServer::kde_output_device_v2::capability_overscan; + } + if (caps & Output::Capability::Vrr) { + ret |= QtWaylandServer::kde_output_device_v2::capability_vrr; + } + if (caps & Output::Capability::RgbRange) { + ret |= QtWaylandServer::kde_output_device_v2::capability_rgb_range; + } + return ret; +} + +static QtWaylandServer::kde_output_device_v2::vrr_policy kwinVrrPolicyToOutputDeviceVrrPolicy(RenderLoop::VrrPolicy policy) +{ + return static_cast(policy); +} + +static QtWaylandServer::kde_output_device_v2::rgb_range kwinRgbRangeToOutputDeviceRgbRange(Output::RgbRange range) +{ + return static_cast(range); +} + class OutputDeviceV2InterfacePrivate : public QtWaylandServer::kde_output_device_v2 { public: OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display, KWin::Output *handle); ~OutputDeviceV2InterfacePrivate() override; - void updateGeometry(); - void sendGeometry(Resource *resource); wl_resource *sendNewMode(Resource *resource, OutputDeviceModeV2Interface *mode); void sendCurrentMode(Resource *resource); @@ -48,33 +84,27 @@ public: void sendRgbRange(Resource *resource); OutputDeviceV2Interface *q; - QPointer display; - KWin::Output *handle; - QSize physicalSize; - QPoint globalPosition; - QString manufacturer = QStringLiteral("org.kde.kwin"); - QString model = QStringLiteral("none"); - qreal scale = 1.0; - QString serialNumber; - QString eisaId; - QString name; - OutputDeviceV2Interface::SubPixel subPixel = OutputDeviceV2Interface::SubPixel::Unknown; - OutputDeviceV2Interface::Transform transform = OutputDeviceV2Interface::Transform::Normal; - - QList modes; - OutputDeviceModeV2Interface *currentMode = nullptr; - - QByteArray edid; - bool enabled = true; - QUuid uuid; - OutputDeviceV2Interface::Capabilities capabilities; - uint32_t overscan = 0; - OutputDeviceV2Interface::VrrPolicy vrrPolicy = OutputDeviceV2Interface::VrrPolicy::Automatic; - OutputDeviceV2Interface::RgbRange rgbRange = OutputDeviceV2Interface::RgbRange::Automatic; - -private: - int32_t toTransform() const; - int32_t toSubPixel() const; + QPointer m_display; + KWin::Output *m_handle; + QSize m_physicalSize; + QPoint m_globalPosition; + QString m_manufacturer = QStringLiteral("org.kde.kwin"); + QString m_model = QStringLiteral("none"); + qreal m_scale = 1.0; + QString m_serialNumber; + QString m_eisaId; + QString m_name; + subpixel m_subPixel = subpixel_unknown; + transform m_transform = transform_normal; + QList m_modes; + OutputDeviceModeV2Interface *m_currentMode = nullptr; + QByteArray m_edid; + bool m_enabled = true; + QUuid m_uuid; + uint32_t m_capabilities = 0; + uint32_t m_overscan = 0; + vrr_policy m_vrrPolicy = vrr_policy_automatic; + rgb_range m_rgbRange = rgb_range_automatic; protected: void kde_output_device_v2_bind_resource(Resource *resource) override; @@ -89,7 +119,7 @@ public: OutputDeviceV2InterfacePrivate::Resource *output; }; - OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, std::weak_ptr handle, const QSize &size, int refreshRate, OutputDeviceModeV2Interface::ModeFlags flags); + OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, std::shared_ptr handle); ~OutputDeviceModeV2InterfacePrivate() override; Resource *createResource(OutputDeviceV2InterfacePrivate::Resource *output); @@ -106,7 +136,7 @@ public: std::weak_ptr m_handle; QSize m_size; int m_refreshRate = 60000; - OutputDeviceModeV2Interface::ModeFlags m_flags; + bool m_preferred = false; protected: Resource *kde_output_device_mode_v2_allocate() override; @@ -115,8 +145,8 @@ protected: OutputDeviceV2InterfacePrivate::OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display, KWin::Output *handle) : QtWaylandServer::kde_output_device_v2(*display, s_version) , q(q) - , display(display) - , handle(handle) + , m_display(display) + , m_handle(handle) { DisplayPrivate *displayPrivate = DisplayPrivate::get(display); displayPrivate->outputdevicesV2.append(q); @@ -124,8 +154,8 @@ OutputDeviceV2InterfacePrivate::OutputDeviceV2InterfacePrivate(OutputDeviceV2Int OutputDeviceV2InterfacePrivate::~OutputDeviceV2InterfacePrivate() { - if (display) { - DisplayPrivate *displayPrivate = DisplayPrivate::get(display); + if (m_display) { + DisplayPrivate *displayPrivate = DisplayPrivate::get(m_display); displayPrivate->outputdevicesV2.removeOne(q); } } @@ -134,6 +164,44 @@ OutputDeviceV2Interface::OutputDeviceV2Interface(Display *display, KWin::Output : QObject(parent) , d(new OutputDeviceV2InterfacePrivate(this, display, handle)) { + updateManufacturer(); + updateEdid(); + updateUuid(); + updateModel(); + updatePhysicalSize(); + updateGlobalPosition(); + updateScale(); + updateTransform(); + updateEisaId(); + updateSerialNumber(); + updateSubPixel(); + updateOverscan(); + updateCapabilities(); + updateVrrPolicy(); + updateRgbRange(); + updateName(); + updateModes(); + + connect(handle, &Output::geometryChanged, + this, &OutputDeviceV2Interface::updateGlobalPosition); + connect(handle, &Output::scaleChanged, + this, &OutputDeviceV2Interface::updateScale); + connect(handle, &Output::enabledChanged, + this, &OutputDeviceV2Interface::updateEnabled); + connect(handle, &Output::transformChanged, + this, &OutputDeviceV2Interface::updateTransform); + connect(handle, &Output::currentModeChanged, + this, &OutputDeviceV2Interface::updateCurrentMode); + connect(handle, &Output::capabilitiesChanged, + this, &OutputDeviceV2Interface::updateCapabilities); + connect(handle, &Output::overscanChanged, + this, &OutputDeviceV2Interface::updateOverscan); + connect(handle, &Output::vrrPolicyChanged, + this, &OutputDeviceV2Interface::updateVrrPolicy); + connect(handle, &Output::modesChanged, + this, &OutputDeviceV2Interface::updateModes); + connect(handle, &Output::rgbRangeChanged, + this, &OutputDeviceV2Interface::updateRgbRange); } OutputDeviceV2Interface::~OutputDeviceV2Interface() @@ -147,8 +215,8 @@ void OutputDeviceV2Interface::remove() return; } - if (d->display) { - DisplayPrivate *displayPrivate = DisplayPrivate::get(d->display); + if (d->m_display) { + DisplayPrivate *displayPrivate = DisplayPrivate::get(d->m_display); displayPrivate->outputdevicesV2.removeOne(this); } @@ -157,90 +225,7 @@ void OutputDeviceV2Interface::remove() KWin::Output *OutputDeviceV2Interface::handle() const { - return d->handle; -} - -QSize OutputDeviceV2Interface::pixelSize() const -{ - if (d->currentMode == nullptr) { - return QSize(); - } - return d->currentMode->size(); -} - -int OutputDeviceV2Interface::refreshRate() const -{ - if (d->currentMode == nullptr) { - return 60000; - } - return d->currentMode->refreshRate(); -} - -QList OutputDeviceV2Interface::modes() const -{ - return d->modes; -} - -void OutputDeviceV2Interface::setCurrentMode(OutputDeviceModeV2Interface *mode) -{ - Q_ASSERT(d->modes.contains(mode)); - if (mode == d->currentMode) { - return; - } - - d->currentMode = mode; - - const auto clientResources = d->resourceMap(); - for (auto it = clientResources.begin(); it != clientResources.end(); ++it) { - auto resource = *it; - d->sendCurrentMode(resource); - d->sendDone(resource); - } - d->updateGeometry(); -} - -int32_t OutputDeviceV2InterfacePrivate::toTransform() const -{ - switch (transform) { - case OutputDeviceV2Interface::Transform::Normal: - return WL_OUTPUT_TRANSFORM_NORMAL; - case OutputDeviceV2Interface::Transform::Rotated90: - return WL_OUTPUT_TRANSFORM_90; - case OutputDeviceV2Interface::Transform::Rotated180: - return WL_OUTPUT_TRANSFORM_180; - case OutputDeviceV2Interface::Transform::Rotated270: - return WL_OUTPUT_TRANSFORM_270; - case OutputDeviceV2Interface::Transform::Flipped: - return WL_OUTPUT_TRANSFORM_FLIPPED; - case OutputDeviceV2Interface::Transform::Flipped90: - return WL_OUTPUT_TRANSFORM_FLIPPED_90; - case OutputDeviceV2Interface::Transform::Flipped180: - return WL_OUTPUT_TRANSFORM_FLIPPED_180; - case OutputDeviceV2Interface::Transform::Flipped270: - return WL_OUTPUT_TRANSFORM_FLIPPED_270; - default: - Q_UNREACHABLE(); - } -} - -int32_t OutputDeviceV2InterfacePrivate::toSubPixel() const -{ - switch (subPixel) { - case OutputDeviceV2Interface::SubPixel::Unknown: - return WL_OUTPUT_SUBPIXEL_UNKNOWN; - case OutputDeviceV2Interface::SubPixel::None: - return WL_OUTPUT_SUBPIXEL_NONE; - case OutputDeviceV2Interface::SubPixel::HorizontalRGB: - return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB; - case OutputDeviceV2Interface::SubPixel::HorizontalBGR: - return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR; - case OutputDeviceV2Interface::SubPixel::VerticalRGB: - return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB; - case OutputDeviceV2Interface::SubPixel::VerticalBGR: - return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR; - default: - Q_UNREACHABLE(); - } + return d->m_handle; } void OutputDeviceV2InterfacePrivate::kde_output_device_v2_destroy_global() @@ -256,7 +241,7 @@ void OutputDeviceV2InterfacePrivate::kde_output_device_v2_bind_resource(Resource sendName(resource); sendSerialNumber(resource); - for (OutputDeviceModeV2Interface *mode : std::as_const(modes)) { + for (OutputDeviceModeV2Interface *mode : std::as_const(m_modes)) { sendNewMode(resource, mode); } sendCurrentMode(resource); @@ -285,42 +270,42 @@ wl_resource *OutputDeviceV2InterfacePrivate::sendNewMode(Resource *resource, Out void OutputDeviceV2InterfacePrivate::sendCurrentMode(Resource *outputResource) { - const auto modeResource = OutputDeviceModeV2InterfacePrivate::get(currentMode)->findResource(outputResource); + const auto modeResource = OutputDeviceModeV2InterfacePrivate::get(m_currentMode)->findResource(outputResource); send_current_mode(outputResource->handle, modeResource->handle); } void OutputDeviceV2InterfacePrivate::sendGeometry(Resource *resource) { send_geometry(resource->handle, - globalPosition.x(), - globalPosition.y(), - physicalSize.width(), - physicalSize.height(), - toSubPixel(), - manufacturer, - model, - toTransform()); + m_globalPosition.x(), + m_globalPosition.y(), + m_physicalSize.width(), + m_physicalSize.height(), + m_subPixel, + m_manufacturer, + m_model, + m_transform); } void OutputDeviceV2InterfacePrivate::sendScale(Resource *resource) { - send_scale(resource->handle, wl_fixed_from_double(scale)); + send_scale(resource->handle, wl_fixed_from_double(m_scale)); } void OutputDeviceV2InterfacePrivate::sendSerialNumber(Resource *resource) { - send_serial_number(resource->handle, serialNumber); + send_serial_number(resource->handle, m_serialNumber); } void OutputDeviceV2InterfacePrivate::sendEisaId(Resource *resource) { - send_eisa_id(resource->handle, eisaId); + send_eisa_id(resource->handle, m_eisaId); } void OutputDeviceV2InterfacePrivate::sendName(Resource *resource) { if (resource->version() >= KDE_OUTPUT_DEVICE_V2_NAME_SINCE_VERSION) { - send_name(resource->handle, name); + send_name(resource->handle, m_name); } } @@ -329,96 +314,115 @@ void OutputDeviceV2InterfacePrivate::sendDone(Resource *resource) send_done(resource->handle); } -void OutputDeviceV2InterfacePrivate::updateGeometry() +void OutputDeviceV2InterfacePrivate::sendEdid(Resource *resource) { - const auto clientResources = resourceMap(); + send_edid(resource->handle, QString::fromStdString(m_edid.toBase64().toStdString())); +} + +void OutputDeviceV2InterfacePrivate::sendEnabled(Resource *resource) +{ + send_enabled(resource->handle, m_enabled); +} + +void OutputDeviceV2InterfacePrivate::sendUuid(Resource *resource) +{ + send_uuid(resource->handle, m_uuid.toString(QUuid::WithoutBraces)); +} + +void OutputDeviceV2InterfacePrivate::sendCapabilities(Resource *resource) +{ + send_capabilities(resource->handle, m_capabilities); +} + +void OutputDeviceV2InterfacePrivate::sendOverscan(Resource *resource) +{ + send_overscan(resource->handle, m_overscan); +} + +void OutputDeviceV2InterfacePrivate::sendVrrPolicy(Resource *resource) +{ + send_vrr_policy(resource->handle, m_vrrPolicy); +} + +void OutputDeviceV2InterfacePrivate::sendRgbRange(Resource *resource) +{ + send_rgb_range(resource->handle, m_rgbRange); +} + +void OutputDeviceV2Interface::updateGeometry() +{ + const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { - sendGeometry(resource); - sendDone(resource); + d->sendGeometry(resource); + d->sendDone(resource); } } -void OutputDeviceV2Interface::setPhysicalSize(const QSize &arg) +void OutputDeviceV2Interface::updatePhysicalSize() { - if (d->physicalSize == arg) { - return; - } - d->physicalSize = arg; + d->m_physicalSize = d->m_handle->physicalSize(); } -void OutputDeviceV2Interface::setGlobalPosition(const QPoint &arg) +void OutputDeviceV2Interface::updateGlobalPosition() { - if (d->globalPosition == arg) { + const QPoint arg = d->m_handle->geometry().topLeft(); + if (d->m_globalPosition == arg) { return; } - d->globalPosition = arg; - d->updateGeometry(); + d->m_globalPosition = arg; + updateGeometry(); } -void OutputDeviceV2Interface::setManufacturer(const QString &arg) +void OutputDeviceV2Interface::updateManufacturer() { - if (d->manufacturer == arg) { - return; - } - d->manufacturer = arg; + d->m_manufacturer = d->m_handle->manufacturer(); } -void OutputDeviceV2Interface::setModel(const QString &arg) +void OutputDeviceV2Interface::updateModel() { - if (d->model == arg) { - return; - } - d->model = arg; + d->m_model = d->m_handle->model(); } -void OutputDeviceV2Interface::setSerialNumber(const QString &arg) +void OutputDeviceV2Interface::updateSerialNumber() { - if (d->serialNumber == arg) { - return; - } - d->serialNumber = arg; + d->m_serialNumber = d->m_handle->serialNumber(); } -void OutputDeviceV2Interface::setEisaId(const QString &arg) +void OutputDeviceV2Interface::updateEisaId() { - if (d->eisaId == arg) { - return; - } - d->eisaId = arg; + d->m_eisaId = d->m_handle->eisaId(); } -void OutputDeviceV2Interface::setName(const QString &arg) +void OutputDeviceV2Interface::updateName() { - if (d->name == arg) { - return; - } - d->name = arg; + d->m_name = d->m_handle->name(); } -void OutputDeviceV2Interface::setSubPixel(SubPixel arg) +void OutputDeviceV2Interface::updateSubPixel() { - if (d->subPixel == arg) { - return; + const auto arg = kwinSubPixelToOutputDeviceSubPixel(d->m_handle->subPixel()); + if (d->m_subPixel != arg) { + d->m_subPixel = arg; + updateGeometry(); } - d->subPixel = arg; - d->updateGeometry(); } -void OutputDeviceV2Interface::setTransform(Transform arg) +void OutputDeviceV2Interface::updateTransform() { - if (d->transform == arg) { - return; + const auto arg = kwinTransformToOutputDeviceTransform(d->m_handle->transform()); + if (d->m_transform != arg) { + d->m_transform = arg; + updateGeometry(); } - d->transform = arg; - d->updateGeometry(); } -void OutputDeviceV2Interface::setScale(qreal scale) +void OutputDeviceV2Interface::updateScale() { - if (qFuzzyCompare(d->scale, scale)) { + const qreal scale = d->m_handle->scale(); + if (qFuzzyCompare(d->m_scale, scale)) { return; } - d->scale = scale; + d->m_scale = scale; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendScale(resource); @@ -426,77 +430,28 @@ void OutputDeviceV2Interface::setScale(qreal scale) } } -QSize OutputDeviceV2Interface::physicalSize() const +void OutputDeviceV2Interface::updateModes() { - return d->physicalSize; -} - -QPoint OutputDeviceV2Interface::globalPosition() const -{ - return d->globalPosition; -} - -QString OutputDeviceV2Interface::manufacturer() const -{ - return d->manufacturer; -} - -QString OutputDeviceV2Interface::model() const -{ - return d->model; -} - -QString OutputDeviceV2Interface::serialNumber() const -{ - return d->serialNumber; -} - -QString OutputDeviceV2Interface::eisaId() const -{ - return d->eisaId; -} - -QString OutputDeviceV2Interface::name() const -{ - return d->name; -} - -qreal OutputDeviceV2Interface::scale() const -{ - return d->scale; -} - -OutputDeviceV2Interface::SubPixel OutputDeviceV2Interface::subPixel() const -{ - return d->subPixel; -} - -OutputDeviceV2Interface::Transform OutputDeviceV2Interface::transform() const -{ - return d->transform; -} - -void OutputDeviceV2Interface::setModes(const QList &modes, OutputDeviceModeV2Interface *currentMode) -{ - if (modes.isEmpty()) { - qCWarning(KWIN_CORE) << "Tried to set no modes for output"; - return; - } + const auto oldModes = d->m_modes; + d->m_modes.clear(); + d->m_currentMode = nullptr; const auto clientResources = d->resourceMap(); + const auto nativeModes = d->m_handle->modes(); - const auto oldModes = d->modes; - d->modes.clear(); + for (const std::shared_ptr &mode : nativeModes) { + OutputDeviceModeV2Interface *deviceMode = new OutputDeviceModeV2Interface(mode, this); + d->m_modes.append(deviceMode); + + if (d->m_handle->currentMode() == mode) { + d->m_currentMode = deviceMode; + } - for (OutputDeviceModeV2Interface *outputDeviceMode : modes) { - d->modes << outputDeviceMode; - outputDeviceMode->setParent(this); for (auto resource : clientResources) { - d->sendNewMode(resource, outputDeviceMode); + d->sendNewMode(resource, deviceMode); } } - d->currentMode = currentMode; for (auto resource : clientResources) { d->sendCurrentMode(resource); } @@ -508,9 +463,27 @@ void OutputDeviceV2Interface::setModes(const QListedid = edid; + for (OutputDeviceModeV2Interface *mode : std::as_const(d->m_modes)) { + if (mode->handle().lock() == d->m_handle->currentMode()) { + if (d->m_currentMode != mode) { + d->m_currentMode = mode; + const auto clientResources = d->resourceMap(); + for (auto resource : clientResources) { + d->sendCurrentMode(resource); + d->sendDone(resource); + } + updateGeometry(); + } + return; + } + } +} + +void OutputDeviceV2Interface::updateEdid() +{ + d->m_edid = d->m_handle->edid(); const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendEdid(resource); @@ -518,15 +491,11 @@ void OutputDeviceV2Interface::setEdid(const QByteArray &edid) } } -QByteArray OutputDeviceV2Interface::edid() const +void OutputDeviceV2Interface::updateEnabled() { - return d->edid; -} - -void OutputDeviceV2Interface::setEnabled(bool enabled) -{ - if (d->enabled != enabled) { - d->enabled = enabled; + bool enabled = d->m_handle->isEnabled(); + if (d->m_enabled != enabled) { + d->m_enabled = enabled; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendEnabled(resource); @@ -535,15 +504,11 @@ void OutputDeviceV2Interface::setEnabled(bool enabled) } } -bool OutputDeviceV2Interface::enabled() const +void OutputDeviceV2Interface::updateUuid() { - return d->enabled; -} - -void OutputDeviceV2Interface::setUuid(const QUuid &uuid) -{ - if (d->uuid != uuid) { - d->uuid = uuid; + const QUuid uuid = d->m_handle->uuid(); + if (d->m_uuid != uuid) { + d->m_uuid = uuid; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendUuid(resource); @@ -552,40 +517,11 @@ void OutputDeviceV2Interface::setUuid(const QUuid &uuid) } } -QUuid OutputDeviceV2Interface::uuid() const +void OutputDeviceV2Interface::updateCapabilities() { - return d->uuid; -} - -void OutputDeviceV2InterfacePrivate::sendEdid(Resource *resource) -{ - send_edid(resource->handle, QString::fromStdString(edid.toBase64().toStdString())); -} - -void OutputDeviceV2InterfacePrivate::sendEnabled(Resource *resource) -{ - send_enabled(resource->handle, enabled); -} - -void OutputDeviceV2InterfacePrivate::sendUuid(Resource *resource) -{ - send_uuid(resource->handle, uuid.toString(QUuid::WithoutBraces)); -} - -uint32_t OutputDeviceV2Interface::overscan() const -{ - return d->overscan; -} - -OutputDeviceV2Interface::Capabilities OutputDeviceV2Interface::capabilities() const -{ - return d->capabilities; -} - -void OutputDeviceV2Interface::setCapabilities(Capabilities cap) -{ - if (d->capabilities != cap) { - d->capabilities = cap; + const uint32_t cap = kwinCapabilitiesToOutputDeviceCapabilities(d->m_handle->capabilities()); + if (d->m_capabilities != cap) { + d->m_capabilities = cap; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendCapabilities(resource); @@ -594,15 +530,11 @@ void OutputDeviceV2Interface::setCapabilities(Capabilities cap) } } -void OutputDeviceV2InterfacePrivate::sendCapabilities(Resource *resource) +void OutputDeviceV2Interface::updateOverscan() { - send_capabilities(resource->handle, static_cast(capabilities)); -} - -void OutputDeviceV2Interface::setOverscan(uint32_t overscan) -{ - if (d->overscan != overscan) { - d->overscan = overscan; + const uint32_t overscan = d->m_handle->overscan(); + if (d->m_overscan != overscan) { + d->m_overscan = overscan; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendOverscan(resource); @@ -611,25 +543,11 @@ void OutputDeviceV2Interface::setOverscan(uint32_t overscan) } } -void OutputDeviceV2InterfacePrivate::sendOverscan(Resource *resource) +void OutputDeviceV2Interface::updateVrrPolicy() { - send_overscan(resource->handle, static_cast(overscan)); -} - -void OutputDeviceV2InterfacePrivate::sendVrrPolicy(Resource *resource) -{ - send_vrr_policy(resource->handle, static_cast(vrrPolicy)); -} - -OutputDeviceV2Interface::VrrPolicy OutputDeviceV2Interface::vrrPolicy() const -{ - return d->vrrPolicy; -} - -void OutputDeviceV2Interface::setVrrPolicy(VrrPolicy policy) -{ - if (d->vrrPolicy != policy) { - d->vrrPolicy = policy; + const auto policy = kwinVrrPolicyToOutputDeviceVrrPolicy(d->m_handle->vrrPolicy()); + if (d->m_vrrPolicy != policy) { + d->m_vrrPolicy = policy; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendVrrPolicy(resource); @@ -638,15 +556,11 @@ void OutputDeviceV2Interface::setVrrPolicy(VrrPolicy policy) } } -OutputDeviceV2Interface::RgbRange OutputDeviceV2Interface::rgbRange() const +void OutputDeviceV2Interface::updateRgbRange() { - return d->rgbRange; -} - -void OutputDeviceV2Interface::setRgbRange(RgbRange rgbRange) -{ - if (d->rgbRange != rgbRange) { - d->rgbRange = rgbRange; + const auto rgbRange = kwinRgbRangeToOutputDeviceRgbRange(d->m_handle->rgbRange()); + if (d->m_rgbRange != rgbRange) { + d->m_rgbRange = rgbRange; const auto clientResources = d->resourceMap(); for (const auto &resource : clientResources) { d->sendRgbRange(resource); @@ -655,16 +569,6 @@ void OutputDeviceV2Interface::setRgbRange(RgbRange rgbRange) } } -void OutputDeviceV2InterfacePrivate::sendRgbRange(Resource *resource) -{ - send_rgb_range(resource->handle, static_cast(rgbRange)); -} - -wl_resource *OutputDeviceV2Interface::resource() const -{ - return d->resource()->handle; -} - OutputDeviceV2Interface *OutputDeviceV2Interface::get(wl_resource *native) { if (auto devicePrivate = resource_cast(native)) { @@ -673,19 +577,19 @@ OutputDeviceV2Interface *OutputDeviceV2Interface::get(wl_resource *native) return nullptr; } -OutputDeviceModeV2InterfacePrivate::OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, std::weak_ptr handle, const QSize &size, int refreshRate, OutputDeviceModeV2Interface::ModeFlags flags) +OutputDeviceModeV2InterfacePrivate::OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, std::shared_ptr handle) : QtWaylandServer::kde_output_device_mode_v2() , q(q) , m_handle(handle) - , m_size(size) - , m_refreshRate(refreshRate) - , m_flags(flags) + , m_size(handle->size()) + , m_refreshRate(handle->refreshRate()) + , m_preferred(handle->flags() & OutputMode::Flag::Preferred) { } -OutputDeviceModeV2Interface::OutputDeviceModeV2Interface(std::weak_ptr handle, const QSize &size, int refreshRate, ModeFlags flags, QObject *parent) +OutputDeviceModeV2Interface::OutputDeviceModeV2Interface(std::shared_ptr handle, QObject *parent) : QObject(parent) - , d(new OutputDeviceModeV2InterfacePrivate(this, handle, size, refreshRate, flags)) + , d(new OutputDeviceModeV2InterfacePrivate(this, handle)) { } @@ -728,27 +632,12 @@ std::weak_ptr OutputDeviceModeV2Interface::handle() const return d->m_handle; } -QSize OutputDeviceModeV2Interface::size() const -{ - return d->m_size; -} - -int OutputDeviceModeV2Interface::refreshRate() const -{ - return d->m_refreshRate; -} - -OutputDeviceModeV2Interface::ModeFlags OutputDeviceModeV2Interface::flags() const -{ - return d->m_flags; -} - void OutputDeviceModeV2InterfacePrivate::bindResource(wl_resource *resource) { send_size(resource, m_size.width(), m_size.height()); send_refresh(resource, m_refreshRate); - if (m_flags.testFlag(OutputDeviceModeV2Interface::ModeFlag::Preferred)) { + if (m_preferred) { send_preferred(resource); } } diff --git a/src/wayland/outputdevice_v2_interface.h b/src/wayland/outputdevice_v2_interface.h index c913344865..398821e081 100644 --- a/src/wayland/outputdevice_v2_interface.h +++ b/src/wayland/outputdevice_v2_interface.h @@ -41,103 +41,39 @@ class OutputDeviceModeV2InterfacePrivate; class KWIN_EXPORT OutputDeviceV2Interface : public QObject { Q_OBJECT -public: - enum class SubPixel { - Unknown, - None, - HorizontalRGB, - HorizontalBGR, - VerticalRGB, - VerticalBGR, - }; - Q_ENUM(SubPixel) - enum class Transform { - Normal, - Rotated90, - Rotated180, - Rotated270, - Flipped, - Flipped90, - Flipped180, - Flipped270, - }; - Q_ENUM(Transform) - enum class Capability { - Overscan = 0x1, - Vrr = 0x2, - RgbRange = 0x4, - }; - Q_ENUM(Capability) - Q_DECLARE_FLAGS(Capabilities, Capability) - enum class VrrPolicy { - Never = 0, - Always = 1, - Automatic = 2 - }; - Q_ENUM(VrrPolicy) - enum class RgbRange { - Automatic = 0, - Full = 1, - Limited = 2, - }; - Q_ENUM(RgbRange) +public: explicit OutputDeviceV2Interface(Display *display, KWin::Output *handle, QObject *parent = nullptr); ~OutputDeviceV2Interface() override; void remove(); KWin::Output *handle() const; - QSize physicalSize() const; - QPoint globalPosition() const; - QString manufacturer() const; - QString model() const; - QString serialNumber() const; - QString eisaId() const; - QString name() const; - QSize pixelSize() const; - int refreshRate() const; - QList modes() const; - qreal scale() const; - SubPixel subPixel() const; - Transform transform() const; - QByteArray edid() const; - bool enabled() const; - QUuid uuid() const; - - Capabilities capabilities() const; - uint32_t overscan() const; - VrrPolicy vrrPolicy() const; - RgbRange rgbRange() const; - - void setPhysicalSize(const QSize &size); - void setGlobalPosition(const QPoint &pos); - void setManufacturer(const QString &manufacturer); - void setModel(const QString &model); - void setSerialNumber(const QString &serialNumber); - void setEisaId(const QString &eisaId); - void setName(const QString &name); - - void setScale(qreal scale); - void setSubPixel(SubPixel subPixel); - void setTransform(Transform transform); - - void setModes(const QList &modes, KWaylandServer::OutputDeviceModeV2Interface *currentMode); - void setCurrentMode(KWaylandServer::OutputDeviceModeV2Interface *mode); - void setEdid(const QByteArray &edid); - void setEnabled(bool enabled); - void setUuid(const QUuid &uuid); - - void setCapabilities(Capabilities cap); - void setOverscan(uint32_t overscan); - void setVrrPolicy(VrrPolicy policy); - void setRgbRange(RgbRange rgbRange); - - wl_resource *resource() const; static OutputDeviceV2Interface *get(wl_resource *native); private: + void updatePhysicalSize(); + void updateGlobalPosition(); + void updateManufacturer(); + void updateModel(); + void updateSerialNumber(); + void updateEisaId(); + void updateName(); + void updateScale(); + void updateSubPixel(); + void updateTransform(); + void updateModes(); + void updateCurrentMode(); + void updateEdid(); + void updateEnabled(); + void updateUuid(); + void updateCapabilities(); + void updateOverscan(); + void updateVrrPolicy(); + void updateRgbRange(); + void updateGeometry(); + std::unique_ptr d; }; @@ -151,20 +87,12 @@ private: class KWIN_EXPORT OutputDeviceModeV2Interface : public QObject { Q_OBJECT -public: - enum class ModeFlag { - Preferred = 0x1, - }; - Q_ENUM(ModeFlag) - Q_DECLARE_FLAGS(ModeFlags, ModeFlag) - OutputDeviceModeV2Interface(std::weak_ptr handle, const QSize &size, int refreshRate, ModeFlags flags, QObject *parent = nullptr); +public: + OutputDeviceModeV2Interface(std::shared_ptr handle, QObject *parent = nullptr); ~OutputDeviceModeV2Interface() override; std::weak_ptr handle() const; - QSize size() const; - int refreshRate() const; - OutputDeviceModeV2Interface::ModeFlags flags() const; static OutputDeviceModeV2Interface *get(wl_resource *native); @@ -174,7 +102,3 @@ private: }; } - -Q_DECLARE_METATYPE(KWaylandServer::OutputDeviceModeV2Interface::ModeFlag) -Q_DECLARE_METATYPE(KWaylandServer::OutputDeviceV2Interface::SubPixel) -Q_DECLARE_METATYPE(KWaylandServer::OutputDeviceV2Interface::Transform) diff --git a/src/wayland/outputmanagement_v2_interface.cpp b/src/wayland/outputmanagement_v2_interface.cpp index aba60a5050..2e9a621b31 100644 --- a/src/wayland/outputmanagement_v2_interface.cpp +++ b/src/wayland/outputmanagement_v2_interface.cpp @@ -229,7 +229,7 @@ void OutputConfigurationV2Interface::kde_output_configuration_v2_apply(Resource if (kwinApp()->platform()->applyOutputChanges(config)) { if (primaryOutput.has_value() || !kwinApp()->platform()->primaryOutput()->isEnabled()) { - auto requestedPrimaryOutput = kwinApp()->platform()->findOutput((*primaryOutput)->uuid()); + auto requestedPrimaryOutput = (*primaryOutput)->handle(); if (requestedPrimaryOutput && requestedPrimaryOutput->isEnabled()) { kwinApp()->platform()->setPrimaryOutput(requestedPrimaryOutput); } else { diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 9b0d884e31..2c8c1ea888 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -38,6 +38,7 @@ #include "wayland/keystate_interface.h" #include "wayland/linuxdmabufv1clientbuffer.h" #include "wayland/output_interface.h" +#include "wayland/outputdevice_v2_interface.h" #include "wayland/outputmanagement_v2_interface.h" #include "wayland/plasmashell_interface.h" #include "wayland/plasmavirtualdesktop_interface.h" @@ -60,7 +61,6 @@ #include "wayland/xdgoutput_v1_interface.h" #include "wayland/xdgshell_interface.h" #include "waylandoutput.h" -#include "waylandoutputdevicev2.h" #include "workspace.h" #include "x11window.h" #include "xdgactivationv1.h" @@ -274,14 +274,14 @@ void WaylandServer::registerXdgGenericWindow(Window *window) void WaylandServer::handleOutputAdded(Output *output) { if (!output->isPlaceholder() && !output->isNonDesktop()) { - m_waylandOutputDevices.insert(output, new WaylandOutputDevice(output)); + m_waylandOutputDevices.insert(output, new KWaylandServer::OutputDeviceV2Interface(m_display, output)); } } void WaylandServer::handleOutputRemoved(Output *output) { - if (!output->isPlaceholder() && !output->isNonDesktop()) { - delete m_waylandOutputDevices.take(output); + if (auto outputDevice = m_waylandOutputDevices.take(output)) { + outputDevice->remove(); } } diff --git a/src/wayland_server.h b/src/wayland_server.h index 9929e77cc9..09c6c60f70 100644 --- a/src/wayland_server.h +++ b/src/wayland_server.h @@ -39,6 +39,7 @@ class PlasmaWindowActivationFeedbackInterface; class PlasmaVirtualDesktopManagementInterface; class PlasmaWindowManagementInterface; class PrimaryOutputV1Interface; +class OutputDeviceV2Interface; class OutputManagementV2Interface; class XdgForeignV2Interface; class XdgOutputManagerV1Interface; @@ -60,7 +61,6 @@ class XdgPopupWindow; class XdgSurfaceWindow; class XdgToplevelWindow; class WaylandOutput; -class WaylandOutputDevice; class KWIN_EXPORT WaylandServer : public QObject { @@ -294,7 +294,7 @@ private: QList m_windows; InitializationFlags m_initFlags; QHash m_waylandOutputs; - QHash m_waylandOutputDevices; + QHash m_waylandOutputDevices; KWIN_SINGLETON(WaylandServer) }; diff --git a/src/waylandoutputdevicev2.cpp b/src/waylandoutputdevicev2.cpp deleted file mode 100644 index 46832062fd..0000000000 --- a/src/waylandoutputdevicev2.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - SPDX-FileCopyrightText: 2021 Vlad Zahorodnii - SPDX-FileCopyrightText: 2021 Méven Car - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include "waylandoutputdevicev2.h" -#include "wayland_server.h" - -using namespace KWaylandServer; - -namespace KWin -{ - -static KWaylandServer::OutputDeviceV2Interface::Transform kwinTransformToOutputDeviceTransform(Output::Transform transform) -{ - return static_cast(transform); -} - -static KWaylandServer::OutputDeviceV2Interface::SubPixel kwinSubPixelToOutputDeviceSubPixel(Output::SubPixel subPixel) -{ - return static_cast(subPixel); -} - -static KWaylandServer::OutputDeviceV2Interface::Capabilities kwinCapabilitiesToOutputDeviceCapabilities(Output::Capabilities caps) -{ - KWaylandServer::OutputDeviceV2Interface::Capabilities ret; - if (caps & Output::Capability::Overscan) { - ret |= KWaylandServer::OutputDeviceV2Interface::Capability::Overscan; - } - if (caps & Output::Capability::Vrr) { - ret |= KWaylandServer::OutputDeviceV2Interface::Capability::Vrr; - } - if (caps & Output::Capability::RgbRange) { - ret |= KWaylandServer::OutputDeviceV2Interface::Capability::RgbRange; - } - return ret; -} - -static KWaylandServer::OutputDeviceV2Interface::VrrPolicy kwinVrrPolicyToOutputDeviceVrrPolicy(RenderLoop::VrrPolicy policy) -{ - return static_cast(policy); -} - -static KWaylandServer::OutputDeviceV2Interface::RgbRange kwinRgbRangeToOutputDeviceRgbRange(Output::RgbRange range) -{ - return static_cast(range); -} - -WaylandOutputDevice::WaylandOutputDevice(Output *output, QObject *parent) - : QObject(parent) - , m_platformOutput(output) - , m_outputDeviceV2(new KWaylandServer::OutputDeviceV2Interface(waylandServer()->display(), output)) -{ - m_outputDeviceV2->setManufacturer(output->manufacturer()); - m_outputDeviceV2->setEdid(output->edid()); - m_outputDeviceV2->setUuid(output->uuid()); - m_outputDeviceV2->setModel(output->model()); - m_outputDeviceV2->setPhysicalSize(output->physicalSize()); - m_outputDeviceV2->setGlobalPosition(output->geometry().topLeft()); - m_outputDeviceV2->setScale(output->scale()); - m_outputDeviceV2->setTransform(kwinTransformToOutputDeviceTransform(output->transform())); - m_outputDeviceV2->setEisaId(output->eisaId()); - m_outputDeviceV2->setSerialNumber(output->serialNumber()); - m_outputDeviceV2->setSubPixel(kwinSubPixelToOutputDeviceSubPixel(output->subPixel())); - m_outputDeviceV2->setOverscan(output->overscan()); - m_outputDeviceV2->setCapabilities(kwinCapabilitiesToOutputDeviceCapabilities(output->capabilities())); - m_outputDeviceV2->setVrrPolicy(kwinVrrPolicyToOutputDeviceVrrPolicy(output->vrrPolicy())); - m_outputDeviceV2->setRgbRange(kwinRgbRangeToOutputDeviceRgbRange(output->rgbRange())); - m_outputDeviceV2->setName(output->name()); - - updateModes(output); - - connect(output, &Output::geometryChanged, - this, &WaylandOutputDevice::handleGeometryChanged); - connect(output, &Output::scaleChanged, - this, &WaylandOutputDevice::handleScaleChanged); - connect(output, &Output::enabledChanged, - this, &WaylandOutputDevice::handleEnabledChanged); - connect(output, &Output::transformChanged, - this, &WaylandOutputDevice::handleTransformChanged); - connect(output, &Output::currentModeChanged, - this, &WaylandOutputDevice::handleCurrentModeChanged); - connect(output, &Output::capabilitiesChanged, - this, &WaylandOutputDevice::handleCapabilitiesChanged); - connect(output, &Output::overscanChanged, - this, &WaylandOutputDevice::handleOverscanChanged); - connect(output, &Output::vrrPolicyChanged, - this, &WaylandOutputDevice::handleVrrPolicyChanged); - connect(output, &Output::modesChanged, - this, &WaylandOutputDevice::handleModesChanged); - connect(output, &Output::rgbRangeChanged, - this, &WaylandOutputDevice::handleRgbRangeChanged); -} - -void WaylandOutputDevice::updateModes(Output *output) -{ - QList deviceModes; - OutputDeviceModeV2Interface *currentMode = nullptr; - - const auto modes = output->modes(); - deviceModes.reserve(modes.size()); - for (const std::shared_ptr &mode : modes) { - OutputDeviceModeV2Interface::ModeFlags flags; - if (mode->flags() & OutputMode::Flag::Preferred) { - flags |= OutputDeviceModeV2Interface::ModeFlag::Preferred; - } - - OutputDeviceModeV2Interface *deviceMode = new OutputDeviceModeV2Interface(mode, mode->size(), mode->refreshRate(), flags); - deviceModes << deviceMode; - - if (output->currentMode() == mode) { - currentMode = deviceMode; - } - } - m_outputDeviceV2->setModes(deviceModes, currentMode); -} - -void WaylandOutputDevice::handleModesChanged() -{ - updateModes(m_platformOutput); -} - -void WaylandOutputDevice::handleGeometryChanged() -{ - m_outputDeviceV2->setGlobalPosition(m_platformOutput->geometry().topLeft()); -} - -void WaylandOutputDevice::handleScaleChanged() -{ - m_outputDeviceV2->setScale(m_platformOutput->scale()); -} - -void WaylandOutputDevice::handleEnabledChanged() -{ - m_outputDeviceV2->setEnabled(m_platformOutput->isEnabled()); -} - -void WaylandOutputDevice::handleTransformChanged() -{ - m_outputDeviceV2->setTransform(kwinTransformToOutputDeviceTransform(m_platformOutput->transform())); -} - -void WaylandOutputDevice::handleCurrentModeChanged() -{ - const auto modes = m_outputDeviceV2->modes(); - for (KWaylandServer::OutputDeviceModeV2Interface *mode : modes) { - if (mode->handle().lock() == m_platformOutput->currentMode()) { - m_outputDeviceV2->setCurrentMode(mode); - break; - } - } -} - -void WaylandOutputDevice::handleCapabilitiesChanged() -{ - m_outputDeviceV2->setCapabilities(kwinCapabilitiesToOutputDeviceCapabilities(m_platformOutput->capabilities())); -} - -void WaylandOutputDevice::handleOverscanChanged() -{ - m_outputDeviceV2->setOverscan(m_platformOutput->overscan()); -} - -void WaylandOutputDevice::handleVrrPolicyChanged() -{ - m_outputDeviceV2->setVrrPolicy(kwinVrrPolicyToOutputDeviceVrrPolicy(m_platformOutput->vrrPolicy())); -} - -void WaylandOutputDevice::handleRgbRangeChanged() -{ - m_outputDeviceV2->setRgbRange(kwinRgbRangeToOutputDeviceRgbRange(m_platformOutput->rgbRange())); -} - -} // namespace KWin diff --git a/src/waylandoutputdevicev2.h b/src/waylandoutputdevicev2.h deleted file mode 100644 index 2c9dd1c68f..0000000000 --- a/src/waylandoutputdevicev2.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - SPDX-FileCopyrightText: 2021 Vlad Zahorodnii - SPDX-FileCopyrightText: 2021 Méven Car - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#pragma once - -#include "output.h" -#include "wayland/outputdevice_v2_interface.h" -#include "wayland/utils.h" - -namespace KWin -{ - -class WaylandOutputDevice : public QObject -{ - Q_OBJECT - -public: - explicit WaylandOutputDevice(Output *output, QObject *parent = nullptr); - -private Q_SLOTS: - void handleGeometryChanged(); - void handleScaleChanged(); - void handleEnabledChanged(); - void handleTransformChanged(); - void handleCurrentModeChanged(); - void handleCapabilitiesChanged(); - void handleOverscanChanged(); - void handleVrrPolicyChanged(); - void handleModesChanged(); - void handleRgbRangeChanged(); - -private: - void updateModes(Output *output); - - Output *m_platformOutput; - KWaylandServer::ScopedGlobalPointer m_outputDeviceV2; -}; - -} // namespace KWin