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)
|
||||
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-xcb.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#if defined(XCB_USE_XINPUT2)
|
||||
@ -437,9 +438,10 @@ void QXcbConnection::initializeScreens()
|
||||
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_canGrabServer(canGrabServer)
|
||||
, m_defaultVisualId(defaultVisualId)
|
||||
, m_primaryScreenNumber(0)
|
||||
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
||||
, m_nativeInterface(nativeInterface)
|
||||
@ -1351,6 +1353,21 @@ void *QXcbConnection::xlib_display() const
|
||||
{
|
||||
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
|
||||
|
||||
void QXcbConnection::processXcbEvents()
|
||||
|
@ -370,7 +370,7 @@ class Q_XCB_EXPORT QXcbConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
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 *connection() const { return const_cast<QXcbConnection *>(this); }
|
||||
@ -400,8 +400,13 @@ public:
|
||||
|
||||
QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
|
||||
xcb_window_t rootWindow();
|
||||
|
||||
bool hasDefaultVisualId() const { return m_defaultVisualId != UINT_MAX; }
|
||||
xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; }
|
||||
|
||||
#ifdef XCB_USE_XLIB
|
||||
void *xlib_display() const;
|
||||
void *createVisualInfoForDefaultVisualId() const;
|
||||
#endif
|
||||
|
||||
#if defined(XCB_USE_XINPUT2)
|
||||
@ -564,6 +569,7 @@ private:
|
||||
xcb_connection_t *m_connection;
|
||||
const xcb_setup_t *m_setup;
|
||||
bool m_canGrabServer;
|
||||
xcb_visualid_t m_defaultVisualId;
|
||||
|
||||
QList<QXcbVirtualDesktop *> m_virtualDesktops;
|
||||
QList<QXcbScreen *> m_screens;
|
||||
@ -632,6 +638,7 @@ private:
|
||||
};
|
||||
|
||||
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
|
||||
#define CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(object) ((XVisualInfo *)(object->connection()->createVisualInfoForDefaultVisualId()))
|
||||
|
||||
template<typename T>
|
||||
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_instanceName(0)
|
||||
, m_canGrab(true)
|
||||
, m_defaultVisualId(UINT_MAX)
|
||||
{
|
||||
m_instance = this;
|
||||
|
||||
@ -143,6 +144,12 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
||||
noGrabArg = true;
|
||||
else if (arg == "-dograb")
|
||||
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
|
||||
argv[j++] = argv[i];
|
||||
}
|
||||
@ -167,12 +174,12 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
||||
if (canNotGrabEnv)
|
||||
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) {
|
||||
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << 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());
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include "qxcbexport.h"
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QXcbConnection;
|
||||
@ -123,6 +125,7 @@ private:
|
||||
mutable QByteArray m_wmClass;
|
||||
const char *m_instanceName;
|
||||
bool m_canGrab;
|
||||
xcb_visualid_t m_defaultVisualId;
|
||||
|
||||
static QXcbIntegration *m_instance;
|
||||
};
|
||||
|
@ -392,6 +392,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio
|
||||
if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) {
|
||||
return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic);
|
||||
}
|
||||
if (function == QXcbWindowFunctions::visualIdIdentifier()) {
|
||||
return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic));
|
||||
}
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,16 @@ void QXcbWindow::create()
|
||||
m_window = platformScreen->root();
|
||||
m_depth = platformScreen->screen()->root_depth;
|
||||
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);
|
||||
connection()->addWindowEventListener(m_window, this);
|
||||
return;
|
||||
@ -442,7 +451,12 @@ void QXcbWindow::create()
|
||||
|
||||
#ifdef XCB_USE_XLIB
|
||||
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)
|
||||
qFatal("Could not initialize OpenGL");
|
||||
|
||||
@ -477,35 +491,49 @@ void QXcbWindow::create()
|
||||
if (!m_window)
|
||||
{
|
||||
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;
|
||||
|
||||
uint32_t mask = 0;
|
||||
uint32_t values[3];
|
||||
|
||||
if (m_format.alphaBufferSize() == 8) {
|
||||
xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
|
||||
while (depthIter.rem) {
|
||||
if (depthIter.data->depth == 32) {
|
||||
xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
|
||||
if (visualIter.rem) {
|
||||
m_visualId = visualIter.data->visual_id;
|
||||
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);
|
||||
}
|
||||
if (connection()->hasDefaultVisualId()) {
|
||||
m_visualId = connection()->defaultVisualId();
|
||||
visual = platformScreen->visualForId(m_visualId);
|
||||
}
|
||||
|
||||
if (!visual) {
|
||||
if (connection()->hasDefaultVisualId())
|
||||
qWarning("Failed to use default visual id. Falling back to using screens root_visual");
|
||||
|
||||
m_visualId = platformScreen->screen()->root_visual;
|
||||
|
||||
if (m_format.alphaBufferSize() == 8) {
|
||||
xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
|
||||
while (depthIter.rem) {
|
||||
if (depthIter.data->depth == 32) {
|
||||
xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
|
||||
if (visualIter.rem) {
|
||||
m_visualId = visualIter.data->visual_id;
|
||||
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);
|
||||
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)));
|
||||
}
|
||||
|
||||
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 result(0);
|
||||
@ -2531,6 +2566,11 @@ void QXcbWindow::setAlertState(bool enabled)
|
||||
changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
|
||||
}
|
||||
|
||||
uint QXcbWindow::visualId() const
|
||||
{
|
||||
return m_visualId;
|
||||
}
|
||||
|
||||
bool QXcbWindow::needsSync() const
|
||||
{
|
||||
return m_syncState == SyncAndConfigureReceived;
|
||||
|
@ -139,10 +139,13 @@ public:
|
||||
void updateNetWmUserTime(xcb_timestamp_t timestamp);
|
||||
|
||||
static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes);
|
||||
static uint visualIdStatic(QWindow *window);
|
||||
|
||||
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
|
||||
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types);
|
||||
|
||||
uint visualId() const;
|
||||
|
||||
bool needsSync() const;
|
||||
|
||||
void postSyncWindowRequest();
|
||||
|
Loading…
Reference in New Issue
Block a user