Contents
Previous
Next
|
#include
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.
Handling Other X Events
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.
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 variable.
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 example FL_SHORTCUT).
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.
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.
This call allows you to supply the X events to FLTK, which may allow
FLTK to cooperate with another toolkit or library. The return value is
true if FLTK understood the event (if the window does not belong to
FLTK and the add_handler() functions all ignore it this returns false).
Besides feeding events your code should call
Fl::flush() periodically so that FLTK redraws its 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.
Drawing using Xlib
The following global variables are set before Fl_Widget::draw() is called, or by
Fl_Window::make_current():
extern Display *fl_display;
extern Window fl_window;
extern GC fl_gc;
extern int fl_screen;
extern XVisualInfo *fl_visual;
extern Colormap fl_colormap;
You must use them to produce Xlib calls. Don't attempt to change
them. A typical X drawing call is written like this:
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.
Returns the X pixel number used to draw the given FLTK color index or
RGB color. This is the X pixel that fl_color() 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.
Changing the Display, Screen, or X Visual
FLTK uses only a single display, screen, X visual, and X colormap.
This greatly simplifies its 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(), which is a portable interface to get a full color and/or double
buffered visual.
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 the display is opened. This call is
provided under WIN32 but it has no effect.
The open X display. This is needed as an argument to most Xlib calls.
Don't attempt to change it! This is NULL before the display is opened.
Opens the display. Does nothing if it is already open. This will
make sure 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.
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.
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. It can also be set by changing
the last number in the Fl::display() string to "host:0,#".
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);
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.
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().
An 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);
}
Fl_X *Fl_X::set_xid(Fl_Window *, Window xid)
Allocate a hidden structure called an Fl_X, put the XID into it, and set a pointer to it from the
Fl_Window. This causes Fl_Window::shown() to return true.
void Fl_X::make_xid(Fl_Window *, XVisualInfo *= fl_visual, Colormap
= fl_colormap)
This static method does the most onerous parts of creating an X
window, including setting the label, resize limitations, etc. It then
does Fl_X::set_xid() with this new window and maps the window.
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) {... draw things into backing store ...}
... copy backing store to window ...
}
virtual void Fl_Window::hide()
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::hide() {
if (mypixmap) {
XFreePixmap(fl_display,mypixmap);
mypixmap = 0;
}
Fl_Window::hide(); // you must call this
}
virtual void Fl_Window::~Fl_Window()
Because of the way C++ works, if you override hide() you must override the destructor as well (otherwise only the base class
hide() is called):
MyWindow::~MyWindow() {
hide();
}
Setting the Icon of a Window
FLTK currently supports setting a window's icon *before* it is shown
using the Fl_Window::icon() method.
void Fl_Window::icon(char *)
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);
|
Contents
Previous
Next
|
#include
The header file defines the interface to FLTK's WIN32-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.
Handling Other WIN32 Messages
By default a single WNDCLASSEX called "FLTK" is created. All
Fl_Windows are of this class unless you use Fl_Window::xclass(). The window class is created the first time Fl_Window::show() is called.
You can probably combine FLTK with other libraries that make their
own WIN32 window classes. The easiest way is to call Fl::wait(), it will call DispatchMessage for all messages to the other windows. If necessary you can let
the other library take over (as long as it calls DispatchMessage()), but you will have to arrange for the function Fl::flush() to be called regularily so that widgets are updated, timeouts are
handled, and the idle functions are called.
The most recent message read by GetMessage (which is called by Fl::wait(). This may not be the most recent message sent to an FLTK window,
because silly WIN32 calls the handle procedures directly for some
events (sigh).
Install a function to parse unrecognized messages sent to FLTK
windows. If FLTK cannot figure out what to do with a message, it calls
each of these functions (most recent first) until one of them returns
non-zero. The argument passed to the fuctions is zero. If all the
handlers return zero then FLTK calls DefWindowProc().
Returns the window handle for a Fl_Window, or zero if not shown().
Return the Fl_Window that corresponds to the given window handle, or NULL if not found. This uses a cache so it is slightly faster than
iterating through the windows yourself.
Drawing Things Using the WIN32 GDI
When the virtual function Fl_Widget::draw() is called, FLTK has stashed in some global variables all the
silly extra arguments you need to make a proper GDI call. These are:
extern HINSTANCE fl_display;
extern HWND fl_window;
extern HDC fl_gc;
COLORREF fl_RGB();
HPEN fl_pen();
HBRUSH fl_brush();
These global variables are set before draw() is called, or by
Fl_Window::make_current(). You can refer to them when needed to produce GDI calls. Don't
attempt to change them. The functions return GDI objects for the
current color set by fl_color() and are created as needed and cached. A typical GDI drawing call
is written like this:
DrawSomething(fl_gc, ..., fl_brush());
It may also be useful to refer to
Fl_Window::current() to get the window's size or position.
Setting the Icon of a Window
FLTK currently supports setting a window's icon *before* it is shown
using the Fl_Window::icon() method.
void Fl_Window::icon(char *)
Sets the icon for the window to the passed pointer. You will need to
cast the HICON handle to a char * when calling this method. To set the icon using an icon resource
compiled with your application use:
window->icon((char *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
How to Not Get a MSDOS Console Window
WIN32 has a really stupid mode switch stored in the executables that
controls whether or not to make a console window.
To always get a console window you simply create a console
application (the "/SUBSYSTEM:CONSOLE" option for the linker). For a
GUI-only application create a WIN32 application (the
"/SUBSYSTEM:WINDOWS" option for the linker).
FLTK includes a WinMain() function that calls the ANSI standard main() entry point for you. This function creates a console window
when you use the debug version of the library.
WIN32 applications without a console cannot write to stdout or stderr, even if they are run from a console window. Any output is
silently thrown away.
Known Bugs
If a program is deactivated, Fl::wait() does not return until it is activated again, even though many
events are delivered to the program. This can cause idle background
processes to stop unexpectedly. This also happens while the user is
dragging or resizing windows or otherwise holding the mouse down. I
was forced to remove most of the efficiency FLTK uses for redrawing in
order to get windows to update while being moved. This is a design
error in WIN32 and probably impossible to get around.
Fl_Gl_Window::can_do_overlay() returns true until the first time it attempts to draw an overlay,
and then correctly returns whether or not there is overlay hardware.
Cut text contains ^J rather than ^M^J to break lines. This is a
feature, not a bug.
SetCapture (used by Fl::grab()) doesn't work, and the main window title bar turns gray while
menus are popped up.
FLUID does not support BMP files yet.
|