1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qscreen.h"
41#include "qscreen_p.h"
42#include "qpixmap.h"
43#include "qguiapplication_p.h"
44#include <qpa/qplatformscreen.h>
45#include <qpa/qplatformscreen_p.h>
46
47#include <QtCore/QDebug>
48#include <QtCore/private/qobject_p.h>
49#include "qhighdpiscaling_p.h"
50
51QT_BEGIN_NAMESPACE
52
53/*!
54 \class QScreen
55 \since 5.0
56 \brief The QScreen class is used to query screen properties.
57 \inmodule QtGui
58
59 A note on logical vs physical dots per inch: physical DPI is based on the
60 actual physical pixel sizes when available, and is useful for print preview
61 and other cases where it's desirable to know the exact physical dimensions
62 of screen displayed contents.
63
64 Logical dots per inch are used to convert font and user interface elements
65 from point sizes to pixel sizes, and might be different from the physical
66 dots per inch. The logical dots per inch are sometimes user-settable in the
67 desktop environment's settings panel, to let the user globally control UI
68 and font sizes in different applications.
69
70 \inmodule QtGui
71*/
72
73QScreen::QScreen(QPlatformScreen *screen)
74 : QObject(*new QScreenPrivate(), 0)
75{
76 Q_D(QScreen);
77 d->setPlatformScreen(screen);
78}
79
80void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
81{
82 Q_Q(QScreen);
83 platformScreen = screen;
84 platformScreen->d_func()->screen = q;
85 orientation = platformScreen->orientation();
86 geometry = platformScreen->deviceIndependentGeometry();
87 availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
88 logicalDpi = platformScreen->logicalDpi();
89 refreshRate = platformScreen->refreshRate();
90 // safeguard ourselves against buggy platform behavior...
91 if (refreshRate < 1.0)
92 refreshRate = 60.0;
93
94 updatePrimaryOrientation();
95
96 filteredOrientation = orientation;
97 if (filteredOrientation == Qt::PrimaryOrientation)
98 filteredOrientation = primaryOrientation;
99
100 updateHighDpi();
101}
102
103
104/*!
105 Destroys the screen.
106 */
107QScreen::~QScreen()
108{
109 // Remove screen
110 const bool wasPrimary = QGuiApplication::primaryScreen() == this;
111 QGuiApplicationPrivate::screen_list.removeOne(this);
112 QGuiApplicationPrivate::resetCachedDevicePixelRatio();
113
114 if (!qGuiApp)
115 return;
116
117 QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
118 if (wasPrimary && newPrimaryScreen)
119 emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
120
121 // Allow clients to manage windows that are affected by the screen going
122 // away, before we fall back to moving them to the primary screen.
123 emit qApp->screenRemoved(this);
124
125 if (QGuiApplication::closingDown())
126 return;
127
128 bool movingFromVirtualSibling = newPrimaryScreen
129 && newPrimaryScreen->handle()->virtualSiblings().contains(handle());
130
131 // Move any leftover windows to the primary screen
132 const auto allWindows = QGuiApplication::allWindows();
133 for (QWindow *window : allWindows) {
134 if (!window->isTopLevel() || window->screen() != this)
135 continue;
136
137 const bool wasVisible = window->isVisible();
138 window->setScreen(newPrimaryScreen);
139
140 // Re-show window if moved from a virtual sibling screen. Otherwise
141 // leave it up to the application developer to show the window.
142 if (movingFromVirtualSibling)
143 window->setVisible(wasVisible);
144 }
145}
146
147/*!
148 Get the platform screen handle.
149*/
150QPlatformScreen *QScreen::handle() const
151{
152 Q_D(const QScreen);
153 return d->platformScreen;
154}
155
156/*!
157 \property QScreen::name
158 \brief a user presentable string representing the screen
159
160 For example, on X11 these correspond to the XRandr screen names,
161 typically "VGA1", "HDMI1", etc.
162*/
163QString QScreen::name() const
164{
165 Q_D(const QScreen);
166 return d->platformScreen->name();
167}
168
169/*!
170 \property QScreen::manufacturer
171 \brief the manufacturer of the screen
172
173 \since 5.9
174*/
175QString QScreen::manufacturer() const
176{
177 Q_D(const QScreen);
178 return d->platformScreen->manufacturer();
179}
180
181/*!
182 \property QScreen::model
183 \brief the model of the screen
184
185 \since 5.9
186*/
187QString QScreen::model() const
188{
189 Q_D(const QScreen);
190 return d->platformScreen->model();
191}
192
193/*!
194 \property QScreen::serialNumber
195 \brief the serial number of the screen
196
197 \since 5.9
198*/
199QString QScreen::serialNumber() const
200{
201 Q_D(const QScreen);
202 return d->platformScreen->serialNumber();
203}
204
205/*!
206 \property QScreen::depth
207 \brief the color depth of the screen
208*/
209int QScreen::depth() const
210{
211 Q_D(const QScreen);
212 return d->platformScreen->depth();
213}
214
215/*!
216 \property QScreen::size
217 \brief the pixel resolution of the screen
218*/
219QSize QScreen::size() const
220{
221 Q_D(const QScreen);
222 return d->geometry.size();
223}
224
225/*!
226 \property QScreen::physicalDotsPerInchX
227 \brief the number of physical dots or pixels per inch in the horizontal direction
228
229 This value represents the actual horizontal pixel density on the screen's display.
230 Depending on what information the underlying system provides the value might not be
231 entirely accurate.
232
233 \sa physicalDotsPerInchY()
234*/
235qreal QScreen::physicalDotsPerInchX() const
236{
237 return size().width() / physicalSize().width() * qreal(25.4);
238}
239
240/*!
241 \property QScreen::physicalDotsPerInchY
242 \brief the number of physical dots or pixels per inch in the vertical direction
243
244 This value represents the actual vertical pixel density on the screen's display.
245 Depending on what information the underlying system provides the value might not be
246 entirely accurate.
247
248 \sa physicalDotsPerInchX()
249*/
250qreal QScreen::physicalDotsPerInchY() const
251{
252 return size().height() / physicalSize().height() * qreal(25.4);
253}
254
255/*!
256 \property QScreen::physicalDotsPerInch
257 \brief the number of physical dots or pixels per inch
258
259 This value represents the pixel density on the screen's display.
260 Depending on what information the underlying system provides the value might not be
261 entirely accurate.
262
263 This is a convenience property that's simply the average of the physicalDotsPerInchX
264 and physicalDotsPerInchY properties.
265
266 \sa physicalDotsPerInchX()
267 \sa physicalDotsPerInchY()
268*/
269qreal QScreen::physicalDotsPerInch() const
270{
271 QSize sz = size();
272 QSizeF psz = physicalSize();
273 return ((sz.height() / psz.height()) + (sz.width() / psz.width())) * qreal(25.4 * 0.5);
274}
275
276/*!
277 \property QScreen::logicalDotsPerInchX
278 \brief the number of logical dots or pixels per inch in the horizontal direction
279
280 This value is used to convert font point sizes to pixel sizes.
281
282 \sa logicalDotsPerInchY()
283*/
284qreal QScreen::logicalDotsPerInchX() const
285{
286 Q_D(const QScreen);
287 if (QHighDpiScaling::isActive())
288 return QHighDpiScaling::logicalDpi().first;
289 return d->logicalDpi.first;
290}
291
292/*!
293 \property QScreen::logicalDotsPerInchY
294 \brief the number of logical dots or pixels per inch in the vertical direction
295
296 This value is used to convert font point sizes to pixel sizes.
297
298 \sa logicalDotsPerInchX()
299*/
300qreal QScreen::logicalDotsPerInchY() const
301{
302 Q_D(const QScreen);
303 if (QHighDpiScaling::isActive())
304 return QHighDpiScaling::logicalDpi().second;
305 return d->logicalDpi.second;
306}
307
308/*!
309 \property QScreen::logicalDotsPerInch
310 \brief the number of logical dots or pixels per inch
311
312 This value can be used to convert font point sizes to pixel sizes.
313
314 This is a convenience property that's simply the average of the logicalDotsPerInchX
315 and logicalDotsPerInchY properties.
316
317 \sa logicalDotsPerInchX()
318 \sa logicalDotsPerInchY()
319*/
320qreal QScreen::logicalDotsPerInch() const
321{
322 Q_D(const QScreen);
323 QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi() : d->logicalDpi;
324 return (dpi.first + dpi.second) * qreal(0.5);
325}
326
327/*!
328 \property QScreen::devicePixelRatio
329 \brief the screen's ratio between physical pixels and device-independent pixels
330 \since 5.5
331
332 Returns the ratio between physical pixels and device-independent pixels for the screen.
333
334 Common values are 1.0 on normal displays and 2.0 on "retina" displays.
335 Higher values are also possible.
336
337 \sa QWindow::devicePixelRatio(), QGuiApplication::devicePixelRatio()
338*/
339qreal QScreen::devicePixelRatio() const
340{
341 Q_D(const QScreen);
342 return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
343}
344
345/*!
346 \property QScreen::physicalSize
347 \brief the screen's physical size (in millimeters)
348
349 The physical size represents the actual physical dimensions of the
350 screen's display.
351
352 Depending on what information the underlying system provides the value
353 might not be entirely accurate.
354*/
355QSizeF QScreen::physicalSize() const
356{
357 Q_D(const QScreen);
358 return d->platformScreen->physicalSize();
359}
360
361/*!
362 \property QScreen::availableSize
363 \brief the screen's available size in pixels
364
365 The available size is the size excluding window manager reserved areas
366 such as task bars and system menus.
367*/
368QSize QScreen::availableSize() const
369{
370 Q_D(const QScreen);
371 return d->availableGeometry.size();
372}
373
374/*!
375 \property QScreen::geometry
376 \brief the screen's geometry in pixels
377
378 As an example this might return QRect(0, 0, 1280, 1024), or in a
379 virtual desktop setting QRect(1280, 0, 1280, 1024).
380*/
381QRect QScreen::geometry() const
382{
383 Q_D(const QScreen);
384 return d->geometry;
385}
386
387/*!
388 \property QScreen::availableGeometry
389 \brief the screen's available geometry in pixels
390
391 The available geometry is the geometry excluding window manager reserved areas
392 such as task bars and system menus.
393
394 Note, on X11 this will return the true available geometry only on systems with one monitor and
395 if window manager has set _NET_WORKAREA atom. In all other cases this is equal to geometry().
396 This is a limitation in X11 window manager specification.
397*/
398QRect QScreen::availableGeometry() const
399{
400 Q_D(const QScreen);
401 return d->availableGeometry;
402}
403
404/*!
405 Get the screen's virtual siblings.
406
407 The virtual siblings are the screen instances sharing the same virtual desktop.
408 They share a common coordinate system, and windows can freely be moved or
409 positioned across them without having to be re-created.
410*/
411QList<QScreen *> QScreen::virtualSiblings() const
412{
413 Q_D(const QScreen);
414 const QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
415 QList<QScreen *> screens;
416 screens.reserve(platformScreens.count());
417 for (QPlatformScreen *platformScreen : platformScreens)
418 screens << platformScreen->screen();
419 return screens;
420}
421
422/*!
423 \property QScreen::virtualSize
424 \brief the pixel size of the virtual desktop to which this screen belongs
425
426 Returns the pixel size of the virtual desktop corresponding to this screen.
427
428 This is the combined size of the virtual siblings' individual geometries.
429
430 \sa virtualSiblings()
431*/
432QSize QScreen::virtualSize() const
433{
434 return virtualGeometry().size();
435}
436
437/*!
438 \property QScreen::virtualGeometry
439 \brief the pixel geometry of the virtual desktop to which this screen belongs
440
441 Returns the pixel geometry of the virtual desktop corresponding to this screen.
442
443 This is the union of the virtual siblings' individual geometries.
444
445 \sa virtualSiblings()
446*/
447QRect QScreen::virtualGeometry() const
448{
449 QRect result;
450 const auto screens = virtualSiblings();
451 for (QScreen *screen : screens)
452 result |= screen->geometry();
453 return result;
454}
455
456/*!
457 \property QScreen::availableVirtualSize
458 \brief the available size of the virtual desktop to which this screen belongs
459
460 Returns the available pixel size of the virtual desktop corresponding to this screen.
461
462 This is the combined size of the virtual siblings' individual available geometries.
463
464 \sa availableSize(), virtualSiblings()
465*/
466QSize QScreen::availableVirtualSize() const
467{
468 return availableVirtualGeometry().size();
469}
470
471/*!
472 \property QScreen::availableVirtualGeometry
473 \brief the available geometry of the virtual desktop to which this screen belongs
474
475 Returns the available geometry of the virtual desktop corresponding to this screen.
476
477 This is the union of the virtual siblings' individual available geometries.
478
479 \sa availableGeometry(), virtualSiblings()
480*/
481QRect QScreen::availableVirtualGeometry() const
482{
483 QRect result;
484 const auto screens = virtualSiblings();
485 for (QScreen *screen : screens)
486 result |= screen->availableGeometry();
487 return result;
488}
489
490/*!
491 Sets the orientations that the application is interested in receiving
492 updates for in conjunction with this screen.
493
494 For example, to receive orientation() updates and thus have
495 orientationChanged() signals being emitted for LandscapeOrientation and
496 InvertedLandscapeOrientation, call setOrientationUpdateMask() with
497 \a{mask} set to Qt::LandscapeOrientation | Qt::InvertedLandscapeOrientation.
498
499 The default, 0, means no orientationChanged() signals are fired.
500*/
501void QScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
502{
503 Q_D(QScreen);
504 d->orientationUpdateMask = mask;
505 d->platformScreen->setOrientationUpdateMask(mask);
506 QGuiApplicationPrivate::updateFilteredScreenOrientation(this);
507}
508
509/*!
510 Returns the currently set orientation update mask.
511
512 \sa setOrientationUpdateMask()
513*/
514Qt::ScreenOrientations QScreen::orientationUpdateMask() const
515{
516 Q_D(const QScreen);
517 return d->orientationUpdateMask;
518}
519
520/*!
521 \property QScreen::orientation
522 \brief the screen orientation
523
524 The screen orientation represents the physical orientation
525 of the display. For example, the screen orientation of a mobile device
526 will change based on how it is being held. A change to the orientation
527 might or might not trigger a change to the primary orientation of the screen.
528
529 Changes to this property will be filtered by orientationUpdateMask(),
530 so in order to receive orientation updates the application must first
531 call setOrientationUpdateMask() with a mask of the orientations it wants
532 to receive.
533
534 Qt::PrimaryOrientation is never returned.
535
536 \sa primaryOrientation()
537*/
538Qt::ScreenOrientation QScreen::orientation() const
539{
540 Q_D(const QScreen);
541 return d->filteredOrientation;
542}
543
544/*!
545 \property QScreen::refreshRate
546 \brief the approximate vertical refresh rate of the screen in Hz
547*/
548qreal QScreen::refreshRate() const
549{
550 Q_D(const QScreen);
551 return d->refreshRate;
552}
553
554/*!
555 \property QScreen::primaryOrientation
556 \brief the primary screen orientation
557
558 The primary screen orientation is Qt::LandscapeOrientation
559 if the screen geometry's width is greater than or equal to its
560 height, or Qt::PortraitOrientation otherwise. This property might
561 change when the screen orientation was changed (i.e. when the
562 display is rotated).
563 The behavior is however platform dependent and can often be specified in
564 an application manifest file.
565
566*/
567Qt::ScreenOrientation QScreen::primaryOrientation() const
568{
569 Q_D(const QScreen);
570 return d->primaryOrientation;
571}
572
573/*!
574 \property QScreen::nativeOrientation
575 \brief the native screen orientation
576 \since 5.2
577
578 The native orientation of the screen is the orientation where the logo
579 sticker of the device appears the right way up, or Qt::PrimaryOrientation
580 if the platform does not support this functionality.
581
582 The native orientation is a property of the hardware, and does not change.
583*/
584Qt::ScreenOrientation QScreen::nativeOrientation() const
585{
586 Q_D(const QScreen);
587 return d->platformScreen->nativeOrientation();
588}
589
590/*!
591 Convenience function to compute the angle of rotation to get from
592 rotation \a a to rotation \a b.
593
594 The result will be 0, 90, 180, or 270.
595
596 Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
597*/
598int QScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b) const
599{
600 if (a == Qt::PrimaryOrientation)
601 a = primaryOrientation();
602
603 if (b == Qt::PrimaryOrientation)
604 b = primaryOrientation();
605
606 return QPlatformScreen::angleBetween(a, b);
607}
608
609/*!
610 Convenience function to compute a transform that maps from the coordinate system
611 defined by orientation \a a into the coordinate system defined by orientation
612 \a b and target dimensions \a target.
613
614 Example, \a a is Qt::Landscape, \a b is Qt::Portrait, and \a target is QRect(0, 0, w, h)
615 the resulting transform will be such that the point QPoint(0, 0) is mapped to QPoint(0, w),
616 and QPoint(h, w) is mapped to QPoint(0, h). Thus, the landscape coordinate system QRect(0, 0, h, w)
617 is mapped (with a 90 degree rotation) into the portrait coordinate system QRect(0, 0, w, h).
618
619 Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
620*/
621QTransform QScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target) const
622{
623 if (a == Qt::PrimaryOrientation)
624 a = primaryOrientation();
625
626 if (b == Qt::PrimaryOrientation)
627 b = primaryOrientation();
628
629 return QPlatformScreen::transformBetween(a, b, target);
630}
631
632/*!
633 Maps the rect between two screen orientations.
634
635 This will flip the x and y dimensions of the rectangle \a{rect} if the orientation \a{a} is
636 Qt::PortraitOrientation or Qt::InvertedPortraitOrientation and orientation \a{b} is
637 Qt::LandscapeOrientation or Qt::InvertedLandscapeOrientation, or vice versa.
638
639 Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
640*/
641QRect QScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect) const
642{
643 if (a == Qt::PrimaryOrientation)
644 a = primaryOrientation();
645
646 if (b == Qt::PrimaryOrientation)
647 b = primaryOrientation();
648
649 return QPlatformScreen::mapBetween(a, b, rect);
650}
651
652/*!
653 Convenience function that returns \c true if \a o is either portrait or inverted portrait;
654 otherwise returns \c false.
655
656 Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
657*/
658bool QScreen::isPortrait(Qt::ScreenOrientation o) const
659{
660 return o == Qt::PortraitOrientation || o == Qt::InvertedPortraitOrientation
661 || (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::PortraitOrientation);
662}
663
664/*!
665 Convenience function that returns \c true if \a o is either landscape or inverted landscape;
666 otherwise returns \c false.
667
668 Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
669*/
670bool QScreen::isLandscape(Qt::ScreenOrientation o) const
671{
672 return o == Qt::LandscapeOrientation || o == Qt::InvertedLandscapeOrientation
673 || (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::LandscapeOrientation);
674}
675
676/*!
677 \fn void QScreen::orientationChanged(Qt::ScreenOrientation orientation)
678
679 This signal is emitted when the orientation of the screen
680 changes with \a orientation as an argument.
681
682 \sa orientation()
683*/
684
685/*!
686 \fn void QScreen::primaryOrientationChanged(Qt::ScreenOrientation orientation)
687
688 This signal is emitted when the primary orientation of the screen
689 changes with \a orientation as an argument.
690
691 \sa primaryOrientation()
692*/
693
694void QScreenPrivate::updatePrimaryOrientation()
695{
696 primaryOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
697}
698
699/*!
700 Creates and returns a pixmap constructed by grabbing the contents
701 of the given \a window restricted by QRect(\a x, \a y, \a width,
702 \a height).
703
704 The arguments (\a{x}, \a{y}) specify the offset in the window,
705 whereas (\a{width}, \a{height}) specify the area to be copied. If
706 \a width is negative, the function copies everything to the right
707 border of the window. If \a height is negative, the function
708 copies everything to the bottom of the window.
709
710 The offset and size arguments are specified in device independent
711 pixels. The returned pixmap may be larger than the requested size
712 when grabbing from a high-DPI screen. Call QPixmap::devicePixelRatio()
713 to determine if this is the case.
714
715 The window system identifier (\c WId) can be retrieved using the
716 QWidget::winId() function. The rationale for using a window
717 identifier and not a QWidget, is to enable grabbing of windows
718 that are not part of the application, window system frames, and so
719 on.
720
721 \warning Grabbing windows that are not part of the application is
722 not supported on systems such as iOS, where sandboxing/security
723 prevents reading pixels of windows not owned by the application.
724
725 The grabWindow() function grabs pixels from the screen, not from
726 the window, i.e. if there is another window partially or entirely
727 over the one you grab, you get pixels from the overlying window,
728 too. The mouse cursor is generally not grabbed.
729
730 Note on X11 that if the given \a window doesn't have the same depth
731 as the root window, and another window partially or entirely
732 obscures the one you grab, you will \e not get pixels from the
733 overlying window. The contents of the obscured areas in the
734 pixmap will be undefined and uninitialized.
735
736 On Windows Vista and above grabbing a layered window, which is
737 created by setting the Qt::WA_TranslucentBackground attribute, will
738 not work. Instead grabbing the desktop widget should work.
739
740 \warning In general, grabbing an area outside the screen is not
741 safe. This depends on the underlying window system.
742*/
743
744QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
745{
746 const QPlatformScreen *platformScreen = handle();
747 if (!platformScreen) {
748 qWarning("invoked with handle==0");
749 return QPixmap();
750 }
751 const qreal factor = QHighDpiScaling::factor(this);
752 if (qFuzzyCompare(factor, 1))
753 return platformScreen->grabWindow(window, x, y, width, height);
754
755 const QPoint nativePos = QHighDpi::toNative(QPoint(x, y), factor);
756 QSize nativeSize(width, height);
757 if (nativeSize.isValid())
758 nativeSize = QHighDpi::toNative(nativeSize, factor);
759 QPixmap result =
760 platformScreen->grabWindow(window, nativePos.x(), nativePos.y(),
761 nativeSize.width(), nativeSize.height());
762 result.setDevicePixelRatio(result.devicePixelRatio() * factor);
763 return result;
764}
765
766#ifndef QT_NO_DEBUG_STREAM
767
768static inline void formatRect(QDebug &debug, const QRect r)
769{
770 debug << r.width() << 'x' << r.height()
771 << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
772}
773
774Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QScreen *screen)
775{
776 const QDebugStateSaver saver(debug);
777 debug.nospace();
778 debug << "QScreen(" << (const void *)screen;
779 if (screen) {
780 debug << ", name=" << screen->name();
781 if (debug.verbosity() > 2) {
782 if (screen == QGuiApplication::primaryScreen())
783 debug << ", primary";
784 debug << ", geometry=";
785 formatRect(debug, screen->geometry());
786 debug << ", available=";
787 formatRect(debug, screen->availableGeometry());
788 debug << ", logical DPI=" << screen->logicalDotsPerInchX()
789 << ',' << screen->logicalDotsPerInchY()
790 << ", physical DPI=" << screen->physicalDotsPerInchX()
791 << ',' << screen->physicalDotsPerInchY()
792 << ", devicePixelRatio=" << screen->devicePixelRatio()
793 << ", orientation=" << screen->orientation()
794 << ", physical size=" << screen->physicalSize().width()
795 << 'x' << screen->physicalSize().height() << "mm";
796 }
797 }
798 debug << ')';
799 return debug;
800}
801#endif // !QT_NO_DEBUG_STREAM
802
803QT_END_NAMESPACE
804