1 /******************************************************************** 2 Copyright © 2020 Roman Gilg <subdiff@gmail.com> 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) version 3, or any 8 later version accepted by the membership of KDE e.V. (or its 9 successor approved by the membership of KDE e.V.), which shall 10 act as a proxy defined in Section 6 of version 3 of the license. 11 12 This library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with this library. If not, see <http://www.gnu.org/licenses/>. 19 *********************************************************************/ 20 #pragma once 21 22 #include "wlr_output_manager_v1.h" 23 24 #include <Wrapland/Client/wraplandclient_export.h> 25 26 #include <QObject> 27 #include <QPoint> 28 29 struct zkwinft_output_management_v1; 30 struct zwlr_output_configuration_v1; 31 32 namespace Wrapland 33 { 34 namespace Client 35 { 36 37 class EventQueue; 38 39 /** @class WlrOutputConfigurationV1 40 * 41 * WlrOutputConfigurationV1 provides access to changing WlrOutputHeadV1s. The interface is async 42 * and atomic. An WlrOutputConfigurationV1 is created through 43 * WlrOutputManagerV1::createConfiguration(). 44 * 45 * The overall mechanism is to get a new WlrOutputConfigurationV1 from the WlrOutputManagerV1 global 46 * and apply changes through the WlrOutputConfigurationV1::set* calls. When all changes are set, the 47 * client calls apply, which asks the server to look at the changes and apply them. The server will 48 * then signal back whether the changes have been applied successfully (@c applied()) or were 49 * rejected or failed to apply (@c failed()). 50 * 51 * The current settings for heads can be gotten from @c Registry::WlrOutputHeadV1s(), these 52 * are used in the set* calls to identify the output the setting applies to. 53 * 54 * These Wrapland classes will not apply changes to the heads, this is the compositor's 55 * task. As such, the configuration set through this interface can be seen as a hint what the 56 * compositor should set up, but whether or not the compositor does it (based on hardware or 57 * rendering policies, for example), is up to the compositor. The mode setting is passed on to 58 * the DRM subsystem through the compositor. The compositor also saves this configuration and reads 59 * it on startup, this interface is not involved in that process. 60 * 61 * @c apply() should only be called after changes to all heads have been made, not after 62 * each change. This allows to test the new configuration as a whole, and is a lot faster since 63 * hardware changes can be tested in their new combination, they done in parallel.and rolled back 64 * as a whole. 65 * 66 * \verbatim 67 // We're just picking the first of our heads 68 Wrapland::Client::WlrOutputHeadV1 *output = m_clientOutputs.first(); 69 70 // Create a new configuration object 71 auto config = m_outputManagement.createConfiguration(); 72 73 // handle applied and failed signals 74 connect(config, &WlrOutputConfigurationV1::applied, []() { 75 qDebug() << "Configuration applied!"; 76 }); 77 connect(config, &WlrOutputConfigurationV1::failed, []() { 78 qDebug() << "Configuration failed!"; 79 }); 80 81 // Change settings 82 config->setMode(output, m_clientOutputs.first()->modes().last().id); 83 config->setTransform(output, WlrOutputHeadV1::Transform::Normal); 84 config->setPosition(output, QPoint(0, 1920)); 85 config->setScale(output, 2); 86 87 // Now ask the compositor to apply the changes 88 config->apply(); 89 // You may wait for the applied() or failed() signal here 90 \endverbatim 91 92 * @see WlrOutputHeadV1 93 * @see WlrOutputManagerV1 94 * @see WlrOutputManagerV1::createConfiguration() 95 * @since 0.519.0 96 */ 97 class WRAPLANDCLIENT_EXPORT WlrOutputConfigurationV1 : public QObject 98 { 99 Q_OBJECT 100 public: 101 ~WlrOutputConfigurationV1() override; 102 103 /** 104 * Setup this WlrOutputConfigurationV1 to manage the @p outputconfiguration. 105 * When using WlrOutputManagerV1::createOutputConfiguration there is no need to call this 106 * method. 107 * @param outputconfiguration the outputconfiguration object to set up. 108 */ 109 void setup(zwlr_output_configuration_v1* outputconfiguration); 110 /** 111 * @returns @c true if managing a zwlr_output_configuration_v1. 112 */ 113 bool isValid() const; 114 /** 115 * Releases the zwlr_output_configuration_v1 interface. 116 * After the interface has been released the WlrOutputConfigurationV1 instance is no 117 * longer valid and can be setup with another zwlr_output_configuration_v1 interface. 118 */ 119 void release(); 120 121 /** 122 * Sets the @p queue to use for creating a WlrOutputConfigurationV1. 123 */ 124 void setEventQueue(EventQueue* queue); 125 /** 126 * @returns The event queue to use for creating a WlrOutputConfigurationV1 127 */ 128 EventQueue* eventQueue(); 129 130 /** 131 * Enable or disable an output. Enabled means it's used by the 132 * compositor for rendering, Disabled means, that no wl_output 133 * is connected to this, and the head is sitting there unused 134 * by this compositor. 135 * The changes done in this call will be recorded in the 136 * head and only applied after apply() has been called. 137 * 138 * @param head the head this change applies to. 139 * @param enable new Enablement state of this head. 140 */ 141 void setEnabled(WlrOutputHeadV1* head, bool enable); 142 143 /** 144 * Set the mode of this output. 145 * 146 * @param head the head this change applies to. 147 * @param mode the mode to set as current. 148 */ 149 void setMode(WlrOutputHeadV1* head, WlrOutputModeV1* mode); 150 151 /** 152 * Set a custom mode for this output. 153 * 154 * @param head the head this change applies to. 155 * @param size the custom mode size of the head. 156 * @param refresh the custom refresh rate of the head. 157 */ 158 void setCustomMode(WlrOutputHeadV1* head, const QSize& size, int refresh); 159 160 /** 161 * Set transformation for this output, for example rotated or flipped. 162 * The changes done in this call will be recorded in the 163 * head and only applied after apply() has been called. 164 * 165 * @param head the head this change applies to. 166 * @param scale the scaling factor for this head. 167 */ 168 void setTransform(WlrOutputHeadV1* head, WlrOutputHeadV1::Transform transform); 169 170 /** 171 * Sets the position of this output in the global space. 172 * 173 * @param head the head this change applies to. 174 * @param geo the head geometry relative to other outputs, 175 * 176 */ 177 void setPosition(WlrOutputHeadV1* head, const QPoint& pos); 178 179 /** 180 * Sets the position of this output in the global space. 181 * 182 * @param head the head this change applies to. 183 * @param geo the head geometry relative to other outputs, 184 * 185 */ 186 void setScale(WlrOutputHeadV1* head, double scale); 187 188 /** 189 * Check if current configuration is valid. Either succeeded() or failed() will be emitted 190 * later on as a result of this call. 191 */ 192 void test(); 193 194 /** 195 * Ask the compositor to apply the changes. 196 * This results in the compositor looking at all heads and if they have 197 * pending changes from the set* calls, these changes will be tested with the 198 * hardware and applied if possible. The compositor will react to these changes 199 * with the applied() or failed() signals. Note that mode setting may take a 200 * while, so the interval between calling apply() and receiving the applied() 201 * signal may be considerable, depending on the hardware. 202 * 203 * @see applied() 204 * @see failed() 205 */ 206 void apply(); 207 208 operator zwlr_output_configuration_v1*(); 209 operator zwlr_output_configuration_v1*() const; 210 211 Q_SIGNALS: 212 /** 213 * The server has applied all settings successfully. In case test() was called before that 214 * nothing else happens. Otherwise pending changes in the heads have been cleared, changed 215 * signals from the head have been emitted. 216 */ 217 void succeeded(); 218 /** 219 * The server has failed to apply the settings or rejected them. Pending changes 220 * in the * heads have been cleared. No changes have been applied to the 221 * heads. 222 */ 223 void failed(); 224 225 /** 226 * Sent if the current configuration is outdated. A new configuration object should be created 227 * via the output manager global and this configura. 228 */ 229 void cancelled(); 230 231 private: 232 explicit WlrOutputConfigurationV1(QObject* parent = nullptr); 233 friend class WlrOutputManagerV1; 234 235 class Private; 236 std::unique_ptr<Private> d; 237 }; 238 239 } 240 } 241 242 Q_DECLARE_METATYPE(Wrapland::Client::WlrOutputConfigurationV1*) 243