5f731445e7
git-svn-id: file:///fltk/svn/fltk/trunk@197 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
452 lines
17 KiB
HTML
452 lines
17 KiB
HTML
<HTML>
|
|
<BODY>
|
|
|
|
<H1 ALIGN=RIGHT><A NAME="osissues">F - Operating System Issues</A></H1>
|
|
|
|
This appendix describes the X and WIN32 specific interfaces in FLTK.
|
|
|
|
<h2>X-Specific Interface</h2>
|
|
|
|
<ul><pre>
|
|
#include <FL/x.H>
|
|
</pre></ul>
|
|
|
|
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.
|
|
|
|
<h3>Handling Other X Events</h3>
|
|
|
|
<h4><a name="add_handler">void Fl::add_handler(int (*f)(int))</a></h4>
|
|
|
|
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.
|
|
|
|
<p>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 <a href="#fl_xevent"><tt>fl_xevent</tt></a> variable.
|
|
|
|
<p>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 <tt>FL_SHORTCUT</tt>).
|
|
|
|
<h4><a name="fl_xevent">extern XEvent *fl_xvent</a></h4>
|
|
|
|
The most recent X event.
|
|
|
|
<h4><a name="fl_event_time">extern ulong fl_event_time</a></h4>
|
|
|
|
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.
|
|
|
|
<h4><a name="fl_xid">Window fl_xid(const Fl_Window *)</a></h4>
|
|
|
|
Returns the XID for a window, or zero if not <tt>shown()</tt>.
|
|
|
|
<h4><a name="fl_find">Fl_Window *fl_find(ulong xid)</a></h4>
|
|
|
|
Returns the <tt>Fl_Window</tt> that corresponds to the given XID, or
|
|
<tt>NULL</tt> if not found. This uses a cache so it is slightly faster
|
|
than iterating through the windows yourself.
|
|
|
|
<h4><a name="fl_handle">int fl_handle(const XEvent &)</a></h4>
|
|
|
|
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 <tt>add_handler()</tt> functions all ignore it this returns
|
|
false).
|
|
|
|
<p>Besides feeding events your code should call <a
|
|
href="#flush"><tt>Fl::flush()</tt></a> periodically so that FLTK
|
|
redraws its windows.
|
|
|
|
<p>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 <a href="#fl_ask"><tt>fl_ask()</tt></a>, for
|
|
instance) it will not return until the modal function returns.
|
|
|
|
<h3>Drawing using Xlib</h3>
|
|
|
|
The following global variables are set before
|
|
<tt>Fl_Widget::draw()</tt> is called, or by <a
|
|
href="#Fl_Window.make_current"><tt>Fl_Window::make_current()</tt></a>:
|
|
|
|
<ul><pre>
|
|
extern Display *fl_display;
|
|
extern Window fl_window;
|
|
extern GC fl_gc;
|
|
extern int fl_screen;
|
|
extern XVisualInfo *fl_visual;
|
|
extern Colormap fl_colormap;
|
|
</pre></ul>
|
|
|
|
You must use them to produce Xlib calls. Don't attempt to change
|
|
them. A typical X drawing call is written like this:
|
|
|
|
<ul><pre>
|
|
XDrawSomething(fl_display, fl_window, fl_gc, ...);
|
|
</pre></ul>
|
|
|
|
Other information such as the position or size of the X window can be
|
|
found by looking at <a
|
|
href="#Fl_Window.make_current"><tt>Fl_Window::current()</tt></a>, which
|
|
returns a pointer to the <tt>Fl_Window</tt> being drawn.
|
|
|
|
<h4><a name="fl_xpixel">unsigned long fl_xpixel(Fl_Color i)<br>
|
|
unsigned long fl_xpixel(uchar r, uchar g, uchar b)</a></h4>
|
|
|
|
Returns the X pixel number used to draw the given FLTK color index or
|
|
RGB color. This is the X pixel that <a
|
|
href="#fl_color"><tt>fl_color()</tt></a> would use.
|
|
|
|
<h4><a name="fl_xfont">extern XFontStruct *fl_xfont</a></h4>
|
|
|
|
Points at the font selected by the most recent <a
|
|
href="#fl_font"><tt>fl_font()</tt></a>. This is not necessarily the
|
|
current font of <tt>fl_gc</tt>, which is not set until <a
|
|
href="#fl_draw"><tt>fl_draw()</tt></a> is called.
|
|
|
|
<h3>Changing the Display, Screen, or X Visual</h3>
|
|
|
|
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
|
|
<i>before the first <tt>Fl_Window::show()</tt> is called</i>. You may
|
|
also want to call <a href="#visual">Fl::visual()</a>, which is a
|
|
portable interface to get a full color and/or double buffered visual.
|
|
|
|
<h4><a name="display">int Fl::display(const char *)</a></h4>
|
|
|
|
Set which X display to use. This actually does
|
|
<tt>putenv("DISPLAY=...")</tt> so that child programs will display on
|
|
the same screen if called with <tt>exec()</tt>. This must be done
|
|
before the display is opened. This call is provided under WIN32 but
|
|
it has no effect.
|
|
|
|
<h4><a name="fl_display">extern Display *fl_display</a></h4>
|
|
|
|
The open X display. This is needed as an argument to most Xlib calls.
|
|
Don't attempt to change it! This is <tt>NULL</tt> before the display is opened.
|
|
|
|
<h4><a name="fl_open_display">void fl_open_display()</a></h4>
|
|
|
|
Opens the display. Does nothing if it is already open. This will make
|
|
sure <tt>fl_display</tt> 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 <tt>show()</tt> of a window.
|
|
|
|
<p>This may call <tt>Fl::abort()</tt> if there is an error opening the display.
|
|
|
|
<h4><a name="fl_close_display">void fl_close_display()</a></h4>
|
|
|
|
This closes the X connection. You do <i>not</i> 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.
|
|
|
|
<h4><a name="fl_screen">extern int fl_screen</a></h4>
|
|
|
|
Which screen number to use. This is set by <tt>fl_open_display()</tt>
|
|
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 <tt>Fl::display()</tt> string to "host:0,#".
|
|
|
|
<h4><a name="fl_visual">extern XVisualInfo *fl_visual</a><br>
|
|
<a name="fl_colormap">extern Colormap fl_colormap</a></h4>
|
|
|
|
The visual and colormap that FLTK will use for all windows. These
|
|
are set by <tt>fl_open_display()</tt> to the default visual and colormap. You
|
|
can change them before calling <tt>show()</tt> on the first window. Typical
|
|
code for changing the default visual is:
|
|
|
|
<ul><pre>
|
|
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);
|
|
</pre></ul>
|
|
|
|
<h3>Using a Subclass of Fl_Window for Special X Stuff</h3>
|
|
|
|
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 <tt>draw()</tt> method that uses Xlib
|
|
(and/or OpenGL) calls only.
|
|
|
|
<p>FLTK can also manage XID's provided by other libraries or programs,
|
|
and call those libraries when the window needs to be redrawn.
|
|
|
|
<p>To do this, you need to make a subclass of <a
|
|
href="#Fl_Window"><tt>Fl_Window</tt></a> and override some of these virtual
|
|
functions:
|
|
|
|
<h4>virtual void Fl_Window::show()</h4>
|
|
|
|
If the window is already <tt>shown()</tt> this must cause it to be raised,
|
|
this can usually be done by calling <tt>Fl_Window::show()</tt>. If not <tt>shown()</tt>
|
|
your implementation must call either <tt>Fl_X::set_xid()</tt> or
|
|
<tt>Fl_X::make_xid()</tt>.
|
|
|
|
<p>An example:
|
|
|
|
<ul><pre>
|
|
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);
|
|
}
|
|
</pre></ul>
|
|
|
|
<h4>Fl_X *Fl_X::set_xid(Fl_Window *, Window xid)</h4>
|
|
|
|
Allocate a hidden structure called an <tt>Fl_X</tt>, put the XID into it, and
|
|
set a pointer to it from the <tt>Fl_Window</tt>. This causes
|
|
<tt>Fl_Window::shown()</tt> to return true.
|
|
|
|
<h4>void Fl_X::make_xid(Fl_Window *, XVisualInfo *= fl_visual, Colormap = fl_colormap)</h4>
|
|
|
|
This static method does the most onerous parts of creating an X window,
|
|
including setting the label, resize limitations, etc. It then does
|
|
<tt>Fl_X::set_xid()</tt> with this new window and maps the window.
|
|
|
|
<h4>virtual void Fl_Window::flush()</h4>
|
|
|
|
This virtual function is called by <tt>Fl::flush()</tt> to update the
|
|
window. For FLTK's own windows it does this by setting the global
|
|
variables <tt>fl_window</tt> and <tt>fl_gc</tt> and then calling the
|
|
<tt>draw()</tt> method. For your own windows you might just want to
|
|
put all the drawing code in here.
|
|
|
|
<p>The X region that is a combination of all <tt>damage()</tt> calls
|
|
done so far is in <tt>Fl_X::i(this)->region</tt>. If <tt>NULL</tt>
|
|
then you should redraw the entire window. The undocumented function
|
|
<tt>fl_clip_region(XRegion)</tt> will initialize the FLTK clip stack
|
|
with a region or <tt>NULL</tt> for no clipping. You must set region to
|
|
<tt>NULL</tt> afterwards as <tt>fl_clip_region()</tt> now owns it and
|
|
will delete it when done.
|
|
|
|
<p>If <tt>damage() & FL_DAMAGE_EXPOSE</tt> then only X expose events
|
|
have happened. This may be useful if you have an undamaged image (such
|
|
as a backing buffer) around.
|
|
|
|
<p>Here is a sample where an undamaged image is kept somewhere:
|
|
|
|
<ul><pre>
|
|
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 ...
|
|
}
|
|
</pre></ul>
|
|
|
|
<h4>virtual void Fl_Window::hide()</h4>
|
|
|
|
Destroy the window server copy of the window. Usually you will destroy
|
|
contexts, pixmaps, or other resources used by the window, and then call
|
|
<tt>Fl_Window::hide()</tt> to get rid of the main window identified by
|
|
<tt>xid()</tt>. If you override this, you must also override the
|
|
destructor as shown:
|
|
|
|
<ul><pre>
|
|
void MyWindow::hide() {
|
|
if (mypixmap) {
|
|
XFreePixmap(fl_display,mypixmap);
|
|
mypixmap = 0;
|
|
}
|
|
Fl_Window::hide(); // you must call this
|
|
}
|
|
</pre></ul>
|
|
|
|
<h4>virtual void Fl_Window::~Fl_Window()</h4>
|
|
|
|
Because of the way C++ works, if you override <tt>hide()</tt> you <i>must</i>
|
|
override the destructor as well (otherwise only the base class <tt>hide()</tt>
|
|
is called):
|
|
|
|
<ul><pre>
|
|
MyWindow::~MyWindow() {
|
|
hide();
|
|
}
|
|
</pre></ul>
|
|
|
|
<h3>Setting the Icon of a Window</h3>
|
|
|
|
FLTK currently supports setting a window's icon *before* it is shown using
|
|
the <tt>Fl_Window::icon()</tt> method.
|
|
|
|
<h4>void Fl_Window::icon(char *)</h4>
|
|
|
|
Sets the icon for the window to the passed pointer. You will need to
|
|
cast the icon <tt>Pixmap</tt> to a <tt>char *</tt> when calling this
|
|
method. To set the icon using a bitmap compiled with your application
|
|
use:
|
|
|
|
<ul><pre>
|
|
#include "icon.xbm"
|
|
|
|
Pixmap p = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
|
|
icon_bits, icon_width, icon_height);
|
|
|
|
window->icon((char *)p);
|
|
</ul></pre>
|
|
|
|
<h2>WIN32-Specific Interface</h2>
|
|
|
|
<ul><pre>
|
|
#include <FL/x.H>
|
|
</pre></ul>
|
|
|
|
The <tt><FL/x.H></tt> 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.
|
|
|
|
<h3>Handling Other WIN32 Messages</h3>
|
|
|
|
By default a single WNDCLASSEX called "FLTK" is created. All
|
|
<tt>Fl_Windows</tt> are of this class unless you use
|
|
<tt>Fl_Window::xclass()</tt>. The window class is created the first
|
|
time <tt>Fl_Window::show()</tt> is called.
|
|
|
|
<p>You can probably combine FLTK with other libraries that make their
|
|
own WIN32 window classes. The easiest way is to call <tt>Fl::wait()</tt>, it
|
|
will call <tt>DispatchMessage</tt> for all messages to the other windows. If
|
|
necessary you can let the other library take over (as long as it calls
|
|
<tt>DispatchMessage()</tt>), but you will have to arrange for the function
|
|
<tt>Fl::flush()</tt> to be called regularily so that widgets are updated,
|
|
timeouts are handled, and the idle functions are called.
|
|
|
|
<h4><a name="fl_msg">extern MSG fl_msg</a></h4>
|
|
|
|
The most recent message read by <tt>GetMessage</tt> (which is called by
|
|
<a href="#wait"><tt>Fl::wait()</tt></a>. 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).
|
|
|
|
<h4><a name="WIN32.add_handler">void Fl::add_handler(int (*f)(int))</a></h4>
|
|
|
|
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 <tt>DefWindowProc()</tt>.
|
|
|
|
<h4><a name="WIN32.fl_xid">HWND fl_xid(const Fl_Window *)</a></h4>
|
|
|
|
Returns the window handle for a <tt>Fl_Window</tt>, or zero if not
|
|
<tt>shown()</tt>.
|
|
|
|
<h4><a name="WIN32.fl_find">Fl_Window *fl_find(HWND xid)</a></h4>
|
|
|
|
Return the <tt>Fl_Window</tt> that corresponds to the given window
|
|
handle, or <tt>NULL</tt> if not found. This uses a cache so it is
|
|
slightly faster than iterating through the windows yourself.
|
|
|
|
<h3>Drawing Things Using the WIN32 GDI</h3>
|
|
|
|
When the virtual function <tt>Fl_Widget::draw()</tt> is called, FLTK has
|
|
stashed in some global variables all the silly extra arguments you
|
|
need to make a proper GDI call. These are:
|
|
|
|
<ul><pre>
|
|
extern HINSTANCE fl_display;
|
|
extern HWND fl_window;
|
|
extern HDC fl_gc;
|
|
COLORREF fl_RGB();
|
|
HPEN fl_pen();
|
|
HBRUSH fl_brush();
|
|
</pre></ul>
|
|
|
|
These global variables are set before <tt>draw()</tt> is called, or by <a
|
|
href="#Fl_Window.make_current"><tt>Fl_Window::make_current()</tt></a>. 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 <tt>fl_color()</tt> and are created as needed and cached. A typical
|
|
GDI drawing call is written like this:
|
|
|
|
<ul><pre>
|
|
DrawSomething(fl_gc, ..., fl_brush());
|
|
</pre></ul>
|
|
|
|
It may also be useful to refer to <a
|
|
href="#Fl_Window.make_current"><tt>Fl_Window::current()</tt></a> to get
|
|
the window's size or position.
|
|
|
|
<h3>Setting the Icon of a Window</h3>
|
|
|
|
FLTK currently supports setting a window's icon *before* it is shown using
|
|
the <tt>Fl_Window::icon()</tt> method.
|
|
|
|
<h4>void Fl_Window::icon(char *)</h4>
|
|
|
|
Sets the icon for the window to the passed pointer. You will need to
|
|
cast the <tt>HICON</tt> handle to a <tt>char *</tt> when calling this
|
|
method. To set the icon using an icon resource compiled with your
|
|
application use:
|
|
|
|
<ul><pre>
|
|
window->icon((char *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
|
|
</ul></pre>
|
|
|
|
<h3>How to Not Get a MSDOS Console Window</h3>
|
|
|
|
WIN32 has a really stupid mode switch stored in the executables that
|
|
controls whether or not to make a console window.
|
|
|
|
<p>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).
|
|
|
|
<p>FLTK includes a <tt>WinMain()</tt> function that calls the ANSI
|
|
standard <tt>main()</tt> entry point for you. <i>This function creates
|
|
a console window when you use the debug version of the library.</i>
|
|
|
|
<p>WIN32 applications without a console cannot write to <tt>stdout</tt> or
|
|
<tt>stderr</tt>, even if they are run from a console window. Any output
|
|
is silently thrown away.
|
|
|
|
<h3>Known Bugs</h3>
|
|
|
|
If a program is deactivated, <tt>Fl::wait()</tt> 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.
|
|
|
|
<p><tt>Fl_Gl_Window::can_do_overlay()</tt> returns true until the first
|
|
time it attempts to draw an overlay, and then correctly returns whether
|
|
or not there is overlay hardware.
|
|
|
|
<p>Cut text contains ^J rather than ^M^J to break lines. This is a
|
|
feature, not a bug.
|
|
|
|
<p><tt>SetCapture</tt> (used by <tt>Fl::grab()</tt>) doesn't work, and
|
|
the main window title bar turns gray while menus are popped up.
|
|
|
|
<p>FLUID does not support BMP files yet.
|
|
|
|
</BODY>
|
|
</HTML>
|