Make it possible to use the -visual argument
for xcb applications to use a specific visual id when creating windows. Also make it possible to retrieve the visual id of a specific window with QXcbWindowFunctions::visualId(QWindow *window). UINT_MAX is used as an invalid visualId. Change-Id: If62ada119ce8f9174cc211f53bbf1ce1bb7d021a Reviewed-by: Andy Shaw <andy.shaw@digia.com>
This commit is contained in:
parent
7432c7c08a
commit
d605883b5e
@ -72,6 +72,17 @@ public:
|
|||||||
if (func)
|
if (func)
|
||||||
func(window, type);
|
func(window, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef uint (*VisualId)(QWindow *window);
|
||||||
|
static const QByteArray visualIdIdentifier() { return QByteArrayLiteral("XcbVisualId"); }
|
||||||
|
|
||||||
|
static uint visualId(QWindow *window)
|
||||||
|
{
|
||||||
|
QXcbWindowFunctions::VisualId func = reinterpret_cast<VisualId>(QGuiApplication::platformFunction(visualIdIdentifier()));
|
||||||
|
if (func)
|
||||||
|
return func(window);
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <X11/Xlibint.h>
|
#include <X11/Xlibint.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(XCB_USE_XINPUT2)
|
#if defined(XCB_USE_XINPUT2)
|
||||||
@ -437,9 +438,10 @@ void QXcbConnection::initializeScreens()
|
|||||||
qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
|
qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName)
|
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
|
||||||
: m_connection(0)
|
: m_connection(0)
|
||||||
, m_canGrabServer(canGrabServer)
|
, m_canGrabServer(canGrabServer)
|
||||||
|
, m_defaultVisualId(defaultVisualId)
|
||||||
, m_primaryScreenNumber(0)
|
, m_primaryScreenNumber(0)
|
||||||
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
||||||
, m_nativeInterface(nativeInterface)
|
, m_nativeInterface(nativeInterface)
|
||||||
@ -1351,6 +1353,21 @@ void *QXcbConnection::xlib_display() const
|
|||||||
{
|
{
|
||||||
return m_xlib_display;
|
return m_xlib_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *QXcbConnection::createVisualInfoForDefaultVisualId() const
|
||||||
|
{
|
||||||
|
if (m_defaultVisualId == UINT_MAX)
|
||||||
|
return 0;
|
||||||
|
XVisualInfo info;
|
||||||
|
memset(&info, 0, sizeof info);
|
||||||
|
info.visualid = m_defaultVisualId;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
XVisualInfo *retVisual = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &info, &count);
|
||||||
|
Q_ASSERT(count < 2);
|
||||||
|
return retVisual;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void QXcbConnection::processXcbEvents()
|
void QXcbConnection::processXcbEvents()
|
||||||
|
@ -370,7 +370,7 @@ class Q_XCB_EXPORT QXcbConnection : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0);
|
QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0);
|
||||||
~QXcbConnection();
|
~QXcbConnection();
|
||||||
|
|
||||||
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
|
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
|
||||||
@ -400,8 +400,13 @@ public:
|
|||||||
|
|
||||||
QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
|
QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
|
||||||
xcb_window_t rootWindow();
|
xcb_window_t rootWindow();
|
||||||
|
|
||||||
|
bool hasDefaultVisualId() const { return m_defaultVisualId != UINT_MAX; }
|
||||||
|
xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; }
|
||||||
|
|
||||||
#ifdef XCB_USE_XLIB
|
#ifdef XCB_USE_XLIB
|
||||||
void *xlib_display() const;
|
void *xlib_display() const;
|
||||||
|
void *createVisualInfoForDefaultVisualId() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(XCB_USE_XINPUT2)
|
#if defined(XCB_USE_XINPUT2)
|
||||||
@ -564,6 +569,7 @@ private:
|
|||||||
xcb_connection_t *m_connection;
|
xcb_connection_t *m_connection;
|
||||||
const xcb_setup_t *m_setup;
|
const xcb_setup_t *m_setup;
|
||||||
bool m_canGrabServer;
|
bool m_canGrabServer;
|
||||||
|
xcb_visualid_t m_defaultVisualId;
|
||||||
|
|
||||||
QList<QXcbVirtualDesktop *> m_virtualDesktops;
|
QList<QXcbVirtualDesktop *> m_virtualDesktops;
|
||||||
QList<QXcbScreen *> m_screens;
|
QList<QXcbScreen *> m_screens;
|
||||||
@ -632,6 +638,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
|
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
|
||||||
|
#define CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(object) ((XVisualInfo *)(object->connection()->createVisualInfoForDefaultVisualId()))
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
|
xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
|
||||||
|
@ -116,6 +116,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
|||||||
: m_services(new QGenericUnixServices)
|
: m_services(new QGenericUnixServices)
|
||||||
, m_instanceName(0)
|
, m_instanceName(0)
|
||||||
, m_canGrab(true)
|
, m_canGrab(true)
|
||||||
|
, m_defaultVisualId(UINT_MAX)
|
||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
|
||||||
@ -143,6 +144,12 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
|||||||
noGrabArg = true;
|
noGrabArg = true;
|
||||||
else if (arg == "-dograb")
|
else if (arg == "-dograb")
|
||||||
doGrabArg = true;
|
doGrabArg = true;
|
||||||
|
else if (arg == "-visual" && i < argc - 1) {
|
||||||
|
bool ok = false;
|
||||||
|
m_defaultVisualId = QByteArray(argv[++i]).toUInt(&ok, 0);
|
||||||
|
if (!ok)
|
||||||
|
m_defaultVisualId = UINT_MAX;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
argv[j++] = argv[i];
|
argv[j++] = argv[i];
|
||||||
}
|
}
|
||||||
@ -167,12 +174,12 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
|||||||
if (canNotGrabEnv)
|
if (canNotGrabEnv)
|
||||||
m_canGrab = false;
|
m_canGrab = false;
|
||||||
|
|
||||||
m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, displayName);
|
m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
|
||||||
|
|
||||||
for (int i = 0; i < parameters.size() - 1; i += 2) {
|
for (int i = 0; i < parameters.size() - 1; i += 2) {
|
||||||
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
|
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
|
||||||
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
|
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
|
||||||
m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, display.toLatin1().constData());
|
m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#include "qxcbexport.h"
|
#include "qxcbexport.h"
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QXcbConnection;
|
class QXcbConnection;
|
||||||
@ -123,6 +125,7 @@ private:
|
|||||||
mutable QByteArray m_wmClass;
|
mutable QByteArray m_wmClass;
|
||||||
const char *m_instanceName;
|
const char *m_instanceName;
|
||||||
bool m_canGrab;
|
bool m_canGrab;
|
||||||
|
xcb_visualid_t m_defaultVisualId;
|
||||||
|
|
||||||
static QXcbIntegration *m_instance;
|
static QXcbIntegration *m_instance;
|
||||||
};
|
};
|
||||||
|
@ -392,6 +392,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio
|
|||||||
if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) {
|
if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) {
|
||||||
return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic);
|
return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic);
|
||||||
}
|
}
|
||||||
|
if (function == QXcbWindowFunctions::visualIdIdentifier()) {
|
||||||
|
return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic));
|
||||||
|
}
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,16 @@ void QXcbWindow::create()
|
|||||||
m_window = platformScreen->root();
|
m_window = platformScreen->root();
|
||||||
m_depth = platformScreen->screen()->root_depth;
|
m_depth = platformScreen->screen()->root_depth;
|
||||||
m_visualId = platformScreen->screen()->root_visual;
|
m_visualId = platformScreen->screen()->root_visual;
|
||||||
const xcb_visualtype_t *visual = platformScreen->visualForId(m_visualId);
|
const xcb_visualtype_t *visual = 0;
|
||||||
|
if (connection()->hasDefaultVisualId()) {
|
||||||
|
visual = platformScreen->visualForId(connection()->defaultVisualId());
|
||||||
|
if (visual)
|
||||||
|
m_visualId = connection()->defaultVisualId();
|
||||||
|
if (!visual)
|
||||||
|
qWarning() << "Could not use default visual id. Falling back to root_visual for screen.";
|
||||||
|
}
|
||||||
|
if (!visual)
|
||||||
|
visual = platformScreen->visualForId(m_visualId);
|
||||||
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
|
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
|
||||||
connection()->addWindowEventListener(m_window, this);
|
connection()->addWindowEventListener(m_window, this);
|
||||||
return;
|
return;
|
||||||
@ -442,7 +451,12 @@ void QXcbWindow::create()
|
|||||||
|
|
||||||
#ifdef XCB_USE_XLIB
|
#ifdef XCB_USE_XLIB
|
||||||
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
|
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
|
||||||
XVisualInfo *visualInfo = static_cast<XVisualInfo *>(createVisual());
|
XVisualInfo *visualInfo = Q_NULLPTR;
|
||||||
|
if (connection()->hasDefaultVisualId())
|
||||||
|
visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this);
|
||||||
|
if (!visualInfo)
|
||||||
|
visualInfo = static_cast<XVisualInfo *>(createVisual());
|
||||||
|
|
||||||
if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
|
if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
|
||||||
qFatal("Could not initialize OpenGL");
|
qFatal("Could not initialize OpenGL");
|
||||||
|
|
||||||
@ -477,35 +491,49 @@ void QXcbWindow::create()
|
|||||||
if (!m_window)
|
if (!m_window)
|
||||||
{
|
{
|
||||||
m_window = xcb_generate_id(xcb_connection());
|
m_window = xcb_generate_id(xcb_connection());
|
||||||
m_visualId = platformScreen->screen()->root_visual;
|
m_visualId = UINT_MAX;
|
||||||
|
const xcb_visualtype_t *visual = Q_NULLPTR;
|
||||||
m_depth = platformScreen->screen()->root_depth;
|
m_depth = platformScreen->screen()->root_depth;
|
||||||
|
|
||||||
uint32_t mask = 0;
|
uint32_t mask = 0;
|
||||||
uint32_t values[3];
|
uint32_t values[3];
|
||||||
|
|
||||||
if (m_format.alphaBufferSize() == 8) {
|
if (connection()->hasDefaultVisualId()) {
|
||||||
xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
|
m_visualId = connection()->defaultVisualId();
|
||||||
while (depthIter.rem) {
|
visual = platformScreen->visualForId(m_visualId);
|
||||||
if (depthIter.data->depth == 32) {
|
}
|
||||||
xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
|
|
||||||
if (visualIter.rem) {
|
if (!visual) {
|
||||||
m_visualId = visualIter.data->visual_id;
|
if (connection()->hasDefaultVisualId())
|
||||||
m_depth = 32;
|
qWarning("Failed to use default visual id. Falling back to using screens root_visual");
|
||||||
uint32_t colormap = xcb_generate_id(xcb_connection());
|
|
||||||
xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
|
m_visualId = platformScreen->screen()->root_visual;
|
||||||
xcb_parent_id, m_visualId);
|
|
||||||
mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
|
if (m_format.alphaBufferSize() == 8) {
|
||||||
values[0] = platformScreen->screen()->white_pixel;
|
xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
|
||||||
values[1] = platformScreen->screen()->black_pixel;
|
while (depthIter.rem) {
|
||||||
values[2] = colormap;
|
if (depthIter.data->depth == 32) {
|
||||||
break;
|
xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
|
||||||
}
|
if (visualIter.rem) {
|
||||||
}
|
m_visualId = visualIter.data->visual_id;
|
||||||
xcb_depth_next(&depthIter);
|
m_depth = 32;
|
||||||
}
|
uint32_t colormap = xcb_generate_id(xcb_connection());
|
||||||
|
xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
|
||||||
|
xcb_parent_id, m_visualId);
|
||||||
|
mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
|
||||||
|
values[0] = platformScreen->screen()->white_pixel;
|
||||||
|
values[1] = platformScreen->screen()->black_pixel;
|
||||||
|
values[2] = colormap;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xcb_depth_next(&depthIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visual = platformScreen->visualForId(m_visualId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const xcb_visualtype_t *visual = platformScreen->visualForId(m_visualId);
|
|
||||||
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
|
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
|
||||||
const QRect xRect = mapToNative(rect, platformScreen);
|
const QRect xRect = mapToNative(rect, platformScreen);
|
||||||
|
|
||||||
@ -1680,6 +1708,13 @@ void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmW
|
|||||||
window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes)));
|
window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint QXcbWindow::visualIdStatic(QWindow *window)
|
||||||
|
{
|
||||||
|
if (window && window->handle())
|
||||||
|
return static_cast<QXcbWindow *>(window->handle())->visualId();
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
|
QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
|
||||||
{
|
{
|
||||||
QXcbWindowFunctions::WmWindowTypes result(0);
|
QXcbWindowFunctions::WmWindowTypes result(0);
|
||||||
@ -2531,6 +2566,11 @@ void QXcbWindow::setAlertState(bool enabled)
|
|||||||
changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
|
changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint QXcbWindow::visualId() const
|
||||||
|
{
|
||||||
|
return m_visualId;
|
||||||
|
}
|
||||||
|
|
||||||
bool QXcbWindow::needsSync() const
|
bool QXcbWindow::needsSync() const
|
||||||
{
|
{
|
||||||
return m_syncState == SyncAndConfigureReceived;
|
return m_syncState == SyncAndConfigureReceived;
|
||||||
|
@ -139,10 +139,13 @@ public:
|
|||||||
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
||||||
|
|
||||||
static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes);
|
static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes);
|
||||||
|
static uint visualIdStatic(QWindow *window);
|
||||||
|
|
||||||
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
|
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
|
||||||
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types);
|
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types);
|
||||||
|
|
||||||
|
uint visualId() const;
|
||||||
|
|
||||||
bool needsSync() const;
|
bool needsSync() const;
|
||||||
|
|
||||||
void postSyncWindowRequest();
|
void postSyncWindowRequest();
|
||||||
|
Loading…
Reference in New Issue
Block a user