# System-Specific Interfaces

## X11/Unix

#### `#include <fltk/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.

#### void fltk::add_handler(int (*f)(int))

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 `fltk::PUSH`). For keystrokes it will be `fltk::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 `fltk::xevent` variable.

#### extern XEvent* fltk::xvent

The most recent X event.

#### extern ulong fltk::event_time

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 that reported it (not all do). Many X calls (like cut and paste) need this value.

#### int fltk::handle(const XEvent &)

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 `fltk::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 `fltk::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 `fltk::ask()`, it will not return until the user clicks yes or no.

#### int fltk::display(const char*)

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 `fltk::open_display` is called. This call is provided under WIN32 but it has no effect.

#### void fltk::open_display()

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 fltk::Window::show()`.

This may call `fltk::abort()` if there is an error opening the display.

#### void fltk::open_display(Display*)

You can make fltk "open" a display that has already been opened, perhaps by another GUI library. Calling this will set `fltk::display` to the passed display and also read information fltk needs from it. Don't call this if the display is already open!

#### extern Display* fltk::display

The open X display. This is needed as an argument to most Xlib calls. Don't attempt to change it! This is `NULL` before `fltk::open_display` is called.

#### extern Window fltk::message_window

This dummy 1x1 window is created by `fltk::open_display()` and is never destroyed. You can use it to communicate with the window manager or other programs.

#### extern int fltk::screen

Which screen number to use. This is set by `fltk::open_display()` to the default screen. You can change it by setting this to a different value immediately afterwards.

#### extern XVisualInfo* fltk::visual
extern Colormap fltk::colormap

The visual and colormap that FLTK will use for all windows. These are set by `fltk::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:

    fltk::args(argc, argv); // do this first so $DISPLAY is set
    fltk::open_display();
    fltk::visual = find_a_good_visual(fltk::display, fltk::screen);
    if (!fltk::visual) fltk::abort("No good visual");
    fltk::colormap = make_a_colormap(fltk::display, fltk::visual->visual, fltk::visual->depth);
    // it is now ok to show() windows:
    window->show(argc, argv);

You may also want to call fltk::visual(), which is a portable interface to get a full color and/or double buffered visual.

#### Window fltk::xid(const fltk::Window*)

Returns the XID for a window, or zero if not `shown()`.

#### fltk::Window* fltk::find(ulong xid)

Returns the `fltk::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.

#### extern Window fltk::window;
extern GC fltk::gc;

These variables are set before `fltk::Widget::draw()` is called, or by `fltk::Window::make_current()`. They are needed by most Xlib drawing calls, a typical call is like this:

    XDrawSomething(fltk::display, fltk::window, fltk::gc, ...);

