7 #include "wayland_pointer_p.h"
13 #include <wayland-client-protocol.h>
24 class Q_DECL_HIDDEN Output::Private
29 void setup(wl_output *o);
31 WaylandPointer<wl_output, wl_output_release> output;
32 EventQueue *queue =
nullptr;
38 SubPixel subPixel = SubPixel::Unknown;
41 Modes::iterator currentMode = modes.
end();
45 static Output *
get(wl_output *o);
48 static void geometryCallback(
void *data,
52 int32_t physicalWidth,
53 int32_t physicalHeight,
58 static void modeCallback(
void *data, wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh);
59 static void doneCallback(
void *data, wl_output *output);
60 static void scaleCallback(
void *data, wl_output *output, int32_t scale);
61 static void nameCallback(
void *data,
struct wl_output *wl_output,
const char *name);
62 static void descriptionCallback(
void *data,
struct wl_output *wl_output,
const char *description);
63 void setPhysicalSize(
const QSize &size);
64 void setGlobalPosition(
const QPoint &pos);
65 void setManufacturer(
const QString &manufacturer);
66 void setModel(
const QString &model);
67 void setScale(
int scale);
68 void setSubPixel(SubPixel subPixel);
69 void setTransform(Transform transform);
70 void addMode(uint32_t flags, int32_t width, int32_t height, int32_t refresh);
73 static struct wl_output_listener s_outputListener;
80 Output::Private::Private(Output *q)
86 Output::Private::~Private()
88 s_allOutputs.removeOne(
this);
93 auto it = std::find_if(s_allOutputs.constBegin(), s_allOutputs.constEnd(), [o](Private *p) {
94 const wl_output *reference = p->output;
95 return reference == o;
97 if (it != s_allOutputs.constEnd()) {
103 void Output::Private::setup(wl_output *o)
108 wl_output_add_listener(output, &s_outputListener,
this);
111 bool Output::Mode::operator==(
const Output::Mode &m)
const
113 return size == m.size && refreshRate == m.refreshRate && flags == m.flags && output == m.output;
118 , d(new Private(this))
127 wl_output_listener Output::Private::s_outputListener = {
128 geometryCallback, modeCallback, doneCallback, scaleCallback,
129 #ifdef WL_OUTPUT_NAME_SINCE_VERSION
132 #ifdef WL_OUTPUT_DESCRIPTION_SINCE_VERSION
137 void Output::Private::geometryCallback(
void *data,
141 int32_t physicalWidth,
142 int32_t physicalHeight,
149 auto o =
reinterpret_cast<Output::Private *
>(data);
150 Q_ASSERT(o->output == output);
151 o->setGlobalPosition(
QPoint(x, y));
152 o->setManufacturer(make);
154 o->setPhysicalSize(
QSize(physicalWidth, physicalHeight));
155 auto toSubPixel = [subPixel]() {
157 case WL_OUTPUT_SUBPIXEL_NONE:
158 return SubPixel::None;
159 case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
160 return SubPixel::HorizontalRGB;
161 case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
162 return SubPixel::HorizontalBGR;
163 case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
164 return SubPixel::VerticalRGB;
165 case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
166 return SubPixel::VerticalBGR;
167 case WL_OUTPUT_SUBPIXEL_UNKNOWN:
169 return SubPixel::Unknown;
172 o->setSubPixel(toSubPixel());
175 case WL_OUTPUT_TRANSFORM_90:
176 return Transform::Rotated90;
177 case WL_OUTPUT_TRANSFORM_180:
178 return Transform::Rotated180;
179 case WL_OUTPUT_TRANSFORM_270:
180 return Transform::Rotated270;
181 case WL_OUTPUT_TRANSFORM_FLIPPED:
182 return Transform::Flipped;
183 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
184 return Transform::Flipped90;
185 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
186 return Transform::Flipped180;
187 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
188 return Transform::Flipped270;
189 case WL_OUTPUT_TRANSFORM_NORMAL:
191 return Transform::Normal;
194 o->setTransform(toTransform());
197 void Output::Private::modeCallback(
void *data, wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh)
199 auto o =
reinterpret_cast<Output::Private *
>(data);
200 Q_ASSERT(o->output == output);
201 o->addMode(flags, width, height, refresh);
204 void Output::Private::addMode(uint32_t flags, int32_t width, int32_t height, int32_t refresh)
208 mode.refreshRate = refresh;
209 mode.size =
QSize(width, height);
210 if (flags & WL_OUTPUT_MODE_CURRENT) {
211 mode.flags |= Mode::Flag::Current;
213 if (flags & WL_OUTPUT_MODE_PREFERRED) {
214 mode.flags |= Mode::Flag::Preferred;
216 auto currentIt = modes.insert(modes.end(), mode);
217 bool existing =
false;
218 if (flags & WL_OUTPUT_MODE_CURRENT) {
219 auto it = modes.begin();
220 while (it != currentIt) {
222 if (m.flags.testFlag(Mode::Flag::Current)) {
223 m.flags &= ~
Mode::Flags(Mode::Flag::Current);
226 if (m.refreshRate == mode.refreshRate && m.size == mode.size) {
227 it = modes.erase(it);
233 currentMode = currentIt;
236 Q_EMIT q->modeChanged(mode);
238 Q_EMIT q->modeAdded(mode);
242 void Output::Private::scaleCallback(
void *data, wl_output *output, int32_t scale)
244 auto o =
reinterpret_cast<Output::Private *
>(data);
245 Q_ASSERT(o->output == output);
249 void Output::Private::nameCallback(
void *data,
struct wl_output *wl_output,
const char *name)
251 auto o =
reinterpret_cast<Output::Private *
>(data);
252 Q_ASSERT(o->output == wl_output);
256 void Output::Private::descriptionCallback(
void *data,
struct wl_output *wl_output,
const char *description)
258 auto o =
reinterpret_cast<Output::Private *
>(data);
259 Q_ASSERT(o->output == wl_output);
263 void Output::Private::doneCallback(
void *data, wl_output *output)
265 auto o =
reinterpret_cast<Output::Private *
>(data);
266 Q_ASSERT(o->output == output);
270 void Output::setup(wl_output *output)
285 void Output::Private::setGlobalPosition(
const QPoint &pos)
287 globalPosition = pos;
290 void Output::Private::setManufacturer(
const QString &m)
295 void Output::Private::setModel(
const QString &m)
300 void Output::Private::setPhysicalSize(
const QSize &size)
305 void Output::Private::setScale(
int s)
312 if (d->currentMode == d->modes.end()) {
315 return QRect(d->globalPosition, pixelSize());
318 void Output::Private::setSubPixel(Output::SubPixel s)
323 void Output::Private::setTransform(Output::Transform t)
330 return d->globalPosition;
335 return d->manufacturer;
343 wl_output *Output::output()
350 return d->physicalSize;
355 if (d->currentMode == d->modes.end()) {
358 return (*d->currentMode).size;
361 int Output::refreshRate()
const
363 if (d->currentMode == d->modes.end()) {
366 return (*d->currentMode).refreshRate;
369 int Output::scale()
const
374 bool Output::isValid()
const
376 return d->output.isValid();
379 Output::SubPixel Output::subPixel()
const
384 Output::Transform Output::transform()
const
401 return d->description;
404 Output::operator wl_output *()
409 Output::operator wl_output *()
const
419 void Output::destroy()