XCB: Do not create instance of QPlatformIntegration for invalid displays
Extract a static factory for QXcbConnection objects and pass potential connection errors to qxcbmain.cpp, which will then return 0. Task-number: QTBUG-68859 Change-Id: I9c0faf82462a78a576360c19bef251ad1d034d84 Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
parent
cdccd0222b
commit
67cc8fea10
@ -544,31 +544,59 @@ void QXcbConnection::initializeScreens()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
|
QXcbConnection *QXcbConnection::create(QXcbNativeInterface *nativeInterface, bool canGrabServer,
|
||||||
: m_canGrabServer(canGrabServer)
|
xcb_visualid_t defaultVisualId,
|
||||||
, m_defaultVisualId(defaultVisualId)
|
const char *displayNameIn)
|
||||||
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
|
|
||||||
, m_nativeInterface(nativeInterface)
|
|
||||||
{
|
{
|
||||||
|
const QByteArray displayName = displayNameIn ? QByteArray(displayNameIn) : qgetenv("DISPLAY");
|
||||||
|
int primaryScreenNumber = 0;
|
||||||
|
void *xlibDisplay = nullptr;
|
||||||
|
xcb_connection_t *connection = nullptr;
|
||||||
#if QT_CONFIG(xcb_xlib)
|
#if QT_CONFIG(xcb_xlib)
|
||||||
Display *dpy = XOpenDisplay(m_displayName.constData());
|
Display *dpy = XOpenDisplay(displayName.constData());
|
||||||
if (dpy) {
|
if (dpy) {
|
||||||
m_primaryScreenNumber = DefaultScreen(dpy);
|
primaryScreenNumber = DefaultScreen(dpy);
|
||||||
m_connection = XGetXCBConnection(dpy);
|
connection = XGetXCBConnection(dpy);
|
||||||
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
|
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
|
||||||
XSetErrorHandler(nullErrorHandler);
|
XSetErrorHandler(nullErrorHandler);
|
||||||
XSetIOErrorHandler(ioErrorHandler);
|
XSetIOErrorHandler(ioErrorHandler);
|
||||||
m_xlib_display = dpy;
|
xlibDisplay = dpy;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
|
connection = xcb_connect(displayName.constData(), &primaryScreenNumber);
|
||||||
#endif // QT_CONFIG(xcb_xlib)
|
#endif // QT_CONFIG(xcb_xlib)
|
||||||
|
if (Q_UNLIKELY(connection == nullptr)) {
|
||||||
if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) {
|
qWarning("QXcbConnection: Could not connect to display \"%s\"", displayName.constData());
|
||||||
qCWarning(lcQpaScreen, "QXcbConnection: Could not connect to display %s", m_displayName.constData());
|
return nullptr;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (Q_UNLIKELY(xcb_connection_has_error(connection))) {
|
||||||
|
#if QT_CONFIG(xcb_xlib)
|
||||||
|
XCloseDisplay(static_cast<Display *>(xlibDisplay));
|
||||||
|
#else
|
||||||
|
xcb_disconnect(connection);
|
||||||
|
#endif
|
||||||
|
qWarning("QXcbConnection: Errors occurred connecting to display \"%s\"", displayName.constData());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return new QXcbConnection(connection, primaryScreenNumber, nativeInterface,
|
||||||
|
canGrabServer, defaultVisualId, displayName, xlibDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QXcbConnection::QXcbConnection(xcb_connection_t *c, int primaryScreenNumber,
|
||||||
|
QXcbNativeInterface *nativeInterface, bool canGrabServer,
|
||||||
|
xcb_visualid_t defaultVisualId, const QByteArray &displayName,
|
||||||
|
void *xlibDisplay)
|
||||||
|
: m_connection(c)
|
||||||
|
, m_canGrabServer(canGrabServer)
|
||||||
|
, m_defaultVisualId(defaultVisualId)
|
||||||
|
, m_primaryScreenNumber(primaryScreenNumber)
|
||||||
|
, m_displayName(displayName)
|
||||||
|
, m_nativeInterface(nativeInterface)
|
||||||
|
#if QT_CONFIG(xcb_xlib)
|
||||||
|
, m_xlib_display(xlibDisplay)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
m_reader = new QXcbEventReader(this);
|
m_reader = new QXcbEventReader(this);
|
||||||
m_reader->start();
|
m_reader->start();
|
||||||
|
|
||||||
|
@ -377,9 +377,16 @@ class Q_XCB_EXPORT QXcbConnection : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0);
|
explicit QXcbConnection(xcb_connection_t *c, int primaryScreenNumber,
|
||||||
|
QXcbNativeInterface *nativeInterface, bool canGrabServer,
|
||||||
|
xcb_visualid_t defaultVisualId, const QByteArray &displayName,
|
||||||
|
void *xlibDisplay = nullptr);
|
||||||
|
|
||||||
~QXcbConnection();
|
~QXcbConnection();
|
||||||
|
|
||||||
|
static QXcbConnection *create(QXcbNativeInterface *nativeInterface, bool canGrabServer,
|
||||||
|
xcb_visualid_t defaultVisualId, const char *displayName = nullptr);
|
||||||
|
|
||||||
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
|
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
|
|
||||||
@ -639,21 +646,21 @@ private:
|
|||||||
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
|
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xcb_connection_t *m_connection = nullptr;
|
xcb_connection_t *const m_connection;
|
||||||
const xcb_setup_t *m_setup = nullptr;
|
const xcb_setup_t *m_setup = nullptr;
|
||||||
const bool m_canGrabServer;
|
const bool m_canGrabServer;
|
||||||
const xcb_visualid_t m_defaultVisualId;
|
const xcb_visualid_t m_defaultVisualId;
|
||||||
|
|
||||||
QList<QXcbVirtualDesktop *> m_virtualDesktops;
|
QList<QXcbVirtualDesktop *> m_virtualDesktops;
|
||||||
QList<QXcbScreen *> m_screens;
|
QList<QXcbScreen *> m_screens;
|
||||||
int m_primaryScreenNumber = 0;
|
const int m_primaryScreenNumber;
|
||||||
|
|
||||||
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
|
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
|
||||||
|
|
||||||
xcb_timestamp_t m_time = XCB_CURRENT_TIME;
|
xcb_timestamp_t m_time = XCB_CURRENT_TIME;
|
||||||
xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
|
xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
|
||||||
|
|
||||||
QByteArray m_displayName;
|
const QByteArray m_displayName;
|
||||||
|
|
||||||
QXcbKeyboard *m_keyboard = nullptr;
|
QXcbKeyboard *m_keyboard = nullptr;
|
||||||
#ifndef QT_NO_CLIPBOARD
|
#ifndef QT_NO_CLIPBOARD
|
||||||
@ -666,7 +673,7 @@ private:
|
|||||||
QXcbNativeInterface *m_nativeInterface = nullptr;
|
QXcbNativeInterface *m_nativeInterface = nullptr;
|
||||||
|
|
||||||
#if QT_CONFIG(xcb_xlib)
|
#if QT_CONFIG(xcb_xlib)
|
||||||
void *m_xlib_display = nullptr;
|
void *const m_xlib_display;
|
||||||
#endif
|
#endif
|
||||||
QXcbEventReader *m_reader = nullptr;
|
QXcbEventReader *m_reader = nullptr;
|
||||||
|
|
||||||
|
@ -192,25 +192,15 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
|||||||
|
|
||||||
const int numParameters = parameters.size();
|
const int numParameters = parameters.size();
|
||||||
m_connections.reserve(1 + numParameters / 2);
|
m_connections.reserve(1 + numParameters / 2);
|
||||||
auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
|
|
||||||
if (conn->isConnected())
|
|
||||||
m_connections << conn;
|
|
||||||
else
|
|
||||||
delete conn;
|
|
||||||
|
|
||||||
for (int i = 0; i < numParameters - 1; i += 2) {
|
if (QXcbConnection *defaultConnection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName)) {
|
||||||
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
|
m_connections.append(defaultConnection);
|
||||||
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
|
for (int i = 0; i < numParameters - 1; i += 2) {
|
||||||
conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
|
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
|
||||||
if (conn->isConnected())
|
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
|
||||||
m_connections << conn;
|
if (QXcbConnection *connection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()))
|
||||||
else
|
m_connections.append(connection);
|
||||||
delete conn;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (m_connections.isEmpty()) {
|
|
||||||
qCritical("Could not connect to any X display.");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
||||||
|
@ -103,6 +103,7 @@ public:
|
|||||||
QPlatformTheme *createPlatformTheme(const QString &name) const override;
|
QPlatformTheme *createPlatformTheme(const QString &name) const override;
|
||||||
QVariant styleHint(StyleHint hint) const override;
|
QVariant styleHint(StyleHint hint) const override;
|
||||||
|
|
||||||
|
bool hasDefaultConnection() const { return !m_connections.isEmpty(); }
|
||||||
QXcbConnection *defaultConnection() const { return m_connections.first(); }
|
QXcbConnection *defaultConnection() const { return m_connections.first(); }
|
||||||
|
|
||||||
QByteArray wmClass() const;
|
QByteArray wmClass() const;
|
||||||
|
@ -52,10 +52,16 @@ public:
|
|||||||
|
|
||||||
QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv)
|
QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv)
|
||||||
{
|
{
|
||||||
if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive))
|
if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) {
|
||||||
return new QXcbIntegration(parameters, argc, argv);
|
QXcbIntegration *xcbIntegration = new QXcbIntegration(parameters, argc, argv);
|
||||||
|
if (!xcbIntegration->hasDefaultConnection()) {
|
||||||
|
delete xcbIntegration;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return xcbIntegration;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
Reference in New Issue
Block a user