G - X-Specific Interface
#include <FL/x.H>
On 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.
Installs a function to parse unrecognized events. If FLTK cannot
figure out what to do with an event, it calls each of these functions
(most recent first) until one of them returns non-zero. If none of
them returns non-zero then the event is ignored. The argument is the
event number (like FL_PUSH). For keystrokes it will be
FL_SHORTCUT.
Besides events that all widgets ignored, FLTK calls this for X
events that it does not recognize, or that contain a window id that
FLTK does not know about. In this case the argument is zero. You can
look at the X event with the fl_xevent
variable.
The most recent X event.
This is the time stamp from the most recent X event that reported it
(not all do). Many X calls (like cut and paste) need this value.
This allows you to "feed" X events to fltk, in cases where you cannot
give fltk control over any file descriptors. Fltk will figure out what
the event is and call widgets normally and also the
Fl::add_handler() functions. The return value is true if a
widget accepted the event or one of the add_handler()
function returned true.
Besides feeding events your code should call
Fl::flush() periodically so that FLTK redraws its
windows.
This function will call any widget callbacks from the widget code.
It will not return until they complete, for instance if it pops up a
modal window with fl_ask(),
it will not return until the user clicks yes or no.
Set which X display to use. This actually does
putenv("DISPLAY=...") so that child programs will
display on the same screen if called with exec(). This must
be done before fl_open_display is called. This call is
provided under WIN32 but it has no effect.
Opens the display. Does nothing if it is already open. 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 is called automatically by Fl_Window::show().
This may call Fl::abort() if there is an error opening the
display.
void fl_open_display(Display*)
You can make fltk "open" a display that has already been opened,
perhaps by another GUI library. Calling this will set
fl_display to the passed display and also read information
fltk needs from it. Don't call this if the display is already open!
The open X display. This is needed as an argument to most Xlib calls.
Don't attempt to change it! This is NULL before
fl_open_display is called.
This dummy 1x1 window is created by fl_open_display() and is
never destroyed. You can use it to communicate with the window
manager or other programs.
Which screen number to use. This is set by fl_open_display()
to the default screen. You can change it by setting this to a
different value immediately afterwards.
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 is:
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);
You may also want to call Fl::visual(), which is a portable
interface to get a full color and/or double buffered visual.
Returns the XID for a window, or zero if not shown().
Returns 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.
These variables are set before Fl_Widget::draw()
is called, or by
Fl_Window::make_current(). They are needed by most Xlib
drawing calls, a typical call is like this:
XDrawSomething(fl_display, fl_window, fl_gc, ...);
Notice that fl_window is the X window id number. 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.
Returns the X pixel number used to draw the given FLTK color index or
RGB color. This is the X pixel that fl_color(i) would use.
Points at the font selected by the most recent fl_font(). This is not
necessarily the current font of fl_gc, which is not set
until fl_draw() is called.
This closes the X connection. You do not need to call this to
exit, and in fact it is faster to not do so! It may be useful to call
this if you want your program to continue without the X connection. You
cannot open the display again, and probably cannot call any FLTK
functions.
This string is used to set the XA_WM_CLASS property of all
the windows fltk creates. The default value is "fltk". Many window
managers can use this string to select an icon. Fl::args(...) will set this to
the name of the program.
This call is provided on WIN32 for compatability, but the value is
ignored.
Sets the icon for the window to the passed pointer. You will need to
cast the icon Pixmap to a char* when calling this
method. To set the icon using a bitmap compiled with your application
use:
#include "icon.xbm"
Pixmap p = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_bits, icon_width, icon_height);
window->icon((char*)p);
This only works if called before it is shown using the
Fl_Window::show() method.
Using a Subclass of Fl_Window for Special X Stuff
FLTK can manage an X window on a different screen, visual and/or
colormap, you just can't use FLTK's drawing routines to draw into it.
But you can write your own draw() method that uses Xlib
(and/or OpenGL) calls only.
To do this, you need to make a subclass of
Fl_Window and override some of these virtual functions:
virtual void Fl_Window::create()
Creates the X window, and perhaps other data such as colormaps needed
by this window. To create the X window you must call
Fl_X::create(). Do not map the window, fltk does that for you.
An example:
void MyWindow::create() {
fl_open_display(); // necessary if this is first window
// we only calcualte the necessary visual & colormap once:
static XVisualInfo* visual;
static Colormap colormap;
static int background;
if (!visual) {
visual = figure_out_visual();
colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
vis->visual, AllocNone);
XColor xcol; xcol.red = 1; xcol.green = 2; xcol.blue = 3;
XAllocColor(fl_display, colormap, &xcol);
background = xcol.pixel;
}
Fl_X::create(this, visual, colormap, background);
}
void Fl_X::create(Fl_Window*, XVisualInfo*, Colormap, int background=-1)
This function calls XCreateWindow and sets things up so that
fl_xid(window) returns the created window id. This also does
a lot of other ugly X stuff, including setting the label, resize
limitations, etc. The
background is a pixel to use for X's automatic fill color, use -1 to
indicate that no background filling should be done.
virtual void Fl_Window::flush()
This virtual function is called by Fl::flush() to update the
window. For FLTK's own windows it does this by setting the global
variables fl_window and fl_gc and then calling the
draw() method. For your own windows you might just want to
put all the drawing code in here.
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 FLTK 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() == FL_DAMAGE_EXPOSE 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) {
fl_window = backing_store_pixmap;
fl_gc = backing_store_gc;
this->draw();
}
copy_image(backing_store_pixmap, fl_xid(this));
}
virtual void Fl_Window::destroy()
Destroy the window server copy of the window. Usually you will
destroy contexts, pixmaps, or other resources used by the window, and
then call Fl_Window::hide() to get rid of the main window
identified by xid(). If you override this, you must also
override the destructor as shown:
void MyWindow::destroy() {
if (mypixmap) {
XFreePixmap(fl_display,mypixmap);
mypixmap = 0;
}
Fl_Window::destroy(); // you must call this
}
virtual void Fl_Window::~Fl_Window()
Because of the way C++ works, if you override destroy() you
must override the destructor as well (otherwise only the base
class destroy() is called):
MyWindow::~MyWindow() {
destroy();
}