summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm193
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.h3
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm10
4 files changed, 24 insertions, 194 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index f63ac0d205..93476ee1b4 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -93,6 +93,7 @@
#include <QtGui/qwindowdefs.h>
#include <QtCore/private/qabstracteventdispatcher_p.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
+#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
#include <CoreFoundation/CoreFoundation.h>
@@ -132,16 +133,9 @@ public:
void wakeUp();
void interrupt();
void flush();
-};
-struct MacSocketInfo {
- MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {}
- CFSocketRef socket;
- CFRunLoopSourceRef runloop;
- QObject *readNotifier;
- QObject *writeNotifier;
+ friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher);
};
-typedef QHash<int, MacSocketInfo *> MacSocketHash;
class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate
{
@@ -183,7 +177,7 @@ public:
void maybeCancelWaitForMoreEvents();
void ensureNSAppInitialized();
- MacSocketHash macSockets;
+ QCFSocketNotifier cfSocketNotifier;
QList<void *> queuedUserInputEvents; // NSEvent *
CFRunLoopSourceRef postedEventsSource;
CFRunLoopObserverRef waitingObserver;
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 987600c6b4..ed4f8cd1fb 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -270,58 +270,6 @@ QCocoaEventDispatcher::registeredTimers(QObject *object) const
return d->timerInfoList.registeredTimers(object);
}
-/**************************************************************************
- Socket Notifiers
- *************************************************************************/
-void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
- const void *, void *info) {
- QCocoaEventDispatcherPrivate *const eventDispatcher
- = static_cast<QCocoaEventDispatcherPrivate *>(info);
- int nativeSocket = CFSocketGetNative(s);
- MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket);
- QEvent notifierEvent(QEvent::SockAct);
-
- // There is a race condition that happen where we disable the notifier and
- // the kernel still has a notification to pass on. We then get this
- // notification after we've successfully disabled the CFSocket, but our Qt
- // notifier is now gone. The upshot is we have to check the notifier
- // everytime.
- if (callbackType == kCFSocketReadCallBack) {
- if (socketInfo->readNotifier)
- QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
- } else if (callbackType == kCFSocketWriteCallBack) {
- if (socketInfo->writeNotifier)
- QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
- }
-
- eventDispatcher->maybeCancelWaitForMoreEvents();
-}
-
-/*
- Adds a loop source for the given socket to the current run loop.
-*/
-CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
-{
- CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
- if (!loopSource)
- return 0;
-
- CFRunLoopAddSource(mainRunLoop(), loopSource, kCFRunLoopCommonModes);
- return loopSource;
-}
-
-/*
- Removes the loop source for the given socket from the current run loop.
-*/
-void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop)
-{
- Q_ASSERT(runloop);
- CFRunLoopRemoveSource(mainRunLoop(), runloop, kCFRunLoopCommonModes);
- CFSocketDisableCallBacks(socket, kCFSocketReadCallBack);
- CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
- CFRunLoopSourceInvalidate(runloop);
-}
-
/*
Register a QSocketNotifier with the mac event system by creating a CFSocket with
with a read/write callback.
@@ -331,130 +279,14 @@ void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSource
*/
void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
{
- Q_ASSERT(notifier);
- int nativeSocket = notifier->socket();
- int type = notifier->type();
-#ifndef QT_NO_DEBUG
- if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
- qWarning("QSocketNotifier: Internal error");
- return;
- } else if (notifier->thread() != thread()
- || thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
- return;
- }
-#endif
-
Q_D(QCocoaEventDispatcher);
-
- if (type == QSocketNotifier::Exception) {
- qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
- return;
- }
-
- // Check if we have a CFSocket for the native socket, create one if not.
- MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
- if (!socketInfo) {
- socketInfo = new MacSocketInfo();
-
- // Create CFSocket, specify that we want both read and write callbacks (the callbacks
- // are enabled/disabled later on).
- const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack;
- CFSocketContext context = {0, d, 0, 0, 0};
- socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context);
- if (CFSocketIsValid(socketInfo->socket) == false) {
- qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket");
- return;
- }
-
- CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket);
- flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write
- flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation
- CFSocketSetSocketFlags(socketInfo->socket, flags);
-
- // Add CFSocket to runloop.
- if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) {
- qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop");
- CFSocketInvalidate(socketInfo->socket);
- CFRelease(socketInfo->socket);
- return;
- }
-
- // Disable both callback types by default. This must be done after
- // we add the CFSocket to the runloop, or else these calls will have
- // no effect.
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
-
- d->macSockets.insert(nativeSocket, socketInfo);
- }
-
- // Increment read/write counters and select enable callbacks if necessary.
- if (type == QSocketNotifier::Read) {
- Q_ASSERT(socketInfo->readNotifier == 0);
- socketInfo->readNotifier = notifier;
- CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- } else if (type == QSocketNotifier::Write) {
- Q_ASSERT(socketInfo->writeNotifier == 0);
- socketInfo->writeNotifier = notifier;
- CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
+ d->cfSocketNotifier.registerSocketNotifier(notifier);
}
-/*
- Unregister QSocketNotifer. The CFSocket correspoding to this notifier is
- removed from the runloop of this is the last notifier that users
- that CFSocket.
-*/
void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
{
- Q_ASSERT(notifier);
- int nativeSocket = notifier->socket();
- int type = notifier->type();
-#ifndef QT_NO_DEBUG
- if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
- qWarning("QSocketNotifier: Internal error");
- return;
- } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
- return;
- }
-#endif
-
Q_D(QCocoaEventDispatcher);
-
- if (type == QSocketNotifier::Exception) {
- qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
- return;
- }
- MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
- if (!socketInfo) {
- qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier");
- return;
- }
-
- // Decrement read/write counters and disable callbacks if necessary.
- if (type == QSocketNotifier::Read) {
- Q_ASSERT(notifier == socketInfo->readNotifier);
- socketInfo->readNotifier = 0;
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- } else if (type == QSocketNotifier::Write) {
- Q_ASSERT(notifier == socketInfo->writeNotifier);
- socketInfo->writeNotifier = 0;
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
-
- // Remove CFSocket from runloop if this was the last QSocketNotifier.
- if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) {
- if (CFSocketIsValid(socketInfo->socket))
- qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
- CFRunLoopSourceInvalidate(socketInfo->runloop);
- CFRelease(socketInfo->runloop);
- CFSocketInvalidate(socketInfo->socket);
- CFRelease(socketInfo->socket);
- delete socketInfo;
- d->macSockets.remove(nativeSocket);
- }
+ d->cfSocketNotifier.unregisterSocketNotifier(notifier);
}
bool QCocoaEventDispatcher::hasPendingEvents()
@@ -940,11 +772,19 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
{
}
+void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher)
+{
+ static_cast<QCocoaEventDispatcher *>(eventDispatcher)->d_func()->maybeCancelWaitForMoreEvents();
+}
+
QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent)
: QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent)
{
Q_D(QCocoaEventDispatcher);
+ d->cfSocketNotifier.setHostEventDispatcher(this);
+ d->cfSocketNotifier.setMaybeCancelWaitForMoreEventsCallback(qt_mac_maybeCancelWaitForMoreEventsForwarder);
+
// keep our sources running when modal loops are running
CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode);
@@ -1127,17 +967,8 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher()
[nsevent release];
}
- // Remove CFSockets from the runloop.
- for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) {
- MacSocketInfo *socketInfo = (*it);
- if (CFSocketIsValid(socketInfo->socket)) {
- qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
- CFRunLoopSourceInvalidate(socketInfo->runloop);
- CFRelease(socketInfo->runloop);
- CFSocketInvalidate(socketInfo->socket);
- CFRelease(socketInfo->socket);
- }
- }
+ d->cfSocketNotifier.removeSocketNotifiers();
+
CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);
CFRelease(d->postedEventsSource);
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h
index 88d5127855..53a75618ce 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.h
+++ b/src/plugins/platforms/ios/qioseventdispatcher.h
@@ -78,6 +78,7 @@
#include <QtCore/qabstracteventdispatcher.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
+#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
#include <CoreFoundation/CoreFoundation.h>
QT_BEGIN_NAMESPACE
@@ -116,6 +117,8 @@ private:
QTimerInfoList m_timerInfoList;
CFRunLoopTimerRef m_runLoopTimerRef;
+ QCFSocketNotifier m_cfSocketNotifier;
+
void processPostedEvents();
void maybeStartCFRunLoopTimer();
void maybeStopCFRunLoopTimer();
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index f6f60387d4..e9bf039047 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -155,6 +155,8 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
, m_interrupted(false)
, m_runLoopTimerRef(0)
{
+ m_cfSocketNotifier.setHostEventDispatcher(this);
+
CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
CFRunLoopSourceContext context;
bzero(&context, sizeof(CFRunLoopSourceContext));
@@ -184,6 +186,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher()
maybeStopCFRunLoopTimer();
CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
CFRelease(m_blockingTimerRunLoopSource);
+
+ m_cfSocketNotifier.removeSocketNotifiers();
}
bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
@@ -215,14 +219,12 @@ bool QIOSEventDispatcher::hasPendingEvents()
void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
{
- qDebug() << __FUNCTION__ << "not implemented";
- Q_UNUSED(notifier);
+ m_cfSocketNotifier.registerSocketNotifier(notifier);
}
void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
{
- qDebug() << __FUNCTION__ << "not implemented";
- Q_UNUSED(notifier);
+ m_cfSocketNotifier.unregisterSocketNotifier(notifier);
}
void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)