This appendix describes the operating system specific interfaces in FLTK.
Accessing the OS Interfaces
All programs that need to access the operating system
specific interfaces must include the following header file:
#include <FL/x.H>
Despite the name, this header file will define the
appropriate interface for your environment. The pages that
follow describe the functionality that is provided for each
operating system.
WARNING:
The interfaces provided by this header file may
change radically in new FLTK releases. Use them only
when an existing generic FLTK interface is not
sufficient.
|
The UNIX (X11) Interface
The UNIX interface provides access to the X Window System
state information and data structures.
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 in the fl_xevent variable.
The argument is the FLTK event type that was not handled, or
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, for example
FL_SHORTCUT.
This variable contains the most recent X event.
This variable contains the time stamp from the most recent X
event that reported it; not all events 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 function 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 non-zero if FLTK understood the event. If the
window does not belong to FLTK and the add_handler()
functions all return 0, this function will return 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.
Convert a name into the red, green, and blue values of a color
by parsing the X11 color names. On other systems, fl_parse_color
can only convert names in hexadecimal encoding, for example #ff8083.
Points to 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. If FLTK was compiled with Xft support, fl_xfont
will usually be 0 and fl_xftfont will contain a pointer
to the XftFont structure instead.
If FLTK was compiled with Xft support enabled, fl_xftfont
Points to the xft font selected by the most recent fl_font(). Otherwise
it will be 0. fl_xftfont should be cast to
XftFont*.
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 MacOS and 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() will own and 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 a monochrome icon using a bitmap compiled
with your application use:
#include "icon.xbm"
fl_open_display(); // needed if display has not been previously opened
Pixmap p = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_bits, icon_width, icon_height);
window->icon((char *)p);
To use a multi-colored icon, the XPM format and library
should be used as follows:
#include <X11/xpm.h>
#include "icon.xpm"
fl_open_display(); // needed if display has not been previously opened
Pixmap p, mask;
XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_xpm, &p, &mask, NULL);
window->icon((char *)p);
When using the Xpm library, be sure to include it in the list
of libraries that are used to link the application (usually
"-lXpm").
NOTE:
You must call Fl_Window::show(argc,
argv) for the icon to be used. The
Fl_Window::show() method does not bind the icon
to the window.
|
X Resources
When the Fl_Window::show(argc,
argv) method is called, FLTK looks for the following X
resources:
- background - The default background color
for widgets (color).
- dndTextOps - The default setting for
drag and drop text operations (boolean).
- foreground - The default foreground (label)
color for widgets (color).
- scheme - The default scheme to use
(string).
- selectBackground - The default selection
color for menus, etc. (color).
- Text.background - The default background
color for text fields (color).
- tooltips - The default setting for
tooltips (boolean).
- visibleFocus - The default setting for
visible keyboard focus on non-text widgets (boolean).
Resources associated with the first window's Fl_Window::xclass()
string are queried first, or if no class has been specified then
the class "fltk" is used (e.g. fltk.background). If no
match is found, a global search is done (e.g.
*background).
The Windows (WIN32) Interface
The Windows interface provides access to the WIN32 GDI
state information and data structures.
Handling Other WIN32 Messages
By default a single WNDCLASSEX called "FLTK" is
created. All Fl_Window's 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(), as 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 regularly so that
widgets are updated, timeouts are handled, and the idle
functions are called.
This variable contains 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).
Installs 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
functions is the FLTK event that was not handled or zero for
unknown messages. If all the handlers return zero then FLTK
calls DefWindowProc().
Returns the window handle for a Fl_Window, or zero
if not shown().
Returns the Fl_Window that corresponds to the given
window handle, or NULL if not found. This function uses
a cache so it is slightly faster than iterating through the
windows yourself.
When the virtual function Fl_Widget::draw() is
called, FLTK stores all the silly extra arguments you need to
make a proper GDI call in some global variables:
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, but 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)));
You can also use the LoadImage() and related
functions to load specific resolutions or create the icon from
bitmap data.
NOTE:
You must call Fl_Window::show(argc,
argv) for the icon to be used. The
Fl_Window::show() method does not bind the icon
to the window.
|
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.
Additionally, WIN32 applications are run in the background by
the console, although you can use "start /wait program" to run
them in the foreground.
Known WIN32 Bugs and Problems
The following is a list of known bugs and problems in the WIN32
version of FLTK:
- 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. We were
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.
- SetCapture (used by Fl::grab())
doesn't work, and the main window title bar turns gray
while menus are popped up.
- Compilation with gcc 3.4.4 and -Os exposes an
optimisation bug in gcc. The symptom is that when drawing
filled circles only the perimeter is drawn. This can for instance
be seen in the symbols demo. Other optimisation options such
as -O2 and -O3 seem to work OK. More details can be found
in STR#1656
The MacOS Interface
FLTK supports MacOS X using the Apple Carbon library. Older
versions of MacOS are not supported.
Control, Option, and Command Modifier Keys
FLTK maps the Mac 'control' key to FL_CTRL, the
'option' key to FL_ALT and the 'Apple' key to
FL_META. Keyboard events return the key name in
Fl::event_key() and the keystroke translation in
Fl::event_text(). For example, typing Option-Y on a Mac
keyboard will set FL_ALT in Fl::event_state(),
set Fl::event_key() to 'y' and return the Yen symbol in
Fl::event_text().
WindowRef fl_xid(const Fl_Window *)
Returns the window reference for an Fl_Window, or
NULL if the window has not been shown.
Fl_Window *fl_find(WindowRef xid)
Returns the Fl_Window that corresponds to the give
window handle, or NULL if not found. FLTK windows that
are children of top-level windows share the WindowRef of the
top-level window.
Apple "Quit" Event
When the user press Cmd-Q or requests a termination of the
application, OS X will send a "Quit" Apple Event. FLTK handles
this event by sending an FL_CLOSE event to all open
windows. If all windows close, the application will terminate.
Apple "Open" Event
Whenever the user drops a file onto an application icon, OS X
generates an Apple Event of the type "Open". You can have FLTK
notify you of an Open event by setting the fl_open_callback.
cb will be called with a single iUnix-style file name and path.
If multiple files were dropped, fl_open_callback will be called
multiple times.
Drawing Things Using QuickDraw
When the virtual function Fl_Widget::draw() is
called, FLTK has prepared the Window and CGrafPort for drawing.
Clipping and offsets are prepared to allow correct subwindow
drawing.
Drawing Things Using Quartz
If the FLTK library was compiled using the configuration
flag --enable-quartz, all code inside Fl_Widget::draw()
is expected to call Quartz drawing functions instead of
QuickDraw. The Quartz coordinate system is flipped to match
FLTK's coordinate system. The origin for all drawing is in the top
left corner of the enclosing Fl_Window.
Fl_Double_Window
OS X double-buffers all windows automatically. On OS X,
Fl_Window and Fl_Double_Window are handled
internally in the same way.
Mac File System Specifics
Resource Forks
FLTK does not access the resource fork of an application.
However, a minimal resource fork must be created for OS X
applications
Caution:
When using UNIX commands to copy or move executables, OS X
will NOT copy any resource forks! For copying and moving use
CpMac and MvMac respectively. For creating a tar archive, all
executables need to be stripped from their Resource Fork before
packing, e.g. "DeRez fluid > fluid.r". After unpacking the
Resource Fork needs to be reattached, e.g. "Rez fluid.r -o
fluid".
|
It is advisable to use the Finder for moving and copying and
Mac archiving tools like Sit for distribution as they will
handle the Resource Fork correctly.
Mac File Paths
FLTK uses UNIX-style filenames and paths.
Known MacOS Bugs and Problems
The following is a list of known bugs and problems in the
MacOS version of FLTK:
- Line styles are not well supported. This is due to
limitations in the QuickDraw interface.
- Nested subwindows are not supported, i.e. you can
have a Fl_Window widget inside a
Fl_Window, but not a Fl_Window inside a
Fl_Window inside a Fl_Window.
From starkjohann, 09:27 Nov 18, 2005 (score=3)
The method described above for setting an X window's icon using XpmCreatePixmapFromData() is not very elegant. It requires an additional library and an image representation in xpm format.
It is much more convenient to use icon images from the user interface. These icons can be imported from many more formats with fluid. The following function sets any FL_Pixmap image (rendered on a quadratic background) as the window icon:
void setWindowIcon(Fl_Window *window, Fl_Pixmap *icon)
{
Fl_Window *dummyWindow = new Fl_Window(50, 50);
dummyWindow->show(); /* needed to define a graphics context */
dummyWindow->make_current();
btint maxDim = icon->w();
if(icon->h() > maxDim)
maxDim = icon->h();
Pixmap pixmap = fl_create_offscreen(maxDim, maxDim);
fl_begin_offscreen(pixmap);
fl_color(FL_BACKGROUND_COLOR);
fl_rectf(0, 0, maxDim, maxDim);
icon->draw((maxDim - icon->w())/2, (maxDim - icon->h())/2);
fl_end_offscreen();
dummyWindow->hide();
delete dummyWindow;
window->icon((char *)pixmap);
}
[ Reply ]From bennyp.rogers, 11:07 Mar 17, 2005 (score=3)
I'm trying to build a mac application for ZynAddSubFX, a synthesizer program (zynaddsubfx.sf.net)
I've built it so that it runs well from command line, but when I roll it up into a .app package, It does not runt because OSX adds a --psn-xxx command lise switch/flag to assign a process number. thi fix for the QT app hydrogen was to move the line QApplication() down several lines.
How shall i fix this? is there a similar function to QApplication() in FLTK?
please email me at bennyp@rogers.com
[ Reply ] From KonstantinLevinski, 18:47 Jun 08, 2004 (score=1)
To set different icons for different windows of my application, I had to dofollowing:
1) Uncomment custom class naming in Fl_X::make() function in the Win32.cxx. By default it ignored class name set with xclass(), but the windows have to be of different classes to have different icons. (dont know why it was commented out in the first place)
const char* class_name = w->xclass(); // why it was commented out???
if (!class_name) class_name = "FLTK"; // create a "FLTK" WNDCLASS
2) Use xclass to name each window differently
3) Do some strange tricks: (asume a,b,c - windows)
a->icon(); a->show(); a->hide();
b->icon(); b->show(); b->hide();
c->icon(); c->show();
//now show other 2 windows
b->show(); c->show();
Otherwise all windows get first icon.. weird.
HTH
[ Reply ] |