On Unix/X you can include this file to access fltk's X-specific functions. Be warned that some of the structures and calls in it are subject to change in future version of fltk. Try to avoid doing this so your code is portable.
void Fl::add_handler(int (*f)(int));
Fltk calls this for any X events it does not recognize, or X events
with a window id that fltk does not recognize. You can look at the X
event with the fl_xevent
.
The argument is zero for unrecognized X events. These handlers are also called for global shortcuts and some other events that the widget they were passed to did not handle. In this case the argument is non-zero (for instance FL_SHORTCUT).
extern XEvent* fl_xvent;
extern ulong fl_event_time;
Window fl_xid(const Fl_Window*);
Fl_Window* fl_find(ulong xid);
Return the Fl_Window that corresponds to the given xid, or null if not found. This uses a cache so it is slightly faster than iterating through the windows yourself.
int fl_handle(const XEvent&);
Besides feeding events your code should call Fl::flush() periodically so that fltk redraws it's windows.
This function will call the callback functions. It will not return until they complete. In particular if a callback pops up a modal window (by calling fl_ask(), for instance) it will not return until the modal function returns.
extern Display* fl_display;
extern Window fl_window;
extern GC fl_gc;
extern int fl_screen;
extern XVisualInfo* fl_visual;
extern Colormap fl_colormap;
XDrawSomething(fl_display, fl_window, fl_gc, ...);
Other information such as the position or size of the X window can be
found by looking at Fl_Window::current()
,
which returns a pointer to the Fl_Window being drawn.
unsigned long fl_xpixel(Fl_Color i);
unsigned long fl_xpixel(uchar r, uchar g, uchar
b);
Fltk uses only a single display, screen, X visual, and X colormap. This greatly simplifies it's internal structure and makes it much smaller and faster. You can change which it uses by setting global variables before the first Fl_Window::show() is called. You may also want to call Fl::visual(int), which is a portable interface to get a full color and/or double buffered visual.
int Fl::display(const char *)
setenv("DISPLAY", x)
so that child programs will
display on the same screen if called with exec(). This must be done
before the display is opened. This call is provided on MSWindows, but
it just sets the environment variable and has no other effect.
extern Display* fl_display;
void fl_open_display();
fl_display
is non-zero. You should call this if you
wish to do X calls and there is a chance that your code will be called
before the first show() of a window.
This may call Fl::abort() if there is an error opening the display.
void fl_close_display();
extern int fl_screen;
extern XVisualInfo* fl_visual;
extern Colormap fl_colormap;
The visual and colormap that fltk will use for all windows. These are set by fl_open_display() to the default visual and colormap. You can change them before calling show() on the first window. Typical code for changing the default visual:
Fl::args(argc, argv); // do this first so $DISPLAY is set
fl_open_display();
fl_visual = find_a_good_visual(fl_display, fl_screen);
if (!fl_visual) Fl::abort("No good visual");
fl_colormap = make_a_colormap(fl_display, fl_visual->visual, fl_visual->depth);
// it is now ok to show() windows:
window->show(argc, argv);
Fltk can also manage xid's provided by other libraries or programs, and call those libraries when the window needs to be redrawn.
To do this, you need to make a subclass of Fl_Window and override some of these virtual functions:
virtual void Fl_Window::show()
If the window is already shown() this must cause it to be raised, this can usually be done by calling Fl_Window::show(). If not shown() your implementation must call either Fl_X::set_xid() or Fl_X::make_xid():
Fl_X* Fl_X::set_xid(Fl_Window*, Window xid);
void Fl_X::make_xid(Fl_Window*, XVisualInfo* =
fl_visual, Colormap = fl_colormap);
Example:
void MyWindow::show() { if (shown()) {Fl_Window::show(); return;} // you must do this! fl_open_display(); // necessary if this is first window // we only calcualte the necessary visual & colormap once: static XVisualInfo *visual; static Colormap colormap; if (!visual) { visual = figure_out_visual(); colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen), vis->visual, AllocNone); } Fl_X::make_xid(this, visual, colormap); }
virtual void Fl_Window::flush()
The X region that is a combination of all damage() calls done so
far is in Fl_X::i(this)->region
. If null then
you should redraw the entire window. The undocumented function
fl_clip_region(XRegion)
will initialize the fl clip stack
with a region or null for no clipping. You must set region to null
afterwards as fl_clip_region() now owns it and will delete it when
done.
If damage()==2
then only X expose events have
happened. This may be useful if you have an undamaged image (such as
a backing buffer) around.
Here is a sample where an undamaged image is kept somewhere:
void MyWindow::flush() { fl_clip_region(Fl_X::i(this)->region); Fl_X::i(this)->region = 0; if (damage() != 2) {... draw things into backing store ...} ... copy backing store to window ... }
virtual void Fl_Window::hide()
void MyWindow::hide() { if (mypixmap) { XFreePixmap(fl_display,mypixmap); mypixmap = 0; } Fl_Window::hide(); // you must call this }
virtual void Fl_Window::~Fl_Window()
MyWindow::~MyWindow() { hide(); }