summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-09-15 09:17:56 +0000
committerPierre Ossman <ossman@cendio.se>2014-09-15 09:17:56 +0000
commite145df21652a643c358afabe979cdca8e0c55429 (patch)
tree908cb2516072100c3fc4198242e71e5d358955fb /src
parent321fb4ed7aa9e36e3b2fc5c95c3c2c3652179366 (diff)
Add methods to intercept low level system events.
This gives applications the means to handle some low level integration with the system that might otherwise not be possible without modifying FLTK itself. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10310 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-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
4 files changed, 90 insertions, 0 deletions
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: