xcb: Add experimental legacy support for native X11 painting
This commit revives the old native QPixmap and QPaintEngine implementations that were present in Qt4. The backing store supports regular raster windows in this commit. Support for render-to-texture widgets and OpenGL compositing will be added in a follow-up commit. Change-Id: I80a9c4f0c42a6f68f571dfee930d95000d5dd950 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
7be9653f12
commit
07942adb77
52
config.tests/x11/xrender/xrender.cpp
Normal file
52
config.tests/x11/xrender/xrender.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the config.tests of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#if RENDER_MAJOR == 0 && RENDER_MINOR < 5
|
||||
# error "Required Xrender version 0.6 not found."
|
||||
#else
|
||||
int main(int, char **)
|
||||
{
|
||||
XRenderPictFormat *format;
|
||||
format = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
3
config.tests/x11/xrender/xrender.pro
Normal file
3
config.tests/x11/xrender/xrender.pro
Normal file
@ -0,0 +1,3 @@
|
||||
SOURCES = xrender.cpp
|
||||
CONFIG += x11
|
||||
CONFIG -= qt
|
@ -40,6 +40,7 @@
|
||||
"tslib": "boolean",
|
||||
"vulkan": "boolean",
|
||||
"xcb": { "type": "enum", "values": [ "no", "yes", "qt", "system" ] },
|
||||
"xcb-native-painting": "boolean",
|
||||
"xcb-xlib": "boolean",
|
||||
"xinput2": "boolean",
|
||||
"xkb": "boolean",
|
||||
@ -305,6 +306,13 @@
|
||||
"sources": [
|
||||
{ "type": "pkgConfig", "args": "xkbcommon xkbcommon-x11 >= 0.4.1" }
|
||||
]
|
||||
},
|
||||
"xrender": {
|
||||
"label": "XRender for native painting",
|
||||
"test": "x11/xrender",
|
||||
"sources": [
|
||||
"-lXrender"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@ -755,6 +763,18 @@
|
||||
"condition": "libs.xcb_glx",
|
||||
"output": [ "privateFeature" ]
|
||||
},
|
||||
"xcb-native-painting": {
|
||||
"label": "Native painting (experimental)",
|
||||
"emitIf": "features.xcb",
|
||||
"condition": "features.xcb-xlib && libs.xrender",
|
||||
"output": [ "privateFeature" ]
|
||||
},
|
||||
"xrender": {
|
||||
"label": "XRender for native painting",
|
||||
"emitIf": "features.xcb && features.xcb-native-painting",
|
||||
"condition": "features.xcb-native-painting",
|
||||
"output": [ "privateFeature" ]
|
||||
},
|
||||
"xcb-render": {
|
||||
"label": "XCB render",
|
||||
"emitIf": "features.xcb",
|
||||
@ -1145,7 +1165,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
|
||||
"section": "X11",
|
||||
"condition": "features.xcb",
|
||||
"entries": [
|
||||
"system-xcb", "egl_x11", "xinput2", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xlib", "xkbcommon-system"
|
||||
"system-xcb", "egl_x11", "xinput2", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xlib", "xkbcommon-system", "xcb-native-painting"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
|
||||
enum ClassId { RasterClass, DirectFBClass,
|
||||
BlitterClass, Direct2DClass,
|
||||
CustomClass = 1024 };
|
||||
X11Class, CustomClass = 1024 };
|
||||
|
||||
QPlatformPixmap(PixelType pixelType, int classId);
|
||||
virtual ~QPlatformPixmap();
|
||||
@ -147,6 +147,7 @@ protected:
|
||||
|
||||
private:
|
||||
friend class QPixmap;
|
||||
friend class QX11PlatformPixmap;
|
||||
friend class QImagePixmapCleanupHooks; // Needs to set is_cached
|
||||
friend class QOpenGLTextureCache; //Needs to check the reference count
|
||||
friend class QExplicitlySharedDataPointer<QPlatformPixmap>;
|
||||
@ -162,7 +163,7 @@ private:
|
||||
|
||||
# define QT_XFORM_TYPE_MSBFIRST 0
|
||||
# define QT_XFORM_TYPE_LSBFIRST 1
|
||||
extern bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, int, int, int, const uchar*, int, int, int);
|
||||
Q_GUI_EXPORT bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, int, int, int, const uchar*, int, int, int);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -100,7 +100,7 @@ const uchar *qt_patternForBrush(int brushStyle, bool invert)
|
||||
return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
|
||||
}
|
||||
|
||||
QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
|
||||
Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
|
||||
{
|
||||
|
||||
QPixmap pm;
|
||||
|
@ -547,8 +547,8 @@ void qt_fill_tile(QPixmap *tile, const QPixmap &pixmap)
|
||||
}
|
||||
}
|
||||
|
||||
void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
|
||||
const QPixmap &pixmap, qreal xOffset, qreal yOffset)
|
||||
Q_GUI_EXPORT void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
|
||||
const QPixmap &pixmap, qreal xOffset, qreal yOffset)
|
||||
{
|
||||
qreal yPos, xPos, drawH, drawW, yOff, xOff;
|
||||
yPos = y;
|
||||
|
22
src/plugins/platforms/xcb/nativepainting/nativepainting.pri
Normal file
22
src/plugins/platforms/xcb/nativepainting/nativepainting.pri
Normal file
@ -0,0 +1,22 @@
|
||||
qtConfig(xcb-native-painting) {
|
||||
qtConfig(xrender): QMAKE_USE += xrender
|
||||
qtConfig(fontconfig): QMAKE_USE_PRIVATE += freetype
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
HEADERS += \
|
||||
$$PWD/qtessellator_p.h \
|
||||
$$PWD/qpixmap_x11_p.h \
|
||||
$$PWD/qpaintengine_x11_p.h \
|
||||
$$PWD/qt_x11_p.h \
|
||||
$$PWD/qcolormap_x11_p.h \
|
||||
$$PWD/qbackingstore_x11_p.h \
|
||||
$$PWD/qxcbnativepainting.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qtessellator.cpp \
|
||||
$$PWD/qpixmap_x11.cpp \
|
||||
$$PWD/qpaintengine_x11.cpp \
|
||||
$$PWD/qcolormap_x11.cpp \
|
||||
$$PWD/qbackingstore_x11.cpp \
|
||||
$$PWD/qxcbnativepainting.cpp
|
||||
}
|
203
src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
Normal file
203
src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbackingstore_x11_p.h"
|
||||
#include "qxcbwindow.h"
|
||||
#include "qpixmap_x11_p.h"
|
||||
|
||||
#include <private/qhighdpiscaling_p.h>
|
||||
#include <QPainter>
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
# include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#ifndef None
|
||||
#define None 0L
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QXcbNativeBackingStore::QXcbNativeBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
, m_translucentBackground(false)
|
||||
{
|
||||
if (QXcbWindow *w = static_cast<QXcbWindow *>(window->handle()))
|
||||
m_translucentBackground = w->connection()->hasXRender() && QImage::toPixelFormat(w->imageFormat()).alphaSize() > 0;
|
||||
}
|
||||
|
||||
QXcbNativeBackingStore::~QXcbNativeBackingStore()
|
||||
{}
|
||||
|
||||
QPaintDevice *QXcbNativeBackingStore::paintDevice()
|
||||
{
|
||||
return &m_pixmap;
|
||||
}
|
||||
|
||||
void QXcbNativeBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
if (m_pixmap.isNull())
|
||||
return;
|
||||
|
||||
QSize pixmapSize = m_pixmap.size();
|
||||
|
||||
QRegion clipped = region;
|
||||
clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
|
||||
clipped &= QRect(0, 0, pixmapSize.width(), pixmapSize.height()).translated(-offset);
|
||||
|
||||
QRect br = clipped.boundingRect();
|
||||
if (br.isNull())
|
||||
return;
|
||||
|
||||
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
|
||||
if (!platformWindow) {
|
||||
qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
|
||||
return;
|
||||
}
|
||||
|
||||
Window wid = platformWindow->xcb_window();
|
||||
Pixmap pid = qt_x11PixmapHandle(m_pixmap);
|
||||
|
||||
QVector<XRectangle> clipRects = qt_region_to_xrectangles(clipped);
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
if (m_translucentBackground)
|
||||
{
|
||||
XWindowAttributes attrib;
|
||||
XGetWindowAttributes(display(), wid, &attrib);
|
||||
XRenderPictFormat *format = XRenderFindVisualFormat(display(), attrib.visual);
|
||||
|
||||
Picture srcPic = qt_x11PictureHandle(m_pixmap);
|
||||
Picture dstPic = XRenderCreatePicture(display(), wid, format, 0, 0);
|
||||
|
||||
XRenderSetPictureClipRectangles(display(), dstPic, 0, 0, clipRects.constData(), clipRects.size());
|
||||
|
||||
XRenderComposite(display(), PictOpSrc, srcPic, None, dstPic,
|
||||
br.x() + offset.x(), br.y() + offset.y(),
|
||||
0, 0,
|
||||
br.x(), br.y(),
|
||||
br.width(), br.height());
|
||||
|
||||
XRenderFreePicture(display(), dstPic);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
GC gc = XCreateGC(display(), wid, 0, Q_NULLPTR);
|
||||
|
||||
if (clipRects.size() != 1)
|
||||
XSetClipRectangles(display(), gc, 0, 0, clipRects.data(), clipRects.size(), YXBanded);
|
||||
|
||||
XCopyArea(display(), pid, wid, gc, br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), br.x(), br.y());
|
||||
XFreeGC(display(), gc);
|
||||
}
|
||||
|
||||
|
||||
if (platformWindow->needsSync()) {
|
||||
platformWindow->updateSyncRequestCounter();
|
||||
} else {
|
||||
XFlush(display());
|
||||
}
|
||||
}
|
||||
|
||||
QImage QXcbNativeBackingStore::toImage() const
|
||||
{
|
||||
return m_pixmap.toImage();
|
||||
}
|
||||
|
||||
void QXcbNativeBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||
{
|
||||
if (size == m_pixmap.size())
|
||||
return;
|
||||
|
||||
QPixmap newPixmap(size);
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
if (m_translucentBackground && newPixmap.depth() != 32)
|
||||
qt_x11Pixmap(newPixmap)->convertToARGB32();
|
||||
#endif
|
||||
|
||||
if (!m_pixmap.isNull()) {
|
||||
Pixmap from = qt_x11PixmapHandle(m_pixmap);
|
||||
Pixmap to = qt_x11PixmapHandle(newPixmap);
|
||||
QRect br = staticContents.boundingRect().intersected(QRect(QPoint(0, 0), size));
|
||||
|
||||
if (!br.isEmpty()) {
|
||||
GC gc = XCreateGC(display(), to, 0, Q_NULLPTR);
|
||||
XCopyArea(display(), from, to, gc, br.x(), br.y(), br.width(), br.height(), br.x(), br.y());
|
||||
XFreeGC(display(), gc);
|
||||
}
|
||||
}
|
||||
|
||||
m_pixmap = newPixmap;
|
||||
}
|
||||
|
||||
bool QXcbNativeBackingStore::scroll(const QRegion &area, int dx, int dy)
|
||||
{
|
||||
if (m_pixmap.isNull())
|
||||
return false;
|
||||
|
||||
QRect rect = area.boundingRect();
|
||||
Pixmap pix = qt_x11PixmapHandle(m_pixmap);
|
||||
|
||||
GC gc = XCreateGC(display(), pix, 0, Q_NULLPTR);
|
||||
XCopyArea(display(), pix, pix, gc,
|
||||
rect.x(), rect.y(), rect.width(), rect.height(),
|
||||
rect.x()+dx, rect.y()+dy);
|
||||
XFreeGC(display(), gc);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QXcbNativeBackingStore::beginPaint(const QRegion ®ion)
|
||||
{
|
||||
#if QT_CONFIG(xrender)
|
||||
if (m_translucentBackground) {
|
||||
const QVector<XRectangle> xrects = qt_region_to_xrectangles(region);
|
||||
const XRenderColor color = { 0, 0, 0, 0 };
|
||||
XRenderFillRectangles(display(), PictOpSrc,
|
||||
qt_x11PictureHandle(m_pixmap), &color,
|
||||
xrects.constData(), xrects.size());
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(region);
|
||||
#endif
|
||||
}
|
||||
|
||||
Display *QXcbNativeBackingStore::display() const
|
||||
{
|
||||
return static_cast<Display *>(static_cast<QXcbWindow *>(window()->handle())->connection()->xlib_display());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBACKINGSTORE_X11_H
|
||||
#define QBACKINGSTORE_X11_H
|
||||
|
||||
#include <qpa/qplatformbackingstore.h>
|
||||
|
||||
typedef struct _XDisplay Display;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QXcbWindow;
|
||||
|
||||
class QXcbNativeBackingStore : public QPlatformBackingStore
|
||||
{
|
||||
public:
|
||||
QXcbNativeBackingStore(QWindow *window);
|
||||
~QXcbNativeBackingStore();
|
||||
|
||||
QPaintDevice *paintDevice() override;
|
||||
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override;
|
||||
|
||||
QImage toImage() const override;
|
||||
|
||||
void resize(const QSize &size, const QRegion &staticContents) override;
|
||||
bool scroll(const QRegion &area, int dx, int dy) override;
|
||||
|
||||
void beginPaint(const QRegion ®ion) override;
|
||||
|
||||
private:
|
||||
Display *display() const;
|
||||
|
||||
QPixmap m_pixmap;
|
||||
bool m_translucentBackground;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBACKINGSTORE_X11_H
|
644
src/plugins/platforms/xcb/nativepainting/qcolormap_x11.cpp
Normal file
644
src/plugins/platforms/xcb/nativepainting/qcolormap_x11.cpp
Normal file
@ -0,0 +1,644 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QVarLengthArray>
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
|
||||
#include "qcolormap_x11_p.h"
|
||||
#include "qxcbnativepainting.h"
|
||||
#include "qt_x11_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QXcbColormapPrivate
|
||||
{
|
||||
public:
|
||||
QXcbColormapPrivate()
|
||||
: ref(1), mode(QXcbColormap::Direct), depth(0),
|
||||
colormap(0), defaultColormap(true),
|
||||
visual(0), defaultVisual(true),
|
||||
r_max(0), g_max(0), b_max(0),
|
||||
r_shift(0), g_shift(0), b_shift(0)
|
||||
{}
|
||||
|
||||
QAtomicInt ref;
|
||||
|
||||
QXcbColormap::Mode mode;
|
||||
int depth;
|
||||
|
||||
Colormap colormap;
|
||||
bool defaultColormap;
|
||||
|
||||
Visual *visual;
|
||||
bool defaultVisual;
|
||||
|
||||
int r_max;
|
||||
int g_max;
|
||||
int b_max;
|
||||
|
||||
uint r_shift;
|
||||
uint g_shift;
|
||||
uint b_shift;
|
||||
|
||||
QVector<QColor> colors;
|
||||
QVector<int> pixels;
|
||||
};
|
||||
|
||||
static uint right_align(uint v)
|
||||
{
|
||||
while (!(v & 0x1))
|
||||
v >>= 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
static int cube_root(int v)
|
||||
{
|
||||
if (v == 1)
|
||||
return 1;
|
||||
// brute force algorithm
|
||||
int i = 1;
|
||||
for (;;) {
|
||||
const int b = i * i * i;
|
||||
if (b <= v) {
|
||||
++i;
|
||||
} else {
|
||||
--i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static Visual *find_visual(Display *display,
|
||||
int screen,
|
||||
int visual_class,
|
||||
int visual_id,
|
||||
int *depth,
|
||||
bool *defaultVisual)
|
||||
{
|
||||
XVisualInfo *vi, rvi;
|
||||
int count;
|
||||
|
||||
uint mask = VisualScreenMask;
|
||||
rvi.screen = screen;
|
||||
|
||||
if (visual_class != -1) {
|
||||
rvi.c_class = visual_class;
|
||||
mask |= VisualClassMask;
|
||||
}
|
||||
if (visual_id != -1) {
|
||||
rvi.visualid = visual_id;
|
||||
mask |= VisualIDMask;
|
||||
}
|
||||
|
||||
Visual *visual = DefaultVisual(display, screen);
|
||||
*defaultVisual = true;
|
||||
*depth = DefaultDepth(display, screen);
|
||||
|
||||
vi = XGetVisualInfo(display, mask, &rvi, &count);
|
||||
if (vi) {
|
||||
int best = 0;
|
||||
for (int x = 0; x < count; ++x) {
|
||||
if (vi[x].depth > vi[best].depth)
|
||||
best = x;
|
||||
}
|
||||
if (best >= 0 && best <= count && vi[best].visualid != XVisualIDFromVisual(visual)) {
|
||||
visual = vi[best].visual;
|
||||
*defaultVisual = (visual == DefaultVisual(display, screen));
|
||||
*depth = vi[best].depth;
|
||||
}
|
||||
}
|
||||
if (vi)
|
||||
XFree((char *)vi);
|
||||
return visual;
|
||||
}
|
||||
|
||||
static void query_colormap(QXcbColormapPrivate *d, int screen)
|
||||
{
|
||||
Display *display = X11->display;
|
||||
|
||||
// query existing colormap
|
||||
int q_colors = (((1u << d->depth) > 256u) ? 256u : (1u << d->depth));
|
||||
XColor queried[256];
|
||||
memset(queried, 0, sizeof(queried));
|
||||
for (int x = 0; x < q_colors; ++x)
|
||||
queried[x].pixel = x;
|
||||
XQueryColors(display, d->colormap, queried, q_colors);
|
||||
|
||||
d->colors.resize(q_colors);
|
||||
for (int x = 0; x < q_colors; ++x) {
|
||||
if (queried[x].red == 0
|
||||
&& queried[x].green == 0
|
||||
&& queried[x].blue == 0
|
||||
&& queried[x].pixel != BlackPixel(display, screen)) {
|
||||
// unallocated color cell, skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
d->colors[x] = QColor::fromRgbF(queried[x].red / float(USHRT_MAX),
|
||||
queried[x].green / float(USHRT_MAX),
|
||||
queried[x].blue / float(USHRT_MAX));
|
||||
}
|
||||
|
||||
// for missing colors, find the closest color in the existing colormap
|
||||
Q_ASSERT(d->pixels.size());
|
||||
for (int x = 0; x < d->pixels.size(); ++x) {
|
||||
if (d->pixels.at(x) != -1)
|
||||
continue;
|
||||
|
||||
QRgb rgb;
|
||||
if (d->mode == QXcbColormap::Indexed) {
|
||||
const int r = (x / (d->g_max * d->b_max)) % d->r_max;
|
||||
const int g = (x / d->b_max) % d->g_max;
|
||||
const int b = x % d->b_max;
|
||||
rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1),
|
||||
(g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1),
|
||||
(b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1));
|
||||
} else {
|
||||
rgb = qRgb(x, x, x);
|
||||
}
|
||||
|
||||
// find closest color
|
||||
int mindist = INT_MAX, best = -1;
|
||||
for (int y = 0; y < q_colors; ++y) {
|
||||
int r = qRed(rgb) - (queried[y].red >> 8);
|
||||
int g = qGreen(rgb) - (queried[y].green >> 8);
|
||||
int b = qBlue(rgb) - (queried[y].blue >> 8);
|
||||
int dist = (r * r) + (g * g) + (b * b);
|
||||
if (dist < mindist) {
|
||||
mindist = dist;
|
||||
best = y;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(best >= 0 && best < q_colors);
|
||||
if (d->visual->c_class & 1) {
|
||||
XColor xcolor;
|
||||
xcolor.red = queried[best].red;
|
||||
xcolor.green = queried[best].green;
|
||||
xcolor.blue = queried[best].blue;
|
||||
xcolor.pixel = queried[best].pixel;
|
||||
|
||||
if (XAllocColor(display, d->colormap, &xcolor)) {
|
||||
d->pixels[x] = xcolor.pixel;
|
||||
} else {
|
||||
// some weird stuff is going on...
|
||||
d->pixels[x] = (qGray(rgb) < 127
|
||||
? BlackPixel(display, screen)
|
||||
: WhitePixel(display, screen));
|
||||
}
|
||||
} else {
|
||||
d->pixels[x] = best;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void init_gray(QXcbColormapPrivate *d, int screen)
|
||||
{
|
||||
d->pixels.resize(d->r_max);
|
||||
|
||||
for (int g = 0; g < d->g_max; ++g) {
|
||||
const int gray = (g * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1);
|
||||
const QRgb rgb = qRgb(gray, gray, gray);
|
||||
|
||||
d->pixels[g] = -1;
|
||||
|
||||
if (d->visual->c_class & 1) {
|
||||
XColor xcolor;
|
||||
xcolor.red = qRed(rgb) * 0x101;
|
||||
xcolor.green = qGreen(rgb) * 0x101;
|
||||
xcolor.blue = qBlue(rgb) * 0x101;
|
||||
xcolor.pixel = 0ul;
|
||||
|
||||
if (XAllocColor(X11->display, d->colormap, &xcolor))
|
||||
d->pixels[g] = xcolor.pixel;
|
||||
}
|
||||
}
|
||||
|
||||
query_colormap(d, screen);
|
||||
}
|
||||
|
||||
static void init_indexed(QXcbColormapPrivate *d, int screen)
|
||||
{
|
||||
d->pixels.resize(d->r_max * d->g_max * d->b_max);
|
||||
|
||||
// create color cube
|
||||
for (int x = 0, r = 0; r < d->r_max; ++r) {
|
||||
for (int g = 0; g < d->g_max; ++g) {
|
||||
for (int b = 0; b < d->b_max; ++b, ++x) {
|
||||
const QRgb rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1),
|
||||
(g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1),
|
||||
(b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1));
|
||||
|
||||
d->pixels[x] = -1;
|
||||
|
||||
if (d->visual->c_class & 1) {
|
||||
XColor xcolor;
|
||||
xcolor.red = qRed(rgb) * 0x101;
|
||||
xcolor.green = qGreen(rgb) * 0x101;
|
||||
xcolor.blue = qBlue(rgb) * 0x101;
|
||||
xcolor.pixel = 0ul;
|
||||
|
||||
if (XAllocColor(X11->display, d->colormap, &xcolor))
|
||||
d->pixels[x] = xcolor.pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query_colormap(d, screen);
|
||||
}
|
||||
|
||||
static void init_direct(QXcbColormapPrivate *d, bool ownColormap)
|
||||
{
|
||||
if (d->visual->c_class != DirectColor || !ownColormap)
|
||||
return;
|
||||
|
||||
// preallocate 768 on the stack, so that we don't have to malloc
|
||||
// for the common case (<= 24 bpp)
|
||||
QVarLengthArray<XColor, 768> colorTable(d->r_max + d->g_max + d->b_max);
|
||||
int i = 0;
|
||||
|
||||
for (int r = 0; r < d->r_max; ++r) {
|
||||
colorTable[i].red = r << 8 | r;
|
||||
colorTable[i].pixel = r << d->r_shift;
|
||||
colorTable[i].flags = DoRed;
|
||||
++i;
|
||||
}
|
||||
|
||||
for (int g = 0; g < d->g_max; ++g) {
|
||||
colorTable[i].green = g << 8 | g;
|
||||
colorTable[i].pixel = g << d->g_shift;
|
||||
colorTable[i].flags = DoGreen;
|
||||
++i;
|
||||
}
|
||||
|
||||
for (int b = 0; b < d->b_max; ++b) {
|
||||
colorTable[i].blue = (b << 8 | b);
|
||||
colorTable[i].pixel = b << d->b_shift;
|
||||
colorTable[i].flags = DoBlue;
|
||||
++i;
|
||||
}
|
||||
|
||||
XStoreColors(X11->display, d->colormap, colorTable.data(), colorTable.count());
|
||||
}
|
||||
|
||||
static QXcbColormap **cmaps = 0;
|
||||
|
||||
void QXcbColormap::initialize()
|
||||
{
|
||||
Display *display = X11->display;
|
||||
const int screens = ScreenCount(display);
|
||||
|
||||
cmaps = new QXcbColormap*[screens];
|
||||
|
||||
for (int i = 0; i < screens; ++i) {
|
||||
cmaps[i] = new QXcbColormap;
|
||||
QXcbColormapPrivate * const d = cmaps[i]->d;
|
||||
|
||||
bool use_stdcmap = false;
|
||||
int color_count = X11->color_count;
|
||||
|
||||
// defaults
|
||||
d->depth = DefaultDepth(display, i);
|
||||
d->colormap = DefaultColormap(display, i);
|
||||
d->defaultColormap = true;
|
||||
d->visual = DefaultVisual(display, i);
|
||||
d->defaultVisual = true;
|
||||
|
||||
Visual *argbVisual = 0;
|
||||
|
||||
if (X11->visual && i == DefaultScreen(display)) {
|
||||
// only use the outside colormap on the default screen
|
||||
d->visual = find_visual(display, i, X11->visual->c_class,
|
||||
XVisualIDFromVisual(X11->visual),
|
||||
&d->depth, &d->defaultVisual);
|
||||
} else if ((X11->visual_class != -1 && X11->visual_class >= 0 && X11->visual_class < 6)
|
||||
|| (X11->visual_id != -1)) {
|
||||
// look for a specific visual or type of visual
|
||||
d->visual = find_visual(display, i, X11->visual_class, X11->visual_id,
|
||||
&d->depth, &d->defaultVisual);
|
||||
} else if (!X11->custom_cmap) {
|
||||
XStandardColormap *stdcmap = 0;
|
||||
int ncmaps = 0;
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
if (X11->use_xrender) {
|
||||
int nvi;
|
||||
XVisualInfo templ;
|
||||
templ.screen = i;
|
||||
templ.depth = 32;
|
||||
templ.c_class = TrueColor;
|
||||
XVisualInfo *xvi = XGetVisualInfo(X11->display, VisualScreenMask |
|
||||
VisualDepthMask |
|
||||
VisualClassMask, &templ, &nvi);
|
||||
for (int idx = 0; idx < nvi; ++idx) {
|
||||
XRenderPictFormat *format = XRenderFindVisualFormat(X11->display,
|
||||
xvi[idx].visual);
|
||||
if (format->type == PictTypeDirect && format->direct.alphaMask) {
|
||||
argbVisual = xvi[idx].visual;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree(xvi);
|
||||
}
|
||||
#endif
|
||||
if (XGetRGBColormaps(display, RootWindow(display, i),
|
||||
&stdcmap, &ncmaps, XA_RGB_DEFAULT_MAP)) {
|
||||
if (stdcmap) {
|
||||
for (int c = 0; c < ncmaps; ++c) {
|
||||
if (!stdcmap[c].red_max ||
|
||||
!stdcmap[c].green_max ||
|
||||
!stdcmap[c].blue_max ||
|
||||
!stdcmap[c].red_mult ||
|
||||
!stdcmap[c].green_mult ||
|
||||
!stdcmap[c].blue_mult)
|
||||
continue; // invalid stdcmap
|
||||
|
||||
XVisualInfo proto;
|
||||
proto.visualid = stdcmap[c].visualid;
|
||||
proto.screen = i;
|
||||
|
||||
int nvisuals = 0;
|
||||
XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask | VisualScreenMask,
|
||||
&proto, &nvisuals);
|
||||
if (vi) {
|
||||
if (nvisuals > 0) {
|
||||
use_stdcmap = true;
|
||||
|
||||
d->mode = ((vi[0].visual->c_class < StaticColor)
|
||||
? Gray
|
||||
: ((vi[0].visual->c_class < TrueColor)
|
||||
? Indexed
|
||||
: Direct));
|
||||
|
||||
d->depth = vi[0].depth;
|
||||
d->colormap = stdcmap[c].colormap;
|
||||
d->defaultColormap = true;
|
||||
d->visual = vi[0].visual;
|
||||
d->defaultVisual = (d->visual == DefaultVisual(display, i));
|
||||
|
||||
d->r_max = stdcmap[c].red_max + 1;
|
||||
d->g_max = stdcmap[c].green_max + 1;
|
||||
d->b_max = stdcmap[c].blue_max + 1;
|
||||
|
||||
if (d->mode == Direct) {
|
||||
// calculate offsets
|
||||
d->r_shift = lowest_bit(d->visual->red_mask);
|
||||
d->g_shift = lowest_bit(d->visual->green_mask);
|
||||
d->b_shift = lowest_bit(d->visual->blue_mask);
|
||||
} else {
|
||||
d->r_shift = 0;
|
||||
d->g_shift = 0;
|
||||
d->b_shift = 0;
|
||||
}
|
||||
}
|
||||
XFree(vi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
XFree(stdcmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!use_stdcmap) {
|
||||
switch (d->visual->c_class) {
|
||||
case StaticGray:
|
||||
d->mode = Gray;
|
||||
|
||||
d->r_max = d->g_max = d->b_max = d->visual->map_entries;
|
||||
break;
|
||||
|
||||
case XGrayScale:
|
||||
d->mode = Gray;
|
||||
|
||||
// follow precedent set in libXmu...
|
||||
if (color_count != 0)
|
||||
d->r_max = d->g_max = d->b_max = color_count;
|
||||
else if (d->visual->map_entries > 65000)
|
||||
d->r_max = d->g_max = d->b_max = 4096;
|
||||
else if (d->visual->map_entries > 4000)
|
||||
d->r_max = d->g_max = d->b_max = 512;
|
||||
else if (d->visual->map_entries > 250)
|
||||
d->r_max = d->g_max = d->b_max = 12;
|
||||
else
|
||||
d->r_max = d->g_max = d->b_max = 4;
|
||||
break;
|
||||
|
||||
case StaticColor:
|
||||
d->mode = Indexed;
|
||||
|
||||
d->r_max = right_align(d->visual->red_mask) + 1;
|
||||
d->g_max = right_align(d->visual->green_mask) + 1;
|
||||
d->b_max = right_align(d->visual->blue_mask) + 1;
|
||||
break;
|
||||
|
||||
case PseudoColor:
|
||||
d->mode = Indexed;
|
||||
|
||||
// follow precedent set in libXmu...
|
||||
if (color_count != 0)
|
||||
d->r_max = d->g_max = d->b_max = cube_root(color_count);
|
||||
else if (d->visual->map_entries > 65000)
|
||||
d->r_max = d->g_max = d->b_max = 27;
|
||||
else if (d->visual->map_entries > 4000)
|
||||
d->r_max = d->g_max = d->b_max = 12;
|
||||
else if (d->visual->map_entries > 250)
|
||||
d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries - 125);
|
||||
else
|
||||
d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries);
|
||||
break;
|
||||
|
||||
case TrueColor:
|
||||
case DirectColor:
|
||||
d->mode = Direct;
|
||||
|
||||
d->r_max = right_align(d->visual->red_mask) + 1;
|
||||
d->g_max = right_align(d->visual->green_mask) + 1;
|
||||
d->b_max = right_align(d->visual->blue_mask) + 1;
|
||||
|
||||
d->r_shift = lowest_bit(d->visual->red_mask);
|
||||
d->g_shift = lowest_bit(d->visual->green_mask);
|
||||
d->b_shift = lowest_bit(d->visual->blue_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool ownColormap = false;
|
||||
if (X11->colormap && i == DefaultScreen(display)) {
|
||||
// only use the outside colormap on the default screen
|
||||
d->colormap = X11->colormap;
|
||||
d->defaultColormap = (d->colormap == DefaultColormap(display, i));
|
||||
} else if ((!use_stdcmap
|
||||
&& (((d->visual->c_class & 1) && X11->custom_cmap)
|
||||
|| d->visual != DefaultVisual(display, i)))
|
||||
|| d->visual->c_class == DirectColor) {
|
||||
// allocate custom colormap (we always do this when using DirectColor visuals)
|
||||
d->colormap =
|
||||
XCreateColormap(display, RootWindow(display, i), d->visual,
|
||||
d->visual->c_class == DirectColor ? AllocAll : AllocNone);
|
||||
d->defaultColormap = false;
|
||||
ownColormap = true;
|
||||
}
|
||||
|
||||
switch (d->mode) {
|
||||
case Gray:
|
||||
init_gray(d, i);
|
||||
break;
|
||||
case Indexed:
|
||||
init_indexed(d, i);
|
||||
break;
|
||||
case Direct:
|
||||
init_direct(d, ownColormap);
|
||||
break;
|
||||
}
|
||||
|
||||
QX11InfoData *screen = X11->screens + i;
|
||||
screen->depth = d->depth;
|
||||
screen->visual = d->visual;
|
||||
screen->defaultVisual = d->defaultVisual;
|
||||
screen->colormap = d->colormap;
|
||||
screen->defaultColormap = d->defaultColormap;
|
||||
screen->cells = screen->visual->map_entries;
|
||||
|
||||
if (argbVisual) {
|
||||
X11->argbVisuals[i] = argbVisual;
|
||||
X11->argbColormaps[i] = XCreateColormap(display, RootWindow(display, i), argbVisual, AllocNone);
|
||||
}
|
||||
|
||||
// ###
|
||||
// We assume that 8bpp == pseudocolor, but this is not
|
||||
// always the case (according to the X server), so we need
|
||||
// to make sure that our internal data is setup in a way
|
||||
// that is compatible with our assumptions
|
||||
if (screen->visual->c_class == TrueColor && screen->depth == 8 && screen->cells == 8)
|
||||
screen->cells = 256;
|
||||
}
|
||||
}
|
||||
|
||||
void QXcbColormap::cleanup()
|
||||
{
|
||||
Display *display = X11->display;
|
||||
const int screens = ScreenCount(display);
|
||||
|
||||
for (int i = 0; i < screens; ++i)
|
||||
delete cmaps[i];
|
||||
|
||||
delete [] cmaps;
|
||||
cmaps = 0;
|
||||
}
|
||||
|
||||
|
||||
QXcbColormap QXcbColormap::instance(int screen)
|
||||
{
|
||||
if (screen == -1)
|
||||
screen = QXcbX11Info::appScreen();
|
||||
return *cmaps[screen];
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
Constructs a new colormap.
|
||||
*/
|
||||
QXcbColormap::QXcbColormap()
|
||||
: d(new QXcbColormapPrivate)
|
||||
{}
|
||||
|
||||
QXcbColormap::QXcbColormap(const QXcbColormap &colormap)
|
||||
:d (colormap.d)
|
||||
{ d->ref.ref(); }
|
||||
|
||||
QXcbColormap::~QXcbColormap()
|
||||
{
|
||||
if (!d->ref.deref()) {
|
||||
if (!d->defaultColormap)
|
||||
XFreeColormap(X11->display, d->colormap);
|
||||
delete d;
|
||||
}
|
||||
}
|
||||
|
||||
QXcbColormap::Mode QXcbColormap::mode() const
|
||||
{ return d->mode; }
|
||||
|
||||
int QXcbColormap::depth() const
|
||||
{ return d->depth; }
|
||||
|
||||
int QXcbColormap::size() const
|
||||
{
|
||||
return (d->mode == Gray
|
||||
? d->r_max
|
||||
: (d->mode == Indexed
|
||||
? d->r_max * d->g_max * d->b_max
|
||||
: -1));
|
||||
}
|
||||
|
||||
uint QXcbColormap::pixel(const QColor &color) const
|
||||
{
|
||||
const QRgba64 rgba64 = color.rgba64();
|
||||
// XXX We emulate the raster engine here by getting the
|
||||
// 8-bit values, but we could instead use the 16-bit
|
||||
// values for slightly better color accuracy
|
||||
const uint r = (rgba64.red8() * d->r_max) >> 8;
|
||||
const uint g = (rgba64.green8() * d->g_max) >> 8;
|
||||
const uint b = (rgba64.blue8() * d->b_max) >> 8;
|
||||
if (d->mode != Direct) {
|
||||
if (d->mode == Gray)
|
||||
return d->pixels.at((r * 30 + g * 59 + b * 11) / 100);
|
||||
return d->pixels.at(r * d->g_max * d->b_max + g * d->b_max + b);
|
||||
}
|
||||
return (r << d->r_shift) + (g << d->g_shift) + (b << d->b_shift);
|
||||
}
|
||||
|
||||
const QColor QXcbColormap::colorAt(uint pixel) const
|
||||
{
|
||||
if (d->mode != Direct) {
|
||||
Q_ASSERT(pixel <= (uint)d->colors.size());
|
||||
return d->colors.at(pixel);
|
||||
}
|
||||
|
||||
const int r = (((pixel & d->visual->red_mask) >> d->r_shift) << 8) / d->r_max;
|
||||
const int g = (((pixel & d->visual->green_mask) >> d->g_shift) << 8) / d->g_max;
|
||||
const int b = (((pixel & d->visual->blue_mask) >> d->b_shift) << 8) / d->b_max;
|
||||
return QColor(r, g, b);
|
||||
}
|
||||
|
||||
const QVector<QColor> QXcbColormap::colormap() const
|
||||
{ return d->colors; }
|
||||
|
||||
QXcbColormap &QXcbColormap::operator=(const QXcbColormap &colormap)
|
||||
{
|
||||
qAtomicAssign(d, colormap.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
75
src/plugins/platforms/xcb/nativepainting/qcolormap_x11_p.h
Normal file
75
src/plugins/platforms/xcb/nativepainting/qcolormap_x11_p.h
Normal file
@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCOLORMAP_X11_H
|
||||
#define QCOLORMAP_X11_H
|
||||
|
||||
#include <QColor>
|
||||
#include <QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QXcbColormapPrivate;
|
||||
class QXcbColormap
|
||||
{
|
||||
public:
|
||||
enum Mode { Direct, Indexed, Gray };
|
||||
|
||||
static void initialize();
|
||||
static void cleanup();
|
||||
|
||||
static QXcbColormap instance(int screen = -1);
|
||||
|
||||
QXcbColormap(const QXcbColormap &colormap);
|
||||
~QXcbColormap();
|
||||
|
||||
QXcbColormap &operator=(const QXcbColormap &colormap);
|
||||
|
||||
Mode mode() const;
|
||||
|
||||
int depth() const;
|
||||
int size() const;
|
||||
|
||||
uint pixel(const QColor &color) const;
|
||||
const QColor colorAt(uint pixel) const;
|
||||
|
||||
const QVector<QColor> colormap() const;
|
||||
|
||||
private:
|
||||
QXcbColormap();
|
||||
QXcbColormapPrivate *d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCOLORMAP_X11_H
|
2837
src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
Normal file
2837
src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
Normal file
File diff suppressed because it is too large
Load Diff
118
src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
Normal file
118
src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
Normal file
@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QPAINTENGINE_X11_H
|
||||
#define QPAINTENGINE_X11_H
|
||||
|
||||
#include <QtGui/QPaintEngine>
|
||||
|
||||
typedef unsigned long XID;
|
||||
typedef XID Drawable;
|
||||
typedef struct _XGC *GC;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
extern "C" {
|
||||
Drawable qt_x11Handle(const QPaintDevice *pd);
|
||||
GC qt_x11_get_pen_gc(QPainter *);
|
||||
GC qt_x11_get_brush_gc(QPainter *);
|
||||
}
|
||||
|
||||
class QX11PaintEnginePrivate;
|
||||
class QX11PaintEngine : public QPaintEngine
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QX11PaintEngine)
|
||||
public:
|
||||
QX11PaintEngine();
|
||||
~QX11PaintEngine();
|
||||
|
||||
bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
|
||||
bool end() Q_DECL_OVERRIDE;
|
||||
|
||||
void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE;
|
||||
|
||||
void updatePen(const QPen &pen);
|
||||
void updateBrush(const QBrush &brush, const QPointF &pt);
|
||||
void updateRenderHints(QPainter::RenderHints hints);
|
||||
void updateFont(const QFont &font);
|
||||
void updateMatrix(const QTransform &matrix);
|
||||
void updateClipRegion_dev(const QRegion ®ion, Qt::ClipOperation op);
|
||||
|
||||
void drawLines(const QLine *lines, int lineCount) Q_DECL_OVERRIDE;
|
||||
void drawLines(const QLineF *lines, int lineCount) Q_DECL_OVERRIDE;
|
||||
|
||||
void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE;
|
||||
void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE;
|
||||
|
||||
void drawPoints(const QPoint *points, int pointCount) Q_DECL_OVERRIDE;
|
||||
void drawPoints(const QPointF *points, int pointCount) Q_DECL_OVERRIDE;
|
||||
|
||||
void drawEllipse(const QRect &r) Q_DECL_OVERRIDE;
|
||||
void drawEllipse(const QRectF &r) Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
|
||||
inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE
|
||||
{ QPaintEngine::drawPolygon(points, pointCount, mode); }
|
||||
|
||||
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
|
||||
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) Q_DECL_OVERRIDE;
|
||||
void drawPath(const QPainterPath &path) Q_DECL_OVERRIDE;
|
||||
void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
|
||||
void drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
|
||||
Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
|
||||
|
||||
virtual Drawable handle() const;
|
||||
inline Type type() const Q_DECL_OVERRIDE { return QPaintEngine::X11; }
|
||||
|
||||
QPainter::RenderHints supportedRenderHints() const;
|
||||
|
||||
protected:
|
||||
QX11PaintEngine(QX11PaintEnginePrivate &dptr);
|
||||
|
||||
#if QT_CONFIG(fontconfig)
|
||||
void drawFreetype(const QPointF &p, const QTextItemInt &ti);
|
||||
bool drawCachedGlyphs(const QTransform &transform, const QTextItemInt &ti);
|
||||
#endif // QT_CONFIG(fontconfig)
|
||||
|
||||
friend class QPixmap;
|
||||
friend class QFontEngineBox;
|
||||
friend GC qt_x11_get_pen_gc(QPainter *);
|
||||
friend GC qt_x11_get_brush_gc(QPainter *);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QX11PaintEngine)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QPAINTENGINE_X11_H
|
2104
src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
Normal file
2104
src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
Normal file
File diff suppressed because it is too large
Load Diff
160
src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h
Normal file
160
src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h
Normal file
@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QX11PLATFORMPIXMAP_H
|
||||
#define QX11PLATFORMPIXMAP_H
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <qpa/qplatformpixmap.h>
|
||||
#include "qxcbnativepainting.h"
|
||||
|
||||
typedef unsigned long XID;
|
||||
typedef XID Drawable;
|
||||
typedef XID Picture;
|
||||
typedef XID Pixmap;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QX11PaintEngine;
|
||||
struct QXImageWrapper;
|
||||
|
||||
class QX11PlatformPixmap : public QPlatformPixmap
|
||||
{
|
||||
public:
|
||||
QX11PlatformPixmap(PixelType pixelType);
|
||||
~QX11PlatformPixmap();
|
||||
|
||||
QPlatformPixmap *createCompatiblePlatformPixmap() const Q_DECL_OVERRIDE;
|
||||
void resize(int width, int height) Q_DECL_OVERRIDE;
|
||||
void fromImage(const QImage &img, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE;
|
||||
void copy(const QPlatformPixmap *data, const QRect &rect) Q_DECL_OVERRIDE;
|
||||
bool scroll(int dx, int dy, const QRect &rect) Q_DECL_OVERRIDE;
|
||||
int metric(QPaintDevice::PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
|
||||
void fill(const QColor &fillColor) Q_DECL_OVERRIDE;
|
||||
QBitmap mask() const Q_DECL_OVERRIDE;
|
||||
void setMask(const QBitmap &mask) Q_DECL_OVERRIDE;
|
||||
bool hasAlphaChannel() const Q_DECL_OVERRIDE;
|
||||
QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const Q_DECL_OVERRIDE;
|
||||
QImage toImage() const Q_DECL_OVERRIDE;
|
||||
QImage toImage(const QRect &rect) const Q_DECL_OVERRIDE;
|
||||
QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
|
||||
qreal devicePixelRatio() const Q_DECL_OVERRIDE;
|
||||
void setDevicePixelRatio(qreal scaleFactor) Q_DECL_OVERRIDE;
|
||||
|
||||
inline Drawable handle() const { return hd; }
|
||||
inline Picture x11PictureHandle() const { return picture; }
|
||||
inline const QXcbX11Info *x11_info() const { return &xinfo; }
|
||||
|
||||
Pixmap x11ConvertToDefaultDepth();
|
||||
static XID createBitmapFromImage(const QImage &image);
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
void convertToARGB32(bool preserveContents = true);
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class QX11PaintEngine;
|
||||
friend const QXcbX11Info &qt_x11Info(const QPixmap &pixmap);
|
||||
friend void qt_x11SetScreen(QPixmap &pixmap, int screen);
|
||||
|
||||
void release();
|
||||
QImage toImage(const QXImageWrapper &xi, const QRect &rect) const;
|
||||
QBitmap mask_to_bitmap(int screen) const;
|
||||
static Pixmap bitmap_to_mask(const QBitmap &, int screen);
|
||||
void bitmapFromImage(const QImage &image);
|
||||
bool canTakeQImageFromXImage(const QXImageWrapper &xi) const;
|
||||
QImage takeQImageFromXImage(const QXImageWrapper &xi) const;
|
||||
|
||||
Pixmap hd = 0;
|
||||
|
||||
enum Flag {
|
||||
NoFlags = 0x0,
|
||||
Uninitialized = 0x1,
|
||||
Readonly = 0x2,
|
||||
InvertedWhenBoundToTexture = 0x4,
|
||||
GlSurfaceCreatedWithAlpha = 0x8
|
||||
};
|
||||
uint flags;
|
||||
|
||||
QXcbX11Info xinfo;
|
||||
Pixmap x11_mask;
|
||||
Picture picture;
|
||||
Picture mask_picture;
|
||||
Pixmap hd2; // sorted in the default display depth
|
||||
//QPixmap::ShareMode share_mode;
|
||||
qreal dpr;
|
||||
|
||||
QX11PaintEngine *pengine;
|
||||
};
|
||||
|
||||
inline QX11PlatformPixmap *qt_x11Pixmap(const QPixmap &pixmap)
|
||||
{
|
||||
return (pixmap.handle() && pixmap.handle()->classId() == QPlatformPixmap::X11Class)
|
||||
? static_cast<QX11PlatformPixmap *>(pixmap.handle())
|
||||
: Q_NULLPTR;
|
||||
}
|
||||
|
||||
inline Picture qt_x11PictureHandle(const QPixmap &pixmap)
|
||||
{
|
||||
if (QX11PlatformPixmap *pm = qt_x11Pixmap(pixmap))
|
||||
return pm->x11PictureHandle();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline Pixmap qt_x11PixmapHandle(const QPixmap &pixmap)
|
||||
{
|
||||
if (QX11PlatformPixmap *pm = qt_x11Pixmap(pixmap))
|
||||
return pm->handle();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline const QXcbX11Info &qt_x11Info(const QPixmap &pixmap)
|
||||
{
|
||||
if (QX11PlatformPixmap *pm = qt_x11Pixmap(pixmap)) {
|
||||
return pm->xinfo;
|
||||
} else {
|
||||
static QXcbX11Info nullX11Info;
|
||||
return nullX11Info;
|
||||
}
|
||||
}
|
||||
|
||||
int qt_x11SetDefaultScreen(int screen);
|
||||
void qt_x11SetScreen(QPixmap &pixmap, int screen);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QX11PLATFORMPIXMAP_H
|
193
src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
Normal file
193
src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
Normal file
@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QT_X11_P_H
|
||||
#define QT_X11_P_H
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
# include "qtessellator_p.h"
|
||||
# include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(fontconfig)
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#if defined(FT_LCD_FILTER_H)
|
||||
#include FT_LCD_FILTER_H
|
||||
#endif
|
||||
|
||||
#if defined(FC_LCD_FILTER)
|
||||
|
||||
#ifndef FC_LCD_FILTER_NONE
|
||||
#define FC_LCD_FILTER_NONE FC_LCD_NONE
|
||||
#endif
|
||||
|
||||
#ifndef FC_LCD_FILTER_DEFAULT
|
||||
#define FC_LCD_FILTER_DEFAULT FC_LCD_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef FC_LCD_FILTER_LIGHT
|
||||
#define FC_LCD_FILTER_LIGHT FC_LCD_LIGHT
|
||||
#endif
|
||||
|
||||
#ifndef FC_LCD_FILTER_LEGACY
|
||||
#define FC_LCD_FILTER_LEGACY FC_LCD_LEGACY
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// rename a couple of X defines to get rid of name clashes
|
||||
// resolve the conflict between X11's FocusIn and QEvent::FocusIn
|
||||
enum {
|
||||
XFocusOut = FocusOut,
|
||||
XFocusIn = FocusIn,
|
||||
XKeyPress = KeyPress,
|
||||
XKeyRelease = KeyRelease,
|
||||
XNone = None,
|
||||
XRevertToParent = RevertToParent,
|
||||
XGrayScale = GrayScale,
|
||||
XCursorShape = CursorShape,
|
||||
};
|
||||
#undef FocusOut
|
||||
#undef FocusIn
|
||||
#undef KeyPress
|
||||
#undef KeyRelease
|
||||
#undef None
|
||||
#undef RevertToParent
|
||||
#undef GrayScale
|
||||
#undef CursorShape
|
||||
|
||||
#ifdef FontChange
|
||||
#undef FontChange
|
||||
#endif
|
||||
|
||||
Q_DECLARE_TYPEINFO(XPoint, Q_PRIMITIVE_TYPE);
|
||||
Q_DECLARE_TYPEINFO(XRectangle, Q_PRIMITIVE_TYPE);
|
||||
Q_DECLARE_TYPEINFO(XChar2b, Q_PRIMITIVE_TYPE);
|
||||
#if QT_CONFIG(xrender)
|
||||
Q_DECLARE_TYPEINFO(XGlyphElt32, Q_PRIMITIVE_TYPE);
|
||||
#endif
|
||||
|
||||
struct QX11InfoData;
|
||||
|
||||
enum DesktopEnvironment {
|
||||
DE_UNKNOWN,
|
||||
DE_KDE,
|
||||
DE_GNOME,
|
||||
DE_CDE,
|
||||
DE_MEEGO_COMPOSITOR,
|
||||
DE_4DWM
|
||||
};
|
||||
|
||||
struct QXcbX11Data {
|
||||
Display *display = nullptr;
|
||||
|
||||
// true if Qt is compiled w/ RENDER support and RENDER is supported on the connected Display
|
||||
bool use_xrender = false;
|
||||
int xrender_major = 0;
|
||||
int xrender_version = 0;
|
||||
|
||||
QX11InfoData *screens = nullptr;
|
||||
Visual **argbVisuals = nullptr;
|
||||
Colormap *argbColormaps = nullptr;
|
||||
int screenCount = 0;
|
||||
int defaultScreen = 0;
|
||||
|
||||
// options
|
||||
int visual_class = 0;
|
||||
int visual_id = 0;
|
||||
int color_count = 0;
|
||||
bool custom_cmap = false;
|
||||
|
||||
// outside visual/colormap
|
||||
Visual *visual = nullptr;
|
||||
Colormap colormap = 0;
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
enum { solid_fill_count = 16 };
|
||||
struct SolidFills {
|
||||
XRenderColor color;
|
||||
int screen;
|
||||
Picture picture;
|
||||
} solid_fills[solid_fill_count];
|
||||
enum { pattern_fill_count = 16 };
|
||||
struct PatternFills {
|
||||
XRenderColor color;
|
||||
XRenderColor bg_color;
|
||||
int screen;
|
||||
int style;
|
||||
bool opaque;
|
||||
Picture picture;
|
||||
} pattern_fills[pattern_fill_count];
|
||||
Picture getSolidFill(int screen, const QColor &c);
|
||||
XRenderColor preMultiply(const QColor &c);
|
||||
#endif
|
||||
|
||||
bool fc_antialias = true;
|
||||
int fc_hint_style = 0;
|
||||
|
||||
DesktopEnvironment desktopEnvironment = DE_GNOME;
|
||||
};
|
||||
|
||||
extern QXcbX11Data *qt_x11Data;
|
||||
#define X11 qt_x11Data
|
||||
|
||||
struct QX11InfoData {
|
||||
int screen;
|
||||
int dpiX;
|
||||
int dpiY;
|
||||
int depth;
|
||||
int cells;
|
||||
Colormap colormap;
|
||||
Visual *visual;
|
||||
bool defaultColormap;
|
||||
bool defaultVisual;
|
||||
int subpixel = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
Q_DECL_RELAXED_CONSTEXPR inline int lowest_bit(T v) Q_DECL_NOTHROW
|
||||
{
|
||||
int result = qCountTrailingZeroBits(v);
|
||||
return ((result >> 3) == sizeof(T)) ? -1 : result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_X11_P_H
|
1491
src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
Normal file
1491
src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
83
src/plugins/platforms/xcb/nativepainting/qtessellator_p.h
Normal file
83
src/plugins/platforms/xcb/nativepainting/qtessellator_p.h
Normal file
@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTESSELATOR_P_H
|
||||
#define QTESSELATOR_P_H
|
||||
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTessellatorPrivate;
|
||||
|
||||
typedef int Q27Dot5;
|
||||
#define Q27Dot5ToDouble(i) ((i)/32.)
|
||||
#define FloatToQ27Dot5(i) (int)((i) * 32)
|
||||
#define IntToQ27Dot5(i) ((i) << 5)
|
||||
#define Q27Dot5ToXFixed(i) ((i) << 11)
|
||||
#define Q27Dot5Factor 32
|
||||
|
||||
class QTessellator {
|
||||
public:
|
||||
QTessellator();
|
||||
virtual ~QTessellator();
|
||||
|
||||
QRectF tessellate(const QPointF *points, int nPoints);
|
||||
void tessellateConvex(const QPointF *points, int nPoints);
|
||||
void tessellateRect(const QPointF &a, const QPointF &b, qreal width);
|
||||
|
||||
void setWinding(bool w);
|
||||
|
||||
struct Vertex {
|
||||
Q27Dot5 x;
|
||||
Q27Dot5 y;
|
||||
};
|
||||
struct Trapezoid {
|
||||
Q27Dot5 top;
|
||||
Q27Dot5 bottom;
|
||||
const Vertex *topLeft;
|
||||
const Vertex *bottomLeft;
|
||||
const Vertex *topRight;
|
||||
const Vertex *bottomRight;
|
||||
};
|
||||
virtual void addTrap(const Trapezoid &trap) = 0;
|
||||
|
||||
private:
|
||||
friend class QTessellatorPrivate;
|
||||
QTessellatorPrivate *d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
315
src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp
Normal file
315
src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qxcbconnection.h"
|
||||
#include "qcolormap_x11_p.h"
|
||||
#include "qxcbnativepainting.h"
|
||||
#include "qt_x11_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QXcbX11Data *qt_x11Data = Q_NULLPTR;
|
||||
|
||||
void qt_xcb_native_x11_info_init(QXcbConnection *conn)
|
||||
{
|
||||
qt_x11Data = new QXcbX11Data;
|
||||
X11->display = (Display *) conn->xlib_display();
|
||||
X11->defaultScreen = DefaultScreen(X11->display);
|
||||
X11->screenCount = ScreenCount(X11->display);
|
||||
|
||||
X11->screens = new QX11InfoData[X11->screenCount];
|
||||
X11->argbVisuals = new Visual *[X11->screenCount];
|
||||
X11->argbColormaps = new Colormap[X11->screenCount];
|
||||
|
||||
for (int s = 0; s < X11->screenCount; s++) {
|
||||
QX11InfoData *screen = X11->screens + s;
|
||||
//screen->ref = 1; // ensures it doesn't get deleted
|
||||
screen->screen = s;
|
||||
|
||||
int widthMM = DisplayWidthMM(X11->display, s);
|
||||
if (widthMM != 0) {
|
||||
screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
|
||||
} else {
|
||||
screen->dpiX = 72;
|
||||
}
|
||||
|
||||
int heightMM = DisplayHeightMM(X11->display, s);
|
||||
if (heightMM != 0) {
|
||||
screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
|
||||
} else {
|
||||
screen->dpiY = 72;
|
||||
}
|
||||
|
||||
X11->argbVisuals[s] = 0;
|
||||
X11->argbColormaps[s] = 0;
|
||||
}
|
||||
|
||||
X11->use_xrender = conn->hasXRender() && !qEnvironmentVariableIsSet("QT_XCB_NATIVE_PAINTING_NO_XRENDER");
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
|
||||
for (int i = 0; i < X11->solid_fill_count; ++i)
|
||||
X11->solid_fills[i].screen = -1;
|
||||
memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
|
||||
for (int i = 0; i < X11->pattern_fill_count; ++i)
|
||||
X11->pattern_fills[i].screen = -1;
|
||||
#endif
|
||||
|
||||
QXcbColormap::initialize();
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
if (X11->use_xrender) {
|
||||
// XRender is supported, let's see if we have a PictFormat for the
|
||||
// default visual
|
||||
XRenderPictFormat *format =
|
||||
XRenderFindVisualFormat(X11->display,
|
||||
(Visual *) QXcbX11Info::appVisual(X11->defaultScreen));
|
||||
|
||||
if (!format) {
|
||||
X11->use_xrender = false;
|
||||
}
|
||||
}
|
||||
#endif // QT_CONFIG(xrender)
|
||||
}
|
||||
|
||||
QVector<XRectangle> qt_region_to_xrectangles(const QRegion &r)
|
||||
{
|
||||
const int numRects = r.rectCount();
|
||||
const QVector<QRect> input = r.rects();
|
||||
QVector<XRectangle> output(numRects);
|
||||
for (int i = 0; i < numRects; ++i) {
|
||||
const QRect &in = input[i];
|
||||
XRectangle &out = output[i];
|
||||
out.x = qMax(SHRT_MIN, in.x());
|
||||
out.y = qMax(SHRT_MIN, in.y());
|
||||
out.width = qMin((int)USHRT_MAX, in.width());
|
||||
out.height = qMin((int)USHRT_MAX, in.height());
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
class QXcbX11InfoData : public QSharedData, public QX11InfoData
|
||||
{};
|
||||
|
||||
QXcbX11Info::QXcbX11Info()
|
||||
: d(Q_NULLPTR)
|
||||
{}
|
||||
|
||||
QXcbX11Info::~QXcbX11Info()
|
||||
{}
|
||||
|
||||
QXcbX11Info::QXcbX11Info(const QXcbX11Info &other)
|
||||
: d(other.d)
|
||||
{}
|
||||
|
||||
QXcbX11Info &QXcbX11Info::operator=(const QXcbX11Info &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
QXcbX11Info QXcbX11Info::fromScreen(int screen)
|
||||
{
|
||||
QXcbX11InfoData *xd = new QXcbX11InfoData;
|
||||
xd->screen = screen;
|
||||
xd->depth = QXcbX11Info::appDepth(screen);
|
||||
xd->cells = QXcbX11Info::appCells(screen);
|
||||
xd->colormap = QXcbX11Info::appColormap(screen);
|
||||
xd->defaultColormap = QXcbX11Info::appDefaultColormap(screen);
|
||||
xd->visual = (Visual *)QXcbX11Info::appVisual(screen);
|
||||
xd->defaultVisual = QXcbX11Info::appDefaultVisual(screen);
|
||||
|
||||
QXcbX11Info info;
|
||||
info.d = xd;
|
||||
return info;
|
||||
}
|
||||
|
||||
void QXcbX11Info::setDepth(int depth)
|
||||
{
|
||||
if (!d)
|
||||
*this = fromScreen(appScreen());
|
||||
|
||||
d->depth = depth;
|
||||
}
|
||||
|
||||
Display *QXcbX11Info::display()
|
||||
{
|
||||
return X11 ? X11->display : 0;
|
||||
}
|
||||
|
||||
int QXcbX11Info::screen() const
|
||||
{
|
||||
return d ? d->screen : QXcbX11Info::appScreen();
|
||||
}
|
||||
|
||||
int QXcbX11Info::depth() const
|
||||
{
|
||||
return d ? d->depth : QXcbX11Info::appDepth();
|
||||
}
|
||||
|
||||
Colormap QXcbX11Info::colormap() const
|
||||
{
|
||||
return d ? d->colormap : QXcbX11Info::appColormap();
|
||||
}
|
||||
|
||||
void *QXcbX11Info::visual() const
|
||||
{
|
||||
return d ? d->visual : QXcbX11Info::appVisual();
|
||||
}
|
||||
|
||||
void QXcbX11Info::setVisual(void *visual)
|
||||
{
|
||||
if (!d)
|
||||
*this = fromScreen(appScreen());
|
||||
|
||||
d->visual = (Visual *) visual;
|
||||
}
|
||||
|
||||
int QXcbX11Info::appScreen()
|
||||
{
|
||||
return X11 ? X11->defaultScreen : 0;
|
||||
}
|
||||
|
||||
int QXcbX11Info::appDepth(int screen)
|
||||
{
|
||||
return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].depth : 32;
|
||||
}
|
||||
|
||||
int QXcbX11Info::appCells(int screen)
|
||||
{
|
||||
return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].cells : 0;
|
||||
}
|
||||
|
||||
Colormap QXcbX11Info::appColormap(int screen)
|
||||
{
|
||||
return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].colormap : 0;
|
||||
}
|
||||
|
||||
void *QXcbX11Info::appVisual(int screen)
|
||||
{
|
||||
return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].visual : 0;
|
||||
}
|
||||
|
||||
Window QXcbX11Info::appRootWindow(int screen)
|
||||
{
|
||||
return X11 ? RootWindow(X11->display, screen == -1 ? X11->defaultScreen : screen) : 0;
|
||||
}
|
||||
|
||||
bool QXcbX11Info::appDefaultColormap(int screen)
|
||||
{
|
||||
return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].defaultColormap : true;
|
||||
}
|
||||
|
||||
bool QXcbX11Info::appDefaultVisual(int screen)
|
||||
{
|
||||
return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].defaultVisual : true;
|
||||
}
|
||||
|
||||
int QXcbX11Info::appDpiX(int screen)
|
||||
{
|
||||
if (!X11)
|
||||
return 75;
|
||||
if (screen < 0)
|
||||
screen = X11->defaultScreen;
|
||||
if (screen > X11->screenCount)
|
||||
return 0;
|
||||
return X11->screens[screen].dpiX;
|
||||
}
|
||||
|
||||
int QXcbX11Info::appDpiY(int screen)
|
||||
{
|
||||
if (!X11)
|
||||
return 75;
|
||||
if (screen < 0)
|
||||
screen = X11->defaultScreen;
|
||||
if (screen > X11->screenCount)
|
||||
return 0;
|
||||
return X11->screens[screen].dpiY;
|
||||
}
|
||||
|
||||
#if QT_CONFIG(xrender)
|
||||
Picture QXcbX11Data::getSolidFill(int screen, const QColor &c)
|
||||
{
|
||||
if (!X11->use_xrender)
|
||||
return XNone;
|
||||
|
||||
XRenderColor color = preMultiply(c);
|
||||
for (int i = 0; i < X11->solid_fill_count; ++i) {
|
||||
if (X11->solid_fills[i].screen == screen
|
||||
&& X11->solid_fills[i].color.alpha == color.alpha
|
||||
&& X11->solid_fills[i].color.red == color.red
|
||||
&& X11->solid_fills[i].color.green == color.green
|
||||
&& X11->solid_fills[i].color.blue == color.blue)
|
||||
return X11->solid_fills[i].picture;
|
||||
}
|
||||
// none found, replace one
|
||||
int i = qrand() % 16;
|
||||
|
||||
if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
|
||||
XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
|
||||
X11->solid_fills[i].picture = 0;
|
||||
}
|
||||
|
||||
if (!X11->solid_fills[i].picture) {
|
||||
Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
|
||||
XRenderPictureAttributes attrs;
|
||||
attrs.repeat = True;
|
||||
X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
|
||||
XRenderFindStandardFormat(X11->display, PictStandardARGB32),
|
||||
CPRepeat, &attrs);
|
||||
XFreePixmap (X11->display, pixmap);
|
||||
}
|
||||
|
||||
X11->solid_fills[i].color = color;
|
||||
X11->solid_fills[i].screen = screen;
|
||||
XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
|
||||
return X11->solid_fills[i].picture;
|
||||
}
|
||||
|
||||
XRenderColor QXcbX11Data::preMultiply(const QColor &c)
|
||||
{
|
||||
XRenderColor color;
|
||||
const uint A = c.alpha(),
|
||||
R = c.red(),
|
||||
G = c.green(),
|
||||
B = c.blue();
|
||||
color.alpha = (A | A << 8);
|
||||
color.red = (R | R << 8) * color.alpha / 0x10000;
|
||||
color.green = (G | G << 8) * color.alpha / 0x10000;
|
||||
color.blue = (B | B << 8) * color.alpha / 0x10000;
|
||||
return color;
|
||||
}
|
||||
#endif // QT_CONFIG(xrender)
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QXCBNATIVEPAINTING_H
|
||||
#define QXCBNATIVEPAINTING_H
|
||||
|
||||
#include <QSharedDataPointer>
|
||||
#include "qt_x11_p.h"
|
||||
|
||||
typedef struct _FcPattern FcPattern;
|
||||
typedef unsigned long XID;
|
||||
typedef XID Colormap;
|
||||
typedef XID Window;
|
||||
typedef struct _XDisplay Display;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QXcbConnection;
|
||||
class QPixmap;
|
||||
|
||||
void qt_xcb_native_x11_info_init(QXcbConnection *conn);
|
||||
QVector<XRectangle> qt_region_to_xrectangles(const QRegion &r);
|
||||
|
||||
class QXcbX11InfoData;
|
||||
class QXcbX11Info
|
||||
{
|
||||
public:
|
||||
QXcbX11Info();
|
||||
~QXcbX11Info();
|
||||
QXcbX11Info(const QXcbX11Info &other);
|
||||
QXcbX11Info &operator=(const QXcbX11Info &other);
|
||||
|
||||
static QXcbX11Info fromScreen(int screen);
|
||||
static Display *display();
|
||||
|
||||
int depth() const;
|
||||
void setDepth(int depth);
|
||||
|
||||
int screen() const;
|
||||
Colormap colormap() const;
|
||||
|
||||
void *visual() const;
|
||||
void setVisual(void *visual);
|
||||
|
||||
static int appScreen();
|
||||
static int appDepth(int screen = -1);
|
||||
static int appCells(int screen = -1);
|
||||
static Colormap appColormap(int screen = -1);
|
||||
static void *appVisual(int screen = -1);
|
||||
static Window appRootWindow(int screen = -1);
|
||||
static bool appDefaultColormap(int screen = -1);
|
||||
static bool appDefaultVisual(int screen = -1);
|
||||
static int appDpiX(int screen = -1);
|
||||
static int appDpiY(int screen = -1);
|
||||
|
||||
private:
|
||||
QSharedDataPointer<QXcbX11InfoData> d;
|
||||
|
||||
friend class QX11PaintEngine;
|
||||
friend class QX11PlatformPixmap;
|
||||
friend void qt_x11SetScreen(QPixmap &pixmap, int screen);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QXCBNATIVEPAINTING_H
|
@ -148,8 +148,18 @@ static const char * const xcbConnectionErrors[] = {
|
||||
"Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */
|
||||
};
|
||||
|
||||
static int nullErrorHandler(Display *, XErrorEvent *)
|
||||
static int nullErrorHandler(Display *dpy, XErrorEvent *err)
|
||||
{
|
||||
#ifndef Q_XCB_DEBUG
|
||||
Q_UNUSED(dpy);
|
||||
Q_UNUSED(err);
|
||||
#else
|
||||
const int buflen = 1024;
|
||||
char buf[buflen];
|
||||
|
||||
XGetErrorText(dpy, err->error_code, buf, buflen);
|
||||
fprintf(stderr, "X Error: serial %lu error %d %s\n", err->serial, (int) err->error_code, buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -528,6 +538,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
, m_defaultVisualId(defaultVisualId)
|
||||
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
||||
, m_nativeInterface(nativeInterface)
|
||||
, has_render_extension(false)
|
||||
{
|
||||
#ifdef XCB_USE_XLIB
|
||||
Display *dpy = XOpenDisplay(m_displayName.constData());
|
||||
@ -1980,11 +1991,14 @@ void QXcbConnection::initializeXRender()
|
||||
if (!reply || !reply->present)
|
||||
return;
|
||||
|
||||
has_render_extension = true;
|
||||
auto xrender_query = Q_XCB_REPLY(xcb_render_query_version, m_connection,
|
||||
XCB_RENDER_MAJOR_VERSION,
|
||||
XCB_RENDER_MINOR_VERSION);
|
||||
if (!xrender_query || (xrender_query->major_version == 0 && xrender_query->minor_version < 5))
|
||||
if (!xrender_query || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) {
|
||||
qWarning("QXcbConnection: Failed to initialize XRender");
|
||||
has_render_extension = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -467,6 +467,7 @@ public:
|
||||
bool hasXRandr() const { return has_randr_extension; }
|
||||
bool hasInputShape() const { return has_input_shape; }
|
||||
bool hasXKB() const { return has_xkb; }
|
||||
bool hasXRender() const { return has_render_extension; }
|
||||
|
||||
bool supportsThreadedRendering() const { return m_reader->isRunning(); }
|
||||
bool threadedEventHandling() const { return m_reader->isRunning(); }
|
||||
@ -660,6 +661,7 @@ private:
|
||||
bool has_randr_extension = false;
|
||||
bool has_input_shape;
|
||||
bool has_xkb = false;
|
||||
bool has_render_extension;
|
||||
|
||||
Qt::MouseButtons m_buttons = 0;
|
||||
|
||||
|
@ -65,6 +65,11 @@
|
||||
|
||||
#ifdef XCB_USE_XLIB
|
||||
#include <X11/Xlib.h>
|
||||
#if QT_CONFIG(xcb_native_painting)
|
||||
#include "qxcbnativepainting.h"
|
||||
#include "qpixmap_x11_p.h"
|
||||
#include "qbackingstore_x11_p.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||
@ -192,6 +197,13 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
||||
}
|
||||
|
||||
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
||||
|
||||
#if QT_CONFIG(xcb_native_painting)
|
||||
if (nativePaintingEnabled()) {
|
||||
qDebug("QXCB USING NATIVE PAINTING");
|
||||
qt_xcb_native_x11_info_init(defaultConnection());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QXcbIntegration::~QXcbIntegration()
|
||||
@ -200,6 +212,16 @@ QXcbIntegration::~QXcbIntegration()
|
||||
m_instance = Q_NULLPTR;
|
||||
}
|
||||
|
||||
QPlatformPixmap *QXcbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
|
||||
{
|
||||
#if QT_CONFIG(xcb_native_painting)
|
||||
if (nativePaintingEnabled())
|
||||
return new QX11PlatformPixmap(type);
|
||||
#endif
|
||||
|
||||
return QPlatformIntegration::createPlatformPixmap(type);
|
||||
}
|
||||
|
||||
QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
|
||||
{
|
||||
QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
|
||||
@ -263,6 +285,11 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont
|
||||
|
||||
QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const
|
||||
{
|
||||
#if QT_CONFIG(xcb_native_painting)
|
||||
if (nativePaintingEnabled())
|
||||
return new QXcbNativeBackingStore(window);
|
||||
#endif
|
||||
|
||||
return new QXcbBackingStore(window);
|
||||
}
|
||||
|
||||
@ -511,6 +538,16 @@ void QXcbIntegration::beep() const
|
||||
xcb_bell(connection, 0);
|
||||
}
|
||||
|
||||
bool QXcbIntegration::nativePaintingEnabled() const
|
||||
{
|
||||
#if QT_CONFIG(xcb_native_painting)
|
||||
static bool enabled = qEnvironmentVariableIsSet("QT_XCB_NATIVE_PAINTING");
|
||||
return enabled;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if QT_CONFIG(vulkan)
|
||||
QPlatformVulkanInstance *QXcbIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
|
||||
{
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
QXcbIntegration(const QStringList ¶meters, int &argc, char **argv);
|
||||
~QXcbIntegration();
|
||||
|
||||
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const override;
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
|
||||
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
|
||||
#ifndef QT_NO_OPENGL
|
||||
@ -113,6 +114,8 @@ public:
|
||||
|
||||
void beep() const override;
|
||||
|
||||
bool nativePaintingEnabled() const;
|
||||
|
||||
#if QT_CONFIG(vulkan)
|
||||
QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
|
||||
#endif
|
||||
|
@ -219,6 +219,12 @@ static inline QImage::Format imageFormatForVisual(int depth, quint32 red_mask, q
|
||||
return QImage::Format_RGB555;
|
||||
}
|
||||
break;
|
||||
#if QT_CONFIG(xcb_native_painting)
|
||||
case 8:
|
||||
if (QXcbIntegration::instance() && QXcbIntegration::instance()->nativePaintingEnabled())
|
||||
return QImage::Format_Indexed8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ qtConfig(xcb-sm) {
|
||||
}
|
||||
|
||||
include(gl_integrations/gl_integrations.pri)
|
||||
include(nativepainting/nativepainting.pri)
|
||||
|
||||
qtConfig(vulkan) {
|
||||
SOURCES += \
|
||||
|
Loading…
x
Reference in New Issue
Block a user