Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qxcbscreen.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qxcbscreen.h"
5#include "qxcbwindow.h"
6#include "qxcbcursor.h"
7#include "qxcbimage.h"
8#include "qnamespace.h"
9#include "qxcbxsettings.h"
10
11#include <stdio.h>
12
13#include <QDebug>
14#include <QtAlgorithms>
15
16#include <qpa/qwindowsysteminterface.h>
17#include <private/qmath_p.h>
18#include <QtGui/private/qhighdpiscaling_p.h>
19
21
24 , m_screen(screen)
25 , m_number(number)
26{
27 const QByteArray cmAtomName = "_NET_WM_CM_S" + QByteArray::number(m_number);
28 m_net_wm_cm_atom = connection->internAtom(cmAtomName.constData());
29 m_compositingActive = connection->selectionOwner(m_net_wm_cm_atom);
30
31 m_workArea = getWorkArea();
32
33 readXResources();
34
35 auto rootAttribs = Q_XCB_REPLY_UNCHECKED(xcb_get_window_attributes, xcb_connection(),
36 screen->root);
37 const quint32 existingEventMask = !rootAttribs ? 0 : rootAttribs->your_event_mask;
38
39 const quint32 mask = XCB_CW_EVENT_MASK;
40 const quint32 values[] = {
41 // XCB_CW_EVENT_MASK
42 XCB_EVENT_MASK_ENTER_WINDOW
43 | XCB_EVENT_MASK_LEAVE_WINDOW
44 | XCB_EVENT_MASK_PROPERTY_CHANGE
45 | XCB_EVENT_MASK_STRUCTURE_NOTIFY // for the "MANAGER" atom (system tray notification).
46 | existingEventMask // don't overwrite the event mask on the root window
47 };
48
49 xcb_change_window_attributes(xcb_connection(), screen->root, mask, values);
50
51 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
52 false, screen->root,
54 XCB_ATOM_WINDOW, 0, 1024);
55 if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) {
56 xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply.get()));
57
58 if (windowManager != XCB_WINDOW_NONE)
59 m_windowManagerName = QXcbWindow::windowTitle(connection, windowManager);
60 }
61
62 xcb_depth_iterator_t depth_iterator =
63 xcb_screen_allowed_depths_iterator(screen);
64
65 while (depth_iterator.rem) {
66 xcb_depth_t *depth = depth_iterator.data;
67 xcb_visualtype_iterator_t visualtype_iterator =
68 xcb_depth_visuals_iterator(depth);
69
70 while (visualtype_iterator.rem) {
71 xcb_visualtype_t *visualtype = visualtype_iterator.data;
72 m_visuals.insert(visualtype->visual_id, *visualtype);
73 m_visualDepths.insert(visualtype->visual_id, depth->depth);
74 xcb_visualtype_next(&visualtype_iterator);
75 }
76
77 xcb_depth_next(&depth_iterator);
78 }
79
80 auto dpiChangedCallback = [](QXcbVirtualDesktop *desktop, const QByteArray &, const QVariant &property, void *) {
81 if (!desktop->setDpiFromXSettings(property))
82 return;
83 const auto dpi = desktop->forcedDpi();
84 for (QXcbScreen *screen : desktop->connection()->screens())
86 };
87 setDpiFromXSettings(xSettings()->setting("Xft/DPI"));
88 xSettings()->registerCallbackForProperty("Xft/DPI", dpiChangedCallback, nullptr);
89}
90
92{
93 delete m_xSettings;
94
95 for (auto cmap : std::as_const(m_visualColormaps))
96 xcb_free_colormap(xcb_connection(), cmap);
97}
98
100{
101 const QSize virtualSize = size();
102 const QSize virtualSizeMillimeters = physicalSize();
103
104 return QDpi(Q_MM_PER_INCH * virtualSize.width() / virtualSizeMillimeters.width(),
105 Q_MM_PER_INCH * virtualSize.height() / virtualSizeMillimeters.height());
106}
107
109{
110 const auto screens = connection()->screens();
111 for (QXcbScreen *screen : screens) {
112 if (screen->virtualDesktop() == this && screen->geometry().contains(pos))
113 return screen;
114 }
115 return nullptr;
116}
117
119{
120 ((QXcbScreen *) s)->isPrimary() ? m_screens.prepend(s) : m_screens.append(s);
121}
122
124{
125 const int idx = m_screens.indexOf(s);
126 Q_ASSERT(idx > -1);
127 m_screens.swapItemsAt(0, idx);
128}
129
131{
132 if (!m_xSettings) {
133 QXcbVirtualDesktop *self = const_cast<QXcbVirtualDesktop *>(this);
134 self->m_xSettings = new QXcbXSettings(self);
135 }
136 return m_xSettings;
137}
138
140{
141 if (connection()->hasXFixes())
142 return m_compositingActive;
143 else
144 return connection()->selectionOwner(m_net_wm_cm_atom);
145}
146
147void QXcbVirtualDesktop::handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event)
148{
149 if (notify_event->selection == m_net_wm_cm_atom)
150 m_compositingActive = notify_event->owner;
151}
152
154{
155 if (connection()->hasXFixes()) {
156 const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
157 XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
158 XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
159 xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->qtSelectionOwner(), m_net_wm_cm_atom, mask);
160 }
161}
162
185void QXcbVirtualDesktop::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
186{
187 // No need to do anything when screen rotation did not change - if any
188 // xcb output geometry has changed, we will get RRCrtcChangeNotify and
189 // RROutputChangeNotify events next
190 if (change_event->rotation == m_rotation)
191 return;
192
193 m_rotation = change_event->rotation;
194 switch (m_rotation) {
195 case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
196 m_screen->width_in_pixels = change_event->width;
197 m_screen->height_in_pixels = change_event->height;
198 m_screen->width_in_millimeters = change_event->mwidth;
199 m_screen->height_in_millimeters = change_event->mheight;
200 break;
201 case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
202 m_screen->width_in_pixels = change_event->height;
203 m_screen->height_in_pixels = change_event->width;
204 m_screen->width_in_millimeters = change_event->mheight;
205 m_screen->height_in_millimeters = change_event->mwidth;
206 break;
207 case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
208 m_screen->width_in_pixels = change_event->width;
209 m_screen->height_in_pixels = change_event->height;
210 m_screen->width_in_millimeters = change_event->mwidth;
211 m_screen->height_in_millimeters = change_event->mheight;
212 break;
213 case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
214 m_screen->width_in_pixels = change_event->height;
215 m_screen->height_in_pixels = change_event->width;
216 m_screen->width_in_millimeters = change_event->mheight;
217 m_screen->height_in_millimeters = change_event->mwidth;
218 break;
219 // We don't need to do anything with these, since QScreen doesn't store reflection state,
220 // and Qt-based applications probably don't need to care about it anyway.
221 case XCB_RANDR_ROTATION_REFLECT_X: break;
222 case XCB_RANDR_ROTATION_REFLECT_Y: break;
223 }
224
225 for (QPlatformScreen *platformScreen : std::as_const(m_screens)) {
226 QDpi ldpi = platformScreen->logicalDpi();
227 QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(platformScreen->screen(), ldpi.first, ldpi.second);
228 }
229}
230
248QRect QXcbVirtualDesktop::getWorkArea() const
249{
250 QRect r;
251 auto workArea = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), false, screen()->root,
253 XCB_ATOM_CARDINAL, 0, 1024);
254 if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) {
255 // If workArea->value_len > 4, the remaining ones seem to be for WM's virtual desktops
256 // (don't mess with QXcbVirtualDesktop which represents an X screen).
257 // But QScreen doesn't know about that concept. In reality there could be a
258 // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop.
259 // But for now just assume the first 4 values give us the geometry of the
260 // "work area", AKA "available geometry"
261 uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea.get());
262 r = QRect(geom[0], geom[1], geom[2], geom[3]);
263 } else {
264 r.setWidth(-1);
265 }
266 return r;
267}
268
270{
271 QRect workArea = getWorkArea();
272 if (m_workArea != workArea) {
273 m_workArea = workArea;
274 for (QPlatformScreen *screen : std::as_const(m_screens))
275 ((QXcbScreen *)screen)->updateAvailableGeometry();
276 }
277}
278
280{
281 return m_workArea.width() >= 0 ? screenGeometry & m_workArea : screenGeometry;
282}
283
284static inline QSizeF sizeInMillimeters(const QSize &size, const QDpi &dpi)
285{
286 return QSizeF(Q_MM_PER_INCH * size.width() / dpi.first,
287 Q_MM_PER_INCH * size.height() / dpi.second);
288}
289
290bool QXcbVirtualDesktop::xResource(const QByteArray &identifier,
291 const QByteArray &expectedIdentifier,
292 QByteArray& stringValue)
293{
294 if (identifier.startsWith(expectedIdentifier)) {
295 stringValue = identifier.mid(expectedIdentifier.size());
296 return true;
297 }
298 return false;
299}
300
301static bool parseXftInt(const QByteArray& stringValue, int *value)
302{
304 bool ok;
305 *value = stringValue.toInt(&ok);
306 return ok;
307}
308
309static bool parseXftDpi(const QByteArray& stringValue, int *value)
310{
312 bool ok = parseXftInt(stringValue, value);
313 // Support GNOME 3 bug that wrote DPI with fraction:
314 if (!ok)
315 *value = qRound(stringValue.toDouble(&ok));
316 return ok;
317}
318
320{
321 if (stringValue == "hintfull")
323 else if (stringValue == "hintnone")
325 else if (stringValue == "hintmedium")
327 else if (stringValue == "hintslight")
329
330 return QFontEngine::HintStyle(-1);
331}
332
334{
335 if (stringValue == "none")
337 else if (stringValue == "rgb")
339 else if (stringValue == "bgr")
341 else if (stringValue == "vrgb")
343 else if (stringValue == "vbgr")
345
347}
348
349void QXcbVirtualDesktop::readXResources()
350{
351 int offset = 0;
352 QByteArray resources;
353 while (true) {
354 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
355 false, screen()->root,
356 XCB_ATOM_RESOURCE_MANAGER,
357 XCB_ATOM_STRING, offset/4, 8192);
358 bool more = false;
359 if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
360 resources += QByteArray((const char *)xcb_get_property_value(reply.get()), xcb_get_property_value_length(reply.get()));
361 offset += xcb_get_property_value_length(reply.get());
362 more = reply->bytes_after != 0;
363 }
364
365 if (!more)
366 break;
367 }
368
369 QList<QByteArray> split = resources.split('\n');
370 for (int i = 0; i < split.size(); ++i) {
371 const QByteArray &r = split.at(i);
372 int value;
373 QByteArray stringValue;
374 if (xResource(r, "Xft.dpi:\t", stringValue)) {
375 if (parseXftDpi(stringValue, &value))
376 m_forcedDpi = value;
377 } else if (xResource(r, "Xft.hintstyle:\t", stringValue)) {
378 m_hintStyle = parseXftHintStyle(stringValue);
379 } else if (xResource(r, "Xft.antialias:\t", stringValue)) {
380 if (parseXftInt(stringValue, &value))
381 m_antialiasingEnabled = value;
382 } else if (xResource(r, "Xft.rgba:\t", stringValue)) {
383 m_subpixelType = parseXftRgba(stringValue);
384 }
385 }
386}
387
388bool QXcbVirtualDesktop::setDpiFromXSettings(const QVariant &property)
389{
390 bool ok;
391 int dpiTimes1k = property.toInt(&ok);
392 if (!ok)
393 return false;
394 int dpi = dpiTimes1k / 1024;
395 if (m_forcedDpi == dpi)
396 return false;
397 m_forcedDpi = dpi;
398 return true;
399}
400
402{
403 const xcb_visualid_t xcb_visualid = connection()->hasDefaultVisualId() ? connection()->defaultVisualId()
404 : screen()->root_visual;
405 const xcb_visualtype_t *xcb_visualtype = visualForId(xcb_visualid);
406
407 const int redSize = qPopulationCount(xcb_visualtype->red_mask);
408 const int greenSize = qPopulationCount(xcb_visualtype->green_mask);
409 const int blueSize = qPopulationCount(xcb_visualtype->blue_mask);
410
412
413 if (result.redBufferSize() < 0)
414 result.setRedBufferSize(redSize);
415
416 if (result.greenBufferSize() < 0)
417 result.setGreenBufferSize(greenSize);
418
419 if (result.blueBufferSize() < 0)
420 result.setBlueBufferSize(blueSize);
421
422 return result;
423}
424
425const xcb_visualtype_t *QXcbVirtualDesktop::visualForFormat(const QSurfaceFormat &format) const
426{
427 const xcb_visualtype_t *candidate = nullptr;
428
429 for (const xcb_visualtype_t &xcb_visualtype : m_visuals) {
430
431 const int redSize = qPopulationCount(xcb_visualtype.red_mask);
432 const int greenSize = qPopulationCount(xcb_visualtype.green_mask);
433 const int blueSize = qPopulationCount(xcb_visualtype.blue_mask);
434 const int alphaSize = depthOfVisual(xcb_visualtype.visual_id) - redSize - greenSize - blueSize;
435
436 if (format.redBufferSize() != -1 && redSize != format.redBufferSize())
437 continue;
438
439 if (format.greenBufferSize() != -1 && greenSize != format.greenBufferSize())
440 continue;
441
442 if (format.blueBufferSize() != -1 && blueSize != format.blueBufferSize())
443 continue;
444
445 if (format.alphaBufferSize() != -1 && alphaSize != format.alphaBufferSize())
446 continue;
447
448 // Try to find a RGB visual rather than e.g. BGR or GBR
449 if (qCountTrailingZeroBits(xcb_visualtype.blue_mask) == 0)
450 return &xcb_visualtype;
451
452 // In case we do not find anything we like, just remember the first one
453 // and hope for the best:
454 if (!candidate)
455 candidate = &xcb_visualtype;
456 }
457
458 return candidate;
459}
460
461const xcb_visualtype_t *QXcbVirtualDesktop::visualForId(xcb_visualid_t visualid) const
462{
464 if (it == m_visuals.constEnd())
465 return nullptr;
466 return &*it;
467}
468
469quint8 QXcbVirtualDesktop::depthOfVisual(xcb_visualid_t visualid) const
470{
471 QMap<xcb_visualid_t, quint8>::const_iterator it = m_visualDepths.find(visualid);
472 if (it == m_visualDepths.constEnd())
473 return 0;
474 return *it;
475}
476
477xcb_colormap_t QXcbVirtualDesktop::colormapForVisual(xcb_visualid_t visualid) const
478{
479 auto it = m_visualColormaps.constFind(visualid);
480 if (it != m_visualColormaps.constEnd())
481 return *it;
482
483 auto cmap = xcb_generate_id(xcb_connection());
484 xcb_create_colormap(xcb_connection(),
485 XCB_COLORMAP_ALLOC_NONE,
486 cmap,
487 screen()->root,
488 visualid);
489 m_visualColormaps.insert(visualid, cmap);
490 return cmap;
491}
492
494 xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output)
496 , m_virtualDesktop(virtualDesktop)
497 , m_monitor(nullptr)
498 , m_output(outputId)
499 , m_crtc(output ? output->crtc : XCB_NONE)
500 , m_outputName(getOutputName(output))
501 , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
502 , m_cursor(std::make_unique<QXcbCursor>(connection, this))
503{
505 xcb_randr_select_input(xcb_connection(), screen()->root, true);
506 auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(),
507 m_crtc, output ? output->timestamp : 0);
508 if (crtc) {
509 updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation);
510 updateRefreshRate(crtc->mode);
511 }
512 }
513
514 if (m_geometry.isEmpty())
515 m_geometry = QRect(QPoint(), virtualDesktop->size());
516
517 if (m_availableGeometry.isEmpty())
518 m_availableGeometry = m_virtualDesktop->availableGeometry(m_geometry);
519
520 if (m_sizeMillimeters.isEmpty())
521 m_sizeMillimeters = virtualDesktop->physicalSize();
522
523 updateColorSpaceAndEdid();
524}
525
526void QXcbScreen::updateColorSpaceAndEdid()
527{
528 {
529 // Read colord ICC data (from GNOME settings)
530 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
531 false, screen()->root,
533 XCB_ATOM_CARDINAL, 0, 8192);
534 if (reply->format == 8 && reply->type == XCB_ATOM_CARDINAL) {
535 QByteArray data(reinterpret_cast<const char *>(xcb_get_property_value(reply.get())), reply->value_len);
536 m_colorSpace = QColorSpace::fromIccProfile(data);
537 }
538 }
539 if (connection()->isAtLeastXRandR12()) { // Parse EDID
540 QByteArray edid = getEdid();
541 if (m_edid.parse(edid)) {
542 qCDebug(lcQpaScreen, "EDID data for output \"%s\": identifier '%s', manufacturer '%s',"
543 "model '%s', serial '%s', physical size: %.2fx%.2f",
544 name().toLatin1().constData(),
545 m_edid.identifier.toLatin1().constData(),
547 m_edid.model.toLatin1().constData(),
549 m_edid.physicalSize.width(), m_edid.physicalSize.height());
550 if (!m_colorSpace.isValid()) {
551 if (m_edid.sRgb)
552 m_colorSpace = QColorSpace::SRgb;
553 else {
554 if (!m_edid.useTables) {
555 m_colorSpace = QColorSpace(m_edid.whiteChromaticity, m_edid.redChromaticity,
556 m_edid.greenChromaticity, m_edid.blueChromaticity,
558 } else {
559 if (m_edid.tables.size() == 1) {
560 m_colorSpace = QColorSpace(m_edid.whiteChromaticity, m_edid.redChromaticity,
561 m_edid.greenChromaticity, m_edid.blueChromaticity,
562 m_edid.tables[0]);
563 } else if (m_edid.tables.size() == 3) {
564 m_colorSpace = QColorSpace(m_edid.whiteChromaticity, m_edid.redChromaticity,
565 m_edid.greenChromaticity, m_edid.blueChromaticity,
566 m_edid.tables[0], m_edid.tables[1], m_edid.tables[2]);
567 }
568 }
569 }
570 }
571 } else {
572 // This property is defined by the xrandr spec. Parsing failure indicates a valid error,
573 // but keep this as debug, for details see 4f515815efc318ddc909a0399b71b8a684962f38.
574 qCDebug(lcQpaScreen) << "Failed to parse EDID data for output" << name() <<
575 "edid data: " << edid;
576 }
577 }
578 if (!m_colorSpace.isValid())
579 m_colorSpace = QColorSpace::SRgb;
580}
581
583 xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp)
585 , m_virtualDesktop(virtualDesktop)
586 , m_monitor(monitorInfo)
587 , m_cursor(std::make_unique<QXcbCursor>(connection, this))
588{
589 setMonitor(monitorInfo, timestamp);
590}
591
592void QXcbScreen::setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp)
593{
594 if (!connection()->isAtLeastXRandR15())
595 return;
596
597 m_outputs.clear();
598 m_crtcs.clear();
599 m_output = XCB_NONE;
600 m_crtc = XCB_NONE;
601 m_singlescreen = false;
602
603 if (!monitorInfo) {
604 m_monitor = nullptr;
605 m_mode = XCB_NONE;
606 m_outputName = defaultName();
607 // TODO: Send an event to the QScreen instance that the screen changed its name
608 return;
609 }
610
611 xcb_randr_select_input(xcb_connection(), screen()->root, true);
612
613 m_monitor = monitorInfo;
614 qCDebug(lcQpaScreen) << "xcb_randr_monitor_info_t: primary=" << m_monitor->primary << ", x=" << m_monitor->x << ", y=" << m_monitor->y
615 << ", width=" << m_monitor->width << ", height=" << m_monitor->height
616 << ", width_in_millimeters=" << m_monitor->width_in_millimeters << ", height_in_millimeters=" << m_monitor->height_in_millimeters;
617 QRect monitorGeometry = QRect(m_monitor->x, m_monitor->y,
618 m_monitor->width, m_monitor->height);
619 m_sizeMillimeters = QSize(m_monitor->width_in_millimeters, m_monitor->height_in_millimeters);
620
621 int outputCount = xcb_randr_monitor_info_outputs_length(m_monitor);
622 xcb_randr_output_t *outputs = nullptr;
623 if (outputCount) {
624 outputs = xcb_randr_monitor_info_outputs(m_monitor);
625 for (int i = 0; i < outputCount; i++) {
626 auto output = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_output_info,
627 xcb_connection(), outputs[i], timestamp);
628 // Invalid, disconnected or disabled output
629 if (!output)
630 continue;
631
632 if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) {
633 qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable(
634 QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.get()),
635 xcb_randr_get_output_info_name_length(output.get()))));
636 continue;
637 }
638
639 if (output->crtc == XCB_NONE) {
640 qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable(
641 QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.get()),
642 xcb_randr_get_output_info_name_length(output.get()))));
643 continue;
644 }
645
646 m_outputs << outputs[i];
647 if (m_output == XCB_NONE) {
648 m_output = outputs[i];
649 m_outputSizeMillimeters = QSize(output->mm_width, output->mm_height);
650 }
651 m_crtcs << output->crtc;
652 if (m_crtc == XCB_NONE)
653 m_crtc = output->crtc;
654 }
655 }
656
657 if (m_crtcs.size() == 1) {
658 auto crtc = Q_XCB_REPLY(xcb_randr_get_crtc_info,
659 xcb_connection(), m_crtcs[0], timestamp);
660 m_singlescreen = (monitorGeometry == (QRect(crtc->x, crtc->y, crtc->width, crtc->height)));
661 if (m_singlescreen) {
662 if (crtc->mode) {
663 updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation);
664 if (mode() != crtc->mode)
665 updateRefreshRate(crtc->mode);
666 }
667 }
668 }
669
670 if (!m_singlescreen)
671 m_geometry = monitorGeometry;
672 m_availableGeometry = m_virtualDesktop->availableGeometry(m_geometry);
673 if (m_geometry.isEmpty())
674 m_geometry = QRect(QPoint(), virtualDesktop()->size());
675 if (m_availableGeometry.isEmpty())
676 m_availableGeometry = m_virtualDesktop->availableGeometry(m_geometry);
677
678 if (m_sizeMillimeters.isEmpty())
679 m_sizeMillimeters = virtualDesktop()->physicalSize();
680
681 m_outputName = getName(monitorInfo);
682 m_primary = false;
683 if (connection()->primaryScreenNumber() == virtualDesktop()->number()) {
684 if (monitorInfo->primary || isPrimaryInXScreen())
685 m_primary = true;
686 }
687
688 updateColorSpaceAndEdid();
689}
690
692{
695 int dotPos = displayName.lastIndexOf('.');
696 if (dotPos != -1)
697 displayName.truncate(dotPos);
699 + QString::number(m_virtualDesktop->number());
700 return name;
701}
702
704{
705 auto primary = Q_XCB_REPLY(xcb_randr_get_output_primary, connection()->xcb_connection(), root());
706 if (!primary)
707 qWarning("failed to get the primary output of the screen");
708
709 const bool isPrimary = primary ? (m_monitor ? m_outputs.contains(primary->output) : m_output == primary->output) : false;
710
711 return isPrimary;
712}
713
717
718QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo)
719{
721 if (outputInfo) {
722 name = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(outputInfo),
723 xcb_randr_get_output_info_name_length(outputInfo));
724 } else {
725 name = defaultName();
726 }
727 return name;
728}
729
730QString QXcbScreen::getName(xcb_randr_monitor_info_t *monitorInfo)
731{
733 QByteArray ba = connection()->atomName(monitorInfo->name);
734 if (!ba.isEmpty()) {
736 } else {
738 int dotPos = displayName.lastIndexOf('.');
739 if (dotPos != -1)
740 displayName.truncate(dotPos);
742 + QString::number(m_virtualDesktop->number());
743 }
744 return name;
745}
746
748{
749 return m_edid.manufacturer;
750}
751
753{
754 return m_edid.model;
755}
756
758{
759 return m_edid.serialNumber;
760}
761
763{
764 xcb_window_t root = screen()->root;
765
766 int x = p.x();
767 int y = p.y();
768
769 xcb_window_t parent = root;
770 xcb_window_t child = root;
771
772 do {
773 auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates, xcb_connection(), parent, child, x, y);
774 if (!translate_reply) {
775 return nullptr;
776 }
777
778 parent = child;
779 child = translate_reply->child;
780 x = translate_reply->dst_x;
781 y = translate_reply->dst_y;
782
783 if (!child || child == root)
784 return nullptr;
785
787 if (platformWindow)
788 return platformWindow->window();
789 } while (parent != child);
790
791 return nullptr;
792}
793
795{
796 // Freedesktop.org Startup Notification
797 if (!connection()->startupId().isEmpty() && window->window()->isTopLevel()) {
798 sendStartupMessage(QByteArrayLiteral("remove: ID=") + connection()->startupId());
800 }
801}
802
804{
805 return m_virtualDesktop->surfaceFormatFor(format);
806}
807
808const xcb_visualtype_t *QXcbScreen::visualForId(xcb_visualid_t visualid) const
809{
810 return m_virtualDesktop->visualForId(visualid);
811}
812
813void QXcbScreen::sendStartupMessage(const QByteArray &message) const
814{
815 xcb_window_t rootWindow = root();
816
817 xcb_client_message_event_t ev;
818 ev.response_type = XCB_CLIENT_MESSAGE;
819 ev.format = 8;
821 ev.sequence = 0;
822 ev.window = rootWindow;
823 int sent = 0;
824 int length = message.size() + 1; // include NUL byte
825 const char *data = message.constData();
826 do {
827 if (sent == 20)
829
830 const int start = sent;
831 const int numBytes = qMin(length - start, 20);
832 memcpy(ev.data.data8, data + start, numBytes);
833 xcb_send_event(connection()->xcb_connection(), false, rootWindow, XCB_EVENT_MASK_PROPERTY_CHANGE, (const char *) &ev);
834
835 sent += numBytes;
836 } while (sent < length);
837}
838
840{
841 static bool enforceNetWorkarea = !qEnvironmentVariableIsEmpty("QT_RELY_ON_NET_WORKAREA_ATOM");
842 bool isMultiHeadSystem = virtualSiblings().size() > 1;
843 bool useScreenGeometry = isMultiHeadSystem && !enforceNetWorkarea;
844 return useScreenGeometry ? m_geometry : m_availableGeometry;
845}
846
848{
850 bool needsRgbSwap;
851 qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual), &format, &needsRgbSwap);
852 // We are ignoring needsRgbSwap here and just assumes the backing-store will handle it.
854 return format;
856}
857
858int QXcbScreen::forcedDpi() const
859{
860 const int forcedDpi = m_virtualDesktop->forcedDpi();
861 if (forcedDpi > 0)
862 return forcedDpi;
863 return 0;
864}
865
867{
868 const int forcedDpi = this->forcedDpi();
869 if (forcedDpi > 0)
870 return QDpi(forcedDpi, forcedDpi);
871
872 // Fall back to 96 DPI in case no logical DPI is set. We don't want to
873 // return physical DPI here, since that is a different type of DPI: Logical
874 // DPI typically accounts for user preference and viewing distance, and is
875 // quantized into DPI classes (96, 144, 192, etc); pysical DPI is an exact
876 // physical measure.
877 return QDpi(96, 96);
878}
879
881{
882 return m_cursor.get();
883}
884
885void QXcbScreen::setOutput(xcb_randr_output_t outputId,
886 xcb_randr_get_output_info_reply_t *outputInfo)
887{
888 m_monitor = nullptr;
889 m_output = outputId;
890 m_crtc = outputInfo ? outputInfo->crtc : XCB_NONE;
891 m_mode = XCB_NONE;
892 m_outputName = getOutputName(outputInfo);
893 // TODO: Send an event to the QScreen instance that the screen changed its name
894}
895
896void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
897{
898 if (!connection()->isAtLeastXRandR12())
899 return;
900
901 auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(),
902 m_crtc, timestamp);
903 if (crtc)
904 updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation);
905}
906
907void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
908{
909 const Qt::ScreenOrientation oldOrientation = m_orientation;
910
911 switch (rotation) {
912 case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
913 m_orientation = Qt::LandscapeOrientation;
914 if (!m_monitor)
915 m_sizeMillimeters = m_outputSizeMillimeters;
916 break;
917 case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
918 m_orientation = Qt::PortraitOrientation;
919 if (!m_monitor)
920 m_sizeMillimeters = m_outputSizeMillimeters.transposed();
921 break;
922 case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
923 m_orientation = Qt::InvertedLandscapeOrientation;
924 if (!m_monitor)
925 m_sizeMillimeters = m_outputSizeMillimeters;
926 break;
927 case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
928 m_orientation = Qt::InvertedPortraitOrientation;
929 if (!m_monitor)
930 m_sizeMillimeters = m_outputSizeMillimeters.transposed();
931 break;
932 }
933
934 // It can be that physical size is unknown while virtual size
935 // is known (probably back-calculated from DPI and resolution),
936 // e.g. on VNC or with some hardware.
937 if (m_sizeMillimeters.isEmpty())
938 m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi());
939
940 m_geometry = geometry;
941 m_availableGeometry = m_virtualDesktop->availableGeometry(m_geometry);
943 if (m_orientation != oldOrientation)
945}
946
948{
949 QRect availableGeometry = m_virtualDesktop->availableGeometry(m_geometry);
950 if (m_availableGeometry != availableGeometry) {
951 m_availableGeometry = availableGeometry;
953 }
954}
955
957{
958 if (!connection()->isAtLeastXRandR12())
959 return;
960
961 if (m_mode == mode)
962 return;
963
964 // we can safely use get_screen_resources_current here, because in order to
965 // get here, we must have called get_screen_resources before
966 auto resources = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_screen_resources_current,
968 if (resources) {
969 xcb_randr_mode_info_iterator_t modesIter =
970 xcb_randr_get_screen_resources_current_modes_iterator(resources.get());
971 for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) {
972 xcb_randr_mode_info_t *modeInfo = modesIter.data;
973 if (modeInfo->id == mode) {
974 const uint32_t dotCount = modeInfo->htotal * modeInfo->vtotal;
975 m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / qreal(dotCount) : 0;
976 m_mode = mode;
977 break;
978 }
979 }
980
982 }
983}
984
985static inline bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent,
986 int *x, int *y)
987{
988 auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates,
989 connection, child, parent, *x, *y);
990 if (!translate_reply)
991 return false;
992 *x = translate_reply->dst_x;
993 *y = translate_reply->dst_y;
994 return true;
995}
996
997QPixmap QXcbScreen::grabWindow(WId window, int xIn, int yIn, int width, int height) const
998{
999 if (width == 0 || height == 0)
1000 return QPixmap();
1001
1002 int x = xIn;
1003 int y = yIn;
1004 QXcbScreen *screen = const_cast<QXcbScreen *>(this);
1005 xcb_window_t root = screen->root();
1006
1007 auto rootReply = Q_XCB_REPLY_UNCHECKED(xcb_get_geometry, xcb_connection(), root);
1008 if (!rootReply)
1009 return QPixmap();
1010
1011 const quint8 rootDepth = rootReply->depth;
1012
1013 QSize windowSize;
1014 quint8 effectiveDepth = 0;
1015 if (window) {
1016 auto windowReply = Q_XCB_REPLY_UNCHECKED(xcb_get_geometry, xcb_connection(), window);
1017 if (!windowReply)
1018 return QPixmap();
1019 windowSize = QSize(windowReply->width, windowReply->height);
1020 effectiveDepth = windowReply->depth;
1021 if (effectiveDepth == rootDepth) {
1022 // if the depth of the specified window and the root window are the
1023 // same, grab pixels from the root window (so that we get the any
1024 // overlapping windows and window manager frames)
1025
1026 // map x and y to the root window
1027 if (!translate(xcb_connection(), window, root, &x, &y))
1028 return QPixmap();
1029
1030 window = root;
1031 }
1032 } else {
1033 window = root;
1034 effectiveDepth = rootDepth;
1035 windowSize = m_geometry.size();
1036 x += m_geometry.x();
1037 y += m_geometry.y();
1038 }
1039
1040 if (width < 0)
1041 width = windowSize.width() - xIn;
1042 if (height < 0)
1043 height = windowSize.height() - yIn;
1044
1045 auto attributes_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_window_attributes, xcb_connection(), window);
1046
1047 if (!attributes_reply)
1048 return QPixmap();
1049
1050 const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
1051
1052 xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection());
1053 xcb_create_pixmap(xcb_connection(), effectiveDepth, pixmap, window, width, height);
1054
1055 uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE;
1056 uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };
1057
1058 xcb_gcontext_t gc = xcb_generate_id(xcb_connection());
1059 xcb_create_gc(xcb_connection(), gc, pixmap, gc_value_mask, gc_value_list);
1060
1061 xcb_copy_area(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height);
1062
1063 QPixmap result = qt_xcb_pixmapFromXPixmap(connection(), pixmap, width, height, effectiveDepth, visual);
1064 xcb_free_gc(xcb_connection(), gc);
1065 xcb_free_pixmap(xcb_connection(), pixmap);
1066
1067 return result;
1068}
1069
1071{
1072 return m_virtualDesktop->xSettings();
1073}
1074
1075QByteArray QXcbScreen::getOutputProperty(xcb_atom_t atom) const
1076{
1078
1079 auto reply = Q_XCB_REPLY(xcb_randr_get_output_property, xcb_connection(),
1080 m_output, atom, XCB_ATOM_ANY, 0, 100, false, false);
1081 if (reply && reply->type == XCB_ATOM_INTEGER && reply->format == 8) {
1082 quint8 *data = new quint8[reply->num_items];
1083 memcpy(data, xcb_randr_get_output_property_data(reply.get()), reply->num_items);
1084 result = QByteArray(reinterpret_cast<const char *>(data), reply->num_items);
1085 delete[] data;
1086 }
1087
1088 return result;
1089}
1090
1091QByteArray QXcbScreen::getEdid() const
1092{
1094 if (!connection()->isAtLeastXRandR12())
1095 return result;
1096
1097 // Try a bunch of atoms
1098 result = getOutputProperty(atom(QXcbAtom::AtomEDID));
1099 if (result.isEmpty())
1100 result = getOutputProperty(atom(QXcbAtom::AtomEDID_DATA));
1101 if (result.isEmpty())
1103
1104 return result;
1105}
1106
1107static inline void formatRect(QDebug &debug, const QRect r)
1108{
1109 debug << r.width() << 'x' << r.height()
1110 << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
1111}
1112
1113static inline void formatSizeF(QDebug &debug, const QSizeF s)
1114{
1115 debug << s.width() << 'x' << s.height() << "mm";
1116}
1117
1119{
1120 const QDebugStateSaver saver(debug);
1121 debug.nospace();
1122 debug << "QXcbScreen(" << (const void *)screen;
1123 if (screen) {
1125 debug << ", name=" << screen->name();
1126 debug << ", geometry=";
1128 debug << ", availableGeometry=";
1130 debug << ", devicePixelRatio=" << screen->devicePixelRatio();
1131 debug << ", logicalDpi=" << screen->logicalDpi();
1132 debug << ", physicalSize=";
1134 // TODO 5.6 if (debug.verbosity() > 2) {
1135 debug << ", screenNumber=" << screen->screenNumber();
1136 const QSize virtualSize = screen->virtualDesktop()->size();
1137 debug << ", virtualSize=" << virtualSize.width() << 'x' << virtualSize.height() << " (";
1138 formatSizeF(debug, virtualSize);
1139 debug << "), orientation=" << screen->orientation();
1140 debug << ", depth=" << screen->depth();
1141 debug << ", refreshRate=" << screen->refreshRate();
1142 debug << ", root=" << Qt::hex << screen->root();
1143 debug << ", windowManagerName=" << screen->windowManagerName();
1144 }
1145 debug << ')';
1146 return debug;
1147}
1148
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
int toInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an int using base base, which is ten by default.
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
double toDouble(bool *ok=nullptr) const
Returns the byte array converted to a double value.
bool startsWith(QByteArrayView bv) const
Definition qbytearray.h:223
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
QByteArray mid(qsizetype index, qsizetype len=-1) const &
The QColorSpace class provides a color space abstraction.
Definition qcolorspace.h:21
bool isValid() const noexcept
Returns true if the color space is valid.
static QColorSpace fromIccProfile(const QByteArray &iccProfile)
Creates a QColorSpace from ICC profile iccProfile.
\inmodule QtCore
\inmodule QtCore
QSizeF physicalSize
QPointF blueChromaticity
QPointF redChromaticity
QList< QList< uint16_t > > tables
QString model
QPointF whiteChromaticity
QString manufacturer
QPointF greenChromaticity
bool parse(const QByteArray &blob)
QString identifier
QString serialNumber
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ Format_RGB32
Definition qimage.h:46
@ Format_Invalid
Definition qimage.h:42
qsizetype size() const noexcept
Definition qlist.h:397
void swapItemsAt(qsizetype i, qsizetype j)
Definition qlist.h:667
void prepend(rvalue_ref t)
Definition qlist.h:473
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
const_iterator constFind(const Key &key) const
Definition qmap.h:655
iterator find(const Key &key)
Definition qmap.h:641
const_iterator constEnd() const
Definition qmap.h:604
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
The QPlatformCursor class provides information about pointer device events (movement,...
The QPlatformScreen class provides an abstraction for visual displays.
QScreen * screen() const
The QPlatformWindow class provides an abstraction for top-level windows.
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
Definition qrect.h:167
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
qreal devicePixelRatio
the screen's ratio between physical pixels and device-independent pixels
Definition qscreen.h:59
QRect availableGeometry
the screen's available geometry in pixels
Definition qscreen.h:46
QSizeF physicalSize
the screen's physical size (in millimeters)
Definition qscreen.h:50
QRect geometry
the screen's geometry in pixels
Definition qscreen.h:45
qreal refreshRate
the approximate vertical refresh rate of the screen in Hz
Definition qscreen.h:64
QSize size
the pixel resolution of the screen
Definition qscreen.h:41
int depth
the color depth of the screen
Definition qscreen.h:40
Qt::ScreenOrientation orientation
the screen orientation
Definition qscreen.h:62
QString name
a user presentable string representing the screen
Definition qscreen.h:36
\inmodule QtCore
Definition qsize.h:208
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:332
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:326
constexpr QSizeF transposed() const noexcept
Definition qsize.h:344
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:335
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QByteArray toLatin1() const &
Definition qstring.h:630
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
void setRedBufferSize(int size)
Set the desired size in bits of the red channel of the color buffer.
\inmodule QtCore
Definition qvariant.h:65
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry)
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation)
static void handleScreenRefreshRateChange(QScreen *screen, qreal newRefreshRate)
static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY)
\inmodule QtGui
Definition qwindow.h:63
@ Atom_NET_SUPPORTING_WM_CHECK
Definition qxcbatom.h:123
@ Atom_ICC_PROFILE
Definition qxcbatom.h:212
@ AtomXFree86_DDC_EDID1_RAWDATA
Definition qxcbatom.h:210
@ Atom_NET_WORKAREA
Definition qxcbatom.h:70
@ AtomEDID_DATA
Definition qxcbatom.h:209
@ Atom_NET_STARTUP_INFO_BEGIN
Definition qxcbatom.h:120
@ Atom_NET_STARTUP_INFO
Definition qxcbatom.h:119
QByteArray atomName(xcb_atom_t atom)
xcb_atom_t internAtom(const char *name)
const char * displayName() const
xcb_atom_t atom(QXcbAtom::Atom qatom) const
xcb_window_t selectionOwner(xcb_atom_t atom) const
xcb_visualid_t defaultVisualId() const
bool hasDefaultVisualId() const
void setStartupId(const QByteArray &nextId)
const QList< QXcbScreen * > & screens() const
QXcbWindow * platformWindowFromId(xcb_window_t id)
QXcbConnection * connection() const
Definition qxcbobject.h:17
xcb_connection_t * xcb_connection() const
Definition qxcbobject.h:20
xcb_atom_t atom(QXcbAtom::Atom atom) const
Definition qxcbobject.h:19
xcb_randr_crtc_t crtc() const
Definition qxcbscreen.h:155
bool isPrimaryInXScreen()
void updateAvailableGeometry()
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &format) const
QString serialNumber() const override
Reimplement this function in subclass to return the serial number of this screen.
QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo)
QString defaultName()
xcb_screen_t * screen() const
Definition qxcbscreen.h:152
QWindow * topLevelAt(const QPoint &point) const override
Return the given top level window for a given position.
bool isPrimary() const
Definition qxcbscreen.h:147
xcb_window_t root() const
Definition qxcbscreen.h:153
QString getName(xcb_randr_monitor_info_t *monitorInfo)
QImage::Format format() const override
Reimplement in subclass to return the image format which corresponds to the screen format.
QString name() const override
Definition qxcbscreen.h:178
void updateRefreshRate(xcb_randr_mode_t mode)
QList< xcb_randr_output_t > outputs() const
Definition qxcbscreen.h:158
void updateGeometry(const QRect &geometry, uint8_t rotation)
QRect geometry() const override
Reimplement in subclass to return the pixel geometry of the screen.
Definition qxcbscreen.h:132
QString model() const override
Reimplement this function in subclass to return the model of this screen.
const xcb_visualtype_t * visualForId(xcb_visualid_t visualid) const
xcb_randr_mode_t mode() const
Definition qxcbscreen.h:156
QRect availableGeometry() const override
Reimplement in subclass to return the pixel geometry of the available space This normally is the desk...
void setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp=XCB_NONE)
QPixmap grabWindow(WId window, int x, int y, int width, int height) const override
This function is called when Qt needs to be able to grab the content of a window.
QXcbVirtualDesktop * virtualDesktop() const
Definition qxcbscreen.h:144
QList< QPlatformScreen * > virtualSiblings() const override
Returns a list of all the platform screens that are part of the same virtual desktop.
Definition qxcbscreen.h:143
void setOutput(xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo)
QPlatformCursor * cursor() const override
Reimplement this function in subclass to return the cursor of the screen.
QString getOutputName(xcb_randr_get_output_info_reply_t *outputInfo)
xcb_randr_output_t output() const
Definition qxcbscreen.h:154
void windowShown(QXcbWindow *window)
QString manufacturer() const override
Reimplement this function in subclass to return the manufacturer of this screen.
QXcbXSettings * xSettings() const
QDpi logicalDpi() const override
Reimplement this function in subclass to return the logical horizontal and vertical dots per inch met...
xcb_colormap_t colormapForVisual(xcb_visualid_t) const
QDpi dpi() const
bool compositingActive() const
void addScreen(QPlatformScreen *s)
int forcedDpi() const
Definition qxcbscreen.h:64
const xcb_visualtype_t * visualForId(xcb_visualid_t) const
xcb_window_t root() const
Definition qxcbscreen.h:43
QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t *screen, int number)
void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
handle the XCB screen change event and update properties
const xcb_visualtype_t * visualForFormat(const QSurfaceFormat &format) const
QSize physicalSize() const
Definition qxcbscreen.h:41
quint8 depthOfVisual(xcb_visualid_t) const
int number() const
Definition qxcbscreen.h:39
QXcbXSettings * xSettings() const
QList< QPlatformScreen * > screens() const
Definition qxcbscreen.h:46
void subscribeToXFixesSelectionNotify()
void setPrimaryScreen(QPlatformScreen *s)
QRect availableGeometry(const QRect &screenGeometry) const
void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event)
QSize size() const
Definition qxcbscreen.h:40
QXcbScreen * screenAt(const QPoint &pos) const
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &format) const
xcb_screen_t * screen() const
Definition qxcbscreen.h:38
static QString windowTitle(const QXcbConnection *conn, xcb_window_t window)
void registerCallbackForProperty(const QByteArray &property, PropertyChangeFunc func, void *handle)
#define this
Definition dialogs.cpp:9
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & noforcesign(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::ForceSign) on stream and...
ScreenOrientation
Definition qnamespace.h:271
@ InvertedLandscapeOrientation
Definition qnamespace.h:276
@ InvertedPortraitOrientation
Definition qnamespace.h:275
@ LandscapeOrientation
Definition qnamespace.h:274
@ PortraitOrientation
Definition qnamespace.h:273
QTextStream & fixed(QTextStream &stream)
Calls QTextStream::setRealNumberNotation(QTextStream::FixedNotation) on stream and returns stream.
QTextStream & forcesign(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ForceSign) on stream and ...
constexpr uint qCountTrailingZeroBits(quint32 v) noexcept
Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR uint qPopulationCount(quint32 v) noexcept
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
static QString displayName(CGDirectDisplayID displayID)
DBusConnection * connection
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
QPair< qreal, qreal > QDpi
#define qWarning
Definition qlogging.h:166
#define qCDebug(category,...)
static const qreal Q_MM_PER_INCH
Definition qmath_p.h:25
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLenum GLsizei GLsizei GLint * values
[15]
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum mode
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei width
GLuint GLsizei const GLchar * message
GLuint start
GLenum GLuint GLintptr offset
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint y
GLdouble s
[6]
Definition qopenglext.h:235
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static void split(QT_FT_Vector *b)
#define qPrintable(string)
Definition qstring.h:1531
QScreen * screen
[1]
Definition main.cpp:29
void gc(QV4::ExecutionEngine &engine, GCFlags flags)
Definition qmlutils.cpp:118
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
QTextStreamManipulator qSetRealNumberPrecision(int precision)
unsigned int quint32
Definition qtypes.h:50
double qreal
Definition qtypes.h:187
unsigned char quint8
Definition qtypes.h:46
QT_BEGIN_NAMESPACE typedef uchar * output
const char property[13]
Definition qwizard.cpp:101
#define Q_XCB_REPLY(call,...)
#define Q_XCB_REPLY_UNCHECKED(call,...)
QT_BEGIN_NAMESPACE bool qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, const xcb_visualtype_t *visual, QImage::Format *imageFormat, bool *needsRgbSwap)
Definition qxcbimage.cpp:68
QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap, int width, int height, int depth, const xcb_visualtype_t *visual)
static QSizeF sizeInMillimeters(const QSize &size, const QDpi &dpi)
static bool parseXftInt(const QByteArray &stringValue, int *value)
static void formatSizeF(QDebug &debug, const QSizeF s)
static QFontEngine::SubpixelAntialiasingType parseXftRgba(const QByteArray &stringValue)
static bool parseXftDpi(const QByteArray &stringValue, int *value)
static void formatRect(QDebug &debug, const QRect r)
static QFontEngine::HintStyle parseXftHintStyle(const QByteArray &stringValue)
static bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent, int *x, int *y)
QDebug operator<<(QDebug debug, const QXcbScreen *screen)
QByteArray ba
[0]
QObject::connect nullptr
QLayoutItem * child
[0]
widget render & pixmap
aWidget window() -> setWindowTitle("New Window Title")
[2]
QNetworkReply * reply
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:962
bool contains(const AT &t) const noexcept
Definition qlist.h:45