diff options
| -rw-r--r-- | FL/Fl.H | 5 | ||||
| -rw-r--r-- | src/Fl.cxx | 77 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 4 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 5 | ||||
| -rw-r--r-- | src/Fl_x.cxx | 4 |
5 files changed, 95 insertions, 0 deletions
@@ -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: |
