Add support for platform plugin specific event filters.

The setEventFilter on the platform native interface allows subscribing to
events on the backend by event name.

Change-Id: Ib10077fbc69f0207edbae1177e7bbd18c8d0f9ae
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Reviewed-by: Michalina Ziemba <michalina.ziemba@nokia.com>
This commit is contained in:
Simon Hausmann 2012-01-18 15:16:09 +01:00 committed by Qt by Nokia
parent 8060dd3c42
commit 1ca05bb0c1
8 changed files with 147 additions and 69 deletions

View File

@ -106,4 +106,51 @@ void QPlatformNativeInterface::setWindowProperty(QPlatformWindow *window, const
Q_UNUSED(value);
}
/*!
\typedef QPlatformNativeInterface::EventFilter
\since 5.0
A function with the following signature that can be used as an
event filter:
\code
bool myEventFilter(void *message, long *result);
\endcode
\sa setEventFilter()
*/
/*!
\fn EventFilter QPlatformNativeInterface::setEventFilter(const QByteArray &eventType, EventFilter filter)
\since 5.0
Replaces the event filter function for the native interface with
\a filter and returns the pointer to the replaced event filter
function. Only the current event filter function is called. If you
want to use both filter functions, save the replaced EventFilter
in a place where you can call it from.
The event filter function set here is called for all messages
received from the platform if they are given type \eventType.
It is \i not called for messages that are not meant for Qt objects.
The type of event is specific to the platform plugin chosen at run-time.
The event filter function should return \c true if the message should
be filtered, (i.e. stopped). It should return \c false to allow
processing the message to continue.
By default, no event filter function is set. For example, this function
returns a null EventFilter the first time it is called.
\note The filter function here receives native messages,
for example, MSG or XEvent structs. It is called by the platform plugin.
*/
QPlatformNativeInterface::EventFilter QPlatformNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter)
{
Q_UNUSED(eventType);
Q_UNUSED(filter);
return 0;
}
QT_END_NAMESPACE

View File

@ -70,6 +70,9 @@ public:
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
virtual void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
typedef bool (*EventFilter)(void *message, long *result);
virtual EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter);
Q_SIGNALS:
void windowPropertyChanged(QPlatformWindow *window, const QString &propertyName);
};

View File

@ -49,11 +49,13 @@
#include "qxcbclipboard.h"
#include "qxcbdrag.h"
#include "qxcbwmsupport.h"
#include "qxcbnativeinterface.h"
#include <QtAlgorithms>
#include <QSocketNotifier>
#include <QAbstractEventDispatcher>
#include <QTimer>
#include <QByteArray>
#include <stdio.h>
#include <errno.h>
@ -93,9 +95,10 @@ static int nullErrorHandler(Display *, XErrorEvent *)
}
#endif
QXcbConnection::QXcbConnection(const char *displayName)
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName)
: m_connection(0)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
#ifdef XCB_USE_XINPUT2_MAEMO
, m_xinputData(0)
#endif
@ -493,10 +496,14 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
m_callLog.remove(0, i);
}
#endif
bool handled = true;
bool handled = false;
if (QPlatformNativeInterface::EventFilter filter = m_nativeInterface->eventFilterForEventType(QByteArrayLiteral("xcb_generic_event_t")))
handled = filter(event, 0);
uint response_type = event->response_type & ~0x80;
if (!handled) {
switch (response_type) {
case XCB_EXPOSE:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
@ -560,6 +567,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
handled = false;
break;
}
}
if (!handled) {
if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {

View File

@ -66,6 +66,7 @@ class QXcbDrag;
class QXcbKeyboard;
class QXcbClipboard;
class QXcbWMSupport;
class QXcbNativeInterface;
typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
@ -289,7 +290,7 @@ class QXcbConnection : public QObject
{
Q_OBJECT
public:
QXcbConnection(const char *displayName = 0);
QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0);
~QXcbConnection();
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
@ -390,6 +391,7 @@ private:
QXcbClipboard *m_clipboard;
QXcbDrag *m_drag;
QScopedPointer<QXcbWMSupport> m_wmSupport;
QXcbNativeInterface *m_nativeInterface;
#if defined(XCB_USE_XLIB)
void *m_xlib_display;

View File

@ -90,13 +90,14 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
#ifdef XCB_USE_XLIB
XInitThreads();
#endif
m_nativeInterface.reset(new QXcbNativeInterface);
m_connections << new QXcbConnection;
m_connections << new QXcbConnection(m_nativeInterface.data());
for (int i = 0; i < parameters.size() - 1; i += 2) {
qDebug() << parameters.at(i) << parameters.at(i+1);
QString display = parameters.at(i) + ':' + parameters.at(i+1);
m_connections << new QXcbConnection(display.toAscii().constData());
m_connections << new QXcbConnection(m_nativeInterface.data(), display.toAscii().constData());
}
foreach (QXcbConnection *connection, m_connections)
@ -104,7 +105,6 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
screenAdded(screen);
m_fontDatabase.reset(new QGenericUnixFontDatabase());
m_nativeInterface.reset(new QXcbNativeInterface);
m_inputContext.reset(QPlatformInputContextFactory::create());
m_accessibility.reset(new QPlatformAccessibility());
}

View File

@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
class QXcbConnection;
class QAbstractEventDispatcher;
class QXcbNativeInterface;
class QXcbIntegration : public QPlatformIntegration
{
@ -80,7 +81,7 @@ private:
QList<QXcbConnection *> m_connections;
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
QScopedPointer<QXcbNativeInterface> m_nativeInterface;
QScopedPointer<QPlatformInputContext> m_inputContext;
QAbstractEventDispatcher *m_eventDispatcher;

View File

@ -118,6 +118,18 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr
return result;
}
QPlatformNativeInterface::EventFilter QXcbNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter)
{
EventFilter oldFilter = m_eventFilters.value(eventType);
m_eventFilters.insert(eventType, filter);
return oldFilter;
}
QPlatformNativeInterface::EventFilter QXcbNativeInterface::eventFilterForEventType(const QByteArray& eventType) const
{
return m_eventFilters.value(eventType);
}
QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
QXcbScreen *screen;

View File

@ -64,6 +64,9 @@ public:
void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter);
EventFilter eventFilterForEventType(const QByteArray& eventType) const;
void *displayForWindow(QWindow *window);
void *eglDisplayForWindow(QWindow *window);
void *connectionForWindow(QWindow *window);
@ -73,6 +76,8 @@ public:
void *eglContextForContext(QOpenGLContext *context);
private:
QHash<QByteArray, EventFilter> m_eventFilters;
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
};