summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-02-19 11:07:43 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-08-20 16:52:29 +0000
commit67cc8fea106c35c7ca75bf476667d07b3bbf3257 (patch)
tree79d66af5c48d0f3cb2760c109aa2a739c9b76c20
parentcdccd0222bbed1954d5d7fe0da9d2308c202f3b1 (diff)
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>
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp58
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h17
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp26
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbmain.cpp12
5 files changed, 73 insertions, 41 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index c14f3f3703..6fe1a121d8 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -544,31 +544,59 @@ void QXcbConnection::initializeScreens()
}
}
-QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
- : m_canGrabServer(canGrabServer)
- , m_defaultVisualId(defaultVisualId)
- , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
- , m_nativeInterface(nativeInterface)
-{
+QXcbConnection *QXcbConnection::create(QXcbNativeInterface *nativeInterface, bool canGrabServer,
+ xcb_visualid_t defaultVisualId,
+ const char *displayNameIn)
+{
+ const QByteArray displayName = displayNameIn ? QByteArray(displayNameIn) : qgetenv("DISPLAY");
+ int primaryScreenNumber = 0;
+ void *xlibDisplay = nullptr;
+ xcb_connection_t *connection = nullptr;
#if QT_CONFIG(xcb_xlib)
- Display *dpy = XOpenDisplay(m_displayName.constData());
+ Display *dpy = XOpenDisplay(displayName.constData());
if (dpy) {
- m_primaryScreenNumber = DefaultScreen(dpy);
- m_connection = XGetXCBConnection(dpy);
+ primaryScreenNumber = DefaultScreen(dpy);
+ connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
XSetErrorHandler(nullErrorHandler);
XSetIOErrorHandler(ioErrorHandler);
- m_xlib_display = dpy;
+ xlibDisplay = dpy;
}
#else
- m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
+ connection = xcb_connect(displayName.constData(), &primaryScreenNumber);
#endif // QT_CONFIG(xcb_xlib)
-
- if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) {
- qCWarning(lcQpaScreen, "QXcbConnection: Could not connect to display %s", m_displayName.constData());
- return;
+ if (Q_UNLIKELY(connection == nullptr)) {
+ qWarning("QXcbConnection: Could not connect to display \"%s\"", displayName.constData());
+ return nullptr;
+ }
+ 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->start();
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 0b31e9c3e7..c88100e580 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -377,9 +377,16 @@ class Q_XCB_EXPORT QXcbConnection : public QObject
{
Q_OBJECT
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();
+ static QXcbConnection *create(QXcbNativeInterface *nativeInterface, bool canGrabServer,
+ xcb_visualid_t defaultVisualId, const char *displayName = nullptr);
+
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
bool isConnected() const;
@@ -639,21 +646,21 @@ private:
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
#endif
- xcb_connection_t *m_connection = nullptr;
+ xcb_connection_t *const m_connection;
const xcb_setup_t *m_setup = nullptr;
const bool m_canGrabServer;
const xcb_visualid_t m_defaultVisualId;
QList<QXcbVirtualDesktop *> m_virtualDesktops;
QList<QXcbScreen *> m_screens;
- int m_primaryScreenNumber = 0;
+ const int m_primaryScreenNumber;
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
xcb_timestamp_t m_time = XCB_CURRENT_TIME;
xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
- QByteArray m_displayName;
+ const QByteArray m_displayName;
QXcbKeyboard *m_keyboard = nullptr;
#ifndef QT_NO_CLIPBOARD
@@ -666,7 +673,7 @@ private:
QXcbNativeInterface *m_nativeInterface = nullptr;
#if QT_CONFIG(xcb_xlib)
- void *m_xlib_display = nullptr;
+ void *const m_xlib_display;
#endif
QXcbEventReader *m_reader = nullptr;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index e9b36c48b8..1ac5445035 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -192,25 +192,15 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
const int numParameters = parameters.size();
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) {
- qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
- QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
- conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
- if (conn->isConnected())
- m_connections << conn;
- else
- delete conn;
- }
- if (m_connections.isEmpty()) {
- qCritical("Could not connect to any X display.");
- exit(1);
+ if (QXcbConnection *defaultConnection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName)) {
+ m_connections.append(defaultConnection);
+ for (int i = 0; i < numParameters - 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);
+ if (QXcbConnection *connection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()))
+ m_connections.append(connection);
+ }
}
m_fontDatabase.reset(new QGenericUnixFontDatabase());
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 69e49cb7f6..a2de22d53d 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -103,6 +103,7 @@ public:
QPlatformTheme *createPlatformTheme(const QString &name) const override;
QVariant styleHint(StyleHint hint) const override;
+ bool hasDefaultConnection() const { return !m_connections.isEmpty(); }
QXcbConnection *defaultConnection() const { return m_connections.first(); }
QByteArray wmClass() const;
diff --git a/src/plugins/platforms/xcb/qxcbmain.cpp b/src/plugins/platforms/xcb/qxcbmain.cpp
index f8cb9a9269..539d033ca9 100644
--- a/src/plugins/platforms/xcb/qxcbmain.cpp
+++ b/src/plugins/platforms/xcb/qxcbmain.cpp
@@ -52,10 +52,16 @@ public:
QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv)
{
- if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive))
- return new QXcbIntegration(parameters, argc, argv);
+ if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) {
+ QXcbIntegration *xcbIntegration = new QXcbIntegration(parameters, argc, argv);
+ if (!xcbIntegration->hasDefaultConnection()) {
+ delete xcbIntegration;
+ return nullptr;
+ }
+ return xcbIntegration;
+ }
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE