QtBase  v6.3.1
qbackingstore_x11.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins 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 "qbackingstore_x11_p.h"
41 #include "qxcbwindow.h"
42 #include "qpixmap_x11_p.h"
43 
44 #include <private/qhighdpiscaling_p.h>
45 #include <QPainter>
46 
47 #if QT_CONFIG(xrender)
48 # include <X11/extensions/Xrender.h>
49 #endif
50 
51 #define register /* C++17 deprecated register */
52 #include <X11/Xlib.h>
53 #undef register
54 
55 #ifndef None
56 #define None 0L
57 #endif
58 
60 
63  , m_translucentBackground(false)
64 {
65  if (QXcbWindow *w = static_cast<QXcbWindow *>(window->handle())) {
66  m_translucentBackground = w->connection()->hasXRender() &&
68  }
69 }
70 
72 {}
73 
75 {
76  return &m_pixmap;
77 }
78 
80 {
81  if (m_pixmap.isNull())
82  return;
83 
84  QSize pixmapSize = m_pixmap.size();
85 
86  QRegion clipped = region;
87  clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
88  clipped &= QRect(0, 0, pixmapSize.width(), pixmapSize.height()).translated(-offset);
89 
90  QRect br = clipped.boundingRect();
91  if (br.isNull())
92  return;
93 
94  QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
95  if (!platformWindow) {
96  qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
97  return;
98  }
99 
100  Window wid = platformWindow->xcb_window();
101  Pixmap pid = qt_x11PixmapHandle(m_pixmap);
102 
103  QList<XRectangle> clipRects = qt_region_to_xrectangles(clipped);
104 
105 #if QT_CONFIG(xrender)
106  if (m_translucentBackground)
107  {
108  XWindowAttributes attrib;
109  XGetWindowAttributes(display(), wid, &attrib);
110  XRenderPictFormat *format = XRenderFindVisualFormat(display(), attrib.visual);
111 
112  Picture srcPic = qt_x11PictureHandle(m_pixmap);
113  Picture dstPic = XRenderCreatePicture(display(), wid, format, 0, 0);
114 
115  XRenderSetPictureClipRectangles(display(), dstPic, 0, 0, clipRects.constData(), clipRects.size());
116 
117  XRenderComposite(display(), PictOpSrc, srcPic, None, dstPic,
118  br.x() + offset.x(), br.y() + offset.y(),
119  0, 0,
120  br.x(), br.y(),
121  br.width(), br.height());
122 
123  XRenderFreePicture(display(), dstPic);
124  }
125  else
126 #endif
127  {
128  GC gc = XCreateGC(display(), wid, 0, nullptr);
129 
130  if (clipRects.size() != 1)
131  XSetClipRectangles(display(), gc, 0, 0, clipRects.data(), clipRects.size(), YXBanded);
132 
133  XCopyArea(display(), pid, wid, gc, br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), br.x(), br.y());
134  XFreeGC(display(), gc);
135  }
136 
137 
138  if (platformWindow->needsSync()) {
139  platformWindow->updateSyncRequestCounter();
140  } else {
141  XFlush(display());
142  }
143 }
144 
146 {
147  return m_pixmap.toImage();
148 }
149 
150 void QXcbNativeBackingStore::resize(const QSize &size, const QRegion &staticContents)
151 {
152  if (size == m_pixmap.size())
153  return;
154 
155  QPixmap newPixmap(size);
156 
157 #if QT_CONFIG(xrender)
158  if (m_translucentBackground && newPixmap.depth() != 32)
159  qt_x11Pixmap(newPixmap)->convertToARGB32();
160 #endif
161 
162  if (!m_pixmap.isNull()) {
163  Pixmap from = qt_x11PixmapHandle(m_pixmap);
164  Pixmap to = qt_x11PixmapHandle(newPixmap);
165  QRect br = staticContents.boundingRect().intersected(QRect(QPoint(0, 0), size));
166 
167  if (!br.isEmpty()) {
168  GC gc = XCreateGC(display(), to, 0, nullptr);
169  XCopyArea(display(), from, to, gc, br.x(), br.y(), br.width(), br.height(), br.x(), br.y());
170  XFreeGC(display(), gc);
171  }
172  }
173 
174  m_pixmap = newPixmap;
175 }
176 
177 bool QXcbNativeBackingStore::scroll(const QRegion &area, int dx, int dy)
178 {
179  if (m_pixmap.isNull())
180  return false;
181 
182  QRect rect = area.boundingRect();
183  Pixmap pix = qt_x11PixmapHandle(m_pixmap);
184 
185  GC gc = XCreateGC(display(), pix, 0, nullptr);
186  XCopyArea(display(), pix, pix, gc,
187  rect.x(), rect.y(), rect.width(), rect.height(),
188  rect.x()+dx, rect.y()+dy);
189  XFreeGC(display(), gc);
190  return true;
191 }
192 
194 {
195  QX11PlatformPixmap *x11pm = qt_x11Pixmap(m_pixmap);
196  if (x11pm)
197  x11pm->setIsBackingStore(true);
198 
199 #if QT_CONFIG(xrender)
200  if (m_translucentBackground) {
201  const QList<XRectangle> xrects = qt_region_to_xrectangles(region);
202  const XRenderColor color = { 0, 0, 0, 0 };
203  XRenderFillRectangles(display(), PictOpSrc,
204  qt_x11PictureHandle(m_pixmap), &color,
205  xrects.constData(), xrects.size());
206  }
207 #else
208  Q_UNUSED(region);
209 #endif
210 }
211 
212 Display *QXcbNativeBackingStore::display() const
213 {
214  return static_cast<Display *>(static_cast<QXcbWindow *>(window()->handle())->connection()->xlib_display());
215 }
216 
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
static QPixelFormat toPixelFormat(QImage::Format format) noexcept
Definition: qimage.cpp:5634
Definition: qlist.h:108
qsizetype size() const noexcept
Definition: qlist.h:414
const_pointer constData() const noexcept
Definition: qlist.h:444
pointer data()
Definition: qlist.h:442
constexpr AlphaUsage alphaUsage() const noexcept
Definition: qpixelformat.h:209
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
QImage toImage() const
Definition: qpixmap.cpp:443
QSize size() const
Definition: qpixmap.cpp:528
int depth() const
Definition: qpixmap.cpp:556
bool isNull() const
Definition: qpixmap.cpp:491
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
constexpr bool isEmpty() const noexcept
Definition: qrect.h:194
constexpr int height() const noexcept
Definition: qrect.h:266
constexpr bool isNull() const noexcept
Definition: qrect.h:191
QRect intersected(const QRect &other) const noexcept
Definition: qrect.h:442
constexpr int x() const noexcept
Definition: qrect.h:212
constexpr int width() const noexcept
Definition: qrect.h:263
constexpr QRect translated(int dx, int dy) const noexcept
Definition: qrect.h:288
constexpr int y() const noexcept
Definition: qrect.h:215
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:63
QRect boundingRect() const noexcept
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
void setIsBackingStore(bool on)
void beginPaint(const QRegion &region) override
QXcbNativeBackingStore(QWindow *window)
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override
QImage toImage() const override
QPaintDevice * paintDevice() override
void resize(const QSize &size, const QRegion &staticContents) override
bool scroll(const QRegion &area, int dx, int dy) override
xcb_window_t xcb_window() const
Definition: qxcbwindow.h:127
void updateSyncRequestCounter()
bool needsSync() const
[Window class definition]
Definition: window.h:64
rect
[4]
QPixmap pix
T toNativePixels(const T &value, const C *context)
DBusConnection * connection
#define qWarning
Definition: qlogging.h:179
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint color
[2]
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
struct _XGC * GC
XID Pixmap
Definition: qpixmap_x11_p.h:52
Pixmap qt_x11PixmapHandle(const QPixmap &pixmap)
Picture qt_x11PictureHandle(const QPixmap &pixmap)
QX11PlatformPixmap * qt_x11Pixmap(const QPixmap &pixmap)
struct _XDisplay Display
Definition: qtx11extras_p.h:58
QList< XRectangle > qt_region_to_xrectangles(const QRegion &r)
Q_UNUSED(salary)
[21]
aWidget window() -> setWindowTitle("New Window Title")
[2]