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
This commit is contained in:
Pierre Ossman 2014-09-15 09:17:56 +00:00
parent 321fb4ed7a
commit e145df2165
5 changed files with 95 additions and 0 deletions

View File

@ -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();
/** @} */

View File

@ -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...

View File

@ -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();

View File

@ -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);

View File

@ -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: