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:
parent
321fb4ed7a
commit
e145df2165
5
FL/Fl.H
5
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();
|
||||
/** @} */
|
||||
|
||||
77
src/Fl.cxx
77
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...
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user