Unlike every other toolkit I have ever seen, you do not need to "initialize" fltk. The constructors for fltk widgets do not require or create a connection to the X display. You can in fact create a whole hierarchy of widgets without opening the display or setting any global state of fltk. Calling redraw() on widgets or Fl::flush() does nothing as long as the display is not open. This is useful if your program has a "non-gui" mode, as you can avoid putting "if" statements around all the gui parts.
Fltk will open the X display when the first Fl_Window::show() is called. There are certain calls that do not work after this is done (such as Fl::display()). There are also other calls that must be done before the first show() which have a side effect of opening the display (such as Fl::visual()). It is important to call these in the correct order.
The argument parsers provided by fltk are optional. You don't have to call them if you don't like them! Everything they can do can be done with other calls to fltk.
int Fl::args(int argc, char** argv, int
&i, int (*callback)(int,char**,int&)=0)
Returns zero if there is an error, returns i if no error.
The callback function lets you define your own switches. It is called with the same argc and argv, and with i the index of each word. The callback should return zero if the switch is unrecognized, and not change i. It should return non-zero if the switch is recognized, and add at least 1 to i (it can add more to consume words after the switch). This function is called before any other tests, so you can override FL's handling of any word.
The following switches are recognized (all may be abbreviated to one letter and case is ignored). You must call Fl_Window::show(argc,argv) to complete the processing of the switches.
-display host:n.n
The X display to use. This
will not work if the display has already been opened!
-geometry WxH+X+Y
The window position and size
will be modified according the the standard X geometry string.
-name string Fl_Window::xclass(string)
will be
done to the window, this will change it's icon.
-title string Fl_Window::label(string)
will be
done to the window, changing both it's title and the icontitle.
-iconic Fl_Window::iconize()
will be done to
the window.
-bg color
XParseColor is used to lookup the
passed color and the is used as the gray background. All
the gray colors in the colormap are changed to be shades of this
color, and this will thus change the default color of most widgets,
and the colors of the shaded edges.
-bg2 color
XParseColor is used to lookup the
passed color and it is stuck in the fl_color slot for FL_WHITE. This
is the background color used by the Fl_Input and Fl_Text widgets.
-fg color
XParseColor is used to lookup the
passed color and it is stuck in the fl_color slot for FL_BLACK. This
is the color used by almost all widgets to draw labels.
int Fl::arg(int argc, char** argv, int &i)
void Fl::args(int argc, char** argv)
Fl::abort(Fl::help)
.
int Fl_Window::show(int argc, char** argv)
XA_WM_COMMAND
attribute to
the passed argc/argv. If this is the first time this has been called
since Fl::args() or Fl::arg(), the results of those switched are used
to set the xclass(), label(), and other attributes of this window.
If Fl::args() or Fl::arg() have never been called, this calls Fl::args(argc,argv) automatically. This is convienent for very small programs that just want to put up a single window and take no switches.
const char* const Fl::help;
int Fl::display(const char *)
setenv("DISPLAY", x)
, so that child programs will work if
called with exec().
int Fl::visual(int)
The integer argument is a bitflag of requirements:
FL_RGB
- Color (TrueColor or StaticColor or DirectColor)
FL_RGB8
- Color with at least 8 bits of each color
FL_DOUBLE
- Hardware double buffering (used by
Fl_Double_Window)
FL_INDEX
- Color is not required (but it may
choose it anyway)
Due to various historical reasons and Glut compatability,
FL_RGB
has a value of zero, it is "on" unless you
give FL_INDEX
.
If the default visual fulfills the requirements, fltk will use it. Otherwise it will use the visual with the largest depth that fulfills the requirements. If there are several of the same depth it will use the first one in the list returned by XGetVisualInfo().
int Fl::gl_visual(int)
See Fl_Gl_Window for a list of values for the argument.
void Fl::foreground(short, short, short);
fl_color(FL_BLACK)
. Also changes
FL_INACTIVE_COLOR
and FL_SELECTION_COLOR
to
be a ramp between this and FL_WHITE
. This is used by the
-fg switch.
void Fl::background(short, short, short);
fl_color(FL_GRAY)
to the given color, and changes
the gray ramp from 32 to 56 to black to white. These are the colors
used as backgrounds by almost all widgets and used to draw the edges
of all the boxtypes. This is used by the -bg switch.
void Fl::background2(short, short, short);
fl_color(FL_WHITE)
and the same colors as
Fl::foreground(). This color is used as a background by Fl_Input and
other text widgets. This is used by the -bg2 switch.
These calls are only supported on the X version. The normal fltk header files do not include Xlib.h or any calls depending on them. But the <FL/x.H> header file does include them. You must include this header file to call these:
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;
Immediately after opening the display it may be useful to clobber
these global variables with new values, to change the screen, visual,
or colormap. This is what Fl::visual(int)
does. Typical
code for changing the default visual:
Fl::args(...); // do arguments first so $DISPLAY is set
fl_open_display(); // insure fl_display is not zero, sets fl_screen
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);
window->show(); // it is now ok to show() windows
Bad things will happen if your screen, visual, and colormap are not a legal combination. Don't blame me, I didn't write X.