fltk/forms.h File Reference

#include <fltk/Fl.h>
#include <fltk/Fl_Group.h>
#include <fltk/Fl_Window.h>
#include <fltk/fl_draw.h>
#include "Fl_FormsBitmap.h"
#include "Fl_FormsPixmap.h"
#include <fltk/Fl_Box.h>
#include <fltk/Fl_Browser.h>
#include <fltk/Fl_Button.h>
#include <fltk/Fl_Light_Button.h>
#include <fltk/Fl_Round_Button.h>
#include <fltk/Fl_Check_Button.h>
#include "Fl_Chart.h"
#include <fltk/Fl_Choice.h>
#include <fltk/Fl_Clock.h>
#include <fltk/Fl_Counter.h>
#include <fltk/Fl_Dial.h>
#include "Fl_Free.h"
#include <fltk/fl_ask.h>
#include <fltk/fl_show_colormap.h>
#include <fltk/filename.h>
#include <fltk/fl_file_chooser.h>
#include <fltk/Fl_Input.h>
#include <fltk/Fl_Menu_Button.h>
#include "Fl_Positioner.h"
#include <fltk/Fl_Slider.h>
#include <fltk/Fl_Value_Slider.h>
#include "Fl_Timer.h"

Detailed Description

This file provides Forms compatibility in FLTK 2.0. This documentation is old and may be inaccurate.

Forms was a popular GUI library on SGI machines before they switched to using X (they used to be GL only, actually a lot more powerful and useful than X or Win32 is today...). It was created by Mark Overmars at ???. X-Forms is a rewrite to work atop X, but unlike Forms it was not distributed as Open Source. Much of FLTK's terminology and widget design is based on and directly descended from Forms.

Importing Forms Layout Files

Fluid can read the .fd files put out by all versions of Forms and XForms fdesign. However, it will mangle them a bit, but it prints a warning message about anything it does not understand. FLUID cannot write fdesign files, so you should save to a new name so you don't write over the old one.

You will need to edit your main code considerably to get it to link with the output from FLUID. If you are not interested in this you may have more immediate luck with the forms compatibility header, <FL/forms.h>.

Using the Compatibility Header File

You should be able to compile existing Forms or XForms source code by changing the include directory switch to your compiler so that the forms.h file supplied with FLTK is included. Take a look at forms.h to see how it works, but the basic trick is lots of inline functions. Most of the XForms demo programs work without changes.

You will also have to compile your Forms or XForms program using a C++ compiler. The FLTK library does not provide C bindings or header files.

Although FLTK was designed to be compatible with the GL Forms library (version 0.3 or so), XForms has bloated severely and it's interface is X-specific. Therefore, XForms compatibility is no longer a goal of FLTK. Compatibility was limited to things that were free, or that would add code that would not be linked in if the feature is unused, or that was not X-specific.

To use any new features of FLTK, you should rewrite your code to not use the inline functions and instead use "pure" FLTK. This will make it a lot cleaner and make it easier to figure out how to call the FLTK functions. Unfortunately this conversion is harder than expected and even Digital Domain's inhouse code still uses forms.H a lot.

Forms-specific Widget classes

The following widget classes are provided to allow direct porting of Forms programs. They should not be used in normal FLTK programs.

  • Fl_FormsBitmap
  • Fl_FormsPixmap
  • Fl_Free
  • Fl_Timer

Problems You Will Encounter

Many parts of XForms use X-specific structures like XEvent in their interface. I did not emulate these! Unfortunately these features (such as the "canvas" widget) are needed by most large programs. You will need to rewrite these to use FLTK subclasses.

Fl_Free widgets emulate the old Forms "free" widget. It may be useful for porting programs that change handle() function on widgets, but you will still need to rewrite things.

Fl_Timer widgets are provided to emulate the XForms timer. These work, but are quite inefficient and inaccurate compared to using fltk::add_timeout().

All instance variables are hidden. If you directly refer to the x, y, w, h, label, or other fields of your Forms widgets you will have to add empty parenthesis after each reference. The easiest way to do this is to globally replace "->x" with "->x()", etc. Replace "boxtype" with "box()".

const char * arguments to most FLTK methods are simply stored, while Forms would strdup() the passed string. This is most noticeable with the label of widgets. Your program must always pass static data such as a string constant or malloc'd buffer to label(). If you are using labels to display program output you may need to change the calls to Widget::copy_label().

