From 5d47e14a5063bb0f959c14ea84eaed331c5ccdbf Mon Sep 17 00:00:00 2001 From: Matteo Salvi Date: Wed, 21 Dec 2022 14:21:37 +0100 Subject: [PATCH] Added NativeEventFilter hook in qt5 --- lcl/interfaces/qt5/cbindings/Qt5Pas.pro | 5 +- lcl/interfaces/qt5/cbindings/src/chandles.h | 3 + lcl/interfaces/qt5/cbindings/src/pascalbind.h | 2 + .../cbindings/src/qnativeeventfilter_hook.h | 96 +++++++++++++++++++ .../src/qnativeeventfilter_hook_c.cpp | 36 +++++++ .../cbindings/src/qnativeeventfilter_hook_c.h | 23 +++++ lcl/interfaces/qt5/qt56.pas | 9 ++ 7 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook.h create mode 100644 lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.cpp create mode 100644 lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.h diff --git a/lcl/interfaces/qt5/cbindings/Qt5Pas.pro b/lcl/interfaces/qt5/cbindings/Qt5Pas.pro index 7dbb594288..e262f54bf9 100644 --- a/lcl/interfaces/qt5/cbindings/Qt5Pas.pro +++ b/lcl/interfaces/qt5/cbindings/Qt5Pas.pro @@ -751,5 +751,8 @@ SOURCES += \ qtcpsocket_hook_c.cpp \ qtcpserver_hook_c.cpp \ qnetworkaccessmanager_hook_c.cpp \ - qnetworkreply_hook_c.cpp + qnetworkreply_hook_c.cpp \ + qnativeeventfilter_hook_c.cpp \ + qnativeeventfilter_hook.h \ + qnativeeventfilter_hook_c.h # end of file diff --git a/lcl/interfaces/qt5/cbindings/src/chandles.h b/lcl/interfaces/qt5/cbindings/src/chandles.h index afbd711a6d..3e818eaea8 100644 --- a/lcl/interfaces/qt5/cbindings/src/chandles.h +++ b/lcl/interfaces/qt5/cbindings/src/chandles.h @@ -529,4 +529,7 @@ typedef struct QAccessibleEvent__ { PTRINT dummy; } *QAccessibleEventH; typedef struct QAccessibleInterface__ { PTRINT dummy; } *QAccessibleInterfaceH; typedef struct QAccessibleWidget__ { PTRINT dummy; } *QAccessibleWidgetH; typedef struct QLCLAccessibleWidget__ { PTRINT dummy; } *QLCLAccessibleWidgetH; + +typedef struct Q_NativeEventFilter_hook__ { PTRINT dummy; } *Q_NativeEventFilter_hookH; +typedef struct Q_NativeEventFilter__ { PTRINT dummy; } *Q_NativeEventFilterH; #endif diff --git a/lcl/interfaces/qt5/cbindings/src/pascalbind.h b/lcl/interfaces/qt5/cbindings/src/pascalbind.h index 1018bfbe34..096de7fd20 100644 --- a/lcl/interfaces/qt5/cbindings/src/pascalbind.h +++ b/lcl/interfaces/qt5/cbindings/src/pascalbind.h @@ -297,4 +297,6 @@ inline void copyQRealArrayToQVectorQReal(PQRealArray parr,QVector &qvecto C_EXPORT void initializeQRealArray(GetQRealArrayAddr gaa, GetQRealArrayLength gal, SetQRealArrayLength sal); +typedef bool (*NativeEventFilter)(const QByteArray &eventType, void *message, long *result); + #endif diff --git a/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook.h b/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook.h new file mode 100644 index 0000000000..297c7a1090 --- /dev/null +++ b/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook.h @@ -0,0 +1,96 @@ +//****************************************************************************** +// Copyright (c) 2005-2022 by Matteo Salvi +// +// See the included file COPYING.TXT for details about the copyright. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +//****************************************************************************** + +#ifndef Q_NATIVEEVENTFILTER_HOOK_H +#define Q_NATIVEEVENTFILTER_HOOK_H + +#include +#include +#include "pascalbind.h" + +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + #define _NATIVE_EVENT_RESULT qintptr +#else + #define _NATIVE_EVENT_RESULT long +#endif + + +class Q_NativeEventFilter_hook : public QAbstractNativeEventFilter { + //Q_OBJECT + + public: + bool nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) override; + + Q_NativeEventFilter_hook(QCoreApplication *handle) : QAbstractNativeEventFilter() { + this->handle = handle; + this->events.func = NULL; + this->destroyed_event.func = NULL; + //connect(handle, SIGNAL(destroyed()), this, SLOT(destroyed_hook())); + } + + virtual ~Q_NativeEventFilter_hook() { + if (handle) { + handle->removeNativeEventFilter(this); + handle = NULL; + } + } + + void hook_installfilter(QHook &hook) { + if (handle) { + if (!events.func) { + handle->installNativeEventFilter(this); + events = hook; + } + if (!hook.func) + handle->removeNativeEventFilter(this); + events = hook; + } + } + void hook_removefilter() { + if (handle) { + handle->removeNativeEventFilter(this); + events.func = NULL; + } + } + + void hook_destroyed(QHook &hook) { + destroyed_event = hook; + } + + protected: + + QCoreApplication *handle; + + private slots: + + void destroyed_hook() { + if ( destroyed_event.func ) { + typedef void (*func_type)(void *data); + (*(func_type)destroyed_event.func)(destroyed_event.data); + } + handle = NULL; + } + + private: + QHook events; + QHook destroyed_event; +}; + + +bool Q_NativeEventFilter_hook::nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) { + if (events.func) { + Q_NativeEventFilter_hook* sender = this; + typedef bool (*func_type)(void *data, Q_NativeEventFilter_hook* sender, const QByteArray &eventType, void *message); + return (*(func_type)events.func)(events.data, sender, eventType, message); + } + return false; +} + +#endif diff --git a/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.cpp b/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.cpp new file mode 100644 index 0000000000..3501171fc5 --- /dev/null +++ b/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.cpp @@ -0,0 +1,36 @@ +//****************************************************************************** +// Copyright (c) 2005-2022 by Matteo Salvi +// +// See the included file COPYING.TXT for details about the copyright. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +//****************************************************************************** + +#include "qnativeeventfilter_hook_c.h" + +Q_NativeEventFilter_hookH Q_NativeEventFilter_hook_Create(QCoreApplicationH handle) +{ + return (Q_NativeEventFilter_hookH) new Q_NativeEventFilter_hook((QCoreApplication*)handle); +} + +void Q_NativeEventFilter_hook_Destroy(Q_NativeEventFilter_hookH handle) +{ + delete (Q_NativeEventFilter_hook *)handle; +} + +void Q_NativeEventFilter_hook_installfilter(Q_NativeEventFilter_hookH handle, QHookH hook) +{ + ((Q_NativeEventFilter_hook *)handle)->hook_installfilter(hook); +} + +void Q_NativeEventFilter_hook_destroyed(Q_NativeEventFilter_hookH handle, QHookH hook) +{ + ((Q_NativeEventFilter_hook *)handle)->hook_destroyed(hook); +} + +void Q_NativeEventFilter_hook_removefilter(Q_NativeEventFilter_hookH handle) +{ + ((Q_NativeEventFilter_hook *)handle)->hook_removefilter(); +} diff --git a/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.h b/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.h new file mode 100644 index 0000000000..ca92008142 --- /dev/null +++ b/lcl/interfaces/qt5/cbindings/src/qnativeeventfilter_hook_c.h @@ -0,0 +1,23 @@ +//****************************************************************************** +// Copyright (c) 2005-2022 by Matteo Salvi +// +// See the included file COPYING.TXT for details about the copyright. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +//****************************************************************************** + +#ifndef Q_NATIVEEVENTFILTER_HOOK_C_H +#define Q_NATIVEEVENTFILTER_HOOK_C_H + +#include "qnativeeventfilter_hook.h" +#include "pascalbind.h" + +C_EXPORT Q_NativeEventFilter_hookH Q_NativeEventFilter_hook_Create(QCoreApplicationH handle); +C_EXPORT void Q_NativeEventFilter_hook_Destroy(Q_NativeEventFilter_hookH handle); +C_EXPORT void Q_NativeEventFilter_hook_installfilter(Q_NativeEventFilter_hookH handle, QHookH hook); +C_EXPORT void Q_NativeEventFilter_hook_destroyed(Q_NativeEventFilter_hookH handle, QHookH hook); +C_EXPORT void Q_NativeEventFilter_hook_removefilter(Q_NativeEventFilter_hookH handle); + +#endif diff --git a/lcl/interfaces/qt5/qt56.pas b/lcl/interfaces/qt5/qt56.pas index 04eb8e6940..52128878fc 100644 --- a/lcl/interfaces/qt5/qt56.pas +++ b/lcl/interfaces/qt5/qt56.pas @@ -15672,6 +15672,15 @@ procedure QNetworkReply_hook_hook_encrypted(handle: QNetworkReply_hookH; hook: Q procedure QNetworkReply_hook_hook_uploadProgress(handle: QNetworkReply_hookH; hook: QNetworkReply_uploadProgress_Event); cdecl; external Qt5PasLib name 'QNetworkReply_hook_hook_uploadProgress'; procedure QNetworkReply_hook_hook_downloadProgress(handle: QNetworkReply_hookH; hook: QNetworkReply_downloadProgress_Event); cdecl; external Qt5PasLib name 'QNetworkReply_hook_hook_downloadProgress'; +type + QNativeEventFilter_hookH = class(TObject) end; + QNativeEventFilterEvent = function (handle: QNativeEventFilter_hookH; eventType: QByteArrayH; message: Pointer):boolean of object cdecl; + +function QNativeEventFilter_hook_Create(handle : QCoreApplicationH) : QNativeEventFilter_hookH; cdecl; external Qt5PasLib name 'Q_NativeEventFilter_hook_Create'; +procedure QNativeEventFilter_Destroy(handle : QNativeEventFilter_hookH ); cdecl; external Qt5PasLib name 'Q_NativeEventFilter_hook_Destroy'; +procedure QNativeEventFilter_hook_installfilter(handle : QNativeEventFilter_hookH; hook : QNativeEventFilterEvent); cdecl; external Qt5PasLib name 'Q_NativeEventFilter_hook_installfilter'; +procedure QNativeEventFilter_hook_destroyed(handle : QNativeEventFilter_hookH; hook : QObject_destroyed_Event); cdecl; external Qt5PasLib name 'Q_NativeEventFilter_hook_destroyed'; +procedure QNativeEventFilter_hook_removefilter(handle : QNativeEventFilter_hookH); cdecl; external Qt5PasLib name 'Q_NativeEventFilter_hook_removefilter'; //=======================================================