Or you can probably use ::belowmouse() to figure out the co-ordinates even relative to non-child widgets too, I think.
OK, example follows. Seems to work.
/*
* fltk-config --compile track-cursor.cxx
*/
/* Standard headers */
#include <stdlib.h>
/* Fltk headers */
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/platform.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Value_Output.H>
#include <FL/fl_draw.H>
// constants to define the view etc.
static const int win_size = 512;
// Output the mouse (x,y)
static Fl_Value_Output *valx = NULL;
static Fl_Value_Output *valy = NULL;
/*****************************************************************************/
class tracker_win : public Fl_Double_Window
{
public:
tracker_win (int W, int H, const char *L = 0)
: Fl_Double_Window(W, H, L) {
}
private:
int handle(int event);
};
// Event handling
int tracker_win::handle(int ev) {
int res = Fl_Double_Window::handle(ev);
switch (ev) {
case FL_MOVE:
{
int X = Fl::event_x();
int Y = Fl::event_y();
Fl_Widget *tgt_widget = Fl::belowmouse ();
int xw = tgt_widget->x();
int yw = tgt_widget->y();
int dx = X - xw;
int dy = Y - yw;
if (this == tgt_widget) {
dx = X;
dy = Y;
}
valx->value(dx);
valy->value(dy);
}
res = 1;
break;
default:
break;
}
return res;
} /* end of handle() method */
/*****************************************************************************/
static tracker_win *main_window = 0;
/*****************************************************************************/
// Quit button callback (closes the window)
void quit_cb(Fl_Button *b, void *) {
main_window->hide();
}
/*****************************************************************************/
int main(int argc, char **argv)
{
main_window = new tracker_win(win_size, win_size, "Mouse tracking demo");
main_window->begin();
main_window->box (FL_FLAT_BOX);
Fl_Box *dummy_box = new Fl_Box (10, 10, 100, 100);
dummy_box->box (FL_BORDER_BOX);
Fl_Box *other_box = new Fl_Box (220, 220, 100, 100);
other_box->box (FL_DOWN_BOX);
valx = new Fl_Value_Output (130, 10, 40, 20, "X");
valx->box (FL_THIN_DOWN_BOX);
valy = new Fl_Value_Output (190, 10, 40, 20, "Y");
valy->box (FL_THIN_DOWN_BOX);
Fl_Button *quit_bt = new Fl_Button (10, 472, 60, 30, "Quit");
quit_bt->box(FL_THIN_UP_BOX);
quit_bt->callback((Fl_Callback *)quit_cb);
main_window->end();
main_window->resizable(main_window);
main_window->show(argc, argv);
return Fl::run();
} // main