diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index e35954caf9..266491d5d9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -58,6 +58,7 @@ #include <QTimer> #include <QByteArray> +#include <dlfcn.h> #include <stdio.h> #include <errno.h> #include <xcb/shm.h> @@ -281,18 +282,16 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData()); m_reader = new QXcbEventReader(this); -#ifdef XCB_POLL_FOR_QUEUED_EVENT connect(m_reader, SIGNAL(eventPending()), this, SLOT(processXcbEvents()), Qt::QueuedConnection); connect(m_reader, SIGNAL(finished()), this, SLOT(processXcbEvents())); - m_reader->start(); -#else - QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents())); + if (!m_reader->startThread()) { + QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents())); - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; - connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents())); - connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents())); -#endif + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; + connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents())); + connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents())); + } xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, @@ -364,10 +363,11 @@ QXcbConnection::~QXcbConnection() finalizeXInput2(); #endif -#ifdef XCB_POLL_FOR_QUEUED_EVENT - sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION); - m_reader->wait(); -#endif + if (m_reader->isRunning()) { + sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION); + m_reader->wait(); + } + delete m_reader; #ifdef XCB_USE_EGL @@ -808,14 +808,37 @@ void QXcbConnection::addPeekFunc(PeekFunc f) m_peekFuncs.append(f); } -#ifdef XCB_POLL_FOR_QUEUED_EVENT +QXcbEventReader::QXcbEventReader(QXcbConnection *connection) + : m_connection(connection) + , m_xcb_poll_for_queued_event(0) +{ +#ifdef RTLD_DEFAULT + m_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event"); +#endif + +#ifdef Q_XCB_DEBUG + if (m_xcb_poll_for_queued_event) + qDebug("Using threaded event reader with xcb_poll_for_queued_event"); +#endif +} + +bool QXcbEventReader::startThread() +{ + if (m_xcb_poll_for_queued_event) { + QThread::start(); + return true; + } + + return false; +} + void QXcbEventReader::run() { xcb_generic_event_t *event; while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) { m_mutex.lock(); addEvent(event); - while (m_connection && (event = xcb_poll_for_queued_event(m_connection->xcb_connection()))) + while (m_connection && (event = m_xcb_poll_for_queued_event(m_connection->xcb_connection()))) addEvent(event); m_mutex.unlock(); emit eventPending(); @@ -824,7 +847,6 @@ void QXcbEventReader::run() for (int i = 0; i < m_events.size(); ++i) free(m_events.at(i)); } -#endif void QXcbEventReader::addEvent(xcb_generic_event_t *event) { @@ -837,10 +859,10 @@ void QXcbEventReader::addEvent(xcb_generic_event_t *event) QXcbEventArray *QXcbEventReader::lock() { m_mutex.lock(); -#ifndef XCB_POLL_FOR_QUEUED_EVENT - while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection())) - m_events << event; -#endif + if (!m_xcb_poll_for_queued_event) { + while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection())) + m_events << event; + } return &m_events; } |