The default fonts and sizes are matched to the older GL version of Forms, so all labels will draw somewhat larger than an XForms program does.

fdesign outputs a setting of a "fdui" instance variable to the main window. I did not emulate this because I wanted all instance variables to be hidden. You can store the same information in the Widget::user_data() field of a window. To do this, search through the fdesign output for all occurrences of "->fdui" and edit to use "->user_data()" instead. This will require casts and is not trivial.

The prototype for the functions passed to fl_add_timeout() and fl_set_idle_callback() callback are different.

All the following XForms calls are missing:

  • FL_REVISION, fl_library_version()
  • FL_RETURN_DBLCLICK (use fl_event_clicks())
  • fl_add_signal_callback()
  • fl_set_form_atactivate() fl_set_form_atdeactivate()
  • fl_set_form_property()
  • fl_set_app_mainform(), fl_get_app_mainform()
  • fl_set_form_minsize(), fl_set_form_maxsize()
  • fl_set_form_event_cmask(), fl_get_form_event_cmask()
  • fl_set_form_dblbuffer(), fl_set_object_dblbuffer() (use an Fl_DoubleBufferWindow instead)
  • fl_adjust_form_size()
  • fl_register_raw_callback()
  • fl_set_object_bw(), fl_set_border_width()
  • fl_set_object_resize(), fl_set_object_gravity()
  • fl_set_object_shortcutkey()
  • fl_set_object_automatic()
  • fl_get_object_bbox() (maybe FLTK should do this)
  • fl_set_object_prehandler(), fl_set_object_posthandler()
  • fl_enumerate_fonts()
  • Most drawing functions
  • fl_set_coordunit() (FLTK uses pixels all the time)
  • fl_ringbell()
  • fl_gettime()
  • fl_win*() (all these functions)
  • fl_initialize(argc,argv,x,y,z) ignores last 3 arguments
  • fl_read_bitmapfile(), fl_read_pixmapfile()
  • fl_addto_browser_chars()
  • FL_MENUBUTTON just draws normally
  • fl_set_bitmapbutton_file(), fl_set_pixmapbutton_file()
  • FL_CANVAS objects
  • FL_DIGITAL_CLOCK (comes out analog)
  • fl_create_bitmap_cursor(), fl_set_cursor_color()
  • fl_set_dial_angles()
  • fl_show_oneliner()
  • fl_set_choice_shortcut(a,b,c)
  • command log
  • Only some of file selector is emulated
  • FL_DATE_INPUT
  • fl_pup*() (all these functions)
  • textbox object (should be easy but I had no sample programs)
  • xyplot object

You Cannot Make Forms Subclasses

Programs that call fl_make_object or directly setting the handle routine will not compile. You have to rewrite them to use a subclass of fltk::Widget. It is important to note that the Widget::handle() method is not exactly the same as the handle() function of Forms. Where a Forms handle() returned non-zero to trigger the widget callback, Widget::handle() must call Widget::do_callback(). And Widget::handle() must return non-zero if it "understood" the event.

An attempt has been made to emulate the "free" widget. This appears to work quite well. It may be quicker to modify your subclass into a "free" widget, since the "handle" functions match.

If your subclass draws into the overlay you are in trouble and will have to rewrite things a lot.

You Cannot Use <device.h>

If you have written your own "free" widgets you will probably get a lot of errors about "getvaluator". You should substitute:

FormsFLTK
MOUSE_Xfltk::event_x_root()
MOUSE_Yfltk::event_y_root()
LEFTSHIFTKEY,RIGHTSHIFTKEYfltk::event_state(fltk::SHIFT)
CAPSLOCKKEYfltk::event_state(fltk::CAPS_LOCK)
LEFTCTRLKEY,RIGHTCTRLKEYfltk::event_state(fltk::CTRL)
LEFTALTKEY,RIGHTALTKEYfltk::event_state(fltk::ALT)
MOUSE1,RIGHTMOUSEfltk::event_state(fltk::BUTTON1)
MOUSE2,MIDDLEMOUSEfltk::event_state(fltk::BUTTON2)
MOUSE3,LEFTMOUSEfltk::event_state(fltk::BUTTON3)

Anything else in getvaluator and you are on your own...

Font Numbers Are Different

The "style" numbers have been changed because I wanted to insert bold-italic versions of the normal fonts. If you use Times, Courier, or Bookman to display any text you will get a different font out of FLTK. Add one to the index for these.