Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qbackingstore_x11.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 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// Qt-Security score:significant reason:default
4
6#include "qxcbwindow.h"
8
9#include <private/qhighdpiscaling_p.h>
10#include <QPainter>
11
12#if QT_CONFIG(xrender)
13# include <X11/extensions/Xrender.h>
14#endif
15
16#define register /* C++17 deprecated register */
17#include <X11/Xlib.h>
18#undef register
19
21
23 : QPlatformBackingStore(window)
24 , m_translucentBackground(false)
25{
26 if (QXcbWindow *w = static_cast<QXcbWindow *>(window->handle())) {
27 m_translucentBackground = w->connection()->hasXRender() &&
28 QImage::toPixelFormat(w->imageFormat()).alphaUsage() == QPixelFormat::UsesAlpha;
29 }
30}
31
34
36{
37 return &m_pixmap;
38}
39
40void QXcbNativeBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
41{
42 if (m_pixmap.isNull())
43 return;
44
45 QSize pixmapSize = m_pixmap.size();
46
47 QRegion clipped = region;
48 clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
49 clipped &= QRect(0, 0, pixmapSize.width(), pixmapSize.height()).translated(-offset);
50
51 QRect br = clipped.boundingRect();
52 if (br.isNull())
53 return;
54
55 QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
56 if (!platformWindow) {
57 qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
58 return;
59 }
60
61 Window wid = platformWindow->xcb_window();
62 Pixmap pid = qt_x11PixmapHandle(m_pixmap);
63
64 QList<XRectangle> clipRects = qt_region_to_xrectangles(clipped);
65
66#if QT_CONFIG(xrender)
67 if (m_translucentBackground)
68 {
69 XWindowAttributes attrib;
70 XGetWindowAttributes(display(), wid, &attrib);
71 XRenderPictFormat *format = XRenderFindVisualFormat(display(), attrib.visual);
72
73 Picture srcPic = qt_x11PictureHandle(m_pixmap);
74 Picture dstPic = XRenderCreatePicture(display(), wid, format, 0, 0);
75
76 XRenderSetPictureClipRectangles(display(), dstPic, 0, 0, clipRects.constData(), clipRects.size());
77
78 XRenderComposite(display(), PictOpSrc, srcPic, 0L /*None*/, dstPic, br.x() + offset.x(),
79 br.y() + offset.y(), 0, 0, br.x(), br.y(), br.width(), br.height());
80
81 XRenderFreePicture(display(), dstPic);
82 }
83 else
84#endif
85 {
86 GC gc = XCreateGC(display(), wid, 0, nullptr);
87
88 if (clipRects.size() != 1)
89 XSetClipRectangles(display(), gc, 0, 0, clipRects.data(), clipRects.size(), YXBanded);
90
91 XCopyArea(display(), pid, wid, gc, br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), br.x(), br.y());
92 XFreeGC(display(), gc);
93 }
94
95
96 if (platformWindow->needsSync()) {
97 platformWindow->updateSyncRequestCounter();
98 } else {
99 XFlush(display());
100 }
101}
102
104{
105 return m_pixmap.toImage();
106}
107
108void QXcbNativeBackingStore::resize(const QSize &size, const QRegion &staticContents)
109{
110 if (size == m_pixmap.size())
111 return;
112
113 QPixmap newPixmap(size);
114
115#if QT_CONFIG(xrender)
116 if (m_translucentBackground && newPixmap.depth() != 32)
117 qt_x11Pixmap(newPixmap)->convertToARGB32();
118#endif
119
120 if (!m_pixmap.isNull()) {
121 Pixmap from = qt_x11PixmapHandle(m_pixmap);
122 Pixmap to = qt_x11PixmapHandle(newPixmap);
123 QRect br = staticContents.boundingRect().intersected(QRect(QPoint(0, 0), size));
124
125 if (!br.isEmpty()) {
126 GC gc = XCreateGC(display(), to, 0, nullptr);
127 XCopyArea(display(), from, to, gc, br.x(), br.y(), br.width(), br.height(), br.x(), br.y());
128 XFreeGC(display(), gc);
129 }
130 }
131
132 m_pixmap = newPixmap;
133}
134
135bool QXcbNativeBackingStore::scroll(const QRegion &area, int dx, int dy)
136{
137 if (m_pixmap.isNull())
138 return false;
139
140 QRect rect = area.boundingRect();
141 Pixmap pix = qt_x11PixmapHandle(m_pixmap);
142
143 GC gc = XCreateGC(display(), pix, 0, nullptr);
144 XCopyArea(display(), pix, pix, gc,
145 rect.x(), rect.y(), rect.width(), rect.height(),
146 rect.x()+dx, rect.y()+dy);
147 XFreeGC(display(), gc);
148 return true;
149}
150
151void QXcbNativeBackingStore::beginPaint(const QRegion &region)
152{
153 QX11PlatformPixmap *x11pm = qt_x11Pixmap(m_pixmap);
154 if (x11pm)
155 x11pm->setIsBackingStore(true);
156
157#if QT_CONFIG(xrender)
158 if (m_translucentBackground) {
159 const QList<XRectangle> xrects = qt_region_to_xrectangles(region);
160 const XRenderColor color = { 0, 0, 0, 0 };
161 XRenderFillRectangles(display(), PictOpSrc,
162 qt_x11PictureHandle(m_pixmap), &color,
163 xrects.constData(), xrects.size());
164 }
165#else
166 Q_UNUSED(region);
167#endif
168}
169
170Display *QXcbNativeBackingStore::display() const
171{
172 return static_cast<Display *>(static_cast<QXcbWindow *>(window()->handle())->connection()->xlib_display());
173}
174
175QT_END_NAMESPACE
\inmodule QtGui
Definition qwindow.h:63
void setIsBackingStore(bool on)
void beginPaint(const QRegion &region) override
This function is called before painting onto the surface begins, with the region in which the paintin...
QImage toImage() const override
Implemented in subclasses to return the content of the backingstore as a QImage.
QPaintDevice * paintDevice() override
Implement this function to return the appropriate paint device.
void resize(const QSize &size, const QRegion &staticContents) override
bool scroll(const QRegion &area, int dx, int dy) override
Scrolls the given area dx pixels to the right and dy downward; both dx and dy may be negative.
XID Pixmap