Notice that `fltk::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 `fltk::Window::current()`, which returns a pointer to the `fltk::Window` being drawn.

#### Region fltk::clip_region();

Return the current clip region, or `NULL` if we are currently clipping to the entire window. Notice that this will be destroyed by the next change to the clipping, copy it if you want to keep it.

#### void fltk::clip_region(Region);

Replace the current clip region with this one, or make there be no clipping if `NULL` is passed. The old clip region is destroyed.

#### unsigned long fltk::xpixel(fltk::Color i)

Returns the X pixel number used to draw the given FLTK color index or RGB color. This is the X pixel that `fltk::color(i)` would use.

#### extern XFontStruct* fltk::xfont

Points at the font selected by the most recent `fltk::font()`. This is not necessarily the current font of `fltk::gc`, which is not set until `fltk::draw()` is called.

#### void fltk::close_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.

#### static void fltk::Window::xclass(const char*)
static const char* fltk::Window::xclass() const

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. `fltk::args(...)` will set this to the name of the program.

This call is provided on WIN32 for compatability, but the value is ignored.

#### void fltk::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(fltk::display, DefaultRootWindow(fltk::display),
                                     icon_bits, icon_width, icon_height);

    window->icon((char*)p);

This only works if called before it is shown using the `fltk::Window::show()` method.

### Drag & Drop information

The `fltk::dnd_*` variables allow your fltk program to use the Xdnd protocol to manipulate files and interact with file managers. You can ignore these if you just want to drag & drop blocks of text. I have little information on how to use these, I just tried to clean up the Xlib interface and present the variables nicely.

#### Window fltk::dnd_source_window

The id of the window being dragged from.

#### Atom fltk::dnd_source_action

The action the source program wants to perform. Due to oddities in the Xdnd design this variable is not set on the `fltk::DND_ENTER` event, instead it is set on each `fltk::DND_DRAG` event, and it may change each time.

To print the string value of the `Atom` use this code:

    char* x = XGetAtomName(fltk::display, fltk::dnd_source_action);
    puts(x);
    XFree(x);

You can set this before calling `fltk::dnd()` to communicate a different action. See `fltk::dnd_source_types`, which you must also set.

#### Atom fltk::dnd_action

The program can set this before returning non-zero for an `fltk::DND_DRAG` event to indicate what it will do to the object. Fltk presets this to `XdndActionCopy` so that is returned if you don't set it.

#### Atom *fltk::dnd_source_types

Zero-terminated list of atoms describing the formats of the source data. This is set on the `fltk::DND_ENTER` event. The following code will print them all as text, a typical value is `"text/plain;charset=UTF-8"` (gag).

    for (int i = 0; fltk::dnd_source_types[i]; i++) {
      char* x = XGetAtomName(fltk::display, fltk::dnd_source_types[i]);
      puts(x);
      XFree(x);
    }

You can set this and `fltk::dnd_source_action` before calling `fltk::dnd()` to change information about the source. You must set both of these, if you don't fltk will default to `"text/plain"` as the type and `XdndActionCopy` as the action. To set this change it to point at your own array. Only the first 3 types are sent. Also, fltk has no support for reporting back what type the target requested, so all your types must use the same block of data.

#### Atom fltk::dnd_type

The program can set this when returning non-zero for an `fltk::DND_RELEASE` event to indicate the translation wanted. Fltk presets this to `"text/plain"` so that is returned if you don't set it (supposedly it should be limited to one of the values in `fltk::dnd_source_types`, but `"text/plain"` appears to always work).

### Using a Subclass of fltk::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 `fltk::Window` and override some of these virtual functions:

#### virtual void fltk::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 `fltk::X::create()`. Do not map the window, fltk does that for you.

An example:

    void MyWindow::create() {
      fltk::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(fltk::display, RootWindow(fltk::display,fltk::screen),
    			        vis->visual, AllocNone);
        XColor xcol; xcol.red = 1; xcol.green = 2; xcol.blue = 3;
        XAllocColor(fltk::display, colormap, &xcol);
        background = xcol.pixel;
      }
      fltk::X::create(this, visual, colormap, background);
    }

#### void fltk::X::create(fltk::Window*, XVisualInfo*, Colormap, int background=-1)

This function calls XCreateWindow and sets things up so that `fltk::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 fltk::Window::flush()

This virtual function is called by `fltk::flush()` to update the window. For FLTK's own windows it does this by setting the global variables `fltk::window` and `fltk::gc` and then calling the `draw()` method. For your own windows you might just want to put all the drawing code in here.

X `Expose` events (and calls to `expose()` of the window or any widget inside it) turn on the `fltk::DAMAGE_EXPOSE` bit in `damage()`, and the regions of all of them are are accumulated into an X region that you can get from `fltk::X::i(this)->region`. This is set to `NULL` if the entire window is damaged. The undocumented function `fltk::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 `fltk::clip_region()` now owns it and will delete it when done.

Any other bits set in `damage()` indicate calls to `redraw()` were done. Notice that the damaged items may be outside the `fltk::X::i(this)->region`.

If `damage() == fltk::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() {
      if (damage() == fltk::DAMAGE_EXPOSE) {
        fltk::clip_region(fltk::X::i(this)->region);
        fltk::X::i(this)->region = 0;
        copy_image(backing_store_pixmap, fltk::xid(this));
      } else {
        fltk::window = backing_store_pixmap;
        fltk::gc = backing_store_gc;
        this->draw();
        copy_image(backing_store_pixmap, fltk::xid(this));
      }
    }

#### virtual void fltk::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 `fltk::Window::hide()` to get rid of the main window identified by `xid()`.

    void MyWindow::destroy() {
      if (backing_store_pixmap) {
        XFreePixmap(fltk::display, backing_store_pixmap);
        backing_store_pixmap = 0;
      }
      fltk::Window::destroy(); // you must call this
    }

#### virtual void fltk::Window::~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();
    }