From e145df21652a643c358afabe979cdca8e0c55429 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 15 Sep 2014 09:17:56 +0000 Subject: 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 --- src/Fl.cxx | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Fl_cocoa.mm | 4 +++ src/Fl_win32.cxx | 5 ++++ src/Fl_x.cxx | 4 +++ 4 files changed, 90 insertions(+) (limited to 'src') 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: -- cgit v1.2.3