summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl.H5
-rw-r--r--src/Fl.cxx77
-rw-r--r--src/Fl_cocoa.mm4
-rw-r--r--src/Fl_win32.cxx5
-rw-r--r--src/Fl_x.cxx4
5 files changed, 95 insertions, 0 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index e0bcd3194..67de3a9bf 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -96,6 +96,9 @@ typedef void (*Fl_FD_Handler)(FL_SOCKET fd, void *data);
/** Signature of add_handler functions passed as parameters */
typedef int (*Fl_Event_Handler)(int event);
+/** Signature of add_system_handler functions passed as parameters */
+typedef int (*Fl_System_Handler)(void *event, void *data);
+
/** Signature of set_abort functions passed as parameters */
typedef void (*Fl_Abort_Handler)(const char *format,...);
@@ -770,6 +773,8 @@ public:
static void focus(Fl_Widget*);
static void add_handler(Fl_Event_Handler h);
static void remove_handler(Fl_Event_Handler h);
+ static void add_system_handler(Fl_System_Handler h, void *data);
+ static void remove_system_handler(Fl_System_Handler h);
static void event_dispatch(Fl_Event_Dispatch d);
static Fl_Event_Dispatch event_dispatch();
/** @} */
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 5386fc105..2b637aa37 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -888,6 +888,83 @@ static int send_handlers(int e) {
return 0;
}
+
+////////////////////////////////////////////////////////////////
+// System event handlers:
+
+
+struct system_handler_link {
+ Fl_System_Handler handle;
+ void *data;
+ system_handler_link *next;
+};
+
+
+static system_handler_link *sys_handlers = 0;
+
+
+/**
+ \brief Install a function to intercept system events.
+
+ FLTK calls each of these functions as soon as a new system event is
+ received. The processing will stop at the first function to return
+ non-zero. If all functions return zero then the event is passed on
+ for normal handling by FLTK.
+
+ Each function will be called with a pointer to the system event as
+ the first argument and \p data as the second argument. The system
+ event pointer will always be void *, but will point to different
+ objects depending on the platform:
+ - X11: XEvent
+ - Windows: MSG
+ - OS X: NSEvent
+
+ \param ha The event handler function to register
+ \param data User data to include on each call
+
+ \see Fl::remove_system_handler(Fl_System_Handler)
+*/
+void Fl::add_system_handler(Fl_System_Handler ha, void *data) {
+ system_handler_link *l = new system_handler_link;
+ l->handle = ha;
+ l->data = data;
+ l->next = sys_handlers;
+ sys_handlers = l;
+}
+
+
+/**
+ Removes a previously added system event handler.
+
+ \param ha The event handler function to remove
+
+ \see Fl::add_system_handler(Fl_System_Handler)
+*/
+void Fl::remove_system_handler(Fl_System_Handler ha) {
+ system_handler_link *l, *p;
+
+ // Search for the handler in the list...
+ for (l = sys_handlers, p = 0; l && l->handle != ha; p = l, l = l->next);
+
+ if (l) {
+ // Found it, so remove it from the list...
+ if (p) p->next = l->next;
+ else sys_handlers = l->next;
+
+ // And free the record...
+ delete l;
+ }
+}
+
+int fl_send_system_handlers(void *e) {
+ for (const system_handler_link *hl = sys_handlers; hl; hl = hl->next) {
+ if (hl->handle(e, hl->data))
+ return 1;
+ }
+ return 0;
+}
+
+
////////////////////////////////////////////////////////////////
Fl_Widget* fl_oldfocus; // kludge for Fl_Group...
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index 5c96fb255..9756c35dc 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -81,6 +81,7 @@ typedef unsigned int NSUInteger;
// external functions
extern void fl_fix_focus();
extern unsigned short *fl_compute_macKeyLookUp();
+extern int fl_send_system_handlers(void *e);
// forward definition of functions in this file
// converting cr lf converter function
@@ -1375,6 +1376,9 @@ void fl_open_callback(void (*cb)(const char *)) {
@implementation FLApplication
+ (void)sendEvent:(NSEvent *)theEvent
{
+ if (fl_send_system_handlers(theEvent))
+ return;
+
NSEventType type = [theEvent type];
if (type == NSLeftMouseDown) {
fl_lock_function();
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index 0dfde6297..d34a54bfa 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -336,6 +336,8 @@ void* Fl::thread_message() {
return r;
}
+extern int fl_send_system_handlers(void *e);
+
IActiveIMMApp *fl_aimm = NULL;
MSG fl_msg;
@@ -402,6 +404,9 @@ int fl_wait(double time_to_wait) {
// Execute the message we got, and all other pending messages:
// have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
while ((have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE)) > 0) {
+ if (fl_send_system_handlers(&fl_msg))
+ continue;
+
// Let applications treat WM_QUIT identical to SIGTERM on *nix
if (fl_msg.message == WM_QUIT)
raise(SIGTERM);
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 7561919b9..35aa6fe63 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -194,6 +194,8 @@ void Fl::remove_fd(int n) {
remove_fd(n, -1);
}
+extern int fl_send_system_handlers(void *e);
+
#if CONSOLIDATE_MOTION
static Fl_Window* send_motion;
extern Fl_Window* fl_xmousewin;
@@ -204,6 +206,8 @@ static void do_queued_events() {
while (XEventsQueued(fl_display,QueuedAfterReading)) {
XEvent xevent;
XNextEvent(fl_display, &xevent);
+ if (fl_send_system_handlers(&xevent))
+ continue;
fl_handle(xevent);
}
// we send FL_LEAVE only if the mouse did not enter some other window: