summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING482
-rw-r--r--FL/Enumerations.H293
-rw-r--r--FL/Fl.H195
-rw-r--r--FL/Fl_Adjuster.H26
-rw-r--r--FL/Fl_Bitmap.H24
-rw-r--r--FL/Fl_Box.H19
-rw-r--r--FL/Fl_Browser.H86
-rw-r--r--FL/Fl_Browser_.H123
-rw-r--r--FL/Fl_Button.H48
-rw-r--r--FL/Fl_Chart.H65
-rw-r--r--FL/Fl_Check_Button.H15
-rw-r--r--FL/Fl_Choice.H20
-rw-r--r--FL/Fl_Clock.H38
-rw-r--r--FL/Fl_Color_Chooser.H71
-rw-r--r--FL/Fl_Counter.H47
-rw-r--r--FL/Fl_Dial.H43
-rw-r--r--FL/Fl_Double_Window.H23
-rw-r--r--FL/Fl_Fill_Dial.H12
-rw-r--r--FL/Fl_Fill_Slider.H12
-rw-r--r--FL/Fl_Float_Input.H12
-rw-r--r--FL/Fl_FormsBitmap.H23
-rw-r--r--FL/Fl_FormsPixmap.H23
-rw-r--r--FL/Fl_Free.H40
-rw-r--r--FL/Fl_Gl_Window.H60
-rw-r--r--FL/Fl_Group.H73
-rw-r--r--FL/Fl_Hold_Browser.H12
-rw-r--r--FL/Fl_Hor_Fill_Slider.H12
-rw-r--r--FL/Fl_Hor_Nice_Slider.H12
-rw-r--r--FL/Fl_Hor_Slider.H12
-rw-r--r--FL/Fl_Hor_Value_Slider.H12
-rw-r--r--FL/Fl_Image.H22
-rw-r--r--FL/Fl_Input.H22
-rw-r--r--FL/Fl_Input_.H107
-rw-r--r--FL/Fl_Int_Input.H12
-rw-r--r--FL/Fl_Light_Button.H23
-rw-r--r--FL/Fl_Line_Dial.H12
-rw-r--r--FL/Fl_Menu.H2
-rw-r--r--FL/Fl_Menu_.H82
-rw-r--r--FL/Fl_Menu_Bar.H27
-rw-r--r--FL/Fl_Menu_Button.H19
-rw-r--r--FL/Fl_Menu_Item.H134
-rw-r--r--FL/Fl_Menu_Window.H29
-rw-r--r--FL/Fl_Multi_Browser.H12
-rw-r--r--FL/Fl_Multi_Label.H18
-rw-r--r--FL/Fl_Multiline_Input.H12
-rw-r--r--FL/Fl_Multiline_Output.H12
-rw-r--r--FL/Fl_Nice_Slider.H12
-rw-r--r--FL/Fl_Object.H5
-rw-r--r--FL/Fl_Output.H18
-rw-r--r--FL/Fl_Overlay_Window.H31
-rw-r--r--FL/Fl_Pack.H22
-rw-r--r--FL/Fl_Pixmap.H22
-rw-r--r--FL/Fl_Positioner.H51
-rw-r--r--FL/Fl_Radio_Button.H12
-rw-r--r--FL/Fl_Radio_Light_Button.H12
-rw-r--r--FL/Fl_Radio_Round_Button.H12
-rw-r--r--FL/Fl_Repeat_Button.H18
-rw-r--r--FL/Fl_Return_Button.H19
-rw-r--r--FL/Fl_Roller.H19
-rw-r--r--FL/Fl_Round_Button.H15
-rw-r--r--FL/Fl_Round_Clock.H12
-rw-r--r--FL/Fl_Scroll.H50
-rw-r--r--FL/Fl_Scrollbar.H30
-rw-r--r--FL/Fl_Secret_Input.H12
-rw-r--r--FL/Fl_Select_Browser.H12
-rw-r--r--FL/Fl_Simple_Counter.H12
-rw-r--r--FL/Fl_Single_Window.H20
-rw-r--r--FL/Fl_Slider.H46
-rw-r--r--FL/Fl_Tabs.H31
-rw-r--r--FL/Fl_Tile.H18
-rw-r--r--FL/Fl_Timer.H38
-rw-r--r--FL/Fl_Toggle_Button.H12
-rw-r--r--FL/Fl_Toggle_Light_Button.H6
-rw-r--r--FL/Fl_Toggle_Round_Button.H6
-rw-r--r--FL/Fl_Valuator.H59
-rw-r--r--FL/Fl_Value_Input.H50
-rw-r--r--FL/Fl_Value_Output.H32
-rw-r--r--FL/Fl_Value_Slider.H26
-rw-r--r--FL/Fl_Widget.H178
-rw-r--r--FL/Fl_Window.H90
-rw-r--r--FL/dirent.h4
-rw-r--r--FL/filename.H41
-rw-r--r--FL/fl_ask.H51
-rw-r--r--FL/fl_draw.H135
-rw-r--r--FL/fl_file_chooser.H9
-rw-r--r--FL/fl_message.H2
-rw-r--r--FL/fl_show_colormap.H10
-rw-r--r--FL/fl_show_input.H2
-rw-r--r--FL/forms.H810
-rw-r--r--FL/gl.h42
-rw-r--r--FL/gl2opengl.h35
-rw-r--r--FL/gl_draw.H2
-rw-r--r--FL/glut.H443
-rw-r--r--FL/math.h27
-rw-r--r--FL/menubar.h64
-rw-r--r--FL/win32.H80
-rw-r--r--FL/x.H87
-rw-r--r--GL/glut.h3
-rw-r--r--Makefile49
-rw-r--r--README123
-rw-r--r--configh.in53
-rwxr-xr-xconfigure2721
-rw-r--r--configure.in106
-rw-r--r--documentation/CHANGES411
-rw-r--r--fluid/Fl_Function_Type.cxx669
-rw-r--r--fluid/Fl_Group_Type.cxx245
-rw-r--r--fluid/Fl_Menu_Type.cxx487
-rw-r--r--fluid/Fl_Type.cxx617
-rw-r--r--fluid/Fl_Type.h142
-rw-r--r--fluid/Fl_Widget_Type.cxx1676
-rw-r--r--fluid/Fl_Widget_Type.h67
-rw-r--r--fluid/Fl_Window_Type.cxx666
-rw-r--r--fluid/Fluid_Image.cxx384
-rw-r--r--fluid/Fluid_Image.h28
-rw-r--r--fluid/Makefile83
-rw-r--r--fluid/README214
-rw-r--r--fluid/Shortcut_Button.h10
-rw-r--r--fluid/about_panel.cxx122
-rw-r--r--fluid/about_panel.fl71
-rw-r--r--fluid/about_panel.h12
-rw-r--r--fluid/alignment_panel.cxx73
-rw-r--r--fluid/alignment_panel.fl65
-rw-r--r--fluid/alignment_panel.h17
-rw-r--r--fluid/class.C123
-rw-r--r--fluid/class.H34
-rw-r--r--fluid/code.cxx263
-rw-r--r--fluid/factory.cxx651
-rw-r--r--fluid/file.cxx562
-rw-r--r--fluid/fluid.cxx387
-rw-r--r--fluid/function_panel.cxx262
-rw-r--r--fluid/function_panel.fl164
-rw-r--r--fluid/function_panel.h46
-rw-r--r--fluid/gif.cxx336
-rw-r--r--fluid/keyboard_ui.cxx536
-rw-r--r--fluid/keyboard_ui.h8
-rw-r--r--fluid/penne.C85
-rw-r--r--fluid/penne.H32
-rw-r--r--fluid/primes.fl22
-rw-r--r--fluid/widget_panel.cxx316
-rw-r--r--fluid/widget_panel.fl300
-rw-r--r--fluid/widget_panel.h61
-rw-r--r--forms.h3
-rw-r--r--install-sh238
-rw-r--r--lib/...0
-rwxr-xr-xmakedist26
-rwxr-xr-xmakefiles/aixmakesharedlib24
-rw-r--r--makefiles/makeinclude.cygnus43
-rw-r--r--makefiles/makeinclude.mingw3236
-rw-r--r--makeinclude.in32
-rw-r--r--src/Fl.cxx566
-rw-r--r--src/Fl_Adjuster.cxx105
-rw-r--r--src/Fl_Bitmap.cxx109
-rw-r--r--src/Fl_Box.cxx11
-rw-r--r--src/Fl_Browser.cxx421
-rw-r--r--src/Fl_Browser_.cxx606
-rw-r--r--src/Fl_Browser_load.cxx29
-rw-r--r--src/Fl_Button.cxx92
-rw-r--r--src/Fl_Chart.cxx344
-rw-r--r--src/Fl_Check_Button.cxx15
-rw-r--r--src/Fl_Choice.cxx63
-rw-r--r--src/Fl_Clock.cxx136
-rw-r--r--src/Fl_Color_Chooser.cxx397
-rw-r--r--src/Fl_Counter.cxx140
-rw-r--r--src/Fl_Dial.cxx113
-rw-r--r--src/Fl_Double_Window.cxx157
-rw-r--r--src/Fl_Font.H63
-rw-r--r--src/Fl_Gl_Choice.H57
-rw-r--r--src/Fl_Gl_Choice.cxx157
-rw-r--r--src/Fl_Gl_Overlay.cxx175
-rw-r--r--src/Fl_Gl_Window.cxx287
-rw-r--r--src/Fl_Group.cxx443
-rw-r--r--src/Fl_Image.cxx62
-rw-r--r--src/Fl_Input.cxx299
-rw-r--r--src/Fl_Input_.cxx704
-rw-r--r--src/Fl_Light_Button.cxx47
-rw-r--r--src/Fl_Menu.cxx694
-rw-r--r--src/Fl_Menu_.cxx96
-rw-r--r--src/Fl_Menu_Bar.cxx33
-rw-r--r--src/Fl_Menu_Button.cxx57
-rw-r--r--src/Fl_Menu_Window.cxx130
-rw-r--r--src/Fl_Menu_add.cxx151
-rw-r--r--src/Fl_Menu_global.cxx20
-rw-r--r--src/Fl_Multi_Label.cxx51
-rw-r--r--src/Fl_Output.cxx23
-rw-r--r--src/Fl_Overlay_Window.cxx115
-rw-r--r--src/Fl_Pack.cxx78
-rw-r--r--src/Fl_Pixmap.cxx113
-rw-r--r--src/Fl_Positioner.cxx106
-rw-r--r--src/Fl_Repeat_Button.cxx36
-rw-r--r--src/Fl_Return_Button.cxx42
-rw-r--r--src/Fl_Roller.cxx111
-rw-r--r--src/Fl_Round_Button.cxx15
-rw-r--r--src/Fl_Scroll.cxx210
-rw-r--r--src/Fl_Scrollbar.cxx158
-rw-r--r--src/Fl_Single_Window.cxx14
-rw-r--r--src/Fl_Slider.cxx200
-rw-r--r--src/Fl_Tabs.cxx234
-rw-r--r--src/Fl_Tile.cxx173
-rw-r--r--src/Fl_Valuator.cxx100
-rw-r--r--src/Fl_Value_Input.cxx100
-rw-r--r--src/Fl_Value_Output.cxx73
-rw-r--r--src/Fl_Value_Slider.cxx45
-rw-r--r--src/Fl_Widget.cxx164
-rw-r--r--src/Fl_Window.cxx83
-rw-r--r--src/Fl_Window_fullscreen.cxx46
-rw-r--r--src/Fl_Window_hotspot.cxx27
-rw-r--r--src/Fl_Window_iconize.cxx19
-rw-r--r--src/Fl_XColor.H18
-rw-r--r--src/Fl_abort.cxx51
-rw-r--r--src/Fl_add_idle.cxx62
-rw-r--r--src/Fl_arg.cxx377
-rw-r--r--src/Fl_cutpaste.cxx127
-rw-r--r--src/Fl_cutpaste_win32.cxx106
-rw-r--r--src/Fl_display.cxx16
-rw-r--r--src/Fl_get_key.cxx37
-rwxr-xr-xsrc/Fl_get_key_win32.cxx108
-rw-r--r--src/Fl_get_system_colors.cxx66
-rw-r--r--src/Fl_own_colormap.cxx50
-rw-r--r--src/Fl_visual.cxx78
-rw-r--r--src/Fl_win32.cxx696
-rw-r--r--src/Fl_x.cxx807
-rw-r--r--src/Makefile215
-rw-r--r--src/cmap.cxx120
-rw-r--r--src/d1.xbm6
-rw-r--r--src/d1_mask.xbm6
-rw-r--r--src/dump_compose.c26
-rw-r--r--src/ew.xbm8
-rw-r--r--src/ew_mask.xbm8
-rw-r--r--src/fastarrow.h6
-rw-r--r--src/filename_absolute.cxx67
-rw-r--r--src/filename_expand.cxx72
-rw-r--r--src/filename_ext.cxx17
-rw-r--r--src/filename_isdir.cxx12
-rw-r--r--src/filename_list.cxx36
-rw-r--r--src/filename_match.cxx74
-rw-r--r--src/filename_setext.cxx12
-rw-r--r--src/fl_arc.cxx50
-rw-r--r--src/fl_arci.cxx45
-rw-r--r--src/fl_ask.cxx165
-rw-r--r--src/fl_boxtype.cxx256
-rw-r--r--src/fl_cmap.h256
-rw-r--r--src/fl_color.cxx309
-rw-r--r--src/fl_color_win32.cxx204
-rw-r--r--src/fl_cursor.cxx145
-rw-r--r--src/fl_curve.cxx73
-rw-r--r--src/fl_diamond_box.cxx49
-rw-r--r--src/fl_draw.cxx175
-rw-r--r--src/fl_draw_image.cxx605
-rw-r--r--src/fl_draw_image_win32.cxx237
-rw-r--r--src/fl_draw_pixmap.cxx224
-rw-r--r--src/fl_engraved_label.cxx64
-rw-r--r--src/fl_file_chooser.cxx600
-rw-r--r--src/fl_font.cxx283
-rw-r--r--src/fl_font_win32.cxx159
-rw-r--r--src/fl_labeltype.cxx104
-rw-r--r--src/fl_oval_box.cxx38
-rw-r--r--src/fl_overlay.cxx39
-rw-r--r--src/fl_overlay_visual.cxx76
-rw-r--r--src/fl_rect.cxx380
-rw-r--r--src/fl_round_box.cxx94
-rw-r--r--src/fl_rounded_box.cxx75
-rw-r--r--src/fl_scroll_area.cxx66
-rw-r--r--src/fl_set_font.cxx51
-rw-r--r--src/fl_set_fonts.cxx300
-rwxr-xr-xsrc/fl_set_fonts_win32.cxx58
-rw-r--r--src/fl_set_gray.cxx35
-rw-r--r--src/fl_shadow_box.cxx31
-rw-r--r--src/fl_shortcut.cxx100
-rw-r--r--src/fl_show_colormap.cxx124
-rw-r--r--src/fl_symbols.cxx364
-rw-r--r--src/fl_vertex.cxx200
-rw-r--r--src/forms_bitmap.cxx24
-rwxr-xr-xsrc/forms_compatability.cxx153
-rw-r--r--src/forms_free.cxx50
-rw-r--r--src/forms_fselect.cxx38
-rw-r--r--src/forms_pixmap.cxx24
-rw-r--r--src/forms_timer.cxx127
-rw-r--r--src/gl_draw.cxx121
-rw-r--r--src/gl_start.cxx98
-rwxr-xr-xsrc/glut_compatability.cxx377
-rw-r--r--src/glut_font.cxx32
-rw-r--r--src/mediumarrow.h6
-rw-r--r--src/ns.xbm8
-rw-r--r--src/ns_mask.xbm8
-rw-r--r--src/numericsort.c53
-rw-r--r--src/scandir.c128
-rw-r--r--src/scandir_win32.c79
-rw-r--r--src/slowarrow.h6
-rw-r--r--test/Makefile51
-rw-r--r--test/README32
-rw-r--r--test/adjuster.cxx37
-rwxr-xr-xtest/arc.cxx70
-rw-r--r--test/ask.cxx90
-rw-r--r--test/bitmap.cxx114
-rw-r--r--test/black_1.xbm60
-rw-r--r--test/black_2.xbm60
-rw-r--r--test/black_3.xbm60
-rw-r--r--test/black_4.xbm60
-rw-r--r--test/blackking_1.xbm60
-rw-r--r--test/blackking_2.xbm60
-rw-r--r--test/blackking_3.xbm60
-rw-r--r--test/blackking_4.xbm60
-rw-r--r--test/boxtype.cxx66
-rw-r--r--test/browser.cxx71
-rw-r--r--test/browserop.cxx81
-rw-r--r--test/button.cxx27
-rw-r--r--test/buttons.cxx25
-rw-r--r--test/checkers.cxx1340
-rw-r--r--test/clock.cxx24
-rw-r--r--test/colbrowser.cxx316
-rw-r--r--test/color_chooser.cxx125
-rw-r--r--test/connect.cxx47
-rw-r--r--test/cube.cxx147
-rw-r--r--test/cursor.cxx138
-rw-r--r--test/curve.cxx88
-rw-r--r--test/demo.cxx255
-rw-r--r--test/demo.menu80
-rw-r--r--test/doublebuffer.cxx99
-rw-r--r--test/fast_slow.C50
-rw-r--r--test/fast_slow.H9
-rw-r--r--test/fast_slow.fl36
-rw-r--r--test/file_chooser.cxx36
-rw-r--r--test/fl_jpeg_image.cxx178
-rw-r--r--test/fonts.cxx127
-rw-r--r--test/forms.cxx205
-rw-r--r--test/fractals.cxx779
-rw-r--r--test/fracviewer.c496
-rw-r--r--test/fracviewer.h104
-rw-r--r--test/fromdos.c65
-rw-r--r--test/fullscreen.cxx219
-rw-r--r--test/gl_overlay.cxx128
-rw-r--r--test/glpuzzle.cxx1455
-rw-r--r--test/hello.cxx16
-rw-r--r--test/iconize.cxx54
-rw-r--r--test/image.cxx108
-rw-r--r--test/inactive.C99
-rw-r--r--test/inactive.H15
-rw-r--r--test/inactive.fl99
-rw-r--r--test/input.cxx92
-rw-r--r--test/jpeg_image.cxx179
-rw-r--r--test/keyboard.cxx102
-rw-r--r--test/keyboard_ui.C558
-rw-r--r--test/keyboard_ui.H11
-rw-r--r--test/keyboard_ui.fl696
-rw-r--r--test/label.cxx137
-rw-r--r--test/list_visuals.cxx205
-rw-r--r--test/mandelbrot.cxx200
-rw-r--r--test/mandelbrot.h54
-rw-r--r--test/mandelbrot_ui.C87
-rw-r--r--test/mandelbrot_ui.H13
-rw-r--r--test/mandelbrot_ui.fl63
-rw-r--r--test/menubar.cxx182
-rw-r--r--test/message.cxx18
-rw-r--r--test/minimum.cxx49
-rw-r--r--test/navigation.cxx42
-rw-r--r--test/output.cxx74
-rw-r--r--test/overlay.cxx57
-rw-r--r--test/pack.cxx89
-rw-r--r--test/pixmap.cxx64
-rw-r--r--test/pixmap_browser.cxx141
-rw-r--r--test/porsche.xpm71
-rw-r--r--test/porsche1.xpm76
-rw-r--r--test/radio.C67
-rw-r--r--test/radio.H9
-rw-r--r--test/radio.fl72
-rw-r--r--test/resize.C71
-rw-r--r--test/resize.H4
-rw-r--r--test/resize.fl48
-rw-r--r--test/resizebox.cxx74
-rw-r--r--test/scroll.cxx112
-rw-r--r--test/shape.cxx91
-rw-r--r--test/shiny.cxx281
-rw-r--r--test/shiny_panel.C103
-rw-r--r--test/shiny_panel.H17
-rw-r--r--test/shiny_panel.fl96
-rw-r--r--test/srs.xbm67
-rw-r--r--test/style.C141
-rw-r--r--test/style_ui.C273
-rw-r--r--test/style_ui.H27
-rw-r--r--test/style_ui.fl343
-rw-r--r--test/subwindow.cxx107
-rw-r--r--test/symbols.cxx62
-rw-r--r--test/tabs.C84
-rw-r--r--test/tabs.H12
-rw-r--r--test/tabs.fl121
-rwxr-xr-xtest/tile.cxx61
-rw-r--r--test/trackball.c324
-rw-r--r--test/trackball.h78
-rw-r--r--test/valuators.C358
-rw-r--r--test/valuators.H15
-rw-r--r--test/valuators.fl206
-rw-r--r--test/white_1.xbm60
-rw-r--r--test/white_2.xbm60
-rw-r--r--test/white_3.xbm60
-rw-r--r--test/white_4.xbm60
-rw-r--r--test/whiteking_1.xbm60
-rw-r--r--test/whiteking_2.xbm60
-rw-r--r--test/whiteking_3.xbm60
-rw-r--r--test/whiteking_4.xbm60
-rw-r--r--version2
-rw-r--r--visualc/README198
-rw-r--r--visualc/adjuster.dsp96
-rw-r--r--visualc/arc.dsp96
-rw-r--r--visualc/ask.dsp96
-rw-r--r--visualc/bitmap.dsp96
-rw-r--r--visualc/boxtype.dsp96
-rw-r--r--visualc/browser.dsp96
-rw-r--r--visualc/button.dsp96
-rw-r--r--visualc/buttons.dsp96
-rw-r--r--visualc/checkers.dsp96
-rw-r--r--visualc/clock.dsp96
-rw-r--r--visualc/colbrowser.dsp96
-rw-r--r--visualc/color_chooser.dsp96
-rw-r--r--visualc/config.h52
-rw-r--r--visualc/cube.dsp96
-rw-r--r--visualc/cursor.dsp96
-rw-r--r--visualc/curve.dsp96
-rw-r--r--visualc/demo.dsp96
-rw-r--r--visualc/doublebuffer.dsp96
-rw-r--r--visualc/fast_slow.dsp96
-rw-r--r--visualc/file_chooser.dsp96
-rw-r--r--visualc/fltk.dsw1013
-rw-r--r--visualc/fltk.lib.dsp534
-rw-r--r--visualc/fluid.dsp156
-rw-r--r--visualc/fonts.dsp96
-rw-r--r--visualc/forms.dsp96
-rw-r--r--visualc/fractals.dsp96
-rw-r--r--visualc/fullscreen.dsp96
-rw-r--r--visualc/gl_overlay.dsp96
-rw-r--r--visualc/glpuzzle.dsp96
-rw-r--r--visualc/hello.dsp96
-rw-r--r--visualc/iconize.dsp96
-rw-r--r--visualc/image.dsp96
-rwxr-xr-xvisualc/inactive.dsp96
-rw-r--r--visualc/input.dsp96
-rw-r--r--visualc/keyboard.dsp96
-rw-r--r--visualc/label.dsp96
-rw-r--r--visualc/mandelbrot.dsp96
-rw-r--r--visualc/menubar.dsp96
-rw-r--r--visualc/message.dsp96
-rw-r--r--visualc/minimum.dsp96
-rw-r--r--visualc/navigation.dsp96
-rw-r--r--visualc/output.dsp96
-rw-r--r--visualc/overlay.dsp96
-rwxr-xr-xvisualc/pack.dsp96
-rw-r--r--visualc/pixmap.dsp96
-rw-r--r--visualc/pixmap_browser.dsp96
-rw-r--r--visualc/radio.dsp96
-rw-r--r--visualc/resize.dsp96
-rw-r--r--visualc/resizebox.dsp96
-rw-r--r--visualc/scroll.dsp96
-rw-r--r--visualc/shape.dsp96
-rw-r--r--visualc/shiny.dsp96
-rwxr-xr-xvisualc/style.dsp96
-rw-r--r--visualc/subwindow.dsp96
-rw-r--r--visualc/symbols.dsp96
-rw-r--r--visualc/tabs.dsp96
-rw-r--r--visualc/tile.dsp96
-rw-r--r--visualc/valuators.dsp96
459 files changed, 61083 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000..43433c494
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ [This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/FL/Enumerations.H b/FL/Enumerations.H
new file mode 100644
index 000000000..e8237ff74
--- /dev/null
+++ b/FL/Enumerations.H
@@ -0,0 +1,293 @@
+#ifndef Fl_Enumerations_H
+#define Fl_Enumerations_H
+
+const double FL_VERSION = 0.99;
+
+typedef unsigned char uchar;
+typedef unsigned long ulong;
+typedef unsigned int u32; // you must fix if not 32 bits on your machine!
+
+enum Fl_Event { // events
+ FL_NO_EVENT = 0,
+ FL_PUSH = 1,
+ FL_RELEASE = 2,
+ FL_ENTER = 3,
+ FL_LEAVE = 4,
+ FL_DRAG = 5,
+ FL_FOCUS = 6,
+ FL_UNFOCUS = 7,
+ FL_KEYBOARD = 8,
+ FL_CLOSE = 9,
+ FL_MOVE = 10,
+ FL_SHORTCUT = 11,
+ FL_DEACTIVATE = 13,
+ FL_ACTIVATE = 14,
+ FL_HIDE = 15,
+ FL_SHOW = 16,
+ FL_PASTE = 17,
+ FL_SELECTIONCLEAR = 18
+};
+
+enum Fl_When { // Fl_Widget::when():
+ FL_WHEN_NEVER = 0,
+ FL_WHEN_CHANGED = 1,
+ FL_WHEN_RELEASE = 4,
+ FL_WHEN_RELEASE_ALWAYS= 6,
+ FL_WHEN_ENTER_KEY = 8,
+ FL_WHEN_ENTER_KEY_ALWAYS=10,
+ FL_WHEN_NOT_CHANGED = 2 // modifier bit to disable changed() test
+};
+
+// Fl::event_key() and Fl::get_key(n) (use ascii letters for all other keys):
+#define FL_Button 0xfee8 // use Fl_Button+n for mouse button n
+#define FL_BackSpace 0xff08
+#define FL_Tab 0xff09
+#define FL_Enter 0xff0d
+#define FL_Pause 0xff13
+#define FL_Scroll_Lock 0xff14
+#define FL_Escape 0xff1b
+#define FL_Home 0xff50
+#define FL_Left 0xff51
+#define FL_Up 0xff52
+#define FL_Right 0xff53
+#define FL_Down 0xff54
+#define FL_Page_Up 0xff55
+#define FL_Page_Down 0xff56
+#define FL_End 0xff57
+#define FL_Print 0xff61
+#define FL_Insert 0xff63
+#define FL_Menu 0xff67 // the "menu/apps" key on XFree86
+#define FL_Num_Lock 0xff7f
+#define FL_KP 0xff80 // use FL_KP+'x' for 'x' on numeric keypad
+#define FL_KP_Enter 0xff8d // same as Fl_KP+'\r'
+#define FL_KP_Last 0xffbd // use to range-check keypad
+#define FL_F 0xffbd // use FL_F+n for function key n
+#define FL_F_Last 0xffe0 // use to range-check function keys
+#define FL_Shift_L 0xffe1
+#define FL_Shift_R 0xffe2
+#define FL_Control_L 0xffe3
+#define FL_Control_R 0xffe4
+#define FL_Caps_Lock 0xffe5
+#define FL_Meta_L 0xffe7 // the left MSWindows key on XFree86
+#define FL_Meta_R 0xffe8 // the right MSWindows key on XFree86
+#define FL_Alt_L 0xffe9
+#define FL_Alt_R 0xffea
+#define FL_Delete 0xffff
+
+// Fl::event_state():
+#define FL_SHIFT 0x00010000
+#define FL_CAPS_LOCK 0x00020000
+#define FL_CTRL 0x00040000
+#define FL_ALT 0x00080000
+#define FL_NUM_LOCK 0x00100000 // most X servers do this?
+#define FL_META 0x00400000 // correct for XFree86
+#define FL_SCROLL_LOCK 0x00800000 // correct for XFree86
+#define FL_BUTTON1 0x01000000
+#define FL_BUTTON2 0x02000000
+#define FL_BUTTON3 0x04000000
+
+enum Fl_Boxtype { // boxtypes (if you change these you must fix fl_boxtype.C):
+ FL_NO_BOX = 0, FL_FLAT_BOX,
+
+ FL_UP_BOX, FL_DOWN_BOX,
+ FL_UP_FRAME, FL_DOWN_FRAME,
+ FL_THIN_UP_BOX, FL_THIN_DOWN_BOX,
+ FL_THIN_UP_FRAME, FL_THIN_DOWN_FRAME,
+ FL_ENGRAVED_BOX, FL_EMBOSSED_BOX,
+ FL_ENGRAVED_FRAME, FL_EMBOSSED_FRAME,
+ FL_BORDER_BOX, _FL_SHADOW_BOX,
+ FL_BORDER_FRAME, _FL_SHADOW_FRAME,
+ _FL_ROUNDED_BOX, _FL_RSHADOW_BOX,
+ _FL_ROUNDED_FRAME, _FL_RFLAT_BOX,
+ _FL_ROUND_UP_BOX, _FL_ROUND_DOWN_BOX,
+ _FL_DIAMOND_UP_BOX, _FL_DIAMOND_DOWN_BOX,
+ _FL_OVAL_BOX, _FL_OSHADOW_BOX,
+ _FL_OVAL_FRAME, _FL_OFLAT_BOX
+};
+extern Fl_Boxtype define_FL_ROUND_UP_BOX();
+#define FL_ROUND_UP_BOX define_FL_ROUND_UP_BOX()
+#define FL_ROUND_DOWN_BOX (Fl_Boxtype)(define_FL_ROUND_UP_BOX()+1)
+extern Fl_Boxtype define_FL_SHADOW_BOX();
+#define FL_SHADOW_BOX define_FL_SHADOW_BOX()
+#define FL_SHADOW_FRAME (Fl_Boxtype)(define_FL_SHADOW_BOX()+2)
+extern Fl_Boxtype define_FL_ROUNDED_BOX();
+#define FL_ROUNDED_BOX define_FL_ROUNDED_BOX()
+#define FL_ROUNDED_FRAME (Fl_Boxtype)(define_FL_ROUNDED_BOX()+2)
+extern Fl_Boxtype define_FL_RFLAT_BOX();
+#define FL_RFLAT_BOX define_FL_RFLAT_BOX()
+extern Fl_Boxtype define_FL_RSHADOW_BOX();
+#define FL_RSHADOW_BOX define_FL_RSHADOW_BOX()
+extern Fl_Boxtype define_FL_DIAMOND_BOX();
+#define FL_DIAMOND_UP_BOX define_FL_DIAMOND_BOX()
+#define FL_DIAMOND_DOWN_BOX (Fl_Boxtype)(define_FL_DIAMOND_BOX()+1)
+extern Fl_Boxtype define_FL_OVAL_BOX();
+#define FL_OVAL_BOX define_FL_OVAL_BOX()
+#define FL_OSHADOW_BOX (Fl_Boxtype)(define_FL_OVAL_BOX()+1)
+#define FL_OVAL_FRAME (Fl_Boxtype)(define_FL_OVAL_BOX()+2)
+#define FL_OFLAT_BOX (Fl_Boxtype)(define_FL_OVAL_BOX()+3)
+
+// conversions of box types to other boxtypes:
+inline Fl_Boxtype down(Fl_Boxtype b) {return (Fl_Boxtype)(b|1);}
+inline Fl_Boxtype frame(Fl_Boxtype b) {return (Fl_Boxtype)(b|2);}
+
+// back-compatability box types:
+#define FL_FRAME FL_ENGRAVED_FRAME
+#define FL_FRAME_BOX FL_ENGRAVED_BOX
+#define FL_CIRCLE_BOX FL_ROUND_DOWN_BOX
+#define FL_DIAMOND_BOX FL_DIAMOND_DOWN_BOX
+
+enum Fl_Labeltype { // labeltypes:
+ FL_NORMAL_LABEL = 0,
+ FL_NO_LABEL,
+ _FL_SYMBOL_LABEL,
+ _FL_SHADOW_LABEL,
+ _FL_ENGRAVED_LABEL,
+ _FL_EMBOSSED_LABEL,
+ _FL_BITMAP_LABEL,
+ _FL_PIXMAP_LABEL,
+ _FL_IMAGE_LABEL,
+ _FL_MULTI_LABEL,
+ FL_FREE_LABELTYPE
+};
+extern Fl_Labeltype define_FL_SYMBOL_LABEL();
+#define FL_SYMBOL_LABEL define_FL_SYMBOL_LABEL()
+extern Fl_Labeltype define_FL_SHADOW_LABEL();
+#define FL_SHADOW_LABEL define_FL_SHADOW_LABEL()
+extern Fl_Labeltype define_FL_ENGRAVED_LABEL();
+#define FL_ENGRAVED_LABEL define_FL_ENGRAVED_LABEL()
+extern Fl_Labeltype define_FL_EMBOSSED_LABEL();
+#define FL_EMBOSSED_LABEL define_FL_EMBOSSED_LABEL()
+
+enum Fl_Align { // align() values
+ FL_ALIGN_CENTER = 0,
+ FL_ALIGN_TOP = 1,
+ FL_ALIGN_BOTTOM = 2,
+ FL_ALIGN_LEFT = 4,
+ FL_ALIGN_RIGHT = 8,
+ FL_ALIGN_INSIDE = 16,
+ FL_ALIGN_CLIP = 64,
+ FL_ALIGN_WRAP = 128,
+ FL_ALIGN_TOP_LEFT = FL_ALIGN_TOP | FL_ALIGN_LEFT,
+ FL_ALIGN_TOP_RIGHT = FL_ALIGN_TOP | FL_ALIGN_RIGHT,
+ FL_ALIGN_BOTTOM_LEFT = FL_ALIGN_BOTTOM | FL_ALIGN_LEFT,
+ FL_ALIGN_BOTTOM_RIGHT = FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT,
+ FL_ALIGN_LEFT_TOP = FL_ALIGN_TOP_LEFT,
+ FL_ALIGN_RIGHT_TOP = FL_ALIGN_TOP_RIGHT,
+ FL_ALIGN_LEFT_BOTTOM = FL_ALIGN_BOTTOM_LEFT,
+ FL_ALIGN_RIGHT_BOTTOM = FL_ALIGN_BOTTOM_RIGHT,
+ FL_ALIGN_NOWRAP = 0 // for back compatability
+};
+
+enum Fl_Font { // standard fonts
+ FL_HELVETICA = 0,
+ FL_HELVETICA_BOLD,
+ FL_HELVETICA_ITALIC,
+ FL_HELVETICA_BOLD_ITALIC,
+ FL_COURIER,
+ FL_COURIER_BOLD,
+ FL_COURIER_ITALIC,
+ FL_COURIER_BOLD_ITALIC,
+ FL_TIMES,
+ FL_TIMES_BOLD,
+ FL_TIMES_ITALIC,
+ FL_TIMES_BOLD_ITALIC,
+ FL_SYMBOL,
+ FL_SCREEN,
+ FL_SCREEN_BOLD,
+ FL_ZAPF_DINGBATS,
+
+ FL_FREE_FONT = 16, // first one to allocate
+ FL_BOLD = 1, // add this to helvetica, courier, or times
+ FL_ITALIC = 2 // add this to helvetica, courier, or times
+};
+
+#define FL_NORMAL_SIZE 14 // default size of all labels & text
+
+enum Fl_Color { // standard colors
+ FL_BLACK = 0,
+ FL_RED = 1,
+ FL_GREEN = 2,
+ FL_YELLOW = 3,
+ FL_BLUE = 4,
+ FL_MAGENTA = 5,
+ FL_CYAN = 6,
+ FL_WHITE = 7,
+ FL_INACTIVE_COLOR = 8,
+ FL_SELECTION_COLOR = 15,
+
+ FL_FREE_COLOR = 16,
+ FL_NUM_FREE_COLOR = 16,
+
+ FL_GRAY_RAMP = 32,
+
+ // boxtypes limit themselves to these colors so whole ramp is not allocated:
+ FL_GRAY0 = 32, // 'A'
+ FL_DARK3 = 39, // 'H'
+ FL_DARK2 = 45, // 'N'
+ FL_DARK1 = 47, // 'P'
+ FL_GRAY = 49, // 'R' default color
+ FL_LIGHT1 = 50, // 'S'
+ FL_LIGHT2 = 52, // 'U'
+ FL_LIGHT3 = 54, // 'W'
+
+ FL_COLOR_CUBE = 56
+};
+
+inline Fl_Color inactive(Fl_Color c) {return (Fl_Color)(c|8);}
+Fl_Color contrast(Fl_Color fg, Fl_Color bg);
+#define FL_NUM_GRAY 24
+inline Fl_Color fl_gray_ramp(int i) {return (Fl_Color)(i+FL_GRAY_RAMP);}
+#define FL_NUM_RED 5
+#define FL_NUM_GREEN 8
+#define FL_NUM_BLUE 5
+inline Fl_Color fl_color_cube(int r, int g, int b) {
+ return (Fl_Color)((b*FL_NUM_RED + r) * FL_NUM_GREEN + g + FL_COLOR_CUBE);}
+
+enum Fl_Cursor { // standard cursors
+ FL_CURSOR_DEFAULT = 0,
+ FL_CURSOR_ARROW = 35,
+ FL_CURSOR_CROSS = 66,
+ FL_CURSOR_WAIT = 76,
+ FL_CURSOR_INSERT = 77,
+ FL_CURSOR_HAND = 31,
+ FL_CURSOR_HELP = 47,
+ FL_CURSOR_MOVE = 27,
+ // fltk provides bitmaps for these:
+ FL_CURSOR_NS = 78,
+ FL_CURSOR_WE = 79,
+ FL_CURSOR_NWSE = 80,
+ FL_CURSOR_NESW = 81,
+ FL_CURSOR_NONE = 255,
+ // for back compatability (non MSWindows ones):
+ FL_CURSOR_N = 70,
+ FL_CURSOR_NE = 69,
+ FL_CURSOR_E = 49,
+ FL_CURSOR_SE = 8,
+ FL_CURSOR_S = 9,
+ FL_CURSOR_SW = 7,
+ FL_CURSOR_W = 36,
+ FL_CURSOR_NW = 68
+ //FL_CURSOR_NS = 22,
+ //FL_CURSOR_WE = 55,
+};
+
+enum { // values for "when" passed to Fl::add_fd()
+ FL_READ = 1,
+ FL_WRITE = 4,
+ FL_EXCEPT = 8
+};
+
+enum Fl_Mode { // visual types and Fl_Gl_Window::mode() (values match Glut)
+ FL_RGB = 0,
+ FL_INDEX = 1,
+ FL_SINGLE = 0,
+ FL_DOUBLE = 2,
+ FL_ACCUM = 4,
+ FL_ALPHA = 8,
+ FL_DEPTH = 16,
+ FL_STENCIL = 32,
+ FL_RGB8 = 64,
+ FL_MULTISAMPLE= 128
+};
+
+#endif
diff --git a/FL/Fl.H b/FL/Fl.H
new file mode 100644
index 000000000..b0cc41fd4
--- /dev/null
+++ b/FL/Fl.H
@@ -0,0 +1,195 @@
+// Fl.H
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+
+// Written by Bill Spitzak spitzak@d2.com
+
+#ifndef Fl_H
+#define Fl_H
+
+#include "Enumerations.H"
+#ifndef Fl_Object
+#define Fl_Object Fl_Widget
+#endif
+
+class Fl_Widget;
+class Fl_Window;
+struct Fl_Label;
+typedef void (Fl_Label_Draw_F)(const Fl_Label*, int,int,int,int, Fl_Align);
+typedef void (Fl_Label_Measure_F)(const Fl_Label*, int&, int&);
+typedef void (Fl_Box_Draw_F)(int,int,int,int, Fl_Color);
+
+class Fl {
+ Fl() {}; // no constructor!
+
+public: // should be private!
+
+ static int e_x,e_y,e_x_root,e_y_root;
+ static int e_state;
+ static int e_clicks;
+ static int e_is_click;
+ static int e_keysym;
+ static char* e_text;
+ static int e_length;
+ static Fl_Widget* belowmouse_;
+ static Fl_Widget* pushed_;
+ static Fl_Widget* focus_;
+ static int damage_;
+ static Fl_Widget* selection_owner_;
+ static Fl_Window* modal_;
+ static Fl_Window* grab_;
+
+ static void damage(int x) {damage_ = x;}
+
+ static void (*idle)();
+
+public:
+
+ // argument parsers:
+ static int arg(int, char**, int&);
+ static int args(int, char**, int&, int (*)(int,char**,int&) = 0);
+ static const char* const help;
+ static void args(int, char**);
+
+ // things called by initialization:
+ static void display(const char*);
+ static int visual(int);
+ static int gl_visual(int, int *alist=0);
+ static void own_colormap();
+ static void get_system_colors();
+ static void foreground(uchar, uchar, uchar);
+ static void background(uchar, uchar, uchar);
+ static void background2(uchar, uchar, uchar);
+
+ // execution:
+ static int wait();
+ static double wait(double time);
+ static int check();
+ static int ready();
+ static int run();
+ static Fl_Widget* readqueue();
+ static void add_timeout(double t,void (*cb)(void*),void* = 0);
+ static void remove_timeout(void (*cb)(void*), void* = 0);
+ static void add_fd(int fd, int when, void (*cb)(int, void*), void* = 0);
+ static void add_fd(int fd, void (*cb)(int, void*), void* = 0);
+ static void remove_fd(int);
+ static void add_idle(void (*cb)(void*), void* = 0);
+ static void remove_idle(void (*cb)(void*), void* = 0);
+ static int damage() {return damage_;}
+ static void redraw();
+ static void flush();
+ static void (*warning)(const char*, ...);
+ static void (*error)(const char*, ...);
+ static void (*fatal)(const char*, ...);
+ static Fl_Window* first_window();
+ static Fl_Window* next_window(const Fl_Window*);
+ static Fl_Window* modal() {return modal_;}
+ static Fl_Window* grab() {return grab_;}
+ static void grab(Fl_Window&);
+ static void release();
+
+ // event information:
+ static int event_x() {return e_x;}
+ static int event_y() {return e_y;}
+ static int event_x_root() {return e_x_root;}
+ static int event_y_root() {return e_y_root;}
+ static void get_mouse(int &,int &);
+ static int event_clicks() {return e_clicks;}
+ static void event_clicks(int i) {e_clicks = i;}
+ static int event_is_click() {return e_is_click;}
+ static void event_is_click(int i) {e_is_click = i;} // only 0 works!
+ static int event_button() {return e_keysym-FL_Button;}
+ static int event_state() {return e_state;}
+ static int event_state(int i) {return e_state&i;}
+ static int event_key() {return e_keysym;}
+ static int event_key(int);
+ static int get_key(int);
+ static const char* event_text() {return e_text;}
+ static int event_length() {return e_length;}
+ static int event_inside(int,int,int,int);
+ static int event_inside(const Fl_Widget*);
+ static int test_shortcut(int);
+
+ // event destinations:
+ static int handle(int, Fl_Window*);
+ static Fl_Widget* belowmouse() {return belowmouse_;}
+ static void belowmouse(Fl_Widget*);
+ static Fl_Widget* pushed() {return pushed_;}
+ static void pushed(Fl_Widget*);
+ static Fl_Widget* focus() {return focus_;}
+ static void focus(Fl_Widget*);
+ static void add_handler(int (*h)(int));
+
+ // cut/paste:
+ static Fl_Widget* selection_owner() {return selection_owner_;}
+ static void selection_owner(Fl_Widget*);
+ static void selection(Fl_Widget &owner, const char* stuff, int len);
+ static void paste(Fl_Widget &receiver);
+
+ // screen size:
+ static int x() {return 0;}
+ static int y() {return 0;}
+ static int w();
+ static int h();
+
+ // color map:
+ static void set_color(Fl_Color, uchar, uchar, uchar);
+ static void set_color(Fl_Color, unsigned);
+ static unsigned get_color(Fl_Color);
+ static void get_color(Fl_Color, uchar&, uchar&, uchar&);
+ static void free_color(Fl_Color, int overlay = 0);
+
+ // fonts:
+ static const char* get_font(Fl_Font);
+ static const char* get_font_name(Fl_Font, int* attributes = 0);
+ static int get_font_sizes(Fl_Font, int*& sizep);
+ static void set_font(Fl_Font, const char*);
+ static void set_font(Fl_Font, Fl_Font);
+ static Fl_Font set_fonts(const char* = 0);
+
+ // labeltypes:
+ static void set_labeltype(Fl_Labeltype,Fl_Label_Draw_F*,Fl_Label_Measure_F*);
+ static void set_labeltype(Fl_Labeltype, Fl_Labeltype from);
+ static void enable_symbols();
+
+ // boxtypes:
+ static void set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*,uchar,uchar,uchar,uchar);
+ static void set_boxtype(Fl_Boxtype, Fl_Boxtype from);
+ static int box_dx(Fl_Boxtype);
+ static int box_dy(Fl_Boxtype);
+ static int box_dw(Fl_Boxtype);
+ static int box_dh(Fl_Boxtype);
+
+ // back compatability:
+ static void set_abort(void (*f)(const char*,...)) {fatal = f;}
+ static void (*atclose)(Fl_Window*,void*);
+ static void default_atclose(Fl_Window*,void*);
+ static void set_atclose(void (*f)(Fl_Window*,void*)) {atclose = f;}
+ static int event_shift() {return e_state&FL_SHIFT;}
+ static int event_ctrl() {return e_state&FL_CTRL;}
+ static int event_alt() {return e_state&FL_ALT;}
+ static int event_buttons() {return e_state&0x7f000000;}
+ static int event_button1() {return e_state&FL_BUTTON1;}
+ static int event_button2() {return e_state&FL_BUTTON2;}
+ static int event_button3() {return e_state&FL_BUTTON3;}
+ static void set_idle(void (*cb)()) {idle = cb;}
+
+};
+
+#endif
diff --git a/FL/Fl_Adjuster.H b/FL/Fl_Adjuster.H
new file mode 100644
index 000000000..df4a2cdd1
--- /dev/null
+++ b/FL/Fl_Adjuster.H
@@ -0,0 +1,26 @@
+// Fl_Adjuster.H
+
+// 3-button "slider", made for Nuke
+
+#ifndef Fl_Adjuster_H
+#define Fl_Adjuster_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+class Fl_Adjuster : public Fl_Valuator {
+ int drag;
+ int ix;
+ int soft_;
+protected:
+ void draw();
+ int handle(int);
+ void value_damage();
+public:
+ Fl_Adjuster(int x,int y,int w,int h,const char *l=0);
+ void soft(int x) {soft_ = x;}
+ int soft() const {return soft_;}
+};
+
+#endif
diff --git a/FL/Fl_Bitmap.H b/FL/Fl_Bitmap.H
new file mode 100644
index 000000000..2707cf1ed
--- /dev/null
+++ b/FL/Fl_Bitmap.H
@@ -0,0 +1,24 @@
+/* Fl_Bitmap.H */
+
+#ifndef Fl_Bitmap_H
+#define Fl_Bitmap_H
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+struct Fl_Bitmap {
+ const uchar *array;
+ int w, h;
+ ulong id; // for internal use
+ Fl_Bitmap(const uchar *bits, int W, int H) :
+ array(bits), w(W), h(H), id(0) {}
+ Fl_Bitmap(const char *bits, int W, int H) :
+ array((const uchar *)bits), w(W), h(H), id(0) {}
+ ~Fl_Bitmap();
+ void label(Fl_Widget*);
+ void label(Fl_Menu_Item*);
+ void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+ void draw(int X, int Y) {draw(X, Y, w, h, 0, 0);}
+};
+
+#endif
diff --git a/FL/Fl_Box.H b/FL/Fl_Box.H
new file mode 100644
index 000000000..a1936a094
--- /dev/null
+++ b/FL/Fl_Box.H
@@ -0,0 +1,19 @@
+/* Fl_Box.H */
+
+#ifndef Fl_Box_H
+#define Fl_Box_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+class Fl_Box : public Fl_Widget {
+ void draw();
+public:
+ Fl_Box(int x, int y, int w, int h, const char *l=0)
+ : Fl_Widget(x,y,w,h,l) {}
+ Fl_Box(Fl_Boxtype b, int x, int y, int w, int h, const char *l)
+ : Fl_Widget(x,y,w,h,l) {box(b);}
+};
+
+#endif
diff --git a/FL/Fl_Browser.H b/FL/Fl_Browser.H
new file mode 100644
index 000000000..aaf2975d5
--- /dev/null
+++ b/FL/Fl_Browser.H
@@ -0,0 +1,86 @@
+/* Fl_Browser.H
+
+ Forms-compatable browser. Probably useful for other
+ lists of textual data. Notice that the line numbers
+ start from 1, and 0 means "no line".
+
+*/
+
+#ifndef Fl_Browser_H
+#define Fl_Browser_H
+
+#include "Fl_Browser_.H"
+
+struct FL_BLINE;
+
+class Fl_Browser : public Fl_Browser_ {
+
+ // required routines for Fl_Browser_ subclass:
+ void* item_first() const ;
+ void* item_next(void*) const ;
+ void* item_prev(void*) const ;
+ int item_selected(void*) const ;
+ void item_select(void*, int);
+ int item_height(void*) const ;
+ int item_width(void*) const ;
+ void item_draw(void*, int, int, int, int) const ;
+ int full_height() const ;
+ int incr_height() const ;
+
+ FL_BLINE *first; // the array of lines
+ FL_BLINE *last;
+ FL_BLINE *cache;
+ int cacheline; // line number of cache
+ int lines; // Number of lines
+ int full_height_;
+ const int* column_widths_;
+ char format_char_; // alternative to @-sign
+ char column_char_; // alternative to tab
+ FL_BLINE* find_line(int) const ;
+ FL_BLINE* _remove(int) ;
+ void insert(int, FL_BLINE*);
+ int lineno(void*) const ;
+
+public:
+
+ void remove(int);
+ void add(const char*, void* = 0);
+ void insert(int, const char*, void* = 0);
+ void move(int to, int from);
+ int load(const char* filename);
+ void clear();
+
+ int size() const {return lines;}
+ int topline() const ;
+ void topline(int);
+
+ int select(int, int=1);
+ int selected(int) const ;
+ void show(int n);
+ void hide(int n);
+ int visible(int n) const ;
+
+ int value() const ;
+ void value(int v) {select(v);}
+ const char* text(int) const ;
+ void text(int, const char*);
+ void* data(int) const ;
+ void data(int, void* v);
+
+ Fl_Browser(int, int, int, int, const char* = 0);
+
+ char format_char() const {return format_char_;}
+ void format_char(char c) {format_char_ = c;}
+ char column_char() const {return column_char_;}
+ void column_char(char c) {column_char_ = c;}
+ const int* column_widths() const {return column_widths_;}
+ void column_widths(const int* l) { column_widths_=l; }
+
+ int displayed(int n) const {return Fl_Browser_::displayed(find_line(n));}
+
+ // for back compatability only:
+ void replace(int a, const char* b) {text(a, b);}
+ void display(int, int=1);
+};
+
+#endif
diff --git a/FL/Fl_Browser_.H b/FL/Fl_Browser_.H
new file mode 100644
index 000000000..f3ff3b521
--- /dev/null
+++ b/FL/Fl_Browser_.H
@@ -0,0 +1,123 @@
+// Fl_Browser_.H
+
+// This is the base class for browsers. To be useful it must
+// be subclassed and several virtual functions defined. The
+// Forms-compatable browser and the file chooser's browser are
+// subclassed off of this.
+
+// Yes, I know this should be a template...
+
+#ifndef Fl_Browser__H
+#define Fl_Browser__H
+
+#ifndef Fl_Group_H
+#include "Fl_Group.H"
+#endif
+#include "Fl_Scrollbar.H"
+
+#define FL_NORMAL_BROWSER 0
+#define FL_SELECT_BROWSER 1
+#define FL_HOLD_BROWSER 2
+#define FL_MULTI_BROWSER 3
+
+class Fl_Browser_ : public Fl_Group {
+ int position_; // where user wants it scrolled to
+ int real_position_; // the current vertical scrolling position
+ int hposition_; // where user wants it panned to
+ int real_hposition_; // the current horizontal scrolling position
+ int offset_; // how far down top_ item the real_position is
+ int max_width; // widest object seen so far
+ uchar textfont_, textsize_, textcolor_;
+ uchar has_scrollbar_; // which scrollbars are enabled
+ void* top_; // which item scrolling position is in
+ void* selection_; // which is selected (except for FL_MULTI_BROWSER)
+ void *redraw1,*redraw2; // minimal update pointers
+ void* max_width_item; // which item has max_width_
+
+ static int scrollbar_width_;
+
+ void update_top();
+
+protected:
+
+ // All of the following must be supplied by the subclass:
+ virtual void *item_first() const = 0;
+ virtual void *item_next(void *) const = 0;
+ virtual void *item_prev(void *) const = 0;
+ virtual int item_height(void *) const = 0;
+ virtual int item_width(void *) const = 0;
+ virtual int item_quick_height(void *) const ;
+ virtual void item_draw(void *,int,int,int,int) const = 0;
+ // you don't have to provide these but it may help speed it up:
+ virtual int full_width() const ; // current width of all items
+ virtual int full_height() const ; // current height of all items
+ virtual int incr_height() const ; // average height of an item
+ // These only need to be done by subclass if you want a multi-browser:
+ virtual void item_select(void *,int=1);
+ virtual int item_selected(void *) const ;
+
+ // things the subclass may want to call:
+ void *top() const {return top_;}
+ void *selection() const {return selection_;}
+ void new_list(); // completely clobber all data, as though list replaced
+ void deleting(void *a); // get rid of any pointers to a
+ void replacing(void *a,void *b); // change a pointers to b
+ void inserting(void *a,void *b); // insert a before b
+ int displayed(void *) const ; // true if this line is visible
+ void redraw_line(void *); // minimal update, no change in size
+ void redraw_lines() {damage(4);} // redraw all of them
+ void bbox(int&,int&,int&,int&) const;
+ int leftedge() const; // x position after scrollbar & border
+ void *find_item(int my); // item under mouse
+ void draw(int,int,int,int);
+ int handle(int,int,int,int,int);
+
+ void draw();
+ int handle(int);
+ Fl_Browser_(int,int,int,int,const char * = 0);
+
+public:
+
+ Fl_Scrollbar scrollbar; // Vertical scrollbar
+ Fl_Scrollbar hscrollbar; // Horizontal scrollbar
+
+ void resize(int,int,int,int);
+
+ int select(void *,int=1,int docallbacks=0);
+ int select_only(void *,int docallbacks=0);
+ int deselect(int docallbacks=0);
+ int position() const {return position_;}
+ int hposition() const {return hposition_;}
+ void position(int); // scroll to here
+ void hposition(int); // pan to here
+ void display(void*); // scroll so this item is shown
+
+ uchar has_scrollbar() const {return has_scrollbar_;}
+ void has_scrollbar(uchar i) {has_scrollbar_ = i;}
+ enum { // values for has_scrollbar()
+ HORIZONTAL = 1,
+ VERTICAL = 2,
+ BOTH = 3,
+ ALWAYS_ON = 4,
+ HORIZONTAL_ALWAYS = 5,
+ VERTICAL_ALWAYS = 6,
+ BOTH_ALWAYS = 7
+ };
+
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar s) {textfont_ = s;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar s) {textsize_ = s;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar n) {textcolor_ = n;}
+
+ static void scrollbar_width(int b) {scrollbar_width_ = b;}
+ static int scrollbar_width() {return scrollbar_width_;}
+
+ // for back compatability:
+ void scrollbar_right() {scrollbar.align(FL_ALIGN_RIGHT);}
+ void scrollbar_left() {scrollbar.align(FL_ALIGN_LEFT);}
+
+};
+
+#endif
diff --git a/FL/Fl_Button.H b/FL/Fl_Button.H
new file mode 100644
index 000000000..49f4b98cb
--- /dev/null
+++ b/FL/Fl_Button.H
@@ -0,0 +1,48 @@
+// Fl_Button.H
+
+#ifndef Fl_Button_H
+#define Fl_Button_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type()
+#define FL_TOGGLE_BUTTON 1
+#define FL_RADIO_BUTTON (FL_RESERVED_TYPE+2)
+#define FL_HIDDEN_BUTTON 3 // for Forms compatability
+
+extern int fl_old_shortcut(const char*);
+
+class Fl_Button : public Fl_Widget {
+
+ int shortcut_;
+ char value_;
+ char oldval;
+ uchar down_box_;
+
+protected:
+
+ virtual void draw();
+
+public:
+
+ virtual int handle(int);
+ Fl_Button(int,int,int,int,const char * = 0);
+ int value(int);
+ char value() const {return value_;}
+ int set() {return value(1);}
+ int clear() {return value(0);}
+ void setonly(); // this should only be called on FL_RADIO_BUTTONs
+ int shortcut() const {return shortcut_;}
+ void shortcut(int s) {shortcut_ = s;}
+ Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;}
+ void down_box(Fl_Boxtype b) {down_box_ = b;}
+
+ // back compatability:
+ void shortcut(const char *s) {shortcut(fl_old_shortcut(s));}
+ Fl_Color down_color() const {return selection_color();}
+ void down_color(uchar c) {selection_color(c);}
+};
+
+#endif
diff --git a/FL/Fl_Chart.H b/FL/Fl_Chart.H
new file mode 100644
index 000000000..08a58f32e
--- /dev/null
+++ b/FL/Fl_Chart.H
@@ -0,0 +1,65 @@
+/* Fl_Chart.H
+
+ Emulation of the Forms Chart widget.
+ I did not try to improve this much, as I doubt it is used.
+
+*/
+
+#ifndef Fl_Chart_H
+#define Fl_Chart_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type()
+#define FL_BAR_CHART 0
+#define FL_HORBAR_CHART 1
+#define FL_LINE_CHART 2
+#define FL_FILL_CHART 3
+#define FL_SPIKE_CHART 4
+#define FL_PIE_CHART 5
+#define FL_SPECIALPIE_CHART 6
+
+#define FL_FILLED_CHART FL_FILL_CHART // compatibility
+
+#define FL_CHART_MAX 128
+#define FL_CHART_LABEL_MAX 18
+
+struct FL_CHART_ENTRY {
+ float val;
+ uchar col;
+ char str[FL_CHART_LABEL_MAX+1];
+};
+
+class Fl_Chart : public Fl_Widget {
+ int numb;
+ int maxnumb;
+ FL_CHART_ENTRY entries[FL_CHART_MAX+1];
+ double min,max;
+ uchar autosize_;
+ uchar textfont_,textsize_,textcolor_;
+protected:
+ void draw();
+public:
+ Fl_Chart(int,int,int,int,const char * = 0);
+ void clear();
+ void add(double, const char * =0, uchar=0);
+ void insert(int, double, const char * =0, uchar=0);
+ void replace(int, double, const char * =0, uchar=0);
+ void bounds(double *a,double *b) const {*a = min; *b = max;}
+ void bounds(double a,double b);
+ int size() const {return numb;}
+ int maxsize() const {return maxnumb;}
+ void maxsize(int);
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar s) {textfont_ = s;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar s) {textsize_ = s;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar n) {textcolor_ = n;}
+ uchar autosize() const {return autosize_;}
+ void autosize(uchar n) {autosize_ = n;}
+};
+
+#endif
diff --git a/FL/Fl_Check_Button.H b/FL/Fl_Check_Button.H
new file mode 100644
index 000000000..bc935a45d
--- /dev/null
+++ b/FL/Fl_Check_Button.H
@@ -0,0 +1,15 @@
+// Fl_Check_Button.H
+
+// Fl_Light_Button with a diamond down_box() and a red color.
+
+#ifndef Fl_Check_Button_H
+#define Fl_Check_Button_H
+
+#include "Fl_Light_Button.H"
+
+class Fl_Check_Button : public Fl_Light_Button {
+public:
+ Fl_Check_Button(int x,int y,int w,int h,const char *l = 0);
+};
+
+#endif
diff --git a/FL/Fl_Choice.H b/FL/Fl_Choice.H
new file mode 100644
index 000000000..8d5d3462f
--- /dev/null
+++ b/FL/Fl_Choice.H
@@ -0,0 +1,20 @@
+// Fl_Choice.H
+
+// Popup menu with last-picked item displayed in button
+
+#ifndef Fl_Choice_H
+#define Fl_Choice_H
+
+#include "Fl_Menu_.H"
+
+class Fl_Choice : public Fl_Menu_ {
+protected:
+ void draw();
+public:
+ int handle(int);
+ Fl_Choice(int,int,int,int,const char * = 0);
+ int value(int i);
+ int value() const {return Fl_Menu_::value();}
+};
+
+#endif
diff --git a/FL/Fl_Clock.H b/FL/Fl_Clock.H
new file mode 100644
index 000000000..b442e5474
--- /dev/null
+++ b/FL/Fl_Clock.H
@@ -0,0 +1,38 @@
+// Fl_Clock.H
+
+#ifndef Fl_Clock_H
+#define Fl_Clock_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type:
+#define FL_SQUARE_CLOCK 0
+#define FL_ROUND_CLOCK 1
+#define FL_ANALOG_CLOCK FL_SQUARE_CLOCK
+#define FL_DIGITAL_CLOCK FL_SQUARE_CLOCK // nyi
+
+class Fl_Clock : public Fl_Widget {
+ int hour_, minute_, second_;
+ ulong value_;
+ void drawhands(Fl_Color,Fl_Color); // part of draw
+protected:
+ void draw(int, int, int, int);
+ void draw();
+ void _Fl_Clock();
+ int handle(int);
+public:
+ Fl_Clock(int x,int y,int w,int h, const char *l = 0);
+ Fl_Clock(uchar t,int x,int y,int w,int h, const char *l);
+ ~Fl_Clock();
+ void value(ulong v); // set to this Unix time
+ void value(int,int,int); // set hour, minute, second
+ ulong value() const {return value_;}
+ int hour() const {return hour_;}
+ int minute() const {return minute_;}
+ int second() const {return second_;}
+};
+
+#endif
+
diff --git a/FL/Fl_Color_Chooser.H b/FL/Fl_Color_Chooser.H
new file mode 100644
index 000000000..e8f01cd56
--- /dev/null
+++ b/FL/Fl_Color_Chooser.H
@@ -0,0 +1,71 @@
+// Fl_Color_Chooser.H
+
+// The color chooser object and the color chooser popup. The popup
+// is just a window containing a single color chooser and some boxes
+// to indicate the current and cancelled color.
+
+#ifndef Fl_Color_Chooser_H
+#define Fl_Color_Chooser_H
+
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Value_Input.H>
+
+class Flcc_HueBox : public Fl_Widget {
+ int handle(int);
+ void draw();
+ int px, py;
+public:
+ Flcc_HueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
+ px = py = 0;}
+};
+
+class Flcc_ValueBox : public Fl_Widget {
+ int handle(int);
+ void draw();
+ int py;
+public:
+ Flcc_ValueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
+ py = 0;}
+};
+
+class Flcc_Value_Input : public Fl_Value_Input {
+public:
+ int format(char*);
+ Flcc_Value_Input(int X, int Y, int W, int H) : Fl_Value_Input(X,Y,W,H) {}
+};
+
+class Fl_Color_Chooser : public Fl_Group {
+ Flcc_HueBox huebox;
+ Flcc_ValueBox valuebox;
+ Fl_Choice choice;
+ Flcc_Value_Input rvalue;
+ Flcc_Value_Input gvalue;
+ Flcc_Value_Input bvalue;
+ Fl_Box resize_box;
+ double hue_, saturation_, value_;
+ double r_, g_, b_;
+ void set_valuators();
+ static void rgb_cb(Fl_Widget*, void*);
+ static void mode_cb(Fl_Widget*, void*);
+public:
+ int mode() {return choice.value();}
+ double hue() const {return hue_;}
+ double saturation() const {return saturation_;}
+ double value() const {return value_;}
+ double r() const {return r_;}
+ double g() const {return g_;}
+ double b() const {return b_;}
+ int hsv(double,double,double);
+ int rgb(double,double,double);
+ static void hsv2rgb(double, double, double,double&,double&,double&);
+ static void rgb2hsv(double, double, double,double&,double&,double&);
+ Fl_Color_Chooser(int,int,int,int,const char* = 0);
+};
+
+int fl_color_chooser(const char* name, double& r, double& g, double& b);
+int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b);
+
+#endif
diff --git a/FL/Fl_Counter.H b/FL/Fl_Counter.H
new file mode 100644
index 000000000..33c0002d2
--- /dev/null
+++ b/FL/Fl_Counter.H
@@ -0,0 +1,47 @@
+// Fl_Counter.H
+
+// A numerical value with up/down step buttons. From Forms.
+
+#ifndef Fl_Counter_H
+#define Fl_Counter_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+// values for type():
+#define FL_NORMAL_COUNTER 0
+#define FL_SIMPLE_COUNTER 1
+
+class Fl_Counter : public Fl_Valuator {
+
+ uchar textfont_, textsize_, textcolor_;
+ double lstep_;
+ uchar mouseobj;
+ static void repeat_callback(void *);
+ int calc_mouseobj();
+ void increment_cb();
+
+protected:
+
+ void draw();
+
+public:
+
+ int handle(int);
+ Fl_Counter(int,int,int,int,const char * = 0);
+ ~Fl_Counter();
+ void lstep(double a) {lstep_ = a;}
+ void step(double a,double b) {Fl_Valuator::step(a); lstep_ = b;}
+ void step(double a) {Fl_Valuator::step(a);}
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar s) {textfont_ = s;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar s) {textsize_ = s;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar s) {textcolor_ = s;}
+
+};
+
+#endif
+
diff --git a/FL/Fl_Dial.H b/FL/Fl_Dial.H
new file mode 100644
index 000000000..a6b74c7b1
--- /dev/null
+++ b/FL/Fl_Dial.H
@@ -0,0 +1,43 @@
+// Fl_Dial.H
+
+// A circular dial control, like xv uses. From Forms.
+
+#ifndef Fl_Dial_H
+#define Fl_Dial_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+// values for type():
+#define FL_NORMAL_DIAL 0
+#define FL_LINE_DIAL 1
+#define FL_FILL_DIAL 2
+
+#define FL_DIAL_CW 0
+#define FL_DIAL_CCW 1
+
+class Fl_Dial : public Fl_Valuator {
+
+ short a1,a2;
+ uchar direction_;
+
+protected:
+
+ // these allow subclasses to put the dial in a smaller area:
+ void draw(int, int, int, int);
+ int handle(int, int, int, int, int);
+ void draw();
+
+public:
+
+ int handle(int);
+ Fl_Dial(int x,int y,int w,int h, const char *l = 0);
+ void angles(short a, short b) {a1=a; a2=b;}
+ void direction(uchar d) {direction_ = d;}
+ uchar direction() const {return direction_;}
+
+};
+
+#endif
+
diff --git a/FL/Fl_Double_Window.H b/FL/Fl_Double_Window.H
new file mode 100644
index 000000000..ba7a42d90
--- /dev/null
+++ b/FL/Fl_Double_Window.H
@@ -0,0 +1,23 @@
+// Fl_Double_Window.H
+
+#ifndef Fl_Double_Window_H
+#define Fl_Double_Window_H
+
+#include "Fl_Window.H"
+
+class Fl_Double_Window : public Fl_Window {
+protected:
+ void _flush(int); // used by Fl_Overlay_Window
+public:
+ void show();
+ void show(int a, char **b) {Fl_Window::show(a,b);}
+ void flush();
+ void resize(int,int,int,int);
+ void hide();
+ ~Fl_Double_Window();
+ Fl_Double_Window(int W, int H, const char *l = 0) : Fl_Window(W,H,l) {}
+ Fl_Double_Window(int X, int Y, int W, int H, const char *l = 0)
+ : Fl_Window(X,Y,W,H,l) {}
+};
+
+#endif
diff --git a/FL/Fl_Fill_Dial.H b/FL/Fl_Fill_Dial.H
new file mode 100644
index 000000000..a0e699a72
--- /dev/null
+++ b/FL/Fl_Fill_Dial.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Fill_Dial_H
+#define Fl_Fill_Dial_H
+
+#include "Fl_Dial.H"
+
+class Fl_Fill_Dial : public Fl_Dial {
+public:
+ Fl_Fill_Dial(int x,int y,int w,int h, const char *l = 0)
+ : Fl_Dial(x,y,w,h,l) {type(FL_FILL_DIAL);}
+};
+
+#endif
diff --git a/FL/Fl_Fill_Slider.H b/FL/Fl_Fill_Slider.H
new file mode 100644
index 000000000..7fa946db0
--- /dev/null
+++ b/FL/Fl_Fill_Slider.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Fill_Slider_H
+#define Fl_Fill_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Fill_Slider : public Fl_Slider {
+public:
+ Fl_Fill_Slider(int x,int y,int w,int h,const char *l=0)
+ : Fl_Slider(x,y,w,h,l) {type(FL_VERT_FILL_SLIDER);}
+};
+
+#endif
diff --git a/FL/Fl_Float_Input.H b/FL/Fl_Float_Input.H
new file mode 100644
index 000000000..fc70bbebc
--- /dev/null
+++ b/FL/Fl_Float_Input.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Float_Input_H
+#define Fl_Float_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Float_Input : public Fl_Input {
+public:
+ Fl_Float_Input(int x,int y,int w,int h,const char *l = 0)
+ : Fl_Input(x,y,w,h,l) {type(FL_FLOAT_INPUT);}
+};
+
+#endif
diff --git a/FL/Fl_FormsBitmap.H b/FL/Fl_FormsBitmap.H
new file mode 100644
index 000000000..2790f66f9
--- /dev/null
+++ b/FL/Fl_FormsBitmap.H
@@ -0,0 +1,23 @@
+/* Fl_FormsBitmap.H
+
+ Forms compatability widget
+
+*/
+
+#ifndef Fl_FormsBitmap_H
+#define Fl_FormsBitmap_H
+
+#include "Fl_Bitmap.H"
+
+class Fl_FormsBitmap : public Fl_Widget {
+ Fl_Bitmap *b;
+protected:
+ void draw();
+public:
+ Fl_FormsBitmap(Fl_Boxtype, int, int, int, int, const char * = 0);
+ void set(int W, int H, const uchar *bits);
+ void bitmap(Fl_Bitmap *B) {b = B;}
+ Fl_Bitmap *bitmap() const {return b;}
+};
+
+#endif
diff --git a/FL/Fl_FormsPixmap.H b/FL/Fl_FormsPixmap.H
new file mode 100644
index 000000000..f5515848c
--- /dev/null
+++ b/FL/Fl_FormsPixmap.H
@@ -0,0 +1,23 @@
+/* Fl_FormsPixmap.H
+
+ Forms compatability widget
+
+*/
+
+#ifndef Fl_FormsPixmap_H
+#define Fl_FormsPixmap_H
+
+#include "Fl_Pixmap.H"
+
+class Fl_FormsPixmap : public Fl_Widget {
+ Fl_Pixmap *b;
+protected:
+ void draw();
+public:
+ Fl_FormsPixmap(Fl_Boxtype, int, int, int, int, const char * = 0);
+ void set(/*const*/char * const * bits);
+ void Pixmap(Fl_Pixmap *B) {b = B;}
+ Fl_Pixmap *Pixmap() const {return b;}
+};
+
+#endif
diff --git a/FL/Fl_Free.H b/FL/Fl_Free.H
new file mode 100644
index 000000000..edba73fb8
--- /dev/null
+++ b/FL/Fl_Free.H
@@ -0,0 +1,40 @@
+// Fl_Free.H
+
+// Emulation of the Forms "free" widget. This emulation allows the
+// free demo to run, but it is not clear if it is sufficient to make
+// porting programs any easier.
+
+#ifndef Fl_Free_H
+#define Fl_Free_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+#define FL_NORMAL_FREE 1
+#define FL_SLEEPING_FREE 2
+#define FL_INPUT_FREE 3
+#define FL_CONTINUOUS_FREE 4
+#define FL_ALL_FREE 5
+
+typedef int (*FL_HANDLEPTR)(Fl_Widget *, int , float, float, char);
+
+class Fl_Free : public Fl_Widget {
+ FL_HANDLEPTR hfunc;
+ static void step(void *);
+ void draw();
+ int handle(int);
+public:
+ Fl_Free(uchar t,int x,int y,int w,int h,const char *l,FL_HANDLEPTR hdl);
+ ~Fl_Free();
+};
+
+// old event names for compatability:
+#define FL_MOUSE FL_DRAG
+#define FL_DRAW 0
+#define FL_STEP 9
+#define FL_FREEMEM 12
+#define FL_FREEZE FL_UNMAP
+#define FL_THAW FL_MAP
+
+#endif
diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H
new file mode 100644
index 000000000..1cc083c53
--- /dev/null
+++ b/FL/Fl_Gl_Window.H
@@ -0,0 +1,60 @@
+#ifndef Fl_Gl_Window_H
+#define Fl_Gl_Window_H
+
+#include "Fl_Window.H"
+
+class Fl_Gl_Choice; // structure to hold result of glXChooseVisual
+
+class Fl_Gl_Window : public Fl_Window {
+
+ int mode_;
+ const int *alist;
+ Fl_Gl_Choice *g;
+ void * context; // actually a GLXContext
+ char valid_;
+ char damage1_; // damage() of back buffer
+ virtual void draw_overlay();
+ void init();
+
+ void *overlay;
+ void make_overlay();
+ friend class _Fl_Gl_Overlay;
+
+ static int can_do(int, const int *);
+ int mode(int, const int *);
+
+public:
+
+ void show();
+ void show(int a, char **b) {Fl_Window::show(a,b);}
+ void flush();
+ void hide();
+ void resize(int,int,int,int);
+
+ char valid() const {return valid_;}
+ void valid(char i) {valid_ = i;}
+ void invalidate();
+
+ static int can_do(int i) {return can_do(i,0);}
+ static int can_do(const int *i) {return can_do(0, i);}
+ int can_do() {return can_do(mode_,alist);}
+ Fl_Mode mode() const {return (Fl_Mode)mode_;}
+ int mode(int a) {return mode(a,0);}
+ int mode(const int *a) {return mode(0, a);}
+
+ int can_do_overlay();
+ void redraw_overlay();
+ void hide_overlay();
+
+ void make_current();
+ void make_overlay_current();
+ void swap_buffers();
+ void ortho();
+
+ ~Fl_Gl_Window();
+ Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();}
+ Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0)
+ : Fl_Window(X,Y,W,H,l) {init();}
+};
+
+#endif
diff --git a/FL/Fl_Group.H b/FL/Fl_Group.H
new file mode 100644
index 000000000..c64af5312
--- /dev/null
+++ b/FL/Fl_Group.H
@@ -0,0 +1,73 @@
+// Fl_Group.H
+
+#ifndef Fl_Group_H
+#define Fl_Group_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+class Fl_Group : public Fl_Widget {
+
+ Fl_Widget** array_;
+ Fl_Widget* savedfocus_;
+ Fl_Widget* resizable_;
+ int children_;
+ short *sizes_; // remembered initial sizes of children
+
+ int navigation(int = 0);
+ static Fl_Group *current_;
+
+protected:
+
+ void draw();
+ int handle(int);
+ void draw_child(Fl_Widget&) const;
+ void update_child(Fl_Widget&) const;
+ void draw_outside_label(const Fl_Widget&) const ;
+ short* sizes();
+
+public:
+
+ void begin() {current_ = this;}
+ void end() {current_ = (Fl_Group*)parent();}
+ static Fl_Group *current() {return current_;}
+ static void current(Fl_Group *g) {current_ = g;}
+
+ int children() const {return children_;}
+ Fl_Widget* child(int n) const {return array()[n];}
+ int find(const Fl_Widget*) const;
+ int find(const Fl_Widget& o) const {return find(&o);}
+ Fl_Widget* const* array() const;
+
+ void resize(int,int,int,int);
+ Fl_Group(int,int,int,int, const char * = 0);
+ virtual ~Fl_Group();
+ void add(Fl_Widget&);
+ void add(Fl_Widget* o) {add(*o);}
+ void insert(Fl_Widget&, int i);
+ void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));}
+ void remove(Fl_Widget&);
+ void remove(Fl_Widget* o) {remove(*o);}
+ void clear();
+
+ void resizable(Fl_Widget& o) {resizable_ = &o;}
+ void resizable(Fl_Widget* o) {resizable_ = o;}
+ Fl_Widget* resizable() const {return resizable_;}
+ void add_resizable(Fl_Widget& o) {resizable_ = &o; add(o);}
+ void init_sizes();
+
+ // back compatability function:
+ void focus(Fl_Widget* o) {o->take_focus();}
+ Fl_Widget* & _ddfdesign_kludge() {return resizable_;}
+ void forms_end();
+};
+
+// dummy class used to end child groups in constructors for complex
+// subclasses of Fl_Group:
+class Fl_End {
+public:
+ Fl_End() {Fl_Group::current()->end();}
+};
+
+#endif
diff --git a/FL/Fl_Hold_Browser.H b/FL/Fl_Hold_Browser.H
new file mode 100644
index 000000000..19faf82f0
--- /dev/null
+++ b/FL/Fl_Hold_Browser.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Hold_Browser_H
+#define Fl_Hold_Browser_H
+
+#include "Fl_Browser.H"
+
+class Fl_Hold_Browser : public Fl_Browser {
+public:
+ Fl_Hold_Browser(int x,int y,int w,int h,const char *l=0)
+ : Fl_Browser(x,y,w,h,l) {type(FL_HOLD_BROWSER);}
+};
+
+#endif
diff --git a/FL/Fl_Hor_Fill_Slider.H b/FL/Fl_Hor_Fill_Slider.H
new file mode 100644
index 000000000..f049b6f75
--- /dev/null
+++ b/FL/Fl_Hor_Fill_Slider.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Hor_Fill_Slider_H
+#define Fl_Hor_Fill_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Hor_Fill_Slider : public Fl_Slider {
+public:
+ Fl_Hor_Fill_Slider(int x,int y,int w,int h,const char *l=0)
+ : Fl_Slider(x,y,w,h,l) {type(FL_HOR_FILL_SLIDER);}
+};
+
+#endif
diff --git a/FL/Fl_Hor_Nice_Slider.H b/FL/Fl_Hor_Nice_Slider.H
new file mode 100644
index 000000000..5fd141a9e
--- /dev/null
+++ b/FL/Fl_Hor_Nice_Slider.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Hor_Nice_Slider_H
+#define Fl_Hor_Nice_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Hor_Nice_Slider : public Fl_Slider {
+public:
+ Fl_Hor_Nice_Slider(int x,int y,int w,int h,const char *l=0)
+ : Fl_Slider(x,y,w,h,l) {type(FL_HOR_NICE_SLIDER); box(FL_FLAT_BOX);}
+};
+
+#endif
diff --git a/FL/Fl_Hor_Slider.H b/FL/Fl_Hor_Slider.H
new file mode 100644
index 000000000..0e9e54fa0
--- /dev/null
+++ b/FL/Fl_Hor_Slider.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Hor_Slider_H
+#define Fl_Hor_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Hor_Slider : public Fl_Slider {
+public:
+ Fl_Hor_Slider(int x,int y,int w,int h,const char *l=0)
+ : Fl_Slider(x,y,w,h,l) {type(FL_HOR_SLIDER);}
+};
+
+#endif
diff --git a/FL/Fl_Hor_Value_Slider.H b/FL/Fl_Hor_Value_Slider.H
new file mode 100644
index 000000000..e0fc43db3
--- /dev/null
+++ b/FL/Fl_Hor_Value_Slider.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Hor_Value_Slider_H
+#define Fl_Hor_Value_Slider_H
+
+#include "Fl_Value_Slider.H"
+
+class Fl_Hor_Value_Slider : public Fl_Value_Slider {
+public:
+ Fl_Hor_Value_Slider(int x,int y,int w,int h,const char *l=0)
+ : Fl_Value_Slider(x,y,w,h,l) {type(FL_HOR_SLIDER);}
+};
+
+#endif
diff --git a/FL/Fl_Image.H b/FL/Fl_Image.H
new file mode 100644
index 000000000..7e03a70aa
--- /dev/null
+++ b/FL/Fl_Image.H
@@ -0,0 +1,22 @@
+/* Fl_Image.H */
+
+#ifndef Fl_Image_H
+#define Fl_Image_H
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+struct Fl_Image {
+ const uchar *array;
+ int w, h, d, ld;
+ ulong id; // for internal use
+ Fl_Image(const uchar *bits, int W, int H, int D=3, int LD=0) :
+ array(bits), w(W), h(H), d(D), ld(LD), id(0) {}
+ ~Fl_Image();
+ void label(Fl_Widget*);
+ void label(Fl_Menu_Item*);
+ void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+ void draw(int X, int Y) {draw(X, Y, w, h, 0, 0);}
+};
+
+#endif
diff --git a/FL/Fl_Input.H b/FL/Fl_Input.H
new file mode 100644
index 000000000..172a30447
--- /dev/null
+++ b/FL/Fl_Input.H
@@ -0,0 +1,22 @@
+// Fl_Input.H
+
+// This is the "user interface", it decodes user actions into what to
+// do to the text. See also Fl_Input_.H for text manipulation functions.
+
+#ifndef Fl_Input_H
+#define Fl_Input_H
+
+#include "Fl_Input_.H"
+
+class Fl_Input : public Fl_Input_ {
+ int handle_key();
+ int shift_position(int p);
+ int shift_up_down_position(int p);
+ void handle_mouse(int keepmark=0);
+public:
+ void draw();
+ int handle(int);
+ Fl_Input(int,int,int,int,const char * = 0);
+};
+
+#endif
diff --git a/FL/Fl_Input_.H b/FL/Fl_Input_.H
new file mode 100644
index 000000000..696ffe829
--- /dev/null
+++ b/FL/Fl_Input_.H
@@ -0,0 +1,107 @@
+// Fl_Input_.H
+
+#ifndef Fl_Input__H
+#define Fl_Input__H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+#define FL_NORMAL_INPUT 0
+#define FL_FLOAT_INPUT 1
+#define FL_INT_INPUT 2
+#define FL_HIDDEN_INPUT 3
+#define FL_MULTILINE_INPUT 4
+#define FL_SECRET_INPUT 5
+
+class Fl_Input_ : public Fl_Widget {
+
+ const char* value_;
+ char* buffer;
+
+ int size_;
+ int bufsize;
+ int position_;
+ int mark_;
+ int xscroll_, yscroll_;
+ int mu_p;
+ int maximum_size_;
+
+ uchar textfont_;
+ uchar textsize_;
+ uchar textcolor_;
+ uchar cursor_color_;
+ uchar erase_cursor_only;
+
+ const char* expand(const char*, char*) const;
+ double expandpos(const char*, const char*, const char*, int*) const;
+ void minimal_update(int, int);
+ void minimal_update(int p);
+ void put_in_buffer(int newsize);
+
+ static Fl_Boxtype default_box_;
+ static Fl_Font default_font_;
+ static int default_size_;
+ void setfont() const;
+
+protected:
+
+ int wordboundary(int i) const;
+ int lineboundary(int i) const;
+ void drawtext(int, int, int, int);
+ int up_down_position(int, int keepmark=0);
+ void handle_mouse(int, int, int, int, int keepmark=0);
+ int handletext(int e, int, int, int, int);
+ void maybe_do_callback();
+ int xscroll() const {return xscroll_;}
+ int yscroll() const {return yscroll_;}
+
+public:
+
+ void resize(int, int, int, int);
+
+ Fl_Input_(int, int, int, int, const char* = 0);
+ ~Fl_Input_();
+
+ int value(const char*);
+ int value(const char*, int);
+ int static_value(const char*);
+ int static_value(const char*, int);
+ const char* value() const {return value_;}
+ char index(int i) const {return value_[i];}
+ int size() const {return size_;}
+ int maximum_size() const {return maximum_size_;}
+ void maximum_size(int m) {maximum_size_ = m;}
+
+ int position() const {return position_;}
+ int mark() const {return mark_;}
+ int position(int p, int m);
+ int position(int p) {return position(p, p);}
+ int mark(int m) {return position(position(), m);}
+ int replace(int, int, const char*, int=0);
+ int cut() {return replace(position(), mark(), 0);}
+ int cut(int n) {return replace(position(), position()+n, 0);}
+ int cut(int a, int b) {return replace(a, b, 0);}
+ int insert(const char* t, int l=0){return replace(position_, mark_, t, l);}
+ int copy();
+ int undo();
+ int copy_cuts();
+
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar s) {textfont_ = s;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar s) {textsize_ = s;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar n) {textcolor_ = n;}
+ Fl_Color cursor_color() const {return (Fl_Color)cursor_color_;}
+ void cursor_color(uchar n) {cursor_color_ = n;}
+
+ static void default_box(Fl_Boxtype b) {default_box_ = b;}
+ static Fl_Boxtype default_box() {return default_box_;}
+ static void default_font(Fl_Font b) {default_font_ = b;}
+ static Fl_Font default_font() {return default_font_;}
+ static void default_size(int b) {default_size_ = b;}
+ static int default_size() {return default_size_;}
+};
+
+#endif
diff --git a/FL/Fl_Int_Input.H b/FL/Fl_Int_Input.H
new file mode 100644
index 000000000..97648e5fa
--- /dev/null
+++ b/FL/Fl_Int_Input.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Int_Input_H
+#define Fl_Int_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Int_Input : public Fl_Input {
+public:
+ Fl_Int_Input(int x,int y,int w,int h,const char *l = 0)
+ : Fl_Input(x,y,w,h,l) {type(FL_INT_INPUT);}
+};
+
+#endif
diff --git a/FL/Fl_Light_Button.H b/FL/Fl_Light_Button.H
new file mode 100644
index 000000000..cd55ded00
--- /dev/null
+++ b/FL/Fl_Light_Button.H
@@ -0,0 +1,23 @@
+// Fl_Light_Button.H
+
+// Subclass of Fl_Button where the "box" indicates whether it is
+// pushed or not, and the "down box" is drawn small and square on
+// the left to indicate the current state.
+
+// The default down_box of zero draws a rectangle designed to look
+// just like Flame's buttons.
+
+#ifndef Fl_Light_Button_H
+#define Fl_Light_Button_H
+
+#include "Fl_Button.H"
+
+class Fl_Light_Button : public Fl_Button {
+protected:
+ virtual void draw();
+public:
+ virtual int handle(int);
+ Fl_Light_Button(int x,int y,int w,int h,const char *l = 0);
+};
+
+#endif
diff --git a/FL/Fl_Line_Dial.H b/FL/Fl_Line_Dial.H
new file mode 100644
index 000000000..c4eb48dd4
--- /dev/null
+++ b/FL/Fl_Line_Dial.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Line_Dial_H
+#define Fl_Line_Dial_H
+
+#include "Fl_Dial.H"
+
+class Fl_Line_Dial : public Fl_Dial {
+public:
+ Fl_Line_Dial(int x,int y,int w,int h, const char *l = 0)
+ : Fl_Dial(x,y,w,h,l) {type(FL_LINE_DIAL);}
+};
+
+#endif
diff --git a/FL/Fl_Menu.H b/FL/Fl_Menu.H
new file mode 100644
index 000000000..6aad15936
--- /dev/null
+++ b/FL/Fl_Menu.H
@@ -0,0 +1,2 @@
+// this include file is for back compatability only
+#include "Fl_Menu_Item.H"
diff --git a/FL/Fl_Menu_.H b/FL/Fl_Menu_.H
new file mode 100644
index 000000000..658ad74a7
--- /dev/null
+++ b/FL/Fl_Menu_.H
@@ -0,0 +1,82 @@
+// Fl_Menu_.H
+
+// This is a base class for all items that have a menu:
+// Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice
+// This provides storage for a menu item, functions to add/modify/delete
+// items, and a call for when the user picks a menu item.
+// Implementation in Fl_Menu.C
+
+#ifndef Fl_Menu__H
+#define Fl_Menu__H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+#include "Fl_Menu_Item.H"
+
+class Fl_Menu_ : public Fl_Widget {
+
+ Fl_Menu_Item *menu_;
+ const Fl_Menu_Item *value_;
+ static Fl_Font default_font_;
+ static int default_size_;
+
+protected:
+
+ const Fl_Menu_Item* picked(const Fl_Menu_Item*);
+ uchar down_box_;
+ uchar textfont_;
+ uchar textsize_;
+ uchar textcolor_;
+ uchar alloc;
+
+public:
+
+ Fl_Menu_(int,int,int,int,const char * =0);
+ ~Fl_Menu_();
+
+ const Fl_Menu_Item* test_shortcut() {return picked(menu()->test_shortcut());}
+ void global();
+
+ const Fl_Menu_Item *menu() const {return menu_;}
+ void menu(const Fl_Menu_Item *m);
+ int add(const char*, int shortcut, Fl_Callback*, void* = 0, int = 0);
+ int add(const char* a, const char* b, Fl_Callback* c,
+ void* d = 0, int e = 0) {return add(a,fl_old_shortcut(b),c,d,e);}
+ int size() const ;
+ void clear();
+ int add(const char *);
+ void replace(int,const char *);
+ void remove(int);
+ void shortcut(int i, int s) {menu_[i].shortcut(s);}
+ void mode(int i,int x) {menu_[i].flags = x;}
+ int mode(int i) const {return menu_[i].flags;}
+
+ const Fl_Menu_Item *mvalue() const {return value_;}
+ int value() const {return value_-menu_;}
+ int value(const Fl_Menu_Item*);
+ int value(int i) {return value(menu_+i);}
+ const char *text() const {return value_ ? value_->text : 0;}
+ const char *text(int i) const {return menu_[i].text;}
+
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar c) {textfont_=c;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar c) {textsize_=c;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar c) {textcolor_=c;}
+
+ static void default_font(Fl_Font b) {default_font_ = b;}
+ static Fl_Font default_font() {return default_font_;}
+ static void default_size(int b) {default_size_ = b;}
+ static int default_size() {return default_size_;}
+
+ Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;}
+ void down_box(Fl_Boxtype b) {down_box_ = b;}
+
+ // back compatability:
+ Fl_Color down_color() const {return selection_color();}
+ void down_color(uchar c) {selection_color(c);}
+};
+
+#endif
diff --git a/FL/Fl_Menu_Bar.H b/FL/Fl_Menu_Bar.H
new file mode 100644
index 000000000..0985b7dbe
--- /dev/null
+++ b/FL/Fl_Menu_Bar.H
@@ -0,0 +1,27 @@
+// Fl_Menu_Bar.H
+
+// The implementation is in Fl_Menu.C
+
+#ifndef Fl_Menu_Bar_H
+#define Fl_Menu_Bar_H
+
+#include "Fl_Menu_.H"
+
+class Fl_Menu_Bar : public Fl_Menu_ {
+protected:
+ int handle(int);
+ void draw();
+public:
+ Fl_Menu_Bar(int x,int y,int w,int h,const char *l=0)
+ : Fl_Menu_(x,y,w,h,l) {}
+};
+
+#endif
+
+
+
+
+
+
+
+
diff --git a/FL/Fl_Menu_Button.H b/FL/Fl_Menu_Button.H
new file mode 100644
index 000000000..81d7d1af0
--- /dev/null
+++ b/FL/Fl_Menu_Button.H
@@ -0,0 +1,19 @@
+// Fl_Menu_Button.C
+
+#ifndef Fl_Menu_Button_H
+#define Fl_Menu_Button_H
+
+#include "Fl_Menu_.H"
+
+class Fl_Menu_Button : public Fl_Menu_ {
+protected:
+ void draw();
+public:
+ // values for type:
+ enum {POPUP1 = 1, POPUP2, POPUP12, POPUP3, POPUP13, POPUP23, POPUP123};
+ int handle(int);
+ const Fl_Menu_Item* popup();
+ Fl_Menu_Button(int,int,int,int,const char * =0);
+};
+
+#endif
diff --git a/FL/Fl_Menu_Item.H b/FL/Fl_Menu_Item.H
new file mode 100644
index 000000000..99085a8b6
--- /dev/null
+++ b/FL/Fl_Menu_Item.H
@@ -0,0 +1,134 @@
+// Fl_Menu_Item.H
+
+// The Fl_Menu_ widget has a pointer to an array of these structures.
+// These are designed so that the array can be built efficiently using
+// a C initialization constant.
+
+#ifndef Fl_Menu_Item_H
+#define Fl_Menu_Item_H
+
+#ifndef Fl_Widget_H
+// used to get the Fl_Callback typedefs:
+#include "Fl_Widget.H"
+#endif
+
+enum { // values for flags:
+ FL_MENU_INACTIVE = 1,
+ FL_MENU_TOGGLE= 2,
+ FL_MENU_VALUE = 4,
+ FL_MENU_RADIO = 8,
+ FL_MENU_INVISIBLE = 0x10,
+ FL_SUBMENU_POINTER = 0x20,
+ FL_SUBMENU = 0x40,
+ FL_MENU_DIVIDER = 0x80,
+ FL_MENU_HORIZONTAL = 0x100
+};
+
+extern int fl_old_shortcut(const char*);
+
+class Fl_Menu_;
+
+struct Fl_Menu_Item {
+ const char *text; // label()
+ int shortcut_;
+ Fl_Callback *callback_;
+ void *user_data_;
+ int flags;
+ uchar labeltype_;
+ uchar labelfont_;
+ uchar labelsize_;
+ uchar labelcolor_;
+
+ // advance N items, skipping submenus:
+ const Fl_Menu_Item *next(int=1) const;
+ Fl_Menu_Item *next(int i=1) {
+ return (Fl_Menu_Item*)(((const Fl_Menu_Item*)this)->next(i));}
+
+ // methods on menu items:
+ const char* label() const {return text;}
+ void label(const char* a) {text=a;}
+ void label(Fl_Labeltype a,const char* b) {labeltype_ = a; text = b;}
+ Fl_Labeltype labeltype() const {return (Fl_Labeltype)labeltype_;}
+ void labeltype(Fl_Labeltype a) {labeltype_ = a;}
+ Fl_Color labelcolor() const {return (Fl_Color)labelcolor_;}
+ void labelcolor(uchar a) {labelcolor_ = a;}
+ Fl_Font labelfont() const {return (Fl_Font)labelfont_;}
+ void labelfont(uchar a) {labelfont_ = a;}
+ uchar labelsize() const {return labelsize_;}
+ void labelsize(uchar a) {labelsize_ = a;}
+ Fl_Callback* callback() const {return callback_;}
+ void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;}
+ void callback(Fl_Callback* c) {callback_=c;}
+ void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;}
+ void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}
+ void* user_data() const {return user_data_;}
+ void user_data(void* v) {user_data_ = v;}
+ long argument() const {return (long)user_data_;}
+ void argument(long v) {user_data_ = (void*)v;}
+ int shortcut() const {return shortcut_;}
+ void shortcut(int s) {shortcut_ = s;}
+ int submenu() const {return flags&(FL_SUBMENU|FL_SUBMENU_POINTER);}
+ int checkbox() const {return flags&FL_MENU_TOGGLE;}
+ int radio() const {return flags&FL_MENU_RADIO;}
+ int value() const {return flags&FL_MENU_VALUE;}
+ void set() {flags |= FL_MENU_VALUE;}
+ void clear() {flags &= ~FL_MENU_VALUE;}
+ void setonly();
+ int visible() const {return !(flags&FL_MENU_INVISIBLE);}
+ void show() {flags &= ~FL_MENU_INVISIBLE;}
+ void hide() {flags |= FL_MENU_INVISIBLE;}
+ int active() const {return !(flags&FL_MENU_INACTIVE);}
+ void activate() {flags &= ~FL_MENU_INACTIVE;}
+ void deactivate() {flags |= FL_MENU_INACTIVE;}
+ int activevisible() const {return !(flags&0x11);}
+
+ // used by menubar:
+ int measure(int* h, const Fl_Menu_*) const;
+ void draw(int x, int y, int w, int h, const Fl_Menu_*, int t=0) const;
+
+ // popup menus without using an Fl_Menu_ widget:
+ const Fl_Menu_Item* popup(
+ int X, int Y,
+ const char *title = 0,
+ const Fl_Menu_Item* picked=0,
+ const Fl_Menu_* = 0) const;
+ const Fl_Menu_Item* pulldown(
+ int X, int Y, int W, int H,
+ const Fl_Menu_Item* picked = 0,
+ const Fl_Menu_* = 0,
+ const Fl_Menu_Item* title = 0,
+ int menubar=0) const;
+ const Fl_Menu_Item* test_shortcut() const;
+ const Fl_Menu_Item* find_shortcut(int *ip=0) const;
+
+ void do_callback(Fl_Widget* o) const {callback_(o, user_data_);}
+ void do_callback(Fl_Widget* o,void* arg) const {callback_(o, arg);}
+ void do_callback(Fl_Widget* o,long arg) const {callback_(o, (void*)arg);}
+
+ // back-compatability, do not use:
+ int checked() const {return flags&FL_MENU_VALUE;}
+ void check() {flags |= FL_MENU_VALUE;}
+ void uncheck() {flags &= ~FL_MENU_VALUE;}
+ int add(const char*, int shortcut, Fl_Callback*, void* =0, int = 0);
+ int add(const char*a, const char* b, Fl_Callback* c,
+ void* d = 0, int e = 0) {
+ return add(a,fl_old_shortcut(b),c,d,e);}
+ int size() const ;
+};
+
+typedef Fl_Menu_Item Fl_Menu; // back compatability
+
+enum { // back-compatability enum:
+ FL_PUP_NONE = 0,
+ FL_PUP_GREY = FL_MENU_INACTIVE,
+ FL_PUP_GRAY = FL_MENU_INACTIVE,
+ FL_MENU_BOX = FL_MENU_TOGGLE,
+ FL_PUP_BOX = FL_MENU_TOGGLE,
+ FL_MENU_CHECK = FL_MENU_VALUE,
+ FL_PUP_CHECK = FL_MENU_VALUE,
+ FL_PUP_RADIO = FL_MENU_RADIO,
+ FL_PUP_INVISIBLE = FL_MENU_INVISIBLE,
+ FL_PUP_SUBMENU = FL_SUBMENU_POINTER
+};
+
+#endif
diff --git a/FL/Fl_Menu_Window.H b/FL/Fl_Menu_Window.H
new file mode 100644
index 000000000..081827e2b
--- /dev/null
+++ b/FL/Fl_Menu_Window.H
@@ -0,0 +1,29 @@
+// Fl_Menu_Window.H
+
+// This is the window type used by Fl_Menu to make the pop-ups. It
+// draws in the overlay planes, if possible, and does other fun things
+// such as turning on override_redirect.
+
+#ifndef Fl_Menu_Window_H
+#define Fl_Menu_Window_H
+
+#include "Fl_Single_Window.H"
+
+class Fl_Menu_Window : public Fl_Single_Window {
+ enum {NO_OVERLAY = 128};
+public:
+ void show();
+ void erase();
+ void flush();
+ void hide();
+ int overlay() {return !(flags()&NO_OVERLAY);}
+ void set_overlay() {clear_flag(NO_OVERLAY);}
+ void clear_overlay() {set_flag(NO_OVERLAY);}
+ ~Fl_Menu_Window();
+ Fl_Menu_Window(int W, int H, const char *l = 0)
+ : Fl_Single_Window(W,H,l) {}
+ Fl_Menu_Window(int X, int Y, int W, int H, const char *l = 0)
+ : Fl_Single_Window(X,Y,W,H,l) {}
+};
+
+#endif
diff --git a/FL/Fl_Multi_Browser.H b/FL/Fl_Multi_Browser.H
new file mode 100644
index 000000000..69a986759
--- /dev/null
+++ b/FL/Fl_Multi_Browser.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Multi_Browser_H
+#define Fl_Multi_Browser_H
+
+#include "Fl_Browser.H"
+
+class Fl_Multi_Browser : public Fl_Browser {
+public:
+ Fl_Multi_Browser(int x,int y,int w,int h,const char *l=0)
+ : Fl_Browser(x,y,w,h,l) {type(FL_MULTI_BROWSER);}
+};
+
+#endif
diff --git a/FL/Fl_Multi_Label.H b/FL/Fl_Multi_Label.H
new file mode 100644
index 000000000..7a30a7497
--- /dev/null
+++ b/FL/Fl_Multi_Label.H
@@ -0,0 +1,18 @@
+// Fl_Multi_Label.H
+
+#ifndef Fl_Multi_Label_H
+#define Fl_Multi_Label_H
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+struct Fl_Multi_Label {
+ const char* labela;
+ const char* labelb;
+ uchar typea;
+ uchar typeb;
+ void label(Fl_Widget*);
+ void label(Fl_Menu_Item*);
+};
+
+#endif
diff --git a/FL/Fl_Multiline_Input.H b/FL/Fl_Multiline_Input.H
new file mode 100644
index 000000000..83bc2bd35
--- /dev/null
+++ b/FL/Fl_Multiline_Input.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Multiline_Input_H
+#define Fl_Multiline_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Multiline_Input : public Fl_Input {
+public:
+ Fl_Multiline_Input(int x,int y,int w,int h,const char *l = 0)
+ : Fl_Input(x,y,w,h,l) {type(FL_MULTILINE_INPUT);}
+};
+
+#endif
diff --git a/FL/Fl_Multiline_Output.H b/FL/Fl_Multiline_Output.H
new file mode 100644
index 000000000..0bf99e5d0
--- /dev/null
+++ b/FL/Fl_Multiline_Output.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Multiline_Output_H
+#define Fl_Multiline_Output_H
+
+#include "Fl_Output.H"
+
+class Fl_Multiline_Output : public Fl_Output {
+public:
+ Fl_Multiline_Output(int x,int y,int w,int h,const char *l = 0)
+ : Fl_Output(x,y,w,h,l) {type(FL_MULTILINE_INPUT);}
+};
+
+#endif
diff --git a/FL/Fl_Nice_Slider.H b/FL/Fl_Nice_Slider.H
new file mode 100644
index 000000000..1bb49b47c
--- /dev/null
+++ b/FL/Fl_Nice_Slider.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Nice_Slider_H
+#define Fl_Nice_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Nice_Slider : public Fl_Slider {
+public:
+ Fl_Nice_Slider(int x,int y,int w,int h,const char *l=0)
+ : Fl_Slider(x,y,w,h,l) {type(FL_VERT_NICE_SLIDER); box(FL_FLAT_BOX);}
+};
+
+#endif
diff --git a/FL/Fl_Object.H b/FL/Fl_Object.H
new file mode 100644
index 000000000..18c1fc110
--- /dev/null
+++ b/FL/Fl_Object.H
@@ -0,0 +1,5 @@
+// This file is provided for back compatability only. Please use Fl_Widget
+#ifndef Fl_Object
+#define Fl_Object Fl_Widget
+#endif
+#include "Fl_Widget.H"
diff --git a/FL/Fl_Output.H b/FL/Fl_Output.H
new file mode 100644
index 000000000..784e3202a
--- /dev/null
+++ b/FL/Fl_Output.H
@@ -0,0 +1,18 @@
+// Fl_Output.H
+// a non-editable subclass of Fl_Input_
+
+#ifndef Fl_Output_H
+#define Fl_Output_H
+
+#include "Fl_Input_.H"
+
+class Fl_Output : public Fl_Input_ {
+protected:
+ void draw();
+public:
+ int handle(int);
+ Fl_Output(int x, int y, int w, int h, const char *l = 0)
+ : Fl_Input_(x, y, w, h, l) {}
+};
+
+#endif
diff --git a/FL/Fl_Overlay_Window.H b/FL/Fl_Overlay_Window.H
new file mode 100644
index 000000000..76bf5bcf3
--- /dev/null
+++ b/FL/Fl_Overlay_Window.H
@@ -0,0 +1,31 @@
+// Fl_Overlay_Window.H
+
+// A window using double-buffering and able to draw an overlay
+// on top of that. Uses the hardware to draw the overlay if
+// possible, otherwise it just draws in the front buffer.
+
+#ifndef Fl_Overlay_Window_H
+#define Fl_Overlay_Window_H
+
+#include "Fl_Double_Window.H"
+
+class Fl_Overlay_Window : public Fl_Double_Window {
+ friend class _Fl_Overlay;
+ virtual void draw_overlay() = 0;
+ Fl_Window *overlay_;
+public:
+ void show();
+ void flush();
+ void hide();
+ void resize(int,int,int,int);
+ ~Fl_Overlay_Window();
+ int can_do_overlay();
+ void redraw_overlay();
+ Fl_Overlay_Window(int W, int H, const char *l=0)
+ : Fl_Double_Window(W,H,l) {overlay_ = 0;}
+ Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0)
+ : Fl_Double_Window(X,Y,W,H,l) {overlay_ = 0;}
+ void show(int a, char **b) {Fl_Double_Window::show(a,b);}
+};
+
+#endif
diff --git a/FL/Fl_Pack.H b/FL/Fl_Pack.H
new file mode 100644
index 000000000..5cc59439f
--- /dev/null
+++ b/FL/Fl_Pack.H
@@ -0,0 +1,22 @@
+// Fl_Pack.H
+
+#ifndef Fl_Pack_H
+#define Fl_Pack_H
+
+#include <FL/Fl_Group.H>
+
+class Fl_Pack : public Fl_Group {
+ int spacing_;
+public:
+ enum { // values for type(int)
+ VERTICAL = 0,
+ HORIZONTAL = 1
+ };
+ void draw();
+ Fl_Pack(int x,int y,int w ,int h,const char *l = 0);
+ int spacing() const {return spacing_;}
+ void spacing(int i) {spacing_ = i;}
+ uchar horizontal() const {return type();}
+};
+
+#endif
diff --git a/FL/Fl_Pixmap.H b/FL/Fl_Pixmap.H
new file mode 100644
index 000000000..128761521
--- /dev/null
+++ b/FL/Fl_Pixmap.H
@@ -0,0 +1,22 @@
+/* Fl_Pixmap.H */
+
+#ifndef Fl_Pixmap_H
+#define Fl_Pixmap_H
+
+class Fl_Widget;
+struct Fl_Menu_Item;
+
+struct Fl_Pixmap {
+ /*const*/ char * const * data;
+ int w, h; // set by first draw...
+ ulong id; // for internal use (the pixmap)
+ ulong mask; // for internal use (mask bitmap)
+ Fl_Pixmap(/*const*/char * const * d) : data(d), w(-1), h(0), id(0),mask(0) {}
+ ~Fl_Pixmap();
+ void label(Fl_Widget*);
+ void label(Fl_Menu_Item*);
+ void draw(int X, int Y, int W, int H, int cx=0, int cy=0);
+ void draw(int X, int Y) {draw(X, Y, w, h, 0, 0);}
+};
+
+#endif
diff --git a/FL/Fl_Positioner.H b/FL/Fl_Positioner.H
new file mode 100644
index 000000000..6b8d4f346
--- /dev/null
+++ b/FL/Fl_Positioner.H
@@ -0,0 +1,51 @@
+// Fl_Positioner.H
+
+// The positioner widget from Forms, gives 2D input
+
+#ifndef Fl_Positioner_H
+#define Fl_Positioner_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+class Fl_Positioner : public Fl_Widget {
+
+ double xmin, ymin;
+ double xmax, ymax;
+ double xvalue_, yvalue_;
+ double xstep_, ystep_;
+
+protected:
+
+ // these allow subclasses to put the dial in a smaller area:
+ void draw(int, int, int, int);
+ int handle(int, int, int, int, int);
+ void draw();
+
+public:
+
+ int handle(int);
+ Fl_Positioner(int x,int y,int w,int h, const char *l=0);
+ double xvalue() const {return xvalue_;}
+ double yvalue() const {return yvalue_;}
+ int xvalue(double);
+ int yvalue(double);
+ int value(double,double);
+ void xbounds(double, double);
+ double xminimum() const {return xmin;}
+ void xminimum(double a) {xbounds(a,xmax);}
+ double xmaximum() const {return xmax;}
+ void xmaximum(double a) {xbounds(xmin,a);}
+ void ybounds(double, double);
+ double yminimum() const {return ymin;}
+ void yminimum(double a) {ybounds(a,ymax);}
+ double ymaximum() const {return ymax;}
+ void ymaximum(double a) {ybounds(ymin,a);}
+ void xstep(double a) {xstep_ = a;}
+ void ystep(double a) {ystep_ = a;}
+
+};
+
+#endif
+
diff --git a/FL/Fl_Radio_Button.H b/FL/Fl_Radio_Button.H
new file mode 100644
index 000000000..494ea03d2
--- /dev/null
+++ b/FL/Fl_Radio_Button.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Radio_Button_H
+#define Fl_Radio_Button_H
+
+#include "Fl_Button.H"
+
+class Fl_Radio_Button : public Fl_Button {
+public:
+ Fl_Radio_Button(int x,int y,int w,int h,const char *l=0)
+ : Fl_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);}
+};
+
+#endif
diff --git a/FL/Fl_Radio_Light_Button.H b/FL/Fl_Radio_Light_Button.H
new file mode 100644
index 000000000..54bb16c93
--- /dev/null
+++ b/FL/Fl_Radio_Light_Button.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Radio_Light_Button_H
+#define Fl_Radio_Light_Button_H
+
+#include "Fl_Light_Button.H"
+
+class Fl_Radio_Light_Button : public Fl_Light_Button {
+public:
+ Fl_Radio_Light_Button(int x,int y,int w,int h,const char *l=0)
+ : Fl_Light_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);}
+};
+
+#endif
diff --git a/FL/Fl_Radio_Round_Button.H b/FL/Fl_Radio_Round_Button.H
new file mode 100644
index 000000000..119a9a5ff
--- /dev/null
+++ b/FL/Fl_Radio_Round_Button.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Radio_Round_Button_H
+#define Fl_Radio_Round_Button_H
+
+#include "Fl_Round_Button.H"
+
+class Fl_Radio_Round_Button : public Fl_Round_Button {
+public:
+ Fl_Radio_Round_Button(int x,int y,int w,int h,const char *l=0)
+ : Fl_Round_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);}
+};
+
+#endif
diff --git a/FL/Fl_Repeat_Button.H b/FL/Fl_Repeat_Button.H
new file mode 100644
index 000000000..849902a4b
--- /dev/null
+++ b/FL/Fl_Repeat_Button.H
@@ -0,0 +1,18 @@
+// Fl_Repeat_Button.H
+
+// When held down, this generates callbacks repeatedly.
+// Forms called this a "touch" button.
+
+#ifndef Fl_Repeat_Button_H
+#define Fl_Repeat_Button_H
+#include "Fl_Button.H"
+
+class Fl_Repeat_Button : public Fl_Button {
+ static void repeat_callback(void *);
+public:
+ int handle(int);
+ Fl_Repeat_Button(int x,int y,int w,int h,const char *l=0)
+ : Fl_Button(x,y,w,h,l) {}
+};
+
+#endif
diff --git a/FL/Fl_Return_Button.H b/FL/Fl_Return_Button.H
new file mode 100644
index 000000000..793e578f3
--- /dev/null
+++ b/FL/Fl_Return_Button.H
@@ -0,0 +1,19 @@
+// Fl_Return_Button.H
+
+// Just like a normal button except it has a built-in shortcut for
+// the Enter key and it draws a user-friendly arrow on the button.
+
+#ifndef Fl_Return_Button_H
+#define Fl_Return_Button_H
+#include "Fl_Button.H"
+
+class Fl_Return_Button : public Fl_Button {
+protected:
+ void draw();
+public:
+ int handle(int);
+ Fl_Return_Button(int x,int y,int w,int h,const char *l=0)
+ : Fl_Button(x,y,w,h,l) {}
+};
+
+#endif
diff --git a/FL/Fl_Roller.H b/FL/Fl_Roller.H
new file mode 100644
index 000000000..ef0da9361
--- /dev/null
+++ b/FL/Fl_Roller.H
@@ -0,0 +1,19 @@
+// Fl_Roller.H
+
+// Rapid-App style knob
+
+#ifndef Fl_Roller_H
+#define Fl_Roller_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+class Fl_Roller : public Fl_Valuator {
+ void draw();
+public:
+ int handle(int);
+ Fl_Roller(int X,int Y,int W,int H,const char* L=0);
+};
+
+#endif
diff --git a/FL/Fl_Round_Button.H b/FL/Fl_Round_Button.H
new file mode 100644
index 000000000..9b7bb22d8
--- /dev/null
+++ b/FL/Fl_Round_Button.H
@@ -0,0 +1,15 @@
+// Fl_Round_Button.H
+
+// A Fl_Light_Button with a round down_box() and a red color.
+
+#ifndef Fl_Round_Button_H
+#define Fl_Round_Button_H
+
+#include "Fl_Light_Button.H"
+
+class Fl_Round_Button : public Fl_Light_Button {
+public:
+ Fl_Round_Button(int x,int y,int w,int h,const char *l = 0);
+};
+
+#endif
diff --git a/FL/Fl_Round_Clock.H b/FL/Fl_Round_Clock.H
new file mode 100644
index 000000000..9ad9b0042
--- /dev/null
+++ b/FL/Fl_Round_Clock.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Round_Clock_H
+#define Fl_Round_Clock_H
+
+#include "Fl_Clock.H"
+
+class Fl_Round_Clock : public Fl_Clock {
+public:
+ Fl_Round_Clock(int x,int y,int w,int h, const char *l = 0)
+ : Fl_Clock(x,y,w,h,l) {type(FL_ROUND_CLOCK); box(FL_NO_BOX);}
+};
+
+#endif
diff --git a/FL/Fl_Scroll.H b/FL/Fl_Scroll.H
new file mode 100644
index 000000000..ce8c83c02
--- /dev/null
+++ b/FL/Fl_Scroll.H
@@ -0,0 +1,50 @@
+// Fl_Scroll.H
+// A scrolling area of child widgets.
+
+#ifndef Fl_Scroll_H
+#define Fl_Scroll_H
+
+#include "Fl_Group.H"
+#include "Fl_Scrollbar.H"
+
+class Fl_Scroll : public Fl_Group {
+
+ int xposition_, yposition_;
+ int width_, height_;
+ int oldx, oldy;
+ static void hscrollbar_cb(Fl_Widget*, void*);
+ static void scrollbar_cb(Fl_Widget*, void*);
+ void fix_scrollbar_order();
+ static void draw_clip(void*,int,int,int,int);
+ void bbox(int&,int&,int&,int&);
+
+protected:
+
+ void draw();
+
+public:
+
+ Fl_Scrollbar scrollbar;
+ Fl_Scrollbar hscrollbar;
+
+ void resize(int,int,int,int);
+ int handle(int);
+
+ Fl_Scroll(int X,int Y,int W,int H,const char*l=0);
+
+ enum { // values for type()
+ HORIZONTAL = 1,
+ VERTICAL = 2,
+ BOTH = 3,
+ ALWAYS_ON = 4,
+ HORIZONTAL_ALWAYS = 5,
+ VERTICAL_ALWAYS = 6,
+ BOTH_ALWAYS = 7
+ };
+
+ int xposition() const {return xposition_;}
+ int yposition() const {return yposition_;}
+ void position(int, int);
+};
+
+#endif
diff --git a/FL/Fl_Scrollbar.H b/FL/Fl_Scrollbar.H
new file mode 100644
index 000000000..cac210f46
--- /dev/null
+++ b/FL/Fl_Scrollbar.H
@@ -0,0 +1,30 @@
+// Fl_Scrollbar.H
+
+#ifndef Fl_Scrollbar_H
+#define Fl_Scrollbar_H
+
+#include "Fl_Slider.H"
+
+class Fl_Scrollbar : public Fl_Slider {
+
+ int linesize_;
+ int pushed_;
+ void draw();
+ int handle(int);
+ static void timeout_cb(void*);
+ void increment_cb();
+
+public:
+
+ Fl_Scrollbar(int x,int y,int w,int h, const char *l = 0);
+
+ int value() {return int(Fl_Slider::value());}
+ int value(int position, int size, int top, int total) {
+ return scrollvalue(position, size, top, total);
+ }
+ int linesize() const {return linesize_;}
+ void linesize(int i) {linesize_ = i;}
+
+};
+
+#endif
diff --git a/FL/Fl_Secret_Input.H b/FL/Fl_Secret_Input.H
new file mode 100644
index 000000000..2a4fac8a3
--- /dev/null
+++ b/FL/Fl_Secret_Input.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Secret_Input_H
+#define Fl_Secret_Input_H
+
+#include "Fl_Input.H"
+
+class Fl_Secret_Input : public Fl_Input {
+public:
+ Fl_Secret_Input(int x,int y,int w,int h,const char *l = 0)
+ : Fl_Input(x,y,w,h,l) {type(FL_SECRET_INPUT);}
+};
+
+#endif
diff --git a/FL/Fl_Select_Browser.H b/FL/Fl_Select_Browser.H
new file mode 100644
index 000000000..205b31f38
--- /dev/null
+++ b/FL/Fl_Select_Browser.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Select_Browser_H
+#define Fl_Select_Browser_H
+
+#include "Fl_Browser.H"
+
+class Fl_Select_Browser : public Fl_Browser {
+public:
+ Fl_Select_Browser(int x,int y,int w,int h,const char *l=0)
+ : Fl_Browser(x,y,w,h,l) {type(FL_SELECT_BROWSER);}
+};
+
+#endif
diff --git a/FL/Fl_Simple_Counter.H b/FL/Fl_Simple_Counter.H
new file mode 100644
index 000000000..bbb316e81
--- /dev/null
+++ b/FL/Fl_Simple_Counter.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Simple_Counter_H
+#define Fl_Simple_Counter_H
+
+#include "Fl_Counter.H"
+
+class Fl_Simple_Counter : public Fl_Counter {
+public:
+ Fl_Simple_Counter(int x,int y,int w,int h, const char *l = 0)
+ : Fl_Counter(x,y,w,h,l) {type(FL_SIMPLE_COUNTER);}
+};
+
+#endif
diff --git a/FL/Fl_Single_Window.H b/FL/Fl_Single_Window.H
new file mode 100644
index 000000000..79b0349c2
--- /dev/null
+++ b/FL/Fl_Single_Window.H
@@ -0,0 +1,20 @@
+// Fl_Single_Window.H
+
+#ifndef Fl_Single_Window_H
+#define Fl_Single_Window_H
+
+#include "Fl_Window.H"
+
+class Fl_Single_Window : public Fl_Window {
+public:
+ void show();
+ void show(int a, char **b) {Fl_Window::show(a,b);}
+ void flush();
+ Fl_Single_Window(int W, int H, const char *l=0)
+ : Fl_Window(W,H,l) {}
+ Fl_Single_Window(int X, int Y, int W, int H, const char *l=0)
+ : Fl_Window(X,Y,W,H,l) {}
+ int make_current();
+};
+
+#endif
diff --git a/FL/Fl_Slider.H b/FL/Fl_Slider.H
new file mode 100644
index 000000000..148f761be
--- /dev/null
+++ b/FL/Fl_Slider.H
@@ -0,0 +1,46 @@
+// Fl_Slider.H
+
+#ifndef Fl_Slider_H
+#define Fl_Slider_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+// values for type(), lowest bit indicate horizontal:
+#define FL_VERT_SLIDER 0
+#define FL_HOR_SLIDER 1
+#define FL_VERT_FILL_SLIDER 2
+#define FL_HOR_FILL_SLIDER 3
+#define FL_VERT_NICE_SLIDER 4
+#define FL_HOR_NICE_SLIDER 5
+
+class Fl_Slider : public Fl_Valuator {
+
+ float slider_size_;
+ uchar slider_;
+ void _Fl_Slider();
+ void draw_bg(int, int, int, int);
+
+protected:
+
+ // these allow subclasses to put the slider in a smaller area:
+ void draw(int, int, int, int);
+ int handle(int, int, int, int, int);
+
+public:
+
+ void draw();
+ int handle(int);
+ Fl_Slider(int x,int y,int w,int h, const char *l = 0);
+ Fl_Slider(uchar t,int x,int y,int w,int h, const char *l);
+
+ int scrollvalue(int windowtop,int windowsize,int first,int totalsize);
+ void bounds(double a, double b);
+ float slider_size() const {return slider_size_;}
+ void slider_size(double v);
+ Fl_Boxtype slider() const {return (Fl_Boxtype)slider_;}
+ void slider(Fl_Boxtype c) {slider_ = c;}
+};
+
+#endif
diff --git a/FL/Fl_Tabs.H b/FL/Fl_Tabs.H
new file mode 100644
index 000000000..2af820908
--- /dev/null
+++ b/FL/Fl_Tabs.H
@@ -0,0 +1,31 @@
+// Fl_Tabs.C
+
+// This is the "file card tabs" interface to allow you to put lots and lots
+// of buttons and switches in a panel, as popularized by many toolkits.
+
+// Each child widget is a card, and it's label() is printed on the card tab.
+// Clicking the tab makes that card visible.
+
+#ifndef Fl_Tabs_H
+#define Fl_Tabs_H
+
+#include "Fl_Group.H"
+
+class Fl_Tabs : public Fl_Group {
+ Fl_Widget *value_;
+ Fl_Widget *push_;
+ void draw();
+ int tab_positions(int*, int*);
+ int tab_height();
+ void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0);
+public:
+ int handle(int);
+ Fl_Widget *value();
+ int value(Fl_Widget *);
+ Fl_Widget *push() const {return push_;}
+ int push(Fl_Widget *);
+ Fl_Tabs(int,int,int,int,const char * = 0);
+ Fl_Widget *which(int event_x, int event_y);
+};
+
+#endif
diff --git a/FL/Fl_Tile.H b/FL/Fl_Tile.H
new file mode 100644
index 000000000..118fd2cc4
--- /dev/null
+++ b/FL/Fl_Tile.H
@@ -0,0 +1,18 @@
+// Fl_Tile.H - Group of 2,3 or 4 "tiles" that can be resized by
+// dragging the borders between them. May be improved in the future
+// to handle more tiles in arbitrary layout.
+
+#ifndef Fl_Tile_H
+#define Fl_Tile_H
+
+#include "Fl_Group.H"
+
+class Fl_Tile : public Fl_Group {
+ int handle(int);
+public:
+ Fl_Tile(int X,int Y,int W,int H,const char*l=0) : Fl_Group(X,Y,W,H,l) {}
+ void resize(int, int, int, int);
+ void position(int, int, int, int);
+};
+
+#endif
diff --git a/FL/Fl_Timer.H b/FL/Fl_Timer.H
new file mode 100644
index 000000000..7ed9e018b
--- /dev/null
+++ b/FL/Fl_Timer.H
@@ -0,0 +1,38 @@
+// Fl_Timer.H
+
+// Emulate the forms Timer widget
+
+#ifndef Fl_Timer_H
+#define Fl_Timer_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// values for type():
+#define FL_NORMAL_TIMER 0
+#define FL_VALUE_TIMER 1
+#define FL_HIDDEN_TIMER 2
+
+class Fl_Timer : public Fl_Widget {
+ static void stepcb(void *);
+ void step();
+ char on, direction_;
+ double delay, total;
+ long lastsec,lastusec;
+protected:
+ void draw();
+public:
+ int handle(int);
+ Fl_Timer(uchar t,int x,int y,int w,int h, const char *l);
+ ~Fl_Timer();
+ void value(double);
+ double value() const {return delay>0.0?delay:0.0;}
+ char direction() const {return direction_;}
+ void direction(char d) {direction_ = d;}
+ char suspended() const {return !on;}
+ void suspended(char d);
+};
+
+#endif
+
diff --git a/FL/Fl_Toggle_Button.H b/FL/Fl_Toggle_Button.H
new file mode 100644
index 000000000..12da9a577
--- /dev/null
+++ b/FL/Fl_Toggle_Button.H
@@ -0,0 +1,12 @@
+#ifndef Fl_Toggle_Button_H
+#define Fl_Toggle_Button_H
+
+#include "Fl_Button.H"
+
+class Fl_Toggle_Button : public Fl_Button {
+public:
+ Fl_Toggle_Button(int x,int y,int w,int h,const char *l=0)
+ : Fl_Button(x,y,w,h,l) {type(FL_TOGGLE_BUTTON);}
+};
+
+#endif
diff --git a/FL/Fl_Toggle_Light_Button.H b/FL/Fl_Toggle_Light_Button.H
new file mode 100644
index 000000000..5ac3c1b16
--- /dev/null
+++ b/FL/Fl_Toggle_Light_Button.H
@@ -0,0 +1,6 @@
+// provided for back-compatability only
+
+#ifndef Fl_Toggle_Light_Button
+#include "Fl_Light_Button.H"
+#define Fl_Toggle_Light_Button Fl_Light_Button
+#endif
diff --git a/FL/Fl_Toggle_Round_Button.H b/FL/Fl_Toggle_Round_Button.H
new file mode 100644
index 000000000..18f74f7b8
--- /dev/null
+++ b/FL/Fl_Toggle_Round_Button.H
@@ -0,0 +1,6 @@
+// provided for back-compatability only
+
+#ifndef Fl_Toggle_Round_Button
+#include "Fl_Round_Button.H"
+#define Fl_Toggle_Round_Button Fl_Round_Button
+#endif
diff --git a/FL/Fl_Valuator.H b/FL/Fl_Valuator.H
new file mode 100644
index 000000000..4444bdd8d
--- /dev/null
+++ b/FL/Fl_Valuator.H
@@ -0,0 +1,59 @@
+// Fl_Valuator.H
+
+// Base class for sliders and all other one-value "knobs"
+
+#ifndef Fl_Valuator_H
+#define Fl_Valuator_H
+
+#ifndef Fl_Widget_H
+#include "Fl_Widget.H"
+#endif
+
+// shared type() values for classes that work in both directions:
+#define FL_VERTICAL 0
+#define FL_HORIZONTAL 1
+
+class Fl_Valuator : public Fl_Widget {
+
+ double value_;
+ double previous_value_;
+ double min, max; // truncates to this range *after* rounding
+ double A; int B; // rounds to multiples of A/B, or no rounding if A is zero
+
+protected:
+
+ int horizontal() const {return type()&1;}
+ Fl_Valuator(int X, int Y, int W, int H, const char* L);
+
+ double previous_value() const {return previous_value_;}
+ void handle_push() {previous_value_ = value_;}
+ double softclamp(double);
+ void handle_drag(double newvalue);
+ void handle_release(); // use drag() value
+ virtual void value_damage(); // cause damage() due to value() changing
+
+public:
+
+ void bounds(double a, double b) {min=a; max=b;}
+ double minimum() const {return min;}
+ void minimum(double a) {min = a;}
+ double maximum() const {return max;}
+ void maximum(double a) {max = a;}
+ void range(double a, double b) {min = a; max = b;}
+ void step(int a) {A = a; B = 1;}
+ void step(double a, int b) {A = a; B = b;}
+ void step(double s);
+ double step() const {return A/B;}
+ void precision(int);
+
+ double value() const {return value_;}
+ int value(double);
+
+ virtual int format(char*);
+ double round(double); // round to nearest multiple of step
+ double clamp(double); // keep in range
+ double increment(double, int); // add n*step to value
+};
+
+#endif
+
diff --git a/FL/Fl_Value_Input.H b/FL/Fl_Value_Input.H
new file mode 100644
index 000000000..ddb557b05
--- /dev/null
+++ b/FL/Fl_Value_Input.H
@@ -0,0 +1,50 @@
+// Fl_Value_Input.H
+
+// Edit text or drag to adjust floating point value.
+// as suggested by Pierre Jasmin
+
+// Current behavior:
+// Dragging left mouse moves by step()
+// Middle mouse is 5*step()
+// Right mouse is 20*step()
+// clicking any mouse button puts insertion cursor there
+// You can also navigate there with tab
+
+// Bugs (?):
+// No way to select region of text
+// Hard to paste in new values
+
+#ifndef Fl_Value_Input_H
+#define Fl_Value_Input_H
+
+#include "Fl_Valuator.H"
+#include "Fl_Input.H"
+
+class Fl_Value_Input : public Fl_Valuator {
+public:
+ Fl_Input input;
+private:
+ char soft_;
+ static void input_cb(Fl_Widget*,void*);
+ virtual void value_damage(); // cause damage() due to value() changing
+public:
+ int handle(int);
+ void draw();
+ void resize(int,int,int,int);
+ Fl_Value_Input(int x,int y,int w,int h,const char *l=0);
+
+ void soft(char x) {soft_ = x;}
+ char soft() const {return soft_;}
+
+ Fl_Font textfont() const {return input.textfont();}
+ void textfont(uchar s) {input.textfont(s);}
+ uchar textsize() const {return input.textsize();}
+ void textsize(uchar s) {input.textsize(s);}
+ Fl_Color textcolor() const {return input.textcolor();}
+ void textcolor(uchar n) {input.textcolor(n);}
+ Fl_Color cursor_color() const {return input.cursor_color();}
+ void cursor_color(uchar n) {input.cursor_color(n);}
+
+};
+
+#endif
diff --git a/FL/Fl_Value_Output.H b/FL/Fl_Value_Output.H
new file mode 100644
index 000000000..0d1e10a7a
--- /dev/null
+++ b/FL/Fl_Value_Output.H
@@ -0,0 +1,32 @@
+// Fl_Value_Output.H
+
+// Fltk widget for drag-adjusting a floating point value.
+// This is much lighter than Fl_Value_Input because it has no text editor
+// If you deactivate() it, it can be used to display a floating-point value
+
+#ifndef Fl_Value_Output_H
+#define Fl_Value_Output_H
+
+#ifndef Fl_Valuator_H
+#include "Fl_Valuator.H"
+#endif
+
+class Fl_Value_Output : public Fl_Valuator {
+ uchar textfont_, textsize_, textcolor_, soft_;
+public:
+ int handle(int);
+ void draw();
+ Fl_Value_Output(int x,int y,int w,int h,const char *l=0);
+
+ void soft(uchar x) {soft_ = x;}
+ uchar soft() const {return soft_;}
+
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar s) {textfont_ = s;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar s) {textsize_ = s;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar s) {textcolor_ = s;}
+};
+
+#endif
diff --git a/FL/Fl_Value_Slider.H b/FL/Fl_Value_Slider.H
new file mode 100644
index 000000000..defc8ccde
--- /dev/null
+++ b/FL/Fl_Value_Slider.H
@@ -0,0 +1,26 @@
+/* Fl_Value_Slider.H
+
+ A slider with a box displaying the current value
+
+*/
+
+#ifndef Fl_Value_Slider_H
+#define Fl_Value_Slider_H
+
+#include "Fl_Slider.H"
+
+class Fl_Value_Slider : public Fl_Slider {
+ uchar textfont_, textsize_, textcolor_;
+public:
+ void draw();
+ int handle(int);
+ Fl_Value_Slider(int x,int y,int w,int h, const char *l = 0);
+ Fl_Font textfont() const {return (Fl_Font)textfont_;}
+ void textfont(uchar s) {textfont_ = s;}
+ uchar textsize() const {return textsize_;}
+ void textsize(uchar s) {textsize_ = s;}
+ Fl_Color textcolor() const {return (Fl_Color)textcolor_;}
+ void textcolor(uchar s) {textcolor_ = s;}
+};
+
+#endif
diff --git a/FL/Fl_Widget.H b/FL/Fl_Widget.H
new file mode 100644
index 000000000..d49fced1b
--- /dev/null
+++ b/FL/Fl_Widget.H
@@ -0,0 +1,178 @@
+// Fl_Widget.H
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+#ifndef Fl_Widget_H
+#define Fl_Widget_H
+
+#include "Enumerations.H"
+
+class Fl_Widget;
+class Fl_Window;
+
+typedef void (Fl_Callback )(Fl_Widget*, void*);
+typedef void (Fl_Callback0)(Fl_Widget*);
+typedef void (Fl_Callback1)(Fl_Widget*, long);
+
+struct Fl_Label {
+ const char* value;
+ uchar type;
+ uchar font;
+ uchar size;
+ uchar color;
+ void draw(int,int,int,int, Fl_Align) const ;
+ void measure(int&, int&) const ;
+};
+
+class Fl_Widget {
+ friend class Fl_Group;
+
+ Fl_Widget* parent_;
+ Fl_Callback* callback_;
+ void* user_data_;
+ short x_,y_,w_,h_;
+ Fl_Label label_;
+ uchar type_;
+ uchar flags_;
+ uchar damage_;
+ uchar box_;
+ uchar color_;
+ uchar color2_;
+ uchar align_;
+ uchar when_;
+
+ // "de-implement" the copy constructors:
+ Fl_Widget & operator=(const Fl_Widget &);
+ Fl_Widget(const Fl_Widget &);
+
+protected:
+
+ Fl_Widget(int,int,int,int,const char* =0);
+
+ void x(int v) {x_ = v;}
+ void y(int v) {y_ = v;}
+ void w(int v) {w_ = v;}
+ void h(int v) {h_ = v;}
+
+ uchar flags() const {return flags_;}
+ void set_flag(int c) {flags_ |= c;}
+ void clear_flag(int c) {flags_ &= ~c;}
+ enum {INACTIVE=1, INVISIBLE=2, OUTPUT=4, SHORTCUT_LABEL=64, CHANGED=128};
+
+ void draw_box() const;
+ void draw_box(Fl_Boxtype, Fl_Color) const;
+ void draw_box(Fl_Boxtype, int,int,int,int, Fl_Color) const;
+ void draw_label() const;
+ void draw_label(int, int, int, int) const;
+
+ static Fl_Font default_font_;
+ static int default_size_;
+
+public:
+
+ virtual ~Fl_Widget();
+
+ virtual void draw() = 0;
+ virtual int handle(int);
+ Fl_Widget* parent() const {return parent_;}
+ void parent(Fl_Widget* w) {parent_ = w;} // for hacks only
+
+ uchar type() const {return type_;}
+ void type(uchar t) {type_ = t;}
+
+ int x() const {return x_;}
+ int y() const {return y_;}
+ int w() const {return w_;}
+ int h() const {return h_;}
+ virtual void resize(int,int,int,int);
+ int damage_resize(int,int,int,int);
+ void position(int X,int Y) {resize(X,Y,w_,h_);}
+ void size(int W,int H) {resize(x_,y_,W,H);}
+
+ Fl_Align align() const {return (Fl_Align)align_;}
+ void align(uchar a) {align_ = a;}
+ Fl_Boxtype box() const {return (Fl_Boxtype)box_;}
+ void box(Fl_Boxtype a) {box_ = a;}
+ Fl_Color color() const {return (Fl_Color)color_;}
+ void color(uchar a) {color_ = a;}
+ Fl_Color selection_color() const {return (Fl_Color)color2_;}
+ void selection_color(uchar a) {color2_ = a;}
+ void color(uchar a, uchar b) {color_=a; color2_=b;}
+ const char* label() const {return label_.value;}
+ void label(const char* a) {label_.value=a;}
+ void label(Fl_Labeltype a,const char* b) {label_.type = a; label_.value = b;}
+ Fl_Labeltype labeltype() const {return (Fl_Labeltype)label_.type;}
+ void labeltype(Fl_Labeltype a) {label_.type = a;}
+ Fl_Color labelcolor() const {return (Fl_Color)label_.color;}
+ void labelcolor(uchar a) {label_.color=a;}
+ Fl_Font labelfont() const {return (Fl_Font)label_.font;}
+ void labelfont(uchar a) {label_.font=a;}
+ uchar labelsize() const {return label_.size;}
+ void labelsize(uchar a) {label_.size=a;}
+ Fl_Callback* callback() const {return callback_;}
+ void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;}
+ void callback(Fl_Callback* c) {callback_=c;}
+ void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;}
+ void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}
+ void* user_data() const {return user_data_;}
+ void user_data(void* v) {user_data_ = v;}
+ long argument() const {return (long)user_data_;}
+ void argument(long v) {user_data_ = (void*)v;}
+ Fl_When when() const {return (Fl_When)when_;}
+ void when(uchar i) {when_ = i;}
+
+ static void default_font(Fl_Font b) {default_font_ = b;}
+ static Fl_Font default_font() {return default_font_;}
+ static void default_size(int b) {default_size_ = b;}
+ static int default_size() {return default_size_;}
+
+ int visible() const {return !(flags_&INVISIBLE);}
+ int visible_r() const;
+ void show();
+ void hide();
+ void set_visible() {flags_ &= ~INVISIBLE;}
+ void clear_visible() {flags_ |= INVISIBLE;}
+ int active() const {return !(flags_&INACTIVE);}
+ int active_r() const;
+ void activate();
+ void deactivate();
+ int output() const {return (flags_&OUTPUT);}
+ void set_output() {flags_ |= OUTPUT;}
+ void clear_output() {flags_ &= ~OUTPUT;}
+ int takesevents() const {return !(flags_&(INACTIVE|INVISIBLE|OUTPUT));}
+ int changed() const {return flags_&CHANGED;}
+ void set_changed() {flags_ |= CHANGED;}
+ void clear_changed() {flags_ &= ~CHANGED;}
+ int take_focus();
+
+ static void default_callback(Fl_Widget*, void*);
+ void do_callback() {callback_(this,user_data_);}
+ void do_callback(Fl_Widget* o,void* arg=0) {callback_(o,arg);}
+ void do_callback(Fl_Widget* o,long arg) {callback_(o,(void*)arg);}
+ int test_shortcut();
+ static int test_shortcut(const char*);
+ int contains(const Fl_Widget*) const ;
+ int inside(const Fl_Widget* o) const {return o ? o->contains(this) : 0;}
+
+ void redraw();
+ uchar damage() const {return damage_;}
+ void clear_damage(uchar c = 0) {damage_ = c;}
+ void damage(uchar c);
+ void damage(uchar c,int,int,int,int);
+ void draw_label(int, int, int, int, Fl_Align) const;
+ void measure_label(int& x, int& y) {label_.measure(x,y);}
+
+ Fl_Window* window() const ;
+
+ // back compatability only:
+ Fl_Color color2() const {return (Fl_Color)color2_;}
+ void color2(uchar a) {color2_ = a;}
+};
+
+// reserved type numbers (necessary for my cheapo RTTI) start here.
+// grep the header files for "RESERVED_TYPE" to find the next available
+// number.
+#define FL_RESERVED_TYPE 100
+
+#endif
diff --git a/FL/Fl_Window.H b/FL/Fl_Window.H
new file mode 100644
index 000000000..b365f67cf
--- /dev/null
+++ b/FL/Fl_Window.H
@@ -0,0 +1,90 @@
+// Fl_Window.H
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+#ifndef Fl_Window_H
+#define Fl_Window_H
+
+#include "Fl_Group.H"
+
+#define FL_WINDOW 0xF0 // all subclasses have type() >= this
+
+class Fl_Window : public Fl_Group {
+
+ friend class Fl_X; Fl_X *i; // points at the system-specific stuff
+
+ const char* iconlabel_;
+ const char* xclass_;
+ // size_range stuff:
+ short minw, minh, maxw, maxh;
+ uchar dw, dh, aspect, size_range_set;
+ void size_range_();
+ // values for flags():
+ enum {
+ FL_MODAL = 64,
+ FL_NOBORDER = 8,
+ FL_FORCE_POSITION = 16,
+ FL_NON_MODAL = 32
+ };
+ static Fl_Window *current_;
+ void _Fl_Window(); // constructor innards
+
+protected:
+
+ virtual void draw();
+ virtual void flush();
+
+public:
+
+ Fl_Window(int,int,int,int, const char* = 0);
+ Fl_Window(int,int, const char* = 0);
+ virtual ~Fl_Window();
+
+ virtual int handle(int);
+
+ virtual void resize(int,int,int,int);
+ void border(int b);
+ void clear_border() {set_flag(FL_NOBORDER);}
+ int border() const {return !(flags() & FL_NOBORDER);}
+ void set_modal() {set_flag(FL_MODAL);}
+ uchar modal() const {return flags() & FL_MODAL;}
+ void set_non_modal() {set_flag(FL_NON_MODAL);}
+ uchar non_modal() const {return flags() & (FL_NON_MODAL|FL_MODAL);}
+
+ void hotspot(int x, int y, int offscreen = 0);
+ void hotspot(const Fl_Widget*, int offscreen = 0);
+ void hotspot(const Fl_Widget& p, int offscreen = 0) {hotspot(&p,offscreen);}
+ void free_position() {clear_flag(FL_FORCE_POSITION);}
+ void size_range(int a, int b, int c=0, int d=0, int e=0, int f=0, int g=0) {
+ minw=a; minh=b; maxw=c; maxh=d; dw=e; dh=f; aspect=g; size_range_();}
+
+ const char* label() const {return Fl_Widget::label();}
+ const char* iconlabel() const {return iconlabel_;}
+ void label(const char*);
+ void iconlabel(const char*);
+ void label(const char* label, const char* iconlabel);
+ const char* xclass() const {return xclass_;}
+ void xclass(const char* c) {xclass_ = c;}
+
+ int shown() {return i != 0;}
+ virtual void show();
+ virtual void hide();
+ void show(int, char**);
+ void fullscreen();
+ void fullscreen_off(int,int,int,int);
+ void iconize();
+
+ int x_root() const ;
+ int y_root() const ;
+
+ static Fl_Window *current() {return current_;}
+ void make_current();
+
+ // for back-compatability only:
+ void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
+ static void default_callback(Fl_Window*, void* v);
+
+};
+
+#endif
diff --git a/FL/dirent.h b/FL/dirent.h
new file mode 100644
index 000000000..2ddc15dae
--- /dev/null
+++ b/FL/dirent.h
@@ -0,0 +1,4 @@
+// this file is for back-compatability only
+#include "fl_scandir.H"
+
+
diff --git a/FL/filename.H b/FL/filename.H
new file mode 100644
index 000000000..2952108e7
--- /dev/null
+++ b/FL/filename.H
@@ -0,0 +1,41 @@
+// filename.H
+
+// fltk filename utilities. These are used by the file chooser but may
+// be useful to other programs.
+
+#ifndef FL_PATH_MAX
+
+#define FL_PATH_MAX 256 // all buffers are this length
+
+const char *filename_name(const char *); // return pointer to name
+const char *filename_ext(const char *); // return pointer to .ext
+char *filename_setext(char *,const char *ext); // clobber .ext
+int filename_expand(char *, const char *from); // do $x and ~x
+int filename_absolute(char *, const char *from); // prepend getcwd()
+int filename_match(const char *, const char *pattern); // glob match
+int filename_isdir(const char*);
+
+// Portable "scandir" function. Ugly but apparently necessary...
+
+#ifdef WIN32
+
+struct dirent {char d_name[1];};
+
+#else
+
+#include <sys/types.h>
+#include <dirent.h>
+// warning: on some systems (very few nowadays?) <dirent.h> may not exist.
+// The correct information is in one of these files:
+//#include <sys/ndir.h>
+//#include <sys/dir.h>
+//#include <ndir.h>
+// plus you must do the following #define:
+//#define dirent direct
+// It would be best to create a <dirent.h> file that does this...
+
+#endif
+
+int filename_list(const char *d, dirent ***list);
+
+#endif
diff --git a/FL/fl_ask.H b/FL/fl_ask.H
new file mode 100644
index 000000000..8671e0140
--- /dev/null
+++ b/FL/fl_ask.H
@@ -0,0 +1,51 @@
+// fl_ask.H
+
+// Pop-up window utilities
+// This header file is usable without including any other fltk headers
+
+#ifndef fl_ask_H
+#define fl_ask_H
+
+class Fl_Widget;
+
+void fl_message(const char *);
+void fl_alert(const char *);
+int fl_ask(const char *);
+int fl_choice(const char *q,const char *b0,const char *b1,const char *b2);
+const char *fl_input(const char *label, const char *deflt, unsigned char type);
+const char *fl_input(const char *label, const char *deflt = 0);
+inline const char *fl_password(const char *label, const char *deflt = 0) {
+ return fl_input(label, deflt, 5);
+}
+Fl_Widget *fl_message_icon();
+extern unsigned char fl_message_font_;
+extern unsigned char fl_message_size_;
+inline void fl_message_font(unsigned char f,unsigned char s) {
+ fl_message_font_ = f; fl_message_size_ = s;}
+
+// pointers you can use to change fltk to a foreign language:
+extern const char* fl_no;
+extern const char* fl_yes;
+extern const char* fl_ok;
+extern const char* fl_cancel;
+
+// back compatability and XForms compatability functions:
+
+inline int fl_show_question(const char *c) {return fl_ask(c);}
+void fl_show_message(const char *,const char *,const char *);
+void fl_show_alert(const char *,const char *,const char *);
+int fl_show_question(const char *,const char *,const char *);
+inline const char *fl_show_input(const char *l,const char*d=0) {return fl_input(l,d);}
+/*const*/ char *fl_show_simple_input(const char *label, const char *deflt = 0);
+
+// all are implemented using this:
+int fl_show_choice(
+ const char *m1,
+ const char *m2,
+ const char *m3,
+ int numb,
+ const char *b0,
+ const char *b1,
+ const char *b2);
+
+#endif
diff --git a/FL/fl_draw.H b/FL/fl_draw.H
new file mode 100644
index 000000000..49b7c51c4
--- /dev/null
+++ b/FL/fl_draw.H
@@ -0,0 +1,135 @@
+// fl_draw.H
+// Portable drawing functions
+
+#ifndef fl_draw_H
+#define fl_draw_H
+
+#include "Enumerations.H" // for the color names
+
+// Colors:
+void fl_color(Fl_Color); // select indexed color
+inline void fl_color(int c) {fl_color((Fl_Color)c);} // for back compatability
+void fl_color(uchar, uchar, uchar); // select actual color
+extern Fl_Color fl_color_; inline Fl_Color fl_color() {return fl_color_;}
+
+// clip:
+void fl_clip(int x, int y, int w, int h);
+#define fl_push_clip fl_clip
+void fl_push_no_clip();
+void fl_pop_clip();
+int fl_not_clipped(int x, int y, int w, int h);
+int fl_clip_box(int, int, int, int, int& x, int& y, int& w, int& h);
+
+// points:
+void fl_point(int x, int y);
+
+// rectangles tweaked to exactly fill the pixel rectangle:
+void fl_rect(int x, int y, int w, int h);
+void fl_rectf(int x, int y, int w, int h);
+
+// line segments:
+void fl_line(int,int, int,int);
+void fl_line(int,int, int,int, int,int);
+
+// closed line segments:
+void fl_loop(int,int, int,int, int,int);
+void fl_loop(int,int, int,int, int,int, int,int);
+
+// filled polygons
+void fl_polygon(int,int, int,int, int,int);
+void fl_polygon(int,int, int,int, int,int, int,int);
+
+// draw rectilinear lines, horizontal segment first:
+void fl_xyline(int x, int y, int x1);
+void fl_xyline(int x, int y, int x1, int y2);
+void fl_xyline(int x, int y, int x1, int y2, int x3);
+
+// draw rectilinear lines, vertical segment first:
+void fl_yxline(int x, int y, int y1);
+void fl_yxline(int x, int y, int y1, int x2);
+void fl_yxline(int x, int y, int y1, int x2, int y3);
+
+// circular lines and pie slices (code in fl_arci.C):
+void fl_arc(int x, int y, int w, int h, double a1, double a2);
+void fl_pie(int x, int y, int w, int h, double a1, double a2);
+void fl_chord(int x, int y, int w, int h, double a1, double a2); // nyi
+
+// scalable drawing code (code in fl_vertex.C and fl_arc.C):
+void fl_push_matrix();
+void fl_pop_matrix();
+void fl_scale(double x, double y);
+void fl_scale(double x);
+void fl_translate(double x, double y);
+void fl_rotate(double d);
+void fl_mult_matrix(double a, double b, double c, double d, double x,double y);
+void fl_begin_points();
+void fl_begin_line();
+void fl_begin_loop();
+void fl_begin_polygon();
+void fl_vertex(double x, double y);
+void fl_curve(double, double, double, double, double, double, double, double);
+void fl_arc(double x, double y, double r, double start, double a);
+void fl_circle(double x, double y, double r);
+void fl_end_points();
+void fl_end_line();
+void fl_end_loop();
+void fl_end_polygon();
+void fl_begin_complex_polygon();
+void fl_gap();
+void fl_end_complex_polygon();
+// get and use transformed positions:
+double fl_transform_x(double x, double y);
+double fl_transform_y(double x, double y);
+double fl_transform_dx(double x, double y);
+double fl_transform_dy(double x, double y);
+void fl_transformed_vertex(double x, double y);
+
+// current font:
+void fl_font(int face, int size);
+void fl_font(int face, int size, Fl_Font default_font, int default_size);
+extern int fl_font_; inline int fl_font() {return fl_font_;}
+extern int fl_size_; inline int fl_size() {return fl_size_;}
+
+// information you can get about the current font:
+int fl_height(); // using "size" should work ok
+int fl_descent();
+double fl_width(const char*);
+double fl_width(const char*, int n);
+double fl_width(uchar);
+
+// draw using current font:
+void fl_draw(const char*, int x, int y);
+void fl_draw(const char*, int n, int x, int y);
+void fl_draw(const char*, int x, int y, int w, int h, Fl_Align);
+void fl_measure(const char*, int& x, int& y);
+
+// boxtypes:
+void fl_frame(const char* s, int x, int y, int w, int h);
+void fl_frame2(const char* s, int x, int y, int w, int h);
+void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color);
+
+// images:
+void fl_draw_image(const uchar*, int,int,int,int, int delta=3, int ldelta=0);
+void fl_draw_image_mono(const uchar*, int,int,int,int, int delta=1, int ld=0);
+typedef void (*Fl_Draw_Image_Cb)(void*,int,int,int,uchar*);
+void fl_draw_image(Fl_Draw_Image_Cb, void*, int,int,int,int, int delta=3);
+void fl_draw_image_mono(Fl_Draw_Image_Cb, void*, int,int,int,int, int delta=1);
+void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b);
+
+// pixmaps:
+int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color=FL_GRAY);
+int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h);
+
+// other:
+extern void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
+ void (*draw_area)(void*, int,int,int,int), void* data);
+const char* fl_shortcut_label(int);
+void fl_overlay_rect(int,int,int,int);
+void fl_overlay_clear();
+void fl_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
+
+// XForms symbols:
+int fl_draw_symbol(const char* label,int x,int y,int w,int h, Fl_Color);
+int fl_add_symbol(const char* name, void (*drawit)(Fl_Color), int scalable);
+
+#endif
diff --git a/FL/fl_file_chooser.H b/FL/fl_file_chooser.H
new file mode 100644
index 000000000..82fef8bbc
--- /dev/null
+++ b/FL/fl_file_chooser.H
@@ -0,0 +1,9 @@
+// fl_file_chooser.H
+
+#ifndef fl_file_chooser_H
+#define fl_file_chooser_H
+
+char *fl_file_chooser(const char *message,const char *pat,const char *fname);
+void fl_file_chooser_callback(void (*cb)(const char *));
+
+#endif
diff --git a/FL/fl_message.H b/FL/fl_message.H
new file mode 100644
index 000000000..c03141c07
--- /dev/null
+++ b/FL/fl_message.H
@@ -0,0 +1,2 @@
+// fl_message.H
+#include "fl_ask.H"
diff --git a/FL/fl_show_colormap.H b/FL/fl_show_colormap.H
new file mode 100644
index 000000000..eb6b0f361
--- /dev/null
+++ b/FL/fl_show_colormap.H
@@ -0,0 +1,10 @@
+// fl_show_colormap.H
+
+// Color picker copied from Forms
+
+#ifndef fl_show_colormap_H
+#define fl_show_colormap_H
+
+Fl_Color fl_show_colormap(Fl_Color oldcol);
+
+#endif
diff --git a/FL/fl_show_input.H b/FL/fl_show_input.H
new file mode 100644
index 000000000..9635836ad
--- /dev/null
+++ b/FL/fl_show_input.H
@@ -0,0 +1,2 @@
+// fl_show_input.H
+#include "fl_ask.H"
diff --git a/FL/forms.H b/FL/forms.H
new file mode 100644
index 000000000..87ca5afc0
--- /dev/null
+++ b/FL/forms.H
@@ -0,0 +1,810 @@
+// forms.h
+
+// Include file for emulating the original Mark Overmars
+// Forms library. Based on version 0.86, 3/22/97
+// Warning: emulation is in no way 100%!!
+
+#ifndef __FORMS_H__
+#define __FORMS_H__
+
+#include "Fl.H"
+#include "Fl_Group.H"
+#include "Fl_Window.H"
+#include "fl_draw.H"
+
+typedef Fl_Widget FL_OBJECT;
+typedef Fl_Window FL_FORM;
+
+////////////////////////////////////////////////////////////////
+// Random constants & symbols defined by forms.h file:
+
+#ifndef NULL
+#define NULL 0
+#endif
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define FL_ON 1
+#define FL_OK 1
+#define FL_VALID 1
+#define FL_PREEMPT 1
+#define FL_AUTO 2
+#define FL_WHEN_NEEDED FL_AUTO
+#define FL_OFF 0
+#define FL_NONE 0
+#define FL_CANCEL 0
+#define FL_INVALID 0
+#define FL_IGNORE -1
+#define FL_CLOSE -2
+
+#define FL_LCOL FL_BLACK
+#define FL_COL1 FL_GRAY
+#define FL_MCOL FL_LIGHT1
+#define FL_LEFT_BCOL FL_LIGHT3 // 53 is better match
+#define FL_TOP_BCOL FL_LIGHT2 // 51
+#define FL_BOTTOM_BCOL FL_DARK2 // 40
+#define FL_RIGHT_BCOL FL_DARK3 // 36
+#define FL_INACTIVE FL_INACTIVE_COLOR
+#define FL_INACTIVE_COL FL_INACTIVE_COLOR
+#define FL_FREE_COL1 FL_FREE_COLOR
+#define FL_FREE_COL2 ((Fl_Color)(FL_FREE_COLOR+1))
+#define FL_FREE_COL3 ((Fl_Color)(FL_FREE_COLOR+2))
+#define FL_FREE_COL4 ((Fl_Color)(FL_FREE_COLOR+3))
+#define FL_FREE_COL5 ((Fl_Color)(FL_FREE_COLOR+4))
+#define FL_FREE_COL6 ((Fl_Color)(FL_FREE_COLOR+5))
+#define FL_FREE_COL7 ((Fl_Color)(FL_FREE_COLOR+6))
+#define FL_FREE_COL8 ((Fl_Color)(FL_FREE_COLOR+7))
+#define FL_FREE_COL9 ((Fl_Color)(FL_FREE_COLOR+8))
+#define FL_FREE_COL10 ((Fl_Color)(FL_FREE_COLOR+9))
+#define FL_FREE_COL11 ((Fl_Color)(FL_FREE_COLOR+10))
+#define FL_FREE_COL12 ((Fl_Color)(FL_FREE_COLOR+11))
+#define FL_FREE_COL13 ((Fl_Color)(FL_FREE_COLOR+12))
+#define FL_FREE_COL14 ((Fl_Color)(FL_FREE_COLOR+13))
+#define FL_FREE_COL15 ((Fl_Color)(FL_FREE_COLOR+14))
+#define FL_FREE_COL16 ((Fl_Color)(FL_FREE_COLOR+15))
+#define FL_TOMATO ((Fl_Color)(131))
+#define FL_INDIANRED ((Fl_Color)(164))
+#define FL_SLATEBLUE ((Fl_Color)(195))
+#define FL_DARKGOLD ((Fl_Color)(84))
+#define FL_PALEGREEN ((Fl_Color)(157))
+#define FL_ORCHID ((Fl_Color)(203))
+#define FL_DARKCYAN ((Fl_Color)(189))
+#define FL_DARKTOMATO ((Fl_Color)(113))
+#define FL_WHEAT ((Fl_Color)(174))
+
+#define FL_ALIGN_BESIDE FL_ALIGN_INSIDE
+
+#define FL_PUP_TOGGLE 2 // FL_MENU_TOGGLE
+#define FL_PUP_INACTIVE 1 // FL_MENU_INACTIVE
+#define FL_NO_FRAME FL_NO_BOX
+#define FL_ROUNDED3D_UPBOX FL_ROUND_UP_BOX
+#define FL_ROUNDED3D_DOWNBOX FL_ROUND_DOWN_BOX
+#define FL_OVAL3D_UPBOX FL_ROUND_UP_BOX
+#define FL_OVAL3D_DOWNBOX FL_ROUND_DOWN_BOX
+
+#define FL_MBUTTON1 1
+#define FL_LEFT_MOUSE 1
+#define FL_LEFTMOUSE 1
+#define FL_MBUTTON2 2
+#define FL_MIDDLE_MOUSE 2
+#define FL_MIDDLEMOUSE 2
+#define FL_MBUTTON3 3
+#define FL_RIGHT_MOUSE 3
+#define FL_RIGHTMOUSE 3
+#define FL_MBUTTON4 4
+#define FL_MBUTTON5 5
+
+#define FL_INVALID_STYLE 255
+#define FL_NORMAL_STYLE FL_HELVETICA
+#define FL_BOLD_STYLE FL_HELVETICA_BOLD
+#define FL_ITALIC_STYLE FL_HELVETICA_ITALIC
+#define FL_BOLDITALIC_STYLE FL_HELVETICA_BOLD_ITALIC
+#define FL_FIXED_STYLE FL_COURIER
+#define FL_FIXEDBOLD_STYLE FL_COURIER_BOLD
+#define FL_FIXEDITALIC_STYLE FL_COURIER_ITALIC
+#define FL_FIXEDBOLDITALIC_STYLE FL_COURIER_BOLD_ITALIC
+#define FL_TIMES_STYLE FL_TIMES
+#define FL_TIMESBOLD_STYLE FL_TIMES_BOLD
+#define FL_TIMESITALIC_STYLE FL_TIMES_ITALIC
+#define FL_TIMESBOLDITALIC_STYLE FL_TIMES_BOLD_ITALIC
+
+// hacks to change the labeltype() when passed to fl_set_object_lstyle():
+#define FL_SHADOW_STYLE (FL_SHADOW_LABEL<<8)
+#define FL_ENGRAVED_STYLE (FL_ENGRAVED_LABEL<<8)
+#define FL_EMBOSSED_STYLE (FL_EMBOSSED_LABEL<<0)
+
+// size values are different from XForms, match older Forms:
+#define FL_TINY_SIZE 8
+#define FL_SMALL_SIZE 11 // 10
+#define FL_NORMAL_SIZE 14 // 12
+#define FL_MEDIUM_SIZE 18 // 14
+#define FL_LARGE_SIZE 24 // 18
+#define FL_HUGE_SIZE 32 // 24
+#define FL_DEFAULT_SIZE FL_SMALL_SIZE
+#define FL_TINY_FONT FL_TINY_SIZE
+#define FL_SMALL_FONT FL_SMALL_SIZE
+#define FL_NORMAL_FONT FL_NORMAL_SIZE
+#define FL_MEDIUM_FONT FL_MEDIUM_SIZE
+#define FL_LARGE_FONT FL_LARGE_SIZE
+#define FL_HUGE_FONT FL_HUGE_SIZE
+#define FL_NORMAL_FONT1 FL_SMALL_FONT
+#define FL_NORMAL_FONT2 FL_NORMAL_FONT
+#define FL_DEFAULT_FONT FL_SMALL_FONT
+
+#define FL_RETURN_END_CHANGED FL_WHEN_RELEASE
+#define FL_RETURN_CHANGED FL_WHEN_CHANGED
+#define FL_RETURN_END FL_WHEN_RELEASE_ALWAYS
+#define FL_RETURN_ALWAYS (FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED)
+
+#define FL_BOUND_WIDTH 3
+
+typedef int FL_Coord;
+typedef int FL_COLOR;
+
+////////////////////////////////////////////////////////////////
+// fltk interaction:
+
+#define FL_CMD_OPT void
+extern void fl_initialize(int*, char*[], const char*, FL_CMD_OPT*, int);
+inline void fl_finish() {}
+
+typedef void (*FL_IO_CALLBACK) (int, void*);
+inline void fl_add_io_callback(int fd, short w, FL_IO_CALLBACK cb, void* v) {
+ Fl::add_fd(fd,w,cb,v);}
+inline void fl_remove_io_callback(int fd, short, FL_IO_CALLBACK) {
+ Fl::remove_fd(fd);} // removes all the callbacks!
+
+// type of callback is different and no "id" number is returned:
+inline void fl_add_timeout(long msec, void (*cb)(void*), void* v) {
+ Fl::add_timeout(msec*.001, cb, v);}
+inline void fl_remove_timeout(int) {}
+
+// type of callback is different!
+inline void fl_set_idle_callback(void (*cb)()) {Fl::set_idle(cb);}
+
+Fl_Widget* fl_do_forms(void);
+Fl_Widget* fl_check_forms();
+inline Fl_Widget* fl_do_only_forms(void) {return fl_do_forms();}
+inline Fl_Widget* fl_check_only_forms(void) {return fl_check_forms();}
+
+// because of new redraw behavior, these are no-ops:
+inline void fl_freeze_object(Fl_Widget*) {}
+inline void fl_unfreeze_object(Fl_Widget*) {}
+inline void fl_freeze_form(Fl_Window*) {}
+inline void fl_unfreeze_form(Fl_Window*) {}
+inline void fl_freeze_all_forms() {}
+inline void fl_unfreeze_all_forms() {}
+
+inline void fl_set_focus_object(Fl_Window*, Fl_Widget* o) {Fl::focus(o);}
+inline void fl_reset_focus_object(Fl_Widget* o) {Fl::focus(o);}
+#define fl_set_object_focus fl_set_focus_object
+
+// void fl_set_form_atclose(Fl_Window*w,int (*cb)(Fl_Window*,void*),void* v)
+// void fl_set_atclose(int (*cb)(Fl_Window*,void*),void*)
+// fl_set_form_atactivate/atdeactivate not implemented!
+
+////////////////////////////////////////////////////////////////
+// Fl_Widget:
+
+inline void fl_set_object_boxtype(Fl_Widget* o, Fl_Boxtype a) {o->box(a);}
+inline void fl_set_object_lsize(Fl_Widget* o,int s) {o->labelsize(s);}
+inline void fl_set_object_lstyle(Fl_Widget* o,int a) {
+ o->labelfont((uchar)a); o->labeltype((Fl_Labeltype)(a>>8));}
+inline void fl_set_object_lcol(Fl_Widget* o, uchar a) {o->labelcolor(a);}
+#define fl_set_object_lcolor fl_set_object_lcol
+inline void fl_set_object_lalign(Fl_Widget* o, Fl_Align a) {o->align(a);}
+#define fl_set_object_align fl_set_object_lalign
+inline void fl_set_object_color(Fl_Widget* o,uchar a,uchar b) {o->color(a,b);}
+inline void fl_set_object_label(Fl_Widget* o, const char* a) {o->label(a); o->redraw();}
+inline void fl_set_object_position(Fl_Widget*o,int x,int y) {o->position(x,y);}
+inline void fl_set_object_size(Fl_Widget* o, int w, int h) {o->size(w,h);}
+inline void fl_set_object_geometry(Fl_Widget* o,int x,int y,int w,int h) {o->resize(x,y,w,h);}
+
+inline void fl_get_object_geometry(Fl_Widget* o,int*x,int*y,int*w,int*h) {
+ *x = o->x(); *y = o->y(); *w = o->w(); *h = o->h();}
+inline void fl_get_object_position(Fl_Widget* o,int*x,int*y) {
+ *x = o->x(); *y = o->y();}
+
+typedef void (*Forms_CB)(Fl_Widget*, long);
+inline void fl_set_object_callback(Fl_Widget*o,Forms_CB c,long a) {o->callback(c,a);}
+#define fl_set_call_back fl_set_object_callback
+inline void fl_call_object_callback(Fl_Widget* o) {o->do_callback();}
+inline void fl_trigger_object(Fl_Widget* o) {o->do_callback();}
+inline void fl_set_object_return(Fl_Widget* o, int v) {
+ o->when((Fl_When)(v|FL_WHEN_RELEASE));}
+
+inline void fl_redraw_object(Fl_Widget* o) {o->redraw();}
+inline void fl_show_object(Fl_Widget* o) {o->show();}
+inline void fl_hide_object(Fl_Widget* o) {o->hide();}
+inline void fl_free_object(Fl_Widget* x) {delete x;}
+inline void fl_delete_object(Fl_Widget* o) {((Fl_Group*)(o->parent()))->remove(*o);}
+inline void fl_activate_object(Fl_Widget* o) {o->activate();}
+inline void fl_deactivate_object(Fl_Widget* o) {o->deactivate();}
+
+inline void fl_add_object(Fl_Window* f, Fl_Widget* x) {f->add(x);}
+inline void fl_insert_object(Fl_Widget* o, Fl_Widget* b) {
+ ((Fl_Group*)(b->parent()))->insert(*o,b);}
+
+inline Fl_Window* FL_ObjWin(Fl_Widget* o) {return o->window();}
+
+////////////////////////////////////////////////////////////////
+// things that appered in the demos a lot that I don't emulate, but
+// I did not want to edit out of all the demos...
+
+inline int fl_get_border_width() {return 3;}
+inline void fl_set_border_width(int) {}
+inline void fl_set_object_dblbuffer(Fl_Widget*, int) {}
+inline void fl_set_form_dblbuffer(Fl_Window*, int) {}
+
+////////////////////////////////////////////////////////////////
+// Fl_Window:
+
+inline void fl_free_form(Fl_Window* x) {delete x;}
+inline void fl_redraw_form(Fl_Window* f) {f->redraw();}
+
+inline Fl_Window* fl_bgn_form(Fl_Boxtype b,int w,int h) {
+ Fl_Window* g = new Fl_Window(w,h,0);
+ g->box(b);
+ return g;
+}
+void fl_end_form();
+inline void fl_addto_form(Fl_Window* f) {f->begin();}
+inline Fl_Group* fl_bgn_group() {return new Fl_Group(0,0,0,0,0);}
+inline void fl_end_group() {Fl_Group::current()->forms_end();}
+inline void fl_addto_group(Fl_Widget* o) {((Fl_Group* )o)->begin();}
+#define resizebox _ddfdesign_kludge()
+
+inline void fl_scale_form(Fl_Window* f, double x, double y) {
+ f->resizable(f); f->size(int(f->w()*x),int(f->h()*y));}
+inline void fl_set_form_position(Fl_Window* f,int x,int y) {f->position(x,y);}
+inline void fl_set_form_size(Fl_Window* f, int w, int h) {f->size(w,h);}
+inline void fl_set_form_geometry(Fl_Window* f,int x,int y,int w,int h) {
+ f->resize(x,y,w,h);}
+#define fl_set_initial_placement fl_set_form_geometry
+inline void fl_adjust_form_size(Fl_Window*) {}
+
+void fl_show_form(Fl_Window* f,int p,int b,const char* n);
+enum { // "p" argument values:
+ FL_PLACE_FREE = 0, // make resizable
+ FL_PLACE_MOUSE = 1, // mouse centered on form
+ FL_PLACE_CENTER = 2, // center of the screen
+ FL_PLACE_POSITION = 4,// fixed position, resizable
+ FL_PLACE_SIZE = 8, // fixed size, normal fltk behavior
+ FL_PLACE_GEOMETRY =16,// fixed size and position
+ FL_PLACE_ASPECT = 32, // keep aspect ratio (ignored)
+ FL_PLACE_FULLSCREEN=64,// fill screen
+ FL_PLACE_HOTSPOT = 128,// enables hotspot
+ FL_PLACE_ICONIC = 256,// iconic (ignored)
+ FL_FREE_SIZE=(1<<14), // force resizable
+ FL_FIX_SIZE =(1<<15) // force off resizable
+};
+#define FL_PLACE_FREE_CENTER (FL_PLACE_CENTER|FL_FREE_SIZE)
+#define FL_PLACE_CENTERFREE (FL_PLACE_CENTER|FL_FREE_SIZE)
+enum { // "b" arguement values:
+ FL_NOBORDER = 0,
+ FL_FULLBORDER,
+ FL_TRANSIENT
+//FL_MODAL = (1<<8) // not implemented yet in Forms
+};
+inline void fl_set_form_hotspot(Fl_Window* w,int x,int y) {w->hotspot(x,y);}
+inline void fl_set_form_hotobject(Fl_Window* w, Fl_Widget* o) {w->hotspot(o);}
+extern char fl_flip; // in forms.C
+inline void fl_flip_yorigin() {fl_flip = 1;}
+
+#define fl_prepare_form_window fl_show_form
+inline void fl_show_form_window(Fl_Window*) {}
+
+inline void fl_raise_form(Fl_Window* f) {f->show();}
+
+inline void fl_hide_form(Fl_Window* f) {f->hide();}
+inline void fl_pop_form(Fl_Window* f) {f->show();}
+
+extern char fl_modal_next; // in forms.C
+inline void fl_activate_all_forms() {}
+inline void fl_deactivate_all_forms() {fl_modal_next = 1;}
+inline void fl_deactivate_form(Fl_Window*w) {w->deactivate();}
+inline void fl_activate_form(Fl_Window*w) {w->activate();}
+
+inline void fl_set_form_title(Fl_Window* f, const char* s) {f->label(s);}
+inline void fl_title_form(Fl_Window* f, const char* s) {f->label(s);}
+
+typedef void (*Forms_FormCB)(Fl_Widget*);
+inline void fl_set_form_callback(Fl_Window* f,Forms_FormCB c) {f->callback(c);}
+#define fl_set_form_call_back fl_set_form_callback
+
+inline void fl_init() {}
+void fl_set_graphics_mode(int,int);
+
+inline int fl_form_is_visible(Fl_Window* f) {return f->visible();}
+
+inline int fl_mouse_button() {return Fl::event_button();}
+#define fl_mousebutton fl_mouse_button
+
+#define fl_free free
+#define fl_malloc malloc
+#define fl_calloc calloc
+#define fl_realloc realloc
+
+////////////////////////////////////////////////////////////////
+// Drawing functions. Only usable inside an Fl_Free object?
+
+inline void fl_drw_box(Fl_Boxtype b,int x,int y,int w,int h,Fl_Color bgc,int=3) {
+ fl_draw_box(b,x,y,w,h,bgc);}
+inline void fl_drw_frame(Fl_Boxtype b,int x,int y,int w,int h,Fl_Color bgc,int=3) {
+ fl_draw_box(b,x,y,w,h,bgc);}
+
+inline void fl_drw_text(Fl_Align align, int x, int y, int w, int h,
+ Fl_Color fgcolor, int size, Fl_Font style,
+ const char* s) {
+ fl_font(style,size);
+ fl_color(fgcolor);
+ fl_draw(s,x,y,w,h,align);
+}
+
+// this does not work except for CENTER...
+inline void fl_drw_text_beside(Fl_Align align, int x, int y, int w, int h,
+ Fl_Color fgcolor, int size, Fl_Font style,
+ const char* s) {
+ fl_font(style,size);
+ fl_color(fgcolor);
+ fl_draw(s,x,y,w,h,align);
+}
+
+inline void fl_set_font_name(Fl_Font n,const char* s) {Fl::set_font(n,s);}
+
+inline void fl_mapcolor(Fl_Color c, uchar r, uchar g, uchar b) {Fl::set_color(c,r,g,b);}
+
+#define fl_set_clipping(x,y,w,h) fl_clip(x,y,w,h)
+#define fl_unset_clipping() fl_pop_clip()
+
+////////////////////////////////////////////////////////////////
+// Forms classes:
+
+inline Fl_Widget* fl_add_new(Fl_Widget* p) {return p;}
+inline Fl_Widget* fl_add_new(uchar t,Fl_Widget* p) {p->type(t); return p;}
+
+#define forms_constructor(type,name) \
+inline type* name(uchar t,int x,int y,int w,int h,const char* l) { \
+ return (type*)(fl_add_new(t, new type(x,y,w,h,l)));}
+#define forms_constructort(type,name) \
+inline type* name(uchar t,int x,int y,int w,int h,const char* l) { \
+ return (type*)(fl_add_new(new type(t,x,y,w,h,l)));}
+#define forms_constructorb(type,name) \
+inline type* name(Fl_Boxtype t,int x,int y,int w,int h,const char* l) { \
+ return (type*)(fl_add_new(new type(t,x,y,w,h,l)));}
+
+#include "Fl_FormsBitmap.H"
+#define FL_NORMAL_BITMAP FL_NO_BOX
+forms_constructorb(Fl_FormsBitmap, fl_add_bitmap)
+inline void fl_set_bitmap_data(Fl_Widget* o, int w, int h, const uchar* b) {
+ ((Fl_FormsBitmap*)o)->set(w,h,b);
+}
+
+#include "Fl_FormsPixmap.H"
+#define FL_NORMAL_PIXMAP FL_NO_BOX
+forms_constructorb(Fl_FormsPixmap, fl_add_pixmap)
+inline void fl_set_pixmap_data(Fl_Widget* o, char*const* b) {
+ ((Fl_FormsPixmap*)o)->set(b);
+}
+//inline void fl_set_pixmap_file(Fl_Widget*, const char*);
+inline void fl_set_pixmap_align(Fl_Widget* o,Fl_Align a,int,int) {o->align(a);}
+//inline void fl_set_pixmap_colorcloseness(int, int, int);
+
+#include "Fl_Box.H"
+forms_constructorb(Fl_Box, fl_add_box)
+
+#include "Fl_Browser.H"
+forms_constructor(Fl_Browser, fl_add_browser)
+
+inline void fl_clear_browser(Fl_Widget* o) {
+ ((Fl_Browser*)o)->clear();}
+inline void fl_add_browser_line(Fl_Widget* o, const char* s) {
+ ((Fl_Browser*)o)->add(s);}
+inline void fl_addto_browser(Fl_Widget* o, const char* s) {
+ ((Fl_Browser*)o)->add(s);} /* should also scroll to bottom */
+//inline void fl_addto_browser_chars(Fl_Widget*, const char*)
+//#define fl_append_browser fl_addto_browser_chars
+inline void fl_insert_browser_line(Fl_Widget* o, int n, const char* s) {
+ ((Fl_Browser*)o)->insert(n,s);}
+inline void fl_delete_browser_line(Fl_Widget* o, int n) {
+ ((Fl_Browser*)o)->remove(n);}
+inline void fl_replace_browser_line(Fl_Widget* o, int n, const char* s) {
+ ((Fl_Browser*)o)->replace(n,s);}
+inline char* fl_get_browser_line(Fl_Widget* o, int n) {
+ return (char*)(((Fl_Browser*)o)->text(n));}
+inline int fl_load_browser(Fl_Widget* o, const char* f) {
+ return ((Fl_Browser*)o)->load(f);}
+inline void fl_select_browser_line(Fl_Widget* o, int n) {
+ ((Fl_Browser*)o)->select(n,1);}
+inline void fl_deselect_browser_line(Fl_Widget* o, int n) {
+ ((Fl_Browser*)o)->select(n,0);}
+inline void fl_deselect_browser(Fl_Widget* o) {
+ ((Fl_Browser*)o)->deselect();}
+inline int fl_isselected_browser_line(Fl_Widget* o, int n) {
+ return ((Fl_Browser*)o)->selected(n);}
+inline int fl_get_browser_topline(Fl_Widget* o) {
+ return ((Fl_Browser*)o)->topline();}
+inline int fl_get_browser(Fl_Widget* o) {
+ return ((Fl_Browser*)o)->value();}
+inline int fl_get_browser_maxline(Fl_Widget* o) {
+ return ((Fl_Browser*)o)->size();}
+//linline int fl_get_browser_screenlines(Fl_Widget*);
+inline void fl_set_browser_topline(Fl_Widget* o, int n) {
+ ((Fl_Browser*)o)->topline(n);}
+inline void fl_set_browser_fontsize(Fl_Widget* o, int s) {
+ ((Fl_Browser*)o)->textsize(s);}
+inline void fl_set_browser_fontstyle(Fl_Widget* o, Fl_Font s) {
+ ((Fl_Browser*)o)->textfont(s);}
+inline void fl_set_browser_specialkey(Fl_Widget* o, char c) {
+ ((Fl_Browser*)o)->format_char(c);}
+//inline void fl_set_browser_vscrollbar(Fl_Widget*, int);
+//inline void fl_set_browser_hscrollbar(Fl_Widget*, int);
+//inline void fl_set_browser_leftslider(Fl_Widget*, int);
+//#define fl_set_browser_leftscrollbar fl_set_browser_leftslider
+//inline void fl_set_browser_line_selectable(Fl_Widget*, int, int);
+//inline void fl_get_browser_dimension(Fl_Widget*,int*,int*,int*,int*);
+//inline void fl_set_browser_dblclick_callback(Fl_Widget*,FL_CALLBACKPTR,long);
+//inline void fl_set_browser_xoffset(Fl_Widget*, FL_Coord);
+//inline void fl_set_browser_scrollbarsize(Fl_Widget*, int, int);
+inline void fl_setdisplayed_browser_line(Fl_Widget* o, int n, int i) {
+ ((Fl_Browser*)o)->display(n,i);}
+inline int fl_isdisplayed_browser_line(Fl_Widget* o, int n) {
+ return ((Fl_Browser*)o)->displayed(n);}
+
+#include "Fl_Button.H"
+
+#define FL_NORMAL_BUTTON 0
+#define FL_TOUCH_BUTTON 4
+#define FL_INOUT_BUTTON 5
+#define FL_RETURN_BUTTON 6
+#define FL_HIDDEN_RET_BUTTON 7
+#define FL_PUSH_BUTTON FL_TOGGLE_BUTTON
+#define FL_MENU_BUTTON 9
+
+Fl_Button* fl_add_button(uchar t,int x,int y,int w,int h,const char* l);
+inline int fl_get_button(Fl_Widget* b) {return ((Fl_Button*)b)->value();}
+inline void fl_set_button(Fl_Widget* b, int v) {((Fl_Button*)b)->value(v);}
+inline int fl_get_button_numb(Fl_Widget*) {return Fl::event_button();}
+inline void fl_set_button_shortcut(Fl_Widget* b, const char* s,int=0) {
+ ((Fl_Button*)b)->shortcut(s);}
+//#define fl_set_object_shortcut(b,s) fl_set_button_shortcut(b,s)
+
+#include "Fl_Light_Button.H"
+forms_constructor(Fl_Light_Button, fl_add_lightbutton)
+
+#include "Fl_Round_Button.H"
+forms_constructor(Fl_Round_Button, fl_add_roundbutton)
+forms_constructor(Fl_Round_Button, fl_add_round3dbutton)
+
+#include "Fl_Check_Button.H"
+forms_constructor(Fl_Check_Button, fl_add_checkbutton)
+
+inline Fl_Widget* fl_add_bitmapbutton(int t,int x,int y,int w,int h,const char* l) {Fl_Widget* o = fl_add_button(t,x,y,w,h,l); return o;}
+inline void fl_set_bitmapbutton_data(Fl_Widget* o,int a,int b,uchar* c) {
+ (new Fl_Bitmap(c,a,b))->label(o);} // does not delete old Fl_Bitmap!
+
+inline Fl_Widget* fl_add_pixmapbutton(int t,int x,int y,int w,int h,const char* l) {Fl_Widget* o = fl_add_button(t,x,y,w,h,l); return o;}
+inline void fl_set_pixmapbutton_data(Fl_Widget* o, char*const* c) {
+ (new Fl_Pixmap(c))->label(o);} // does not delete old Fl_Pixmap!
+
+// Fl_Canvas object not yet implemented!
+
+#include "Fl_Chart.H"
+
+forms_constructor(Fl_Chart, fl_add_chart)
+inline void fl_clear_chart(Fl_Widget* o) {
+ ((Fl_Chart*)o)->clear();}
+inline void fl_add_chart_value(Fl_Widget* o,double v,const char* s,uchar c){
+ ((Fl_Chart*)o)->add(v,s,c);}
+inline void fl_insert_chart_value(Fl_Widget* o, int i, double v, const char* s, uchar c) {
+ ((Fl_Chart*)o)->insert(i,v,s,c);}
+inline void fl_replace_chart_value(Fl_Widget* o, int i, double v, const char* s, uchar c) {
+ ((Fl_Chart*)o)->replace(i,v,s,c);}
+inline void fl_set_chart_bounds(Fl_Widget* o, double a, double b) {
+ ((Fl_Chart*)o)->bounds(a,b);}
+inline void fl_set_chart_maxnumb(Fl_Widget* o, int v) {
+ ((Fl_Chart*)o)->maxsize(v);}
+inline void fl_set_chart_autosize(Fl_Widget* o, int v) {
+ ((Fl_Chart*)o)->autosize(v);}
+inline void fl_set_chart_lstyle(Fl_Widget* o, Fl_Font v) {
+ ((Fl_Chart*)o)->textfont(v);}
+inline void fl_set_chart_lsize(Fl_Widget* o, int v) {
+ ((Fl_Chart*)o)->textsize(v);}
+inline void fl_set_chart_lcolor(Fl_Widget* o, uchar v) {
+ ((Fl_Chart*)o)->textcolor(v);}
+#define fl_set_chart_lcol fl_set_chart_lcolor
+
+#include "Fl_Choice.H"
+
+#define FL_NORMAL_CHOICE 0
+#define FL_NORMAL_CHOICE2 0
+#define FL_DROPLIST_CHOICE 0
+
+forms_constructor(Fl_Choice, fl_add_choice)
+inline void fl_clear_choice(Fl_Widget* o) {
+ ((Fl_Choice*)o)->clear();}
+inline void fl_addto_choice(Fl_Widget* o, const char* s) {
+ ((Fl_Choice*)o)->add(s);}
+inline void fl_replace_choice(Fl_Widget* o, int i, const char* s) {
+ ((Fl_Choice*)o)->replace(i-1,s);}
+inline void fl_delete_choice(Fl_Widget* o, int i) {
+ ((Fl_Choice*)o)->remove(i-1);}
+inline void fl_set_choice(Fl_Widget* o, int i) {
+ ((Fl_Choice*)o)->value(i-1);}
+// inline void fl_set_choice_text(Fl_Widget*, const char*);
+inline int fl_get_choice(Fl_Widget* o) {
+ return ((Fl_Choice*)o)->value()+1;}
+// inline const char* fl_get_choice_item_text(Fl_Widget*, int);
+// inline int fl_get_choice_maxitems(Fl_Widget*);
+inline const char* fl_get_choice_text(Fl_Widget* o) {
+ return ((Fl_Choice*)o)->text();}
+inline void fl_set_choice_fontsize(Fl_Widget* o, int x) {
+ ((Fl_Choice*)o)->textsize(x);}
+inline void fl_set_choice_fontstyle(Fl_Widget* o, Fl_Font x) {
+ ((Fl_Choice*)o)->textfont(x);}
+// inline void fl_set_choice_item_mode(Fl_Widget*, int, unsigned);
+// inline void fl_set_choice_item_shortcut(Fl_Widget*, int, const char*);
+
+#include "Fl_Clock.H"
+forms_constructort(Fl_Clock, fl_add_clock)
+inline void fl_get_clock(Fl_Widget* o, int* h, int* m, int* s) {
+ *h = ((Fl_Clock*)o)->hour();
+ *m = ((Fl_Clock*)o)->minute();
+ *s = ((Fl_Clock*)o)->second();
+}
+
+#include "Fl_Counter.H"
+forms_constructor(Fl_Counter, fl_add_counter)
+inline void fl_set_counter_value(Fl_Widget* o, double v) {
+ ((Fl_Counter*)o)->value(v);}
+inline void fl_set_counter_bounds(Fl_Widget* o, double a, double b) {
+ ((Fl_Counter*)o)->bounds(a,b);}
+inline void fl_set_counter_step(Fl_Widget* o, double a, double b) {
+ ((Fl_Counter*)o)->step(a,b);}
+inline void fl_set_counter_precision(Fl_Widget* o, int v) {
+ ((Fl_Counter*)o)->precision(v);}
+inline void fl_set_counter_return(Fl_Widget* o, int v) {
+ ((Fl_Counter*)o)->when((Fl_When)(v|FL_WHEN_RELEASE));}
+inline double fl_get_counter_value(Fl_Widget* o) {
+ return ((Fl_Counter*)o)->value();}
+inline void fl_get_counter_bounds(Fl_Widget* o, float* a, float* b) {
+ *a = float(((Fl_Counter*)o)->minimum());
+ *b = float(((Fl_Counter*)o)->maximum());
+}
+//inline void fl_set_counter_filter(Fl_Widget*,const char* (*)(Fl_Widget*,double,int));
+
+// Cursor stuff cannot be emulated because it uses X stuff
+inline void fl_set_cursor(Fl_Window* w, Fl_Cursor c) {w->cursor(c);}
+#define FL_INVISIBLE_CURSOR FL_CURSOR_NONE
+#define FL_DEFAULT_CURSOR FL_CURSOR_DEFAULT
+
+#include "Fl_Dial.H"
+
+#define FL_DIAL_COL1 FL_GRAY
+#define FL_DIAL_COL2 37
+
+forms_constructor(Fl_Dial, fl_add_dial)
+inline void fl_set_dial_value(Fl_Widget* o, double v) {
+ ((Fl_Dial*)o)->value(v);}
+inline double fl_get_dial_value(Fl_Widget* o) {
+ return ((Fl_Dial*)o)->value();}
+inline void fl_set_dial_bounds(Fl_Widget* o, double a, double b) {
+ ((Fl_Dial*)o)->bounds(a, b);}
+inline void fl_get_dial_bounds(Fl_Widget* o, float* a, float* b) {
+ *a = float(((Fl_Dial*)o)->minimum());
+ *b = float(((Fl_Dial*)o)->maximum());
+}
+inline void fl_set_dial_return(Fl_Widget* o, int i) {
+ ((Fl_Dial*)o)->when((Fl_When)(i|FL_WHEN_RELEASE));}
+inline void fl_set_dial_angles(Fl_Widget* o, int a, int b) {
+ ((Fl_Dial*)o)->angles(a,b);}
+//inline void fl_set_dial_cross(Fl_Widget* o, int);
+inline void fl_set_dial_direction(Fl_Widget* o, uchar d) {
+ ((Fl_Dial*)o)->direction(d);}
+inline void fl_set_dial_step(Fl_Widget* o, double v) {
+ ((Fl_Dial*)o)->step(v);}
+
+// Frames:
+
+inline Fl_Widget* fl_add_frame(Fl_Boxtype i,int x,int y,int w,int h,const char* l) {
+ return fl_add_box(i,x-3,y-3,w+6,h+6,l);}
+
+// labelframe nyi
+inline Fl_Widget* fl_add_labelframe(Fl_Boxtype i,int x,int y,int w,int h,const char* l) {
+ Fl_Widget* o = fl_add_box(i,x-3,y-3,w+6,h+6,l);
+ o->align(FL_ALIGN_TOP_LEFT);
+ return o;
+}
+
+#include "Fl_Free.H"
+inline Fl_Free*
+fl_add_free(int t,double x,double y,double w,double h,const char* l,
+ FL_HANDLEPTR hdl) {
+ return (Fl_Free*)(fl_add_new(
+ new Fl_Free(t,int(x),int(y),int(w),int(h),l,hdl)));
+}
+
+#include "fl_ask.H"
+#include "fl_show_colormap.H"
+
+inline int fl_show_question(const char* c, int) {return fl_ask(c);}
+inline void fl_show_alert(const char* a,const char*b,const char*c,int) {
+ fl_show_alert(a,b,c);}
+inline void fl_set_goodies_font(uchar a, uchar b) {fl_message_font(a,b);}
+#define fl_show_messages fl_message
+inline int fl_show_choices(const char* c,int n,const char* b1,const char* b2,
+ const char* b3, int) {
+ return fl_show_choice(0,c,0,n,b1,b2,b3);
+}
+
+#include "filename.H"
+#include "fl_file_chooser.H"
+inline int do_matching(char* a, const char* b) {return filename_match(a,b);}
+
+// Forms-compatable file chooser (implementation in fselect.C):
+char* fl_show_file_selector(const char* message,const char* dir,
+ const char* pat,const char* fname);
+char* fl_get_directory();
+char* fl_get_pattern();
+char* fl_get_filename();
+
+#include "Fl_Input.H"
+forms_constructor(Fl_Input, fl_add_input)
+inline void fl_set_input(Fl_Widget* o, const char* v) {
+ ((Fl_Input*)o)->value(v);}
+inline void fl_set_input_return(Fl_Widget* o, int x) {
+ ((Fl_Input*)o)->when((Fl_When)(x | FL_WHEN_RELEASE));}
+inline void fl_set_input_color(Fl_Widget* o, uchar a, uchar b) {
+ ((Fl_Input*)o)->textcolor(a);
+ ((Fl_Input*)o)->cursor_color(b);
+}
+// inline void fl_set_input_scroll(Fl_Widget*, int);
+inline void fl_set_input_cursorpos(Fl_Widget* o, int x, int /*y*/) {
+ ((Fl_Input*)o)->position(x);}
+// inline void fl_set_input_selected(Fl_Widget*, int);
+// inline void fl_set_input_selected_range(Fl_Widget*, int, int);
+// inline void fl_set_input_maxchars(Fl_Widget*, int);
+// inline void fl_set_input_format(Fl_Widget*, int, int);
+// inline void fl_set_input_hscrollbar(Fl_Widget*, int);
+// inline void fl_set_input_vscrollbar(Fl_Widget*, int);
+// inline void fl_set_input_xoffset(Fl_Widget*, int);
+// inline void fl_set_input_topline(Fl_Widget*, int);
+// inline void fl_set_input_scrollbarsize(Fl_Widget*, int, int);
+// inline int fl_get_input_topline(Fl_Widget*);
+// inline int fl_get_input_screenlines(Fl_Widget*);
+inline int fl_get_input_cursorpos(Fl_Widget* o, int*x, int*y) {
+ *x = ((Fl_Input*)o)->position(); *y = 0; return *x;}
+// inline int fl_get_input_numberoflines(Fl_Widget*);
+// inline void fl_get_input_format(Fl_Widget*, int*, int*);
+inline const char* fl_get_input(Fl_Widget* o) {return ((Fl_Input*)o)->value();}
+
+#include "Fl_Menu_Button.H"
+
+// types are not implemented, they all act like FL_PUSH_MENU:
+#define FL_TOUCH_MENU 0
+#define FL_PUSH_MENU 1
+#define FL_PULLDOWN_MENU 2
+forms_constructor(Fl_Menu_Button, fl_add_menu)
+
+inline void fl_clear_menu(Fl_Widget* o) {
+ ((Fl_Menu_Button*)o)->clear();}
+inline void fl_set_menu(Fl_Widget* o, const char* s) {
+ ((Fl_Menu_Button*)o)->clear(); ((Fl_Menu_Button*)o)->add(s);}
+inline void fl_addto_menu(Fl_Widget* o, const char* s) {
+ ((Fl_Menu_Button*)o)->add(s);}
+inline void fl_replace_menu_item(Fl_Widget* o, int i, const char* s) {
+ ((Fl_Menu_Button*)o)->replace(i-1,s);}
+inline void fl_delete_menu_item(Fl_Widget* o, int i) {
+ ((Fl_Menu_Button*)o)->remove(i-1);}
+inline void fl_set_menu_item_shortcut(Fl_Widget* o, int i, const char* s) {
+ ((Fl_Menu_Button*)o)->shortcut(i-1,fl_old_shortcut(s));}
+inline void fl_set_menu_item_mode(Fl_Widget* o, int i, long x) {
+ ((Fl_Menu_Button*)o)->mode(i-1,x);}
+inline void fl_show_menu_symbol(Fl_Widget*, int ) {
+/* ((Fl_Menu_Button*)o)->show_menu_symbol(i); */}
+// inline void fl_set_menu_popup(Fl_Widget*, int);
+inline int fl_get_menu(Fl_Widget* o) {
+ return ((Fl_Menu_Button*)o)->value()+1;}
+inline const char* fl_get_menu_item_text(Fl_Widget* o, int i) {
+ return ((Fl_Menu_Button*)o)->text(i);}
+inline int fl_get_menu_maxitems(Fl_Widget* o) {
+ return ((Fl_Menu_Button*)o)->size();}
+inline int fl_get_menu_item_mode(Fl_Widget* o, int i) {
+ return ((Fl_Menu_Button*)o)->mode(i);}
+inline const char* fl_get_menu_text(Fl_Widget* o) {
+ return ((Fl_Menu_Button*)o)->text();}
+
+#include "Fl_Positioner.H"
+#define FL_NORMAL_POSITIONER 0
+forms_constructor(Fl_Positioner, fl_add_positioner)
+inline void fl_set_positioner_xvalue(Fl_Widget* o, double v) {
+ ((Fl_Positioner*)o)->xvalue(v);}
+inline double fl_get_positioner_xvalue(Fl_Widget* o) {
+ return ((Fl_Positioner*)o)->xvalue();}
+inline void fl_set_positioner_xbounds(Fl_Widget* o, double a, double b) {
+ ((Fl_Positioner*)o)->xbounds(a,b);}
+inline void fl_get_positioner_xbounds(Fl_Widget* o, float* a, float* b) {
+ *a = float(((Fl_Positioner*)o)->xminimum());
+ *b = float(((Fl_Positioner*)o)->xmaximum());
+}
+inline void fl_set_positioner_yvalue(Fl_Widget* o, double v) {
+ ((Fl_Positioner*)o)->yvalue(v);}
+inline double fl_get_positioner_yvalue(Fl_Widget* o) {
+ return ((Fl_Positioner*)o)->yvalue();}
+inline void fl_set_positioner_ybounds(Fl_Widget* o, double a, double b) {
+ ((Fl_Positioner*)o)->ybounds(a,b);}
+inline void fl_get_positioner_ybounds(Fl_Widget* o, float* a, float* b) {
+ *a = float(((Fl_Positioner*)o)->yminimum());
+ *b = float(((Fl_Positioner*)o)->ymaximum());
+}
+inline void fl_set_positioner_xstep(Fl_Widget* o, double v) {
+ ((Fl_Positioner*)o)->xstep(v);}
+inline void fl_set_positioner_ystep(Fl_Widget* o, double v) {
+ ((Fl_Positioner*)o)->ystep(v);}
+inline void fl_set_positioner_return(Fl_Widget* o, int v) {
+ ((Fl_Positioner*)o)->when((Fl_When)(v|FL_WHEN_RELEASE));}
+
+#include "Fl_Slider.H"
+
+#define FL_HOR_BROWSER_SLIDER FL_HOR_SLIDER
+#define FL_VERT_BROWSER_SLIDER FL_VERT_SLIDER
+
+forms_constructort(Fl_Slider, fl_add_slider)
+#define FL_SLIDER_COL1 FL_GRAY
+inline void fl_set_slider_value(Fl_Widget* o, double v) {
+ ((Fl_Slider*)o)->value(v);}
+inline double fl_get_slider_value(Fl_Widget* o) {
+ return ((Fl_Slider*)o)->value();}
+inline void fl_set_slider_bounds(Fl_Widget* o, double a, double b) {
+ ((Fl_Slider*)o)->bounds(a, b);}
+inline void fl_get_slider_bounds(Fl_Widget* o, float* a, float* b) {
+ *a = float(((Fl_Slider*)o)->minimum());
+ *b = float(((Fl_Slider*)o)->maximum());
+}
+inline void fl_set_slider_return(Fl_Widget* o, int i) {
+ ((Fl_Slider*)o)->when((Fl_When)(i|FL_WHEN_RELEASE));}
+inline void fl_set_slider_step(Fl_Widget* o, double v) {
+ ((Fl_Slider*)o)->step(v);}
+// inline void fl_set_slider_increment(Fl_Widget* o, double v, double);
+inline void fl_set_slider_size(Fl_Widget* o, double v) {
+ ((Fl_Slider*)o)->slider_size(v);}
+
+#include "Fl_Value_Slider.H"
+forms_constructor(Fl_Value_Slider, fl_add_valslider)
+
+inline void fl_set_slider_precision(Fl_Widget* o, int i) {
+ ((Fl_Value_Slider*)o)->precision(i);}
+// filter function!
+
+// The forms text object was the same as an Fl_Box except it inverted the
+// meaning of FL_ALIGN_INSIDE. Implementation in forms.C
+class Fl_FormsText : public Fl_Widget {
+protected:
+ void draw();
+public:
+ Fl_FormsText(Fl_Boxtype b, int x, int y, int w, int h, const char* l=0)
+ : Fl_Widget(x,y,w,h,l) {box(b); align(FL_ALIGN_LEFT);}
+};
+#define FL_NORMAL_TEXT FL_NO_BOX
+forms_constructorb(Fl_FormsText, fl_add_text)
+
+#include "Fl_Timer.H"
+forms_constructort(Fl_Timer, fl_add_timer)
+inline void fl_set_timer(Fl_Widget* o, double v) {((Fl_Timer*)o)->value(v);}
+inline double fl_get_timer(Fl_Widget* o) {return ((Fl_Timer*)o)->value();}
+inline void fl_suspend_timer(Fl_Widget* o) {((Fl_Timer*)o)->suspended(1);}
+inline void fl_resume_timer(Fl_Widget* o) {((Fl_Timer*)o)->suspended(0);}
+inline void fl_set_timer_countup(Fl_Widget* o,char d) {((Fl_Timer*)o)->direction(d);}
+void fl_gettime(long* sec, long* usec);
+
+// Fl_XYPlot nyi
+
+
+// stuff from DDForms:
+
+inline int fl_double_click() {return Fl::event_clicks();}
+inline void fl_draw() {Fl::flush();}
+
+#endif /* define __FORMS_H__ */
diff --git a/FL/gl.h b/FL/gl.h
new file mode 100644
index 000000000..5db50e046
--- /dev/null
+++ b/FL/gl.h
@@ -0,0 +1,42 @@
+// gl.H
+// Fltk gl drawing functions.
+// You must include this instead of GL/gl.h to get around a stupid
+// fuck up by our good friends at Microsloth.
+// This file also provides "missing" OpenGL functions, and
+// gl_start() and gl_finish() to allow OpenGL to be used in any window
+
+#ifndef gl_draw_H
+#define gl_draw_H
+
+#include "Enumerations.H" // for color names
+#ifdef WIN32
+# include <windows.h>
+#endif
+#include <GL/gl.h>
+
+void gl_start();
+void gl_finish();
+
+void gl_color(Fl_Color);
+inline void gl_color(int c) {gl_color((Fl_Color)c);} // back compatability
+
+void gl_rect(int x,int y,int w,int h);
+inline void gl_rectf(int x,int y,int w,int h) {glRecti(x,y,x+w,y+h);}
+
+void gl_font(int fontid, int size);
+int gl_height();
+int gl_descent();
+double gl_width(const char *);
+double gl_width(const char *, int n);
+double gl_width(uchar);
+
+void gl_draw(const char*);
+void gl_draw(const char*, int n);
+void gl_draw(const char*, int x, int y);
+void gl_draw(const char*, int n, int x, int y);
+void gl_draw(const char*, int x, int y, int w, int h, Fl_Align);
+void gl_measure(const char*, int& x, int& y);
+
+void gl_draw_image(const uchar *, int x,int y,int w,int h, int d=3, int ld=0);
+
+#endif
diff --git a/FL/gl2opengl.h b/FL/gl2opengl.h
new file mode 100644
index 000000000..b89614e0f
--- /dev/null
+++ b/FL/gl2opengl.h
@@ -0,0 +1,35 @@
+/* gl.h
+
+ GL to OpenGL translator.
+ If you include this, you might be able to port old GL programs.
+ There are also much better emulators available on the net.
+
+*/
+
+#include <FL/gl.h>
+#include "gl_draw.H"
+
+inline void clear() {glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);}
+#define RGBcolor(r,g,b) glColor3ub(r,g,b)
+#define bgnline() glBegin(GL_LINE_STRIP)
+#define bgnpolygon() glBegin(GL_POLYGON)
+#define bgnclosedline() glBegin(GL_LINE_LOOP)
+#define endline() glEnd()
+#define endpolygon() glEnd()
+#define endclosedline() glEnd()
+#define v2f(v) glVertex2fv(v)
+#define v2s(v) glVertex2sv(v)
+#define cmov(x,y,z) glRasterPos3f(x,y,z)
+#define charstr(s) gl_draw(s)
+#define fmprstr(s) gl_draw(s)
+typedef float Matrix[4][4];
+inline void pushmatrix() {glPushMatrix();}
+inline void popmatrix() {glPopMatrix();}
+inline void multmatrix(Matrix m) {glMultMatrixf((float *)m);}
+inline void color(int n) {glIndexi(n);}
+inline void rect(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);}
+inline void rectf(int x,int y,int r,int t) {glRectf(x,y,r+1,t+1);}
+inline void recti(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);}
+inline void rectfi(int x,int y,int r,int t) {glRecti(x,y,r+1,t+1);}
+inline void rects(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);}
+inline void rectfs(int x,int y,int r,int t) {glRects(x,y,r+1,t+1);}
diff --git a/FL/gl_draw.H b/FL/gl_draw.H
new file mode 100644
index 000000000..b65c50f1f
--- /dev/null
+++ b/FL/gl_draw.H
@@ -0,0 +1,2 @@
+// gl_draw.H
+#include "gl.h"
diff --git a/FL/glut.H b/FL/glut.H
new file mode 100644
index 000000000..0d72acb9f
--- /dev/null
+++ b/FL/glut.H
@@ -0,0 +1,443 @@
+// glut.h
+
+// Emulation of Glut using fltk.
+
+// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996:
+// "This program is freely distributable without licensing fees and is
+// provided without guarantee or warrantee expressed or implied. This
+// program is -not- in the public domain."
+
+// Although I have copied the GLUT API, none of my code is based on
+// any Glut implementation details and is therefore covered by the LGPL.
+
+// Fltk does not include the Glut drawing functions (such as
+// glutWireTeapot()) or the stroke fonts but the declarations for the
+// drawing functions are included here because otherwise there is no
+// way to get them along with this. To use them you will have to
+// link in the original Glut library, put -lglut *after* -lfltk.
+
+// Commented out lines indicate parts of Glut that are not emulated.
+
+#ifndef __glut_h__
+#define __glut_h__
+
+#include <FL/gl.h>
+#include <GL/glu.h>
+
+////////////////////////////////////////////////////////////////
+// Glut is emulated using this window class and these static variables
+// (plus several more static variables hidden in glut.C):
+
+#include "Fl.H"
+#include "Fl_Gl_Window.H"
+
+class Fl_Glut_Window : public Fl_Gl_Window {
+ void draw();
+ void draw_overlay();
+ int handle(int);
+ void _init();
+ int mouse_down;
+public: // so the inline functions work
+ int number;
+ int menu[3];
+ void make_current();
+ void (*display)();
+ void (*overlaydisplay)();
+ void (*reshape)(int w, int h);
+ void (*keyboard)(uchar, int x, int y);
+ void (*mouse)(int b, int state, int x, int y);
+ void (*motion)(int x, int y);
+ void (*passivemotion)(int x, int y);
+ void (*entry)(int);
+ void (*visibility)(int);
+ void (*special)(int, int x, int y);
+ Fl_Glut_Window(int w, int h, const char *);
+ Fl_Glut_Window(int x, int y, int w, int h, const char *);
+ ~Fl_Glut_Window();
+};
+
+extern Fl_Glut_Window *glut_window; // the current window
+extern int glut_menu; // the current menu
+
+// function pointers that are not per-window:
+extern void (*glut_idle_function)();
+extern void (*glut_menustate_function)(int);
+extern void (*glut_menustatus_function)(int,int,int);
+
+////////////////////////////////////////////////////////////////
+
+//#define GLUT_API_VERSION This does not match any version of Glut exactly...
+
+void glutInit(int *argcp, char **argv); // creates first window
+
+void glutInitDisplayMode(unsigned int mode);
+// the FL_ symbols have the same value as the GLUT ones:
+#define GLUT_RGB FL_RGB
+#define GLUT_RGBA FL_RGB
+#define GLUT_INDEX FL_INDEX
+#define GLUT_SINGLE FL_SINGLE
+#define GLUT_DOUBLE FL_DOUBLE
+#define GLUT_ACCUM FL_ACCUM
+#define GLUT_ALPHA FL_ALPHA
+#define GLUT_DEPTH FL_DEPTH
+#define GLUT_STENCIL FL_STENCIL
+#define GLUT_MULTISAMPLE FL_MULTISAMPLE
+// #define GLUT_STEREO 256
+// #define GLUT_LUMINANCE 512
+
+void glutInitWindowPosition(int x, int y);
+
+void glutInitWindowSize(int w, int h);
+
+void glutMainLoop();
+
+int glutCreateWindow(char *title);
+
+int glutCreateSubWindow(int win, int x, int y, int width, int height);
+
+void glutDestroyWindow(int win);
+
+inline void glutPostRedisplay() {glut_window->redraw();}
+
+void glutSwapBuffers();
+
+inline int glutGetWindow() {return glut_window->number;}
+
+void glutSetWindow(int win);
+
+inline void glutSetWindowTitle(char *t) {glut_window->label(t);}
+
+inline void glutSetIconTitle(char *t) {glut_window->iconlabel(t);}
+
+inline void glutPositionWindow(int x, int y) {glut_window->position(x,y);}
+
+inline void glutReshapeWindow(int w, int h) {glut_window->size(w,h);}
+
+inline void glutPopWindow() {glut_window->show();}
+
+//inline void glutPushWindow();
+
+inline void glutIconifyWindow() {glut_window->iconize();}
+
+inline void glutShowWindow() {glut_window->show();}
+
+inline void glutHideWindow() {glut_window->hide();}
+
+inline void glutFullScreen() {glut_window->fullscreen();}
+
+inline void glutSetCursor(Fl_Cursor cursor) {glut_window->cursor(cursor);}
+// notice that the numeric values are different than glut:
+#define GLUT_CURSOR_RIGHT_ARROW ((Fl_Cursor)2)
+#define GLUT_CURSOR_LEFT_ARROW ((Fl_Cursor)67)
+#define GLUT_CURSOR_INFO FL_CURSOR_HAND
+#define GLUT_CURSOR_DESTROY ((Fl_Cursor)45)
+#define GLUT_CURSOR_HELP FL_CURSOR_HELP
+#define GLUT_CURSOR_CYCLE ((Fl_Cursor)26)
+#define GLUT_CURSOR_SPRAY ((Fl_Cursor)63)
+#define GLUT_CURSOR_WAIT FL_CURSOR_WAIT
+#define GLUT_CURSOR_TEXT FL_CURSOR_INSERT
+#define GLUT_CURSOR_CROSSHAIR FL_CURSOR_CROSS
+#define GLUT_CURSOR_UP_DOWN FL_CURSOR_NS
+#define GLUT_CURSOR_LEFT_RIGHT FL_CURSOR_WE
+#define GLUT_CURSOR_TOP_SIDE FL_CURSOR_N
+#define GLUT_CURSOR_BOTTOM_SIDE FL_CURSOR_S
+#define GLUT_CURSOR_LEFT_SIDE FL_CURSOR_W
+#define GLUT_CURSOR_RIGHT_SIDE FL_CURSOR_E
+#define GLUT_CURSOR_TOP_LEFT_CORNER FL_CURSOR_NW
+#define GLUT_CURSOR_TOP_RIGHT_CORNER FL_CURSOR_NE
+#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER FL_CURSOR_SE
+#define GLUT_CURSOR_BOTTOM_LEFT_CORNER FL_CURSOR_SW
+#define GLUT_CURSOR_INHERIT FL_CURSOR_DEFAULT
+#define GLUT_CURSOR_NONE FL_CURSOR_NONE
+#define GLUT_CURSOR_FULL_CROSSHAIR FL_CURSOR_CROSS
+
+//inline void glutWarpPointer(int x, int y);
+
+inline void glutEstablishOverlay() {glut_window->make_overlay_current();}
+
+inline void glutRemoveOverlay() {glut_window->hide_overlay();}
+
+inline void glutUseLayer(GLenum layer) {
+ layer ? glut_window->make_overlay_current() : glut_window->make_current();}
+enum {GLUT_NORMAL, GLUT_OVERLAY};
+
+inline void glutPostOverlayRedisplay() {glut_window->redraw_overlay();}
+
+inline void glutShowOverlay() {glut_window->redraw_overlay();}
+
+inline void glutHideOverlay() {glut_window->hide_overlay();}
+
+int glutCreateMenu(void (*)(int));
+
+void glutDestroyMenu(int menu);
+
+inline int glutGetMenu() {return glut_menu;}
+
+inline void glutSetMenu(int m) {glut_menu = m;}
+
+void glutAddMenuEntry(char *label, int value);
+
+void glutAddSubMenu(char *label, int submenu);
+
+void glutChangeToMenuEntry(int item, char *label, int value);
+
+void glutChangeToSubMenu(int item, char *label, int submenu);
+
+void glutRemoveMenuItem(int item);
+
+inline void glutAttachMenu(int b) {glut_window->menu[b] = glut_menu;}
+
+inline void glutDetachMenu(int b) {glut_window->menu[b] = 0;}
+
+inline void glutDisplayFunc(void (*f)()) {glut_window->display = f;}
+
+inline void glutReshapeFunc(void (*f)(int w, int h)) {glut_window->reshape=f;}
+
+inline void glutKeyboardFunc(void (*f)(uchar key, int x, int y)) {
+ glut_window->keyboard = f;}
+
+inline void glutMouseFunc(void (*f)(int b, int state, int x, int y)) {
+ glut_window->mouse = f;}
+#define GLUT_LEFT_BUTTON 0
+#define GLUT_MIDDLE_BUTTON 1
+#define GLUT_RIGHT_BUTTON 2
+#define GLUT_DOWN 0
+#define GLUT_UP 1
+
+inline void glutMotionFunc(void (*f)(int x, int y)) {glut_window->motion= f;}
+
+inline void glutPassiveMotionFunc(void (*f)(int x, int y)) {
+ glut_window->passivemotion= f;}
+
+inline void glutEntryFunc(void (*f)(int s)) {glut_window->entry = f;}
+enum {GLUT_LEFT, GLUT_ENTERED};
+
+inline void glutVisibilityFunc(void (*f)(int s)) {glut_window->visibility=f;}
+enum {GLUT_NOT_VISIBLE, GLUT_VISIBLE};
+
+inline void glutIdleFunc(void (*f)()) {Fl::set_idle(f);}
+
+// Warning: this cast may not work on all machines:
+inline void glutTimerFunc(unsigned int msec, void (*f)(int), int value) {
+ Fl::add_timeout(msec*.001, (void (*)(void *))f, (void *)value);
+}
+
+inline void glutMenuStateFunc(void (*f)(int state)) {
+ glut_menustate_function = f;}
+
+inline void glutMenuStatusFunc(void (*f)(int status, int x, int y)) {
+ glut_menustatus_function = f;}
+enum {GLUT_MENU_NOT_IN_USE, GLUT_MENU_IN_USE};
+
+inline void glutSpecialFunc(void (*f)(int key, int x, int y)) {
+ glut_window->special = f;}
+#define GLUT_KEY_F1 1
+#define GLUT_KEY_F2 2
+#define GLUT_KEY_F3 3
+#define GLUT_KEY_F4 4
+#define GLUT_KEY_F5 5
+#define GLUT_KEY_F6 6
+#define GLUT_KEY_F7 7
+#define GLUT_KEY_F8 8
+#define GLUT_KEY_F9 9
+#define GLUT_KEY_F10 10
+#define GLUT_KEY_F11 11
+#define GLUT_KEY_F12 12
+// WARNING: Different values than Glut uses:
+#define GLUT_KEY_LEFT FL_Left
+#define GLUT_KEY_UP FL_Up
+#define GLUT_KEY_RIGHT FL_Right
+#define GLUT_KEY_DOWN FL_Down
+#define GLUT_KEY_PAGE_UP FL_Page_Up
+#define GLUT_KEY_PAGE_DOWN FL_Page_Down
+#define GLUT_KEY_HOME FL_Home
+#define GLUT_KEY_END FL_End
+#define GLUT_KEY_INSERT FL_Insert
+
+//inline void glutSpaceballMotionFunc(void (*)(int x, int y, int z));
+
+//inline void glutSpaceballRotateFunc(void (*)(int x, int y, int z));
+
+//inline void glutSpaceballButtonFunc(void (*)(int button, int state));
+
+//inline void glutButtonBoxFunc(void (*)(int button, int state));
+
+//inline void glutDialsFunc(void (*)(int dial, int value));
+
+//inline void glutTabletMotionFunc(void (*)(int x, int y));
+
+//inline void glutTabletButtonFunc(void (*)(int button, int state, int x, int y));
+
+inline void glutOverlayDisplayFunc(void (*f)()) {
+ glut_window->overlaydisplay = f;}
+
+//inline void glutWindowStatusFunc(void (*)(int state));
+//enum {GLUT_HIDDEN, GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED,
+// GLUT_FULLY_COVERED};
+
+//inline void glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+
+//inline GLfloat glutGetColor(int ndx, int component);
+//#define GLUT_RED 0
+//#define GLUT_GREEN 1
+//#define GLUT_BLUE 2
+
+//inline void glutCopyColormap(int win);
+
+// Warning: values are changed from Glut!
+// Also relies on the GL_ symbols having values greater than 100
+int glutGet(GLenum type);
+enum {
+ GLUT_RETURN_ZERO = 0,
+ GLUT_WINDOW_X,
+ GLUT_WINDOW_Y,
+ GLUT_WINDOW_WIDTH,
+ GLUT_WINDOW_HEIGHT,
+ GLUT_WINDOW_PARENT,
+//GLUT_WINDOW_NUM_CHILDREN,
+//GLUT_WINDOW_CURSOR,
+ GLUT_SCREEN_WIDTH,
+ GLUT_SCREEN_HEIGHT,
+//GLUT_SCREEN_WIDTH_MM,
+//GLUT_SCREEN_HEIGHT_MM,
+ GLUT_MENU_NUM_ITEMS,
+ GLUT_DISPLAY_MODE_POSSIBLE,
+ GLUT_INIT_WINDOW_X,
+ GLUT_INIT_WINDOW_Y,
+ GLUT_INIT_WINDOW_WIDTH,
+ GLUT_INIT_WINDOW_HEIGHT,
+ GLUT_INIT_DISPLAY_MODE,
+//GLUT_ELAPSED_TIME,
+ GLUT_WINDOW_BUFFER_SIZE
+};
+
+#define GLUT_WINDOW_STENCIL_SIZE GL_STENCIL_BITS
+#define GLUT_WINDOW_DEPTH_SIZE GL_DEPTH_BITS
+#define GLUT_WINDOW_RED_SIZE GL_RED_BITS
+#define GLUT_WINDOW_GREEN_SIZE GL_GREEN_BITS
+#define GLUT_WINDOW_BLUE_SIZE GL_BLUE_BITS
+#define GLUT_WINDOW_ALPHA_SIZE GL_ALPHA_BITS
+#define GLUT_WINDOW_ACCUM_RED_SIZE GL_ACCUM_RED_BITS
+#define GLUT_WINDOW_ACCUM_GREEN_SIZE GL_ACCUM_GREEN_BITS
+#define GLUT_WINDOW_ACCUM_BLUE_SIZE GL_ACCUM_BLUE_BITS
+#define GLUT_WINDOW_ACCUM_ALPHA_SIZE GL_ACCUM_ALPHA_BITS
+#define GLUT_WINDOW_DOUBLEBUFFER GL_DOUBLEBUFFER
+#define GLUT_WINDOW_RGBA GL_RGBA
+#define GLUT_WINDOW_COLORMAP_SIZE GL_INDEX_BITS
+#ifdef GL_SAMPLES_SGIS
+#define GLUT_WINDOW_NUM_SAMPLES GL_SAMPLES_SGIS
+#else
+#define GLUT_WINDOW_NUM_SAMPLES GLUT_RETURN_ZERO
+#endif
+#define GLUT_WINDOW_STEREO GL_STEREO
+
+//int glutDeviceGet(GLenum type);
+//#define GLUT_HAS_KEYBOARD 600
+//#define GLUT_HAS_MOUSE 601
+//#define GLUT_HAS_SPACEBALL 602
+//#define GLUT_HAS_DIAL_AND_BUTTON_BOX 603
+//#define GLUT_HAS_TABLET 604
+//#define GLUT_NUM_MOUSE_BUTTONS 605
+//#define GLUT_NUM_SPACEBALL_BUTTONS 606
+//#define GLUT_NUM_BUTTON_BOX_BUTTONS 607
+//#define GLUT_NUM_DIALS 608
+//#define GLUT_NUM_TABLET_BUTTONS 609
+
+inline int glutGetModifiers() {return Fl::event_state();}
+// WARNING: these values are different than Glut uses:
+#define GLUT_ACTIVE_SHIFT FL_SHIFT
+#define GLUT_ACTIVE_CTRL FL_CTRL
+#define GLUT_ACTIVE_ALT FL_ALT
+
+int glutLayerGet(GLenum);
+#define GLUT_OVERLAY_POSSIBLE 800
+//#define GLUT_LAYER_IN_USE 801
+//#define GLUT_HAS_OVERLAY 802
+#define GLUT_TRANSPARENT_INDEX 803
+#define GLUT_NORMAL_DAMAGED 804
+#define GLUT_OVERLAY_DAMAGED 805
+
+//inline int glutVideoResizeGet(GLenum param);
+//#define GLUT_VIDEO_RESIZE_POSSIBLE 900
+//#define GLUT_VIDEO_RESIZE_IN_USE 901
+//#define GLUT_VIDEO_RESIZE_X_DELTA 902
+//#define GLUT_VIDEO_RESIZE_Y_DELTA 903
+//#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904
+//#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905
+//#define GLUT_VIDEO_RESIZE_X 906
+//#define GLUT_VIDEO_RESIZE_Y 907
+//#define GLUT_VIDEO_RESIZE_WIDTH 908
+//#define GLUT_VIDEO_RESIZE_HEIGHT 909
+
+//inline void glutSetupVideoResizing();
+
+//inline void glutStopVideoResizing();
+
+//inline void glutVideoResize(int x, int y, int width, int height);
+
+//inline void glutVideoPan(int x, int y, int width, int height);
+
+////////////////////////////////////////////////////////////////
+// Emulated Glut drawing functions:
+
+// Font argument must be a void* for compatability, so...
+extern struct Glut_Bitmap_Font {uchar font; int size;}
+ glutBitmap9By15, glutBitmap8By13, glutBitmapTimesRoman10,
+ glutBitmapTimesRoman24, glutBitmapHelvetica10, glutBitmapHelvetica12,
+ glutBitmapHelvetica18;
+#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15)
+#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13)
+#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10)
+#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24)
+#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10)
+#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12)
+#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18)
+
+void glutBitmapCharacter(void *font, int character);
+int glutBitmapWidth(void *font, int character);
+
+////////////////////////////////////////////////////////////////
+// Glut drawing functions. These are NOT emulated but you can
+// link in the glut library to get them. This assummes the object
+// files in Glut remain as they currently are so that there are
+// not symbol conflicts with the above.
+
+extern "C" {
+
+extern int glutExtensionSupported(char *name);
+
+/* Stroke font opaque addresses (use constants instead in source code). */
+extern void *glutStrokeRoman;
+extern void *glutStrokeMonoRoman;
+
+/* Stroke font constants (use these in GLUT program). */
+#define GLUT_STROKE_ROMAN (&glutStrokeRoman)
+#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman)
+
+/* GLUT font sub-API */
+extern void glutStrokeCharacter(void *font, int character);
+extern int glutStrokeWidth(void *font, int character);
+
+/* GLUT pre-built models sub-API */
+extern void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+extern void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+extern void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+extern void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+extern void glutWireCube(GLdouble size);
+extern void glutSolidCube(GLdouble size);
+extern void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+extern void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+extern void glutWireDodecahedron();
+extern void glutSolidDodecahedron();
+extern void glutWireTeapot(GLdouble size);
+extern void glutSolidTeapot(GLdouble size);
+extern void glutWireOctahedron();
+extern void glutSolidOctahedron();
+extern void glutWireTetrahedron();
+extern void glutSolidTetrahedron();
+extern void glutWireIcosahedron();
+extern void glutSolidIcosahedron();
+
+}
+
+#endif /* __glut_h__ */
diff --git a/FL/math.h b/FL/math.h
new file mode 100644
index 000000000..57dc3f9c8
--- /dev/null
+++ b/FL/math.h
@@ -0,0 +1,27 @@
+#include <math.h>
+
+#ifdef WIN32
+// things missing from <math.h>:
+
+#define M_PI 3.14159265358979323846
+#define M_PI_2 1.57079632679489661923
+#define M_PI_4 0.78539816339744830962
+#define M_1_PI 0.31830988618379067154
+#define M_2_PI 0.63661977236758134308
+#define M_SQRT2 1.41421356237309504880
+#define M_SQRT1_2 0.70710678118654752440
+
+#else
+
+#ifdef __EMX__
+#include <float.h>
+#endif
+
+#endif
+
+#if defined(WIN32) || defined(CRAY)
+
+inline double rint(double v) {return floor(v+.5);}
+inline double copysign(double a, double b) {return b<0 ? -a : a;}
+
+#endif
diff --git a/FL/menubar.h b/FL/menubar.h
new file mode 100644
index 000000000..1dc7cc8bd
--- /dev/null
+++ b/FL/menubar.h
@@ -0,0 +1,64 @@
+// This is an additional header file for "DDForms", which was our internal
+// enhancement of Forms. This defines the precursor of the Fl_Menu class.
+//
+// Unfortunately it defined the callbacks as taking a long rather
+// than a void* argument, requiring some dubious casts to emulate it:
+
+#include "Fl_Menu_Bar.H"
+
+struct MenuEntry {
+ const char *text; /*initial character indicates "type", 0 = end of menu*/
+ ulong bind; /* key binding in forms format (#x, etc) */
+ void (*cb)(Fl_Widget *,long); /* callback */
+ long data; /* value for callback */
+ int flags; /* see below for flags */
+ uchar labeltype;
+ uchar labelfont;
+ uchar labelsize;
+ uchar labelcolor;
+};
+
+#define CHECKED FL_MENU_CHECK
+#define UNCHECKED FL_MENU_BOX
+#define DISABLED FL_MENU_INACTIVE
+
+/* Turn a box into a menu bar: */
+inline void MenuBar(Fl_Widget *o,MenuEntry *m) {
+ Fl_Menu_Bar *mb = new Fl_Menu_Bar(o->x(),o->y(),o->w(),o->h());
+ mb->menu((Fl_Menu_Item*)m);
+ mb->box(0);
+ Fl_Group *g = (Fl_Group *)(o->parent());
+ int i = g->find(*o);
+ g->insert(*mb, i<g->children()-1 ? g->child(i+1) : 0);
+}
+
+/* advance to the Nth item in menu, skipping submenus: */
+inline MenuEntry *MenuGetEntry(MenuEntry *m,int i) {
+ return (MenuEntry*)(((Fl_Menu_Item*)m)->next(i));
+}
+
+/* Init the shortcuts for a widget with a popup menu: */
+inline void MenuSetShortcuts(Fl_Widget *, MenuEntry *) {}
+
+inline void MenuAdd(
+ MenuEntry m[],
+ int, /* number of entries in menutable, ignored here */
+ const char *text,
+ const char *bind,
+ void (*cb)(Fl_Widget *,long),
+ long data,
+ int flags) {
+ ((Fl_Menu_Item*)m)->add(text,bind,(Fl_Callback*)cb,(void *)data,flags);
+}
+
+inline MenuEntry *MenuPopup(Fl_Widget *o,const char *title,MenuEntry *m,double x,double y) {
+ const Fl_Menu_Item* v = ((Fl_Menu_Item*)m)->popup(x,y,title);
+ if (v && v->callback_) v->do_callback(o);
+ return (MenuEntry *)v;
+}
+
+inline MenuEntry *MenuHandleShortcut(Fl_Widget *o,MenuEntry *m,char) {
+ const Fl_Menu_Item* v = ((Fl_Menu_Item*)m)->test_shortcut();
+ if (v && v->callback_) v->do_callback(o);
+ return (MenuEntry *)v;
+}
diff --git a/FL/win32.H b/FL/win32.H
new file mode 100644
index 000000000..1572c9e73
--- /dev/null
+++ b/FL/win32.H
@@ -0,0 +1,80 @@
+// win32.H
+
+// Do not directly include this file, instead use <FL/x.H>. It will
+// include this file if WIN32 is defined. This is to encourage
+// portability of even the system-specific code...
+
+#include <windows.h>
+#ifndef LPMINMAXINFO
+// the gcc header files are missing some stuff:
+#define LPMINMAXINFO MINMAXINFO*
+#define VK_LWIN 0x5B
+#define VK_RWIN 0x5C
+#define VK_APPS 0x5D
+#endif
+
+// some random X equivalents
+#define Window HWND
+#define XPoint POINT
+struct XRectangle {int x, y, width, height;};
+struct Region {int x, y, r, b; void operator=(int x) {r = x;}};
+inline void XClipBox(Region& i, XRectangle* o) {
+ o->x = i.x; o->y = i.y; o->width = i.r-i.x; o->height = i.b-i.y;}
+#define fl_clip_region(R) fl_clip((R).x,(R).y,(R).r-(R).x,(R).b-(R).y)
+#define XDestroyWindow(a,b) DestroyWindow(b)
+#define XMapWindow(a,b) ShowWindow(b, SW_RESTORE)
+#define XUnmapWindow(a,b) ShowWindow(b, SW_HIDE)
+
+#include "Fl_Window.H"
+// this object contains all win32-specific stuff about a window:
+// Warning: this object is highly subject to change!
+class Fl_X {
+public:
+ Window xid;
+ HBITMAP other_xid; // for double-buffered windows
+ Fl_Window* w;
+ Region region;
+ Fl_X *next;
+ HDC private_dc; // used for OpenGL
+ HCURSOR cursor;
+ static Fl_X* first;
+ static Fl_X* i(const Fl_Window* w) {return w->i;}
+ void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
+ void flush() {w->flush();}
+ void set_minmax(LPMINMAXINFO minmax);
+ void mapraise();
+ static Fl_X* make(Fl_Window*);
+};
+extern HCURSOR fl_default_cursor;
+inline Window fl_xid(const Fl_Window*w) {return Fl_X::i(w)->xid;}
+Fl_Window* fl_find(Window xid);
+extern char fl_override_redirect; // hack into Fl_Window::make_xid()
+extern int fl_background_pixel; // hack into Fl_Window::make_xid()
+
+// most recent fl_color() or fl_rgbcolor() points at one of these:
+extern struct Fl_XMap {
+ COLORREF rgb; // this should be the type the RGB() macro returns
+ HPEN pen; // pen, 0 if none created yet
+ int brush; // ref to solid brush, 0 if none created yet
+} *fl_current_xmap;
+inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
+inline HPEN fl_pen() {return fl_current_xmap->pen;}
+HBRUSH fl_brush(); // allocates a brush if necessary
+
+extern HINSTANCE fl_display;
+extern Window fl_window;
+extern HDC fl_gc;
+extern HPALETTE fl_palette; // non-zero only on 8-bit displays!
+extern HDC fl_DC(Window);
+extern MSG fl_msg;
+
+// off-screen pixmaps: create, destroy, draw into, copy to window
+#define Fl_Offscreen HBITMAP
+#define fl_create_offscreen(w, h) CreateCompatibleBitmap(fl_gc, w, h)
+extern void fl_switch_offscreen(HBITMAP);
+#define fl_begin_offscreen(b) HDC _sw=fl_gc; fl_switch_offscreen(b)
+#define fl_end_offscreen() fl_gc = _sw
+void fl_make_current(HBITMAP bitmap);
+void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy);
+#define fl_delete_offscreen(bitmap) DeleteObject(bitmap);
+
diff --git a/FL/x.H b/FL/x.H
new file mode 100644
index 000000000..39d1e7bb3
--- /dev/null
+++ b/FL/x.H
@@ -0,0 +1,87 @@
+// x.H
+
+// These are internal fltk symbols that are necessary or useful for
+// calling Xlib. You should include this file if (and ONLY if) you
+// need to call Xlib directly. These symbols may not exist on non-X
+// systems.
+
+#ifndef Fl_X_H
+#define Fl_X_H
+
+#include "Enumerations.H"
+
+#ifdef WIN32
+
+#include "win32.H"
+
+#else
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include "Fl_Window.H"
+
+void fl_open_display();
+void fl_close_display();
+
+// constant info about the X server connection:
+extern Display *fl_display;
+extern int fl_screen;
+extern XVisualInfo *fl_visual;
+extern Colormap fl_colormap;
+
+// drawing functions:
+extern GC fl_gc;
+extern Window fl_window;
+ulong fl_xpixel(Fl_Color i);
+ulong fl_xpixel(uchar r, uchar g, uchar b);
+void fl_clip_region(Region);
+
+// feed events into fltk:
+int fl_handle(const XEvent&);
+
+// you can use these in Fl::add_handler() to look at events:
+extern const XEvent* fl_xevent;
+extern ulong fl_event_time;
+
+// off-screen pixmaps: create, destroy, draw into, copy to window:
+#define Fl_Offscreen ulong
+#define fl_create_offscreen(w,h) \
+XCreatePixmap(fl_display, fl_window, w, h, fl_visual->depth)
+#define fl_begin_offscreen(pixmap) Window _sw=fl_window;fl_window=pixmap;fl_push_no_clip()
+#define fl_end_offscreen() fl_pop_clip();fl_window = _sw
+#define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \
+ XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y)
+#define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap)
+
+// this object contains all X-specific stuff about a window:
+// Warning: this object is highly subject to change! It's definition
+// is only here so that fl_xid can be declared inline:
+class Fl_X {
+public:
+ Window xid;
+ Window other_xid;
+ Fl_Window *w;
+ Region region;
+ Fl_X *next;
+ static Fl_X* first;
+ static Fl_X* i(const Fl_Window* w) {return w->i;}
+ void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
+ void sendxjunk();
+ static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
+ static Fl_X* set_xid(Fl_Window*, Window);
+ // kludges to get around protection:
+ void flush() {w->flush();}
+ static void x(Fl_Window* w, int X) {w->x(X);}
+ static void y(Fl_Window* w, int Y) {w->y(Y);}
+};
+
+// convert xid <-> Fl_Window:
+inline Window fl_xid(const Fl_Window*w) {return Fl_X::i(w)->xid;}
+Fl_Window* fl_find(Window xid);
+
+extern char fl_override_redirect; // hack into Fl_X::make_xid()
+extern int fl_background_pixel; // hack into Fl_X::make_xid()
+
+#endif
+#endif
diff --git a/GL/glut.h b/GL/glut.h
new file mode 100644
index 000000000..367bf8929
--- /dev/null
+++ b/GL/glut.h
@@ -0,0 +1,3 @@
+// this file allows some glut programs to be compiled with no change.
+// Put this in a directory "GL" in your include path.
+#include <FL/glut.H>
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..5df40f8f2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,49 @@
+SHELL=/bin/sh
+
+all : src fluid test
+shared : srcshared fluid test
+lib : SRC
+src : SRC
+
+SRC : makeinclude src/makedepend
+ cd src && $(MAKE)
+src/makedepend :
+ touch src/makedepend
+srcshared : makeinclude src/makedepend
+ cd src && $(MAKE) shared
+
+fluid : FLUID
+FLUID : makeinclude fluid/makedepend
+ cd fluid && $(MAKE)
+fluid/makedepend :
+ touch fluid/makedepend
+
+test : TEST
+TEST : makeinclude
+ cd test && $(MAKE)
+
+install : SRC FLUID
+ cd src && $(MAKE) install
+ cd fluid && $(MAKE) install
+
+uninstall : makeinclude src/makedepend fluid/makedepend
+ cd src && $(MAKE) uninstall
+ cd fluid && $(MAKE) uninstall
+
+clean :
+ -@ rm -f *.o core *~
+ cd src && $(MAKE) clean
+ cd fluid && $(MAKE) clean
+ cd test && $(MAKE) clean
+
+distclean : clean
+ -@ rm config.* makeinclude
+
+realclean : distclean
+
+include ./version
+dist :
+ ./makedist $(VERSION).$(REVISION)
+
+makeinclude :
+ ./configure
diff --git a/README b/README
new file mode 100644
index 000000000..04ce612f6
--- /dev/null
+++ b/README
@@ -0,0 +1,123 @@
+Fast Light Tool Kit (fltk) Version 0.99
+
+----------------------------------------------------------------
+How to build and install fltk:
+----------------------------------------------------------------
+
+See the file win32/README for information for Windoze95/NT.
+
+1. Type "./configure", and then examine config.h and makeinclude.
+1. Edit the file ./style.h to customize the appearance of fltk
+3. Type "make", or (Linux and gcc only) type "make shared" to make
+ a shared library.
+4. For shared libraries, type "setenv LD_LIBRARY_PATH $PWD/lib"
+5. Test it by running "test/demo".
+
+To install the new version of Fltk and fluid (this puts the library in
+/usr/local/lib, the include files in /usr/local/include/FL, and fluid
+into /usr/local/bin):
+
+1. If you made the shared version, type "unsetenv LD_LIBRARY_PATH"
+2. Type "su" and then your password
+3. Type "make install"
+4. If you made the shared version, type "/sbin/ldconfig"
+5. Type ^D to get out of su.
+
+----------------------------------------------------------------
+On-line documentation:
+----------------------------------------------------------------
+
+All the documentation is in html in the subdirectory "documentation".
+Use file:<here>/documentation/index.html to get started. Install
+should put the documentation in /usr/doc/fltk but this is not yet
+implemented.
+
+These files are readable without a browser:
+
+Change log is in documentation/CHANGES
+To Do list is in documentatoin/TODO.html
+
+----------------------------------------------------------------
+WWW resources:
+----------------------------------------------------------------
+
+The Fltk home page: http://www.cinenet.net/users/spitzak/fltk
+
+Mirror site: http://fltk.easysw.com
+
+To post to the fltk mailing list: fltk@easysw.com
+
+To subscribe, send "subscribe fltk" to majordomo@easysw.com
+
+Send mail to Bill Spitzak (the author of fltk): spitzak@d2.com
+
+Get Mesa (necessary to run OpenGl on most Linux machines):
+ http://www.ssec.wisc.edu/~brianp/Mesa.html
+
+----------------------------------------------------------------
+Window managers
+----------------------------------------------------------------
+
+Fltk now uses X transient windows for modal() windows. This may
+confuse some window managers. Mostly it causes them to not put
+any borders on the modal windows and prevent you from moving them.
+
+For FVWM I recommend you put "DecorateTransients" into your .fvwmrc.
+
+----------------------------------------------------------------
+Mesa:
+----------------------------------------------------------------
+
+Currently the best way to get OpenGL on your Linux system is to use
+Mesa. Fltk has been tested with Mesa on several machines (and also
+with "real" OpenGL on SGI machines).
+
+Mesa is at: http://www.ssec.wisc.edu/~brianp/Mesa.html
+
+./configure will not see Mesa unless it is installed as either libGL
+or libMesa. If you don't want to do this you will have to edit
+config.h (set HAVE_GL to 1) and makeinclude (add the libraries).
+
+----------------------------------------------------------------
+How to write programs that use Fltk:
+----------------------------------------------------------------
+
+The proper way to include Fltk header files is "#include <FL/Fl_xyz.H>".
+If Fltk is installed this will work without switches. If not you will
+need to provide a -I switch pointing to this directory (all the
+headers are in ./FL).
+
+Linker switches will be something like "-lfltk -L/usr/X11R6/lib -lX11".
+Some programs may require -lXext or -lm. If Fltk is not installed you
+will need to add a -L switch pointing at ./lib.
+
+If you wish to distribute a program (in source form) that uses Fltk,
+you are allowed by the license to directly include the portions of
+Fltk that you need. This may make it easier for a user to compile
+your program since they don't need to install the library. Please
+provide instructions for the user on how they can get the entire
+source of Fltk.
+
+If you wish to distribute a compiled program without source code: this
+is allowed. See the license.
+
+----------------------------------------------------------------
+Copyright (C) 1998 Bill Spitzak
+----------------------------------------------------------------
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+USA.
+
+Written by Bill Spitzak spitzak@d2.com
+----------------------------------------------------------------
diff --git a/configh.in b/configh.in
new file mode 100644
index 000000000..0ff8d77a5
--- /dev/null
+++ b/configh.in
@@ -0,0 +1,53 @@
+/* configh.in: this file is read by ./configure to produce config.h */
+
+/* Thickness of FL_UP_BOX and FL_DOWN_BOX. Current 1,2, and 3 are
+ supported. 3 is the historic fltk look. 2 looks more like windoze
+ (and KDE and Qt). 1 is a plausible future evolution... Notice
+ that this may be simulated at runtime by redefining the boxtypes
+ using Fl::set_boxtype() */
+#define BORDER_WIDTH 3
+
+/* Do you have OpenGL?
+ Set this to 0 if you don't plan to use OpenGL, and fltk will be smaller */
+#define HAVE_GL 0
+
+/* Use XAllocColor
+ Setting this to zero will save a good deal of code (esp for
+ fl_draw_image), but fltk will only work on TrueColor visuals. */
+#define USE_COLORMAP 1
+
+/* Do we have the X double-buffer extension? */
+#define HAVE_XDBE 0
+
+/* Actually try to use the double-buffer extension?
+ Set this to zero disable use of XDBE without breaking the
+ list_visuals program: */
+#define USE_XDBE HAVE_XDBE
+
+/* Use the X overlay extension? Fltk will try to use an overlay
+ visual for Fl_Overlay_Window, the Gl_Window overlay, and for the
+ menus. Setting this to zero will remove a substatial amount of
+ code from fltk. Overlays have only been tested on SGI servers! */
+#define HAVE_OVERLAY 0
+/* It is possible your GL has an overlay even if X does not, if so
+ turn this on: */
+#define HAVE_GL_OVERLAY HAVE_OVERLAY
+
+/* Byte order of your machine: */
+#define WORDS_BIGENDIAN 0
+
+/* Types used by fl_draw_image. One of U32 or U64 must be defined.
+ U16 is optional but fltk will work better with it! */
+#undef U16
+#undef U32
+#undef U64
+
+/* Where is <dirent.h> (used only by fl_file_chooser and scandir): */
+#define HAVE_DIRENT_H 1
+#define HAVE_SYS_NDIR_H 0
+#define HAVE_SYS_DIR_H 0
+#define HAVE_NDIR_H 0
+#define HAVE_SCANDIR 0
+
+/* use poll() instead of select(): */
+#define HAVE_POLL 0
diff --git a/configure b/configure
new file mode 100755
index 000000000..b67eb4535
--- /dev/null
+++ b/configure
@@ -0,0 +1,2721 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-x use the X Window System"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=src/Fl.C
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:527: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:556: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:604: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 614 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:638: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:643: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:652: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:667: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:699: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CXX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+ echo "$ac_t""$CXX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:730: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 740 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cxx_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cxx_cross=no
+ else
+ ac_cv_prog_cxx_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+ { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:770: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:775: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.C <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:784: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+ ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS=
+ echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:799: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ ac_cv_prog_cxx_g=yes
+else
+ ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+ if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ elif test $ac_cv_prog_cxx_g = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-O2"
+ fi
+else
+ GXX=
+ test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
+fi
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:828: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 835 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:846: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 850 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:861: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 881 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:894: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:919: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_short=2
+else
+ cat > conftest.$ac_ext <<EOF
+#line 927 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(short));
+ exit(0);
+}
+EOF
+if { (eval echo configure:938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_short=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:958: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_int=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 966 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(int));
+ exit(0);
+}
+EOF
+if { (eval echo configure:977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_int=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:997: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_long=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1005 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+if test $ac_cv_sizeof_short -eq 2; then
+cat >> confdefs.h <<\EOF
+#define U16 unsigned short
+EOF
+
+fi
+if test $ac_cv_sizeof_int -eq 4; then
+cat >> confdefs.h <<\EOF
+#define U32 unsigned
+EOF
+
+else
+if test $ac_cv_sizeof_long -eq 4; then
+cat >> confdefs.h <<\EOF
+#define U32 unsigned long
+EOF
+
+fi
+fi
+if test $ac_cv_sizeof_int -eq 8; then
+cat >> confdefs.h <<\EOF
+#define U64 unsigned
+EOF
+
+else
+if test $ac_cv_sizeof_long -eq 8; then
+cat >> confdefs.h <<\EOF
+#define U64 unsigned long
+EOF
+
+fi
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:1073: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1078 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:1086: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:1111: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1119 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:1152: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1160 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+for ac_func in scandir
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1197: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1202 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1253: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1281: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1296 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1302: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1313 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1319: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:1346: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ # Both variables are already set.
+ have_x=yes
+ else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 1408 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1413: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1482 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:1489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11/lib \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /lib/usr/lib/X11 \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+ # Didn't find X anywhere. Cache the known absence of X.
+ ac_cv_have_x="have_x=no"
+else
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ echo "$ac_t""$have_x" 1>&6
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+if test "$no_x" = yes; then
+ # Not all programs may use this symbol, but it does not hurt to define it.
+ cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+ X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+ if test -n "$x_includes"; then
+ X_CFLAGS="$X_CFLAGS -I$x_includes"
+ fi
+
+ # It would also be nice to do this for all -L options, not just this one.
+ if test -n "$x_libraries"; then
+ X_LIBS="$X_LIBS -L$x_libraries"
+ # For Solaris; some versions of Sun CC require a space after -R and
+ # others require no space. Words are not sufficient . . . .
+ case "`(uname -sr) 2>/dev/null`" in
+ "SunOS 5"*)
+ echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:1595: checking whether -R must be followed by a space" >&5
+ ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+ cat > conftest.$ac_ext <<EOF
+#line 1598 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ ac_R_nospace=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_R_nospace=no
+fi
+rm -f conftest*
+ if test $ac_R_nospace = yes; then
+ echo "$ac_t""no" 1>&6
+ X_LIBS="$X_LIBS -R$x_libraries"
+ else
+ LIBS="$ac_xsave_LIBS -R $x_libraries"
+ cat > conftest.$ac_ext <<EOF
+#line 1621 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ ac_R_space=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_R_space=no
+fi
+rm -f conftest*
+ if test $ac_R_space = yes; then
+ echo "$ac_t""yes" 1>&6
+ X_LIBS="$X_LIBS -R $x_libraries"
+ else
+ echo "$ac_t""neither works" 1>&6
+ fi
+ fi
+ LIBS="$ac_xsave_LIBS"
+ esac
+ fi
+
+ # Check for system-dependent libraries X programs must link with.
+ # Do this before checking for the system-independent R6 libraries
+ # (-lICE), since we may need -lsocket or whatever for X linking.
+
+ if test "$ISC" = yes; then
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+ else
+ # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+ # libraries were built with DECnet support. And karl@cs.umb.edu says
+ # the Alpha needs dnet_stub (dnet does not exist).
+ echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:1660: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldnet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1668 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:1679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+ echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:1701: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1709 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:1720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+ # to get the SysV transport functions.
+ # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+ # needs -lnsl.
+ # The nsl library prevents programs from opening the X display
+ # on Irix 5.2, according to dickey@clark.net.
+ echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:1749: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1754 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostbyname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_gethostbyname = no; then
+ echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:1798: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1806 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:1817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # lieder@skyler.mavd.honeywell.com says without -lsocket,
+ # socket/setsockopt and other routines are undefined under SCO ODT
+ # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+ # on later versions), says simon@lia.di.epfl.ch: it contains
+ # gethostby* variants that don't use the nameserver (or something).
+ # -lsocket must be given before -lnsl if both are needed.
+ # We assume that if connect needs -lnsl, so does gethostbyname.
+ echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:1847: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1852 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char connect(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_connect=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_connect = no; then
+ echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:1896: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1904 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:1915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+ echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:1939: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1944 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char remove(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_remove=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_remove = no; then
+ echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:1988: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lposix $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1996 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:2007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+ echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:2031: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2036 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shmat(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_shmat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_shmat = no; then
+ echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:2080: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lipc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2088 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:2099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ fi
+
+ # Check for libraries that X11R6 Xt/Xaw programs need.
+ ac_save_LDFLAGS="$LDFLAGS"
+ test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+ # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+ # check for ICE first), but we must link in the order -lSM -lICE or
+ # we get undefined symbols. So assume we have SM if we have ICE.
+ # These have to be linked with before -lX11, unlike the other
+ # libraries we check for below, so use a different variable.
+ # --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+ echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:2132: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lICE $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2140 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:2151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+echo "Ignoring libraries \"$X_PRE_LIBS\" requested by configure."
+LIBS="$LIBS$X_LIBS"
+CFLAGS="$CFLAGS $X_CFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+GLLIB=
+echo $ac_n "checking for glXMakeCurrent in -lGL""... $ac_c" 1>&6
+echo "configure:2182: checking for glXMakeCurrent in -lGL" >&5
+ac_lib_var=`echo GL'_'glXMakeCurrent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lGL \
+ -lX11 -lXext $X_EXTRA_LIBS -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2191 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char glXMakeCurrent();
+
+int main() {
+glXMakeCurrent()
+; return 0; }
+EOF
+if { (eval echo configure:2202: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_GL 1
+EOF
+ GLLIB=" -lGLU -lGL"
+else
+ echo "$ac_t""no" 1>&6
+\
+ echo $ac_n "checking for glXMakeCurrent in -lMesaGL""... $ac_c" 1>&6
+echo "configure:2225: checking for glXMakeCurrent in -lMesaGL" >&5
+ac_lib_var=`echo MesaGL'_'glXMakeCurrent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lMesaGL \
+ -lX11 -lXext $X_EXTRA_LIBS -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2234 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char glXMakeCurrent();
+
+int main() {
+glXMakeCurrent()
+; return 0; }
+EOF
+if { (eval echo configure:2245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_GL 1
+EOF
+ GLLIB=" -lMesaGLU -lMesaGL"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+
+ac_safe=`echo "X11/extensions/Xdbe.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for X11/extensions/Xdbe.h""... $ac_c" 1>&6
+echo "configure:2274: checking for X11/extensions/Xdbe.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2279 "configure"
+#include "confdefs.h"
+#include <X11/extensions/Xdbe.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2284: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_XDBE 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking "for X overlay visuals"""... $ac_c" 1>&6
+echo "configure:2310: checking "for X overlay visuals"" >&5
+if eval "test \"`echo '$''{'ac_cv_have_overlay'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if xprop -root 2>/dev/null | grep -c "SERVER_OVERLAY_VISUALS" >/dev/null; then
+ ac_cv_have_overlay=yes
+else
+ ac_cv_have_overlay=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_have_overlay" 1>&6
+if test "$ac_cv_have_overlay" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_OVERLAY 1
+EOF
+
+fi
+
+MAKEDEPEND="\$(CXX) -M"
+
+if test -n "$GXX"; then
+ CFLAGS="-Wall -O2"
+ CFLAGS_D="-Wall -Wno-return-type -g -DDEBUG"
+ CXXFLAGS="-Wall -Wno-return-type -O2"
+ CXXFLAGS_D="-Wall -Wno-return-type -g -DDEBUG"
+else
+if test "`(uname) 2>/dev/null`" = IRIX; then
+ if expr "`(uname -r)`" \>= 6.2; then
+ # compiler names:
+ CXX="CC -n32"
+ CC="cc -n32"
+ LD="ld -n32"
+ MAKEDEPEND="CC -M"
+ # -woff 3322 is necessary due to errors in Xlib headers on IRIX
+ CFLAGS="-fullwarn -O2"
+ CFLAGS_D="-fullwarn -gslim -DDEBUG"
+ CXXFLAGS="-fullwarn -woff 1685 -woff 3322 -O2"
+ CXXFLAGS_D="-fullwarn -woff 1685 -woff 3322 -gslim -DDEBUG"
+ else
+ CFLAGS="-O2"
+ CFLAGS_D="-g -DDEBUG"
+ CXXFLAGS="+w +pp -O2"
+ CXXFLAGS_D="+w +pp -g -DDEBUG"
+ fi
+else
+ CFLAGS="-O"
+ CFLAGS_D="-g -DDEBUG"
+ CXXFLAGS="-O"
+ CXXFLAGS_D="-g -DDEBUG"
+fi
+fi
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "makeinclude config.h:configh.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@CXX@%$CXX%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@GLLIB@%$GLLIB%g
+s%@MAKEDEPEND@%$MAKEDEPEND%g
+s%@CFLAGS_D@%$CFLAGS_D%g
+s%@CXXFLAGS_D@%$CXXFLAGS_D%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"makeinclude "}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:configh.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 000000000..46b856b68
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,106 @@
+dnl# -*- sh -*-
+dnl# the "configure" script is made from this by running GNU "autoconf"
+
+AC_INIT(src/Fl.C)
+AC_PROG_CC
+AC_PROG_CXX
+dnl# AC_PROG_INSTALL
+
+AC_C_BIGENDIAN
+
+AC_CHECK_SIZEOF(short, 2)
+AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(long, 4)
+if test $ac_cv_sizeof_short -eq 2; then
+AC_DEFINE(U16,unsigned short)
+fi
+if test $ac_cv_sizeof_int -eq 4; then
+AC_DEFINE(U32,unsigned)
+else
+if test $ac_cv_sizeof_long -eq 4; then
+AC_DEFINE(U32,unsigned long)
+fi
+fi
+if test $ac_cv_sizeof_int -eq 8; then
+AC_DEFINE(U64,unsigned)
+else
+if test $ac_cv_sizeof_long -eq 8; then
+AC_DEFINE(U64,unsigned long)
+fi
+fi
+
+AC_HEADER_DIRENT
+
+AC_CHECK_FUNCS(scandir)
+
+AC_PROG_RANLIB
+
+AC_PATH_XTRA
+echo "Ignoring libraries \"$X_PRE_LIBS\" requested by configure."
+dnl# LIBS="$LIBS$X_LIBS$X_PRE_LIBS"
+LIBS="$LIBS$X_LIBS"
+CFLAGS="$CFLAGS $X_CFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+dnl# My test to see if OpenGL is on this machine:
+GLLIB=
+AC_CHECK_LIB(GL, glXMakeCurrent, AC_DEFINE(HAVE_GL) GLLIB=" -lGLU -lGL", \
+ AC_CHECK_LIB(MesaGL,glXMakeCurrent, AC_DEFINE(HAVE_GL) GLLIB=" -lMesaGLU -lMesaGL",,\
+ -lX11 -lXext $X_EXTRA_LIBS -lm), \
+ -lX11 -lXext $X_EXTRA_LIBS -lm)
+AC_SUBST(GLLIB)
+
+AC_CHECK_HEADER(X11/extensions/Xdbe.h, AC_DEFINE(HAVE_XDBE))
+
+AC_CACHE_CHECK("for X overlay visuals", ac_cv_have_overlay,
+if xprop -root 2>/dev/null | grep -c "SERVER_OVERLAY_VISUALS" >/dev/null; then
+ ac_cv_have_overlay=yes
+else
+ ac_cv_have_overlay=no
+fi)
+if test "$ac_cv_have_overlay" = yes; then
+ AC_DEFINE(HAVE_OVERLAY)
+fi
+
+MAKEDEPEND="\$(CXX) -M"
+
+dnl# add warnings and optimization to compiler switches:
+dnl# do this last so messing with switches does not break tests
+if test -n "$GXX"; then
+ CFLAGS="-Wall -O2"
+ CFLAGS_D="-Wall -Wno-return-type -g -DDEBUG"
+ CXXFLAGS="-Wall -Wno-return-type -O2"
+ CXXFLAGS_D="-Wall -Wno-return-type -g -DDEBUG"
+else
+if test "`(uname) 2>/dev/null`" = IRIX; then
+ if expr "`(uname -r)`" \>= 6.2; then
+ # compiler names:
+ CXX="CC -n32"
+ CC="cc -n32"
+ LD="ld -n32"
+ MAKEDEPEND="CC -M"
+ # -woff 3322 is necessary due to errors in Xlib headers on IRIX
+ CFLAGS="-fullwarn -O2"
+ CFLAGS_D="-fullwarn -gslim -DDEBUG"
+ CXXFLAGS="-fullwarn -woff 1685 -woff 3322 -O2"
+ CXXFLAGS_D="-fullwarn -woff 1685 -woff 3322 -gslim -DDEBUG"
+ else
+ CFLAGS="-O2"
+ CFLAGS_D="-g -DDEBUG"
+ CXXFLAGS="+w +pp -O2"
+ CXXFLAGS_D="+w +pp -g -DDEBUG"
+ fi
+else
+ CFLAGS="-O"
+ CFLAGS_D="-g -DDEBUG"
+ CXXFLAGS="-O"
+ CXXFLAGS_D="-g -DDEBUG"
+fi
+fi
+AC_SUBST(MAKEDEPEND)
+AC_SUBST(CFLAGS_D)
+AC_SUBST(CXXFLAGS_D)
+AC_CONFIG_HEADER(config.h:configh.in)
+AC_OUTPUT(makeinclude )
+
+dnl# end of configure.in
diff --git a/documentation/CHANGES b/documentation/CHANGES
new file mode 100644
index 000000000..0624e8679
--- /dev/null
+++ b/documentation/CHANGES
@@ -0,0 +1,411 @@
+Fltk modification history <pre>
+
+9/22/98: uses X regions for update
+9/16/98: added Fl_Widget::output(), works like inactive but draws normally
+9/15/98: multi-browser has some keyboard navigation
+9/10/98: fl_ok, fl_cancel, fl_yes, fl_no pointers added to change language
+9/09/98: default_font() & default_size() added, made style demo
+9/09/98: fixed so child windows activate/deactivate correctly
+9/08/98: does not set colormap, relies on WM_COLORMAP_WINDOWS working
+9/08/98: added default_box, _font, _size to Fl_Input & Fl_Browser
+9/04/98: Fl_Tabs changes cursor to show what you can move
+9/03/98: child windows respond to FL_SHOW/FL_HIDE (so OpenGL in Fl_Tabs works!)
+9/03/98: Fl_Group::add() calls Fl_Group::remove() if child already in a group
+9/02/98: moved textsize/font/color from Fl_Browser to Fl_Browser_.
+9/02/98: most boxtypes draw inactive when widget is inactive
+9/01/98: Fl_Browser can store a void* data() value with each line
+9/01/98: added Fl_Browser_::has_scrollbar(uchar)
+8/31/98: Fl_Valuator step 'A' value is now a double instead of int
+8/27/98: transparecy in Fl_Pixmap handled correctly! (X only)
+8/26/98: fl_rotate(0,90,180,270,-90) fixed to not have math rounding errors
+8/26/98: added fl_point and fl_begin/end_points drawing functions
+8/24/98: Added ability to #define WINDOWS_STYLE in config.h (try it)
+8/24/98: Made default color be 75% gray to match KDE & Gnome (and Windows)
+8/23/98: All widgets draw their labels gray if inactive (try inactive demo)
+8/23/98: Fl_Color, Fl_Font, Fl_Boxtype, Fl_Labeltype enumerations
+ (this may break some existing code and need casts added)
+8/21/98: filename_list() and filename_isdir() made public and documented
+8/21/98: fl_draw_image will use 64 bit data types if available (Cray fix)
+8/18/98: fluid can set the output file names (on preferences panel)
+8/18/98: fluid lets you set textfont() and textsize() of Fl_Menu_ widgets
+8/16/98: Added Fl_Scrollbar, and used for Fl_Browser & Fl_Scroll
+8/14/98: Fluid didn't put variable into .h file if 'o' variable not needed
+8/14/98: Vastly improved display on MSWindows in 8-bit mode, matches X 8bit mode
+8/11/98: fixed stupid error that broke the menus on MSWindows
+8/11/98: Fl::args(a,b,&i,c) no longer depends on initial value of i
+8/10/98: fixed the mouse position during grab() on MSWindows!
+8/10/98: some bugs with resizing in fluid fixed, does not raise panel
+8/10/98: Fl::event_key() returns unshifted (lowercase) keysym always
+8/09/98: Tested on NT, compilation errors there fixed
+8/07/98: Fl_Scroll can force scrollbars on at all times (add 4 to type())
+8/07/98: renamed one of the Fl_Menu_Item methods from "popup" to "pulldown"
+8/06/98: you no longer have to call show() on child windows!!!
+8/06/98: added move() to Fl_Browser (Curtis please test!)
+8/06/98: Some fixes to resizable() handling, it does not need to be a child
+8/06/98: & in Fl_Choice menu item is not drawn in the widget itself
+8/05/98: Fl_Menu_Button::type(POPUP) allows box() to work for menu
+8/04/98: fixed Fl_Menu_Button to not call menu item twice
+7/30/98: Fl_Browser scrolls to bottom when add() is done
+7/30/98: fixed some bugs with the horizontal scrollbars in Fl_Browser_
+7/29/98: kludge so it can simulate MSWindows menus (try the menubar demo)
+7/27/98: you can set a menu's boxtype & color! Try it in fluid
+7/26/98: float/int input fields do not prevent letters from being shortcuts
+7/26/98: fluid reads .xpm and .xbm files with comments inserted at start
+7/25/98: added fl_password() popup utility
+7/25/98: added horizontal scrollbar to Fl_Browser
+7/25/98: fixed fluid crash on startup (Fl::get_system_colors opens display)
+7/18/98: new menu behavior so moving mouse does not wreck keyboard navigation
+7/17/98: added Fl::own_colormap() and Fl::get_system_colors() init functions
+7/16/98: fixed overlay on Reality Engine
+7/14/98: fl_begin_offscreen() clears clip region, fl_end_offscreen restores it
+7/14/98: uses gettimeofday() instead of times() (faster & more portable?)
+7/10/98: fl_color() and gl_color() work in the overlays!
+7/09/98: inverted meaning & default of the FL_ALIGN_WRAP bit (INCOMPATABLE!)
+7/08/98: fixed (brute force) the titlebar & grab during menus on MSWindows
+7/08/98: shortcuts fixed so they work when mouse is not pointing at any window
+7/07/98: fixed FL_NO_LABEL and some other symbols output by fluid
+7/06/98: Fl_Gl_Window overlay was missized if window resize before redraw_overlay
+7/06/98: Fl_Window::resize() changes size immediately, does not wait for X
+7/05/98: Fl::wait(), Fl::check(), and Fl::run() return 0 when no windows
+6/30/98: buttons and toggle/radio menu items write value() to .fl file
+6/29/98: made output of fluid more readable
+6/29/98: fluid writes callbacks inside a class as real (not static) methods
+6/27/98: added classes to fluid
+6/24/98: emulated Fl::set_atclose(), lots of programs use it!
+6/24/98: Added Fl_Pack. Fl_Scroll still needs some work to use this
+6/23/98: Removed (most of) the unused-variable errors in fluid output
+6/22/98: Renamed Fl_Menu to Fl_Menu_Item (typedef for back compatability)
+6/22/98: Added @|| symbol so you have complete tape deck controls
+6/22/98: MSWindows menus now come out atop the icon dock
+6/22/98: FL_MENU_RADIO draws diamond rather than square
+6/22/98: X fl_polygon changed to match the MSWindows version
+6/19/98: Fixed bug on Solaris (sprintf in fl_font.C)
+6/18/98: Fixed Alt-GR on foreign keyboards under MSWindows
+6/17/98: added Fl_Menu_::global() so shortcuts work everywhere
+6/16/98: Tried to make Fl_Scroll better, children can change their size
+6/15/98: Fl_Window::callback replaces Fl::atclose (which is deleted)
+6/15/98: FL_INT_INPUT & FL_FLOAT_INPUT just draw text red if it is illegal
+6/15/98: Fl_Valuator::format() is a virtual function
+6/14/98: fixed fl_draw_image on 8-bit truecolor visuals
+6/10/98: simplified forms compatability: Fl_Group::end_forms() replaces stuff
+6/09/98: Added "New" to fluid, fixed some bugs with redisplay
+
+fltk-0.99
+
+6/07/98: fluid no longer puts 'if (!w) {...}' around code for window w
+6/07/98: Can compile shared library on Linux (matches Debian release)
+6/05/98: added Fl_Menu_::popup(x,y,w,h) and Fl_Menu_Button::popup()
+6/05/98: greatly speeded up truecolor visuals by not doing XAllocColor
+6/03/98: zero-sized fl_clip() works
+6/02/98: fluid cut file moved from /tmp to $HOME for security reasons
+6/01/98: MSWindows color palette support on 8-bit displays
+5/27/98: fluid can set shortcuts of buttons and menu items
+5/26/98: integer (instead of string) button & menu shortcuts (INCOMPATABLE)
+5/23/98: cut/paste for MSWindows
+5/23/98: detects if OpenGL overlay exists on MSWindows
+5/22/98: fixes for IRIX 6.2 n32 compiler
+5/20/98: added code, codeblock, decl, and declblock to fluid
+5/20/98: you can pick the items off of menus in fluid
+5/19/98: fluid can now create menus & menu items!
+5/19/98: Fl_Bitmap, Fl_Pixmap, Fl_Image now have label(Fl_Menu) method
+5/17/98: Can use hardware overlay planes in Fl_Gl_Window on MSWindows
+5/16/98: Fl_Light_Button uses down_box() to determine light shape
+5/13/98: fixed many annoying bugs on MSWindows
+5/10/98: new Fl::grab(Fl_Widget*) replaces modal(Fl_Widget*)
+5/05/98: Fl_Gl_Window does not use scissor anymore
+5/04/98: changed Fl_Color_Chooser to use floating point rgb values
+5/04/98: added Fl_Browser @-commands to set font, color, size, background
+5/04/98: added Fl_Browser::column_widths() for multi-column display
+5/04/98: renamed Fl_Browser::specialkey() to Fl_Browser::format_char()
+5/04/98: fixed float/int input where they never work after 1st illegal char.
+5/03/98: fixed bitmaps on MSWindows
+4/27/98: renamed Fl_Slider::size() to Fl_Slider::slider_size()
+4/27/98: renamed fl_pixmap_size to fl_measure_pixmap
+4/27/98: added labeltype measure function, tabs & menus use it
+4/26/98: added labeltype/font/size/color to Fl_Menu
+4/26/98: '_' in menus replaced with FL_MENU_DIVIDER bit (!!! INCOMPATABLE !!!)
+4/21/98: swapped OK/cancel positions on popups to match gtk/gnome
+4/20/98: added Fl_Window::non_modal()
+4/19/98: '/' in menus replaced with FL_SUBMENU bit (!!! INCOMPATABLE !!!)
+4/16/98: fluid puts extra_code for windows & groups *after* adding children
+4/15/98: fixed numericsort to work for more than 10 digits.
+4/15/98: merges adjacent mouse-moved events (should have motion history)
+4/15/98: event mask for children windows left on (helps for using fl_xevent)
+4/12/98: added Fl_Input::static_value(x) that avoids doing malloc & copy
+4/12/98: you can insert ^@ (nul) into Fl_Input, Fl_Output, and cut/paste
+4/12/98: secret fl_encoding variable may be set to override iso8859-1
+4/11/98: added FL_ALIGN_NOWRAP & FL_ALIGN_CLIP
+4/10/98: MSWindows supports OpenGL!
+4/10/98: uses transient_for property for modal windows
+4/05/98: added Fl::modal(window) to fix menu problems
+4/05/98: better drawing of dials
+3/22/98: replaced Fl::abort() with: Fl::warning(), Fl::error(), Fl::fatal()
+3/22/98: added Fl::set_fonts() to get all the fonts from server
+3/21/98: really neato new color chooser
+3/17/98: new fl_draw_image with callback for arbitrary image data formats
+3/17/98: mucho improvement in the MSWindows port, it is now usable!
+3/16/98: new fl_show_colormap (single pop-up array of all colors)
+3/13/98: fixed borders under KDE's kwm.
+3/13/98: Uses X regions to update window, new fl_clip functions
+3/08/98: Round buttons now draw much more attractively
+3/05/98: Fl_Tabs draws the tabs much nicer
+3/05/98: Fl_Input now does compose-character sequences
+3/04/98: Fluid: changing objects with panel open saves changes to old objects
+3/03/98: Uses select() instead of poll() even on sgi (fixes Irix 6.3)
+2/26/98: Added Fl::get_key(n), Fl::event_key(n), Fl::event_state(n)
+2/23/98: Added Fl_Tile (maximum of 2 across and 2 down children)
+2/07/98: Esc key (if not used for anything else) will close window
+2/07/98: Adds ":0.0" to -display if missing
+2/06/98: Rearrangement to make a MSWindows port easier
+2/02/98: Does not die on X errors
+2/01/98: Controls for valuators added to fluid
+2/01/98: Added Fl_Value_Input and Fl_Value_Output
+1/29/98: Added Fl_Valuator base class for sliders, dials, etc
+1/29/98: fixed colormap-allocation hang on Solaris
+1/27/98: fixed the red-window problem in fluid on IRIX 6.2
+1/26/98: changed float to double everywhere to shut MSVC++ up
+1/23/98: Fl_Group does begin() in constructor (dangerous?)
+1/23/98: Greatly simplified how to subclass groups and redraw them
+1/22/98: Added Fl_Widget::damage(bits,x,y,w,h) to do clipped redrawing
+1/22/98: New Fl_Bitmap::draw() methods (and Fl_Pixmap, Fl_Image)
+1/22/98: Word wrap in the labels
+1/21/98: Renamed Fl_Object to Fl_Widget, to match common toolkit terminology
+
+fltk-0.98
+
+1/17/98: renamed the library to fltk
+1/14/98: added fl_curve
+1/14/98: fl_arc really works (finally!) no more 16-sided circles
+1/14/98: replaced fl_end() with fl_end_line(), etc
+1/12/98: Does not crash with very large WM_COMMAND strings
+1/12/98: Cleaner menus that work ok w/o overlay or save-behind
+1/12/98: Fluid objects may be named "a.x" or "a->x" or similar
+1/12/98: Fl_Double_Window supported in fluid with a kludge
+
+FL-0.98
+
+1/9/98: Fl_Group now uses array, eliminated next(), prev(), first(), last()
+1/7/98: Removed many uninteresting test programs to make distribution smaller
+1/7/98: Removed Fl_Window::set_atclose(), use Fl::set_atclose() instead
+1/6/98: Reduction of number of .html files used for documentation
+1/6/98: added event_is_click(), renamed reset_clicks to event_is_click(0)
+12/15/97: Huge improvements to menus: can pop up with any item selected
+ and Fl_Choice uses this to pop up lists with arrow on item,
+ underscore shortcuts added to Fl_Menu_Button and Fl_Choice
+ and Fl_Menu_Bar.
+12/12/97: Fl_Gl_Window::invalidate() added, use this instead of valid(0)
+12/11/97: New navigation keys in the menu code!
+12/11/97: Microsloth-style underscore shortcuts on all buttons
+12/07/97: Fixed Xdbe (it sent backbuffer rather than window toXDBEswap...())
+12/05/97: mandelbrot demo created
+12/05/97: Fl_Window::make_current() for incremental redrawing added
+12/05/97: fl_overlay_rect() and fl_overlay_erase() to xor selection box
+12/02/97: Shortcut keys to scroll browser up/down (finally!)
+
+FL-0.97
+
+11/30/97: Many bugs with overlay + Xdbe windows fixed
+11/30/97: Numeric keypad types numbers even if NumLock off (not portable?)
+11/28/97: Fluid frees unused images
+11/25/97: Added Fl_Object::size_range(...) to control resizing
+11/25/97: Fluid can label objects with xbm, xpm, or gif images!
+11/24/97: FL_DRAG & FL_MOVE set Fl::event_time()
+11/23/97: minimal update for sliders (less blinking of large sliders)
+11/17/97: renamed Fl_Input_::handle to handletext to prevent C++ warnings
+11/17/97: minimal update for Fl_Browser (less blinking)
+11/17/97: ability to set and check edge thickness of box types
+11/16/97: Added Xdbe (double buffer extension) support to Fl_Double_Window
+11/11/97: fixed crash if FL_RELEASE deletes Fl::pushed() object
+11/11/97: ./configure makes a config.h, detects many more things
+11/10/97: can use 32bit visuals with xrgb data layout
+11/10/97: restored code for arbitrary 32 bit visual color masks
+11/10/97: fl_draw_pixmap shares buffer with fl_draw_image
+
+FL-0.96
+
+11/06/97: Uses GNU ./configure script to build
+11/05/97: Made fluid work with Fl_Tabs
+11/03/97: Fl_Browser_ has show_scrollbar() virtual func for subclass
+ to override to change type of scrollbar or force it on
+11/03/97: Fl_Slider::slider(uchar) attribute to set box type for slider
+11/03/97: no limit on how many points are sent to fl_vertex()
+11/03/97: added FL_OVAL_BOX, FL_OFLAT_BOX, FL_OSHADOW_BOX, FL_OVAL_FRAME
+10/29/97: made fluid read fd files from Forms and XForms fdesign (sort of)
+10/28/97: fluid works! I am ready to release it. Needs directions
+10/28/97: renamed Fl_Text to Fl_Output
+10/28/97: added Fl_Text_Adjuster
+10/28/97: fixed double window crash when fl_gc is not set correctly
+10/22/97: made Fl_Text be a subclass of Fl_Input_
+10/16/97: mucho work on fluid! almost there...
+10/15/97: added Fl_Fill_Dial
+10/15/97: changed fl_circle to use XDrawArc
+10/14/97: minimal update of Fl_Input, to reduce blinking
+10/14/97: Removed all uses of fl->, replaced with Fl:: "namespace"
+10/14/97: moved setting of colors, fonts, boxtypes, labeltypes to Fl::
+10/14/97: fixed the gray ramp to really go from black to white
+10/10/97: Cleanup of button and button subclasses
+10/9/97: Changed "style" to "font" for clarity
+10/8/97: Added engraved/embossed/shadow label types
+10/6/97: Added when() to many objects
+10/1/97: Fl_Overlay_Window will use hardware overlay if possible
+10/1/97: Fixed shortcuts for Fl_Choice to do redraw
+9/29/97: Much better fl_draw_image for 8-bit visuals
+9/26/97: Fixed gl_color() when drawing into gl overlay
+9/25/97: Fl_Gl_Window simulates overlay if hardware not provided
+9/22/97: Added FL_ACTIVATE/DEACTIVATE/HIDE/SHOW event types
+9/18/97: Click/shift+click on Fl_Adjuster moves it by increments
+9/18/97: cleanup & simplification of window creation and drawing code
+9/18/97: fl_draw_into(xid), Fl_Window::make_xid(vis) added
+9/18/97: Fixed background pixel support to not try so hard
+
+FL-0.95
+
+8/25/97: Forms file chooser is emulated using libFL file chooser
+8/25/97: Uses background_pixel if possible to speed up box drawing
+8/23/97: XForms .86 compatability added, required many changes
+8/22/97: Added fl_draw_pixmap and Fl_Pixmap (simple version only!)
+8/19/97: The BIG FLIP! Turned coordinate system over so +y is down
+8/08/97: Glut compatability added
+8/06/97: added fl_color(r,g,b) to set rgb color to draw in
+8/05/97: added fl_draw_image for color pictures (!)
+8/03/97: made x.H and put X-specific fl variables in there
+7/27/97: greately improved fl_font_enumerate to return sizes
+7/26/97: Much cleanup, rearrangement of function and header file names
+7/20/97: Added overlay drawing ability to Fl_Gl_Window
+7/17/97: Celebrated Titanic being done! Well, mostly...
+6/25/97: Make -DUSE_X true all the time, GL fl_draw functions removed
+6/10/97: fluid finally produced code that compiles! Still a long
+ ways to go...
+6/8/97: Added fl->add_xevent_handler so your program can get at those
+ XExtension events. Rewrote fl->selection_owner so it uses
+ this, mostly to test it. Added Fl_Implementation.H header
+ to src to clean up public header files.
+6/5/97: Added Fl_Window::show(argc,argv,i) so that standard switches
+ can be passed to the main window in a window-system
+ independent way. Removed xclass() property from Fl_Window,
+ as this replaces it.
+6/5/97: Deferred XMapWindow till fl->flush(), to allow above to work
+4/15/97: needdraw() renamed to damage(), for clarity.
+4/15/97: code rearranged so you don't have to link -lGL if you don't use it
+4/15/97: #ifdef MESA will cause Fl_Gl_Window to take advantage of
+ the fact that the back buffer is unchanged by damage.
+4/18/97: Can use poll() instead of select(). To make your machine
+ use this, see Fl_Poll.H and turn on USE_POLL and turn off USE_SELECT.
+
+FL-0.94
+
+3/26/97: Fl_Browser_ (and Fl_Browser) preserves the position(), even
+ if it is below the data.
+3/26/97: Renamed resizebox() to resizable()
+3/25/97: Made all Fl object instance variables be static.
+3/23/97: Added focus(), belowmouse(), pushed(), and selection_owner()
+ tracking to the Fl object. Since only one object can be this
+ at a time, this gets rid of redundant storage in every object
+ such as the pushed_ field that was on the buttons. Also
+ greatly simplified Fl_Group.
+3/21/97: Added glXReleaseBuffersMESA if #ifdef MESA
+3/7/97: Renamed some source files to avoid name conflicts on MSWindows.
+3/5/97: Fl_Menu returns item selected, caller now does the callback.
+3/5/97: Renamed Fl_Menubar to Fl_Menu_Bar.
+3/5/97: Improvements to how Fl_Input scrolls.
+2/11/97: Installs the window's colormap when the mouse enters window.
+2/5/97: Cleaned up the close and exit behavior. The only way to stop
+ the close box from closing a window is to subclass it and
+ change the response to FL_CLOSE. The callback is done,
+ however, before closing the window. Added exit() and error()
+ methods to Fl class, which you can "override" by defining
+ your own versions in your source code.
+1/24/97: Restored setting of XSizeHints (many window managers ignore
+ the Motif window information).
+
+FL-0.93
+
+1/23/97: Got it to compile and run (with -DNO_GL) on Dec Alpha Unix!
+ Mostly this meant getting rid of trailing commas on enum lists.
+1/20/97: DDForms-compatable resize behavior, where it scales
+ everything inside the resizebox. Also fixed resizing of a
+ group inside a window.
+1/12/97: typing a shift key on some Xlib versions no longer produces
+ a character. Fixed display of characters shown as \xxx.
+1/12/97: Got it to compile and run (with -DNO_GL) on Alpha Linux.
+1/11/97: Fl_Browser now has a topline() attribute that you can get
+ and set, as well as the Fl_Browser_::position() attribute.
+ topline() is in lines, position() is in pixels.
+1/11/97: General code clean up and size reduction.
+1/11/97: Fl_Group::focus(x) fixed to always work
+1/8/97: fl_file_chooser uses the scandir(), much faster!
+1/7/97: Removed setting of XSizeHints
+12/96: More work on fluid
+
+FL-0.92
+
+10/31/96: New fl->wait() and fl->check() handling so that flip
+ book program would work.
+10/20/96: Removed calls to glFlush when not in a glx context. This
+ bug caused Mesa 2.0 to crash. Fixing it required extensive
+ rewriting of the Fl_Window base classes and virtual functions.
+10/../96: Lots of work done on writing fluid
+10/09/96: Added the Fl_Input_ base class.
+09/25/96: All constructors of the form Fl_x(x,y,w,h,label=0).
+09/16/96: More changes to Fl_Input, fixed the scrolling behavior,
+ made it not crash if you paste huge amounts of text in.
+09/11/96: Fixed minimal update when you resize a subwindow.
+09/10/96: Constructor no longer does add().
+09/07/96: FL_SHORTCUT is sent mouse window rather than focus window
+09/07/96: Added ^Z=undo, ^X=cut, ^C=copy ^V=paste to Fl_Input, and
+ made double-click select words and triple-click select lines.
+08/23/96: Tries to send maximum size in XSizeHints
+
+FL-0.91
+
+08/21/96: fluid uses Fl_Overlay_Window
+08/20/96: Added Fl_Overlay_Window
+08/19/96: Added Fl_Double_Window to provide double buffering
+08/19/96: Documentation for subclassing windows
+08/15/96: Fixed bugs with overriding resize() on Fl_Window
+08/15/96: Erases menus before unmap, to fix colormap flash on O2
+08/14/96: Replaced <strings.h> with <string.h>
+08/14/96: Added makeinclude.svr4 (tested on a "SINEX-Z" os)
+08/14/96: Added scandir.c from the GNU C library for SVR4
+08/13/96: makefiles have LIBNAME, VERSION, and REVISION switches
+08/13/96: added (completely untested!) makeinclude.linux.so to make
+ a shared library. I recommend however that if you are making
+ programs for any kind of distribution that you use the static
+ version of the library, rather than relying on users correctly
+ installing the shared one!
+08/13/96: fixed *many* occurances of wrong scoping of for(int x;;)
+08/13/96: patched out warning messages for enumerations from gcc.
+08/13/96: fixed crash for fixed-pitch XFonts (per_char ptr is NULL)
+08/13/96: some fixes to Fl_Chart so output matches Forms.
+08/13/96: Insure radio button not pressed if mouse released outside it
+08/13/96: Clicking in the value box of a Value_Slider does not move slider.
+08/13/96: Added switches so arrows can't navigate between text fields
+08/13/96: Initializes some stuff it should have in Fl_Menu_Button.
+08/13/96: Non-multiline Fl_Inputs do not treat ^J characters as
+ special, for instance ^K always deletes to the end even if
+ there are imbedded newlines.
+08/13/96: Tab inserts a tab in Fl_MultiLine_Input. Use Ctrl+Tab to navigate
+08/10/96: renamed from libFL to libFl to avoid existing SGI library
+08/10/96: the static Fl_Object method readqueue has been moved to
+ a method on the Fl object.
+08/10/96: the static Fl_Object method draw_box() renamed fl_box() and
+ put in Draw.H
+08/10/96: fl_label_bitmap has been renamed fl_draw and put in Draw.H
+08/10/96: fixed the deactivated menu items to not draw over the right edge.
+08/09/96: fl_clip works in both X and GL windows when USE_X is defined.
+08/09/96: the static Fl_Object methods event_inside and test_shortcut
+ have been moved to methods on the Fl object.
+ The static Fl_Object method shortcut_text has been renamed
+ to a function fl_shortcut_text and put in the Draw.H header.
+08/09/96: many internal changes to Fl_Group and Fl_Window to support
+ minimal update. expose() is no longer a virtual function and
+ is private to Fl_Window. Fl_Object::flush() and qredraw()
+ deleted. New methods: draw_child(), redraw_child(), and
+ done_drawing(), for calling by draw() implementations.
+ See (not yet written) drawing documentation.
+08/05/96: to make it possible to do minimal update, Fl_Group must draw
+ everything outside of the object's bounding box. So draw_label()
+ changed to only draw FL_INSIDE or FL_CENTER alignements. New
+ method draw_outside_label() added to be called by Fl_Group
+ to draw the other labels. This simplified Fl_Slider and
+ Fl_LightButton some, too.
diff --git a/fluid/Fl_Function_Type.cxx b/fluid/Fl_Function_Type.cxx
new file mode 100644
index 000000000..21bdb5b37
--- /dev/null
+++ b/fluid/Fl_Function_Type.cxx
@@ -0,0 +1,669 @@
+/* Fl_Function_Type_Type.C
+
+ Type describing a C function output by Fluid.
+
+*/
+
+#include <FL/Fl.H>
+#include "Fl_Type.H"
+#include <FL/fl_show_input.H>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+////////////////////////////////////////////////////////////////
+// quick check of any C code for legality, returns an error message
+// these currently require comments to parse correctly!
+
+static char buffer[128]; // for error messages
+
+// check a quoted string ending in either " or ' or >:
+const char *_q_check(const char * & c, int type) {
+ for (;;) switch (*c++) {
+ case '\0':
+ sprintf(buffer,"missing %c",type);
+ return buffer;
+ case '\\':
+ if (*c) c++;
+ break;
+ default:
+ if (*(c-1) == type) return 0;
+ }
+}
+
+// check normal code, match braces and parenthesis:
+const char *_c_check(const char * & c, int type) {
+ const char *d;
+ for (;;) switch (*c++) {
+ case 0:
+ if (!type) return 0;
+ sprintf(buffer, "missing %c", type);
+ return buffer;
+ case '{':
+ if (type==')') goto UNEXPECTED;
+ d = _c_check(c,'}'); if (d) return d; break;
+ case '(':
+ d = _c_check(c,')'); if (d) return d; break;
+ case '\"':
+ d = _q_check(c,'\"'); if (d) return d; break;
+ case '\'':
+ d = _q_check(c,'\''); if (d) return d; break;
+ case '}':
+ case ')':
+ case '#':
+ UNEXPECTED:
+ if (type == *(c-1)) return 0;
+ sprintf(buffer, "unexpected %c", *(c-1));
+ return buffer;
+ }
+}
+
+const char *c_check(const char *c, int type) {
+ return _c_check(c,type);
+}
+
+////////////////////////////////////////////////////////////////
+
+class Fl_Function_Type : public Fl_Type {
+ const char* return_type;
+ char public_, constructor, havewidgets;
+public:
+ Fl_Type *make();
+ void write_declare();
+ void write_code1();
+ void write_code2();
+ void open();
+ int ismain() {return name_ == 0;}
+ virtual const char *type_name() {return "Function";}
+ virtual const char *title() {
+ return name() ? name() : "main()";
+ }
+ int is_parent() const {return 1;}
+ int is_code_block() const {return 1;}
+ void write_properties();
+ void read_property(const char *);
+};
+
+Fl_Type *Fl_Function_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_decl_block()) p = p->parent;
+ Fl_Function_Type *o = new Fl_Function_Type();
+ o->name("make_window()");
+ o->return_type = 0;
+ o->add(p);
+ o->factory = this;
+ o->public_ = 1;
+ return o;
+}
+
+void Fl_Function_Type::write_properties() {
+ Fl_Type::write_properties();
+ if (!public_) write_string("private");
+ if (return_type) {
+ write_string("return_type");
+ write_word(return_type);
+ }
+}
+
+void Fl_Function_Type::read_property(const char *c) {
+ if (!strcmp(c,"private")) {
+ public_ = 0;
+ } else if (!strcmp(c,"return_type")) {
+ storestring(read_word(),return_type);
+ } else {
+ Fl_Type::read_property(c);
+ }
+}
+
+#include "function_panel.H"
+#include <FL/fl_ask.H>
+
+void Fl_Function_Type::open() {
+ if (!function_panel) make_function_panel();
+ f_return_type_input->static_value(return_type);
+ f_name_input->static_value(name());
+ f_public_button->value(public_);
+ function_panel->show();
+ const char* message = 0;
+ for (;;) { // repeat as long as there are errors
+ if (message) fl_alert(message);
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == f_panel_cancel) goto BREAK2;
+ else if (w == f_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+ const char*c = f_name_input->value();
+ while (isspace(*c)) c++;
+ message = c_check(c); if (message) continue;
+ const char *d = c;
+ for (; *d != '('; d++) if (isspace(*d) || !*d) break;
+ if (*c && *d != '(') {
+ message = "must be name(arguments), try again:"; continue;
+ }
+ c = f_return_type_input->value();
+ message = c_check(c); if (message) continue;
+ name(f_name_input->value());
+ storestring(c, return_type);
+ public_ = f_public_button->value();
+ break;
+ }
+ BREAK2:
+ function_panel->hide();
+}
+
+Fl_Function_Type Fl_Function_type;
+
+void Fl_Function_Type::write_declare() {
+ ::write_declare("#include <FL/Fl.H>");
+}
+
+extern const char* subclassname(Fl_Type*);
+
+void Fl_Function_Type::write_code1() {
+ constructor=0;
+ havewidgets = 0;
+ Fl_Type *child;
+ const char* widget_type = 0;
+ for (child = next; child && child->level > level; child = child->next)
+ if (child->is_widget()) {
+ havewidgets = 1;
+ widget_type = subclassname(child);
+ break;
+ }
+ write_c("\n");
+ if (ismain())
+ write_c("int main(int argc, char **argv) {\n");
+ else {
+ const char* t = return_type;
+ const char* star = "";
+ if (!t) {
+ if (havewidgets) {t = widget_type; star = "*";}
+ else t = "void";
+ }
+ const char* k = class_name();
+ if (k) {
+ write_public(public_);
+ if (name()[0] == '~')
+ constructor = 1;
+ else {
+ size_t n; for (n=0; name()[n] && name()[n]!='('; n++);
+ if (n == strlen(k) && !strncmp(name(), k, n)) constructor = 1;
+ }
+ write_h(" ");
+ if (!constructor) {write_h("%s%s ", t, star); write_c("%s%s ", t,star);}
+ write_h("%s;\n", name());
+ write_c("%s::%s {\n", k, name());
+ } else {
+ if (public_) write_h("%s%s %s;\n", t, star, name());
+ else write_c("static ");
+ write_c("%s%s %s {\n", t, star, name());
+ }
+ }
+ if (havewidgets) write_c(" %s* w;\n", widget_type);
+ indentation += 2;
+}
+
+void Fl_Function_Type::write_code2() {
+ if (ismain()) {
+ if (havewidgets) write_c(" w->show(argc, argv);\n");
+ write_c(" return Fl::run();\n");
+ } else if (havewidgets && !constructor)
+ write_c(" return w;\n");
+ write_c("}\n");
+ indentation = 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+class Fl_Code_Type : public Fl_Type {
+public:
+ Fl_Type *make();
+ void write_declare();
+ void write_code1();
+ void write_code2();
+ void open();
+ virtual const char *type_name() {return "code";}
+ int is_code_block() const {return 0;}
+};
+
+Fl_Type *Fl_Code_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_code_block()) p = p->parent;
+ if (!p) {
+ fl_message("Please select a function");
+ return 0;
+ }
+ Fl_Code_Type *o = new Fl_Code_Type();
+ o->name("printf(\"Hello, World!\\n\");");
+ o->add(p);
+ o->factory = this;
+ return o;
+}
+
+void Fl_Code_Type::open() {
+ if (!code_panel) make_code_panel();
+ code_input->static_value(name());
+ code_panel->show();
+ const char* message = 0;
+ for (;;) { // repeat as long as there are errors
+ if (message) fl_alert(message);
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == code_panel_cancel) goto BREAK2;
+ else if (w == code_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+ const char*c = code_input->value();
+ message = c_check(c); if (message) continue;
+ name(c);
+ break;
+ }
+ BREAK2:
+ code_panel->hide();
+}
+
+Fl_Code_Type Fl_Code_type;
+
+void Fl_Code_Type::write_declare() {}
+
+void Fl_Code_Type::write_code1() {
+ const char* c = name();
+ if (!c) return;
+ write_c("%s%s\n", indent(), c);
+}
+
+void Fl_Code_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+
+class Fl_CodeBlock_Type : public Fl_Type {
+ const char* after;
+public:
+ Fl_Type *make();
+ void write_declare();
+ void write_code1();
+ void write_code2();
+ void open();
+ virtual const char *type_name() {return "codeblock";}
+ int is_code_block() const {return 1;}
+ int is_parent() const {return 1;}
+ void write_properties();
+ void read_property(const char *);
+};
+
+Fl_Type *Fl_CodeBlock_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_code_block()) p = p->parent;
+ if (!p) {
+ fl_message("Please select a function");
+ return 0;
+ }
+ Fl_CodeBlock_Type *o = new Fl_CodeBlock_Type();
+ o->name("if (test())");
+ o->after = 0;
+ o->add(p);
+ o->factory = this;
+ return o;
+}
+
+void Fl_CodeBlock_Type::write_properties() {
+ Fl_Type::write_properties();
+ if (after) {
+ write_string("after");
+ write_word(after);
+ }
+}
+
+void Fl_CodeBlock_Type::read_property(const char *c) {
+ if (!strcmp(c,"after")) {
+ storestring(read_word(),after);
+ } else {
+ Fl_Type::read_property(c);
+ }
+}
+
+void Fl_CodeBlock_Type::open() {
+ if (!codeblock_panel) make_codeblock_panel();
+ code_before_input->static_value(name());
+ code_after_input->static_value(after);
+ codeblock_panel->show();
+ const char* message = 0;
+ for (;;) { // repeat as long as there are errors
+ if (message) fl_alert(message);
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == codeblock_panel_cancel) goto BREAK2;
+ else if (w == codeblock_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+ const char*c = code_before_input->value();
+ message = c_check(c); if (message) continue;
+ name(c);
+ c = code_after_input->value();
+ message = c_check(c); if (message) continue;
+ storestring(c, after);
+ break;
+ }
+ BREAK2:
+ codeblock_panel->hide();
+}
+
+Fl_CodeBlock_Type Fl_CodeBlock_type;
+
+void Fl_CodeBlock_Type::write_declare() {}
+
+void Fl_CodeBlock_Type::write_code1() {
+ const char* c = name();
+ write_c("%s%s {\n", indent(), c ? c : "");
+ indentation += 2;
+}
+
+void Fl_CodeBlock_Type::write_code2() {
+ indentation += 2;
+ if (after) write_c("%s} %s\n", indent(), after);
+ else write_c("%s}\n", indent());
+}
+
+////////////////////////////////////////////////////////////////
+
+class Fl_Decl_Type : public Fl_Type {
+ char public_;
+public:
+ Fl_Type *make();
+ void write_declare();
+ void write_code1();
+ void write_code2();
+ void open();
+ virtual const char *type_name() {return "decl";}
+ void write_properties();
+ void read_property(const char *);
+};
+
+Fl_Type *Fl_Decl_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_decl_block()) p = p->parent;
+ Fl_Decl_Type *o = new Fl_Decl_Type();
+ o->public_ = 0;
+ o->name("int x;");
+ o->add(p);
+ o->factory = this;
+ return o;
+}
+
+void Fl_Decl_Type::write_properties() {
+ Fl_Type::write_properties();
+ if (public_) write_string("public");
+}
+
+void Fl_Decl_Type::read_property(const char *c) {
+ if (!strcmp(c,"public")) {
+ public_ = 1;
+ } else {
+ Fl_Type::read_property(c);
+ }
+}
+
+void Fl_Decl_Type::open() {
+ if (!decl_panel) make_decl_panel();
+ decl_input->static_value(name());
+ decl_public_button->value(public_);
+ decl_panel->show();
+ const char* message = 0;
+ for (;;) { // repeat as long as there are errors
+ if (message) fl_alert(message);
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == decl_panel_cancel) goto BREAK2;
+ else if (w == decl_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+ const char*c = decl_input->value();
+ while (isspace(*c)) c++;
+ message = c_check(c&&c[0]=='#' ? c+1 : c);
+ if (message) continue;
+ name(c);
+ public_ = decl_public_button->value();
+ break;
+ }
+ BREAK2:
+ decl_panel->hide();
+}
+
+Fl_Decl_Type Fl_Decl_type;
+
+void Fl_Decl_Type::write_declare() {}
+
+void Fl_Decl_Type::write_code1() {
+ const char* c = name();
+ if (!c) return;
+ // handle putting #include or extern into decl:
+ if (!isalpha(*c) || !strncmp(c,"extern",6)) {
+ if (public_)
+ write_h("%s\n", c);
+ else
+ write_c("%s\n", c);
+ return;
+ }
+ // lose all trailing semicolons so I can add one:
+ const char* e = c+strlen(c);
+ while (e>c && e[-1]==';') e--;
+ if (class_name()) {
+ write_public(public_);
+ write_h(" %.*s;\n", e-c, c);
+ } else {
+ if (public_) {
+ write_h("extern %.*s;\n", e-c, c);
+ write_c("%.*s;\n", e-c, c);
+ } else {
+ write_c("static %.*s;\n", e-c, c);
+ }
+ }
+}
+
+void Fl_Decl_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+
+class Fl_DeclBlock_Type : public Fl_Type {
+ const char* after;
+public:
+ Fl_Type *make();
+ void write_declare();
+ void write_code1();
+ void write_code2();
+ void open();
+ virtual const char *type_name() {return "declblock";}
+ void write_properties();
+ void read_property(const char *);
+ int is_parent() const {return 1;}
+ int is_decl_block() const {return 1;}
+};
+
+Fl_Type *Fl_DeclBlock_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_decl_block()) p = p->parent;
+ Fl_DeclBlock_Type *o = new Fl_DeclBlock_Type();
+ o->name("#if 1");
+ o->after = strdup("#endif");
+ o->add(p);
+ o->factory = this;
+ return o;
+}
+
+void Fl_DeclBlock_Type::write_properties() {
+ Fl_Type::write_properties();
+ write_string("after");
+ write_word(after);
+}
+
+void Fl_DeclBlock_Type::read_property(const char *c) {
+ if (!strcmp(c,"after")) {
+ storestring(read_word(),after);
+ } else {
+ Fl_Type::read_property(c);
+ }
+}
+
+void Fl_DeclBlock_Type::open() {
+ if (!declblock_panel) make_declblock_panel();
+ decl_before_input->static_value(name());
+ decl_after_input->static_value(after);
+ declblock_panel->show();
+ const char* message = 0;
+ for (;;) { // repeat as long as there are errors
+ if (message) fl_alert(message);
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == declblock_panel_cancel) goto BREAK2;
+ else if (w == declblock_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+ const char*c = decl_before_input->value();
+ while (isspace(*c)) c++;
+ message = c_check(c&&c[0]=='#' ? c+1 : c);
+ if (message) continue;
+ name(c);
+ c = decl_after_input->value();
+ while (isspace(*c)) c++;
+ message = c_check(c&&c[0]=='#' ? c+1 : c);
+ if (message) continue;
+ storestring(c,after);
+ break;
+ }
+ BREAK2:
+ declblock_panel->hide();
+}
+
+Fl_DeclBlock_Type Fl_DeclBlock_type;
+
+void Fl_DeclBlock_Type::write_declare() {}
+
+void Fl_DeclBlock_Type::write_code1() {
+ const char* c = name();
+ if (c) write_c("%s\n", c);
+}
+
+void Fl_DeclBlock_Type::write_code2() {
+ const char* c = after;
+ if (c) write_c("%s\n", c);
+}
+
+////////////////////////////////////////////////////////////////
+
+class Fl_Class_Type : public Fl_Type {
+ const char* subclass_of;
+ char public_;
+public:
+ // state variables for output:
+ char write_public_state; // true when public: has been printed
+ Fl_Class_Type* parent_class; // save class if nested
+//
+ Fl_Type *make();
+ void write_declare();
+ void write_code1();
+ void write_code2();
+ void open();
+ virtual const char *type_name() {return "class";}
+ int is_parent() const {return 1;}
+ int is_decl_block() const {return 1;}
+ int is_class() const {return 1;}
+ void write_properties();
+ void read_property(const char *);
+};
+
+const char* Fl_Type::class_name() const {
+ Fl_Type* p = parent;
+ while (p) {if (p->is_class()) return p->name(); p = p->parent;}
+ return 0;
+}
+
+Fl_Type *Fl_Class_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_decl_block()) p = p->parent;
+ Fl_Class_Type *o = new Fl_Class_Type();
+ o->name("UserInterface");
+ o->subclass_of = 0;
+ o->public_ = 1;
+ o->add(p);
+ o->factory = this;
+ return o;
+}
+
+void Fl_Class_Type::write_properties() {
+ Fl_Type::write_properties();
+ if (subclass_of) {
+ write_string(":");
+ write_word(subclass_of);
+ }
+ if (!public_) write_string("private");
+}
+
+void Fl_Class_Type::read_property(const char *c) {
+ if (!strcmp(c,"private")) {
+ public_ = 0;
+ } else if (!strcmp(c,":")) {
+ storestring(read_word(), subclass_of);
+ } else {
+ Fl_Type::read_property(c);
+ }
+}
+
+void Fl_Class_Type::open() {
+ if (!class_panel) make_class_panel();
+ c_name_input->static_value(name());
+ c_subclass_input->static_value(subclass_of);
+ c_public_button->value(public_);
+ class_panel->show();
+ const char* message = 0;
+ for (;;) { // repeat as long as there are errors
+ if (message) fl_alert(message);
+ for (;;) {
+ Fl_Widget* w = Fl::readqueue();
+ if (w == c_panel_cancel) goto BREAK2;
+ else if (w == c_panel_ok) break;
+ else if (!w) Fl::wait();
+ }
+ const char*c = c_name_input->value();
+ while (isspace(*c)) c++;
+ if (!*c) goto OOPS;
+ while (is_id(*c)) c++;
+ while (isspace(*c)) c++;
+ if (*c) {OOPS: message = "class name must be C++ identifier"; continue;}
+ c = c_subclass_input->value();
+ message = c_check(c); if (message) continue;
+ name(c_name_input->value());
+ storestring(c, subclass_of);
+ public_ = c_public_button->value();
+ break;
+ }
+ BREAK2:
+ class_panel->hide();
+}
+
+Fl_Class_Type Fl_Class_type;
+
+void Fl_Class_Type::write_declare() {}
+
+static Fl_Class_Type *current_class;
+extern int varused_test;
+void write_public(int state) {
+ if (!current_class || varused_test) return;
+ if (current_class->write_public_state == state) return;
+ current_class->write_public_state = state;
+ write_h(state ? "public:\n" : "private:\n");
+}
+
+void Fl_Class_Type::write_code1() {
+ parent_class = current_class;
+ current_class = this;
+ write_public_state = 0;
+ write_h("\nclass %s ", name());
+ if (subclass_of) write_h(": %s ", subclass_of);
+ write_h("{\n");
+}
+
+void Fl_Class_Type::write_code2() {
+ write_h("};\n");
+ current_class = parent_class;
+}
diff --git a/fluid/Fl_Group_Type.cxx b/fluid/Fl_Group_Type.cxx
new file mode 100644
index 000000000..0e499339d
--- /dev/null
+++ b/fluid/Fl_Group_Type.cxx
@@ -0,0 +1,245 @@
+// Fl_Group_Type.C
+
+// Object describing an Fl_Group
+// Probably also links to Fl_Window_Type.C
+
+// Also the Fl_Tabs widget, with special stuff to select tab items
+// and insure that only one is visible.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/fl_message.H>
+#include "Fl_Widget_Type.H"
+
+class igroup : public Fl_Group {
+public:
+ void resize(int,int,int,int);
+ igroup(int x,int y,int w,int h) : Fl_Group(x,y,w,h) {Fl_Group::current(0);}
+};
+// Override group's resize behavior to do nothing to children:
+void igroup::resize(int X, int Y, int W, int H) {
+ Fl_Widget::resize(X,Y,W,H);
+ redraw();
+}
+
+class Fl_Group_Type : public Fl_Widget_Type {
+public:
+ virtual const char *type_name() {return "Fl_Group";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ igroup *g = new igroup(x,y,w,h); Fl_Group::current(0); return g;}
+ Fl_Widget_Type *_make() {return new Fl_Group_Type();}
+ Fl_Type *make();
+ void write_code1();
+ void write_code2();
+ void add_child(Fl_Type*, Fl_Type*);
+ void move_child(Fl_Type*, Fl_Type*);
+ void remove_child(Fl_Type*);
+ int is_parent() const {return 1;}
+ int is_group() const {return 1;}
+};
+Fl_Group_Type Fl_Group_type; // the "factory"
+
+Fl_Type *Fl_Group_Type::make() {
+ return Fl_Widget_Type::make();
+}
+
+void fix_group_size(Fl_Type *tt) {
+ if (!tt || !tt->is_group()) return;
+ Fl_Group_Type* t = (Fl_Group_Type*)tt;
+ int X = t->o->x();
+ int Y = t->o->y();
+ int R = X+t->o->w();
+ int B = Y+t->o->h();
+ for (Fl_Type *nn = t->next; nn && nn->level > t->level; nn = nn->next) {
+ if (!nn->is_widget() || nn->is_menu_item()) continue;
+ Fl_Widget_Type* n = (Fl_Widget_Type*)nn;
+ int x = n->o->x(); if (x < X) X = x;
+ int y = n->o->y(); if (y < Y) Y = y;
+ int r = x+n->o->w();if (r > R) R = r;
+ int b = y+n->o->h();if (b > B) B = b;
+ }
+ t->o->resize(X,Y,R-X,B-Y);
+}
+
+extern int force_parent;
+
+void group_cb(Fl_Widget *, void *) {
+ // Find the current widget:
+ Fl_Type *qq = Fl_Type::current;
+ while (qq && (!qq->is_widget() || qq->is_menu_item())) qq = qq->parent;
+ if (!qq || qq->level <= 1) {
+ fl_message("Please select widgets to group");
+ return;
+ }
+ Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
+ force_parent = 1;
+ Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make());
+ n->move_before(q);
+ n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h());
+ for (Fl_Type *t = Fl_Type::first; t;) {
+ if (t->level != n->level || t == n || !t->selected) {
+ t = t->next; continue;}
+ Fl_Type *nxt = t->remove();
+ t->add(n);
+ t = nxt;
+ }
+ fix_group_size(n);
+}
+
+void ungroup_cb(Fl_Widget *, void *) {
+ // Find the group:
+ Fl_Type *q = Fl_Type::current;
+ while (q && (!q->is_widget() || q->is_menu_item())) q = q->parent;
+ if (q) q = q->parent;
+ if (!q || q->level <= 1) {
+ fl_message("Please select widgets in a group");
+ return;
+ }
+ Fl_Type* n;
+ for (n = q->next; n && n->level > q->level; n = n->next) {
+ if (n->level == q->level+1 && !n->selected) {
+ fl_message("Please select all widgets in group");
+ return;
+ }
+ }
+ for (n = q->next; n && n->level > q->level;) {
+ Fl_Type *nxt = n->remove();
+ n->insert(q);
+ n = nxt;
+ }
+ delete q;
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+
+void Fl_Group_Type::write_code1() {
+ Fl_Widget_Type::write_code1();
+}
+
+void Fl_Group_Type::write_code2() {
+ write_c("%so->end();\n", indent());
+ if (resizable()) write_c("%sFl_Group::current()->resizable(o);\n", indent());
+ Fl_Widget_Type::write_code2();
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Tabs.H>
+
+class itabs : public Fl_Tabs {
+public:
+ void resize(int,int,int,int);
+ itabs(int x,int y,int w,int h) : Fl_Tabs(x,y,w,h) {}
+};
+// Override group's resize behavior to do nothing to children:
+void itabs::resize(int X, int Y, int W, int H) {
+ Fl_Widget::resize(X,Y,W,H);
+ redraw();
+}
+
+static const char tabs_type_name[] = "Fl_Tabs";
+
+class Fl_Tabs_Type : public Fl_Group_Type {
+public:
+ virtual const char *type_name() {return tabs_type_name;}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ itabs *g = new itabs(x,y,w,h); Fl_Group::current(0); return g;}
+ Fl_Widget_Type *_make() {return new Fl_Tabs_Type();}
+ Fl_Type* click_test(int,int);
+ void add_child(Fl_Type*, Fl_Type*);
+ void remove_child(Fl_Type*);
+};
+Fl_Tabs_Type Fl_Tabs_type; // the "factory"
+
+// This is called when user clicks on a widget in the window. See
+// if it is a tab title, and adjust visibility and return new selection:
+// If none, return o unchanged:
+
+Fl_Type* Fl_Tabs_Type::click_test(int x, int y) {
+ Fl_Tabs *t = (Fl_Tabs*)o;
+ Fl_Widget *a = t->which(x,y);
+ if (!a) return 0; // didn't click on tab
+ // okay, run the tabs ui until they let go of mouse:
+ t->handle(FL_PUSH);
+ Fl::pushed(t);
+ while (Fl::pushed()==t) Fl::wait();
+ return (Fl_Type*)(t->value()->user_data());
+}
+
+// This is called when o is created. If it is in the tab group make
+// sure it is visible:
+
+void Fl_Group_Type::add_child(Fl_Type* cc, Fl_Type* before) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+ ((Fl_Group*)o)->insert(*(c->o), b);
+ o->redraw();
+}
+
+void Fl_Tabs_Type::add_child(Fl_Type* c, Fl_Type* before) {
+ Fl_Group_Type::add_child(c, before);
+ ((Fl_Tabs*)o)->value(0);
+}
+
+// This is called when o is deleted. If it is in the tab group make
+// sure it is not visible:
+
+void Fl_Group_Type::remove_child(Fl_Type* cc) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ ((Fl_Group*)o)->remove(c->o);
+ o->redraw();
+}
+
+void Fl_Tabs_Type::remove_child(Fl_Type* cc) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ Fl_Tabs *t = (Fl_Tabs*)o;
+ if (t->value() == c->o) t->value(0);
+ Fl_Group_Type::remove_child(c);
+}
+
+// move, don't change selected value:
+
+void Fl_Group_Type::move_child(Fl_Type* cc, Fl_Type* before) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+ ((Fl_Group*)o)->remove(c->o);
+ ((Fl_Group*)o)->insert(*(c->o), b);
+ o->redraw();
+}
+
+////////////////////////////////////////////////////////////////
+// some other group subclasses that fluid does not treat specially:
+
+#include <FL/Fl_Scroll.H>
+
+static const char scroll_type_name[] = "Fl_Scroll";
+
+static Fl_Menu_Item scroll_type_menu[] = {
+ {"BOTH", 0, 0, 0/*(void*)Fl_Scroll::BOTH*/},
+ {"HORIZONTAL", 0, 0, (void*)Fl_Scroll::HORIZONTAL},
+ {"VERTICAL", 0, 0, (void*)Fl_Scroll::VERTICAL},
+ {"HORIZONTAL_ALWAYS", 0, 0, (void*)Fl_Scroll::HORIZONTAL_ALWAYS},
+ {"VERTICAL_ALWAYS", 0, 0, (void*)Fl_Scroll::VERTICAL_ALWAYS},
+ {"BOTH_ALWAYS", 0, 0, (void*)Fl_Scroll::BOTH_ALWAYS},
+ {0}};
+
+class Fl_Scroll_Type : public Fl_Group_Type {
+ Fl_Menu_Item *subtypes() {return scroll_type_menu;}
+public:
+ virtual const char *type_name() {return scroll_type_name;}
+ Fl_Widget_Type *_make() {return new Fl_Scroll_Type();}
+};
+Fl_Scroll_Type Fl_Scroll_type; // the "factory"
+
+////////////////////////////////////////////////////////////////
+
+static const char tile_type_name[] = "Fl_Tile";
+
+class Fl_Tile_Type : public Fl_Group_Type {
+public:
+ virtual const char *type_name() {return tile_type_name;}
+ Fl_Widget_Type *_make() {return new Fl_Tile_Type();}
+};
+Fl_Tile_Type Fl_Tile_type; // the "factory"
diff --git a/fluid/Fl_Menu_Type.cxx b/fluid/Fl_Menu_Type.cxx
new file mode 100644
index 000000000..02318602c
--- /dev/null
+++ b/fluid/Fl_Menu_Type.cxx
@@ -0,0 +1,487 @@
+// Fl_Menu_Type.C
+
+// Menu items are kludged by making a phony Fl_Box widget so the normal
+// widget panel can be used to control them.
+
+// This file also contains code to make Fl_Menu_Button, Fl_Menu_Bar,
+// etc widgets.
+
+#include <FL/Fl.H>
+#include "Fl_Widget_Type.H"
+#include <FL/fl_message.H>
+#include <FL/Fl_Menu_.H>
+#include <FL/Fl_Button.H>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static Fl_Menu_Item menu_item_type_menu[] = {
+ {"Normal",0,0,(void*)0},
+ {"Toggle",0,0,(void*)FL_MENU_BOX},
+ {"Radio",0,0,(void*)FL_MENU_RADIO},
+ {0}};
+
+class Fl_Menu_Item_Type : public Fl_Widget_Type {
+public:
+ Fl_Menu_Item* subtypes() {return menu_item_type_menu;}
+ const char* type_name() {return "menuitem";}
+ Fl_Type* make();
+ int is_menu_item() const {return 1;}
+ int is_button() const {return 1;} // this gets shortcut to work
+ Fl_Widget* widget(int,int,int,int) {return 0;}
+ Fl_Widget_Type* _make() {return 0;}
+ void write_declare();
+ const char* menu_name(int& i);
+ int flags();
+ void write_static();
+ void write_item();
+ void write_code1();
+ void write_code2();
+};
+
+class Fl_Submenu_Type : public Fl_Menu_Item_Type {
+public:
+ Fl_Menu_Item* subtypes() {return 0;}
+ const char* type_name() {return "submenu";}
+ int is_parent() const {return 1;}
+ int is_button() const {return 0;} // disable shortcut
+ Fl_Type* make();
+ // changes to submenu must propagate up so build_menu is called
+ // on the parent Fl_Menu_Type:
+ void add_child(Fl_Type*a, Fl_Type*b) {parent->add_child(a,b);}
+ void move_child(Fl_Type*a, Fl_Type*b) {parent->move_child(a,b);}
+ void remove_child(Fl_Type*a) {parent->remove_child(a);}
+};
+
+extern int reading_file;
+extern int force_parent;
+
+static char submenuflag;
+
+Fl_Type *Fl_Menu_Item_Type::make() {
+ // Find the current menu item:
+ Fl_Type* q = Fl_Type::current;
+ Fl_Type* p = q;
+ if (p) {
+ if (force_parent && q->is_menu_item() || !q->is_parent()) p = p->parent;
+ }
+ force_parent = 0;
+ if (!p || !(p->is_menu_button() || p->is_menu_item() && p->is_parent())) {
+ fl_message("Please select a menu to add to");
+ return 0;
+ }
+ if (!o) {
+ o = new Fl_Button(0,0,100,20); // create template widget
+ }
+
+ Fl_Menu_Item_Type* t = submenuflag ? new Fl_Submenu_Type() : new Fl_Menu_Item_Type();
+ t->o = new Fl_Button(0,0,100,20);
+ t->factory = this;
+ t->add(p);
+ if (!reading_file) t->label(submenuflag ? "submenu" : "item");
+ return t;
+}
+
+Fl_Type *Fl_Submenu_Type::make() {
+ submenuflag = 1;
+ Fl_Type* t = Fl_Menu_Item_Type::make();
+ submenuflag = 0;
+ return t;
+}
+
+Fl_Menu_Item_Type Fl_Menu_Item_type;
+Fl_Submenu_Type Fl_Submenu_type;
+
+////////////////////////////////////////////////////////////////
+// Writing the C code:
+
+#include <ctype.h>
+
+// test functions in Fl_Widget_Type.C:
+int is_name(const char *c);
+const char *array_name(Fl_Widget_Type *o);
+int isdeclare(const char *c);
+
+void Fl_Menu_Item_Type::write_declare() {
+ if (callback() && is_name(callback()))
+ ::write_declare("extern void %s(Fl_Menu_*, %s);", callback(),
+ user_data_type() ? user_data_type() : "void*");
+ for (int n=0; n < NUM_EXTRA_CODE; n++) {
+ if (extra_code(n) && isdeclare(extra_code(n)))
+ ::write_declare("%s", extra_code(n));
+ }
+}
+
+const char* Fl_Menu_Item_Type::menu_name(int& i) {
+ i = 0;
+ Fl_Type* t = prev;
+ while (t && t->is_menu_item()) {
+ // be sure to count the {0} that ends a submenu:
+ if (t->level > t->next->level ||
+ // detect empty submenu:
+ t->level==t->next->level &&t->is_parent())
+ i++;
+ t = t->prev; i++;
+ }
+ return unique_id(t, "menu", t->name(), t->label());
+}
+
+#include "Fluid_Image.H"
+
+void Fl_Menu_Item_Type::write_static() {
+ if (callback() && !is_name(callback())) {
+ // see if 'o' or 'v' used, to prevent unused argument warnings:
+ int use_o = 0;
+ int use_v = 0;
+ const char *d;
+ for (d = callback(); *d;) {
+ if (*d == 'o' && !is_id(d[1])) use_o = 1;
+ if (*d == 'v' && !is_id(d[1])) use_v = 1;
+ do d++; while (is_id(*d));
+ while (*d && !is_id(*d)) d++;
+ }
+ const char* cn = callback_name();
+ const char* k = class_name();
+ if (k) {
+ write_c("\ninline void %s::%s_i(Fl_Menu_*", k, cn);
+ } else {
+ write_c("\nstatic void %s(Fl_Menu_*", cn);
+ }
+ if (use_o) write_c(" o");
+ const char* ut = user_data_type() ? user_data_type() : "void*";
+ write_c(", %s", ut);
+ if (use_v) write_c(" v");
+ write_c(") {\n %s", callback());
+ if (*(d-1) != ';') write_c(";");
+ write_c("\n}\n");
+ if (k) {
+ write_c("void %s::%s(Fl_Menu_* o, %s v) {\n", k, cn, ut);
+ write_c(" ((%s*)(o->", k);
+ Fl_Type* t = parent; while (t->is_menu_item()) t = t->parent;
+ for (t = t->parent; t->is_widget(); t = t->parent) write_c("parent()->");
+ write_c("user_data()))->%s_i(o,v);\n}\n", cn);
+ }
+ }
+ if (image) {
+ if (image->written != write_number) {
+ image->write_static();
+ image->written = write_number;
+ }
+ }
+ if (next && next->is_menu_item()) return;
+ // okay, when we hit last item in the menu we have to write the
+ // entire array out:
+ int level;
+ const char* k = class_name();
+ if (k) {
+ write_c("\nFl_Menu_Item %s::%s[] = {\n", k, menu_name(level));
+ } else
+ write_c("\nFl_Menu_Item %s[] = {\n", menu_name(level));
+ Fl_Type* t = prev; while (t && t->is_menu_item()) t = t->prev;
+ level = t->level+1;
+ for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) {
+ ((Fl_Menu_Item_Type*)q)->write_item();
+ if (q->is_parent()) level++;
+ int l1 =
+ (q->next && q->next->is_menu_item()) ? q->next->level : t->next->level;
+ while (level > l1) {write_c(" {0},\n"); level--;}
+ level = l1;
+ }
+ write_c(" {0}\n};\n");
+}
+
+int Fl_Menu_Item_Type::flags() {
+ int i = o->type();
+ if (((Fl_Button*)o)->value()) i |= FL_MENU_VALUE;
+ if (!o->active()) i |= FL_MENU_INACTIVE;
+ if (!o->visible()) i |= FL_MENU_INVISIBLE;
+ if (is_parent()) i |= FL_SUBMENU;
+ if (hotspot()) i |= FL_MENU_DIVIDER;
+ return i;
+}
+
+void Fl_Menu_Item_Type::write_item() {
+ write_c(" {");
+ if (image) write_c("0");
+ else if (label()) write_cstring(label());
+ else write_c("\"\"");
+ if (((Fl_Button*)o)->shortcut())
+ write_c(", 0x%x, ", ((Fl_Button*)o)->shortcut());
+ else
+ write_c(", 0, ");
+ if (callback()) {
+ const char* k = class_name();
+ if (k) {
+ write_c(" (Fl_Callback*)%s::%s,", k, callback_name());
+ } else {
+ write_c(" (Fl_Callback*)%s,", callback_name());
+ }
+ } else
+ write_c(" 0,");
+ if (user_data())
+ write_c(" (void*)(%s),", user_data());
+ else
+ write_c(" 0,");
+ write_c(" %d, %d, %d, %d, %d", flags(),
+ o->labeltype(), o->labelfont(), o->labelsize(), o->labelcolor());
+ write_c("},\n");
+}
+
+void Fl_Menu_Item_Type::write_code1() {
+ if (!prev->is_menu_item()) {
+ // for first menu item, declare the array
+ int i; const char* n = menu_name(i);
+ if (class_name())
+ write_h(" static Fl_Menu_Item %s[];\n", n);
+ else
+ write_h("extern Fl_Menu_Item %s[];\n", n);
+ }
+
+ const char *c = array_name(this);
+ if (c) {
+ int i; const char* n = menu_name(i);
+ write_h("#define %s (%s+%d)\n", c, n, i);
+ }
+
+ if (callback()) {
+ if (!is_name(callback()) && class_name()) {
+ const char* cn = callback_name();
+ const char* ut = user_data_type() ? user_data_type() : "void*";
+ write_public(0);
+ write_h(" inline void %s_i(Fl_Menu_*, %s);\n", cn, ut);
+ write_h(" static void %s(Fl_Menu_*, %s);\n", cn, ut);
+ }
+ }
+
+ int init = 0;
+ if (image) {
+ int i; const char* n = menu_name(i);
+ write_c(" {Fl_Menu_Item* o = &%s[%d];\n", n, i);
+ init = 1;
+ image->write_code();
+ }
+ for (int n=0; n < NUM_EXTRA_CODE; n++)
+ if (extra_code(n) && !isdeclare(extra_code(n))) {
+ if (!init) {
+ init = 1;
+ int i; const char* n = menu_name(i);
+ write_c("%s{ Fl_Menu_Item* o = &%s[%d];\n", indent(), n, i);
+ }
+ write_c("%s %s\n", indent(), extra_code(n));
+ }
+ if (init) write_c("%s}\n",indent());
+}
+
+void Fl_Menu_Item_Type::write_code2() {}
+
+////////////////////////////////////////////////////////////////
+// This is the base class for widgets that contain a menu (ie
+// subclasses of Fl_Menu_.
+// This is a parent widget and menu items can be added as
+// children. An actual array of Fl_Menu_Items is kept parallel
+// with the child objects and updated as they change.
+
+class Fl_Menu_Type : public Fl_Widget_Type {
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Menu_ *o = (Fl_Menu_*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+public:
+ int is_menu_button() const {return 1;}
+ int is_parent() const {return 1;}
+ int menusize;
+ void build_menu();
+ Fl_Menu_Type() : Fl_Widget_Type() {menusize = 0;}
+ ~Fl_Menu_Type() {
+ if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Menu_*)o)->menu());
+ }
+ void add_child(Fl_Type*, Fl_Type*) {build_menu();}
+ void move_child(Fl_Type*, Fl_Type*) {build_menu();}
+ void remove_child(Fl_Type*) {build_menu();}
+ Fl_Type* click_test(int x, int y);
+ void write_code2();
+};
+
+void Fl_Menu_Type::build_menu() {
+ Fl_Menu_* w = (Fl_Menu_*)o;
+ // count how many Fl_Menu_Item structures needed:
+ int n = 0;
+ Fl_Type* q;
+ for (q = next; q && q->level > level; q = q->next) {
+ if (q->is_parent()) n++; // space for null at end of submenu
+ n++;
+ }
+ if (!n) {
+ if (menusize) delete[] (Fl_Menu_Item*)(w->menu());
+ w->menu(0);
+ menusize = 0;
+ } else {
+ n++; // space for null at end of menu
+ if (menusize<n) {
+ if (menusize) delete[] (Fl_Menu_Item*)(w->menu());
+ menusize = n+10;
+ w->menu(new Fl_Menu_Item[menusize]);
+ }
+ // fill them all in:
+ Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu());
+ int lvl = level+1;
+ for (q = next; q && q->level > level; q = q->next) {
+ Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q;
+ m->label(i->o->label());
+ m->shortcut(((Fl_Button*)(i->o))->shortcut());
+ m->callback(0,(void*)i);
+ m->flags = i->flags();
+ m->labeltype(i->o->labeltype());
+ m->labelfont(i->o->labelfont());
+ m->labelsize(i->o->labelsize());
+ m->labelcolor(i->o->labelcolor());
+ m++;
+ if (q->is_parent()) lvl++;
+ int l1 =
+ (q->next && q->next->is_menu_item()) ? q->next->level : level;
+ while (lvl > l1) {m->label(0); m++; lvl--;}
+ lvl = l1;
+ }
+ }
+ o->redraw();
+}
+
+Fl_Type* Fl_Menu_Type::click_test(int, int) {
+ if (selected) return 0; // let user move the widget
+ Fl_Menu_* w = (Fl_Menu_*)o;
+ if (!menusize) return 0;
+ const Fl_Menu_Item* save = w->mvalue();
+ w->value((Fl_Menu_Item*)0);
+ Fl::pushed(w);
+ w->handle(FL_PUSH);
+ const Fl_Menu_Item* m = w->mvalue();
+ if (m) {
+ // restore the settings of toggles & radio items:
+ if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu();
+ return (Fl_Type*)(m->user_data());
+ }
+ w->value(save);
+ return this;
+}
+
+void Fl_Menu_Type::write_code2() {
+ if (next && next->is_menu_item())
+ write_c("%so->menu(%s);\n", indent(),
+ unique_id(this, "menu", name(), label()));
+ Fl_Widget_Type::write_code2();
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Menu_Button.H>
+static Fl_Menu_Item button_type_menu[] = {
+ {"normal",0,0,(void*)0},
+ {"popup1",0,0,(void*)Fl_Menu_Button::POPUP1},
+ {"popup2",0,0,(void*)Fl_Menu_Button::POPUP2},
+ {"popup3",0,0,(void*)Fl_Menu_Button::POPUP3},
+ {"popup12",0,0,(void*)Fl_Menu_Button::POPUP12},
+ {"popup23",0,0,(void*)Fl_Menu_Button::POPUP23},
+ {"popup13",0,0,(void*)Fl_Menu_Button::POPUP13},
+ {"popup123",0,0,(void*)Fl_Menu_Button::POPUP123},
+ {0}};
+class Fl_Menu_Button_Type : public Fl_Menu_Type {
+ Fl_Menu_Item *subtypes() {return button_type_menu;}
+public:
+ virtual const char *type_name() {return "Fl_Menu_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Menu_Button(x,y,w,h,"menu");}
+ Fl_Widget_Type *_make() {return new Fl_Menu_Button_Type();}
+};
+Fl_Menu_Button_Type Fl_Menu_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Choice.H>
+
+static Fl_Menu_Item dummymenu[] = {{"CHOICE"},{0}};
+
+class Fl_Choice_Type : public Fl_Menu_Type {
+public:
+ virtual const char *type_name() {return "Fl_Choice";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ Fl_Choice *o = new Fl_Choice(x,y,w,h,"choice:");
+ o->menu(dummymenu);
+ return o;
+ }
+ Fl_Widget_Type *_make() {return new Fl_Choice_Type();}
+};
+Fl_Choice_Type Fl_Choice_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Menu_Bar.H>
+class Fl_Menu_Bar_Type : public Fl_Menu_Type {
+public:
+ virtual const char *type_name() {return "Fl_Menu_Bar";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Menu_Bar(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Menu_Bar_Type();}
+};
+Fl_Menu_Bar_Type Fl_Menu_Bar_type;
+
+////////////////////////////////////////////////////////////////
+// Shortcut entry item in panel:
+
+#include <FL/Fl_Output.H>
+#include "Shortcut_Button.H"
+#include <FL/fl_draw.H>
+
+void Shortcut_Button::draw() {
+ if (value()) draw_box(FL_THIN_DOWN_BOX, (Fl_Color)9);
+ else draw_box(FL_THIN_UP_BOX, FL_WHITE);
+ fl_font(FL_HELVETICA,14); fl_color(FL_BLACK);
+ fl_draw(fl_shortcut_label(svalue),x()+6,y(),w(),h(),FL_ALIGN_LEFT);
+}
+
+int Shortcut_Button::handle(int e) {
+ when(0); type(FL_TOGGLE_BUTTON);
+ if (e == FL_KEYBOARD) {
+ if (!value()) return 0;
+ int v = Fl::event_text()[0];
+ if (v > 32 && v < 0x7f || v > 0xa0 && v <= 0xff) {
+ v = v | Fl::event_state()&(FL_META|FL_ALT|FL_CTRL);
+ } else {
+ v = Fl::event_state()&(FL_META|FL_ALT|FL_CTRL|FL_SHIFT) | Fl::event_key();
+ if (v == FL_BackSpace && svalue) v = 0;
+ }
+ if (v != svalue) {svalue = v; set_changed(); redraw();}
+ return 1;
+ } else if (e == FL_UNFOCUS) {
+ int c = changed(); value(0); if (c) set_changed();
+ return 1;
+ } else if (e == FL_FOCUS) {
+ return value();
+ } else {
+ int r = Fl_Button::handle(e);
+ if (e == FL_RELEASE && value() && Fl::focus() != this) take_focus();
+ return r;
+ }
+}
+
+void shortcut_in_cb(Shortcut_Button* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_button()) {i->hide(); return;}
+ i->show();
+ i->svalue = ((Fl_Button*)(current_widget->o))->shortcut();
+ i->redraw();
+ } else {
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_button()) {
+ Fl_Button* b = (Fl_Button*)(((Fl_Widget_Type*)o)->o);
+ b->shortcut(i->svalue);
+ if (o->is_menu_item()) ((Fl_Widget_Type*)o)->redraw();
+ }
+ }
+}
diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx
new file mode 100644
index 000000000..f57a970d4
--- /dev/null
+++ b/fluid/Fl_Type.cxx
@@ -0,0 +1,617 @@
+/* Fl_Type.C
+
+ Each object described by Fluid is one of these objects. They
+ are all stored in a double-linked list.
+
+ They "type" of the object is covered by the virtual functions.
+ There will probably be a lot of these virtual functions.
+
+ The type browser is also a list of these objects, but they
+ are "factory" instances, not "real" ones. These objects exist
+ only so the "make" method can be called on them. They are
+ not in the linked list and are not written to files or
+ copied or otherwise examined.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/Fl_Browser_.H>
+#include <FL/fl_draw.H>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "Fl_Type.H"
+
+////////////////////////////////////////////////////////////////
+
+class Widget_Browser : public Fl_Browser_ {
+ friend class Fl_Type;
+
+ // required routines for Fl_Browser_ subclass:
+ void *item_first() const ;
+ void *item_next(void *) const ;
+ void *item_prev(void *) const ;
+ int item_selected(void *) const ;
+ void item_select(void *,int);
+ int item_width(void *) const ;
+ int item_height(void *) const ;
+ void item_draw(void *,int,int,int,int) const ;
+ int incr_height() const ;
+
+public:
+
+ int handle(int);
+ void callback();
+ Widget_Browser(int,int,int,int,const char * =0);
+};
+
+static Widget_Browser *widget_browser;
+Fl_Widget *make_widget_browser(int x,int y,int w,int h) {
+ return (widget_browser = new Widget_Browser(x,y,w,h));
+}
+
+void select(Fl_Type *o, int v) {
+ widget_browser->select(o,v,1);
+ // Fl_Type::current = o;
+}
+
+void select_only(Fl_Type *o) {
+ widget_browser->select_only(o,1);
+}
+
+void deselect() {
+ widget_browser->deselect();
+ //Fl_Type::current = 0; // this breaks the paste & merge functions
+}
+
+Fl_Type *Fl_Type::first;
+Fl_Type *Fl_Type::last;
+
+static void Widget_Browser_callback(Fl_Widget *o,void *) {
+ ((Widget_Browser *)o)->callback();
+}
+
+Widget_Browser::Widget_Browser(int x,int y,int w,int h,const char*l)
+: Fl_Browser_(x,y,w,h,l) {
+ type(FL_MULTI_BROWSER);
+ Fl_Widget::callback(Widget_Browser_callback);
+ when(FL_WHEN_RELEASE);
+}
+
+void *Widget_Browser::item_first() const {return Fl_Type::first;}
+
+void *Widget_Browser::item_next(void *l) const {return ((Fl_Type*)l)->next;}
+
+void *Widget_Browser::item_prev(void *l) const {return ((Fl_Type*)l)->prev;}
+
+int Widget_Browser::item_selected(void *l) const {return ((Fl_Type*)l)->new_selected;}
+
+void Widget_Browser::item_select(void *l,int v) {((Fl_Type*)l)->new_selected = v;}
+
+int Widget_Browser::item_height(void *l) const {
+ return ((Fl_Type *)l)->visible ? textsize()+2 : 0;
+}
+
+int Widget_Browser::incr_height() const {return textsize()+2;}
+
+static Fl_Type* pushedtitle;
+
+// Generate a descriptive text for this item, to put in browser & window titles
+const char* Fl_Type::title() {
+ const char* c = name(); if (c) return c;
+ return type_name();
+}
+
+extern const char* subclassname(Fl_Type*);
+
+void Widget_Browser::item_draw(void *v, int x, int y, int, int) const {
+ Fl_Type *l = (Fl_Type *)v;
+ x += 3 + l->level * 10;
+ fl_color(FL_BLACK);
+ if (l->is_parent()) {
+ if (!l->next || l->next->level <= l->level) {
+ if (l->open_!=(l==pushedtitle)) {
+ fl_loop(x,y+7,x+5,y+12,x+10,y+7);
+ } else {
+ fl_loop(x+2,y+2,x+7,y+7,x+2,y+12);
+ }
+ } else {
+ if (l->open_!=(l==pushedtitle)) {
+ fl_polygon(x,y+7,x+5,y+12,x+10,y+7);
+ } else {
+ fl_polygon(x+2,y+2,x+7,y+7,x+2,y+12);
+ }
+ }
+ x += 10;
+ }
+ if (l->is_widget() || l->is_class()) {
+ const char* c = subclassname(l);
+ if (!strncmp(c,"Fl_",3)) c += 3;
+ fl_font(textfont(), textsize());
+ fl_draw(c, x, y+13);
+ x += int(fl_width(c)+fl_width('n'));
+ c = l->name();
+ if (c) {
+ fl_font(textfont()|FL_BOLD, textsize());
+ fl_draw(c, x, y+13);
+ } else if ((c=l->label())) {
+ char buf[50]; char* p = buf;
+ *p++ = '"';
+ for (int i = 20; i--;) {
+ if (! (*c & -32)) break;
+ *p++ = *c++;
+ }
+ if (*c) {strcpy(p,"..."); p+=3;}
+ *p++ = '"';
+ *p = 0;
+ fl_draw(buf, x, y+13);
+ }
+ } else {
+ const char* c = l->title();
+ char buf[60]; char* p = buf;
+ for (int i = 55; i--;) {
+ if (! (*c & -32)) break;
+ *p++ = *c++;
+ }
+ if (*c) {strcpy(p,"..."); p+=3;}
+ *p = 0;
+ fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize());
+ fl_draw(buf, x, y+13);
+ }
+}
+
+int Widget_Browser::item_width(void *v) const {
+ Fl_Type *l = (Fl_Type *)v;
+
+ if (!l->visible) return 0;
+
+ int w = 3 + l->level*10;
+ if (l->is_parent()) w += 10;
+
+ if (l->is_widget() || l->is_class()) {
+ const char* c = l->type_name();
+ if (!strncmp(c,"Fl_",3)) c += 3;
+ fl_font(textfont(), textsize());
+ w += int(fl_width(c) + fl_width('n'));
+ c = l->name();
+ if (c) {
+ fl_font(textfont()|FL_BOLD, textsize());
+ w += int(fl_width(c));
+ } else if ((c=l->label())) {
+ char buf[50]; char* p = buf;
+ *p++ = '"';
+ for (int i = 20; i--;) {
+ if (! (*c & -32)) break;
+ *p++ = *c++;
+ }
+ if (*c) {strcpy(p,"..."); p+=3;}
+ *p++ = '"';
+ *p = 0;
+ w += int(fl_width(buf));
+ }
+ } else {
+ const char* c = l->title();
+ char buf[60]; char* p = buf;
+ for (int i = 55; i--;) {
+ if (! (*c & -32)) break;
+ *p++ = *c++;
+ }
+ if (*c) {strcpy(p,"..."); p+=3;}
+ *p = 0;
+ fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize());
+ w += int(fl_width(buf));
+ }
+
+ return w;
+}
+
+void redraw_browser() {
+ widget_browser->redraw();
+}
+
+void Widget_Browser::callback() {
+ selection_changed((Fl_Type*)selection());
+}
+
+int Widget_Browser::handle(int e) {
+ static Fl_Type *title;
+ Fl_Type *l;
+ int X,Y,W,H; bbox(X,Y,W,H);
+ switch (e) {
+ case FL_PUSH:
+ if (!Fl::event_inside(X,Y,W,H)) break;
+ l = (Fl_Type*)find_item(Fl::event_y());
+ if (l) {
+ X += 10*l->level;
+ if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) {
+ title = pushedtitle = l;
+ redraw_line(l);
+ return 1;
+ }
+ }
+ break;
+ case FL_DRAG:
+ if (!title) break;
+ l = (Fl_Type*)find_item(Fl::event_y());
+ if (l) {
+ X += 10*l->level;
+ if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) ;
+ else l = 0;
+ }
+ if (l != pushedtitle) {
+ if (pushedtitle) redraw_line(pushedtitle);
+ if (l) redraw_line(l);
+ pushedtitle = l;
+ }
+ return 1;
+ case FL_RELEASE:
+ if (!title) {
+ l = (Fl_Type*)find_item(Fl::event_y());
+ if (l && l->new_selected && (Fl::event_clicks() || Fl::event_state(FL_CTRL)))
+ l->open();
+ break;
+ }
+ l = pushedtitle;
+ title = pushedtitle = 0;
+ if (l) {
+ if (l->open_) {
+ l->open_ = 0;
+ for (Fl_Type*k = l->next; k&&k->level>l->level; k = k->next)
+ k->visible = 0;
+ } else {
+ l->open_ = 1;
+ for (Fl_Type*k=l->next; k&&k->level>l->level;) {
+ k->visible = 1;
+ if (k->is_parent() && !k->open_) {
+ Fl_Type *j;
+ for (j = k->next; j && j->level>k->level; j = j->next);
+ k = j;
+ } else
+ k = k->next;
+ }
+ }
+ redraw();
+ }
+ return 1;
+ }
+ return Fl_Browser_::handle(e);
+}
+
+Fl_Type::Fl_Type() {
+ factory = 0;
+ parent = 0;
+ next = prev = 0;
+ selected = new_selected = 0;
+ visible = 0;
+ name_ = 0;
+ label_ = 0;
+ user_data_ = 0;
+ user_data_type_ = 0;
+ callback_ = 0;
+ rtti = 0;
+ level = 0;
+}
+
+static void fixvisible(Fl_Type *p) {
+ Fl_Type *t = p;
+ for (;;) {
+ if (t->parent) t->visible = t->parent->visible && t->parent->open_;
+ else t->visible = 1;
+ t = t->next;
+ if (!t || t->level <= p->level) break;
+ }
+}
+
+// turn a click at x,y on this into the actual picked object:
+Fl_Type* Fl_Type::click_test(int,int) {return 0;}
+void Fl_Type::add_child(Fl_Type*, Fl_Type*) {}
+void Fl_Type::move_child(Fl_Type*, Fl_Type*) {}
+void Fl_Type::remove_child(Fl_Type*) {}
+
+// add a list of widgets as a new child of p:
+void Fl_Type::add(Fl_Type *p) {
+ parent = p;
+ Fl_Type *end = this;
+ while (end->next) end = end->next;
+ Fl_Type *q;
+ int newlevel;
+ if (p) {
+ for (q = p->next; q && q->level > p->level; q = q->next);
+ newlevel = p->level+1;
+ } else {
+ q = 0;
+ newlevel = 0;
+ }
+ for (Fl_Type *t = this->next; t; t = t->next) t->level += (newlevel-level);
+ level = newlevel;
+ if (q) {
+ prev = q->prev;
+ prev->next = this;
+ q->prev = end;
+ end->next = q;
+ } else if (first) {
+ prev = last;
+ prev->next = this;
+ end->next = 0;
+ last = end;
+ } else {
+ first = this;
+ last = end;
+ prev = end->next = 0;
+ }
+ if (p) p->add_child(this,0);
+ open_ = 1;
+ fixvisible(this);
+ modflag = 1;
+ widget_browser->redraw();
+}
+
+// add to a parent before another widget:
+void Fl_Type::insert(Fl_Type *g) {
+ Fl_Type *end = this;
+ while (end->next) end = end->next;
+ parent = g->parent;
+ int newlevel = g->level;
+ visible = g->visible;
+ for (Fl_Type *t = this->next; t; t = t->next) t->level += newlevel-level;
+ level = newlevel;
+ prev = g->prev;
+ if (prev) prev->next = this; else first = this;
+ end->next = g;
+ g->prev = end;
+ fixvisible(this);
+ if (parent) parent->add_child(this, g);
+ widget_browser->redraw();
+}
+
+// delete from parent:
+Fl_Type *Fl_Type::remove() {
+ Fl_Type *end = this;
+ for (;;) {
+ if (!end->next || end->next->level <= level) break;
+ end = end->next;
+ }
+ if (prev) prev->next = end->next;
+ else first = end->next;
+ if (end->next) end->next->prev = prev;
+ else last = prev;
+ Fl_Type *r = end->next;
+ prev = end->next = 0;
+ if (parent) parent->remove_child(this);
+ parent = 0;
+ widget_browser->redraw();
+ selection_changed(0);
+ return r;
+}
+
+// update a string member:
+int storestring(const char *n, const char * & p, int nostrip) {
+ if (n == p) return 0;
+ int length = 0;
+ if (n) { // see if blank, strip leading & trailing blanks
+ if (!nostrip) while (isspace(*n)) n++;
+ const char *e = n + strlen(n);
+ if (!nostrip) while (e > n && isspace(*(e-1))) e--;
+ length = e-n;
+ if (!length) n = 0;
+ }
+ if (n == p) return 0;
+ if (n && p && !strncmp(n,p,length) && !p[length]) return 0;
+ if (p) free((void *)p);
+ if (!n || !*n) {
+ p = 0;
+ } else {
+ char *q = (char *)malloc(length+1);
+ strncpy(q,n,length);
+ q[length] = 0;
+ p = q;
+ }
+ modflag = 1;
+ return 1;
+}
+
+void Fl_Type::name(const char *n) {
+ if (storestring(n,name_)) {
+ if (visible) widget_browser->redraw();
+ }
+}
+
+void Fl_Type::label(const char *n) {
+ if (storestring(n,label_,1)) {
+ setlabel(label_);
+ if (visible && !name_) widget_browser->redraw();
+ }
+}
+
+void Fl_Type::callback(const char *n) {
+ storestring(n,callback_);
+}
+
+void Fl_Type::user_data(const char *n) {
+ storestring(n,user_data_);
+}
+
+void Fl_Type::user_data_type(const char *n) {
+ storestring(n,user_data_type_);
+}
+
+void Fl_Type::open() {
+ printf("Open of '%s' is not yet implemented\n",type_name());
+}
+
+void Fl_Type::setlabel(const char *) {}
+
+Fl_Type::~Fl_Type() {
+ if (parent) parent->remove_child(this);
+ // warning: destructor only works for widgets that have been add()ed.
+ if (widget_browser) widget_browser->deleting(this);
+ if (prev) prev->next = next; else first = next;
+ if (next) next->prev = prev; else last = prev;
+ if (current == this) current = 0;
+ modflag = 1;
+}
+
+int Fl_Type::is_parent() const {return 0;}
+int Fl_Type::is_widget() const {return 0;}
+int Fl_Type::is_valuator() const {return 0;}
+int Fl_Type::is_button() const {return 0;}
+int Fl_Type::is_menu_item() const {return 0;}
+int Fl_Type::is_menu_button() const {return 0;}
+int Fl_Type::is_group() const {return 0;}
+int Fl_Type::is_window() const {return 0;}
+int Fl_Type::is_code_block() const {return 0;}
+int Fl_Type::is_decl_block() const {return 0;}
+int Fl_Type::is_class() const {return 0;}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Type *in_this_only; // set if menu popped-up in window
+
+void select_all_cb(Fl_Widget *,void *) {
+ Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0;
+ if (in_this_only) {
+ Fl_Type *t = p;
+ for (; t && t != in_this_only; t = t->parent);
+ if (t != in_this_only) p = in_this_only;
+ }
+ for (;;) {
+ if (p) {
+ int foundany = 0;
+ for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) {
+ if (!t->new_selected) {widget_browser->select(t,1,0); foundany = 1;}
+ }
+ if (foundany) break;
+ p = p->parent;
+ } else {
+ for (Fl_Type *t = Fl_Type::first; t; t = t->next)
+ widget_browser->select(t,1,0);
+ break;
+ }
+ }
+ selection_changed(p);
+}
+
+static void delete_children(Fl_Type *p) {
+ Fl_Type *f;
+ for (f = p; f && f->next && f->next->level > p->level; f = f->next);
+ for (; f != p; ) {
+ Fl_Type *g = f->prev;
+ delete f;
+ f = g;
+ }
+}
+
+void delete_all(int selected_only) {
+ for (Fl_Type *f = Fl_Type::first; f;) {
+ if (f->selected || !selected_only) {
+ delete_children(f);
+ Fl_Type *g = f->next;
+ delete f;
+ f = g;
+ } else f = f->next;
+ }
+ selection_changed(0);
+}
+
+// move f (and it's children) into list before g:
+// returns pointer to whatever is after f & children
+void Fl_Type::move_before(Fl_Type* g) {
+ if (level != g->level) printf("move_before levels don't match! %d %d\n",
+ level, g->level);
+ Fl_Type* n;
+ for (n = next; n && n->level > level; n = n->next);
+ if (n == g) return;
+ Fl_Type *l = n ? n->prev : Fl_Type::last;
+ prev->next = n;
+ if (n) n->prev = prev; else Fl_Type::last = prev;
+ prev = g->prev;
+ l->next = g;
+ if (prev) prev->next = this; else Fl_Type::first = this;
+ g->prev = l;
+ if (parent) parent->move_child(this,g);
+ widget_browser->redraw();
+}
+
+// move selected widgets in their parent's list:
+void earlier_cb(Fl_Widget*,void*) {
+ Fl_Type *f;
+ for (f = Fl_Type::first; f; f=f->next) if (f->selected) {
+ Fl_Type *g;
+ for (g = f->prev; g && g->level > f->level; g = g->prev);
+ if (g && g->level == f->level) f->move_before(g);
+ }
+}
+
+void later_cb(Fl_Widget*,void*) {
+ Fl_Type *f;
+ for (f = Fl_Type::last; f; f=f->prev) if (f->selected) {
+ Fl_Type *g;
+ for (g = f->next; g && g->level > f->level; g = g->next);
+ if (g && g->level == f->level && !g->selected) g->move_before(f);
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// write a widget and all it's children:
+void Fl_Type::write() {
+ write_indent(level);
+ write_word(type_name());
+ write_word(name());
+ write_open(level);
+ write_properties();
+ write_close(level);
+ if (!is_parent()) return;
+ // now do children:
+ write_open(level);
+ Fl_Type *child;
+ for (child = next; child && child->level > level; child = child->next)
+ if (child->level == level+1) child->write();
+ write_close(level);
+}
+
+void Fl_Type::write_properties() {
+ // repeat this for each attribute:
+ if (label()) {
+ write_indent(level+1);
+ write_word("label");
+ write_word(label());
+ }
+ if (user_data()) {
+ write_indent(level+1);
+ write_word("user_data");
+ write_word(user_data());
+ if (user_data_type()) {
+ write_word("user_data_type");
+ write_word(user_data_type());
+ }
+ }
+ if (callback()) {
+ write_indent(level+1);
+ write_word("callback");
+ write_word(callback());
+ }
+ if (is_parent() && open_) write_word("open");
+ if (selected) write_word("selected");
+}
+
+void Fl_Type::read_property(const char *c) {
+ if (!strcmp(c,"label"))
+ label(read_word());
+ else if (!strcmp(c,"user_data"))
+ user_data(read_word());
+ else if (!strcmp(c,"user_data_type"))
+ user_data_type(read_word());
+ else if (!strcmp(c,"callback"))
+ callback(read_word());
+ else if (!strcmp(c,"open"))
+ open_ = 1;
+ else if (!strcmp(c,"selected"))
+ select(this,1);
+ else
+ read_error("Unknown property \"%s\"", c);
+}
+
+int Fl_Type::read_fdesign(const char*, const char*) {return 0;}
diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h
new file mode 100644
index 000000000..737423a1d
--- /dev/null
+++ b/fluid/Fl_Type.h
@@ -0,0 +1,142 @@
+// Fl_Type.H
+
+// Each object described by Fluid is one of these objects. They
+// are all stored in a double-linked list.
+
+// There is also a single "factory" instance of each type of this.
+// The method "make()" is called on this factory to create a new
+// instance of this object. It could also have a "copy()" function,
+// but it was easier to implement this by using the file read/write
+// that is needed to save the setup anyways.
+
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu.H>
+
+class Fl_Type {
+
+ friend class Widget_Browser;
+ friend Fl_Widget *make_type_browser(int,int,int,int,const char *l=0);
+ friend class Fl_Window_Type;
+ virtual void setlabel(const char *); // virtual part of label(char*)
+
+protected:
+
+ Fl_Type();
+
+ const char *name_;
+ const char *label_;
+ const char *callback_;
+ const char *user_data_;
+ const char *user_data_type_;
+
+public: // things that should not be public:
+
+ Fl_Type *parent; // parent, which is previous in list
+ char new_selected; // browser highlight
+ char selected; // copied here by selection_changed()
+ char open_; // state of triangle in browser
+ char visible; // true if all parents are open
+ char rtti; // hack because I have no rtti, this is 0 for base class
+ int level; // number of parents over this
+ static Fl_Type *first, *last; // linked list of all objects
+ Fl_Type *next, *prev; // linked list of all objects
+
+ Fl_Type *factory;
+ const char *callback_name();
+
+public:
+
+ virtual ~Fl_Type();
+ virtual Fl_Type *make() = 0;
+
+ void add(Fl_Type *parent); // add as new child
+ void insert(Fl_Type *n); // insert into list before n
+ Fl_Type* remove(); // remove from list
+ void move_before(Fl_Type*); // move before a sibling
+
+ virtual const char *title(); // string for browser
+ virtual const char *type_name() = 0; // type for code output
+
+ const char *name() const {return name_;}
+ void name(const char *);
+ const char *label() const {return label_;}
+ void label(const char *);
+ const char *callback() const {return callback_;}
+ void callback(const char *);
+ const char *user_data() const {return user_data_;}
+ void user_data(const char *);
+ const char *user_data_type() const {return user_data_type_;}
+ void user_data_type(const char *);
+
+ virtual Fl_Type* click_test(int,int);
+ virtual void add_child(Fl_Type*, Fl_Type* beforethis);
+ virtual void move_child(Fl_Type*, Fl_Type* beforethis);
+ virtual void remove_child(Fl_Type*);
+
+ static Fl_Type *current; // most recently picked object
+ virtual void open(); // what happens when you double-click
+
+ // read and write data to a saved file:
+ void write();
+ virtual void write_properties();
+ virtual void read_property(const char *);
+ virtual int read_fdesign(const char*, const char*);
+
+ // write code, these are called in order:
+ virtual void write_declare(); // write #include and #define to .h file
+ virtual void write_static(); // write static stuff to .c file
+ virtual void write_code1(); // code and .h before children
+ virtual void write_code2(); // code and .h after children
+
+ // fake rtti:
+ virtual int is_parent() const;
+ virtual int is_widget() const;
+ virtual int is_button() const;
+ virtual int is_valuator() const;
+ virtual int is_menu_item() const;
+ virtual int is_menu_button() const;
+ virtual int is_group() const;
+ virtual int is_window() const;
+ virtual int is_code_block() const;
+ virtual int is_decl_block() const;
+ virtual int is_class() const;
+
+ const char* class_name() const;
+};
+
+// object list operations:
+Fl_Widget *make_widget_browser(int x,int y,int w,int h);
+extern int modflag;
+void delete_all(int selected_only=0);
+void selection_changed(Fl_Type* new_current);
+
+// file operations:
+void write_word(const char *);
+void write_string(const char *,...);
+int write_file(const char *, int selected_only = 0);
+int write_code(const char *cfile, const char *hfile);
+
+int write_declare(const char *, ...);
+int is_id(char);
+const char* unique_id(void* o, const char*, const char*, const char*);
+void write_c(const char*, ...);
+void write_h(const char*, ...);
+void write_cstring(const char *);
+void write_cstring(const char *,int length);
+void write_indent(int n);
+void write_open(int);
+void write_close(int n);
+extern int write_number;
+void write_public(int state); // writes pubic:/private: as needed
+extern int indentation;
+extern const char* indent();
+
+int read_file(const char *, int merge);
+const char *read_word(int wantbrace = 0);
+void read_error(const char *format, ...);
+
+// check legality of c code (sort of) and return error:
+const char *c_check(const char *c, int type = 0);
+
+// replace a string pointer with new value, strips leading/trailing blanks:
+int storestring(const char *n, const char * & p, int nostrip=0);
diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx
new file mode 100644
index 000000000..96c22acea
--- /dev/null
+++ b/fluid/Fl_Widget_Type.cxx
@@ -0,0 +1,1676 @@
+// Fl_Widget_Type.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include "Fl_Widget_Type.H"
+#include <FL/fl_message.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Window.H>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// Make an Fl_Widget_Type subclass instance.
+// It figures out the automatic size and parent of the new widget,
+// creates the Fl_Widget (by calling the virtual function _make),
+// adds it to the Fl_Widget hierarchy, creates a new Fl_Type
+// instance, sets the widget pointers, and makes all the display
+// update correctly...
+
+extern int reading_file;
+int force_parent;
+extern int gridx;
+extern int gridy;
+
+int Fl_Widget_Type::is_widget() const {return 1;}
+
+const char* subclassname(Fl_Type* l) {
+ if (l->is_widget()) {
+ Fl_Widget_Type* p = (Fl_Widget_Type*)l;
+ const char* c = p->subclass();
+ if (c) return c;
+ if (p->o->type() == FL_WINDOW+1) return "Fl_Double_Window";
+ }
+ return l->type_name();
+}
+
+Fl_Type *Fl_Widget_Type::make() {
+ // Find the current widget, or widget to copy:
+ Fl_Type *qq = Fl_Type::current;
+ while (qq && (!qq->is_widget() || qq->is_menu_item())) qq = qq->parent;
+ if (!qq) {
+ fl_message("Please select a widget");
+ return 0;
+ }
+ Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
+ // find the parent widget:
+ Fl_Widget_Type* p = q;
+ if ((force_parent || !p->is_group()) && p->parent->is_widget())
+ p = (Fl_Widget_Type*)(p->parent);
+ force_parent = 0;
+
+ // Figure out a border between widget and window:
+ int B = p->o->w()/2; if (p->o->h()/2 < B) B = p->o->h()/2; if (B>25) B = 25;
+
+ int ULX,ULY; // parent's origin in window
+ if (!p->is_window()) { // if it is a group, add corner
+ ULX = p->o->x(); ULY = p->o->y();
+ } else {
+ ULX = ULY = 0;
+ }
+
+ // Figure out a position and size for the widget
+ int X,Y,W,H;
+ if (is_group()) { // fill the parent with the widget
+ X = ULX+B;
+ W = p->o->w()-B;
+ Y = ULY+B;
+ H = p->o->h()-B;
+ } else if (q != p) { // copy position and size of current widget
+ W = q->o->w();
+ H = q->o->h();
+ X = q->o->x()+W;
+ Y = q->o->y();
+ if (X+W > ULX+p->o->w()) {
+ X = q->o->x();
+ Y = q->o->y()+H;
+ if (Y+H > ULY+p->o->h()) Y = ULY+B;
+ }
+ } else { // just make it small and square...
+ X = ULX+B;
+ Y = ULY+B;
+ W = H = B;
+ }
+
+ // satisfy the grid requirements (otherwise it edits really strangely):
+ if (gridx>1) {
+ X = (X/gridx)*gridx;
+ W = ((W-1)/gridx+1)*gridx;
+ }
+ if (gridy>1) {
+ Y = (Y/gridy)*gridy;
+ H = ((H-1)/gridy+1)*gridy;
+ }
+
+ // Construct the Fl_Type:
+ Fl_Widget_Type *t = _make();
+ if (!o) o = widget(0,0,100,100); // create template widget
+ t->factory = this;
+ // Construct the Fl_Widget:
+ t->o = widget(X,Y,W,H);
+ if (reading_file) t->o->label(0);
+ else if (t->o->label()) t->label(t->o->label()); // allow editing
+ t->o->user_data((void*)t);
+ // Put it in the parent:
+ // ((Fl_Group *)(p->o))->add(t->o); (done by Fl_Type::add())
+ // add to browser:
+ t->add(p);
+ t->redraw();
+ return t;
+}
+
+#include "Fluid_Image.H"
+
+void Fl_Widget_Type::setimage(Fluid_Image *i) {
+ if (i == image) return;
+ if (image) image->decrement();
+ if (i) i->increment();
+ image = i;
+ if (i) i->label(o);
+ else o->labeltype(FL_NORMAL_LABEL);
+ redraw();
+}
+
+static char dont_touch_image;
+void Fl_Widget_Type::setlabel(const char *n) {
+ if (image) {
+ if (dont_touch_image) return;
+ Fluid_Image *i = Fluid_Image::find(n);
+ setimage(i);
+ if (i) return;
+ }
+ o->label(n);
+ redraw();
+}
+
+Fl_Widget_Type::Fl_Widget_Type() {
+ for (int n=0; n<NUM_EXTRA_CODE; n++) {extra_code_[n] = 0; subclass_ = 0;}
+ hotspot_ = 0;
+ image = 0;
+ xclass = 0;
+ o = 0;
+ public_ = 1;
+}
+
+Fl_Widget_Type::~Fl_Widget_Type() {
+ if (o) {
+ o->hide();
+ if (o->parent()) ((Fl_Group*)o->parent())->remove(*o);
+ delete o;
+ }
+}
+
+void Fl_Widget_Type::extra_code(int m,const char *n) {
+ storestring(n,extra_code_[m]);
+}
+
+extern void redraw_browser();
+void Fl_Widget_Type::subclass(const char *n) {
+ if (storestring(n,subclass_) && visible)
+ redraw_browser();
+}
+
+void Fl_Widget_Type::redraw() {
+ Fl_Type *t = this;
+ if (is_menu_item()) {
+ // find the menu button that parents this menu:
+ do t = t->parent; while (t && t->is_menu_item());
+ // kludge to cause build_menu to be called again:
+ t->add_child(0,0);
+ } else {
+ while (t->parent && t->parent->is_widget()) t = t->parent;
+ ((Fl_Widget_Type*)t)->o->redraw();
+ }
+}
+
+// the recursive part sorts all children, returns pointer to next:
+Fl_Type *sort(Fl_Type *parent) {
+ Fl_Type *f,*n=0;
+ for (f = parent ? parent->next : Fl_Type::first; ; f = n) {
+ if (!f || parent && f->level <= parent->level) return f;
+ n = sort(f);
+ if (!f->selected || (!f->is_widget() || f->is_menu_item())) continue;
+ Fl_Widget* fw = ((Fl_Widget_Type*)f)->o;
+ Fl_Type *g; // we will insert before this
+ for (g = parent->next; g != f; g = g->next) {
+ if (!g->selected || g->level > f->level) continue;
+ Fl_Widget* gw = ((Fl_Widget_Type*)g)->o;
+ if (gw->y() > fw->y()) break;
+ if (gw->y() == fw->y() && gw->x() > fw->x()) break;
+ }
+ if (g != f) f->move_before(g);
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// The control panels!
+
+#include "widget_panel.H"
+#include <FL/fl_show_colormap.H>
+
+// All the callbacks use the argument to indicate whether to load or store.
+// This avoids the need for pointers to all the widgets, and keeps the
+// code localized in the callbacks.
+// A value of LOAD means to load. The hope is that this will not collide
+// with any actual useful values for the argument. I also use this to
+// initialized parts of the widget that are nyi by fluid.
+
+Fl_Widget_Type *current_widget; // one of the selected ones
+static int numselected; // number selected
+static int haderror;
+
+void name_cb(Fl_Input* o, void *v) {
+ if (v == LOAD) {
+ if (numselected != 1) {
+ static char buf[16];
+ sprintf(buf,"(%d widgets)",numselected);
+ ((Fl_Window*)(o->parent()))->label(buf);
+ o->hide();
+ } else {
+ o->static_value(current_widget->name());
+ o->show();
+ ((Fl_Window*)(o->parent()))->label(current_widget->title());
+ }
+ } else {
+ if (numselected == 1) {
+ current_widget->name(o->value());
+ // I don't update window title, as it probably is being closed
+ // and wm2 (a window manager) barfs if you retitle and then
+ // hide a window:
+ // ((Fl_Window*)(o->parent()))->label(current_widget->title());
+ }
+ }
+}
+
+void name_public_cb(Fl_Light_Button* i, void* v) {
+ if (v == LOAD) {
+ i->value(current_widget->public_);
+ } else {
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget())
+ ((Fl_Widget_Type*)o)->public_ = i->value();
+ }
+}
+
+static char* oldlabel;
+static unsigned oldlabellen;
+static Fl_Input *label_input;
+
+void label_cb(Fl_Input* i, void *v) {
+ if (v == LOAD) {
+ label_input = i;
+ i->static_value(current_widget->label());
+ if (strlen(i->value()) >= oldlabellen) {
+ oldlabellen = strlen(i->value())+128;
+ oldlabel = (char*)realloc(oldlabel,oldlabellen);
+ }
+ strcpy(oldlabel,i->value());
+ if (current_widget->image) i->deactivate();
+ else i->activate();
+ } else {
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) o->label(i->value());
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// turn number to string or string to number for saving to file:
+// does not work for hierarchial menus!
+
+const char *item_name(Fl_Menu_Item* m, int i) {
+ if (m) {
+ while (m->label()) {
+ if (m->argument() == i) return m->label();
+ m++;
+ }
+ }
+ static char buffer[20];
+ sprintf(buffer, "%d", i);
+ return buffer;
+}
+int item_number(Fl_Menu_Item* m, const char* i) {
+ if (m && i) {
+ if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
+ while (m->label()) {
+ if (!strcmp(m->label(), i)) return int(m->argument());
+ m++;
+ }
+ }
+ return atoi(i);
+}
+
+#define ZERO_ENTRY 1000
+
+Fl_Menu_Item boxmenu[] = {
+{"NO_BOX",0,0,(void *)ZERO_ENTRY},
+{"boxes",0,0,0,FL_SUBMENU},
+{"UP_BOX",0,0,(void *)FL_UP_BOX},
+{"DOWN_BOX",0,0,(void *)FL_DOWN_BOX},
+{"FLAT_BOX",0,0,(void *)FL_FLAT_BOX},
+{"BORDER_BOX",0,0,(void *)FL_BORDER_BOX},
+{"THIN_UP_BOX",0,0,(void *)FL_THIN_UP_BOX},
+{"THIN_DOWN_BOX",0,0,(void *)FL_THIN_DOWN_BOX},
+{"ENGRAVED_BOX",0,0,(void *)FL_ENGRAVED_BOX},
+{"EMBOSSED_BOX",0,0,(void *)FL_EMBOSSED_BOX},
+{"ROUND_UP_BOX",0,0,(void *)FL_ROUND_UP_BOX},
+{"ROUND_DOWN_BOX",0,0,(void *)FL_ROUND_DOWN_BOX},
+{"DIAMOND_UP_BOX",0,0,(void *)FL_DIAMOND_UP_BOX},
+{"DIAMOND_DOWN_BOX",0,0,(void *)FL_DIAMOND_DOWN_BOX},
+{"SHADOW_BOX",0,0,(void *)FL_SHADOW_BOX},
+{"ROUNDED_BOX",0,0,(void *)FL_ROUNDED_BOX},
+{"RSHADOW_BOX",0,0,(void *)FL_RSHADOW_BOX},
+{"RFLAT_BOX",0,0,(void *)FL_RFLAT_BOX},
+{"OVAL_BOX",0,0,(void *)FL_OVAL_BOX},
+{"OSHADOW_BOX",0,0,(void *)FL_OSHADOW_BOX},
+{"OFLAT_BOX",0,0,(void *)FL_OFLAT_BOX},
+{0},
+{"frames",0,0,0,FL_SUBMENU},
+{"UP_FRAME",0,0,(void *)FL_UP_FRAME},
+{"DOWN_FRAME",0,0,(void *)FL_DOWN_FRAME},
+{"THIN_UP_FRAME",0,0,(void *)FL_THIN_UP_FRAME},
+{"THIN_DOWN_FRAME",0,0,(void *)FL_THIN_DOWN_FRAME},
+{"ENGRAVED_FRAME",0,0,(void *)FL_ENGRAVED_FRAME},
+{"EMBOSSED_FRAME",0,0,(void *)FL_EMBOSSED_FRAME},
+{"BORDER_FRAME",0,0,(void *)FL_BORDER_FRAME},
+{"SHADOW_FRAME",0,0,(void *)FL_SHADOW_FRAME},
+{"ROUNDED_FRAME",0,0,(void *)FL_ROUNDED_FRAME},
+{"OVAL_FRAME",0,0,(void *)FL_OVAL_FRAME},
+{0},
+{0}};
+
+const char *boxname(int i) {
+ if (!i) i = ZERO_ENTRY;
+ for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+ if (boxmenu[j].argument() == i) return boxmenu[j].label();
+ return 0;
+}
+
+int boxnumber(const char *i) {
+ if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
+ for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+ if (boxmenu[j].label() && !strcmp(boxmenu[j].label(), i)) {
+ return int(boxmenu[j].argument());
+ }
+ return 0;
+}
+
+void box_cb(Fl_Choice* i, void *v) {
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ int n = current_widget->o->box(); if (!n) n = ZERO_ENTRY;
+ for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+ if (boxmenu[j].argument() == n) {i->value(j); break;}
+ } else {
+ int m = i->value();
+ int n = int(boxmenu[m].argument());
+ if (!n) return; // should not happen
+ if (n == ZERO_ENTRY) n = 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->box((Fl_Boxtype)n);
+ q->redraw();
+ }
+ }
+}
+
+void down_box_cb(Fl_Choice* i, void *v) {
+ if (v == LOAD) {
+ int n;
+ if (current_widget->is_button() && !current_widget->is_menu_item())
+ n = ((Fl_Button*)(current_widget->o))->down_box();
+ else if (current_widget->is_menu_button())
+ n = ((Fl_Menu_*)(current_widget->o))->down_box();
+ else {
+ i->hide(); return;
+ }
+ i->show();
+ if (!n) n = ZERO_ENTRY;
+ for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+ if (boxmenu[j].argument() == n) {i->value(j); break;}
+ } else {
+ int m = i->value();
+ int n = int(boxmenu[m].argument());
+ if (!n) return; // should not happen
+ if (n == ZERO_ENTRY) n = 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) if (o->selected) {
+ if (o->is_button() && !o->is_menu_item()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ ((Fl_Button*)(q->o))->down_box((Fl_Boxtype)n);
+ if (((Fl_Button*)(q->o))->value()) q->redraw();
+ } else if (o->is_menu_button()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ ((Fl_Menu_*)(q->o))->down_box((Fl_Boxtype)n);
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item whenmenu[] = {
+ {"never",0,0,(void*)ZERO_ENTRY},
+ {"Release",0,0,(void*)FL_WHEN_RELEASE},
+ {"Changed",0,0,(void*)FL_WHEN_CHANGED},
+ {"Enter key",0,0,(void*)FL_WHEN_ENTER_KEY},
+ //{"Release or Enter",0,0,(void*)(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE)},
+ {0}};
+
+void when_cb(Fl_Choice* i, void *v) {
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ int n = current_widget->o->when() & (~FL_WHEN_NOT_CHANGED);
+ if (!n) n = ZERO_ENTRY;
+ for (int j = 0; j < int(sizeof(whenmenu)/sizeof(*whenmenu)); j++)
+ if (whenmenu[j].argument() == n) {i->value(j); break;}
+ } else {
+ int m = i->value();
+ int n = int(whenmenu[m].argument());
+ if (!n) return; // should not happen
+ if (n == ZERO_ENTRY) n = 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->when(n|(q->o->when()&FL_WHEN_NOT_CHANGED));
+ }
+ }
+}
+
+void when_button_cb(Fl_Light_Button* i, void *v) {
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ i->value(current_widget->o->when()&FL_WHEN_NOT_CHANGED);
+ } else {
+ int n = i->value() ? FL_WHEN_NOT_CHANGED : 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->when(n|(q->o->when()&~FL_WHEN_NOT_CHANGED));
+ }
+ }
+}
+
+uchar Fl_Widget_Type::resizable() const {
+ if (is_window()) return ((Fl_Window*)o)->resizable() != 0;
+ Fl_Group* p = (Fl_Group*)o->parent();
+ if (p) return p->resizable() == o;
+ else return 0;
+}
+
+void Fl_Widget_Type::resizable(uchar v) {
+ if (v) {
+ if (resizable()) return;
+ if (is_window()) ((Fl_Window*)o)->resizable(o);
+ else {
+ Fl_Group* p = (Fl_Group*)o->parent();
+ if (p) p->resizable(o);
+ }
+ } else {
+ if (!resizable()) return;
+ if (is_window()) {
+ ((Fl_Window*)o)->resizable(0);
+ } else {
+ Fl_Group* p = (Fl_Group*)o->parent();
+ if (p) p->resizable(0);
+ }
+ }
+}
+
+void resizable_cb(Fl_Light_Button* i,void* v) {
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;}
+ if (numselected > 1) {i->hide(); return;}
+ i->show();
+ i->value(current_widget->resizable());
+ } else {
+ current_widget->resizable(i->value());
+ }
+}
+
+void hotspot_cb(Fl_Light_Button* i,void* v) {
+ if (v == LOAD) {
+ if (numselected > 1) {i->hide(); return;}
+ if (current_widget->is_menu_item()) i->label("divider");
+ else i->label("hotspot");
+ i->show();
+ i->value(current_widget->hotspot());
+ } else {
+ current_widget->hotspot(i->value());
+ if (current_widget->is_menu_item()) {current_widget->redraw(); return;}
+ if (i->value()) {
+ Fl_Type *p = current_widget->parent;
+ if (!p || !p->is_widget()) return;
+ while (!p->is_window()) p = p->parent;
+ for (Fl_Type *o = p->next; o && o->level > p->level; o = o->next) {
+ if (o->is_widget() && o != current_widget)
+ ((Fl_Widget_Type*)o)->hotspot(0);
+ }
+ }
+ }
+}
+
+void visible_cb(Fl_Light_Button* i, void* v) {
+ if (v == LOAD) {
+ i->value(current_widget->o->visible());
+ } else {
+ int n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ n ? q->o->show() : q->o->hide();
+ q->redraw();
+ }
+ }
+}
+
+void active_cb(Fl_Light_Button* i, void* v) {
+ if (v == LOAD) {
+ i->value(current_widget->o->active());
+ } else {
+ int n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ n ? q->o->activate() : q->o->deactivate();
+ q->redraw();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item fontmenu[] = {
+{"Helvetica"},
+{"Helvetica bold"},
+{"Helvetica italic"},
+{"Helvetica bold italic"},
+{"Courier"},
+{"Courier bold"},
+{"Courier italic"},
+{"Courier bold italic"},
+{"Times"},
+{"Times bold"},
+{"Times italic"},
+{"Times bold italic"},
+{"Symbol"},
+{"Terminal"},
+{"Terminal Bold"},
+{"Zapf Dingbats"},
+{0}};
+
+void labelfont_cb(Fl_Choice* i, void *v) {
+ if (v == LOAD) {
+ int n = current_widget->o->labelfont();
+ if (n > 15) n = 0;
+ i->value(n);
+ } else {
+ int n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->labelfont(n);
+ q->redraw();
+ }
+ }
+}
+
+void labelsize_cb(Fl_Value_Input* i, void *v) {
+ int n;
+ if (v == LOAD) {
+ n = current_widget->o->labelsize();
+ } else {
+ n = int(i->value());
+ if (n <= 0) n = FL_NORMAL_SIZE;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->labelsize(n);
+ q->redraw();
+ }
+ }
+ i->value(n);
+}
+
+extern const char *ui_find_image_name;
+void image_cb(Fl_Widget *a, void *) {
+ Fluid_Image *i = ui_find_image(current_widget->label());
+ if (!ui_find_image_name) return; // user hit "Cancel"
+ // if i is zero then user picked a non-existent file. So that the
+ // directory they chose is preserved, we change to a normal text label.
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* p = (Fl_Widget_Type*)o;
+ dont_touch_image = 1;
+ p->setimage(i);
+ p->label(ui_find_image_name);
+ dont_touch_image = 0;
+ }
+ label_cb(label_input,LOAD);
+ a->when(FL_WHEN_RELEASE|FL_WHEN_NOT_CHANGED);
+}
+
+Fl_Menu_Item labeltypemenu[] = {
+ {"Image...",0,image_cb,(void*)(-1)},
+ {"NORMAL_LABEL",0,0,(void*)0},
+ {"SYMBOL_LABEL",0,0,(void*)FL_SYMBOL_LABEL},
+ {"SHADOW_LABEL",0,0,(void*)FL_SHADOW_LABEL},
+ {"ENGRAVED_LABEL",0,0,(void*)FL_ENGRAVED_LABEL},
+ {"EMBOSSED_LABEL",0,0,(void*)FL_EMBOSSED_LABEL},
+ {"NO_LABEL",0,0,(void*)(FL_NO_LABEL)},
+{0}};
+
+void labeltype_cb(Fl_Choice* i, void *v) {
+ if (v == LOAD) {
+ int n;
+ if (current_widget->image) {
+ n = -1;
+ i->when(FL_WHEN_RELEASE|FL_WHEN_NOT_CHANGED);
+ } else {
+ n = current_widget->o->labeltype();
+ i->when(FL_WHEN_RELEASE);
+ }
+ for (int j = 0; j < int(sizeof(labeltypemenu)/sizeof(*labeltypemenu)); j++)
+ if (labeltypemenu[j].argument() == n) {i->value(j); break;}
+ } else {
+ int m = i->value();
+ int n = int(labeltypemenu[m].argument());
+ if (n<0) return; // should not happen
+ if (current_widget->image) label_input->activate();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* p = (Fl_Widget_Type*)o;
+ if (p->image) {
+ p->setimage(0);
+ p->o->label(p->label());
+ }
+ p->o->labeltype((Fl_Labeltype)n);
+ p->redraw();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+void color_cb(Fl_Button* i, void *v) {
+ Fl_Color c = current_widget->o->color();
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ } else {
+ Fl_Color d = fl_show_colormap(c);
+ if (d == c) return;
+ c = d;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->color(c); q->o->redraw();
+ }
+ }
+ i->color(c); i->labelcolor(contrast(FL_BLACK,c)); i->redraw();
+}
+
+void color2_cb(Fl_Button* i, void *v) {
+ Fl_Color c = current_widget->o->selection_color();
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ } else {
+ Fl_Color d = fl_show_colormap(c);
+ if (d == c) return;
+ c = d;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->selection_color(c); q->o->redraw();
+ }
+ }
+ i->color(c); i->labelcolor(contrast(FL_BLACK,c)); i->redraw();
+}
+
+void labelcolor_cb(Fl_Button* i, void *v) {
+ Fl_Color c = current_widget->o->labelcolor();
+ if (v != LOAD) {
+ Fl_Color d = fl_show_colormap(c);
+ if (d == c) return;
+ c = d;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->o->labelcolor(c); q->redraw();
+ }
+ }
+ i->color(c); i->labelcolor(contrast(FL_BLACK,c)); i->redraw();
+}
+
+static Fl_Button* relative(Fl_Widget* o, int i) {
+ Fl_Group* g = (Fl_Group*)(o->parent());
+ return (Fl_Button*)(g->child(g->find(*o)+i));
+}
+
+void align_cb(Fl_Button* i, void *v) {
+ int b = int(long(i->user_data()));
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ i->value(current_widget->o->align() & b);
+ } else {
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ int x = q->o->align();
+ int y;
+ if (i->value()) {
+ y = x | b;
+ if (b == FL_ALIGN_LEFT || b == FL_ALIGN_TOP) {
+ Fl_Button *b1 = relative(i,+1);
+ b1->clear();
+ y = y & ~(b1->argument());
+ }
+ if (b == FL_ALIGN_RIGHT || b == FL_ALIGN_BOTTOM) {
+ Fl_Button *b1 = relative(i,-1);
+ b1->clear();
+ y = y & ~(b1->argument());
+ }
+ } else {
+ y = x & ~b;
+ }
+ if (x != y) {q->o->align(y); q->redraw();}
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+void callback_cb(Fl_Input* i, void *v) {
+ if (v == LOAD) {
+ i->static_value(current_widget->callback());
+ } else {
+ const char *c = i->value();
+ const char *d = c_check(c);
+ if (d) {fl_show_message("Error in callback:",d,0); haderror = 1; return;}
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) if (o->selected) {
+ o->callback(c);
+ }
+ }
+}
+
+void user_data_cb(Fl_Input *i, void *v) {
+ if (v == LOAD) {
+ i->static_value(current_widget->user_data());
+ } else {
+ const char *c = i->value();
+ const char *d = c_check(c);
+ if (d) {fl_show_message("Error in user_data:",d,0); haderror = 1; return;}
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) if (o->selected) {
+ o->user_data(c);
+ }
+ }
+}
+
+void user_data_type_cb(Fl_Input *i, void *v) {
+ static const char *dflt = "void*";
+ if (v == LOAD) {
+ const char *c = current_widget->user_data_type();
+ if (!c) c = dflt;
+ i->static_value(c);
+ } else {
+ const char *c = i->value();
+ if (!*c) i->value(dflt);
+ else if (!strcmp(c,dflt)) c = 0;
+ const char *d = c_check(c);
+ if (!d) {
+ if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long"))
+ d = "must be pointer or long";
+ }
+ if (d) {fl_show_message("Error in type:",d,0); haderror = 1; return;}
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) if (o->selected) {
+ o->user_data_type(c);
+ }
+ }
+}
+
+// "v_attributes" let user type in random code for attribute settings:
+
+void v_input_cb(Fl_Input* i, void* v) {
+ int n = int(long(i->user_data()));
+ if (v == LOAD) {
+ i->static_value(current_widget->extra_code(n));
+ } else {
+ const char *c = i->value();
+ const char *d = c_check(c&&c[0]=='#' ? c+1 : c);
+ if (d) {fl_show_message("Error in",i->label(),d); haderror = 1; return;}
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type *t = (Fl_Widget_Type*)o;
+ t->extra_code(n,c);
+ }
+ }
+}
+
+void subclass_cb(Fl_Input* i, void* v) {
+ if (v == LOAD) {
+ if (current_widget->is_menu_item()) {i->hide(); return;} else i->show();
+ i->static_value(current_widget->subclass());
+ } else {
+ const char *c = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type *t = (Fl_Widget_Type*)o;
+ t->subclass(c);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// textstuff: set textfont, textsize, textcolor attributes:
+
+// default widget returns 0 to indicate not-implemented:
+int Fl_Widget_Type::textstuff(int, Fl_Font&, int&, Fl_Color&) {return 0;}
+
+void textfont_cb(Fl_Choice* i, void* v) {
+ Fl_Font n; int s; Fl_Color c;
+ if (v == LOAD) {
+ if (!current_widget->textstuff(0,n,s,c)) {i->hide(); return;}
+ i->show();
+ if (n > 15) n = FL_HELVETICA;
+ i->value(n);
+ } else {
+ n = (Fl_Font)i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->textstuff(1,n,s,c);
+ q->o->redraw();
+ }
+ }
+}
+
+void textsize_cb(Fl_Value_Input* i, void* v) {
+ Fl_Font n; int s; Fl_Color c;
+ if (v == LOAD) {
+ if (!current_widget->textstuff(0,n,s,c)) {i->hide(); return;}
+ i->show();
+ } else {
+ s = int(i->value());
+ if (s <= 0) s = FL_NORMAL_SIZE;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->textstuff(2,n,s,c);
+ q->o->redraw();
+ }
+ }
+ i->value(s);
+}
+
+void textcolor_cb(Fl_Button* i, void* v) {
+ Fl_Font n; int s; Fl_Color c;
+ if (v == LOAD) {
+ if (!current_widget->textstuff(0,n,s,c)) {i->hide(); return;}
+ i->show();
+ } else {
+ c = i->labelcolor();
+ Fl_Color d = fl_show_colormap(c);
+ if (d == c) return;
+ c = d;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ q->textstuff(3,n,s,c); q->o->redraw();
+ }
+ }
+ i->color(c); i->labelcolor(contrast(FL_BLACK,c)); i->redraw();
+}
+
+////////////////////////////////////////////////////////////////
+// Kludges to the panel for subclasses:
+
+void slider_size_cb(Fl_Value_Input* i, void* v) {
+ if (v == LOAD) {
+ if (current_widget->is_valuator()!=2) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Slider*)(current_widget->o))->slider_size());
+ } else {
+ double n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ if (q->is_valuator()==2) {
+ ((Fl_Slider*)(q->o))->slider_size(n);
+ q->o->redraw();
+ }
+ }
+ }
+}
+
+void min_cb(Fl_Value_Input* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_valuator()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Valuator*)(current_widget->o))->minimum());
+ } else {
+ double n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ if (q->is_valuator()) {
+ ((Fl_Valuator*)(q->o))->minimum(n);
+ q->o->redraw();
+ }
+ }
+ }
+}
+
+void max_cb(Fl_Value_Input* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_valuator()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Valuator*)(current_widget->o))->maximum());
+ } else {
+ double n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ if (q->is_valuator()) {
+ ((Fl_Valuator*)(q->o))->maximum(n);
+ q->o->redraw();
+ }
+ }
+ }
+}
+
+void step_cb(Fl_Value_Input* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_valuator()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Valuator*)(current_widget->o))->step());
+ } else {
+ double n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ if (q->is_valuator()) {
+ ((Fl_Valuator*)(q->o))->step(n);
+ q->o->redraw();
+ }
+ }
+ }
+}
+
+void value_cb(Fl_Value_Input* i, void* v) {
+ if (v == LOAD) {
+ if (current_widget->is_valuator()) {
+ i->show();
+ i->value(((Fl_Valuator*)(current_widget->o))->value());
+ } else if (current_widget->is_button()) {
+ i->show();
+ i->value(((Fl_Button*)(current_widget->o))->value());
+ } else
+ i->hide();
+ } else {
+ double n = i->value();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ if (q->is_valuator()) {
+ ((Fl_Valuator*)(q->o))->value(n);
+ } else if (q->is_button()) {
+ ((Fl_Button*)(q->o))->value(n != 0);
+ if (q->is_menu_item()) q->redraw();
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// subtypes:
+
+Fl_Menu_Item *Fl_Widget_Type::subtypes() {return 0;}
+
+void subtype_cb(Fl_Choice* i, void* v) {
+ if (v == LOAD) {
+ Fl_Menu_Item* m = current_widget->subtypes();
+ if (!m) {i->hide(); return;}
+ i->menu(m);
+ int j;
+ for (j = 0;; j++) {
+ if (!m[j].text) {j = 0; break;}
+ if (m[j].argument() == current_widget->o->type()) break;
+ }
+ i->value(j);
+ i->show();
+ i->redraw();
+ } else {
+ int n = int(i->mvalue()->argument());
+ Fl_Menu_Item* m = current_widget->subtypes();
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* q = (Fl_Widget_Type*)o;
+ if (q->subtypes()==m) {
+ q->o->type(n);
+ q->redraw();
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+static Fl_Window *the_panel;
+
+void propagate_load(Fl_Group* g, void* v) {
+ if (v == LOAD) {
+ Fl_Widget*const* a = g->array();
+ for (int i=g->children(); i--;) {
+ Fl_Widget* o = *a++;
+ o->do_callback(o,LOAD);
+ }
+ }
+}
+
+void set_cb(Fl_Button*, void*) {
+ haderror = 0;
+ Fl_Widget*const* a = the_panel->array();
+ for (int i=the_panel->children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o->changed()) {
+ o->do_callback();
+ if (haderror) return;
+ o->clear_changed();
+ }
+ }
+}
+
+void ok_cb(Fl_Return_Button* o, void* v) {
+ set_cb(o,v);
+ if (!haderror) the_panel->hide();
+}
+
+void revert_cb(Fl_Button*, void*) {
+ // We have to revert all dynamically changing fields:
+ // but for now only the first label works...
+ if (numselected == 1) current_widget->label(oldlabel);
+ propagate_load(the_panel, LOAD);
+}
+
+void cancel_cb(Fl_Button* o, void* v) {
+ revert_cb(o,v);
+ the_panel->hide();
+}
+
+void toggle_overlays(Fl_Widget *,void *); // in Fl_Window_Type.C
+void overlay_cb(Fl_Button*o,void *v) {
+ toggle_overlays(o,v);
+}
+
+// update the panel according to current widget set:
+static void load_panel() {
+ if (!the_panel) return;
+
+ // find all the Fl_Widget subclasses currently selected:
+ numselected = 0;
+ current_widget = 0;
+ if (Fl_Type::current) {
+ if (Fl_Type::current->is_widget())
+ current_widget=(Fl_Widget_Type*)Fl_Type::current;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+ if (o->is_widget() && o->selected) {
+ numselected++;
+ if (!current_widget) current_widget = (Fl_Widget_Type*)o;
+ }
+ }
+ }
+ if (numselected)
+ propagate_load(the_panel, LOAD);
+ else
+ the_panel->hide();
+}
+
+// This is called when user double-clicks an item, open or update the panel:
+void Fl_Widget_Type::open() {
+ if (!the_panel) the_panel = make_widget_panel();
+ load_panel();
+ if (numselected) the_panel->show();
+}
+
+Fl_Type *Fl_Type::current;
+
+extern void redraw_overlays();
+extern void redraw_browser();
+
+// Called when ui changes what objects are selected:
+// p is selected object, null for all deletions (we must throw away
+// old panel in that case, as the object may no longer exist)
+void selection_changed(Fl_Type *p) {
+ // store all changes to the current selected objects:
+ if (p && the_panel && the_panel->visible()) {
+ set_cb(0,0);
+ // if there was an error, we try to leave the selected set unchanged:
+ if (haderror) {
+ Fl_Type *q = 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+ o->new_selected = o->selected;
+ if (!q && o->selected) q = o;
+ }
+ if (!p || !p->selected) p = q;
+ Fl_Type::current = p;
+ redraw_browser();
+ return;
+ }
+ }
+ // update the selected flags to new set:
+ Fl_Type *q = 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
+ o->selected = o->new_selected;
+ if (!q && o->selected) q = o;
+ }
+ if (!p || !p->selected) p = q;
+ Fl_Type::current = p;
+ redraw_overlays();
+ // load the panel with the new settings:
+ load_panel();
+}
+
+////////////////////////////////////////////////////////////////
+// Writing the C code:
+
+#include <ctype.h>
+
+// test to see if user named a function, or typed in code:
+int is_name(const char *c) {
+ for (; *c; c++) if (ispunct(*c) && *c!='_') return 0;
+ return 1;
+}
+
+// Test to see if name() is an array entry. If so, and this is the
+// highest number, return name[num+1]. Return null if not the highest
+// number or a field or function. Return name() if not an array entry.
+const char *array_name(Fl_Widget_Type *o) {
+ const char *c = o->name();
+ if (!c) return 0;
+ const char *d;
+ for (d = c; *d != '['; d++) {
+ if (!*d) return c;
+ if (ispunct(*d) && *d!='_') return 0;
+ }
+ int num = atoi(d+1);
+ int sawthis = 0;
+ for (Fl_Type *t = Fl_Type::first; t; t = t->next) {
+ if (t == o) {sawthis=1; continue;}
+ const char *e = t->name();
+ if (!e) continue;
+ if (strncmp(c,e,d-c)) continue;
+ int n1 = atoi(e+(d-c)+1);
+ if (n1 > num || n1==num && sawthis) return 0;
+ }
+ static char buffer[128];
+ strncpy(buffer,c,d-c+1);
+ sprintf(buffer+(d-c+1),"%d]",num+1);
+ return buffer;
+}
+
+// Test to see if extra code is a declaration:
+int isdeclare(const char *c) {
+ while (isspace(*c)) c++;
+ if (*c == '#') return 1;
+ if (!strncmp(c,"extern",6)) return 1;
+ return 0;
+}
+
+void Fl_Widget_Type::write_declare() {
+ const char *t = subclassname(this);
+ if (!subclass()) ::write_declare("#include <FL/%s.H>", t);
+ if (callback() && is_name(callback()))
+ ::write_declare("extern void %s(%s*, %s);", callback(), t,
+ user_data_type() ? user_data_type() : "void*");
+ for (int n=0; n < NUM_EXTRA_CODE; n++) {
+ if (extra_code(n) && isdeclare(extra_code(n)))
+ ::write_declare("%s", extra_code(n));
+ }
+}
+
+void Fl_Widget_Type::write_static() {
+ const char* t = subclassname(this);
+ const char* c = array_name(this);
+ const char* k = class_name();
+ if (c && !k) {
+ write_c("\n");
+ if (!public_) write_c("static ");
+ else write_h("extern %s *%s;\n", t, c);
+ write_c("%s *%s;\n", t, c);
+ }
+ if (callback() && !is_name(callback())) {
+ // see if 'o' or 'v' used, to prevent unused argument warnings:
+ int use_o = 0;
+ int use_v = 0;
+ const char *d;
+ for (d = callback(); *d;) {
+ if (*d == 'o' && !is_id(d[1])) use_o = 1;
+ if (*d == 'v' && !is_id(d[1])) use_v = 1;
+ do d++; while (is_id(*d));
+ while (*d && !is_id(*d)) d++;
+ }
+ const char* cn = callback_name();
+ if (k) {
+ write_c("\ninline void %s::%s_i(%s*", k, cn, t);
+ } else {
+ write_c("\nstatic void %s(%s*", cn, t);
+ }
+ if (use_o) write_c(" o");
+ const char* ut = user_data_type() ? user_data_type() : "void*";
+ write_c(", %s", ut);
+ if (use_v) write_c(" v");
+ write_c(") {\n %s", callback());
+ if (*(d-1) != ';') write_c(";");
+ write_c("\n}\n");
+ if (k) {
+ write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t, ut);
+ write_c(" ((%s*)(o->", k);
+ for (Fl_Type* p = parent; p->is_widget(); p = p->parent)
+ write_c("parent()->");
+ write_c("user_data()))->%s_i(o,v);\n}\n", cn);
+ }
+ }
+ if (image) {
+ if (image->written != write_number) {
+ image->write_static();
+ image->written = write_number;
+ }
+ }
+}
+
+const char *Fl_Type::callback_name() {
+ if (is_name(callback())) return callback();
+ return unique_id(this, "cb", name(), label());
+}
+
+extern int varused_test, varused;
+
+void Fl_Widget_Type::write_code1() {
+ const char* t = subclassname(this);
+ const char *c = array_name(this);
+ if (c) {
+ if (class_name()) {
+ write_public(public_);
+ write_h(" %s *%s;\n", t, c);
+ } else if (!public_)
+ write_h("extern %s *%s;\n", t, c);
+ }
+ if (class_name() && callback() && !is_name(callback())) {
+ const char* cn = callback_name();
+ const char* ut = user_data_type() ? user_data_type() : "void*";
+ write_public(0);
+ write_h(" inline void %s_i(%s*, %s);\n", cn, t, ut);
+ write_h(" static void %s(%s*, %s);\n", cn, t, ut);
+ }
+ // figure out if local varaible will be used (prevent compiler warnings):
+ if (is_parent())
+ varused = 1;
+ else {
+ varused_test = 1; varused = 0;
+ write_widget_code();
+ varused_test = 0;
+ for (int n=0; n < NUM_EXTRA_CODE; n++)
+ if (extra_code(n) && !isdeclare(extra_code(n))) varused = 1;
+ }
+ write_c(indent());
+ if (varused) write_c("{ %s* o = ", t);
+ if (name()) write_c("%s = ", name());
+ if (is_window()) {
+ write_c("w = new %s(%d, %d", t, o->w(), o->h());
+ // prevent type() code from being emitted:
+ ((Fl_Widget_Type*)factory)->o->type(o->type());
+ } else {
+ write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
+ }
+ if (!image && label() && *label()) {
+ write_c(", ");
+ write_cstring(label());
+ }
+ write_c(");\n");
+ indentation += 2;
+ if (varused) write_widget_code();
+}
+
+// this is split from write_code1() for Fl_Window_Type:
+void Fl_Widget_Type::write_widget_code() {
+ Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
+ if (o->type() != tplate->type())
+ write_c("%so->type(%d);\n", indent(), o->type());
+ if (o->box() != tplate->box())
+ write_c("%so->box(FL_%s);\n", indent(), boxname(o->box()));
+ if (is_button()) {
+ Fl_Button* b = (Fl_Button*)o;
+ if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
+ boxname(b->down_box()));
+ if (b->value()) write_c("%so->value(1);\n", indent());
+ if (b->shortcut())
+ write_c("%so->shortcut(0x%x);\n", indent(), b->shortcut());
+ }
+ if (is_menu_button()) {
+ Fl_Menu_* b = (Fl_Menu_*)o;
+ if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
+ boxname(b->down_box()));
+ }
+ if (o->color() != tplate->color())
+ write_c("%so->color(%d);\n", indent(), o->color());
+ if (o->selection_color() != tplate->selection_color())
+ write_c("%so->selection_color(%d);\n", indent(), o->selection_color());
+ if (image)
+ image->write_code();
+ else if (o->labeltype() != tplate->labeltype())
+ write_c("%so->labeltype(FL_%s);\n", indent(),
+ item_name(labeltypemenu, o->labeltype()));
+ if (o->labelfont() != tplate->labelfont())
+ write_c("%so->labelfont(%d);\n", indent(), o->labelfont());
+ if (o->labelsize() != tplate->labelsize())
+ write_c("%so->labelsize(%d);\n", indent(), o->labelsize());
+ if (o->labelcolor() != tplate->labelcolor())
+ write_c("%so->labelcolor(%d);\n", indent(), o->labelcolor());
+ if (is_valuator()) {
+ Fl_Valuator* v = (Fl_Valuator*)o;
+ Fl_Valuator* f = (Fl_Valuator*)(tplate);
+ if (v->minimum()!=f->minimum())
+ write_c("%so->minimum(%g);\n", indent(), v->minimum());
+ if (v->maximum()!=f->maximum())
+ write_c("%so->maximum(%g);\n", indent(), v->maximum());
+ if (v->step()!=f->step())
+ write_c("%so->step(%g);\n", indent(), v->step());
+ if (v->value())
+ write_c("%so->value(%g);\n", indent(), v->value());
+ if (is_valuator()==2) {
+ double x = ((Fl_Slider*)v)->slider_size();
+ double y = ((Fl_Slider*)f)->slider_size();
+ if (x != y) write_c("%so->slider_size(%g);\n", indent(), x);
+ }
+ }
+ {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+ Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c);
+ if (f != ff) write_c("%so->textfont(%d);\n", indent(), f);
+ if (s != fs) write_c("%so->textsize(%d);\n", indent(), s);
+ if (c != fc) write_c("%so->textcolor(%d);\n",indent(), c);
+ }}
+ const char* ud = user_data();
+ if (class_name() && !parent->is_widget()) ud = "this";
+ if (callback()) {
+ write_c("%so->callback((Fl_Callback*)%s", indent(), callback_name());
+ if (ud)
+ write_c(", (void*)(%s));\n", ud);
+ else
+ write_c(");\n");
+ } else if (ud) {
+ write_c("%so->user_data((void*)(%s));\n", indent(), ud);
+ }
+ if (o->align() != tplate->align())
+ write_c("%so->align(%d);\n", indent(), o->align());
+ if (o->when() != tplate->when())
+ write_c("%so->when(%d);\n", indent(), o->when());
+ if (!o->visible() && o->parent())
+ write_c("%so->hide();\n", indent());
+ if (!o->active())
+ write_c("%so->deactivate();\n", indent());
+ if (!is_group() && resizable())
+ write_c("%sFl_Group::current()->resizable(o);\n",indent());
+ if (hotspot())
+ write_c("%sw->hotspot(o);\n", indent());
+}
+
+void Fl_Widget_Type::write_code2() {
+ indentation -= 2;
+ if (!is_parent() && !varused) return;
+ for (int n=0; n < NUM_EXTRA_CODE; n++)
+ if (extra_code(n) && !isdeclare(extra_code(n)))
+ write_c("%s %s\n", indent(), extra_code(n));
+ write_c("%s}\n", indent());
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Widget_Type::write_properties() {
+ Fl_Type::write_properties();
+ write_indent(level+1);
+ if (!public_) write_string("private");
+ write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h());
+ Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
+ if (o->type() != tplate->type()) {
+ write_string("type");
+ write_word(item_name(subtypes(), o->type()));
+ }
+ if (o->box() != tplate->box()) {
+ write_string("box"); write_word(boxname(o->box()));}
+ if (is_button()) {
+ Fl_Button* b = (Fl_Button*)o;
+ if (b->down_box()) {
+ write_string("down_box"); write_word(boxname(b->down_box()));}
+ if (b->shortcut()) write_string("shortcut 0x%x", b->shortcut());
+ if (b->value()) write_string("value 1");
+ }
+ if (is_menu_button()) {
+ Fl_Menu_* b = (Fl_Menu_*)o;
+ if (b->down_box()) {
+ write_string("down_box"); write_word(boxname(b->down_box()));}
+ }
+ if (o->color()!=tplate->color())
+ write_string("color %d", o->color());
+ if (o->selection_color()!=tplate->selection_color())
+ write_string("selection_color %d", o->selection_color());
+ if (image)
+ write_string("labeltype image");
+ else if (o->labeltype()!=tplate->labeltype()) {
+ write_string("labeltype");
+ write_word(item_name(labeltypemenu, o->labeltype()));
+ }
+ if (o->labelfont()!=tplate->labelfont())
+ write_string("labelfont %d", o->labelfont());
+ if (o->labelsize()!=tplate->labelsize())
+ write_string("labelsize %d", o->labelsize());
+ if (o->labelcolor()!=tplate->labelcolor())
+ write_string("labelcolor %d", o->labelcolor());
+ if (o->align()!=tplate->align())
+ write_string("align %d", o->align());
+ if (o->when() != tplate->when())
+ write_string("when %d", o->when());
+ if (is_valuator()) {
+ Fl_Valuator* v = (Fl_Valuator*)o;
+ Fl_Valuator* f = (Fl_Valuator*)(tplate);
+ if (v->minimum()!=f->minimum()) write_string("minimum %g",v->minimum());
+ if (v->maximum()!=f->maximum()) write_string("maximum %g",v->maximum());
+ if (v->step()!=f->step()) write_string("step %g",v->step());
+ if (v->value()!=0.0) write_string("value %g",v->value());
+ if (is_valuator()==2) {
+ double x = ((Fl_Slider*)v)->slider_size();
+ double y = ((Fl_Slider*)f)->slider_size();
+ if (x != y) write_string("slider_size %g", x);
+ }
+ }
+ {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+ Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c);
+ if (f != ff) write_string("textfont %d", f);
+ if (s != fs) write_string("textsize %d", s);
+ if (c != fc) write_string("textcolor %d", c);
+ }}
+ if (!o->visible()) write_string("hide");
+ if (!o->active()) write_string("deactivate");
+ if (resizable()) write_string("resizable");
+ if (hotspot()) write_string(is_menu_item() ? "divider" : "hotspot");
+ for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n)) {
+ write_indent(level+1);
+ write_string("code%d",n);
+ write_word(extra_code(n));
+ }
+ if (subclass()) {
+ write_indent(level+1);
+ write_string("class");
+ write_word(subclass());
+ }
+}
+
+int pasteoffset;
+
+void Fl_Widget_Type::read_property(const char *c) {
+ int x,y,w,h; Fl_Font f; int s; Fl_Color cc;
+ if (!strcmp(c,"private")) {
+ public_ = 0;
+ } else if (!strcmp(c,"xywh")) {
+ if (sscanf(read_word(),"%d %d %d %d",&x,&y,&w,&h) == 4) {
+ x += pasteoffset;
+ y += pasteoffset;
+ o->resize(x,y,w,h);
+ }
+ } else if (!strcmp(c,"type")) {
+ o->type(item_number(subtypes(), read_word()));
+ } else if (!strcmp(c,"box")) {
+ const char* value = read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ o->box((Fl_Boxtype)x);
+ } else if (sscanf(value,"%d",&x) == 1) o->box((Fl_Boxtype)x);
+ } else if (is_button() && !strcmp(c,"down_box")) {
+ const char* value = read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ ((Fl_Button*)o)->down_box((Fl_Boxtype)x);
+ }
+ } else if (is_menu_button() && !strcmp(c,"down_box")) {
+ const char* value = read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ ((Fl_Menu_*)o)->down_box((Fl_Boxtype)x);
+ }
+ } else if (is_button() && !strcmp(c,"value")) {
+ const char* value = read_word();
+ ((Fl_Button*)o)->value(atoi(value));
+ } else if (!strcmp(c,"color")) {
+ int n = sscanf(read_word(),"%d %d",&x,&y);
+ if (n == 2) { // back compatability...
+ if (x != 47) o->color(x);
+ o->selection_color(y);
+ } else {
+ o->color(x);
+ }
+ } else if (!strcmp(c,"selection_color")) {
+ if (sscanf(read_word(),"%d",&x)) o->selection_color(x);
+ } else if (!strcmp(c,"labeltype")) {
+ c = read_word();
+ if (!strcmp(c,"image")) {
+ Fluid_Image *i = Fluid_Image::find(label());
+ if (!i) read_error("Image file '%s' not found", label());
+ else setimage(i);
+ } else {
+ o->labeltype((Fl_Labeltype)item_number(labeltypemenu,c));
+ }
+ } else if (!strcmp(c,"labelfont")) {
+ if (sscanf(read_word(),"%d",&x) == 1) o->labelfont(x);
+ } else if (!strcmp(c,"labelsize")) {
+ if (sscanf(read_word(),"%d",&x) == 1) o->labelsize(x);
+ } else if (!strcmp(c,"labelcolor")) {
+ if (sscanf(read_word(),"%d",&x) == 1) o->labelcolor(x);
+ } else if (!strcmp(c,"align")) {
+ if (sscanf(read_word(),"%d",&x) == 1) o->align(x);
+ } else if (!strcmp(c,"when")) {
+ if (sscanf(read_word(),"%d",&x) == 1) o->when(x);
+ } else if (!strcmp(c,"minimum") && is_valuator()) {
+ ((Fl_Valuator*)o)->minimum(strtod(read_word(),0));
+ } else if (!strcmp(c,"maximum") && is_valuator()) {
+ ((Fl_Valuator*)o)->maximum(strtod(read_word(),0));
+ } else if (!strcmp(c,"step") && is_valuator()) {
+ ((Fl_Valuator*)o)->step(strtod(read_word(),0));
+ } else if (!strcmp(c,"value") && is_valuator()) {
+ ((Fl_Valuator*)o)->value(strtod(read_word(),0));
+ } else if ((!strcmp(c,"slider_size")||!strcmp(c,"size"))&&is_valuator()==2) {
+ ((Fl_Slider*)o)->slider_size(strtod(read_word(),0));
+ } else if (!strcmp(c,"textfont")) {
+ if (sscanf(read_word(),"%d",&x) == 1) {f=(Fl_Font)x; textstuff(1,f,s,cc);}
+ } else if (!strcmp(c,"textsize")) {
+ if (sscanf(read_word(),"%d",&x) == 1) {s=x; textstuff(2,f,s,cc);}
+ } else if (!strcmp(c,"textcolor")) {
+ if (sscanf(read_word(),"%d",&x) == 1) {cc=(Fl_Color)x;textstuff(3,f,s,cc);}
+ } else if (!strcmp(c,"hide")) {
+ o->hide();
+ } else if (!strcmp(c,"deactivate")) {
+ o->deactivate();
+ } else if (!strcmp(c,"resizable")) {
+ resizable(1);
+ } else if (!strcmp(c,"hotspot") || !strcmp(c, "divider")) {
+ hotspot(1);
+ } else if (!strcmp(c,"class")) {
+ subclass(read_word());
+ } else if (is_button() && !strcmp(c,"shortcut")) {
+ ((Fl_Button*)o)->shortcut(strtol(read_word(),0,0));
+ } else {
+ if (!strncmp(c,"code",4)) {
+ int n = atoi(c+4);
+ if (n >= 0 && n <= NUM_EXTRA_CODE) {
+ extra_code(n,read_word());
+ return;
+ }
+ }
+ Fl_Type::read_property(c);
+ }
+}
+
+Fl_Menu_Item boxmenu1[] = {
+ // these extra ones are for looking up fdesign saved strings:
+ {"NO_FRAME", 0,0,(void *)FL_NO_BOX},
+ {"ROUNDED3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX},
+ {"ROUNDED3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX},
+ {"OVAL3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX},
+ {"OVAL3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX},
+ {"0", 0,0,(void *)ZERO_ENTRY},
+ {"1", 0,0,(void *)FL_UP_BOX},
+ {"2", 0,0,(void *)FL_DOWN_BOX},
+ {"3", 0,0,(void *)FL_FLAT_BOX},
+ {"4", 0,0,(void *)FL_BORDER_BOX},
+ {"5", 0,0,(void *)FL_SHADOW_BOX},
+ {"6", 0,0,(void *)FL_FRAME_BOX},
+ {"7", 0,0,(void *)FL_ROUNDED_BOX},
+ {"8", 0,0,(void *)FL_RFLAT_BOX},
+ {"9", 0,0,(void *)FL_RSHADOW_BOX},
+ {"10", 0,0,(void *)FL_UP_FRAME},
+ {"11", 0,0,(void *)FL_DOWN_FRAME},
+{0}};
+
+extern int fdesign_flip;
+int lookup_symbol(const char *, int &, int numberok = 0);
+
+int Fl_Widget_Type::read_fdesign(const char* name, const char* value) {
+ int v;
+ if (!strcmp(name,"box")) {
+ float x,y,w,h;
+ if (sscanf(value,"%f %f %f %f",&x,&y,&w,&h) == 4) {
+ if (fdesign_flip) {
+ Fl_Type *p;
+ for (p = parent; p && !p->is_window(); p = p->parent);
+ if (p && p->is_widget()) y = ((Fl_Widget_Type*)p)->o->h()-(y+h);
+ }
+ x += pasteoffset;
+ y += pasteoffset;
+ o->resize(int(x),int(y),int(w),int(h));
+ }
+ } else if (!strcmp(name,"label")) {
+ label(value);
+ if (value[0] == '@') o->labeltype(FL_SYMBOL_LABEL);
+ } else if (!strcmp(name,"name")) {
+ this->name(value);
+ } else if (!strcmp(name,"callback")) {
+ callback(value); user_data_type("long");
+ } else if (!strcmp(name,"argument")) {
+ user_data(value);
+ } else if (!strcmp(name,"shortcut")) {
+ if (value[0]) {
+ char buf[128]; sprintf(buf,"o->shortcut(\"%s\");",value);
+ extra_code(0,buf);
+ }
+ } else if (!strcmp(name,"style")) {
+ if (!strncmp(value,"FL_NORMAL",9)) return 1;
+ if (!lookup_symbol(value,v,1)) return 0;
+ o->labelfont(v); o->labeltype((Fl_Labeltype)(v>>8));
+ } else if (!strcmp(name,"size")) {
+ if (!lookup_symbol(value,v,1)) return 0;
+ o->labelsize(v);
+ } else if (!strcmp(name,"type")) {
+ if (!strncmp(value,"NORMAL",6)) return 1;
+ if (lookup_symbol(value,v,1)) {o->type(v); return 1;}
+ if (!strcmp(value+strlen(value)-5,"FRAME")) goto TRY_BOXTYPE;
+ if (!strcmp(value+strlen(value)-3,"BOX")) goto TRY_BOXTYPE;
+ return 0;
+ } else if (!strcmp(name,"lcol")) {
+ if (!lookup_symbol(value,v,1)) return 0;
+ o->labelcolor(v);
+ } else if (!strcmp(name,"return")) {
+ if (!lookup_symbol(value,v,0)) return 0;
+ o->when(v|FL_WHEN_RELEASE);
+ } else if (!strcmp(name,"alignment")) {
+ if (!lookup_symbol(value,v)) {
+ // convert old numeric values:
+ int v1 = atoi(value); if (v1 <= 0 && strcmp(value,"0")) return 0;
+ v = 0;
+ if (v1 >= 5) {v = FL_ALIGN_INSIDE; v1 -= 5;}
+ switch (v1) {
+ case 0: v += FL_ALIGN_TOP; break;
+ case 1: v += FL_ALIGN_BOTTOM; break;
+ case 2: v += FL_ALIGN_LEFT; break;
+ case 3: v += FL_ALIGN_RIGHT; break;
+ case 4: v += FL_ALIGN_CENTER; break;
+ default: return 0;
+ }
+ }
+ o->align(v);
+ } else if (!strcmp(name,"resizebox")) {
+ resizable(1);
+ } else if (!strcmp(name,"colors")) {
+ char* p = (char*)value;
+ while (*p != ' ') {if (!*p) return 0; p++;}
+ *p = 0;
+ int v1;
+ if (!lookup_symbol(value,v,1) || !lookup_symbol(p+1,v1,1)) {
+ *p=' '; return 0;}
+ o->color(v,v1);
+ } else if (!strcmp(name,"resize")) {
+ return !strcmp(value,"FL_RESIZE_ALL");
+ } else if (!strcmp(name,"gravity")) {
+ return !strcmp(value,"FL_NoGravity FL_NoGravity");
+ } else if (!strcmp(name,"boxtype")) {
+ TRY_BOXTYPE:
+ int x = boxnumber(value);
+ if (!x) {x = item_number(boxmenu1, value); if (x < 0) return 0;}
+ if (x == ZERO_ENTRY) {
+ x = 0;
+ if (o->box() != ((Fl_Widget_Type*)factory)->o->box()) return 1; // kludge for frame
+ }
+ o->box((Fl_Boxtype)x);
+ } else {
+ return 0;
+ }
+ return 1;
+}
diff --git a/fluid/Fl_Widget_Type.h b/fluid/Fl_Widget_Type.h
new file mode 100644
index 000000000..c911054fa
--- /dev/null
+++ b/fluid/Fl_Widget_Type.h
@@ -0,0 +1,67 @@
+// Fl_Widget_Type.H
+
+// Type for creating all subclasses of Fl_Widget
+// This should have the widget pointer in it, but it is still in the
+// Fl_Type base class.
+
+#include "Fl_Type.H"
+
+struct Fl_Menu_Item;
+class Fluid_Image;
+
+#define NUM_EXTRA_CODE 4
+
+class Fl_Widget_Type : public Fl_Type {
+ virtual Fl_Widget *widget(int,int,int,int) = 0;
+ virtual Fl_Widget_Type *_make() = 0; // virtual constructor
+ virtual void setlabel(const char *);
+
+ const char *extra_code_[NUM_EXTRA_CODE];
+ const char *subclass_;
+ uchar hotspot_;
+
+protected:
+
+ void write_declare();
+ void write_static();
+ void write_code1();
+ void write_widget_code();
+ void write_code2();
+
+public:
+
+ const char *xclass; // junk string, used for shortcut
+ Fl_Widget *o;
+ int public_;
+
+ Fluid_Image *image;
+ void setimage(Fluid_Image *);
+
+ Fl_Widget_Type();
+ Fl_Type *make();
+ void open();
+
+ const char *extra_code(int n) const {return extra_code_[n];}
+ void extra_code(int n,const char *);
+ const char *subclass() const {return subclass_;}
+ void subclass(const char *);
+ uchar hotspot() const {return hotspot_;}
+ void hotspot(uchar v) {hotspot_ = v;}
+ uchar resizable() const;
+ void resizable(uchar v);
+
+ virtual int textstuff(int what, Fl_Font &, int &, Fl_Color &);
+ virtual Fl_Menu_Item *subtypes();
+
+ virtual int is_widget() const;
+
+ virtual void write_properties();
+ virtual void read_property(const char *);
+ virtual int read_fdesign(const char*, const char*);
+
+ ~Fl_Widget_Type();
+ void redraw();
+};
+
+void* const LOAD = (void *)9831;
+extern Fl_Widget_Type *current_widget; // one of the selected ones
diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx
new file mode 100644
index 000000000..044c8233f
--- /dev/null
+++ b/fluid/Fl_Window_Type.cxx
@@ -0,0 +1,666 @@
+/* Fl_Window_Type.C
+
+ The widget describing an Fl_Window. This is also all the code
+ for interacting with the overlay, which allows the user to
+ select, move, and resize the children widgets.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/Fl_Overlay_Window.H>
+#include <FL/fl_message.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_Item.H>
+#include "Fl_Widget_Type.H"
+#include <math.h>
+#include <stdlib.h>
+#include "alignment_panel.H"
+#include <stdio.h>
+
+int gridx = 5;
+int gridy = 5;
+int snap = 3;
+
+void alignment_cb(Fl_Input *i, long v) {
+ int n = atoi(i->value());
+ if (n < 0) n = 0;
+ switch (v) {
+ case 1: gridx = n; break;
+ case 2: gridy = n; break;
+ case 3: snap = n; break;
+ }
+}
+
+extern const char* header_file_name;
+extern const char* code_file_name;
+
+void show_alignment_cb(Fl_Widget *, void *) {
+ make_alignment_window();
+ header_file_input->value(header_file_name);
+ code_file_input->value(code_file_name);
+ char buf[128];
+ sprintf(buf,"%d",gridx); horizontal_input->value(buf);
+ sprintf(buf,"%d",gridy); vertical_input->value(buf);
+ sprintf(buf,"%d",snap); snap_input->value(buf);
+ alignment_window->show();
+}
+
+void header_input_cb(Fl_Input* i, void*) {
+ header_file_name = i->value();
+}
+void code_input_cb(Fl_Input* i, void*) {
+ code_file_name = i->value();
+ printf("code file name set to %s\n", code_file_name);
+}
+
+////////////////////////////////////////////////////////////////
+
+static Fl_Menu_Item window_type_menu[] = {
+ {"Single",0,0,(void*)FL_WINDOW},
+ {"Double",0,0,(void*)(FL_WINDOW+1)},
+ {0}};
+class Fl_Window_Type : public Fl_Widget_Type {
+ Fl_Menu_Item* subtypes() {return window_type_menu;}
+
+ friend class Overlay_Window;
+ int mx,my; // mouse position during dragging
+ int x1,y1; // initial position of selection box
+ int bx,by,br,bt; // bounding box of selection
+ int dx,dy;
+ int drag; // which parts of bbox are being moved
+ int numselected; // number of children selected
+ enum {LEFT=1,RIGHT=2,BOTTOM=4,TOP=8,DRAG=16,BOX=32};
+ void draw_overlay();
+ void newdx();
+ void newposition(Fl_Widget_Type *,int &x,int &y,int &w,int &h);
+ int handle(int);
+ virtual void setlabel(const char *);
+ void write_code1();
+ void write_code2();
+ Fl_Widget_Type *_make() {return 0;} // we don't call this
+ Fl_Widget *widget(int,int,int,int) {return 0;}
+ int recalc; // set by fix_overlay()
+
+public:
+
+ uchar modal, non_modal;
+
+ Fl_Type *make();
+ virtual const char *type_name() {return "Fl_Window";}
+
+ void open();
+
+ void fix_overlay(); // update the bounding box, etc
+
+ virtual void write_properties();
+ virtual void read_property(const char *);
+ virtual int read_fdesign(const char*, const char*);
+
+ void add_child(Fl_Type*, Fl_Type*);
+ void move_child(Fl_Type*, Fl_Type*);
+ void remove_child(Fl_Type*);
+
+ int is_parent() const {return 1;}
+ int is_group() const {return 1;}
+ int is_window() const {return 1;}
+};
+
+static int overlays_invisible;
+
+// The following Fl_Widget is used to simulate the windows. It has
+// an overlay for the fluid ui, and special-cases the FL_NO_BOX.
+
+class Overlay_Window : public Fl_Overlay_Window {
+ void draw();
+ void draw_overlay();
+public:
+ Fl_Window_Type *window;
+ int handle(int);
+ Overlay_Window(int w,int h) : Fl_Overlay_Window(w,h) {Fl_Group::current(0);}
+ void resize(int,int,int,int);
+};
+void Overlay_Window::draw() {
+ const int CHECKSIZE = 8;
+ // see if box is clear or a frame or rounded:
+ if ((damage()&128) &&
+ (!box() || (box()>=4&&!(box()&2)) || box()>=_FL_ROUNDED_BOX)) {
+ // if so, draw checkerboard so user can see what areas are clear:
+ for (int y = 0; y < h(); y += CHECKSIZE)
+ for (int x = 0; x < w(); x += CHECKSIZE) {
+ fl_color(((y/(2*CHECKSIZE))&1) != ((x/(2*CHECKSIZE))&1) ?
+ FL_WHITE : FL_BLACK);
+ fl_rectf(x,y,CHECKSIZE,CHECKSIZE);
+ }
+ }
+ Fl_Overlay_Window::draw();
+}
+
+void Overlay_Window::draw_overlay() {
+ window->draw_overlay();
+}
+int Overlay_Window::handle(int e) {
+ return window->handle(e);
+}
+
+Fl_Type *Fl_Window_Type::make() {
+ Fl_Type *p = Fl_Type::current;
+ while (p && !p->is_code_block()) p = p->parent;
+ if (!p) {
+ fl_message("Please select a function");
+ return 0;
+ }
+ Fl_Window_Type *o = new Fl_Window_Type();
+ if (!this->o) {// template widget
+ this->o = new Fl_Window(100,100);
+ Fl_Group::current(0);
+ }
+ o->factory = this;
+ o->drag = 0;
+ o->numselected = 0;
+ Overlay_Window *w = new Overlay_Window(100,100);
+ w->window = o;
+ o->o = w;
+ o->add(p);
+ o->modal = 0;
+ o->non_modal = 0;
+ return o;
+}
+
+void Fl_Window_Type::add_child(Fl_Type* cc, Fl_Type* before) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+ ((Fl_Window*)o)->insert(*(c->o), b);
+ o->redraw();
+}
+
+void Fl_Window_Type::remove_child(Fl_Type* cc) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ ((Fl_Window*)o)->remove(c->o);
+ o->redraw();
+}
+
+void Fl_Window_Type::move_child(Fl_Type* cc, Fl_Type* before) {
+ Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+ ((Fl_Window*)o)->remove(c->o);
+ Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+ ((Fl_Window*)o)->insert(*(c->o), b);
+ o->redraw();
+}
+
+////////////////////////////////////////////////////////////////
+
+// Double-click on window widget shows the window, or if already shown,
+// it shows the control panel.
+void Fl_Window_Type::open() {
+ Overlay_Window *w = (Overlay_Window *)o;
+ if (w->shown()) {
+ w->show();
+ Fl_Widget_Type::open();
+ } else {
+ Fl_Widget *p = w->resizable();
+ if (!p) w->resizable(w);
+ w->show();
+ w->resizable(p);
+ }
+}
+
+// control panel items:
+#include "widget_panel.H"
+
+void modal_cb(Fl_Light_Button* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_window()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Window_Type *)current_widget)->modal);
+ } else {
+ ((Fl_Window_Type *)current_widget)->modal = i->value();
+ }
+}
+
+void non_modal_cb(Fl_Light_Button* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_window()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Window_Type *)current_widget)->non_modal);
+ } else {
+ ((Fl_Window_Type *)current_widget)->non_modal = i->value();
+ }
+}
+
+void border_cb(Fl_Light_Button* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_window()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Window*)(current_widget->o))->border());
+ } else {
+ ((Fl_Window*)(current_widget->o))->border(i->value());
+ }
+}
+
+void xclass_cb(Fl_Input* i, void* v) {
+ if (v == LOAD) {
+ if (!current_widget->is_window()) {i->hide(); return;}
+ i->show();
+ i->value(((Fl_Widget_Type *)current_widget)->xclass);
+ } else {
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected && o->is_widget()) {
+ Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+ if (w->is_window() || w->is_button())
+ storestring(i->value(),w->xclass);
+ if (w->is_window()) ((Fl_Window*)(w->o))->xclass(w->xclass);
+ else if (w->is_menu_item()) w->redraw();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window_Type::setlabel(const char *n) {
+ if (o) ((Fl_Window *)o)->label(n);
+}
+
+// make() is called on this widget when user picks window off New menu:
+Fl_Window_Type Fl_Window_type;
+
+// Resize from window manager, try to resize it back to a legal size.
+// This is not proper X behavior, but works on 4DWM and fvwm
+void Overlay_Window::resize(int X,int Y,int W,int H) {
+ if (!visible() || W==w() && H==h()) {
+ Fl_Overlay_Window::resize(X,Y,W,H);
+ return;
+ }
+ int nw = gridx&&W!=w() ? ((W+gridx/2)/gridx)*gridx : W;
+ int nh = gridy&&H!=h() ? ((H+gridy/2)/gridy)*gridy : H;
+ Fl_Widget* t = resizable(); resizable(0);
+ Fl_Overlay_Window::resize(X,Y,W,H);
+ resizable(t);
+ // make sure new window size surrounds the widgets:
+ int b = 0;
+ int r = 0;
+ for (Fl_Type *o=window->next; o && o->level>window->level; o=o->next)
+ if (o->is_widget() && !o->is_menu_item()) {
+ Fl_Widget* w = ((Fl_Widget_Type*)o)->o;
+ if (w->x()+w->w() > r) r = w->x()+w->w();
+ if (w->y()+w->h() > b) b = w->y()+w->h();
+ }
+ if (nh < b) nh = b;
+ if (nw < r) nw = r;
+ // If changed, tell the window manager. Skip really big windows
+ // that might be bigger than screen:
+ if (nw != W && nw < Fl::w()-100 || nh != H && nh < Fl::h()-100) size(nw,nh);
+}
+
+// calculate actual move by moving mouse position (mx,my) to
+// nearest multiple of gridsize, and snap to original position
+void Fl_Window_Type::newdx() {
+ int dx, dy;
+ if (Fl::event_state(FL_ALT)) {
+ dx = mx-x1;
+ dy = my-y1;
+ } else {
+ int dx0 = mx-x1;
+ int ix = (drag&RIGHT) ? br : bx;
+ dx = gridx ? ((ix+dx0+gridx/2)/gridx)*gridx - ix : dx0;
+ if (dx0 > snap) {
+ if (dx < 0) dx = 0;
+ } else if (dx0 < -snap) {
+ if (dx > 0) dx = 0;
+ } else
+ dx = 0;
+ int dy0 = my-y1;
+ int iy = (drag&BOTTOM) ? by : bt;
+ dy = gridy ? ((iy+dy0+gridy/2)/gridy)*gridy - iy : dy0;
+ if (dy0 > snap) {
+ if (dy < 0) dy = 0;
+ } else if (dy0 < -snap) {
+ if (dy > 0) dy = 0;
+ } else
+ dy = 0;
+ }
+ if (this->dx != dx || this->dy != dy) {
+ this->dx = dx; this->dy = dy;
+ ((Overlay_Window *)(this->o))->redraw_overlay();
+ }
+}
+
+// Move a widget according to dx and dy calculated above
+void Fl_Window_Type::newposition(Fl_Widget_Type *o,int &X,int &Y,int &R,int &T) {
+ X = o->o->x();
+ Y = o->o->y();
+ R = X+o->o->w();
+ T = Y+o->o->h();
+ if (!drag) return;
+ if (drag&DRAG) {
+ X += dx;
+ Y += dy;
+ R += dx;
+ T += dy;
+ } else {
+ if (drag&LEFT) if (X==bx) X += dx; else if (X<bx+dx) X = bx+dx;
+ if (drag&BOTTOM) if (Y==by) Y += dy; else if (Y<by+dy) Y = by+dy;
+ if (drag&RIGHT) if (R==br) R += dx; else if (R>br+dx) R = br+dx;
+ if (drag&TOP) if (T==bt) T += dy; else if (T>bt+dx) T = bt+dx;
+ }
+ if (R<X) {int n = X; X = R; R = n;}
+ if (T<Y) {int n = Y; Y = T; T = n;}
+}
+
+void Fl_Window_Type::draw_overlay() {
+ if (recalc) {
+ bx = o->w(); by = o->h(); br = 0; bt = 0;
+ numselected = 0;
+ for (Fl_Type *q=next; q && q->level>level; q=q->next)
+ if (q->selected && q->is_widget() && !q->is_menu_item()) {
+ numselected++;
+ Fl_Widget_Type* o = (Fl_Widget_Type*)q;
+ if (o->o->x() < bx) bx = o->o->x();
+ if (o->o->y() < by) by = o->o->y();
+ if (o->o->x()+o->o->w() > br) br = o->o->x()+o->o->w();
+ if (o->o->y()+o->o->h() > bt) bt = o->o->y()+o->o->h();
+ }
+ recalc = 0;
+ }
+ fl_color(FL_RED);
+ if (drag==BOX && (x1 != mx || y1 != my)) {
+ int x = x1; int r = mx; if (x > r) {x = mx; r = x1;}
+ int y = y1; int b = my; if (y > b) {y = my; b = y1;}
+ fl_rect(x,y,r-x,b-y);
+ }
+ if (overlays_invisible) return;
+ if (selected) fl_rect(0,0,o->w(),o->h());
+ if (!numselected) return;
+ int bx,by,br,bt;
+ bx = o->w(); by = o->h(); br = 0; bt = 0;
+ for (Fl_Type *q=next; q && q->level>level; q = q->next)
+ if (q->selected && q->is_widget() && !q->is_menu_item()) {
+ Fl_Widget_Type* o = (Fl_Widget_Type*)q;
+ int x,y,r,t;
+ newposition(o,x,y,r,t);
+ fl_rect(x,y,r-x,t-y);
+ if (x < bx) bx = x;
+ if (y < by) by = y;
+ if (r > br) br = r;
+ if (t > bt) bt = t;
+ }
+ if (selected) return;
+ if (numselected>1) fl_rect(bx,by,br-bx,bt-by);
+ fl_rectf(bx,by,5,5);
+ fl_rectf(br-5,by,5,5);
+ fl_rectf(br-5,bt-5,5,5);
+ fl_rectf(bx,bt-5,5,5);
+}
+
+// Calculate new bounding box of selected widgets:
+void Fl_Window_Type::fix_overlay() {
+ overlays_invisible = 0;
+ recalc = 1;
+ ((Overlay_Window *)(this->o))->redraw_overlay();
+}
+
+// do that for every window (when selected set changes):
+void redraw_overlays() {
+ for (Fl_Type *o=Fl_Type::first; o; o=o->next)
+ if (o->is_window()) ((Fl_Window_Type*)o)->fix_overlay();
+}
+
+void toggle_overlays(Fl_Widget *,void *) {
+ overlays_invisible = !overlays_invisible;
+ for (Fl_Type *o=Fl_Type::first; o; o=o->next)
+ if (o->is_window()) {
+ Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+ ((Overlay_Window*)(w->o))->redraw_overlay();
+ }
+}
+
+extern void select(Fl_Type *,int);
+extern void select_only(Fl_Type *);
+extern void deselect();
+extern Fl_Type* in_this_only;
+extern void fix_group_size(Fl_Type *t);
+
+extern Fl_Menu_Item Main_Menu[];
+extern Fl_Menu_Item New_Menu[];
+
+int Fl_Window_Type::handle(int event) {
+ static Fl_Type* selection;
+ switch (event) {
+ case FL_PUSH:
+ x1 = mx = Fl::event_x();
+ y1 = my = Fl::event_y();
+ drag = 0;
+ // test for popup menu:
+ if (Fl::event_button() >= 3) {
+ in_this_only = this; // modifies how some menu items work.
+ static const Fl_Menu_Item* prev;
+ const Fl_Menu_Item* m = New_Menu->popup(mx,my,"New",prev);
+ if (m && m->callback()) {prev = m; m->do_callback(this->o);}
+ in_this_only = 0;
+ return 1;
+ }
+ // find the innermost item clicked on:
+ selection = this;
+ {for (Fl_Type* i=next; i && i->level>level; i=i->next)
+ if (i->is_widget() && !i->is_menu_item()) {
+ Fl_Widget_Type* o = (Fl_Widget_Type*)i;
+ for (Fl_Widget *o1 = o->o; o1; o1 = o1->parent())
+ if (!o1->visible()) goto CONTINUE2;
+ if (Fl::event_inside(o->o)) selection = o;
+ CONTINUE2:;
+ }}
+ // do object-specific selection of other objects:
+ {Fl_Type* t = selection->click_test(mx, my);
+ if (t) {
+ //if (t == selection) return 1; // indicates mouse eaten w/o change
+ if (Fl::event_state(FL_SHIFT)) {
+ Fl::event_is_click(0);
+ select(t, !t->selected);
+ } else {
+ deselect();
+ select(t, 1);
+ if (t->is_menu_item()) t->open();
+ }
+ selection = t;
+ return 1;
+ }}
+ // see if user grabs edges of selected region:
+ if (numselected && !overlays_invisible && !(Fl::event_state(FL_SHIFT)) &&
+ mx<=br+snap && mx>=bx-snap && my<=bt+snap && my>=by-snap) {
+ int snap1 = snap>5 ? snap : 5;
+ int w1 = (br-bx)/4; if (w1 > snap1) w1 = snap1;
+ if (mx>=br-w1) drag |= RIGHT;
+ else if (mx<bx+w1) drag |= LEFT;
+ w1 = (bt-by)/4; if (w1 > snap1) w1 = snap1;
+ if (my<=by+w1) drag |= BOTTOM;
+ else if (my>bt-w1) drag |= TOP;
+ if (!drag) drag = DRAG;
+ } else {
+ drag = BOX; // start a new selection region
+ }
+ return 1;
+ case FL_DRAG:
+ if (!drag) return 0;
+ mx = Fl::event_x();
+ my = Fl::event_y();
+ newdx();
+ return 1;
+ case FL_RELEASE:
+ if (!drag) return 0;
+ mx = Fl::event_x();
+ my = Fl::event_y();
+ newdx();
+ if (drag != BOX && (dx || dy || !Fl::event_is_click())) {
+ if (dx || dy) {
+ Fl_Type *i;
+ for (i=next; i && i->level>level;) {
+ if (i->selected && i->is_widget() && !i->is_menu_item()) {
+ Fl_Widget_Type* o = (Fl_Widget_Type*)i;
+ int x,y,r,t;
+ newposition(o,x,y,r,t);
+ o->o->resize(x,y,r-x,t-y);
+ // move all the children, whether selected or not:
+ Fl_Type* p;
+ for (p = o->next; p && p->level>o->level; p = p->next)
+ if (p->is_widget() && !p->is_menu_item()) {
+ Fl_Widget_Type* o = (Fl_Widget_Type*)p;
+ int x,y,r,t;
+ newposition(o,x,y,r,t);
+ o->o->resize(x,y,r-x,t-y);
+ }
+ i = p;
+ } else {
+ i = i->next;
+ }
+ }
+ for (i=next; i && i->level>level; i=i->next) fix_group_size(i);
+ this->o->redraw();
+ fix_overlay();
+ modflag = 1;
+ }
+ } else if ((Fl::event_clicks() || Fl::event_state(FL_CTRL))) {
+ Fl_Widget_Type::open();
+ } else {
+ if (mx<x1) {int t = x1; x1 = mx; mx = t;}
+ if (my<y1) {int t = y1; y1 = my; my = t;}
+ int n = 0;
+ int toggle = Fl::event_state(FL_SHIFT);
+ // clear selection on everything:
+ if (!toggle) deselect(); else Fl::event_is_click(0);
+ // select everything in box:
+ for (Fl_Type*i=next; i&&i->level>level; i=i->next)
+ if (i->is_widget() && !i->is_menu_item()) {
+ Fl_Widget_Type* o = (Fl_Widget_Type*)i;
+ for (Fl_Widget *o1 = o->o; o1; o1 = o1->parent())
+ if (!o1->visible()) goto CONTINUE;
+ if (Fl::event_inside(o->o)) selection = o;
+ if (o->o->x()>=x1 && o->o->y()>y1 &&
+ o->o->x()+o->o->w()<mx && o->o->y()+o->o->h()<my) {
+ n++;
+ select(o, toggle ? !o->selected : 1);
+ }
+ CONTINUE:;
+ }
+ // if nothing in box, select what was clicked on:
+ if (!n) {
+ select(selection, toggle ? !selection->selected : 1);
+ }
+ }
+ drag = 0;
+ return 1;
+
+ case FL_KEYBOARD: {
+ if (Fl::event_key() == FL_Escape) {((Fl_Window*)o)->hide(); return 1;}
+ // find current child:
+ Fl_Type *i = Fl_Type::current;
+ while (i && (!i->is_widget() || i->is_menu_item())) i = i->parent;
+ if (!i) return 0;
+ Fl_Type *p = i->parent;
+ while (p && p != this) p = p->parent;
+ if (!p || !p->is_widget()) {i=next; if (!i || i->level <= level) return 0;}
+ p = i;
+ // try to navigate to another child:
+ for (;;) {
+ switch (Fl::event_key()) {
+ case FL_Tab:
+ if (Fl::event_state(FL_SHIFT)) goto LEFT;
+ case FL_Right:
+ case FL_Down:
+ i = i->next; break;
+ case FL_Left:
+ case FL_Up:
+ LEFT:
+ i = i->prev; break;
+ default:
+ return 0;
+ }
+ if (!i || i->level <= level) {i = p; break;}
+ if (!i->is_widget() || i->is_menu_item()) continue;
+ switch (Fl::event_key()) {
+ case FL_Up:
+ case FL_Down: if (p->is_widget() && !p->is_menu_item()) {
+ Fl_Widget* w = ((Fl_Widget_Type*)i)->o;
+ Fl_Widget* pw = ((Fl_Widget_Type*)p)->o;
+ if (w->x() >= pw->x()+pw->w() ||
+ w->x()+w->w() <= pw->x()) continue;
+ }}
+ break;
+ }
+ // select it:
+ deselect(); select(i,1);
+ } return 1;
+
+ case FL_SHORTCUT: {
+ in_this_only = this; // modifies how some menu items work.
+ const Fl_Menu_Item* m = Main_Menu->test_shortcut();
+ if (m && m->callback()) m->do_callback(this->o);
+ in_this_only = 0;
+ return (m != 0);
+ }
+ default:
+ return 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <string.h>
+
+void Fl_Window_Type::write_code1() {
+ Fl_Widget_Type::write_code1();
+}
+
+void Fl_Window_Type::write_code2() {
+ if (modal) write_c("%so->set_modal();\n", indent());
+ else if (non_modal) write_c("%so->set_non_modal();\n", indent());
+ if (!((Fl_Window*)o)->border()) write_c("%so->clear_border();\n", indent());
+ write_c("%so->end();\n", indent());
+ if (((Fl_Window*)o)->resizable() == o)
+ write_c("%so->resizable(o);\n", indent());
+ Fl_Widget_Type::write_code2();
+}
+
+void Fl_Window_Type::write_properties() {
+ Fl_Widget_Type::write_properties();
+ if (modal) write_string("modal");
+ else if (non_modal) write_string("non_modal");
+ if (!((Fl_Window*)o)->border()) write_string("noborder");
+ if (xclass) {write_string("xclass"); write_word(xclass);}
+ if (o->visible()) write_string("visible");
+}
+
+void Fl_Window_Type::read_property(const char *c) {
+ if (!strcmp(c,"modal")) {
+ modal = 1;
+ } else if (!strcmp(c,"non_modal")) {
+ non_modal = 1;
+ } else if (!strcmp(c, "visible")) {
+ if (Fl::first_window()) open(); // only if we are using user interface
+ } else if (!strcmp(c,"noborder")) {
+ ((Fl_Window*)o)->border(0);
+ } else if (!strcmp(c,"xclass")) {
+ storestring(read_word(),xclass);
+ ((Fl_Window*)o)->xclass(xclass);
+ } else {
+ Fl_Widget_Type::read_property(c);
+ }
+}
+
+int Fl_Window_Type::read_fdesign(const char* name, const char* value) {
+ int x;
+ o->box(FL_NO_BOX); // because fdesign always puts an Fl_Box next
+ if (!strcmp(name,"Width")) {
+ if (sscanf(value,"%d",&x) == 1) o->size(x,o->h());
+ } else if (!strcmp(name,"Height")) {
+ if (sscanf(value,"%d",&x) == 1) o->size(o->w(),x);
+ } else if (!strcmp(name,"NumberofWidgets")) {
+ return 1; // we can figure out count from file
+ } else if (!strcmp(name,"border")) {
+ if (sscanf(value,"%d",&x) == 1) ((Fl_Window*)o)->border(x);
+ } else if (!strcmp(name,"title")) {
+ label(value);
+ } else {
+ return Fl_Widget_Type::read_fdesign(name,value);
+ }
+ return 1;
+}
diff --git a/fluid/Fluid_Image.cxx b/fluid/Fluid_Image.cxx
new file mode 100644
index 000000000..e01022502
--- /dev/null
+++ b/fluid/Fluid_Image.cxx
@@ -0,0 +1,384 @@
+// Fluid_Image.C
+
+// For pixmap labels.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include "Fl_Type.H"
+#include "Fluid_Image.H"
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <stdlib.h> // needed for DEC's Alpha cxx ?
+#include <FL/filename.H>
+
+extern void goto_source_dir(); // in fluid.C
+extern void leave_source_dir(); // in fluid.C
+
+////////////////////////////////////////////////////////////////
+#include <FL/Fl_Pixmap.H>
+
+class pixmap_image : public Fluid_Image {
+protected:
+ Fl_Pixmap *p;
+ int *linelength;
+public:
+ pixmap_image(const char *name, FILE *);
+ ~pixmap_image();
+ virtual void label(Fl_Widget *); // set the label of this widget
+ virtual void write_static();
+ virtual void write_code();
+ static int test_file(char *buffer);
+};
+
+int pixmap_image::test_file(char *buffer) {
+ return (strstr(buffer,"/* XPM") != 0);
+}
+
+void pixmap_image::label(Fl_Widget *o) {
+ if (p) p->label(o);
+}
+
+static int pixmap_header_written;
+
+void pixmap_image::write_static() {
+ if (!p) return;
+ write_c("\n");
+ if (pixmap_header_written != write_number) {
+ write_c("#include <FL/Fl_Pixmap.H>\n");
+ pixmap_header_written = write_number;
+ }
+ write_c("static char *%s[] = {\n",
+ unique_id(this, "image", filename_name(name()), 0));
+ int l;
+ for (l = 0; p->data[l]; l++) {
+ if (l) write_c(",\n");
+ write_cstring(p->data[l],linelength[l]);
+ }
+ write_c("\n};\n");
+ write_c("static Fl_Pixmap %s(%s);\n",
+ unique_id(this, "pixmap", filename_name(name()), 0),
+ unique_id(this, "image", filename_name(name()), 0));
+}
+
+void pixmap_image::write_code() {
+ if (!p) return;
+ write_c("%s%s.label(o);\n", indent(),
+ unique_id(this, "pixmap", filename_name(name()), 0));
+}
+
+static int hexdigit(int x) {
+ if (isdigit(x)) return x-'0';
+ if (isupper(x)) return x-'A'+10;
+ if (islower(x)) return x-'a'+10;
+ return 20;
+}
+
+#define MAXSIZE 1024
+
+pixmap_image::pixmap_image(const char *name, FILE *f) : Fluid_Image(name) {
+ if (!f) return; // for subclasses
+ // read all the c-strings out of the file:
+ char *data[MAXSIZE+1];
+ int length[MAXSIZE+1];
+ char buffer[MAXSIZE+20];
+ int i = 0;
+ while (i < MAXSIZE && fgets(buffer,MAXSIZE+20,f)) {
+ if (buffer[0] != '\"') continue;
+ char *p = buffer;
+ char *q = buffer+1;
+ while (*q != '\"') {
+ if (*q == '\\') switch (*++q) {
+ case '\n':
+ fgets(q,(buffer+MAXSIZE+20)-q,f); break;
+ case 0:
+ break;
+ case 'x': {
+ q++;
+ int n = 0;
+ for (int x = 0; x < 3; x++) {
+ int d = hexdigit(*q);
+ if (d > 15) break;
+ n = (n<<4)+d;
+ q++;
+ }
+ *p++ = n;
+ } break;
+ default: {
+ int c = *q++;
+ if (c>='0' && c<='7') {
+ c -= '0';
+ for (int x=0; x<2; x++) {
+ int d = hexdigit(*q);
+ if (d>7) break;
+ c = (c<<3)+d;
+ q++;
+ }
+ }
+ *p++ = c;
+ } break;
+ } else {
+ *p++ = *q++;
+ }
+ }
+ *p++ = 0;
+ data[i] = new char[p-buffer];
+ memcpy(data[i],buffer,p-buffer);
+ length[i] = p-buffer-1;
+ i++;
+ }
+ data[i++] = 0; // put a null at the end
+
+ char** real_data = new char*[i];
+ linelength = new int[i];
+ while (i--) {real_data[i] = data[i]; linelength[i] = length[i];}
+ p = new Fl_Pixmap(real_data);
+}
+
+pixmap_image::~pixmap_image() {
+ if (p && p->data) {
+ char** real_data = (char**)(p->data);
+ for (int i = 0; real_data[i]; i++) delete[] real_data[i];
+ delete[] real_data;
+ }
+ delete[] linelength;
+ delete p;
+}
+
+////////////////////////////////////////////////////////////////
+
+class gif_image : public pixmap_image {
+public:
+ gif_image(const char *name, FILE *);
+ ~gif_image();
+ static int test_file(char *buffer);
+};
+
+int gif_image::test_file(char *buffer) {
+ return !strncmp(buffer,"GIF",3);
+}
+
+// function in gif.C:
+int gif2xpm(
+ const char *infname,// filename for error messages
+ FILE *GifFile, // file to read
+ char*** datap, // return xpm data here
+ int** lengthp, // return line lengths here
+ int inumber // which image in movie (0 = first)
+);
+
+gif_image::gif_image(const char *name, FILE *f) : pixmap_image(name,0) {
+ char** datap;
+ if (gif2xpm(name,f,&datap,&linelength,0)) {
+ p = new Fl_Pixmap(datap);
+ } else
+ p = 0;
+}
+
+gif_image::~gif_image() {
+ if (p && p->data) {
+ char** real_data = (char**)(p->data);
+ for (int i = 0; i < 3; i++) delete[] real_data[i];
+ delete[] real_data;
+ p->data = 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+#include <FL/Fl_Bitmap.H>
+
+class bitmap_image : public Fluid_Image {
+ Fl_Bitmap *p;
+public:
+ ~bitmap_image();
+ bitmap_image(const char *name, FILE *);
+ virtual void label(Fl_Widget *); // set the label of this widget
+ virtual void write_static();
+ virtual void write_code();
+ static int test_file(char *buffer);
+};
+
+// bad test, always do this last!
+int bitmap_image::test_file(char *buffer) {
+ return (strstr(buffer,"#define ") != 0);
+}
+
+void bitmap_image::label(Fl_Widget *o) {
+ if (p) p->label(o); else o->labeltype(FL_NORMAL_LABEL);
+}
+
+static int bitmap_header_written;
+
+void bitmap_image::write_static() {
+ if (!p) return;
+ write_c("\n");
+ if (bitmap_header_written != write_number) {
+ write_c("#include <FL/Fl_Bitmap.H>\n");
+ bitmap_header_written = write_number;
+ }
+ write_c("static char %s[] = { \n",
+ unique_id(this, "bits", filename_name(name()), 0));
+ int n = ((p->w+7)/8)*p->h;
+ for (int i = 0; i < n; i++) {
+ if (i) write_c(", ");
+ write_c("%d",p->array[i]);
+ }
+ write_c("\n};\n");
+ write_c("static Fl_Bitmap %s(%s, %d, %d);\n",
+ unique_id(this, "bitmap", filename_name(name()), 0),
+ unique_id(this, "bits", filename_name(name()), 0),
+ p->w, p->h);
+}
+
+void bitmap_image::write_code() {
+ if (!p) return;
+ write_c("%s%s.label(o);\n", indent(),
+ unique_id(this, "bitmap", filename_name(name()), 0));
+}
+
+bitmap_image::bitmap_image(const char *name, FILE *f) : Fluid_Image(name) {
+ p = 0; // if any problems with parse we exit with this zero
+ char buffer[1024];
+ char junk[1024];
+ int wh[2]; // width and height
+ int i;
+ for (i = 0; i<2; i++) {
+ for (;;) {
+ if (!fgets(buffer,1024,f)) return;
+ int r = sscanf(buffer,"#define %s %d",junk,&wh[i]);
+ if (r >= 2) break;
+ }
+ }
+ // skip to data array:
+ for (;;) {
+ if (!fgets(buffer,1024,f)) return;
+ if (!strncmp(buffer,"static ",7)) break;
+ }
+ int n = ((wh[0]+7)/8)*wh[1];
+ uchar *data = new uchar[n];
+ // read the data:
+ i = 0;
+ for (;i<n;) {
+ if (!fgets(buffer,1024,f)) return;
+ const char *a = buffer;
+ while (*a && i<n) {
+ int t;
+ if (sscanf(a," 0x%x",&t)>0) data[i++] = t;
+ while (*a && *a++ != ',');
+ }
+ }
+ p = new Fl_Bitmap(data,wh[0],wh[1]);
+}
+
+bitmap_image::~bitmap_image() {
+ if (p) {
+ delete[] (uchar*)(p->array);
+ delete p;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+static Fluid_Image** images; // sorted list
+static int numimages;
+static int tablesize;
+
+Fluid_Image* Fluid_Image::find(const char *name) {
+ if (!name || !*name) return 0;
+
+ // first search to see if it exists already:
+ int a = 0;
+ int b = numimages;
+ while (a < b) {
+ int c = (a+b)/2;
+ int i = strcmp(name,images[c]->name_);
+ if (i < 0) b = c;
+ else if (i > 0) a = c+1;
+ else return images[c];
+ }
+
+ // no, so now see if the file exists:
+
+ goto_source_dir();
+ FILE *f = fopen(name,"rb");
+ if (!f) {
+ read_error("%s : %s",name,strerror(errno));
+ leave_source_dir();
+ return 0;
+ }
+
+ Fluid_Image *ret;
+
+ // now see if we can identify the type, by reading in some data
+ // and asking all the types we know about:
+
+ char buffer[1025];
+ fread(buffer, 1, 1024, f);
+ rewind(f);
+ buffer[1024] = 0; // null-terminate so strstr() works
+
+ if (pixmap_image::test_file(buffer)) {
+ ret = new pixmap_image(name,f);
+ } else if (gif_image::test_file(buffer)) {
+ ret = new gif_image(name,f);
+ } else if (bitmap_image::test_file(buffer)) {
+ ret = new bitmap_image(name,f);
+ } else {
+ ret = 0;
+ read_error("%s : unrecognized image format", name);
+ }
+ fclose(f);
+ leave_source_dir();
+ if (!ret) return 0;
+
+ // make a new entry in the table:
+ numimages++;
+ if (numimages > tablesize) {
+ tablesize = tablesize ? 2*tablesize : 16;
+ images = (Fluid_Image**)realloc(images, tablesize*sizeof(Fluid_Image*));
+ }
+ for (b = numimages-1; b > a; b--) images[b] = images[b-1];
+ images[a] = ret;
+
+ return ret;
+}
+
+Fluid_Image::Fluid_Image(const char *name) {
+ name_ = strdup(name);
+ written = 0;
+ refcount = 0;
+}
+
+void Fluid_Image::increment() {
+ ++refcount;
+}
+
+void Fluid_Image::decrement() {
+ --refcount;
+ if (refcount > 0) return;
+ delete this;
+}
+
+Fluid_Image::~Fluid_Image() {
+ int a;
+ for (a = 0;; a++) if (images[a] == this) break;
+ numimages--;
+ for (; a < numimages; a++) images[a] = images[a+1];
+ free((void*)name_);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/fl_file_chooser.H>
+
+const char *ui_find_image_name;
+Fluid_Image *ui_find_image(const char *oldname) {
+ goto_source_dir();
+ const char *name = fl_file_chooser("Image","*.{bm|xbm|xpm|gif}",oldname);
+ ui_find_image_name = name;
+ Fluid_Image *ret = (name && *name) ? Fluid_Image::find(name) : 0;
+ leave_source_dir();
+ return ret;
+}
diff --git a/fluid/Fluid_Image.h b/fluid/Fluid_Image.h
new file mode 100644
index 000000000..fdc7937bc
--- /dev/null
+++ b/fluid/Fluid_Image.h
@@ -0,0 +1,28 @@
+// Fluid_Image.H
+
+// This class stores the image labels for widgets in fluid. This is
+// not a class in fltk itself, and this will produce different types of
+// code depending on what the image type is. There are private subclasses
+// in Fluid_Image.C for each type of image format. Right now only xpm
+// files are supported.
+
+class Fluid_Image {
+ const char *name_;
+ int refcount;
+protected:
+ Fluid_Image(const char *name); // no public constructor
+ virtual ~Fluid_Image(); // no public destructor
+public:
+ int written;
+ static Fluid_Image* find(const char *);
+ void decrement(); // reference counting & automatic free
+ void increment();
+ virtual void label(Fl_Widget *) = 0; // set the label of this widget
+ virtual void write_static() = 0;
+ virtual void write_code() = 0;
+ const char *name() const {return name_;}
+};
+
+// pop up file chooser and return a legal image selected by user,
+// or zero for any errors:
+Fluid_Image *ui_find_image(const char *);
diff --git a/fluid/Makefile b/fluid/Makefile
new file mode 100644
index 000000000..876b52a09
--- /dev/null
+++ b/fluid/Makefile
@@ -0,0 +1,83 @@
+PROGRAM = fluid
+
+CPPFILES = \
+ Fl_Function_Type.C \
+ Fl_Menu_Type.C \
+ Fl_Group_Type.C \
+ Fl_Widget_Type.C \
+ Fl_Type.C \
+ Fl_Window_Type.C \
+ Fluid_Image.C \
+ code.C \
+ factory.C \
+ file.C \
+ fluid.C \
+ about_panel.C \
+ widget_panel.C \
+ alignment_panel.C \
+ function_panel.C \
+ gif.C
+
+################################################################
+
+OBJECTS = $(CPPFILES:.C=.o)
+
+include ../makeinclude
+
+.SUFFIXES : .C .c .o .do .fl .H
+
+.C.o :
+ @echo $<:
+ @$(CXX) -I.. $(CXXFLAGS) -c $<
+.c.o :
+ @echo $<:
+ @$(CC) -I.. $(CFLAGS) -c $<
+.C :
+ @echo $@:
+ @$(CXX) -I.. $(CXXFLAGS) -o $@ $< -L../lib -lfltk $(LDLIBS)
+
+.fl.C .fl.H :
+ -fluid -c $<
+
+# better way to do this for gnu make:
+# %.H %.C: %.fl
+# fluid -c $<
+
+$(PROGRAM) : $(OBJECTS) ../lib/$(LIBNAME)
+ @echo linking $@:
+ @$(CXX) $(CXXFLAGS) -o $(PROGRAM) $(OBJECTS) -L../lib -lfltk $(LDLIBS)
+
+clean :
+ -@ rm -f *.o $(PROGRAM) $(CLEAN) core *~ makedepend
+ @touch makedepend
+
+depend:
+ $(MAKEDEPEND) -I.. $(CXXFLAGS) $(CPPFILES) $(CFILES) > makedepend
+include makedepend
+
+install: $(PROGRAM)
+ strip $(PROGRAM)
+ cp $(PROGRAM) $(bindir)/$(PROGRAM)
+ @chmod a+rx,g-w,o-w $(bindir)/$(PROGRAM)
+
+uninstall:
+ -@ rm -f $(bindir)/$(PROGRAM)
+
+################################################################
+
+PROGRAM_D = $(PROGRAM)_d
+
+debug: $(PROGRAM_D)
+
+OBJECTS_D = $(CPPFILES:.C=.do) $(CFILES:.c=.do)
+
+.C.do :
+ @echo $<:
+ @$(CXX) -I.. $(CXXFLAGS_D) -c -o $@ $<
+.c.do :
+ @echo $<:
+ @$(CC) -I.. $(CFLAGS_D) -c -o $@ $<
+
+$(PROGRAM_D) : $(OBJECTS_D) ../lib/$(LIBNAME_D)
+ @echo linking $@:
+ @$(CXX) $(CXXFLAGS_D) -o $(PROGRAM_D) $(OBJECTS_D) -L../lib -lfltk_d $(LDLIBS)
diff --git a/fluid/README b/fluid/README
new file mode 100644
index 000000000..9fe6d6c36
--- /dev/null
+++ b/fluid/README
@@ -0,0 +1,214 @@
+Fluid (the FL User Interface Designer) is a graphical editor that
+is used to produce FL source code.
+
+Fluid edits and saves it's state in ".fl" files. These files are
+text, and you could (with care) edit them in a text editor, perhaps to
+get some special effects.
+
+When asked to "compile", fluid outputs a .C source file and a .H
+header file: The .C file contains one or more public functions, each
+of which will create one or more FL windows and all the objects in
+those windows. The .H file declares (as externs) all the functions
+and named objects created by the .C file, and includes all the
+necessary FL header files for those objects.
+
+The C file must be compiled and linked with a "main" source file(s)
+that you write. This source code must include the .H output, and
+should call the functions in the .C file to create windows. The main
+code must do show() on the windows and run the Fl::wait() loop.
+
+ _________
+ / /
+ __________ +->/.C file /--------+
+ / / / /________/ |
+ /.fl file /<==>[fluid]< #include |
+ /_________/ \ ___v_____ |
+ \ / / |
+ +>/.H file / |
+ /________/ |
+ ^ |
+ #include |
+ ___|_____ | __________
+ / / V / /
+ / main.C /--->[c++,link]-->/ program /
+ /________/ /_________/
+
+
+Objects created by fluid are either "named" or "unnamed". If they
+are named, the .C file will declare a global variable with that name
+of type "<type>*". This pointer has a value of zero until the fluid
+function is called, the fluid function will set it to the instance of
+the . Unnamed objects are only accessible through
+pointers from other objects.
+
+Windows may be named or unnamed. Named windows are only created
+once even if you call the function several times (fluid outputs "if
+(!name) {...}" around the code that creates the window). Unnamed
+windows lets you create many instances of the same window structure, a
+pointer to the unnamed window is returned from the fluid function (you
+can only put one unnamed window in a function).
+
+Objects may either call a named callback function that you write in
+another source file, or you can supply a small piece of C++ source and
+fluid will write a private callback function into the .C file.
+
+================================================================
+Worlds shortest tutorial:
+================================================================
+
+Type "fluid&"
+
+Pick "New/Function" off the menu.
+
+Delete the function name in the popup window and hit OK. The text
+"main()" with a triangle next to it should appear highlighted in the
+main window.
+
+Pick "New/Window" off the menu.
+
+Move the window and resize it to the size you want.
+
+Pick "New/buttons/Button" off the menu.
+
+Hit the "OK" button to dismiss the panel that appears.
+
+In the window you created, try moving the button by dragging it
+around. Notice that it "snaps" to fixed locations. If you want to
+drag it smoothly, hold down Alt. You can also change the size of the
+steps with Edit/Preferences.
+
+Try resizing the object by dragging the edges and corners.
+
+Type Alt+c to copy the object.
+
+Type Alt+v to paste a copy into the window.
+
+Type Alt+v several times.
+
+Drag the objects and resize them so they don't overlap. Notice
+that you have to click an object to pick it first, then drag it.
+
+Try selecting several objects by dragging a box around them. Check
+what happens when you move them, or when you drag an edge to resize
+them.
+
+You can also use Shift+click to toggle objects on and off.
+
+You can also select objects by clicking on them in the list in the
+main window, try that.
+
+Double-click one of the buttons. You will get a control panel.
+
+Try changing the "label". Try changing other items near the top of
+the panel. To see any changes to the box type clearer, type "Alt+o"
+to make the red overlay disappear.
+
+Type "#include <stdlib.h>" into the first line of "extra code:".
+
+Type "exit(0);" into the "callback:".
+
+Hit OK.
+
+Pick "File/Save As" off the menu.
+
+Type "test.fl" into the file chooser and hit return.
+
+Pick "File/Write Code" off the menu.
+
+Go back to your terminal window. Type "more test.C" and "more
+test.H" and you can see the code it made.
+
+Type "make test" (you may have to add libaries to your Makefile).
+
+Type "./test" to run your program.
+
+Try the buttons. The one you put the code into will exit the
+program.
+
+Type "Alt+Q" to exit fluid.
+
+Ok, now try to make a real program.
+
+================================================================
+
+This code is quite a kludge and probably impossible to figure out. I
+hope it will be fixed someday, but my intention was to make FL itself
+clean and simple, even if the user interface designer is forced to be
+more complex as a result.
+
+An object in fluid is represented by a subclass of "Fl_Type".
+
+Creating a new instance of an object is done by calling the virtual
+method "make()" on Fl_Type. To allow an initial version of each type
+to be created, there is a static "factory" instance of every subclass
+of Fl_Type. For now, make() is only called on these. The intention
+was to use make() to copy objects, but that did not happen. Instead I
+write the descriptions and read them back from a file in /usr/tmp,
+which is much more reliable because the read/write code is tested
+every time a file is saved!
+
+The (non-factory) instances are linked into a list by the previous and
+next pointers. The "hierarchy" is stored by a "level" number on each
+object, and an "isparent" flag on the parent. To find the "brother"
+of an object, code must search forward for the next object whose level
+is equal to this one. A null pointer or an object with a lower level
+number indicates no brother.
+
+If the type is a subclass of Fl_Object, the "o" pointer points at an
+Fl_Object. This allows the code in FL to be used to draw the object.
+The user_data() field on the Fl_Object is used as a back pointer to
+the Fl_Type. The "factory" has an "o" pointer that points at the
+"template object". This is an Fl_Object created the first time make()
+is called and is used to figure out what the default values for the
+fields are for the object.
+
+This "o" pointer exists in all Fl_Type objects, even the base class.
+If this is not an Fl_Object item, then the "o" pointer is zero. This
+avoided a lot of virtual functions, but is mostly for historical
+reasons. Rather than RTTI, I use some tests to determine subclasses:
+
+ if (o && level == 1)
+ this is an Fl_Window_Type
+ else if (o && isparent)
+ this is a Fl_Group_Type
+ else if (o)
+ this is a Fl_Object_Type
+ else if (!level)
+ this is a function
+ else
+ this is a menu item or something
+ (none of these implemented yet)
+
+
+ Fl_Type::first
+ |
+ | NULL
+ | ^
+ V |
+ +---------+ +-----------+
+ | Fl_Type |------ o ---> | Fl_Window |
+ | level=0 |<-user_data()-| |
+ |isparent |<-+ +-----------+
+ +---------+ | | ^
+ | ^ parent first |
+ next prev / | parent
+ V | / V |
+ +---------+ +-----------+
+ | Fl_Type |------ o ---> | Fl_Object |
+ | level=1 | | |
+ | |<-user_data()-| |
+ | | +-----------+
+ | | +---------+
+ | |-factory->| Fl_Type |---- o ---->[Fl_Object]
+ +---------+ | | template object
+ | ^ +---------+
+ next prev (next,prev=NULL)
+ V |
+ +---------+
+ | Fl_Type |
+ +---------+
+ | ^
+ V |
+ NULL |
+ |
+ Fl_Type::last
diff --git a/fluid/Shortcut_Button.h b/fluid/Shortcut_Button.h
new file mode 100644
index 000000000..eea4ddc70
--- /dev/null
+++ b/fluid/Shortcut_Button.h
@@ -0,0 +1,10 @@
+#include <FL/Fl_Button.H>
+
+class Shortcut_Button : public Fl_Button {
+public:
+ int svalue;
+ int handle(int);
+ void draw();
+ Shortcut_Button(int x, int y, int w, int h, const char* l = 0) :
+ Fl_Button(x,y,w,h,l) {svalue = 0;}
+};
diff --git a/fluid/about_panel.cxx b/fluid/about_panel.cxx
new file mode 100644
index 000000000..a880d39dd
--- /dev/null
+++ b/fluid/about_panel.cxx
@@ -0,0 +1,122 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "about_panel.H"
+
+Fl_Window *about_panel;
+
+Fl_Group *display_group;
+
+static void cb_1998(Fl_Button*, void*) {
+ display_group->hide();
+copyright_box->show();
+}
+
+Fl_Box *copyright_box;
+
+static void cb_OK(Fl_Return_Button* o, void*) {
+ ((Fl_Window*)(o->parent()))->hide();
+}
+
+Fl_Window* make_about_panel(const char *copyright) {
+ Fl_Window* w;
+ { Fl_Window* o = about_panel = w = new Fl_Window(309, 221, "about fluid");
+ o->box(FL_UP_BOX);
+ o->color(97);
+ o->selection_color(47);
+ w->hotspot(o);
+ { Fl_Group* o = display_group = new Fl_Group(24, 14, 275, 186);
+ { Fl_Box* o = new Fl_Box(64, 14, 50, 126);
+ o->box(FL_ROUND_UP_BOX);
+ o->color(14);
+ o->selection_color(47);
+ o->labelcolor(6);
+ }
+ { Fl_Box* o = new Fl_Box(54, 14, 70, 16);
+ o->box(FL_FLAT_BOX);
+ o->color(97);
+ o->selection_color(47);
+ }
+ { Fl_Box* o = new Fl_Box(68, 30, 42, 50);
+ o->box(FL_DOWN_BOX);
+ o->color(6);
+ o->selection_color(47);
+ }
+ { Fl_Box* o = new Fl_Box(54, 20, 70, 20);
+ o->box(FL_ROUND_UP_BOX);
+ o->color(6);
+ o->selection_color(47);
+ o->labelcolor(6);
+ o->align(16);
+ }
+ { Fl_Box* o = new Fl_Box(24, 110, 130, 90, "fluid");
+ o->box(FL_ROUND_UP_BOX);
+ o->color(14);
+ o->selection_color(47);
+ o->labeltype(FL_SHADOW_LABEL);
+ o->labelfont(1);
+ o->labelsize(40);
+ o->labelcolor(6);
+ }
+ { Fl_Box* o = new Fl_Box(67, 110, 44, 10);
+ o->box(FL_FLAT_BOX);
+ o->color(14);
+ o->selection_color(47);
+ }
+ { Fl_Box* o = new Fl_Box(84, 120, 15, 15, "` ");
+ o->box(FL_OVAL_BOX);
+ o->color(6);
+ o->selection_color(47);
+ o->labelsize(20);
+ o->labelcolor(7);
+ o->align(17);
+ }
+ { Fl_Box* o = new Fl_Box(75, 105, 15, 15, "` ");
+ o->box(FL_OVAL_BOX);
+ o->color(6);
+ o->selection_color(47);
+ o->labelsize(20);
+ o->labelcolor(7);
+ o->align(17);
+ }
+ { Fl_Box* o = new Fl_Box(89, 85, 15, 15, "` ");
+ o->box(FL_OVAL_BOX);
+ o->color(6);
+ o->selection_color(47);
+ o->labelsize(20);
+ o->labelcolor(7);
+ o->align(17);
+ }
+ { Fl_Box* o = new Fl_Box(159, 27, 131, 95, "Fltk User\nInterface\nDesigner\nVersion 1.00");
+ o->box(FL_OVAL_BOX);
+ o->color(12);
+ o->selection_color(47);
+ o->labeltype(FL_SHADOW_LABEL);
+ o->labelfont(1);
+ o->labelsize(18);
+ o->labelcolor(7);
+ }
+ { Fl_Button* o = new Fl_Button(169, 138, 115, 30, "\xa9\x31\x39\x39\x38 Bill Spitzak\n(click here)");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(10);
+ o->labelcolor(136);
+ o->callback((Fl_Callback*)cb_1998);
+ }
+ o->end();
+ }
+ { Fl_Box* o = copyright_box = new Fl_Box(5, 5, 300, 210);
+ o->labelsize(8);
+ o->labelcolor(6);
+ o->align(148);
+ o->hide();
+ o->label(copyright);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(168, 182, 116, 22, "OK");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)cb_OK);
+ }
+ o->set_non_modal();
+ o->clear_border();
+ o->end();
+ }
+ return w;
+}
diff --git a/fluid/about_panel.fl b/fluid/about_panel.fl
new file mode 100644
index 000000000..b35c59251
--- /dev/null
+++ b/fluid/about_panel.fl
@@ -0,0 +1,71 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+gridx 2
+gridy 2
+snap 3
+Function {make_about_panel(const char *copyright)} {open
+} {
+ Fl_Window about_panel {
+ label {about fluid} open
+ xywh {345 417 309 221} box UP_BOX color {97 47} hide hotspot non_modal noborder
+ } {
+ Fl_Group display_group {open
+ xywh {24 14 275 186}
+ } {
+ Fl_Box {} {
+ xywh {64 14 50 126} box ROUND_UP_BOX color {14 47} labelcolor 6
+ }
+ Fl_Box {} {
+ xywh {54 14 70 16} box FLAT_BOX color {97 47}
+ }
+ Fl_Box {} {
+ xywh {68 30 42 50} box DOWN_BOX color {6 47}
+ }
+ Fl_Box {} {
+ xywh {54 20 70 20} box ROUND_UP_BOX color {6 47} labelcolor 6 align 16
+ }
+ Fl_Box {} {
+ label fluid
+ xywh {24 110 130 90} box ROUND_UP_BOX color {14 47} labeltype SHADOW_LABEL labelfont 1 labelsize 40 labelcolor 6
+ }
+ Fl_Box {} {
+ xywh {67 110 44 10} box FLAT_BOX color {14 47}
+ }
+ Fl_Box {} {
+ label {` }
+ xywh {84 120 15 15} box OVAL_BOX color {6 47} labelsize 20 labelcolor 7 align 17
+ }
+ Fl_Box {} {
+ label {` }
+ xywh {75 105 15 15} box OVAL_BOX color {6 47} labelsize 20 labelcolor 7 align 17
+ }
+ Fl_Box {} {
+ label {` }
+ xywh {89 85 15 15} box OVAL_BOX color {6 47} labelsize 20 labelcolor 7 align 17
+ }
+ Fl_Box {} {
+ label {Fltk User
+Interface
+Designer
+Version 1.00}
+ xywh {159 27 131 95} box OVAL_BOX color {12 47} labeltype SHADOW_LABEL labelfont 1 labelsize 18 labelcolor 7
+ }
+ Fl_Button {} {
+ label {©1998 Bill Spitzak
+(click here)}
+ callback {display_group->hide();
+copyright_box->show();}
+ xywh {169 138 115 30} box THIN_UP_BOX labelsize 10 labelcolor 136
+ }
+ }
+ Fl_Box copyright_box {selected
+ xywh {5 5 300 210} labelsize 8 labelcolor 6 align 148 hide
+ code0 {o->label(copyright);}
+ }
+ Fl_Return_Button {} {
+ label OK
+ callback {((Fl_Window*)(o->parent()))->hide();}
+ xywh {168 182 116 22} labelsize 10
+ }
+ }
+}
diff --git a/fluid/about_panel.h b/fluid/about_panel.h
new file mode 100644
index 000000000..7113cf5cf
--- /dev/null
+++ b/fluid/about_panel.h
@@ -0,0 +1,12 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Window.H>
+extern Fl_Window *about_panel;
+extern Fl_Group *display_group;
+extern Fl_Box *copyright_box;
+Fl_Window* make_about_panel(const char *copyright);
diff --git a/fluid/alignment_panel.cxx b/fluid/alignment_panel.cxx
new file mode 100644
index 000000000..fa8c7c089
--- /dev/null
+++ b/fluid/alignment_panel.cxx
@@ -0,0 +1,73 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "alignment_panel.H"
+
+Fl_Window *alignment_window;
+
+Fl_Input *horizontal_input;
+
+Fl_Input *vertical_input;
+
+Fl_Input *snap_input;
+
+static void cb_close(Fl_Button*, void*) {
+ alignment_window->hide();
+}
+
+Fl_Input *header_file_input;
+
+Fl_Input *code_file_input;
+
+Fl_Window* make_alignment_window() {
+ Fl_Window *w;
+ { Fl_Window* o = alignment_window = w = new Fl_Window(210, 282, "fluid Preferences");
+ { Fl_Box* o = new Fl_Box(10, 20, 190, 100, "ALIGNMENT:");
+ o->box(FL_ENGRAVED_FRAME);
+ o->labelsize(10);
+ o->align(5);
+ }
+ { Fl_Input* o = horizontal_input = new Fl_Input(90, 30, 100, 20, "horizontal:");
+ o->type(2);
+ o->box(FL_THIN_DOWN_BOX);
+ o->callback((Fl_Callback*)alignment_cb, (void*)(1));
+ o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
+ }
+ { Fl_Input* o = vertical_input = new Fl_Input(90, 60, 100, 20, "vertical:");
+ o->type(2);
+ o->box(FL_THIN_DOWN_BOX);
+ o->callback((Fl_Callback*)alignment_cb, (void*)(2));
+ o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
+ }
+ { Fl_Input* o = snap_input = new Fl_Input(90, 90, 100, 20, "snap:");
+ o->type(2);
+ o->box(FL_THIN_DOWN_BOX);
+ o->callback((Fl_Callback*)alignment_cb, (void*)(3));
+ o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);
+ }
+ { Fl_Button* o = new Fl_Button(10, 250, 190, 20, "close");
+ o->callback((Fl_Callback*)cb_close);
+ w->hotspot(o);
+ }
+ { Fl_Box* o = new Fl_Box(10, 140, 190, 100, "OUTPUT FILE NAMES:");
+ o->box(FL_ENGRAVED_FRAME);
+ o->labelsize(10);
+ o->align(5);
+ }
+ { Fl_Box* o = new Fl_Box(10, 140, 190, 40, "Use \"name.ext\" to set name, use just \".ext\" to set only extension.");
+ o->labelsize(10);
+ o->align(128);
+ }
+ { Fl_Input* o = header_file_input = new Fl_Input(90, 180, 100, 20, "header file:");
+ o->box(FL_THIN_DOWN_BOX);
+ o->callback((Fl_Callback*)header_input_cb, (void*)(1));
+ o->when(1);
+ }
+ { Fl_Input* o = code_file_input = new Fl_Input(90, 210, 100, 20, "code file:");
+ o->box(FL_THIN_DOWN_BOX);
+ o->callback((Fl_Callback*)code_input_cb, (void*)(1));
+ o->when(1);
+ }
+ o->end();
+ }
+ return w;
+}
diff --git a/fluid/alignment_panel.fl b/fluid/alignment_panel.fl
new file mode 100644
index 000000000..c2e7f9286
--- /dev/null
+++ b/fluid/alignment_panel.fl
@@ -0,0 +1,65 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+header_name {.H}
+code_name {.C}
+gridx 10
+gridy 10
+snap 3
+Function {make_alignment_window()} {open
+} {
+ Fl_Window alignment_window {
+ label {fluid Preferences} open selected
+ xywh {303 187 210 282} visible
+ } {
+ Fl_Box {} {
+ label {ALIGNMENT:}
+ xywh {10 20 190 100} box ENGRAVED_FRAME labelsize 10 align 5
+ }
+ Fl_Input horizontal_input {
+ label {horizontal:}
+ user_data 1 user_data_type long
+ callback alignment_cb
+ xywh {90 30 100 20} type Int box THIN_DOWN_BOX
+ code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
+ }
+ Fl_Input vertical_input {
+ label {vertical:}
+ user_data 2 user_data_type long
+ callback alignment_cb
+ xywh {90 60 100 20} type Int box THIN_DOWN_BOX
+ code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
+ }
+ Fl_Input snap_input {
+ label {snap:}
+ user_data 3 user_data_type long
+ callback alignment_cb
+ xywh {90 90 100 20} type Int box THIN_DOWN_BOX
+ code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);}
+ }
+ Fl_Button {} {
+ label close
+ callback {alignment_window->hide();}
+ xywh {10 250 190 20} hotspot
+ }
+ Fl_Box {} {
+ label {OUTPUT FILE NAMES:}
+ xywh {10 140 190 100} box ENGRAVED_FRAME labelsize 10 align 5
+ }
+ Fl_Box {} {
+ label {Use "name.ext" to set name, use just ".ext" to set only extension.}
+ xywh {10 140 190 40} labelsize 10 align 128
+ }
+ Fl_Input header_file_input {
+ label {header file:}
+ user_data 1 user_data_type {void*}
+ callback header_input_cb
+ xywh {90 180 100 20} box THIN_DOWN_BOX when 1
+ }
+ Fl_Input code_file_input {
+ label {code file:}
+ user_data 1 user_data_type {void*}
+ callback code_input_cb
+ xywh {90 210 100 20} box THIN_DOWN_BOX when 1
+ }
+ }
+}
diff --git a/fluid/alignment_panel.h b/fluid/alignment_panel.h
new file mode 100644
index 000000000..437d7640f
--- /dev/null
+++ b/fluid/alignment_panel.h
@@ -0,0 +1,17 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Window.H>
+extern void alignment_cb(Fl_Input*, long);
+extern void code_input_cb(Fl_Input*, void*);
+extern void header_input_cb(Fl_Input*, void*);
+extern Fl_Window *alignment_window;
+extern Fl_Input *horizontal_input;
+extern Fl_Input *vertical_input;
+extern Fl_Input *snap_input;
+extern Fl_Input *header_file_input;
+extern Fl_Input *code_file_input;
+Fl_Window* make_alignment_window();
diff --git a/fluid/class.C b/fluid/class.C
new file mode 100644
index 000000000..e547cf2a7
--- /dev/null
+++ b/fluid/class.C
@@ -0,0 +1,123 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "class.H"
+
+inline void essai::cb_button_i(Fl_Button*, void*) {
+ printf("button\n");
+}
+void essai::cb_button(Fl_Button* o, void* v) {
+ ((essai*)(o->parent()->user_data()))->cb_button_i(o,v);
+}
+
+inline void essai::cb_unnamed_i(Fl_Button*, void*) {
+ printf("unnamed\n");
+}
+void essai::cb_unnamed(Fl_Button* o, void* v) {
+ ((essai*)(o->parent()->user_data()))->cb_unnamed_i(o,v);
+}
+
+inline void essai::cb_src_i(Fl_Button*, void*) {
+ (new essai)->win->show();
+}
+void essai::cb_src(Fl_Button* o, void* v) {
+ ((essai*)(o->parent()->user_data()))->cb_src_i(o,v);
+}
+
+#include <FL/Fl_Bitmap.H>
+static char bits_ew_mask[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 28, 56, 254, 127, 255, 255, 255, 255, 254, 127, 28, 56, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static Fl_Bitmap bitmap_ew_mask(bits_ew_mask, 16, 16);
+
+inline void essai::cb_change_i(Fl_Menu_*, void*) {
+ cbox->color(cbox->color()+1);
+cbox->redraw();
+}
+void essai::cb_change(Fl_Menu_* o, void* v) {
+ ((essai*)(o->parent()->user_data()))->cb_change_i(o,v);
+}
+
+Fl_Menu_Item essai::menu_menu[] = {
+ {"change color", 0, (Fl_Callback*)essai::cb_change, 0, 0, 0, 3, 14, 0},
+ {"radio off", 0, 0, 0, 8, 0, 3, 14, 0},
+ {"radio on", 0, 0, 0, 12, 0, 3, 14, 0},
+ {"toggle off", 0, 0, 0, 2, 0, 3, 14, 0},
+ {"toggle on", 0, 0, 0, 6, 0, 3, 14, 0},
+ {"new item 5", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 6", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 7", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 8", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 9", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 10", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 11", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 12", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 13", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 14", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 15", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 16", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 17", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 18", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 19", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 20", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 21", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 22", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 23", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"new item 24", 0, 0, 0, 0, 0, 3, 14, 0},
+ {0}
+};
+
+inline void essai::cb_color_i(Fl_Button*, void*) {
+ cbox->color(cbox->color()+1);
+cbox->redraw();
+}
+void essai::cb_color(Fl_Button* o, void* v) {
+ ((essai*)(o->parent()->user_data()))->cb_color_i(o,v);
+}
+
+inline void essai::cb_delete_i(Fl_Button*, void*) {
+ delete this;
+}
+void essai::cb_delete(Fl_Button* o, void* v) {
+ ((essai*)(o->parent()->user_data()))->cb_delete_i(o,v);
+}
+
+essai::essai() {
+ Fl_Window *w;
+ { Fl_Window* o = win = w = new Fl_Window(282, 193);
+ o->user_data((void*)(this));
+ { Fl_Button* o = new Fl_Button(10, 10, 55, 35, "button");
+ o->callback((Fl_Callback*)cb_button);
+ }
+ { Fl_Button* o = new Fl_Button(10, 45, 145, 35, "unnamed");
+ o->callback((Fl_Callback*)cb_unnamed);
+ }
+ { Fl_Button* o = new Fl_Button(10, 80, 145, 35);
+ bitmap_ew_mask.label(o);
+ o->callback((Fl_Callback*)cb_src);
+ }
+ { Fl_Menu_Button* o = new Fl_Menu_Button(10, 115, 145, 35, "menu");
+ o->menu(menu_menu);
+ }
+ { Fl_Button* o = new Fl_Button(70, 150, 85, 35, "color");
+ o->callback((Fl_Callback*)cb_color);
+ }
+ new Fl_Button(200, 10, 55, 35, "boring");
+ { Fl_Box* o = cbox = new Fl_Box(165, 80, 55, 35, "color");
+ o->box(FL_FLAT_BOX);
+ }
+ { Fl_Button* o = new Fl_Button(200, 125, 55, 35, "delete this");
+ o->callback((Fl_Callback*)cb_delete);
+ }
+ button_variable = new Fl_Button(100, 10, 55, 35, "button");
+ w->end();
+ }
+}
+
+essai::~essai() {
+ delete win;
+}
+
+int main(int argc, char **argv) {
+ essai E; E.win->show();
+ return Fl::run();
+}
diff --git a/fluid/class.H b/fluid/class.H
new file mode 100644
index 000000000..302ce0486
--- /dev/null
+++ b/fluid/class.H
@@ -0,0 +1,34 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Window.H>
+#include <stdio.h>
+
+class essai {
+public:
+ essai();
+ Fl_Window *win;
+private:
+ inline void cb_button_i(Fl_Button*, void*);
+ static void cb_button(Fl_Button*, void*);
+ inline void cb_unnamed_i(Fl_Button*, void*);
+ static void cb_unnamed(Fl_Button*, void*);
+ inline void cb_src_i(Fl_Button*, void*);
+ static void cb_src(Fl_Button*, void*);
+ static Fl_Menu_Item menu_menu[];
+ inline void cb_change_i(Fl_Menu_*, void*);
+ static void cb_change(Fl_Menu_*, void*);
+ inline void cb_color_i(Fl_Button*, void*);
+ static void cb_color(Fl_Button*, void*);
+public:
+ Fl_Box *cbox;
+private:
+ inline void cb_delete_i(Fl_Button*, void*);
+ static void cb_delete(Fl_Button*, void*);
+public:
+ Fl_Button *button_variable;
+ ~essai();
+};
diff --git a/fluid/code.cxx b/fluid/code.cxx
new file mode 100644
index 000000000..171593fff
--- /dev/null
+++ b/fluid/code.cxx
@@ -0,0 +1,263 @@
+/* code.C
+
+ Code to write .C files from Fluid
+
+*/
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <FL/Fl.H>
+#include "Fl_Type.H"
+
+static FILE *code_file;
+static FILE *header_file;
+
+// return true if c can be in a C identifier. I needed this so
+// it is not messed up by locale settings:
+int is_id(char c) {
+ return c>='a' && c<='z' || c>='A' && c<='Z' || c>='0' && c<='9' || c=='_';
+}
+
+////////////////////////////////////////////////////////////////
+// Generate unique but human-readable identifiers:
+
+struct id {
+ char* text;
+ void* object;
+ id *left, *right;
+ id (const char* t, void* o) : text(strdup(t)), object(o) {left = right = 0;}
+ ~id();
+};
+
+id::~id() {
+ delete left;
+ free((void *)text);
+ delete right;
+}
+
+static id* id_root;
+
+const char* unique_id(void* o, const char* type, const char* name, const char* label) {
+ char buffer[128];
+ char* q = buffer;
+ while (*type) *q++ = *type++;
+ *q++ = '_';
+ const char* n = name;
+ if (!n || !*n) n = label;
+ if (n && *n) {
+ while (!is_id(*n)) n++;
+ while (is_id(*n)) *q++ = *n++;
+ }
+ *q = 0;
+ // okay, search the tree and see if the name was already used:
+ id** p = &id_root;
+ int which = 0;
+ while (*p) {
+ int i = strcmp(buffer, (*p)->text);
+ if (!i) {
+ if ((*p)->object == o) return (*p)->text;
+ // already used, we need to pick a new name:
+ sprintf(q,"%x",++which);
+ p = &id_root;
+ continue;
+ }
+ else if (i < 0) p = &((*p)->left);
+ else p = &((*p)->right);
+ }
+ *p = new id(buffer, o);
+ return (*p)->text;
+}
+
+////////////////////////////////////////////////////////////////
+// return current indentation:
+
+static const char* spaces = " ";
+int indentation;
+const char* indent() {
+ int i = indentation; if (i>16) i = 16;
+ return spaces+16-i;
+}
+
+////////////////////////////////////////////////////////////////
+// declarations/include files:
+// These are sorted in alphabetical order and only included once each:
+// Relies on '#' being less than any letter to put #include first.
+// I use a binary tree to sort these out.
+
+struct included {
+ char *text;
+ included *left, *right;
+ included(const char *t) {
+ text = strdup(t);
+ left = right = 0;
+ }
+ ~included();
+};
+
+included::~included() {
+ delete left;
+ fprintf(header_file,"%s\n",text);
+ free((void *)text);
+ delete right;
+}
+static included *included_root;
+
+int write_declare(const char *format, ...) {
+ va_list args;
+ char buf[1024];
+ va_start(args, format);
+ vsprintf(buf, format, args);
+ va_end(args);
+ included **p = &included_root;
+ while (*p) {
+ int i = strcmp(buf,(*p)->text);
+ if (!i) return 0;
+ else if (i < 0) p = &((*p)->left);
+ else p = &((*p)->right);
+ }
+ *p = new included(buf);
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+// silly thing to prevent declaring unused variables:
+// When this symbol is on, all attempts to write code don't write
+// anything, but set a variable if it looks like the varaible "o" is used:
+int varused_test;
+int varused;
+
+// write an array of C characters (adds a null):
+void write_cstring(const char *w, int length) {
+ if (varused_test) return;
+ const char *e = w+length;
+ int linelength = 1;
+ putc('\"', code_file);
+ for (; w < e;) {
+ if (linelength >= 75) {fputs("\\\n",code_file); linelength = 0;}
+ int c = *w++;
+ switch (c) {
+ case '\b': c = 'b'; goto QUOTED;
+ case '\t': c = 't'; goto QUOTED;
+ case '\n': c = 'n'; goto QUOTED;
+ case '\f': c = 'f'; goto QUOTED;
+ case '\r': c = 'r'; goto QUOTED;
+ case '\"':
+ case '\'':
+ case '\\':
+ QUOTED:
+ putc('\\',code_file);
+ putc(c,code_file);
+ linelength += 2;
+ break;
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ if (*w < '0' || *w > '9') {c += '0'; goto QUOTED;}
+ // else fall through:
+ default:
+ if (c < ' ' || c >= 127) {
+ QUOTENEXT:
+ fprintf(code_file, "\\x%02x",c&255);
+ linelength += 4;
+ c = *w;
+ if (w < e && (c>='0'&&c<='9' || c>='a'&&c<='f' || c>='A'&&c<='F')) {
+ w++; goto QUOTENEXT;
+ }
+ } else {
+ putc(c,code_file);
+ linelength++;
+ }
+ break;
+ }
+ }
+ putc('\"', code_file);
+}
+
+// write a C string, quoting characters if necessary:
+void write_cstring(const char *w) {write_cstring(w,strlen(w));}
+
+void write_c(const char* format,...) {
+ if (varused_test) {varused = 1; return;}
+ va_list args;
+ va_start(args, format);
+ vfprintf(code_file, format, args);
+ va_end(args);
+}
+
+void write_h(const char* format,...) {
+ if (varused_test) return;
+ va_list args;
+ va_start(args, format);
+ vfprintf(header_file, format, args);
+ va_end(args);
+}
+
+#include <FL/filename.H>
+int write_number;
+
+// recursively dump code, putting children between the two parts
+// of the parent code:
+static Fl_Type* write_code(Fl_Type* p) {
+ p->write_code1();
+ Fl_Type* q;
+ for (q = p->next; q && q->level > p->level;) q = write_code(q);
+ p->write_code2();
+ return q;
+}
+
+int write_code(const char *s, const char *t) {
+ write_number++;
+ delete id_root; id_root = 0;
+ indentation = 0;
+ if (!s) code_file = stdout;
+ else {
+ FILE *f = fopen(s,"w");
+ if (!f) return 0;
+ code_file = f;
+ }
+ if (!t) header_file = stdout;
+ else {
+ FILE *f = fopen(t,"w");
+ if (!f) {fclose(code_file); return 0;}
+ header_file = f;
+ }
+ const char *hdr = "\
+// generated by Fast Light User Interface Designer (fluid) version %.2f\n\n";
+ fprintf(header_file, hdr, FL_VERSION);
+ fprintf(code_file, hdr, FL_VERSION);
+ Fl_Type *p;
+
+ for (p = Fl_Type::first; p; p = p->next) p->write_declare();
+ delete included_root; included_root = 0;
+
+ if (t) write_c("#include \"%s\"\n", filename_name(t));
+ for (p = Fl_Type::first; p; p = p->next) p->write_static();
+ for (p = Fl_Type::first; p;) p = write_code(p);
+
+ if (!s) return 1;
+ int x = fclose(code_file);
+ code_file = 0;
+ int y = fclose(header_file);
+ header_file = 0;
+ return x >= 0 && y >= 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Type::write_declare() {}
+void Fl_Type::write_static() {}
+void Fl_Type::write_code1() {
+ write_h("// Header for %s\n", title());
+ write_c("// Code for %s\n", title());
+}
+void Fl_Type::write_code2() {}
diff --git a/fluid/factory.cxx b/fluid/factory.cxx
new file mode 100644
index 000000000..5a5ff5383
--- /dev/null
+++ b/fluid/factory.cxx
@@ -0,0 +1,651 @@
+/* factory.C
+
+ Type classes for most of the fltk widgets. Most of the work
+ is done by code in Fl_Widget_Type.C. Also a factory instance
+ of each of these type classes.
+
+ This file also contains the "new" menu, which has a pointer
+ to a factory instance for every class (both the ones defined
+ here and ones in other files)
+*/
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Menu_Item.H>
+#include <string.h>
+#include <stdio.h>
+
+#if defined(WIN32) || defined(__EMX__)
+#define strcasecmp stricmp
+#endif
+
+#include "Fl_Widget_Type.H"
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Box.H>
+class Fl_Box_Type : public Fl_Widget_Type {
+public:
+ virtual const char *type_name() {return "Fl_Box";}
+ Fl_Widget *widget(int x,int y,int w, int h) {
+ return new Fl_Box(x,y,w,h,"label");}
+ Fl_Widget_Type *_make() {return new Fl_Box_Type();}
+};
+static Fl_Box_Type Fl_Box_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Button.H>
+static Fl_Menu_Item button_type_menu[] = {
+ {"Normal",0,0,(void*)0},
+ {"Toggle",0,0,(void*)FL_TOGGLE_BUTTON},
+ {"Radio",0,0,(void*)FL_RADIO_BUTTON},
+ {0}};
+class Fl_Button_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return button_type_menu;}
+public:
+ virtual const char *type_name() {return "Fl_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Button(x,y,w,h,"button");}
+ Fl_Widget_Type *_make() {return new Fl_Button_Type();}
+ int is_button() const {return 1;}
+};
+static Fl_Button_Type Fl_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Return_Button.H>
+class Fl_Return_Button_Type : public Fl_Button_Type {
+public:
+ virtual const char *type_name() {return "Fl_Return_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Return_Button(x,y,w,h,0);}
+ Fl_Widget_Type *_make() {return new Fl_Return_Button_Type();}
+};
+static Fl_Return_Button_Type Fl_Return_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Repeat_Button.H>
+class Fl_Repeat_Button_Type : public Fl_Widget_Type {
+public:
+ virtual const char *type_name() {return "Fl_Repeat_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Repeat_Button(x,y,w,h,0);}
+ Fl_Widget_Type *_make() {return new Fl_Repeat_Button_Type();}
+};
+static Fl_Repeat_Button_Type Fl_Repeat_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Light_Button.H>
+class Fl_Light_Button_Type : public Fl_Button_Type {
+public:
+ virtual const char *type_name() {return "Fl_Light_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Light_Button(x,y,w,h,"button");}
+ Fl_Widget_Type *_make() {return new Fl_Light_Button_Type();}
+};
+static Fl_Light_Button_Type Fl_Light_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Check_Button.H>
+class Fl_Check_Button_Type : public Fl_Button_Type {
+public:
+ virtual const char *type_name() {return "Fl_Check_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Check_Button(x,y,w,h,"button");}
+ Fl_Widget_Type *_make() {return new Fl_Check_Button_Type();}
+};
+static Fl_Check_Button_Type Fl_Check_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Round_Button.H>
+class Fl_Round_Button_Type : public Fl_Button_Type {
+public:
+ virtual const char *type_name() {return "Fl_Round_Button";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Round_Button(x,y,w,h,"button");}
+ Fl_Widget_Type *_make() {return new Fl_Round_Button_Type();}
+};
+static Fl_Round_Button_Type Fl_Round_Button_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Browser.H>
+static Fl_Menu_Item browser_type_menu[] = {
+ {"No Select",0,0,(void*)FL_NORMAL_BROWSER},
+ {"Select",0,0,(void*)FL_SELECT_BROWSER},
+ {"Hold",0,0,(void*)FL_HOLD_BROWSER},
+ {"Multi",0,0,(void*)FL_MULTI_BROWSER},
+ {0}};
+class Fl_Browser_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return browser_type_menu;}
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Browser *o = (Fl_Browser*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+public:
+ virtual const char *type_name() {return "Fl_Browser";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ Fl_Browser* b = new Fl_Browser(x,y,w,h);
+ char buffer[20];
+ for (int i = 1; i <= 20; i++) {
+ sprintf(buffer,"Browser Line %d",i);
+ b->add(buffer);
+ }
+ return b;
+ }
+ Fl_Widget_Type *_make() {return new Fl_Browser_Type();}
+};
+static Fl_Browser_Type Fl_Browser_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Counter.H>
+static Fl_Menu_Item counter_type_menu[] = {
+ {"Normal",0,0,(void*)FL_NORMAL_COUNTER},
+ {"Simple",0,0,(void*)FL_SIMPLE_COUNTER},
+ {0}};
+class Fl_Counter_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return counter_type_menu;}
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Counter *o = (Fl_Counter*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+ int is_valuator() const {return 1;}
+public:
+ virtual const char *type_name() {return "Fl_Counter";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Counter(x,y,w,h,"counter:");}
+ Fl_Widget_Type *_make() {return new Fl_Counter_Type();}
+};
+static Fl_Counter_Type Fl_Counter_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Input.H>
+static Fl_Menu_Item input_type_menu[] = {
+ {"Normal",0,0,(void*)FL_NORMAL_INPUT},
+ {"Multiline",0,0,(void*)FL_MULTILINE_INPUT},
+ {"Secret",0,0,(void*)FL_SECRET_INPUT},
+ {"Int",0,0,(void*)FL_INT_INPUT},
+ {"Float",0,0,(void*)FL_FLOAT_INPUT},
+ {0}};
+class Fl_Input_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return input_type_menu;}
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Input_ *o = (Fl_Input_*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+public:
+ virtual const char *type_name() {return "Fl_Input";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ Fl_Input *o = new Fl_Input(x,y,w,h,"input:");
+ o->value("Text Input");
+ return o;
+ }
+ Fl_Widget_Type *_make() {return new Fl_Input_Type();}
+};
+static Fl_Input_Type Fl_Input_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Clock.H>
+class Fl_Clock_Type : public Fl_Widget_Type {
+public:
+ virtual const char *type_name() {return "Fl_Clock";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Clock(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Clock_Type();}
+};
+static Fl_Clock_Type Fl_Clock_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Adjuster.H>
+class Fl_Adjuster_Type : public Fl_Widget_Type {
+ int is_valuator() const {return 1;}
+public:
+ virtual const char *type_name() {return "Fl_Adjuster";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Adjuster(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Adjuster_Type();}
+};
+static Fl_Adjuster_Type Fl_Adjuster_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Dial.H>
+static Fl_Menu_Item dial_type_menu[] = {
+ {"Dot",0,0,(void*)0},
+ {"Line",0,0,(void*)FL_LINE_DIAL},
+ {"Fill",0,0,(void*)FL_FILL_DIAL},
+ {0}};
+class Fl_Dial_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return dial_type_menu;}
+ int is_valuator() const {return 1;}
+public:
+ virtual const char *type_name() {return "Fl_Dial";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Dial(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Dial_Type();}
+};
+static Fl_Dial_Type Fl_Dial_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Roller.H>
+static Fl_Menu_Item roller_type_menu[] = {
+ {"Vertical",0,0,(void*)0},
+ {"Horizontal",0,0,(void*)FL_HORIZONTAL},
+ {0}};
+class Fl_Roller_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return roller_type_menu;}
+ int is_valuator() const {return 1;}
+public:
+ virtual const char *type_name() {return "Fl_Roller";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Roller(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Roller_Type();}
+};
+static Fl_Roller_Type Fl_Roller_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Scrollbar.H>
+static Fl_Menu_Item slider_type_menu[] = {
+ {"Vertical",0,0,(void*)FL_VERT_SLIDER},
+ {"Horizontal",0,0,(void*)FL_HOR_SLIDER},
+ {"Vert Fill",0,0,(void*)FL_VERT_FILL_SLIDER},
+ {"Horz Fill",0,0,(void*)FL_HOR_FILL_SLIDER},
+ {"Vert Knob",0,0,(void*)FL_VERT_NICE_SLIDER},
+ {"Horz Knob",0,0,(void*)FL_HOR_NICE_SLIDER},
+ {0}};
+class Fl_Slider_Type : public Fl_Widget_Type {
+ Fl_Menu_Item *subtypes() {return slider_type_menu;}
+ int is_valuator() const {return 2;}
+public:
+ virtual const char *type_name() {return "Fl_Slider";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Slider(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Slider_Type();}
+};
+static Fl_Slider_Type Fl_Slider_type;
+
+static Fl_Menu_Item scrollbar_type_menu[] = {
+ {"Vertical",0,0,(void*)FL_VERT_SLIDER},
+ {"Horizontal",0,0,(void*)FL_HOR_SLIDER},
+ {0}};
+class Fl_Scrollbar_Type : public Fl_Slider_Type {
+ Fl_Menu_Item *subtypes() {return scrollbar_type_menu;}
+public:
+ virtual const char *type_name() {return "Fl_Scrollbar";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Scrollbar(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Scrollbar_Type();}
+};
+static Fl_Scrollbar_Type Fl_Scrollbar_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Output.H>
+static Fl_Menu_Item output_type_menu[] = {
+ {"Normal",0,0,(void*)FL_NORMAL_INPUT},
+ {"Multiline",0,0,(void*)FL_MULTILINE_INPUT},
+ {0}};
+class Fl_Output_Type : public Fl_Input_Type {
+ Fl_Menu_Item *subtypes() {return output_type_menu;}
+public:
+ virtual const char *type_name() {return "Fl_Output";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ Fl_Output *o = new Fl_Output(x,y,w,h,"output:");
+ o->value("Text Output");
+ return o;
+ }
+ Fl_Widget_Type *_make() {return new Fl_Output_Type();}
+};
+static Fl_Output_Type Fl_Output_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Value_Input.H>
+class Fl_Value_Input_Type : public Fl_Widget_Type {
+public:
+ virtual const char *type_name() {return "Fl_Value_Input";}
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Value_Input *o = (Fl_Value_Input*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+ int is_valuator() const {return 1;}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ Fl_Value_Input *o = new Fl_Value_Input(x,y,w,h,"value:");
+ return o;
+ }
+ Fl_Widget_Type *_make() {return new Fl_Value_Input_Type();}
+};
+static Fl_Value_Input_Type Fl_Value_Input_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Value_Output.H>
+class Fl_Value_Output_Type : public Fl_Widget_Type {
+public:
+ virtual const char *type_name() {return "Fl_Value_Output";}
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Value_Output *o = (Fl_Value_Output*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+ int is_valuator() const {return 1;}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ Fl_Value_Output *o = new Fl_Value_Output(x,y,w,h,"value:");
+ return o;
+ }
+ Fl_Widget_Type *_make() {return new Fl_Value_Output_Type();}
+};
+static Fl_Value_Output_Type Fl_Value_Output_type;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Value_Slider.H>
+class Fl_Value_Slider_Type : public Fl_Slider_Type {
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) {
+ Fl_Value_Slider *o = (Fl_Value_Slider*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = o->textfont(); s = o->textsize(); c = o->textcolor(); break;
+ case 1: o->textfont(f); break;
+ case 2: o->textsize(s); break;
+ case 3: o->textcolor(c); break;
+ }
+ return 1;
+ }
+public:
+ virtual const char *type_name() {return "Fl_Value_Slider";}
+ Fl_Widget *widget(int x,int y,int w,int h) {
+ return new Fl_Value_Slider(x,y,w,h);}
+ Fl_Widget_Type *_make() {return new Fl_Value_Slider_Type();}
+};
+static Fl_Value_Slider_Type Fl_Value_Slider_type;
+
+////////////////////////////////////////////////////////////////
+
+extern class Fl_Function_Type Fl_Function_type;
+extern class Fl_Code_Type Fl_Code_type;
+extern class Fl_CodeBlock_Type Fl_CodeBlock_type;
+extern class Fl_Decl_Type Fl_Decl_type;
+extern class Fl_DeclBlock_Type Fl_DeclBlock_type;
+extern class Fl_Class_Type Fl_Class_type;
+extern class Fl_Window_Type Fl_Window_type;
+extern class Fl_Group_Type Fl_Group_type;
+extern class Fl_Tabs_Type Fl_Tabs_type;
+extern class Fl_Scroll_Type Fl_Scroll_type;
+extern class Fl_Tile_Type Fl_Tile_type;
+extern class Fl_Choice_Type Fl_Choice_type;
+extern class Fl_Menu_Bar_Type Fl_Menu_Bar_type;
+extern class Fl_Menu_Button_Type Fl_Menu_Button_type;
+extern class Fl_Menu_Item_Type Fl_Menu_Item_type;
+extern class Fl_Submenu_Type Fl_Submenu_type;
+
+extern void select(Fl_Type *,int);
+extern void select_only(Fl_Type *);
+
+static void cb(Fl_Widget *, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->make();
+ if (t) {select_only(t); modflag = 1; t->open();}
+}
+
+Fl_Menu_Item New_Menu[] = {
+{"code",0,0,0,FL_SUBMENU},
+ {"function/method",0,cb,(void*)&Fl_Function_type},
+ {"code",0,cb,(void*)&Fl_Code_type},
+ {"code block",0,cb,(void*)&Fl_CodeBlock_type},
+ {"declaration",0,cb,(void*)&Fl_Decl_type},
+ {"declaration block",0,cb,(void*)&Fl_DeclBlock_type},
+ {"class",0,cb,(void*)&Fl_Class_type},
+{0},
+{"group",0,0,0,FL_SUBMENU},
+ {0,0,cb,(void*)&Fl_Window_type},
+ {0,0,cb,(void*)&Fl_Group_type},
+ {0,0,cb,(void*)&Fl_Tabs_type},
+ {0,0,cb,(void*)&Fl_Scroll_type},
+ {0,0,cb,(void*)&Fl_Tile_type},
+{0},
+{"buttons",0,0,0,FL_SUBMENU},
+ {0,0,cb,(void*)&Fl_Button_type},
+ {0,0,cb,(void*)&Fl_Return_Button_type},
+ {0,0,cb,(void*)&Fl_Light_Button_type},
+ {0,0,cb,(void*)&Fl_Check_Button_type},
+ {0,0,cb,(void*)&Fl_Round_Button_type},
+ {0,0,cb,(void*)&Fl_Repeat_Button_type},
+{0},
+{"valuators",0,0,0,FL_SUBMENU},
+ {0,0,cb,(void*)&Fl_Slider_type},
+ {0,0,cb,(void*)&Fl_Scrollbar_type},
+ {0,0,cb,(void*)&Fl_Value_Slider_type},
+ {0,0,cb,(void*)&Fl_Adjuster_type},
+ {0,0,cb,(void*)&Fl_Counter_type},
+ {0,0,cb,(void*)&Fl_Dial_type},
+ {0,0,cb,(void*)&Fl_Roller_type},
+ {0,0,cb,(void*)&Fl_Value_Input_type},
+ {0,0,cb,(void*)&Fl_Value_Output_type},
+{0},
+{"text",0,0,0,FL_SUBMENU},
+ {0,0,cb,(void*)&Fl_Input_type},
+ {0,0,cb,(void*)&Fl_Output_type},
+{0},
+{"menus",0,0,0,FL_SUBMENU},
+ {0,0,cb,(void*)&Fl_Menu_Bar_type},
+ {0,0,cb,(void*)&Fl_Menu_Button_type},
+ {0,0,cb,(void*)&Fl_Choice_type},
+ {0,0,cb, (void*)&Fl_Submenu_type},
+ {0,0,cb, (void*)&Fl_Menu_Item_type},
+{0},
+{"other",0,0,0,FL_SUBMENU},
+ {0,0,cb,(void*)&Fl_Browser_type},
+ {0,0,cb,(void*)&Fl_Box_type},
+ {0,0,cb,(void*)&Fl_Clock_type},
+{0},
+{0}};
+
+void fill_in_New_Menu() {
+ for (unsigned i = 0; i < sizeof(New_Menu)/sizeof(*New_Menu); i++) {
+ Fl_Menu_Item *m = New_Menu+i;
+ if (m->user_data() && !m->text) {
+ const char *n = ((Fl_Type*)(m->user_data()))->type_name();
+ if (!strncmp(n,"Fl_",3)) n += 3;
+ m->text = n;
+ }
+ }
+}
+
+// use keyword to pick the type, this is used to parse files:
+int reading_file;
+Fl_Type *Fl_Type_make(const char *tn) {
+ reading_file = 1; // makes labels be null
+ Fl_Type *r = 0;
+ for (unsigned i = 0; i < sizeof(New_Menu)/sizeof(*New_Menu); i++) {
+ Fl_Menu_Item *m = New_Menu+i;
+ if (!m->user_data()) continue;
+ Fl_Type *t = (Fl_Type*)(m->user_data());
+ if (!strcasecmp(tn,t->type_name())) {r = t->make(); break;}
+ }
+ reading_file = 0;
+ return r;
+}
+
+////////////////////////////////////////////////////////////////
+
+// Since I have included all the .H files, do this table here:
+// This table is only used to read fdesign files:
+
+struct symbol {const char *name; int value;};
+
+static symbol table[] = {
+ {"BLACK", FL_BLACK},
+ {"RED", FL_RED},
+ {"GREEN", FL_GREEN},
+ {"YELLOW", FL_YELLOW},
+ {"BLUE", FL_BLUE},
+ {"MAGENTA", FL_MAGENTA},
+ {"CYAN", FL_CYAN},
+ {"WHITE", FL_WHITE},
+
+ {"LCOL", FL_BLACK},
+ {"COL1", FL_GRAY},
+ {"MCOL", FL_LIGHT1},
+ {"LEFT_BCOL", FL_LIGHT3},
+ {"TOP_BCOL", FL_LIGHT2},
+ {"BOTTOM_BCOL", FL_DARK2},
+ {"RIGHT_BCOL", FL_DARK3},
+ {"INACTIVE", FL_INACTIVE_COLOR},
+ {"INACTIVE_COL", FL_INACTIVE_COLOR},
+ {"FREE_COL1", FL_FREE_COLOR},
+ {"FREE_COL2", FL_FREE_COLOR+1},
+ {"FREE_COL3", FL_FREE_COLOR+2},
+ {"FREE_COL4", FL_FREE_COLOR+3},
+ {"FREE_COL5", FL_FREE_COLOR+4},
+ {"FREE_COL6", FL_FREE_COLOR+5},
+ {"FREE_COL7", FL_FREE_COLOR+6},
+ {"FREE_COL8", FL_FREE_COLOR+7},
+ {"FREE_COL9", FL_FREE_COLOR+8},
+ {"FREE_COL10", FL_FREE_COLOR+9},
+ {"FREE_COL11", FL_FREE_COLOR+10},
+ {"FREE_COL12", FL_FREE_COLOR+11},
+ {"FREE_COL13", FL_FREE_COLOR+12},
+ {"FREE_COL14", FL_FREE_COLOR+13},
+ {"FREE_COL15", FL_FREE_COLOR+14},
+ {"FREE_COL16", FL_FREE_COLOR+15},
+ {"TOMATO", 131},
+ {"INDIANRED", 164},
+ {"SLATEBLUE", 195},
+ {"DARKGOLD", 84},
+ {"PALEGREEN", 157},
+ {"ORCHID", 203},
+ {"DARKCYAN", 189},
+ {"DARKTOMATO", 113},
+ {"WHEAT", 174},
+ {"ALIGN_CENTER", FL_ALIGN_CENTER},
+ {"ALIGN_TOP", FL_ALIGN_TOP},
+ {"ALIGN_BOTTOM", FL_ALIGN_BOTTOM},
+ {"ALIGN_LEFT", FL_ALIGN_LEFT},
+ {"ALIGN_RIGHT", FL_ALIGN_RIGHT},
+ {"ALIGN_INSIDE", FL_ALIGN_INSIDE},
+ {"ALIGN_TOP_LEFT", FL_ALIGN_TOP | FL_ALIGN_LEFT},
+ {"ALIGN_TOP_RIGHT", FL_ALIGN_TOP | FL_ALIGN_RIGHT},
+ {"ALIGN_BOTTOM_LEFT", FL_ALIGN_BOTTOM | FL_ALIGN_LEFT},
+ {"ALIGN_BOTTOM_RIGHT", FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT},
+ {"ALIGN_CENTER|FL_ALIGN_INSIDE", FL_ALIGN_CENTER|FL_ALIGN_INSIDE},
+ {"ALIGN_TOP|FL_ALIGN_INSIDE", FL_ALIGN_TOP|FL_ALIGN_INSIDE},
+ {"ALIGN_BOTTOM|FL_ALIGN_INSIDE", FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE},
+ {"ALIGN_LEFT|FL_ALIGN_INSIDE", FL_ALIGN_LEFT|FL_ALIGN_INSIDE},
+ {"ALIGN_RIGHT|FL_ALIGN_INSIDE", FL_ALIGN_RIGHT|FL_ALIGN_INSIDE},
+ {"ALIGN_INSIDE|FL_ALIGN_INSIDE", FL_ALIGN_INSIDE|FL_ALIGN_INSIDE},
+ {"ALIGN_TOP_LEFT|FL_ALIGN_INSIDE", FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE},
+ {"ALIGN_TOP_RIGHT|FL_ALIGN_INSIDE", FL_ALIGN_TOP|FL_ALIGN_RIGHT|FL_ALIGN_INSIDE},
+ {"ALIGN_BOTTOM_LEFT|FL_ALIGN_INSIDE", FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_INSIDE},
+ {"ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE",FL_ALIGN_BOTTOM|FL_ALIGN_RIGHT|FL_ALIGN_INSIDE},
+
+ {"ALIGN_LEFT_TOP", FL_ALIGN_TOP | FL_ALIGN_LEFT},
+ {"ALIGN_RIGHT_TOP", FL_ALIGN_TOP | FL_ALIGN_RIGHT},
+ {"ALIGN_LEFT_BOTTOM", FL_ALIGN_BOTTOM | FL_ALIGN_LEFT},
+ {"ALIGN_RIGHT_BOTTOM", FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT},
+ {"INVALID_STYLE", 255},
+ {"NORMAL_STYLE", FL_HELVETICA},
+ {"BOLD_STYLE", FL_HELVETICA|FL_BOLD},
+ {"ITALIC_STYLE", FL_HELVETICA|FL_ITALIC},
+ {"BOLDITALIC_STYLE", FL_HELVETICA|FL_BOLD|FL_ITALIC},
+ {"FIXED_STYLE", FL_COURIER},
+ {"FIXEDBOLD_STYLE", FL_COURIER|FL_BOLD},
+ {"FIXEDITALIC_STYLE", FL_COURIER|FL_ITALIC},
+ {"FIXEDBOLDITALIC_STYLE", FL_COURIER|FL_BOLD|FL_ITALIC},
+ {"TIMES_STYLE", FL_TIMES},
+ {"TIMESBOLD_STYLE", FL_TIMES|FL_BOLD},
+ {"TIMESITALIC_STYLE", FL_TIMES|FL_ITALIC},
+ {"TIMESBOLDITALIC_STYLE", FL_TIMES|FL_BOLD|FL_ITALIC},
+ {"SHADOW_STYLE", (_FL_SHADOW_LABEL<<8)},
+ {"ENGRAVED_STYLE", (_FL_ENGRAVED_LABEL<<8)},
+ {"EMBOSSED_STYLE", (_FL_EMBOSSED_LABEL<<0)},
+ {"TINY_SIZE", 8},
+ {"SMALL_SIZE", 11},
+ {"NORMAL_SIZE", FL_NORMAL_SIZE},
+ {"MEDIUM_SIZE", 18},
+ {"LARGE_SIZE", 24},
+ {"HUGE_SIZE", 32},
+ {"DEFAULT_SIZE", FL_NORMAL_SIZE},
+ {"TINY_FONT", 8},
+ {"SMALL_FONT", 11},
+ {"NORMAL_FONT", FL_NORMAL_SIZE},
+ {"MEDIUM_FONT", 18},
+ {"LARGE_FONT", 24},
+ {"HUGE_FONT", 32},
+ {"NORMAL_FONT1", 11},
+ {"NORMAL_FONT2", FL_NORMAL_SIZE},
+ {"DEFAULT_FONT", 11},
+ {"RETURN_END_CHANGED", 0},
+ {"RETURN_CHANGED", 1},
+ {"RETURN_END", 2},
+ {"RETURN_ALWAYS", 3},
+ {"PUSH_BUTTON", FL_TOGGLE_BUTTON},
+ {"RADIO_BUTTON", FL_RADIO_BUTTON},
+ {"HIDDEN_BUTTON", FL_HIDDEN_BUTTON},
+ {"SELECT_BROWSER", FL_SELECT_BROWSER},
+ {"HOLD_BROWSER", FL_HOLD_BROWSER},
+ {"MULTI_BROWSER", FL_MULTI_BROWSER},
+ {"SIMPLE_COUNTER", FL_SIMPLE_COUNTER},
+ {"LINE_DIAL", FL_LINE_DIAL},
+ {"FILL_DIAL", FL_FILL_DIAL},
+ {"VERT_SLIDER", FL_VERT_SLIDER},
+ {"HOR_SLIDER", FL_HOR_SLIDER},
+ {"VERT_FILL_SLIDER", FL_VERT_FILL_SLIDER},
+ {"HOR_FILL_SLIDER", FL_HOR_FILL_SLIDER},
+ {"VERT_NICE_SLIDER", FL_VERT_NICE_SLIDER},
+ {"HOR_NICE_SLIDER", FL_HOR_NICE_SLIDER},
+};
+
+#include <stdlib.h>
+
+int lookup_symbol(const char *name, int &v, int numberok) {
+ if (name[0]=='F' && name[1]=='L' && name[2]=='_') name += 3;
+ for (int i=0; i < int(sizeof(table)/sizeof(*table)); i++)
+ if (!strcasecmp(name,table[i].name)) {v = table[i].value; return 1;}
+ if (numberok && ((v = atoi(name)) || !strcmp(name,"0"))) return 1;
+ return 0;
+}
diff --git a/fluid/file.cxx b/fluid/file.cxx
new file mode 100644
index 000000000..69bc97d17
--- /dev/null
+++ b/fluid/file.cxx
@@ -0,0 +1,562 @@
+/* file.C
+
+ Code to read and write Fluid .fl files
+
+ You may find the basic read_* and write_* routines to
+ be useful for other programs. I have used them many times.
+ They are somewhat similar to tcl, using matching { and }
+ to quote strings.
+
+*/
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+////////////////////////////////////////////////////////////////
+// BASIC FILE WRITING:
+
+static FILE *fout;
+
+int open_write(const char *s) {
+ if (!s) {fout = stdout; return 1;}
+ FILE *f = fopen(s,"w");
+ if (!f) return 0;
+ fout = f;
+ return 1;
+}
+
+int close_write() {
+ if (fout != stdout) {
+ int x = fclose(fout);
+ fout = stdout;
+ return x >= 0;
+ }
+ return 1;
+}
+
+static int needspace;
+int is_id(char); // in code.C
+
+// write a string, quoting characters if necessary:
+void write_word(const char *w) {
+ if (needspace) putc(' ', fout);
+ needspace = 1;
+ if (!w || !*w) {fprintf(fout,"{}"); return;}
+ const char *p;
+ // see if it is a single word:
+ for (p = w; is_id(*p); p++) ;
+ if (!*p) {fprintf(fout,"%s",w); return;}
+ // see if there are matching braces:
+ int n = 0;
+ for (p = w; *p; p++) {
+ if (*p == '{') n++;
+ else if (*p == '}') {n--; if (n<0) break;}
+ }
+ int mismatched = (n != 0);
+ // write out brace-quoted string:
+ putc('{', fout);
+ for (; *w; w++) {
+ switch (*w) {
+ case '{':
+ case '}':
+ if (!mismatched) break;
+ case '\\':
+ case '#':
+ putc('\\',fout);
+ break;
+ }
+ putc(*w,fout);
+ }
+ putc('}', fout);
+}
+
+// write an arbitrary formatted word, or a comment, etc:
+void write_string(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ if (needspace) fputc(' ',fout);
+ vfprintf(fout, format, args);
+ va_end(args);
+ needspace = !isspace(format[strlen(format)-1]);
+}
+
+// start a new line and indent it for a given nesting level:
+void write_indent(int n) {
+ fputc('\n',fout);
+ while (n--) {fputc(' ',fout); fputc(' ',fout);}
+ needspace = 0;
+}
+
+// write a '{' at the given indenting level:
+void write_open(int) {
+ if (needspace) fputc(' ',fout);
+ fputc('{',fout);
+ needspace = 0;
+}
+
+// write a '}' at the given indenting level:
+void write_close(int n) {
+ if (needspace) write_indent(n);
+ fputc('}',fout);
+ needspace = 1;
+}
+
+////////////////////////////////////////////////////////////////
+// BASIC FILE READING:
+
+static FILE *fin;
+static int lineno;
+static const char *fname;
+
+int open_read(const char *s) {
+ lineno = 1;
+ if (!s) {fin = stdin; fname = "stdin"; return 1;}
+ FILE *f = fopen(s,"r");
+ if (!f) return 0;
+ fin = f;
+ fname = s;
+ return 1;
+}
+
+int close_read() {
+ if (fin != stdin) {
+ int x = fclose(fin);
+ fin = 0;
+ return x >= 0;
+ }
+ return 1;
+}
+
+#include <FL/fl_message.H>
+
+void read_error(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ if (!fin) {
+ char buffer[1024];
+ vsprintf(buffer, format, args);
+ fl_message(buffer);
+ } else {
+ fprintf(stderr, "%s:%d: ", fname, lineno);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+ }
+ va_end(args);
+}
+
+static int hexdigit(int x) {
+ if (isdigit(x)) return x-'0';
+ if (isupper(x)) return x-'A'+10;
+ if (islower(x)) return x-'a'+10;
+ return 20;
+}
+
+
+static int read_quoted() { // read whatever character is after a \ .
+ int c,d,x;
+ switch(c = fgetc(fin)) {
+ case '\n': lineno++; return -1;
+ case 'a' : return('\a');
+ case 'b' : return('\b');
+ case 'f' : return('\f');
+ case 'n' : return('\n');
+ case 'r' : return('\r');
+ case 't' : return('\t');
+ case 'v' : return('\v');
+ case 'x' : /* read hex */
+ for (c=x=0; x<3; x++) {
+ int ch = fgetc(fin);
+ d = hexdigit(ch);
+ if (d > 15) {ungetc(ch,fin); break;}
+ c = (c<<4)+d;
+ }
+ break;
+ default: /* read octal */
+ if (c<'0' || c>'7') break;
+ c -= '0';
+ for (x=0; x<2; x++) {
+ int ch = fgetc(fin);
+ d = hexdigit(ch);
+ if (d>7) {ungetc(ch,fin); break;}
+ c = (c<<3)+d;
+ }
+ break;
+ }
+ return(c);
+}
+
+// return a word read from the file, or NULL at the EOF:
+// This will skip all comments (# to end of line), and evaluate
+// all \xxx sequences and use \ at the end of line to remove the newline.
+// A word is any one of:
+// a continuous string of non-space chars except { and } and #
+// everything between matching {...} (unless wantbrace != 0)
+// the characters '{' and '}'
+
+static char *buffer;
+static int buflen;
+static void expand_buffer(int length) {
+ if (length >= buflen) {
+ if (!buflen) {
+ buflen = length+1;
+ buffer = (char*)malloc(buflen);
+ } else {
+ buflen = 2*buflen;
+ if (length >= buflen) buflen = length+1;
+ buffer = (char *)realloc((void *)buffer,buflen);
+ }
+ }
+}
+
+const char *read_word(int wantbrace) {
+ int x;
+
+ // skip all the whitespace before it:
+ for (;;) {
+ x = getc(fin);
+ if (x < 0) { // eof
+ return 0;
+ } else if (x == '#') { // comment
+ do x = getc(fin); while (x >= 0 && x != '\n');
+ lineno++;
+ continue;
+ } else if (x == '\n') {
+ lineno++;
+ } else if (!isspace(x)) {
+ break;
+ }
+ }
+
+ expand_buffer(100);
+
+ if (x == '{' && !wantbrace) {
+
+ // read in whatever is between braces
+ int length = 0;
+ int nesting = 0;
+ for (;;) {
+ x = getc(fin);
+ if (x<0) {read_error("Missing '}'"); break;}
+ else if (x == '#') { // embedded comment
+ do x = getc(fin); while (x >= 0 && x != '\n');
+ lineno++;
+ continue;
+ } else if (x == '\n') lineno++;
+ else if (x == '\\') {x = read_quoted(); if (x<0) continue;}
+ else if (x == '{') nesting++;
+ else if (x == '}') {if (!nesting--) break;}
+ buffer[length++] = x;
+ expand_buffer(length);
+ }
+ buffer[length] = 0;
+ return buffer;
+
+ } else if (x == '{' || x == '}') {
+ // all the punctuation is a word:
+ buffer[0] = x;
+ buffer[1] = 0;
+ return buffer;
+
+ } else {
+
+ // read in an unquoted word:
+ int length = 0;
+ for (;;) {
+ if (x == '\\') {x = read_quoted(); if (x<0) continue;}
+ else if (x<0 || isspace(x) || x=='{' || x=='}' || x=='#') break;
+ buffer[length++] = x;
+ expand_buffer(length);
+ x = getc(fin);
+ }
+ ungetc(x, fin);
+ buffer[length] = 0;
+ return buffer;
+
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl.H>
+#include "Fl_Widget_Type.H"
+
+// global int variables:
+extern int gridx, gridy, snap;
+static struct {const char* name; int* value;} inttable[] = {
+ {"gridx", &gridx},
+ {"gridy", &gridy},
+ {"snap", &snap}
+};
+
+extern const char* header_file_name;
+extern const char* code_file_name;
+
+int write_file(const char *filename, int selected_only) {
+ if (!open_write(filename)) return 0;
+ write_string("# data file for the Fltk User Interface Designer (fluid)\n"
+ "version %.2f",FL_VERSION);
+ if (!selected_only) {
+ write_string("\nheader_name"); write_word(header_file_name);
+ write_string("\ncode_name"); write_word(code_file_name);
+ for (unsigned int i=0; i<sizeof(inttable)/sizeof(*inttable); i++)
+ write_string("\n%s %d",inttable[i].name, *inttable[i].value);
+ }
+ for (Fl_Type *p = Fl_Type::first; p;) {
+ if (!selected_only || p->selected) {
+ p->write();
+ write_string("\n");
+ int q = p->level;
+ for (p = p->next; p && p->level > q; p = p->next);
+ } else {
+ p = p->next;
+ }
+ }
+ return close_write();
+}
+
+////////////////////////////////////////////////////////////////
+// read all the objects out of the input file:
+
+void read_fdesign();
+
+double read_version;
+
+extern Fl_Type *Fl_Type_make(const char *tn);
+
+static void read_children(Fl_Type *p, int paste) {
+ Fl_Type::current = p;
+ for (;;) {
+ unsigned int i;
+ const char *c = read_word();
+ REUSE_C:
+ if (!c) {
+ if (p && !paste) read_error("Missing '}'");
+ break;
+ }
+
+ if (!strcmp(c,"}")) {
+ if (!p) read_error("Unexpected '}'");
+ break;
+ }
+
+ // this is the first word in a .fd file:
+ if (!strcmp(c,"Magic:")) {
+ read_fdesign();
+ return;
+ }
+
+ if (!strcmp(c,"version")) {
+ c = read_word();
+ read_version = strtod(c,0);
+ if (read_version<=0 || read_version>FL_VERSION)
+ read_error("unknown version '%s'",c);
+ continue;
+ }
+
+ // back compatability with Vincent Penne's original class code:
+ if (!p && !strcmp(c,"define_in_struct")) {
+ Fl_Type *t = Fl_Type_make("class");
+ t->name(read_word());
+ Fl_Type::current = p = t;
+ paste = 1; // stops "missing }" error
+ continue;
+ }
+
+ if (!strcmp(c,"header_name")) {
+ header_file_name = strdup(read_word());
+ goto CONTINUE;
+ }
+
+ if (!strcmp(c,"code_name")) {
+ code_file_name = strdup(read_word());
+ goto CONTINUE;
+ }
+
+ for (i=0; i<sizeof(inttable)/sizeof(*inttable); i++) {
+ if (!strcmp(c,inttable[i].name)) {
+ c = read_word();
+ *inttable[i].value = atoi(c);
+ goto CONTINUE;
+ }
+ }
+
+ {Fl_Type *t = Fl_Type_make(c);
+ if (!t) {
+ read_error("Unknown word \"%s\"", c);
+ continue;
+ }
+ t->name(read_word());
+
+ c = read_word(1);
+ if (strcmp(c,"{")) {
+ read_error("Missing property list for %s\n",t->title());
+ goto REUSE_C;
+ }
+
+ t->open_ = 0;
+ for (;;) {
+ const char *c = read_word();
+ if (!c || !strcmp(c,"}")) break;
+ t->read_property(c);
+ }
+
+ if (!t->is_parent()) continue;
+ c = read_word(1);
+ if (strcmp(c,"{")) {
+ read_error("Missing child list for %s\n",t->title());
+ goto REUSE_C;
+ }
+ read_children(t, 0);}
+ Fl_Type::current = p;
+ CONTINUE:;
+ }
+}
+
+extern void deselect();
+
+int read_file(const char *filename, int merge) {
+ read_version = 0.0;
+ if (!open_read(filename)) return 0;
+ if (merge) deselect(); else delete_all();
+ read_children(Fl_Type::current, merge);
+ Fl_Type::current = 0;
+ for (Fl_Type *o = Fl_Type::first; o; o = o->next)
+ if (o->selected) {Fl_Type::current = o; break;}
+ return close_read();
+}
+
+////////////////////////////////////////////////////////////////
+// Read Forms and XForms fdesign files:
+
+int read_fdesign_line(const char*& name, const char*& value) {
+
+ int length = 0;
+ int x;
+ // find a colon:
+ for (;;) {
+ x = getc(fin);
+ if (x < 0) return 0;
+ if (x == '\n') {length = 0; continue;} // no colon this line...
+ if (!isspace(x)) {
+ buffer[length++] = x;
+ expand_buffer(length);
+ }
+ if (x == ':') break;
+ }
+ int valueoffset = length;
+ buffer[length-1] = 0;
+
+ // skip to start of value:
+ for (;;) {
+ x = getc(fin);
+ if (x < 0 || x == '\n' || !isspace(x)) break;
+ }
+
+ // read the value:
+ for (;;) {
+ if (x == '\\') {x = read_quoted(); if (x<0) continue;}
+ else if (x == '\n') break;
+ buffer[length++] = x;
+ expand_buffer(length);
+ x = getc(fin);
+ }
+ buffer[length] = 0;
+ name = buffer;
+ value = buffer+valueoffset;
+ return 1;
+}
+
+int fdesign_flip;
+int fdesign_magic;
+#include <FL/Fl_Group.H>
+
+static const char *class_matcher[] = {
+"FL_CHECKBUTTON", "Fl_Check_Button",
+"FL_ROUNDBUTTON", "Fl_Round_Button",
+"FL_ROUND3DBUTTON", "Fl_Round_Button",
+"FL_LIGHTBUTTON", "Fl_Light_Button",
+"FL_FRAME", "Fl_Box",
+"FL_LABELFRAME", "Fl_Box",
+"FL_TEXT", "Fl_Box",
+"FL_VALSLIDER", "Fl_Value_Slider",
+"FL_MENU", "Fl_Menu_Button",
+"3", "FL_BITMAP",
+"1", "FL_BOX",
+"71","FL_BROWSER",
+"11","FL_BUTTON",
+"4", "FL_CHART",
+"42","FL_CHOICE",
+"61","FL_CLOCK",
+"25","FL_COUNTER",
+"22","FL_DIAL",
+"101","FL_FREE",
+"31","FL_INPUT",
+"12","Fl_Light_Button",
+"41","FL_MENU",
+"23","FL_POSITIONER",
+"13","Fl_Round_Button",
+"21","FL_SLIDER",
+"2", "FL_BOX", // was FL_TEXT
+"62","FL_TIMER",
+"24","Fl_Value_Slider",
+0};
+
+void read_fdesign() {
+ fdesign_magic = atoi(read_word());
+ fdesign_flip = (fdesign_magic < 13000);
+ Fl_Widget_Type *window = 0;
+ Fl_Widget_Type *group = 0;
+ Fl_Widget_Type *widget = 0;
+ if (!Fl_Type::current) {
+ Fl_Type *t = Fl_Type_make("Function");
+ t->name("create_the_forms()");
+ Fl_Type::current = t;
+ }
+ for (;;) {
+ const char *name;
+ const char *value;
+ if (!read_fdesign_line(name, value)) break;
+
+ if (!strcmp(name,"Name")) {
+
+ window = (Fl_Widget_Type*)Fl_Type_make("Fl_Window");
+ window->name(value);
+ window->label(value);
+ Fl_Type::current = widget = window;
+
+ } else if (!strcmp(name,"class")) {
+
+ if (!strcmp(value,"FL_BEGIN_GROUP")) {
+ group = widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Group");
+ Fl_Type::current = group;
+ } else if (!strcmp(value,"FL_END_GROUP")) {
+ if (group) {
+ Fl_Group* g = (Fl_Group*)(group->o);
+ g->begin();
+ g->forms_end();
+ Fl_Group::current(0);
+ }
+ group = widget = 0;
+ Fl_Type::current = window;
+ } else {
+ for (int i = 0; class_matcher[i]; i += 2)
+ if (!strcmp(value,class_matcher[i])) {
+ value = class_matcher[i+1]; break;}
+ widget = (Fl_Widget_Type*)Fl_Type_make(value);
+ if (!widget) {
+ printf("class %s not found, using Fl_Button\n", value);
+ widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Button");
+ }
+ }
+
+ } else if (widget) {
+ if (!widget->read_fdesign(name, value))
+ printf("Ignoring \"%s: %s\"\n", name, value);
+ }
+ }
+}
+
+
diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
new file mode 100644
index 000000000..384eb5104
--- /dev/null
+++ b/fluid/fluid.cxx
@@ -0,0 +1,387 @@
+// fluid.C
+
+// Please see README for some information about the construction of this
+// rather nasty piece of code.
+
+const char *copyright =
+"The FLTK user interface designer version 0.99\n"
+"Copyright \xa9 1998 Bill Spitzak\n"
+"\n"
+"This library is free software; you can redistribute it and/or "
+"modify it under the terms of the GNU Library General Public "
+"License as published by the Free Software Foundation; either "
+"version 2 of the License, or (at your option) any later version.\n"
+"\n"
+"This library is distributed in the hope that it will be useful, "
+"but WITHOUT ANY WARRANTY; without even the implied warranty of "
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "
+"See the GNU Library General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU Library General Public "
+"License along with this library; if not, write to the Free Software "
+"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
+"USA.\n"
+"\n"
+"Written by Bill Spitzak spitzak@d2.com\n";
+
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Hold_Browser.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_file_chooser.H>
+#include <FL/fl_message.H>
+#include <FL/filename.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#if defined(WIN32) && !defined(CYGNUS)
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif
+
+#include "about_panel.H"
+
+#include "Fl_Type.H"
+
+////////////////////////////////////////////////////////////////
+
+void nyi(Fl_Widget *,void *) {
+ fl_message("That's not yet implemented, sorry");
+}
+
+static const char *filename;
+void set_filename(const char *c);
+int modflag;
+
+static char* pwd;
+static char in_source_dir;
+void goto_source_dir() {
+ if (in_source_dir) return;
+ if (!filename || !*filename) return;
+ const char *p = filename_name(filename);
+ if (p <= filename) return; // it is in the current directory
+ char buffer[1024];
+ strcpy(buffer,filename);
+ int n = p-filename; if (n>1) n--; buffer[n] = 0;
+ if (!pwd) {
+ pwd = getcwd(0,1024);
+ if (!pwd) {fprintf(stderr,"getwd : %s\n",strerror(errno)); return;}
+ }
+ if (chdir(buffer)<0) {fprintf(stderr, "Can't chdir to %s : %s\n",
+ buffer, strerror(errno)); return;}
+ in_source_dir = 1;
+}
+
+void leave_source_dir() {
+ if (!in_source_dir) return;
+ if (chdir(pwd)<0) {fprintf(stderr, "Can't chdir to %s : %s\n",
+ pwd, strerror(errno));}
+ in_source_dir = 0;
+}
+
+Fl_Window *main_window;
+
+void exit_cb(Fl_Widget *,void *) {
+ if (!modflag || fl_ask("Exit without saving changes?")) exit(0);
+}
+
+void save_cb(Fl_Widget *, void *v) {
+ const char *c = filename;
+ if (v || !c || !*c) {
+ if (!(c=fl_file_chooser("Save to:", "*.f[ld]", c))) return;
+ set_filename(c);
+ }
+ if (!write_file(c)) {
+ fl_show_message("Error writing", c, strerror(errno));
+ return;
+ }
+ modflag = 0;
+}
+
+void open_cb(Fl_Widget *, void *v) {
+ if (!v && modflag && !fl_ask("Discard changes?")) return;
+ const char *c;
+ if (!(c = fl_file_chooser("Open:", "*.f[ld]", filename))) return;
+ if (!read_file(c, v!=0)) {
+ fl_show_message("Can't read", c, strerror(errno));
+ return;
+ }
+ if (!v) {set_filename(c); modflag = 0;}
+ else modflag = 1;
+}
+
+void new_cb(Fl_Widget *, void *v) {
+ if (!v && modflag && !fl_ask("Discard changes?")) return;
+ const char *c;
+ if (!(c = fl_file_chooser("New:", "*.f[ld]", 0))) return;
+ delete_all();
+ set_filename(c);
+ modflag = 0;
+}
+
+static int compile_only;
+
+const char* header_file_name = ".H";
+const char* code_file_name = ".C";
+
+void write_cb(Fl_Widget *, void *) {
+ if (!filename) {
+ save_cb(0,0);
+ if (!filename) return;
+ }
+ char cname[1024];
+ char hname[1024];
+ if (*code_file_name == '.') {
+ strcpy(cname,filename_name(filename));
+ filename_setext(cname, code_file_name);
+ } else {
+ strcpy(cname, code_file_name);
+ }
+ if (*header_file_name == '.') {
+ strcpy(hname,filename_name(filename));
+ filename_setext(hname, header_file_name);
+ } else {
+ strcpy(hname, header_file_name);
+ }
+ int x = write_code(cname,hname);
+ strcat(cname, "/"); strcat(cname,header_file_name);
+ if (compile_only) {
+ if (!x) {fprintf(stderr,"%s : %s\n",cname,strerror(errno)); exit(1);}
+ } else {
+ if (!x) {
+ fl_show_message("Can't write", cname, strerror(errno));
+ } else {
+ fl_show_message("Wrote", cname, 0);
+ }
+ }
+}
+
+void openwidget_cb(Fl_Widget *, void *) {
+ if (!Fl_Type::current) {
+ fl_message("Please select a widget");
+ return;
+ }
+ Fl_Type::current->open();
+}
+
+void toggle_overlays(Fl_Widget *,void *);
+
+void select_all_cb(Fl_Widget *,void *);
+
+void group_cb(Fl_Widget *, void *);
+
+void ungroup_cb(Fl_Widget *, void *);
+
+extern int pasteoffset;
+static int ipasteoffset;
+
+static char* cutfname() {
+#ifdef WIN32
+ return ".fluid_cut_buffer";
+#else
+ static char name[256] = "~/.fluid_cut_buffer";
+ static char beenhere;
+ if (!beenhere) {beenhere = 1; filename_expand(name,name);}
+ return name;
+#endif
+}
+
+void copy_cb(Fl_Widget*, void*) {
+ if (!Fl_Type::current) return;
+ ipasteoffset = 10;
+ if (!write_file(cutfname(),1)) {
+ fl_show_message("Can't write", cutfname(), strerror(errno));
+ return;
+ }
+}
+
+extern void select_only(Fl_Type *);
+void cut_cb(Fl_Widget *, void *) {
+ if (!Fl_Type::current) return;
+ ipasteoffset = 0;
+ Fl_Type *p = Fl_Type::current->parent;
+ while (p && p->selected) p = p->parent;
+ if (!write_file(cutfname(),1)) {
+ fl_show_message("Can't write", cutfname(), strerror(errno));
+ return;
+ }
+ delete_all(1);
+ if (p) select_only(p);
+}
+
+extern int force_parent, gridx, gridy;
+
+void paste_cb(Fl_Widget*, void*) {
+ if (ipasteoffset) force_parent = 1;
+ pasteoffset = ipasteoffset;
+ if (gridx>1) pasteoffset = ((pasteoffset-1)/gridx+1)*gridx;
+ if (gridy>1) pasteoffset = ((pasteoffset-1)/gridy+1)*gridy;
+ if (!read_file(cutfname(), 1)) {
+ fl_show_message("Can't read", cutfname(), strerror(errno));
+ }
+ pasteoffset = 0;
+ ipasteoffset += 10;
+ force_parent = 0;
+}
+
+void earlier_cb(Fl_Widget*,void*);
+
+void later_cb(Fl_Widget*,void*);
+
+Fl_Type *sort(Fl_Type *parent);
+
+static void sort_cb(Fl_Widget *,void *) {
+ sort((Fl_Type*)0);
+}
+
+void show_alignment_cb(Fl_Widget *, void *);
+
+void about_cb(Fl_Widget *, void *) {
+ if (!about_panel) make_about_panel(copyright);
+ copyright_box->hide();
+ display_group->show();
+ about_panel->show();
+}
+
+////////////////////////////////////////////////////////////////
+
+extern Fl_Menu_Item New_Menu[];
+
+Fl_Menu_Item Main_Menu[] = {
+{"File",0,0,0,FL_SUBMENU},
+ {"New", FL_ALT+'N', new_cb, 0},
+ {"Open...", FL_ALT+'O', open_cb, 0},
+ {"Save", FL_ALT+'s', save_cb, 0},
+ {"Save As...", FL_ALT+'S', save_cb, (void*)1},
+ {"Merge...", FL_ALT+'i', open_cb, (void*)1, FL_MENU_DIVIDER},
+ {"Write code", FL_ALT+'C', write_cb, 0},
+ {"Quit", FL_ALT+'q', exit_cb},
+ {0},
+{"Edit",0,0,0,FL_SUBMENU},
+ {"Undo", FL_ALT+'z', nyi},
+ {"Cut", FL_ALT+'x', cut_cb},
+ {"Copy", FL_ALT+'c', copy_cb},
+ {"Paste", FL_ALT+'v', paste_cb},
+ {"Select All", FL_ALT+'a', select_all_cb, 0, FL_MENU_DIVIDER},
+ {"Open...", FL_F+1, openwidget_cb},
+ {"Sort",0,sort_cb},
+ {"Earlier", FL_F+2, earlier_cb},
+ {"Later", FL_F+3, later_cb},
+//{"Show", FL_F+5, show_cb},
+//{"Hide", FL_F+6, hide_cb},
+ {"Group", FL_F+7, group_cb},
+ {"Ungroup", FL_F+8, ungroup_cb,0, FL_MENU_DIVIDER},
+//{"Deactivate", 0, nyi},
+//{"Activate", 0, nyi, 0, FL_MENU_DIVIDER},
+ {"Overlays on/off",FL_ALT+'o',toggle_overlays},
+ {"Preferences",FL_ALT+'p',show_alignment_cb},
+ {0},
+{"New", 0, 0, (void *)New_Menu, FL_SUBMENU_POINTER},
+{"Help",0,0,0,FL_SUBMENU},
+ {"About fluid",0,about_cb},
+ {"Manual",0,nyi},
+ {0},
+{0}};
+
+#define BROWSERWIDTH 300
+#define BROWSERHEIGHT 500
+#define WINWIDTH 300
+#define MENUHEIGHT 30
+#define WINHEIGHT (BROWSERHEIGHT+MENUHEIGHT)
+
+extern void fill_in_New_Menu();
+
+void make_main_window() {
+ if (!main_window) {
+ Fl_Widget *o;
+ main_window = new Fl_Double_Window(WINWIDTH,WINHEIGHT,"fluid");
+ main_window->box(FL_NO_BOX);
+ o = make_widget_browser(0,MENUHEIGHT,BROWSERWIDTH,BROWSERHEIGHT);
+ o->box(FL_FLAT_BOX);
+ main_window->resizable(o);
+ Fl_Menu_Bar *m = new Fl_Menu_Bar(0,0,BROWSERWIDTH,MENUHEIGHT);
+ m->menu(Main_Menu);
+ m->global();
+ fill_in_New_Menu();
+ main_window->end();
+ }
+}
+
+void set_filename(const char *c) {
+ if (filename) free((void *)filename);
+ filename = strdup(c);
+ if (main_window) main_window->label(filename);
+}
+
+////////////////////////////////////////////////////////////////
+
+static int arg(int argc, char** argv, int& i) {
+ if (argv[i][1] == 'c' && !argv[i][2]) {compile_only = 1; i++; return 1;}
+ if (argv[i][1] == 'o' && !argv[i][2] && i+1 < argc) {
+ code_file_name = argv[i+1]; i += 2; return 2;}
+ if (argv[i][1] == 'h' && !argv[i][2]) {
+ header_file_name = argv[i+1]; i += 2; return 2;}
+ return 0;
+}
+
+#ifndef WIN32
+
+#include <signal.h>
+#ifdef _sigargs
+#define SIGARG _sigargs
+#else
+#ifdef __sigargs
+#define SIGARG __sigargs
+#else
+#define SIGARG int // you may need to fix this for older systems
+#endif
+#endif
+
+static void sigint(SIGARG) {
+ signal(SIGINT,sigint);
+ exit_cb(0,0);
+}
+
+#endif
+
+int main(int argc,char **argv) {
+ int i = 1;
+ if (!Fl::args(argc,argv,i,arg) || i < argc-1) {
+ fprintf(stderr,"usage: %s <switches> name.fl\n"
+" -c : write .C and .H and exit\n"
+" -o <name> : .C output filename, or extension if <name> starts with '.'\n"
+" -h <name> : .H output filename, or extension if <name> starts with '.'\n"
+"%s\n", argv[0], Fl::help);
+ return 1;
+ }
+ const char *c = argv[i];
+ make_main_window();
+ if (c) set_filename(c);
+ if (!compile_only) {
+ Fl::visual((Fl_Mode)(FL_DOUBLE|FL_INDEX));
+ main_window->callback(exit_cb);
+ main_window->show(argc,argv);
+ }
+ if (c && !read_file(c,0)) {
+ if (compile_only) {
+ fprintf(stderr,"%s : %s\n", c, strerror(errno));
+ exit(1);
+ }
+ fl_show_message("Can't read", c, strerror(errno));
+ }
+ if (compile_only) {write_cb(0,0); exit(0);}
+ modflag = 0;
+#ifndef WIN32
+ signal(SIGINT,sigint);
+#endif
+ return Fl::run();
+}
diff --git a/fluid/function_panel.cxx b/fluid/function_panel.cxx
new file mode 100644
index 000000000..0b6bccd61
--- /dev/null
+++ b/fluid/function_panel.cxx
@@ -0,0 +1,262 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "function_panel.H"
+
+Fl_Window *function_panel;
+
+Fl_Light_Button *f_public_button;
+
+Fl_Input *f_name_input;
+
+Fl_Input *f_return_type_input;
+
+Fl_Return_Button *f_panel_ok;
+
+Fl_Button *f_panel_cancel;
+
+Fl_Window *code_panel;
+
+Fl_Input *code_input;
+
+Fl_Return_Button *code_panel_ok;
+
+Fl_Button *code_panel_cancel;
+
+Fl_Window *codeblock_panel;
+
+Fl_Input *code_before_input;
+
+Fl_Input *code_after_input;
+
+Fl_Return_Button *codeblock_panel_ok;
+
+Fl_Button *codeblock_panel_cancel;
+
+Fl_Window *declblock_panel;
+
+Fl_Input *decl_before_input;
+
+Fl_Input *decl_after_input;
+
+Fl_Return_Button *declblock_panel_ok;
+
+Fl_Button *declblock_panel_cancel;
+
+Fl_Window *decl_panel;
+
+Fl_Light_Button *decl_public_button;
+
+Fl_Input *decl_input;
+
+Fl_Return_Button *decl_panel_ok;
+
+Fl_Button *decl_panel_cancel;
+
+Fl_Window *class_panel;
+
+Fl_Light_Button *c_public_button;
+
+Fl_Input *c_name_input;
+
+Fl_Input *c_subclass_input;
+
+Fl_Return_Button *c_panel_ok;
+
+Fl_Button *c_panel_cancel;
+
+Fl_Window* make_function_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(287, 173, "function/method");
+ w = function_panel = o;
+ w->set_modal();
+ { Fl_Light_Button* o = new Fl_Light_Button(10, 15, 65, 25, "public");
+ f_public_button = o;
+ o->labelsize(10);
+ o->when(0);
+ }
+ { Fl_Input* o = new Fl_Input(10, 60, 270, 25, "name(args): (blank for main())");
+ f_name_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Input* o = new Fl_Input(10, 105, 270, 25, "return type: (blank to return outermost widget)");
+ f_return_type_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(110, 140, 80, 25, "OK");
+ f_panel_ok = o;
+ w->hotspot(o);
+ }
+ { Fl_Button* o = new Fl_Button(200, 140, 80, 25, "cancel");
+ f_panel_cancel = o;
+ o->shortcut(0xff1b);
+ }
+ w->end();
+ }
+ return w;
+}
+
+Fl_Window* make_code_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(291, 178, "code");
+ w = code_panel = o;
+ w->set_modal();
+ { Fl_Input* o = new Fl_Input(6, 5, 280, 135);
+ code_input = o;
+ o->type(4);
+ o->labelsize(12);
+ o->align(0);
+ o->when(0);
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(115, 145, 80, 25, "OK");
+ code_panel_ok = o;
+ w->hotspot(o);
+ }
+ { Fl_Button* o = new Fl_Button(205, 145, 80, 25, "cancel");
+ code_panel_cancel = o;
+ o->shortcut(0xff1b);
+ }
+ w->end();
+ }
+ return w;
+}
+
+Fl_Window* make_codeblock_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(293, 134, "codeblock");
+ w = codeblock_panel = o;
+ w->set_modal();
+ { Fl_Input* o = new Fl_Input(10, 5, 275, 25);
+ code_before_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Box* o = new Fl_Box(10, 35, 270, 25, "\"{...child code...}\" is inserted here");
+ o->align(20);
+ }
+ { Fl_Input* o = new Fl_Input(10, 65, 275, 25);
+ code_after_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(115, 100, 80, 25, "OK");
+ codeblock_panel_ok = o;
+ w->hotspot(o);
+ }
+ { Fl_Button* o = new Fl_Button(205, 100, 80, 25, "cancel");
+ codeblock_panel_cancel = o;
+ o->shortcut(0xff1b);
+ }
+ w->end();
+ }
+ return w;
+}
+
+Fl_Window* make_declblock_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(293, 134, "declaration block");
+ w = declblock_panel = o;
+ w->set_modal();
+ { Fl_Input* o = new Fl_Input(15, 10, 275, 25);
+ decl_before_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Box* o = new Fl_Box(15, 40, 270, 25, "\"\\n...child code...\\n\" is inserted here");
+ o->align(20);
+ }
+ { Fl_Input* o = new Fl_Input(15, 70, 275, 25);
+ decl_after_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(120, 105, 80, 25, "OK");
+ declblock_panel_ok = o;
+ w->hotspot(o);
+ }
+ { Fl_Button* o = new Fl_Button(210, 105, 80, 25, "cancel");
+ declblock_panel_cancel = o;
+ o->shortcut(0xff1b);
+ }
+ w->end();
+ }
+ return w;
+}
+
+Fl_Window* make_decl_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(290, 176, "declaration");
+ w = decl_panel = o;
+ { Fl_Light_Button* o = new Fl_Light_Button(10, 15, 65, 25, "public");
+ decl_public_button = o;
+ o->labelsize(10);
+ o->when(0);
+ }
+ { Fl_Input* o = new Fl_Input(10, 50, 270, 25, "can be any declartion, like \"int x;\",\nan external symbol like \"extern \
+int foo();\",\na #directive like \"#include <foo.h>\",\nor a comment like \"\
+//foo\" or \"/*foo*/\"");
+ decl_input = o;
+ o->labelsize(12);
+ o->align(6);
+ o->when(0);
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(115, 145, 80, 25, "OK");
+ decl_panel_ok = o;
+ w->hotspot(o);
+ }
+ { Fl_Button* o = new Fl_Button(205, 145, 80, 25, "cancel");
+ decl_panel_cancel = o;
+ o->shortcut(0xff1b);
+ }
+ w->end();
+ }
+ return w;
+}
+
+Fl_Window* make_class_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(287, 173, "class");
+ w = class_panel = o;
+ w->set_modal();
+ { Fl_Light_Button* o = new Fl_Light_Button(10, 10, 65, 25, "public");
+ c_public_button = o;
+ o->labelsize(10);
+ o->when(0);
+ }
+ { Fl_Input* o = new Fl_Input(10, 55, 270, 25, "name:");
+ c_name_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Input* o = new Fl_Input(10, 100, 270, 25, "subclass of (text between : and {)");
+ c_subclass_input = o;
+ o->labelsize(12);
+ o->align(5);
+ o->when(0);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(110, 135, 80, 25, "OK");
+ c_panel_ok = o;
+ w->hotspot(o);
+ }
+ { Fl_Button* o = new Fl_Button(200, 135, 80, 25, "cancel");
+ c_panel_cancel = o;
+ o->shortcut(0xff1b);
+ }
+ w->end();
+ }
+ return w;
+}
diff --git a/fluid/function_panel.fl b/fluid/function_panel.fl
new file mode 100644
index 000000000..e4ad307f1
--- /dev/null
+++ b/fluid/function_panel.fl
@@ -0,0 +1,164 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 5
+snap 3
+Function {make_function_panel()} {open
+} {
+ Fl_Window function_panel {
+ label {function/method} open
+ xywh {281 608 287 173} modal visible
+ } {
+ Fl_Light_Button f_public_button {
+ label public
+ xywh {10 15 65 25} labelsize 10 when 0
+ }
+ Fl_Input f_name_input {
+ label {name(args): (blank for main())}
+ xywh {10 60 270 25} labelsize 12 align 5 when 0 resizable
+ }
+ Fl_Input f_return_type_input {
+ label {return type: (blank to return outermost widget)}
+ xywh {10 105 270 25} labelsize 12 align 5 when 0
+ }
+ Fl_Return_Button f_panel_ok {
+ label OK
+ xywh {110 140 80 25} hotspot
+ }
+ Fl_Button f_panel_cancel {
+ label cancel
+ xywh {200 140 80 25} shortcut 0xff1b
+ }
+ }
+}
+
+Function {make_code_panel()} {open
+} {
+ Fl_Window code_panel {
+ label code open
+ xywh {256 219 291 178} modal visible
+ } {
+ Fl_Input code_input {
+ xywh {6 5 280 135} type Multiline labelsize 12 align 0 when 0 resizable
+ }
+ Fl_Return_Button code_panel_ok {
+ label OK
+ xywh {115 145 80 25} hotspot
+ }
+ Fl_Button code_panel_cancel {
+ label cancel
+ xywh {205 145 80 25} shortcut 0xff1b
+ }
+ }
+}
+
+Function {make_codeblock_panel()} {open
+} {
+ Fl_Window codeblock_panel {
+ label codeblock open
+ xywh {285 439 293 134} modal visible
+ } {
+ Fl_Input code_before_input {
+ xywh {10 5 275 25} labelsize 12 align 5 when 0 resizable
+ }
+ Fl_Box {} {
+ label {"{...child code...}" is inserted here}
+ xywh {10 35 270 25} align 20
+ }
+ Fl_Input code_after_input {
+ xywh {10 65 275 25} labelsize 12 align 5 when 0
+ }
+ Fl_Return_Button codeblock_panel_ok {
+ label OK
+ xywh {115 100 80 25} hotspot
+ }
+ Fl_Button codeblock_panel_cancel {
+ label cancel
+ xywh {205 100 80 25} shortcut 0xff1b
+ }
+ }
+}
+
+Function {make_declblock_panel()} {open
+} {
+ Fl_Window declblock_panel {
+ label {declaration block} open
+ xywh {296 118 293 134} modal visible
+ } {
+ Fl_Input decl_before_input {
+ xywh {15 10 275 25} labelsize 12 align 5 when 0 resizable
+ }
+ Fl_Box {} {
+ label {"\\n...child code...\\n" is inserted here}
+ xywh {15 40 270 25} align 20
+ }
+ Fl_Input decl_after_input {
+ xywh {15 70 275 25} labelsize 12 align 5 when 0
+ }
+ Fl_Return_Button declblock_panel_ok {
+ label OK
+ xywh {120 105 80 25} hotspot
+ }
+ Fl_Button declblock_panel_cancel {
+ label cancel
+ xywh {210 105 80 25} shortcut 0xff1b
+ }
+ }
+}
+
+Function {make_decl_panel()} {open
+} {
+ Fl_Window decl_panel {
+ label declaration open
+ xywh {278 800 290 176} visible
+ } {
+ Fl_Light_Button decl_public_button {
+ label public
+ xywh {10 15 65 25} labelsize 10 when 0
+ }
+ Fl_Input decl_input {
+ label {can be any declartion, like "int x;",
+an external symbol like "extern int foo();",
+a \#directive like "\#include <foo.h>",
+or a comment like "//foo" or "/*foo*/"}
+ xywh {10 50 270 25} labelsize 12 align 6 when 0 resizable
+ }
+ Fl_Return_Button decl_panel_ok {
+ label OK
+ xywh {115 145 80 25} hotspot
+ }
+ Fl_Button decl_panel_cancel {
+ label cancel
+ xywh {205 145 80 25} shortcut 0xff1b
+ }
+ }
+}
+
+Function {make_class_panel()} {open
+} {
+ Fl_Window class_panel {
+ label class open selected
+ xywh {291 618 287 173} modal visible
+ } {
+ Fl_Light_Button c_public_button {
+ label public
+ xywh {10 10 65 25} labelsize 10 when 0
+ }
+ Fl_Input c_name_input {
+ label {name:}
+ xywh {10 55 270 25} labelsize 12 align 5 when 0 resizable
+ }
+ Fl_Input c_subclass_input {
+ label {subclass of (text between : and \{)}
+ xywh {10 100 270 25} labelsize 12 align 5 when 0
+ }
+ Fl_Return_Button c_panel_ok {
+ label OK
+ xywh {110 135 80 25} hotspot
+ }
+ Fl_Button c_panel_cancel {
+ label cancel
+ xywh {200 135 80 25} shortcut 0xff1b
+ }
+ }
+}
diff --git a/fluid/function_panel.h b/fluid/function_panel.h
new file mode 100644
index 000000000..f0a9d2506
--- /dev/null
+++ b/fluid/function_panel.h
@@ -0,0 +1,46 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Window.H>
+extern Fl_Window *function_panel;
+extern Fl_Light_Button *f_public_button;
+extern Fl_Input *f_name_input;
+extern Fl_Input *f_return_type_input;
+extern Fl_Return_Button *f_panel_ok;
+extern Fl_Button *f_panel_cancel;
+extern Fl_Window *code_panel;
+extern Fl_Input *code_input;
+extern Fl_Return_Button *code_panel_ok;
+extern Fl_Button *code_panel_cancel;
+extern Fl_Window *codeblock_panel;
+extern Fl_Input *code_before_input;
+extern Fl_Input *code_after_input;
+extern Fl_Return_Button *codeblock_panel_ok;
+extern Fl_Button *codeblock_panel_cancel;
+extern Fl_Window *declblock_panel;
+extern Fl_Input *decl_before_input;
+extern Fl_Input *decl_after_input;
+extern Fl_Return_Button *declblock_panel_ok;
+extern Fl_Button *declblock_panel_cancel;
+extern Fl_Window *decl_panel;
+extern Fl_Light_Button *decl_public_button;
+extern Fl_Input *decl_input;
+extern Fl_Return_Button *decl_panel_ok;
+extern Fl_Button *decl_panel_cancel;
+extern Fl_Window *class_panel;
+extern Fl_Light_Button *c_public_button;
+extern Fl_Input *c_name_input;
+extern Fl_Input *c_subclass_input;
+extern Fl_Return_Button *c_panel_ok;
+extern Fl_Button *c_panel_cancel;
+Fl_Window* make_function_panel();
+Fl_Window* make_code_panel();
+Fl_Window* make_codeblock_panel();
+Fl_Window* make_declblock_panel();
+Fl_Window* make_decl_panel();
+Fl_Window* make_class_panel();
diff --git a/fluid/gif.cxx b/fluid/gif.cxx
new file mode 100644
index 000000000..1af6556a7
--- /dev/null
+++ b/fluid/gif.cxx
@@ -0,0 +1,336 @@
+// gif.C
+
+// Read a .gif file and convert it to a "xpm" format (actually my
+// modified one with compressed colormaps).
+
+// Extensively modified from original code for gif2ras by
+// Patrick J. Naughton of Sun Microsystems. The original
+// copyright notice follows:
+
+/* gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
+ *
+ * Copyright (c) 1988 by Patrick J. Naughton
+ *
+ * Author: Patrick J. Naughton
+ * naughton@wind.sun.com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * Comments and additions should be sent to the author:
+ *
+ * Patrick J. Naughton
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Ave, MS 14-40
+ * Mountain View, CA 94043
+ * (415) 336-1080
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef unsigned char uchar;
+
+#define NEXTBYTE getc(GifFile)
+#define GETSHORT(var) var = NEXTBYTE; var += NEXTBYTE << 8
+
+int gif2xpm(
+ const char *infname,// filename for error messages
+ FILE *GifFile, // file to read
+ char*** datap, // return xpm data here
+ int** lengthp, // return line lengths here
+ int inumber // which image in movie (0 = first)
+) {
+
+ {char b[6];
+ if (fread(b,1,6,GifFile)<6) return 0; /* quit on eof */
+ if (b[0]!='G' || b[1]!='I' || b[2] != 'F') {
+ fprintf(stderr,"%s is not a GIF file.\n", infname); return 0;}
+ if (b[3]!='8' || b[4]>'9' || b[5]!= 'a')
+ fprintf(stderr,"%s is version %c%c%c.\n",infname,b[3],b[4],b[5]);
+ }
+
+ int Width; GETSHORT(Width);
+ int Height; GETSHORT(Height);
+
+ uchar ch = NEXTBYTE;
+ char HasColormap = ((ch & 0x80) != 0);
+ int BitsPerPixel = (ch & 7) + 1;
+ int ColorMapSize = 1 << BitsPerPixel;
+ // int OriginalResolution = ((ch>>4)&7)+1;
+ // int SortedTable = (ch&8)!=0;
+ NEXTBYTE; // Background Color index
+ NEXTBYTE; // Aspect ratio is N/64
+
+ // Read in global colormap:
+ uchar transparent_pixel = 0;
+ char has_transparent = 0;
+ uchar Red[256], Green[256], Blue[256]; /* color map */
+ if (HasColormap) {
+ for (int i=0; i < ColorMapSize; i++) {
+ Red[i] = NEXTBYTE;
+ Green[i] = NEXTBYTE;
+ Blue[i] = NEXTBYTE;
+ }
+ } else {
+ fprintf(stderr,"%s does not have a colormap.\n", infname);
+ for (int i = 0; i < ColorMapSize; i++)
+ Red[i] = Green[i] = Blue[i] = (i*256+ColorMapSize-1)/ColorMapSize;
+ }
+
+ int CodeSize; /* Code size, init from GIF header, increases... */
+ char Interlace;
+
+ for (;;) {
+
+ int i = NEXTBYTE;
+ if (i<0) {fprintf(stderr,"%s: unexpected EOF\n",infname); return 0;}
+ int blocklen;
+
+ // if (i == 0x3B) return 0; eof code
+
+ if (i == 0x21) { // a "gif extension"
+
+ ch = NEXTBYTE;
+ blocklen = NEXTBYTE;
+
+ if (ch==0xF9 && blocklen==4) { // Netscape animation extension
+
+ char bits;
+ bits = NEXTBYTE;
+ NEXTBYTE; NEXTBYTE; // GETSHORT(delay);
+ transparent_pixel = NEXTBYTE;
+ if (bits & 1) has_transparent = 1;
+ blocklen = NEXTBYTE;
+
+ } else if (ch == 0xFF) { // Netscape repeat count
+ ;
+
+ } else if (ch == 0xFE) { //Gif Comment
+#if 0
+ if(blocklen>0) {
+ char *comment=new char[blocklen+1];
+ int l;
+ for(l=0;blocklen;l++,blocklen--)
+ comment[l]=NEXTBYTE;
+ comment[l]=0;
+ fprintf(stderr,"%s: Gif Comment: '%s'\n", infname, comment);
+ delete comment;
+ NEXTBYTE; //End marker
+ }
+#endif
+ } else {
+ fprintf(stderr,"%s: unknown gif extension 0x%02x\n", infname, ch);
+
+ }
+
+ } else if (i == 0x2c) { // an image
+
+ NEXTBYTE; NEXTBYTE; // GETSHORT(x_position);
+ NEXTBYTE; NEXTBYTE; // GETSHORT(y_position);
+ GETSHORT(Width);
+ GETSHORT(Height);
+ ch = NEXTBYTE;
+ Interlace = ((ch & 0x40) != 0);
+ if (ch&0x80) {
+ // read local color map
+ int n = 1<<((ch&7)+1); // does this replace ColorMapSize ??
+ for (i=0; i < n; i++) {
+ Red[i] = NEXTBYTE;
+ Green[i] = NEXTBYTE;
+ Blue[i] = NEXTBYTE;
+ }
+ }
+ CodeSize = NEXTBYTE+1;
+
+ if (!inumber--) break; // okay, this is the image we want
+ blocklen = NEXTBYTE;
+
+ } else {
+ fprintf(stderr,"%s: unknown gif code 0x%02x\n", infname, i);
+ blocklen = 0;
+ }
+
+ // skip the data:
+ while (blocklen>0) {while (blocklen--) {NEXTBYTE;} blocklen=NEXTBYTE;}
+ }
+
+ uchar *Image = new uchar[Width*Height];
+ if (!Image) {
+ fprintf (stderr, "Insufficient memory\n");
+ exit (2);
+ }
+ int YC = 0, Pass = 0; /* Used to de-interlace the picture */
+ uchar *p = Image;
+ uchar *eol = p+Width;
+
+ int InitCodeSize = CodeSize;
+ int ClearCode = (1 << (CodeSize-1));
+ int EOFCode = ClearCode + 1;
+ int FirstFree = ClearCode + 2;
+ int FinChar = 0;
+ int ReadMask = (1<<CodeSize) - 1;
+ int FreeCode = FirstFree;
+ int OldCode = ClearCode;
+
+ // tables used by LZW decompresser:
+ short int Prefix[4096];
+ uchar Suffix[4096];
+
+ int blocklen = NEXTBYTE;
+ uchar thisbyte = NEXTBYTE; blocklen--;
+ int frombit = 0;
+
+ for (;;) {
+
+/* Fetch the next code from the raster data stream. The codes can be
+ * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
+ * maintain our location as a pointer and a bit offset.
+ * In addition, gif adds totally useless and annoying block counts
+ * that must be correctly skipped over. */
+ int CurCode = thisbyte;
+ if (frombit+CodeSize > 7) {
+ if (blocklen <= 0) {
+ blocklen = NEXTBYTE;
+ if (blocklen <= 0) break;
+ }
+ thisbyte = NEXTBYTE; blocklen--;
+ CurCode |= thisbyte<<8;
+ }
+ if (frombit+CodeSize > 15) {
+ if (blocklen <= 0) {
+ blocklen = NEXTBYTE;
+ if (blocklen <= 0) break;
+ }
+ thisbyte = NEXTBYTE; blocklen--;
+ CurCode |= thisbyte<<16;
+ }
+ CurCode = (CurCode>>frombit)&ReadMask;
+ frombit = (frombit+CodeSize)%8;
+
+ if (CurCode == ClearCode) {
+ CodeSize = InitCodeSize;
+ ReadMask = (1<<CodeSize) - 1;
+ FreeCode = FirstFree;
+ OldCode = ClearCode;
+ continue;
+ }
+
+ if (CurCode == EOFCode) break;
+
+ uchar OutCode[1025]; // temporary array for reversing codes
+ uchar *tp = OutCode;
+ int i;
+ if (CurCode < FreeCode) i = CurCode;
+ else if (CurCode == FreeCode) {*tp++ = FinChar; i = OldCode;}
+ else {fprintf(stderr,"%s : LZW Barf!\n",infname); break;}
+
+ while (i >= ColorMapSize) {*tp++ = Suffix[i]; i = Prefix[i];}
+ *tp++ = FinChar = i;
+ while (tp > OutCode) {
+ *p++ = *--tp;
+ if (p >= eol) {
+ if (!Interlace) YC++;
+ else switch (Pass) {
+ case 0: YC += 8; if (YC >= Height) {Pass++; YC = 4;} break;
+ case 1: YC += 8; if (YC >= Height) {Pass++; YC = 2;} break;
+ case 2: YC += 4; if (YC >= Height) {Pass++; YC = 1;} break;
+ case 3: YC += 2; break;
+ }
+ if (YC>=Height) YC=0; /* cheap bug fix when excess data */
+ p = Image + YC*Width;
+ eol = p+Width;
+ }
+ }
+
+ if (OldCode != ClearCode) {
+ Prefix[FreeCode] = OldCode;
+ Suffix[FreeCode] = FinChar;
+ FreeCode++;
+ if (FreeCode > ReadMask) {
+ if (CodeSize < 12) {
+ CodeSize++;
+ ReadMask = (1 << CodeSize) - 1;
+ }
+ else FreeCode--;
+ }
+ }
+ OldCode = CurCode;
+ }
+
+ // We are done reading the file, now convert to xpm:
+
+ // allocate line pointer arrays:
+ char** data = new char*[Height+3];
+ *datap = data;
+ int* length = new int[Height+2];
+ *lengthp = length;
+
+ // transparent pixel must be zero, swap if it isn't:
+ if (has_transparent && transparent_pixel != 0) {
+ // swap transparent pixel with zero
+ p = Image+Width*Height;
+ while (p-- > Image) {
+ if (*p==transparent_pixel) *p = 0;
+ else if (!*p) *p = transparent_pixel;
+ }
+ uchar t;
+ t = Red[0]; Red[0] = Red[transparent_pixel]; Red[transparent_pixel] = t;
+ t =Green[0];Green[0]=Green[transparent_pixel];Green[transparent_pixel]=t;
+ t =Blue[0];Blue[0] =Blue[transparent_pixel];Blue[transparent_pixel] = t;
+ }
+
+ // find out what colors are actually used:
+ uchar used[256]; uchar remap[256];
+ int i;
+ for (i = 0; i < ColorMapSize; i++) used[i] = 0;
+ p = Image+Width*Height;
+ while (p-- > Image) used[*p] = 1;
+
+ // remap them to start with printing characters:
+ int base = has_transparent && used[0] ? ' ' : ' '+1;
+ int numcolors = 0;
+ for (i = 0; i < ColorMapSize; i++) if (used[i]) {
+ remap[i] = base++;
+ numcolors++;
+ }
+
+ // write the first line of xpm data (use suffix as temp array):
+ length[0] = sprintf((char*)(Suffix),
+ "%d %d %d %d",Width,Height,-numcolors,1);
+ data[0] = new char[length[0]+1];
+ strcpy(data[0], (char*)Suffix);
+
+ // write the colormap
+ length[1] = 4*numcolors;
+ data[1] = (char*)(p = new uchar[4*numcolors]);
+ for (i = 0; i < ColorMapSize; i++) if (used[i]) {
+ *p++ = remap[i];
+ *p++ = Red[i];
+ *p++ = Green[i];
+ *p++ = Blue[i];
+ }
+
+ // remap the image data:
+ p = Image+Width*Height;
+ while (p-- > Image) *p = remap[*p];
+
+ // split the image data into lines:
+ for (i=0; i<Height; i++) {
+ data[i+2] = (char*)(Image + i*Width);
+ length[i+2] = Width;
+ }
+
+ data[Height+2] = 0; // null to end string array
+ return 1;
+}
diff --git a/fluid/keyboard_ui.cxx b/fluid/keyboard_ui.cxx
new file mode 100644
index 000000000..7c7b65ae6
--- /dev/null
+++ b/fluid/keyboard_ui.cxx
@@ -0,0 +1,536 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "keyboard_ui.H"
+
+Fl_Window *make_window() {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(494, 193);
+ w = o;
+ }
+ {Fl_Button* o = new Fl_Button(15, 50, 20, 20, "Esc");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Escape));
+ }
+ {Fl_Button* o = new Fl_Button(50, 50, 20, 20, "F1");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+1));
+ }
+ {Fl_Button* o = new Fl_Button(70, 50, 20, 20, "F2");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+2));
+ }
+ {Fl_Button* o = new Fl_Button(90, 50, 20, 20, "F3");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+3));
+ }
+ {Fl_Button* o = new Fl_Button(110, 50, 20, 20, "F4");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+4));
+ }
+ {Fl_Button* o = new Fl_Button(140, 50, 20, 20, "F5");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+5));
+ }
+ {Fl_Button* o = new Fl_Button(160, 50, 20, 20, "F6");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+6));
+ }
+ {Fl_Button* o = new Fl_Button(180, 50, 20, 20, "F7");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+7));
+ }
+ {Fl_Button* o = new Fl_Button(200, 50, 20, 20, "F8");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+8));
+ }
+ {Fl_Button* o = new Fl_Button(230, 50, 20, 20, "F9");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+9));
+ }
+ {Fl_Button* o = new Fl_Button(250, 50, 20, 20, "F10");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+10));
+ }
+ {Fl_Button* o = new Fl_Button(270, 50, 20, 20, "F11");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+11));
+ }
+ {Fl_Button* o = new Fl_Button(290, 50, 20, 20, "F12");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+12));
+ }
+ {Fl_Button* o = new Fl_Button(325, 50, 20, 20, "Print");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Print));
+ }
+ {Fl_Button* o = new Fl_Button(345, 50, 20, 20, "Sclk");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Scroll_Lock));
+ }
+ {Fl_Button* o = new Fl_Button(365, 50, 20, 20, "Paus");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Pause));
+ }
+ {Fl_Button* o = new Fl_Button(15, 80, 20, 20, "`");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(35, 80, 20, 20, "1");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(55, 80, 20, 20, "2");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(75, 80, 20, 20, "3");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(95, 80, 20, 20, "4");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(115, 80, 20, 20, "5");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(135, 80, 20, 20, "6");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(155, 80, 20, 20, "7");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(175, 80, 20, 20, "8");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(195, 80, 20, 20, "9");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(215, 80, 20, 20, "0");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(235, 80, 20, 20, "-");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(255, 80, 20, 20, "=");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(275, 80, 35, 20, "Bksp");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_BackSpace));
+ }
+ {Fl_Button* o = new Fl_Button(325, 80, 20, 20, "Ins");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Insert));
+ }
+ {Fl_Button* o = new Fl_Button(345, 80, 20, 20, "Home");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Home));
+ }
+ {Fl_Button* o = new Fl_Button(365, 80, 20, 20, "pgup");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Page_Up));
+ }
+ {Fl_Button* o = new Fl_Button(400, 80, 20, 20, "Num");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Num_Lock));
+ }
+ {Fl_Button* o = new Fl_Button(420, 80, 20, 20, "/");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'/'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 80, 20, 20, "*");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'*'));
+ }
+ {Fl_Button* o = new Fl_Button(460, 80, 20, 20, "-");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'-'));
+ }
+ {Fl_Button* o = new Fl_Button(15, 100, 27, 20, "Tab");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Tab));
+ }
+ {Fl_Button* o = new Fl_Button(42, 100, 20, 20, "Q");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(62, 100, 20, 20, "W");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(82, 100, 20, 20, "E");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(102, 100, 20, 20, "R");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(122, 100, 20, 20, "T");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(142, 100, 20, 20, "Y");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(162, 100, 20, 20, "U");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(182, 100, 20, 20, "I");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(202, 100, 20, 20, "O");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(222, 100, 20, 20, "P");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(242, 100, 20, 20, "[");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(262, 100, 20, 20, "]");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(282, 100, 28, 20, "\\");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)('|'));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(325, 100, 20, 20, "Del");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Delete));
+ }
+ {Fl_Button* o = new Fl_Button(345, 100, 20, 20, "End");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_End));
+ }
+ {Fl_Button* o = new Fl_Button(365, 100, 20, 20, "pgdn");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Page_Down));
+ }
+ {Fl_Button* o = new Fl_Button(400, 100, 20, 20, "7");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'7'));
+ }
+ {Fl_Button* o = new Fl_Button(420, 100, 20, 20, "8");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'8'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 100, 20, 20, "9");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'9'));
+ }
+ {Fl_Button* o = new Fl_Button(460, 100, 20, 40, "+");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'+'));
+ o->align(17);
+ }
+ {Fl_Button* o = new Fl_Button(15, 120, 36, 20, "Lock");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Caps_Lock));
+ }
+ {Fl_Button* o = new Fl_Button(51, 120, 20, 20, "A");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(71, 120, 20, 20, "S");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(91, 120, 20, 20, "D");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(111, 120, 20, 20, "F");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(131, 120, 20, 20, "G");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(151, 120, 20, 20, "H");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(171, 120, 20, 20, "J");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(191, 120, 20, 20, "K");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(211, 120, 20, 20, "L");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(231, 120, 20, 20, ";");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(251, 120, 20, 20, "\'");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(271, 120, 39, 20, "Enter");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Enter));
+ }
+ {Fl_Button* o = new Fl_Button(400, 120, 20, 20, "4");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'4'));
+ }
+ {Fl_Button* o = new Fl_Button(420, 120, 20, 20, "5");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'5'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 120, 20, 20, "6");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'6'));
+ }
+ {Fl_Button* o = new Fl_Button(15, 140, 45, 20, "Shift");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Shift_L));
+ }
+ {Fl_Button* o = new Fl_Button(60, 140, 20, 20, "Z");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(80, 140, 20, 20, "X");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(100, 140, 20, 20, "C");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(120, 140, 20, 20, "V");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(140, 140, 20, 20, "B");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(160, 140, 20, 20, "N");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(180, 140, 20, 20, "M");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(200, 140, 20, 20, ",");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(220, 140, 20, 20, ".");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(240, 140, 20, 20, "/");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(260, 140, 50, 20, "Shift");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Shift_R));
+ }
+ {Fl_Button* o = new Fl_Button(345, 140, 20, 20, "@8->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Up));
+ }
+ {Fl_Button* o = new Fl_Button(400, 140, 20, 20, "1");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'1'));
+ }
+ {Fl_Button* o = new Fl_Button(420, 140, 20, 20, "2");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'2'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 140, 20, 20, "3");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'3'));
+ }
+ {Fl_Button* o = new Fl_Button(460, 140, 20, 40);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP_Enter));
+ }
+ {Fl_Button* o = new Fl_Button(15, 160, 30, 20, "Ctrl");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Control_L));
+ }
+ {Fl_Button* o = new Fl_Button(45, 160, 30, 20, "Meta");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Meta_L));
+ }
+ {Fl_Button* o = new Fl_Button(75, 160, 30, 20, "Alt");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Alt_L));
+ }
+ {Fl_Button* o = new Fl_Button(105, 160, 85, 20);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(' '));
+ }
+ {Fl_Button* o = new Fl_Button(190, 160, 30, 20, "Alt");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Alt_R));
+ }
+ {Fl_Button* o = new Fl_Button(220, 160, 30, 20, "Meta");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Meta_R));
+ }
+ {Fl_Button* o = new Fl_Button(250, 160, 30, 20, "Menu");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Menu));
+ }
+ {Fl_Button* o = new Fl_Button(280, 160, 30, 20, "Ctrl");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Control_R));
+ }
+ {Fl_Button* o = new Fl_Button(325, 160, 20, 20, "@4->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Left));
+ }
+ {Fl_Button* o = new Fl_Button(345, 160, 20, 20, "@2->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Down));
+ }
+ {Fl_Button* o = new Fl_Button(365, 160, 20, 20, "@6->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Right));
+ }
+ {Fl_Button* o = new Fl_Button(400, 160, 40, 20, "0");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'0'));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(440, 160, 20, 20, ".");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'.'));
+ }
+ {Fl_Input* o = new Fl_Input(15, 10, 370, 30);
+ }
+ {Fl_Button* o = new Fl_Button(400, 5, 20, 10, "shift");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_SHIFT));
+ }
+ {Fl_Button* o = new Fl_Button(420, 5, 20, 10, "lock");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_CAPS_LOCK));
+ }
+ {Fl_Button* o = new Fl_Button(440, 5, 20, 10, "ctrl");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_CTRL));
+ }
+ {Fl_Button* o = new Fl_Button(460, 5, 20, 10, "alt");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_ALT));
+ }
+ {Fl_Button* o = new Fl_Button(440, 15, 20, 10, "meta");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_META));
+ }
+ {Fl_Button* o = new Fl_Button(420, 15, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x20));
+ }
+ {Fl_Button* o = new Fl_Button(400, 15, 20, 10, "num");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_NUM_LOCK));
+ }
+ {Fl_Button* o = new Fl_Button(400, 25, 20, 10, "b1");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_BUTTON1));
+ }
+ {Fl_Button* o = new Fl_Button(420, 25, 20, 10, "b2");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_BUTTON2));
+ }
+ {Fl_Button* o = new Fl_Button(440, 25, 20, 10, "b3");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_BUTTON3));
+ }
+ {Fl_Button* o = new Fl_Button(460, 15, 20, 10, "sclk");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_SCROLL_LOCK));
+ }
+ {Fl_Button* o = new Fl_Button(460, 25, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x800));
+ }
+ {Fl_Button* o = new Fl_Button(400, 35, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x1000));
+ }
+ {Fl_Button* o = new Fl_Button(420, 35, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x2000));
+ }
+ {Fl_Button* o = new Fl_Button(440, 35, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x4000));
+ }
+ {Fl_Button* o = new Fl_Button(460, 35, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x8000));
+ }
+ w->end();
+ return w;
+}
diff --git a/fluid/keyboard_ui.h b/fluid/keyboard_ui.h
new file mode 100644
index 000000000..ec1ba7722
--- /dev/null
+++ b/fluid/keyboard_ui.h
@@ -0,0 +1,8 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Window.H>
+extern void key_cb(Fl_Button*, void*);
+extern void shift_cb(Fl_Button*, void*);
+Fl_Window *make_window();
diff --git a/fluid/penne.C b/fluid/penne.C
new file mode 100644
index 000000000..cc1db0937
--- /dev/null
+++ b/fluid/penne.C
@@ -0,0 +1,85 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "penne.H"
+
+inline void UserInterface::cb_New_i(Fl_Button*, void*) {
+ new UserInterface;
+}
+void UserInterface::cb_New(Fl_Button* o, void* v) {
+ ((UserInterface*)(o->parent()->user_data()))->cb_New_i(o,v);
+}
+
+inline void UserInterface::cb_Delete_i(Fl_Button*, void*) {
+ delete this;
+}
+void UserInterface::cb_Delete(Fl_Button* o, void* v) {
+ ((UserInterface*)(o->parent()->user_data()))->cb_Delete_i(o,v);
+}
+
+inline void UserInterface::cb_button1_i(Fl_Light_Button* o, void*) {
+ Button->value(o->value());
+}
+void UserInterface::cb_button1(Fl_Light_Button* o, void* v) {
+ ((UserInterface*)(o->parent()->user_data()))->cb_button1_i(o,v);
+}
+
+inline void UserInterface::cb_When_i(Fl_Menu_* o, void*) {
+ Button->value(o->value());
+}
+void UserInterface::cb_When(Fl_Menu_* o, void* v) {
+ ((UserInterface*)(o->parent()->user_data()))->cb_When_i(o,v);
+}
+
+Fl_Menu_Item UserInterface::menu_[] = {
+ {"coucou", 0, 0, 0, 64, 0, 3, 14, 0},
+ {"When you press this, it should crash !", 0, (Fl_Callback*)UserInterface::cb_When, 0, 2, 0, 3, 14, 0},
+ {0},
+ {0}
+};
+
+UserInterface::UserInterface() {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(375, 199);
+ w = Win = o;
+ o->user_data((void*)(this));
+ { Fl_Button* o = new Fl_Button(35, 145, 120, 35, "New window");
+ o->callback((Fl_Callback*)cb_New);
+ }
+ { Fl_Button* o = new Fl_Button(215, 145, 120, 35, "Delete window");
+ o->callback((Fl_Callback*)cb_Delete);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(45, 25, 95, 25, "button1");
+ o->callback((Fl_Callback*)cb_button1);
+ }
+ { Fl_Check_Button* o = new Fl_Check_Button(220, 25, 95, 25, "button2");
+ Button = o;
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ }
+ { Fl_Tile* o = new Fl_Tile(110, 55, 165, 80);
+ { Fl_Box* o = new Fl_Box(110, 55, 165, 50, "label");
+ o->box(FL_DOWN_BOX);
+ }
+ { Fl_Box* o = new Fl_Box(110, 105, 80, 30, "label");
+ o->box(FL_DOWN_BOX);
+ }
+ { Fl_Box* o = new Fl_Box(190, 105, 85, 30, "label");
+ o->box(FL_DOWN_BOX);
+ }
+ o->end();
+ }
+ { Fl_Menu_Bar* o = new Fl_Menu_Bar(0, 0, 375, 25);
+ o->menu(menu_);
+ }
+ w->end();
+ }
+ Win->show();
+}
+
+UserInterface::~UserInterface() {
+ delete Win;
+}
+
+int main() {
+ new UserInterface;
+return Fl::run();
+}
diff --git a/fluid/penne.H b/fluid/penne.H
new file mode 100644
index 000000000..ebabab473
--- /dev/null
+++ b/fluid/penne.H
@@ -0,0 +1,32 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_Window.H>
+
+class UserInterface {
+public:
+ UserInterface();
+ Fl_Window *Win;
+private:
+ inline void cb_New_i(Fl_Button*, void*);
+ static void cb_New(Fl_Button*, void*);
+ inline void cb_Delete_i(Fl_Button*, void*);
+ static void cb_Delete(Fl_Button*, void*);
+ inline void cb_button1_i(Fl_Light_Button*, void*);
+ static void cb_button1(Fl_Light_Button*, void*);
+public:
+ Fl_Check_Button *Button;
+ static Fl_Menu_Item menu_[];
+private:
+ inline void cb_When_i(Fl_Menu_*, void*);
+ static void cb_When(Fl_Menu_*, void*);
+public:
+ ~UserInterface();
+};
+int main();
diff --git a/fluid/primes.fl b/fluid/primes.fl
new file mode 100644
index 000000000..e221b739a
--- /dev/null
+++ b/fluid/primes.fl
@@ -0,0 +1,22 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 10
+snap 3
+decl {// This is a demo of fluid used to write a normal C program} {}
+
+decl {\#include <stdio.h>} {}
+
+Function {main()} {open selected
+} {
+ code {printf("%d ", 2);} {}
+ codeblock {for (int x=3; x < 10000; x += 2)} {open
+ } {
+ code {for (int y=3; x%y; y += 2)} {}
+ codeblock {if (y*y > x)} {open
+ } {
+ code {printf("%d ", x);
+break;} {}
+ }
+ }
+}
diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx
new file mode 100644
index 000000000..23ee01e19
--- /dev/null
+++ b/fluid/widget_panel.cxx
@@ -0,0 +1,316 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "widget_panel.H"
+
+Fl_Input *v_input[4];
+
+Fl_Window* make_widget_panel() {
+ Fl_Window *w;
+ { Fl_Window* o = w = new Fl_Window(370, 480);
+ w->hotspot(o);
+ { Fl_Input* o = new Fl_Input(90, 10, 210, 20, "name:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)name_cb);
+ o->when(0);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(300, 10, 60, 20, "public");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)name_public_cb);
+ o->when(1);
+ }
+ { Fl_Input* o = new Fl_Input(90, 35, 170, 20, "class:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)subclass_cb, (void*)(4));
+ o->when(0);
+ }
+ { Fl_Choice* o = new Fl_Choice(260, 35, 100, 20);
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)subtype_cb);
+ }
+ { Fl_Input* o = new Fl_Input(90, 60, 270, 20, "label:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)label_cb);
+ o->when(1);
+ }
+ { Fl_Choice* o = new Fl_Choice(90, 80, 150, 20, "labeltype:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)labeltype_cb);
+ o->menu(labeltypemenu);
+ }
+ { Fl_Button* o = new Fl_Button(240, 80, 20, 20, "@-1<-");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_LEFT));
+ }
+ { Fl_Button* o = new Fl_Button(260, 80, 20, 20, "@-1->");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_RIGHT));
+ }
+ { Fl_Button* o = new Fl_Button(280, 80, 20, 20, "@-18");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_TOP));
+ }
+ { Fl_Button* o = new Fl_Button(300, 80, 20, 20, "@-12");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_BOTTOM));
+ }
+ { Fl_Button* o = new Fl_Button(320, 80, 20, 20, "@-3square");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_INSIDE));
+ }
+ { Fl_Button* o = new Fl_Button(340, 80, 20, 10, "wrap");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_WRAP));
+ }
+ { Fl_Button* o = new Fl_Button(340, 90, 20, 10, "clip");
+ o->type(1);
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)align_cb, (void*)(FL_ALIGN_CLIP));
+ }
+ { Fl_Choice* o = new Fl_Choice(90, 100, 170, 20, "labelfont:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)labelfont_cb);
+ o->menu(fontmenu);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(260, 100, 50, 20);
+ o->box(FL_THIN_UP_BOX);
+ o->maximum(100);
+ o->step(1);
+ o->value(14);
+ o->callback((Fl_Callback*)labelsize_cb);
+ }
+ { Fl_Button* o = new Fl_Button(310, 100, 50, 20, "labelcolor");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)labelcolor_cb);
+ }
+ { Fl_Choice* o = new Fl_Choice(90, 125, 220, 20, "box:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)box_cb);
+ o->menu(boxmenu);
+ }
+ { Fl_Button* o = new Fl_Button(310, 125, 50, 20, "color");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)color_cb);
+ }
+ { Fl_Choice* o = new Fl_Choice(90, 145, 220, 20, "down_box:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)down_box_cb);
+ o->menu(boxmenu);
+ }
+ { Fl_Button* o = new Fl_Button(310, 145, 50, 20, "select color");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)color2_cb);
+ }
+ { Fl_Choice* o = new Fl_Choice(90, 170, 170, 20, "textfont:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)textfont_cb);
+ o->hide();
+ o->menu(fontmenu);
+ }
+ { Fl_Input* o = new Fl_Input(90, 170, 170, 20, "xclass:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)xclass_cb);
+ o->when(0);
+ }
+ { Shortcut_Button* o = new Shortcut_Button(90, 170, 270, 20, "shortcut:");
+ o->box(FL_THIN_UP_BOX);
+ o->color(7);
+ o->selection_color(7);
+ o->callback((Fl_Callback*)shortcut_in_cb);
+ o->align(4);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(260, 170, 50, 20);
+ o->box(FL_THIN_UP_BOX);
+ o->maximum(100);
+ o->step(1);
+ o->value(14);
+ o->callback((Fl_Callback*)textsize_cb);
+ o->hide();
+ }
+ { Fl_Button* o = new Fl_Button(310, 170, 50, 20, "textcolor");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)textcolor_cb);
+ o->hide();
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(20, 205, 60, 20, "size:");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(10);
+ o->step(0.010101);
+ o->callback((Fl_Callback*)slider_size_cb);
+ o->align(5);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(90, 205, 60, 20, "minimum:");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)min_cb);
+ o->align(5);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(160, 205, 60, 20, "maximum:");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(10);
+ o->value(1);
+ o->callback((Fl_Callback*)max_cb);
+ o->align(5);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(230, 205, 60, 20, "step:");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)step_cb);
+ o->align(5);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(300, 205, 60, 20, "value:");
+ o->box(FL_THIN_UP_BOX);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)value_cb);
+ o->align(5);
+ }
+ { Fl_Group* o = new Fl_Group(20, 230, 340, 20);
+ o->callback((Fl_Callback*)propagate_load);
+ o->align(5);
+ { Fl_Light_Button* o = new Fl_Light_Button(20, 230, 70, 20, "non_modal");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(9);
+ o->callback((Fl_Callback*)non_modal_cb);
+ o->align(148);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(90, 230, 60, 20, "visible");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)visible_cb);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(90, 230, 60, 20, "modal");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)modal_cb);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(160, 230, 60, 20, "active");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)active_cb);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(160, 230, 60, 20, "border");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)border_cb);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(230, 230, 60, 20, "resizable");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)resizable_cb);
+ o->when(1);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(300, 230, 60, 20, "hotspot");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)hotspot_cb);
+ o->when(1);
+ }
+ o->end();
+ }
+ { Fl_Input* o = v_input[0] = new Fl_Input(90, 260, 270, 20, "extra code:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)v_input_cb, (void*)(0));
+ o->when(0);
+ }
+ { Fl_Input* o = v_input[1] = new Fl_Input(90, 280, 270, 20);
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)v_input_cb, (void*)(1));
+ o->when(0);
+ }
+ { Fl_Input* o = v_input[2] = new Fl_Input(90, 300, 270, 20);
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)v_input_cb, (void*)(2));
+ o->when(0);
+ }
+ { Fl_Input* o = v_input[3] = new Fl_Input(90, 320, 270, 20);
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)v_input_cb, (void*)(3));
+ o->when(0);
+ }
+ { Fl_Box* o = new Fl_Box(0, 350, 90, 20, "callback:");
+ o->align(24);
+ }
+ { Fl_Input* o = new Fl_Input(90, 350, 270, 50);
+ o->type(4);
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)callback_cb);
+ o->when(0);
+ }
+ { Fl_Box* o = new Fl_Box(90, 370, 100, 30, "label");
+ o->hide();
+ o->deactivate();
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Input* o = new Fl_Input(90, 400, 170, 20, "user_data:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)user_data_cb);
+ o->when(0);
+ }
+ { Fl_Input* o = new Fl_Input(300, 400, 60, 20, "type:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)user_data_type_cb);
+ o->when(0);
+ }
+ { Fl_Choice* o = new Fl_Choice(90, 420, 100, 20, "when:");
+ o->box(FL_THIN_UP_BOX);
+ o->callback((Fl_Callback*)when_cb);
+ o->when(0);
+ o->menu(whenmenu);
+ }
+ { Fl_Light_Button* o = new Fl_Light_Button(190, 420, 70, 20, "no change");
+ o->box(FL_THIN_UP_BOX);
+ o->selection_color(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)when_button_cb);
+ o->when(0);
+ }
+ { Fl_Group* o = new Fl_Group(10, 450, 350, 20);
+ { Fl_Button* o = new Fl_Button(10, 450, 80, 20, "no &overlay");
+ o->labelcolor(1);
+ o->callback((Fl_Callback*)overlay_cb);
+ }
+ { Fl_Button* o = new Fl_Button(100, 450, 80, 20, "Revert");
+ o->callback((Fl_Callback*)revert_cb);
+ }
+ { Fl_Button* o = new Fl_Button(190, 450, 80, 20, "Cancel");
+ o->callback((Fl_Callback*)cancel_cb);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(280, 450, 80, 20, "OK");
+ o->callback((Fl_Callback*)ok_cb);
+ }
+ o->end();
+ }
+ o->end();
+ }
+ return w;
+}
diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl
new file mode 100644
index 000000000..0fb973c51
--- /dev/null
+++ b/fluid/widget_panel.fl
@@ -0,0 +1,300 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+header_name {.H}
+code_name {.C}
+gridx 10
+gridy 5
+snap 3
+Function {make_widget_panel()} {open
+} {
+ Fl_Window {} {open
+ xywh {189 164 370 480} hotspot visible
+ } {
+ Fl_Input {} {
+ label {name:}
+ callback name_cb
+ xywh {90 10 210 20} box THIN_UP_BOX when 0
+ }
+ Fl_Light_Button {} {
+ label public
+ callback name_public_cb
+ xywh {300 10 60 20} box THIN_UP_BOX color {49 1} labelsize 10 when 1
+ }
+ Fl_Input {} {
+ label {class:}
+ user_data 4
+ callback subclass_cb
+ xywh {90 35 170 20} box THIN_UP_BOX when 0
+ }
+ Fl_Choice {} {
+ callback subtype_cb
+ xywh {260 35 100 20} box THIN_UP_BOX
+ } {}
+ Fl_Input {} {
+ label {label:}
+ callback label_cb
+ xywh {90 60 270 20} box THIN_UP_BOX when 1
+ }
+ Fl_Choice {} {
+ label {labeltype:}
+ callback labeltype_cb
+ xywh {90 80 150 20} box THIN_UP_BOX
+ code0 {extern Fl_Menu_Item labeltypemenu[];}
+ code1 {o->menu(labeltypemenu);}
+ } {}
+ Fl_Button {} {
+ label {@-1<-}
+ user_data FL_ALIGN_LEFT
+ callback align_cb
+ xywh {240 80 20 20} type Toggle box THIN_UP_BOX labeltype SYMBOL_LABEL labelcolor 8
+ }
+ Fl_Button {} {
+ label {@-1->}
+ user_data FL_ALIGN_RIGHT
+ callback align_cb
+ xywh {260 80 20 20} type Toggle box THIN_UP_BOX labeltype SYMBOL_LABEL labelcolor 8
+ }
+ Fl_Button {} {
+ label {@-18}
+ user_data FL_ALIGN_TOP
+ callback align_cb
+ xywh {280 80 20 20} type Toggle box THIN_UP_BOX labeltype SYMBOL_LABEL labelcolor 8
+ }
+ Fl_Button {} {
+ label {@-12}
+ user_data FL_ALIGN_BOTTOM
+ callback align_cb
+ xywh {300 80 20 20} type Toggle box THIN_UP_BOX labeltype SYMBOL_LABEL labelcolor 8
+ }
+ Fl_Button {} {
+ label {@-3square}
+ user_data FL_ALIGN_INSIDE
+ callback align_cb
+ xywh {320 80 20 20} type Toggle box THIN_UP_BOX labeltype SYMBOL_LABEL labelcolor 8
+ }
+ Fl_Button {} {
+ label wrap
+ user_data FL_ALIGN_WRAP
+ callback align_cb
+ xywh {340 80 20 10} type Toggle box THIN_UP_BOX labelsize 8
+ }
+ Fl_Button {} {
+ label clip
+ user_data FL_ALIGN_CLIP
+ callback align_cb
+ xywh {340 90 20 10} type Toggle box THIN_UP_BOX labelsize 8
+ }
+ Fl_Choice {} {
+ label {labelfont:}
+ callback labelfont_cb
+ xywh {90 100 170 20} box THIN_UP_BOX
+ code0 {extern Fl_Menu_Item fontmenu[];}
+ code1 {o->menu(fontmenu);}
+ } {}
+ Fl_Value_Input {} {
+ callback labelsize_cb
+ xywh {260 100 50 20} box THIN_UP_BOX maximum 100 step 1 value 14
+ }
+ Fl_Button {} {
+ label labelcolor
+ callback labelcolor_cb
+ xywh {310 100 50 20} box THIN_UP_BOX labelsize 8
+ }
+ Fl_Choice {} {
+ label {box:}
+ callback box_cb
+ xywh {90 125 220 20} box THIN_UP_BOX
+ code0 {extern Fl_Menu_Item boxmenu[];}
+ code1 {o->menu(boxmenu);}
+ } {}
+ Fl_Button {} {
+ label color
+ callback color_cb
+ xywh {310 125 50 20} box THIN_UP_BOX labelsize 8
+ }
+ Fl_Choice {} {
+ label {down_box:}
+ callback down_box_cb
+ xywh {90 145 220 20} box THIN_UP_BOX
+ code0 {extern Fl_Menu_Item boxmenu[];}
+ code1 {o->menu(boxmenu);}
+ } {}
+ Fl_Button {} {
+ label {select color}
+ callback color2_cb
+ xywh {310 145 50 20} box THIN_UP_BOX labelsize 8
+ }
+ Fl_Choice {} {
+ label {textfont:}
+ callback textfont_cb selected
+ xywh {90 170 170 20} box THIN_UP_BOX hide
+ code0 {extern Fl_Menu_Item fontmenu[];}
+ code1 {o->menu(fontmenu);}
+ } {}
+ Fl_Input {} {
+ label {xclass:}
+ callback xclass_cb
+ xywh {90 170 170 20} box THIN_UP_BOX when 0
+ }
+ Fl_Button {} {
+ label {shortcut:}
+ callback shortcut_in_cb
+ xywh {90 170 270 20} box THIN_UP_BOX color {7 7} align 4
+ code0 {\#include "Shortcut_Button.H"}
+ class Shortcut_Button
+ }
+ Fl_Value_Input {} {
+ callback textsize_cb
+ xywh {260 170 50 20} box THIN_UP_BOX maximum 100 step 1 value 14 hide
+ }
+ Fl_Button {} {
+ label textcolor
+ callback textcolor_cb
+ xywh {310 170 50 20} box THIN_UP_BOX labelsize 8 hide
+ }
+ Fl_Value_Input {} {
+ label {size:}
+ callback slider_size_cb
+ xywh {20 205 60 20} box THIN_UP_BOX labelsize 10 align 5 step 0.010101
+ }
+ Fl_Value_Input {} {
+ label {minimum:}
+ callback min_cb
+ xywh {90 205 60 20} box THIN_UP_BOX labelsize 10 align 5
+ }
+ Fl_Value_Input {} {
+ label {maximum:}
+ callback max_cb
+ xywh {160 205 60 20} box THIN_UP_BOX labelsize 10 align 5 value 1
+ }
+ Fl_Value_Input {} {
+ label {step:}
+ callback step_cb
+ xywh {230 205 60 20} box THIN_UP_BOX labelsize 10 align 5
+ }
+ Fl_Value_Input {} {
+ label {value:}
+ callback value_cb
+ xywh {300 205 60 20} box THIN_UP_BOX labelsize 10 align 5
+ }
+ Fl_Group {} {
+ callback propagate_load open
+ xywh {20 230 340 20} align 5
+ } {
+ Fl_Light_Button {} {
+ label non_modal
+ callback non_modal_cb
+ xywh {20 230 70 20} box THIN_UP_BOX color {49 1} labelsize 9 align 148
+ }
+ Fl_Light_Button {} {
+ label visible
+ callback visible_cb
+ xywh {90 230 60 20} box THIN_UP_BOX color {49 1} labelsize 10
+ }
+ Fl_Light_Button {} {
+ label modal
+ callback modal_cb
+ xywh {90 230 60 20} box THIN_UP_BOX color {49 1} labelsize 10
+ }
+ Fl_Light_Button {} {
+ label active
+ callback active_cb
+ xywh {160 230 60 20} box THIN_UP_BOX color {49 1} labelsize 10
+ }
+ Fl_Light_Button {} {
+ label border
+ callback border_cb
+ xywh {160 230 60 20} box THIN_UP_BOX color {49 1} labelsize 10
+ }
+ Fl_Light_Button {} {
+ label resizable
+ callback resizable_cb
+ xywh {230 230 60 20} box THIN_UP_BOX color {49 1} labelsize 10 when 1
+ }
+ Fl_Light_Button {} {
+ label hotspot
+ callback hotspot_cb
+ xywh {300 230 60 20} box THIN_UP_BOX color {49 1} labelsize 10 when 1
+ }
+ }
+ Fl_Input {v_input[0]} {
+ label {extra code:}
+ user_data 0
+ callback v_input_cb
+ xywh {90 260 270 20} box THIN_UP_BOX when 0
+ }
+ Fl_Input {v_input[1]} {
+ user_data 1
+ callback v_input_cb
+ xywh {90 280 270 20} box THIN_UP_BOX when 0
+ }
+ Fl_Input {v_input[2]} {
+ user_data 2
+ callback v_input_cb
+ xywh {90 300 270 20} box THIN_UP_BOX when 0
+ }
+ Fl_Input {v_input[3]} {
+ user_data 3
+ callback v_input_cb
+ xywh {90 320 270 20} box THIN_UP_BOX when 0
+ }
+ Fl_Box {} {
+ label {callback:}
+ xywh {0 350 90 20} align 24
+ }
+ Fl_Input {} {
+ callback callback_cb
+ xywh {90 350 270 50} type Multiline box THIN_UP_BOX when 0
+ }
+ Fl_Box {} {
+ label label
+ xywh {90 370 100 30} hide deactivate resizable
+ }
+ Fl_Input {} {
+ label {user_data:}
+ callback user_data_cb
+ xywh {90 400 170 20} box THIN_UP_BOX when 0
+ }
+ Fl_Input {} {
+ label {type:}
+ callback user_data_type_cb
+ xywh {300 400 60 20} box THIN_UP_BOX when 0
+ }
+ Fl_Choice {} {
+ label {when:}
+ callback when_cb
+ xywh {90 420 100 20} box THIN_UP_BOX when 0
+ code0 {extern Fl_Menu_Item whenmenu[];}
+ code1 {o->menu(whenmenu);}
+ } {}
+ Fl_Light_Button {} {
+ label {no change}
+ callback when_button_cb
+ xywh {190 420 70 20} box THIN_UP_BOX color {49 1} labelsize 10 when 0
+ }
+ Fl_Group {} {open
+ xywh {10 450 350 20}
+ } {
+ Fl_Button {} {
+ label {no &overlay}
+ callback overlay_cb
+ xywh {10 450 80 20} labelcolor 1
+ }
+ Fl_Button {} {
+ label Revert
+ callback revert_cb
+ xywh {100 450 80 20}
+ }
+ Fl_Button {} {
+ label Cancel
+ callback cancel_cb
+ xywh {190 450 80 20}
+ }
+ Fl_Return_Button {} {
+ label OK
+ callback ok_cb
+ xywh {280 450 80 20}
+ }
+ }
+ }
+}
diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h
new file mode 100644
index 000000000..9e304d16a
--- /dev/null
+++ b/fluid/widget_panel.h
@@ -0,0 +1,61 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "Shortcut_Button.H"
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Value_Input.H>
+#include <FL/Fl_Window.H>
+extern Fl_Menu_Item boxmenu[];
+extern Fl_Menu_Item fontmenu[];
+extern Fl_Menu_Item labeltypemenu[];
+extern Fl_Menu_Item whenmenu[];
+extern void active_cb(Fl_Light_Button*, void*);
+extern void align_cb(Fl_Button*, void*);
+extern void border_cb(Fl_Light_Button*, void*);
+extern void box_cb(Fl_Choice*, void*);
+extern void callback_cb(Fl_Input*, void*);
+extern void cancel_cb(Fl_Button*, void*);
+extern void color2_cb(Fl_Button*, void*);
+extern void color_cb(Fl_Button*, void*);
+extern void down_box_cb(Fl_Choice*, void*);
+extern void hotspot_cb(Fl_Light_Button*, void*);
+extern void label_cb(Fl_Input*, void*);
+extern void labelcolor_cb(Fl_Button*, void*);
+extern void labelfont_cb(Fl_Choice*, void*);
+extern void labelsize_cb(Fl_Value_Input*, void*);
+extern void labeltype_cb(Fl_Choice*, void*);
+extern void max_cb(Fl_Value_Input*, void*);
+extern void min_cb(Fl_Value_Input*, void*);
+extern void modal_cb(Fl_Light_Button*, void*);
+extern void name_cb(Fl_Input*, void*);
+extern void name_public_cb(Fl_Light_Button*, void*);
+extern void non_modal_cb(Fl_Light_Button*, void*);
+extern void ok_cb(Fl_Return_Button*, void*);
+extern void overlay_cb(Fl_Button*, void*);
+extern void propagate_load(Fl_Group*, void*);
+extern void resizable_cb(Fl_Light_Button*, void*);
+extern void revert_cb(Fl_Button*, void*);
+extern void shortcut_in_cb(Shortcut_Button*, void*);
+extern void slider_size_cb(Fl_Value_Input*, void*);
+extern void step_cb(Fl_Value_Input*, void*);
+extern void subclass_cb(Fl_Input*, void*);
+extern void subtype_cb(Fl_Choice*, void*);
+extern void textcolor_cb(Fl_Button*, void*);
+extern void textfont_cb(Fl_Choice*, void*);
+extern void textsize_cb(Fl_Value_Input*, void*);
+extern void user_data_cb(Fl_Input*, void*);
+extern void user_data_type_cb(Fl_Input*, void*);
+extern void v_input_cb(Fl_Input*, void*);
+extern void value_cb(Fl_Value_Input*, void*);
+extern void visible_cb(Fl_Light_Button*, void*);
+extern void when_button_cb(Fl_Light_Button*, void*);
+extern void when_cb(Fl_Choice*, void*);
+extern void xclass_cb(Fl_Input*, void*);
+extern Fl_Input *v_input[4];
+Fl_Window* make_widget_panel();
diff --git a/forms.h b/forms.h
new file mode 100644
index 000000000..967b24b67
--- /dev/null
+++ b/forms.h
@@ -0,0 +1,3 @@
+// this file allows some forms programs to be compiled with no change.
+// put it in your include path.
+#include <FL/forms.H>
diff --git a/install-sh b/install-sh
new file mode 100644
index 000000000..89fc9b098
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/lib/... b/lib/...
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/lib/...
diff --git a/makedist b/makedist
new file mode 100755
index 000000000..480aa01a3
--- /dev/null
+++ b/makedist
@@ -0,0 +1,26 @@
+#!/bin/tcsh
+# I use tcsh to get the better glob matching. Wish there were a more
+# portable way...
+# argument to this script is the version number or word like "BETA"
+
+if ( $1 == "" ) then
+echo "Version number needed"
+exit 1
+endif
+
+set f="fltk-$1"
+rm -f $f
+ln -s . $f
+
+echo "Making $f.tgz"
+tar -cf \
+ $f.tar $f/README $f/COPYING $f/version $f/Makefile \
+ $f/configure $f/*.in $f/makefiles/* $f/makedist $f/install-sh \
+ $f/{src,fluid,FL,test,GL}/{README,Makefile,*.{fl,[CHch],x?m,menu}} \
+ $f/documentation/*.{html,gif,jpg} $f/documentation/CHANGES \
+ $f/forms.h $f/win32/* $f/lib/... \
+
+gzip -f $f.tar
+mv $f.tar.gz $f.tgz
+
+rm -f $f
diff --git a/makefiles/aixmakesharedlib b/makefiles/aixmakesharedlib
new file mode 100755
index 000000000..8fd62a8d7
--- /dev/null
+++ b/makefiles/aixmakesharedlib
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# aixmakesharedlib - a simple script for AIX shared lib creation from a
+# non shared library
+#
+# Notes:
+# - Should work for both AIX 3.2.x & 4.1.x
+# - Copies original (non shared) lib to be lib.NS
+# - May require slight modifications for different uses (this was written
+# with the FL library in mind)
+#
+
+/bin/rm -f shr.o syms.exp
+
+# create the exports list:
+echo "#!" > syms.exp
+dump -g $1 | egrep -e '[ \t]*[0-9]+' | sed 's/^[ \t]*[0-9][0-9]*[ \t]*[^ \t]//' | sed 's/^\.//' | sort | uniq >> syms.exp
+
+xlC -o shr.o $1 -bM:SRE -bE:syms.exp -bnoentry -lc -lm -lX11
+
+mv $1 $1.NS
+
+ar ruv $1 shr.o syms.exp
+/bin/rm -f shr.o syms.exp
diff --git a/makefiles/makeinclude.cygnus b/makefiles/makeinclude.cygnus
new file mode 100644
index 000000000..239e87661
--- /dev/null
+++ b/makefiles/makeinclude.cygnus
@@ -0,0 +1,43 @@
+# !!!! YOU PROBABLY WANT TO USE makeinclude.mingw32 INSTEAD !!!!
+
+# Makeinclude file for the Cygwin B19 release of GCC for Windoze
+#
+# This will try to use Cygwin's Unix emulation as much as possible,
+# which means it will link in Cygwin's libraries. This seems to
+# result in much slower performance, and the only real difference
+# is that the file chooser uses cygwin's scandir implementation
+# rather than my own. To compile with direct windoze calls
+# use the file makeinclude.mingw32.
+
+# Copy this file to .. and run make.
+# Thanks to Philipp Knirsch at Lucent and Carl Thompson
+
+prefix =/usr/local
+exec_prefix =${prefix}
+bindir =${exec_prefix}/bin
+includedir =${prefix}/include
+libdir =${exec_prefix}/lib
+srcdir =.
+
+# compiler names:
+CXX =g++
+CC =gcc
+
+# flags for C++ compiler:
+CFLAGS =-Wall -O2 -DCYGNUS
+CXXFLAGS =-Wall -O2 -DCYGNUS
+CXXFLAGS_D =-Wall -g -DDEBUG -DCYGNUS
+
+# program to make the archive:
+LIBNAME =libfltk.a
+LIBNAME_D =libfltk_d.a
+AR =ar -ruv
+RANLIB =ranlib
+
+# libraries to link with:
+LDLIBS =-lgdi32 -luser32 -lm
+
+# libraries to link with when using GL:
+GLDLIBS =-lgdi32 -luser32 -lglu32 -lopengl32 -lm
+
+INSTALL =/CYGNUS/B19/H-I386~1/BIN/install -c
diff --git a/makefiles/makeinclude.mingw32 b/makefiles/makeinclude.mingw32
new file mode 100644
index 000000000..3390f113a
--- /dev/null
+++ b/makefiles/makeinclude.mingw32
@@ -0,0 +1,36 @@
+# Makeinclude file for the Cygwin B19 release of GCC for Windoze
+
+# This will compile the code to directly call Windows interfaces
+# and does not use the CYGWIN library.
+
+# Thanks to Philipp Knirsch at Lucent and Carl Thompson
+
+prefix =/usr/local
+exec_prefix =${prefix}
+bindir =${exec_prefix}/bin
+includedir =${prefix}/include
+libdir =${exec_prefix}/lib
+srcdir =.
+
+# compiler names:
+CXX =g++
+CC =g++
+
+# flags for C++ compiler:
+CFLAGS =-Wall -O2 -DWIN32
+CXXFLAGS =-Wall -O2 -DWIN32
+CXXFLAGS_D =-Wall -g -DDEBUG -DWIN32
+
+# program to make the archive:
+LIBNAME =libfltk.a
+LIBNAME_D =libfltk_d.a
+AR =ar -ruv
+RANLIB =ranlib
+
+# libraries to link with:
+LDLIBS =-lgdi32 -luser32 -lm -mwindows
+
+# libraries to link with when using GL:
+GLDLIBS =-lgdi32 -luser32 -lglu32 -lopengl32 -lm -mwindows
+
+INSTALL =/CYGNUS/B19/H-I386~1/BIN/install -c
diff --git a/makeinclude.in b/makeinclude.in
new file mode 100644
index 000000000..1791e680f
--- /dev/null
+++ b/makeinclude.in
@@ -0,0 +1,32 @@
+# @configure_input@
+
+prefix =@prefix@
+exec_prefix =@exec_prefix@
+bindir =@bindir@
+includedir =@includedir@
+libdir =@libdir@
+srcdir =@srcdir@
+VPATH =@srcdir@
+
+# compiler names:
+CXX =@CXX@
+CC =@CC@
+MAKEDEPEND =@MAKEDEPEND@
+
+# flags for C++ compiler:
+CFLAGS =@CFLAGS@
+CFLAGS_D =@CFLAGS_D@
+CXXFLAGS =@CXXFLAGS@ @X_CFLAGS@
+CXXFLAGS_D =@CXXFLAGS_D@ @X_CFLAGS@
+
+# program to make the archive:
+LIBNAME =libfltk.a
+LIBNAME_D =libfltk_d.a
+AR =ar rc
+RANLIB =@RANLIB@
+
+# libraries to link with:
+LDLIBS =@LIBS@ -lX11 -lXext @X_EXTRA_LIBS@ -lm
+
+# libraries to link with when using GL:
+GLDLIBS =@LIBS@ @GLLIB@ -lX11 -lXext @X_EXTRA_LIBS@ -lm
diff --git a/src/Fl.cxx b/src/Fl.cxx
new file mode 100644
index 000000000..06a0c62b1
--- /dev/null
+++ b/src/Fl.cxx
@@ -0,0 +1,566 @@
+// Fl.C
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+
+// Written by Bill Spitzak spitzak@d2.com
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#include <ctype.h>
+
+int Fl::damage_;
+Fl_Widget *Fl::belowmouse_;
+Fl_Widget *Fl::pushed_;
+Fl_Widget *Fl::focus_;
+Fl_Widget *Fl::selection_owner_;
+int Fl::e_x, Fl::e_y, Fl::e_x_root, Fl::e_y_root;
+int Fl::e_state;
+int Fl::e_clicks;
+int Fl::e_is_click;
+int Fl::e_keysym;
+char *Fl::e_text;
+int Fl::e_length;
+
+int Fl::event_inside(int x,int y,int w,int h) /*const*/ {
+ int mx = event_x();
+ int my = event_y();
+ return (mx >= x && mx < x+w && my >= y && my < y+h);
+}
+
+int Fl::event_inside(const Fl_Widget *o) /*const*/ {
+ return event_inside(o->x(),o->y(),o->w(),o->h());
+}
+
+// Timeouts are insert-sorted into order. This works good if there
+// are only a small number:
+
+#define MAXTIMEOUT 8
+
+static struct {
+ double time;
+ void (*cb)(void*);
+ void* arg;
+} timeout[MAXTIMEOUT+1];
+static int numtimeouts;
+
+void Fl::add_timeout(double t, void (*cb)(void *), void *v) {
+ int i;
+ if (numtimeouts<MAXTIMEOUT) numtimeouts++;
+ for (i=0; i<numtimeouts-1; i++) {
+ if (timeout[i].time > t) {
+ for (int j=numtimeouts-1; j>i; j--) timeout[j] = timeout[j-1];
+ break;
+ }
+ }
+ timeout[i].time = t;
+ timeout[i].cb = cb;
+ timeout[i].arg = v;
+}
+
+void Fl::remove_timeout(void (*cb)(void *), void *v) {
+ int i,j;
+ for (i=j=0; i<numtimeouts; i++) {
+ if (timeout[i].cb == cb && timeout[i].arg==v) ;
+ else {if (j<i) timeout[j]=timeout[i]; j++;}
+ }
+ numtimeouts = j;
+}
+
+static void call_timeouts() {
+ if (timeout[0].time > 0) return;
+ struct {
+ void (*cb)(void *);
+ void *arg;
+ } temp[MAXTIMEOUT];
+ int i,j,k;
+ // copy all expired timeouts to temp array:
+ for (i=j=0; j<numtimeouts && timeout[j].time <= 0; i++,j++) {
+ temp[i].cb = timeout[j].cb;
+ temp[i].arg= timeout[j].arg;
+ }
+ // remove them from source array:
+ for (k=0; j<numtimeouts;) timeout[k++] = timeout[j++];
+ numtimeouts = k;
+ // and then call them:
+ for (k=0; k<i; k++) temp[k].cb(temp[k].arg);
+}
+
+void Fl::flush() {
+ if (damage()) {
+ damage_ = 0;
+ for (Fl_X* x = Fl_X::first; x; x = x->next) {
+ if (x->w->damage() && x->w->visible()) {
+ x->flush();
+ x->w->clear_damage();
+ }
+ }
+ }
+#ifndef WIN32
+ if (fl_display) XFlush(fl_display);
+#endif
+}
+
+extern double fl_wait(int timeout_flag, double timeout);
+extern int fl_ready();
+
+static int initclock; // if false we didn't call fl_elapsed() last time
+
+#ifndef WIN32
+#include <sys/time.h>
+#endif
+
+// fl_elapsed must return the amount of time since the last time it was
+// called. To reduce the number of system calls the to get the
+// current time, the "initclock" symbol is turned on by an indefinate
+// wait. This should then reset the measured-from time and return zero
+static double fl_elapsed() {
+
+#ifdef WIN32
+
+ unsigned long newclock = fl_msg.time; // NOT YET IMPLEMENTED!
+ const int TICKS_PER_SECOND = 1000; // divisor of the value to get seconds
+ static unsigned long prevclock;
+ if (!initclock) {prevclock = newclock; initclock = 1; return 0.0;}
+ double t = double(newclock-prevclock)/TICKS_PER_SECOND;
+ prevclock = newclock;
+
+#else
+
+ static struct timeval prevclock;
+ struct timeval newclock;
+ gettimeofday(&newclock, 0);
+ if (!initclock) {
+ prevclock.tv_sec = newclock.tv_sec;
+ prevclock.tv_usec = newclock.tv_usec;
+ initclock = 1;
+ return 0.0;
+ }
+ double t = newclock.tv_sec - prevclock.tv_sec +
+ (newclock.tv_usec - prevclock.tv_usec)/1000000.0;
+ prevclock.tv_sec = newclock.tv_sec;
+ prevclock.tv_usec = newclock.tv_usec;
+
+#endif
+
+ // expire any timeouts:
+ if (t > 0.0) for (int i=0; i<numtimeouts; i++) timeout[i].time -= t;
+ return t;
+}
+
+void (*Fl::idle)();
+static char in_idle;
+static void callidle() {
+ if (!Fl::idle || in_idle) return;
+ in_idle = 1;
+ Fl::idle();
+ in_idle = 0;
+}
+
+int Fl::wait() {
+ callidle();
+ if (numtimeouts) {fl_elapsed(); call_timeouts();}
+ flush();
+ if (!Fl_X::first) return 0; // no windows
+ if (idle && !in_idle)
+ fl_wait(1,0.0);
+ else if (numtimeouts)
+ fl_wait(1, timeout[0].time);
+ else {
+ initclock = 0;
+ fl_wait(0,0);
+ }
+ return 1;
+}
+
+double Fl::wait(double time) {
+ callidle();
+ if (numtimeouts) {time -= fl_elapsed(); call_timeouts();}
+ flush();
+ double wait_time = idle && !in_idle ? 0.0 : time;
+ if (numtimeouts && timeout[0].time < wait_time) wait_time = timeout[0].time;
+ fl_wait(1, wait_time);
+ return time - fl_elapsed();
+}
+
+int Fl::check() {
+ callidle();
+ if (numtimeouts) {fl_elapsed(); call_timeouts();}
+ flush();
+ if (!Fl_X::first) return 0; // no windows
+ fl_wait(1, 0.0);
+ return 1;
+}
+
+int Fl::ready() {
+ // if (idle && !in_idle) return 1; // should it do this?
+ if (numtimeouts) {fl_elapsed(); if (timeout[0].time <= 0) return 1;}
+ return fl_ready();
+}
+
+int Fl::run() {
+ while (wait());
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////
+// Window list management:
+
+Fl_X* Fl_X::first;
+
+Fl_Window* fl_find(Window xid) {
+ Fl_X *window;
+ for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next)
+ if (window->xid == xid) {
+ if (window != Fl_X::first && !Fl::modal()) {
+ // make this window be first to speed up searches
+ // this is not done if modal is true to avoid messing up modal stack
+ *pp = window->next;
+ window->next = Fl_X::first;
+ Fl_X::first = window;
+ }
+ return window->w;
+ }
+ return 0;
+}
+
+void Fl::redraw() {
+ for (Fl_X* x = Fl_X::first; x; x = x->next) x->w->redraw();
+}
+
+Fl_Window* Fl::first_window() {Fl_X* x = Fl_X::first; return x ? x->w : 0;}
+
+Fl_Window* Fl::next_window(const Fl_Window* w) {
+ Fl_X* x = Fl_X::i(w)->next; return x ? x->w : 0;}
+
+////////////////////////////////////////////////////////////////
+// Event handlers:
+
+struct handler_link {
+ int (*handle)(int);
+ const handler_link *next;
+};
+
+static const handler_link *handlers = 0;
+
+void Fl::add_handler(int (*h)(int)) {
+ handler_link *l = new handler_link;
+ l->handle = h;
+ l->next = handlers;
+ handlers = l;
+}
+
+static int send_handlers(int event) {
+ for (const handler_link *h = handlers; h; h = h->next)
+ if (h->handle(event)) return 1;
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Widget* fl_oldfocus; // kludge for Fl_Group...
+
+void Fl::focus(Fl_Widget *o) {
+ Fl_Widget *p = focus_;
+ if (o != p) {
+ focus_ = o;
+ fl_oldfocus = 0;
+ for (; p && !p->contains(o); p = p->parent()) {
+ p->handle(FL_UNFOCUS);
+ fl_oldfocus = p;
+ }
+ }
+}
+
+void Fl::belowmouse(Fl_Widget *o) {
+ Fl_Widget *p = belowmouse_;
+ if (o != p) {
+ event_is_click(0);
+ belowmouse_ = o;
+ for (; p && !p->contains(o); p = p->parent()) p->handle(FL_LEAVE);
+ }
+}
+
+// Because mouse events are posted to the outermost window we need to
+// adjust them for child windows if they are pushed(). This should also
+// be done for the focus() but that is nyi.
+static int mouse_dx;
+static int mouse_dy;
+
+void Fl::pushed(Fl_Widget *o) {
+ pushed_ = o;
+ mouse_dx = 0;
+ mouse_dy = 0;
+ if (o) for (Fl_Widget* w = o; w->parent(); w = w->parent()) {
+ if (w->type()>=FL_WINDOW) {mouse_dx -= w->x(); mouse_dy -= w->y();}
+ }
+}
+
+Fl_Window *fl_xfocus; // which window X thinks has focus
+Fl_Window *fl_xmousewin; // which window X thinks has FL_ENTER
+Fl_Window *Fl::grab_; // most recent Fl::grab()
+Fl_Window *Fl::modal_;
+
+// Update modal(), focus() and other state according to system state.
+// This is called whenever a window is added or hidden, and whenever
+// X says the focus or mouse window have changed, and when grab_ is
+// changed.
+void fl_fix_focus() {
+
+ // set Fl::modal() based on grab or any modal windows displayed:
+ if (Fl::grab_)
+ Fl::modal_ = Fl::grab_;
+ else {
+ Fl_Window* w = Fl::first_window();
+ while (w && w->parent()) w = Fl::next_window(w);
+ Fl::modal_ = w && w->modal() ? w : 0;
+ }
+
+ // set focus based on Fl::modal() and fl_xfocus
+ Fl_Window *w = fl_xfocus;
+ while (w && w->parent()) w = w->window();
+ if (w) {
+ if (Fl::modal()) w = Fl::modal();
+ if (!w->contains(Fl::focus()))
+ if (!w->take_focus()) Fl::focus(w);
+ } else
+ Fl::focus(0);
+
+ if (Fl::pushed()) {
+
+ // move pushed() to modal window (necessary for menus):
+ if (Fl::modal() && !Fl::modal()->contains(Fl::pushed()))
+ Fl::pushed_ = Fl::modal();
+
+ } else { // set belowmouse only when pushed() is false
+
+ // set belowmouse based on Fl::modal() and fl_xmousewin:
+ w = fl_xmousewin;
+ if (w) {
+ if (Fl::modal()) w = Fl::modal();
+ if (!w->contains(Fl::belowmouse())) {
+ Fl::belowmouse(w); w->handle(FL_ENTER);}
+ } else
+ Fl::belowmouse(0);
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl::handle(int event, Fl_Window* window)
+{
+ Fl_Widget* w = window;
+
+ switch (event) {
+
+ case FL_CLOSE:
+ if (modal() && window != modal()) return 0;
+ w->do_callback();
+ return 1;
+
+ case FL_SHOW:
+ ((Fl_Widget*)w)->show();
+ return 1;
+
+ case FL_HIDE:
+ ((Fl_Widget*)w)->hide();
+ return 1;
+
+ case FL_PUSH:
+ if (Fl::grab()) w = Fl::grab();
+ else if (Fl::modal() && w != Fl::modal()) return 0;
+ Fl::pushed_ = w; mouse_dx = mouse_dy = 0;
+ if (w->handle(event)) return 1;
+ // raise windows that are clicked on:
+ window->show();
+ return 1;
+
+ case FL_MOVE:
+ case FL_DRAG:
+ if (window != fl_xmousewin) {
+ // this should not happen if enter/leave events were reported
+ // correctly by the system, but just in case...
+ fl_xmousewin = window; fl_fix_focus();
+ }
+ if (Fl::pushed()) {
+ Fl::e_x += mouse_dx;
+ Fl::e_y += mouse_dy;
+ event = FL_DRAG;
+ w = Fl::pushed();
+ } else if (Fl::grab())
+ w = Fl::grab();
+ else if (Fl::modal() && w != Fl::modal())
+ w = 0;
+ break;
+
+ case FL_RELEASE: {
+ if (Fl::pushed_) w = Fl::pushed_; Fl::pushed_ = 0;
+ int r = w->handle(event);
+ fl_fix_focus();
+ if (fl_xmousewin) fl_xmousewin->handle(FL_MOVE);
+ return r;}
+
+ case FL_UNFOCUS:
+ window = 0;
+ case FL_FOCUS:
+ fl_xfocus = window;
+ Fl::e_keysym = 0; // make sure it is not confused with navigation key
+ fl_fix_focus();
+ return 1;
+
+ case FL_KEYBOARD:
+ if (window != fl_xfocus) {
+ // this should not happen if enter/leave events were reported
+ // correctly by the system, but just in case...
+ fl_xfocus = window; fl_fix_focus();
+ }
+ // Try it as keystroke, sending it to focus and all parents:
+ for (w = Fl::focus(); w; w = w->parent())
+ if (w->handle(FL_KEYBOARD)) return 1;
+
+ // Try it as shortcut, sending to mouse widget and all parents:
+ w = Fl::belowmouse(); if (!w) {w = Fl::modal(); if (!w) w = window;}
+ for (; w; w = w->parent()) if (w->handle(FL_SHORTCUT)) return 1;
+
+ // try using add_handle() functions:
+ if (send_handlers(FL_SHORTCUT)) return 1;
+
+ // Try swapping the case of the text in the shortcut:
+ if (isalpha(Fl::event_text()[0])) {
+ *(char*)(Fl::event_text()) ^= ('A'^'a');
+ w = Fl::belowmouse(); if (!w) {w = Fl::modal(); if (!w) w = window;}
+ for (; w; w = w->parent()) if (w->handle(FL_SHORTCUT)) return 1;
+ if (send_handlers(FL_SHORTCUT)) return 1;
+ }
+
+ // make Escape key close windows:
+ if (Fl::event_key()==FL_Escape) {
+ window->do_callback();
+ return 1;
+ }
+
+ return 0;
+
+ case FL_ENTER:
+ fl_xmousewin = window; fl_fix_focus();
+ return 1;
+
+ case FL_LEAVE:
+ if (window == fl_xmousewin) {fl_xmousewin = 0; fl_fix_focus();}
+ return 1;
+
+ default:
+ break;
+ }
+ if (w && w->handle(event)) return 1;
+ return send_handlers(event);
+}
+
+////////////////////////////////////////////////////////////////
+// hide() destroys the X window, it does not do unmap!
+
+void fl_throw_focus(Fl_Widget*); // in Fl_x.C
+
+void Fl_Window::hide() {
+ if (!shown()) return;
+
+ // remove from the list of windows:
+ Fl_X* x = i;
+ Fl_X** pp = &Fl_X::first;
+ for (; *pp != x; pp = &(*pp)->next) if (!*pp) return;
+ *pp = x->next;
+ i = 0;
+
+ // recursively remove any subwindows:
+ for (Fl_X *w = Fl_X::first; w;) {
+ Fl_Window* W = w->w;
+ if (W->window() == this) {
+ W->hide();
+ W->set_visible();
+ w = Fl_X::first;
+ } else w = w->next;
+ }
+
+ // Make sure no events are sent to this window:
+ if (this == fl_xmousewin) fl_xmousewin = 0;
+ if (this == fl_xfocus) fl_xfocus = 0;
+ fl_throw_focus(this);
+ handle(FL_HIDE);
+
+#ifdef WIN32
+ if (x->private_dc) ReleaseDC(x->xid,x->private_dc);
+ if (x->xid == fl_window) fl_GetDC(0); // releases dc belonging to window
+#else
+ if (x->region) XDestroyRegion(x->region);
+#endif
+ XDestroyWindow(fl_display, x->xid);
+
+ delete x;
+}
+
+Fl_Window::~Fl_Window() {
+ hide();
+}
+
+// Child windows must respond to FL_SHOW and FL_HIDE by actually
+// doing unmap operations. Outer windows assumme FL_SHOW & FL_HIDE
+// are messages from X:
+
+int Fl_Window::handle(int event) {
+ if (parent()) switch (event) {
+ case FL_SHOW:
+ if (!shown()) show();
+ else XMapWindow(fl_display, fl_xid(this));
+ break;
+ case FL_HIDE:
+ if (shown()) XUnmapWindow(fl_display, fl_xid(this));
+ break;
+ }
+ return Fl_Group::handle(event);
+}
+
+////////////////////////////////////////////////////////////////
+// ~Fl_Widget() calls this: this function must get rid of any
+// global pointers to the widget. This is also called by hide()
+// and deactivate().
+
+// call this to free a selection (or change the owner):
+void Fl::selection_owner(Fl_Widget *owner) {
+ if (selection_owner_ && owner != selection_owner_)
+ selection_owner_->handle(FL_SELECTIONCLEAR);
+ selection_owner_ = owner;
+}
+
+#ifndef WIN32
+Fl_Widget *fl_selection_requestor; // from Fl_cutpaste.C
+#endif
+
+void fl_throw_focus(Fl_Widget *o) {
+ if (o->contains(Fl::pushed())) Fl::pushed(0);
+ if (o->contains(Fl::selection_owner())) Fl::selection_owner(0);
+#ifndef WIN32
+ if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0;
+#endif
+ int fix = 0;
+ if (o->contains(Fl::belowmouse())) {Fl::belowmouse(0); fix = 1;}
+ if (o->contains(Fl::focus())) {Fl::focus(0); fix = 1;}
+ if (fix) fl_fix_focus();
+}
+
+// End of Fl.C //
diff --git a/src/Fl_Adjuster.cxx b/src/Fl_Adjuster.cxx
new file mode 100644
index 000000000..a9b39d7bf
--- /dev/null
+++ b/src/Fl_Adjuster.cxx
@@ -0,0 +1,105 @@
+// Fl_Adjuster.C
+
+// Fltk widget for drag-adjusting a floating point value.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Adjuster.H>
+#include <FL/Fl_Bitmap.H>
+#include <FL/fl_draw.H>
+
+#include "fastarrow.h"
+static Fl_Bitmap fastarrow(fastarrow_bits, fastarrow_width, fastarrow_height);
+#include "mediumarrow.h"
+static Fl_Bitmap mediumarrow(mediumarrow_bits, mediumarrow_width, mediumarrow_height);
+#include "slowarrow.h"
+static Fl_Bitmap slowarrow(slowarrow_bits, slowarrow_width, slowarrow_height);
+
+// changing the value does not change the appearance:
+void Fl_Adjuster::value_damage() {}
+
+void Fl_Adjuster::draw() {
+ int dx, dy, W, H;
+ if (w()>=h()) {
+ dx = W = w()/3;
+ dy = 0; H = h();
+ } else {
+ dx = 0; W = w();
+ dy = H = h()/3;
+ }
+ draw_box(drag==1?FL_DOWN_BOX:box(), x(), y()+2*dy, W, H, color());
+ draw_box(drag==2?FL_DOWN_BOX:box(), x()+dx, y()+dy, W, H, color());
+ draw_box(drag==3?FL_DOWN_BOX:box(), x()+2*dx, y(), W, H, color());
+ fl_color(selection_color());
+ fastarrow.draw(x()+(W-fastarrow_width)/2,
+ y()+2*dy+(H-fastarrow_height)/2, W, H);
+ mediumarrow.draw(x()+dx+(W-mediumarrow_width)/2,
+ y()+dy+(H-mediumarrow_height)/2, W, H);
+ slowarrow.draw(x()+2*dx+(W-slowarrow_width)/2,
+ y()+(H-slowarrow_width)/2, W, H);
+}
+
+int Fl_Adjuster::handle(int event) {
+ double v;
+ int delta;
+ int mx = Fl::event_x();
+ switch (event) {
+ case FL_PUSH:
+ ix = mx;
+ if (w()>=h())
+ drag = 3*(mx-x())/w() + 1;
+ else
+ drag = 3-3*(Fl::event_y()-y()-1)/h();
+ handle_push();
+ redraw();
+ return 1;
+ case FL_DRAG:
+ if (w() >= h()) {
+ delta = x()+(drag-1)*w()/3; // left edge of button
+ if (mx < delta)
+ delta = mx-delta;
+ else if (mx > delta+w()/3) // right edge of button
+ delta = mx-delta-w()/3;
+ else
+ delta = 0;
+ } else {
+ if (mx < x())
+ delta = mx-x();
+ else if (mx > x()+w())
+ delta = mx-x()-w();
+ else
+ delta = 0;
+ }
+ switch (drag) {
+ case 3: v = increment(previous_value(), delta); break;
+ case 2: v = increment(previous_value(), delta*10); break;
+ default:v = increment(previous_value(), delta*100); break;
+ }
+ handle_drag(soft() ? softclamp(v) : clamp(v));
+ return 1;
+ case FL_RELEASE:
+ if (Fl::event_is_click()) { // detect click but no drag
+ if (Fl::event_state()&0xF0000) delta = -10;
+ else delta = 10;
+ switch (drag) {
+ case 3: v = increment(previous_value(), delta); break;
+ case 2: v = increment(previous_value(), delta*10); break;
+ default:v = increment(previous_value(), delta*100); break;
+ }
+ handle_drag(soft() ? softclamp(v) : clamp(v));
+ }
+ drag = 0;
+ redraw();
+ handle_release();
+ return 1;
+ }
+ return 0;
+}
+
+Fl_Adjuster::Fl_Adjuster(int x, int y, int w, int h, const char* l)
+ : Fl_Valuator(x, y, w, h, l) {
+ box(FL_UP_BOX);
+ step(1, 10000);
+ selection_color(FL_BLACK);
+ drag = 0;
+ soft_ = 1;
+}
diff --git a/src/Fl_Bitmap.cxx b/src/Fl_Bitmap.cxx
new file mode 100644
index 000000000..b0bb53ab8
--- /dev/null
+++ b/src/Fl_Bitmap.cxx
@@ -0,0 +1,109 @@
+/* Fl_Bitmap.C
+
+ Draw a bitmap in a box.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Bitmap.H>
+
+void Fl_Bitmap::draw(int X, int Y, int W, int H, int cx,int cy) {
+ // clip the box down to the size of image, quit if empty:
+ if (cx < 0) {W += cx; X -= cx; cx = 0;}
+ if (cx+W > w) W = w-cx;
+ if (W <= 0) return;
+ if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+ if (cy+H > h) H = h-cy;
+ if (H <= 0) return;
+#ifdef WIN32
+ if (!id) {
+ // we need to pad the lines out to words & swap the bits
+ // in each byte.
+ int w1 = (w+7)/8;
+ int w2 = ((w+15)/16)*2;
+ uchar* newarray = new uchar[w2*h];
+ const uchar* src = array;
+ uchar* dest = newarray;
+ for (int y=0; y < h; y++) {
+ for (int n = 0; n < w1; n++) {
+ *dest++ =
+ ((*src&0x01) << 7) +
+ ((*src&0x02) << 5) +
+ ((*src&0x04) << 3) +
+ ((*src&0x08) << 1) +
+ ((*src&0x10) >> 1) +
+ ((*src&0x20) >> 3) +
+ ((*src&0x40) >> 5) +
+ ((*src&0x80) >> 7);
+ src++;
+ }
+ dest += w2-w1;
+ }
+ id = (ulong)CreateBitmap(w, h, 1, 1, newarray);
+ array = newarray; // keep the pointer so I can free it later
+ }
+ HDC tempdc = CreateCompatibleDC(fl_gc);
+ SelectObject(tempdc, (HGDIOBJ)id);
+ SelectObject(fl_gc, fl_brush());
+ // secret bitblt code found in old MSWindows reference manual:
+ BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
+ DeleteDC(tempdc);
+#else
+ if (!id) id = XCreateBitmapFromData(fl_display, fl_window,
+ (const char*)array, (w+7)&-8, h);
+ XSetStipple(fl_display, fl_gc, id);
+ int ox = X-cx; if (ox < 0) ox += w;
+ int oy = Y-cy; if (oy < 0) oy += h;
+ XSetTSOrigin(fl_display, fl_gc, ox, oy);
+ XSetFillStyle(fl_display, fl_gc, FillStippled);
+ XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H);
+ XSetFillStyle(fl_display, fl_gc, FillSolid);
+#endif
+}
+
+Fl_Bitmap::~Fl_Bitmap() {
+#ifdef WIN32
+ if (id) {
+ DeleteObject((HGDIOBJ)id);
+ delete[] (uchar*)array;
+ }
+#else
+ if (id) fl_delete_offscreen((Fl_Offscreen)id);
+#endif
+}
+
+static void bitmap_labeltype(
+ const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
+{
+ Fl_Bitmap* b = (Fl_Bitmap*)(o->value);
+ int cx;
+ if (a & FL_ALIGN_LEFT) cx = 0;
+ else if (a & FL_ALIGN_RIGHT) cx = b->w-w;
+ else cx = (b->w-w)/2;
+ int cy;
+ if (a & FL_ALIGN_TOP) cy = 0;
+ else if (a & FL_ALIGN_BOTTOM) cy = b->h-h;
+ else cy = (b->h-h)/2;
+ fl_color((Fl_Color)o->color);
+ b->draw(x,y,w,h,cx,cy);
+}
+
+static void bitmap_measure(const Fl_Label* o, int& w, int& h) {
+ Fl_Bitmap* b = (Fl_Bitmap*)(o->value);
+ w = b->w;
+ h = b->h;
+}
+
+void Fl_Bitmap::label(Fl_Widget* o) {
+ Fl::set_labeltype(_FL_BITMAP_LABEL, bitmap_labeltype, bitmap_measure);
+ o->label(_FL_BITMAP_LABEL, (const char*)this);
+}
+
+void Fl_Bitmap::label(Fl_Menu_Item* o) {
+ Fl::set_labeltype(_FL_BITMAP_LABEL, bitmap_labeltype, bitmap_measure);
+ o->label(_FL_BITMAP_LABEL, (const char*)this);
+}
diff --git a/src/Fl_Box.cxx b/src/Fl_Box.cxx
new file mode 100644
index 000000000..48b968b39
--- /dev/null
+++ b/src/Fl_Box.cxx
@@ -0,0 +1,11 @@
+// Fl_Box.C
+
+// The box widget. An almost non-functional subclass of Fl_Widget.
+
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Box.H>
+
+void Fl_Box::draw() {
+ draw_box();
+ draw_label();
+}
diff --git a/src/Fl_Browser.cxx b/src/Fl_Browser.cxx
new file mode 100644
index 000000000..f58447386
--- /dev/null
+++ b/src/Fl_Browser.cxx
@@ -0,0 +1,421 @@
+// Fl_Browser.C
+
+// Forms-compatable browser. Probably useful for other lists of
+// textual data.
+
+// I modified this from the original Forms data to use a linked list
+// so that the number of items in the browser and size of those items
+// is unlimited. The only problem is that the old browser used an
+// index number to identify a line, and it is slow to convert from/to
+// a pointer. I use a cache of the last match to try to speed this
+// up.
+
+// Also added the ability to "hide" a line. This set's it's height to
+// zero, so the Fl_Browser_ cannot pick it.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Browser.H>
+#include <FL/fl_draw.H>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <FL/Fl_Input_.H> // for default_font
+
+#define SELECTED 1
+#define NOTDISPLAYED 2
+
+struct FL_BLINE { // data is in a linked list of these
+ FL_BLINE* prev;
+ FL_BLINE* next;
+ void* data;
+ short length; // sizeof(txt)-1, may be longer than string
+ char flags; // selected, displayed
+ char txt[1]; // start of allocated array
+};
+
+void* Fl_Browser::item_first() const {return first;}
+
+void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;}
+
+void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;}
+
+int Fl_Browser::item_selected(void* l) const {
+ return ((FL_BLINE*)l)->flags&SELECTED;}
+
+void Fl_Browser::item_select(void* l, int v) {
+ if (v) ((FL_BLINE*)l)->flags |= SELECTED;
+ else ((FL_BLINE*)l)->flags &= ~SELECTED;
+}
+
+FL_BLINE* Fl_Browser::find_line(int line) const {
+ int n; FL_BLINE* l;
+ if (line == cacheline) return cache;
+ if (cacheline && line > cacheline/2 && line < (cacheline+lines)/2) {
+ n = cacheline; l = cache;
+ } else if (line <= lines/2) {
+ n = 1; l = first;
+ } else {
+ n = lines; l = last;
+ }
+ for (; n < line && l; n++) l = l->next;
+ for (; n > line && l; n--) l = l->prev;
+ ((Fl_Browser*)this)->cacheline = line;
+ ((Fl_Browser*)this)->cache = l;
+ return l;
+}
+
+int Fl_Browser::lineno(void* v) const {
+ FL_BLINE* l = (FL_BLINE*)v;
+ if (!l) return 0;
+ if (l == cache) return cacheline;
+ if (l == first) return 1;
+ if (l == last) return lines;
+ if (!cache) {
+ ((Fl_Browser*)this)->cache = first;
+ ((Fl_Browser*)this)->cacheline = 1;
+ }
+ // assumme it is near cache, search both directions:
+ FL_BLINE* b = cache->prev;
+ int bnum = cacheline-1;
+ FL_BLINE* f = cache->next;
+ int fnum = cacheline+1;
+ int n = 0;
+ for (;;) {
+ if (b == l) {n = bnum; break;}
+ if (f == l) {n = fnum; break;}
+ if (b) {b = b->prev; bnum--;}
+ if (f) {f = f->next; fnum++;}
+ }
+ ((Fl_Browser*)this)->cache = l;
+ ((Fl_Browser*)this)->cacheline = n;
+ return n;
+}
+
+FL_BLINE* Fl_Browser::_remove(int line) {
+ FL_BLINE* ttt = find_line(line);
+ deleting(ttt);
+
+ cacheline = line-1;
+ cache = ttt->prev;
+ if (ttt->prev) ttt->prev->next = ttt->next;
+ else first = ttt->next;
+ if (ttt->next) ttt->next->prev = ttt->prev;
+ else last = ttt->prev;
+
+ lines--;
+ full_height_ -= item_height(ttt);
+ return(ttt);
+}
+
+void Fl_Browser::remove(int line) {
+ if (line < 1 || line > lines) return;
+ free(_remove(line));
+}
+
+void Fl_Browser::insert(int line, FL_BLINE* t) {
+ if (!first) {
+ t->prev = t->next = 0;
+ first = last = t;
+ } else if (line <= 1) {
+ inserting(first, t);
+ t->prev = 0;
+ t->next = first;
+ t->next->prev = t;
+ first = t;
+ } else if (line > lines) {
+ t->prev = last;
+ t->prev->next = t;
+ t->next = 0;
+ last = t;
+ } else {
+ FL_BLINE* n = find_line(line);
+ inserting(n, t);
+ t->next = n;
+ t->prev = n->prev;
+ t->prev->next = t;
+ n->prev = t;
+ }
+ cacheline = line;
+ cache = t;
+ lines++;
+ full_height_ += item_height(t);
+ redraw_line(t);
+}
+
+void Fl_Browser::insert(int line, const char* newtext, void* data) {
+ int l = strlen(newtext);
+ FL_BLINE* t = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);
+ t->length = l;
+ t->flags = 0;
+ strcpy(t->txt, newtext);
+ t->data = data;
+ insert(line, t);
+}
+
+void Fl_Browser::move(int to, int from) {
+ if (from < 1 || from > lines) return;
+ insert(to, _remove(from));
+}
+
+void Fl_Browser::text(int line, const char* newtext) {
+ if (line < 1 || line > lines) return;
+ FL_BLINE* t = find_line(line);
+ int l = strlen(newtext);
+ if (l > t->length) {
+ FL_BLINE* n = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);
+ replacing(t, n);
+ cache = n;
+ n->length = l;
+ n->flags = t->flags;
+ n->prev = t->prev;
+ if (n->prev) n->prev->next = n; else first = n;
+ n->next = t->next;
+ if (n->next) n->next->prev = n; else last = n;
+ free(t);
+ t = n;
+ }
+ strcpy(t->txt, newtext);
+ redraw_line(t);
+}
+
+void Fl_Browser::data(int line, void* data) {
+ if (line < 1 || line > lines) return;
+ find_line(line)->data = data;
+}
+
+int Fl_Browser::item_height(void* lv) const {
+ FL_BLINE* l = (FL_BLINE*)lv;
+ if (l->flags & NOTDISPLAYED) return 0;
+ char* str = l->txt;
+ int t = textsize()+2;
+ if (*str == format_char()) switch (*(str+1)) {
+ case 'l': case 'L': t = 26; break;
+ case 'm': case 'M': t = 20; break;
+ case 's': case 'S': t = 13; break;
+ }
+ return t + Fl_Input_::default_size();
+}
+
+int Fl_Browser::item_width(void* v) const {
+ char* str = ((FL_BLINE*)v)->txt;
+ const int* i = column_widths();
+ int w = 0;
+
+ while (*i) { // add up all tab-seperated fields
+ w += *i++;
+ char* e;
+ for (e = str; *e && *e != column_char(); e++);
+ if (!*e) return 0; // last one occupied by text
+ str = e+1;
+ }
+
+ // OK, we gotta parse the string and find the string width...
+ int size = textsize();
+ Fl_Font font = textfont();
+ int done = 0;
+
+ while (*str == format_char_ && *++str && *str != format_char_) {
+ switch (*str++) {
+ case 'l': case 'L': size = 24; break;
+ case 'm': case 'M': size = 18; break;
+ case 's': size = 11; break;
+ case 'b': font = (Fl_Font)(font|FL_BOLD); break;
+ case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
+ case 'f': case 't': font = FL_COURIER; break;
+ case 'S':
+ size = strtol(str, &str, 10);
+ break;
+ case '.':
+ done = 1;
+ case '@':
+ str--;
+ done = 1;
+ }
+
+ if (done)
+ break;
+ }
+
+ fl_font(font, size, Fl_Input_::default_font(), Fl_Input_::default_size());
+ return w + int(fl_width(str)) + 6;
+}
+
+int Fl_Browser::full_height() const {
+ return full_height_;
+}
+
+int Fl_Browser::incr_height() const {
+ return textsize()+2;
+}
+
+void Fl_Browser::item_draw(void* v, int x, int y, int w, int h) const {
+ char* str = ((FL_BLINE*)v)->txt;
+ const int* i = column_widths();
+
+ while (w > 6) { // do each tab-seperated field
+ int w1 = w; // width for this field
+ char* e = 0; // pointer to end of field or null if none
+ if (*i) { // find end of field and temporarily replace with 0
+ for (e = str; *e && *e != column_char(); e++);
+ if (*e) {*e = 0; w1 = *i++;} else e = 0;
+ }
+ int size = textsize();
+ Fl_Font font = textfont();
+ Fl_Color lcol = textcolor();
+ Fl_Align align = FL_ALIGN_LEFT;
+ // check for all the @-lines recognized by XForms:
+ while (*str == format_char() && *++str && *str != format_char()) {
+ switch (*str++) {
+ case 'l': case 'L': size = 24; break;
+ case 'm': case 'M': size = 18; break;
+ case 's': size = 11; break;
+ case 'b': font = (Fl_Font)(font|FL_BOLD); break;
+ case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
+ case 'f': case 't': font = FL_COURIER; break;
+ case 'c': align = FL_ALIGN_CENTER; break;
+ case 'r': align = FL_ALIGN_RIGHT; break;
+ case 'B':
+ fl_color((Fl_Color)strtol(str, &str, 10));
+ fl_rectf(x, y, w1, h);
+ break;
+ case 'C':
+ lcol = (Fl_Color)strtol(str, &str, 10);
+ break;
+ case 'F':
+ font = (Fl_Font)strtol(str, &str, 10);
+ break;
+ case 'N':
+ lcol = FL_INACTIVE_COLOR;
+ break;
+ case 'S':
+ size = strtol(str, &str, 10);
+ break;
+ case '-':
+ fl_color(FL_DARK3);
+ fl_line(x+3, y+h/2, x+w1-3, y+h/2);
+ fl_color(FL_LIGHT3);
+ fl_line(x+3, y+h/2+1, x+w1-3, y+h/2+1);
+ break;
+ case 'u':
+ case '_':
+ fl_color(lcol);
+ fl_line(x+3, y+h-1, x+w1-3, y+h-1);
+ break;
+ case '.':
+ goto BREAK;
+ case '@':
+ str--; goto BREAK;
+ }
+ }
+ BREAK:
+ fl_font(font, size, Fl_Input_::default_font(), Fl_Input_::default_size());
+ if (!active_r()) lcol = inactive(lcol);
+ if (((FL_BLINE*)v)->flags & SELECTED)
+ lcol = contrast(lcol, selection_color());
+ fl_color(lcol);
+ fl_draw(str, x+3, y, w1-6, h, align);
+ if (!e) break; // no more fields...
+ *e = column_char(); // put the seperator back
+ x += w1;
+ w -= w1;
+ str = e+1;
+ }
+}
+
+static const int no_columns[1] = {0};
+
+Fl_Browser::Fl_Browser(int x, int y, int w, int h, const char*l)
+ : Fl_Browser_(x, y, w, h, l) {
+ column_widths_ = no_columns;
+ lines = 0;
+ full_height_ = 0;
+ cacheline = 0;
+ format_char_ = '@';
+ column_char_ = '\t';
+ first = last = cache = 0;
+}
+
+void Fl_Browser::topline(int line) {
+ if (line<1) line = 1;
+ if (line>lines) line = lines;
+ int p = 0;
+ for (FL_BLINE* l=first; l&& line>1; l = l->next) {
+ line--; p += item_height(l);
+ }
+ position(p);
+}
+
+int Fl_Browser::topline() const {
+ return lineno(top());
+}
+
+void Fl_Browser::clear() {
+ for (FL_BLINE* l = first; l;) {
+ FL_BLINE* h = l->next;
+ free(l);
+ l = h;
+ }
+ full_height_ = 0;
+ first = 0;
+ lines = 0;
+ new_list();
+}
+
+void Fl_Browser::add(const char* newtext, void* data) {
+ insert(lines+1, newtext, data);
+ Fl_Browser_::display(last);
+}
+
+const char* Fl_Browser::text(int line) const {
+ if (line < 1 || line > lines) return 0;
+ return find_line(line)->txt;
+}
+
+void* Fl_Browser::data(int line) const {
+ if (line < 1 || line > lines) return 0;
+ return find_line(line)->data;
+}
+
+int Fl_Browser::select(int line, int value) {
+ if (line < 1 || line > lines) return 0;
+ return Fl_Browser_::select(find_line(line), value);
+}
+
+int Fl_Browser::selected(int line) const {
+ if (line < 1 || line > lines) return 0;
+ return find_line(line)->flags & SELECTED;
+}
+
+void Fl_Browser::show(int line) {
+ FL_BLINE* t = find_line(line);
+ if (t->flags & NOTDISPLAYED) {
+ t->flags &= ~NOTDISPLAYED;
+ full_height_ += item_height(t);
+ if (Fl_Browser_::displayed(t)) redraw_lines();
+ }
+}
+
+void Fl_Browser::hide(int line) {
+ FL_BLINE* t = find_line(line);
+ if (!(t->flags & NOTDISPLAYED)) {
+ full_height_ -= item_height(t);
+ t->flags |= NOTDISPLAYED;
+ if (Fl_Browser_::displayed(t)) redraw_lines();
+ }
+}
+
+void Fl_Browser::display(int line, int value) {
+ if (line < 1 || line > lines) return;
+ if (value) show(line); else hide(line);
+}
+
+int Fl_Browser::visible(int line) const {
+ if (line < 1 || line > lines) return 0;
+ return !(find_line(line)->flags&NOTDISPLAYED);
+}
+
+int Fl_Browser::value() const {
+ return lineno(selection());
+}
+
+// end of Fl_Browser.C
diff --git a/src/Fl_Browser_.cxx b/src/Fl_Browser_.cxx
new file mode 100644
index 000000000..ae1908808
--- /dev/null
+++ b/src/Fl_Browser_.cxx
@@ -0,0 +1,606 @@
+// Fl_Browser_.C
+
+// This is the base class for browsers. To be useful it must be
+// subclassed and several virtual functions defined. The
+// Forms-compatable browser and the file chooser's browser are
+// subclassed off of this.
+
+// Yes, I know this should be a template...
+
+// This has been designed so that the subclass has complete control
+// over the storage of the data, although because next() and prev()
+// functions are used to index, it works best as a linked list or as a
+// large block of characters in which the line breaks must be searched
+// for.
+
+// A great deal of work has been done so that the "height" of a data
+// object does not need to be determined until it is drawn. This was
+// done for the file chooser, because the height requires doing stat()
+// to see if the file is a directory, which can be annoyingly slow
+// over the network.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Browser_.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Input_.H> // for default_font
+
+/* redraw bits:
+ 1 = redraw children (the scrollbar)
+ 2 = redraw one or two items
+ 4 = redraw all items
+*/
+
+static void scrollbar_callback(Fl_Widget* s, void*) {
+ ((Fl_Browser_*)(s->parent()))->position(int(((Fl_Scrollbar*)s)->value()));
+}
+
+static void hscrollbar_callback(Fl_Widget* s, void*) {
+ ((Fl_Browser_*)(s->parent()))->hposition(int(((Fl_Scrollbar*)s)->value()));
+}
+
+int Fl_Browser_::scrollbar_width_ = 17;
+
+// return where to draw the actual box:
+void Fl_Browser_::bbox(int& X, int& Y, int& W, int& H) const {
+ Fl_Boxtype b = box() ? box() : Fl_Input_::default_box();
+ X = x()+Fl::box_dx(b);
+ Y = y()+Fl::box_dy(b);
+ W = w()-Fl::box_dw(b);
+ H = h()-Fl::box_dh(b);
+ if (scrollbar.visible()) {
+ W -= scrollbar_width_;
+ if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar_width_;
+ }
+ if (hscrollbar.visible()) {
+ H -= scrollbar_width_;
+ if (scrollbar.align() & FL_ALIGN_TOP) Y += scrollbar_width_;
+ }
+}
+
+int Fl_Browser_::leftedge() const {
+ int X, Y, W, H; bbox(X, Y, W, H);
+ return X;
+}
+
+// the scrollbars are resized & placed by draw(), since each one's size
+// depends on whether the other is visible or not. This skips over
+// Fl_Group::resize since it moves the scrollbars uselessly.
+void Fl_Browser_::resize(int X, int Y, int W, int H) {
+ Fl_Widget::resize(X, Y, W, H);
+}
+
+// Cause minimal update to redraw the given item:
+void Fl_Browser_::redraw_line(void* l) {
+ if (!redraw1 || redraw1 == l) {redraw1 = l; damage(2);}
+ else if (!redraw2 || redraw2 == l) {redraw2 = l; damage(2);}
+ else damage(4);
+}
+
+// Figure out top() based on position():
+void Fl_Browser_::update_top() {
+ if (!top_) top_ = item_first();
+ if (position_ != real_position_) {
+ void* l;
+ int ly;
+ int y = position_;
+ // start from either head or current position, whichever is closer:
+ if (!top_ || y <= real_position_/2) {
+ l = item_first();
+ ly = 0;
+ } else {
+ l = top_;
+ ly = real_position_-offset_;
+ }
+ if (!l) {
+ top_ = 0;
+ offset_ = 0;
+ real_position_ = 0;
+ } else {
+ int h = item_quick_height(l);
+ // step through list until we find line containing this point:
+ while (ly > y) {
+ void* l1 = item_prev(l);
+ if (!l1) {ly = 0; break;} // hit the top
+ l = l1;
+ h = item_quick_height(l);
+ ly -= h;
+ }
+ while (ly+h <= y) {
+ void* l1 = item_next(l);
+ if (!l1) {y = ly+h-1; break;}
+ l = l1;
+ ly += h;
+ h = item_quick_height(l);
+ }
+ // top item must *really* be visible, use slow height:
+ for (;;) {
+ h = item_height(l);
+ if (ly+h > y) break; // it is big enough to see
+ // go up to top of previous item:
+ void* l1 = item_prev(l);
+ if (!l1) {ly = y = 0; break;} // hit the top
+ l = l1; y = position_ = ly = ly-item_quick_height(l);
+ }
+ // use it:
+ top_ = l;
+ offset_ = y-ly;
+ real_position_ = y;
+ }
+ damage(4);
+ }
+}
+
+// Change position(), top() will update when update_top() is called
+// (probably by draw() or handle()):
+void Fl_Browser_::position(int y) {
+ if (y < 0) y = 0;
+ if (y == position_) return;
+ position_ = y;
+ if (y != real_position_) redraw_lines();
+}
+
+void Fl_Browser_::hposition(int x) {
+ if (x < 0) x = 0;
+ if (x == hposition_) return;
+ hposition_ = x;
+ if (x != real_hposition_) redraw_lines();
+}
+
+// Tell whether item is currently displayed:
+int Fl_Browser_::displayed(void* x) const {
+ int X, Y, W, H; bbox(X, Y, W, H);
+ int yy = H+offset_;
+ for (void* l = top_; l && yy > 0; l = item_next(l)) {
+ if (l == x) return 1;
+ yy -= item_height(l);
+ }
+ return 0;
+}
+
+// Insure this item is displayed:
+// Messy because we have no idea if it is before top or after bottom:
+void Fl_Browser_::display(void* x) {
+ if (!top_) top_ = item_first();
+ if (x == item_first()) {position(0); return;}
+ int X, Y, W, H; bbox(X, Y, W, H);
+ void* l = top_;
+ Y = -offset_;
+ // see if it is at the top or just above it:
+ if (l == x) {position(real_position_+Y); return;} // scroll up a bit
+ void* lp = item_prev(l);
+ if (lp == x) {position(real_position_+Y-item_quick_height(lp)); return;}
+ // search forward for it:
+ for (; l; l = item_next(l)) {
+ int h1 = item_quick_height(l);
+ if (l == x) {
+ if (Y <= H) { // it is visible or right at bottom
+ Y = Y+h1-H; // find where bottom edge is
+ if (Y > 0) position(real_position_+Y); // scroll down a bit
+ } else {
+ position(real_position_+Y-(H-h1)/2); // center it
+ }
+ return;
+ }
+ Y += h1;
+ }
+ // search backward for it, if found center it:
+ l = lp;
+ Y = -offset_;
+ for (; l; l = item_prev(l)) {
+ int h1 = item_quick_height(l);
+ Y -= h1;
+ if (l == x) {
+ if (Y + h1 >= 0) position(real_position_+Y);
+ else position(real_position_+Y-(H-h1)/2);
+ return;
+ }
+ }
+}
+
+// redraw, has side effect of updating top and setting scrollbar:
+void Fl_Browser_::draw() {
+ int drawsquare = 0;
+ if (damage() & 128) { // redraw the box if full redraw
+ Fl_Boxtype b = box() ? box() : Fl_Input_::default_box();
+ draw_box(b, x(), y(), w(), h(), color());
+ drawsquare = 1;
+ }
+
+ update_top();
+ int full_width_ = full_width();
+ int full_height_ = full_height();
+ int X, Y, W, H; bbox(X, Y, W, H);
+J1:
+ // see if scrollbar needs to be switched on/off:
+ if ((has_scrollbar_ & VERTICAL) && (
+ (has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) {
+ if (!scrollbar.visible()) {scrollbar.show(); drawsquare = 1;}
+ } else {
+ top_ = item_first(); real_position_ = offset_ = 0;
+ scrollbar.hide();
+ }
+
+ if ((has_scrollbar_ & HORIZONTAL) && (
+ (has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_ > W)) {
+ if (!hscrollbar.visible()) {hscrollbar.show(); drawsquare = 1;}
+ } else {
+ real_hposition_ = 0;
+ hscrollbar.hide();
+ }
+
+ bbox(X, Y, W, H);
+
+ fl_clip(X, Y, W, H);
+ // for each line, draw it if full redraw or scrolled. Erase background
+ // if not a full redraw or if it is selected:
+ void* l = top();
+ int yy = -offset_;
+ for (; l && yy < H; l = item_next(l)) {
+ int hh = item_height(l);
+ if (hh <= 0) continue;
+ if ((damage()&4) || l == redraw1 || l == redraw2) {
+ if (item_selected(l)) {
+ fl_color(selection_color());
+ fl_rectf(X, yy+Y, W, hh);
+ } else if (!(damage()&128)) {
+ fl_color(color());
+ fl_rectf(X, yy+Y, W, hh);
+ }
+ if (type() == FL_MULTI_BROWSER && l == selection_) {
+ fl_color(textcolor());
+ fl_rect(X+1, yy+Y, W-2, hh);
+ }
+ item_draw(l, X-hposition_, yy+Y, W, hh);
+ int w = item_width(l);
+ if (w > max_width) {max_width = w; max_width_item = l;}
+ }
+ yy += hh;
+ }
+ // erase the area below last line:
+ if (!(damage()&128) && yy < H) {
+ fl_color(color());
+ fl_rectf(X, yy+Y, W, H-yy);
+ }
+ fl_pop_clip();
+ redraw1 = redraw2 = 0;
+
+ // see if changes to full_height caused by calls to slow_height
+ // caused scrollbar state to change, in which case we have to redraw:
+ full_height_ = full_height();
+ full_width_ = full_width();
+ if ((has_scrollbar_ & VERTICAL) && (
+ (has_scrollbar_ & ALWAYS_ON) || position_ || full_height_>H)) {
+ if (!scrollbar.visible()) goto J1;
+ } else {
+ if (scrollbar.visible()) goto J1;
+ }
+ if ((has_scrollbar_ & HORIZONTAL) && (
+ (has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_>W)) {
+ if (!hscrollbar.visible()) goto J1;
+ } else {
+ if (hscrollbar.visible()) goto J1;
+ }
+
+ // update the scrollbars and redraw them:
+ int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10;
+ if (scrollbar.visible()) {
+ scrollbar.damage_resize(
+ scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W,
+ Y, scrollbar_width_, H);
+ scrollbar.value(position_, H, 0, full_height_);
+ scrollbar.linesize(dy);
+ if (drawsquare) draw_child(scrollbar);
+ else update_child(scrollbar);
+ }
+ if (hscrollbar.visible()) {
+ hscrollbar.damage_resize(
+ X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H,
+ W, scrollbar_width_);
+ hscrollbar.value(hposition_, W, 0, full_width_);
+ hscrollbar.linesize(dy);
+ if (drawsquare) draw_child(hscrollbar);
+ else update_child(hscrollbar);
+ }
+
+ // draw that little square between the scrolbars:
+ if (drawsquare && scrollbar.visible() && hscrollbar.visible()) {
+ fl_color(parent()->color());
+ fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar_width_,scrollbar_width_);
+ }
+
+ real_hposition_ = hposition_;
+}
+
+// Quick way to delete and reset everything:
+void Fl_Browser_::new_list() {
+ top_ = 0;
+ position_ = real_position_ = 0;
+ hposition_ = real_hposition_ = 0;
+ selection_ = 0;
+ offset_ = 0;
+ max_width = 0;
+ max_width_item = 0;
+ redraw_lines();
+}
+
+// Tell it that this item is going away, and that this must remove
+// all pointers to it:
+void Fl_Browser_::deleting(void* l) {
+ if (displayed(l)) redraw_lines();
+ if (l == selection_) selection_ = 0;
+ if (l == top_) {
+ real_position_ -= offset_;
+ offset_ = 0;
+ top_ = item_next(l);
+ if (!top_) top_ = item_prev(l);
+ }
+ if (l == max_width_item) {max_width_item = 0; max_width = 0;}
+}
+
+void Fl_Browser_::replacing(void* a, void* b) {
+ redraw_line(a);
+ if (a == selection_) selection_ = b;
+ if (a == top_) top_ = b;
+ if (a == max_width_item) {max_width_item = 0; max_width = 0;}
+}
+
+void Fl_Browser_::inserting(void* a, void* b) {
+ if (displayed(a)) redraw_lines();
+ if (a == top_) top_ = b;
+}
+
+void* Fl_Browser_::find_item(int my) {
+ update_top();
+ int X, Y, W, H; bbox(X, Y, W, H);
+ void* l;
+ int yy = Y-offset_;
+ for (l = top_; l; l = item_next(l)) {
+ int hh = item_height(l); if (hh <= 0) continue;
+ yy += hh;
+ if (my <= yy || yy>=Y+H) return l;
+ }
+ return 0;
+}
+
+int Fl_Browser_::select(void* l, int i, int docallbacks) {
+ if (type() == FL_MULTI_BROWSER) {
+ if (selection_ != l) {
+ if (selection_) redraw_line(selection_);
+ selection_ = l;
+ redraw_line(l);
+ }
+ if ((!i)==(!item_selected(l))) return 0;
+ item_select(l, i);
+ redraw_line(l);
+ } else {
+ if (i && selection_ == l) return 0;
+ if (!i && selection_ != l) return 0;
+ if (selection_) {
+ item_select(selection_, 0);
+ redraw_line(selection_);
+ selection_ = 0;
+ }
+ if (i) {
+ item_select(l, 1);
+ selection_ = l;
+ redraw_line(l);
+ display(l);
+ }
+ }
+ Fl::event_clicks(0);
+ if (docallbacks) do_callback();
+ return 1;
+}
+
+int Fl_Browser_::deselect(int docallbacks) {
+ if (type() == FL_MULTI_BROWSER) {
+ int change = 0;
+ for (void* p = item_first(); p; p = item_next(p))
+ change |= select(p, 0, docallbacks);
+ return change;
+ } else {
+ if (!selection_) return 0;
+ item_select(selection_, 0);
+ redraw_line(selection_);
+ selection_ = 0;
+ return 1;
+ }
+}
+
+int Fl_Browser_::select_only(void* l, int docallbacks) {
+ if (!l) return deselect(docallbacks);
+ int change = 0;
+ if (type() == FL_MULTI_BROWSER) {
+ for (void* p = item_first(); p; p = item_next(p))
+ if (p != l) change |= select(p, 0, docallbacks);
+ }
+ change |= select(l, 1, docallbacks);
+ display(l);
+ return change;
+}
+
+int Fl_Browser_::handle(int event) {
+
+ // must do shortcuts first or the scrollbar will get them...
+ if (event == FL_SHORTCUT && type() >= FL_HOLD_BROWSER) {
+ void* l1 = selection_;
+ void* l = l1; if (!l) l = top_; if (!l) l = item_first();
+ if (l) {
+ if (type()==FL_HOLD_BROWSER) switch (Fl::event_key()) {
+ case FL_Down:
+ while ((l = item_next(l)))
+ if (item_height(l)>0) {select_only(l, 1); break;}
+ return 1;
+ case FL_Up:
+ while ((l = item_prev(l))) if (item_height(l)>0) {
+ select_only(l, 1); break;}
+ return 1;
+ } else switch (Fl::event_key()) {
+ case FL_Enter:
+ select_only(l, 1);
+ return 1;
+ case ' ':
+ selection_ = l;
+ select(l, !item_selected(l), 1);
+ return 1;
+ case FL_Down:
+ while ((l = item_next(l))) {
+ if (Fl::event_state(FL_SHIFT|FL_CTRL))
+ select(l, l1 ? item_selected(l1) : 1, 1);
+ if (item_height(l)>0) goto J1;
+ }
+ return 1;
+ case FL_Up:
+ while ((l = item_prev(l))) {
+ if (Fl::event_state(FL_SHIFT|FL_CTRL))
+ select(l, l1 ? item_selected(l1) : 1, 1);
+ if (item_height(l)>0) goto J1;
+ }
+ return 1;
+ J1:
+ if (selection_) redraw_line(selection_);
+ selection_ = l; redraw_line(l);
+ display(l);
+ return 1;
+ }
+ }
+ }
+
+ if (Fl_Group::handle(event)) return 1;
+ int X, Y, W, H; bbox(X, Y, W, H);
+ int my;
+ static char change;
+ static char whichway;
+ static int py;
+ switch (event) {
+ case FL_PUSH:
+ if (!Fl::event_inside(X, Y, W, H)) return 0;
+ if (type() == FL_SELECT_BROWSER) deselect();
+ my = py = Fl::event_y();
+ change = 0;
+ if (type() == FL_NORMAL_BROWSER || !top_)
+ ;
+ else if (type() == FL_MULTI_BROWSER) {
+ void* l = find_item(my);
+ whichway = 1;
+ if (Fl::event_state(FL_SHIFT|FL_CTRL)) { // toggle selection:
+ if (l) {
+ whichway = !item_selected(l);
+ change = select(l, whichway, when() & FL_WHEN_CHANGED);
+ }
+ } else {
+ change = select_only(l, when() & FL_WHEN_CHANGED);
+ }
+ } else {
+ change = select_only(find_item(my), when() & FL_WHEN_CHANGED);
+ }
+ return 1;
+ case FL_DRAG:
+ // do the scrolling first:
+ my = Fl::event_y();
+ if (my < Y && my < py) {
+ int p = real_position_+my-Y;
+ if (p<0) p = 0;
+ position(p);
+ } else if (my > Y+H && my > py) {
+ int p = real_position_+my-(Y+H);
+ int h = full_height()-H; if (p > h) p = h;
+ if (p<0) p = 0;
+ position(p);
+ }
+ if (type() == FL_NORMAL_BROWSER || !top_)
+ ;
+ else if (type() == FL_MULTI_BROWSER) {
+ void* l = find_item(my);
+ void* t; void* b; // this will be the range to change
+ if (my > py) { // go down
+ t = selection_ ? item_next(selection_) : 0;
+ b = l ? item_next(l) : 0;
+ } else { // go up
+ t = l;
+ b = selection_;
+ }
+ for (; t && t != b; t = item_next(t))
+ change |= select(t, whichway, when() & FL_WHEN_CHANGED);
+ if (l) selection_ = l;
+ } else {
+ void* l1 = selection_;
+ void* l =
+ (Fl::event_x()<x() || Fl::event_x()>x()+w()) ? selection_ :
+ find_item(my);
+ select_only(l, when() & FL_WHEN_CHANGED);
+ change = (l != l1);
+ }
+ py = my;
+ return 1;
+ case FL_RELEASE:
+ if (type() == FL_SELECT_BROWSER) {
+ void* t = selection_; deselect(); selection_ = t;
+ }
+ if (change) {
+ if (when() & FL_WHEN_RELEASE) do_callback();
+ else if (!(when()&FL_WHEN_CHANGED)) set_changed();
+ } else {
+ if (when() & FL_WHEN_NOT_CHANGED) do_callback();
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+Fl_Browser_::Fl_Browser_(int x, int y, int w, int h, const char* l)
+ : Fl_Group(x, y, w, h, l),
+ scrollbar(0, 0, 0, 0, 0), // they will be resized by draw()
+ hscrollbar(0, 0, 0, 0, 0)
+{
+ box(FL_NO_BOX);
+ align(FL_ALIGN_BOTTOM);
+ position_ = real_position_ = 0;
+ hposition_ = real_hposition_ = 0;
+ offset_ = 0;
+ top_ = 0;
+ when(FL_WHEN_RELEASE_ALWAYS);
+ selection_ = 0;
+ color(FL_WHITE);
+ selection_color(FL_SELECTION_COLOR);
+ scrollbar.callback(scrollbar_callback);
+//scrollbar.align(FL_ALIGN_LEFT|FL_ALIGN_BOTTOM); // back compatability?
+ hscrollbar.callback(hscrollbar_callback);
+ hscrollbar.type(FL_HORIZONTAL);
+ textfont_ = FL_HELVETICA;
+ textsize_ = FL_NORMAL_SIZE;
+ textcolor_ = FL_BLACK;
+ has_scrollbar_ = BOTH;
+ max_width = 0;
+ max_width_item = 0;
+ end();
+}
+
+// Default versions of some of the virtual functions:
+
+int Fl_Browser_::item_quick_height(void* l) const {
+ return item_height(l);
+}
+
+int Fl_Browser_::incr_height() const {
+ return item_quick_height(item_first());
+}
+
+int Fl_Browser_::full_height() const {
+ int t = 0;
+ for (void* p = item_first(); p; p = item_next(p))
+ t += item_quick_height(p);
+ return t;
+}
+
+int Fl_Browser_::full_width() const {
+ return max_width;
+}
+
+void Fl_Browser_::item_select(void*, int) {}
+
+int Fl_Browser_::item_selected(void* l) const {return l==selection_;}
+
+// end of Fl_Browser_.C
diff --git a/src/Fl_Browser_load.cxx b/src/Fl_Browser_load.cxx
new file mode 100644
index 000000000..8e1da435a
--- /dev/null
+++ b/src/Fl_Browser_load.cxx
@@ -0,0 +1,29 @@
+// Fl_Browser_load.C
+// this should be moved to another source file, since it links stdio?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Browser.H>
+#include <stdio.h>
+
+int Fl_Browser::load(const char *filename) {
+#define MAXFL_BLINE 1024
+ char newtext[MAXFL_BLINE];
+ int c;
+ int i;
+ clear();
+ if (!filename || !(filename[0])) return 1;
+ FILE *fl = fopen(filename,"r");
+ if (!fl) return 0;
+ i = 0;
+ do {
+ c = getc(fl);
+ if (c == '\n' || c <= 0 || i>=MAXFL_BLINE-1) {
+ newtext[i] = 0;
+ add(newtext);
+ i = 0;
+ } else
+ newtext[i++] = c;
+ } while (c >= 0);
+ fclose(fl);
+ return 1;
+}
diff --git a/src/Fl_Button.cxx b/src/Fl_Button.cxx
new file mode 100644
index 000000000..86b563e78
--- /dev/null
+++ b/src/Fl_Button.cxx
@@ -0,0 +1,92 @@
+// Fl_Button.C
+
+// There are a lot of subclasses, named Fl_*_Button. Some of
+// them are implemented by setting the type() value and testing it
+// here. This includes Fl_Radio_Button and Fl_Toggle_Button
+
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Group.H>
+
+int Fl_Button::value(int v) {
+ v = v ? 1 : 0;
+ oldval = v;
+ clear_changed();
+ if (value_ != v) {value_ = v; redraw(); return 1;}
+ else return 0;
+}
+
+void Fl_Button::setonly() { // set this radio button on, turn others off
+ value(1);
+ Fl_Group* g = (Fl_Group*)parent();
+ Fl_Widget*const* a = g->array();
+ for (int i = g->children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0);
+ }
+}
+
+void Fl_Button::draw() {
+ if (type() == FL_HIDDEN_BUTTON) return;
+ Fl_Color col = value() ? selection_color() : color();
+//if (col == FL_GRAY && Fl::belowmouse()==this) col = FL_LIGHT1;
+ draw_box(value() ? (down_box()?down_box():down(box())) : box(), col);
+ draw_label();
+}
+int Fl_Button::handle(int event) {
+ int newval;
+ switch (event) {
+ case FL_ENTER:
+ case FL_LEAVE:
+// if ((value_?selection_color():color())==FL_GRAY) redraw();
+ return 1;
+ case FL_PUSH:
+ case FL_DRAG:
+ if (Fl::event_inside(this)) {
+ if (type() == FL_RADIO_BUTTON) newval = 1;
+ else newval = !oldval;
+ } else
+ newval = oldval;
+ if (newval != value_) {
+ value_ = newval;
+ redraw();
+ if (when() & FL_WHEN_CHANGED) do_callback();
+ }
+ return 1;
+ case FL_RELEASE:
+ if (value_ == oldval) return 1;
+ if (type() == FL_RADIO_BUTTON)
+ setonly();
+ else if (type() == FL_TOGGLE_BUTTON)
+ oldval = value_;
+ else {
+ value(oldval);
+ if (when() & FL_WHEN_CHANGED) do_callback();
+ }
+ if (when() & FL_WHEN_RELEASE) do_callback(); else set_changed();
+ return 1;
+ case FL_SHORTCUT:
+ if (!(shortcut() ?
+ Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
+ if (type() == FL_RADIO_BUTTON && !value_) {
+ setonly();
+ if (when() & FL_WHEN_CHANGED) do_callback();
+ } else if (type() == FL_TOGGLE_BUTTON) {
+ value(!value());
+ if (when() & FL_WHEN_CHANGED) do_callback();
+ }
+ if (when() & FL_WHEN_RELEASE) do_callback(); else set_changed();
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+Fl_Button::Fl_Button(int x,int y,int w,int h, const char *l)
+: Fl_Widget(x,y,w,h,l) {
+ box(FL_UP_BOX);
+ down_box(FL_NO_BOX);
+ value_ = oldval = 0;
+ shortcut_ = 0;
+ set_flag(SHORTCUT_LABEL);
+}
diff --git a/src/Fl_Chart.cxx b/src/Fl_Chart.cxx
new file mode 100644
index 000000000..54c6913f9
--- /dev/null
+++ b/src/Fl_Chart.cxx
@@ -0,0 +1,344 @@
+// Fl_Chart.C
+
+// Emulation of the Forms Chart widget.
+// I did not try to improve this much, as I doubt it is used.
+
+// display code Written by: Mark Overmars
+
+#include <FL/math.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Chart.H>
+#include <FL/fl_draw.H>
+#include <string.h>
+
+#define ARCINC (2.0*M_PI/360.0)
+
+// this function is in fl_boxtype.C:
+void fl_rectbound(int x,int y,int w,int h, Fl_Color color);
+
+/* Widget specific information */
+
+static void draw_barchart(int x,int y,int w,int h,
+ int numb, FL_CHART_ENTRY entries[],
+ double min, double max, int autosize, int maxnumb,
+ Fl_Color textcolor)
+/* Draws a bar chart. x,y,w,h is the bounding box, entries the array of
+ numb entries and min and max the boundaries. */
+{
+ double incr = h/(max-min);
+ int zeroh;
+ double lh = fl_height();
+ if ( -min*incr < lh) {
+ incr = (h - lh + min*incr)/(max-min);
+ zeroh = int(y+h-lh);
+ } else {
+ zeroh = int(y+h+min * incr + .5);
+ }
+ int bwidth = int(w/double(autosize?numb:maxnumb)+.5);
+ /* Draw base line */
+ fl_color(textcolor);
+ fl_line(x, zeroh, x+w, zeroh);
+ if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */
+ int i;
+ /* Draw the bars */
+ for (i=0; i<numb; i++) {
+ int h = int(entries[i].val*incr+.5);
+ if (h < 0)
+ fl_rectbound(x+i*bwidth,zeroh,bwidth+1,-h+1, (Fl_Color)entries[i].col);
+ else if (h > 0)
+ fl_rectbound(x+i*bwidth,zeroh-h,bwidth+1,h+1,(Fl_Color)entries[i].col);
+ }
+ /* Draw the labels */
+ fl_color(textcolor);
+ for (i=0; i<numb; i++)
+ fl_draw(entries[i].str,
+ x+i*bwidth+bwidth/2,zeroh,0,0,
+ FL_ALIGN_TOP);
+}
+
+static void draw_horbarchart(int x,int y,int w,int h,
+ int numb, FL_CHART_ENTRY entries[],
+ double min, double max, int autosize, int maxnumb,
+ Fl_Color textcolor)
+/* Draws a horizontal bar chart. x,y,w,h is the bounding box, entries the
+ array of numb entries and min and max the boundaries. */
+{
+ int i;
+ double lw = 0.0; /* Maximal label width */
+ /* Compute maximal label width */
+ for (i=0; i<numb; i++) {
+ double w1 = fl_width(entries[i].str);
+ if (w1 > lw) lw = w1;
+ }
+ if (lw > 0.0) lw += 4.0;
+ double incr = w/(max-min);
+ int zeroh;
+ if ( -min*incr < lw) {
+ incr = (w - lw + min*incr)/(max-min);
+ zeroh = x+int(lw+.5);
+ } else {
+ zeroh = int(x-min * incr + .5);
+ }
+ int bwidth = int(h/double(autosize?numb:maxnumb)+.5);
+ /* Draw base line */
+ fl_color(textcolor);
+ fl_line(zeroh, y, zeroh, y+h);
+ if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */
+ /* Draw the bars */
+ for (i=0; i<numb; i++) {
+ int w = int(entries[i].val*incr+.5);
+ if (w > 0)
+ fl_rectbound(zeroh,y+i*bwidth,w+1,bwidth+1, (Fl_Color)entries[i].col);
+ else if (w < 0)
+ fl_rectbound(zeroh+w,y+i*bwidth,-w+1,bwidth+1,(Fl_Color)entries[i].col);
+ }
+ /* Draw the labels */
+ for (i=0; i<numb; i++)
+ fl_draw(entries[i].str,
+ zeroh-2,y+i*bwidth+bwidth/2,0,0,
+ FL_ALIGN_RIGHT);
+}
+
+static void draw_linechart(int type, int x,int y,int w,int h,
+ int numb, FL_CHART_ENTRY entries[],
+ double min, double max, int autosize, int maxnumb,
+ Fl_Color textcolor)
+/* Draws a line chart. x,y,w,h is the bounding box, entries the array of
+ numb entries and min and max the boundaries. */
+{
+ int i;
+ double lh = fl_height();
+ double incr = (h-2.0*lh)/ (max-min);
+ int zeroh = int(y+h-lh+min * incr + .5);
+ double bwidth = w/double(autosize?numb:maxnumb);
+ /* Draw the values */
+ for (i=0; i<numb; i++) {
+ int x0 = x + int((i-.5)*bwidth+.5);
+ int x1 = x + int((i+.5)*bwidth+.5);
+ int y0 = i ? zeroh - int(entries[i-1].val*incr+.5) : 0;
+ int y1 = zeroh - int(entries[i].val*incr+.5);
+ if (type == FL_SPIKE_CHART) {
+ fl_color((Fl_Color)entries[i].col);
+ fl_line(x1, zeroh, x1, y1);
+ } else if (type == FL_LINE_CHART && i != 0) {
+ fl_color((Fl_Color)entries[i-1].col);
+ fl_line(x0,y0,x1,y1);
+ } else if (type == FL_FILLED_CHART && i != 0) {
+ fl_color((Fl_Color)entries[i-1].col);
+ if ((entries[i-1].val>0.0)!=(entries[i].val>0.0)) {
+ double ttt = entries[i-1].val/(entries[i-1].val-entries[i].val);
+ int xt = x + int((i-.5+ttt)*bwidth+.5);
+ fl_polygon(x0,zeroh, x0,y0, xt,zeroh);
+ fl_polygon(xt,zeroh, x1,y1, x1,zeroh);
+ } else {
+ fl_polygon(x0,zeroh, x0,y0, x1,y1, x1,zeroh);
+ }
+ fl_color(textcolor);
+ fl_line(x0,y0,x1,y1);
+ }
+ }
+ /* Draw base line */
+ fl_color(textcolor);
+ fl_line(x,zeroh,x+w,zeroh);
+ /* Draw the labels */
+ for (i=0; i<numb; i++)
+ fl_draw(entries[i].str,
+ x+int((i+.5)*bwidth+.5), zeroh - int(entries[i].val*incr+.5),0,0,
+ entries[i].val>=0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP);
+}
+
+static void draw_piechart(int x,int y,int w,int h,
+ int numb, FL_CHART_ENTRY entries[], int special,
+ Fl_Color textcolor)
+/* Draws a pie chart. x,y,w,h is the bounding box, entries the array of
+ numb entries */
+{
+ int i;
+ double xc,yc,rad; /* center and radius */
+ double tot; /* sum of values */
+ double incr; /* increment in angle */
+ double curang; /* current angle we are drawing */
+ double txc,tyc; /* temporary center */
+ double lh = fl_height();
+ /* compute center and radius */
+ xc = x+w/2.0; yc = y+h/2.0;
+ rad = h/2.0 - lh;
+ if (special) { yc += 0.1*rad; rad = 0.9*rad;}
+ /* compute sum of values */
+ tot = 0.0;
+ for (i=0; i<numb; i++)
+ if (entries[i].val > 0.0) tot += entries[i].val;
+ if (tot == 0.0) return;
+ incr = 360.0/tot;
+ /* Draw the pie */
+ curang = 0.0;
+ for (i=0; i<numb; i++)
+ if (entries[i].val > 0.0)
+ {
+ txc = xc; tyc = yc;
+ /* Correct for special pies */
+ if (special && i==0)
+ {
+ txc += 0.3*rad*cos(ARCINC*(curang+0.5*incr*entries[i].val));
+ tyc -= 0.3*rad*sin(ARCINC*(curang+0.5*incr*entries[i].val));
+ }
+ fl_color((Fl_Color)entries[i].col);
+ fl_begin_polygon(); fl_vertex(txc,tyc);
+ fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val);
+ fl_end_polygon();
+ fl_color(textcolor);
+ fl_begin_loop(); fl_vertex(txc,tyc);
+ fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val);
+ fl_end_loop();
+ curang += 0.5 * incr * entries[i].val;
+ /* draw the label */
+ double xl = txc + 1.1*rad*cos(ARCINC*curang);
+ fl_draw(entries[i].str,
+ int(xl+.5),
+ int(tyc - 1.1*rad*sin(ARCINC*curang)+.5),
+ 0, 0,
+ xl<txc ? FL_ALIGN_RIGHT : FL_ALIGN_LEFT);
+ curang += 0.5 * incr * entries[i].val;
+ }
+}
+
+void Fl_Chart::draw() {
+ int xx,yy,ww,hh;
+ int i;
+
+ xx = x()+9;
+ yy = y()+9;
+ ww = w()-2*9;
+ hh = h()-2*9;
+
+ if (min >= max) {
+ min = max = 0.0;
+ for (i=0; i<numb; i++) {
+ if (entries[i].val < min) min = entries[i].val;
+ if (entries[i].val > max) max = entries[i].val;
+ }
+ }
+
+ draw_box();
+ fl_font(textfont(),textsize());
+
+ switch (type()) {
+ case FL_BAR_CHART:
+ draw_barchart(xx,yy,ww,hh, numb, entries, min, max,
+ autosize(), maxnumb, textcolor());
+ break;
+ case FL_HORBAR_CHART:
+ draw_horbarchart(xx,yy,ww,hh, numb, entries, min, max,
+ autosize(), maxnumb, textcolor());
+ break;
+ case FL_PIE_CHART:
+ draw_piechart(xx,yy,ww,hh,numb,entries,0, textcolor());
+ break;
+ case FL_SPECIALPIE_CHART:
+ draw_piechart(xx,yy,ww,hh,numb,entries,1,textcolor());
+ break;
+ default:
+ draw_linechart(type(),xx,yy,ww,hh, numb, entries, min, max,
+ autosize(), maxnumb, textcolor());
+ break;
+ }
+ draw_label();
+}
+
+/*------------------------------*/
+
+#define FL_CHART_BOXTYPE FL_BORDER_BOX
+#define FL_CHART_COL1 FL_COL1
+#define FL_CHART_LCOL FL_LCOL
+#define FL_CHART_ALIGN FL_ALIGN_BOTTOM
+
+Fl_Chart::Fl_Chart(int x,int y,int w,int h,const char *l) :
+Fl_Widget(x,y,w,h,l) {
+ box(FL_BORDER_BOX);
+ align(FL_ALIGN_BOTTOM);
+ numb = 0;
+ maxnumb = FL_CHART_MAX;
+ autosize_ = 1;
+ min = max = 0;
+ textfont_ = FL_HELVETICA;
+ textsize_ = 10;
+ textcolor_ = FL_BLACK;
+}
+
+void Fl_Chart::clear() {
+ numb = 0;
+ redraw();
+}
+
+void Fl_Chart::add(double val, const char *str, uchar col) {
+ int i;
+ /* Shift entries if required */
+ if (numb >= maxnumb) {
+ for (i=0; i<numb-1; i++) entries[i] = entries[i+1];
+ numb--;
+ }
+ entries[numb].val = float(val);
+ entries[numb].col = col;
+ if (str) {
+ strncpy(entries[numb].str,str,FL_CHART_LABEL_MAX+1);
+ entries[numb].str[FL_CHART_LABEL_MAX] = 0;
+ } else {
+ entries[numb].str[0] = 0;
+ }
+ numb++;
+ redraw();
+}
+
+void Fl_Chart::insert(int index, double val, const char *str, uchar col) {
+ int i;
+ if (index < 1 || index > numb+1) return;
+ /* Shift entries */
+ for (i=numb; i >= index; i--) entries[i] = entries[i-1];
+ if (numb < maxnumb) numb++;
+ /* Fill in the new entry */
+ entries[index-1].val = float(val);
+ entries[index-1].col = col;
+ if (str) {
+ strncpy(entries[index-1].str,str,FL_CHART_LABEL_MAX+1);
+ entries[index-1].str[FL_CHART_LABEL_MAX] = 0;
+ } else {
+ entries[index-1].str[0] = 0;
+ }
+ redraw();
+}
+
+void Fl_Chart::replace(int index,double val, const char *str, uchar col) {
+ if (index < 1 || index > numb) return;
+ entries[index-1].val = float(val);
+ entries[index-1].col = col;
+ if (str) {
+ strncpy(entries[index-1].str,str,FL_CHART_LABEL_MAX+1);
+ entries[index-1].str[FL_CHART_LABEL_MAX] = 0;
+ } else {
+ entries[index-1].str[0] = 0;
+ }
+ redraw();
+}
+
+void Fl_Chart::bounds(double min, double max) {
+ this->min = min;
+ this->max = max;
+ redraw();
+}
+
+void Fl_Chart::maxsize(int m) {
+ int i;
+ /* Fill in the new number */
+ if (m < 0) return;
+ if (m > FL_CHART_MAX)
+ maxnumb = FL_CHART_MAX;
+ else
+ maxnumb = m;
+ /* Shift entries if required */
+ if (numb > maxnumb) {
+ for (i = 0; i<maxnumb; i++)
+ entries[i] = entries[i+numb-maxnumb];
+ numb = maxnumb;
+ redraw();
+ }
+}
diff --git a/src/Fl_Check_Button.cxx b/src/Fl_Check_Button.cxx
new file mode 100644
index 000000000..6c123861b
--- /dev/null
+++ b/src/Fl_Check_Button.cxx
@@ -0,0 +1,15 @@
+// Fl_Check_Button.C
+
+// A subclass of Fl_Button that always draws as a diamond box. This
+// diamond is smaller than the widget size and can be surchecked by
+// another box type, for compatability with Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Check_Button.H>
+
+Fl_Check_Button::Fl_Check_Button(int x, int y, int w, int h, const char *l)
+: Fl_Light_Button(x, y, w, h, l) {
+ box(FL_NO_BOX);
+ down_box(FL_DIAMOND_DOWN_BOX);
+ selection_color(FL_RED);
+}
diff --git a/src/Fl_Choice.cxx b/src/Fl_Choice.cxx
new file mode 100644
index 000000000..de41d4ffc
--- /dev/null
+++ b/src/Fl_Choice.cxx
@@ -0,0 +1,63 @@
+// Fl_Choice.C
+
+// Emulates the Forms choice widget. This is almost exactly the same
+// as an Fl_Menu_Button. The only difference is the appearance of the
+// button: it draws the text of the current pick and a down-arrow.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Choice.H>
+#include <FL/fl_draw.H>
+
+extern char fl_draw_shortcut;
+
+void Fl_Choice::draw() {
+ draw_box();
+ if (box() == FL_FLAT_BOX) return; // for XForms compatability
+ int H = labelsize()/2+1;
+ draw_box(FL_THIN_UP_BOX,x()+w()-3*H,y()+(h()-H)/2,2*H,H,color());
+ fl_font(textfont(),textsize(),default_font(),default_size());
+ fl_color(active_r() ? textcolor() : inactive(textcolor()));
+ fl_draw_shortcut = 2; // hack value to make '&' disappear
+ fl_draw(text(),x()+6,y(),w()-6,h(),FL_ALIGN_LEFT);
+ fl_draw_shortcut = 0;
+ draw_label();
+}
+
+Fl_Choice::Fl_Choice(int x,int y,int w,int h, const char *l)
+: Fl_Menu_(x,y,w,h,l) {
+ align(FL_ALIGN_LEFT);
+ when(FL_WHEN_RELEASE);
+ textfont(FL_HELVETICA);
+ down_box(FL_NO_BOX);
+}
+
+int Fl_Choice::value(int v) {
+ if (!Fl_Menu_::value(v)) return 0;
+ redraw();
+ return 1;
+}
+
+int Fl_Choice::handle(int e) {
+ if (!menu() || !menu()->text) return 0;
+ const Fl_Menu_Item* v;
+ switch (e) {
+ case FL_PUSH:
+ J1:
+ v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this);
+ if (!v || v->submenu()) return 1;
+ if (v != mvalue()) redraw();
+ picked(v);
+ return 1;
+ case FL_SHORTCUT:
+ if (Fl_Widget::test_shortcut()) goto J1;
+ v = menu()->test_shortcut();
+ if (!v) return 0;
+ if (v != mvalue()) redraw();
+ picked(v);
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+// end of Fl_Choice.C
diff --git a/src/Fl_Clock.cxx b/src/Fl_Clock.cxx
new file mode 100644
index 000000000..852dcb476
--- /dev/null
+++ b/src/Fl_Clock.cxx
@@ -0,0 +1,136 @@
+// Fl_Clock.C
+
+// There really should be a way to make this display something other
+// than the current time...
+
+// Original clock display written by Paul Haeberli at SGI.
+// Modifications by Mark Overmars for Forms
+// Further changes by Bill Spitzak for fltk
+
+#include <FL/Fl.H>
+#include <FL/Fl_Clock.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+#include <time.h>
+
+const float hourhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -7.0f}};
+const float minhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -11.5f}};
+const float sechand[4][2] = {{-0.1f, 0}, {0, 2.0f}, {0.1f, 0}, {0, -11.5f}};
+
+static void drawhand(double ang,const float v[][2],Fl_Color fill,Fl_Color line)
+{
+ fl_push_matrix();
+ fl_rotate(ang);
+ fl_color(fill); fl_begin_polygon();
+ int i; for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_polygon();
+ fl_color(line); fl_begin_loop();
+ for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_loop();
+ fl_pop_matrix();
+}
+
+void Fl_Clock::drawhands(Fl_Color fill, Fl_Color line) {
+ drawhand(-360*(hour()+minute()/60.0)/12, hourhand, fill, line);
+ drawhand(-360*(minute()+second()/60.0)/60, minhand, fill, line);
+ drawhand(-360*(second()/60.0), sechand, fill, line);
+}
+
+static void rect(double x, double y, double w, double h) {
+ double r = x+w;
+ double t = y+h;
+ fl_begin_polygon();
+ fl_vertex(x, y);
+ fl_vertex(r, y);
+ fl_vertex(r, t);
+ fl_vertex(x, t);
+ fl_end_polygon();
+}
+
+void Fl_Clock::draw(int x, int y, int w, int h) {
+ draw_box(box(), x, y, w, h, type()==FL_ROUND_CLOCK ? FL_GRAY : color());
+ fl_push_matrix();
+ fl_translate(x+w/2.0-.5, y+h/2.0-.5);
+ fl_scale((w-1)/28.0, (h-1)/28.0);
+ if (type() == FL_ROUND_CLOCK) {
+ fl_color(color());
+ fl_begin_polygon(); fl_circle(0,0,14); fl_end_polygon();
+ fl_color(FL_BLACK);
+ fl_begin_loop(); fl_circle(0,0,14); fl_end_loop();
+ }
+ // draw the shadows:
+ fl_push_matrix();
+ fl_translate(0.60, 0.60);
+ drawhands(FL_DARK3, FL_DARK3);
+ fl_pop_matrix();
+ // draw the tick marks:
+ fl_push_matrix();
+ fl_color(FL_BLACK); // color was 52
+ for (int i=0; i<12; i++) {
+ if (i==6) rect(-0.5, 9, 1, 2);
+ else if (i==3 || i==0 || i== 9) rect(-0.5, 9.5, 1, 1);
+ else rect(-0.25, 9.5, .5, 1);
+ fl_rotate(-30);
+ }
+ fl_pop_matrix();
+ // draw the hands:
+ drawhands(selection_color(), FL_GRAY0); // color was 54
+ fl_pop_matrix();
+}
+
+void Fl_Clock::draw() {
+ draw(x(), y(), w(), h());
+ draw_label();
+}
+
+void Fl_Clock::value(int h, int m, int s) {
+ if (h!=hour_ || m!=minute_ || s!=second_) {
+ hour_ = h; minute_ = m; second_ = s;
+ redraw();
+ }
+}
+
+void Fl_Clock::value(ulong v) {
+ struct tm *timeofday;
+ timeofday = localtime((const time_t *)&v);
+ value(timeofday->tm_hour, timeofday->tm_min, timeofday->tm_sec);
+}
+
+static void tick(void *v) {
+ ((Fl_Clock*)v)->value(time(0));
+ Fl::add_timeout(1, tick, v);
+}
+
+void Fl_Clock::_Fl_Clock() {
+ selection_color(fl_gray_ramp(5));
+ align(FL_ALIGN_BOTTOM);
+ value(time(0));
+ //Fl::add_timeout(1, tick, this);
+}
+
+Fl_Clock::Fl_Clock(int x, int y, int w, int h, const char *l)
+: Fl_Widget(x, y, w, h, l) {
+ box(FL_UP_BOX);
+ _Fl_Clock();
+}
+
+Fl_Clock::Fl_Clock(uchar t, int x, int y, int w, int h, const char *l)
+: Fl_Widget(x, y, w, h, l) {
+ type(t);
+ box(t==FL_ROUND_CLOCK ? FL_NO_BOX : FL_UP_BOX);
+ _Fl_Clock();
+}
+
+Fl_Clock::~Fl_Clock() {
+ Fl::remove_timeout(tick, this);
+}
+
+int Fl_Clock::handle(int event) {
+ switch (event) {
+ case FL_HIDE:
+ Fl::remove_timeout(tick, this);
+ break;
+ case FL_SHOW:
+ Fl::remove_timeout(tick, this);
+ tick(this);
+ }
+ return 0;
+}
diff --git a/src/Fl_Color_Chooser.cxx b/src/Fl_Color_Chooser.cxx
new file mode 100644
index 000000000..e0e2d926a
--- /dev/null
+++ b/src/Fl_Color_Chooser.cxx
@@ -0,0 +1,397 @@
+// Fl_Color_Chooser.C
+
+// Besides being a useful object on it's own, the Fl_Color_Chooser was
+// an attempt to make a complex composite object that could be easily
+// imbedded into a user interface. If you wish to make complex objects
+// of your own, be sure to read this code.
+
+// The function fl_color_chooser() creates a window containing a color
+// chooser and a few buttons and current-color indicators. It is an
+// easier interface for simple programs that just need a color.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Color_Chooser.H>
+#include <FL/fl_draw.H>
+#include <FL/math.h>
+#include <stdio.h>
+
+// The "hue box" can be a circle or rectilinear.
+// You get a circle by defining this:
+// #define CIRCLE 1
+// And the "hue box" can auto-update when the value changes
+// you get this by defining this:
+#define UPDATE_HUE_BOX 1
+
+void Fl_Color_Chooser::hsv2rgb(
+ double H, double S, double V, double& r, double& g, double& b) {
+ if (S < 5.0e-6) {
+ r = g = b = V;
+ } else {
+ int i = (int)H;
+ double f = H - (float)i;
+ double p1 = V*(1.0-S);
+ double p2 = V*(1.0-S*f);
+ double p3 = V*(1.0-S*(1.0-f));
+ switch (i) {
+ case 0: r = V; g = p3; b = p1; break;
+ case 1: r = p2; g = V; b = p1; break;
+ case 2: r = p1; g = V; b = p3; break;
+ case 3: r = p1; g = p2; b = V; break;
+ case 4: r = p3; g = p1; b = V; break;
+ case 5: r = V; g = p1; b = p2; break;
+ }
+ }
+}
+
+void Fl_Color_Chooser::rgb2hsv(
+ double r, double g, double b, double& H, double& S, double& V) {
+ double maxv = r > g ? r : g; if (b > maxv) maxv = b;
+ V = maxv;
+ if (maxv>0) {
+ double minv = r < g ? r : g; if (b < minv) minv = b;
+ S = 1.0 - double(minv)/maxv;
+ if (maxv > minv) {
+ if (maxv == r) {H = (g-b)/double(maxv-minv); if (H<0) H += 6.0;}
+ else if (maxv == g) H = 2.0+(b-r)/double(maxv-minv);
+ else H = 4.0+(r-g)/double(maxv-minv);
+ }
+ }
+}
+
+enum {M_RGB, M_BYTE, M_HEX, M_HSV}; // modes
+static Fl_Menu_Item mode_menu[] = {
+ {"rgb"},
+ {"byte"},
+ {"hex"},
+ {"hsv"},
+ {0}
+};
+
+int Flcc_Value_Input::format(char* buf) {
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+ if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value()));
+ else return Fl_Valuator::format(buf);
+}
+
+void Fl_Color_Chooser::set_valuators() {
+ switch (mode()) {
+ case M_RGB:
+ rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_);
+ gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_);
+ bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_);
+ break;
+ case M_BYTE:
+ case M_HEX:
+ rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5));
+ gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5));
+ bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5));
+ break;
+ case M_HSV:
+ rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_);
+ gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_);
+ bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_);
+ break;
+ }
+}
+
+int Fl_Color_Chooser::rgb(double r, double g, double b) {
+ if (r == r_ && g == g_ && b == b_) return 0;
+ r_ = r; g_ = g; b_ = b;
+ double ph = hue_;
+ double ps = saturation_;
+ double pv = value_;
+ rgb2hsv(r,g,b,hue_,saturation_,value_);
+ set_valuators();
+ if (value_ != pv) {
+#ifdef UPDATE_HUE_BOX
+ huebox.damage(6);
+#endif
+ valuebox.damage(2);}
+ if (hue_ != ph || saturation_ != ps) {huebox.damage(2); valuebox.damage(6);}
+ return 1;
+}
+
+int Fl_Color_Chooser::hsv(double h, double s, double v) {
+ h = fmod(h,6.0); if (h < 0.0) h += 6.0;
+ if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0;
+ if (v < 0.0) v = 0.0; else if (v > 1.0) v = 1.0;
+ if (h == hue_ && s == saturation_ && v == value_) return 0;
+ double ph = hue_;
+ double ps = saturation_;
+ double pv = value_;
+ hue_ = h; saturation_ = s; value_ = v;
+ if (value_ != pv) {
+#ifdef UPDATE_HUE_BOX
+ huebox.damage(6);
+#endif
+ valuebox.damage(2);}
+ if (hue_ != ph || saturation_ != ps) {huebox.damage(2); valuebox.damage(6);}
+ hsv2rgb(h,s,v,r_,g_,b_);
+ set_valuators();
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+static void tohs(double x, double y, double& h, double& s) {
+#ifdef CIRCLE
+ x = 2*x-1;
+ y = 1-2*y;
+ s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0;
+ h = (3.0/M_PI)*atan2(y,x);
+ if (h<0) h += 6.0;
+#else
+ h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0;
+ s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0;
+#endif
+}
+
+int Flcc_HueBox::handle(int e) {
+ static double ih, is;
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+ switch (e) {
+ case FL_PUSH:
+ ih = c->hue();
+ is = c->saturation();
+ case FL_DRAG: {
+ double Xf, Yf, H, S;
+ Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box()));
+ Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
+ tohs(Xf, Yf, H, S);
+ if (fabs(H-ih) < 3*6.0/w()) H = ih;
+ if (fabs(S-is) < 3*1.0/h()) S = is;
+ if (Fl::event_state(FL_CTRL)) H = ih;
+ if (c->hsv(H, S, c->value())) c->do_callback();
+ } return 1;
+ default:
+ return 0;
+ }
+}
+
+static void generate_image(void* vv, int X, int Y, int W, uchar* buf) {
+ Flcc_HueBox* v = (Flcc_HueBox*)vv;
+ int iw = v->w()-Fl::box_dw(v->box());
+ double Yf = double(Y)/(v->h()-Fl::box_dh(v->box()));
+#ifdef UPDATE_HUE_BOX
+ const double V = ((Fl_Color_Chooser*)(v->parent()))->value();
+#else
+ const double V = 1.0;
+#endif
+ for (int x = X; x < X+W; x++) {
+ double Xf = double(x)/iw;
+ double H,S; tohs(Xf,Yf,H,S);
+ double r,g,b;
+ Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b);
+ *buf++ = uchar(255*r+.5);
+ *buf++ = uchar(255*g+.5);
+ *buf++ = uchar(255*b+.5);
+ }
+}
+
+void Flcc_HueBox::draw() {
+ if (damage()&128) draw_box();
+ int x1 = x()+Fl::box_dx(box());
+ int y1 = y()+Fl::box_dy(box());
+ int w1 = w()-Fl::box_dw(box());
+ int h1 = h()-Fl::box_dh(box());
+ if (damage() == 2) fl_clip(x1+px,y1+py,6,6);
+ fl_draw_image(generate_image, this, x1, y1, w1, h1);
+ if (damage() == 2) fl_pop_clip();
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+#ifdef CIRCLE
+ int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6));
+ int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6));
+#else
+ int X = int(c->hue()/6.0*(w1-6));
+ int Y = int((1-c->saturation())*(h1-6));
+#endif
+ if (X < 0) X = 0; else if (X > w1-6) X = w1-6;
+ if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
+ // fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE);
+ draw_box(FL_UP_BOX,x1+X,y1+Y,6,6,FL_GRAY);
+ px = X; py = Y;
+}
+
+////////////////////////////////////////////////////////////////
+
+int Flcc_ValueBox::handle(int e) {
+ static double iv;
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+ switch (e) {
+ case FL_PUSH:
+ iv = c->value();
+ case FL_DRAG: {
+ double Yf;
+ Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
+ if (fabs(Yf-iv)<3*1.0/h()) Yf = iv;
+ if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback();
+ } return 1;
+ default:
+ return 0;
+ }
+}
+
+static double tr, tg, tb;
+static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) {
+ Flcc_ValueBox* v = (Flcc_ValueBox*)vv;
+ double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box())));
+ uchar r = uchar(tr*Yf+.5);
+ uchar g = uchar(tg*Yf+.5);
+ uchar b = uchar(tb*Yf+.5);
+ for (int x = X; x < X+W; x++) {
+ *buf++ = r; *buf++ = g; *buf++ = b;
+ }
+}
+
+void Flcc_ValueBox::draw() {
+ if (damage()&128) draw_box();
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
+ c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb);
+ int x1 = x()+Fl::box_dx(box());
+ int y1 = y()+Fl::box_dy(box());
+ int w1 = w()-Fl::box_dw(box());
+ int h1 = h()-Fl::box_dh(box());
+ if (damage() == 2) fl_clip(x1,y1+py,w1,6);
+ fl_draw_image(generate_vimage, this, x1, y1, w1, h1);
+ if (damage() == 2) fl_pop_clip();
+ int Y = int((1-c->value()) * (h1-6));
+ if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
+ draw_box(FL_UP_BOX,x1,y1+Y,w1,6,FL_GRAY);
+ py = Y;
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) {
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
+ double r = c->rvalue.value();
+ double g = c->gvalue.value();
+ double b = c->bvalue.value();
+ if (c->mode() == M_HSV) {
+ if (c->hsv(r,g,b)) c->do_callback();
+ return;
+ }
+ if (c->mode() != M_RGB) {
+ r = r/255;
+ g = g/255;
+ b = b/255;
+ }
+ if (c->rgb(r,g,b)) c->do_callback();
+}
+
+void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) {
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
+ c->set_valuators();
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L)
+ : Fl_Group(0,0,180,100,L),
+ huebox(0,0,100,100),
+ valuebox(100,0,20,100),
+ choice(120,0,60,20),
+ rvalue(120,20,60,25),
+ gvalue(120,45,60,25),
+ bvalue(120,70,60,25),
+ resize_box(0,95,100,5)
+{
+ end();
+ resizable(resize_box);
+ resize(X,Y,W,H);
+ r_ = g_ = b_ = 0;
+ hue_ = 0.0;
+ saturation_ = 0.0;
+ value_ = 0.0;
+ huebox.box(FL_DOWN_FRAME);
+ valuebox.box(FL_DOWN_FRAME);
+ choice.menu(mode_menu);
+ set_valuators();
+ rvalue.callback(rgb_cb);
+ gvalue.callback(rgb_cb);
+ bvalue.callback(rgb_cb);
+ choice.callback(mode_cb);
+ choice.box(FL_THIN_UP_BOX);
+ choice.textfont(FL_HELVETICA_BOLD_ITALIC);
+}
+
+////////////////////////////////////////////////////////////////
+// fl_color_chooser():
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Return_Button.H>
+
+class ColorChip : public Fl_Widget {
+ void draw();
+public:
+ uchar r,g,b;
+ ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
+ box(FL_ENGRAVED_FRAME);}
+};
+
+void ColorChip::draw() {
+ if (damage()&128) draw_box();
+ fl_rectf(x()+Fl::box_dx(box()),
+ y()+Fl::box_dy(box()),
+ w()-Fl::box_dw(box()),
+ h()-Fl::box_dh(box()),r,g,b);
+}
+
+static void chooser_cb(Fl_Object* o, void* vv) {
+ Fl_Color_Chooser* c = (Fl_Color_Chooser*)o;
+ ColorChip* v = (ColorChip*)vv;
+ v->r = uchar(255*c->r()+.5);
+ v->g = uchar(255*c->g()+.5);
+ v->b = uchar(255*c->b()+.5);
+ v->damage(2);
+}
+
+extern const char* fl_ok;
+extern const char* fl_cancel;
+
+int fl_color_chooser(const char* name, double& r, double& g, double& b) {
+ Fl_Window window(210,165,name);
+ Fl_Color_Chooser chooser(5, 5, 200, 95);
+ ColorChip ok_color(5, 105, 95, 30);
+ Fl_Return_Button ok_button(5, 135, 95, 25, fl_ok);
+ ColorChip cancel_color(110, 105, 95, 30);
+ cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r;
+ ok_color.g = cancel_color.g = uchar(255*g+.5);
+ ok_color.b = cancel_color.b = uchar(255*b+.5);
+ Fl_Button cancel_button(110, 135, 95, 25, fl_cancel);
+ window.resizable(chooser);
+ chooser.rgb(r,g,b);
+ chooser.callback(chooser_cb, &ok_color);
+ window.end();
+ window.set_modal();
+ window.hotspot(window);
+ window.show();
+ while (window.shown()) {
+ Fl::wait();
+ Fl_Widget* o;
+ while ((o = Fl::readqueue())) {
+ if (o == &ok_button) {
+ r = chooser.r();
+ g = chooser.g();
+ b = chooser.b();
+ return 1;
+ }
+ if (o == &window || o == &cancel_button) return 0;
+ }
+ }
+ return 0;
+}
+
+int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b) {
+ double dr = r/255.0;
+ double dg = g/255.0;
+ double db = b/255.0;
+ if (fl_color_chooser(name,dr,dg,db)) {
+ r = uchar(255*dr+.5);
+ g = uchar(255*dg+.5);
+ b = uchar(255*db+.5);
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/Fl_Counter.cxx b/src/Fl_Counter.cxx
new file mode 100644
index 000000000..6064f99b6
--- /dev/null
+++ b/src/Fl_Counter.cxx
@@ -0,0 +1,140 @@
+// Fl_Counter.H
+
+// A numerical value with up/down step buttons. From Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Counter.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Input.H> // for default_font
+
+void Fl_Counter::draw() {
+ int i; Fl_Boxtype boxtype[5];
+
+ boxtype[0] = box();
+ if (boxtype[0] == FL_UP_BOX) boxtype[0] = Fl_Input::default_box();
+ for (i=1; i<5; i++)
+ if (mouseobj == i)
+ boxtype[i] = down(box());
+ else
+ boxtype[i] = box();
+
+ int xx[5], ww[5];
+ if (type() == FL_NORMAL_COUNTER) {
+ int W = w()*15/100;
+ xx[1] = x(); ww[1] = W;
+ xx[2] = x()+1*W; ww[2] = W;
+ xx[0] = x()+2*W; ww[0] = w()-4*W;
+ xx[3] = x()+w()-2*W; ww[3] = W;
+ xx[4] = x()+w()-1*W; ww[4] = W;
+ } else {
+ int W = w()*20/100;
+ xx[2] = x(); ww[2] = W;
+ xx[0] = x()+W; ww[0] = w()-2*W;
+ xx[3] = x()+w()-1*W; ww[3] = W;
+ }
+
+ draw_box(boxtype[0], xx[0], y(), ww[0], h(), FL_WHITE);
+ fl_font(textfont(), textsize(),
+ Fl_Input::default_font(), Fl_Input::default_size());
+ fl_color(active_r() ? textcolor() : inactive(textcolor()));
+ char str[128]; format(str);
+ fl_draw(str, xx[0], y(), ww[0], h(), FL_ALIGN_CENTER);
+ if (!(damage()&128)) return; // only need to redraw text
+
+ if (type() == FL_NORMAL_COUNTER) {
+ draw_box(boxtype[1], xx[1], y(), ww[1], h(), color());
+ fl_draw_symbol("@-4<<", xx[1], y(), ww[1], h(), selection_color());
+ }
+ draw_box(boxtype[2], xx[2], y(), ww[2], h(), color());
+ fl_draw_symbol("@-4<", xx[2], y(), ww[2], h(), selection_color());
+ draw_box(boxtype[3], xx[3], y(), ww[3], h(), color());
+ fl_draw_symbol("@-4>", xx[3], y(), ww[3], h(), selection_color());
+ if (type() == FL_NORMAL_COUNTER) {
+ draw_box(boxtype[4], xx[4], y(), ww[4], h(), color());
+ fl_draw_symbol("@-4>>", xx[4], y(), ww[4], h(), selection_color());
+ }
+}
+
+void Fl_Counter::increment_cb() {
+ if (!mouseobj) return;
+ double v = value();
+ switch (mouseobj) {
+ case 1: v -= lstep_; break;
+ case 2: v = increment(v, -1); break;
+ case 3: v = increment(v, 1); break;
+ case 4: v += lstep_; break;
+ }
+ handle_drag(clamp(round(v)));
+}
+
+#define INITIALREPEAT .5
+#define REPEAT .1
+
+void Fl_Counter::repeat_callback(void* v) {
+ Fl_Counter* b = (Fl_Counter*)v;
+ if (b->mouseobj) {
+ Fl::add_timeout(REPEAT, repeat_callback, b);
+ b->increment_cb();
+ }
+}
+
+int Fl_Counter::calc_mouseobj() {
+ if (type() == FL_NORMAL_COUNTER) {
+ int W = w()*15/100;
+ if (Fl::event_inside(x(), y(), W, h())) return 1;
+ if (Fl::event_inside(x()+W, y(), W, h())) return 2;
+ if (Fl::event_inside(x()+w()-2*W, y(), W, h())) return 3;
+ if (Fl::event_inside(x()+w()-W, y(), W, h())) return 4;
+ } else {
+ int W = w()*20/100;
+ if (Fl::event_inside(x(), y(), W, h())) return 2;
+ if (Fl::event_inside(x()+w()-W, y(), W, h())) return 3;
+ }
+ return -1;
+}
+
+int Fl_Counter::handle(int event) {
+ int i;
+ switch (event) {
+ case FL_RELEASE:
+ if (mouseobj) {
+ Fl::remove_timeout(repeat_callback, this);
+ mouseobj = 0;
+ redraw();
+ }
+ handle_release();
+ return 1;
+ case FL_PUSH:
+ handle_push();
+ case FL_DRAG:
+ i = calc_mouseobj();
+ if (i != mouseobj) {
+ Fl::remove_timeout(repeat_callback, this);
+ mouseobj = i;
+ if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this);
+ increment_cb();
+ redraw();
+ }
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+Fl_Counter::~Fl_Counter() {
+ Fl::remove_timeout(repeat_callback, this);
+}
+
+Fl_Counter::Fl_Counter(int x, int y, int w, int h, const char* l)
+ : Fl_Valuator(x, y, w, h, l) {
+ box(FL_UP_BOX);
+ selection_color(FL_INACTIVE_COLOR); // was FL_BLUE
+ align(FL_ALIGN_BOTTOM);
+ bounds(-1000000.0, 1000000.0);
+ Fl_Valuator::step(1, 10);
+ lstep_ = 1.0;
+ mouseobj = 0;
+ textfont_ = FL_HELVETICA;
+ textsize_ = FL_NORMAL_SIZE;
+ textcolor_ = FL_BLACK;
+}
diff --git a/src/Fl_Dial.cxx b/src/Fl_Dial.cxx
new file mode 100644
index 000000000..66b207180
--- /dev/null
+++ b/src/Fl_Dial.cxx
@@ -0,0 +1,113 @@
+// Fl_Dial.C
+
+// A circular dial control, like xv uses. From Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Dial.H>
+#include <FL/fl_draw.H>
+#include <stdlib.h>
+#include <FL/math.h>
+
+void Fl_Dial::draw(int x, int y, int w, int h) {
+ if (damage()&128) draw_box(box(), x, y, w, h, color());
+ x += Fl::box_dx(box());
+ y += Fl::box_dy(box());
+ w -= Fl::box_dw(box());
+ h -= Fl::box_dh(box());
+ double angle = 270.0*(value()-minimum())/(maximum()-minimum());
+ if (type() == FL_FILL_DIAL) {
+ double a = angle; if (a < 0) a = 0;
+ // foo: draw this nicely in certain round box types
+ int foo = (box() > _FL_ROUND_UP_BOX && Fl::box_dx(box()));
+ if (foo) {x--; y--; w+=2; h+=2;}
+ fl_color(color());
+ fl_pie(x, y, w-1, h-1, 225, 225+360-a);
+ fl_color(selection_color());
+ fl_pie(x, y, w-1, h-1, 225-a, 225);
+ if (foo) {
+ fl_color(FL_BLACK);
+ fl_arc(x, y, w, h, 0, 360);
+ }
+ return;
+ }
+ if (!(damage()&128)) {
+ fl_color(color());
+ fl_pie(x+1, y+1, w-2, h-2, 0, 360);
+ }
+ fl_push_matrix();
+ fl_translate(x+w/2-.5, y+h/2-.5);
+ fl_scale(w-1, h-1);
+ if (type() == FL_FILL_DIAL) {
+ fl_rotate(225);
+ fl_begin_line(); fl_vertex(0, 0); fl_vertex(.5, 0); fl_end_line();
+ }
+ fl_rotate(-angle);
+ fl_color(selection_color());
+ if (type() == FL_LINE_DIAL) {
+ fl_begin_polygon();
+ fl_vertex(0.0, 0.0);
+ fl_vertex(-0.04, 0.0);
+ fl_vertex(-0.25, 0.25);
+ fl_vertex(0.0, 0.04);
+ fl_end_polygon();
+ fl_color(FL_BLACK);
+ fl_begin_loop();
+ fl_vertex(0.0, 0.0);
+ fl_vertex(-0.04, 0.0);
+ fl_vertex(-0.25, 0.25);
+ fl_vertex(0.0, 0.04);
+ fl_end_loop();
+ } else {
+ fl_begin_polygon(); fl_circle(-0.20, 0.20, 0.07); fl_end_polygon();
+ fl_color(FL_BLACK);
+ fl_begin_loop(); fl_circle(-0.20, 0.20, 0.07); fl_end_loop();
+ }
+ fl_pop_matrix();
+}
+
+void Fl_Dial::draw() {
+ draw(x(), y(), w(), h());
+ draw_label();
+}
+
+int Fl_Dial::handle(int event, int x, int y, int w, int h) {
+ switch (event) {
+ case FL_PUSH:
+ handle_push();
+ case FL_DRAG: {
+ double angle;
+ double val = value();
+ int mx = Fl::event_x()-x-w/2;
+ int my = Fl::event_y()-y-h/2;
+ if (!mx && !my) return 1;
+ if (abs(mx) > abs(my)) {
+ angle = atan(-(double)my/mx);
+ if (mx>0) angle = 1.25*M_PI - angle;
+ else angle = 0.25*M_PI - angle;
+ } else {
+ angle = atan(-(double)mx/my);
+ if (my<0) angle = 0.75*M_PI + angle;
+ else angle = -0.25*M_PI + angle;
+ }
+ if (angle<-0.25*M_PI) angle += 2.0*M_PI;
+ val = minimum() + (maximum()-minimum())*angle/(1.5*M_PI);
+ if (fabs(val-value()) < (maximum()-minimum())/2.0)
+ handle_drag(clamp(round(val)));
+ } return 1;
+ case FL_RELEASE:
+ handle_release();
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int Fl_Dial::handle(int e) {
+ return handle(e, x(), y(), w(), h());
+}
+
+Fl_Dial::Fl_Dial(int x, int y, int w, int h, const char* l)
+ : Fl_Valuator(x, y, w, h, l) {
+ box(FL_OVAL_BOX);
+ selection_color(FL_INACTIVE_COLOR); // was 37
+}
diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx
new file mode 100644
index 000000000..aa285a5d2
--- /dev/null
+++ b/src/Fl_Double_Window.cxx
@@ -0,0 +1,157 @@
+// Fl_Double_Window.C
+
+// A double-buffered window. This is achieved by using the Xdbe extension,
+// or a pixmap if that is not available.
+
+// On systems that support double buffering "naturally" the base
+// Fl_Window class will probably do double-buffer and this subclass
+// does nothing.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+#if USE_XDBE
+
+#include <X11/extensions/Xdbe.h>
+
+static int use_xdbe;
+
+static int can_xdbe() {
+ static int tried;
+ if (!tried) {
+ tried = 1;
+ int event_base, error_base;
+ if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
+ Drawable root = RootWindow(fl_display,fl_screen);
+ int numscreens = 1;
+ XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+ if (!a) return 0;
+ for (int j = 0; j < a->count; j++)
+ if (a->visinfo[j].visual == fl_visual->visualid
+ /*&& a->visinfo[j].perflevel > 0*/) {use_xdbe = 1; break;}
+ XdbeFreeVisualInfo(a);
+ }
+ return use_xdbe;
+}
+#endif
+
+void Fl_Double_Window::show() {
+#ifndef WIN32
+ if (!shown()) { // don't set the background pixel
+ fl_open_display();
+ Fl_X::make_xid(this);
+ return;
+ }
+#endif
+ Fl_Window::show();
+}
+
+#ifdef WIN32
+
+// Code to switch output to an off-screen window:
+// this is lame, I allow two to exist...
+
+static HDC blt_gc[2];
+
+void fl_switch_offscreen(HBITMAP bitmap) {
+ if (!blt_gc[0]) for (int i = 0; i < 2; i++) {
+ blt_gc[i] = CreateCompatibleDC(fl_gc);
+ SetTextAlign(blt_gc[i], TA_BASELINE|TA_LEFT);
+ SetBkMode(blt_gc[i], TRANSPARENT);
+#if USE_COLORMAP
+ if (fl_palette) SelectPalette(blt_gc[i], fl_palette, FALSE);
+#endif
+ }
+ int which = 0; if (fl_gc == blt_gc[0]) which = 1;
+ SelectObject(blt_gc[which], bitmap);
+ fl_gc = blt_gc[which];
+}
+
+void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
+ int which = 0; if (fl_gc == blt_gc[0]) which = 1;
+ SelectObject(blt_gc[which], bitmap);
+ BitBlt(fl_gc, x, y, w, h, blt_gc[which], srcx, srcy, SRCCOPY);
+}
+
+#endif
+
+// protected method used by Fl_Overlay_Window to fake overlay:
+void Fl_Double_Window::_flush(int eraseoverlay) {
+ make_current(); // make sure fl_gc is non-zero
+ Fl_X *i = Fl_X::i(this);
+ if (!i->other_xid) {
+#if USE_XDBE
+ if (can_xdbe()) i->other_xid =
+ XdbeAllocateBackBufferName(fl_display, fl_xid(this), XdbeCopied);
+ else
+#endif
+ i->other_xid = fl_create_offscreen(w(), h());
+ clear_damage(~0);
+ }
+ XRectangle rect = {0,0,w(),h()};
+ if (damage()) {
+ if (i->region && !eraseoverlay) XClipBox(i->region, &rect);
+ if ( // don't draw if back buffer is ok
+#if USE_XDBE
+ use_xdbe ||
+#endif
+ damage() != 2) {
+#ifdef WIN32
+ fl_begin_offscreen(i->other_xid);
+ fl_clip_region(i->region); i->region = 0;
+ draw();
+ fl_end_offscreen();
+#else
+ fl_window = i->other_xid;
+ fl_clip_region(i->region); i->region = 0;
+ draw();
+ fl_window = i->xid;
+#endif
+ }
+ }
+ fl_clip_region(0);
+#if USE_XDBE
+ if (use_xdbe) {
+ XdbeSwapInfo s;
+ s.swap_window = fl_xid(this);
+ s.swap_action = XdbeCopied;
+ XdbeSwapBuffers(fl_display,&s,1);
+ } else
+#endif
+ fl_copy_offscreen(rect.x, rect.y, rect.width, rect.height,
+ i->other_xid, rect.x, rect.y);
+}
+
+void Fl_Double_Window::flush() {_flush(0);}
+
+void Fl_Double_Window::resize(int X,int Y,int W,int H) {
+ int ow = w();
+ int oh = h();
+ Fl_Window::resize(X,Y,W,H);
+#if USE_XDBE
+ if (use_xdbe) return;
+#endif
+ Fl_X* i = Fl_X::i(this);
+ if (i && i->other_xid && (ow != w() || oh != h())) {
+ fl_delete_offscreen(i->other_xid);
+ i->other_xid = 0;
+ }
+}
+
+void Fl_Double_Window::hide() {
+ Fl_X* i = Fl_X::i(this);
+ if (i && i->other_xid) {
+#if USE_XDBE
+ if (!use_xdbe)
+#endif
+ fl_delete_offscreen(i->other_xid);
+ }
+ Fl_Window::hide();
+}
+
+Fl_Double_Window::~Fl_Double_Window() {
+ hide();
+}
diff --git a/src/Fl_Font.H b/src/Fl_Font.H
new file mode 100644
index 000000000..5296b9e2e
--- /dev/null
+++ b/src/Fl_Font.H
@@ -0,0 +1,63 @@
+// Fl_Font.H
+
+// Two internal fltk data structures:
+
+// Fl_Fontdesc: an entry into the fl_font() table. This entry may contain
+// several "fonts" according to the system, for instance under X all the
+// sizes are different X fonts, but only one fl_font.
+
+// Fl_XFont: a structure for an actual system font, with junk to help
+// choose it and info on character sizes. Each Fl_Font has a linked
+// list of these. These are created the first time each system font
+// is used.
+
+#ifndef FL_FONT_
+#define FL_FONT_
+
+class Fl_XFont {
+public:
+ Fl_XFont *next; // linked list of sizes of this style
+#ifndef WIN32
+ XFontStruct* font; // X font information, 0 for display list
+ XCharStruct* per_char;// modified from XFontStruct to have 0x20-0xff in it
+ XCharStruct* free_this; // pointer saved for delete[]
+ Fl_XFont(const char*, int);
+#else
+ HFONT fid;
+ int width[256];
+ TEXTMETRIC metr;
+ Fl_XFont(const char*, int, int);
+#endif
+ int number; // which slot in FL's font table
+ int minsize; // smallest point size that should use this
+ int maxsize; // largest point size that should use this
+#if HAVE_GL
+ unsigned int listbase;// base of display list, 0 = none
+#endif
+ ~Fl_XFont();
+};
+
+extern Fl_XFont *fl_current_xfont;
+extern Fl_XFont *fl_fixed_xfont;
+
+struct Fl_Fontdesc {
+ const char *name;
+ Fl_XFont *first; // linked list of sizes of this style
+#ifndef WIN32
+ char **xlist; // matched X font names
+ int n; // size of xlist, negative = don't free xlist!
+#endif
+};
+
+extern Fl_Fontdesc *fl_fonts; // the table
+
+#ifndef WIN32
+// functions for parsing X font names:
+const char* fl_font_word(const char *p, int n);
+char *fl_find_fontsize(char *name);
+#endif
+
+void fl_draw(const char *, int x, int y, int w, int h, Fl_Align,
+ void (*callthis)(const char *, int n, int x, int y));
+
+#endif
diff --git a/src/Fl_Gl_Choice.H b/src/Fl_Gl_Choice.H
new file mode 100644
index 000000000..c112559a9
--- /dev/null
+++ b/src/Fl_Gl_Choice.H
@@ -0,0 +1,57 @@
+// Internal interface to set up OpenGL.
+
+// A "Fl_Gl_Choice" is used to cache results of calling the
+// OpenGL code for system-specific information needed to
+// implement a "mode".
+// For X this is a visual, and this must be called *before*
+// the X window is created.
+// For win32 this can be delayed to a more convienent time,
+// as it only returns information for modifying a device
+// context.
+// This is used by Fl_Gl_Window, gl_start(), and gl_visual()
+
+#ifndef Fl_Gl_Choice_H
+#define Fl_Gl_Choice_H
+
+#ifdef WIN32
+# include <windows.h>
+# include <FL/gl.h>
+# define GLXContext HGLRC
+# define GLX_BUFFER_SIZE 1
+# define GLX_RGBA 2
+# define GLX_GREEN_SIZE 3
+# define GLX_ALPHA_SIZE 4
+# define GLX_ACCUM_GREEN_SIZE 5
+# define GLX_ACCUM_ALPHA_SIZE 6
+# define GLX_DOUBLEBUFFER 7
+# define GLX_DEPTH_SIZE 8
+# define GLX_STENCIL_SIZE 9
+#else
+# include <GL/glx.h>
+#endif
+
+// one of these structures is returned:
+class Fl_Gl_Choice {
+ int mode;
+ const int *alist;
+ Fl_Gl_Choice *next;
+public:
+#ifdef WIN32
+ PIXELFORMATDESCRIPTOR pfd;
+#else
+ XVisualInfo *vis; // the visual to use
+ Colormap colormap; // a colormap to use
+#endif
+ uchar r,d,o; // rgb mode, double buffered, overlay flags
+ // either use mode flags from gl_draw.H or a literal glX int list.
+ // one of the two arguments must be zero!
+ static Fl_Gl_Choice *find(int mode, const int *);
+};
+
+#ifdef WIN32
+// function to create and init the dc needed to draw OpenGL:
+class Fl_Window;
+HDC fl_private_dc(Fl_Window*, int, Fl_Gl_Choice **gp);
+#endif
+
+#endif
diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx
new file mode 100644
index 000000000..cd5c497d7
--- /dev/null
+++ b/src/Fl_Gl_Choice.cxx
@@ -0,0 +1,157 @@
+// Internal interface to select glX visuals
+// Called by Fl_Gl_Window.C and by gl_visual() (in gl_start.C)
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <stdlib.h>
+
+#include "Fl_Gl_Choice.H"
+
+static Fl_Gl_Choice *first;
+GLXContext fl_first_context;
+
+// this assummes one of the two arguments is zero:
+// We keep the list system in Win32 to stay compatible and interpret
+// the list later...
+Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) {
+ Fl_Gl_Choice *g;
+
+ for (g = first; g; g = g->next)
+ if (g->mode == mode && g->alist == alist)
+ return g;
+
+#ifndef WIN32
+ const int *blist;
+ int list[32];
+
+ if (alist)
+ blist = alist;
+ else {
+ int n = 0;
+ if (mode & FL_INDEX) {
+ list[n++] = GLX_BUFFER_SIZE;
+ list[n++] = 8; // glut tries many sizes, but this should work...
+ } else {
+ list[n++] = GLX_RGBA;
+ list[n++] = GLX_GREEN_SIZE;
+ list[n++] = (mode & FL_RGB8) ? 8 : 1;
+ if (mode & FL_ALPHA) {
+ list[n++] = GLX_ALPHA_SIZE;
+ list[n++] = 1;
+ }
+ if (mode & FL_ACCUM) {
+ list[n++] = GLX_ACCUM_GREEN_SIZE;
+ list[n++] = 1;
+ if (mode & FL_ALPHA) {
+ list[n++] = GLX_ACCUM_ALPHA_SIZE;
+ list[n++] = 1;
+ }
+ }
+ }
+ if (mode & FL_DOUBLE) {
+ list[n++] = GLX_DOUBLEBUFFER;
+ }
+ if (mode & FL_DEPTH) {
+ list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
+ }
+ if (mode & FL_STENCIL) {
+ list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
+ }
+#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+ if (mode & FL_MULTISAMPLE) {
+ list[n++] = GLX_SAMPLES_SGIS;
+ list[n++] = 4; // value Glut uses
+ }
+#endif
+ list[n] = 0;
+ blist = list;
+ }
+
+ fl_open_display();
+ XVisualInfo *vis = glXChooseVisual(fl_display, fl_screen, (int *)blist);
+ if (!vis) {
+# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+ if (mode&FL_MULTISAMPLE) return find(mode&~FL_MULTISAMPLE,0);
+# endif
+ return 0;
+ }
+
+#else
+
+ PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL /*| PFD_DEPTH_DONTCARE*/,
+ PFD_TYPE_RGBA, 24 };
+
+ if (mode & FL_INDEX) {
+ pfd.iPixelType = PFD_TYPE_COLORINDEX;
+ pfd.cColorBits = 8;
+ } else {
+ if (mode & FL_ALPHA) pfd.cAlphaBits = 8;
+ if (mode & FL_ACCUM) {
+ pfd.cAccumBits = 6; // Wonko: I didn't find any documentation on those bits
+ pfd.cAccumGreenBits = 1;// Wonko: They don't seem to get anny support yet (4/98)
+ if (mode & FL_ALPHA) pfd.cAccumAlphaBits = 1;
+ }
+ }
+ if (mode & FL_DOUBLE) pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ // if (!(mode & FL_DEPTH)) pfd.dwFlags = PFD_DEPTH_DONTCARE;
+ if (mode & FL_STENCIL) pfd.cStencilBits = 1;
+ pfd.bReserved = 1; // always ask for overlay
+
+#endif
+
+ g = new Fl_Gl_Choice;
+ g->mode = mode;
+ g->alist = alist;
+ g->next = first;
+ first = g;
+
+#ifdef WIN32
+ memcpy(&g->pfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR));
+ g->d = ((mode&FL_DOUBLE) != 0);
+ g->r = (mode & FL_INDEX);
+ g->o = 0; // not an overlay
+#else
+ g->vis = vis;
+ g->colormap = 0;
+ int i;
+ glXGetConfig(fl_display, vis, GLX_DOUBLEBUFFER, &i); g->d = i;
+ glXGetConfig(fl_display, vis, GLX_RGBA, &i); g->r = i;
+ glXGetConfig(fl_display, vis, GLX_LEVEL, &i); g->o = i;
+
+ if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
+ vis->visualid == fl_visual->visualid &&
+ !getenv("MESA_PRIVATE_CMAP"))
+ g->colormap = fl_colormap;
+ else
+ g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ vis->visual, AllocNone);
+#endif
+
+ return g;
+}
+
+#ifdef WIN32
+
+HDC fl_private_dc(Fl_Window* w, int mode, Fl_Gl_Choice **gp) {
+ Fl_X* i = Fl_X::i(w);
+ if (!i->private_dc) {
+ i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
+ Fl_Gl_Choice *g = Fl_Gl_Choice::find(mode, 0);
+ if (gp) *gp = g;
+ int pixelFormat = ChoosePixelFormat(i->private_dc, &g->pfd);
+ if (!pixelFormat) {Fl::error("Insufficient GL support"); return NULL;}
+ SetPixelFormat(i->private_dc, pixelFormat, &g->pfd);
+#if USE_COLORMAP
+ if (fl_palette) SelectPalette(i->private_dc, fl_palette, FALSE);
+#endif
+ }
+ return i->private_dc;
+}
+#endif
+
+#endif
diff --git a/src/Fl_Gl_Overlay.cxx b/src/Fl_Gl_Overlay.cxx
new file mode 100644
index 000000000..cdc9583bc
--- /dev/null
+++ b/src/Fl_Gl_Overlay.cxx
@@ -0,0 +1,175 @@
+// Fl_Gl_Overlay.C
+
+// Methods on Fl_Gl_Window that create an overlay window. Because
+// many programs don't need the overlay, this is seperated into this
+// source file so it is not linked in if not used.
+
+// Under X this is done by creating another window, of class _Fl_Gl_Overlay
+// which is a subclass of Fl_Gl_Window except it uses the overlay planes.
+// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
+
+// Under win32 another GLX context is created to draw into the overlay
+// and it is stored in into the "overlay" pointer.
+
+// In both cases if overlay hardware is unavailable, the overlay is
+// "faked" by drawing into the main layers. This is indicated by
+// setting overlay == this.
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/Fl_Gl_Window.H>
+#include <FL/x.H>
+#include "Fl_Gl_Choice.H"
+#include <stdlib.h>
+
+#if HAVE_GL_OVERLAY
+
+#ifndef WIN32
+
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+static Fl_Gl_Choice overlay_choice;
+extern uchar fl_overlay;
+
+class _Fl_Gl_Overlay : public Fl_Gl_Window {
+ void draw();
+public:
+ void show();
+ _Fl_Gl_Overlay(int x, int y, int w, int h) :
+ Fl_Gl_Window(x,y,w,h) {
+ overlay_choice.vis = fl_overlay_visual;
+ overlay_choice.colormap = fl_overlay_colormap;
+ overlay_choice.r = 0;
+ overlay_choice.d = 0;
+ overlay_choice.o = 1;
+ g = &overlay_choice;
+ deactivate();
+ }
+};
+
+void _Fl_Gl_Overlay::draw() {
+ if (damage() != 2) glClear(GL_COLOR_BUFFER_BIT);
+ Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
+ uchar save_valid = w->valid_;
+ w->valid_ = valid_;
+ fl_overlay = 1;
+ w->draw_overlay();
+ fl_overlay = 0;
+ valid_ = w->valid_;
+ w->valid_ = save_valid;
+}
+
+void _Fl_Gl_Overlay::show() {
+ if (shown()) {Fl_Gl_Window::show(); return;}
+ fl_background_pixel = int(fl_transparent_pixel);
+ Fl_Gl_Window::show();
+ fl_background_pixel = -1;
+ // find the outermost window to tell wm about the colormap:
+ Fl_Window *w = window();
+ for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
+ XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
+}
+
+int Fl_Gl_Window::can_do_overlay() {
+ return fl_find_overlay_visual() != 0;
+}
+
+#else // WIN32:
+
+static int no_overlay_hardware;
+int Fl_Gl_Window::can_do_overlay() {
+ if (no_overlay_hardware) return 0;
+ // need to write a test here...
+ return 1;
+}
+
+extern GLXContext fl_first_context;
+
+#endif
+
+#else
+
+int Fl_Gl_Window::can_do_overlay() {return 0;}
+
+#endif
+
+void Fl_Gl_Window::make_overlay() {
+ if (!overlay) {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+ if (!no_overlay_hardware) {
+ HDC hdc = fl_private_dc(this, mode_,&g);
+ GLXContext context = wglCreateLayerContext(hdc, 1);
+ if (!context) { // no overlay hardware
+ no_overlay_hardware = 1;
+ } else {
+ // copy all colors except #0 into the overlay palette:
+ COLORREF pcr[256];
+ for (int i = 0; i < 256; i++) {
+ uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
+ pcr[i] = RGB(r,g,b);
+ }
+ wglSetLayerPaletteEntries(hdc, 1, 1, 255, pcr+1);
+ wglRealizeLayerPalette(hdc, 1, TRUE);
+ if (fl_first_context) wglShareLists(fl_first_context, context);
+ else fl_first_context = context;
+ overlay = context;
+ valid(0);
+ return;
+ }
+ }
+#else
+ if (can_do_overlay()) {
+ _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
+ overlay = o;
+ add_resizable(*o);
+ o->show();
+ return;
+ }
+#endif
+#endif
+ overlay = this; // fake the overlay
+ }
+}
+
+void Fl_Gl_Window::redraw_overlay() {
+ if (!shown()) return;
+ make_overlay();
+#ifndef WIN32
+ if (overlay != this)
+ ((Fl_Gl_Window*)overlay)->redraw();
+ else
+#endif
+ damage(8);
+}
+
+void Fl_Gl_Window::make_overlay_current() {
+ make_overlay();
+#if HAVE_GL_OVERLAY
+ if (overlay != this) {
+#ifdef WIN32
+ wglMakeCurrent(Fl_X::i(this)->private_dc, (GLXContext)overlay);
+#else
+ Fl_Gl_Window* w = (Fl_Gl_Window*)overlay;
+ w->make_current();
+#endif
+ } else
+#endif
+ glDrawBuffer(GL_FRONT);
+}
+
+void Fl_Gl_Window::hide_overlay() {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+ // nothing needs to be done? Or should it be erased?
+#else
+ if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
+#endif
+#endif
+}
+
+#endif
diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx
new file mode 100644
index 000000000..acd08e6f3
--- /dev/null
+++ b/src/Fl_Gl_Window.cxx
@@ -0,0 +1,287 @@
+// Fl_Gl_Window.C
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Gl_Window.H>
+#include "Fl_Gl_Choice.H"
+
+////////////////////////////////////////////////////////////////
+
+// The symbol SWAP_TYPE defines what is in the back buffer after doing
+// a glXSwapBuffers().
+
+// The OpenGl documentation says that the contents of the backbuffer
+// are "undefined" after glXSwapBuffers(). However, if we know what
+// is in the backbuffers then we can save a good deal of time. For
+// this reason you can define some symbols to describe what is left in
+// the back buffer.
+
+// The default of SWAP_SWAP works on an SGI, and will also work (but
+// is sub-optimal) on machines that should be SWAP_COPY or SWAP_NODAMAGE.
+// The win32 emulation of OpenGL can use COPY, but some (all?) OpenGL
+// cards use SWAP.
+
+// contents of back buffer after glXSwapBuffers():
+#define UNDEFINED 0 // unknown
+#define SWAP 1 // former front buffer
+#define COPY 2 // unchanged
+#define NODAMAGE 3 // unchanged even by X expose() events
+
+#ifdef MESA
+#define SWAP_TYPE NODAMAGE
+#else
+#define SWAP_TYPE SWAP
+#endif
+
+////////////////////////////////////////////////////////////////
+
+int Fl_Gl_Window::can_do(int a, const int *b) {
+#ifdef WIN32
+ Fl_Gl_Choice *g = Fl_Gl_Choice::find(a,b);
+ HWND w = GetDesktopWindow();
+ HDC dc = GetDC(w);
+ int r = ChoosePixelFormat(dc, &g->pfd);
+ ReleaseDC(w,dc);
+ return r != 0;
+#else
+ return Fl_Gl_Choice::find(a,b) != 0;
+#endif
+}
+
+void Fl_Gl_Window::show() {
+#ifndef WIN32
+ if (!shown()) {
+ if (!g) {
+ g = Fl_Gl_Choice::find(mode_,alist);
+ if (!g) {Fl::error("Insufficient GL support"); return;}
+ }
+ Fl_X::make_xid(this, g->vis, g->colormap);
+ if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
+ }
+#endif
+ Fl_Window::show();
+}
+
+void Fl_Gl_Window::invalidate() {
+ valid(0);
+#ifndef WIN32
+ if (overlay) ((Fl_Gl_Window*)overlay)->valid(0);
+#endif
+}
+
+extern GLXContext fl_first_context; // in Fl_Gl_Choice.C
+
+int Fl_Gl_Window::mode(int m, const int *a) {
+ if (m == mode_ && a == alist) return 0;
+ mode_ = m; alist = a;
+#ifdef WIN32
+ // destroy context and g:
+ if (shown()) {hide(); show();}
+#else
+ // under X, if the visual changes we must make a new X window (!):
+ if (shown()) {
+ Fl_Gl_Choice *g1 = g;
+ g = Fl_Gl_Choice::find(mode_,alist);
+ if (!g || g->vis->visualid != g1->vis->visualid || g->d != g1->d) {
+ hide(); show();
+ }
+ }
+#endif
+ return 1;
+}
+
+#ifdef WIN32
+extern char fl_direct_paint; // true when responding to WM_PAINT
+#endif
+
+void Fl_Gl_Window::make_current() {
+#ifdef WIN32
+ HDC hdc = fl_private_dc(this, mode_,&g);
+ if (!context) {
+ context = wglCreateContext(hdc);
+ if (fl_first_context) wglShareLists(fl_first_context, (GLXContext)context);
+ else fl_first_context = (GLXContext)context;
+ valid(0);
+ }
+ wglMakeCurrent(hdc, (GLXContext)context);
+#else
+ if (!context) {
+ context = glXCreateContext(fl_display, g->vis, fl_first_context, 1);
+ if (!fl_first_context) fl_first_context = (GLXContext)context;
+ valid(0);
+ }
+ glXMakeCurrent(fl_display, fl_xid(this), (GLXContext)context);
+#endif
+ glDrawBuffer(GL_BACK);
+}
+
+void Fl_Gl_Window::ortho() {
+ glLoadIdentity();
+ glViewport(0, 0, w(), h());
+ glOrtho(0, w(), 0, h(), -1, 1);
+}
+
+void Fl_Gl_Window::swap_buffers() {
+#ifdef WIN32
+ SwapBuffers(Fl_X::i(this)->private_dc);
+#else
+ glXSwapBuffers(fl_display, fl_xid(this));
+#endif
+}
+
+#if HAVE_GL_OVERLAY
+#if WIN32
+uchar fl_overlay; // changes how fl_color() works
+#endif
+#endif
+
+void Fl_Gl_Window::flush() {
+ make_current();
+
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+ uchar save_valid = valid_;
+ if (overlay && overlay!= this && damage() == 8) goto DRAW_OVERLAY_ONLY;
+#endif
+#endif
+
+ if (g->d) {
+
+#if SWAP_TYPE == NODAMAGE
+
+ // don't draw if only overlay damage or expose events:
+ if ((damage()&~0xA0) || !valid()) draw();
+ swap_buffers();
+
+#elif SWAP_TYPE == COPY
+
+ // don't draw if only the overlay is damaged:
+ if (damage() != 8 || !valid()) draw();
+ swap_buffers();
+
+#else // SWAP_TYPE == SWAP || SWAP_TYPE == UNDEFINED
+
+ if (overlay == this) { // Use CopyPixels to act like SWAP_TYPE == COPY
+
+ // don't draw if only the overlay is damaged:
+ if (damage1_ || damage() != 8 || !valid()) draw();
+ // we use a seperate context for the copy because rasterpos must be 0
+ // and depth test needs to be off:
+ static GLXContext ortho_context;
+ int init = !ortho_context;
+#ifdef WIN32
+ if (init) ortho_context = wglCreateContext(Fl_X::i(this)->private_dc);
+ wglMakeCurrent(Fl_X::i(this)->private_dc, ortho_context);
+#else
+ if (init)
+ ortho_context = glXCreateContext(fl_display,g->vis,fl_first_context,1);
+ glXMakeCurrent(fl_display, fl_xid(this), ortho_context);
+#endif
+ if (init) {
+ glDisable(GL_DEPTH_TEST);
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_FRONT);
+ }
+ glCopyPixels(0,0,w(),h(),GL_COLOR);
+ make_current(); // set current context back to draw overlay
+ damage1_ = 0;
+
+ } else {
+
+#if SWAP_TYPE == SWAP
+ uchar old_damage = damage();
+ clear_damage(damage1_|old_damage); draw();
+ swap_buffers();
+ damage1_ = old_damage;
+#else // SWAP_TYPE == UNDEFINED
+ clear_damage(~0); draw();
+ swap_buffers();
+ damage1_ = ~0;
+#endif
+
+ }
+#endif
+
+ if (overlay==this) { // fake overlay in front buffer
+ glDrawBuffer(GL_FRONT);
+ draw_overlay();
+ glDrawBuffer(GL_BACK);
+ glFlush();
+ }
+
+ } else { // single-buffered context is simpler:
+
+ // this faking of the overlay is incorrect but worked good for
+ // one in-house program:
+ if (overlay != this || damage()!=8 || !Fl::pushed()) draw();
+ if (overlay == this) draw_overlay();
+ glFlush();
+
+ }
+
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+ if (overlay && overlay != this) {
+ DRAW_OVERLAY_ONLY:
+ valid_ = save_valid;
+ wglMakeCurrent(Fl_X::i(this)->private_dc, (GLXContext)overlay);
+ glDisable(GL_SCISSOR_TEST);
+ fl_overlay = 1;
+ glClear(GL_COLOR_BUFFER_BIT);
+ draw_overlay();
+ wglSwapLayerBuffers(Fl_X::i(this)->private_dc,WGL_SWAP_OVERLAY1);
+ fl_overlay = 0;
+ }
+#endif
+#endif
+
+ valid(1);
+}
+
+void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
+ if (W != w() || H != h()) valid(0);
+ Fl_Window::resize(X,Y,W,H);
+}
+
+void Fl_Gl_Window::hide() {
+ if (context) {
+#ifdef WIN32
+ wglMakeCurrent(0, 0);
+ if (context && context != fl_first_context)
+ wglDeleteContext((GLXContext)context);
+ g = 0;
+#else
+ glXMakeCurrent(fl_display, 0, 0);
+ if (context != fl_first_context)
+ glXDestroyContext(fl_display, (GLXContext)context);
+#ifdef GLX_MESA_release_buffers
+ glXReleaseBuffersMESA(fl_display, fl_xid(this));
+#endif
+#endif
+ context = 0;
+ }
+ Fl_Window::hide();
+}
+
+Fl_Gl_Window::~Fl_Gl_Window() {
+ hide();
+// delete overlay; this is done by ~Fl_Group
+}
+
+void Fl_Gl_Window::init() {
+ end(); // we probably don't want any children
+ box(FL_NO_BOX);
+ mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE;
+ alist = 0;
+ context = 0;
+ g = 0;
+ overlay = 0;
+ damage1_ = 0;
+}
+
+void Fl_Gl_Window::draw_overlay() {}
+
+#endif
diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx
new file mode 100644
index 000000000..e1a0b43ad
--- /dev/null
+++ b/src/Fl_Group.cxx
@@ -0,0 +1,443 @@
+// Fl_Group.C
+
+// The Fl_Group is the only defined container type in fltk.
+
+// Fl_Window itself is a subclass of this, and most of the event
+// handling is designed so windows themselves work correctly.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_draw.H>
+#include <stdlib.h>
+
+Fl_Group* Fl_Group::current_;
+
+// Hack: A single child is stored in the pointer to the array, while
+// multiple children are stored in an allocated array:
+Fl_Widget*const* Fl_Group::array() const {
+ return children_ <= 1 ? (Fl_Widget**)(&array_) : array_;
+}
+
+int Fl_Group::find(const Fl_Widget* o) const {
+ Fl_Widget*const* a = array();
+ int i; for (i=0; i < children_; i++) if (*a++ == o) break;
+ return i;
+}
+
+extern Fl_Widget* fl_oldfocus; // set by Fl::focus
+
+// For back-compatability, we must adjust all events sent to child
+// windows so they are relative to that window.
+
+static int send(Fl_Widget* o, int event) {
+ if (o->type() < FL_WINDOW) return o->handle(event);
+ int save_x = Fl::e_x; Fl::e_x -= o->x();
+ int save_y = Fl::e_y; Fl::e_y -= o->y();
+ int ret = o->handle(event);
+ Fl::e_y = save_y;
+ Fl::e_x = save_x;
+ return ret;
+}
+
+int Fl_Group::handle(int event) {
+
+ Fl_Widget*const* a = array();
+ int i;
+ Fl_Widget* o;
+
+ switch (event) {
+
+ case FL_FOCUS:
+ if (savedfocus_ && savedfocus_->take_focus()) return 1;
+ for (i = children(); i--;) if ((*a++)->take_focus()) return 1;
+ return 0;
+
+ case FL_UNFOCUS:
+ savedfocus_ = fl_oldfocus;
+ return 0;
+
+ case FL_KEYBOARD:
+ return navigation();
+
+ case FL_SHORTCUT:
+ for (i = children(); i--;) {
+ o = a[i];
+ if (o->takesevents() && Fl::event_inside(o) && send(o,FL_SHORTCUT))
+ return 1;
+ }
+ for (i = children(); i--;) {
+ o = a[i];
+ if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_SHORTCUT))
+ return 1;
+ }
+ if (Fl::event_key() == FL_Enter) return navigation(FL_Down);
+ return 0;
+
+ case FL_ENTER:
+ case FL_MOVE:
+ for (i = children(); i--;) {
+ o = a[i];
+ if (o->takesevents() && Fl::event_inside(o)) {
+ if (o->contains(Fl::belowmouse())) {
+ return send(o,FL_MOVE);
+ } else if (send(o,FL_ENTER)) {
+ if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o);
+ return 1;
+ }
+ }
+ }
+ Fl::belowmouse(this);
+ return 1;
+
+ case FL_PUSH:
+ for (i = children(); i--;) {
+ o = a[i];
+ if (o->takesevents() && Fl::event_inside(o)) {
+ if (send(o,FL_PUSH)) {
+ if (Fl::pushed() && !o->contains(Fl::pushed())) Fl::pushed(o);
+ return 1;
+ }
+ }
+ }
+ return 0;
+
+ case FL_DEACTIVATE:
+ case FL_ACTIVATE:
+ for (i = children(); i--;) {
+ o = *a++;
+ if (o->active()) o->handle(event);
+ }
+ return 1;
+
+ case FL_SHOW:
+ case FL_HIDE:
+ for (i = children(); i--;) {
+ o = *a++;
+ if (o->visible()) o->handle(event);
+ }
+ return 1;
+
+ default:
+ return 0;
+
+ }
+}
+
+// translate the current keystroke into up/down/left/right for navigation:
+#define ctrl(x) (x^0x40)
+int navkey() {
+ switch (Fl::event_key()) {
+ case FL_Tab:
+ return (Fl::event_state(FL_SHIFT) ? FL_Left : FL_Right);
+ case FL_Right:
+ return FL_Right;
+ case FL_Left:
+ return FL_Left;
+ case FL_Up:
+ return FL_Up;
+ case FL_Down:
+ return FL_Down;
+ default:
+ switch (Fl::event_text()[0]) {
+ case ctrl('N') : return FL_Down;
+ case ctrl('P') : return FL_Up;
+ case ctrl('F') : return FL_Right;
+ case ctrl('B') : return FL_Left;
+ }
+ }
+ return 0;
+}
+
+//void Fl_Group::focus(Fl_Widget *o) {Fl::focus(o); o->handle(FL_FOCUS);}
+
+#if 0
+const char *nameof(Fl_Widget *o) {
+ if (!o) return "NULL";
+ if (!o->label()) return "<no label>";
+ return o->label();
+}
+#endif
+
+// try to move the focus in response to a keystroke:
+int Fl_Group::navigation(int key) {
+ if (children() <= 1) return 0;
+ if (!key) {key = navkey(); if (!key) return 0;}
+ Fl_Widget *focus_ = Fl::focus();
+ int old_i;
+ for (old_i=0;;old_i++) {
+ if (old_i >= children_) return 0;
+ if (array_[old_i]->contains(focus_)) break;
+ }
+ int i = old_i;
+
+ for (;;) {
+ switch (key) {
+ case FL_Right:
+ case FL_Down:
+ i++; if (i >= children_) i = 0;
+ break;
+ case FL_Left:
+ case FL_Up:
+ if (i) i--; else i = children_-1;
+ break;
+ default:
+ return 0;
+ }
+ if (i == old_i) return 0;
+ Fl_Widget* o = array_[i];
+ switch (key) {
+ case FL_Down:
+ case FL_Up:
+ if (o->x() >= focus_->x()+focus_->w() ||
+ o->x()+o->w() <= focus_->x()) continue;
+ }
+ if (o->take_focus()) return 1;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l)
+: Fl_Widget(X,Y,W,H,l) {
+ align(FL_ALIGN_TOP);
+ children_ = 0;
+ array_ = 0;
+ savedfocus_ = 0;
+ resizable_ = this;
+ sizes_ = 0; // this is allocated when first resize() is done
+ // Subclasses may want to construct child objects as part of their
+ // constructor, so make sure they are add()'d to this object.
+ // But you must end() the object!
+ begin();
+}
+
+void Fl_Group::clear() {
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ // test the parent to see if child already destructed:
+ if (o->parent() == this) delete o;
+ }
+ if (children() > 1) free((void*)array_);
+ children_ = 0;
+ array_ = 0;
+ savedfocus_ = 0;
+ resizable_ = this;
+ init_sizes();
+}
+
+Fl_Group::~Fl_Group() {clear();}
+
+void Fl_Group::insert(Fl_Widget &o, int i) {
+ if (o.parent()) ((Fl_Group*)(o.parent()))->remove(o);
+ o.parent_ = this;
+ if (children_ == 0) { // use array pointer to point at single child
+ array_ = (Fl_Widget**)&o;
+ } else if (children_ == 1) { // go from 1 to 2 children
+ Fl_Widget* t = (Fl_Widget*)array_;
+ array_ = (Fl_Widget**)malloc(2*sizeof(Fl_Widget*));
+ array_[!i] = t; array_[i] = &o;
+ } else {
+ if (!(children_ & (children_-1))) // double number of children
+ array_ = (Fl_Widget**)realloc((void*)array_,
+ 2*children_*sizeof(Fl_Widget*));
+ for (int j = children_; j > i; j--) array_[j] = array_[j-1];
+ array_[i] = &o;
+ }
+ children_++;
+ init_sizes();
+}
+
+void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}
+
+void Fl_Group::remove(Fl_Widget &o) {
+ int i = find(o);
+ if (i >= children_) return;
+ if (&o == savedfocus_) savedfocus_ = 0;
+ o.parent_ = 0;
+ children_--;
+ if (children_ == 1) { // go from 2 to 1 child
+ Fl_Widget *t = array_[!i];
+ free((void*)array_);
+ array_ = (Fl_Widget**)t;
+ } else if (children_ > 1) { // delete from array
+ for (; i < children_; i++) array_[i] = array_[i+1];
+ }
+ init_sizes();
+}
+
+////////////////////////////////////////////////////////////////
+
+// Rather lame kludge here, I need to detect windows and ignore the
+// changes to X,Y, since all children are relative to X,Y. That
+// is why I check type():
+
+// sizes array stores the initial positions of widgets as
+// left,right,top,bottom quads. The first quad is the group, the
+// second is the resizable (clipped to the group), and the
+// rest are the children. This is a convienent order for the
+// algorithim. If you change this be sure to fix Fl_Tile which
+// also uses this array!
+
+void Fl_Group::init_sizes() {
+ delete[] sizes_; sizes_ = 0;
+}
+
+short* Fl_Group::sizes() {
+ if (!sizes_) {
+ short* p = sizes_ = new short[4*(children_+2)];
+ // first thing in sizes array is the group's size:
+ if (type() < FL_WINDOW) {p[0] = x(); p[2] = y();} else {p[0] = p[2] = 0;}
+ p[1] = p[0]+w(); p[3] = p[2]+h();
+ // next is the resizable's size:
+ p[4] = p[0]; // init to the group's size
+ p[5] = p[1];
+ p[6] = p[2];
+ p[7] = p[3];
+ Fl_Widget* r = resizable();
+ if (r && r != this) { // then clip the resizable to it
+ int t;
+ t = r->x(); if (t > p[0]) p[4] = t;
+ t +=r->w(); if (t < p[1]) p[5] = t;
+ t = r->y(); if (t > p[2]) p[6] = t;
+ t +=r->h(); if (t < p[3]) p[7] = t;
+ }
+ // next is all the children's sizes:
+ p += 8;
+ Fl_Widget*const* a = array();
+ for (int i=children_; i--;) {
+ Fl_Widget* o = *a++;
+ *p++ = o->x();
+ *p++ = o->x()+o->w();
+ *p++ = o->y();
+ *p++ = o->y()+o->h();
+ }
+ }
+ return sizes_;
+}
+
+void Fl_Group::resize(int X, int Y, int W, int H) {
+
+ if (!resizable() || W==w() && H==h()) {
+
+ if (type() < FL_WINDOW) {
+ int dx = X-x();
+ int dy = Y-y();
+ Fl_Widget*const* a = array();
+ for (int i=children_; i--;) {
+ Fl_Widget* o = *a++;
+ o->resize(o->x()+dx, o->y()+dy, o->w(), o->h());
+ }
+ }
+
+ } else if (children_) {
+
+ short* p = sizes();
+
+ // get changes in size/position from the initial size:
+ int dx = X - p[0];
+ int dw = W - (p[1]-p[0]);
+ int dy = Y - p[2];
+ int dh = H - (p[3]-p[2]);
+ if (type() >= FL_WINDOW) dx = dy = 0;
+ p += 4;
+
+ // get initial size of resizable():
+ int IX = *p++;
+ int IR = *p++;
+ int IY = *p++;
+ int IB = *p++;
+
+ Fl_Widget*const* a = array();
+ for (int i=children_; i--;) {
+ Fl_Widget* o = *a++;
+
+ int X = *p++;
+ if (X >= IR) X += dw;
+ else if (X > IX) X = IX+((X-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
+ int R = *p++;
+ if (R >= IR) R += dw;
+ else if (R > IX) R = IX+((R-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
+
+ int Y = *p++;
+ if (Y >= IB) Y += dh;
+ else if (Y > IY) Y = IY+((Y-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
+ int B = *p++;
+ if (B >= IB) B += dh;
+ else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
+
+ o->resize(X+dx, Y+dy, R-X, B-Y);
+ }
+ }
+
+ Fl_Widget::resize(X,Y,W,H);
+}
+
+void Fl_Group::draw() {
+ Fl_Widget*const* a = array();
+ if (damage() & ~1) { // redraw the entire thing:
+ draw_box();
+ draw_label();
+ for (int i=children_; i--;) {
+ Fl_Widget& o = **a++;
+ draw_child(o);
+ draw_outside_label(o);
+ }
+ } else { // only redraw the children that need it:
+ for (int i=children_; i--;) update_child(**a++);
+ }
+}
+
+// Draw a child only if it needs it:
+void Fl_Group::update_child(Fl_Widget& w) const {
+ if (w.damage() && w.visible() && w.type() < FL_WINDOW &&
+ fl_not_clipped(w.x(), w.y(), w.w(), w.h())) {
+ w.draw();
+ w.clear_damage();
+ }
+}
+
+// Force a child to redraw:
+void Fl_Group::draw_child(Fl_Widget& w) const {
+ if (w.visible() && w.type() < FL_WINDOW &&
+ fl_not_clipped(w.x(), w.y(), w.w(), w.h())) {
+ w.clear_damage(~0);
+ w.draw();
+ w.clear_damage();
+ }
+}
+
+extern char fl_draw_shortcut;
+
+// Parents normally call this to draw outside labels:
+void Fl_Group::draw_outside_label(const Fl_Widget& w) const {
+ if (!w.visible()) return;
+ // skip any labels that are inside the widget:
+ if (!(w.align()&15) || (w.align() & FL_ALIGN_INSIDE)) return;
+ // invent a box that is outside the widget:
+ int align = w.align();
+ int X = w.x();
+ int Y = w.y();
+ int W = w.w();
+ int H = w.h();
+ if (align & FL_ALIGN_TOP) {
+ align ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
+ Y = y();
+ H = w.y()-Y;
+ } else if (align & FL_ALIGN_BOTTOM) {
+ align ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
+ Y = Y+H;
+ H = y()+h()-Y;
+ } else if (align & FL_ALIGN_LEFT) {
+ align ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
+ X = x();
+ W = w.x()-X-3;
+ } else if (align & FL_ALIGN_RIGHT) {
+ align ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
+ X = X+W+3;
+ W = x()+this->w()-X;
+ }
+ w.draw_label(X,Y,W,H,(Fl_Align)align);
+}
+
diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx
new file mode 100644
index 000000000..1aac860d4
--- /dev/null
+++ b/src/Fl_Image.cxx
@@ -0,0 +1,62 @@
+// Fl_Image.C
+
+// Draw a image in a box.
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Image.H>
+
+void Fl_Image::draw(int X, int Y, int W, int H, int cx,int cy) {
+ // clip the box down to the size of image, quit if empty:
+ if (cx < 0) {W += cx; X -= cx; cx = 0;}
+ if (cx+W > w) W = w-cx;
+ if (W <= 0) return;
+ if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+ if (cy+H > h) H = h-cy;
+ if (H <= 0) return;
+ if (!id) {
+ id = (ulong)fl_create_offscreen(w, h);
+ fl_begin_offscreen((Fl_Offscreen)id);
+ fl_draw_image(array, 0, 0, w, h, d, ld);
+ fl_end_offscreen();
+ }
+ fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+}
+
+Fl_Image::~Fl_Image() {
+ if (id) fl_delete_offscreen((Fl_Offscreen)id);
+}
+
+static void image_labeltype(
+ const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
+{
+ Fl_Image* b = (Fl_Image*)(o->value);
+ int cx;
+ if (a & FL_ALIGN_LEFT) cx = 0;
+ else if (a & FL_ALIGN_RIGHT) cx = b->w-w;
+ else cx = (b->w-w)/2;
+ int cy;
+ if (a & FL_ALIGN_TOP) cy = 0;
+ else if (a & FL_ALIGN_BOTTOM) cy = b->h-h;
+ else cy = (b->h-h)/2;
+ b->draw(x,y,w,h,cx,cy);
+}
+
+static void image_measure(const Fl_Label* o, int& w, int& h) {
+ Fl_Image* b = (Fl_Image*)(o->value);
+ w = b->w;
+ h = b->h;
+}
+
+void Fl_Image::label(Fl_Widget* o) {
+ Fl::set_labeltype(_FL_IMAGE_LABEL, image_labeltype, image_measure);
+ o->label(_FL_IMAGE_LABEL, (const char*)this);
+}
+
+void Fl_Image::label(Fl_Menu_Item* o) {
+ Fl::set_labeltype(_FL_IMAGE_LABEL, image_labeltype, image_measure);
+ o->label(_FL_IMAGE_LABEL, (const char*)this);
+}
diff --git a/src/Fl_Input.cxx b/src/Fl_Input.cxx
new file mode 100644
index 000000000..34dfce1b9
--- /dev/null
+++ b/src/Fl_Input.cxx
@@ -0,0 +1,299 @@
+// Fl_Input.C
+
+// This is the "user interface", it decodes user actions into what to
+// do to the text. See also Fl_Input_.C, where the text is actually
+// manipulated (and some ui, in particular the mouse, is done...).
+// In theory you can replace this code with another subclass to change
+// the keybindings.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+
+void Fl_Input::draw() {
+ if (type() == FL_HIDDEN_INPUT) return;
+ Fl_Boxtype b = box() ? box() : default_box();
+ if (damage() & 128) draw_box(b, color());
+ Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
+ w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
+}
+
+// kludge so shift causes selection to extend:
+int Fl_Input::shift_position(int p) {
+ return position(p, Fl::event_state(FL_SHIFT) ? mark() : p);
+}
+int Fl_Input::shift_up_down_position(int p) {
+ return up_down_position(p, Fl::event_state(FL_SHIFT));
+}
+
+////////////////////////////////////////////////////////////////
+// Fltk "compose"
+// I tried to do compose characters "correctly" with much more user
+// feedback. They can see the character they will get, rather than
+// the "dead key" effect. Notice that I completely ignore that horrid
+// XIM extension!
+// Although the current scheme only works for Latin-NR1 character sets
+// the intention is to expand this to UTF-8 someday, to allow you to
+// compose all characters in all languages with no stupid "locale"
+// setting.
+// To use, you call "fl_compose()" for each keystroke. You pass it
+// the characters it displayed last time plus the new character. It
+// returns a new set of characters to replace the old one with. If
+// it returns zero length you should leave the old set unchanged and
+// treat the new key normally.
+// Pressing any function keys or moving the cursor should set the
+// compose state back to zero.
+
+// This string lists a pair for each possible foreign letter in Latin-NR1
+// starting at code 0xa0 (nbsp). If the second character is a space then
+// only the first character needs to by typed:
+static const char* const compose_pairs =
+" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
+"A`A'A^A~A:A*AEC,E`E'E^E:I`I'I^I:D-N~O`O'O^O~O:x O/U`U'U^U:Y'DDss"
+"a`a'a^a~a:a*aec,e`e'e^e:i`i'i^i:d-n~o`o'o^o~o:-:o/u`u'u^u:y'ddy:";
+
+int fl_compose(int state, char c, int& del, char* buffer, int& ins) {
+ del = 0; ins = 1; buffer[0] = c;
+
+ if (c == '"') c = ':';
+
+ if (!state) { // first character
+ if (c == ' ') {buffer[0]=char(0xA0);return 0x100;} // space turns into nbsp
+ // see if it is either character of any pair:
+ state = 0;
+ for (const char *p = compose_pairs; *p; p += 2)
+ if (p[0] == c || p[1] == c) {
+ if (p[1] == ' ') buffer[0] = (p-compose_pairs)/2+0xA0;
+ state = c;
+ }
+ return state;
+
+ } else if (state == 0x100) { // third character
+ return 0;
+
+ } else { // second character
+ char c1 = char(state); // first character
+ // now search for the pair in either order:
+ for (const char *p = compose_pairs; *p; p += 2) {
+ if (p[0] == c && p[1] == c1 || p[1] == c && p[0] == c1) {
+ buffer[0] = (p-compose_pairs)/2+0xA0;
+ ins = del = 1;
+ return 0x100;
+ }
+ }
+ return 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+static int compose; // compose state (# of characters so far + 1)
+
+// If you define this symbol as zero you will get the peculiar fltk
+// behavior where moving off the end of an input field will move the
+// cursor into the next field:
+// define it as 1 to prevent cursor movement from going to next field:
+#define NORMAL_INPUT_MOVE 0
+
+#define ctrl(x) (x^0x40)
+
+int Fl_Input::handle_key() {
+ int i;
+
+ int pcompose = compose; compose = 0;
+ char key = Fl::event_text()[0];
+
+ if (pcompose && Fl::event_length()) {
+ char buf[20]; int ins; int del;
+ compose = fl_compose(pcompose-1, key, del, buf, ins);
+ if (compose) {
+ replace(position(), del ? position()-del : mark(), buf, ins);
+ compose++; // store value+1 so 1 can initialize compose state
+ return 1;
+ } else {
+ if (pcompose==1) // compose also acts as quote-next:
+ return replace(position(),mark(),Fl::event_text(),Fl::event_length());
+ }
+ }
+
+ if (Fl::event_state(FL_ALT|FL_META)) { // reserved for shortcuts
+ compose = pcompose;
+ return 0;
+ }
+
+ switch (Fl::event_key()) {
+ case FL_Left:
+ key = ctrl('B'); break;
+ case FL_Right:
+ key = ctrl('F'); break;
+ case FL_Up:
+ key = ctrl('P'); break;
+ case FL_Down:
+ key = ctrl('N'); break;
+ case FL_Delete:
+ key = ctrl('D'); break;
+ case FL_Home:
+ key = ctrl('A'); break;
+ case FL_End:
+ key = ctrl('E'); break;
+ case FL_BackSpace:
+ if (mark() != position()) cut();
+ else cut(-1);
+ return 1;
+ case FL_Enter:
+ case FL_KP_Enter:
+ if (when() & FL_WHEN_ENTER_KEY) {
+ position(size(), 0);
+ maybe_do_callback();
+ return 1;
+ } else if (type() == FL_MULTILINE_INPUT)
+ return replace(position(), mark(), "\n", 1);
+ else
+ return 0; // reserved for shortcuts
+ case FL_Tab:
+ if (Fl::event_state(FL_CTRL) || type()!=FL_MULTILINE_INPUT) return 0;
+ break;
+ case FL_Escape:
+ return 0; // reserved for shortcuts (Forms cleared field)
+ case FL_Control_R:
+ case 0xff20: // Multi-Key
+ compose = 1;
+ return 1;
+ }
+
+ switch(key) {
+ case 0: // key did not translate to any text
+ compose = pcompose; // allow user to hit shift keys after ^Q
+ return 0;
+ case ctrl('A'):
+ if (type() == FL_MULTILINE_INPUT)
+ for (i=position(); i && index(i-1)!='\n'; i--) ;
+ else
+ i = 0;
+ return shift_position(i) + NORMAL_INPUT_MOVE;
+ case ctrl('B'):
+ return shift_position(position()-1) + NORMAL_INPUT_MOVE;
+ case ctrl('C'): // copy
+ return copy();
+ case ctrl('D'):
+ if (mark() != position()) return cut();
+ else return cut(1);
+ case ctrl('E'):
+ if (type() == FL_MULTILINE_INPUT)
+ for (i=position(); index(i) && index(i)!='\n'; i++) ;
+ else
+ i = size();
+ return shift_position(i) + NORMAL_INPUT_MOVE;
+ case ctrl('F'):
+ return shift_position(position()+1) + NORMAL_INPUT_MOVE;
+ case ctrl('K'):
+ if (position()>=size()) return 0;
+ if (type() == FL_MULTILINE_INPUT) {
+ if (index(position()) == '\n')
+ i = position() + 1;
+ else
+ for (i=position()+1; index(i) && index(i) != '\n'; i++);
+ } else
+ i = size();
+ cut(position(), i);
+ return copy_cuts();
+ case ctrl('N'):
+ if (type()!=FL_MULTILINE_INPUT) return 0;
+ for (i=position(); index(i)!='\n'; i++)
+ if (!index(i)) return NORMAL_INPUT_MOVE;
+ shift_up_down_position(i+1);
+ return 1;
+ case ctrl('P'):
+ if (type()!=FL_MULTILINE_INPUT) return 0;
+ for (i = position(); i > 0 && index(i-1) != '\n'; i--) ;
+ if (!i) return NORMAL_INPUT_MOVE;
+ shift_up_down_position(i-1);
+ return 1;
+ case ctrl('Q'):
+ compose = 1;
+ return 1;
+ case ctrl('U'):
+ return cut(0, size());
+ case ctrl('V'):
+ case ctrl('Y'):
+ Fl::paste(*this);
+ return 1;
+ case ctrl('X'):
+ case ctrl('W'):
+ copy();
+ return cut();
+ case ctrl('Z'):
+ case ctrl('_'):
+ return undo();
+ }
+
+ // skip all illegal characters
+ // this could be improved to make sure characters are inserted at
+ // legal positions...
+ if (type() == FL_FLOAT_INPUT) {
+ if (!strchr("0123456789.eE+-", key)) return 0;
+ } else if (type() == FL_INT_INPUT) {
+ if (!strchr("0123456789+-", key)) return 0;
+ }
+
+ return replace(position(), mark(), Fl::event_text(), Fl::event_length());
+}
+
+int Fl_Input::handle(int event) {
+ switch (event) {
+
+ case FL_FOCUS:
+ switch (Fl::event_key()) {
+ case FL_Right:
+ position(0);
+ break;
+ case FL_Left:
+ position(size());
+ break;
+ case FL_Down:
+ up_down_position(0);
+ break;
+ case FL_Up:
+ up_down_position(size());
+ break;
+ case FL_Tab:
+ position(size(),0);
+ break;
+ }
+ break;
+
+ case FL_UNFOCUS:
+ compose = 0;
+ break;
+
+ case FL_KEYBOARD:
+ return handle_key();
+
+ case FL_PUSH:
+ compose = 0;
+ if (Fl::event_button() == 2) {
+ Fl::paste(*this);
+ if (Fl::focus()==this) return 1; // remove line for Motif behavior
+ }
+ if (Fl::focus() != this) {
+ Fl::focus(this);
+ handle(FL_FOCUS); // cause minimal update
+ }
+ break;
+
+ case FL_DRAG:
+ case FL_RELEASE:
+ if (Fl::event_button() == 2) return 0;
+ break;
+ }
+ Fl_Boxtype b = box() ? box() : default_box();
+ return Fl_Input_::handletext(event,
+ x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
+ w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
+}
+
+Fl_Input::Fl_Input(int x, int y, int w, int h, const char *l)
+: Fl_Input_(x, y, w, h, l) {}
diff --git a/src/Fl_Input_.cxx b/src/Fl_Input_.cxx
new file mode 100644
index 000000000..a04d3cef2
--- /dev/null
+++ b/src/Fl_Input_.cxx
@@ -0,0 +1,704 @@
+// Fl_Input_.C
+
+// This is the base class for Fl_Input. You can use it directly
+// if you are one of those people who like to define their own
+// set of editing keys. It may also be useful for adding scrollbars
+// to the input field.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Input_.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define MAXBUF 1024
+
+////////////////////////////////////////////////////////////////
+
+// Copy string p..e to the buffer, replacing characters with ^X and \nnn
+// as necessary. Truncate if necessary so the resulting string and
+// null terminator fits in a buffer of size n. Return new end pointer.
+const char* Fl_Input_::expand(const char* p, char* buf) const {
+ char* o = buf;
+ char* e = buf+(MAXBUF-4);
+ if (type()==FL_SECRET_INPUT) {
+ while (o<e && p < value_+size_) {*o++ = '*'; p++;}
+ } else while (o<e) {
+ if (p >= value_+size_) break;
+ int c = *p++ & 255;
+ if (c < ' ' || c == 127) {
+ if (c=='\n' && type()==FL_MULTILINE_INPUT) {p--; break;}
+ if (c == '\t' && type()==FL_MULTILINE_INPUT) {
+ for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' ';
+ } else {
+ *o++ = '^';
+ *o++ = c ^ 0x40;
+ }
+ } else if (c >= 128 && c < 0xA0) {
+ *o++ = '\\';
+ *o++ = (c>>6)+'0';
+ *o++ = ((c>>3)&7)+'0';
+ *o++ = (c&7)+'0';
+ } else if (c == 0xA0) { // nbsp
+ *o++ = ' ';
+ } else {
+ *o++ = c;
+ }
+ }
+ *o = 0;
+ return p;
+}
+
+// After filling in such a buffer, find the width to e
+double Fl_Input_::expandpos(
+ const char* p, // real string
+ const char* e, // pointer into real string
+ const char* buf, // conversion of real string by expand()
+ int* returnn // return offset into buf here
+) const {
+ int n = 0;
+ if (type()==FL_SECRET_INPUT) n = e-p;
+ else while (p<e) {
+ int c = *p++ & 255;
+ if (c < ' ' || c == 127) {
+ if (c == '\t' && type()==FL_MULTILINE_INPUT) n += 8-(n%8);
+ else n += 2;
+ } else if (c >= 128 && c < 0xA0) {
+ n += 4;
+ } else {
+ n++;
+ }
+ }
+ if (returnn) *returnn = n;
+ return fl_width(buf, n);
+}
+
+////////////////////////////////////////////////////////////////
+
+// minimal update:
+// Characters from mu_p to end of widget are redrawn.
+// If erase_cursor_only, small part at mu_p is redrawn.
+// Right now minimal update just keeps unchanged characters from
+// being erased, so they don't blink.
+
+void Fl_Input_::minimal_update(int p) {
+ if (damage() & 128) return; // don't waste time if it won't be done
+ if (damage() & 2) {
+ if (p < mu_p) mu_p = p;
+ } else {
+ mu_p = p;
+ }
+ damage(2);
+ erase_cursor_only = 0;
+}
+
+void Fl_Input_::minimal_update(int p, int q) {
+ if (q < p) p = q;
+ minimal_update(p);
+}
+
+////////////////////////////////////////////////////////////////
+
+static double up_down_pos;
+static int was_up_down;
+
+void Fl_Input_::setfont() const {
+ fl_font(textfont(), textsize(), default_font(), default_size());
+}
+
+void Fl_Input_::drawtext(int X, int Y, int W, int H) {
+
+ int do_mu = !(damage()&128);
+ if (Fl::focus()!=this && !size()) {
+ if (do_mu) { // we have to erase it if cursor was there
+ fl_color(color());
+ fl_rectf(X, Y, W, H);
+ }
+ return;
+ }
+
+ int selstart, selend;
+ if (Fl::focus()!=this && Fl::selection_owner()!=this && Fl::pushed()!=this)
+ selstart = selend = 0;
+ else if (position() <= mark()) {
+ selstart = position(); selend = mark();
+ } else {
+ selend = position(); selstart = mark();
+ }
+
+ setfont();
+
+#if 0 // patch to do auto-wrap written by Ian West
+ if ((type()==FL_MULTILINE_INPUT) && (value_==buffer) && (bufsize>=size_)) {
+ int wwidth = W-10;
+ int strtofln=0,lastsp=0,idx=0,lastbr=0;
+ while(idx <= size_){
+ if((buffer[idx] <= ' ') || (idx == size_)) {
+ if(buffer[idx] == '\n') lastbr=idx;
+ buffer[idx]=' ';
+ int twidth=(int)fl_width(&buffer[strtofln],idx-strtofln);
+ if ((twidth >= wwidth) && (lastsp > strtofln)) {
+// printf(stderr,"Line break, lastsp=%d, idx=%d, strtofln=%d, lastbr=%d\n",lastsp,idx,strtofln,lastbr);
+ buffer[lastsp]='\n';
+ if (lastsp != lastbr) {
+ if (lastsp < mu_p){
+ mu_p=lastsp;
+ erase_cursor_only = 0;
+ }
+ }
+ strtofln=lastsp+1;
+ } else {
+ lastsp=idx;
+ }
+ }
+ idx++;
+ }
+// fprintf(stderr,"Line length %d %d %d\n",(int)fl_width(buffer),size_, mu_p);
+// if(xscroll_ > 0) {xscroll_=0; mu_p=0;}
+ buffer[size_] = 0;
+ }
+#endif
+
+ const char *p, *e;
+ char buf[MAXBUF];
+
+ // count how many lines and put the last one into the buffer:
+ // And figure out where the cursor is:
+ int height = fl_height();
+ int lines;
+ int curx, cury;
+ for (p=value(), curx=cury=lines=0; ;) {
+ e = expand(p, buf);
+ if (position() >= p-value() && position() <= e-value()) {
+ curx = int(expandpos(p, value()+position(), buf, 0)+.5);
+ if (Fl::focus()==this && !was_up_down) up_down_pos = curx;
+ cury = lines*height;
+ if (Fl::focus()==this) {
+ int fullw = int(expandpos(p, e, buf, 0));
+ if (curx > xscroll_+W-20) {
+ xscroll_ = curx+20-W;
+ if (xscroll_ > fullw-W+2) xscroll_ = fullw-W+2;
+ mu_p = 0; erase_cursor_only = 0;
+ }
+ if (curx < xscroll_+20 && xscroll_) {
+ if (fullw > W-2) xscroll_ = curx-20;
+ else xscroll_ = 0;
+ mu_p = 0; erase_cursor_only = 0;
+ }
+ if (xscroll_ < 0) xscroll_ = 0;
+ }
+ }
+ lines++;
+ if (e >= value_+size_) break;
+ if (*e == '\n') e++;
+ p = e;
+ }
+
+ // adjust the scrolling:
+ if (type()==FL_MULTILINE_INPUT) {
+ int newy = yscroll_;
+ if (cury < newy) newy = cury;
+ if (cury > newy+H-height) newy = cury-H+height;
+ if (newy < -1) newy = -1;
+ if (newy != yscroll_) {yscroll_ = newy; mu_p = 0; erase_cursor_only = 0;}
+ } else {
+ yscroll_ = -(H-height)/2;
+ }
+
+ fl_clip(X, Y, W, H);
+ Fl_Color color = active_r() ? textcolor() : inactive(textcolor());
+
+ p = value();
+ // visit each line and draw it:
+ int desc = height-fl_descent();
+ int ypos = -yscroll_;
+ for (; ypos < H;) {
+
+ // re-expand line unless it is the last one calculated above:
+ if (lines>1) e = expand(p, buf);
+
+ if (ypos <= -height) goto CONTINUE; // clipped off top
+
+ if (do_mu) { // for minimal update:
+ const char* pp = value()+mu_p; // pointer to where minimal update starts
+ if (e >= pp && (!erase_cursor_only || p <= pp)) { // we must erase this
+ // calculate area to erase:
+ int x1 = -xscroll_;
+ if (p < pp) x1 += int(expandpos(p, pp, buf, 0));
+ // erase it:
+ fl_color(this->color());
+ fl_rectf(X+x1, Y+ypos, erase_cursor_only?2:W-x1, height);
+ // it now draws entire line over it
+ // this should not draw letters to left of erased area, but
+ // that is nyi.
+ }
+ }
+
+ // Draw selection area if required:
+ if (selstart < selend && selstart <= e-value() && selend > p-value()) {
+ const char* pp = value()+selstart;
+ int x1 = -xscroll_;
+ int offset1 = 0;
+ if (pp > p) {
+ fl_color(color);
+ x1 += int(expandpos(p, pp, buf, &offset1));
+ fl_draw(buf, offset1, X-xscroll_, Y+ypos+desc);
+ }
+ pp = value()+selend;
+ int x2 = W;
+ int offset2;
+ if (pp <= e) x2 = int(expandpos(p, pp, buf, &offset2))-xscroll_;
+ else offset2 = strlen(buf);
+ fl_color(selection_color());
+ fl_rectf(X+int(x1+.5), Y+ypos, int(x2-x1), height);
+ fl_color(contrast(textcolor(), selection_color()));
+ fl_draw(buf+offset1, offset2-offset1, X+x1, Y+ypos+desc);
+ if (pp < e) {
+ fl_color(color);
+ fl_draw(buf+offset2, X+x2, Y+ypos+desc);
+ }
+ } else {
+ // draw the cursor:
+ if (Fl::focus() == this && selstart == selend &&
+ position() >= p-value() && position() <= e-value()) {
+ fl_color(cursor_color());
+ fl_rectf(X+curx-xscroll_, Y+ypos, 2, height);
+ }
+ fl_color(color);
+ fl_draw(buf, X-xscroll_, Y+ypos+desc);
+ }
+ CONTINUE:
+ ypos += height;
+ if (e >= value_+size_) break;
+ if (*e == '\n') e++;
+ p = e;
+ }
+
+ // for minimal update, erase all lines below last one if necessary:
+ if (type()==FL_MULTILINE_INPUT && do_mu && ypos<H
+ && (!erase_cursor_only || p <= value()+mu_p)) {
+ if (ypos < 0) ypos = 0;
+ fl_color(this->color());
+ fl_rectf(X, Y+ypos, W, H-ypos);
+ }
+
+ fl_pop_clip();
+}
+
+static int isword(char c) {
+ return (c&128 || isalnum(c) || strchr("#%&-/@\\_~", c));
+}
+
+int Fl_Input_::wordboundary(int i) const {
+ if (i<=0 || i>=size()) return 1;
+ return isword(index(i-1)) != isword(index(i));
+}
+
+int Fl_Input_::lineboundary(int i) const {
+ if (i<=0 || i>=size()) return 1;
+ if (type() != FL_MULTILINE_INPUT) return 0;
+ return index(i-1) == '\n' || index(i) == '\n';
+}
+
+void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) {
+ was_up_down = 0;
+ if (!size()) return;
+ setfont();
+
+ const char *p, *e;
+ char buf[MAXBUF];
+
+ int theline = (type()==FL_MULTILINE_INPUT) ?
+ (Fl::event_y()-Y+yscroll_)/fl_height() : 0;
+
+ int newpos = 0;
+ for (p=value();; ) {
+ e = expand(p, buf);
+ theline--; if (theline < 0) break;
+ if (*e == '\n') e++;
+ p = e;
+ if (e >= value_+size_) break;
+ }
+ const char *l, *r, *t;
+ for (l = p, r = e; l<r; ) {
+ double f;
+ t = l+(r-l+1)/2;
+ f = X-xscroll_+expandpos(p, t, buf, 0);
+ if (f <= Fl::event_x()) l = t;
+ else r = t-1;
+ }
+ newpos = l-value();
+
+ int newmark = drag ? mark() : newpos;
+ if (Fl::event_clicks()) {
+ if (newpos >= newmark) {
+ if (newpos == newmark) {
+ if (newpos < size()) newpos++;
+ else newmark--;
+ }
+ if (Fl::event_clicks()>1) {
+ while (!lineboundary(newpos)) newpos++;
+ while (!lineboundary(newmark)) newmark--;
+ } else {
+ while (!wordboundary(newpos)) newpos++;
+ while (!wordboundary(newmark)) newmark--;
+ }
+ } else {
+ if (Fl::event_clicks()>1) {
+ while (!lineboundary(newpos)) newpos--;
+ } else {
+ while (!wordboundary(newpos)) newpos--;
+ }
+ }
+ }
+ position(newpos, newmark);
+}
+
+int Fl_Input_::position(int p, int m) {
+ was_up_down = 0;
+ if (p<0) p = 0;
+ if (p>size()) p = size();
+ if (m<0) m = 0;
+ if (m>size()) m = size();
+ if (p == position_ && m == mark_) return 0;
+ if (Fl::selection_owner() == this) Fl::selection_owner(0);
+ if (p != m) {
+ // new position is a selection
+ if (Fl::focus()==this || Fl::pushed()==this) {
+ if (p != position_) minimal_update(position_, p);
+ if (m != mark_) minimal_update(mark_, m);
+ }
+ } else if (Fl::focus() == this) {
+ // new position is a cursor
+ if (position_ == mark_) {
+ // old position was just a cursor
+ if (!(damage()&2)) {
+ minimal_update(position_); erase_cursor_only = 1;
+ }
+ } else { // old position was a selection
+ minimal_update(position_, mark_);
+ }
+ }
+ position_ = p;
+ mark_ = m;
+ return 1;
+}
+
+int Fl_Input_::up_down_position(int i, int keepmark) {
+ while (i > 0 && index(i-1) != '\n') i--; // go to start of line
+ double oldwid = 0.0;
+ setfont();
+ while (index(i) && index(i)!='\n') {
+ double tt = oldwid + fl_width(index(i));
+ if ((oldwid+tt)/2 >= up_down_pos) break;
+ oldwid = tt;
+ i++;
+ }
+ int j = position(i, keepmark ? mark_ : i);
+ was_up_down = 1;
+ return j;
+}
+
+int Fl_Input_::copy() {
+ if (mark() != position()) {
+ int b, e; if (position() < mark()) {
+ b = position(); e = mark();
+ } else {
+ e = position(); b = mark();
+ }
+ if (type()!=FL_SECRET_INPUT) Fl::selection(*this, value()+b, e-b);
+ return 1;
+ }
+ return 0;
+}
+
+#define MAXFLOATSIZE 40
+
+static char* undobuffer;
+static int undobufferlength;
+static Fl_Input_* undowidget;
+static int undoat; // points after insertion
+static int undocut; // number of characters deleted there
+static int undoinsert; // number of characters inserted
+static int yankcut; // length of valid contents of buffer, even if undocut=0
+
+static void undobuffersize(int n) {
+ if (n > undobufferlength) {
+ if (undobuffer) {
+ do {undobufferlength *= 2;} while (undobufferlength < n);
+ undobuffer = (char*)realloc(undobuffer, undobufferlength);
+ } else {
+ undobufferlength = n+9;
+ undobuffer = (char*)malloc(undobufferlength);
+ }
+ }
+}
+
+// all changes go through here, delete characters b-e and insert text:
+int Fl_Input_::replace(int b, int e, const char* text, int ilen) {
+
+ was_up_down = 0;
+
+ if (b<0) b = 0;
+ if (e<0) e = 0;
+ if (b>size_) b = size_;
+ if (e>size_) e = size_;
+ if (e<b) {int t=b; b=e; e=t;}
+ if (text && !ilen) ilen = strlen(text);
+ if (e<=b && !ilen) return 0; // don't clobber undo for a null operation
+ if (size_+ilen-(e-b) > maximum_size_) {
+ ilen = maximum_size_-size_+(e-b);
+ if (ilen < 0) ilen = 0;
+ }
+
+ put_in_buffer(size_+ilen);
+
+ if (e>b) {
+ if (undowidget == this && b == undoat) {
+ undobuffersize(undocut+(e-b));
+ memcpy(undobuffer+undocut, value_+b, e-b);
+ undocut += e-b;
+ } else if (undowidget == this && e == undoat && !undoinsert) {
+ undobuffersize(undocut+(e-b));
+ memmove(undobuffer+(e-b), undobuffer, undocut);
+ memcpy(undobuffer, value_+b, e-b);
+ undocut += e-b;
+ } else if (undowidget == this && e == undoat && (e-b)<undoinsert) {
+ undoinsert -= e-b;
+ } else {
+ undobuffersize(e-b);
+ memmove(undobuffer, value_+b, e-b);
+ undocut = e-b;
+ undoinsert = 0;
+ }
+ memcpy(buffer+b, buffer+e, size_-b+1);
+ size_ -= e-b;
+ undowidget = this;
+ undoat = b;
+ if (type() == FL_SECRET_INPUT) yankcut = 0; else yankcut = undocut;
+ }
+
+ if (ilen) {
+ size_ += ilen;
+ if (undowidget == this && b == undoat)
+ undoinsert += ilen;
+ else {
+ undocut = 0;
+ undoinsert = ilen;
+ }
+ int i;
+ for (i=size_; i>b; i--) buffer[i] = buffer[i-ilen];
+ for (i=0; i<ilen; i++) buffer[b+i] = text[i];
+ }
+ undowidget = this;
+ mark_ = position_ = undoat = b+ilen;
+
+ minimal_update(b);
+ if (when()&FL_WHEN_CHANGED) do_callback(); else set_changed();
+ return 1;
+}
+
+int Fl_Input_::undo() {
+ was_up_down = 0;
+ if (undowidget != this || !undocut && !undoinsert) return 0;
+
+ int ilen = undocut;
+ int xlen = undoinsert;
+ int b = undoat-xlen;
+ int b1 = b;
+
+ put_in_buffer(size_+ilen);
+
+ if (ilen) {
+ size_ += ilen;
+ int i;
+ for (i=size_; i>b; i--) buffer[i] = buffer[i-ilen];
+ for (i=0; i<ilen; i++) buffer[b++] = undobuffer[i];
+ }
+
+ if (xlen) {
+ undobuffersize(xlen);
+ memcpy(undobuffer, buffer+b, xlen);
+ memmove(buffer+b, buffer+b+xlen, size_-xlen-b);
+ size_ -= xlen;
+ }
+
+ undocut = xlen;
+ if (xlen) yankcut = xlen;
+ undoinsert = ilen;
+ undoat = b;
+ mark_ = b /* -ilen */;
+ position_ = b;
+
+ minimal_update(b1);
+ if (when()&FL_WHEN_CHANGED) do_callback(); else set_changed();
+ return 1;
+}
+
+#if 0
+int Fl_Input_::yank() {
+ // fake yank by trying to get it out of undobuffer
+ if (!yankcut) return 0;
+ return change(position(), position(), undobuffer, yankcut);
+}
+#endif
+
+int Fl_Input_::copy_cuts() {
+ // put the yank buffer into the X clipboard
+ if (!yankcut) return 0;
+ Fl::selection(*this, undobuffer, yankcut);
+ return 1;
+}
+
+void Fl_Input_::maybe_do_callback() {
+ if (changed() || (when()&FL_WHEN_NOT_CHANGED)) {
+ clear_changed(); do_callback();}
+}
+
+int Fl_Input_::handletext(int event, int X, int Y, int W, int H) {
+ switch (event) {
+
+ case FL_FOCUS:
+ if (mark_ == position_) {
+ minimal_update(size()+1);
+ } else if (Fl::selection_owner() != this)
+ minimal_update(mark_, position_);
+ return 1;
+
+ case FL_UNFOCUS:
+ if (mark_ == position_) {
+ if (!(damage()&2)) {minimal_update(position_); erase_cursor_only = 1;}
+ } else if (Fl::selection_owner() != this) {
+ minimal_update(mark_, position_);
+ }
+ if (when() & FL_WHEN_RELEASE) maybe_do_callback();
+ return 1;
+
+ case FL_PUSH:
+ handle_mouse(X, Y, W, H, Fl::event_state(FL_SHIFT));
+ return 1;
+
+ case FL_DRAG:
+ handle_mouse(X, Y, W, H, 1);
+ return 1;
+
+ case FL_RELEASE:
+// handle_mouse(X, Y, W, H, 1);
+ copy();
+ return 1;
+
+ case FL_SELECTIONCLEAR:
+ minimal_update(mark_, position_);
+ return 1;
+
+ case FL_PASTE: {
+ // strip trailing control characters and spaces before pasting:
+ const char* t = Fl::event_text();
+ const char* e = t+Fl::event_length();
+ if (type()!=FL_MULTILINE_INPUT) while (e > t && *(uchar*)(e-1) <= ' ') e--;
+ return replace(position(), mark(), t, e-t);}
+
+ default:
+ return 0;
+ }
+}
+
+/*------------------------------*/
+
+Fl_Input_::Fl_Input_(int x, int y, int w, int h, const char* l)
+: Fl_Widget(x, y, w, h, l) {
+ box(FL_NO_BOX);
+ color(FL_WHITE, FL_SELECTION_COLOR);
+ align(FL_ALIGN_LEFT);
+ textsize_ = FL_NORMAL_SIZE;
+ textfont_ = FL_HELVETICA;
+ textcolor_ = FL_BLACK;
+ cursor_color_ = FL_BLACK; // was FL_BLUE
+ mark_ = position_ = size_ = 0;
+ bufsize = 0;
+ value_ = "";
+ xscroll_ = yscroll_ = 0;
+ maximum_size_ = 32767;
+}
+
+void Fl_Input_::put_in_buffer(int len) {
+ if (value_ == buffer && bufsize > len) return;
+ if (!bufsize) {
+ if (len > size_) len += 9; // let a few characters insert before realloc
+ bufsize = len+1;
+ buffer = (char*)malloc(bufsize);
+ } else if (bufsize <= len) {
+ // we may need to move old value in case it points into buffer:
+ int moveit = (value_ >= buffer && value_ < buffer+bufsize);
+ // enlarge current buffer
+ if (len > size_) {
+ do {bufsize *= 2;} while (bufsize <= len);
+ } else {
+ bufsize = len+1;
+ }
+ char* nbuffer = (char*)realloc(buffer, bufsize);
+ if (moveit) value_ += (nbuffer-buffer);
+ buffer = nbuffer;
+ }
+ memmove(buffer, value_, size_); buffer[size_] = 0;
+ value_ = buffer;
+}
+
+int Fl_Input_::static_value(const char* str, int len) {
+ clear_changed();
+ if (undowidget == this) undowidget = 0;
+ if (str == value_ && len == size_) return 0;
+ if (len) { // non-empty new value:
+ if (xscroll_ || yscroll_) {
+ xscroll_ = yscroll_ = 0;
+ minimal_update(0);
+ } else {
+ int i = 0;
+ // find first different character:
+ if (value_) {
+ for (; i<size_ && i<len && str[i]==value_[i]; i++);
+ if (i==size_ && i==len) return 0;
+ }
+ minimal_update(i);
+ }
+ value_ = str;
+ size_ = len;
+ } else { // empty new value:
+ if (!size_) return 0; // both old and new are empty.
+ size_ = 0;
+ value_ = "";
+ xscroll_ = yscroll_ = 0;
+ minimal_update(0);
+ }
+ position(size(), 0);
+ return 1;
+}
+
+int Fl_Input_::static_value(const char* str) {
+ return static_value(str, str ? strlen(str) : 0);
+}
+
+int Fl_Input_::value(const char* str, int len) {
+ int r = static_value(str, len);
+ if (len) put_in_buffer(len);
+ return r;
+}
+
+int Fl_Input_::value(const char* str) {
+ return value(str, str ? strlen(str) : 0);
+}
+
+void Fl_Input_::resize(int X, int Y, int W, int H) {
+ if (W != w()) xscroll_ = 0;
+ if (H != h()) yscroll_ = 0;
+ Fl_Widget::resize(X, Y, W, H);
+}
+
+Fl_Input_::~Fl_Input_() {
+ if (undowidget == this) undowidget = 0;
+ if (bufsize) free((void*)buffer);
+}
+
+// end of Fl_Input_.C
diff --git a/src/Fl_Light_Button.cxx b/src/Fl_Light_Button.cxx
new file mode 100644
index 000000000..dcf7400f5
--- /dev/null
+++ b/src/Fl_Light_Button.cxx
@@ -0,0 +1,47 @@
+// Fl_Light_Button.C
+
+// Subclass of Fl_Button where the "box" indicates whether it is
+// pushed or not, and the "down box" is drawn small and square on
+// the left to indicate the current state.
+
+// The default down_box of zero draws a rectangle designed to look
+// just like Flame's buttons.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/fl_draw.H>
+
+void Fl_Light_Button::draw() {
+ if (box()) draw_box(this==Fl::pushed() ? down(box()) : box(), color());
+ Fl_Color col = value() ? selection_color() : color();
+ int d = h()/6;
+ int W = w()<h() ? w() : h();
+ if (down_box()) {
+ // draw other down_box() styles:
+ draw_box(down_box(), x()+d, y()+d+1, W-2*d-2, W-2*d-2, col);
+ } else {
+ // if down_box() is zero, draw light button style:
+ int hh = h()-2*d;
+ int ww = hh/2+1;
+ int xx = d*2;
+ if (w()<ww+2*xx) xx = (w()-ww)/2;
+ draw_box(FL_THIN_DOWN_BOX, x()+xx, y()+d, ww, hh, col);
+ }
+ draw_label(x()+W-d, y(), w()-W+d, h());
+}
+
+int Fl_Light_Button::handle(int event) {
+ switch (event) {
+ case FL_RELEASE:
+ if (box()) redraw();
+ default:
+ return Fl_Button::handle(event);
+ }
+}
+
+Fl_Light_Button::Fl_Light_Button(int x, int y, int w, int h, const char* l)
+: Fl_Button(x, y, w, h, l) {
+ type(FL_TOGGLE_BUTTON);
+ selection_color(FL_YELLOW);
+ align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+}
diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx
new file mode 100644
index 000000000..ddd80c80b
--- /dev/null
+++ b/src/Fl_Menu.cxx
@@ -0,0 +1,694 @@
+// Fl_Menu.C
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// Warning: this menu code is quite a mess!
+
+// This file contains code for implementing Fl_Menu_Item, and for
+// methods for bringing up popup menu hierarchies without using the
+// Fl_Menu_ widget.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Window.H>
+#include <FL/Fl_Menu_.H>
+#include <FL/fl_draw.H>
+
+int Fl_Menu_Item::size() const {
+ const Fl_Menu_Item* m = this;
+ int nest = 0;
+ for (;;) {
+ if (!m->text) {
+ if (!nest) return (m-this+1);
+ nest--;
+ } else if (m->flags & FL_SUBMENU) {
+ nest++;
+ }
+ m++;
+ }
+}
+
+const Fl_Menu_Item* Fl_Menu_Item::next(int n) const {
+ if (n < 0) return 0; // this is so selected==-1 returns NULL
+ const Fl_Menu_Item* m = this;
+ int nest = 0;
+ while (n>0) {
+ if (!m->text) {
+ if (!nest) return m;
+ nest--;
+ } else if (m->flags&FL_SUBMENU) {
+ nest++;
+ }
+ m++;
+ if (!nest && m->visible()) n--;
+ }
+ return m;
+}
+
+// appearance of current menus are pulled from this parent widget:
+static const Fl_Menu_* button;
+
+////////////////////////////////////////////////////////////////
+
+// tiny window for title of menu:
+class menutitle : public Fl_Menu_Window {
+ void draw();
+public:
+ const Fl_Menu_Item* menu;
+ menutitle(int X, int Y, int W, int H, const Fl_Menu_Item*);
+};
+
+// each vertical menu has one of these:
+class menuwindow : public Fl_Menu_Window {
+ void draw();
+ void drawentry(const Fl_Menu_Item*, int i, int erase);
+public:
+ menutitle* title;
+ int handle(int);
+ int itemheight; // zero == menubar
+ int numitems;
+ int selected;
+ int drawn_selected; // last redraw has this selected
+ const Fl_Menu_Item* menu;
+ menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H,
+ const Fl_Menu_Item* picked, const Fl_Menu_Item* title,
+ int menubar = 0);
+ ~menuwindow();
+ void set_selected(int);
+ int find_selected(int mx, int my);
+ int titlex(int);
+ void autoscroll(int);
+ void position(int x, int y);
+};
+
+#define BW 3 // border thickness
+#define LEFT 6 // between left edge of item and edge of box
+#define RIGHT 8 // between right edge of item and edge of box
+#define BOTTOM 4 // between bottom item and bottom of box
+#define LEADING 4 // extra vertical leading
+#define TOP 5 // between top item and top of box
+
+extern char fl_draw_shortcut;
+
+// width of label, including effect of & characters:
+int Fl_Menu_Item::measure(int* hp, const Fl_Menu_* m) const {
+ Fl_Label l;
+ l.value = text;
+ l.type = labeltype_;
+ l.font = labelsize_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA);
+ if (l.font < 4) l.font = (Fl_Font)(l.font | Fl_Menu_::default_font());
+ l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE;
+ l.size += Fl_Menu_::default_size();
+ l.color = labelcolor_;
+ fl_draw_shortcut = 1;
+ int w = 0; int h = 0; l.measure(w, hp ? *hp : h);
+ fl_draw_shortcut = 0;
+ if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) w += 14;
+ return w;
+}
+
+void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m,
+ int selected) const {
+ Fl_Label l;
+ l.value = text;
+ l.type = labeltype_;
+ l.font = labelsize_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA);
+ if (l.font < 4) l.font = (Fl_Font)(l.font | Fl_Menu_::default_font());
+ l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE;
+ l.size += Fl_Menu_::default_size();
+ l.color = !active() ? (labelcolor_|8) : labelcolor_;
+ Fl_Color color = m ? m->color() : FL_GRAY;
+ if (selected) {
+ Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR;
+ Fl_Boxtype b = m && m->down_box() ? m->down_box() : FL_FLAT_BOX;
+ if (contrast(r,color)!=r) { // back compatability boxtypes
+ if (selected == 2) { // menu title
+ r = color;
+ b = m ? m->box() : FL_UP_BOX;
+ } else {
+ r = (Fl_Color)(FL_COLOR_CUBE-1); // white
+ b = FL_THIN_UP_BOX;
+ }
+ } else {
+ l.color = contrast((Fl_Color)labelcolor_, r);
+ }
+ if (selected == 2) {
+ fl_draw_box(b, x, y, w, h, r);
+ x += LEFT;
+ w -= LEFT+RIGHT;
+ } else {
+ fl_draw_box(b, x-2, y-1, w+7, h+2, r);
+ }
+ }
+
+ if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) {
+ int y1 = y+(h-14)/2;
+ fl_color(FL_DARK3);
+ if (flags & FL_MENU_RADIO) {
+ fl_line(x-1, y1+7, x+5, y1+1, x+11, y1+7);
+ if (selected) {
+ fl_color(color);
+ fl_polygon(x, y1+7, x+5, y1+2, x+10, y1+7, x+5, y1+12);
+ }
+ fl_color(FL_LIGHT3); fl_line(x+11, y1+7, x+5, y1+13, x-1, y1+7);
+ if (value()) {
+ fl_color(FL_BLACK);
+ fl_polygon(x+1, y1+7, x+5, y1+3, x+9, y1+7, x+5, y1+11);
+ }
+ } else {
+ fl_yxline(x, y1+11, y1+2, x+9);
+ if (selected) {fl_color(color); fl_rectf(x+1, y1+3, 9, 9);}
+ fl_color(FL_LIGHT3); fl_xyline(x+1, y1+12, x+10, y1+3);
+ if (value()) {fl_color(FL_BLACK); fl_rectf(x+2, y1+4, 7, 7);}
+ }
+ x += 14; w -= 14;
+ }
+
+ fl_draw_shortcut = 1;
+ l.draw(x, y, w, h, FL_ALIGN_LEFT);
+ fl_draw_shortcut = 0;
+}
+
+menutitle::menutitle(int X, int Y, int W, int H, const Fl_Menu_Item* L) :
+ Fl_Menu_Window(X, Y, W, H, 0) {
+ end();
+ set_modal();
+ clear_border();
+ menu = L;
+ if (L->labelcolor_) clear_overlay();
+ box(FL_NO_BOX);
+}
+
+menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
+ const Fl_Menu_Item* picked, const Fl_Menu_Item* t,
+ int menubar)
+ : Fl_Menu_Window(X, Y, Wp, Hp, 0)
+{
+ end();
+ set_modal();
+ clear_border();
+ menu = m;
+ drawn_selected = -1;
+ box(FL_NO_BOX);
+ selected = -1;
+ {int i = 0;
+ if (m) for (const Fl_Menu_Item* m1=m; ; m1 = m1->next(), i++) {
+ if (picked) {
+ if (m1 == picked) {selected = i; picked = 0;}
+ else if (m1 > picked) {selected = i-1; picked = 0; Wp = Hp = 0;}
+ }
+ if (!m1->text) break;
+ }
+ numitems = i;}
+
+ if (menubar) {
+ itemheight = 0;
+ title = 0;
+ return;
+ }
+
+ itemheight = 1;
+
+ int hotKeysw = 0;
+ int Wtitle = 0;
+ int Htitle = 0;
+ if (t) Wtitle = t->measure(&Htitle, button);
+ int W = Wtitle;
+ if (m) for (; m->text; m = m->next()) {
+ int h; int w1 = m->measure(&h, button);
+ if (h+LEADING>itemheight) itemheight = h+LEADING;
+ if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14;
+ if (w1 > W) W = w1;
+ if (m->shortcut_) {
+ w1 = int(fl_width(fl_shortcut_label(m->shortcut_))) + 8;
+ if (w1 > hotKeysw) hotKeysw = w1;
+ }
+ if (m->labelcolor_) clear_overlay();
+ }
+ if (selected >= 0 && !Wp) X -= W/2;
+ W += hotKeysw+LEFT+RIGHT; if (Wp > W) W = Wp;
+
+ if (!Wp) {if (X < 0) X = 0; if (X > Fl::w()-W) X= Fl::w()-W;}
+ x(X); w(W);
+ h((numitems ? itemheight*numitems-LEADING : 0)+TOP+BOTTOM+1);
+ if (selected >= 0)
+ Y = Y+(Hp-itemheight)/2-selected*itemheight-2;
+ else
+ Y = Y+Hp;
+ if (m) y(Y-1); else {y(Y-3); w(1); h(1);}
+
+ if (t) {
+ int ht = button && button->h() <= 50 ? button->h()-6
+ : Htitle+TOP+BOTTOM-1;
+ title = new menutitle(X, Y-ht-3, Wtitle+LEFT+RIGHT, ht, t);
+ } else
+ title = 0;
+}
+
+menuwindow::~menuwindow() {
+ delete title;
+}
+
+void menuwindow::position(int X, int Y) {
+ if (title) {title->position(X, title->y()+Y-y());}
+ Fl_Menu_Window::position(X, Y);
+ x(X); y(Y); // don't wait for response from X
+}
+
+// scroll so item i is visible on screen
+void menuwindow::autoscroll(int i) {
+ int Y = y()+h()-(BOTTOM + (numitems-i)*itemheight - LEADING + 1);
+ if (Y <= 0) Y = -Y+10;
+ else {
+ Y = Y+itemheight-Fl::h();
+ if (Y <= 0) return;
+ Y = -Y-10;
+ }
+ Fl_Menu_Window::position(x(), y()+Y);
+ y(y()+Y); // don't wait for response from X
+}
+
+////////////////////////////////////////////////////////////////
+
+void menuwindow::drawentry(const Fl_Menu_Item* m, int i, int erase) {
+ if (!m) return; // this happens if -1 is selected item and redrawn
+
+ int x = LEFT-3;
+ int W = this->w();
+ int w = W-(LEFT+RIGHT-6);
+ int y = h()-(BOTTOM + (numitems-i)*itemheight - LEADING + 1);
+ int h = itemheight - LEADING;
+
+ if (erase && i != selected) {
+ fl_color(button ? button->color() : FL_GRAY);
+ fl_rectf(x+1, y-1, w+1, h+2);
+ }
+
+ m->draw(x+3, y, w-6, h, button, i==selected);
+
+ // the shortcuts and arrows assumme fl_color() was left set by draw():
+ if (m->submenu()) {
+ int y1 = y+(h-14)/2;
+ fl_polygon(x+w-10, y1+2, x+w-10, y1+2+10, x+w, y1+2+5);
+ } else if (m->shortcut_) {
+ Fl_Font f = button ? button->textfont() : FL_HELVETICA;
+ fl_font(f, button ? button->textsize() : FL_NORMAL_SIZE,
+ Fl_Menu_::default_font(), Fl_Menu_::default_size());
+ fl_draw(fl_shortcut_label(m->shortcut_), x, y, w-3, h, FL_ALIGN_RIGHT);
+ }
+
+ if (m->flags & FL_MENU_DIVIDER) {
+ fl_color(FL_DARK3);
+ fl_xyline(BW-1, y+h+1, W-BW);
+ fl_color(FL_LIGHT3);
+ fl_xyline(BW, y+h+2, W-BW);
+ }
+
+}
+
+void menutitle::draw() {
+ menu->draw(0, 0, w(), h(), button, 2);
+}
+
+void menuwindow::draw() {
+
+ if (damage() != 1) { // complete redraw
+ if (menu) {
+ fl_draw_box(button&&button->box() ? button->box() : FL_UP_BOX,
+ 0, 0, w(), h(),
+ button ? button->color() : FL_GRAY);
+ const Fl_Menu_Item* m; int i;
+ for (m=menu, i=0; m->text; i++, m = m->next()) drawentry(m, i, 0);
+ }
+ } else {
+ if (damage() & 1 && selected!=drawn_selected) { // change selection
+ drawentry(menu->next(drawn_selected), drawn_selected, 1);
+ drawentry(menu->next(selected), selected, 1);
+ }
+ }
+ drawn_selected = selected;
+}
+
+void menuwindow::set_selected(int i) {
+ if (i != selected) {selected = i; damage(1);}
+}
+
+////////////////////////////////////////////////////////////////
+
+int menuwindow::find_selected(int mx, int my) {
+ if (!menu || !menu->text) return -1;
+ mx -= x();
+ my -= y();
+ if (my <= 0 || my >= h()) return -1;
+ if (!itemheight) { // menubar
+ int x = BW; int i = 0;
+ const Fl_Menu_Item* m = menu;
+ for (; ; m = m->next(), i++) {
+ if (!m->text) return -1;
+ x += m->measure(0, button) + 16;
+ if (x > mx) break;
+ }
+ return i;
+ }
+ if (mx <= 0 || mx >= w()) return -1;
+ my -= h()-(BOTTOM + numitems*itemheight - LEADING + 2);
+ if (my <= 0) return -1;
+ int i = my/itemheight;
+ if (i>=numitems) i = numitems-1;
+ return i;
+}
+
+// return horizontal position for item i in a menubar:
+int menuwindow::titlex(int i) {
+ const Fl_Menu_Item* m;
+ int x = BW;
+ for (m=menu; i--; m = m->next()) x += m->measure(0, button) + 16;
+ return x;
+}
+
+// match shortcuts & label shortcuts, don't search submenus:
+// returns menu item and index
+const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip) const {
+ const Fl_Menu_Item* m1 = this;
+ for (int ii = 0; m1 && m1->text; m1 = m1->next(1), ii++) {
+ if (m1->activevisible() &&
+ (Fl::test_shortcut(m1->shortcut_)
+ || Fl_Widget::test_shortcut(m1->text))) {if (ip) *ip=ii; return m1;}
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////
+// Fl_Menu_Item::popup(...)
+
+// Because Fl::grab() is done, all events go to one of the menu windows.
+// But the handle method needs to look at all of them to find out
+// what item the user is pointing at. And it needs a whole lot
+// of other state variables to determine what is going on with
+// the currently displayed menus.
+// So the main loop (handlemenu()) puts all the state in a structure
+// and puts a pointer to it in a static location, so the handle()
+// on menus can refer to it and alter it. The handle() method
+// changes variables in this state to indicate what item is
+// picked, but does not actually alter the display, instead the
+// main loop does that. This is because the X mapping and unmapping
+// of windows is slow, and we don't want to fall behind the events.
+
+struct menustate {
+ const Fl_Menu_Item* current_item; // what mouse is pointing at
+ int menu_number; // which menu it is in
+ int item_number; // which item in that menu
+ menuwindow* p[20]; // pointers to menus
+ int nummenus;
+ int menubar; // if true p[0] is a menubar
+ int state; // 0 at first, 1 after push, 2 when done
+};
+static menustate* p;
+
+static inline void setitem(const Fl_Menu_Item* i, int m, int n) {
+ p->current_item = i;
+ p->menu_number = m;
+ p->item_number = n;
+}
+
+static void setitem(int m, int n) {
+ menustate &p = *(::p);
+ p.current_item = (m >= 0 && n >= 0) ?
+ p.current_item = p.p[m]->menu->next(n) : 0;
+ p.menu_number = m;
+ p.item_number = n;
+}
+
+static int forward(int menu) { // go to next item in menu menu if possible
+ menustate &p = *(::p);
+ menuwindow &m = *(p.p[menu]);
+ int item = (menu == p.menu_number) ? p.item_number : m.selected;
+ while (++item < m.numitems) {
+ const Fl_Menu_Item* m1 = m.menu->next(item);
+ if (m1->activevisible()) {setitem(m1, menu, item); return 1;}
+ }
+ return 0;
+}
+
+static int backward(int menu) { // previous item in menu menu if possible
+ menustate &p = *(::p);
+ menuwindow &m = *(p.p[menu]);
+ int item = (menu == p.menu_number) ? p.item_number : m.selected;
+ while (--item >= 0) {
+ const Fl_Menu_Item* m1 = m.menu->next(item);
+ if (m1->activevisible()) {setitem(m1, menu, item); return 1;}
+ }
+ return 0;
+}
+
+int menuwindow::handle(int e) {
+ menustate &p = *(::p);
+ switch (e) {
+ case FL_KEYBOARD:
+ switch (Fl::event_key()) {
+ case FL_Up:
+ if (p.menu_number < 0) setitem(0, 0);
+ if (p.menubar && p.menu_number == 0) ;
+ else if (backward(p.menu_number));
+ else if (p.menubar && p.menu_number==1) setitem(0, p.p[0]->selected);
+ return 1;
+ case FL_Down:
+ if (p.menu_number < 0) setitem(0, 0);
+ else if (p.menu_number || !p.menubar) forward(p.menu_number);
+ else if (p.menu_number < p.nummenus-1) forward(p.menu_number+1);
+ return 1;
+ case FL_Right:
+ if (p.menubar && (p.menu_number<=0 || p.menu_number==1 && p.nummenus==2))
+ forward(0);
+ else if (p.menu_number < p.nummenus-1) forward(p.menu_number+1);
+ return 1;
+ case FL_Left:
+ if (p.menubar && p.menu_number<=1) backward(0);
+ else if (p.menu_number>0)
+ setitem(p.menu_number-1, p.p[p.menu_number-1]->selected);
+ return 1;
+ case FL_Enter:
+ p.state = 2;
+ return 1;
+ case FL_Escape:
+ setitem(0, -1, 0);
+ p.state = 2;
+ return 1;
+ }
+ break;
+ case FL_SHORTCUT: {
+ for (int menu = p.nummenus; menu--;) {
+ menuwindow &mw = *(p.p[menu]);
+ int item; const Fl_Menu_Item* m = mw.menu->find_shortcut(&item);
+ if (m) {
+ setitem(m, menu, item);
+ if (!m->submenu()) p.state = 2;
+ return 1;
+ }
+ }} break;
+ case FL_PUSH:
+ //case FL_MOVE:
+ case FL_DRAG: {
+ int mx = Fl::event_x_root();
+ int my = Fl::event_y_root();
+ int item=0; int menu;
+ for (menu = p.nummenus-1; menu >= 0; menu--) {
+ item = p.p[menu]->find_selected(mx, my);
+ if (item >= 0) break;
+ }
+ setitem(menu, item);
+ if (e == FL_PUSH) {
+ // detect second click on a menu title:
+ if (p.current_item && item == p.p[menu]->selected) p.state = 3;
+ else p.state = 1;
+ }
+ } return 1;
+ case FL_RELEASE:
+ if (!p.current_item) {
+ if (p.state || !Fl::event_is_click()) p.state = 2;
+ } else {
+ if (p.state == 3 && Fl::event_is_click()) p.state = 2;
+ else if (p.current_item->activevisible() && !p.current_item->submenu())
+ p.state = 2;
+ }
+ return 1;
+ }
+ return Fl_Window::handle(e);
+}
+
+const Fl_Menu_Item* Fl_Menu_Item::pulldown(
+ int X, int Y, int W, int H,
+ const Fl_Menu_Item* initial_item,
+ const Fl_Menu_* pbutton,
+ const Fl_Menu_Item* t,
+ int menubar) const
+{
+ Fl_Group::current(0); // fix possible user error...
+
+ button = pbutton;
+ if (pbutton) {
+ for (Fl_Window* w = pbutton->window(); w; w = w->window()) {
+ X += w->x();
+ Y += w->y();
+ }
+ } else {
+ X += Fl::event_x_root()-Fl::event_x();
+ Y += Fl::event_y_root()-Fl::event_y();
+ }
+ menuwindow mw(this, X, Y, W, H, initial_item, t, menubar);
+ Fl::grab(mw);
+ menustate p; ::p = &p;
+ p.p[0] = &mw;
+ p.nummenus = 1;
+ p.menubar = menubar;
+ p.state = 0;
+
+ menuwindow* fakemenu = 0; // kludge for buttons in menubar
+
+ // preselected item, pop up submenus if necessary:
+ if (initial_item && mw.selected >= 0) {
+ setitem(0, mw.selected);
+ goto STARTUP;
+ }
+
+ p.current_item = 0; p.menu_number = -1; p.item_number = -1;
+ if (menubar) mw.handle(FL_DRAG); // find the initial menu
+ initial_item = p.current_item;
+ if (initial_item) goto STARTUP;
+
+ // the main loop, runs until p.state goes to 2:
+ for (;;) {
+
+ // make sure all the menus are shown:
+ {for (int k = menubar; k < p.nummenus; k++)
+ if (!p.p[k]->shown()) {
+ if (p.p[k]->title) p.p[k]->title->show();
+ p.p[k]->show();
+ }
+ }
+
+ // get events:
+ {const Fl_Menu_Item* oldi = p.current_item;
+ Fl::wait();
+ if (p.state == 2) break; // done.
+ if (p.current_item == oldi) continue;}
+ // only do rest if item changes:
+
+ delete fakemenu; fakemenu = 0; // turn off "menubar button"
+
+ if (!p.current_item) { // pointing at nothing
+ // turn off selection in deepest menu, but don't erase other menus:
+ p.p[p.nummenus-1]->set_selected(-1);
+ continue;
+ }
+
+ delete fakemenu; fakemenu = 0;
+ initial_item = 0; // stop the startup code
+ p.p[p.menu_number]->autoscroll(p.item_number);
+
+ STARTUP:
+ menuwindow& cw = *p.p[p.menu_number];
+ const Fl_Menu_Item* m = p.current_item;
+ if (!m->activevisible()) { // pointing at inactive item
+ cw.set_selected(-1);
+ initial_item = 0; // turn off startup code
+ continue;
+ }
+ cw.set_selected(p.item_number);
+
+ if (m==initial_item) initial_item=0; // stop the startup code if item found
+ if (m->submenu()) {
+ const Fl_Menu_Item* title = m;
+ const Fl_Menu_Item* menutable;
+ if (m->flags&FL_SUBMENU) menutable = m+1;
+ else menutable = (Fl_Menu_Item*)(m)->user_data_;
+ // figure out where new menu goes:
+ int nX, nY;
+ if (!p.menu_number && p.menubar) { // menu off a menubar:
+ nX = cw.x() + cw.titlex(p.item_number);
+ nY = cw.y() + cw.h();
+ initial_item = 0;
+ } else {
+ nX = cw.x() + cw.w();
+ nY = cw.y() + 1 + p.item_number * cw.itemheight;
+ title = 0;
+ }
+ if (initial_item) { // bring up submenu containing initial item:
+ menuwindow* n = new menuwindow(menutable,X,Y,W,H,initial_item,title);
+ p.p[p.nummenus++] = n;
+ // move all earlier menus to line up with this new one:
+ if (n->selected>=0) {
+ int dy = n->y()-nY;
+ int dx = n->x()-nX;
+ for (int menu = 0; menu <= p.menu_number; menu++) {
+ menuwindow* t = p.p[menu];
+ int nx = t->x()+dx; if (nx < 0) {nx = 0; dx = -t->x();}
+ int ny = t->y()+dy+1; if (ny < 0) {ny = 0; dy = -t->y()-1;}
+ t->position(nx, ny);
+ }
+ setitem(p.nummenus-1, n->selected);
+ goto STARTUP;
+ }
+ } else if (p.nummenus > p.menu_number+1 &&
+ p.p[p.menu_number+1]->menu == menutable) {
+ // the menu is already up:
+ while (p.nummenus > p.menu_number+2) delete p.p[--p.nummenus];
+ p.p[p.nummenus-1]->set_selected(-1);
+ } else {
+ // delete all the old menus and create new one:
+ while (p.nummenus > p.menu_number+1) delete p.p[--p.nummenus];
+ p.p[p.nummenus++]= new menuwindow(menutable,nX,nY,title?1:0,0,0,title);
+ }
+ } else { // !m->submenu():
+ while (p.nummenus > p.menu_number+1) delete p.p[--p.nummenus];
+ if (!p.menu_number && p.menubar) {
+ // kludge so "menubar buttons" turn "on" by using menu title:
+ fakemenu = new menuwindow(0,
+ cw.x()+cw.titlex(p.item_number),
+ cw.y()+cw.h(), 0, 0,
+ 0, m);
+ fakemenu->title->show();
+ }
+ }
+ }
+ const Fl_Menu_Item* m = p.current_item;
+ delete fakemenu;
+ while (p.nummenus>1) delete p.p[--p.nummenus];
+ mw.hide();
+ Fl::release();
+ return m;
+}
+
+const Fl_Menu_Item*
+Fl_Menu_Item::popup(
+ int X, int Y,
+ const char* title,
+ const Fl_Menu_Item* picked,
+ const Fl_Menu_* button
+ ) const
+{
+ static Fl_Menu_Item dummy; // static so it is all zeros
+ dummy.text = title;
+ return pulldown(X, Y, 0, 0, picked, button, title ? &dummy : 0);
+}
+
+const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const {
+ const Fl_Menu_Item* m = this;
+ const Fl_Menu_Item* ret = 0;
+ if (m) for (; m->text; m = m->next()) {
+ if (m->activevisible()) {
+ // return immediately any match of an item in top level menu:
+ if (Fl::test_shortcut(m->shortcut_)) return m;
+ // if (Fl_Widget::test_shortcut(m->text)) return m;
+ // only return matches from lower menu if nothing found in top menu:
+ if (!ret && m->submenu()) {
+ const Fl_Menu_Item* s =
+ (m->flags&FL_SUBMENU) ? m+1:(const Fl_Menu_Item*)m->user_data_;
+ ret = s->test_shortcut();
+ }
+ }
+ }
+ return ret;
+}
+
+// end of Fl_Menu.C
diff --git a/src/Fl_Menu_.cxx b/src/Fl_Menu_.cxx
new file mode 100644
index 000000000..a045b3489
--- /dev/null
+++ b/src/Fl_Menu_.cxx
@@ -0,0 +1,96 @@
+// Fl_Menu_.C
+
+// This is a base class for all items that have a menu:
+// Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice
+// This provides storage for a menu item, functions to add/modify/delete
+// items, and a call for when the user picks a menu item.
+
+// More code in Fl_Menu_add.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_.H>
+#include <stdlib.h>
+
+Fl_Font Fl_Menu_::default_font_;
+int Fl_Menu_::default_size_;
+
+int Fl_Menu_::value(const Fl_Menu_Item* m) {
+ clear_changed();
+ if (value_ != m) {value_ = m; return 1;}
+ return 0;
+}
+
+// When user picks a menu item, call this. It will do the callback.
+// Unfortunatly this also casts away const for the checkboxes, but this
+// was necessary so non-checkbox menus can really be declared const...
+const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) {
+ if (v) {
+ if (v->radio()) {
+ if (!v->value()) { // they are turning on a radio item
+ set_changed();
+ ((Fl_Menu_Item*)v)->setonly();
+ }
+ } else if (v->flags & FL_MENU_TOGGLE) {
+ set_changed();
+ ((Fl_Menu_Item*)v)->flags ^= FL_MENU_VALUE;
+ } else if (v != value_) { // normal item
+ set_changed();
+ }
+ value_ = v;
+ if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) {
+ if (changed() || when()&FL_WHEN_NOT_CHANGED) {
+ clear_changed();
+ if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this);
+ else do_callback();
+ }
+ }
+ }
+ return v;
+}
+
+// turn on one of a set of radio buttons
+void Fl_Menu_Item::setonly() {
+ flags |= FL_MENU_RADIO | FL_MENU_VALUE;
+ Fl_Menu_Item* j;
+ for (j = this; ; ) { // go down
+ if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines
+ j++;
+ if (!j->text || !j->radio()) break; // stop after group
+ j->clear();
+ }
+ for (j = this-1; ; j--) { // go up
+ if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break;
+ j->clear();
+ }
+}
+
+Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l)
+: Fl_Widget(X,Y,W,H,l) {
+ set_flag(SHORTCUT_LABEL);
+ box(FL_UP_BOX);
+ when(FL_WHEN_RELEASE_ALWAYS);
+ value_ = menu_ = 0;
+ alloc = 0;
+ selection_color(FL_SELECTION_COLOR);
+ textfont(FL_HELVETICA);
+ textsize(FL_NORMAL_SIZE);
+ textcolor(FL_BLACK);
+ down_box(FL_NO_BOX);
+}
+
+int Fl_Menu_::size() const {
+ if (!menu_) return 0;
+ return menu_->size();
+}
+
+void Fl_Menu_::menu(const Fl_Menu_Item* m) {
+ // if (alloc) clear();
+ alloc = 0;
+ value_ = menu_ = (Fl_Menu_Item*)m;
+}
+
+Fl_Menu_::~Fl_Menu_() {
+ // if (alloc) clear();
+}
+
+// end of Fl_Menu_.C
diff --git a/src/Fl_Menu_Bar.cxx b/src/Fl_Menu_Bar.cxx
new file mode 100644
index 000000000..763f1acb1
--- /dev/null
+++ b/src/Fl_Menu_Bar.cxx
@@ -0,0 +1,33 @@
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Bar.H>
+
+void Fl_Menu_Bar::draw() {
+ draw_box();
+ if (!menu() || !menu()->text) return;
+ const Fl_Menu_Item* m;
+ int X = x()+9;
+ for (m=menu(); m->text; m = m->next()) {
+ m->draw(X, y(), 0, h(), this);
+ X += m->measure(0,this) + 16;
+ }
+}
+
+int Fl_Menu_Bar::handle(int event) {
+ const Fl_Menu_Item* v;
+ if (menu() && menu()->text) switch (event) {
+ case FL_PUSH:
+ v = 0;
+ J1:
+ v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
+ picked(v);
+ return 1;
+ case FL_SHORTCUT:
+ v = menu()->test_shortcut();
+ if (v) {picked(v); return 1;}
+ v = menu()->find_shortcut();
+ if (v) goto J1;
+ return 0;
+ }
+ return 0;
+}
+
diff --git a/src/Fl_Menu_Button.cxx b/src/Fl_Menu_Button.cxx
new file mode 100644
index 000000000..96c250063
--- /dev/null
+++ b/src/Fl_Menu_Button.cxx
@@ -0,0 +1,57 @@
+// Fl_Menu_Button.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/fl_draw.H>
+
+void Fl_Menu_Button::draw() {
+ if (!box() || type()) return;
+ draw_box(box(), color());
+ draw_label();
+ if (box() == FL_FLAT_BOX) return; // for XForms compatability
+ int H = (labelsize()-3)&-2;
+ int X = x()+w()-H*2;
+ int Y = y()+(h()-H)/2;
+ fl_color(FL_DARK3); fl_line(X+H/2, Y+H, X, Y, X+H, Y);
+ fl_color(FL_LIGHT3); fl_line(X+H, Y, X+H/2, Y+H);
+}
+
+const Fl_Menu_Item* Fl_Menu_Button::popup() {
+ const Fl_Menu_Item* m;
+ if (!box() || type()) {
+ m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this);
+ } else {
+ m = menu()->pulldown(x(), y(), w(), h(), 0, this);
+ }
+ picked(m);
+ return m;
+}
+
+int Fl_Menu_Button::handle(int e) {
+ if (!menu() || !menu()->text) return 0;
+ switch (e) {
+ case FL_ENTER:
+ case FL_LEAVE:
+ return (box() && !type()) ? 1 : 0;
+ case FL_PUSH:
+ if (!box()) {
+ if (Fl::event_button() != 3) return 0;
+ } else if (type()) {
+ if (!(type() & (1 << (Fl::event_button()-1)))) return 0;
+ }
+ popup();
+ return 1;
+ case FL_SHORTCUT:
+ if (Fl_Widget::test_shortcut()) {popup(); return 1;}
+ return test_shortcut() != 0;
+ default:
+ return 0;
+ }
+}
+
+Fl_Menu_Button::Fl_Menu_Button(int X,int Y,int W,int H,const char *l)
+: Fl_Menu_(X,Y,W,H,l) {
+ down_box(FL_NO_BOX);
+}
+
+// end of Fl_Menu_Button.C
diff --git a/src/Fl_Menu_Window.cxx b/src/Fl_Menu_Window.cxx
new file mode 100644
index 000000000..f74db6ea2
--- /dev/null
+++ b/src/Fl_Menu_Window.cxx
@@ -0,0 +1,130 @@
+// Fl_Menu_Window.H
+
+// This is the window type used by Fl_Menu to make the pop-ups.
+// It draws in the overlay planes if possible.
+
+// Also here is the implementation of the mouse & keyboard grab,
+// which are used so that clicks outside the program's windows
+// can be used to dismiss the menus.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_Window.H>
+
+// WIN32 note: HAVE_OVERLAY is false
+#if HAVE_OVERLAY
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+static GC gc; // the GC used by all X windows
+extern uchar fl_overlay; // changes how fl_color(x) works
+#endif
+
+#include <stdio.h>
+
+void Fl_Menu_Window::show() {
+#if HAVE_OVERLAY
+ if (!shown() && overlay() && fl_find_overlay_visual()) {
+ XInstallColormap(fl_display, fl_overlay_colormap);
+ fl_background_pixel = int(fl_transparent_pixel);
+ Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+ fl_background_pixel = -1;
+ } else
+#endif
+ Fl_Single_Window::show();
+}
+
+void Fl_Menu_Window::flush() {
+#if HAVE_OVERLAY
+ if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;}
+ Fl_X *i = Fl_X::i(this);
+ fl_window = i->xid;
+ if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
+ fl_gc = gc;
+ fl_overlay = 1;
+ fl_clip_region(i->region); i->region = 0;
+ draw();
+ fl_overlay = 0;
+#else
+ Fl_Single_Window::flush();
+#endif
+}
+
+void Fl_Menu_Window::erase() {
+#if HAVE_OVERLAY
+ if (!gc || !shown()) return;
+//XSetForeground(fl_display, gc, 0);
+//XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h());
+ XClearWindow(fl_display, fl_xid(this));
+#endif
+}
+
+// Fix the colormap flashing on Maximum Impact Graphics by erasing the
+// menu before unmapping it:
+void Fl_Menu_Window::hide() {
+ erase();
+ Fl_Single_Window::hide();
+}
+
+Fl_Menu_Window::~Fl_Menu_Window() {
+ hide();
+}
+
+////////////////////////////////////////////////////////////////
+// "Grab" is done while menu systems are up. This has several effects:
+// Events are all sent to the "grab window", which does not even
+// have to be displayed (and in the case of Fl_Menu.C it isn't).
+// Under X override_redirect and save_under is done to new windows.
+// The system is also told to "grab" events and send them to this app.
+
+extern void fl_fix_focus();
+#ifdef WIN32
+HWND fl_capture; // for some reason we must keep forcing it back on!
+#endif
+
+void Fl::grab(Fl_Window& w) {
+ grab_ = &w;
+ fl_fix_focus();
+#ifdef WIN32
+ // this seems to have no effect...
+ SetCapture(fl_capture = fl_xid(first_window()));
+#else
+ XGrabPointer(fl_display,
+ fl_xid(first_window()),
+ 1,
+ ButtonPressMask|ButtonReleaseMask|
+ ButtonMotionMask|PointerMotionMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ 0,
+ fl_event_time);
+ XGrabKeyboard(fl_display,
+ fl_xid(first_window()),
+ 1,
+ GrabModeAsync,
+ GrabModeAsync,
+ fl_event_time);
+#endif
+}
+
+void Fl::release() {
+ grab_ = 0;
+ fl_fix_focus();
+#ifdef WIN32
+ fl_capture = 0;
+ ReleaseCapture();
+#else
+ XUngrabKeyboard(fl_display, fl_event_time);
+ XUngrabPointer(fl_display, fl_event_time);
+ // this flush is done in case the picked menu item goes into
+ // an infinite loop, so we don't leave the X server locked up:
+ XFlush(fl_display);
+#endif
+ return;
+}
+
+// end of Fl_Menu_Window.C
diff --git a/src/Fl_Menu_add.cxx b/src/Fl_Menu_add.cxx
new file mode 100644
index 000000000..1aee7517a
--- /dev/null
+++ b/src/Fl_Menu_add.cxx
@@ -0,0 +1,151 @@
+// Fl_Menu_add.C
+
+// Methods to alter the menu in an Fl_Menu_ widget.
+// This code is seperated so that it is not linked in if not used.
+
+// These functions are for emulation of Forms and for dynamically
+// changing the menus. They are in this source file so they are
+// not linked in if not used, which is what will happen if the
+// the program only uses constant menu tables.
+
+// Not at all guaranteed to be Forms compatable, especially with any
+// string with a % sign in it!
+
+#include <FL/Fl_Menu_.H>
+#include <string.h>
+#include <stdlib.h>
+
+int fl_old_shortcut(const char* s) {
+ if (!s || !*s) return 0;
+ int n = 0;
+ if (*s == '#') {n |= FL_ALT; s++;}
+ if (*s == '+') {n |= FL_SHIFT; s++;}
+ if (*s == '^') {n |= FL_CTRL; s++;}
+ return n | *s;
+}
+
+int Fl_Menu_Item::add(
+ const char *text,
+ int shortcut,
+ Fl_Callback *cb,
+ void *data,
+ int flags)
+{
+ Fl_Menu_Item *m;
+ const char *p;
+ char *q;
+ char buf[1024];
+
+ int size = this->size();
+ int flags1 = 0;
+ char* item;
+
+ m = this;
+
+ for (;;) { /* do all the supermenus: */
+
+ /* fill in the buf with name, changing \x to x: */
+ q = buf;
+ for (p=text; *p && *p != '/'; *q++ = *p++) if (*p=='\\') p++;
+ *q = 0;
+
+ item = buf;
+ if (*item == '_') {item++; flags1 = FL_MENU_DIVIDER;}
+ if (*p != '/') break; /* not a menu title */
+ text = p+1; /* point at item title */
+
+ /* find a matching menu title: */
+ for (; m->text; m = m->next())
+ if (m->flags&FL_SUBMENU && !strcmp(item,m->text)) break;
+
+ if (!m->text) { /* create a new menu */
+ memmove(m+2,m,sizeof(Fl_Menu_Item)*(this+size-m));
+ m->text = strdup(item);
+ m->shortcut_ = 0;
+ m->callback_ = 0;
+ m->user_data_ = 0;
+ m->flags = FL_SUBMENU|flags1;
+ m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
+ (m+1)->text = 0;
+ size += 2;
+ }
+ m++; /* go into the menu */
+ flags1 = 0;
+ }
+
+ /* find a matching menu item: */
+ for (; m->text; m = m->next())
+ if (!strcmp(m->text,item)) break;
+
+ if (!m->text) { /* add a new menu item */
+ memmove(m+1,m,sizeof(Fl_Menu_Item)*(this+size-m));
+ size++;
+ m->text = strdup(item);
+ }
+
+ /* fill it in */
+ m->shortcut_ = shortcut;
+ m->callback_ = cb;
+ m->user_data_ = data;
+ m->flags = flags|flags1;
+ m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
+
+ return m-this;
+}
+
+// this is really lame, it will crash if this many items are added:
+#define FL_MENU_MAXITEMS 128
+
+int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) {
+ if (!menu_) {
+ value_ = menu_ = new Fl_Menu_Item[FL_MENU_MAXITEMS+1];
+ alloc = 1;
+ menu_[0].text = 0;
+ }
+ return menu_->add(t,s,c,v,f);
+}
+
+int Fl_Menu_::add(const char *str) {
+ char buf[128];
+ int r = 0;
+ while (*str) {
+ int shortcut = 0;
+ char *c;
+ for (c = buf; *str && *str != '|'; str++) {
+ if (*str == '\t') {*c++ = 0; shortcut = fl_old_shortcut(str);}
+ else *c++ = *str;
+ }
+ *c = 0;
+ r = add(buf, shortcut, 0, 0, 0);
+ if (*str) str++;
+ }
+ return r;
+}
+
+void Fl_Menu_::replace(int i, const char *str) {
+ if (i<0 || i>=size()) return;
+ if (alloc) free((void *)menu_[i].text);
+ menu_[i].text = strdup(str);
+}
+
+void Fl_Menu_::remove(int i) {
+ int n = size();
+ if (i<0 || i>=n) return;
+ if (alloc) free((void *)menu_[i].text);
+ memmove(&menu_[i],&menu_[i+1],(n-i)*sizeof(Fl_Menu_Item));
+}
+
+void Fl_Menu_::clear() {
+ for (int i = size(); i--;)
+ if (menu_[i].text) free((void*)menu_[i].text);
+ if (alloc) {
+ delete[] menu_;
+ menu_ = 0;
+ alloc = 0;
+ } else if (menu_) {
+ menu_[0].text = 0;
+ value_ = menu_;
+ }
+}
+
+// end of Fl_Menu_.C
diff --git a/src/Fl_Menu_global.cxx b/src/Fl_Menu_global.cxx
new file mode 100644
index 000000000..ddbf8e1de
--- /dev/null
+++ b/src/Fl_Menu_global.cxx
@@ -0,0 +1,20 @@
+// Fl_Menu_global.C
+
+// Make all the shortcuts in this menu global.
+// Currently only one menu at a time and you cannot destruct the menu,
+// is this sufficient?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_.H>
+
+static Fl_Menu_* the_widget;
+
+static int handler(int e) {
+ if (e != FL_SHORTCUT || Fl::modal()) return 0;
+ return the_widget->test_shortcut() != 0;
+}
+
+void Fl_Menu_::global() {
+ if (!the_widget) Fl::add_handler(handler);
+ the_widget = this;
+}
diff --git a/src/Fl_Multi_Label.cxx b/src/Fl_Multi_Label.cxx
new file mode 100644
index 000000000..e2b59168b
--- /dev/null
+++ b/src/Fl_Multi_Label.cxx
@@ -0,0 +1,51 @@
+// Fl_Multi_Label.C
+
+// Allows two labels to be used on a widget (by having one of them
+// be one of these it allows an infinte number!)
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Multi_Label.H>
+
+static void multi_labeltype(
+ const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
+{
+ Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value);
+ Fl_Label local = *o;
+ local.value = b->labela;
+ local.type = b->typea;
+ int W = w; int H = h; local.measure(W, H);
+ local.draw(x,y,w,h,a);
+ if (a & FL_ALIGN_BOTTOM) h -= H;
+ else if (a & FL_ALIGN_TOP) {y += H; h -= H;}
+ else if (a & FL_ALIGN_RIGHT) w -= W;
+ else if (a & FL_ALIGN_LEFT) {x += W; w -= W;}
+ else {int d = (h+H)/2; y += d; h -= d;}
+ local.value = b->labelb;
+ local.type = b->typeb;
+ local.draw(x,y,w,h,a);
+}
+
+// measurement is only correct for left-to-right appending...
+static void multi_measure(const Fl_Label* o, int& w, int& h) {
+ Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value);
+ Fl_Label local = *o;
+ local.value = b->labela;
+ local.type = b->typea;
+ local.measure(w,h);
+ local.value = b->labelb;
+ local.type = b->typeb;
+ int W = 0; int H = 0; local.measure(W,H);
+ w += W; if (H>h) h = H;
+}
+
+void Fl_Multi_Label::label(Fl_Widget* o) {
+ Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure);
+ o->label(_FL_MULTI_LABEL, (const char*)this);
+}
+
+void Fl_Multi_Label::label(Fl_Menu_Item* o) {
+ Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure);
+ o->label(_FL_MULTI_LABEL, (const char*)this);
+}
diff --git a/src/Fl_Output.cxx b/src/Fl_Output.cxx
new file mode 100644
index 000000000..a6dba007e
--- /dev/null
+++ b/src/Fl_Output.cxx
@@ -0,0 +1,23 @@
+// Fl_Output.C
+
+// This subclass of Fl_Input_ does not allow user to edit the output.
+// Used to display output.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Output.H>
+#include <FL/fl_draw.H>
+
+void Fl_Output::draw() {
+ Fl_Boxtype b = box() ? box() : default_box();
+ if (damage() & 128) draw_box(b, color());
+ Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
+ w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
+}
+
+int Fl_Output::handle(int event) {
+ if (event == FL_FOCUS) return 0;
+ Fl_Boxtype b = box() ? box() : default_box();
+ return Fl_Input_::handletext(event,
+ x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
+ w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
+}
diff --git a/src/Fl_Overlay_Window.cxx b/src/Fl_Overlay_Window.cxx
new file mode 100644
index 000000000..7bbd85904
--- /dev/null
+++ b/src/Fl_Overlay_Window.cxx
@@ -0,0 +1,115 @@
+// Fl_Overlay_Window.C
+
+// A window using double-buffering and able to draw an overlay
+// on top of that. Uses the hardware to draw the overlay if
+// possible, otherwise it just draws in the front buffer.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Overlay_Window.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+void Fl_Overlay_Window::show() {
+ Fl_Double_Window::show();
+ if (overlay_ && overlay_ != this) overlay_->show();
+}
+
+void Fl_Overlay_Window::hide() {
+ Fl_Double_Window::hide();
+}
+
+void Fl_Overlay_Window::flush() {
+ // a non-zero argument copies entire back buffer to window, erasing
+ // the overlay. We should only do this if fake overlay needs redraw:
+ uchar overlay_damage = damage()&8; clear_damage(damage()&~8);
+ _flush(overlay_damage);
+ if (overlay_ == this) draw_overlay();
+}
+
+void Fl_Overlay_Window::resize(int X, int Y, int W, int H) {
+ Fl_Double_Window::resize(X,Y,W,H);
+ if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h());
+}
+
+Fl_Overlay_Window::~Fl_Overlay_Window() {
+ hide();
+// delete overlay; this is done by ~Fl_Group
+}
+
+#if !HAVE_OVERLAY
+
+int Fl_Overlay_Window::can_do_overlay() {return 0;}
+
+void Fl_Overlay_Window::redraw_overlay() {overlay_ = this; damage(8);}
+
+#else
+
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+static GC gc; // the GC used by all X windows
+extern uchar fl_overlay; // changes how fl_color(x) works
+
+class _Fl_Overlay : public Fl_Window {
+ friend class Fl_Overlay_Window;
+ void flush();
+ void show();
+public:
+ _Fl_Overlay(int x, int y, int w, int h) :
+ Fl_Window(x,y,w,h) {deactivate();}
+};
+
+int Fl_Overlay_Window::can_do_overlay() {
+ return fl_find_overlay_visual() != 0;
+}
+
+void _Fl_Overlay::show() {
+ if (shown()) {Fl_Window::show(); return;}
+ fl_background_pixel = int(fl_transparent_pixel);
+ Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+ fl_background_pixel = -1;
+ // find the outermost window to tell wm about the colormap:
+ Fl_Window *w = window();
+ for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
+ XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
+}
+
+void _Fl_Overlay::flush() {
+ fl_window = fl_xid(this);
+ if (!gc) gc = XCreateGC(fl_display, fl_xid(this), 0, 0);
+ fl_gc = gc;
+ fl_overlay = 1;
+ Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent();
+ Fl_X *i = Fl_X::i(this);
+ if (damage() != 2) XClearWindow(fl_display, fl_xid(this));
+ fl_clip_region(i->region); i->region = 0;
+ w->draw_overlay();
+ fl_overlay = 0;
+}
+
+void Fl_Overlay_Window::redraw_overlay() {
+ if (!fl_display) return; // this prevents fluid -c from opening display
+ if (!overlay_) {
+ if (can_do_overlay()) {
+ Fl_Group::current(this);
+ overlay_ = new _Fl_Overlay(0,0,w(),h());
+ Fl_Group::current(0);
+ } else {
+ overlay_ = this; // fake the overlay
+ }
+ }
+ if (shown()) {
+ if (overlay_ == this)
+ damage(8);
+ else if (!overlay_->shown())
+ overlay_->show();
+ else
+ overlay_->redraw();
+ }
+}
+
+#endif
+
+// End of Fl_Overlay_Window.C
diff --git a/src/Fl_Pack.cxx b/src/Fl_Pack.cxx
new file mode 100644
index 000000000..c236f29c6
--- /dev/null
+++ b/src/Fl_Pack.cxx
@@ -0,0 +1,78 @@
+// Fl_Pack.C
+
+// Based on code by Curtis Edwards
+// Group that compresses all it's children together and resizes to surround
+// them on each redraw (only if box() is zero)
+// Bugs: ?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Pack.H>
+#include <FL/fl_draw.H>
+
+Fl_Pack::Fl_Pack(int x,int y,int w ,int h,const char *l)
+: Fl_Group(x, y, w, h, l) {
+ resizable(0);
+ spacing_ = 0;
+ // type(VERTICAL); // already set like this
+}
+
+void Fl_Pack::draw() {
+ int tx = x()+Fl::box_dx(box());
+ int ty = y()+Fl::box_dy(box());
+ int tw = w()-Fl::box_dw(box());
+ int th = h()-Fl::box_dh(box());
+ int current_position = horizontal() ? tx : ty;
+ int maximum_position = current_position;
+ uchar d = damage();
+ Fl_Widget*const* a = array();
+ for (int i = children(); i--;) {
+ Fl_Widget* o = *a++;
+ int X,Y,W,H;
+ if (horizontal()) {
+ X = current_position;
+ W = o->w();
+ Y = ty;
+ H = th;
+ } else {
+ X = tx;
+ W = tw;
+ Y = current_position;
+ H = o->h();
+ }
+ if (spacing_ && current_position>maximum_position &&
+ (X != o->x() || Y != o->y() || d&128)) {
+ fl_color(color());
+ if (horizontal())
+ fl_rectf(maximum_position, ty, spacing_, th);
+ else
+ fl_rectf(tx, maximum_position, tw, spacing_);
+ }
+ if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) {
+ o->resize(X,Y,W,H);
+ o->clear_damage(~0);
+ }
+ if (d&128) draw_child(*o); else update_child(*o);
+ // child's draw() can change it's size, so use new size:
+ current_position += (horizontal() ? o->w() : o->h());
+ if (current_position > maximum_position)
+ maximum_position = current_position;
+ current_position += spacing_;
+ }
+ if (horizontal()) {
+ if (maximum_position < tx+tw) {
+ fl_color(color());
+ fl_rectf(maximum_position, ty, tx+tw-maximum_position, th);
+ }
+ tw = maximum_position-tx;
+ } else {
+ if (maximum_position < ty+th) {
+ fl_color(color());
+ fl_rectf(tx, maximum_position, tw, ty+th-maximum_position);
+ }
+ th = maximum_position-ty;
+ }
+ tw += Fl::box_dw(box()); if (tw <= 0) tw = 1;
+ th += Fl::box_dh(box()); if (th <= 0) th = 1;
+ if (tw != w() || th != h()) {Fl_Widget::resize(x(),y(),tw,th); d = 128;}
+ if (d&128) draw_box();
+}
diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx
new file mode 100644
index 000000000..3e4e1af11
--- /dev/null
+++ b/src/Fl_Pixmap.cxx
@@ -0,0 +1,113 @@
+// Fl_Pixmap.C
+
+// Draws X pixmap data, keeping it stashed in a server pixmap so it
+// redraws fast.
+
+// See fl_draw_pixmap.C for code used to get the actual data into pixmap.
+// Implemented without using the xpm library (which I can't use because
+// it interferes with the color cube used by fl_draw_image).
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Pixmap.H>
+
+extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.C to store mask
+void fl_restore_clip(); // in fl_rect.C
+
+void Fl_Pixmap::draw(int X, int Y, int W, int H, int cx,int cy) {
+ if (w<0) fl_measure_pixmap(data, w, h);
+ if (!w) return;
+ // clip the box down to the size of image, quit if empty:
+ if (cx < 0) {W += cx; X -= cx; cx = 0;}
+ if (cx+W > w) W = w-cx;
+ if (W <= 0) return;
+ if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+ if (cy+H > h) H = h-cy;
+ if (H <= 0) return;
+ if (!id) {
+ id = (ulong)fl_create_offscreen(w, h);
+ fl_begin_offscreen((Fl_Offscreen)id);
+#ifdef WIN32 // mask is nyi, instead use a constant color
+ fl_draw_pixmap(data, 0, 0, (Fl_Color)mask);
+#else
+ uchar *bitmap = 0;
+ fl_mask_bitmap = &bitmap;
+ fl_draw_pixmap(data, 0, 0, FL_BLACK);
+ fl_mask_bitmap = 0;
+ if (bitmap) {
+ mask = XCreateBitmapFromData(fl_display, fl_window,
+ (const char*)bitmap, (w+7)&-8, h);
+ delete[] bitmap;
+ }
+#endif
+ fl_end_offscreen();
+ }
+#ifndef WIN32
+ if (mask) {
+ // I can't figure out how to combine a mask with existing region,
+ // so cut the image down to a clipped rectangle:
+ int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
+ cx += nx-X; X = nx;
+ cy += ny-Y; Y = ny;
+ // make X use the bitmap as a mask:
+ XSetClipMask(fl_display, fl_gc, mask);
+ int ox = X-cx; if (ox < 0) ox += w;
+ int oy = Y-cy; if (oy < 0) oy += h;
+ XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
+ }
+#endif
+ fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
+#ifndef WIN32
+ if (mask) {
+ // put the old clip region back
+ XSetClipOrigin(fl_display, fl_gc, 0, 0);
+ fl_restore_clip();
+ }
+#endif
+}
+
+Fl_Pixmap::~Fl_Pixmap() {
+ if (id) fl_delete_offscreen((Fl_Offscreen)id);
+#ifndef WIN32
+ if (mask) fl_delete_offscreen((Fl_Offscreen)mask);
+#endif
+}
+
+static void pixmap_labeltype(
+ const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
+{
+ Fl_Pixmap* b = (Fl_Pixmap*)(o->value);
+ if (b->w<0) fl_measure_pixmap(b->data, b->w, b->h);
+ int cx;
+ if (a & FL_ALIGN_LEFT) cx = 0;
+ else if (a & FL_ALIGN_RIGHT) cx = b->w-w;
+ else cx = (b->w-w)/2;
+ int cy;
+ if (a & FL_ALIGN_TOP) cy = 0;
+ else if (a & FL_ALIGN_BOTTOM) cy = b->h-h;
+ else cy = (b->h-h)/2;
+ b->draw(x,y,w,h,cx,cy);
+}
+
+static void pixmap_measure(const Fl_Label* o, int& w, int& h) {
+ Fl_Pixmap* b = (Fl_Pixmap*)(o->value);
+ if (b->w<0) fl_measure_pixmap(b->data, b->w, b->h);
+ w = b->w;
+ h = b->h;
+}
+
+void Fl_Pixmap::label(Fl_Widget* o) {
+#ifdef WIN32
+ mask = o->color();
+#endif
+ Fl::set_labeltype(_FL_PIXMAP_LABEL, pixmap_labeltype, pixmap_measure);
+ o->label(_FL_PIXMAP_LABEL, (const char*)this);
+}
+
+void Fl_Pixmap::label(Fl_Menu_Item* o) {
+ Fl::set_labeltype(_FL_PIXMAP_LABEL, pixmap_labeltype, pixmap_measure);
+ o->label(_FL_PIXMAP_LABEL, (const char*)this);
+}
diff --git a/src/Fl_Positioner.cxx b/src/Fl_Positioner.cxx
new file mode 100644
index 000000000..017a4ef4d
--- /dev/null
+++ b/src/Fl_Positioner.cxx
@@ -0,0 +1,106 @@
+// Fl_Positioner.C
+
+// The positioner widget from Forms, gives 2D input
+// Written by: Mark Overmars
+
+#include <FL/Fl.H>
+#include <FL/Fl_Positioner.H>
+#include <FL/fl_draw.H>
+
+static double flinear(double val, double smin, double smax, double gmin, double gmax)
+{
+ if (smin == smax) return gmax;
+ else return gmin + (gmax - gmin) * (val - smin) / (smax - smin);
+}
+
+void Fl_Positioner::draw(int x, int y, int w, int h) {
+ int x1 = x + 4;
+ int y1 = y + 4;
+ int w1 = w - 2 * 4;
+ int h1 = h - 2 * 4;
+ int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5);
+ int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5);
+ draw_box(box(), x, y, w, h, color());
+ fl_color(selection_color());
+ fl_xyline(x1, yy, x1+w1);
+ fl_yxline(xx, y1, y1+h1);
+}
+
+void Fl_Positioner::draw() {
+ draw(x(), y(), w(), h());
+ draw_label();
+}
+
+int Fl_Positioner::value(double X, double Y) {
+ clear_changed();
+ if (X == xvalue_ && Y == yvalue_) return 0;
+ xvalue_ = X; yvalue_ = Y;
+ redraw();
+ return 1;
+}
+
+int Fl_Positioner::xvalue(double X) {
+ return(value(X, yvalue_));
+}
+
+int Fl_Positioner::yvalue(double Y) {
+ return(value(xvalue_, Y));
+}
+
+int Fl_Positioner::handle(int event, int x, int y, int w, int h) {
+ switch (event) {
+ case FL_PUSH:
+ case FL_DRAG:
+ case FL_RELEASE: {
+ double x1 = x + 4;
+ double y1 = y + 4;
+ double w1 = w - 2 * 4;
+ double h1 = h - 2 * 4;
+ double X = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax);
+ if (xstep_) X = int(X/xstep_+0.5) * xstep_;
+ if (X < xmin) X = xmin;
+ if (X > xmax) X = xmax;
+ double Y = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax);
+ if (ystep_) Y = int(Y/ystep_+0.5) * ystep_;
+ if (Y < ymin) Y = ymin;
+ if (Y > ymax) Y = ymax;
+ if (value(X, Y)) set_changed();}
+ if (!(when() & FL_WHEN_CHANGED ||
+ when() & FL_WHEN_RELEASE && event == FL_RELEASE)) return 1;
+ if (changed() || when()&FL_WHEN_NOT_CHANGED) {
+ clear_changed(); do_callback();}
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int Fl_Positioner::handle(int e) {
+ return handle(e, x(), y(), w(), h());
+}
+
+Fl_Positioner::Fl_Positioner(int x, int y, int w, int h, const char* l)
+: Fl_Widget(x, y, w, h, l) {
+ box(FL_DOWN_BOX);
+ selection_color(FL_RED);
+ align(FL_ALIGN_BOTTOM);
+ when(FL_WHEN_CHANGED);
+ xmin = ymin = 0;
+ xmax = ymax = 1;
+ xvalue_ = yvalue_ = .5;
+ xstep_ = ystep_ = 0;
+}
+
+void Fl_Positioner::xbounds(double a, double b) {
+ if (a != xmin || b != xmax) {
+ xmin = a; xmax = b;
+ redraw();
+ }
+}
+
+void Fl_Positioner::ybounds(double a, double b) {
+ if (a != ymin || b != ymax) {
+ ymin = a; ymax = b;
+ redraw();
+ }
+}
diff --git a/src/Fl_Repeat_Button.cxx b/src/Fl_Repeat_Button.cxx
new file mode 100644
index 000000000..e13e05c44
--- /dev/null
+++ b/src/Fl_Repeat_Button.cxx
@@ -0,0 +1,36 @@
+// Fl_Repeat_Button.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Repeat_Button.H>
+
+#define INITIALREPEAT .5
+#define REPEAT .1
+
+void Fl_Repeat_Button::repeat_callback(void *v) {
+ Fl_Button *b = (Fl_Button*)v;
+ Fl::add_timeout(REPEAT,repeat_callback,b);
+ b->do_callback();
+}
+
+int Fl_Repeat_Button::handle(int event) {
+ int newval;
+ switch (event) {
+ case FL_RELEASE:
+ newval = 0; goto J1;
+ case FL_PUSH:
+ case FL_DRAG:
+ newval = Fl::event_inside(this);
+ J1:
+ if (value(newval)) {
+ if (newval) {
+ Fl::add_timeout(INITIALREPEAT,repeat_callback,this);
+ do_callback();
+ } else {
+ Fl::remove_timeout(repeat_callback,this);
+ }
+ }
+ return 1;
+ default:
+ return Fl_Button::handle(event);
+ }
+}
diff --git a/src/Fl_Return_Button.cxx b/src/Fl_Return_Button.cxx
new file mode 100644
index 000000000..6d2e224ff
--- /dev/null
+++ b/src/Fl_Return_Button.cxx
@@ -0,0 +1,42 @@
+// Fl_Return_Button.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/fl_draw.H>
+
+int fl_return_arrow(int x, int y, int w, int h) {
+ int size = w; if (h<size) size = h;
+ int d = (size+2)/4; if (d<3) d = 3;
+ int t = (size+9)/12; if (t<1) t = 1;
+ int x0 = x+(w-2*d-2*t-1)/2;
+ int x1 = x0+d;
+ int y0 = y+h/2;
+ fl_color(FL_LIGHT3);
+ fl_line(x0, y0, x1, y0+d);
+ fl_yxline(x1, y0+d, y0+t, x1+d+2*t, y0-d);
+ fl_yxline(x1, y0-t, y0-d);
+ fl_color(fl_gray_ramp(0));
+ fl_line(x0, y0, x1+1, y0-d-1);
+ fl_color(FL_DARK3);
+ fl_xyline(x1+1, y0-t, x1+d, y0-d, x1+d+2*t);
+ return 1;
+}
+
+void Fl_Return_Button::draw() {
+ if (type() == FL_HIDDEN_BUTTON) return;
+ draw_box(value() ? (down_box()?down_box():down(box())) : box(),
+ value() ? selection_color() : color());
+ int W = h();
+ if (w()/3 < W) W = w()/3;
+ fl_return_arrow(x()+w()-W-4, y(), W, h());
+ draw_label(x(), y(), w()-W+4, h());
+}
+
+int Fl_Return_Button::handle(int event) {
+ if (event == FL_SHORTCUT &&
+ (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) {
+ do_callback();
+ return 1;
+ } else
+ return Fl_Button::handle(event);
+}
diff --git a/src/Fl_Roller.cxx b/src/Fl_Roller.cxx
new file mode 100644
index 000000000..5e175385f
--- /dev/null
+++ b/src/Fl_Roller.cxx
@@ -0,0 +1,111 @@
+// Fl_Roller.C
+
+// Rapid-App style knob
+
+#include <FL/Fl.H>
+#include <FL/Fl_Roller.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+int Fl_Roller::handle(int event) {
+ static int ipos;
+ int newpos = horizontal() ? Fl::event_x() : Fl::event_y();
+ switch (event) {
+ case FL_PUSH:
+ handle_push();
+ ipos = newpos;
+ return 1;
+ case FL_DRAG:
+ handle_drag(clamp(round(increment(previous_value(),newpos-ipos))));
+ return 1;
+ case FL_RELEASE:
+ handle_release();
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+void Fl_Roller::draw() {
+ if (damage()&128) draw_box();
+ int X = x()+Fl::box_dx(box());
+ int Y = y()+Fl::box_dy(box());
+ int W = w()-Fl::box_dw(box())-1;
+ int H = h()-Fl::box_dh(box())-1;
+ int offset = step() ? int(value()/step()) : 0;
+ const double ARC = 1.5; // 1/2 the number of radians visible
+ const double delta = .2; // radians per knurl
+ if (horizontal()) { // horizontal one
+ // draw shaded ends of wheel:
+ int h1 = W/4+1; // distance from end that shading starts
+ fl_color(color()); fl_rectf(X+h1,Y,W-2*h1,H);
+ for (int i=0; h1; i++) {
+ fl_color((Fl_Color)(FL_GRAY-i-1));
+ int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
+ fl_rectf(X+h2,Y,h1-h2,H);
+ fl_rectf(X+W-h1,Y,h1-h2,H);
+ h1 = h2;
+ }
+ // draw ridges:
+ double junk;
+ for (double y = -ARC+modf(offset*sin(ARC)/(W/2)/delta,&junk)*delta;;
+ y += delta) {
+ int y1 = int((sin(y)/sin(ARC)+1)*W/2);
+ if (y1 <= 0) continue; else if (y1 >= W-1) break;
+ fl_color(FL_DARK3); fl_yxline(X+y1,Y+1,Y+H-1);
+ if (y < 0) y1--; else y1++;
+ fl_color(FL_LIGHT1);fl_yxline(X+y1,Y+1,Y+H-1);
+ }
+ // draw edges:
+ h1 = W/8+1; // distance from end the color inverts
+ fl_color(FL_DARK2);
+ fl_xyline(X+h1,Y+H-1,X+W-h1);
+ fl_color(FL_DARK3);
+ fl_yxline(X,Y+H,Y,X+h1);
+ fl_xyline(X+W-h1,Y,X+W);
+ fl_color(FL_LIGHT2);
+ fl_xyline(X+h1,Y-1,X+W-h1);
+ fl_yxline(X+W,Y,Y+H,X+W-h1);
+ fl_xyline(X+h1,Y+H,X);
+ } else { // vertical one
+ // draw shaded ends of wheel:
+ int h1 = H/4+1; // distance from end that shading starts
+ fl_color(color()); fl_rectf(X,Y+h1,W,H-2*h1);
+ for (int i=0; h1; i++) {
+ fl_color((Fl_Color)(FL_GRAY-i-1));
+ int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
+ fl_rectf(X,Y+h2,W,h1-h2);
+ fl_rectf(X,Y+H-h1,W,h1-h2);
+ h1 = h2;
+ }
+ // draw ridges:
+ double junk;
+ for (double y = -ARC+modf(offset*sin(ARC)/(H/2)/delta,&junk)*delta;
+ ; y += delta) {
+ int y1 = int((sin(y)/sin(ARC)+1)*H/2);
+ if (y1 <= 0) continue; else if (y1 >= H-1) break;
+ fl_color(FL_DARK3); fl_xyline(X+1,Y+y1,X+W-1);
+ if (y < 0) y1--; else y1++;
+ fl_color(FL_LIGHT1);fl_xyline(X+1,Y+y1,X+W-1);
+ }
+ // draw edges:
+ h1 = H/8+1; // distance from end the color inverts
+ fl_color(FL_DARK2);
+ fl_yxline(X+W-1,Y+h1,Y+H-h1);
+ fl_color(FL_DARK3);
+ fl_xyline(X+W,Y,X,Y+h1);
+ fl_yxline(X,Y+H-h1,Y+H);
+ fl_color(FL_LIGHT2);
+ fl_yxline(X,Y+h1,Y+H-h1);
+ fl_xyline(X,Y+H,X+W,Y+H-h1);
+ fl_yxline(X+W,Y+h1,Y);
+ }
+}
+
+Fl_Roller::Fl_Roller(int X,int Y,int W,int H,const char* L)
+ : Fl_Valuator(X,Y,W,H,L) {
+ box(FL_UP_FRAME);
+ step(1,1000);
+}
+
+// end of Fl_Roller.C
diff --git a/src/Fl_Round_Button.cxx b/src/Fl_Round_Button.cxx
new file mode 100644
index 000000000..34a3eab72
--- /dev/null
+++ b/src/Fl_Round_Button.cxx
@@ -0,0 +1,15 @@
+// Fl_Round_Button.C
+
+// A subclass of Fl_Button that always draws as a round circle. This
+// circle is smaller than the widget size and can be surrounded by
+// another box type, for compatability with Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Round_Button.H>
+
+Fl_Round_Button::Fl_Round_Button(int x,int y,int w,int h, const char *l)
+: Fl_Light_Button(x,y,w,h,l) {
+ box(FL_NO_BOX);
+ down_box(FL_ROUND_DOWN_BOX);
+ selection_color(FL_RED);
+}
diff --git a/src/Fl_Scroll.cxx b/src/Fl_Scroll.cxx
new file mode 100644
index 000000000..b5cc49520
--- /dev/null
+++ b/src/Fl_Scroll.cxx
@@ -0,0 +1,210 @@
+// Fl_Scroll.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/fl_draw.H>
+
+// Insure the scrollbars are the last children:
+void Fl_Scroll::fix_scrollbar_order() {
+ Fl_Widget*const* a = array();
+ if (a[children()-1] != &scrollbar) {
+ Fl_Widget** a = (Fl_Widget**)array();
+ int i,j; for (i = j = 0; j < children(); j++)
+ if (a[j] != &hscrollbar && a[j] != &scrollbar) a[i++] = a[j];
+ a[i++] = &hscrollbar;
+ a[i++] = &scrollbar;
+ }
+}
+
+void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) {
+ fl_clip(X,Y,W,H);
+ Fl_Scroll* s = (Fl_Scroll*)v;
+ // erase background if there is a boxtype:
+ if (s->box() && !(s->damage()&128)) {
+ fl_color(s->color());
+ fl_rectf(X,Y,W,H);
+ }
+ Fl_Widget*const* a = s->array();
+ int R = X; int B = Y; // track bottom & right edge of all children
+ for (int i=s->children()-2; i--;) {
+ Fl_Widget& o = **a++;
+ s->draw_child(o);
+ s->draw_outside_label(o);
+ if (o.x()+o.w() > R) R = o.x()+o.w();
+ if (o.y()+o.h() > B) B = o.y()+o.h();
+ }
+ // fill any area to right & bottom of widgets:
+ if (R < X+W && B > Y) {
+ fl_color(s->color());
+ fl_rectf(R,Y,X+W-R,B-Y);
+ }
+ if (B < Y+H) {
+ fl_color(s->color());
+ fl_rectf(X,B,W,Y+H-B);
+ }
+ fl_pop_clip();
+}
+
+void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) {
+ X = x()+Fl::box_dx(box());
+ Y = y()+Fl::box_dy(box());
+ W = w()-Fl::box_dw(box());
+ H = h()-Fl::box_dh(box());
+ if (scrollbar.visible()) {
+ W -= scrollbar.w();
+ if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
+ }
+ if (hscrollbar.visible()) {
+ H -= hscrollbar.h();
+ if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h();
+ }
+}
+
+void Fl_Scroll::draw() {
+ fix_scrollbar_order();
+ int X,Y,W,H; bbox(X,Y,W,H);
+
+ uchar d = damage();
+
+ if (d & 128) { // full redraw
+ draw_box(box(),x(),y(),w(),h(),color());
+ draw_clip(this, X, Y, W, H);
+ } else {
+ if (d & 2) { // scroll the contents:
+ fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this);
+ }
+ if (d & 1) { // draw damaged children
+ fl_clip(X, Y, W, H);
+ Fl_Widget*const* a = array();
+ for (int i=children()-2; i--;) update_child(**a++);
+ fl_pop_clip();
+ }
+ }
+
+ // accumulate bounding box of children:
+ int l = X; int r = X; int t = Y; int b = Y;
+ Fl_Widget*const* a = array();
+ for (int i=children()-2; i--;) {
+ Fl_Object* o = *a++;
+ if (o->x() < l) l = o->x();
+ if (o->y() < t) t = o->y();
+ if (o->x()+o->w() > r) r = o->x()+o->w();
+ if (o->y()+o->h() > b) b = o->y()+o->h();
+ }
+
+ // turn the scrollbars on and off as necessary:
+ for (int z = 0; z<2; z++) {
+ if ((type()&VERTICAL) && (type()&ALWAYS_ON || t < Y || b > Y+H)) {
+ if (!scrollbar.visible()) {
+ scrollbar.set_visible();
+ W -= scrollbar.w();
+ d = 128;
+ }
+ } else {
+ if (scrollbar.visible()) {
+ scrollbar.clear_visible();
+ draw_clip(this,
+ scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W,
+ Y, scrollbar.w(), H);
+ W += scrollbar.w();
+ d = 128;
+ }
+ }
+ if ((type()&HORIZONTAL) && (type()&ALWAYS_ON || l < X || r > X+W)) {
+ if (!hscrollbar.visible()) {
+ hscrollbar.set_visible();
+ H -= hscrollbar.h();
+ d = 128;
+ }
+ } else {
+ if (hscrollbar.visible()) {
+ hscrollbar.clear_visible();
+ draw_clip(this, X,
+ scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
+ W, hscrollbar.h());
+ H += hscrollbar.h();
+ d = 128;
+ }
+ }
+ }
+
+ scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W,
+ Y, scrollbar.w(), H);
+ scrollbar.value(oldy = yposition_ = Y, H, t, b-t);
+
+ hscrollbar.resize(X,
+ scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
+ W, hscrollbar.h());
+ hscrollbar.value(oldx = xposition_ = X, W, l, r-l);
+
+ // draw the scrollbars:
+ if (d & 128) {
+ draw_child(scrollbar);
+ draw_child(hscrollbar);
+ if (scrollbar.visible() && hscrollbar.visible()) {
+ // fill in the little box in the corner
+ fl_color(color());
+ fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar.w(), hscrollbar.h());
+ }
+ } else {
+ update_child(scrollbar);
+ update_child(hscrollbar);
+ }
+}
+
+void Fl_Scroll::resize(int X, int Y, int W, int H) {
+ fix_scrollbar_order();
+ // move all the children:
+ Fl_Widget*const* a = array();
+ for (int i=children()-2; i--;) {
+ Fl_Object* o = *a++;
+ o->position(o->x()+X-x(), o->y()+Y-y());
+ }
+ Fl_Widget::resize(X,Y,W,H);
+}
+
+void Fl_Scroll::position(int X, int Y) {
+ int dx = xposition_-X;
+ int dy = yposition_-Y;
+ if (!dx && !dy) return;
+ xposition_ = X;
+ yposition_ = Y;
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o == &hscrollbar || o == &scrollbar) continue;
+ o->position(o->x()+dx, o->y()+dy);
+ }
+ damage(2);
+}
+
+void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) {
+ Fl_Scroll* s = (Fl_Scroll*)(o->parent());
+ s->position(int(((Fl_Scrollbar*)o)->value()), s->yposition());
+}
+
+void Fl_Scroll::scrollbar_cb(Fl_Widget* o, void*) {
+ Fl_Scroll* s = (Fl_Scroll*)(o->parent());
+ s->position(s->xposition(), int(((Fl_Scrollbar*)o)->value()));
+}
+
+#define SLIDER_WIDTH 17
+
+Fl_Scroll::Fl_Scroll(int X,int Y,int W,int H,const char* L)
+ : Fl_Group(X,Y,W,H,L),
+ scrollbar(X+W-SLIDER_WIDTH,Y,SLIDER_WIDTH,H-SLIDER_WIDTH),
+ hscrollbar(X,Y+H-SLIDER_WIDTH,W-SLIDER_WIDTH,SLIDER_WIDTH) {
+ type(BOTH);
+ xposition_ = 0;
+ yposition_ = 0;
+ hscrollbar.type(FL_HORIZONTAL);
+ hscrollbar.callback(hscrollbar_cb);
+ scrollbar.callback(scrollbar_cb);
+}
+
+int Fl_Scroll::handle(int event) {
+ fix_scrollbar_order();
+ return Fl_Group::handle(event);
+}
+
+// end of Fl_Scroll.C
diff --git a/src/Fl_Scrollbar.cxx b/src/Fl_Scrollbar.cxx
new file mode 100644
index 000000000..4863d9431
--- /dev/null
+++ b/src/Fl_Scrollbar.cxx
@@ -0,0 +1,158 @@
+// Fl_Scrollbar.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Scrollbar.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+#define INITIALREPEAT .5
+#define REPEAT .05
+
+void Fl_Scrollbar::increment_cb() {
+ handle_drag(clamp(value() + (
+ ((pushed_>1) == (maximum()>=minimum())) ? linesize_ : -linesize_)));
+}
+
+void Fl_Scrollbar::timeout_cb(void* v) {
+ Fl_Scrollbar* s = (Fl_Scrollbar*)v;
+ s->increment_cb();
+ Fl::add_timeout(REPEAT, timeout_cb, s);
+}
+
+int Fl_Scrollbar::handle(int event) {
+ if (!pushed_) {
+ if (horizontal()) {
+ if (w() < 3*h()) return Fl_Slider::handle(event);
+ if (Fl_Slider::handle(event, x()+h(), y(), w()-2*h(), h())) return 1;
+ } else {
+ if (h() < 3*w()) return Fl_Slider::handle(event);
+ if (Fl_Slider::handle(event, x(), y()+w(), w(), h()-2*w())) return 1;
+ }
+ }
+ switch (event) {
+ case FL_RELEASE:
+ if (pushed_) {
+ Fl::remove_timeout(timeout_cb, this);
+ pushed_ = 0;
+ redraw();
+ }
+ handle_release();
+ return 1;
+ case FL_PUSH:
+ if (horizontal()) {
+ if (Fl::event_inside(x(), y(), h(), h())) pushed_ = 1;
+ if (Fl::event_inside(x()+w()-h(), y(), h(), h())) pushed_ = 2;
+ } else {
+ if (Fl::event_inside(x(), y(), w(), w())) pushed_ = 1;
+ if (Fl::event_inside(x(), y()+h()-w(), w(), w())) pushed_ = 2;
+ }
+ if (pushed_) {
+ handle_push();
+ Fl::add_timeout(INITIALREPEAT, timeout_cb, this);
+ increment_cb();
+ redraw();
+ }
+ return 1;
+ case FL_DRAG:
+ return pushed_;
+ case FL_SHORTCUT: {
+ int v = value();
+ int ls = maximum()>=minimum() ? linesize_ : -linesize_;
+ if (horizontal()) {
+ switch (Fl::event_key()) {
+ case FL_Left:
+ v -= ls;
+ break;
+ case FL_Right:
+ v += ls;
+ break;
+ default:
+ return 0;
+ }
+ } else { // vertical
+ switch (Fl::event_key()) {
+ case FL_Up:
+ v -= ls;
+ break;
+ case FL_Down:
+ v += ls;
+ break;
+ case FL_Page_Up:
+ if (slider_size() >= 1.0) return 0;
+ v -= int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
+ v += ls;
+ break;
+ case FL_Page_Down:
+ if (slider_size() >= 1.0) return 0;
+ v += int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
+ v -= ls;
+ break;
+ case FL_Home:
+ v = int(minimum());
+ break;
+ case FL_End:
+ v = int(maximum());
+ break;
+ default:
+ return 0;
+ }
+ }
+ v = int(clamp(v));
+ if (v != value()) {
+ Fl_Slider::value(v);
+ value_damage();
+ do_callback();
+ }
+ return 1;}
+ }
+ return 0;
+}
+
+void Fl_Scrollbar::draw() {
+ if (horizontal()) {
+ if (w() < 3*h()) {Fl_Slider::draw(); return;}
+ Fl_Slider::draw(x()+h(), y(), w()-2*h(), h());
+ if (damage()&128) {
+ draw_box((pushed_&1) ? down(slider()) : slider(),
+ x(), y(), h(), h(), selection_color());
+ draw_box((pushed_&2) ? down(slider()) : slider(),
+ x()+w()-h(), y(), h(), h(), selection_color());
+ fl_color(labelcolor());
+ int w1 = (h()-1)|1; // use odd sizes only
+ int Y = y()+w1/2;
+ int W = w1/3;
+ int X = x()+w1/2+W/2;
+ fl_polygon(X-W, Y, X, Y-W, X, Y+W);
+ X = x()+w()-(X-x())-1;
+ fl_polygon(X+W, Y, X, Y+W, X, Y-W);
+ }
+ } else { // vertical
+ if (h() < 3*w()) {Fl_Slider::draw(); return;}
+ Fl_Slider::draw(x(), y()+w(), w(), h()-2*w());
+ if (damage()&128) {
+ draw_box((pushed_&1) ? down(slider()) : slider(),
+ x(), y(), w(), w(), selection_color());
+ draw_box((pushed_&2) ? down(slider()) : slider(),
+ x(), y()+h()-w(), w(), w(), selection_color());
+ fl_color(labelcolor());
+ int w1 = (w()-1)|1; // use odd sizes only
+ int X = x()+w1/2;
+ int W = w1/3;
+ int Y = y()+w1/2+W/2;
+ fl_polygon(X, Y-W, X+W, Y, X-W, Y);
+ Y = y()+h()-(Y-y())-1;
+ fl_polygon(X, Y+W, X-W, Y, X+W, Y);
+ }
+ }
+}
+
+Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L)
+ : Fl_Slider(X, Y, W, H, L)
+{
+ box(FL_FLAT_BOX);
+ color(FL_DARK2);
+ slider(FL_UP_BOX);
+ linesize_ = 16;
+ pushed_ = 0;
+ step(1);
+}
diff --git a/src/Fl_Single_Window.cxx b/src/Fl_Single_Window.cxx
new file mode 100644
index 000000000..6bfe091a5
--- /dev/null
+++ b/src/Fl_Single_Window.cxx
@@ -0,0 +1,14 @@
+/* Fl_Single_Window.H
+
+ A window with a single-buffered context
+
+ This is provided for systems where the base class is double
+ buffered. You can turn it off using this subclass in case
+ your display looks better without it.
+
+*/
+
+#include <FL/Fl_Single_Window.H>
+
+void Fl_Single_Window::show() {Fl_Window::show();}
+void Fl_Single_Window::flush() {Fl_Window::flush();}
diff --git a/src/Fl_Slider.cxx b/src/Fl_Slider.cxx
new file mode 100644
index 000000000..6d062a608
--- /dev/null
+++ b/src/Fl_Slider.cxx
@@ -0,0 +1,200 @@
+// Fl_Slider.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Slider.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+
+void Fl_Slider::_Fl_Slider() {
+ slider_size_ = 0;
+ slider_ = 0; // FL_UP_BOX;
+}
+
+Fl_Slider::Fl_Slider(int x, int y, int w, int h, const char* l)
+: Fl_Valuator(x, y, w, h, l) {
+ box(FL_DOWN_BOX);
+ _Fl_Slider();
+}
+
+Fl_Slider::Fl_Slider(uchar t, int x, int y, int w, int h, const char* l)
+ : Fl_Valuator(x, y, w, h, l) {
+ type(t);
+ box(t==FL_HOR_NICE_SLIDER || t==FL_VERT_NICE_SLIDER ?
+ FL_FLAT_BOX : FL_DOWN_BOX);
+ _Fl_Slider();
+}
+
+void Fl_Slider::slider_size(double v) {
+ if (v < 0) v = 0;
+ if (v > 1) v = 1;
+ if (slider_size_ != float(v)) {slider_size_ = float(v); damage(2);}
+}
+
+void Fl_Slider::bounds(double a, double b) {
+ if (minimum() != a || maximum() != b) {Fl_Valuator::bounds(a, b); damage(2);}
+}
+
+int Fl_Slider::scrollvalue(int p, int w, int t, int l) {
+// p = position, first line displayed
+// w = window, number of lines displayed
+// t = top, number of first line
+// l = length, total number of lines
+ step(1, 1);
+ if (p+w > t+l) l = p+w-t;
+ slider_size(w >= l ? 1.0 : double(w)/double(l));
+ bounds(t, l-w+t);
+ return value(p);
+}
+
+// All slider interaction is done as though the slider ranges from
+// zero to one, and the left (bottom) edge of the slider is at the
+// given position. Since when the slider is all the way to the
+// right (top) the left (bottom) edge is not all the way over, a
+// position on the widget itself covers a wider range than 0-1,
+// actually it ranges from 0 to 1/(1-size).
+
+void Fl_Slider::draw_bg(int x, int y, int w, int h) {
+ draw_box(box(), x, y, w, h, color());
+ int BW = Fl::box_dx(box());
+ if (type() == FL_VERT_NICE_SLIDER) {
+ draw_box(FL_THIN_DOWN_BOX, x+w/2-2, y+BW, 4, h-2*BW, FL_BLACK);
+ } else if (type() == FL_HOR_NICE_SLIDER) {
+ draw_box(FL_THIN_DOWN_BOX, x+BW, y+h/2-2, w-2*BW, 4, FL_BLACK);
+ }
+}
+
+void Fl_Slider::draw(int x, int y, int w, int h) {
+ double val;
+
+ if (minimum() == maximum())
+ val = 0.5;
+ else {
+ val = (value()-minimum())/(maximum()-minimum());
+ if (val > 1.0) val = 1.0;
+ else if (val < 0.0) val = 0.0;
+ }
+
+ int BW = Fl::box_dx(box());
+ int W = (horizontal() ? w : h) - 2*BW;
+ int X, S;
+ if (type()==FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) {
+ S = int(val*W+.5);
+ if (minimum()>maximum()) {S = W-S; X = h-BW-S;}
+ else X = BW;
+ } else {
+ S = int(slider_size_*W+.5);
+ int T = (horizontal() ? h : w)/2-BW+1;
+ if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4;
+ if (S < T) S = T;
+ X = BW+int(val*(W-S)+.5);
+ }
+ int xsl, ysl, wsl, hsl;
+ if (horizontal()) {
+ xsl = x+X;
+ wsl = S;
+ ysl = y+BW;
+ hsl = h-2*BW;
+ } else {
+ ysl = y+X;
+ hsl = S;
+ xsl = x+BW;
+ wsl = w-2*BW;
+ }
+
+ if (damage()&128) { // complete redraw
+ draw_bg(x, y, w, h);
+ } else { // partial redraw, clip off new position of slider
+ if (X > BW) {
+ if (horizontal()) fl_clip(x, ysl, X, hsl);
+ else fl_clip(xsl, y, wsl, X);
+ draw_bg(x, y, w, h);
+ fl_pop_clip();
+ }
+ if (X+S < W+BW) {
+ if (horizontal()) fl_clip(xsl+wsl, ysl, x+w-BW-xsl-wsl, hsl);
+ else fl_clip(xsl, ysl+hsl, wsl, y+h-BW-ysl-hsl);
+ draw_bg(x, y, w, h);
+ fl_pop_clip();
+ }
+ }
+
+ Fl_Boxtype box1 = slider();
+ if (!box1) {box1 = (Fl_Boxtype)(box()&-2); if (!box1) box1 = FL_UP_BOX;}
+ if (type() == FL_VERT_NICE_SLIDER) {
+ draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY);
+ int d = (hsl-4)/2;
+ draw_box(FL_THIN_DOWN_BOX, xsl+2, ysl+d, wsl-4, hsl-2*d,selection_color());
+ } else if (type() == FL_HOR_NICE_SLIDER) {
+ draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY);
+ int d = (wsl-4)/2;
+ draw_box(FL_THIN_DOWN_BOX, xsl+d, ysl+2, wsl-2*d, hsl-4,selection_color());
+ } else {
+ if (wsl>0 && hsl>0) draw_box(box1, xsl, ysl, wsl, hsl, selection_color());
+ }
+
+ draw_label(xsl, ysl, wsl, hsl);
+}
+
+void Fl_Slider::draw() {
+ draw(x(), y(), w(), h());
+}
+
+int Fl_Slider::handle(int event, int x, int y, int w, int h) {
+ switch (event) {
+ case FL_PUSH:
+ if (!Fl::event_inside(x, y, w, h)) return 0;
+ handle_push();
+ case FL_DRAG: {
+ if (slider_size() >= 1 || minimum()==maximum()) return 1;
+ int BW = Fl::box_dx(box());
+ int W = (horizontal() ? w : h) - 2*BW;
+ int X = (horizontal() ? Fl::event_x()-x : Fl::event_y()-y) - BW;
+ int S = int(slider_size_*W+.5);
+ int T = (horizontal() ? h : w)/2-BW+1;
+ if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4;
+ if (S < T) S = T;
+ double v = double(X)/(W-S);
+ double sliderwidth = double(S)/(W-S);
+ double val = (value()-minimum())/(maximum()-minimum());
+ static double offcenter;
+ if (event == FL_PUSH) {
+ offcenter = v-val;
+ if (offcenter < 0) offcenter = 0;
+ else if (offcenter > sliderwidth) offcenter = sliderwidth;
+ else return 1;
+ }
+ TRY_AGAIN:
+ v -= offcenter;
+ if (v < 0) {
+ offcenter = v+offcenter;
+ if (offcenter<0) offcenter=0;
+ v = 0;
+ } else if (v > 1) {
+ offcenter = v+offcenter-1;
+ if (offcenter > sliderwidth) offcenter = sliderwidth;
+ v = 1;
+ }
+ // if (Fl::event_state(FL_SHIFT)) v = val+(v-val)*.05;
+ v = round(v*(maximum()-minimum())+minimum());
+ // make sure a click outside the sliderbar moves it:
+ if (event == FL_PUSH && v == value()) {
+ offcenter = sliderwidth/2;
+ v = double(X)/(W-S);
+ event = FL_DRAG;
+ goto TRY_AGAIN;
+ }
+ handle_drag(clamp(v));
+ } return 1;
+ case FL_RELEASE:
+ handle_release();
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int Fl_Slider::handle(int event) {
+ return handle(event, x(), y(), w(), h());
+}
+
+// End of Fl_Slider.C
diff --git a/src/Fl_Tabs.cxx b/src/Fl_Tabs.cxx
new file mode 100644
index 000000000..44e2d7ecf
--- /dev/null
+++ b/src/Fl_Tabs.cxx
@@ -0,0 +1,234 @@
+// Fl_Tabs.C
+
+// This is the "file card tabs" interface to allow you to put lots and lots
+// of buttons and switches in a panel, as popularized by many toolkits.
+
+// Each child widget is a card, and it's label() is printed on the card tab.
+// Clicking the tab makes that card visible.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/fl_draw.H>
+
+#define BORDER 10
+#define TABSLOPE 8
+
+// return the left edges of each tab (plus a fake left edge for a tab
+// past the right-hand one). These position are actually of the left
+// edge of the slope. They are either seperated by the correct distance
+// or by TABSLOPE or by zero.
+// Return value is the index of the selected item.
+
+int Fl_Tabs::tab_positions(int* p, int* w) {
+ int selected = 0;
+ Fl_Widget*const* a = array();
+ int i;
+ p[0] = 0;
+ for (i=0; i<children(); i++) {
+ Fl_Widget* o = *a++;
+ if (o == value_) selected = i;
+ if (o->label()) {
+ int wt = 0; int ht = 0; o->measure_label(wt,ht);
+ w[i] = wt+TABSLOPE;
+ } else
+ w[i] = 2*TABSLOPE;
+ p[i+1] = p[i]+w[i];
+ }
+ int r = this->w()-TABSLOPE-1;
+ if (p[i] <= r) return selected;
+ // uh oh, they are too big:
+ // pack them against right edge:
+ p[i] = r;
+ for (i = children(); i--;) {
+ int l = r-w[i];
+ if (p[i+1]-TABSLOPE < l) l = p[i+1]-TABSLOPE;
+ if (p[i] <= l) break;
+ p[i] = l;
+ r -= TABSLOPE;
+ }
+ // pack them against left edge and truncate width if they still don't fit:
+ for (i = 0; i<children(); i++) {
+ if (p[i] >= i*TABSLOPE) break;
+ p[i] = i*TABSLOPE;
+ int W = this->w()-1-TABSLOPE*(children()-i) - p[i];
+ if (w[i] > W) w[i] = W;
+ }
+ // adjust edges according to visiblity:
+ for (i = children(); i > selected; i--) {
+ p[i] = p[i-1]+w[i-1];
+ }
+ return selected;
+}
+
+// return space needed for tabs. Negative to put them on the bottom:
+int Fl_Tabs::tab_height() {
+ int H = h();
+ int H2 = y();
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o->y() < y()+H) H = o->y()-y();
+ if (o->y()+o->h() > H2) H2 = o->y()+o->h();
+ }
+ H2 = y()+h()-H2;
+ if (H2 > H) {
+ H = H2-Fl::box_dy(box());
+ return (H <= 0) ? 0 : -H;
+ } else {
+ H = H-Fl::box_dy(box());
+ return (H <= 0) ? 0 : H;
+ }
+}
+
+// this is used by fluid to pick tabs:
+Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
+ int H = tab_height();
+ if (H < 0) {
+ if (event_y > y()+h() || event_y < y()+h()+H) return 0;
+ } else {
+ if (event_y > y()+H || event_y < y()) return 0;
+ }
+ if (event_x < x()) return 0;
+ int p[128], w[128];
+ int selected = tab_positions(p, w);
+ int d = (event_y-(H>=0?y():y()+h()))*TABSLOPE/H;
+ for (int i=0; i<children(); i++) {
+ if (event_x < x()+p[i+1]+(i<selected ? TABSLOPE-d : d)) return child(i);
+ }
+ return 0;
+}
+
+int Fl_Tabs::handle(int event) {
+
+ Fl_Widget *o;
+
+ switch (event) {
+
+ case FL_PUSH: {
+ int H = tab_height();
+ if (H >= 0) {
+ if (Fl::event_y() > y()+H) goto DEFAULT;
+ } else {
+ if (Fl::event_y() < y()+h()+H) goto DEFAULT;
+ }}
+ case FL_DRAG:
+ case FL_RELEASE:
+ o = which(Fl::event_x(), Fl::event_y());
+ if (event == FL_RELEASE) {push(0); if (o) value(o);}
+ else push(o);
+ return 1;
+
+ default:
+ DEFAULT:
+ value(); // initialize value & visibility if value_ == 0
+ return Fl_Group::handle(event);
+
+ }
+}
+
+int Fl_Tabs::push(Fl_Widget *o) {
+ if (push_ == o) return 0;
+ if (push_ && push_ != value_ || o && o != value_) damage(2);
+ push_ = o;
+ return 1;
+}
+
+Fl_Widget* Fl_Tabs::value() {
+ Fl_Widget *v = value_;
+ if (!v) {
+ // If value() has not been called, find first visible() child:
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (v) o->hide();
+ else if (o->visible()) v = o;
+ }
+ if (!v) return 0; // no children...
+ value_ = v;
+ }
+ return v;
+}
+
+int Fl_Tabs::value(Fl_Widget *o) {
+ if (value_ == o) return 0;
+ if (o) o->show();
+ if (value_) value_->hide();
+ value_ = o;
+ redraw();
+ do_callback();
+ return 1;
+}
+
+enum {LEFT, RIGHT, SELECTED};
+
+void Fl_Tabs::draw() {
+ Fl_Widget *v = value();
+ int H = tab_height();
+ if (damage() & ~3) { // redraw the entire thing:
+ fl_clip(x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H));
+ draw_box(box(), x(), y(), w(), h(), v->color());
+ fl_pop_clip();
+ draw_child(*v);
+ } else { // redraw the child
+ update_child(*v);
+ }
+ if (damage() & 2) {
+ int p[128]; int w[128];
+ int selected = tab_positions(p,w);
+ int i;
+ Fl_Widget*const* a = array();
+ for (i=0; i<selected; i++)
+ draw_tab(x()+p[i], x()+p[i+1], w[i], H, a[i], LEFT);
+ for (i=children()-1; i > selected; i--)
+ draw_tab(x()+p[i], x()+p[i+1], w[i], H, a[i], RIGHT);
+ i = selected;
+ draw_tab(x()+p[i], x()+p[i+1], w[i], H, a[i], SELECTED);
+ }
+}
+
+void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
+ if (x2 < x1+W) {
+ if (what == LEFT) {
+ if (x1+W < x2+TABSLOPE) x2 = x1+W;
+ else x2 += TABSLOPE;
+ } else {
+ if (x1+W < x2+TABSLOPE) x1 = x2-W;
+ else x1 -= TABSLOPE;
+ }
+ }
+ int sel = (what == SELECTED);
+ fl_color(o->color());
+ if (H >= 0) {
+ fl_polygon(x1, y()+H+sel, x1+TABSLOPE, y(), x2, y(),
+ x2+TABSLOPE, y()+H+sel);
+ fl_color(!sel && o==push_ ? FL_DARK3 : FL_LIGHT3);
+ fl_line(x1, y()+H, x1+TABSLOPE, y(), x2, y());
+ if (sel) {
+ if (x1>x()) fl_xyline(x(), y()+H, x1);
+ if (x2+TABSLOPE < x()+w()-1) fl_xyline(x2+TABSLOPE, y()+H, x()+w()-1);
+ }
+ fl_color(!sel && o==push_ ? FL_LIGHT3 : FL_DARK3);
+ fl_line(x2, y(), x2+TABSLOPE, y()+H);
+ } else {
+ fl_polygon(x1, y()+h()+H-sel, x1+TABSLOPE, y()+h(), x2, y()+h(),
+ x2+TABSLOPE, y()+h()+H-sel);
+ fl_color(!sel && o==push_ ? FL_LIGHT3 : FL_DARK3);
+ fl_line(x1+TABSLOPE, y()+h()-1, x2, y()+h()-1, x2+TABSLOPE, y()+h()+H);
+ if (sel) {
+ if (x1>x()) fl_xyline(x(), y()+h()+H, x1);
+ if (x2+TABSLOPE < x()+w()-1) fl_xyline(x2+TABSLOPE, y()+h()+H,x()+w()-1);
+ }
+ fl_color(!sel && o==push_ ? FL_DARK3 : FL_LIGHT3);
+ fl_line(x1, y()+h()+H, x1+TABSLOPE, y()+h()-1);
+ }
+ if (x2-x1 > 2*TABSLOPE)
+ o->draw_label(what==LEFT ? x1+TABSLOPE : x2-W+TABSLOPE,
+ y()+(H<0?h()+H-3:0), W-TABSLOPE,
+ (H<0?-H:H)+3, FL_ALIGN_CENTER);
+}
+
+Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) :
+ Fl_Group(X,Y,W,H,l) {
+ box(FL_THIN_UP_BOX);
+ value_ = push_ = 0;
+}
diff --git a/src/Fl_Tile.cxx b/src/Fl_Tile.cxx
new file mode 100644
index 000000000..d422b844d
--- /dev/null
+++ b/src/Fl_Tile.cxx
@@ -0,0 +1,173 @@
+// Fl_Tile.C - Group of 2 or 4 "tiles" that can be resized by dragging border
+
+// The size of the first child determines where the resize border is.
+// The resizebox is used to limit where the border can be dragged to.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_Window.H>
+#include <stdlib.h>
+
+// Drag the edges that were initially at oldx,oldy to newx,newy:
+// pass zero as oldx or oldy to disable drag in that direction:
+
+void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
+ Fl_Widget*const* a = array();
+ short* p = sizes();
+ p += 8; // skip group & resizable's saved size
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o == resizable()) continue;
+ int X = o->x();
+ int R = X+o->w();
+ if (oix) {
+ int t = p[0];
+ if (t == oix || t>oix && X<newx || t<oix && X>newx) X = newx;
+ t = p[1];
+ if (t == oix || t>oix && R<newx || t<oix && R>newx) R = newx;
+ }
+ int Y = o->y();
+ int B = Y+o->h();
+ if (oiy) {
+ int t = p[2];
+ if (t == oiy || t>oiy && Y<newy || t<oiy && Y>newy) Y = newy;
+ t = p[3];
+ if (t == oiy || t>oiy && B<newy || t<oiy && B>newy) B = newy;
+ }
+ o->damage_resize(X,Y,R-X,B-Y);
+ p += 4;
+ }
+}
+
+// move the lower-right corner (sort of):
+void Fl_Tile::resize(int X,int Y,int W,int H) {
+ // remember how much to move the child widgets:
+ int dx = X-x();
+ int dy = Y-y();
+ int dw = W-w();
+ int dh = H-h();
+ short* p = sizes();
+ // resize this (skip the Fl_Group resize):
+ Fl_Widget::resize(X,Y,W,H);
+ // find bottom-right of resiable:
+ int OR = p[5];
+ int NR = X+W-(p[1]-OR);
+ int OB = p[7];
+ int NB = Y+H-(p[3]-OB);
+ // move everything to be on correct side of new resizable:
+ Fl_Widget*const* a = array();
+ p += 8;
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ int X = o->x()+dx;
+ int R = X+o->w();
+ if (*p++ >= OR) X += dw; else if (X > NR) X = NR;
+ if (*p++ >= OR) R += dw; else if (R > NR) R = NR;
+ int Y = o->y()+dy;
+ int B = Y+o->h();
+ if (*p++ >= OB) Y += dh; else if (Y > NB) Y = NB;
+ if (*p++ >= OB) B += dh; else if (B > NB) B = NB;
+ o->resize(X,Y,R-X,B-Y); o->redraw();
+ }
+}
+
+static void set_cursor(Fl_Tile*t, Fl_Cursor c) {
+ static Fl_Cursor cursor;
+ if (cursor == c) return;
+ cursor = c;
+#ifdef __sgi
+ t->window()->cursor(c,FL_RED,FL_WHITE);
+#else
+ t->window()->cursor(c);
+#endif
+}
+
+static Fl_Cursor cursors[4] = {
+ FL_CURSOR_DEFAULT,
+ FL_CURSOR_WE,
+ FL_CURSOR_NS,
+ FL_CURSOR_MOVE};
+
+int Fl_Tile::handle(int event) {
+ static int sdrag;
+ static int sdx, sdy;
+ static int sx, sy;
+#define DRAGH 1
+#define DRAGV 2
+#define GRABAREA 4
+
+ int mx = Fl::event_x();
+ int my = Fl::event_y();
+
+ switch (event) {
+
+ case FL_MOVE:
+ case FL_ENTER:
+ case FL_PUSH: {
+ int mindx = 100;
+ int mindy = 100;
+ int oldx = 0;
+ int oldy = 0;
+ Fl_Widget*const* a = array();
+ short* q = sizes();
+ short* p = q+8;
+ for (int i=children(); i--; p += 4) {
+ Fl_Widget* o = *a++;
+ if (o == resizable()) continue;
+ if (p[1]<q[1] && o->y()<=my+GRABAREA && o->y()+o->h()>=my-GRABAREA) {
+ int t = mx - (o->x()+o->w());
+ if (abs(t) < mindx) {
+ sdx = t;
+ mindx = abs(t);
+ oldx = p[1];
+ }
+ }
+ if (p[3]<q[3] && o->x()<=mx+GRABAREA && o->x()+o->w()>=mx-GRABAREA) {
+ int t = my - (o->y()+o->h());
+ if (abs(t) < mindy) {
+ sdy = t;
+ mindy = abs(t);
+ oldy = p[3];
+ }
+ }
+ }
+ sdrag = 0; sx = sy = 0;
+ if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oldx;}
+ if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oldy;}
+ set_cursor(this, cursors[sdrag]);
+ if (sdrag) return 1;
+ return Fl_Group::handle(event);
+ }
+
+ case FL_LEAVE:
+ set_cursor(this, FL_CURSOR_DEFAULT);
+ break;
+
+ case FL_DRAG:
+ if (damage()) return 1; // don't fall behind
+ case FL_RELEASE: {
+ if (!sdrag) return 0; // should not happen
+ Fl_Widget* r = resizable(); if (!r) r = this;
+ int newx;
+ if (sdrag&DRAGH) {
+ newx = Fl::event_x()-sdx;
+ if (newx < r->x()) newx = r->x();
+ else if (newx > r->x()+r->w()) newx = r->x()+r->w();
+ } else
+ newx = sx;
+ int newy;
+ if (sdrag&DRAGV) {
+ newy = Fl::event_y()-sdy;
+ if (newy < r->y()) newy = r->y();
+ else if (newy > r->y()+r->h()) newy = r->y()+r->h();
+ } else
+ newy = sy;
+ position(sx,sy,newx,newy);
+ return 1;}
+
+ }
+
+ return Fl_Group::handle(event);
+}
+
+// end of Fl_Tile.C
diff --git a/src/Fl_Valuator.cxx b/src/Fl_Valuator.cxx
new file mode 100644
index 000000000..a39513c37
--- /dev/null
+++ b/src/Fl_Valuator.cxx
@@ -0,0 +1,100 @@
+// Fl_Valuator.C
+
+// Base class for sliders and all other one-value "knobs"
+
+#include <FL/Fl.H>
+#include <FL/Fl_Valuator.H>
+#include <FL/math.h>
+#include <stdio.h>
+
+Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L)
+ : Fl_Widget(X,Y,W,H,L) {
+ align(FL_ALIGN_BOTTOM);
+ when(FL_WHEN_CHANGED);
+ value_ = 0;
+ min = 0;
+ max = 1;
+ A = 0.0;
+ B = 1;
+}
+
+const double epsilon = 1e-12 ;
+
+void Fl_Valuator::step(double s) {
+ if (s < 0) s = -s;
+ A = rint(s);
+ B = 1;
+ while (fabs(s-A/B) > epsilon) {B *= 10; A = rint(s*B);}
+}
+
+void Fl_Valuator::precision(int p) {
+ A = 1.0;
+ for (B = 1; p--;) B *= 10;
+}
+
+void Fl_Valuator::value_damage() {damage(2);} // by default do partial-redraw
+
+int Fl_Valuator::value(double v) {
+ clear_changed();
+ if (v == value_) return 0;
+ value_ = v;
+ value_damage();
+ return 1;
+}
+
+double Fl_Valuator::softclamp(double v) {
+ int which = (min<=max);
+ double p = previous_value_;
+ if ((v<min)==which && p!=min && (p<min)!=which) return min;
+ else if ((v>max)==which && p!=max && (p>max)!=which) return max;
+ else return v;
+}
+
+// inline void Fl_Valuator::handle_push() {previous_value_ = value_;}
+
+void Fl_Valuator::handle_drag(double v) {
+ if (v != value_) {
+ value_ = v;
+ value_damage();
+ if (when() & FL_WHEN_CHANGED) do_callback();
+ else set_changed();
+ }
+}
+
+void Fl_Valuator::handle_release() {
+ if (when()&FL_WHEN_RELEASE) {
+ // insure changed() is off even if no callback is done. It may have
+ // been turned on by the drag, and then the slider returned to it's
+ // initial position:
+ clear_changed();
+ // now do the callback only if slider in new position or always is on:
+ if (value_ != previous_value_ || when() & FL_WHEN_NOT_CHANGED)
+ do_callback();
+ }
+}
+
+double Fl_Valuator::round(double v) {
+ if (A) return rint(v*B/A)*A/B;
+ else return v;
+}
+
+double Fl_Valuator::clamp(double v) {
+ if ((v<min)==(min<=max)) return min;
+ else if ((v>max)==(min<=max)) return max;
+ else return v;
+}
+
+double Fl_Valuator::increment(double v, int n) {
+ if (!A) return v+n*(max-min)/100;
+ if (min > max) n = -n;
+ return (rint(v*B/A)+n)*A/B;
+}
+
+int Fl_Valuator::format(char* buffer) {
+ double v = value();
+ if (!A || B==1) return sprintf(buffer, "%g", v);
+ int i, x;
+ for (x = 10, i = 2; x < B; x *= 10) i++;
+ if (x == B) i--;
+ return sprintf(buffer, "%.*f", i, v);
+}
diff --git a/src/Fl_Value_Input.cxx b/src/Fl_Value_Input.cxx
new file mode 100644
index 000000000..c9cf28db1
--- /dev/null
+++ b/src/Fl_Value_Input.cxx
@@ -0,0 +1,100 @@
+// Fl_Value_Input.C
+
+// Fltk widget for drag-adjusting a floating point value.
+
+// Warning: this works by making a child Fl_Input object, even
+// though this object is *not* an Fl_Group. May be a kludge?
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Input.H>
+#include <FL/Fl_Group.H>
+#include <stdlib.h>
+
+void Fl_Value_Input::input_cb(Fl_Widget*, void* v) {
+ Fl_Value_Input& t = *(Fl_Value_Input*)v;
+ double nv;
+ if (t.step()>=1.0) nv = strtol(t.input.value(), 0, 0);
+ else nv = strtod(t.input.value(), 0);
+ t.handle_push();
+ t.handle_drag(nv);
+ t.handle_release();
+}
+
+void Fl_Value_Input::draw() {
+ if (damage()&~1) input.clear_damage(~0);
+ input.box(box());
+ input.color(color(), selection_color());
+ input.draw();
+ input.clear_damage();
+}
+
+void Fl_Value_Input::resize(int X, int Y, int W, int H) {
+ Fl_Valuator::resize(X, Y, W, H);
+ input.resize(X, Y, W, H);
+}
+
+void Fl_Value_Input::value_damage() {
+ char buf[128];
+ format(buf);
+ input.value(buf);
+ input.mark(input.position()); // turn off selection highlight
+}
+
+int Fl_Value_Input::handle(int event) {
+ double v;
+ int delta;
+ int mx = Fl::event_x();
+ static int ix, drag;
+ switch (event) {
+ case FL_PUSH:
+ if (!step()) goto DEFAULT;
+ ix = mx;
+ drag = Fl::event_button();
+ handle_push();
+ return 1;
+ case FL_DRAG:
+ if (!step()) goto DEFAULT;
+ delta = Fl::event_x()-ix;
+ if (delta > 5) delta -= 5;
+ else if (delta < -5) delta += 5;
+ else delta = 0;
+ switch (drag) {
+ case 3: v = increment(previous_value(), delta*100); break;
+ case 2: v = increment(previous_value(), delta*10); break;
+ default:v = increment(previous_value(), delta); break;
+ }
+ v = round(v);
+ handle_drag(soft()?softclamp(v):clamp(v));;
+ return 1;
+ case FL_RELEASE:
+ if (!step()) goto DEFAULT;
+ if (value() != previous_value() || !Fl::event_is_click())
+ handle_release();
+ else {
+ input.handle(FL_PUSH);
+ input.handle(FL_RELEASE);
+ }
+ return 1;
+ case FL_FOCUS:
+ return input.take_focus();
+ default:
+ DEFAULT:
+ input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
+ return input.handle(event);
+ }
+}
+
+Fl_Value_Input::Fl_Value_Input(int x, int y, int w, int h, const char* l)
+: Fl_Valuator(x, y, w, h, l), input(x, y, w, h, 0) {
+ soft_ = 0;
+ if (input.parent()) // defeat automatic-add
+ ((Fl_Group*)input.parent())->remove(input);
+ input.parent(this); // kludge!
+ input.callback(input_cb, this);
+ input.when((Fl_When)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY));
+ box(input.box());
+ color(input.color());
+ selection_color(input.selection_color());
+ align(FL_ALIGN_LEFT);
+ value_damage();
+}
diff --git a/src/Fl_Value_Output.cxx b/src/Fl_Value_Output.cxx
new file mode 100644
index 000000000..8c3f26bcd
--- /dev/null
+++ b/src/Fl_Value_Output.cxx
@@ -0,0 +1,73 @@
+// Fl_Value_Output.C
+
+// Fltk widget for drag-adjusting a floating point value.
+// This is much lighter than Fl_Value_Input because it has no text editor
+// If step() is zero then it can be used to display a floating-point value
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Output.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Input.H> // for default_font
+
+void Fl_Value_Output::draw() {
+ Fl_Boxtype b = box() ? box() : Fl_Input::default_box();
+ int X = x()+Fl::box_dx(b);
+ int Y = y()+Fl::box_dy(b);
+ int W = w()-Fl::box_dw(b);
+ int H = h()-Fl::box_dh(b);
+ if (damage()&~1)
+ draw_box(b, color());
+ else {
+ fl_color(color());
+ fl_rectf(X, Y, W, H);
+ }
+ char buf[128];
+ format(buf);
+ fl_color(active_r() ? textcolor() : inactive(textcolor()));
+ fl_font(textfont(), textsize(),
+ Fl_Input::default_font(), Fl_Input::default_size());
+ fl_draw(buf,X+3,Y,W-6,H,FL_ALIGN_LEFT);
+}
+
+int Fl_Value_Output::handle(int event) {
+ if (!step()) return 0;
+ double v;
+ int delta;
+ int mx = Fl::event_x();
+ static int ix, drag;
+ switch (event) {
+ case FL_PUSH:
+ ix = mx;
+ drag = Fl::event_button();
+ handle_push();
+ return 1;
+ case FL_DRAG:
+ delta = Fl::event_x()-ix;
+ if (delta > 5) delta -= 5;
+ else if (delta < -5) delta += 5;
+ else delta = 0;
+ switch (drag) {
+ case 3: v = increment(previous_value(),delta*100); break;
+ case 2: v = increment(previous_value(),delta*10); break;
+ default:v = increment(previous_value(),delta); break;
+ }
+ v = round(v);
+ handle_drag(soft()?softclamp(v):clamp(v));;
+ return 1;
+ case FL_RELEASE:
+ handle_release();
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+Fl_Value_Output::Fl_Value_Output(int x,int y,int w,int h,const char *l)
+: Fl_Valuator(x,y,w,h,l) {
+ box(FL_NO_BOX);
+ align(FL_ALIGN_LEFT);
+ textfont_ = FL_HELVETICA;
+ textsize_ = FL_NORMAL_SIZE;
+ textcolor_ = FL_BLACK;
+ soft_ = 0;
+}
diff --git a/src/Fl_Value_Slider.cxx b/src/Fl_Value_Slider.cxx
new file mode 100644
index 000000000..ade51106d
--- /dev/null
+++ b/src/Fl_Value_Slider.cxx
@@ -0,0 +1,45 @@
+/* Fl_Value_Slider.C */
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Slider.H>
+#include <FL/fl_draw.H>
+#include <math.h>
+#include <FL/Fl_Input_.H> // for default_font
+
+Fl_Value_Slider::Fl_Value_Slider(int x,int y,int w,int h, const char*l)
+: Fl_Slider(x,y,w,h,l) {
+ step(1,100);
+ textfont_ = FL_HELVETICA;
+ textsize_ = 10;
+ textcolor_ = FL_BLACK;
+}
+
+void Fl_Value_Slider::draw() {
+ int sxx = x(), syy = y(), sww = w(), shh = h();
+ int bxx = x(), byy = y(), bww = w(), bhh = h();
+ if (horizontal()) {
+ bww = 35; sxx += 35; sww -= 35;
+ } else {
+ syy += 25; bhh = 25; shh -= 25;
+ }
+ Fl_Slider::draw(sxx,syy,sww,shh);
+ draw_box(box(),bxx,byy,bww,bhh,color());
+ char buf[128];
+ format(buf);
+ fl_font(textfont(), textsize(),
+ Fl_Input_::default_font(), Fl_Input_::default_size());
+ fl_color(active_r() ? textcolor() : inactive(textcolor()));
+ fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP);
+}
+
+int Fl_Value_Slider::handle(int event) {
+ int sxx = x(), syy = y(), sww = w(), shh = h();
+ if (horizontal()) {
+ sxx += 35; sww -= 35;
+ } else {
+ syy += 25; shh -= 25;
+ }
+ return Fl_Slider::handle(event,sxx,syy,sww,shh);
+}
+
+// End of Fl_Value_Slider.C
diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx
new file mode 100644
index 000000000..65fda468c
--- /dev/null
+++ b/src/Fl_Widget.cxx
@@ -0,0 +1,164 @@
+// Fl_Widget.C
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Group.H>
+
+////////////////////////////////////////////////////////////////
+// for compatability with Forms, all widgets without callbacks are
+// inserted into a "queue" when they are activated, and the forms
+// compatability interaction functions (fl_do_events, etc) will
+// read one widget at a time from this queue and return it:
+
+const int QUEUE_SIZE = 20;
+
+static Fl_Widget *obj_queue[QUEUE_SIZE];
+static int obj_head, obj_tail;
+
+void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
+#if 0
+ // This is necessary for strict forms compatability but is confusing.
+ // Use the parent's callback if this widget does not have one.
+ for (Fl_Widget *p = o->parent(); p; p = p->parent())
+ if (p->callback() != default_callback) {
+ p->do_callback(o,v);
+ return;
+ }
+#endif
+ obj_queue[obj_head++] = o;
+ if (obj_head >= QUEUE_SIZE) obj_head = 0;
+ if (obj_head == obj_tail) {
+ obj_tail++;
+ if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
+ }
+}
+
+Fl_Widget *Fl::readqueue() {
+ if (obj_tail==obj_head) return 0;
+ Fl_Widget *o = obj_queue[obj_tail++];
+ if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
+ return o;
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl_Widget::handle(int) {return 0;}
+
+Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {
+
+ x_ = X; y_ = Y; w_ = W; h_ = H;
+
+ label_.value = L;
+ label_.type = FL_NORMAL_LABEL;
+ label_.font = FL_HELVETICA;
+ label_.size = FL_NORMAL_SIZE;
+ label_.color = FL_BLACK;
+ callback_ = default_callback;
+ user_data_ = 0;
+ type_ = 0;
+ flags_ = 0;
+ damage_ = 0;
+ box_ = FL_NO_BOX;
+ color_ = FL_GRAY;
+ color2_ = FL_GRAY;
+ align_ = FL_ALIGN_CENTER;
+ when_ = FL_WHEN_RELEASE;
+
+ parent_ = 0;
+ if (Fl_Group::current()) Fl_Group::current()->add(this);
+}
+
+void Fl_Widget::resize(int X, int Y, int W, int H) {
+ x_ = X; y_ = Y; w_ = W; h_ = H;
+}
+
+// this is useful for parent widgets to call to resize children:
+int Fl_Widget::damage_resize(int X, int Y, int W, int H) {
+ if (x() == X && y() == Y && w() == W && h() == H) return 0;
+ resize(X, Y, W, H);
+ redraw();
+ return 1;
+}
+
+int Fl_Widget::take_focus() {
+ if (!takesevents()) return 0;
+ if (!handle(FL_FOCUS)) return 0; // see if it wants it
+ if (contains(Fl::focus())) return 1; // it called Fl::focus for us
+ Fl::focus(this);
+ return 1;
+}
+
+extern void fl_throw_focus(Fl_Widget*); // in Fl_x.C
+
+// Destruction does not remove from any parent group! And groups when
+// destroyed destroy all their children. This is convienent and fast.
+// However, it is only legal to destroy a "root" such as an Fl_Window,
+// and automatic destructors may be called.
+Fl_Widget::~Fl_Widget() {
+ parent_ = 0; // kludge to prevent ~Fl_Group from destroying again
+ fl_throw_focus(this);
+}
+
+// redraw this, plus redraw opaque object if there is an outside label
+static void redraw_label(Fl_Widget* w) {
+ w->redraw();
+ if (w->label() && (w->align()&15) && !(w->align() & FL_ALIGN_INSIDE)) {
+ for (Fl_Widget *p = w->parent(); p; p = p->parent())
+ if (p->box() || !p->parent()) {p->redraw(); break;}
+ }
+}
+
+void Fl_Widget::activate() {
+ if (active()) return;
+ clear_flag(INACTIVE);
+ handle(FL_ACTIVATE);
+ if (inside(Fl::focus())) Fl::focus()->take_focus();
+ redraw_label(this);
+}
+
+void Fl_Widget::deactivate() {
+ if (!active()) return;
+ set_flag(INACTIVE);
+ handle(FL_DEACTIVATE);
+ fl_throw_focus(this);
+ redraw_label(this);
+}
+
+int Fl_Widget::active_r() const {
+ for (const Fl_Widget* o = this; o; o = o->parent())
+ if (!o->active()) return 0;
+ return 1;
+}
+
+void Fl_Widget::show() {
+ if (visible()) return;
+ clear_flag(INVISIBLE);
+ handle(FL_SHOW);
+ if (inside(Fl::focus())) Fl::focus()->take_focus();
+ redraw_label(this);
+}
+
+void Fl_Widget::hide() {
+ if (!visible()) return;
+ set_flag(INVISIBLE);
+ handle(FL_HIDE);
+ fl_throw_focus(this);
+ for (Fl_Widget *p = parent(); p; p = p->parent())
+ if (p->box() || !p->parent()) {p->redraw(); break;}
+}
+
+int Fl_Widget::visible_r() const {
+ for (const Fl_Widget* o = this; o; o = o->parent())
+ if (!o->visible()) return 0;
+ return 1;
+}
+
+// return true if widget is inside (or equal to) this:
+// Returns false for null widgets.
+int Fl_Widget::contains(const Fl_Widget *o) const {
+ for (; o; o = o->parent_) if (o == this) return 1;
+ return 0;
+}
diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx
new file mode 100644
index 000000000..9c987df4e
--- /dev/null
+++ b/src/Fl_Window.cxx
@@ -0,0 +1,83 @@
+// Fl_Window.C
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// The Fl_Window is a window in the fltk library.
+// This is the system-independent portions. The huge amount of
+// crap you need to do to communicate with X is in Fl_x.C, the
+// equivalent (but totally different) crap for MSWindows is in Fl_win32.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+
+void Fl_Window::_Fl_Window() {
+ type(FL_WINDOW);
+ box(FL_FLAT_BOX);
+ labeltype(FL_NO_LABEL);
+ i = 0;
+ xclass_ = 0;
+ iconlabel_ = 0;
+ resizable(0);
+ size_range_set = 0;
+ callback((Fl_Callback*)default_callback);
+}
+
+Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l)
+: Fl_Group(X, Y, W, H, l) {
+ _Fl_Window();
+ set_flag(FL_FORCE_POSITION);
+}
+
+Fl_Window::Fl_Window(int W, int H, const char *l)
+// fix common user error of a missing end() with current(0):
+ : Fl_Group((Fl_Group::current(0),0), 0, W, H, l) {
+ _Fl_Window();
+ clear_visible();
+}
+
+Fl_Window *Fl_Widget::window() const {
+ for (Fl_Widget *o = parent(); o; o = o->parent())
+ if (o->type()>=FL_WINDOW) return (Fl_Window*)o;
+ return 0;
+}
+
+int Fl_Window::x_root() const {
+ Fl_Window *p = window();
+ if (p) return p->x_root() + x();
+ return x();
+}
+
+int Fl_Window::y_root() const {
+ Fl_Window *p = window();
+ if (p) return p->y_root() + y();
+ return y();
+}
+
+void Fl_Window::draw() {
+ int savex = x(); x(0);
+ int savey = y(); y(0);
+ Fl_Group::draw();
+ y(savey);
+ x(savex);
+}
+
+void Fl_Window::label(const char *name) {label(name, iconlabel());}
+
+void Fl_Window::iconlabel(const char *iname) {label(label(), iname);}
+
+// the Fl::atclose pointer is provided for back compatability. You
+// can now just change the callback for the window instead.
+
+void Fl::default_atclose(Fl_Window* window, void* v) {
+ window->hide();
+ Fl_Widget::default_callback(window, v); // put on Fl::read_queue()
+}
+
+void (*Fl::atclose)(Fl_Window*, void*) = default_atclose;
+
+void Fl_Window::default_callback(Fl_Window* window, void* v) {
+ Fl::atclose(window, v);
+}
+
+// End of Fl_Window.C
diff --git a/src/Fl_Window_fullscreen.cxx b/src/Fl_Window_fullscreen.cxx
new file mode 100644
index 000000000..332a52cc4
--- /dev/null
+++ b/src/Fl_Window_fullscreen.cxx
@@ -0,0 +1,46 @@
+// Turning the border on/off by changing the motif_wm_hints property
+// works on Irix 4DWM. Does not appear to work for any other window
+// manager. Fullscreen still works on some window managers (fvwm is one)
+// because they allow the border to be placed off-screen.
+
+// Unfortunatly most X window managers ignore changes to the border
+// and refuse to position the border off-screen, so attempting to make
+// the window full screen will lose the size of the border off the
+// bottom and right.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+void Fl_Window::border(int b) {
+ if (b) {
+ if (border()) return;
+ clear_flag(FL_NOBORDER);
+ } else {
+ if (!border()) return;
+ set_flag(FL_NOBORDER);
+ }
+#ifdef WIN32
+ // not yet implemented, but it's possible
+ // for full fullscreen we have to make the window topmost as well
+#else
+ if (shown()) Fl_X::i(this)->sendxjunk();
+#endif
+}
+
+void Fl_Window::fullscreen() {
+ border(0);
+ if (!x()) x(1); // force it to call XResizeWindow()
+ resize(0,0,Fl::w(),Fl::h());
+}
+
+void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
+#ifdef WIN32
+ border(1);
+ resize(X,Y,W,H);
+#else
+ // this order produces less blinking on IRIX:
+ resize(X,Y,W,H);
+ border(1);
+#endif
+}
+
diff --git a/src/Fl_Window_hotspot.cxx b/src/Fl_Window_hotspot.cxx
new file mode 100644
index 000000000..9a6f58a20
--- /dev/null
+++ b/src/Fl_Window_hotspot.cxx
@@ -0,0 +1,27 @@
+// Fl_Window_hotspot.C
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+
+void Fl_Window::hotspot(int X, int Y, int offscreen) {
+ int mx,my; Fl::get_mouse(mx,my);
+ X = mx-X; Y = my-Y;
+ if (!offscreen) {
+ if (X < 0) X = 0;
+ if (X > Fl::w()-w()) X = Fl::w()-w();
+ if (Y > Fl::h()-h()) Y = Fl::h()-h();
+ if (Y < 0) Y = 0;
+ if (border() && Y < 20) Y = 20;
+ }
+ position(X,Y);
+}
+
+void Fl_Window::hotspot(const Fl_Widget *o, int offscreen) {
+ int X = o->w()/2;
+ int Y = o->h()/2;
+ while (o != this) {
+ X += o->x(); Y += o->y();
+ o = o->window();
+ }
+ hotspot(X,Y,offscreen);
+}
diff --git a/src/Fl_Window_iconize.cxx b/src/Fl_Window_iconize.cxx
new file mode 100644
index 000000000..a89080623
--- /dev/null
+++ b/src/Fl_Window_iconize.cxx
@@ -0,0 +1,19 @@
+// X-specific code that is not called by all programs, so it is put
+// here in it's own source file to make programs smaller.
+
+#include <FL/x.H>
+
+extern char fl_show_iconic; // in Fl_x.C
+
+void Fl_Window::iconize() {
+ if (!shown()) {
+ fl_show_iconic = 1;
+ show();
+ } else {
+#ifdef WIN32
+ ShowWindow(i->xid, SW_MINIMIZE);
+#else
+ XIconifyWindow(fl_display, i->xid, fl_screen);
+#endif
+ }
+}
diff --git a/src/Fl_XColor.H b/src/Fl_XColor.H
new file mode 100644
index 000000000..0f2936d74
--- /dev/null
+++ b/src/Fl_XColor.H
@@ -0,0 +1,18 @@
+// X-specific structure for storing allocated colors. Used by fl_color.C,
+// fl_draw_image.C, fl_set_color.C.
+
+#include <config.h>
+
+// one of these for each color in fltk's "colormap":
+// if overlays are enabled, another one for the overlay
+struct Fl_XColor {
+ unsigned char r,g,b; // actual color used by X
+ unsigned char mapped; // true when XAllocColor done
+ unsigned long pixel; // the X pixel to use
+};
+extern Fl_XColor fl_xmap[/*overlay*/][256];
+
+// mask & shifts to produce xcolor for truecolor visuals:
+extern unsigned char fl_redmask, fl_greenmask, fl_bluemask;
+extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;
+
diff --git a/src/Fl_abort.cxx b/src/Fl_abort.cxx
new file mode 100644
index 000000000..047af80a9
--- /dev/null
+++ b/src/Fl_abort.cxx
@@ -0,0 +1,51 @@
+// This method is in it's own source file so that stdlib and stdio
+// do not need to be included in Fl.C:
+// You can also override this by redefining all of these.
+
+#include <FL/Fl.H>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef WIN32
+
+static void warning(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fputc('\n', stderr);
+ fflush(stderr);
+}
+
+static void error(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fputc('\n', stderr);
+ fflush(stderr);
+//abort(); // this produces a core dump, probably not desirable?
+ ::exit(1);
+}
+
+#else
+
+// windows version is currently lame as vsprintf() is missing?
+
+#include <windows.h>
+
+static void warning(const char *format, ...) {
+ MessageBox(0,format,"Fltk warning",MB_ICONEXCLAMATION|MB_OK);
+}
+
+static void error(const char *format, ...) {
+ MessageBox(0,format,"Fltk error",MB_ICONSTOP|MB_SYSTEMMODAL);
+ ::exit(1);
+}
+
+#endif
+
+void (*Fl::warning)(const char* format, ...) = ::warning;
+void (*Fl::error)(const char* format, ...) = ::error;
+void (*Fl::fatal)(const char* format, ...) = ::error;
diff --git a/src/Fl_add_idle.cxx b/src/Fl_add_idle.cxx
new file mode 100644
index 000000000..3b0e127c2
--- /dev/null
+++ b/src/Fl_add_idle.cxx
@@ -0,0 +1,62 @@
+// Fl_add_idle.C
+
+// Allows you to manage an arbitrary set of idle() callbacks.
+// Replaces the older set_idle() call (which is used to implement this)
+
+#include <FL/Fl.H>
+
+struct idle_cb {
+ void (*cb)(void*);
+ void* data;
+ idle_cb *next;
+};
+
+// the callbacks are stored linked in a ring. last points at the one
+// just called, first at the next to call. last->next == first.
+
+static idle_cb* first;
+static idle_cb* last;
+static idle_cb* freelist;
+
+static void call_idle() {
+ idle_cb* p = first;
+ last = p; first = p->next;
+ p->cb(p->data); // this may call add_idle() or remove_idle()!
+}
+
+void Fl::add_idle(void (*cb)(void*), void* data) {
+ idle_cb* p = freelist;
+ if (p) freelist = p->next;
+ else p = new idle_cb;
+ p->cb = cb;
+ p->data = data;
+ if (first) {
+ last->next = p;
+ p->next = first;
+ first = p;
+ } else {
+ first = last = p;
+ p->next = p;
+ set_idle(call_idle);
+ }
+}
+
+void Fl::remove_idle(void (*cb)(void*), void* data) {
+ idle_cb* p = first;
+ if (!p) return;
+ idle_cb* l = last;
+ for (;; p = p->next) {
+ if (p->cb == cb && p->data == data) break;
+ if (p==last) return; // not found
+ l = p;
+ }
+ if (l == p) { // only one
+ first = last = 0;
+ set_idle(0);
+ } else {
+ last = l;
+ first = l->next = p->next;
+ }
+ p->next = freelist;
+ freelist = p;
+}
diff --git a/src/Fl_arg.cxx b/src/Fl_arg.cxx
new file mode 100644
index 000000000..f15d4b5b7
--- /dev/null
+++ b/src/Fl_arg.cxx
@@ -0,0 +1,377 @@
+// Fl_arg.C
+
+// OPTIONAL initialization code for a program using fltk.
+// You do not need to call this! Feel free to make up your own switches.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <FL/filename.H>
+#include <FL/fl_draw.H>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef WIN32
+int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+#endif
+
+static int match(const char *a, const char *match, int atleast = 1) {
+ const char *b = match;
+ while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;}
+ return !*a && b >= match+atleast;
+}
+
+// flags set by previously parsed arguments:
+extern char fl_show_iconic; // in Fl_x.C
+static char arg_called;
+static char return_i;
+static const char *name;
+static const char *fg;
+static const char *bg;
+static const char *bg2;
+static const char *geometry;
+static const char *title;
+
+// consume a switch from argv. Returns number of words eaten, 0 on error:
+int Fl::arg(int argc, char **argv, int &i) {
+ arg_called = 1;
+ const char *s = argv[i];
+
+ if (!s) {i++; return 1;} // something removed by calling program?
+
+ // a word that does not start with '-', or a word after a '--', or
+ // the word '-' by itself all start the "non-switch arguments" to
+ // a program. Return 0 to indicate that we don't understand the
+ // word, but set a flag (return_i) so that args() will return at
+ // that point:
+ if (s[0] != '-' || !s[1]) {return_i = 1; return 0;}
+ if (s[1] == '-') {
+ if (!s[2]) {i++; return_i = 1; return 0;}
+ s++; // make "--word" work the same as "-word" for Gnu compatability
+ }
+ s++; // point after the dash
+
+ if (match(s, "iconic")) {
+ fl_show_iconic = 1;
+ i++;
+ return 1;
+ }
+
+ const char *v = argv[i+1];
+ if (i >= argc-1 || !v)
+ return 0; // all the rest need an argument, so if missing it is an error
+
+ if (match(s, "geometry")) {
+
+ int flags, gx, gy; unsigned int gw, gh;
+ flags = XParseGeometry(v, &gx, &gy, &gw, &gh);
+ if (!flags) return 0;
+ geometry = v;
+
+#ifndef WIN32
+ } else if (match(s, "display")) {
+ Fl::display(v);
+#endif
+
+ } else if (match(s, "title")) {
+ title = v;
+
+ } else if (match(s, "name")) {
+ name = v;
+
+ } else if (match(s, "bg2", 3) || match(s, "background2", 11)) {
+ bg2 = v;
+
+ } else if (match(s, "bg") || match(s, "background")) {
+ bg = v;
+
+ } else if (match(s, "fg") || match(s, "foreground")) {
+ fg = v;
+
+ } else return 0; // unrecognized
+
+ i += 2;
+ return 2;
+}
+
+// consume all switches from argv. Returns number of words eaten.
+// Returns zero on error. 'i' will either point at first word that
+// does not start with '-', at the error word, or after a '--', or at
+// argc. If your program does not take any word arguments you can
+// report an error if i < argc.
+
+int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) {
+ arg_called = 1;
+ i = 1; // skip argv[0]
+ while (i < argc) {
+ if (cb && cb(argc,argv,i)) continue;
+ if (!arg(argc,argv,i)) return return_i ? i : 0;
+ }
+ return i;
+}
+
+#ifdef WIN32
+#include <stdio.h>
+// simulation of XParseColor:
+int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) {
+ if (*p == '#') p++;
+ int n = strlen(p);
+ int m = n/3;
+ const char *pattern = 0;
+ switch(m) {
+ case 1: pattern = "%1x%1x%1x"; break;
+ case 2: pattern = "%2x%2x%2x"; break;
+ case 3: pattern = "%3x%3x%3x"; break;
+ case 4: pattern = "%4x%4x%4x"; break;
+ default: return 0;
+ }
+ int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0;
+ r = R; g = G; b = B;
+ return 1;
+}
+
+static void parsecolor(const char *name, void (*func)(uchar,uchar,uchar)) {
+ uchar r,g,b;
+ if (!name) return;
+ if (!fl_parse_color(name, r,g,b))
+ Fl::error("Unknown color: %s", name);
+ else
+ func(r,g,b);
+}
+
+#else
+
+static void parsecolor(const char *name, void (*func)(uchar,uchar,uchar)) {
+ XColor x;
+ if (!name) return;
+ if (!XParseColor(fl_display, fl_colormap, name, &x))
+ Fl::error("Unknown color: %s", name);
+ else
+ func(x.red>>8, x.green>>8, x.blue>>8);
+}
+
+#endif
+
+// show a main window, use any parsed arguments
+void Fl_Window::show(int argc, char **argv) {
+ if (!arg_called) Fl::args(argc,argv);
+
+ // set colors first, so background_pixel is correct:
+ static char beenhere;
+ if (!beenhere) {
+ beenhere = 1;
+ Fl::get_system_colors(); // opens display! May call Fl::fatal()
+ parsecolor(fg, Fl::foreground);
+ parsecolor(bg, Fl::background);
+ parsecolor(bg2,Fl::background2);
+ if (geometry) {
+ int flags = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
+ flags = XParseGeometry(geometry, &gx, &gy, &gw, &gh);
+ if (flags & XNegative) gx = Fl::w()-w()+gx;
+ if (flags & YNegative) gy = Fl::h()-h()+gy;
+ // int mw,mh; minsize(mw,mh);
+ // if (mw > gw) gw = mw;
+ // if (mh > gh) gh = mh;
+ Fl_Widget *r = resizable();
+ if (!r) resizable(this);
+ // for WIN32 we assumme window is not mapped yet:
+ if (flags & (XValue | YValue))
+ x(-1), resize(gx,gy,gw,gh);
+ else
+ size(gw,gh);
+ resizable(r);
+ }
+ }
+
+ if (name) {xclass(name); name = 0;}
+ else if (!xclass()) xclass(filename_name(argv[0]));
+ if (title) {label(title); title = 0;}
+ else if (!label()) label(xclass());
+ show();
+
+#ifndef WIN32
+ // set the command string, used by state-saving window managers:
+ int i;
+ int n=0; for (i=0; i<argc; i++) n += strlen(argv[i])+1;
+#ifdef __GNUC__
+ char buffer[n];
+#else
+ char *buffer = new char[n];
+#endif
+ char *p = buffer;
+ for (i=0; i<argc; i++) for (const char *q = argv[i]; (*p++ = *q++););
+ XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0,
+ (unsigned char *)buffer, p-buffer-1);
+#ifndef __GNUC__
+ delete[] buffer;
+#endif
+#endif
+
+}
+
+// Calls useful for simple demo programs, with automatic help message:
+
+static const char * const helpmsg =
+"options are:\n"
+" -display host:n.n\n"
+" -geometry WxH+X+Y\n"
+" -title windowtitle\n"
+" -name classname\n"
+" -iconic\n"
+" -fg color\n"
+" -bg color\n"
+" -bg2 color";
+
+const char * const Fl::help = helpmsg+13;
+
+void Fl::args(int argc, char **argv) {
+ int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg);
+}
+
+#ifdef WIN32
+
+/* the following function was stolen from the X sources as indicated. */
+
+/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */
+/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
+
+/*
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission. M.I.T. makes no representations about the
+suitability of this software for any purpose. It is provided "as is"
+without express or implied warranty.
+*/
+
+/*
+ * XParseGeometry parses strings of the form
+ * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ * width, height, xoffset, and yoffset are unsigned integers.
+ * Example: "=80x24+300-49"
+ * The equal sign is optional.
+ * It returns a bitmask that indicates which of the four values
+ * were actually found in the string. For each value found,
+ * the corresponding argument is updated; for each value
+ * not found, the corresponding argument is left unchanged.
+ */
+
+static int ReadInteger(char* string, char** NextString)
+{
+ register int Result = 0;
+ int Sign = 1;
+
+ if (*string == '+')
+ string++;
+ else if (*string == '-') {
+ string++;
+ Sign = -1;
+ }
+ for (; (*string >= '0') && (*string <= '9'); string++) {
+ Result = (Result * 10) + (*string - '0');
+ }
+ *NextString = string;
+ if (Sign >= 0)
+ return (Result);
+ else
+ return (-Result);
+}
+
+int XParseGeometry(const char* string, int* x, int* y,
+ unsigned int* width, unsigned int* height)
+{
+ int mask = NoValue;
+ register char *strind;
+ unsigned int tempWidth, tempHeight;
+ int tempX, tempY;
+ char *nextCharacter;
+
+ if ( (string == NULL) || (*string == '\0')) return(mask);
+ if (*string == '=')
+ string++; /* ignore possible '=' at beg of geometry spec */
+
+ strind = (char *)string;
+ if (*strind != '+' && *strind != '-' && *strind != 'x') {
+ tempWidth = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= WidthValue;
+ }
+
+ if (*strind == 'x' || *strind == 'X') {
+ strind++;
+ tempHeight = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= HeightValue;
+ }
+
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempX = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= XNegative;
+
+ } else {
+ strind++;
+ tempX = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= XValue;
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempY = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ mask |= YNegative;
+
+ } else {
+ strind++;
+ tempY = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= YValue;
+ }
+ }
+
+ /* If strind isn't at the end of the string the it's an invalid
+ geometry specification. */
+
+ if (*strind != '\0') return (0);
+
+ if (mask & XValue)
+ *x = tempX;
+ if (mask & YValue)
+ *y = tempY;
+ if (mask & WidthValue)
+ *width = tempWidth;
+ if (mask & HeightValue)
+ *height = tempHeight;
+ return (mask);
+}
+
+#endif // ifdef WIN32
+
+// end of Fl_Window_arg.C
diff --git a/src/Fl_cutpaste.cxx b/src/Fl_cutpaste.cxx
new file mode 100644
index 000000000..e7fcdd5e5
--- /dev/null
+++ b/src/Fl_cutpaste.cxx
@@ -0,0 +1,127 @@
+// Fl_cutpaste.C
+
+// Implementation of cut and paste.
+
+// This is seperated from Fl.C mostly to test Fl::add_handler().
+// But this will save a small amount of code size in a program that
+// has no text editing fields or other things that call cut or paste.
+
+#ifdef WIN32
+#include "Fl_cutpaste_win32.C"
+#else
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <string.h>
+
+static char *selection_buffer;
+static int selection_length;
+static int selection_buffer_length;
+static char beenhere;
+
+extern Fl_Widget *fl_selection_requestor; // widget doing request_paste()
+
+static int selection_xevent_handler(int) {
+
+ switch (fl_xevent->type) {
+
+ case SelectionNotify: {
+ if (!fl_selection_requestor) return 0;
+ static char *pastebuffer;
+ if (pastebuffer) {XFree(pastebuffer); pastebuffer = 0;}
+ if (fl_xevent->xselection.property != 0) {
+ Atom a; int f; unsigned long n,b;
+ if (!XGetWindowProperty(fl_display,
+ fl_xevent->xselection.requestor,
+ fl_xevent->xselection.property,
+ 0,100000,1,0,&a,&f,&n,&b,
+ (unsigned char**)&pastebuffer)) {
+ Fl::e_text = pastebuffer;
+ Fl::e_length = int(n);
+ fl_selection_requestor->handle(FL_PASTE);
+ }
+ }}
+ return 1;
+
+ case SelectionClear:
+ Fl::selection_owner(0);
+ return 1;
+
+ case SelectionRequest: {
+ XSelectionEvent e;
+ e.type = SelectionNotify;
+ e.display = fl_display;
+ e.requestor = fl_xevent->xselectionrequest.requestor;
+ e.selection = fl_xevent->xselectionrequest.selection;
+ e.target = fl_xevent->xselectionrequest.target;
+ e.time = fl_xevent->xselectionrequest.time;
+ if (fl_xevent->xselectionrequest.target != XA_STRING || !selection_length) {
+ e.property = 0;
+ } else {
+ e.property = fl_xevent->xselectionrequest.property;
+ }
+ if (e.property) {
+ XChangeProperty(fl_display, e.requestor, e.property,
+ XA_STRING, 8, 0, (unsigned char *)selection_buffer,
+ selection_length);
+ }
+ XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Call this when a "paste" operation happens:
+void Fl::paste(Fl_Widget &receiver) {
+ if (selection_owner()) {
+ // We already have it, do it quickly without window server.
+ // Notice that the text is clobbered if set_selection is
+ // called in response to FL_PASTE!
+ Fl::e_text = selection_buffer;
+ Fl::e_length = selection_length;
+ receiver.handle(FL_PASTE);
+ return;
+ }
+ // otherwise get the window server to return it:
+ fl_selection_requestor = &receiver;
+ XConvertSelection(fl_display, XA_PRIMARY, XA_STRING, XA_PRIMARY,
+ fl_xid(Fl::first_window()), fl_event_time);
+ if (!beenhere) {
+ Fl::add_handler(selection_xevent_handler);
+ beenhere = 1;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// call this when you create a selection:
+void Fl::selection(Fl_Widget &owner, const char *stuff, int len) {
+ if (!stuff || len<=0) return;
+ if (len+1 > selection_buffer_length) {
+ delete[] selection_buffer;
+ selection_buffer = new char[len+100];
+ selection_buffer_length = len+100;
+ }
+ memcpy(selection_buffer, stuff, len);
+ selection_buffer[len] = 0; // needed for direct paste
+ selection_length = len;
+ selection_owner(&owner);
+ static Window selxid; // window X thinks selection belongs to
+ if (!selxid) selxid =
+ XCreateSimpleWindow(fl_display,
+ RootWindow(fl_display, fl_screen),
+ 0,0,1,1,0,0,0);
+ XSetSelectionOwner(fl_display, XA_PRIMARY, selxid, fl_event_time);
+ if (!beenhere) {
+ Fl::add_handler(selection_xevent_handler);
+ beenhere = 1;
+ }
+}
+
+#endif
+// end of Fl_cutpaste.C
diff --git a/src/Fl_cutpaste_win32.cxx b/src/Fl_cutpaste_win32.cxx
new file mode 100644
index 000000000..de60c8ed2
--- /dev/null
+++ b/src/Fl_cutpaste_win32.cxx
@@ -0,0 +1,106 @@
+// Fl_cutpaste_win32.C
+
+// Implementation of cut and paste.
+
+// This is seperated from Fl.C mostly to test Fl::add_handler().
+// But this will save a small amount of code size in a program that
+// has no text editing fields or other things that call cut or paste.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Widget.H>
+#include <string.h>
+
+static char *selection_buffer;
+static int selection_length;
+static int selection_buffer_length;
+static char beenhere;
+
+extern Fl_Widget *fl_selection_requestor; // widget doing request_paste()
+
+static int selection_xevent_handler(int) {
+
+ switch (fl_msg.message) {
+
+ case WM_DESTROYCLIPBOARD:
+ Fl::selection_owner(0);
+ Fl::flush(); // get the redraw to happen
+ return 1;
+
+ case WM_RENDERALLFORMATS:
+ if (!OpenClipboard(fl_xid(Fl::first_window()))) return 0;
+ EmptyClipboard();
+ // fall through...
+ case WM_RENDERFORMAT: {
+ HANDLE h = GlobalAlloc(GHND, selection_length+1);
+ if (h) {
+ LPSTR p = (LPSTR)GlobalLock(h);
+ memcpy(p, selection_buffer, selection_length);
+ p[selection_length] = 0;
+ GlobalUnlock(h);
+ SetClipboardData(CF_TEXT, h);
+ }
+ if (fl_msg.message == WM_RENDERALLFORMATS)
+ CloseClipboard();
+ return 1;}
+
+ default:
+ return 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// call this when you create a selection:
+void Fl::selection(Fl_Widget &owner, const char *stuff, int len) {
+ if (!stuff || len<=0) return;
+ if (len+1 > selection_buffer_length) {
+ delete[] selection_buffer;
+ selection_buffer = new char[len+100];
+ selection_buffer_length = len+100;
+ }
+ memcpy(selection_buffer, stuff, len);
+ selection_buffer[len] = 0; // needed for direct paste
+ selection_length = len;
+ if (OpenClipboard(fl_xid(Fl::first_window()))) {
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, NULL);
+ CloseClipboard();
+ if (!beenhere) {
+ Fl::add_handler(selection_xevent_handler);
+ beenhere = 1;
+ }
+ }
+ selection_owner(&owner);
+}
+
+////////////////////////////////////////////////////////////////
+
+// Call this when a "paste" operation happens:
+void Fl::paste(Fl_Widget &receiver) {
+ if (selection_owner()) {
+ // We already have it, do it quickly without window server.
+ // Notice that the text is clobbered if set_selection is
+ // called in response to FL_PASTE!
+ Fl::e_text = selection_buffer;
+ Fl::e_length = selection_length;
+ receiver.handle(FL_PASTE);
+ } else {
+ if (!OpenClipboard(fl_xid(Fl::first_window()))) return;
+ HANDLE h = GetClipboardData(CF_TEXT);
+ if (h) {
+ Fl::e_text = (LPSTR)GlobalLock(h);
+ LPSTR a,b;
+ a = b = Fl::e_text;
+ while (*a) { // strip the CRLF pairs ($%$#@^)
+ if (*a == '\r' && a[1] == '\n') a++;
+ else *b++ = *a++;
+ }
+ *b = 0;
+ Fl::e_length = b - Fl::e_text;
+ receiver.handle(FL_PASTE);
+ GlobalUnlock(h);
+ }
+ CloseClipboard();
+ }
+}
diff --git a/src/Fl_display.cxx b/src/Fl_display.cxx
new file mode 100644
index 000000000..12985db54
--- /dev/null
+++ b/src/Fl_display.cxx
@@ -0,0 +1,16 @@
+// Fl_display.C
+
+// Startup method to set what display to use.
+// Using setenv makes programs that are exec'd use the same display.
+
+#include <FL/Fl.H>
+#include <stdlib.h>
+#include <string.h>
+
+void Fl::display(const char *d) {
+ char *e = new char[strlen(d)+13];
+ strcpy(e,"DISPLAY=");
+ strcpy(e+8,d);
+ for (char *c = e+8; *c!=':'; c++) if (!*c) {strcpy(c,":0.0"); break;}
+ putenv(e);
+}
diff --git a/src/Fl_get_key.cxx b/src/Fl_get_key.cxx
new file mode 100644
index 000000000..72d9d070a
--- /dev/null
+++ b/src/Fl_get_key.cxx
@@ -0,0 +1,37 @@
+// Fl_get_key.C
+
+#ifdef WIN32
+#include "Fl_get_key_win32.C"
+#else
+
+// Return the current state of a key. This is the X version. I identify
+// keys (mostly) by the X keysym. So this turns the keysym into a keycode
+// and looks it up in the X key bit vector, which Fl_x.C keeps track of.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+extern char fl_key_vector[32]; // in Fl_x.C
+
+int Fl::event_key(int k) {
+ if (k > FL_Button && k <= FL_Button+8)
+ return Fl::event_state(8<<(k-FL_Button));
+ int i;
+#ifdef __sgi
+ // get some missing PC keyboard keys:
+ if (k == FL_Meta_L) i = 147;
+ else if (k == FL_Meta_R) i = 148;
+ else if (k == FL_Menu) i = 149;
+ else
+#endif
+ i = XKeysymToKeycode(fl_display, k);
+ return fl_key_vector[i/8] & (1 << (i%8));
+}
+
+int Fl::get_key(int k) {
+ fl_open_display();
+ XQueryKeymap(fl_display, fl_key_vector);
+ return event_key(k);
+}
+
+#endif
diff --git a/src/Fl_get_key_win32.cxx b/src/Fl_get_key_win32.cxx
new file mode 100755
index 000000000..f094e2982
--- /dev/null
+++ b/src/Fl_get_key_win32.cxx
@@ -0,0 +1,108 @@
+// Fl_get_key_win32.C
+
+// Return the current state of a key. Keys are named by fltk symbols,
+// which are actually X keysyms. So this has to translate to MSWindows
+// VK_x symbols.
+
+#include <FL/Fl.H>
+#include <FL/win32.H>
+
+// convert an Fltk (X) keysym to a MSWindows VK symbol:
+// See also the inverse converter in Fl_win32.C
+// This table is in numeric order by Fltk symbol order for binary search:
+
+static const struct {unsigned short vk, fltk;} vktab[] = {
+ {VK_SPACE, ' '},
+ {'1', '!'},
+ {0xde, '\"'},
+ {'3', '#'},
+ {'4', '$'},
+ {'5', '%'},
+ {'7', '&'},
+ {0xde, '\''},
+ {'9', '('},
+ {'0', ')'},
+ {'8', '*'},
+ {0xbb, '+'},
+ {0xbc, ','},
+ {0xbd, '-'},
+ {0xbe, '.'},
+ {0xbf, '/'},
+ {0xba, ':'},
+ {0xba, ';'},
+ {0xbc, '<'},
+ {0xbb, '='},
+ {0xbe, '>'},
+ {0xbf, '?'},
+ {'2', '@'},
+ {0xdb, '['},
+ {0xdc, '\\'},
+ {0xdd, ']'},
+ {'6', '^'},
+ {0xbd, '_'},
+ {0xc0, '`'},
+ {0xdb, '{'},
+ {0xdc, '|'},
+ {0xdd, '}'},
+ {0xc0, '~'},
+ {VK_BACK, FL_BackSpace},
+ {VK_TAB, FL_Tab},
+ {VK_RETURN, FL_Enter},
+ {VK_PAUSE, FL_Pause},
+ {VK_SCROLL, FL_Scroll_Lock},
+ {VK_ESCAPE, FL_Escape},
+ {VK_HOME, FL_Home},
+ {VK_LEFT, FL_Left},
+ {VK_UP, FL_Up},
+ {VK_RIGHT, FL_Right},
+ {VK_DOWN, FL_Down},
+ {VK_PRIOR, FL_Page_Up},
+ {VK_NEXT, FL_Page_Down},
+ {VK_END, FL_End},
+ {VK_SNAPSHOT, FL_Print},
+ {VK_INSERT, FL_Insert},
+ {VK_APPS, FL_Menu},
+ {VK_NUMLOCK, FL_Num_Lock},
+//{VK_???, FL_KP_Enter},
+ {VK_MULTIPLY, FL_KP+'*'},
+ {VK_ADD, FL_KP+'+'},
+ {VK_SUBTRACT, FL_KP+'-'},
+ {VK_DECIMAL, FL_KP+'.'},
+ {VK_DIVIDE, FL_KP+'/'},
+ {VK_LSHIFT, FL_Shift_L},
+ {VK_RSHIFT, FL_Shift_R},
+ {VK_LCONTROL, FL_Control_L},
+ {VK_RCONTROL, FL_Control_R},
+ {VK_CAPITAL, FL_Caps_Lock},
+ {VK_LWIN, FL_Meta_L},
+ {VK_RWIN, FL_Meta_R},
+ {VK_LMENU, FL_Alt_L},
+ {VK_RMENU, FL_Alt_R},
+ {VK_DELETE, FL_Delete}
+};
+
+static int fltk2ms(int fltk) {
+ if (fltk >= '0' && fltk <= '9') return fltk;
+ if (fltk >= 'A' && fltk <= 'Z') return fltk;
+ if (fltk >= 'a' && fltk <= 'z') return toupper(fltk);
+ if (fltk > FL_F && fltk <= FL_F+16) return fltk-(FL_F-(VK_F1-1));
+ if (fltk >= FL_KP+'0' && fltk<=FL_KP+'9') return fltk-(FL_KP+'0'-VK_NUMPAD0);
+ int a = 0;
+ int b = sizeof(vktab)/sizeof(*vktab);
+ while (a < b) {
+ int c = (a+b)/2;
+ if (vktab[c].fltk == fltk) return vktab[c].vk;
+ if (vktab[c].fltk < fltk) a = c+1; else b = c;
+ }
+ return 0;
+}
+
+int Fl::event_key(int k) {
+ return GetKeyState(fltk2ms(k))&~1;
+}
+
+int Fl::get_key(int k) {
+ uchar foo[256];
+ GetKeyboardState(foo);
+ return foo[fltk2ms(k)]&~1;
+}
diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx
new file mode 100644
index 000000000..ada3fdd3c
--- /dev/null
+++ b/src/Fl_get_system_colors.cxx
@@ -0,0 +1,66 @@
+// Fl_get_system_colors.C
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/math.h>
+
+void Fl::background(uchar r, uchar g, uchar b) {
+ // replace the gray ramp so that FL_GRAY is this color
+ if (!r) r = 1; else if (r==255) r = 254;
+ double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+ if (!g) g = 1; else if (g==255) g = 254;
+ double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+ if (!b) b = 1; else if (b==255) b = 254;
+ double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+ for (int i = 0; i < FL_NUM_GRAY; i++) {
+ double gray = i/(FL_NUM_GRAY-1.0);
+ Fl::set_color(fl_gray_ramp(i),
+ uchar(pow(gray,powr)*255+.5),
+ uchar(pow(gray,powg)*255+.5),
+ uchar(pow(gray,powb)*255+.5));
+ }
+}
+
+static void set_others() {
+ uchar r,g,b; Fl::get_color(FL_BLACK,r,g,b);
+ uchar r1,g1,b1; Fl::get_color(FL_WHITE,r1,g1,b1);
+ Fl::set_color(FL_INACTIVE_COLOR,(2*r+r1)/3, (2*g+g1)/3, (2*b+b1)/3);
+ Fl::set_color(FL_SELECTION_COLOR,(2*r1+r)/3, (2*g1+g)/3, (2*b1+b)/3);
+}
+
+void Fl::foreground(uchar r, uchar g, uchar b) {
+ Fl::set_color(FL_BLACK,r,g,b);
+ set_others();
+}
+
+void Fl::background2(uchar r, uchar g, uchar b) {
+ Fl::set_color(FL_WHITE,r,g,b);
+ set_others();
+}
+
+#ifdef WIN32
+
+static void getsyscolor(int what, void (*func)(uchar,uchar,uchar)) {
+ DWORD x = GetSysColor(what);
+ uchar r = uchar(x&255);
+ uchar g = uchar(x>>8);
+ uchar b = uchar(x>>16);
+ func(r,g,b);
+}
+
+void Fl::get_system_colors() {
+ getsyscolor(COLOR_WINDOWTEXT, Fl::foreground);
+ getsyscolor(COLOR_BTNFACE, Fl::background);
+ getsyscolor(COLOR_WINDOW, Fl::background2);
+}
+
+#else
+// For X we should do something. KDE stores these colors in some standard
+// place, where?
+
+void Fl::get_system_colors()
+{
+ fl_open_display();
+}
+
+#endif
diff --git a/src/Fl_own_colormap.cxx b/src/Fl_own_colormap.cxx
new file mode 100644
index 000000000..8f4ca3524
--- /dev/null
+++ b/src/Fl_own_colormap.cxx
@@ -0,0 +1,50 @@
+// Fl_own_colormap.C
+
+// Using the default system colormap can be a bad idea on PseudoColor
+// visuals, since typically every application uses the default colormap and
+// you can run out of colormap entries easily.
+//
+// The solution is to always create a new colormap on PseudoColor displays
+// and copy the first 16 colors from the default colormap so that we won't
+// get huge color changes when switching windows.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+#ifdef WIN32
+// There is probably something relevant to do on MSWindows 8-bit displays
+// but I don't know what it is
+
+void Fl::own_colormap() {}
+
+#else
+// X version
+
+void Fl::own_colormap() {
+ fl_open_display();
+#if USE_COLORMAP
+ switch (fl_visual->c_class) {
+ case GrayScale :
+ case PseudoColor :
+ case DirectColor :
+ break;
+ default:
+ return; // don't do anything for non-colormapped visuals
+ }
+ int i;
+ XColor colors[16];
+ // Get the first 16 colors from the default colormap...
+ for (i = 0; i < 16; i ++) colors[i].pixel = i;
+ XQueryColors(fl_display, fl_colormap, colors, 16);
+ // Create a new colormap...
+ fl_colormap = XCreateColormap(fl_display,
+ RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ // Copy those first 16 colors to our own colormap:
+ for (i = 0; i < 16; i ++)
+ XAllocColor(fl_display, fl_colormap, colors + i);
+#endif
+}
+
+#endif
diff --git a/src/Fl_visual.cxx b/src/Fl_visual.cxx
new file mode 100644
index 000000000..d45c3ed49
--- /dev/null
+++ b/src/Fl_visual.cxx
@@ -0,0 +1,78 @@
+// Fl_visual.C
+//
+// Set the default visual according to passed switches:
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+#ifdef WIN32
+int Fl::visual(int flags) {
+ if (flags & FL_DOUBLE) return 0;
+ if (!(flags & FL_INDEX) &&
+ GetDeviceCaps(fl_GetDC(0),BITSPIXEL) <= 8) return 0;
+ if ((flags & FL_RGB8) && GetDeviceCaps(fl_GetDC(0),BITSPIXEL)<24) return 0;
+ return 1;
+}
+#else
+
+#if USE_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+
+static int test_visual(XVisualInfo& v, int flags) {
+ if (v.screen != fl_screen) return 0;
+ if (!(flags & FL_INDEX)) {
+ if (!v.red_mask) return 0; // detects static, true, and direct color
+ if (v.depth <= 8) return 0; // fltk will work better in colormap mode
+ }
+ if (flags & FL_RGB8) {
+ if (v.depth < 24) return 0;
+ }
+ // for now, fltk does not like colormaps of more than 8 bits:
+ if (!v.red_mask && v.depth > 8) return 0;
+#if USE_XDBE
+ if (flags & FL_DOUBLE) {
+ static XdbeScreenVisualInfo *xdbejunk;
+ if (!xdbejunk) {
+ int event_base, error_base;
+ if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
+ Drawable root = RootWindow(fl_display,fl_screen);
+ int numscreens = 1;
+ xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+ if (!xdbejunk) return 0;
+ }
+ for (int j = 0; ; j++) {
+ if (j >= xdbejunk->count) return 0;
+ if (xdbejunk->visinfo[j].visual == v.visualid) break;
+ }
+ }
+#endif
+ return 1;
+}
+
+int Fl::visual(int flags) {
+#if USE_XDBE == 0
+ if (flags & FL_DOUBLE) return 0;
+#endif
+ fl_open_display();
+ // always use default if possible:
+ if (test_visual(*fl_visual, flags)) return 1;
+ // get all the visuals:
+ XVisualInfo vTemplate;
+ int num;
+ XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num);
+ // find all matches, use the one with greatest depth:
+ XVisualInfo *found = 0;
+ for (int i=0; i<num; i++) if (test_visual(visualList[i], flags)) {
+ if (!found || found->depth < visualList[i].depth)
+ found = &visualList[i];
+ }
+ if (!found) {XFree((void*)visualList); return 0;}
+ fl_visual = found;
+ fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ return 1;
+}
+
+#endif
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
new file mode 100644
index 000000000..d00a22531
--- /dev/null
+++ b/src/Fl_win32.cxx
@@ -0,0 +1,696 @@
+// Fl_win32.C
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+
+// Written by Bill Spitzak spitzak@d2.com
+
+// This file contains win32-specific code for fltk which is always linked
+// in. Search other files for "WIN32" or filenames ending in _win32.C
+// for other system-specific code.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/win32.H>
+#include <FL/Fl_Window.H>
+#include <string.h>
+
+////////////////////////////////////////////////////////////////
+// interface to poll/select call:
+
+// fd's are not yet implemented.
+// On NT these are probably only used for network stuff, so this may
+// talk to a package that Wonko has proposed writing to make the network
+// interface system independent.
+
+#define POLLIN 1
+#define POLLOUT 4
+#define POLLERR 8
+
+void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {}
+
+void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
+ Fl::add_fd(fd,POLLIN,cb,v);
+}
+
+void Fl::remove_fd(int n) {}
+
+MSG fl_msg;
+
+int fl_ready() {
+ return PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE);
+}
+
+double fl_wait(int timeout_flag, double time) {
+ int have_message;
+ // get the first message by waiting the correct amount of time:
+ if (!timeout_flag) {
+ GetMessage(&fl_msg, NULL, 0, 0);
+ have_message = 1;
+ } else {
+ if (time >= 0.001) {
+ int timerid = SetTimer(NULL, 0, int(time*1000), NULL);
+ GetMessage(&fl_msg, NULL, 0, 0);
+ KillTimer(NULL, timerid);
+ have_message = 1;
+ } else {
+ have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
+ }
+ }
+ // execute it, them execute any other messages that become ready during it:
+ while (have_message) {
+ DispatchMessage(&fl_msg);
+ have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
+ }
+ return time;
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl::h() {return GetSystemMetrics(SM_CYSCREEN);}
+
+int Fl::w() {return GetSystemMetrics(SM_CXSCREEN);}
+
+void Fl::get_mouse(int &x, int &y) {
+ POINT p;
+ GetCursorPos(&p);
+ x = p.x;
+ y = p.y;
+}
+
+////////////////////////////////////////////////////////////////
+
+extern Fl_Window *fl_xfocus; // in Fl.C
+extern Fl_Window *fl_xmousewin; // in Fl.C
+void fl_fix_focus(); // in Fl.C
+
+////////////////////////////////////////////////////////////////
+
+extern HWND fl_capture;
+
+static int mouse_event(Fl_Window *window, int what, int button,
+ WPARAM wParam, LPARAM lParam)
+{
+ static int px, py, pmx, pmy;
+ POINT pt;
+ Fl::e_x = pt.x = (signed short)LOWORD(lParam);
+ Fl::e_y = pt.y = (signed short)HIWORD(lParam);
+ ClientToScreen(fl_xid(window), &pt);
+ Fl::e_x_root = pt.x;
+ Fl::e_y_root = pt.y;
+ while (window->parent()) {
+ Fl::e_x += window->x();
+ Fl::e_y += window->y();
+ window = window->window();
+ }
+
+ ulong state = Fl::e_state & 0xff0000; // keep shift key states
+#if 0
+ // mouse event reports some shift flags, perhaps save them?
+ if (wParam & MK_SHIFT) state |= FL_SHIFT;
+ if (wParam & MK_CONTROL) state |= FL_CTRL;
+#endif
+ if (wParam & MK_LBUTTON) state |= FL_BUTTON1;
+ if (wParam & MK_MBUTTON) state |= FL_BUTTON2;
+ if (wParam & MK_RBUTTON) state |= FL_BUTTON3;
+ Fl::e_state = state;
+
+ switch (what) {
+ case 1: // double-click
+ if (Fl::e_is_click) {Fl::e_clicks++; goto J1;}
+ case 0: // single-click
+ Fl::e_clicks = 0;
+ J1:
+ if (!fl_capture) SetCapture(fl_xid(window));
+ Fl::e_keysym = FL_Button + button;
+ Fl::e_is_click = 1;
+ px = pmx = Fl::e_x_root; py = pmy = Fl::e_y_root;
+ return Fl::handle(FL_PUSH,window);
+
+ case 2: // release:
+ if (!fl_capture) ReleaseCapture();
+ Fl::e_keysym = FL_Button + button;
+ return Fl::handle(FL_RELEASE,window);
+
+ case 3: // move:
+ default: // avoid compiler warning
+ // MSWindows produces extra events even if mouse does not move, ignore em:
+ if (Fl::e_x_root == pmx && Fl::e_y_root == pmy) return 1;
+ pmx = Fl::e_x_root; pmy = Fl::e_y_root;
+ if (abs(Fl::e_x_root-px)>5 || abs(Fl::e_y_root-py)>5) Fl::e_is_click = 0;
+ return Fl::handle(FL_MOVE,window);
+
+ }
+}
+
+// convert a Micro$oft VK_x to an Fltk (X) Keysym:
+// See also the inverse converter in Fl_get_key_win32.C
+// This table is in numeric order by VK:
+static const struct {unsigned short vk, fltk;} vktab[] = {
+ {VK_BACK, FL_BackSpace},
+ {VK_TAB, FL_Tab},
+ {VK_CLEAR, FL_KP+'5'},
+ {VK_RETURN, FL_Enter},
+ {VK_SHIFT, FL_Shift_L},
+ {VK_CONTROL, FL_Control_L},
+ {VK_MENU, FL_Alt_L},
+ {VK_PAUSE, FL_Pause},
+ {VK_CAPITAL, FL_Caps_Lock},
+ {VK_ESCAPE, FL_Escape},
+ {VK_SPACE, ' '},
+ {VK_PRIOR, FL_Page_Up},
+ {VK_NEXT, FL_Page_Down},
+ {VK_END, FL_End},
+ {VK_HOME, FL_Home},
+ {VK_LEFT, FL_Left},
+ {VK_UP, FL_Up},
+ {VK_RIGHT, FL_Right},
+ {VK_DOWN, FL_Down},
+ {VK_SNAPSHOT, FL_Print}, // does not work on NT
+ {VK_INSERT, FL_Insert},
+ {VK_DELETE, FL_Delete},
+ {VK_LWIN, FL_Meta_L},
+ {VK_RWIN, FL_Meta_R},
+ {VK_APPS, FL_Menu},
+ {VK_MULTIPLY, FL_KP+'*'},
+ {VK_ADD, FL_KP+'+'},
+ {VK_SUBTRACT, FL_KP+'-'},
+ {VK_DECIMAL, FL_KP+'.'},
+ {VK_DIVIDE, FL_KP+'/'},
+ {VK_NUMLOCK, FL_Num_Lock},
+ {VK_SCROLL, FL_Scroll_Lock},
+ {0xba, ';'},
+ {0xbb, '='},
+ {0xbc, ','},
+ {0xbd, '-'},
+ {0xbe, '.'},
+ {0xbf, '/'},
+ {0xc0, '`'},
+ {0xdb, '['},
+ {0xdc, '\\'},
+ {0xdd, ']'},
+ {0xde, '\''}
+};
+static int ms2fltk(int vk, int extended) {
+ static unsigned short vklut[256];
+ if (!vklut[1]) { // init the table
+ int i;
+ for (i = 0; i < 256; i++) vklut[i] = tolower(i);
+ for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1));
+ for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);
+ for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++)
+ vklut[vktab[i].vk] = vktab[i].fltk;
+ }
+ if (extended) switch (vk) {
+ case VK_CONTROL : return FL_Control_R;
+ case VK_MENU: return FL_Alt_R;
+ case VK_RETURN: return FL_KP_Enter;
+ }
+ return vklut[vk];
+}
+
+char fl_direct_paint;
+static HDC direct_paint_dc;
+
+#if USE_COLORMAP
+extern HPALETTE fl_select_palette(); // in fl_color_win32.C
+#endif
+
+static Fl_Window* resize_bug_fix;
+
+static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static char buffer[2];
+
+ fl_msg.message = uMsg;
+
+ Fl_Window *window = fl_find(hWnd);
+
+ STUPID_MICROSOFT:
+ if (window) switch (uMsg) {
+
+ case WM_QUIT: // this should not happen?
+ Fl::fatal("WM_QUIT message");
+
+ case WM_CLOSE: // user clicked close box
+ Fl::handle(FL_CLOSE, window);
+ return 0;
+
+ case WM_PAINT: {
+ // MSWindows has already set the clip region! Fltk does not like this,
+ // since it wants to draw it's own damage at the same time, and
+ // this damage may be outside the clip region. I kludge around
+ // this, grep for fl_direct_paint to find the kludges...
+ if (!window->damage()) fl_direct_paint = 1;
+ PAINTSTRUCT ps;
+ direct_paint_dc = BeginPaint(hWnd, &ps);
+ window->expose(2, ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right-ps.rcPaint.left,
+ ps.rcPaint.bottom-ps.rcPaint.top);
+ if (!fl_direct_paint) {EndPaint(hWnd,&ps);ReleaseDC(hWnd,direct_paint_dc);}
+ Fl_X::i(window)->flush();
+ window->clear_damage();
+ Fl_X::i(window)->region = 0;
+ if (fl_direct_paint) {EndPaint(hWnd, &ps); fl_direct_paint = 0;}
+ } break;
+
+ case WM_LBUTTONDOWN: mouse_event(window, 0, 1, wParam, lParam); return 0;
+ case WM_LBUTTONDBLCLK:mouse_event(window, 1, 1, wParam, lParam); return 0;
+ case WM_LBUTTONUP: mouse_event(window, 2, 1, wParam, lParam); return 0;
+ case WM_MBUTTONDOWN: mouse_event(window, 0, 2, wParam, lParam); return 0;
+ case WM_MBUTTONDBLCLK:mouse_event(window, 1, 2, wParam, lParam); return 0;
+ case WM_MBUTTONUP: mouse_event(window, 2, 2, wParam, lParam); return 0;
+ case WM_RBUTTONDOWN: mouse_event(window, 0, 3, wParam, lParam); return 0;
+ case WM_RBUTTONDBLCLK:mouse_event(window, 1, 3, wParam, lParam); return 0;
+ case WM_RBUTTONUP: mouse_event(window, 2, 3, wParam, lParam); return 0;
+ case WM_MOUSEMOVE: mouse_event(window, 3, 0, wParam, lParam); return 0;
+
+ // kludges so the pop-up menus work. Title bar still blinks, sigh...
+ case WM_CAPTURECHANGED:
+ if (fl_capture && lParam != (LPARAM)fl_capture) {
+ SetCapture(fl_capture);
+ return 0;
+ }
+ break;
+ case WM_ACTIVATE:
+ if (fl_capture && wParam && hWnd!=fl_capture) {
+ SetActiveWindow(fl_capture);
+ return 0;
+ }
+ break;
+
+ case WM_SETFOCUS:
+ Fl::handle(FL_FOCUS, window);
+ break;
+
+ case WM_KILLFOCUS:
+ Fl::handle(FL_UNFOCUS, window);
+ Fl::flush(); // it never returns to main loop when deactivated...
+ break;
+
+ case WM_SHOWWINDOW:
+ if (!window->parent())
+ Fl::handle(wParam ? FL_SHOW : FL_HIDE, window);
+ break;
+
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ // save the keysym until we figure out the characters:
+ Fl::e_keysym = ms2fltk(wParam,lParam&(1<<24));
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ TranslateMessage(&fl_msg); // always returns 1!!!
+ // TranslateMessage is supposed to return true only if it turns
+ // into another message, but it seems to always return 1 on my
+ // NT machine. So I will instead peek to see if there is a
+ // character message in the queue, I hope this can only happen
+ // if the translation worked:
+ if (PeekMessage(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, 1)) {
+ uMsg = fl_msg.message;
+ wParam = fl_msg.wParam;
+ lParam = fl_msg.lParam;
+ goto STUPID_MICROSOFT;
+ }
+ // otherwise use it as a 0-character key...
+ case WM_DEADCHAR:
+ case WM_SYSDEADCHAR:
+ buffer[0] = 0;
+ Fl::e_text = buffer;
+ Fl::e_length = 0;
+ goto GETSTATE;
+ case WM_CHAR:
+ case WM_SYSCHAR:
+ buffer[0] = char(wParam);
+ Fl::e_text = buffer;
+ Fl::e_length = 1;
+ GETSTATE:
+ {ulong state = Fl::e_state & 0xff000000; // keep the mouse button state
+ // if GetKeyState is expensive we might want to comment some of these out:
+ if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
+ if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK;
+ if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL;
+ // Alt gets reported for the Alt-GR switch on foreign keyboards.
+ // so we need to check the event as well to get it right:
+ if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU)
+ && uMsg != WM_CHAR) state |= FL_ALT;
+ if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK;
+ if (GetKeyState(VK_LWIN)&~1 || GetKeyState(VK_RWIN)&~1) state |= FL_META;
+ if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
+ Fl::e_state = state;}
+ if (lParam & (1<<31)) goto DEFAULT; // ignore up events after fixing shift
+ // for (int i = lParam&0xff; i--;)
+ while (window->parent()) window = window->window();
+ if (Fl::handle(FL_KEYBOARD,window)) return 0;
+ break;
+
+ case WM_GETMINMAXINFO:
+ Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
+ break;
+
+ case WM_SIZE:
+ if (!window->parent()) {
+ if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) {
+ Fl::handle(FL_HIDE, window);
+ } else {
+ Fl::handle(FL_SHOW, window);
+ resize_bug_fix = window;
+ window->size(LOWORD(lParam), HIWORD(lParam));
+ }
+ }
+ break;
+
+ case WM_MOVE:
+ resize_bug_fix = window;
+ window->position(LOWORD(lParam), HIWORD(lParam));
+ break;
+
+ case WM_SETCURSOR:
+ if (LOWORD(lParam) == HTCLIENT) {
+ while (window->parent()) window = window->window();
+ SetCursor(Fl_X::i(window)->cursor);
+ return 0;
+ }
+ break;
+
+#if USE_COLORMAP
+ case WM_QUERYNEWPALETTE :
+ fl_GetDC(hWnd);
+ if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE);
+ break;
+
+ case WM_PALETTECHANGED:
+ fl_GetDC(hWnd);
+ if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc);
+ break;
+
+ case WM_CREATE :
+ fl_GetDC(hWnd);
+ fl_select_palette();
+ break;
+#endif
+
+ default:
+ DEFAULT:
+ if (Fl::handle(0,0)) return 0;
+ break;
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window::resize(int X,int Y,int W,int H) {
+ int resize_from_program = 1;
+ if (this == resize_bug_fix) {
+ resize_from_program = 0;
+ resize_bug_fix = 0;
+ }
+ if (X==x() && Y==y() && W==w() && H==h()) return;
+ if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION);
+ if (W != w() || H != h()) Fl_Group::resize(X,Y,W,H); else {x(X); y(Y);}
+ if (resize_from_program && shown()) {
+ if (border() && !parent()) {
+ X -= GetSystemMetrics(SM_CXFRAME);
+ Y -= GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYCAPTION);
+ W += 2*GetSystemMetrics(SM_CXFRAME);
+ H += 2*GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYCAPTION);
+ }
+ MoveWindow(i->xid, X, Y, W, H, TRUE);
+ //if (!parent()) redraw();
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+char fl_show_iconic; // hack for Fl_Window::iconic()
+// int fl_background_pixel = -1; // color to use for background
+HCURSOR fl_default_cursor;
+int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
+
+Fl_X* Fl_X::make(Fl_Window* w) {
+ Fl_Group::current(0); // get rid of very common user bug: forgot end()
+ w->clear_damage(); // wait for expose events
+
+ static char* class_name;
+ if (!class_name) { // create a single WNDCLASS used for everything:
+ class_name = "FLTK";
+ WNDCLASSEX wc;
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
+ wc.lpfnWndProc = (WNDPROC)WndProc;
+ wc.cbClsExtra = wc.cbWndExtra = 0;
+ wc.hInstance = fl_display;
+ wc.hIcon = wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
+ //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
+ //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = class_name;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ RegisterClassEx(&wc);
+ }
+
+ HWND parent;
+ DWORD style;
+ DWORD styleEx;
+ int xp = w->x();
+ int yp = w->y();
+ int wp = w->w();
+ int hp = w->h();
+
+ if (w->parent()) {
+ style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+ styleEx = WS_EX_LEFT | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
+ parent = fl_xid(w->window());
+ } else {
+ if (!w->size_range_set) {
+ if (w->resizable()) {
+ Fl_Widget *o = w->resizable();
+ int minw = o->w(); if (minw > 100) minw = 100;
+ int minh = o->h(); if (minh > 100) minh = 100;
+ w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
+ } else {
+ w->size_range(w->w(), w->h(), w->w(), w->h());
+ }
+ }
+ if (w->border()) {
+ style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
+ | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+ styleEx = WS_EX_LEFT | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
+ if (w->maxw != w->minw || w->maxh != w->minh)
+ style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
+ if (!w->modal()) style |= WS_MINIMIZEBOX;
+ xp -= GetSystemMetrics(SM_CXFRAME);
+ yp -= GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYCAPTION);
+ wp += 2*GetSystemMetrics(SM_CXFRAME);
+ hp += 2*GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYCAPTION);
+ } else {
+ style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPED;
+ styleEx = WS_EX_LEFT | WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
+ }
+ if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) {
+ xp = yp = CW_USEDEFAULT;
+ }
+ parent = 0;
+ if (w->non_modal() && !fl_disable_transient_for) {
+ // find some other window to be "transient for":
+ for (Fl_X* y = Fl_X::first; y; y = y->next) {
+ Fl_Window* w = y->w;
+ while (w->parent()) w = w->window();
+ if (!w->non_modal()) {
+ parent = fl_xid(w);
+ break;
+ }
+ }
+ }
+ }
+
+ Fl_X* x = new Fl_X;
+ x->other_xid = 0;
+ x->setwindow(w);
+ x->region = 0;
+ x->private_dc = 0;
+ x->cursor = fl_default_cursor;
+ x->xid = CreateWindowEx(
+ styleEx,
+ class_name, w->label(), style,
+ xp, yp, wp, hp,
+ parent,
+ NULL, // menu
+ fl_display,
+ NULL // creation parameters
+ );
+ x->next = Fl_X::first;
+ Fl_X::first = x;
+
+ // use w->xclass() to set the icon...
+
+ w->set_visible();
+ w->handle(FL_SHOW); // get child windows to appear
+ ShowWindow(x->xid, fl_show_iconic ? SW_MINIMIZE : SW_SHOW);
+ fl_show_iconic = 0;
+ fl_fix_focus();
+ return x;
+}
+
+////////////////////////////////////////////////////////////////
+
+HINSTANCE fl_display;
+
+int Fl_WinMain(HINSTANCE hInstance, LPSTR lpCmdLine, int nCmdShow,
+ int (*mainp)(int, char**)) {
+ fl_display = hInstance;
+
+ int argc;
+ char **argv;
+ // test version for now:
+ argc = 1; char* testargv[] = {"test", 0}; argv = testargv;
+
+ return mainp(argc, argv);
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window::size_range_() {
+ size_range_set = 1;
+}
+
+void Fl_X::set_minmax(LPMINMAXINFO minmax)
+{
+ int wd, hd;
+ if (w->border()) {
+ wd = 2*GetSystemMetrics(SM_CXFRAME);
+ hd = 2*GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION);
+ } else {
+ wd = hd = 0;
+ }
+ minmax->ptMinTrackSize.x = w->minw + wd;
+ minmax->ptMinTrackSize.y = w->minh + hd;
+ if (w->maxw) {
+ minmax->ptMaxTrackSize.x = w->maxw + wd;
+ minmax->ptMaxSize.x = w->maxw + wd;
+ }
+ if (w->maxh) {
+ minmax->ptMaxTrackSize.y = w->maxh + hd;
+ minmax->ptMaxSize.y = w->maxh + hd;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// returns pointer to the filename, or null if name ends with '/'
+const char *filename_name(const char *name) {
+ const char *p,*q;
+ q = name;
+ if (q[0] && q[1]==':') q += 2; // skip leading drive letter
+ for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1;
+ return q;
+}
+
+void Fl_Window::label(const char *name,const char *iname) {
+ Fl_Widget::label(name);
+ iconlabel_ = iname;
+ if (shown() && !parent()) {
+ if (!name) name = "";
+ SetWindowText(i->xid, name);
+ // if (!iname) iname = filename_name(name);
+ // should do something with iname here...
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// Implement the virtual functions for the base Fl_Window class:
+
+// If the box is a filled rectangle, we can make the redisplay *look*
+// faster by using X's background pixel erasing. We can make it
+// actually *be* faster by drawing the frame only, this is done by
+// setting fl_boxcheat, which is seen by code in fl_drawbox.C:
+// For WIN32 it looks like all windows share a background color, so
+// I use FL_GRAY for this and only do this cheat for windows that are
+// that color.
+// Actually it is totally disabled.
+// Fl_Widget *fl_boxcheat;
+//static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}
+
+void Fl_Window::show() {
+ if (!shown()) {
+ // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color());
+ Fl_X::make(this);
+ } else {
+ ShowWindow(i->xid, SW_RESTORE);
+ SetActiveWindow(i->xid);
+ }
+}
+
+Fl_Window *Fl_Window::current_;
+HDC fl_gc; // the current context
+HWND fl_window; // the current window
+
+// Make sure we always ReleaseDC every DC we allocate...
+HDC fl_GetDC(HWND w) {
+ if (fl_gc) {
+ if (w == fl_window) return fl_gc;
+ ReleaseDC(fl_window, fl_gc);
+ }
+ fl_gc = fl_direct_paint ? direct_paint_dc : GetDC(w);
+ fl_window = w;
+ // calling GetDC seems to always reset these: (?)
+ SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
+ SetBkMode(fl_gc, TRANSPARENT);
+ return fl_gc;
+}
+
+// make X drawing go into this window (called by subclass flush() impl.)
+void Fl_Window::make_current() {
+ fl_GetDC(fl_xid(this));
+ current_ = this;
+}
+
+// WM_PAINT events and cropped damage call this:
+void Fl_Window::expose(uchar flags,int X,int Y,int W,int H) {
+ if (i) {
+ if (!i->region.r) {
+ i->region.x = X;
+ i->region.y = Y;
+ i->region.r = X+W;
+ i->region.b = Y+H;
+ } else {
+ if (X < i->region.x) i->region.x = X;
+ if (Y < i->region.y) i->region.y = Y;
+ if (X+W > i->region.r) i->region.r = X+W;
+ if (Y+H > i->region.b) i->region.b = Y+H;
+ }
+ }
+ damage(flags);
+}
+
+#include <FL/fl_draw.H>
+
+void Fl_Window::flush() {
+ make_current();
+ if (damage() & ~6) {
+ draw();
+ } else {
+ fl_clip_region(i->region);
+ draw();
+ fl_pop_clip();
+ }
+}
+
+// End of Fl_win32.C //
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
new file mode 100644
index 000000000..2d5a5ab46
--- /dev/null
+++ b/src/Fl_x.cxx
@@ -0,0 +1,807 @@
+// Fl_x.C
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+
+// Written by Bill Spitzak spitzak@d2.com
+
+#ifdef WIN32
+#include "Fl_win32.C"
+#else
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+////////////////////////////////////////////////////////////////
+// interface to poll/select call:
+
+#if HAVE_POLL
+#include <poll.h>
+#else
+struct pollfd {int fd; short events; short revents;};
+#define POLLIN 1
+#define POLLOUT 4
+#define POLLERR 8
+#ifdef __sgi // fix bugs in Irix's select header:
+//inline static void bzero(void *b, int l) {memset(b,0,l);}
+extern "C" int select( int, fd_set *, fd_set *, fd_set *, struct timeval * );
+#endif
+#ifdef hpux // fix from wm2:
+#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
+#endif
+#ifdef __EMX__
+#include <sys/select.h>
+#endif
+#endif
+
+#define MAXFD 8
+#if !HAVE_POLL
+static fd_set fdsets[3];
+static int maxfd;
+#endif
+static int nfds;
+static struct pollfd fds[MAXFD];
+static struct {
+ void (*cb)(int, void*);
+ void* arg;
+} fd[MAXFD];
+
+void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
+ int i;
+ if (nfds < MAXFD) {i = nfds; nfds++;} else {i = MAXFD-1;}
+ fds[i].fd = n;
+ fds[i].events = events;
+#if !HAVE_POLL
+ if (events & POLLIN) FD_SET(n, &fdsets[0]);
+ if (events & POLLOUT) FD_SET(n, &fdsets[1]);
+ if (events & POLLERR) FD_SET(n, &fdsets[2]);
+ if (n > maxfd) maxfd = n;
+#endif
+ fd[i].cb = cb;
+ fd[i].arg = v;
+}
+
+void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
+ Fl::add_fd(fd,POLLIN,cb,v);
+}
+
+void Fl::remove_fd(int n) {
+ int i,j;
+ for (i=j=0; i<nfds; i++) {
+ if (fds[i].fd == n);
+ else {if (j<i) {fd[j]=fd[i]; fds[j]=fds[i];} j++;}
+ }
+ nfds = j;
+#if !HAVE_POLL
+ FD_CLR(n, &fdsets[0]);
+ FD_CLR(n, &fdsets[1]);
+ FD_CLR(n, &fdsets[2]);
+ if (n == maxfd) maxfd--;
+#endif
+}
+
+int fl_ready() {
+ if (XQLength(fl_display)) return 1;
+#if HAVE_POLL
+ return ::poll(fds, nfds, 0);
+#else
+ timeval t;
+ t.tv_sec = 0;
+ t.tv_usec = 0;
+ fd_set fdt[3];
+ fdt[0] = fdsets[0];
+ fdt[1] = fdsets[1];
+ fdt[2] = fdsets[2];
+ return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
+#endif
+}
+
+static void do_queued_events() {
+ while (XEventsQueued(fl_display,QueuedAfterReading)) {
+ XEvent xevent;
+ XNextEvent(fl_display, &xevent);
+ fl_handle(xevent);
+ }
+}
+
+double fl_wait(int timeout_flag, double time) {
+
+ // OpenGL and other broken libraries call XEventsQueued
+ // unnecessarily and thus cause the file descriptor to not be ready,
+ // so we must check for already-read events:
+ if (XQLength(fl_display)) {do_queued_events(); return time;}
+
+#if !HAVE_POLL
+ fd_set fdt[3];
+ fdt[0] = fdsets[0];
+ fdt[1] = fdsets[1];
+ fdt[2] = fdsets[2];
+#endif
+ int n;
+
+ if (!timeout_flag) {
+#if HAVE_POLL
+ n = ::poll(fds, nfds, -1);
+#else
+ n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
+#endif
+ } else {
+#if HAVE_POLL
+ int n = ::poll(fds, nfds, time > 0.0 ? int(time*1000) : 0);
+#else
+ timeval t;
+ if (time <= 0.0) {
+ t.tv_sec = 0;
+ t.tv_usec = 0;
+ } else {
+ t.tv_sec = int(time);
+ t.tv_usec = int(1000000 * (time-t.tv_sec));
+ }
+ n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
+#endif
+ }
+ if (n > 0) {
+ for (int i=0; i<nfds; i++) {
+#if HAVE_POLL
+ if (fds[i].revents) fd[i].cb(fds[i].fd, fd[i].arg);
+#else
+ int f = fds[i].fd;
+ short revents = 0;
+ if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
+ if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
+ if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
+ if (fds[i].events & revents) fd[i].cb(f, fd[i].arg);
+#endif
+ }
+ }
+ return time;
+}
+
+////////////////////////////////////////////////////////////////
+
+Display *fl_display;
+int fl_screen;
+XVisualInfo *fl_visual;
+Colormap fl_colormap;
+
+static Atom wm_delete_window;
+static Atom wm_protocols;
+static Atom _motif_wm_hints;
+
+static void fd_callback(int,void *) {do_queued_events();}
+
+static int io_error_handler(Display*) {Fl::fatal("X I/O error"); return 0;}
+
+static int xerror_handler(Display* d, XErrorEvent* e) {
+ char buf1[128], buf2[128];
+ sprintf(buf1, "XRequest.%d", e->request_code);
+ XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128);
+ XGetErrorText(d, e->error_code, buf1, 128);
+ Fl::warning("%s: %s 0x%lx", buf2, buf1, e->resourceid);
+ return 0;
+}
+
+void fl_open_display() {
+ if (fl_display) return;
+
+ XSetIOErrorHandler(io_error_handler);
+ XSetErrorHandler(xerror_handler);
+
+ Display *d = XOpenDisplay(0);
+ if (!d) Fl::fatal("Can't open display: %s",XDisplayName(0));
+
+ fl_display = d;
+
+ wm_delete_window = XInternAtom(d,"WM_DELETE_WINDOW",0);
+ wm_protocols = XInternAtom(d,"WM_PROTOCOLS",0);
+ _motif_wm_hints = XInternAtom(d,"_MOTIF_WM_HINTS",0);
+ Fl::add_fd(ConnectionNumber(d), POLLIN, fd_callback);
+
+ fl_screen = DefaultScreen(fl_display);
+// construct an XVisualInfo that matches the default Visual:
+ XVisualInfo templt; int num;
+ templt.visualid = XVisualIDFromVisual(DefaultVisual(fl_display,fl_screen));
+ fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+ fl_colormap = DefaultColormap(fl_display,fl_screen);
+}
+
+void fl_close_display() {
+ Fl::remove_fd(ConnectionNumber(fl_display));
+ XCloseDisplay(fl_display);
+}
+
+int Fl::h() {
+ fl_open_display();
+ return DisplayHeight(fl_display,fl_screen);
+}
+
+int Fl::w() {
+ fl_open_display();
+ return DisplayWidth(fl_display,fl_screen);
+}
+
+void Fl::get_mouse(int &x, int &y) {
+ fl_open_display();
+ Window root = RootWindow(fl_display, fl_screen);
+ Window c; int mx,my,cx,cy; unsigned int mask;
+ XQueryPointer(fl_display,root,&root,&c,&mx,&my,&cx,&cy,&mask);
+ x = mx;
+ y = my;
+}
+
+////////////////////////////////////////////////////////////////
+
+extern Fl_Window *fl_xfocus; // in Fl.C
+extern Fl_Window *fl_xmousewin; // in Fl.C
+void fl_fix_focus(); // in Fl.C
+
+////////////////////////////////////////////////////////////////
+
+const XEvent* fl_xevent; // the current x event
+ulong fl_event_time; // the last timestamp from an x event
+
+char fl_key_vector[32]; // used by Fl::get_key()
+
+// Record event mouse position and state from an XEvent:
+
+static int px, py;
+static ulong ptime;
+
+static void set_event_xy() {
+ Fl::e_x_root = fl_xevent->xbutton.x_root;
+ Fl::e_x = fl_xevent->xbutton.x;
+ Fl::e_y_root = fl_xevent->xbutton.y_root;
+ Fl::e_y = fl_xevent->xbutton.y;
+ Fl::e_state = fl_xevent->xbutton.state << 16;
+ fl_event_time = fl_xevent->xbutton.time;
+#ifdef __sgi
+ // get the meta key off PC keyboards:
+ if (fl_key_vector[18]&0x18) Fl::e_state |= FL_META;
+#endif
+ // turn off is_click if enough time or mouse movement has passed:
+ if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3
+ || fl_event_time >= ptime+1000)
+ Fl::e_is_click = 0;
+}
+
+// if this is same event as last && is_click, increment click count:
+static inline void checkdouble() {
+ if (Fl::e_is_click == Fl::e_keysym)
+ Fl::e_clicks++;
+ else {
+ Fl::e_clicks = 0;
+ Fl::e_is_click = Fl::e_keysym;
+ }
+ px = Fl::e_x_root;
+ py = Fl::e_y_root;
+ ptime = fl_event_time;
+}
+
+static Fl_Window* resize_bug_fix;
+
+////////////////////////////////////////////////////////////////
+
+int fl_handle(const XEvent& xevent)
+{
+ fl_xevent = &xevent;
+
+ switch (xevent.type) { // events where we don't care about window
+
+ case KeymapNotify:
+ memcpy(fl_key_vector, xevent.xkeymap.key_vector, 32);
+ return 0;
+
+ case MappingNotify:
+ XRefreshKeyboardMapping((XMappingEvent*)&xevent.xmapping);
+ return 0;
+ }
+
+ int event = 0;
+ Fl_Window* window = fl_find(xevent.xany.window);
+
+ if (window) switch (xevent.type) {
+
+ case ClientMessage:
+ if ((Atom)(xevent.xclient.data.l[0]) == wm_delete_window) event = FL_CLOSE;
+ break;
+
+ case MapNotify:
+ event = FL_SHOW;
+ break;
+
+ case UnmapNotify:
+ event = FL_HIDE;
+ break;
+
+ case Expose:
+ case GraphicsExpose:
+#if 1 // try to keep windows on top even if WM_TRANSIENT_FOR does not work:
+ if (Fl::first_window()->non_modal() && window != Fl::first_window())
+ Fl::first_window()->show();
+#endif
+ window->damage(2, xevent.xexpose.x, xevent.xexpose.y,
+ xevent.xexpose.width, xevent.xexpose.height);
+ return 1;
+
+ case ButtonPress:
+ Fl::e_keysym = FL_Button + xevent.xbutton.button;
+ set_event_xy(); checkdouble();
+ // fix buggy window managers that position window wrong:
+ Fl_X::x(window,Fl::e_x_root-Fl::e_x);
+ Fl_X::y(window,Fl::e_y_root-Fl::e_y);
+ Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
+ event = FL_PUSH;
+ break;
+
+ case MotionNotify:
+ set_event_xy();
+ event = FL_MOVE;
+ break;
+
+ case ButtonRelease:
+ Fl::e_keysym = FL_Button + xevent.xbutton.button;
+ set_event_xy();
+ Fl::e_state &= ~(FL_BUTTON1 << (xevent.xbutton.button-1));
+ event = FL_RELEASE;
+ break;
+
+ case FocusIn:
+ event = FL_FOCUS;
+ break;
+
+ case FocusOut:
+ event = FL_UNFOCUS;
+ break;
+
+ case KeyPress: {
+ static int got_backspace;
+ static char buffer[21];
+ KeySym keysym;
+ int i = xevent.xkey.keycode; fl_key_vector[i/8] |= (1 << (i%8));
+ int len = XLookupString((XKeyEvent*)&(xevent.xkey),buffer,20,&keysym,0);
+ if (!len && keysym < 0x400) {
+ // turn all latin-2,3,4 characters into 8-bit codes:
+ buffer[0] = char(keysym);
+ len = 1;
+ }
+ // ignore all effects of shift on the keysyms (makes it a lot
+ // easier to program shortcuts!)
+ keysym = XKeycodeToKeysym(fl_display, i, 0);
+#ifdef __sgi
+ // get some missing PC keyboard keys:
+ if (!keysym) switch(i) {
+ case 147: keysym = FL_Meta_L; break;
+ case 148: keysym = FL_Meta_R; break;
+ case 149: keysym = FL_Menu; break;
+ }
+#endif
+ if (!got_backspace) {
+ // Backspace kludge: until user hits the backspace key, assumme
+ // it is missing and use the Delete key for that purpose:
+ if (keysym == FL_Delete) keysym = FL_BackSpace;
+ else if (keysym == FL_BackSpace) got_backspace = 1;
+ }
+ if (keysym >= 0xff95 && keysym < 0xffa0) {
+ // Make NumLock irrelevant (always on):
+ // This lookup table turns the XK_KP_* functions back into the
+ // ascii characters. This won't work on non-PC layout keyboards,
+ // but are there any of those left??
+ buffer[0] = "7486293150."[keysym-0xff95];
+ len = 1;
+ keysym = FL_KP+buffer[0];
+ }
+ buffer[len] = 0;
+ Fl::e_keysym = int(keysym);
+ Fl::e_text = buffer;
+ Fl::e_length = len;
+ set_event_xy(); Fl::e_is_click = 0;
+ if (Fl::event_state(FL_CTRL) && keysym == '-') buffer[0] = 0x1f; // ^_
+ event = FL_KEYBOARD;
+ break;}
+
+ case KeyRelease: {
+ int i = xevent.xkey.keycode; fl_key_vector[i/8] &= ~(1 << (i%8));
+ set_event_xy();}
+ break;
+
+ case EnterNotify:
+ if (xevent.xcrossing.detail == NotifyInferior) break;
+ // XInstallColormap(fl_display, Fl_X::i(window)->colormap);
+ set_event_xy();
+ Fl::e_state = xevent.xcrossing.state << 16;
+ event = FL_ENTER;
+ break;
+
+ case LeaveNotify:
+ if (xevent.xcrossing.detail == NotifyInferior) break;
+ set_event_xy();
+ Fl::e_state = xevent.xcrossing.state << 16;
+ event = FL_LEAVE;
+ break;
+
+ case ConfigureNotify: {
+ int x = xevent.xconfigure.x;
+ int y = xevent.xconfigure.y;
+ // avoid bug (?) in 4DWM, it reports position of 0,0 on resize:
+ if (!x && !y) {
+ Window r, c; int X, Y; unsigned int m;
+ XQueryPointer(fl_display, fl_xid(window), &r, &c, &x, &y, &X, &Y, &m);
+ x = x-X; y = y-Y;
+ }
+ resize_bug_fix = window;
+ window->resize(x, y,
+ xevent.xconfigure.width, xevent.xconfigure.height);
+ return 1;}
+ }
+
+ return Fl::handle(event, window);
+}
+
+////////////////////////////////////////////////////////////////
+
+void Fl_Window::resize(int X,int Y,int W,int H) {
+ if (resize_bug_fix == this)
+ resize_bug_fix = 0;
+ else if (shown()) {
+ // tell X window manager to change window size:
+ if (!(flags()&FL_FORCE_POSITION) && X == x() && Y == y())
+ XResizeWindow(fl_display, i->xid, W>0 ? W : 1, H>0 ? H : 1);
+ else if (W != w() || H != h())
+ XMoveResizeWindow(fl_display, i->xid, X, Y, W>0 ? W : 1, H>0 ? H : 1);
+ else
+ XMoveWindow(fl_display, i->xid, X, Y);
+ }
+ if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION);
+ if (W != w() || H != h()) Fl_Group::resize(X,Y,W,H); else {x(X); y(Y);}
+ // Notice that this does *not* set any redraw bits. I assumme
+ // I will receive damage for the whole window from X. I think
+ // that "ForgetGravity" forces the expose event for the entire
+ // window, but this may not be true on some implementations.
+}
+
+////////////////////////////////////////////////////////////////
+
+// A subclass of Fl_Window may call this to associate an X window it
+// creates with the Fl_Window:
+
+Fl_X* Fl_X::set_xid(Fl_Window* w, Window xid) {
+ Fl_X* x = new Fl_X;
+ x->xid = xid;
+ x->other_xid = 0;
+ x->setwindow(w);
+ x->next = Fl_X::first;
+ x->region = 0;
+ Fl_X::first = x;
+ w->set_visible();
+ w->handle(FL_SHOW); // get child windows to appear
+ fl_fix_focus(); // if this is modal we must fix focus now
+ return x;
+}
+
+// More commonly a subclass calls this, because it hides the really
+// ugly parts of X and sets all the stuff for a window that is set
+// normally. The global variables like fl_show_iconic are so that
+// subclasses of *that* class may change the behavior...
+
+char fl_show_iconic; // hack for iconize()
+int fl_background_pixel = -1; // hack to speed up bg box drawing
+int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
+
+static const int childEventMask = ExposureMask;
+
+static const int XEventMask =
+ExposureMask|StructureNotifyMask
+|KeyPressMask|KeyReleaseMask|KeymapStateMask|FocusChangeMask
+|ButtonPressMask|ButtonReleaseMask
+|EnterWindowMask|LeaveWindowMask
+|PointerMotionMask;
+
+void Fl_X::make_xid(Fl_Window* w, XVisualInfo *visual, Colormap colormap)
+{
+ Fl_Group::current(0); // get rid of very common user bug: forgot end()
+
+ ulong root = w->parent() ?
+ fl_xid(w->window()) : RootWindow(fl_display, fl_screen);
+
+ XSetWindowAttributes attr;
+ int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity;
+ attr.event_mask = w->parent() ? childEventMask : XEventMask;
+ attr.colormap = colormap;
+ attr.border_pixel = 0;
+ attr.bit_gravity = 0; // StaticGravity;
+ attr.override_redirect = 0;
+ if (Fl::grab()) {
+ attr.save_under = 1; mask |= CWSaveUnder;
+ if (!w->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;}
+ }
+ if (fl_background_pixel >= 0) {
+ attr.background_pixel = fl_background_pixel;
+ fl_background_pixel = -1;
+ mask |= CWBackPixel;
+ }
+ Fl_X* x =
+ set_xid(w, XCreateWindow(fl_display,
+ root,
+ w->x(), w->y(),
+ w->w()>0 ? w->w() : 1,
+ w->h()>0 ? w->h() : 1,
+ 0, // borderwidth
+ visual->depth,
+ InputOutput,
+ visual->visual,
+ mask, &attr));
+ //XInstallColormap(fl_display, colormap);
+
+ if (!w->parent() && !attr.override_redirect) {
+ // Communicate all kinds 'o junk to the X Window Manager:
+
+ w->label(w->label(), w->iconlabel());
+
+ XChangeProperty(fl_display, x->xid, wm_protocols,
+ XA_ATOM, 32, 0, (uchar*)&wm_delete_window, 1);
+
+ // send size limits and border:
+ x->sendxjunk();
+
+ // set the class property, which controls the icon used:
+ if (w->xclass()) {
+ char buffer[1024];
+ char *p; const char *q;
+ // truncate on any punctuation, because they break XResource lookup:
+ for (p = buffer, q = w->xclass(); isalnum(*q)||(*q&128);) *p++ = *q++;
+ *p++ = 0;
+ // create the capitalized version:
+ q = buffer;
+ *p = toupper(*q++); if (*p++ == 'X') *p++ = toupper(*q++);
+ while ((*p++ = *q++));
+ XChangeProperty(fl_display, x->xid, XA_WM_CLASS, XA_STRING, 8, 0,
+ (unsigned char *)buffer, p-buffer-1);
+ }
+
+ if (w->non_modal() && x->next && !fl_disable_transient_for) {
+ // find some other window to be "transient for":
+ Fl_Window* w = x->next->w;
+ while (w->parent()) w = w->window();
+ XSetTransientForHint(fl_display, x->xid, fl_xid(w));
+ }
+
+ if (fl_show_iconic) {
+ XWMHints hints;
+ hints.flags = StateHint;
+ hints.initial_state = 3;
+ XSetWMHints(fl_display, x->xid, &hints);
+ fl_show_iconic = 0;
+ }
+ }
+
+ XMapWindow(fl_display, x->xid);
+}
+
+////////////////////////////////////////////////////////////////
+// Send X window stuff that can be changed over time:
+
+void Fl_X::sendxjunk() {
+ if (w->parent()) return; // it's not a window manager window!
+
+ if (!w->size_range_set) { // default size_range based on resizable():
+ if (w->resizable()) {
+ Fl_Widget *o = w->resizable();
+ int minw = o->w(); if (minw > 100) minw = 100;
+ int minh = o->h(); if (minh > 100) minh = 100;
+ w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
+ } else {
+ w->size_range(w->w(), w->h(), w->w(), w->h());
+ }
+ return; // because this recursively called here
+ }
+
+ XSizeHints hints;
+ hints.min_width = w->minw;
+ hints.min_height = w->minh;
+ hints.max_width = w->maxw;
+ hints.max_height = w->maxh;
+ hints.width_inc = w->dw;
+ hints.height_inc = w->dh;
+
+ // see the file /usr/include/X11/Xm/MwmUtil.h:
+ // fill all fields to avoid bugs in kwm and perhaps other window managers:
+ // 0, MWM_FUNC_ALL, MWM_DECOR_ALL
+ long prop[5] = {0, 1, 1, 0, 0};
+
+ if (hints.min_width != hints.max_width ||
+ hints.min_height != hints.max_height) { // resizable
+ hints.flags = PMinSize;
+ if (hints.max_width >= hints.min_width ||
+ hints.max_height >= hints.min_height) {
+ hints.flags = PMinSize|PMaxSize;
+ // unfortunately we can't set just one maximum size. Guess a
+ // value for the other one. Some window managers will make the
+ // window fit on screen when maximized, others will put it off screen:
+ if (hints.max_width < hints.min_width) hints.max_width = Fl::w();
+ if (hints.max_height < hints.min_height) hints.max_height = Fl::h();
+ }
+ if (hints.width_inc && hints.height_inc) hints.flags |= PResizeInc;
+ if (w->aspect) {
+ // stupid X! It could insist that the corner go on the
+ // straight line between min and max...
+ hints.min_aspect.x = hints.max_aspect.x = hints.min_width;
+ hints.min_aspect.y = hints.max_aspect.y = hints.min_height;
+ hints.flags |= PAspect;
+ }
+ } else { // not resizable:
+ hints.flags = PMinSize|PMaxSize;
+ prop[0] = 1; // MWM_HINTS_FUNCTIONS
+ prop[1] = 1|2|16; // MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE
+ }
+ if (w->non_modal()) {
+ prop[0] = 1; // MWM_HINTS_FUNCTIONS
+ prop[1] |= 8; // turn off MWM_FUNC_MINIMIZE in 4Dwm
+ }
+
+ if (w->flags() & Fl_Window::FL_FORCE_POSITION) {
+ hints.flags |= USPosition;
+ hints.x = w->x();
+ hints.y = w->y();
+ }
+
+ if (!w->border()) {
+ prop[0] |= 2; // MWM_HINTS_DECORATIONS
+ prop[2] = 0; // no decorations
+ }
+
+ XSetWMNormalHints(fl_display, xid, &hints);
+ XChangeProperty(fl_display, xid,
+ _motif_wm_hints, _motif_wm_hints,
+ 32, 0, (unsigned char *)prop, 5);
+}
+
+void Fl_Window::size_range_() {
+ size_range_set = 1;
+ if (shown()) i->sendxjunk();
+}
+
+////////////////////////////////////////////////////////////////
+
+// returns pointer to the filename, or null if name ends with '/'
+const char *filename_name(const char *name) {
+ const char *p,*q;
+ for (p=q=name; *p;) if (*p++ == '/') q = p;
+ return q;
+}
+
+void Fl_Window::label(const char *name,const char *iname) {
+ Fl_Widget::label(name);
+ iconlabel_ = iname;
+ if (shown() && !parent()) {
+ if (!name) name = "";
+ XChangeProperty(fl_display, i->xid, XA_WM_NAME,
+ XA_STRING, 8, 0, (uchar*)name, strlen(name));
+ if (!iname) iname = filename_name(name);
+ XChangeProperty(fl_display, i->xid, XA_WM_ICON_NAME,
+ XA_STRING, 8, 0, (uchar*)iname, strlen(iname));
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// Implement the virtual functions for the base Fl_Window class:
+
+// If the box is a filled rectangle, we can make the redisplay *look*
+// faster by using X's background pixel erasing. We can make it
+// actually *be* faster by drawing the frame only, this is done by
+// setting fl_boxcheat, which is seen by code in fl_drawbox.C:
+//
+// On XFree86 (and prehaps all X's) this has a problem if the window
+// is resized while a save-behind window is atop it. The previous
+// contents are restored to the area, but this assummes the area
+// is cleared to background color. So this is disabled in this version.
+// Fl_Window *fl_boxcheat;
+static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}
+
+void Fl_Window::show() {
+ if (!shown()) {
+ fl_open_display();
+ if (can_boxcheat(box())) fl_background_pixel = int(fl_xpixel(color()));
+ Fl_X::make_xid(this);
+ } else {
+ XMapRaised(fl_display, i->xid);
+ }
+}
+
+Window fl_window;
+Fl_Window *Fl_Window::current_;
+GC fl_gc;
+
+// make X drawing go into this window (called by subclass flush() impl.)
+void Fl_Window::make_current() {
+ static GC gc; // the GC used by all X windows
+ if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
+ fl_window = i->xid;
+ fl_gc = gc;
+ current_ = this;
+ fl_clip_region(0);
+}
+
+#include <FL/fl_draw.H>
+
+// Current meaning of damage() bits on a window:
+// 1 = a child needs redrawing
+// 2 = expose events
+// 128 = redraw everything
+
+void Fl_Widget::damage(uchar flags) {
+ if (type() < FL_WINDOW) {
+ damage(flags, x(), y(), w(), h());
+ } else {
+ Fl_X* i = Fl_X::i((Fl_Window*)this);
+ if (i) {
+ if (i->region) {XDestroyRegion(i->region); i->region = 0;}
+ damage_ |= flags;
+ Fl::damage(1);
+ }
+ }
+}
+
+void Fl_Widget::redraw() {damage(~0);}
+
+Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.C
+
+void Fl_Widget::damage(uchar flags, int X, int Y, int W, int H) {
+ if (type() < FL_WINDOW) {
+ damage_ |= flags;
+ if (parent()) parent()->damage(1,X,Y,W,H);
+ } else {
+ // see if damage covers entire window:
+ if (X<=0 && Y<=0 && W>=w() && H>=h()) {damage(flags); return;}
+ Fl_X* i = Fl_X::i((Fl_Window*)this);
+ if (i) {
+ if (damage()) {
+ // if we already have damage we must merge with existing region:
+ if (i->region) {
+ XRectangle R;
+ R.x = X; R.y = Y; R.width = W; R.height = H;
+ XUnionRectWithRegion(&R, i->region, i->region);
+ }
+ damage_ |= flags;
+ } else {
+ // create a new region:
+ if (i->region) XDestroyRegion(i->region);
+ i->region = XRectangleRegion(X,Y,W,H);
+ damage_ = flags;
+ }
+ Fl::damage(1);
+ }
+ }
+}
+
+void Fl_Window::flush() {
+ make_current();
+//if (damage() == 2 && can_boxcheat(box())) fl_boxcheat = this;
+ fl_clip_region(i->region); i->region = 0;
+ draw();
+}
+
+#endif
+// End of Fl_x.C
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 000000000..1de491e1e
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,215 @@
+CPPFILES = \
+ Fl.C \
+ Fl_Adjuster.C \
+ Fl_Bitmap.C \
+ Fl_Browser.C \
+ Fl_Browser_.C \
+ Fl_Browser_load.C \
+ Fl_Box.C \
+ Fl_Button.C \
+ Fl_Chart.C \
+ Fl_Check_Button.C \
+ Fl_Choice.C \
+ Fl_Clock.C \
+ Fl_Color_Chooser.C \
+ Fl_Counter.C \
+ Fl_Dial.C \
+ Fl_Double_Window.C \
+ Fl_Gl_Choice.C \
+ Fl_Gl_Overlay.C \
+ Fl_Gl_Window.C \
+ Fl_Group.C \
+ Fl_Image.C \
+ Fl_Input.C \
+ Fl_Input_.C \
+ Fl_Light_Button.C \
+ Fl_Menu.C \
+ Fl_Menu_.C \
+ Fl_Menu_Bar.C \
+ Fl_Menu_Button.C \
+ Fl_Menu_Window.C \
+ Fl_Menu_add.C \
+ Fl_Menu_global.C \
+ Fl_Multi_Label.C \
+ Fl_Output.C \
+ Fl_Overlay_Window.C \
+ Fl_Pack.C \
+ Fl_Pixmap.C \
+ Fl_Positioner.C \
+ Fl_Repeat_Button.C \
+ Fl_Return_Button.C \
+ Fl_Roller.C \
+ Fl_Round_Button.C \
+ Fl_Scroll.C \
+ Fl_Scrollbar.C \
+ Fl_Single_Window.C \
+ Fl_Slider.C \
+ Fl_Tabs.C \
+ Fl_Tile.C \
+ Fl_Valuator.C \
+ Fl_Value_Input.C \
+ Fl_Value_Output.C \
+ Fl_Value_Slider.C \
+ Fl_Widget.C \
+ Fl_Window.C \
+ Fl_Window_fullscreen.C \
+ Fl_Window_hotspot.C \
+ Fl_Window_iconize.C \
+ Fl_abort.C \
+ Fl_add_idle.C \
+ Fl_arg.C \
+ Fl_cutpaste.C \
+ Fl_display.C \
+ Fl_get_key.C \
+ Fl_get_system_colors.C \
+ Fl_own_colormap.C \
+ Fl_visual.C \
+ Fl_x.C \
+ filename_absolute.C \
+ filename_expand.C \
+ filename_ext.C \
+ filename_isdir.C \
+ filename_list.C \
+ filename_match.C \
+ filename_setext.C \
+ fl_arc.C \
+ fl_arci.C \
+ fl_ask.C \
+ fl_boxtype.C \
+ fl_color.C \
+ fl_cursor.C \
+ fl_curve.C \
+ fl_diamond_box.C \
+ fl_draw.C \
+ fl_draw_image.C \
+ fl_draw_pixmap.C \
+ fl_engraved_label.C \
+ fl_file_chooser.C \
+ fl_font.C \
+ fl_labeltype.C \
+ fl_oval_box.C \
+ fl_overlay.C \
+ fl_overlay_visual.C \
+ fl_rect.C \
+ fl_round_box.C \
+ fl_rounded_box.C \
+ fl_set_font.C \
+ fl_set_fonts.C \
+ fl_scroll_area.C \
+ fl_shadow_box.C \
+ fl_shortcut.C \
+ fl_show_colormap.C \
+ fl_symbols.C \
+ fl_vertex.C \
+ forms_compatability.C \
+ forms_bitmap.C \
+ forms_free.C \
+ forms_fselect.C \
+ forms_pixmap.C \
+ forms_timer.C \
+ gl_draw.C \
+ gl_start.C \
+ glut_compatability.C \
+ glut_font.C
+
+CFILES = scandir.c numericsort.c
+
+CLEAN =
+
+################################################################
+
+include ../makeinclude
+
+LIBRARY = ../lib/$(LIBNAME)
+
+OBJECTS = $(CPPFILES:.C=.o) $(CFILES:.c=.o)
+
+$(LIBRARY) : $(OBJECTS)
+ @echo Building $(LIBRARY)
+ @$(AR) $(LIBRARY) $(OBJECTS)
+ @$(RANLIB) $(LIBRARY)
+
+.C.o :
+ @echo $<:
+ @$(CXX) -I.. $(CXXFLAGS) -c $<
+.c.o :
+ @echo $<:
+ @$(CC) -I.. $(CFLAGS) -c -o $@ $<
+
+clean :
+ -@ rm -f *.o *.do $(LIBRARY) $(CLEAN) core *~ makedepend
+ @touch makedepend
+
+depend:
+ @echo Making makedepend
+ @$(MAKEDEPEND) -I.. $(CXXFLAGS) $(CPPFILES) $(CFILES) > makedepend
+include makedepend
+
+################################################################
+
+LIBRARY_D = ../lib/$(LIBNAME_D)
+
+debug: $(LIBRARY_D)
+
+OBJECTS_D = $(CPPFILES:.C=.do) $(CFILES:.c=.do)
+
+.SUFFIXES : .C .c .o .do
+
+.C.do :
+ @echo $<:
+ @$(CXX) -I.. $(CXXFLAGS_D) -c -o $@ $<
+.c.do :
+ @echo $<:
+ @$(CC) -I.. $(CFLAGS) -c -o $@ $<
+
+$(LIBRARY_D) : $(OBJECTS_D)
+ @echo building $(LIBRARY_D):
+ @$(AR) $(LIBRARY_D) $(OBJECTS_D)
+ @$(RANLIB) $(LIBRARY_D)
+
+################################################################
+# Linux-specific shared libraries:
+
+include ../version
+
+SHBASENAME = libfltk.so
+SONAME = $(SHBASENAME).$(VERSION)
+SHLIBNAME = $(SHBASENAME).$(VERSION).$(REVISION)
+PICOBJECTS = $(CPPFILES:.C=.pic.o) $(CFILES:.c=.pic.o)
+
+shared: ../lib/$(SHLIBNAME) ../lib/$(SONAME) ../lib/$(SHBASENAME)
+ touch ../lib/$(LIBNAME)
+
+../lib/$(SHLIBNAME): $(PICOBJECTS)
+ @echo building $@:
+ @$(CXX) -shared -Wl,-soname,$(SONAME) $(GLDLIBS) -o $@ $(PICOBJECTS)
+
+../lib/$(SONAME): ../lib/$(SHLIBNAME)
+ ln -nsf $(SHLIBNAME) $@
+
+../lib/$(SHBASENAME): ../lib/$(SHLIBNAME)
+ ln -nsf $(SHLIBNAME) $@
+
+%.pic.o: %.C
+ @echo $<:
+ @$(CXX) -fPIC -I.. $(CXXFLAGS) -c -o $@ $<
+%.pic.o: %.c
+ @echo $<:
+ @$(CC) -fPIC -I.. $(CFLAGS) -c -o $@ $<
+
+################################################################
+
+install: ../lib/$(LIBNAME)
+ cp -f ../lib/$(LIBNAME) $(libdir)
+ -cp -f ../lib/$(SHLIBNAME) $(libdir)
+ @chmod a+r,u+w,g-w,o-w $(libdir)/$(LIBNAME)*
+ cp -rf ../FL $(includedir)
+ @chmod -R a+r,u+w,g-w,o-w $(includedir)/FL
+
+# it used to do this, but it was recommended that I take it out
+# @chown root $(libdir)/$(LIBNAME)*
+# @chown -R root $(includedir)/FL
+
+uninstall:
+ -@ rm -f $(libdir)/libfltk*
+ -@ rm -rf $(includedir)/FL
diff --git a/src/cmap.cxx b/src/cmap.cxx
new file mode 100644
index 000000000..e98b765b5
--- /dev/null
+++ b/src/cmap.cxx
@@ -0,0 +1,120 @@
+// This program produces the contents of "fl_cmap.h" as stdout
+
+// #include <gl/gl.h>
+#include <stdio.h>
+
+// This table is initialized with color values I got by reading the
+// colormap on an IRIX 4.3 machine:
+
+// "full intensity colors" have been turned down some to make white
+// background less intense by default. The hope is that this will make
+// fltk programs more friendly on color-adjusted screens. If you want
+// pure colors you should get them out of the colormap.
+
+#define III 244 // maximum intensity of the basic colors
+
+static short cmap[256][3] = {
+// 3-bit colormap:
+ { 0, 0, 0}, // black
+ {III, 0, 0}, // red
+ { 0,III, 0}, // green
+ {III,III, 0}, // yellow
+ { 0, 0,III}, // blue
+ {III, 0,III}, // magenta
+ { 0,III,III}, // cyan
+ {III,III,III}, // white
+// pastel versions of those colors:
+ { 85, 85, 85}, // 1/3 gray
+ {198,113,113}, // salmon? pale red?
+ {113,198,113}, // pale green
+ {142,142, 56}, // khaki
+ {113,113,198}, // pale blue
+ {142, 56,142}, // purple, orchid, pale magenta
+ { 56,142,142}, // cadet blue, aquamarine, pale cyan
+ {170,170,170}, // 2/3 gray
+// These next 16 are the FL_FREE_COLOR area. For compatability with
+// some existing DD programs, I prefill them with the random colors
+// you get on a 5.3 machine:
+ { 16, 16, 16},
+ {128, 40,128},
+ {198, 30, 30},
+ { 66, 30, 30},
+ {176,140,140},
+ { 0, 20, 20},
+ { 20, 10, 10},
+ { 40, 20, 20},
+ { 60, 30, 30},
+ { 0, 80, 80},
+ { 0, 40, 40},
+ { 20, 20, 0},
+ { 40, 40, 0},
+ { 80, 80, 10},
+ {150,150, 20},
+ {160, 10, 10},
+// The rest of the colormap is a gray ramp and table, filled in below:
+};
+
+// This is Fl::background from Fl_get_system_colors.C, with modifications:
+
+#define FL_GRAY_RAMP 32
+#define FL_NUM_GRAY 24
+#define FL_GRAY 49 // old value is 47
+typedef unsigned char uchar;
+#include <math.h>
+
+void background(uchar r, uchar g, uchar b) {
+ // replace the gray ramp so that color 47 (by default 2/3) is this color
+ if (!r) r = 1; else if (r==255) r = 254;
+ double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+ if (!g) g = 1; else if (g==255) g = 254;
+ double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+ if (!b) b = 1; else if (b==255) b = 254;
+ double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
+ for (int i = 0; i < FL_NUM_GRAY; i++) {
+ double gray = i/(FL_NUM_GRAY-1.0);
+ cmap[i+FL_GRAY_RAMP][0] = uchar(pow(gray,powr)*255+.5);
+ cmap[i+FL_GRAY_RAMP][1] = uchar(pow(gray,powg)*255+.5);
+ cmap[i+FL_GRAY_RAMP][2] = uchar(pow(gray,powb)*255+.5);
+ }
+}
+
+int main() {
+ int i,r,g,b;
+#if 0
+ /* Read colormap colors into internal table */
+ long cmwin;
+ noport();
+ cmwin = winopen("CM");
+ for (i=0; i<256; i++)
+ getmcolor(i,&cmap[i][0],&cmap[i][1],&cmap[i][2]);
+ winclose(cmwin);
+#endif
+// overwrite the X allocation area with one color so people are
+// discouraged from using it:
+ for (i=16; i<32; i++) {cmap[i][0]=cmap[i][1]=cmap[i][2] = 85;}
+
+ // fill in the gray ramp:
+ background(0xc0, 0xc0, 0xc0); // microsoft colors
+ // background(cmap[15][0],cmap[15][1],cmap[15][2]); // old fltk colors
+ // copy the 1/3 and 2/3 gray to the closest locations in gray ramp:
+ cmap[39][0] = cmap[39][1] = cmap[39][2] = cmap[8][0];
+ cmap[47][0] = cmap[47][1] = cmap[47][2] = cmap[15][0];
+
+ // fill in the color cube
+ i = 56;
+ for (b=0; b<5; b++)
+ for (r=0; r<5; r++)
+ for (g=0; g<8; g++) {
+ cmap[i][0] = r*255/4;
+ cmap[i][1] = g*255/7;
+ cmap[i][2] = b*255/4;
+ i++;
+ }
+
+ for (i=0; i<256; i++) {
+ printf("\t0x%02x%02x%02x00",cmap[i][0],cmap[i][1],cmap[i][2]);
+ if (i < 255) printf(",\n");
+ }
+ printf("\n");
+ return 0;
+}
diff --git a/src/d1.xbm b/src/d1.xbm
new file mode 100644
index 000000000..a0e67f029
--- /dev/null
+++ b/src/d1.xbm
@@ -0,0 +1,6 @@
+#define d1_width 16
+#define d1_height 16
+static unsigned char d1_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
+ 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
+ 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/d1_mask.xbm b/src/d1_mask.xbm
new file mode 100644
index 000000000..6b1e14dac
--- /dev/null
+++ b/src/d1_mask.xbm
@@ -0,0 +1,6 @@
+#define d1_mask_width 16
+#define d1_mask_height 16
+static unsigned char d1_mask_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
+ 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
+ 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/dump_compose.c b/src/dump_compose.c
new file mode 100644
index 000000000..fe41991cf
--- /dev/null
+++ b/src/dump_compose.c
@@ -0,0 +1,26 @@
+/* write out the documentation for the compose key */
+
+/* copy the string from Fl_Input.C */
+static const char* const compose_pairs =
+" ! @ # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
+"A`A'A^A~A:A*AEC,E`E'E^E:I`I'I^I:D-N~O`O'O^O~O:x O/U`U'U^U:Y'DDss"
+"a`a'a^a~a:a*aec,e`e'e^e:i`i'i^i:d-n~o`o'o^o~o:-:o/u`u'u^u:y'ddy:";
+
+#include <stdio.h>
+
+int main() {
+ int x,y;
+ for (x = 0; x<16; x++) {
+ for (y = 0; y<6; y++) {
+ const char *p = compose_pairs + (16*y+x)*2;
+ if (p[1] == ' ')
+ printf("<td><code>%c&nbsp</code>&nbsp&nbsp&nbsp%c\n",
+ p[0],(p-compose_pairs)/2+0xA0);
+ else
+ printf("<td><code>%c%c</code>&nbsp&nbsp&nbsp%c\n",
+ p[0],p[1],(p-compose_pairs)/2+0xA0);
+ }
+ printf("<tr>");
+ }
+ return 0;
+}
diff --git a/src/ew.xbm b/src/ew.xbm
new file mode 100644
index 000000000..1ff835cd5
--- /dev/null
+++ b/src/ew.xbm
@@ -0,0 +1,8 @@
+#define ew_width 16
+#define ew_height 16
+#define ew_x_hot 8
+#define ew_y_hot 8
+static unsigned char ew_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
+ 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/ew_mask.xbm b/src/ew_mask.xbm
new file mode 100644
index 000000000..49dc1df88
--- /dev/null
+++ b/src/ew_mask.xbm
@@ -0,0 +1,8 @@
+#define ew_mask_width 16
+#define ew_mask_height 16
+#define ew_mask_x_hot 8
+#define ew_mask_y_hot 8
+static unsigned char ew_mask_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
+ 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/fastarrow.h b/src/fastarrow.h
new file mode 100644
index 000000000..e381acdce
--- /dev/null
+++ b/src/fastarrow.h
@@ -0,0 +1,6 @@
+#define fastarrow_width 16
+#define fastarrow_height 16
+static unsigned char fastarrow_bits[] = {
+ 0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03,
+ 0xe0, 0x07, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x07, 0xc0, 0x3f, 0xff, 0xff,
+ 0xc0, 0x3f, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00};
diff --git a/src/filename_absolute.cxx b/src/filename_absolute.cxx
new file mode 100644
index 000000000..d5a937539
--- /dev/null
+++ b/src/filename_absolute.cxx
@@ -0,0 +1,67 @@
+/* expand a file name by prepending current directory, deleting . and
+ .. (not really correct for symbolic links) between the prepended
+ current directory. Use $PWD if it exists.
+ Returns true if any changes were made.
+*/
+
+#include <FL/filename.H>
+#include <stdlib.h>
+#include <string.h>
+#if defined(WIN32) && !defined(CYGNUS)
+# include <direct.h>
+# define getcwd(a,b) _getdcwd(0,a,b)
+#else
+# include <unistd.h>
+# ifdef __EMX__
+# define getcwd _getcwd2
+# endif
+#endif
+
+#if defined(WIN32) || defined(__EMX__)
+inline int isdirsep(char c) {return c=='/' || c=='\\';}
+#else
+#define isdirsep(c) ((c)=='/')
+#endif
+
+int filename_absolute(char *to,const char *from) {
+
+ if (isdirsep(*from) || *from == '|'
+#if defined(WIN32) || defined(__EMX__)
+ || from[1]==':'
+#endif
+ ) {
+ strcpy(to,from);
+ return 0;
+ }
+
+ char *a,temp[FL_PATH_MAX];
+ const char *start = from;
+
+ a = getenv("PWD");
+ if (a) strncpy(temp,a,FL_PATH_MAX);
+ else {a = getcwd(temp,FL_PATH_MAX); if (!a) return 0;}
+#if defined(WIN32) || defined(__EMX__)
+ for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
+#else
+ a = temp+strlen(temp);
+#endif
+ if (isdirsep(*(a-1))) a--;
+ /* remove intermediate . and .. names: */
+ while (*start == '.') {
+ if (start[1]=='.' && isdirsep(start[2])) {
+ char *b;
+ for (b = a-1; b >= temp && !isdirsep(*b); b--);
+ if (b < temp) break;
+ a = b;
+ start += 3;
+ } else if (isdirsep(start[1])) {
+ start += 2;
+ } else
+ break;
+ }
+ *a++ = '/';
+ strcpy(a,start);
+ strcpy(to,temp);
+ return 1;
+
+}
diff --git a/src/filename_expand.cxx b/src/filename_expand.cxx
new file mode 100644
index 000000000..27e593389
--- /dev/null
+++ b/src/filename_expand.cxx
@@ -0,0 +1,72 @@
+/* expand a file name by substuting environment variables and
+ home directories. Returns true if any changes were made.
+ to & from may be the same buffer.
+*/
+
+#include <FL/filename.H>
+#include <stdlib.h>
+#include <string.h>
+#ifdef WIN32
+#else
+# include <unistd.h>
+# include <pwd.h>
+#endif
+
+#if defined(WIN32) || defined(__EMX__)
+static inline int isdirsep(char c) {return c=='/' || c=='\\';}
+#else
+#define isdirsep(c) ((c)=='/')
+#endif
+
+int filename_expand(char *to,const char *from) {
+
+ char temp[FL_PATH_MAX];
+ strcpy(temp,from);
+ const char *start = temp;
+ const char *end = temp+strlen(temp);
+
+ int ret = 0;
+
+ for (char *a=temp; a<end; ) { // for each slash component
+ char *e; for (e=a; e<end && !isdirsep(*e); e++); // find next slash
+ const char *value = 0; // this will point at substitute value
+ switch (*a) {
+ case '~': // a home directory name
+ if (e <= a+1) { // current user's directory
+ value = getenv("HOME");
+#ifndef WIN32
+ } else { // another user's directory
+ struct passwd *pwd;
+ char t = *e; *(char *)e = 0;
+ pwd = getpwnam(a+1);
+ *(char *)e = t;
+ if (pwd) value = pwd->pw_dir;
+#endif
+ }
+ break;
+ case '$': /* an environment variable */
+ {char t = *e; *(char *)e = 0; value = getenv(a+1); *(char *)e = t;}
+ break;
+ }
+ if (value) {
+ // substitutions that start with slash delete everything before them:
+ if (isdirsep(value[0])) start = a;
+#if defined(WIN32) || defined(__EMX__)
+ // also if it starts with "A:"
+ if (value[0] && value[1]==':') start = a;
+#endif
+ int t = strlen(value); if (isdirsep(value[t-1])) t--;
+ memmove(a+t, e, end+1-e);
+ end = a+t+(end-e);
+ memcpy(a, value, t);
+ ret++;
+ } else {
+ a = e+1;
+#if defined(WIN32) || defined(__EMX__)
+ if (*e == '\\') {*e = '/'; ret++;} // ha ha!
+#endif
+ }
+ }
+ strcpy(to,start);
+ return ret;
+}
diff --git a/src/filename_ext.cxx b/src/filename_ext.cxx
new file mode 100644
index 000000000..9fcd67096
--- /dev/null
+++ b/src/filename_ext.cxx
@@ -0,0 +1,17 @@
+// returns pointer to the last '.' or to the null if none:
+
+#include <FL/filename.H>
+
+const char *filename_ext(const char *buf) {
+ const char *q = 0;
+ const char *p = buf;
+ for (p=buf; *p; p++) {
+ if (*p == '/') q = 0;
+#if defined(WIN32) || defined(__EMX__)
+ else if (*p == '\\') q = 0;
+#endif
+ else if (*p == '.') q = p;
+ }
+ return q ? q : p;
+}
+
diff --git a/src/filename_isdir.cxx b/src/filename_isdir.cxx
new file mode 100644
index 000000000..ce02d2302
--- /dev/null
+++ b/src/filename_isdir.cxx
@@ -0,0 +1,12 @@
+// filename_isdir.C
+
+// Used by fl_file_chooser
+
+#include <config.h>
+#include <FL/filename.H>
+#include <sys/stat.h>
+
+int filename_isdir(const char* n) {
+ struct stat s;
+ return !stat(n, &s) && (s.st_mode&0170000)==0040000;
+}
diff --git a/src/filename_list.cxx b/src/filename_list.cxx
new file mode 100644
index 000000000..31fd52eea
--- /dev/null
+++ b/src/filename_list.cxx
@@ -0,0 +1,36 @@
+// filename_list.C
+
+// Wrapper for scandir with const-correct function prototypes.
+
+#include <config.h>
+#include <FL/filename.H>
+
+#if !defined(WIN32) || defined(__GNUC__)
+extern "C" {
+#endif
+ int numericsort(const dirent **, const dirent **);
+#if HAVE_SCANDIR
+#else
+ int alphasort(const dirent **, const dirent **);
+ int scandir (const char *dir, dirent ***namelist,
+ int (*select)(const dirent *),
+ int (*compar)(const dirent **, const dirent **));
+#endif
+#if !defined(WIN32) || defined(__GNUC__)
+}
+#endif
+
+int filename_list(const char *d, dirent ***list) {
+#if defined(_AIX) || defined(CRAY)
+ // on some systems you may need to do this, due to a rather common
+ // error in the prototype for the sorting function, where a level
+ // of pointer indirection is missing:
+ return scandir(d, list, 0, (int(*)(const void*,const void*))numericsort);
+#else
+#if HAVE_SCANDIR
+ return scandir(d, list, 0, (int(*)(dirent**,dirent**))numericsort);
+#else // built-in scandir is const-correct:
+ return scandir(d, list, 0, numericsort);
+#endif
+#endif
+}
diff --git a/src/filename_match.cxx b/src/filename_match.cxx
new file mode 100644
index 000000000..ba8ad4aad
--- /dev/null
+++ b/src/filename_match.cxx
@@ -0,0 +1,74 @@
+/*------------------- Pattern matching --------------------------*/
+/* Adapted from Rich Salz. */
+#include <FL/filename.H>
+
+int filename_match(const char *s, const char *p) {
+ int matched;
+
+ for (;;) {
+ switch(*p++) {
+
+ case '?' : // match any single character
+ if (!*s++) return 0;
+ break;
+
+ case '*' : // match 0-n of any characters
+ if (!*p) return 1; // do trailing * quickly
+ while (!filename_match(s, p)) if (!*s++) return 0;
+ return 1;
+
+ case '[': { // match one character in set of form [abc-d] or [^a-b]
+ if (!*s) return 0;
+ int reverse = (*p=='^' || *p=='!'); if (reverse) p++;
+ matched = 0;
+ char last = 0;
+ while (*p) {
+ if (*p=='-' && last) {
+ if (*s <= *++p && *s >= last ) matched = 1;
+ last = 0;
+ } else {
+ if (*s == *p) matched = 1;
+ }
+ last = *p++;
+ if (*p==']') break;
+ }
+ if (matched == reverse) return 0;
+ s++; p++;}
+ break;
+
+ case '{' : // {pattern1|pattern2|pattern3}
+ NEXTCASE:
+ if (filename_match(s,p)) return 1;
+ for (matched = 0;;) {
+ switch (*p++) {
+ case '\\': if (*p) p++; break;
+ case '{': matched++; break;
+ case '}': if (!matched--) return 0; break;
+ case '|': case ',': if (matched==0) goto NEXTCASE;
+ case 0: return 0;
+ }
+ }
+ case '|': // skip rest of |pattern|pattern} when called recursively
+ case ',':
+ for (matched = 0; *p && matched >= 0;) {
+ switch (*p++) {
+ case '\\': if (*p) p++; break;
+ case '{': matched++; break;
+ case '}': matched--; break;
+ }
+ }
+ break;
+ case '}':
+ break;
+
+ case 0: // end of pattern
+ return !*s;
+
+ case '\\': // quote next character
+ if (*p) p++;
+ default : // other characters
+ if (*s++ != *(p-1)) return 0;
+ break;
+ }
+ }
+}
diff --git a/src/filename_setext.cxx b/src/filename_setext.cxx
new file mode 100644
index 000000000..2e9ca128c
--- /dev/null
+++ b/src/filename_setext.cxx
@@ -0,0 +1,12 @@
+// Replace .ext with new extension
+// If no . in name, append new extension
+// If new extension is null, act like it is ""
+
+#include <FL/filename.H>
+#include <string.h>
+
+char *filename_setext(char *buf, const char *ext) {
+ char *q = (char *)filename_ext(buf);
+ if (ext) strcpy(q,ext); else *q = 0;
+ return(buf);
+}
diff --git a/src/fl_arc.cxx b/src/fl_arc.cxx
new file mode 100644
index 000000000..756c2a4bb
--- /dev/null
+++ b/src/fl_arc.cxx
@@ -0,0 +1,50 @@
+// fl_arc.C
+
+// Utility for drawing arcs and circles. They are added to
+// the current fl_begin/fl_vertex/fl_end path.
+// Incremental math implementation:
+
+#include <FL/fl_draw.H>
+#include <FL/math.h>
+
+void fl_arc(double x, double y, double r, double start, double end) {
+
+ // draw start point accurately:
+ double A = start*(M_PI/180);
+ double X = r*cos(A);
+ double Y = -r*sin(A);
+ fl_vertex(x+X,y+Y);
+
+ // number of segments per radian:
+ int n; {
+ double x1 = fl_transform_dx(r,0);
+ double y1 = fl_transform_dy(r,0);
+ double r1 = x1*x1+y1*y1;
+ x1 = fl_transform_dx(0,r);
+ y1 = fl_transform_dy(0,r);
+ double r2 = x1*x1+y1*y1;
+ if (r2 < r1) r1 = r2;
+ n = int(sqrt(r1)*.841471);
+ if (n < 2) n = 2;
+ }
+ double epsilon = 1.0/n;
+ double E = end*(M_PI/180);
+ int i = int((E-A)*n);
+ if (i < 0) {i = -i; epsilon = -epsilon;}
+ double epsilon2 = epsilon/2;
+ for (; i>1; i--) {
+ X += epsilon*Y;
+ Y -= epsilon2*X;
+ fl_vertex(x+X,y+Y);
+ Y -= epsilon2*X;
+ }
+
+ // draw the end point accurately:
+ fl_vertex(x+r*cos(E), y-r*sin(E));
+}
+
+#if 0 // portable version. X-specific one in fl_vertex.C
+void fl_circle(double x,double y,double r) {
+ _fl_arc(x, y, r, r, 0, 360);
+}
+#endif
diff --git a/src/fl_arci.cxx b/src/fl_arci.cxx
new file mode 100644
index 000000000..1a96535c6
--- /dev/null
+++ b/src/fl_arci.cxx
@@ -0,0 +1,45 @@
+// fl_arci.C
+
+// "integer" circle drawing functions. These draw the limited
+// circle types provided by X and NT graphics. The advantage of
+// these is that small ones draw quite nicely (probably due to stored
+// hand-drawn bitmaps of small circles!) and may be implemented by
+// hardware and thus are fast.
+
+// Probably should add fl_chord.
+
+// 3/10/98: created
+
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#ifdef WIN32
+#include <FL/math.h>
+#endif
+
+void fl_arc(int x,int y,int w,int h,double a1,double a2) {
+ if (w <= 0 || h <= 0) return;
+#ifdef WIN32
+ int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
+ int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
+ int xb = x+w/2+int(w*cos(a2/180.0*M_PI));
+ int yb = y+h/2-int(h*sin(a2/180.0*M_PI));
+ Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb);
+#else
+ XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64));
+#endif
+}
+
+void fl_pie(int x,int y,int w,int h,double a1,double a2) {
+ if (w <= 0 || h <= 0) return;
+#ifdef WIN32
+ if (a1 == a2) return;
+ int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
+ int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
+ int xb = x+w/2+int(w*cos(a2/180.0*M_PI));
+ int yb = y+h/2-int(h*sin(a2/180.0*M_PI));
+ SelectObject(fl_gc, fl_brush());
+ Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb);
+#else
+ XFillArc(fl_display, fl_window, fl_gc, x,y,w,h, int(a1*64),int((a2-a1)*64));
+#endif
+}
diff --git a/src/fl_ask.cxx b/src/fl_ask.cxx
new file mode 100644
index 000000000..8d92fe482
--- /dev/null
+++ b/src/fl_ask.cxx
@@ -0,0 +1,165 @@
+// fl_ask.C
+
+// Implementation of fl_message, fl_ask, fl_choice, fl_input
+
+// The three-message fl_show_x functions are for forms compatibility
+// mostly. In most cases it is easier to get a multi-line message
+// by putting newlines in the message.
+
+#include <FL/Fl.H>
+
+#include <FL/fl_ask.H>
+
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Secret_Input.H>
+static Fl_Window *message_form;
+static Fl_Box *message[3];
+static Fl_Box *icon;
+static Fl_Button *button[3];
+static Fl_Input *input;
+static char *iconlabel;
+uchar fl_message_font_ = 0;
+uchar fl_message_size_ = FL_NORMAL_SIZE;
+
+static Fl_Window *makeform() {
+ if (message_form) return message_form;
+ Fl_Window *w = message_form = new Fl_Window(410,105);
+ // w->clear_border();
+ // w->box(FL_UP_BOX);
+ (message[0] = new Fl_Box(60, 9, 340, 20))
+ ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ (message[1] = new Fl_Box(60, 25, 340, 20))
+ ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ (message[2] = new Fl_Box(60, 41, 340, 20))
+ ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ (input = new Fl_Input(60,32,340,30))->hide();
+ {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50);
+ o->box(FL_THIN_UP_BOX);
+ o->labelfont(FL_TIMES_BOLD);
+ o->labelsize(34);
+ o->color(FL_WHITE);
+ o->labelcolor(FL_BLUE);
+ }
+ (button[0] = new Fl_Button(310, 70, 90, 25))->shortcut("^[");
+ button[1] = new Fl_Return_Button(210, 70, 90, 25);
+ button[2] = new Fl_Button(110, 70, 90, 25);
+ w->end();
+ w->set_modal();
+ return w;
+}
+
+// back-compatable functions:
+
+int fl_show_choice(
+ const char *m0,
+ const char *m1,
+ const char *m2,
+ int, // number of buttons, ignored
+ const char *b0,
+ const char *b1,
+ const char *b2)
+{
+ makeform();
+ message[0]->label(m0);
+ message[1]->label(m1);
+ message[2]->label(m2);
+ Fl_Font f = (Fl_Font)fl_message_font_;
+ if (!f) f = Fl_Input_::default_font();
+ int s = fl_message_size_ + Fl_Input::default_size();
+ for (int i=0; i<3; i++) {
+ message[i]->labelfont(f);
+ message[i]->labelsize(s);
+ }
+ if (b0) {button[0]->show();button[0]->label(b0);button[1]->position(210,70);}
+ else {button[0]->hide(); button[1]->position(310,70);}
+ if (b1) {button[1]->show(); button[1]->label(b1);}
+ else button[1]->hide();
+ if (b2) {button[2]->show(); button[2]->label(b2);}
+ else button[2]->hide();
+ const char* prev_icon_label = icon->label();
+ if (!prev_icon_label) icon->label(iconlabel);
+ message_form->hotspot(button[0]);
+ message_form->show();
+ int r;
+ for (;;) {
+ Fl_Widget *o = Fl::readqueue();
+ if (!o) Fl::wait();
+ else if (o == button[0]) {r = 0; break;}
+ else if (o == button[1]) {r = 1; break;}
+ else if (o == button[2]) {r = 2; break;}
+ else if (o == message_form) {r = 0; break;}
+ }
+ message_form->hide();
+ icon->label(prev_icon_label);
+ return r+1;
+}
+
+// pointers you can use to change fltk to a foreign language:
+const char* fl_no = "No";
+const char* fl_yes= "Yes";
+const char* fl_ok = "OK";
+const char* fl_cancel= "Cancel";
+
+// back-compatable XForms functions:
+
+void fl_show_message(const char *q1,const char *q2,const char *q3) {
+ iconlabel = "i";
+ fl_show_choice(q1, q2, q3, 1, 0, fl_ok, 0);
+}
+
+void fl_show_alert(const char *q1,const char *q2,const char *q3) {
+ iconlabel = "!";
+ fl_show_choice(q1, q2, q3, 1, 0, fl_ok, 0);
+}
+
+int fl_show_question(const char *q1,const char *q2,const char *q3) {
+ iconlabel = "?";
+ return fl_show_choice(q1, q2, q3, 2, fl_no, fl_yes, 0) - 1;
+}
+
+// fltk functions:
+
+void fl_message(const char *question) {
+ fl_show_message(0, question, 0);
+}
+
+void fl_alert(const char *question) {
+ fl_show_alert(0, question, 0);
+}
+
+int fl_ask(const char *question) {
+ return fl_show_question(0, question, 0);
+}
+
+int fl_choice(const char *q,const char *b0,const char *b1,const char *b2) {
+ iconlabel = "?";
+ return fl_show_choice(0,q,0,3,b0,b1,b2) - 1;
+}
+
+Fl_Widget *fl_message_icon() {makeform(); return icon;}
+
+const char *fl_input(const char *str1, const char *defstr, uchar type) {
+ makeform();
+ input->type(type);
+ input->show();
+ input->value(defstr);
+ iconlabel = "?";
+ int r = fl_show_choice(str1,0,0,2,fl_cancel,fl_ok,0);
+ input->hide();
+ return r==2 ? input->value() : 0;
+}
+
+const char *fl_input(const char *str1, const char *defstr) {
+ return fl_input(str1, defstr, FL_NORMAL_INPUT);
+}
+
+char *fl_show_simple_input(const char *str1, const char *defstr) {
+ const char *r = fl_input(str1, defstr, FL_NORMAL_INPUT);
+ return (char *)(r ? r : defstr);
+}
+
+// end of fl_ask.C
diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx
new file mode 100644
index 000000000..8bfa7dd71
--- /dev/null
+++ b/src/fl_boxtype.cxx
@@ -0,0 +1,256 @@
+// fl_boxtype.c
+
+// Box drawing code for the common box types and the table of
+// boxtypes. Other box types are in seperate files so they are not
+// linked in if not used.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <config.h>
+
+////////////////////////////////////////////////////////////////
+
+static uchar active_ramp[24] = {
+ FL_GRAY_RAMP+0, FL_GRAY_RAMP+1, FL_GRAY_RAMP+2, FL_GRAY_RAMP+3,
+ FL_GRAY_RAMP+4, FL_GRAY_RAMP+5, FL_GRAY_RAMP+6, FL_GRAY_RAMP+7,
+ FL_GRAY_RAMP+8, FL_GRAY_RAMP+9, FL_GRAY_RAMP+10,FL_GRAY_RAMP+11,
+ FL_GRAY_RAMP+12,FL_GRAY_RAMP+13,FL_GRAY_RAMP+14,FL_GRAY_RAMP+15,
+ FL_GRAY_RAMP+16,FL_GRAY_RAMP+17,FL_GRAY_RAMP+18,FL_GRAY_RAMP+19,
+ FL_GRAY_RAMP+20,FL_GRAY_RAMP+21,FL_GRAY_RAMP+22,FL_GRAY_RAMP+23};
+static uchar inactive_ramp[24] = {
+ 43, 43, 44, 44,
+ 44, 45, 45, 46,
+ 46, 46, 47, 47,
+ 48, 48, 48, 49,
+ 49, 49, 50, 50,
+ 51, 51, 52, 52};
+uchar* Fl_Gray_Ramp = (uchar*)active_ramp-'A';
+
+void fl_frame(const char* s, int x, int y, int w, int h) {
+ if (h > 0 && w > 0) for (;*s;) {
+ // draw top line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_xyline(x, y, x+w-1);
+ y++; if (--h <= 0) break;
+ // draw left line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_yxline(x, y+h-1, y);
+ x++; if (--w <= 0) break;
+ // draw bottom line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_xyline(x, y+h-1, x+w-1);
+ if (--h <= 0) break;
+ // draw right line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_yxline(x+w-1, y+h-1, y);
+ if (--w <= 0) break;
+ }
+}
+
+void fl_frame2(const char* s, int x, int y, int w, int h) {
+ if (h > 0 && w > 0) for (;*s;) {
+ // draw bottom line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_xyline(x, y+h-1, x+w-1);
+ if (--h <= 0) break;
+ // draw right line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_yxline(x+w-1, y+h-1, y);
+ if (--w <= 0) break;
+ // draw top line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_xyline(x, y, x+w-1);
+ y++; if (--h <= 0) break;
+ // draw left line:
+ fl_color(Fl_Gray_Ramp[*s++]);
+ fl_yxline(x, y+h-1, y);
+ x++; if (--w <= 0) break;
+ }
+}
+
+void fl_no_box(int, int, int, int, Fl_Color) {}
+
+void fl_thin_down_frame(int x, int y, int w, int h, Fl_Color) {
+ fl_frame2("WWHH",x,y,w,h);
+}
+
+void fl_thin_down_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_thin_down_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
+}
+
+void fl_thin_up_frame(int x, int y, int w, int h, Fl_Color) {
+ fl_frame2("HHWW",x,y,w,h);
+}
+
+void fl_thin_up_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_thin_up_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
+}
+
+void fl_up_frame(int x, int y, int w, int h, Fl_Color) {
+#if BORDER_WIDTH == 1
+ fl_frame2("HHWW",x,y,w,h);
+#else
+#if BORDER_WIDTH == 2
+ fl_frame2("AAPPMMWU",x,y,w,h);
+#else
+ fl_frame("AAAAWUJJUSNN",x,y,w,h);
+#endif
+#endif
+}
+
+#define D1 BORDER_WIDTH
+#define D2 (BORDER_WIDTH+BORDER_WIDTH)
+
+void fl_up_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_up_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2);
+}
+
+void fl_down_frame(int x, int y, int w, int h, Fl_Color) {
+#if BORDER_WIDTH == 1
+ fl_frame2("WWHH",x,y,w,h);
+#else
+#if BORDER_WIDTH == 2
+ fl_frame2("UWMMPPAA",x,y,w,h);
+#else
+ fl_frame("NNSUJJUWAAAA",x,y,w,h);
+#endif
+#endif
+}
+
+void fl_down_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_down_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2);
+}
+
+void fl_engraved_frame(int x, int y, int w, int h, Fl_Color) {
+ fl_frame("HHWWWWHH",x,y,w,h);
+}
+
+void fl_engraved_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_engraved_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+2, y+2, w-4, h-4);
+}
+
+void fl_embossed_frame(int x, int y, int w, int h, Fl_Color) {
+ fl_frame("WWHHHHWW",x,y,w,h);
+}
+
+void fl_embossed_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_embossed_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+2, y+2, w-4, h-4);
+}
+
+void fl_rectbound(int x, int y, int w, int h, Fl_Color bgcolor) {
+ fl_color(FL_BLACK); fl_rect(x, y, w, h);
+ fl_color(bgcolor); fl_rectf(x+1, y+1, w-2, h-2);
+}
+#define fl_border_box fl_rectbound
+
+void fl_rectf(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c);
+ fl_rectf(x, y, w, h);
+}
+
+void fl_border_frame(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c);
+ fl_rect(x, y, w, h);
+}
+
+////////////////////////////////////////////////////////////////
+
+static struct {
+ Fl_Box_Draw_F *f;
+ uchar dx, dy, dw, dh;
+} fl_box_table[] = {
+// must match list in Enumerations.H!!!
+ {fl_no_box, 0,0,0,0},
+ {fl_rectf, 0,0,0,0}, // FL_FLAT_BOX
+ {fl_up_box, D1,D1,D2,D2},
+ {fl_down_box, D1,D1,D2,D2},
+ {fl_up_frame, D1,D1,D2,D2},
+ {fl_down_frame, D1,D1,D2,D2},
+ {fl_thin_up_box, 1,1,2,2},
+ {fl_thin_down_box, 1,1,2,2},
+ {fl_thin_up_frame, 1,1,2,2},
+ {fl_thin_down_frame, 1,1,2,2},
+ {fl_engraved_box, 2,2,4,4},
+ {fl_embossed_box, 2,2,4,4},
+ {fl_engraved_frame, 2,2,4,4},
+ {fl_embossed_frame, 2,2,4,4},
+ {fl_border_box, 1,1,2,2},
+ {fl_border_box, 1,1,2,2}, // _FL_SHADOW_BOX,
+ {fl_border_frame, 1,1,2,2},
+ {fl_border_frame, 1,1,2,2}, // _FL_SHADOW_FRAME,
+ {fl_border_box, 1,1,2,2}, // _FL_ROUNDED_BOX,
+ {fl_border_box, 1,1,2,2}, // _FL_RSHADOW_BOX,
+ {fl_border_frame, 1,1,2,2}, // _FL_ROUNDED_FRAME
+ {fl_rectf, 0,0,0,0}, // _FL_RFLAT_BOX,
+ {fl_up_box, 3,3,6,6}, // _FL_ROUND_UP_BOX
+ {fl_down_box, 3,3,6,6}, // _FL_ROUND_DOWN_BOX,
+ {fl_up_box, 0,0,0,0}, // _FL_DIAMOND_UP_BOX
+ {fl_down_box, 0,0,0,0}, // _FL_DIAMOND_DOWN_BOX
+ {fl_border_box, 1,1,2,2}, // _FL_OVAL_BOX,
+ {fl_border_box, 1,1,2,2}, // _FL_OVAL_SHADOW_BOX,
+ {fl_border_frame, 1,1,2,2}, // _FL_OVAL_FRAME
+ {fl_rectf, 0,0,0,0}, // _FL_OVAL_FLAT_BOX,
+ {fl_up_box, 3,3,6,6}, // FL_FREE_BOX+0
+ {fl_down_box, 3,3,6,6}, // FL_FREE_BOX+1
+ {fl_up_box, 3,3,6,6}, // FL_FREE_BOX+2
+ {fl_down_box, 3,3,6,6}, // FL_FREE_BOX+3
+ {fl_up_box, 3,3,6,6}, // FL_FREE_BOX+4
+ {fl_down_box, 3,3,6,6}, // FL_FREE_BOX+5
+ {fl_up_box, 3,3,6,6}, // FL_FREE_BOX+6
+ {fl_down_box, 3,3,6,6}, // FL_FREE_BOX+7
+};
+
+int Fl::box_dx(Fl_Boxtype t) {return fl_box_table[t].dx;}
+int Fl::box_dy(Fl_Boxtype t) {return fl_box_table[t].dy;}
+int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;}
+int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;}
+
+void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) {fl_box_table[t].f=f;}
+
+void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f,
+ uchar a, uchar b, uchar c, uchar d) {
+ fl_box_table[t].f=f;
+ fl_box_table[t].dx = a;
+ fl_box_table[t].dy = b;
+ fl_box_table[t].dw = c;
+ fl_box_table[t].dh = d;
+}
+
+void Fl::set_boxtype(Fl_Boxtype t, Fl_Boxtype f) {
+ fl_box_table[t] = fl_box_table[f];
+}
+
+void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) {
+ if (t) fl_box_table[t].f(x,y,w,h,c);
+}
+
+//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.C
+
+void Fl_Widget::draw_box() const {
+ int t = box_;
+ if (!t) return;
+// if (this == fl_boxcheat) {
+// fl_boxcheat = 0;
+// if (t == FL_FLAT_BOX) return;
+// t += 2; // convert box to frame
+// }
+ draw_box((Fl_Boxtype)t, x_, y_, w_, h_, (Fl_Color)color_);
+}
+
+void Fl_Widget::draw_box(Fl_Boxtype b, Fl_Color c) const {
+ draw_box(b, x_, y_, w_, h_, c);
+}
+
+void Fl_Widget::draw_box(Fl_Boxtype b, int x, int y, int w, int h, Fl_Color c)
+const {
+ if (!active_r()) Fl_Gray_Ramp = inactive_ramp-'A';
+ fl_box_table[b].f(x, y, w, h, c);
+ Fl_Gray_Ramp = active_ramp-'A';
+}
diff --git a/src/fl_cmap.h b/src/fl_cmap.h
new file mode 100644
index 000000000..934172440
--- /dev/null
+++ b/src/fl_cmap.h
@@ -0,0 +1,256 @@
+ 0x00000000,
+ 0xf4000000,
+ 0x00f40000,
+ 0xf4f40000,
+ 0x0000f400,
+ 0xf400f400,
+ 0x00f4f400,
+ 0xf4f4f400,
+ 0x55555500,
+ 0xc6717100,
+ 0x71c67100,
+ 0x8e8e3800,
+ 0x7171c600,
+ 0x8e388e00,
+ 0x388e8e00,
+ 0xaaaaaa00,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x00000000,
+ 0x0d0d0d00,
+ 0x1a1a1a00,
+ 0x26262600,
+ 0x31313100,
+ 0x3d3d3d00,
+ 0x48484800,
+ 0x55555500,
+ 0x5f5f5f00,
+ 0x6a6a6a00,
+ 0x75757500,
+ 0x80808000,
+ 0x8a8a8a00,
+ 0x95959500,
+ 0xa0a0a000,
+ 0xaaaaaa00,
+ 0xb5b5b500,
+ 0xc0c0c000,
+ 0xcbcbcb00,
+ 0xd5d5d500,
+ 0xe0e0e000,
+ 0xeaeaea00,
+ 0xf5f5f500,
+ 0xffffff00,
+ 0x00000000,
+ 0x00240000,
+ 0x00480000,
+ 0x006d0000,
+ 0x00910000,
+ 0x00b60000,
+ 0x00da0000,
+ 0x00ff0000,
+ 0x3f000000,
+ 0x3f240000,
+ 0x3f480000,
+ 0x3f6d0000,
+ 0x3f910000,
+ 0x3fb60000,
+ 0x3fda0000,
+ 0x3fff0000,
+ 0x7f000000,
+ 0x7f240000,
+ 0x7f480000,
+ 0x7f6d0000,
+ 0x7f910000,
+ 0x7fb60000,
+ 0x7fda0000,
+ 0x7fff0000,
+ 0xbf000000,
+ 0xbf240000,
+ 0xbf480000,
+ 0xbf6d0000,
+ 0xbf910000,
+ 0xbfb60000,
+ 0xbfda0000,
+ 0xbfff0000,
+ 0xff000000,
+ 0xff240000,
+ 0xff480000,
+ 0xff6d0000,
+ 0xff910000,
+ 0xffb60000,
+ 0xffda0000,
+ 0xffff0000,
+ 0x00003f00,
+ 0x00243f00,
+ 0x00483f00,
+ 0x006d3f00,
+ 0x00913f00,
+ 0x00b63f00,
+ 0x00da3f00,
+ 0x00ff3f00,
+ 0x3f003f00,
+ 0x3f243f00,
+ 0x3f483f00,
+ 0x3f6d3f00,
+ 0x3f913f00,
+ 0x3fb63f00,
+ 0x3fda3f00,
+ 0x3fff3f00,
+ 0x7f003f00,
+ 0x7f243f00,
+ 0x7f483f00,
+ 0x7f6d3f00,
+ 0x7f913f00,
+ 0x7fb63f00,
+ 0x7fda3f00,
+ 0x7fff3f00,
+ 0xbf003f00,
+ 0xbf243f00,
+ 0xbf483f00,
+ 0xbf6d3f00,
+ 0xbf913f00,
+ 0xbfb63f00,
+ 0xbfda3f00,
+ 0xbfff3f00,
+ 0xff003f00,
+ 0xff243f00,
+ 0xff483f00,
+ 0xff6d3f00,
+ 0xff913f00,
+ 0xffb63f00,
+ 0xffda3f00,
+ 0xffff3f00,
+ 0x00007f00,
+ 0x00247f00,
+ 0x00487f00,
+ 0x006d7f00,
+ 0x00917f00,
+ 0x00b67f00,
+ 0x00da7f00,
+ 0x00ff7f00,
+ 0x3f007f00,
+ 0x3f247f00,
+ 0x3f487f00,
+ 0x3f6d7f00,
+ 0x3f917f00,
+ 0x3fb67f00,
+ 0x3fda7f00,
+ 0x3fff7f00,
+ 0x7f007f00,
+ 0x7f247f00,
+ 0x7f487f00,
+ 0x7f6d7f00,
+ 0x7f917f00,
+ 0x7fb67f00,
+ 0x7fda7f00,
+ 0x7fff7f00,
+ 0xbf007f00,
+ 0xbf247f00,
+ 0xbf487f00,
+ 0xbf6d7f00,
+ 0xbf917f00,
+ 0xbfb67f00,
+ 0xbfda7f00,
+ 0xbfff7f00,
+ 0xff007f00,
+ 0xff247f00,
+ 0xff487f00,
+ 0xff6d7f00,
+ 0xff917f00,
+ 0xffb67f00,
+ 0xffda7f00,
+ 0xffff7f00,
+ 0x0000bf00,
+ 0x0024bf00,
+ 0x0048bf00,
+ 0x006dbf00,
+ 0x0091bf00,
+ 0x00b6bf00,
+ 0x00dabf00,
+ 0x00ffbf00,
+ 0x3f00bf00,
+ 0x3f24bf00,
+ 0x3f48bf00,
+ 0x3f6dbf00,
+ 0x3f91bf00,
+ 0x3fb6bf00,
+ 0x3fdabf00,
+ 0x3fffbf00,
+ 0x7f00bf00,
+ 0x7f24bf00,
+ 0x7f48bf00,
+ 0x7f6dbf00,
+ 0x7f91bf00,
+ 0x7fb6bf00,
+ 0x7fdabf00,
+ 0x7fffbf00,
+ 0xbf00bf00,
+ 0xbf24bf00,
+ 0xbf48bf00,
+ 0xbf6dbf00,
+ 0xbf91bf00,
+ 0xbfb6bf00,
+ 0xbfdabf00,
+ 0xbfffbf00,
+ 0xff00bf00,
+ 0xff24bf00,
+ 0xff48bf00,
+ 0xff6dbf00,
+ 0xff91bf00,
+ 0xffb6bf00,
+ 0xffdabf00,
+ 0xffffbf00,
+ 0x0000ff00,
+ 0x0024ff00,
+ 0x0048ff00,
+ 0x006dff00,
+ 0x0091ff00,
+ 0x00b6ff00,
+ 0x00daff00,
+ 0x00ffff00,
+ 0x3f00ff00,
+ 0x3f24ff00,
+ 0x3f48ff00,
+ 0x3f6dff00,
+ 0x3f91ff00,
+ 0x3fb6ff00,
+ 0x3fdaff00,
+ 0x3fffff00,
+ 0x7f00ff00,
+ 0x7f24ff00,
+ 0x7f48ff00,
+ 0x7f6dff00,
+ 0x7f91ff00,
+ 0x7fb6ff00,
+ 0x7fdaff00,
+ 0x7fffff00,
+ 0xbf00ff00,
+ 0xbf24ff00,
+ 0xbf48ff00,
+ 0xbf6dff00,
+ 0xbf91ff00,
+ 0xbfb6ff00,
+ 0xbfdaff00,
+ 0xbfffff00,
+ 0xff00ff00,
+ 0xff24ff00,
+ 0xff48ff00,
+ 0xff6dff00,
+ 0xff91ff00,
+ 0xffb6ff00,
+ 0xffdaff00,
+ 0xffffff00
diff --git a/src/fl_color.cxx b/src/fl_color.cxx
new file mode 100644
index 000000000..d17cfafc9
--- /dev/null
+++ b/src/fl_color.cxx
@@ -0,0 +1,309 @@
+// fl_color.C
+
+// Implementation of fl_color(i), fl_color(r,g,b).
+
+#ifdef WIN32
+#include "fl_color_win32.C"
+#else
+
+// Also code to look at the X visual and figure out the best way to turn
+// a color into a pixel value.
+
+// SGI compiler seems to have problems with unsigned char arguments
+// being used to index arrays. So I always copy them to an integer
+// before use.
+
+#include "Fl_XColor.H"
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+////////////////////////////////////////////////////////////////
+// figure_out_visual() calculates masks & shifts for generating
+// pixels in true-color visuals:
+
+uchar fl_redmask, fl_greenmask, fl_bluemask;
+int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;
+static uchar beenhere;
+
+static void figure_out_visual() {
+ beenhere = 1;
+ if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){
+#if USE_COLORMAP
+ fl_redmask = 0;
+ return;
+#else
+ Fl::fatal("Requires true color visual");
+#endif
+ }
+
+ // get the bit masks into a more useful form:
+ int i,j,m;
+
+ for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->red_mask & m) break;
+ for (j = i; m; j++, m<<=1) if (!(fl_visual->red_mask & m)) break;
+ fl_redshift = j-8;
+ fl_redmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
+
+ for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->green_mask & m) break;
+ for (j = i; m; j++, m<<=1) if (!(fl_visual->green_mask & m)) break;
+ fl_greenshift = j-8;
+ fl_greenmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
+
+ for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->blue_mask & m) break;
+ for (j = i; m; j++, m<<=1) if (!(fl_visual->blue_mask & m)) break;
+ fl_blueshift = j-8;
+ fl_bluemask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
+
+ i = fl_redshift;
+ if (fl_greenshift < i) i = fl_greenshift;
+ if (fl_blueshift < i) i = fl_blueshift;
+ if (i < 0) {
+ fl_extrashift = -i;
+ fl_redshift -= i; fl_greenshift -= i; fl_blueshift -= i;
+ } else
+ fl_extrashift = 0;
+
+}
+
+////////////////////////////////////////////////////////////////
+// Get an rgb color. This is easy for a truecolor visual. For
+// colormapped it picks the closest color out of the fltk colormap
+// but be warned that this results in *two* approximations: one
+// to the fltk colormap, and another to whatever colors X allocates.
+
+ulong fl_xpixel(uchar r,uchar g,uchar b) {
+ if (!beenhere) figure_out_visual();
+#if USE_COLORMAP
+ if (!fl_redmask) {
+ Fl_Color i;
+ if (r == g && r == b) { // get it out of gray ramp
+ i = fl_gray_ramp(r*FL_NUM_GRAY/256);
+ } else { // get it out of color cube:
+ i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
+ }
+ return fl_xpixel(i);
+ }
+#endif
+ return
+ (((r&fl_redmask) << fl_redshift)+
+ ((g&fl_greenmask)<<fl_greenshift)+
+ ((b&fl_bluemask)<< fl_blueshift)
+ ) >> fl_extrashift;
+}
+
+void fl_color(uchar r,uchar g,uchar b) {
+ XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b));
+}
+
+////////////////////////////////////////////////////////////////
+// Get a color out of the the fltk colormap. Again for truecolor
+// visuals this is easy. For colormap this actually tries to allocate
+// an X color, and does a least-squares match to find the closest
+// color if X cannot allocate that color.
+
+static unsigned fl_cmap[256] = {
+#include "fl_cmap.h" // this is a file produced by "cmap.C":
+};
+
+#if HAVE_OVERLAY
+Fl_XColor fl_xmap[2][256];
+uchar fl_overlay;
+Colormap fl_overlay_colormap;
+XVisualInfo* fl_overlay_visual;
+ulong fl_transparent_pixel;
+#else
+Fl_XColor fl_xmap[1][256];
+#endif
+
+// calculate what color is actually on the screen for a mask:
+static inline uchar realcolor(uchar color, uchar mask) {
+#if 1
+ // accurate version if the display has linear gamma, but fl_draw_image
+ // works better with the simpler version on most screens...
+ uchar m = mask;
+ uchar result = color&m;
+ for (;;) {
+ while (m&mask) {m>>=1; color>>=1;}
+ if (!m) break;
+ mask = m;
+ result |= color&m;
+ }
+ return result;
+#else
+ return (color&mask) | (~mask)&(mask>>1);
+#endif
+}
+
+ulong fl_xpixel(Fl_Color i) {
+
+#if HAVE_OVERLAY
+ Fl_XColor &xmap = fl_xmap[fl_overlay][i];
+#else
+ Fl_XColor &xmap = fl_xmap[0][i];
+#endif
+ if (xmap.mapped) return xmap.pixel;
+
+ if (!beenhere) figure_out_visual();
+ uchar r,g,b;
+ {unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);}
+
+#if USE_COLORMAP
+ Colormap colormap;
+#if HAVE_OVERLAY
+ if (fl_overlay) {colormap = fl_overlay_colormap; goto J1;}
+#endif
+ if (!fl_redmask) {
+ colormap = fl_colormap;
+#if HAVE_OVERLAY
+ J1:
+ static XColor* ac[2];
+ XColor*& allcolors = ac[fl_overlay];
+ static int nc[2];
+ int& numcolors = nc[fl_overlay];
+#else
+ static XColor *allcolors;
+ static int numcolors;
+#endif
+
+ // I don't try to allocate colors with XAllocColor once it fails
+ // with any color. It is possible that it will work, since a color
+ // may have been freed, but some servers are extremely slow and this
+ // avoids one round trip:
+ if (!numcolors) { // don't try after a failure
+ XColor xcol;
+ xcol.red = r<<8; xcol.green = g<<8; xcol.blue = b<<8;
+ if (XAllocColor(fl_display, colormap, &xcol)) {
+ xmap.mapped = 1;
+ xmap.r = xcol.red>>8;
+ xmap.g = xcol.green>>8;
+ xmap.b = xcol.blue>>8;
+ return xmap.pixel = xcol.pixel;
+ }
+
+ // I only read the colormap once. Again this is due to the slowness
+ // of round-trips to the X server, even though other programs may alter
+ // the colormap after this and make decisions here wrong.
+#if HAVE_OVERLAY
+ if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else
+#endif
+ numcolors = fl_visual->colormap_size;
+ if (!allcolors) allcolors = new XColor[numcolors];
+ for (int p = numcolors; p--;) allcolors[p].pixel = p;
+ XQueryColors(fl_display, colormap, allcolors, numcolors);
+ }
+
+ // find least-squares match:
+ int mindist = 0x7FFFFFFF;
+ unsigned int bestmatch = 0;
+ for (unsigned int n = numcolors; n--;) {
+#if HAVE_OVERLAY
+ if (fl_overlay && n == fl_transparent_pixel) continue;
+#endif
+ XColor &a = allcolors[n];
+ int d, t;
+ t = int(r)-int(a.red>>8); d = t*t;
+ t = int(g)-int(a.green>>8); d += t*t;
+ t = int(b)-int(a.blue>>8); d += t*t;
+ if (d <= mindist) {bestmatch = n; mindist = d;}
+ }
+ XColor &p = allcolors[bestmatch];
+
+ // It appears to "work" to not call this XAllocColor, which will
+ // avoid another round-trip to the server. But then X does not
+ // know that this program "owns" this value, and can (and will)
+ // change it when the program that did allocate it exits:
+ if (XAllocColor(fl_display, colormap, &p)) {
+ xmap.mapped = 1;
+ xmap.pixel = p.pixel;
+ } else {
+ // However, if that XAllocColor fails, I have to give up and
+ // assumme the pixel is ok for the duration of the program. This
+ // is due to bugs (?) in the Solaris X and some X terminals
+ // where XAllocColor *always* fails when the colormap is full,
+ // even if we ask for a color already in it...
+ xmap.mapped = 2; // 2 prevents XFreeColor from being called
+ xmap.pixel = bestmatch;
+ }
+ xmap.r = p.red>>8;
+ xmap.g = p.green>>8;
+ xmap.b = p.blue>>8;
+ return xmap.pixel;
+ }
+#endif
+ // return color for a truecolor visual:
+ xmap.mapped = 2; // 2 prevents XFreeColor from being called
+ xmap.r = realcolor(r, fl_redmask);
+ xmap.g = realcolor(g, fl_greenmask);
+ xmap.b = realcolor(b, fl_bluemask);
+ return xmap.pixel = fl_xpixel(r,g,b);
+}
+
+Fl_Color fl_color_;
+
+void fl_color(Fl_Color i) {
+ fl_color_ = i;
+ XSetForeground(fl_display, fl_gc, fl_xpixel(i));
+}
+
+////////////////////////////////////////////////////////////////
+// Ways to modify the fltk colormap:
+
+Fl_Color contrast(Fl_Color fg, Fl_Color bg) {
+ // bright/dark is decided based on high bit of green:
+ if (fl_cmap[bg] & 0x800000) {
+ if (fl_cmap[fg] & 0x800000) return FL_GRAY_RAMP; // black from gray ramp
+ } else {
+ if (!(fl_cmap[fg] & 0x800000))
+ return (Fl_Color)(FL_COLOR_CUBE-1); // white from gray ramp
+ }
+ return fg; // this color is ok
+}
+
+void Fl::free_color(Fl_Color i, int overlay) {
+#if HAVE_OVERLAY
+#else
+ if (overlay) return;
+#endif
+ if (fl_xmap[overlay][i].mapped) {
+#if USE_COLORMAP
+#if HAVE_OVERLAY
+ Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap;
+#else
+ Colormap colormap = fl_colormap;
+#endif
+ if (fl_xmap[overlay][i].mapped == 1)
+ XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0);
+#endif
+ fl_xmap[overlay][i].mapped = 0;
+ }
+}
+
+void Fl::set_color(Fl_Color i, unsigned c) {
+ if (fl_cmap[i] != c) {
+ free_color(i,0);
+#if HAVE_OVERLAY
+ free_color(i,1);
+#endif
+ fl_cmap[i] = c;
+ }
+}
+
+unsigned Fl::get_color(Fl_Color i) {
+ return fl_cmap[i];
+}
+
+void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) {
+ Fl::set_color(i,
+ ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8));
+}
+
+void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) {
+ unsigned c = fl_cmap[i];
+ red = uchar(c>>24);
+ green = uchar(c>>16);
+ blue = uchar(c>>8);
+}
+
+#endif
+// end of fl_color.C
diff --git a/src/fl_color_win32.cxx b/src/fl_color_win32.cxx
new file mode 100644
index 000000000..360bc1b96
--- /dev/null
+++ b/src/fl_color_win32.cxx
@@ -0,0 +1,204 @@
+// fl_color_win32.C
+
+// The fltk "colormap". This allows ui colors to be stored in 8-bit
+// locations, and provides a level of indirection so that global color
+// changes can be made. Not to be confused with the X colormap, which
+// I try to hide completely.
+
+// SGI compiler seems to have problems with unsigned char arguments
+// being used to index arrays. So I always copy them to an integer
+// before use.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/win32.H>
+#include <FL/fl_draw.H>
+
+static unsigned fl_cmap[256] = {
+#include "fl_cmap.h" // this is a file produced by "cmap.C":
+};
+
+// Translations to win32 data structures:
+Fl_XMap fl_xmap[256];
+
+Fl_XMap* fl_current_xmap;
+
+HPALETTE fl_palette;
+
+static void clear_xmap(Fl_XMap& xmap) {
+ if (xmap.pen) {
+ DeleteObject((HGDIOBJ)(xmap.pen));
+ xmap.pen = 0;
+ xmap.brush = -1;
+ }
+}
+
+static void set_xmap(Fl_XMap& xmap, COLORREF c) {
+ xmap.rgb = c;
+ xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb);
+ xmap.brush = -1;
+}
+
+Fl_Color fl_color_;
+
+void fl_color(Fl_Color i) {
+ fl_color_ = i;
+ Fl_XMap &xmap = fl_xmap[i];
+ if (!xmap.pen) {
+#if USE_COLORMAP
+ if (fl_palette) {
+ set_xmap(xmap, PALETTEINDEX(i));
+ } else {
+#endif
+ unsigned c = fl_cmap[i];
+ set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8)));
+#if USE_COLORMAP
+ }
+#endif
+ }
+ fl_current_xmap = &xmap;
+ SelectObject(fl_gc, (HGDIOBJ)(xmap.pen));
+}
+
+void fl_color(uchar r, uchar g, uchar b) {
+ static Fl_XMap xmap;
+ COLORREF c = RGB(r,g,b);
+ if (!xmap.pen || c != xmap.rgb) {
+ clear_xmap(xmap);
+ set_xmap(xmap, c);
+ }
+ fl_current_xmap = &xmap;
+ SelectObject(fl_gc, (HGDIOBJ)(xmap.pen));
+}
+
+HBRUSH fl_brush() {
+ Fl_XMap *xmap = fl_current_xmap;
+ // Wonko: we use some statistics to cache only a limited number
+ // of brushes:
+#define FL_N_BRUSH 16
+ static struct Fl_Brush {
+ HBRUSH brush;
+ unsigned short usage;
+ Fl_XMap* backref;
+ } brushes[FL_N_BRUSH];
+
+ int i = xmap->brush; // find the associated brush
+ if (i != -1) { // if the brush was allready allocated
+ if (brushes[i].brush == NULL) goto CREATE_BRUSH;
+ if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic
+ for (int j=0; j<FL_N_BRUSH; j++) {
+ if (brushes[j].usage>16000)
+ brushes[j].usage -= 16000;
+ else
+ brushes[j].usage = 0;
+ }
+ }
+ return brushes[i].brush;
+ } else {
+ int umin = 32000, imin = 0;
+ for (i=0; i<FL_N_BRUSH; i++) {
+ if (brushes[i].brush == NULL) goto CREATE_BRUSH;
+ if (brushes[i].usage<umin) {
+ umin = brushes[i].usage;
+ imin = i;
+ }
+ }
+ i = imin;
+ DeleteObject(brushes[i].brush);
+ brushes[i].brush = NULL;
+ brushes[i].backref->brush = -1;
+ }
+CREATE_BRUSH:
+ brushes[i].brush = CreateSolidBrush(xmap->rgb);
+ brushes[i].usage = 0;
+ brushes[i].backref = xmap;
+ xmap->brush = i;
+ return brushes[i].brush;
+}
+
+Fl_Color contrast(Fl_Color fg, Fl_Color bg) {
+ // bright/dark is decided based on high bit of green:
+ if (fl_cmap[bg] & 0x800000) {
+ if (fl_cmap[fg] & 0x800000) return FL_GRAY_RAMP; // black from gray ramp
+ } else {
+ if (!(fl_cmap[fg] & 0x800000))
+ return (Fl_Color)(FL_COLOR_CUBE-1); // white from gray ramp
+ }
+ return fg; // this color is ok
+}
+
+void Fl::free_color(Fl_Color i, int overlay) {
+ if (overlay) return; // do something about GL overlay?
+ clear_xmap(fl_xmap[i]);
+}
+
+void Fl::set_color(Fl_Color i, unsigned c) {
+ if (fl_cmap[i] != c) {
+ clear_xmap(fl_xmap[i]);
+ fl_cmap[i] = c;
+ }
+}
+
+unsigned Fl::get_color(Fl_Color i) {
+ return fl_cmap[i];
+}
+
+void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) {
+ Fl::set_color(i,
+ ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8));
+}
+
+void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) {
+ unsigned c = fl_cmap[i];
+ red = uchar(c>>24);
+ green = uchar(c>>16);
+ blue = uchar(c>>8);
+}
+
+#if USE_COLORMAP
+
+// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary
+// Thanks to Michael Sweet @ Easy Software Products for this
+
+HPALETTE
+fl_select_palette(void)
+{
+ static char beenhere;
+ if (!beenhere) {
+ beenhere = 1;
+
+ //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL;
+ int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE);
+ if (nColors <= 0 || nColors > 256) return NULL;
+ // this will try to work on < 256 color screens, but will probably
+ // come out quite badly.
+
+ // I lamely try to get this variable-sized object allocated on stack:
+ ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1];
+ LOGPALETTE *pPal = (LOGPALETTE*)foo;
+
+ pPal->palVersion = 0x300;
+ pPal->palNumEntries = nColors;
+
+ // Build 256 colors from the standard FLTK colormap...
+
+ for (int i = 0; i < nColors; i ++) {
+ pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255;
+ pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255;
+ pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255;
+ pPal->palPalEntry[i].peFlags = 0;
+ };
+
+ // Create the palette:
+ fl_palette = CreatePalette(pPal);
+ }
+ if (fl_palette) {
+ SelectPalette(fl_gc, fl_palette, FALSE);
+ RealizePalette(fl_gc);
+ }
+ return fl_palette;
+}
+
+#endif
+
+// end of fl_color_win32.C
diff --git a/src/fl_cursor.cxx b/src/fl_cursor.cxx
new file mode 100644
index 000000000..e058c3f7c
--- /dev/null
+++ b/src/fl_cursor.cxx
@@ -0,0 +1,145 @@
+// fl_cursor.C
+
+// Change the current cursor.
+
+// Under X the cursor is attached to the X window. I tried to hide
+// this and pretend that changing the cursor is a drawing function.
+// This avoids a field in the Fl_Window, and I suspect is more
+// portable to other systems.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#ifndef WIN32
+#include <X11/cursorfont.h>
+#endif
+#include <FL/fl_draw.H>
+
+void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
+ if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
+}
+
+#ifdef WIN32
+
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
+ if (!shown()) return;
+ if (c > FL_CURSOR_NESW) {
+ i->cursor = 0;
+ } else if (c == FL_CURSOR_DEFAULT) {
+ i->cursor = fl_default_cursor;
+ } else {
+ LPSTR n;
+ switch (c) {
+ case FL_CURSOR_ARROW: n = IDC_ARROW; break;
+ case FL_CURSOR_CROSS: n = IDC_CROSS; break;
+ case FL_CURSOR_WAIT: n = IDC_WAIT; break;
+ case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
+ case FL_CURSOR_HELP: n = IDC_HELP; break;
+ case FL_CURSOR_HAND: n = IDC_UPARROW; break;
+ case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
+ case FL_CURSOR_N:
+ case FL_CURSOR_S:
+ case FL_CURSOR_NS: n = IDC_SIZENS; break;
+ case FL_CURSOR_NE:
+ case FL_CURSOR_SW:
+ case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
+ case FL_CURSOR_E:
+ case FL_CURSOR_W:
+ case FL_CURSOR_WE: n = IDC_SIZEWE; break;
+ case FL_CURSOR_SE:
+ case FL_CURSOR_NW:
+ case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
+ default: n = IDC_NO; break;
+ }
+ i->cursor = LoadCursor(NULL, n);
+ }
+ SetCursor(i->cursor);
+}
+
+#else
+
+// I like the MSWindows resize cursors, so I duplicate them here:
+
+#define CURSORSIZE 16
+#define HOTXY 7
+struct TableEntry {
+ uchar bits[CURSORSIZE*CURSORSIZE/8];
+ uchar mask[CURSORSIZE*CURSORSIZE/8];
+ Cursor cursor;
+} table[] = {
+ {{ // FL_CURSOR_NS
+ 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
+ {
+ 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
+ 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
+ 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
+ {{ // FL_CURSOR_EW
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
+ 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
+ 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{ // FL_CURSOR_NWSE
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
+ 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
+ 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
+ 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
+ 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
+ {{ // FL_CURSOR_NESW
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
+ 0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
+ 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
+ 0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
+ 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0}, {0}} // FL_CURSOR_NONE & unknown
+};
+
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
+ if (!shown()) return;
+ Cursor cursor;
+ int deleteit = 0;
+ if (!c) {
+ cursor = None;
+ } else {
+ if (c >= FL_CURSOR_NS) {
+ TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
+ if (!(q->cursor)) {
+ XColor dummy;
+ Pixmap p = XCreateBitmapFromData(fl_display,
+ RootWindow(fl_display, fl_screen), (const char*)(q->bits),
+ CURSORSIZE, CURSORSIZE);
+ Pixmap m = XCreateBitmapFromData(fl_display,
+ RootWindow(fl_display, fl_screen), (const char*)(q->mask),
+ CURSORSIZE, CURSORSIZE);
+ q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy,
+ HOTXY, HOTXY);
+ XFreePixmap(fl_display, m);
+ XFreePixmap(fl_display, p);
+ }
+ cursor = q->cursor;
+ } else {
+ cursor = XCreateFontCursor(fl_display, (c-1)*2);
+ deleteit = 1;
+ }
+ XColor fgc;
+ uchar r,g,b;
+ Fl::get_color(fg,r,g,b);
+ fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8;
+ XColor bgc;
+ Fl::get_color(bg,r,g,b);
+ bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8;
+ XRecolorCursor(fl_display, cursor, &fgc, &bgc);
+ }
+ XDefineCursor(fl_display, fl_xid(this), cursor);
+ if (deleteit) XFreeCursor(fl_display, cursor);
+}
+
+#endif
diff --git a/src/fl_curve.cxx b/src/fl_curve.cxx
new file mode 100644
index 000000000..0fc125e89
--- /dev/null
+++ b/src/fl_curve.cxx
@@ -0,0 +1,73 @@
+// fl_curve.C
+
+// Utility for drawing Bezier curves, adding the points to
+// the current fl_begin/fl_vertex/fl_end path.
+
+// Incremental math implementation:
+// I very much doubt this is optimal! From Foley/vanDam page 511.
+// If anybody has a better algorithim, please send it!
+
+#include <FL/fl_draw.H>
+#include <math.h>
+
+void fl_curve(double X0, double Y0,
+ double X1, double Y1,
+ double X2, double Y2,
+ double X3, double Y3) {
+ double x = fl_transform_x(X0,Y0);
+ double y = fl_transform_y(X0,Y0);
+ double x1 = fl_transform_x(X1,Y1);
+ double y1 = fl_transform_y(X1,Y1);
+ double x2 = fl_transform_x(X2,Y2);
+ double y2 = fl_transform_y(X2,Y2);
+ double x3 = fl_transform_x(X3,Y3);
+ double y3 = fl_transform_y(X3,Y3);
+
+ int n; { // find smaller size of bounding box
+ double lx = x; if (x1<lx) lx=x1; if (x2<lx) lx=x2; if (x3<lx) lx=x3;
+ double rx = x; if (x1>rx) rx=x1; if (x2>rx) rx=x2; if (x3>rx) rx=x3;
+ double ly = y; if (y1<ly) ly=y1; if (y2<ly) ly=y2; if (y3<ly) ly=y3;
+ double ry = y; if (y1>ry) ry=y1; if (y2>ry) ry=y2; if (y3>ry) ry=y3;
+ // calculate number of pieces to cut curve into:
+ n = int((rx-lx+ry-ly)/8); if (n < 3) n = 3;
+ }
+ double e = 1.0/n;
+
+ // calculate the coefficients of 3rd order equation:
+ double xa = (x3-3*x2+3*x1-x);
+ double xb = 3*(x2-2*x1+x);
+ double xc = 3*(x1-x);
+ // calculate the forward differences:
+ double dx1 = ((xa*e+xb)*e+xc)*e;
+ double dx3 = 6*xa*e*e*e;
+ double dx2 = dx3 + 2*xb*e*e;
+
+ // calculate the coefficients of 3rd order equation:
+ double ya = (y3-3*y2+3*y1-y);
+ double yb = 3*(y2-2*y1+y);
+ double yc = 3*(y1-y);
+ // calculate the forward differences:
+ double dy1 = ((ya*e+yb)*e+yc)*e;
+ double dy3 = 6*ya*e*e*e;
+ double dy2 = dy3 + 2*yb*e*e;
+
+ // draw point 0:
+ fl_transformed_vertex(x,y);
+
+ // draw points 1 .. n-2:
+ for (int m=2; m<n; m++) {
+ x += dx1;
+ dx1 += dx2;
+ dx2 += dx3;
+ y += dy1;
+ dy1 += dy2;
+ dy2 += dy3;
+ fl_transformed_vertex(x,y);
+ }
+
+ // draw point n-1:
+ fl_transformed_vertex(x+dx1, y+dy1);
+
+ // draw point n:
+ fl_transformed_vertex(x3,y3);
+}
diff --git a/src/fl_diamond_box.cxx b/src/fl_diamond_box.cxx
new file mode 100644
index 000000000..81e1c27cf
--- /dev/null
+++ b/src/fl_diamond_box.cxx
@@ -0,0 +1,49 @@
+// fl_diamond_box.C
+
+// Box drawing code for an obscure box type.
+// These box types are in seperate files so they are not linked
+// in if not used.
+
+// The diamond box draws best if the area is square!
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+extern uchar* Fl_Gray_Ramp;
+
+static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
+ w &= -2;
+ h &= -2;
+ int x1 = x+w/2;
+ int y1 = y+h/2;
+ fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
+ fl_color(Fl_Gray_Ramp['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
+ fl_color(Fl_Gray_Ramp['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
+ fl_color(Fl_Gray_Ramp['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
+ fl_color(Fl_Gray_Ramp['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
+ fl_color(Fl_Gray_Ramp['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
+ fl_color(Fl_Gray_Ramp['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
+ fl_color(Fl_Gray_Ramp['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
+}
+
+static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
+ w &= -2;
+ h &= -2;
+ int x1 = x+w/2;
+ int y1 = y+h/2;
+ fl_color(Fl_Gray_Ramp['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
+ fl_color(Fl_Gray_Ramp['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
+ fl_color(Fl_Gray_Ramp['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
+ fl_color(Fl_Gray_Ramp['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
+ fl_color(Fl_Gray_Ramp['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
+ fl_color(Fl_Gray_Ramp['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
+ fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
+ fl_color(Fl_Gray_Ramp['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype define_FL_DIAMOND_BOX() {
+ fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box);
+ fl_internal_boxtype(_FL_DIAMOND_UP_BOX,fl_diamond_up_box);
+ return _FL_DIAMOND_UP_BOX;
+}
diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx
new file mode 100644
index 000000000..eda4bff29
--- /dev/null
+++ b/src/fl_draw.cxx
@@ -0,0 +1,175 @@
+// fl_draw.C
+
+// Implementation of fl_draw(const char*,int,int,int,int,Fl_Align)
+
+// Used to draw all the labels and text, this routine:
+
+// Word wraps the labels to fit into their bounding box.
+// Breaks them into lines at the newlines.
+// Expands all unprintable characters to ^X or \nnn notation
+// Aligns them against the inside of the box.
+
+#include <FL/fl_draw.H>
+#include <string.h>
+
+#define MAXBUF 1024
+
+char fl_draw_shortcut; // set by fl_labeltypes.C
+static char* underline_at;
+
+// Copy p to buf, replacing unprintable characters with ^X and \nnn
+// Stop at a newline of if MAXBUF characters written to buffer.
+// Also word-wrap if width exceeds maxw.
+// Returns a pointer to the start of the next line of caharcters.
+// Sets n to the number of characters put into the buffer.
+// Sets width to the width of the string in the current font.
+
+static const char*
+expand(const char* from, char* buf, double maxw, int& n, double &width, int wrap) {
+
+ char* o = buf;
+ char* e = buf+(MAXBUF-4);
+ underline_at = 0;
+ char* word_end = o;
+ const char* word_start = from;
+ double w = 0;
+
+ const char* p = from;
+ for (;; p++) {
+
+ int c = *p & 255;
+
+ if (!c || c == ' ' || c == '\n') {
+ // test for word-wrap:
+ if (word_start < p && wrap) {
+ double newwidth = w + fl_width(word_end, o-word_end);
+ if (word_end > buf && newwidth > maxw) { // break before this word
+ o = word_end;
+ p = word_start;
+ break;
+ }
+ word_end = o;
+ w = newwidth;
+ }
+ if (!c) break;
+ else if (c == '\n') {p++; break;}
+ word_start = p+1;
+ }
+
+ if (o > e) break; // don't overflow buffer
+
+ if (c == '\t') {
+ for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' ';
+
+ } else if (c == '&' && fl_draw_shortcut && *(p+1)) {
+ if (*(p+1) == '&') {p++; *o++ = '&';}
+ else if (fl_draw_shortcut != 2) underline_at = o;
+
+ } else if (c < ' ' || c == 127) { // ^X
+ *o++ = '^';
+ *o++ = c ^ 0x40;
+
+ } else if (c >= 128 && c < 0xA0) { // \nnn
+ *o++ = '\\';
+ *o++ = (c>>6)+'0';
+ *o++ = ((c>>3)&7)+'0';
+ *o++ = (c&7)+'0';
+
+ } else if (c == 0xA0) { // non-breaking space
+ *o++ = ' ';
+
+ } else {
+ *o++ = c;
+
+ }
+ }
+
+ width = w + fl_width(word_end, o-word_end);
+ *o = 0;
+ n = o-buf;
+ return p;
+}
+
+void fl_draw(
+ const char* str, // the (multi-line) string
+ int x, int y, int w, int h, // bounding box
+ Fl_Align align,
+ void (*callthis)(const char*,int,int,int)
+) {
+ if (!str || !*str) return;
+
+ // clip:
+ if (w && h && !fl_not_clipped(x, y, w, h)) return;
+ if (align & FL_ALIGN_CLIP) fl_clip(x, y, w, h);
+
+ const char* p;
+ const char* e;
+ char buf[MAXBUF];
+ int buflen;
+
+ // count how many lines and put the last one into the buffer:
+ int lines;
+ double width;
+ for (p=str,lines=0; ;) {
+ e = expand(p, buf, w, buflen, width, align&FL_ALIGN_WRAP);
+ lines++;
+ if (!*e) break;
+ p = e;
+ }
+
+ // figure out vertical position of the first line:
+ int ypos;
+ int height = fl_height();
+ if (align & FL_ALIGN_BOTTOM) ypos = y+h-(lines-1)*height;
+ else if (align & FL_ALIGN_TOP) ypos = y+height;
+ else ypos = y+(h-lines*height)/2+height;
+
+ // now draw all the lines:
+ int desc = fl_descent();
+ for (p=str; ; ypos += height) {
+ if (lines>1) e = expand(p, buf, w, buflen, width, align&FL_ALIGN_WRAP);
+
+ int xpos;
+ if (align & FL_ALIGN_LEFT) xpos = x;
+ else if (align & FL_ALIGN_RIGHT) xpos = x+w-int(width+.5);
+ else xpos = x+int((w-width)/2);
+
+ callthis(buf,buflen,xpos,ypos-desc);
+
+ if (underline_at)
+ callthis("_",1,xpos+int(fl_width(buf,underline_at-buf)),ypos-desc);
+
+ if (!*e) break;
+ p = e;
+ }
+
+ if (align & FL_ALIGN_CLIP) fl_pop_clip();
+}
+
+void fl_draw(
+ const char* str, // the (multi-line) string
+ int x, int y, int w, int h, // bounding box
+ Fl_Align align) {
+ fl_draw(str, x, y, w, h, align, fl_draw);
+}
+
+void fl_measure(const char* str, int& w, int& h) {
+ h = fl_height();
+ if (!str || !*str) {w = 0; return;}
+ const char* p;
+ const char* e;
+ char buf[MAXBUF];
+ int buflen;
+ int lines;
+ double width;
+ int W = 0;
+ for (p=str,lines=0; ;) {
+ e = expand(p, buf, w, buflen, width, w!=0);
+ if (int(width) > W) W = int(width);
+ lines++;
+ if (!*e) break;
+ p = e;
+ }
+ w = W;
+ h = lines*h;
+}
diff --git a/src/fl_draw_image.cxx b/src/fl_draw_image.cxx
new file mode 100644
index 000000000..e66384c56
--- /dev/null
+++ b/src/fl_draw_image.cxx
@@ -0,0 +1,605 @@
+// fl_draw_image.C
+
+// I hope a simple and portable method of drawing color and monochrome
+// images. To keep this simple, only a single storage type is
+// supported: 8 bit unsigned data, byte order RGB, and pixels are
+// stored packed into rows with the origin at the top-left. It is
+// possible to alter the size of pixels with the "delta" argument, to
+// add alpha or other information per pixel. It is also possible to
+// change the origin and direction of the image data by messing with
+// the "delta" and "linedelta", making them negative, though this may
+// defeat some of the shortcuts in translating the image for X.
+
+#ifdef WIN32
+#include "fl_draw_image_win32.C"
+#else
+
+// A list of assumptions made about the X display:
+
+// bits_per_pixel must be one of 8, 16, 24, 32.
+
+// scanline_pad must be a power of 2 and greater or equal to 8.
+
+// PsuedoColor visuals must have 8 bits_per_pixel (although the depth
+// may be less than 8). This is the only limitation that affects any
+// modern X displays, you can't use 12 or 16 bit colormaps.
+
+// The mask bits in TrueColor visuals for each color are
+// contiguous and have at least one bit of each color. This
+// is not checked for.
+
+// For 24 and 32 bit visuals there must be at least 8 bits of each color.
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include "Fl_XColor.H"
+
+static XImage i; // template used to pass info to X
+static int bytes_per_pixel;
+static int scanline_add;
+static int scanline_mask;
+
+static void (*converter)(const uchar *from, uchar *to, int w, int delta);
+static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta);
+
+static int dir; // direction-alternator
+static int ri,gi,bi; // saved error-diffusion value
+
+#if USE_COLORMAP
+////////////////////////////////////////////////////////////////
+// 8-bit converter with error diffusion
+
+// I make a 16x16x16 cube of the closest colors in the fltk colormap
+// we could allocate to each of the colors in a 4-bit image. This is
+// then used to find the pixel values and actual colors for error diffusion.
+static uchar cube[16*16*16];
+
+// calculate sum-of-squares error between 4-bit index and pixel colors:
+static int calc_error(int r, int g, int b, int i) {
+ int t; int s;
+ t = ((r<<4)+8)-fl_xmap[0][i].r; s = t*t;
+ t = ((g<<4)+8)-fl_xmap[0][i].g; s += t*t;
+ t = ((b<<4)+8)-fl_xmap[0][i].b; s += t*t;
+ return s;
+}
+
+// replace the color stored at a location with a better one:
+static void improve(uchar *p, int& e, int r, int g, int b, int i) {
+ if (i < FL_GRAY_RAMP || i > 255) return;
+ int e1 = calc_error(r,g,b,i);
+ if (e1 < e) {*p = i; e = e1;}
+}
+
+static int filled_color_cube;
+static void fill_color_cube() {
+ filled_color_cube = 1;
+ int i;
+ // allocate all the colors in the fltk color cube and gray ramp:
+ // allocate widely seperated values first so that the bad ones are
+ // distributed evenly through the colormap:
+ for (i=0;;) {
+ fl_xpixel((Fl_Color)(i+FL_COLOR_CUBE));
+ i = (i+109)%(FL_NUM_RED*FL_NUM_GREEN*FL_NUM_BLUE); if (!i) break;
+ }
+ for (i=0;;) {
+ fl_xpixel((Fl_Color)(i+FL_GRAY_RAMP));
+ i = (i+7)%FL_NUM_GRAY; if (!i) break;
+ }
+ // fill in the 16x16x16 cube:
+ uchar *p = cube;
+ for (int r = 0; r<16; r++) {
+ for (int g = 0; g<16; g++) {
+ for (int b = 0; b<16; b++, p++) {
+ // initial try is value from color cube:
+ Fl_Color i = fl_color_cube(r*FL_NUM_RED/16, g*FL_NUM_GREEN/16,
+ b*FL_NUM_BLUE/16);
+ int e = calc_error(r,g,b,i);
+ *p = uchar(i);
+ // try neighbor pixels in the cube to see if they are better:
+ improve(p,e,r,g,b,i+FL_NUM_RED*FL_NUM_GREEN);
+ improve(p,e,r,g,b,i-FL_NUM_RED*FL_NUM_GREEN);
+ improve(p,e,r,g,b,i+FL_NUM_GREEN);
+ improve(p,e,r,g,b,i-FL_NUM_GREEN);
+ improve(p,e,r,g,b,i+1);
+ improve(p,e,r,g,b,i-1);
+ // try the gray ramp:
+ i = fl_gray_ramp(g*FL_NUM_GRAY/15);
+ improve(p,e,r,g,b,i);
+ improve(p,e,r,g,b,i+1);
+ improve(p,e,r,g,b,i-1);
+ }
+ }
+ }
+}
+
+static void color8_converter(const uchar *from, uchar *to, int w, int delta) {
+ if (!filled_color_cube) fill_color_cube();
+ int r=ri, g=gi, b=bi;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ to = to+(w-1);
+ d = -delta;
+ td = -1;
+ } else {
+ dir = 1;
+ d = delta;
+ td = 1;
+ }
+ for (; w--; from += d, to += td) {
+ r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
+ g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
+ b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
+ Fl_XColor* x = fl_xmap[0] + cube[((r<<4)&0xf00)+(g&0xf0)+(b>>4)];
+ r -= x->r;
+ g -= x->g;
+ b -= x->b;
+ *to = uchar(x->pixel);
+ }
+ ri = r; gi = g; bi = b;
+}
+
+static void mono8_converter(const uchar *from, uchar *to, int w, int delta) {
+ if (!filled_color_cube) fill_color_cube();
+ int r=ri;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ to = to+(w-1);
+ d = -delta;
+ td = -1;
+ } else {
+ dir = 1;
+ d = delta;
+ td = 1;
+ }
+ for (; w--; from += d, to += td) {
+ r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
+ Fl_XColor* x = fl_xmap[0] + cube[(r>>4)*0x111];
+ r -= x->g;
+ *to = uchar(x->pixel);
+ }
+ ri = r;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////
+// 16 bit TrueColor converters with error diffusion
+// Cray computers have no 16-bit type, so we use character pointers
+// (which may be slow)
+
+#ifdef U16
+#define OUTTYPE U16
+#define OUTSIZE 1
+#define OUTASSIGN(v) *t = v
+#else
+#define OUTTYPE uchar
+#define OUTSIZE 2
+#define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt)
+#endif
+
+static void color16_converter(const uchar *from, uchar *to, int w, int delta) {
+ OUTTYPE *t = (OUTTYPE *)to;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ t = t+(w-1)*OUTSIZE;
+ d = -delta;
+ td = -OUTSIZE;
+ } else {
+ dir = 1;
+ d = delta;
+ td = OUTSIZE;
+ }
+ int r=ri, g=gi, b=bi;
+ for (; w--; from += d, t += td) {
+ r = (r&~fl_redmask) +from[0]; if (r>255) r = 255;
+ g = (g&~fl_greenmask)+from[1]; if (g>255) g = 255;
+ b = (b&~fl_bluemask) +from[2]; if (b>255) b = 255;
+ OUTASSIGN((
+ ((r&fl_redmask)<<fl_redshift)+
+ ((g&fl_greenmask)<<fl_greenshift)+
+ ((b&fl_bluemask)<<fl_blueshift)
+ ) >> fl_extrashift);
+ }
+ ri = r; gi = g; bi = b;
+}
+
+static void mono16_converter(const uchar *from,uchar *to,int w, int delta) {
+ OUTTYPE *t = (OUTTYPE *)to;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ t = t+(w-1)*OUTSIZE;
+ d = -delta;
+ td = -OUTSIZE;
+ } else {
+ dir = 1;
+ d = delta;
+ td = OUTSIZE;
+ }
+ uchar mask = fl_redmask & fl_greenmask & fl_bluemask;
+ int r=ri;
+ for (; w--; from += d, t += td) {
+ r = (r&~mask) + *from; if (r > 255) r = 255;
+ uchar m = r&mask;
+ OUTASSIGN((
+ (m<<fl_redshift)+
+ (m<<fl_greenshift)+
+ (m<<fl_blueshift)
+ ) >> fl_extrashift);
+ }
+ ri = r;
+}
+
+// special-case the 5r6g5b layout used by XFree86:
+
+static void c565_converter(const uchar *from, uchar *to, int w, int delta) {
+ OUTTYPE *t = (OUTTYPE *)to;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ t = t+(w-1)*OUTSIZE;
+ d = -delta;
+ td = -OUTSIZE;
+ } else {
+ dir = 1;
+ d = delta;
+ td = OUTSIZE;
+ }
+ int r=ri, g=gi, b=bi;
+ for (; w--; from += d, t += td) {
+ r = (r&7)+from[0]; if (r>255) r = 255;
+ g = (g&3)+from[1]; if (g>255) g = 255;
+ b = (b&7)+from[2]; if (b>255) b = 255;
+ OUTASSIGN(((r&0xf8)<<8) + ((g&0xfc)<<3) + (b>>3));
+ }
+ ri = r; gi = g; bi = b;
+}
+
+static void m565_converter(const uchar *from,uchar *to,int w, int delta) {
+ OUTTYPE *t = (OUTTYPE *)to;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ t = t+(w-1)*OUTSIZE;
+ d = -delta;
+ td = -OUTSIZE;
+ } else {
+ dir = 1;
+ d = delta;
+ td = OUTSIZE;
+ }
+ int r=ri;
+ for (; w--; from += d, t += td) {
+ r = (r&7) + *from; if (r > 255) r = 255;
+ OUTASSIGN((r>>3) * 0x841);
+ }
+ ri = r;
+}
+
+////////////////////////////////////////////////////////////////
+// 24bit TrueColor converters:
+
+static void rgb_converter(const uchar *from, uchar *to, int w, int delta) {
+ int d = delta-3;
+ for (; w--; from += d) {
+ *to++ = *from++;
+ *to++ = *from++;
+ *to++ = *from++;
+ }
+}
+
+static void bgr_converter(const uchar *from, uchar *to, int w, int delta) {
+ for (; w--; from += delta) {
+ uchar r = from[0];
+ uchar g = from[1];
+ *to++ = from[2];
+ *to++ = g;
+ *to++ = r;
+ }
+}
+
+static void rrr_converter(const uchar *from, uchar *to, int w, int delta) {
+ for (; w--; from += delta) {
+ *to++ = *from;
+ *to++ = *from;
+ *to++ = *from;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// 32bit TrueColor converters on a 32 or 64-bit machine:
+
+#ifdef U64
+#define STORETYPE U64
+#if WORDS_BIGENDIAN
+#define INNARDS32(f) \
+ U64 *t = (U64*)to; \
+ int w1 = (w+1)/2; \
+ for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);}
+#else
+#define INNARDS32(f) \
+ U64 *t = (U64*)to; \
+ int w1 = (w+1)/2; \
+ for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;}
+#endif
+#else
+#define STORETYPE U32
+#define INNARDS32(f) \
+ U32 *t = (U32*)to; for (; w--; from += delta) *t++ = f
+#endif
+
+static void rgbx_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8));
+}
+
+static void xbgr_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32((from[0])+(from[1]<<8)+(from[2]<<16));
+}
+
+static void xrgb_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32((from[0]<<16)+(from[1]<<8)+(from[2]));
+}
+
+static void bgrx_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32((from[0]<<8)+(from[1]<<16)+(unsigned(from[2])<<24));
+}
+
+static void rrrx_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32(unsigned(*from) * 0x1010100U);
+}
+
+static void xrrr_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32(*from * 0x10101U);
+}
+
+static void
+color32_converter(const uchar *from, uchar *to, int w, int delta) {
+ INNARDS32(
+ (from[0]<<fl_redshift)+(from[1]<<fl_greenshift)+(from[2]<<fl_blueshift));
+}
+
+static void
+mono32_converter(const uchar *from,uchar *to,int w, int delta) {
+ INNARDS32(
+ (*from << fl_redshift)+(*from << fl_greenshift)+(*from << fl_blueshift));
+}
+
+////////////////////////////////////////////////////////////////
+
+static void figure_out_visual() {
+
+ static XPixmapFormatValues *pfvlist;
+ static int FL_NUM_pfv;
+ if (!pfvlist) pfvlist = XListPixmapFormats(fl_display,&FL_NUM_pfv);
+ XPixmapFormatValues *pfv;
+ for (pfv = pfvlist; pfv < pfvlist+FL_NUM_pfv; pfv++)
+ if (pfv->depth == fl_visual->depth) break;
+ i.format = ZPixmap;
+ i.byte_order = ImageByteOrder(fl_display);
+//i.bitmap_unit = 8;
+//i.bitmap_bit_order = MSBFirst;
+//i.bitmap_pad = 8;
+ i.depth = fl_visual->depth;
+ i.bits_per_pixel = pfv->bits_per_pixel;
+
+ if (i.bits_per_pixel & 7) bytes_per_pixel = 0; // produce fatal error
+ else bytes_per_pixel = i.bits_per_pixel/8;
+
+ unsigned int n = pfv->scanline_pad/8;
+ if (pfv->scanline_pad & 7 || (n&(n-1)))
+ Fl::fatal("Can't do scanline_pad of %d",pfv->scanline_pad);
+ if (n < sizeof(STORETYPE)) n = sizeof(STORETYPE);
+ scanline_add = n-1;
+ scanline_mask = -n;
+
+#if USE_COLORMAP
+ if (bytes_per_pixel == 1) {
+ converter = color8_converter;
+ mono_converter = mono8_converter;
+ return;
+ }
+ if (!fl_visual->red_mask)
+ Fl::fatal("Can't do %d bits_per_pixel colormap",i.bits_per_pixel);
+#endif
+
+ // otherwise it is a TrueColor visual:
+ fl_xpixel(0,0,0); // setup fl_redmask, etc, in fl_color.C
+
+ int rs = fl_redshift;
+ int gs = fl_greenshift;
+ int bs = fl_blueshift;
+
+ switch (bytes_per_pixel) {
+
+ case 2:
+ // All 16-bit TrueColor visuals are supported on any machine with
+ // 24 or more bits per integer.
+#ifdef U16
+ ::i.byte_order = WORDS_BIGENDIAN;
+#else
+ ::i.byte_order = 1;
+#endif
+ if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) {
+ converter = c565_converter;
+ mono_converter = m565_converter;
+ } else {
+ converter = color16_converter;
+ mono_converter = mono16_converter;
+ }
+ break;
+
+ case 3:
+ if (::i.byte_order) {rs = 16-rs; gs = 16-gs; bs = 16-bs;}
+ if (rs == 0 && gs == 8 && bs == 16) {
+ converter = rgb_converter;
+ mono_converter = rrr_converter;
+ } else if (rs == 16 && gs == 8 && bs == 0) {
+ converter = bgr_converter;
+ mono_converter = rrr_converter;
+ } else {
+ Fl::fatal("Can't do arbitrary 24bit color");
+ }
+ break;
+
+ case 4:
+ if ((::i.byte_order!=0) != WORDS_BIGENDIAN)
+ {rs = 24-rs; gs = 24-gs; bs = 24-bs;}
+ if (rs == 0 && gs == 8 && bs == 16) {
+ converter = xbgr_converter;
+ mono_converter = xrrr_converter;
+ } else if (rs == 24 && gs == 16 && bs == 8) {
+ converter = rgbx_converter;
+ mono_converter = rrrx_converter;
+ } else if (rs == 8 && gs == 16 && bs == 24) {
+ converter = bgrx_converter;
+ mono_converter = rrrx_converter;
+ } else if (rs == 16 && gs == 8 && bs == 0) {
+ converter = xrgb_converter;
+ mono_converter = xrrr_converter;
+ } else {
+ ::i.byte_order = WORDS_BIGENDIAN;
+ converter = color32_converter;
+ mono_converter = mono32_converter;
+ }
+ break;
+
+ default:
+ Fl::fatal("Can't do %d bits_per_pixel",i.bits_per_pixel);
+ }
+
+}
+
+#define MAXBUFFER 0x40000 // 256k
+
+static void innards(const uchar *buf, int X, int Y, int W, int H,
+ int delta, int linedelta, int mono,
+ Fl_Draw_Image_Cb cb, void* userdata)
+{
+ if (!linedelta) linedelta = W*delta;
+
+ int dx, dy, w, h;
+ fl_clip_box(X,Y,W,H,dx,dy,w,h);
+ if (w<=0 || h<=0) return;
+ dx -= X;
+ dy -= Y;
+
+ if (!bytes_per_pixel) figure_out_visual();
+ i.width = w;
+ i.height = h;
+
+ void (*conv)(const uchar *from, uchar *to, int w, int delta) = converter;
+ if (mono) conv = mono_converter;
+
+ // See if the data is already in the right format. Unfortunately
+ // some 32-bit x servers (XFree86) care about the unknown 8 bits
+ // and they must be zero. I can't confirm this for user-supplied
+ // data, so the 32-bit shortcut is disabled...
+ // This can set bytes_per_line negative if image is bottom-to-top
+ // I tested it on Linux, but it may fail on other Xlib implementations:
+ if (buf && (
+#if 0 // set this to 1 to allow 32-bit shortcut
+ delta == 4 &&
+#if WORDS_BIGENDIAN
+ conv == rgbx_converter
+#else
+ conv == xbgr_converter
+#endif
+ ||
+#endif
+ conv == rgb_converter && delta==3
+ ) && !(linedelta&scanline_add)) {
+ i.data = (char *)(buf+delta*dx+linedelta*dy);
+ i.bytes_per_line = linedelta;
+
+ } else {
+ int linesize = ((w*bytes_per_pixel+scanline_add)&scanline_mask)/sizeof(STORETYPE);
+ int blocking = h;
+ static STORETYPE *buffer; // our storage, always word aligned
+ static long buffer_size;
+ {int size = linesize*h;
+ if (size > MAXBUFFER) {
+ size = MAXBUFFER;
+ blocking = MAXBUFFER/linesize;
+ }
+ if (size > buffer_size) {
+ delete[] buffer;
+ buffer_size = size;
+ buffer = new STORETYPE[size];
+ }}
+ i.data = (char *)buffer;
+ i.bytes_per_line = linesize*sizeof(STORETYPE);
+ if (buf) {
+ buf += delta*dx+linedelta*dy;
+ for (int j=0; j<h; ) {
+ STORETYPE *to = buffer;
+ int k;
+ for (k = 0; j<h && k<blocking; k++, j++) {
+ conv(buf, (uchar*)to, w, delta);
+ buf += linedelta;
+ to += linesize;
+ }
+ XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k);
+ }
+ } else {
+#ifdef __GNUC__
+ STORETYPE linebuf[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];
+#else
+ STORETYPE* linebuf = new STORETYPE[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];
+#endif
+ for (int j=0; j<h; ) {
+ STORETYPE *to = buffer;
+ int k;
+ for (k = 0; j<h && k<blocking; k++, j++) {
+ cb(userdata, dx, dy+j, w, (uchar*)linebuf);
+ conv((uchar*)linebuf, (uchar*)to, w, delta);
+ to += linesize;
+ }
+ XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k);
+ }
+#ifndef __GNUC__
+ delete[] linebuf;
+#endif
+ }
+ }
+}
+
+void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+ innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
+}
+void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+ int x, int y, int w, int h,int d) {
+ innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
+}
+void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+ innards(buf,x,y,w,h,d,l,1,0,0);
+}
+void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+ int x, int y, int w, int h,int d) {
+ innards(0,x,y,w,h,d,0,1,cb,data);
+}
+
+void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
+ if (fl_visual->depth > 16) {
+ fl_color(r,g,b);
+ fl_rectf(x,y,w,h);
+ } else {
+ uchar c[3];
+ c[0] = r; c[1] = g; c[2] = b;
+ innards(c,x,y,w,h,0,0,0,0,0);
+ }
+}
+
+#endif
+// End of fl_draw_image.C
diff --git a/src/fl_draw_image_win32.cxx b/src/fl_draw_image_win32.cxx
new file mode 100644
index 000000000..ec58452c1
--- /dev/null
+++ b/src/fl_draw_image_win32.cxx
@@ -0,0 +1,237 @@
+// fl_draw_image_win32.C
+
+// I hope a simple and portable method of drawing color and monochrome
+// images. To keep this simple, only a single storage type is
+// supported: 8 bit unsigned data, byte order RGB, and pixels are
+// stored packed into rows with the origin at the top-left. It is
+// possible to alter the size of pixels with the "delta" argument, to
+// add alpha or other information per pixel. It is also possible to
+// change the origin and direction of the image data by messing with
+// the "delta" and "linedelta", making them negative, though this may
+// defeat some of the shortcuts in translating the image for X.
+
+// Unbelievably (since it conflicts with how most PC software works)
+// Micro$oft picked a bottom-up and BGR storage format for their
+// DIB images. I'm pretty certain there is a way around this, but
+// I can't find any other than the brute-force method of drawing
+// each line as a seperate image. This may also need to be done
+// if the delta is any amount other than 1, 3, or 4.
+
+////////////////////////////////////////////////////////////////
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+#define MAXBUFFER 0x40000 // 256k
+
+#if USE_COLORMAP
+
+// error-diffusion dither into the fltk colormap
+static void dither(uchar* to, const uchar* from, int w, int delta) {
+ static int ri, gi, bi, dir;
+ int r=ri, g=gi, b=bi;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ to = to+(w-1);
+ d = -delta;
+ td = -1;
+ } else {
+ dir = 1;
+ d = delta;
+ td = 1;
+ }
+ for (; w--; from += d, to += td) {
+ r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
+ int rr = r*FL_NUM_RED/256;
+ r -= rr*255/(FL_NUM_RED-1);
+ g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
+ int gg = g*FL_NUM_GREEN/256;
+ g -= gg*255/(FL_NUM_GREEN-1);
+ b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
+ int bb = b*FL_NUM_BLUE/256;
+ b -= bb*255/(FL_NUM_BLUE-1);
+ *to = uchar(FL_COLOR_CUBE+(bb*FL_NUM_RED+rr)*FL_NUM_GREEN+gg);
+ }
+ ri = r; gi = g; bi = b;
+}
+
+// error-diffusion dither into the fltk colormap
+static void monodither(uchar* to, const uchar* from, int w, int delta) {
+ static int ri,dir;
+ int r=ri;
+ int d, td;
+ if (dir) {
+ dir = 0;
+ from = from+(w-1)*delta;
+ to = to+(w-1);
+ d = -delta;
+ td = -1;
+ } else {
+ dir = 1;
+ d = delta;
+ td = 1;
+ }
+ for (; w--; from += d, to += td) {
+ r += *from; if (r < 0) r = 0; else if (r>255) r = 255;
+ int rr = r*FL_NUM_GRAY/256;
+ r -= rr*255/(FL_NUM_GRAY-1);
+ *to = uchar(FL_GRAY_RAMP+rr);
+ }
+ ri = r;
+}
+
+#endif // USE_COLORMAP
+
+static void innards(const uchar *buf, int X, int Y, int W, int H,
+ int delta, int linedelta, int mono,
+ Fl_Draw_Image_Cb cb, void* userdata)
+{
+#if USE_COLORMAP
+ char indexed = (fl_palette != 0);
+#endif
+
+ if (!linedelta) linedelta = W*delta;
+
+ int x, y, w, h;
+ fl_clip_box(X,Y,W,H,x,y,w,h);
+ if (w<=0 || h<=0) return;
+ if (buf) buf += (x-X)*delta + (y-Y)*linedelta;
+
+ static U32 bmibuffer[256+12];
+ BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer);
+ if (!bmi.bmiHeader.biSize) {
+ bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type?
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biXPelsPerMeter = 0;
+ bmi.bmiHeader.biYPelsPerMeter = 0;
+ bmi.bmiHeader.biClrUsed = 0;
+ bmi.bmiHeader.biClrImportant = 0;
+ }
+#if USE_COLORMAP
+ if (indexed) {
+ for (int i=0; i<256; i++) {
+ *((short*)(bmi.bmiColors)+i) = i;
+ }
+ } else
+#endif
+ if (mono) {
+ for (int i=0; i<256; i++) {
+ bmi.bmiColors[i].rgbBlue = i;
+ bmi.bmiColors[i].rgbGreen = i;
+ bmi.bmiColors[i].rgbRed = i;
+ bmi.bmiColors[i].rgbReserved = i;
+ }
+ }
+ bmi.bmiHeader.biWidth = w;
+#if USE_COLORMAP
+ bmi.bmiHeader.biBitCount = mono|indexed ? 8 : 24;
+ int pixelsize = mono|indexed ? 1 : 3;
+#else
+ bmi.bmiHeader.biBitCount = mono ? 8 : 24;
+ int pixelsize = mono ? 1 : 3;
+#endif
+ int linesize = (pixelsize*w+3)&~3;
+
+ static U32* buffer;
+ int blocking = h;
+ {int size = linesize*h;
+ if (size > MAXBUFFER) {
+ size = MAXBUFFER;
+ blocking = MAXBUFFER/linesize;
+ }
+ static long buffer_size;
+ if (size > buffer_size) {
+ delete[] buffer;
+ buffer_size = size;
+ buffer = new U32[(size+3)/4];
+ }}
+ bmi.bmiHeader.biHeight = blocking;
+ static U32* line_buffer;
+ if (!buf) {
+ int size = W*delta;
+ static int line_buf_size;
+ if (size > line_buf_size) {
+ delete[] line_buffer;
+ line_buf_size = size;
+ line_buffer = new U32[(size+3)/4];
+ }
+ }
+ for (int j=0; j<h; ) {
+ int k;
+ for (k = 0; j<h && k<blocking; k++, j++) {
+ const uchar* from;
+ if (!buf) { // run the converter:
+ cb(userdata, x-X, y-Y+j, w, (uchar*)line_buffer);
+ from = (uchar*)line_buffer;
+ } else {
+ from = buf;
+ buf += linedelta;
+ }
+ uchar *to = (uchar*)buffer+(blocking-k-1)*linesize;
+#if USE_COLORMAP
+ if (indexed) {
+ if (mono)
+ monodither(to, from, w, delta);
+ else
+ dither(to, from, w, delta);
+ to += w;
+ } else
+#endif
+ if (mono) {
+ for (int i=w; i--; from += delta) *to++ = *from;
+ } else {
+ for (int i=w; i--; from += delta, to += 3) {
+ uchar r = from[0];
+ to[0] = from[2];
+ to[1] = from[1];
+ to[2] = r;
+ }
+ }
+ }
+ SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k,
+ (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
+ &bmi,
+#if USE_COLORMAP
+ indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
+#else
+ DIB_RGB_COLORS
+#endif
+ );
+ }
+}
+
+void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+ innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
+}
+void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
+ int x, int y, int w, int h,int d) {
+ innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
+}
+void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+ innards(buf,x,y,w,h,d,l,1,0,0);
+}
+void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+ int x, int y, int w, int h,int d) {
+ innards(0,x,y,w,h,d,0,1,cb,data);
+}
+
+void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
+#if USE_COLORMAP
+ // use the error diffusion dithering code to produce a much nicer block:
+ if (fl_palette) {
+ uchar c[3];
+ c[0] = r; c[1] = g; c[2] = b;
+ innards(c,x,y,w,h,0,0,0,0,0);
+ return;
+ }
+#endif
+ fl_color(r,g,b);
+ fl_rectf(x,y,w,h);
+}
+
+// End of fl_draw_image_win32.C
diff --git a/src/fl_draw_pixmap.cxx b/src/fl_draw_pixmap.cxx
new file mode 100644
index 000000000..2522093c0
--- /dev/null
+++ b/src/fl_draw_pixmap.cxx
@@ -0,0 +1,224 @@
+// fl_draw_pixmap.C
+
+// Implemented without using the xpm library (which I can't use because
+// it interferes with the color cube used by fl_draw_image).
+
+// Current implementation is cheap and slow, and works best on a full-color
+// display. Transparency is not handled, and colors are dithered to
+// the color cube. Color index is achieved by adding the id
+// characters together! Also mallocs a lot of temporary memory!
+
+// Notice that there is no pixmap file interface. This is on purpose,
+// as I want to discourage programs that require support files to work.
+// All data needed by a program ui should be compiled in!!!
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+static int ncolors, chars_per_pixel;
+
+int fl_measure_pixmap(/*const*/char * const *data, int &w, int &h) {
+ int i = sscanf(data[0],"%d %d %d %d",&w,&h,&ncolors,&chars_per_pixel);
+ if (i<4 || w<=0 || h<=0 ||
+ chars_per_pixel!=1 && chars_per_pixel!=2) return w=0;
+ return 1;
+}
+
+#ifdef U64
+
+// The callback from fl_draw_image to get a row of data passes this:
+struct pixmap_data {
+ int w, h;
+ char*const* data;
+ U64 colors[256];
+};
+
+// callback for 1 byte per pixel:
+static void cb1(void*v, int x, int y, int w, uchar* buf) {
+ pixmap_data& d = *(pixmap_data*)v;
+ const char* p = d.data[y]+x;
+ U64* q = (U64*)buf;
+ for (int X=(w+1)/2; X--; p += 2) {
+#if WORDS_BIGENDIAN
+ *q++ = (d.colors[p[0]&255]<<32) | d.colors[p[1]&255];
+#else
+ *q++ = (d.colors[p[1]&255]<<32) | d.colors[p[0]&255];
+#endif
+ }
+}
+
+// callback for 2 bytes per pixel:
+static void cb2(void*v, int x, int y, int w, uchar* buf) {
+ pixmap_data& d = *(pixmap_data*)v;
+ const char* p = d.data[y]+2*x;
+ U64* q = (U64*)buf;
+ for (int X=(w+1)/2; X--;) {
+ int index = *p++; int t = *p++; index += (t<<4)+(t>>4);
+ int index1= *p++; t = *p++; index1 += (t<<4)+(t>>4);
+#if WORDS_BIGENDIAN
+ *q++ = (d.colors[index&255]<<32) | d.colors[index1&255];
+#else
+ *q++ = (d.colors[index1&255]<<32) | d.colors[index&255];
+#endif
+ }
+}
+
+#else
+
+// The callback from fl_draw_image to get a row of data passes this:
+struct pixmap_data {
+ int w, h;
+ char*const* data;
+ U32 colors[256];
+};
+
+// callback for 1 byte per pixel:
+static void cb1(void*v, int x, int y, int w, uchar* buf) {
+ pixmap_data& d = *(pixmap_data*)v;
+ const char* p = d.data[y]+x;
+ U32* q = (U32*)buf;
+ for (int X=w; X--;) *q++ = d.colors[(*p++)&255];
+}
+
+// callback for 2 bytes per pixel:
+static void cb2(void*v, int x, int y, int w, uchar* buf) {
+ pixmap_data& d = *(pixmap_data*)v;
+ const char* p = d.data[y]+2*x;
+ U32* q = (U32*)buf;
+ for (int X=w; X--;) {
+ int index = *p++; int t = *p++; index += (t<<4)+(t>>4);
+ *q++ = d.colors[index&255];
+ }
+}
+
+#endif
+
+#ifdef WIN32
+// this is in Fl_arg.C:
+extern int fl_parse_color(const char*, uchar&, uchar&, uchar&);
+#endif
+
+uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
+
+int fl_draw_pixmap(/*const*/char*const* data, int x, int y, Fl_Color bg) {
+ pixmap_data d;
+ if (!fl_measure_pixmap(data, d.w, d.h)) return 0;
+ data++;
+ int transparent_index = -1;
+
+ if (ncolors < 0) { // fltk (non standard) compressed colormap
+ ncolors = -ncolors;
+ const char *p = *data++;
+ // if first color is ' ' it is transparent (put it later to make
+ // it not be transparent):
+ if (*p == ' ') {
+ uchar* c = (uchar*)&d.colors[' '];
+#ifdef U64
+ *(U64*)c = 0;
+#if WORDS_BIGENDIAN
+ c += 4;
+#endif
+#endif
+ transparent_index = ' ';
+ Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
+ p += 4;
+ ncolors--;
+ }
+ // read all the rest of the colors:
+ for (int i=0; i < ncolors; i++) {
+ uchar* c = (uchar*)&d.colors[(*p++)&255];
+#ifdef U64
+ *(U64*)c = 0;
+#if WORDS_BIGENDIAN
+ c += 4;
+#endif
+#endif
+ *c++ = *p++;
+ *c++ = *p++;
+ *c++ = *p++;
+ *c = 0;
+ }
+ } else { // normal XPM colormap with names
+ for (int i=0; i<ncolors; i++) {
+ const char *p = *data++;
+ // the first 1 or 2 characters are the color index:
+ int index = *p++;
+ if (chars_per_pixel>1) {int t = *p++; index += (t<<4)+(t>>4);}
+ // look for "c word", or last word if none:
+ const char *previous_word = p;
+ for (;;) {
+ while (*p && isspace(*p)) p++; char what = *p++;
+ while (*p && !isspace(*p)) p++;
+ while (*p && isspace(*p)) p++;
+ if (!*p) {p = previous_word; break;}
+ if (what == 'c') break;
+ previous_word = p;
+ while (*p && !isspace(*p)) p++;
+ }
+ // copy the color name and look it up:
+ char name[256];
+ char *q; for (q = name; *p && !isspace(*p); *q++ = *p++); *q++ = 0;
+ uchar *c = (uchar *)&d.colors[index&255];
+#ifdef U64
+ *(U64*)c = 0;
+#if WORDS_BIGENDIAN
+ c += 4;
+#endif
+#endif
+#ifdef WIN32
+ if (fl_parse_color(name, c[0], c[1], c[2])) {;
+#else
+ XColor x;
+ if (XParseColor(fl_display, fl_colormap, name, &x)) {
+ c[0] = x.red>>8; c[1] = x.green>>8; c[2] = x.blue>>8;
+#endif
+ } else { // assumme "None" or "#transparent" for any errors
+ // this should be transparent...
+ Fl::get_color(bg, c[0], c[1], c[2]);
+ transparent_index = index&255;
+ }
+ }
+ }
+ d.data = data;
+
+ // build the mask bitmap used by Fl_Pixmap:
+ if (fl_mask_bitmap && transparent_index >= 0) {
+ int W = (d.w+7)/8;
+ uchar *bitmap = new uchar[W * d.h];
+ *fl_mask_bitmap = bitmap;
+ for (int y = 0; y < d.h; y++) {
+ uchar* p = (uchar*)data[y];
+ if (chars_per_pixel <= 1) {
+ for (int x = 0; x < W; x++) {
+ int b = (*p++ != transparent_index);
+ if (*p++ != transparent_index) b |= 2;
+ if (*p++ != transparent_index) b |= 4;
+ if (*p++ != transparent_index) b |= 8;
+ if (*p++ != transparent_index) b |= 16;
+ if (*p++ != transparent_index) b |= 32;
+ if (*p++ != transparent_index) b |= 64;
+ if (*p++ != transparent_index) b |= 128;
+ *bitmap++ = b;
+ }
+ } else {
+ for (int x = 0; x < W; x++) {
+ int b = 0;
+ for (int i = 0; i < 8; i++) {
+ int index = *p++; int t = *p++; index += (t<<4)+(t>>4);
+ if ((index&255) != transparent_index) b |= (1<<i);
+ }
+ *bitmap++ = b;
+ }
+ }
+ }
+ }
+
+ fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
+ return 1;
+}
+
diff --git a/src/fl_engraved_label.cxx b/src/fl_engraved_label.cxx
new file mode 100644
index 000000000..07a6523a7
--- /dev/null
+++ b/src/fl_engraved_label.cxx
@@ -0,0 +1,64 @@
+// fl_engraved_label.C
+
+// Drawing code for XForms style engraved & embossed labels
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+
+// data[] is dx, dy, color triples
+
+static void innards(
+ const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align,
+ int data[][3], int n)
+{
+ Fl_Align a1 = align;
+ if (a1 & FL_ALIGN_CLIP) {
+ fl_clip(X, Y, W, H); a1 = (Fl_Align)(a1&~FL_ALIGN_CLIP);}
+ fl_font((Fl_Font)o->font, o->size);
+ for (int i = 0; i < n; i++) {
+ fl_color((Fl_Color)(i < n-1 ? data[i][2] : o->color));
+ fl_draw(o->value, X+data[i][0], Y+data[i][1], W, H, a1);
+ }
+ if (align & FL_ALIGN_CLIP) fl_pop_clip();
+}
+
+static void fl_shadow_label(
+ const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+ static int data[2][3] = {{2,2,FL_DARK3},{0,0,0}};
+ innards(o, X, Y, W, H, align, data, 2);
+}
+
+static void fl_engraved_label(
+ const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+ static int data[7][3] = {
+ {1,0,FL_LIGHT3},{1,1,FL_LIGHT3},{0,1,FL_LIGHT3},
+ {-1,0,FL_DARK3},{-1,-1,FL_DARK3},{0,-1,FL_DARK3},
+ {0,0,0}};
+ innards(o, X, Y, W, H, align, data, 7);
+}
+
+static void fl_embossed_label(
+ const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+ static int data[7][3] = {
+ {-1,0,FL_LIGHT3},{-1,-1,FL_LIGHT3},{0,-1,FL_LIGHT3},
+ {1,0,FL_DARK3},{1,1,FL_DARK3},{0,1,FL_DARK3},
+ {0,0,0}};
+ innards(o, X, Y, W, H, align, data, 7);
+}
+
+Fl_Labeltype define_FL_SHADOW_LABEL() {
+ Fl::set_labeltype(_FL_SHADOW_LABEL, fl_shadow_label, 0);
+ return _FL_SHADOW_LABEL;
+}
+Fl_Labeltype define_FL_ENGRAVED_LABEL() {
+ Fl::set_labeltype(_FL_ENGRAVED_LABEL, fl_engraved_label, 0);
+ return _FL_ENGRAVED_LABEL;
+}
+Fl_Labeltype define_FL_EMBOSSED_LABEL() {
+ Fl::set_labeltype(_FL_EMBOSSED_LABEL, fl_embossed_label, 0);
+ return _FL_EMBOSSED_LABEL;
+}
diff --git a/src/fl_file_chooser.cxx b/src/fl_file_chooser.cxx
new file mode 100644
index 000000000..35cbeb747
--- /dev/null
+++ b/src/fl_file_chooser.cxx
@@ -0,0 +1,600 @@
+// fl_file_chooser.c
+
+// fltk (Fast Light Tool Kit) version 0.99
+// Copyright (C) 1998 Bill Spitzak
+
+// The "completion" file chooser for fltk
+// Designed and implemented by Bill Spitzak 12/17/93
+// Rewritten for fltk 4/29/96
+// Rewritten to use scandir() 1/7/97
+
+#include <config.h>
+#include <FL/fl_file_chooser.H>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Browser_.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_draw.H>
+#include <FL/filename.H>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+static void default_callback(const char*) {}
+static void (*current_callback)(const char*) = default_callback;
+void fl_file_chooser_callback(void (*cb)(const char*)) {
+ current_callback = cb ? cb : default_callback;
+}
+
+// "File Chooser Browser" widget:
+class FCB : public Fl_Browser_ {
+ void* item_first() const ;
+ void* item_next(void*) const ;
+ void* item_prev(void*) const ;
+ int item_height(const dirent*, int) const ;
+ int item_height(void*) const ;
+ int item_width(const dirent*) const ;
+ int item_width(void*) const ;
+ int item_quick_height(void*) const ;
+ int incr_height() const ;
+ void item_draw(void*, int, int, int, int) const ;
+ int checkdir(const dirent*, char*) const ;
+ void draw();
+ void clear_prev();
+public:
+ char listed[FL_PATH_MAX];// current dir & starname
+ int dirend; // points after last / before starname
+ int nameend; // length to trailing '*' or '\0'
+ const char* pattern; // default pattern
+ dirent** list; // the file names
+ dirent** last; // pointer after end of list
+ const char* message; // message if no file names
+ char preved[FL_PATH_MAX];// directory listed in prev
+ dirent** prev; // cached list of another directory
+ dirent** prev_last; // end of that list
+ int prev_count;
+ FCB(int x, int y, int w, int h) : Fl_Browser_(x, y, w, h, 0) {
+ type(FL_HOLD_BROWSER);
+ listed[0] = 0;
+ dirend = nameend = 1;
+ pattern = 0;
+ list = prev = 0;
+ message = 0;
+ }
+ // ~FCB nyi
+ void clear();
+ void set(const char*);
+ int get(char*);
+};
+
+// "File Chooser Window" widget:
+class FCW : public Fl_Window {
+public:
+ int handle(int);
+ Fl_Input input;
+ Fl_Button* ok_button;
+ Fl_Button* cancel_button;
+ Fl_Button* normal_button;
+ FCB browser;
+ FCW();
+};
+
+/* Files are marked as being directories by replacing the trailing null
+ with a '/' if it is a directory, a '\001' if it is *not* a directory.
+ An item has height (and is thus selectable) if it is either a directory
+ or if it matches the pattern. Quick-height assummes all unknown files
+ are directories, and thus saves the time needed to do a stat().
+*/
+
+// return pointer to last character:
+static const char* end_of_name(const dirent* d) {
+#if HAVE_DIRENT_H
+ const char* e;
+ for (e = d->d_name; ;e++) switch (*e) {
+ case 0: case 1: case '/': return e;
+ }
+#else
+ // warning: clobbers byte after end of name
+ return d->d_name + d->d_namelen;
+#endif
+}
+
+// return true if item is directory, when given pointer to last character:
+int FCB::checkdir(const dirent* d, char* e) const {
+ if (*e == 1) return 0;
+ if (*e == '/') return 1;
+ char buf[FL_PATH_MAX];
+ memcpy(buf, listed, dirend);
+ memcpy(buf+dirend, d->d_name, e-d->d_name);
+ *(buf+dirend+(e-d->d_name)) = 0;
+ if (filename_isdir(buf)) {
+ *e = '/'; return 1;
+ } else {
+ *e = 1; return 0;
+ }
+}
+
+void* FCB::item_first() const {return list;}
+
+void* FCB::item_next(void* p) const {
+ if ((dirent**)p+1 >= last) return 0;
+ return (dirent**)p+1;
+}
+
+void* FCB::item_prev(void* p) const {
+ if ((dirent**)p <= list) return 0;
+ return ((dirent**)p)-1;
+}
+
+static int ido_matching(const dirent* p, const char* e, const char* n) {
+ // replace / or 1 at end with 0 and do match, then put back. yukko
+ int save = *e; *(char*)e = 0;
+ int r = filename_match(p->d_name, n);
+ *(char*)e = save;
+ return(r);
+}
+
+int FCB::incr_height() const {return textsize()+2;}
+
+int FCB::item_height(const dirent* p, int slow) const {
+ const char* e = end_of_name(p);
+ if (listed[dirend]) {
+// if (p->d_name[0]=='.' && listed[dirend]!='.') return 0;
+ if (listed[nameend-1]=='/') {
+ if (slow ? !checkdir(p, (char*)e) : *e==1) return 0;
+ ((char*)listed)[nameend-1] = 0;
+ int r = ido_matching(p, e, listed+dirend);
+ ((char*)listed)[nameend-1] = '/';
+ if (!r) return 0;
+ } else {
+ if (!ido_matching(p, e, listed+dirend)) return 0;
+ }
+ } else {
+ if (p->d_name[0]=='.') return 0;
+ if (pattern && (slow ? !checkdir(p, (char*)e) : *e==1) &&
+ !ido_matching(p, e, pattern)) return 0;
+ }
+ return textsize()+2;
+}
+
+int FCB::item_height(void* x) const {
+ return item_height(*(const dirent**)x, 1);
+}
+
+int FCB::item_quick_height(void* x) const {
+ return item_height(*(const dirent**)x, 0);
+}
+
+void FCB::item_draw(void* v, int x, int y, int, int h) const {
+ const dirent* p = *(const dirent**)v;
+ const char* e = end_of_name(p);
+ if (checkdir(p, (char*)e)) e++;
+ if (v == selection()) fl_color(contrast(textcolor(), selection_color()));
+ else fl_color(textcolor());
+ fl_font(textfont(), textsize(), default_font(), default_size());
+ fl_draw(p->d_name, e-p->d_name, x+4, y+h-3);
+}
+
+int FCB::item_width(const dirent* p) const {
+ const char* e = end_of_name(p); if (*e == '/') e++;
+ fl_font(textfont(), textsize(), default_font(), default_size());
+ return (int)fl_width(p->d_name, e-p->d_name)+4;
+}
+
+int FCB::item_width(void* x) const {
+ return item_width(*(const dirent**)x);
+}
+
+// "get" the current value by copying the name of the selected file
+// or if none are selected, by copying as many common letters as
+// possible of the matched file list:
+int FCB::get(char* buf) {
+ dirent** q = (dirent**)selection(); // the file to copy from
+ int n = 0; // number of letters
+ if (q) { // a file is selected
+ const char* e = end_of_name(*q);
+ n = e - (*q)->d_name;
+ if (*e == '/') n++;
+ } else { // do filename completion
+ for (q = list; q < last && !item_height(*q, 0); q++);
+ if (q < last) {
+ const char* e = end_of_name(*q);
+ n = e - (*q)->d_name;
+ if (*e == '/') n++;
+ for (dirent** r = q+1; n && r < last; r++) {
+ if (!item_height(*r, 0)) continue;
+ int i;
+ for (i=0; i<n && (*q)->d_name[i]==(*r)->d_name[i]; i++);
+ n = i;
+ }
+ }
+ }
+ if (n) {
+ memcpy(buf, listed, dirend);
+ memcpy(buf+dirend, (*q)->d_name, n);
+ buf[dirend+n]=0;
+ }
+ return n;
+}
+
+// "set" the current value by changing the directory being listed and
+// changing the highlighted item, if possible:
+void FCB::set(const char* buf) {
+
+ int bufdirend;
+ int ispattern = 0;
+ const char* c = buf;
+ for (bufdirend=0; *c;) switch(*c++) {
+ case '?': case '[': case '*': case '{': ispattern = 1; goto BREAK;
+#if defined(WIN32) || defined(__EMX__)
+ case '\\':
+#endif
+ case '/': bufdirend=c-buf; break;
+ }
+#if defined(WIN32) || defined(__EMX__)
+ if ((!bufdirend) && isalpha(buf[0]) && (buf[1]==':')) bufdirend = 2;
+#endif
+ BREAK:
+ int bufend = strlen(buf);
+ if (bufend<=bufdirend) ispattern = 1;
+
+ // if directory is different, change list to xxx/ :
+ if (bufdirend != dirend || strncmp(buf, listed, bufdirend)) {
+ if (prev &&
+ preved[bufdirend]==0 && !strncmp(buf, preved, bufdirend)) {
+ strcpy(preved, listed); preved[dirend] = 0;
+ dirent** t;
+ t = prev; prev = list; list = t;
+ t = prev_last; prev_last = last; last = t;
+ strcpy(listed, buf);
+ dirend = nameend = bufdirend;
+ message = 0;
+ } else {
+ if (list) {
+ clear_prev();
+ strcpy(preved, listed); preved[dirend]=0;
+ prev = list;
+ prev_last = last;
+ }
+ list = last = 0;
+ message = "reading..."; redraw(); Fl::flush();
+ strcpy(listed, buf);
+ dirend = nameend = bufdirend;
+ listed[dirend] = listed[dirend+1] = 0;
+ int n = filename_list(dirend ? listed : ".", &list);
+ if (n < 0) {
+ if (errno==ENOENT) message = "No such directory";
+ else message = strerror(errno);
+ n = 0; list = 0;
+ } else message = 0;
+ last = list+n;
+ }
+ if (list && last <= list+2) message = "Empty directory";
+ new_list();
+ }
+
+ dirent** q = 0; // will point to future selection
+ int any = 0; // true if any names shown
+
+ // do we match one item in the previous list?
+ if (!ispattern && bufend >= nameend) {
+ for (q = list; ; q++) {
+ if (q >= last) {q = 0; break;}
+ if (item_height(*q, 0)==0) continue;
+ any = 1;
+ const char* a = (*q)->d_name;
+ const char* b = buf+bufdirend;
+ while (*b && *a==*b) {a++; b++;}
+ if (!*b && (*a==0 || /* *a=='/' ||*/ *a==1)) break;
+ }
+ }
+
+ // no, change the list pattern to the new text + a star:
+ if (!q) {
+ strcpy(listed+dirend, buf+bufdirend);
+ nameend = bufend;
+ if (!ispattern) {listed[nameend]='*'; listed[nameend+1]=0;}
+ any = 0;
+ // search again for an exact match:
+ for (q = list; ; q++) {
+ if (q >= last) {q = 0; break;}
+ if (item_height(*q, 0)==0) continue;
+ any = 1;
+ const char* a = (*q)->d_name;
+ const char* b = buf+bufdirend;
+ while (*b && *a==*b) {a++; b++;}
+ if (!*b && (*a==0 || /* *a=='/' ||*/ *a==1)) break;
+ }
+ new_list();
+ }
+
+ if (any) message = 0;
+ else if (!message) message = "No matching files";
+ select_only(q);
+ if (q) current_callback(buf);
+}
+
+void FCB::draw() {
+ if (message) {
+ Fl_Boxtype b = box(); if (!b) b = Fl_Input_::default_box();
+ draw_box(b,color());
+ fl_color(FL_INACTIVE_COLOR);
+ fl_draw(message, x()+7, y()+3, w(), h()-3, FL_ALIGN_TOP_LEFT);
+ } else {
+ Fl_Browser_::draw();
+ if (full_height()<=0) {
+ message = "No matching files";
+ draw();
+ }
+ }
+}
+
+void FCB::clear_prev() {
+ if (prev) {
+ for (dirent**p=prev_last-1; p>=prev; p--) free((void*)*p);
+ free((void*)prev);
+ prev = prev_last = 0;
+ }
+}
+
+void FCB::clear() {
+ if (list) {
+ for (dirent**p=last-1; p>=list; p--) free((void*)*p);
+ free((void*)list);
+ list = last = 0;
+ }
+ clear_prev();
+ listed[0] = 0; dirend = 1;
+}
+
+////////////////////////////////////////////////////////////////
+
+static void fcb_cb(Fl_Widget*, void* v) {
+ FCW* w = (FCW*)v;
+ char buf[FL_PATH_MAX];
+ if (w->browser.get(buf)) {
+ w->input.value(buf);
+ w->input.position(10000);
+// w->input.position(10000, w->browser.dirend);
+ if (Fl::event_button()==1) {
+ if (Fl::event_clicks()) w->ok_button->do_callback();
+ else w->browser.set(buf);
+ } else {
+ current_callback(buf);
+ }
+ }
+}
+
+static void tab_cb(Fl_Widget*, void* v) {
+ FCW* w = (FCW*)v;
+ char buf[FL_PATH_MAX];
+ if (w->browser.get(buf)) {
+ w->input.value(buf);
+ w->input.position(10000);
+ w->browser.set(buf);
+ }
+}
+
+#if defined(WIN32) || defined(__EMX__)
+// ':' needs very special handling!
+static inline int isdirsep(char c) {return c=='/' || c=='\\';}
+#else
+#define isdirsep(c) ((c)=='/')
+#endif
+
+static void input_cb(Fl_Widget*, void* v) {
+ FCW* w = (FCW*)v;
+ const char* buf = w->input.value();
+ char localbuf[FL_PATH_MAX];
+ if (buf[0] && isdirsep(buf[w->input.size()-1])
+ && filename_expand(localbuf, buf)) {
+ buf = localbuf;
+ w->input.value(localbuf);
+ w->input.position(10000);
+ }
+ w->browser.set(buf);
+}
+
+static void up_cb(Fl_Widget*, void* v) { // the .. button
+ FCW* w = (FCW*)v;
+ char* p;
+ char* newname;
+ char buf[FL_PATH_MAX];
+ p = w->browser.listed+w->browser.dirend-1; // point right before last '/'
+ if (p < w->browser.listed)
+ newname = "../"; // go up from current directory
+ else {
+ for (; p>w->browser.listed; p--) if (isdirsep(*(p-1))) break;
+ if (isdirsep(*p) || *p=='.' &&
+ (isdirsep(p[1]) || p[1]=='.' && isdirsep(p[2]))) {
+ p = w->browser.listed+w->browser.dirend;
+ memcpy(buf, w->browser.listed, p-w->browser.listed);
+ strcpy(buf+(p-w->browser.listed), "../");
+ } else {
+ memcpy(buf, w->browser.listed, p-w->browser.listed);
+ buf[p-w->browser.listed] = 0;
+ }
+ newname = buf;
+ }
+ w->input.value(newname);
+ w->input.position(10000);
+ w->browser.set(newname);
+}
+
+static void dir_cb(Fl_Widget* obj, void* v) { // directory buttons
+ FCW* w = (FCW*)v;
+ const char* p = obj->label(); if (*p=='&') p++;
+ char buf[FL_PATH_MAX];
+ char* q; for (q=buf; *p && *p!=' '; *q++ = *p++); *q = 0;
+ filename_expand(buf, buf);
+ w->input.value(buf);
+ w->input.position(10000);
+ w->browser.set(buf);
+}
+
+static void working_cb(Fl_Widget*, void* v) { // directory buttons
+ FCW*w = (FCW*)v;
+ char buf[FL_PATH_MAX];
+ filename_absolute(buf, "");
+ w->input.value(buf);
+ w->input.position(10000);
+ w->browser.set(buf);
+}
+
+static void files_cb(Fl_Widget* obj, void* v) { // file pattern buttons
+ FCW* w = (FCW*)v;
+ char buf[FL_PATH_MAX];
+ strcpy(buf, w->input.value());
+ char* q = buf+w->browser.dirend;
+ if (obj != w->normal_button) { // tack on first word of label
+ const char* p = obj->label(); if (*p=='&') p++;
+ for (; *p && *p!=' '; *q++ = *p++);
+ }
+ *q = 0;
+ w->input.value(buf);
+ w->input.position(10000, w->browser.dirend);
+ w->browser.set(buf);
+}
+
+/*----------------------- The Main Routine ----------------------*/
+#define HEIGHT_BOX (4*WIDTH_SPC+HEIGHT_BUT+HEIGHT_INPUT+HEIGHT_BROWSER)
+#define HEIGHT_BUT 25
+#define HEIGHT_INPUT 30
+#define HEIGHT_BROWSER (9*HEIGHT_BUT+2) // must be > buttons*HEIGHT_BUT
+#define WIDTH_BOX (3*WIDTH_SPC+WIDTH_BUT+WIDTH_BROWSER)
+#define WIDTH_BROWSER 350
+#define WIDTH_BUT 125
+#define WIDTH_OK 70
+#define WIDTH_SPC 5
+
+int FCW::handle(int event) {
+ if (Fl_Window::handle(event)) return 1;
+ if (event==FL_KEYBOARD && Fl::event_key()==FL_Tab) {
+ tab_cb(this, this);
+ return 1;
+ }
+ return 0;
+}
+
+// set this to make extra directory-jumping button:
+const char* fl_file_chooser_button;
+extern const char* fl_ok;
+extern const char* fl_cancel;
+
+FCW::FCW() : Fl_Window(WIDTH_BOX, HEIGHT_BOX),
+ input(WIDTH_SPC, HEIGHT_BOX-HEIGHT_BUT-2*WIDTH_SPC-HEIGHT_INPUT,
+ WIDTH_BOX-2*WIDTH_SPC, HEIGHT_INPUT, 0),
+ browser(2*WIDTH_SPC+WIDTH_BUT, WIDTH_SPC,
+ WIDTH_BROWSER, HEIGHT_BROWSER)
+{
+ int but_y = WIDTH_SPC;
+ input.callback(input_cb, this);
+ input.when(FL_WHEN_CHANGED);
+ // add(browser);
+ browser.callback(fcb_cb, this);
+
+ begin();
+ Fl_Widget* obj;
+ obj = ok_button = new Fl_Return_Button(
+ WIDTH_BOX-2*(WIDTH_SPC+WIDTH_OK), HEIGHT_BOX-WIDTH_SPC-HEIGHT_BUT,
+ WIDTH_OK, HEIGHT_BUT, fl_ok);
+ obj = cancel_button = new Fl_Button(
+ WIDTH_BOX-WIDTH_SPC-WIDTH_OK, HEIGHT_BOX-WIDTH_SPC-HEIGHT_BUT,
+ WIDTH_OK, HEIGHT_BUT, fl_cancel);
+ cancel_button->shortcut("^[");
+
+ obj=new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, "&Up one directory");
+ obj->callback(up_cb, this);
+ but_y += HEIGHT_BUT;
+
+ obj = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&~/ Home");
+ obj->callback(dir_cb, this);
+ but_y += HEIGHT_BUT;
+
+ obj = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&/ Root");
+ obj->callback(dir_cb, this);
+ but_y += HEIGHT_BUT;
+
+ obj=new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&Current dir");
+ obj->callback(working_cb, this);
+ but_y += HEIGHT_BUT;
+
+ if (fl_file_chooser_button) {
+ obj=new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT,fl_file_chooser_button);
+ obj->callback(dir_cb, this);
+ but_y += HEIGHT_BUT;
+ }
+
+ normal_button = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "");
+ normal_button->callback(files_cb, this);
+ but_y += HEIGHT_BUT;
+
+ obj = new Fl_Button(WIDTH_SPC,but_y, WIDTH_BUT, HEIGHT_BUT, "* &All files");
+ obj->callback(files_cb, this);
+ but_y += HEIGHT_BUT;
+
+ obj = new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, ". &Hidden files");
+ obj->callback(files_cb, this);
+ but_y += HEIGHT_BUT;
+
+ obj = new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, "*/ &Directories");
+ obj->callback(files_cb, this);
+ but_y += HEIGHT_BUT;
+
+ resizable(new Fl_Box(browser.x(), but_y,
+ cancel_button->x()-browser.x(),
+ browser.y()+browser.h()-but_y));
+ // add(input); // put last for better draw() speed
+ end();
+ set_modal();
+}
+
+char* fl_file_chooser(const char* message, const char* pat, const char* fname)
+{
+ static FCW* f; if (!f) f = new FCW();
+ f->ok_button->label(fl_ok);
+ f->cancel_button->label(fl_cancel);
+
+ if (pat && !*pat) pat = 0;
+ if (fname && *fname) {
+ f->input.value(fname);
+ } else if (f->browser.pattern != pat && (!pat || !f->browser.pattern ||
+ strcmp(pat,f->browser.pattern))) {
+ // if pattern is different, remove name but leave old directory:
+ const char* p = f->input.value();
+ const char* q = filename_name(p);
+ f->input.value(p, q-p);
+ }
+ f->browser.pattern = pat;
+ f->normal_button->label(pat ? pat : "visible files");
+ f->browser.set(f->input.value());
+ f->input.position(10000, f->browser.dirend);
+
+ f->label(message);
+ f->hotspot(f);
+ f->show();
+ int ok = 0;
+ for (;;) {
+ Fl::wait();
+ Fl_Widget* o = Fl::readqueue();
+ if (o == f->ok_button) {ok = 1; break;}
+ else if (o == f->cancel_button || o == f) break;
+ }
+ f->hide();
+ f->browser.clear();
+
+ if (!ok) return 0;
+ const char* r = f->input.value();
+ const char* p;
+ for (p=r+f->browser.dirend; *p; p++)
+ if (*p=='*' || *p=='?' || *p=='[' || *p=='{') return 0;
+ return (char*)r;
+}
+
+// end of fl_file_chooser.C
diff --git a/src/fl_font.cxx b/src/fl_font.cxx
new file mode 100644
index 000000000..746f65547
--- /dev/null
+++ b/src/fl_font.cxx
@@ -0,0 +1,283 @@
+// fl_font.C
+
+// Select fonts from the fltk font table.
+
+#ifdef WIN32
+#include "fl_font_win32.C"
+#else
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include "Fl_Font.H"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+Fl_XFont::Fl_XFont(const char *name, int num)
+ : number(num)
+{
+ font = XLoadQueryFont(fl_display, name);
+ if (!font) {
+ Fl::warning("bad font: %s", name);
+ font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash
+ }
+ XCharStruct *p = font->per_char;
+ if (!p) {
+ free_this = per_char = 0;
+ } else if (font->min_char_or_byte2>0x20 || font->max_char_or_byte2<0xff) {
+ // fill in short fonts so fl_width does not crash:
+ XCharStruct *q = free_this = new XCharStruct[0xff-0x20+1];
+ per_char = q - 0x20;
+ unsigned int i = 0x20;
+ for (; i<font->min_char_or_byte2; i++, q++)
+ q->width = font->min_bounds.width;
+ for (; i<=font->max_char_or_byte2; i++)
+ *q++ = *p++;
+ for (; i<=0xff; i++)
+ q->width = font->min_bounds.width;
+ } else {
+ free_this = 0;
+ per_char = p - font->min_char_or_byte2;
+ }
+#if HAVE_GL
+ listbase = 0;
+#endif
+}
+
+Fl_XFont *fl_current_xfont;
+Fl_XFont *fl_fixed_xfont;
+
+Fl_XFont::~Fl_XFont() {
+#if HAVE_GL
+// Delete list created by gl_draw(). This is not done by this code
+// as it will link in GL unnecessarily. There should be some kind
+// of "free" routine pointer, or a subclass?
+// if (listbase) {
+// int base = font->min_char_or_byte2;
+// int size = font->max_char_or_byte2-base+1;
+// int base = 0; int size = 256;
+// glDeleteLists(listbase+base,size);
+// }
+#endif
+ if (this == fl_current_xfont) fl_current_xfont = 0;
+ delete[] free_this;
+ XFreeFont(fl_display, font);
+}
+
+////////////////////////////////////////////////////////////////
+
+// WARNING: if you add to this table, you must redefine FL_FREE_FONT
+// in Enumerations.H & recompile!!
+static Fl_Fontdesc built_in_table[] = {
+{"-*-helvetica-medium-r-normal--*"},
+{"-*-helvetica-bold-r-normal--*"},
+{"-*-helvetica-medium-o-normal--*"},
+{"-*-helvetica-bold-o-normal--*"},
+{"-*-courier-medium-r-normal--*"},
+{"-*-courier-bold-r-normal--*"},
+{"-*-courier-medium-o-normal--*"},
+{"-*-courier-bold-o-normal--*"},
+{"-*-times-medium-r-normal--*"},
+{"-*-times-bold-r-normal--*"},
+{"-*-times-medium-i-normal--*"},
+{"-*-times-bold-i-normal--*"},
+{"-*-symbol-*"},
+{"-*-lucidatypewriter-medium-r-normal-sans-*"},
+{"-*-lucidatypewriter-bold-r-normal-sans-*"},
+{"-*-*zapf dingbats-*"}
+};
+
+Fl_Fontdesc *fl_fonts = built_in_table;
+
+#define MAXSIZE 32767
+
+// return dash number N, or pointer to ending null if none:
+const char* fl_font_word(const char *p, int n) {
+ while (*p) {if (*p=='-') {if (!--n) break;} p++;}
+ return p;
+}
+
+// return a pointer to a number we think is "point size":
+char *fl_find_fontsize(char* name) {
+ char *c = name;
+ // for standard x font names, try after 7th dash:
+ if (*c == '-') {
+ c = (char*)fl_font_word(c,7);
+ if (*c++ && isdigit(*c)) return c;
+ return 0; // malformed x font name?
+ }
+ char *r = 0;
+ // find last set of digits:
+ for (c++; *c; c++)
+ if (isdigit(*c) && !isdigit(*(c-1))) r = c;
+ return r;
+}
+
+const char* fl_encoding = "iso8859-1";
+
+// return true if this matches fl_encoding:
+int fl_correct_encoding(const char* name) {
+ if (*name != '-') return 0;
+ const char* c = fl_font_word(name,13);
+ return (*c++ && !strcmp(c,fl_encoding));
+}
+
+// locate or create an Fl_XFont for a given Fl_Fontdesc and size:
+static Fl_XFont *find(int fnum, int size) {
+ Fl_Fontdesc *s = fl_fonts+fnum;
+ if (!s->name) s = fl_fonts; // use font 0 if still undefined
+ Fl_XFont *f;
+ for (f = s->first; f; f = f->next)
+ if (f->minsize <= size && f->maxsize >= size) return f;
+ fl_open_display();
+ if (!s->xlist) {
+ s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
+ if (!s->xlist) { // use fixed if no matching font...
+ if (!fl_fixed_xfont) {
+ fl_fixed_xfont = new Fl_XFont("fixed",fnum);
+ fl_fixed_xfont->minsize = 0;
+ fl_fixed_xfont->maxsize = 32767;
+ }
+ s->first = fl_fixed_xfont;
+ return fl_fixed_xfont;
+ }
+ }
+ // search for largest <= font size:
+ char *name = s->xlist[0]; int ptsize = 0; // best one found so far
+ int matchedlength = 32767;
+ char namebuffer[1024]; // holds scalable font name
+ int found_encoding = 0;
+ int m = s->n; if (m<0) m = -m;
+ for (int n=0; n < m; n++) {
+
+ char *thisname = s->xlist[n];
+ if (fl_correct_encoding(thisname)) {
+ if (!found_encoding) ptsize = 0; // force it to choose this
+ found_encoding = 1;
+ } else {
+ if (found_encoding) continue;
+ }
+ char *c = fl_find_fontsize(thisname);
+ int thissize = c ? atoi(c) : MAXSIZE;
+ int thislength = strlen(thisname);
+ if (thissize == size && thislength < matchedlength) {
+ // exact match, use it:
+ name = thisname;
+ ptsize = size;
+ matchedlength = thislength;
+ } else if (!thissize && ptsize!=size) {
+ // whoa! A scalable font! Use unless exact match found:
+ int l = c-thisname;
+ memcpy(namebuffer,thisname,l);
+#if 1 // this works if you don't want stdio
+ if (size>=100) namebuffer[l++] = size/100+'0';
+ if (size>=10) namebuffer[l++] = (size/10)%10+'0';
+ namebuffer[l++] = (size%10)+'0';
+#else
+ //for some reason, sprintf fails to return the right value under Solaris.
+ l += sprintf(namebuffer+l,"%d",size);
+#endif
+ while (*c == '0') c++;
+ strcpy(namebuffer+l,c);
+ name = namebuffer;
+ ptsize = size;
+ } else if (!ptsize || // no fonts yet
+ thissize < ptsize && ptsize > size || // current font too big
+ thissize > ptsize && thissize <= size // current too small
+ ) {
+ name = thisname; ptsize = thissize;
+ matchedlength = thislength;
+ }
+ }
+
+ if (ptsize != size) { // see if we already found this unscalable font:
+ for (f = s->first; f; f = f->next) {
+ if (f->minsize <= ptsize && f->maxsize >= ptsize) {
+ if (f->minsize > size) f->minsize = size;
+ if (f->maxsize < size) f->maxsize = size;
+ return f;
+ }
+ }
+ }
+
+ // okay, we definately have some name, make the font:
+ f = new Fl_XFont(name,fnum);
+ if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;}
+ else {f->minsize = size; f->maxsize = ptsize;}
+ f->next = s->first;
+ s->first = f;
+ return f;
+
+}
+
+////////////////////////////////////////////////////////////////
+// Public interface:
+
+int fl_font_;
+int fl_size_;
+static GC font_gc;
+
+void fl_font(int fnum, int size) {
+ if (fnum == fl_font_ && size == fl_size_) return;
+ fl_font_ = fnum; fl_size_ = size;
+ Fl_XFont *f = find(fnum, size);
+ if (f != fl_current_xfont) {fl_current_xfont = f; font_gc = 0;}
+}
+
+void fl_font(int fnum, int size, Fl_Font default_font, int default_size) {
+ if (fnum<4) fnum |= default_font;
+ fl_font(fnum, size + default_size);
+}
+
+int fl_height() {
+ return (fl_current_xfont->font->ascent + fl_current_xfont->font->descent);
+}
+
+int fl_descent() {
+ return fl_current_xfont->font->descent;
+}
+
+double fl_width(const char *c) {
+ XCharStruct *p = fl_current_xfont->per_char;
+ if (!p) return strlen(c)*fl_current_xfont->font->min_bounds.width;
+ int w = 0;
+ while (*c)
+ if (*c >= ' ')
+ w += p[(uchar)(*c++)].width;
+ else
+ c ++;
+
+ return w;
+}
+
+double fl_width(const char *c, int n) {
+ XCharStruct *p = fl_current_xfont->per_char;
+ if (!p) return n*fl_current_xfont->font->min_bounds.width;
+ int w = 0;
+ while (n--) w += p[(uchar)(*c++)].width;
+ return w;
+}
+
+double fl_width(uchar c) {
+ XCharStruct *p = fl_current_xfont->per_char;
+ if (!p) return fl_current_xfont->font->min_bounds.width;
+ return p[c].width;
+}
+
+void fl_draw(const char *str, int n, int x, int y) {
+ if (font_gc != fl_gc) {
+ font_gc = fl_gc;
+ XSetFont(fl_display, fl_gc, fl_current_xfont->font->fid);
+ }
+ XDrawString(fl_display, fl_window, fl_gc, x, y, str, n);
+}
+
+void fl_draw(const char *str, int x, int y) {
+ fl_draw(str, strlen(str), x, y);
+}
+
+#endif
+// end of fl_font.C
diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx
new file mode 100644
index 000000000..0f4e20e77
--- /dev/null
+++ b/src/fl_font_win32.cxx
@@ -0,0 +1,159 @@
+// fl_font_win32.C
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/win32.H>
+#include "Fl_Font.H"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+Fl_XFont::Fl_XFont(const char *name, int size, int num) {
+ int weight = FW_NORMAL;
+ int italic = 0;
+ switch (*name++) {
+ case 'I': italic = 1; break;
+ case 'P': italic = 1;
+ case 'B': weight = FW_BOLD; break;
+ case ' ': break;
+ default: name--;
+ }
+ fid = CreateFont(
+ -size, // negative makes it use "char size"
+ 0, // logical average character width
+ 0, // angle of escapement
+ 0, // base-line orientation angle
+ weight,
+ italic,
+ FALSE, // underline attribute flag
+ FALSE, // strikeout attribute flag
+ DEFAULT_CHARSET, // character set identifier
+ OUT_DEFAULT_PRECIS, // output precision
+ CLIP_DEFAULT_PRECIS,// clipping precision
+ DEFAULT_QUALITY, // output quality
+ DEFAULT_PITCH, // pitch and family
+ name // pointer to typeface name string
+ );
+ if (!fl_gc) fl_gc = fl_GetDC(0);
+ SelectObject(fl_gc, fid);
+ GetTextMetrics(fl_gc, &metr);
+// BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar);
+// ...would be the right call, but is not implemented into Window95! (WinNT?)
+ GetCharWidth(fl_gc, 0, 255, width);
+#if HAVE_GL
+ listbase = 0;
+#endif
+ number = num;
+ minsize = maxsize = size;
+}
+
+Fl_XFont *fl_current_xfont;
+
+Fl_XFont::~Fl_XFont() {
+#if HAVE_GL
+// Delete list created by gl_draw(). This is not done by this code
+// as it will link in GL unnecessarily. There should be some kind
+// of "free" routine pointer, or a subclass?
+// if (listbase) {
+// int base = font->min_char_or_byte2;
+// int size = font->max_char_or_byte2-base+1;
+// int base = 0; int size = 256;
+// glDeleteLists(listbase+base,size);
+// }
+#endif
+ if (this == fl_current_xfont) fl_current_xfont = 0;
+ DeleteObject(fid);
+}
+
+////////////////////////////////////////////////////////////////
+
+// WARNING: if you add to this table, you must redefine FL_FREE_FONT
+// in Enumerations.H & recompile!!
+static Fl_Fontdesc built_in_table[] = {
+{" Arial"},
+{"BArial"},
+{"IArial"},
+{"PArial"},
+{" Courier New"},
+{"BCourier New"},
+{"ICourier New"},
+{"PCourier New"},
+{" Times New Roman"},
+{"BTimes New Roman"},
+{"ITimes New Roman"},
+{"PTimes New Roman"},
+{" Symbol"},
+{" Terminal"},
+{"BTerminal"},
+{" Wingdings"},
+};
+
+Fl_Fontdesc *fl_fonts = built_in_table;
+
+static Fl_XFont *find(int fnum, int size) {
+ Fl_Fontdesc *s = fl_fonts+fnum;
+ if (!s->name) s = fl_fonts; // use 0 if fnum undefined
+ Fl_XFont *f;
+ for (f = s->first; f; f = f->next)
+ if (f->minsize <= size && f->maxsize >= size) return f;
+ f = new Fl_XFont(s->name, size, fnum);
+ f->next = s->first;
+ s->first = f;
+ return f;
+}
+
+////////////////////////////////////////////////////////////////
+// Public interface:
+
+int fl_font_;
+int fl_size_;
+static HDC font_gc;
+
+void fl_font(int fnum, int size) {
+ if (fnum == fl_font_ && size == fl_size_) return;
+ fl_font_ = fnum; fl_size_ = size;
+ fl_current_xfont = find(fnum, size);
+}
+
+void fl_font(int fnum, int size, Fl_Font default_font, int default_size) {
+ if (fnum<4) fnum |= default_font;
+ fl_font(fnum, size + default_size);
+}
+
+int fl_height() {
+ return (fl_current_xfont->metr.tmAscent + fl_current_xfont->metr.tmDescent);
+}
+
+int fl_descent() {
+ return fl_current_xfont->metr.tmDescent;
+}
+
+double fl_width(const char *c) {
+ double w = 0.0;
+ while (*c) w += fl_current_xfont->width[uchar(*c++)];
+ return w;
+}
+
+double fl_width(const char *c, int n) {
+ double w = 0.0;
+ while (n--) w += fl_current_xfont->width[uchar(*c++)];
+ return w;
+}
+
+double fl_width(uchar c) {
+ return fl_current_xfont->width[c];
+}
+
+void fl_draw(const char *str, int n, int x, int y) {
+ SetTextColor(fl_gc, fl_RGB());
+ SelectObject(fl_gc, fl_current_xfont->fid);
+ TextOut(fl_gc, x, y, str, n);
+}
+
+void fl_draw(const char *str, int x, int y) {
+ fl_draw(str, strlen(str), x, y);
+}
+
+// end of fl_font_win32.C
diff --git a/src/fl_labeltype.cxx b/src/fl_labeltype.cxx
new file mode 100644
index 000000000..8b7755eaf
--- /dev/null
+++ b/src/fl_labeltype.cxx
@@ -0,0 +1,104 @@
+// fl_labeltype.C
+
+// Drawing code for the (one) common label types.
+// Other label types (symbols) are in their own source files
+// to avoid linking if not used.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Group.H>
+#include <FL/fl_draw.H>
+
+void
+fl_no_label(const Fl_Label*,int,int,int,int,Fl_Align) {}
+
+void
+fl_normal_label(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
+{
+ fl_font(o->font, o->size);
+ fl_color((Fl_Color)o->color);
+ fl_draw(o->value, X, Y, W, H, align);
+}
+
+void
+fl_normal_measure(const Fl_Label* o, int& W, int& H) {
+ fl_font(o->font, o->size);
+ fl_measure(o->value, W, H);
+}
+
+#define MAX_LABELTYPE 16
+
+static Fl_Label_Draw_F* table[MAX_LABELTYPE] = {
+ fl_normal_label,
+ fl_no_label,
+ fl_normal_label, // _FL_SYMBOL_LABEL,
+ fl_normal_label, // _FL_SHADOW_LABEL,
+ fl_normal_label, // _FL_ENGRAVED_LABEL,
+ fl_normal_label, // _FL_EMBOSSED_LABEL,
+ fl_no_label, // _FL_BITMAP_LABEL,
+ fl_no_label, // _FL_PIXMAP_LABEL,
+ fl_no_label, // _FL_IMAGE_LABEL,
+ // FL_FREE_LABELTYPE+n:
+ fl_no_label, fl_no_label, fl_no_label,
+ fl_no_label, fl_no_label, fl_no_label, fl_no_label,
+};
+
+static Fl_Label_Measure_F* measure[MAX_LABELTYPE];
+
+void Fl::set_labeltype(Fl_Labeltype t,Fl_Label_Draw_F* f,Fl_Label_Measure_F*m)
+{
+ table[t] = f; measure[t] = m;
+}
+
+////////////////////////////////////////////////////////////////
+
+// draw label with arbitrary alignment in arbitrary box:
+void Fl_Label::draw(int X, int Y, int W, int H, Fl_Align align) const {
+ if (!value) return;
+ table[type](this, X, Y, W, H, align);
+}
+
+void Fl_Label::measure(int& W, int& H) const {
+ if (!value) return;
+ Fl_Label_Measure_F* f = ::measure[type]; if (!f) f = fl_normal_measure;
+ f(this, W, H);
+}
+
+// The normal call for a draw() method:
+void Fl_Widget::draw_label() const {
+ int X = x_+Fl::box_dx(box());
+ int W = w_-Fl::box_dw(box());
+ if (W > 11 && align()&(FL_ALIGN_LEFT|FL_ALIGN_RIGHT)) {X += 3; W -= 6;}
+ draw_label(X, y_+Fl::box_dy(box()), W, h_-Fl::box_dh(box()));
+}
+
+// draw() can use this instead to change the bounding box:
+void Fl_Widget::draw_label(int X, int Y, int W, int H) const {
+ // quit if we are not drawing a label inside the widget:
+ if ((align()&15) && !(align() & FL_ALIGN_INSIDE)) return;
+ draw_label(X,Y,W,H,align());
+}
+
+Fl_Font Fl_Widget::default_font_;
+int Fl_Widget::default_size_;
+
+// Anybody can call this to force the label to draw anywhere:
+extern char fl_draw_shortcut;
+void Fl_Widget::draw_label(int X, int Y, int W, int H, Fl_Align a) const {
+ if (flags()&SHORTCUT_LABEL) fl_draw_shortcut = 1;
+ Fl_Label l1 = label_;
+ if (!active_r()) l1.color |= 8;
+ if (l1.font<4) l1.font |= default_font_;
+ l1.size += default_size_;
+ l1.draw(X,Y,W,H,a);
+ fl_draw_shortcut = 0;
+}
+
+// include these vars here so they can be referenced without including
+// Fl_Input_ code:
+#include <FL/Fl_Input_.H>
+
+Fl_Boxtype Fl_Input_::default_box_ = FL_DOWN_BOX;
+Fl_Font Fl_Input_::default_font_;
+int Fl_Input_::default_size_;
+
diff --git a/src/fl_oval_box.cxx b/src/fl_oval_box.cxx
new file mode 100644
index 000000000..8e5c1c564
--- /dev/null
+++ b/src/fl_oval_box.cxx
@@ -0,0 +1,38 @@
+/* fl_oval_box.C
+
+ Less-used box types are in seperate files so they are not linked
+ in if not used.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+static void fl_oval_flat_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c);
+ fl_pie(x, y, w, h, 0, 360);
+}
+
+static void fl_oval_frame(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c);
+ fl_arc(x, y, w, h, 0, 360);
+}
+
+static void fl_oval_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_oval_flat_box(x,y,w-1,h-1,c);
+ fl_oval_frame(x,y,w,h,FL_BLACK);
+}
+
+static void fl_oval_shadow_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_oval_flat_box(x+3,y+3,w,h,FL_DARK3);
+ fl_oval_box(x,y,w,h,c);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype define_FL_OVAL_BOX() {
+ fl_internal_boxtype(_FL_OSHADOW_BOX,fl_oval_shadow_box);
+ fl_internal_boxtype(_FL_OVAL_FRAME,fl_oval_frame);
+ fl_internal_boxtype(_FL_OFLAT_BOX,fl_oval_flat_box);
+ fl_internal_boxtype(_FL_OVAL_BOX,fl_oval_box);
+ return _FL_OVAL_BOX;
+}
diff --git a/src/fl_overlay.cxx b/src/fl_overlay.cxx
new file mode 100644
index 000000000..ed44ec9c6
--- /dev/null
+++ b/src/fl_overlay.cxx
@@ -0,0 +1,39 @@
+// fl_overlay.C
+
+// Extremely limited "overlay" support. You can use this to drag out
+// a rectangle in response to mouse events. It is your responsibility
+// to erase the overlay before drawing anything that might intersect
+// it.
+
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+static int px,py,pw,ph;
+
+static void draw_current_rect() {
+#ifdef WIN32
+ int old = SetROP2(fl_gc, R2_NOT);
+ fl_rect(px, py, pw, ph);
+ SetROP2(fl_gc, old);
+#else
+ XSetFunction(fl_display, fl_gc, GXxor);
+ XSetForeground(fl_display, fl_gc, 0xffffffff);
+ XDrawRectangle(fl_display, fl_window, fl_gc, px, py, pw, ph);
+ XSetFunction(fl_display, fl_gc, GXcopy);
+#endif
+}
+
+void fl_overlay_clear() {
+ if (pw > 0) {draw_current_rect(); pw = 0;}
+}
+
+void fl_overlay_rect(int x, int y, int w, int h) {
+ if (w < 0) {x += w; w = -w;} else if (!w) w = 1;
+ if (h < 0) {y += h; h = -h;} else if (!h) h = 1;
+ if (pw > 0) {
+ if (x==px && y==py && w==pw && h==ph) return;
+ draw_current_rect();
+ }
+ px = x; py = y; pw = w; ph = h;
+ draw_current_rect();
+}
diff --git a/src/fl_overlay_visual.cxx b/src/fl_overlay_visual.cxx
new file mode 100644
index 000000000..a176bf69c
--- /dev/null
+++ b/src/fl_overlay_visual.cxx
@@ -0,0 +1,76 @@
+// Stupid X tricks
+
+// Return an overlay visual, if any. Also allocate a colormap and
+// record the depth for fl_color() to use.
+// Another disgusting X interface, based on code extracted and
+// purified with great difficulty from XLayerUtil.C:
+
+#include <config.h>
+#if HAVE_OVERLAY
+#include <FL/Fl.H>
+#include <FL/x.H>
+
+// SERVER_OVERLAY_VISUALS property element:
+struct OverlayInfo {
+ long overlay_visual;
+ long transparent_type;
+ long value;
+ long layer;
+};
+
+extern Colormap fl_overlay_colormap;
+extern XVisualInfo* fl_overlay_visual;
+extern ulong fl_transparent_pixel;
+
+XVisualInfo *fl_find_overlay_visual() {
+ static char beenhere;
+ if (beenhere) return fl_overlay_visual;
+ beenhere = 1;
+
+ fl_open_display();
+ Atom overlayVisualsAtom =
+ XInternAtom(fl_display,"SERVER_OVERLAY_VISUALS",1);
+ if (!overlayVisualsAtom) return 0;
+ OverlayInfo *overlayInfo;
+ ulong sizeData, bytesLeft;
+ Atom actualType;
+ int actualFormat;
+ if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
+ overlayVisualsAtom, 0L, 10000L, False,
+ overlayVisualsAtom, &actualType, &actualFormat,
+ &sizeData, &bytesLeft,
+ (unsigned char **) &overlayInfo)) return 0;
+
+ if (actualType == overlayVisualsAtom && actualFormat == 32) {
+ int n = int(sizeData/4);
+ XVisualInfo* v = 0;
+ // find the greatest depth that has a transparent pixel:
+ for (int i = 0; i < n; i++) {
+ if (overlayInfo[i].transparent_type != 1) continue;
+ if (overlayInfo[i].layer <= 0) continue;
+ XVisualInfo templt;
+ templt.visualid = overlayInfo[i].overlay_visual;
+ int num;
+ XVisualInfo *v1=XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+ if (v1->screen == fl_screen &&
+ !v1->red_mask && (!v || v1->depth >= v->depth && v1->depth <= 8)) {
+ if (v) XFree((char*)v);
+ v = v1;
+ fl_transparent_pixel = overlayInfo[i].value;
+ } else {
+ XFree((char*)v1);
+ }
+ }
+ if (v) {
+ fl_overlay_visual = v;
+ fl_overlay_colormap =
+ XCreateColormap(fl_display, RootWindow(fl_display, fl_screen),
+ v->visual, AllocNone);
+ }
+ }
+ XFree((char*)overlayInfo);
+ // printf("overlay visual %d selected\n", fl_overlay_visual->visualid);
+ return fl_overlay_visual;
+}
+
+#endif
diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx
new file mode 100644
index 000000000..2e294bd96
--- /dev/null
+++ b/src/fl_rect.cxx
@@ -0,0 +1,380 @@
+// fl_rect.C
+
+// These routines from fl_draw.H are used by the standard boxtypes
+// and thus are always linked into an fltk program.
+
+// Also all fl_clip routines, since they are always linked in so
+// that minimal update works.
+
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+void fl_rect(int x, int y, int w, int h) {
+ if (w<=0 || h<=0) return;
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x+w-1, y);
+ LineTo(fl_gc, x+w-1, y+h-1);
+ LineTo(fl_gc, x, y+h-1);
+ LineTo(fl_gc, x, y);
+#else
+ XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
+#endif
+}
+
+void fl_rectf(int x, int y, int w, int h) {
+ if (w<=0 || h<=0) return;
+#ifdef WIN32
+ RECT rect;
+ rect.left = x; rect.top = y;
+ rect.right = x + w; rect.bottom = y + h;
+ FillRect(fl_gc, &rect, fl_brush());
+#else
+ if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
+#endif
+}
+
+void fl_xyline(int x, int y, int x1) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
+#else
+ XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
+#endif
+}
+
+void fl_xyline(int x, int y, int x1, int y2) {
+#ifdef WIN32
+ if (y2 < y) y2--;
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x1, y);
+ LineTo(fl_gc, x1, y2);
+#else
+ XPoint p[3];
+ p[0].x = x; p[0].y = p[1].y = y;
+ p[1].x = p[2].x = x1; p[2].y = y2;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
+#endif
+}
+
+void fl_xyline(int x, int y, int x1, int y2, int x3) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x1, y);
+ LineTo(fl_gc, x1, y2);
+ LineTo(fl_gc, x3, y2);
+#else
+ XPoint p[4];
+ p[0].x = x; p[0].y = p[1].y = y;
+ p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
+ p[3].x = x3;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_yxline(int x, int y, int y1) {
+#ifdef WIN32
+ if (y1 < y) y1--;
+ MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1);
+#else
+ XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
+#endif
+}
+
+void fl_yxline(int x, int y, int y1, int x2) {
+#ifdef WIN32
+ if (x2 > x) x2++;
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x, y1);
+ LineTo(fl_gc, x2, y1);
+#else
+ XPoint p[3];
+ p[0].x = p[1].x = x; p[0].y = y;
+ p[1].y = p[2].y = y1; p[2].x = x2;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
+#endif
+}
+
+void fl_yxline(int x, int y, int y1, int x2, int y3) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x, y1);
+ LineTo(fl_gc, x2, y1);
+ LineTo(fl_gc, x2, y3);
+#else
+ XPoint p[4];
+ p[0].x = p[1].x = x; p[0].y = y;
+ p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
+ p[3].y = y3;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_line(int x, int y, int x1, int y1) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x1, y1);
+#else
+ XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1);
+#endif
+}
+
+void fl_line(int x, int y, int x1, int y1, int x2, int y2) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x1, y1);
+ LineTo(fl_gc, x2, y2);
+#else
+ XPoint p[3];
+ p[0].x = x; p[0].y = y;
+ p[1].x = x1; p[1].y = y1;
+ p[2].x = x2; p[2].y = y2;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
+#endif
+}
+
+void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x1, y1);
+ LineTo(fl_gc, x2, y2);
+ LineTo(fl_gc, x, y);
+#else
+ XPoint p[4];
+ p[0].x = x; p[0].y = y;
+ p[1].x = x1; p[1].y = y1;
+ p[2].x = x2; p[2].y = y2;
+ p[3].x = x; p[3].y = y;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+#ifdef WIN32
+ MoveToEx(fl_gc, x, y, 0L);
+ LineTo(fl_gc, x1, y1);
+ LineTo(fl_gc, x2, y2);
+ LineTo(fl_gc, x3, y3);
+ LineTo(fl_gc, x, y);
+#else
+ XPoint p[5];
+ p[0].x = x; p[0].y = y;
+ p[1].x = x1; p[1].y = y1;
+ p[2].x = x2; p[2].y = y2;
+ p[3].x = x3; p[3].y = y3;
+ p[4].x = x; p[4].y = y;
+ XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
+#endif
+}
+
+void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {
+ XPoint p[4];
+ p[0].x = x; p[0].y = y;
+ p[1].x = x1; p[1].y = y1;
+ p[2].x = x2; p[2].y = y2;
+#ifdef WIN32
+ SelectObject(fl_gc, fl_brush());
+ Polygon(fl_gc, p, 3);
+#else
+ p[3].x = x; p[3].y = y;
+ XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0);
+ XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
+#endif
+}
+
+void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+ XPoint p[5];
+ p[0].x = x; p[0].y = y;
+ p[1].x = x1; p[1].y = y1;
+ p[2].x = x2; p[2].y = y2;
+ p[3].x = x3; p[3].y = y3;
+#ifdef WIN32
+ SelectObject(fl_gc, fl_brush());
+ Polygon(fl_gc, p, 4);
+#else
+ p[4].x = x; p[4].y = y;
+ XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0);
+ XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
+#endif
+}
+
+void fl_point(int x, int y) {
+#ifdef WIN32
+ SetPixel(fl_gc, x, y, fl_RGB());
+#else
+ XDrawPoint(fl_display, fl_window, fl_gc, x, y);
+#endif
+}
+
+////////////////////////////////////////////////////////////////
+
+#ifdef WIN32
+
+static struct rect {int notnull, x, y, r, b;} rstack[10];
+static int rstackptr;
+int fl_clip_state_number; // used by gl_begin.C to update GL clip
+extern char fl_direct_paint; // in Fl_win32.C
+
+void fl_clip(int x, int y, int w, int h) {
+ fl_clip_state_number++;
+ int r = x+w;
+ int b = y+h;
+ rect& current = rstack[rstackptr];
+ if (current.notnull) {
+ if (current.x > x) x = current.x;
+ if (current.y > y) y = current.y;
+ if (current.r < r) r = current.r;
+ if (current.b < b) b = current.b;
+ }
+ rect& newrect = rstack[++rstackptr];
+ newrect.notnull = 1;
+ newrect.x = x;
+ newrect.y = y;
+ newrect.r = r;
+ newrect.b = b;
+ if (rstackptr == 1 && fl_direct_paint) return;
+ HRGN R = CreateRectRgn(x,y,r,b);
+ SelectClipRgn(fl_gc, R);
+ DeleteObject(R);
+}
+
+void fl_push_no_clip() {
+ fl_clip_state_number++;
+ if (rstack[rstackptr].notnull) SelectClipRgn(fl_gc, 0);
+ rstack[++rstackptr].notnull = 0;
+}
+
+void fl_pop_clip() {
+ fl_clip_state_number++;
+ rect& r = rstack[--rstackptr];
+ if (r.notnull) {
+ HRGN R = CreateRectRgn(r.x, r.y, r.r, r.b);
+ SelectClipRgn(fl_gc, R);
+ DeleteObject(R);
+ } else {
+ SelectClipRgn(fl_gc, 0);
+ }
+}
+
+// does this rectangle intersect current clip?
+int fl_not_clipped(int x, int y, int w, int h) {
+ rect& r = rstack[rstackptr];
+ if (!r.notnull) return 2;
+ return (x < r.r && x+w > r.x && y < r.b && y+h > r.y);
+}
+
+// return rectangle surrounding intersection of this rectangle and clip:
+int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
+ X = x; Y = y; W = w; H = h;
+ rect& r = rstack[rstackptr];
+ if (!r.notnull) return 0;
+ int R = x+w;
+ int B = y+h;
+ int ret = 0;
+ if (r.x > x) {X = r.x; ret = 1;}
+ if (r.y > y) {Y = r.y; ret = 1;}
+ if (r.r < R) {R = r.r; ret = 1;}
+ if (r.b < B) {B = r.b; ret = 1;}
+ if (B <= Y || R <= X) {W = H = 0; return 2;}
+ W = R-X;
+ H = B-Y;
+ return ret;
+}
+
+#else
+
+// Missing X call: (is this the fastest way to init a 1-rectangle region?)
+Region XRectangleRegion(int x, int y, int w, int h) {
+ XRectangle R;
+ R.x = x; R.y = y; R.width = w; R.height = h;
+ Region r = XCreateRegion();
+ XUnionRectWithRegion(&R, r, r);
+ return r;
+}
+
+static Region rstack[10];
+static int rstackptr;
+int fl_clip_state_number; // used by gl_begin.C to update GL clip
+
+// undo any clobbering of clip done by your program:
+void fl_restore_clip() {
+ fl_clip_state_number++;
+ Region r = rstack[rstackptr];
+ if (r) XSetRegion(fl_display, fl_gc, r);
+ else XSetClipMask(fl_display, fl_gc, 0);
+}
+
+// Replace the top of the clip stack:
+void fl_clip_region(Region r) {
+ Region oldr = rstack[rstackptr];
+ if (oldr) XDestroyRegion(oldr);
+ rstack[rstackptr] = r;
+ fl_restore_clip();
+}
+
+// Intersect & push a new clip rectangle:
+void fl_clip(int x, int y, int w, int h) {
+ Region r;
+ if (w > 0 && h > 0) {
+ r = XRectangleRegion(x,y,w,h);
+ Region current = rstack[rstackptr];
+ if (current) {
+ Region temp = XCreateRegion();
+ XIntersectRegion(current, r, temp);
+ XDestroyRegion(r);
+ r = temp;
+ }
+ } else { // make empty clip region:
+ r = XCreateRegion();
+ }
+ rstack[++rstackptr] = r;
+ fl_restore_clip();
+}
+
+// make there be no clip (used by fl_begin_offscreen() only!)
+void fl_push_no_clip() {
+ rstack[++rstackptr] = 0;
+ fl_restore_clip();
+}
+
+// pop back to previous clip:
+void fl_pop_clip() {
+ Region oldr = rstack[rstackptr--];
+ if (oldr) XDestroyRegion(oldr);
+ fl_restore_clip();
+}
+
+// does this rectangle intersect current clip?
+int fl_not_clipped(int x, int y, int w, int h) {
+ Region r = rstack[rstackptr];
+ return r ? XRectInRegion(r, x, y, w, h) : 1;
+}
+
+// return rectangle surrounding intersection of this rectangle and clip:
+int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
+ X = x; Y = y; W = w; H = h;
+ Region r = rstack[rstackptr];
+ if (!r) return 0;
+ switch (XRectInRegion(r, x, y, w, h)) {
+ case 0: // completely outside
+ W = H = 0;
+ return 2;
+ case 1: // completely inside:
+ return 0;
+ default: // partial:
+ break;
+ }
+ Region rr = XRectangleRegion(x,y,w,h);
+ Region temp = XCreateRegion();
+ XIntersectRegion(r, rr, temp);
+ XRectangle rect;
+ XClipBox(temp, &rect);
+ X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
+ XDestroyRegion(temp);
+ XDestroyRegion(rr);
+ return 1;
+}
+
+#endif
+
+// end of fl_rect.C
diff --git a/src/fl_round_box.cxx b/src/fl_round_box.cxx
new file mode 100644
index 000000000..c165e22ec
--- /dev/null
+++ b/src/fl_round_box.cxx
@@ -0,0 +1,94 @@
+/* fl_round_box.C
+
+ Box drawing code for an obscure box type.
+ These box types are in seperate files so they are not linked
+ in if not used.
+
+ 3/8/99: Complete rewrite to use XDrawArc
+*/
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+// A compiler from a certain very large software company will not compile
+// the function pointer assignment due to the name conflict with fl_arc.
+// This function is to fix that:
+void fl_arc_i(int x,int y,int w,int h,double a1,double a2) {
+ fl_arc(x,y,w,h,a1,a2);
+}
+
+enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL};
+
+static void draw(int which, int x,int y,int w,int h, int inset, uchar color)
+{
+ if (inset*2 >= w) inset = (w-1)/2;
+ if (inset*2 >= h) inset = (h-1)/2;
+ x += inset;
+ y += inset;
+ w -= 2*inset;
+ h -= 2*inset;
+ int d = w <= h ? w : h;
+ if (d <= 1) return;
+ fl_color((Fl_Color)color);
+ void (*f)(int,int,int,int,double,double) =
+ (which==FILL) ? fl_pie : fl_arc_i;
+ if (which >= CLOSED) {
+ f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90);
+ f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270);
+ } else if (which == UPPER_LEFT) {
+ f(x+w-d, y, d, d, 45, w<=h ? 180 : 90);
+ f(x, y+h-d, d, d, w<=h ? 180 : 90, 225);
+ } else { // LOWER_RIGHT
+ f(x, y+h-d, d, d, 225, w<=h ? 360 : 270);
+ f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45);
+ }
+ if (which == FILL) {
+ if (w < h)
+ fl_rectf(x, y+d/2, w, h-(d&-2));
+ else if (w > h)
+ fl_rectf(x+d/2, y, w-(d&-2), h);
+ } else {
+ if (w < h) {
+ if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2, y+h-d/2);
+ if (which != LOWER_RIGHT) fl_yxline(x, y+d/2, y+h-d/2);
+ } else if (w > h) {
+ if (which != UPPER_LEFT) fl_xyline(x+d/2, y+h-1, x+w-d/2);
+ if (which != LOWER_RIGHT) fl_xyline(x+d/2, y, x+w-d/2);
+ }
+ }
+}
+
+extern uchar* Fl_Gray_Ramp;
+
+static void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) {
+ draw(FILL, x, y, w, h, 2, bgcolor);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['N']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['H']);
+ draw(UPPER_LEFT, x, y, w, h, 0, Fl_Gray_Ramp['N']);
+ draw(UPPER_LEFT, x, y, w, h, 1, Fl_Gray_Ramp['H']);
+ draw(LOWER_RIGHT, x, y, w, h, 0, Fl_Gray_Ramp['S']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['U']);
+ draw(LOWER_RIGHT, x, y, w, h, 1, Fl_Gray_Ramp['U']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['W']);
+ draw(CLOSED, x, y, w, h, 2, Fl_Gray_Ramp['A']);
+}
+
+static void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) {
+ draw(FILL, x, y, w, h, 2, bgcolor);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['H']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['N']);
+ draw(LOWER_RIGHT, x, y, w, h, 1, Fl_Gray_Ramp['H']);
+ draw(LOWER_RIGHT, x, y, w, h, 2, Fl_Gray_Ramp['N']);
+ draw(UPPER_LEFT, x, y, w, h, 2, Fl_Gray_Ramp['U']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['S']);
+ draw(UPPER_LEFT, x, y, w, h, 1, Fl_Gray_Ramp['W']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['U']);
+ draw(CLOSED, x, y, w, h, 0, Fl_Gray_Ramp['A']);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype define_FL_ROUND_UP_BOX() {
+ fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box);
+ fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box);
+ return _FL_ROUND_UP_BOX;
+}
diff --git a/src/fl_rounded_box.cxx b/src/fl_rounded_box.cxx
new file mode 100644
index 000000000..f670726c1
--- /dev/null
+++ b/src/fl_rounded_box.cxx
@@ -0,0 +1,75 @@
+/* fl_rounded_box.C
+
+ Less-used box types are in seperate files so they are not linked
+ in if not used.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+#define RN 5
+#define RS 15
+#define BW 3
+
+static double offset[RN] = { 0.0, 0.07612, 0.29289, 0.61732, 1.0};
+
+static void rbox(int fill, int x, int y, int w, int h) {
+ int i;
+ int rsx ,rsy, rs;
+ rsx = w*2/5; rsy = h*2/5;
+ if (rsx > rsy) rs = rsy; else rs = rsx;
+ if (rs > RS) rs = RS;
+ rsx = rs; rsy = rs;
+
+ if (fill) fl_begin_polygon(); else fl_begin_loop();
+ for (i=0; i<RN; i++)
+ fl_vertex(x + offset[RN-i-1]*rsx, y + offset[i] * rsy);
+ for (i=0; i<RN; i++)
+ fl_vertex(x + offset[i]*rsx, y + h-1 - offset[RN-i-1] * rsy);
+ for (i=0; i<RN; i++)
+ fl_vertex(x + w-1 - offset[RN-i-1]*rsx, y + h-1 - offset[i] * rsy);
+ for (i=0; i<RN; i++)
+ fl_vertex(x + w-1 - offset[i]*rsx, y + offset[RN-i-1] * rsy);
+ if (fill) fl_end_polygon(); else fl_end_loop();
+}
+
+static void fl_rflat_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c); rbox(1, x, y, w, h); rbox(0, x, y, w, h);
+}
+
+static void fl_rounded_frame(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c); rbox(0, x, y, w, h);
+}
+
+static void fl_rounded_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c); rbox(1, x, y, w, h);
+ fl_color(FL_BLACK); rbox(0, x, y, w, h);
+}
+
+static void fl_rshadow_box(int x, int y, int w, int h, Fl_Color c) {
+ // draw shadow:
+ fl_color(FL_DARK3);
+ rbox(1, x+BW, y+BW, w, h);
+ rbox(0, x+BW, y+BW, w, h);
+ // draw the box:
+ fl_rounded_box(x, y, w, h, c);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+
+Fl_Boxtype define_FL_ROUNDED_BOX() {
+ fl_internal_boxtype(_FL_ROUNDED_FRAME, fl_rounded_frame);
+ fl_internal_boxtype(_FL_ROUNDED_BOX, fl_rounded_box);
+ return _FL_ROUNDED_BOX;
+}
+
+Fl_Boxtype define_FL_RFLAT_BOX() {
+ fl_internal_boxtype(_FL_RFLAT_BOX, fl_rflat_box);
+ return _FL_RFLAT_BOX;
+}
+
+Fl_Boxtype define_FL_RSHADOW_BOX() {
+ fl_internal_boxtype(_FL_RSHADOW_BOX, fl_rshadow_box);
+ return _FL_RSHADOW_BOX;
+}
diff --git a/src/fl_scroll_area.cxx b/src/fl_scroll_area.cxx
new file mode 100644
index 000000000..2aecee7ad
--- /dev/null
+++ b/src/fl_scroll_area.cxx
@@ -0,0 +1,66 @@
+// fl_scroll_area.C
+
+// Drawing function to move the contents of a rectangle. This is passed
+// a "callback" which is called to draw rectangular areas that are moved
+// into the drawing area.
+
+#include <FL/x.H>
+
+// scroll a rectangle and redraw the newly exposed portions:
+void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
+ void (*draw_area)(void*, int,int,int,int), void* data)
+{
+ if (!dx && !dy) return;
+ if (dx <= -W || dx >= W || dy <= -H || dy >= H) {
+ // no intersection of old an new scroll
+ draw_area(data,X,Y,W,H);
+ return;
+ }
+ int src_x, src_w, dest_x, clip_x, clip_w;
+ if (dx > 0) {
+ src_x = X;
+ dest_x = X+dx;
+ src_w = W-dx;
+ clip_x = X;
+ clip_w = dx;
+ } else {
+ src_x = X-dx;
+ dest_x = X;
+ src_w = W+dx;
+ clip_x = X+src_w;
+ clip_w = W-src_w;
+ }
+ int src_y, src_h, dest_y, clip_y, clip_h;
+ if (dy > 0) {
+ src_y = Y;
+ dest_y = Y+dy;
+ src_h = H-dy;
+ clip_y = Y;
+ clip_h = dy;
+ } else {
+ src_y = Y-dy;
+ dest_y = Y;
+ src_h = H+dy;
+ clip_y = Y+src_h;
+ clip_h = H-src_h;
+ }
+#ifdef WIN32
+ BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY);
+ // NYI: need to redraw areas that the source of BitBlt was bad due to
+ // overlapped windows, probably similar to X version:
+#else
+ XCopyArea(fl_display, fl_window, fl_window, fl_gc,
+ src_x, src_y, src_w, src_h, dest_x, dest_y);
+ // we have to sync the display and get the GraphicsExpose events! (sigh)
+ for (;;) {
+ XEvent e; XWindowEvent(fl_display, fl_window, ExposureMask, &e);
+ if (e.type == NoExpose) break;
+ // otherwise assumme it is a GraphicsExpose event:
+ draw_area(data, e.xexpose.x, e.xexpose.y,
+ e.xexpose.width, e.xexpose.height);
+ if (!e.xgraphicsexpose.count) break;
+ }
+#endif
+ if (dx) draw_area(data, clip_x, dest_y, clip_w, src_h);
+ if (dy) draw_area(data, X, clip_y, W, clip_h);
+}
diff --git a/src/fl_set_font.cxx b/src/fl_set_font.cxx
new file mode 100644
index 000000000..2d166bf9f
--- /dev/null
+++ b/src/fl_set_font.cxx
@@ -0,0 +1,51 @@
+// fl_set_font.C
+
+// Add a font to the internal table.
+// Also see fl_set_fonts.C which adds all possible fonts.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include "Fl_Font.H"
+#include <stdlib.h>
+#include <string.h>
+
+static int table_size;
+
+void Fl::set_font(Fl_Font fnum, const char *name) {
+ if (fnum >= table_size) {
+ int i = table_size;
+ if (!i) { // don't realloc the built-in table
+ table_size = 2*FL_FREE_FONT;
+ i = FL_FREE_FONT;
+ Fl_Fontdesc *t = (Fl_Fontdesc*)malloc(table_size*sizeof(Fl_Fontdesc));
+ memcpy(t, fl_fonts, FL_FREE_FONT*sizeof(Fl_Fontdesc));
+ fl_fonts = t;
+ } else {
+ table_size = 2*table_size;
+ fl_fonts=(Fl_Fontdesc*)realloc(fl_fonts, table_size*sizeof(Fl_Fontdesc));
+ }
+ for (; i < table_size; i++) fl_fonts[i].name = 0;
+ }
+ Fl_Fontdesc *s = fl_fonts+fnum;
+ if (s->name) {
+ if (!strcmp(s->name, name)) {s->name = name; return;}
+#ifndef WIN32
+ if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist);
+#endif
+ for (Fl_XFont *f = s->first; f;) {
+#ifndef WIN32
+ if (f == fl_fixed_xfont) break;
+#endif
+ Fl_XFont *n = f->next; delete f; f = n;
+ }
+ s->first = 0;
+ }
+ s->name = name;
+#ifndef WIN32
+ s->xlist = 0;
+#endif
+ s->first = 0;
+}
+
+const char *Fl::get_font(Fl_Font fnum) {return fl_fonts[fnum].name;}
diff --git a/src/fl_set_fonts.cxx b/src/fl_set_fonts.cxx
new file mode 100644
index 000000000..e3834d32b
--- /dev/null
+++ b/src/fl_set_fonts.cxx
@@ -0,0 +1,300 @@
+// fl_set_fonts.C
+
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server. It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+#ifdef WIN32
+#include "fl_set_fonts_win32.C"
+#else
+
+// Standard X fonts are matched by a pattern that is always of
+// this form, and this pattern is put in the table:
+// "-*-family-weight-slant-width1-style-*-registry-encoding"
+
+// Non-standard font names (those not starting with '-') are matched
+// by a pattern of the form "prefix*suffix", where the '*' is where
+// fltk thinks the point size is, or by the actual font name if no
+// point size is found.
+
+// Fltk knows how to pull an "attribute" out of a font name, such as
+// bold or italic, by matching known x font field values. All words
+// that don't match a known attribute are combined into the "name"
+// of the font. Names are compared before attributes for sorting, this
+// makes the bold and plain version of a font come out next to each
+// other despite the poor X font naming scheme.
+
+// By default fl_set_fonts() only does iso8859-1 encoded fonts. You can
+// do all normal X fonts by passing "-*" or every possible font with "*".
+
+// Fl::set_font will take strings other than the ones this stores
+// and can identify any font on X that way. You may want to write your
+// own system of font management and not use this code.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include "Fl_Font.H"
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+// turn word N of a X font name into either some attribute bits
+// (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that
+// the word should be put into the name:
+
+static int attribute(int n, const char *p) {
+ // don't put blank things into name:
+ if (!*p || *p=='-' || *p=='*') return 0;
+ if (n == 3) { // weight
+ if (!strncmp(p,"normal",6) ||
+ !strncmp(p,"light",5) ||
+ !strncmp(p,"medium",6) ||
+ !strncmp(p,"book",4)) return 0;
+ if (!strncmp(p,"bold",4) || !strncmp(p,"demi",4)) return FL_BOLD;
+ } else if (n == 4) { // slant
+ if (*p == 'r') return 0;
+ if (*p == 'i' || *p == 'o') return FL_ITALIC;
+ } else if (n == 5) { // sWidth
+ if (!strncmp(p,"normal",6)) return 0;
+ }
+ return -1;
+}
+
+// return non-zero if the registry-encoding should be used:
+extern const char* fl_encoding;
+static int use_registry(const char *p) {
+ return *p && *p!='*' && strcmp(p,fl_encoding);
+}
+
+// turn a stored (with *'s) X font name into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+ const char* p = fl_fonts[fnum].name;
+ if (!p) return "";
+ static char *buffer; if (!buffer) buffer = new char[128];
+ char *o = buffer;
+
+ if (*p != '-') { // non-standard font, just replace * with spaces:
+ if (ap) {
+ int type = 0;
+ if (strstr(p,"bold")) type = FL_BOLD;
+ if (strstr(p,"ital")) type |= FL_ITALIC;
+ *ap = type;
+ }
+ for (;*p; p++) {
+ if (*p == '*' || *p == ' ' || *p == '-') {
+ do p++; while (*p == '*' || *p == ' ' || *p == '-');
+ if (!*p) break;
+ *o++ = ' ';
+ }
+ *o++ = *p;
+ }
+ *o = 0;
+ return buffer;
+ }
+
+ // get the family:
+ const char *x = fl_font_word(p,2); if (*x) x++; if (*x=='*') x++;
+ if (!*x) return p;
+ const char *e = fl_font_word(x,1);
+ strncpy(o,x,e-x); o += e-x;
+
+ // collect all the attribute words:
+ int type = 0;
+ for (int n = 3; n <= 6; n++) {
+ // get the next word:
+ if (*e) e++; x = e; e = fl_font_word(x,1);
+ int t = attribute(n,x);
+ if (t < 0) {*o++ = ' '; strncpy(o,x,e-x); o += e-x;}
+ else type |= t;
+ }
+
+ // skip over the '*' for the size and get the registry-encoding:
+ x = fl_font_word(e,2);
+ if (*x) {x++; *o++ = '('; while (*x) *o++ = *x++; *o++ = ')';}
+
+ *o = 0;
+ if (ap) *ap = type;
+
+ return buffer;
+}
+
+// sort raw (non-'*') X font names into perfect order:
+
+static int ultrasort(const void *aa, const void *bb) {
+ const char *a = *(char **)aa;
+ const char *b = *(char **)bb;
+
+ // sort all non x-fonts at the end:
+ if (*a != '-') {
+ if (*b == '-') return 1;
+ // 2 non-x fonts are matched by "numeric sort"
+ int ret = 0;
+ for (;;) {
+ if (isdigit(*a) && isdigit(*b)) {
+ int na = strtol(a, (char **)&a, 10);
+ int nb = strtol(b, (char **)&b, 10);
+ if (!ret) ret = na-nb;
+ } else if (*a != *b) {
+ return (*a-*b);
+ } else if (!*a) {
+ return ret;
+ } else {
+ a++; b++;
+ }
+ }
+ } else {
+ if (*b != '-') return -1;
+ }
+
+ // skip the foundry (assumme equal):
+ for (a++; *a && *a++!='-';);
+ for (b++; *b && *b++!='-';);
+
+ // compare the family and all the attribute words:
+ int atype = 0;
+ int btype = 0;
+ for (int n = 2; n <= 6; n++) {
+ int at = attribute(n,a);
+ int bt = attribute(n,b);
+ if (at < 0) {
+ if (bt >= 0) return 1;
+ for (;;) {if (*a!=*b) return *a-*b; b++; if (!*a || *a++=='-') break;}
+ } else {
+ if (bt < 0) return -1;
+ a = fl_font_word(a,1); if (*a) a++;
+ b = fl_font_word(b,1); if (*b) b++;
+ atype |= at; btype |= bt;
+ }
+ }
+
+ // remember the pixel size:
+ int asize = atoi(a);
+ int bsize = atoi(b);
+
+ // compare the registry/encoding:
+ a = fl_font_word(a,6); if (*a) a++;
+ b = fl_font_word(b,6); if (*b) b++;
+ if (use_registry(a)) {
+ if (!use_registry(b)) return 1;
+ int r = strcmp(a,b); if (r) return r;
+ } else {
+ if (use_registry(b)) return -1;
+ }
+
+ if (atype != btype) return atype-btype;
+ if (asize != bsize) return asize-bsize;
+
+ // something wrong, just do a string compare...
+ return strcmp(*(char**)aa, *(char**)bb);
+}
+
+// converts a X font name to a standard starname, returns point size:
+static int to_canonical(char *to, const char *from) {
+ char* c = fl_find_fontsize((char*)from);
+ if (!c) return -1; // no point size found...
+ char* endptr;
+ int size = strtol(c,&endptr,10);
+ if (from[0] == '-') {
+ // replace the "foundry" with -*-:
+ *to++ = '-'; *to++ = '*';
+ for (from++; *from && *from != '-'; from++);
+ // skip to the registry-encoding:
+ endptr = (char*)fl_font_word(endptr,6);
+ if (*endptr && !use_registry(endptr+1)) endptr = "";
+ }
+ int n = c-from;
+ strncpy(to,from,n);
+ to[n++] = '*';
+ strcpy(to+n,endptr);
+ return size;
+}
+
+static int fl_free_font = FL_FREE_FONT;
+
+Fl_Font Fl::set_fonts(const char* xstarname) {
+ fl_open_display();
+ int xlistsize;
+ char buf[20];
+ if (!xstarname) {
+ strcpy(buf,"-*-"); strcpy(buf+3,fl_encoding);
+ xstarname = buf;
+ }
+ char **xlist = XListFonts(fl_display, xstarname, 10000, &xlistsize);
+ if (!xlist) return (Fl_Font)fl_free_font;
+ qsort(xlist, xlistsize, sizeof(*xlist), ultrasort);
+ int used_xlist = 0;
+ for (int i=0; i<xlistsize;) {
+ int first_xlist = i;
+ const char *p = xlist[i++];
+ char canon[1024];
+ int size = to_canonical(canon, p);
+ if (size >= 0) {
+ for (;;) { // find all matching fonts:
+ if (i >= xlistsize) break;
+ const char *q = xlist[i];
+ char this_canon[1024];
+ if (to_canonical(this_canon, q) < 0) break;
+ if (strcmp(canon, this_canon)) break;
+ i++;
+ }
+ /*if (*p=='-' || i > first_xlist+1)*/ p = canon;
+ }
+ int j;
+ for (j = 0;; j++) {
+ if (j < FL_FREE_FONT) {
+ // see if it is one of our built-in fonts:
+ // if so, set the list of x fonts, since we have it anyway
+ if (fl_fonts[j].name && !strcmp(fl_fonts[j].name, p)) break;
+ } else {
+ j = fl_free_font++;
+ if (p == canon) p = strdup(p); else used_xlist = 1;
+ Fl::set_font((Fl_Font)j, p);
+ break;
+ }
+ }
+ if (!fl_fonts[j].xlist) {
+ fl_fonts[j].xlist = xlist+first_xlist;
+ fl_fonts[j].n = -(i-first_xlist);
+ used_xlist = 1;
+ }
+ }
+ if (!used_xlist) XFreeFontNames(xlist);
+ return (Fl_Font)fl_free_font;
+}
+
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+ Fl_Fontdesc *s = fl_fonts+fnum;
+ if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+ if (!s->xlist) {
+ fl_open_display();
+ s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
+ if (!s->xlist) return 0;
+ }
+ int listsize = s->n; if (listsize<0) listsize = -listsize;
+ static int sizes[128];
+ int numsizes = 0;
+ for (int i = 0; i < listsize; i++) {
+ char *q = s->xlist[i];
+ char *d = fl_find_fontsize(q);
+ if (!d) continue;
+ int s = strtol(d,0,10);
+ if (!numsizes || sizes[numsizes-1] < s) {
+ sizes[numsizes++] = s;
+ } else {
+ // insert-sort the new size into list:
+ int n;
+ for (n = numsizes-1; n > 0; n--) if (sizes[n-1] < s) break;
+ if (sizes[n] != s) {
+ for (int m = numsizes; m > n; m--) sizes[m] = sizes[m-1];
+ sizes[n] = s;
+ numsizes++;
+ }
+ }
+ }
+ sizep = sizes;
+ return numsizes;
+}
+
+#endif
+// end of fl_set_fonts.C
diff --git a/src/fl_set_fonts_win32.cxx b/src/fl_set_fonts_win32.cxx
new file mode 100755
index 000000000..2a00363e9
--- /dev/null
+++ b/src/fl_set_fonts_win32.cxx
@@ -0,0 +1,58 @@
+// fl_set_fonts_win32.C
+
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server. It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+#include <FL/Fl.H>
+#include <FL/win32.H>
+#include "Fl_Font.H"
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+// turn a stored font name into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+ const char* p = fl_fonts[fnum].name;
+ if (!p || !*p) {if (ap) *ap = 0; return "";}
+ if (ap) switch (*p) {
+ case 'B': *ap = FL_BOLD; break;
+ case 'I': *ap = FL_ITALIC; break;
+ case 'P': *ap = FL_BOLD | FL_ITALIC; break;
+ default: *ap = 0; break;
+ }
+ return p+1;
+}
+
+static int fl_free_font = FL_FREE_FONT;
+
+static int CALLBACK enumcb(ENUMLOGFONT FAR *lpelf,
+ NEWTEXTMETRIC FAR *lpntm, int FontType, LPARAM p) {
+ if (!p && lpelf->elfLogFont.lfCharSet != ANSI_CHARSET) return 1;
+ char *n = (char*)(lpelf->elfFullName);
+ for (int i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts
+ if (!strcmp(Fl::get_font_name((Fl_Font)i),n)) return 1;
+ char buffer[128];
+ strcpy(buffer+1, n);
+ buffer[0] = ' '; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+ if (lpelf->elfLogFont.lfWeight <= 400)
+ buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+ buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+ if (lpelf->elfLogFont.lfWeight <= 400)
+ buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
+ return 1;
+}
+
+Fl_Font Fl::set_fonts(const char* xstarname) {
+ EnumFontFamilies(fl_gc, NULL, (FONTENUMPROC)enumcb, xstarname != 0);
+ return (Fl_Font)fl_free_font;
+}
+
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+ // pretend all fonts are scalable (most are and I don't know how
+ // to tell anyways)
+ static int array[1];
+ sizep = array;
+ return 1;
+}
diff --git a/src/fl_set_gray.cxx b/src/fl_set_gray.cxx
new file mode 100644
index 000000000..c3b869f47
--- /dev/null
+++ b/src/fl_set_gray.cxx
@@ -0,0 +1,35 @@
+// fl_set_gray.C
+
+// -fg, -bg, and -bg2 switches
+
+#include <FL/Fl.H>
+
+void Fl::background(uchar r, uchar g, uchar b) {
+ // replace the gray ramp so that color 47 is this color
+ int i;
+ for (i = 32; i <= 47; i++) {
+ int m = (i-32)*255/23;
+ Fl::set_color(i,r*m/166,g*m/166,b*m/166);
+ }
+ for (; i < 56; i++) {
+ int m = 255-(i-32)*255/23;
+ Fl::set_color(i,255-(255-r)*m/89,255-(255-g)*m/89,255-(255-b)*m/89);
+ }
+}
+
+static void set_others() {
+ uchar r,g,b; Fl::get_color(FL_BLACK,r,g,b);
+ uchar r1,g1,b1; Fl::get_color(FL_WHITE,r1,g1,b1);
+ Fl::set_color(FL_INACTIVE_COLOR,(2*r+r1)/3, (2*g+g1)/3, (2*b+b1)/3);
+ Fl::set_color(FL_SELECTION_COLOR,(2*r1+r)/3, (2*g1+g)/3, (2*b1+b)/3);
+}
+
+void Fl::foreground(uchar r, uchar g, uchar b) {
+ Fl::set_color(FL_BLACK,r,g,b);
+ set_others();
+}
+
+void Fl::background2(uchar r, uchar g, uchar b) {
+ Fl::set_color(FL_WHITE,r,g,b);
+ set_others();
+}
diff --git a/src/fl_shadow_box.cxx b/src/fl_shadow_box.cxx
new file mode 100644
index 000000000..d48b6ba96
--- /dev/null
+++ b/src/fl_shadow_box.cxx
@@ -0,0 +1,31 @@
+// fl_shadow_box.C
+
+// Box drawing code for an obscure box type.
+// These box types are in seperate files so they are not linked
+// in if not used.
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+#define BW 3
+
+static void fl_shadow_frame(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(FL_DARK3);
+ fl_rectf(x+BW, y+h, w, BW);
+ fl_rectf(x+w, y+BW, BW, h);
+ fl_color(c);
+ fl_rect(x,y,w,h);
+}
+
+static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c);
+ fl_rectf(x+1,y+1,w-2,h-2);
+ fl_shadow_frame(x,y,w,h,FL_GRAY0);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+Fl_Boxtype define_FL_SHADOW_BOX() {
+ fl_internal_boxtype(_FL_SHADOW_FRAME, fl_shadow_frame);
+ fl_internal_boxtype(_FL_SHADOW_BOX, fl_shadow_box);
+ return _FL_SHADOW_BOX;
+}
diff --git a/src/fl_shortcut.cxx b/src/fl_shortcut.cxx
new file mode 100644
index 000000000..b81853873
--- /dev/null
+++ b/src/fl_shortcut.cxx
@@ -0,0 +1,100 @@
+// fl_shortcut.C
+
+// Code to test and parse fltk shortcut numbers.
+
+// A shortcut is a keysym or'd with shift flags. In the simplest
+// sense a shortcut is matched if the shift state is exactly as
+// given and the key returning that keysym is pressed.
+
+// To make it easier to match some things it is more complex:
+
+// Only FL_META, FL_ALT, FL_SHIFT, and FL_CTRL must be "off". A
+// zero in the other shift flags indicates "dont care".
+
+// It also checks against the first character of Fl::event_text(),
+// and zero for FL_SHIFT means "don't care".
+// This allows punctuation shortcuts like "#" to work (rather than
+// calling it "shift+3")
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <ctype.h>
+#include <string.h>
+#ifndef WIN32
+#include <X11/Xlib.h>
+#endif
+
+int Fl::test_shortcut(int shortcut) {
+ if (!shortcut) return 0;
+
+ int shift = Fl::event_state();
+ // see if any required shift flags are off:
+ if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0;
+ // record shift flags that are wrong:
+ int mismatch = (shortcut^shift)&0x7fff0000;
+ // these three must always be correct:
+ if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0;
+
+ int key = shortcut & 0xffff;
+
+ // if shift is also correct, check for exactly equal keysyms:
+ if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1;
+
+ // try matching ascii, ignore shift:
+ if (key == event_text()[0]) return 1;
+
+ // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'):
+ if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F
+ && event_text()[0]==(key^0x40)) return 1;
+ return 0;
+}
+
+const char * fl_shortcut_label(int shortcut) {
+ static char buf[20];
+ char *p = buf;
+ if (!shortcut) {*p = 0; return buf;}
+ if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;}
+ if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;}
+ if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;}
+ if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;}
+ int key = shortcut & 0xFFFF;
+#ifdef WIN32
+ if (key >= FL_F && key <= FL_F_Last) {
+ *p++ = 'F';
+ if (key > FL_F+9) *p++ = (key-FL_F)/10+'0';
+ *p++ = (key-FL_F)%10 + '0';
+ } else {
+ if (key == FL_Enter || key == '\r') {strcpy(p,"Enter"); return buf;}
+ *p++ = uchar(key);
+ }
+ *p = 0;
+ return buf;
+#else
+ const char* q;
+ if (key == FL_Enter || key == '\r') q="Enter"; // don't use Xlib's "Return"
+ else if (key > 32 && key < 0x100) q = 0;
+ else q = XKeysymToString(key);
+ if (!q) {*p++ = uchar(key); *p = 0; return buf;}
+ if (p > buf) {strcpy(p,q); return buf;} else return q;
+#endif
+}
+
+// Tests for &x shortcuts in button labels:
+
+int Fl_Widget::test_shortcut(const char *label) {
+ char c = Fl::event_text()[0];
+ if (!c || !label) return 0;
+ for (;;) {
+ if (!*label) return 0;
+ if (*label++ == '&' && *label) {
+ if (*label == '&') label++;
+ else if (*label == c) return 1;
+ else return 0;
+ }
+ }
+}
+
+int Fl_Widget::test_shortcut() {
+ if (!(flags()&SHORTCUT_LABEL)) return 0;
+ return test_shortcut(label());
+}
diff --git a/src/fl_show_colormap.cxx b/src/fl_show_colormap.cxx
new file mode 100644
index 000000000..5e3b18c88
--- /dev/null
+++ b/src/fl_show_colormap.cxx
@@ -0,0 +1,124 @@
+// fl_show_colormap.C
+
+// Select a color from the colormap.
+// Pretty much unchanged from Forms.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_show_colormap.H>
+#include <config.h>
+
+#define BOXSIZE 14
+#define BORDER 4
+
+class ColorMenu : public Fl_Window {
+ Fl_Color initial;
+ Fl_Color which, previous;
+ int done;
+ void drawbox(Fl_Color);
+ void draw();
+ int handle(int);
+public:
+ ColorMenu(Fl_Color oldcol);
+ Fl_Color run();
+};
+
+ColorMenu::ColorMenu(Fl_Color oldcol) :
+ Fl_Window(BOXSIZE*8+1+2*BORDER, BOXSIZE*32+1+2*BORDER) {
+ clear_border();
+ set_modal();
+ initial = which = oldcol;
+}
+
+void ColorMenu::drawbox(Fl_Color c) {
+ if (c < 0 || c > 255) return;
+ int x = (c%8)*BOXSIZE+BORDER;
+ int y = (c/8)*BOXSIZE+BORDER;
+#if BORDER_WIDTH < 3
+ if (c == which) fl_draw_box(FL_DOWN_BOX, x+1, y+1, BOXSIZE-1, BOXSIZE-1, c);
+ else fl_draw_box(FL_BORDER_BOX, x, y, BOXSIZE+1, BOXSIZE+1, c);
+#else
+ fl_draw_box(c == which ? FL_DOWN_BOX : FL_BORDER_BOX,
+ x, y, BOXSIZE+1, BOXSIZE+1, c);
+#endif
+}
+
+void ColorMenu::draw() {
+ if (damage() != 1) {
+ fl_draw_box(FL_UP_BOX,0,0,w(),h(),color());
+ for (int c = 0; c < 256; c++) drawbox((Fl_Color)c);
+ } else {
+ drawbox(previous);
+ drawbox(which);
+ }
+ previous = which;
+}
+
+int ColorMenu::handle(int e) {
+ int c = which;
+ switch (e) {
+ case FL_PUSH:
+ case FL_DRAG: {
+ int X = (Fl::event_x_root() - x() - BORDER);
+ if (X >= 0) X = X/BOXSIZE;
+ int Y = (Fl::event_y_root() - y() - BORDER);
+ if (Y >= 0) Y = Y/BOXSIZE;
+ if (X >= 0 && X < 8 && Y >= 0 && Y < 32)
+ c = 8*Y + X;
+ else
+ c = initial;
+ } break;
+ case FL_RELEASE:
+ done = 1;
+ return 1;
+ case FL_KEYBOARD:
+ switch (Fl::event_key()) {
+ case FL_Up: if (c > 7) c -= 8; break;
+ case FL_Down: if (c < 256-8) c += 8; break;
+ case FL_Left: if (c > 0) c--; break;
+ case FL_Right: if (c < 255) c++; break;
+ case FL_Escape: which = initial; done = 1; return 1;
+ case FL_Enter: done = 1; return 1;
+ default: return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ if (c != which) {
+ which = (Fl_Color)c; damage(1);
+ int bx = (c%8)*BOXSIZE+BORDER;
+ int by = (c/8)*BOXSIZE+BORDER;
+ int px = x();
+ int py = y();
+ if (px+bx+BOXSIZE+BORDER >= Fl::w()) px = Fl::w()-bx-BOXSIZE-BORDER;
+ if (py+by+BOXSIZE+BORDER >= Fl::h()) py = Fl::h()-by-BOXSIZE-BORDER;
+ if (px+bx < BORDER) px = BORDER-bx;
+ if (py+by < BORDER) py = BORDER-by;
+ position(px,py);
+ }
+ return 1;
+}
+
+extern char fl_override_redirect; // hack for menus
+
+Fl_Color ColorMenu::run() {
+ if (which < 0 || which > 255) {
+ position(Fl::event_x_root()-w()/2, Fl::event_y_root()-y()/2);
+ } else {
+ position(Fl::event_x_root()-(initial%8)*BOXSIZE-BOXSIZE/2-BORDER,
+ Fl::event_y_root()-(initial/8)*BOXSIZE-BOXSIZE/2-BORDER);
+ }
+ Fl::grab(*this);
+ show();
+ done = 0;
+ while (!done) Fl::wait();
+ Fl::release();
+ return which;
+}
+
+Fl_Color fl_show_colormap(Fl_Color oldcol) {
+ ColorMenu m(oldcol);
+ return m.run();
+}
diff --git a/src/fl_symbols.cxx b/src/fl_symbols.cxx
new file mode 100644
index 000000000..df2f20926
--- /dev/null
+++ b/src/fl_symbols.cxx
@@ -0,0 +1,364 @@
+// fl_symbols.C
+
+// These are small graphics drawn by the normal label-drawing
+// code when the string starts with an '@' sign.
+
+// Adapted from original code written by:
+
+// Written by Mark Overmars
+// Version 2.1 a
+// Date: Oct 2, 1992
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <string.h>
+
+typedef struct {
+ const char *name;
+ void (*drawit)(Fl_Color);
+ char scalable;
+ char notempty;
+} SYMBOL;
+
+#define MAXSYMBOL 211
+ /* Maximal number of symbols in table. Only half of them are
+ used. Should be prime. */
+
+static SYMBOL symbols[MAXSYMBOL]; /* The symbols */
+static int symbnumb = -1; /* Their number */
+
+static int find(const char *name) {
+// returns hash entry if it exists, or first empty slot:
+ int pos = name[0] ? (
+ name[1] ? (
+ name[2] ? 71*name[0]+31*name[1]+name[2] : 31*name[0]+name[1]
+ ) :
+ name[0]
+ ) : 0;
+ pos %= MAXSYMBOL;
+ int hh2 = name[0] ? (
+ (name[1]) ? 51*name[0]+3*name[1] : 3*name[0]
+ ) : 1;
+ hh2 %= MAXSYMBOL; if (!hh2) hh2 = 1;
+ for (;;) {
+ if (!symbols[pos].notempty) return pos;
+ if (!strcmp(symbols[pos].name,name)) return pos;
+ pos = (pos + hh2) % MAXSYMBOL;
+ }
+}
+
+static void fl_init_symbols(void);
+
+/**************** The routines seen by the user *************************/
+
+int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable)
+/* Adds a symbol to the system. Returns whether correct. */
+{
+ fl_init_symbols();
+ int pos;
+ if (symbnumb > MAXSYMBOL / 2) return 0; // table is full
+ pos = find(name);
+ symbols[pos].name = name;
+ symbols[pos].drawit = drawit;
+ symbols[pos].notempty = 1;
+ symbols[pos].scalable = scalable;
+ symbnumb++;
+ return 1;
+}
+
+int fl_return_arrow(int x,int y,int w,int h);
+
+// provided for back compatability:
+int fl_draw_symbol(const char *label,int x,int y,int w,int h,Fl_Color col) {
+ const char *p = label;
+ if (*p++ != '@') return 0;
+ fl_init_symbols();
+ int equalscale = 0;
+ if (*p == '#') {equalscale = 1; p++;}
+ if (*p == '-' && p[1]>='1' && p[1]<='9') {
+ int n = p[1]-'0';
+ x += n; y += n; w -= 2*n; h -= 2*n;
+ p += 2;
+ } else if (*p == '+' && p[1]>='1' && p[1]<='9') {
+ int n = p[1]-'0';
+ x -= n; y -= n; w += 2*n; h += 2*n;
+ p += 2;
+ }
+ if (w < 10) {x -= (10-w)/2; w = 10;}
+ if (h < 10) {y -= (10-h)/2; h = 10;}
+ w = (w-1)|1; h = (h-1)|1;
+ int rotangle;
+ switch (*p++) {
+ case '0':
+ rotangle = 1000*(p[1]-'0') + 100*(p[2]-'0') + 10*(p[3]-'0');
+ p += 4;
+ break;
+ case '1': rotangle = 2250; break;
+ case '2': rotangle = 2700; break;
+ case '3': rotangle = 3150; break;
+ case '4': rotangle = 1800; break;
+ case '5':
+ case '6': rotangle = 0; break;
+ case '7': rotangle = 1350; break;
+ case '8': rotangle = 900; break;
+ case '9': rotangle = 450; break;
+ default: rotangle = 0; p--; break;
+ }
+ int pos = find(p);
+ if (!symbols[pos].notempty) return 0;
+ if (symbols[pos].scalable == 3) { // kludge to detect return arrow
+ fl_return_arrow(x,y,w,h);
+ return 1;
+ }
+ fl_push_matrix();
+ fl_translate(x+w/2,y+h/2);
+ if (symbols[pos].scalable) {
+ if (equalscale) {if (w<h) h = w; else w = h;}
+ fl_scale(0.5*w, 0.5*h);
+ fl_rotate(rotangle/10.0);
+ }
+ (symbols[pos].drawit)(col);
+ fl_pop_matrix();
+ return 1;
+}
+
+/******************** THE DEFAULT SYMBOLS ****************************/
+
+/* Some help stuff */
+
+#define BP fl_begin_polygon()
+#define EP fl_end_polygon()
+#define BL fl_begin_line()
+#define EL fl_end_line()
+#define BC fl_begin_loop()
+#define EC fl_end_loop()
+#define vv(x,y) fl_vertex(x,y)
+
+static void rectangle(double x,double y,double x2,double y2,Fl_Color c) {
+ fl_color(c);
+ BP; vv(x,y); vv(x2,y); vv(x2,y2); vv(x,y2); EP;
+ fl_color(FL_BLACK);
+ BC; vv(x,y); vv(x2,y); vv(x2,y2); vv(x,y2); EC;
+}
+
+/* The drawing routines */
+
+static void draw_arrow1(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,-0.4); EP;
+ BP; vv(0.0,0.8); vv(0.8,0.0); vv(0.0,-0.8); vv(0.0,-0.4); vv(0.0,0.4); EP;
+ fl_color(FL_BLACK);
+ BC; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,0.8); vv(0.8,0.0);
+ vv(0.0,-0.8); vv(0.0,-0.4); EC;
+}
+
+static void draw_arrow1bar(Fl_Color col)
+{
+ draw_arrow1(col);
+ rectangle(.6,-.8,.9,.8,col);
+}
+
+static void draw_arrow2(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(-0.3,0.8); vv(0.50,0.0); vv(-0.3,-0.8); EP;
+ fl_color(FL_BLACK);
+ BC; vv(-0.3,0.8); vv(0.50,0.0); vv(-0.3,-0.8); EC;
+}
+
+static void draw_arrow3(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EP;
+ BP; vv(-0.7,0.8); vv(0.1,0.0); vv(-0.7,-0.8); EP;
+ fl_color(FL_BLACK);
+ BC; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EC;
+ BC; vv(-0.7,0.8); vv(0.1,0.0); vv(-0.7,-0.8); EC;
+}
+
+static void draw_arrowbar(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EP;
+ BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
+ fl_color(FL_BLACK);
+ BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
+ BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
+}
+
+static void draw_arrowbox(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
+ fl_color(FL_BLACK);
+ BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
+ BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
+}
+
+static void draw_bararrow(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EP;
+ BP; vv(-0.5,0.8); vv(-0.1,0.8); vv(-0.1,-0.8); vv(-0.5,-0.8); EP;
+ fl_color(FL_BLACK);
+ BC; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EC;
+ BC; vv(-0.5,0.8); vv(-0.1,0.8); vv(-0.1,-0.8); vv(-0.5,-0.8); EC;
+}
+
+static void draw_doublebar(Fl_Color col) {
+ rectangle(-0.6,-0.8,-.1,.8,col);
+ rectangle(.1,-0.8,.6,.8,col);
+}
+
+static void draw_arrow01(Fl_Color col)
+ { fl_rotate(180); draw_arrow1(col); }
+
+static void draw_arrow02(Fl_Color col)
+ { fl_rotate(180); draw_arrow2(col); }
+
+static void draw_arrow03(Fl_Color col)
+ { fl_rotate(180); draw_arrow3(col); }
+
+static void draw_0arrowbar(Fl_Color col)
+ { fl_rotate(180); draw_arrowbar(col); }
+
+static void draw_0arrowbox(Fl_Color col)
+ { fl_rotate(180); draw_arrowbox(col); }
+
+static void draw_0bararrow(Fl_Color col)
+ { fl_rotate(180); draw_bararrow(col); }
+
+static void draw_doublearrow(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(-0.35,-0.4); vv(-0.35,0.4); vv(0.35,0.4); vv(0.35,-0.4); EP;
+ BP; vv(0.15,0.8); vv(0.95,0.0); vv(0.15,-0.8); EP;
+ BP; vv(-0.15,0.8); vv(-0.95,0.0); vv(-0.15,-0.8); EP;
+ fl_color(FL_BLACK);
+ BC; vv(-0.15,0.4); vv(0.15,0.4); vv(0.15,0.8); vv(0.95,0.0);
+ vv(0.15,-0.8); vv(0.15,-0.4); vv(-0.15,-0.4); vv(-0.15,-0.8);
+ vv(-0.95,0.0); vv(-0.15,0.8); EC;
+}
+
+static void draw_arrow(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EP;
+ fl_color(FL_BLACK);
+ BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
+ BC; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EC;
+}
+
+#if 0
+static void fl_draw_returnarrow(Fl_Color col) {
+ fl_color(col);
+ fl_begin_polygon();
+ vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7);
+ fl_end_polygon();
+ fl_color(FL_BLACK);
+ fl_begin_loop(); vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7);fl_end_loop();
+ fl_begin_line(); vv(-0.1,0.0); vv(0.8,0.0); vv(0.8,-0.7); fl_end_line();
+}
+#endif
+
+static void draw_square(Fl_Color col)
+ { rectangle(-1,-1,1,1,col); }
+
+static void draw_circle(Fl_Color col) {
+ fl_color(col); BP; fl_circle(0,0,1); EP;
+ fl_color(FL_BLACK); BC; fl_circle(0,0,1); EC;
+}
+
+static void draw_line(Fl_Color col)
+ { fl_color(col); BL; vv(-1.0,0.0); vv(1.0,0.0); EL; }
+
+static void draw_plus(Fl_Color col)
+{
+ fl_color(col);
+ BP; vv(-0.9,-0.15); vv(-0.9,0.15); vv(0.9,0.15); vv(0.9,-0.15); EP;
+ BP; vv(-0.15,-0.9); vv(-0.15,0.9); vv(0.15,0.9); vv(0.15,-0.9); EP;
+ fl_color(FL_BLACK);
+ BC;
+ vv(-0.9,-0.15); vv(-0.9,0.15); vv(-0.15,0.15); vv(-0.15,0.9);
+ vv(0.15,0.9); vv(0.15,0.15); vv(0.9,0.15); vv(0.9,-0.15);
+ vv(0.15,-0.15); vv(0.15,-0.9); vv(-0.15,-0.9); vv(-0.15,-0.15);
+ EC;
+}
+
+static void draw_uparrow(Fl_Color) {
+ fl_color(FL_LIGHT3);
+ BL; vv(-.8,.8); vv(-.8,-.8); vv(.8,0); EL;
+ fl_color(FL_DARK3);
+ BL; vv(-.8,.8); vv(.8, 0); EL;
+}
+
+static void draw_downarrow(Fl_Color) {
+ fl_color(FL_DARK3);
+ BL; vv(-.8,.8); vv(-.8,-.8); vv(.8,0); EL;
+ fl_color(FL_LIGHT3);
+ BL; vv(-.8,.8); vv(.8, 0); EL;
+}
+
+static void draw_menu(Fl_Color col)
+{
+ rectangle(-0.65, 0.85, 0.65, -0.25, col);
+ rectangle(-0.65, -0.6, 0.65, -1.0, col);
+}
+
+static void fl_init_symbols(void) {
+ static char beenhere;
+ if (beenhere) return;
+ beenhere = 1;
+ symbnumb = 0;
+
+ fl_add_symbol("", draw_arrow1, 1);
+ fl_add_symbol("->", draw_arrow1, 1);
+ fl_add_symbol(">", draw_arrow2, 1);
+ fl_add_symbol(">>", draw_arrow3, 1);
+ fl_add_symbol(">|", draw_arrowbar, 1);
+ fl_add_symbol(">[]", draw_arrowbox, 1);
+ fl_add_symbol("|>", draw_bararrow, 1);
+ fl_add_symbol("<-", draw_arrow01, 1);
+ fl_add_symbol("<", draw_arrow02, 1);
+ fl_add_symbol("<<", draw_arrow03, 1);
+ fl_add_symbol("|<", draw_0arrowbar, 1);
+ fl_add_symbol("[]<", draw_0arrowbox, 1);
+ fl_add_symbol("<|", draw_0bararrow, 1);
+ fl_add_symbol("<->", draw_doublearrow, 1);
+ fl_add_symbol("-->", draw_arrow, 1);
+ fl_add_symbol("+", draw_plus, 1);
+ fl_add_symbol("->|", draw_arrow1bar, 1);
+ fl_add_symbol("arrow", draw_arrow, 1);
+ fl_add_symbol("returnarrow", 0, 3);
+ fl_add_symbol("square", draw_square, 1);
+ fl_add_symbol("circle", draw_circle, 1);
+ fl_add_symbol("line", draw_line, 1);
+ fl_add_symbol("plus", draw_plus, 1);
+ fl_add_symbol("menu", draw_menu, 1);
+ fl_add_symbol("UpArrow", draw_uparrow, 1);
+ fl_add_symbol("DnArrow", draw_downarrow, 1);
+ fl_add_symbol("||", draw_doublebar, 1);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Widget.H>
+
+// this is the labeltype function:
+extern void fl_normal_label(const Fl_Label*, int, int, int, int, Fl_Align);
+static void fl_symbol_label(
+ const Fl_Label* o, int x, int y, int w, int h, Fl_Align align)
+{
+ if (!fl_draw_symbol(o->value, x, y, w, h, (Fl_Color)o->color))
+ fl_normal_label(o, x, y, w, h, align);
+}
+
+Fl_Labeltype define_FL_SYMBOL_LABEL() {
+ Fl::set_labeltype(_FL_SYMBOL_LABEL, fl_symbol_label, 0);
+ return _FL_SYMBOL_LABEL;
+}
+
+void Fl::enable_symbols() {
+ Fl::set_labeltype(FL_NORMAL_LABEL, fl_symbol_label, 0);
+}
diff --git a/src/fl_vertex.cxx b/src/fl_vertex.cxx
new file mode 100644
index 000000000..cdf9b1df0
--- /dev/null
+++ b/src/fl_vertex.cxx
@@ -0,0 +1,200 @@
+// fl_vertex.C
+
+// Portable drawing code for drawing arbitrary shapes with
+// simple 2D transformations. See also fl_arc.C
+
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/math.h>
+#include <stdlib.h>
+
+struct matrix {double a, b, c, d, x, y;};
+
+static matrix m = {1, 0, 0, 1, 0, 0};
+
+static matrix stack[10];
+static int sptr = 0;
+
+void fl_push_matrix() {stack[sptr++] = m;}
+
+void fl_pop_matrix() {m = stack[--sptr];}
+
+void fl_mult_matrix(double a, double b, double c, double d, double x, double y) {
+ matrix o;
+ o.a = a*m.a + b*m.c;
+ o.b = a*m.b + b*m.d;
+ o.c = c*m.a + d*m.c;
+ o.d = c*m.b + d*m.d;
+ o.x = x*m.a + y*m.c + m.x;
+ o.y = x*m.b + y*m.d + m.y;
+ m = o;
+}
+
+void fl_scale(double x,double y) {fl_mult_matrix(x,0,0,y,0,0);}
+
+void fl_scale(double x) {fl_mult_matrix(x,0,0,x,0,0);}
+
+void fl_translate(double x,double y) {fl_mult_matrix(1,0,0,1,x,y);}
+
+void fl_rotate(double d) {
+ if (d) {
+ double s, c;
+ if (d == 0) {s = 0; c = 1;}
+ else if (d == 90) {s = 1; c = 0;}
+ else if (d == 180) {s = 0; c = -1;}
+ else if (d == 270 || d == -90) {s = -1; c = 0;}
+ else {s = sin(d*M_PI/180); c = cos(d*M_PI/180);}
+ fl_mult_matrix(c,-s,s,c,0,0);
+ }
+}
+
+static XPoint *p;
+// typedef what the x,y fields in a point are:
+#ifdef WIN32
+typedef int COORD_T;
+#else
+typedef short COORD_T;
+#endif
+
+static int p_size;
+static int n;
+static int what;
+enum {LINE, LOOP, POLYGON, POINT_};
+
+void fl_begin_points() {n = 0; what = POINT_;}
+
+void fl_begin_line() {n = 0; what = LINE;}
+
+void fl_begin_loop() {n = 0; what = LOOP;}
+
+void fl_begin_polygon() {n = 0; what = POLYGON;}
+
+double fl_transform_x(double x, double y) {return x*m.a + y*m.c + m.x;}
+
+double fl_transform_y(double x, double y) {return x*m.b + y*m.d + m.y;}
+
+double fl_transform_dx(double x, double y) {return x*m.a + y*m.c;}
+
+double fl_transform_dy(double x, double y) {return x*m.b + y*m.d;}
+
+static void fl_transformed_vertex(COORD_T x, COORD_T y) {
+ if (!n || x != p[n-1].x || y != p[n-1].y) {
+ if (n >= p_size) {
+ p_size = p ? 2*p_size : 16;
+ p = (XPoint *)realloc((void*)p, p_size*sizeof(*p));
+ }
+ p[n].x = x;
+ p[n].y = y;
+ n++;
+ }
+}
+
+void fl_transformed_vertex(double xf, double yf) {
+ fl_transformed_vertex(COORD_T(xf+.5), COORD_T(yf+.5));
+}
+
+void fl_vertex(double x,double y) {
+ fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y);
+}
+
+void fl_end_points() {
+#ifdef WIN32
+ for (int i=0; i<n; i++) SetPixel(fl_gc, p[i].x, p[i].y, fl_RGB());
+#else
+ if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0);
+#endif
+}
+
+void fl_end_line() {
+#ifdef WIN32
+ if (n>1) Polyline(fl_gc, p, n);
+#else
+ if (n>1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0);
+#endif
+}
+
+static void fixloop() { // remove equal points from closed path
+ while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--;
+}
+
+void fl_end_loop() {
+ fixloop();
+ if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y);
+ fl_end_line();
+}
+
+void fl_end_polygon() {
+ fixloop();
+#ifdef WIN32
+ if (n>2) {
+ SelectObject(fl_gc, fl_brush());
+ Polygon(fl_gc, p, n);
+ }
+#else
+ if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0);
+#endif
+}
+
+static int gap;
+#ifdef WIN32
+static int counts[20];
+static int numcount;
+#endif
+
+void fl_begin_complex_polygon() {
+ fl_begin_polygon();
+ gap = 0;
+#ifdef WIN32
+ numcount = 0;
+#endif
+}
+
+void fl_gap() {
+ while (n>gap+2 && p[n-1].x == p[gap].x && p[n-1].y == p[gap].y) n--;
+ if (n > gap+2) {
+ fl_transformed_vertex((COORD_T)p[gap].x, (COORD_T)p[gap].y);
+#ifdef WIN32
+ counts[numcount++] = n-gap;
+#endif
+ gap = n;
+ } else {
+ n = gap;
+ }
+}
+
+void fl_end_complex_polygon() {
+ fl_gap();
+#ifdef WIN32
+ if (n>2) {
+ SelectObject(fl_gc, fl_brush());
+ PolyPolygon(fl_gc, p, counts, numcount);
+ }
+#else
+ if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0);
+#endif
+}
+
+// shortcut the closed circles so they use XDrawArc:
+// warning: these do not draw rotated ellipses correctly!
+// See fl_arc.c for portable version.
+
+void fl_circle(double x, double y,double r) {
+ double xt = fl_transform_x(x,y);
+ double yt = fl_transform_y(x,y);
+ double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a));
+ double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d));
+ int llx = int(xt-rx+.5);
+ int w = int(xt+rx+.5)-llx;
+ int lly = int(yt-ry+.5);
+ int h = int(yt+ry+.5)-lly;
+#ifdef WIN32
+ if (what==POLYGON) {
+ SelectObject(fl_gc, fl_brush());
+ Pie(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0);
+ } else
+ Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0);
+#else
+ (what == POLYGON ? XFillArc : XDrawArc)
+ (fl_display, fl_window, fl_gc, llx, lly, w, h, 0, 360*64);
+#endif
+}
diff --git a/src/forms_bitmap.cxx b/src/forms_bitmap.cxx
new file mode 100644
index 000000000..1b0eae749
--- /dev/null
+++ b/src/forms_bitmap.cxx
@@ -0,0 +1,24 @@
+// forms_bitmap.C
+// Forms compatability widget to draw a bitmap
+
+#include <FL/forms.H>
+
+Fl_FormsBitmap::Fl_FormsBitmap(
+ Fl_Boxtype t, int x, int y, int w, int h, const char* l)
+: Fl_Widget(x, y, w, h, l) {
+ box(t);
+ b = 0;
+ color(FL_BLACK);
+ align(FL_ALIGN_BOTTOM);
+}
+
+void Fl_FormsBitmap::set(int W, int H, const uchar *bits) {
+ delete b;
+ bitmap(new Fl_Bitmap(bits, W, H));
+}
+
+void Fl_FormsBitmap::draw() {
+ draw_box(box(), selection_color());
+ if (b) {fl_color(color()); b->draw(x(), y(), w(), h());}
+ draw_label();
+}
diff --git a/src/forms_compatability.cxx b/src/forms_compatability.cxx
new file mode 100755
index 000000000..763269af6
--- /dev/null
+++ b/src/forms_compatability.cxx
@@ -0,0 +1,153 @@
+// forms.C
+
+// Forms library compatability functions.
+// Many more functions are defined as inlines in forms.h!
+
+#include <FL/forms.H>
+#include <stdlib.h>
+
+char fl_flip = 2;
+void fl_end_form() {
+ while (Fl_Group::current()) Fl_Group::current()->forms_end();
+}
+void Fl_Group::forms_end() {
+ // set the dimensions of a group to surround contents
+ if (children() && !w()) {
+ Fl_Widget*const* a = array();
+ Fl_Widget* o = *a++;
+ int rx = o->x();
+ int ry = o->y();
+ int rw = rx+o->w();
+ int rh = ry+o->h();
+ for (int i=children_-1; i--;) {
+ o = *a++;
+ if (o->x() < rx) rx = o->x();
+ if (o->y() < ry) ry = o->y();
+ if (o->x()+o->w() > rw) rw = o->x()+o->w();
+ if (o->y()+o->h() > rh) rh = o->y()+o->h();
+ }
+ x(rx);
+ y(ry);
+ w(rw-rx);
+ h(rh-ry);
+ }
+ // flip all the children's coordinate systems:
+ if (fl_flip) {
+ Fl_Widget* o = (type()>=FL_WINDOW) ? this : window();
+ int Y = o->h();
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ int newy = Y-o->y()-o->h();
+ o->y(newy);
+ }
+ }
+ end();
+}
+
+static int initargc;
+static char **initargv;
+
+void fl_initialize(int *argc, char **argv, const char *, FL_CMD_OPT *, int) {
+ initargc = *argc;
+ initargv = new char*[*argc+1];
+ int i,j;
+ for (i=0; i<=*argc; i++) initargv[i] = argv[i];
+ for (i=j=1; i<*argc; ) {
+ if (Fl::arg(*argc,argv,i));
+ else argv[j++] = argv[i++];
+ }
+ argv[j] = 0;
+ *argc = j;
+ if (fl_flip==2) fl_flip = 0;
+}
+
+char fl_modal_next; // set by fl_freeze_forms()
+
+void fl_show_form(Fl_Window *f,int place,int b,const char *n) {
+
+ Fl::enable_symbols();
+
+ f->label(n);
+ if (!b) f->clear_border();
+ if (fl_modal_next || b==FL_TRANSIENT) {f->set_modal(); fl_modal_next = 0;}
+
+ if (place & FL_PLACE_MOUSE) f->hotspot(f);
+
+ if (place & FL_PLACE_CENTER)
+ f->position((Fl::w()-f->w())/2, (Fl::h()-f->h())/2);
+
+ if (place & FL_PLACE_FULLSCREEN)
+ f->fullscreen();
+
+ if (place & (FL_PLACE_POSITION | FL_PLACE_GEOMETRY))
+ f->position(
+ (f->x() < 0) ? Fl::w()-f->w()+f->x()-1 : f->x(),
+ (f->y() < 0) ? Fl::h()-f->h()+f->y()-1 : f->y());
+
+// if (place & FL_PLACE_ASPECT) {
+// this is not yet implemented
+// it can be done by setting size_range().
+
+ if (place == FL_PLACE_FREE || place == FL_PLACE_SIZE)
+ f->free_position();
+
+ if (place == FL_PLACE_FREE || place & FL_FREE_SIZE)
+ if (!f->resizable()) f->resizable(f);
+
+ if (initargc) {f->show(initargc,initargv); initargc = 0;}
+ else f->show();
+}
+
+Fl_Widget *fl_do_forms(void) {
+ Fl_Widget *obj;
+ while (!(obj = Fl::readqueue())) if (!Fl::wait()) exit(0);
+ return obj;
+}
+
+Fl_Widget *fl_check_forms() {
+ Fl::check();
+ return Fl::readqueue();
+}
+
+void fl_set_graphics_mode(int /*r*/,int /*d*/) {}
+
+void Fl_FormsText::draw() {
+ draw_box();
+ align(align()|FL_ALIGN_INSIDE); // questionable method of compatability
+ draw_label();
+}
+
+// Create a forms button by selecting correct fltk subclass:
+
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Repeat_Button.H>
+
+Fl_Button *fl_add_button(uchar t,int x,int y,int w,int h,const char *l) {
+ Fl_Button *b;
+ switch (t) {
+ case FL_RETURN_BUTTON:
+ case FL_HIDDEN_RET_BUTTON:
+ b = new Fl_Return_Button(x,y,w,h,l);
+ break;
+ case FL_TOUCH_BUTTON:
+ b = new Fl_Repeat_Button(x,y,w,h,l);
+ break;
+ default:
+ b = new Fl_Button(x,y,w,h,l);
+ }
+ switch (t) {
+ case FL_TOGGLE_BUTTON:
+ case FL_RADIO_BUTTON:
+ b->type(t);
+ break;
+ case FL_HIDDEN_BUTTON:
+ case FL_HIDDEN_RET_BUTTON:
+ b->type(FL_HIDDEN_BUTTON);
+ break;
+ case FL_INOUT_BUTTON:
+ b->when(FL_WHEN_CHANGED);
+ break;
+ }
+ return b;
+}
diff --git a/src/forms_free.cxx b/src/forms_free.cxx
new file mode 100644
index 000000000..826211620
--- /dev/null
+++ b/src/forms_free.cxx
@@ -0,0 +1,50 @@
+// forms_free.C
+
+// Emulation of the Forms "free" widget.
+// This emulation allows the free demo to run, and has allowed
+// me to port several other programs, but it is in no way
+// complete.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Free.H>
+
+void Fl_Free::step(void *v) {
+ Fl_Free *f = (Fl_Free *)v;
+ f->handle(FL_STEP);
+ Fl::add_timeout(.01,step,v);
+}
+
+Fl_Free::Fl_Free(uchar t,int x,int y,int w,int h,const char *l,
+ FL_HANDLEPTR hdl) :
+Fl_Widget(x,y,w,h,l) {
+ type(t);
+ hfunc = hdl;
+ if (t == FL_SLEEPING_FREE) deactivate();
+ if (t == FL_CONTINUOUS_FREE || t == FL_ALL_FREE)
+ Fl::add_timeout(.01,step,this);
+}
+
+Fl_Free::~Fl_Free() {
+ Fl::remove_timeout(step,this);
+ hfunc(this,FL_FREEMEM,0,0,0);
+}
+
+void Fl_Free::draw() {hfunc(this,FL_DRAW,0,0,0);}
+
+int Fl_Free::handle(int e) {
+ char key = Fl::event_key();
+ switch (e) {
+ case FL_FOCUS:
+ if (type()!=FL_INPUT_FREE && type()!=FL_ALL_FREE) return 0;
+ break;
+ case FL_PUSH:
+ case FL_DRAG:
+ case FL_RELEASE:
+ key = 4-Fl::event_button();
+ break;
+ case FL_SHORTCUT:
+ return 0;
+ }
+ if (hfunc(this, e, float(Fl::event_x()), float(Fl::event_y()), key)) do_callback();
+ return 1;
+}
diff --git a/src/forms_fselect.cxx b/src/forms_fselect.cxx
new file mode 100644
index 000000000..077f69f32
--- /dev/null
+++ b/src/forms_fselect.cxx
@@ -0,0 +1,38 @@
+// fselect.C
+
+// Emulate the Forms file chooser using the fltk file chooser.
+
+#include <FL/forms.H>
+#include <string.h>
+
+static char fl_directory[1024];
+static const char *fl_pattern; // assummed passed value is static
+static char fl_filename[256];
+
+char* fl_show_file_selector(const char *message,const char *dir,
+ const char *pat,const char *fname) {
+ if (dir && dir[0]) strncpy(fl_directory,dir,1023);
+ if (pat && pat[0]) fl_pattern = pat;
+ if (fname && fname[0]) strncpy(fl_filename,fname,255);
+ char *p = fl_directory+strlen(fl_directory);
+ if (p > fl_directory && *(p-1)!='/'
+#ifdef WIN32
+ && *(p-1)!='\\' && *(p-1)!=':'
+#endif
+ ) *p++ = '/';
+ strcpy(p,fl_filename);
+ const char *q = fl_file_chooser(message,fl_pattern,fl_directory);
+ if (!q) return 0;
+ strcpy(fl_directory, q);
+ p = (char *)filename_name(fl_directory);
+ strcpy(fl_filename, p);
+ if (p > fl_directory+1) p--;
+ *p = 0;
+ return (char *)q;
+}
+
+char* fl_get_directory() {return fl_directory;}
+
+char* fl_get_pattern() {return (char *)fl_pattern;}
+
+char* fl_get_filename() {return fl_filename;}
diff --git a/src/forms_pixmap.cxx b/src/forms_pixmap.cxx
new file mode 100644
index 000000000..5263531ba
--- /dev/null
+++ b/src/forms_pixmap.cxx
@@ -0,0 +1,24 @@
+// forms_pixmap.C
+// Forms compatability widget to draw a pixmap
+
+#include <FL/forms.H>
+
+Fl_FormsPixmap::Fl_FormsPixmap(
+ Fl_Boxtype t, int x, int y, int w, int h, const char* l)
+: Fl_Widget(x, y, w, h, l) {
+ box(t);
+ b = 0;
+ color(FL_BLACK);
+ align(FL_ALIGN_BOTTOM);
+}
+
+void Fl_FormsPixmap::set(char*const* bits) {
+ delete b;
+ b = new Fl_Pixmap(bits);
+}
+
+void Fl_FormsPixmap::draw() {
+ draw_box(box(), selection_color());
+ if (b) {fl_color(color()); b->draw(x(), y(), w(), h());}
+ draw_label();
+}
diff --git a/src/forms_timer.cxx b/src/forms_timer.cxx
new file mode 100644
index 000000000..2b7694f80
--- /dev/null
+++ b/src/forms_timer.cxx
@@ -0,0 +1,127 @@
+// forms_timer.H
+
+// Emulate the Forms Timer object
+// You don't want to use this if you just want a timeout, call
+// Fl::add_timeout directly!
+
+#include <FL/Fl.H>
+#include <FL/Fl_Timer.H>
+#include <FL/fl_draw.H>
+#ifdef WIN32
+# include <sys/types.h>
+# include <sys/timeb.h>
+#else
+# include <sys/time.h>
+#endif
+#include <stdio.h>
+
+#define FL_TIMER_BLINKRATE 0.2
+
+void fl_gettime(long* sec, long* usec) {
+#ifdef WIN32
+ struct timeb tp;
+ ftime(&tp);
+ *sec = tp.time;
+ *usec = tp.millitm * 1000;
+#else
+ struct timeval tp;
+ struct timezone tzp;
+ gettimeofday(&tp, &tzp);
+ *sec = tp.tv_sec;
+ *usec = tp.tv_usec;
+#endif
+}
+
+void Fl_Timer::draw() {
+ int tt;
+ Fl_Color col;
+ char str[32];
+ if (!on || delay>0.0)
+ col = color();
+ else if ((int) (delay / FL_TIMER_BLINKRATE) % 2)
+ col = color();
+ else
+ col = selection_color();
+ draw_box(box(), col);
+ if (type() == FL_VALUE_TIMER && delay>0.0) {
+ double d = direction_ ? total-delay : delay;
+ if (d < 60.0)
+ sprintf(str, "%.1f", d);
+ else {
+ tt = (int) ((d+0.05) / 60.0);
+ sprintf(str, "%d:%04.1f", tt, d - 60.0 * tt);
+ }
+ fl_font(labelfont(), labelsize());
+ fl_color(labelcolor());
+ fl_draw(str, x(), y(), w(), h(), FL_ALIGN_CENTER);
+ } else
+ draw_label();
+}
+
+void Fl_Timer::stepcb(void* v) {
+ ((Fl_Timer*)v)->step();
+}
+
+void Fl_Timer::step() {
+ if (!on) return;
+ double lastdelay = delay;
+ long sec, usec; fl_gettime(&sec, &usec);
+ delay -= (double) (sec - lastsec) + (double) (usec - lastusec) / 1000000.0;
+ lastsec = sec; lastusec = usec;
+ if (lastdelay > 0.0 && delay <= 0.0) {
+ if (type() == FL_HIDDEN_TIMER) {
+ on = 0;
+ delay = 0;
+ } else {
+ redraw();
+ Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+ }
+ do_callback();
+ } else {
+ if (type() == FL_VALUE_TIMER) redraw();
+ Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+ }
+}
+
+int Fl_Timer::handle(int event) {
+ if (event == FL_RELEASE && delay <= 0) value(0.0);
+ return 0;
+}
+
+Fl_Timer::~Fl_Timer() {
+ Fl::remove_timeout(stepcb, this);
+}
+
+Fl_Timer::Fl_Timer(uchar t, int x, int y, int w, int h, const char* l)
+: Fl_Widget(x, y, w, h, l) {
+ box(FL_DOWN_BOX);
+ selection_color(FL_RED);
+ delay = 0;
+ on = 0;
+ direction_ = 0;
+ type(t);
+ if (t == FL_HIDDEN_TIMER) clear_visible();
+ if (t == FL_VALUE_TIMER) align(FL_ALIGN_LEFT);
+}
+
+void Fl_Timer::value(double d) {
+ delay = total = d;
+ on = (d > 0.0);
+ fl_gettime(&(lastsec), &(lastusec));
+ if (type() != FL_HIDDEN_TIMER) redraw();
+ Fl::remove_timeout(stepcb, this);
+ if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+}
+
+void Fl_Timer::suspended(char d) {
+ if (!d) {
+ if (on) return;
+ on = (delay > 0.0);
+ fl_gettime(&(lastsec), &(lastusec));
+ if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
+ } else {
+ if (!on) return;
+ on = 0;
+ Fl::remove_timeout(stepcb, this);
+ }
+}
diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx
new file mode 100644
index 000000000..574b50ced
--- /dev/null
+++ b/src/gl_draw.cxx
@@ -0,0 +1,121 @@
+// gl_draw.C
+
+// Functions from <FL/gl.h>
+// See also Fl_Gl_Window and gl_start.C
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/gl.h>
+#include <FL/x.H>
+#include "Fl_Gl_Choice.H"
+#include "Fl_Font.H"
+#include <string.h>
+
+// stuff from fl_draw.H:
+void fl_font(int fontid, int size);
+int fl_height(); // using "size" should work ok
+int fl_descent();
+void fl_measure(const char*, int& x, int& y);
+double fl_width(const char*);
+double fl_width(const char*, int n);
+double fl_width(uchar);
+unsigned long fl_xpixel(uchar i);
+
+void gl_font(int fontid, int size) {fl_font(fontid, size);}
+int gl_height() {return fl_height();}
+int gl_descent() {return fl_descent();}
+double gl_width(const char* s) {return fl_width(s);}
+double gl_width(const char* s, int n) {return fl_width(s,n);}
+double gl_width(uchar c) {return fl_width(c);}
+
+void gl_draw(const char* str, int n) {
+#ifdef WIN32
+ if (!fl_current_xfont->listbase) {
+ int base = fl_current_xfont->metr.tmFirstChar;
+ int size = fl_current_xfont->metr.tmLastChar-base+1;
+ HFONT oldFid = (HFONT)SelectObject(fl_gc, fl_current_xfont->fid);
+ fl_current_xfont->listbase = glGenLists(size)-base;
+ wglUseFontBitmaps(fl_gc, base, size, fl_current_xfont->listbase+base);
+ SelectObject(fl_gc, oldFid);
+ }
+#else
+ if (!fl_current_xfont->listbase) {
+ int base = fl_current_xfont->font->min_char_or_byte2;
+ int size = fl_current_xfont->font->max_char_or_byte2-base+1;
+// int base = 0; int size = 256;
+ fl_current_xfont->listbase = glGenLists(size)-base;
+ glXUseXFont(fl_current_xfont->font->fid, base, size,
+ fl_current_xfont->listbase+base);
+ }
+#endif
+ glListBase(fl_current_xfont->listbase);
+ glCallLists(n, GL_UNSIGNED_BYTE, str);
+}
+
+void gl_draw(const char* str, int n, int x, int y) {
+ glRasterPos2i(x, y);
+ gl_draw(str, n);
+}
+
+void gl_draw(const char* str) {
+ gl_draw(str, strlen(str));
+}
+
+void gl_draw(const char* str, int x, int y) {
+ gl_draw(str, strlen(str), x, y);
+}
+
+static void gl_draw_invert(const char* str, int n, int x, int y) {
+ glRasterPos2i(x, -y);
+ gl_draw(str, n);
+}
+
+void gl_draw(
+ const char* str, // the (multi-line) string
+ int x, int y, int w, int h, // bounding box
+ Fl_Align align) {
+ fl_draw(str, x, -y-h, w, h, align, gl_draw_invert);
+}
+
+void gl_measure(const char* str, int& x, int& y) {fl_measure(str,x,y);}
+
+void gl_rect(int x, int y, int w, int h) {
+ if (w < 0) {w = -w; x = x-w;}
+ if (h < 0) {h = -h; y = y-h;}
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(x+w-1, y+h-1);
+ glVertex2i(x+w-1, y);
+ glVertex2i(x, y);
+ glVertex2i(x, y+h-1);
+ glVertex2i(x+w, y+h-1);
+ glEnd();
+}
+
+#if HAVE_GL_OVERLAY
+extern uchar fl_overlay;
+#endif
+
+void gl_color(Fl_Color i) {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+ if (fl_overlay) {glIndexi(i ? i : FL_GRAY_RAMP); return;}
+#else
+ if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;}
+#endif
+#endif
+ uchar red, green, blue;
+ Fl::get_color(i, red, green, blue);
+ glColor3ub(red, green, blue);
+}
+
+void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
+ if (!ld) ld = w*d;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d);
+ glRasterPos2i(x,y);
+ glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
+}
+
+#endif
+
diff --git a/src/gl_start.cxx b/src/gl_start.cxx
new file mode 100644
index 000000000..255a78127
--- /dev/null
+++ b/src/gl_start.cxx
@@ -0,0 +1,98 @@
+// Code to switch current fltk drawing context in/out of GL "mode":
+
+// You MUST use gl_visual() to select the default visual before doing
+// show() of any windows. Mesa will crash if you try to use a visual
+// not returned by glxChooseVisual.
+
+// This does not work with Fl_Double_Window's! It will try to draw
+// into the front buffer. Depending on the system this will either
+// crash or do nothing (when pixmaps are being used as back buffer
+// and GL is being done by hardware), work correctly (when GL is done
+// with software, such as Mesa), or draw into the front buffer and
+// be erased when the buffers are swapped (when double buffer hardware
+// is being used)
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+#include "Fl_Gl_Choice.H"
+
+extern GLXContext fl_first_context; // in Fl_Gl_Choice.C
+extern int fl_clip_state_number; // in fl_rect.C
+
+static GLXContext context;
+static int clip_state_number;
+static int pw, ph;
+
+#ifdef WIN32
+static int default_mode;
+#endif
+
+Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.C
+
+void gl_start() {
+#ifdef WIN32
+ HDC hdc = fl_private_dc(Fl_Window::current(), default_mode,0);
+ if (!context) {
+ context = wglCreateContext(hdc);
+ if (!fl_first_context) fl_first_context = context;
+ else wglShareLists(fl_first_context, context);
+ }
+ wglMakeCurrent(hdc, context);
+#else
+ if (!context) {
+ context = glXCreateContext(fl_display, fl_visual, fl_first_context, 1);
+ if (!context) Fl::fatal("OpenGL does not support this visual");
+ if (!fl_first_context) fl_first_context = context;
+ }
+ glXMakeCurrent(fl_display, fl_window, context);
+ glXWaitX();
+#endif
+ if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
+ pw = Fl_Window::current()->w();
+ ph = Fl_Window::current()->h();
+ glLoadIdentity();
+ glViewport(0, 0, pw, ph);
+ glOrtho(0, pw, 0, ph, -1, 1);
+ glDrawBuffer(GL_FRONT);
+ }
+ if (clip_state_number != fl_clip_state_number) {
+ clip_state_number = fl_clip_state_number;
+ int x, y, w, h;
+ if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(),
+ x, y, w, h)) {
+ fl_clip_region(XRectangleRegion(x,y,w,h));
+ glScissor(x, Fl_Window::current()->h()-(y+h), w, h);
+ glEnable(GL_SCISSOR_TEST);
+ } else {
+ glDisable(GL_SCISSOR_TEST);
+ }
+ }
+}
+
+void gl_finish() {
+#ifdef WIN32
+ glFlush();
+#else
+ glXWaitGL();
+#endif
+}
+
+int Fl::gl_visual(int mode, int *alist) {
+#ifdef WIN32
+ default_mode = mode;
+#else
+ Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist);
+ if (!c) return 0;
+ fl_visual = c->vis;
+ fl_colormap = c->colormap;
+#endif
+ return 1;
+}
+
+#endif
diff --git a/src/glut_compatability.cxx b/src/glut_compatability.cxx
new file mode 100755
index 000000000..e5d93bdc5
--- /dev/null
+++ b/src/glut_compatability.cxx
@@ -0,0 +1,377 @@
+// glut.C
+
+// Emulation of Glut using fltk.
+
+// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996.
+// "This program is freely distributable without licensing fees and is
+// provided without guarantee or warrantee expressed or implied. This
+// program is -not- in the public domain."
+
+// Although I have copied the GLUT API, none of my code is based on
+// any Glut implementation details and is therefore covered by the LGPL.
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/glut.H>
+
+#define MAXWINDOWS 32
+static Fl_Glut_Window *windows[MAXWINDOWS+1];
+
+Fl_Glut_Window *glut_window;
+int glut_menu;
+void (*glut_menustate_function)(int);
+void (*glut_menustatus_function)(int,int,int);
+
+static void default_reshape(int w, int h) {glViewport(0,0,w,h);}
+
+void Fl_Glut_Window::make_current() {
+ glut_window = this;
+ if (shown()) Fl_Gl_Window::make_current();
+}
+
+static int indraw;
+void Fl_Glut_Window::draw() {
+ glut_window = this;
+ indraw = 1;
+ if (!valid()) {reshape(w(),h()); valid(1);}
+ display();
+ indraw = 0;
+}
+
+void glutSwapBuffers() {
+ if (!indraw) glut_window->swap_buffers();
+}
+
+void Fl_Glut_Window::draw_overlay() {
+ glut_window = this;
+ if (!valid()) {reshape(w(),h()); valid(1);}
+ overlaydisplay();
+}
+
+static void domenu(int, int, int);
+
+int Fl_Glut_Window::handle(int event) {
+ make_current();
+ int ex = Fl::event_x();
+ int ey = Fl::event_y();
+ int button;
+ switch (event) {
+
+ case FL_PUSH:
+ button = Fl::event_button()-1;
+ if (button<0) button = 0;
+ if (button>2) button = 2;
+ if (menu[button]) {domenu(menu[button],ex,ey); return 1;}
+ mouse_down |= 1<<button;
+ if (mouse) {mouse(button,GLUT_DOWN,ex,ey); return 1;}
+ if (motion) return 1;
+ break;
+
+ case FL_RELEASE:
+ for (button = 0; button < 3; button++) if (mouse_down & 1<<button) {
+ if (mouse) mouse(button,GLUT_UP,ex,ey);
+ }
+ mouse_down = 0;
+ return 1;
+
+ case FL_ENTER:
+ if (entry) {entry(GLUT_ENTERED); return 1;}
+ if (passivemotion) return 1;
+ break;
+
+ case FL_LEAVE:
+ if (entry) {entry(GLUT_LEFT); return 1;}
+ if (passivemotion) return 1;
+ break;
+
+ case FL_DRAG:
+ if (motion) {motion(ex, ey); return 1;}
+ break;
+
+ case FL_MOVE:
+ if (passivemotion) {passivemotion(ex, ey); return 1;}
+ break;
+
+ case FL_FOCUS:
+ if (keyboard || special) return 1;
+ break;
+
+ case FL_KEYBOARD:
+ if (Fl::event_text()[0]) {
+ if (keyboard) {keyboard(Fl::event_text()[0],ex,ey); return 1;}
+ break;
+ } else {
+ if (special) {
+ int i = Fl::event_key();
+ if (i >= FL_F && i < FL_F_Last) i = i-FL_F+1;
+ special(i,ex,ey);
+ return 1;
+ }
+ break;
+ }
+
+ case FL_HIDE:
+ if (visibility) visibility(GLUT_NOT_VISIBLE);
+ break;
+
+ case FL_SHOW:
+ if (visibility) visibility(GLUT_VISIBLE);
+ break;
+ }
+
+ return Fl_Gl_Window::handle(event);
+}
+
+static int glut_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
+
+void Fl_Glut_Window::_init() {
+ for (number=1; number<MAXWINDOWS; number++) if (!windows[number]) break;
+ windows[number] = this;
+ menu[0] = menu[1] = menu[2] = 0;
+ reshape = default_reshape;
+ keyboard = 0;
+ mouse = 0;
+ motion = 0;
+ passivemotion = 0;
+ entry = 0;
+ visibility = 0;
+ special = 0;
+ mouse_down = 0;
+ mode(glut_mode);
+}
+
+Fl_Glut_Window::Fl_Glut_Window(int w, int h, const char *t) :
+ Fl_Gl_Window(w,h,t) {_init();}
+
+Fl_Glut_Window::Fl_Glut_Window(int x,int y,int w,int h, const char *t) :
+ Fl_Gl_Window(x,y,w,h,t) {_init();}
+
+static int initargc;
+static char **initargv;
+
+void glutInit(int *argc, char **argv) {
+ initargc = *argc;
+ initargv = new char*[*argc+1];
+ int i,j;
+ for (i=0; i<=*argc; i++) initargv[i] = argv[i];
+ for (i=j=1; i<*argc; ) {
+ if (Fl::arg(*argc,argv,i));
+ else argv[j++] = argv[i++];
+ }
+ argv[j] = 0;
+ *argc = j;
+}
+
+void glutInitDisplayMode(unsigned int mode) {
+ glut_mode = mode;
+}
+
+void glutMainLoop() {Fl::run();}
+
+////////////////////////////////////////////////////////////////
+
+static int initx, inity, initw=300, inith=300, initpos;
+
+void glutInitWindowPosition(int x, int y) {
+ initx = x; inity = y; initpos = 1;
+}
+
+void glutInitWindowSize(int w, int h) {
+ initw = w; inith = h;
+}
+
+int glutCreateWindow(char *title) {
+ Fl_Glut_Window *W;
+ if (initpos) {
+ W = new Fl_Glut_Window(initx,inity,initw,inith,title);
+ initpos = 0;
+ } else {
+ W = new Fl_Glut_Window(initw,inith,title);
+ }
+ W->resizable(W);
+ if (initargc) {
+ W->show(initargc,initargv);
+ initargc = 0;
+ } else {
+ W->show();
+ }
+ W->make_current();
+ return W->number;
+}
+
+int glutCreateSubWindow(int win, int x, int y, int w, int h) {
+ Fl_Glut_Window *W = new Fl_Glut_Window(x,y,w,h,0);
+ windows[win]->add(W);
+ if (windows[win]->shown()) W->show();
+ W->make_current();
+ return W->number;
+}
+
+Fl_Glut_Window::~Fl_Glut_Window() {
+ if (glut_window == this) glut_window = 0;
+ windows[number] = 0;
+}
+
+void glutDestroyWindow(int win) {
+ // should destroy children!!!
+ delete windows[win];
+}
+
+void glutSetWindow(int win) {
+ windows[win]->make_current();
+}
+
+////////////////////////////////////////////////////////////////
+#include <FL/Fl_Menu_Item.H>
+
+struct menu {
+ void (*cb)(int);
+ Fl_Menu_Item *m;
+ int size;
+ int alloc;
+};
+
+#define MAXMENUS 32
+static menu menus[MAXMENUS+1];
+
+static void domenu(int n, int ex, int ey) {
+ glut_menu = n;
+ menu *m = &menus[n];
+ if (glut_menustate_function) glut_menustate_function(1);
+ if (glut_menustatus_function) glut_menustatus_function(1,ex,ey);
+ const Fl_Menu_Item* g = m->m->popup(Fl::event_x(), Fl::event_y(), 0);
+ if (g && g->callback_) ((void (*)(int))(g->callback_))(int(g->argument()));
+ if (glut_menustatus_function) glut_menustatus_function(0,ex,ey);
+ if (glut_menustate_function) glut_menustate_function(0);
+}
+
+int glutCreateMenu(void (*cb)(int)) {
+ int i;
+ for (i=1; i<MAXMENUS; i++) if (!menus[i].cb) break;
+ menu *m = &menus[i];
+ m->cb = cb;
+ return glut_menu = i;
+}
+
+void glutDestroyMenu(int n) {
+ menu *m = &menus[n];
+ delete[] m->m;
+ m->m = 0;
+ m->cb = 0;
+ m->size = m->alloc = 0;
+}
+
+static Fl_Menu_Item* additem(menu *m) {
+ if (m->size+1 >= m->alloc) {
+ m->alloc = m->size*2+10;
+ Fl_Menu_Item* nm = new Fl_Menu_Item[m->alloc];
+ for (int i=0; i<m->size; i++) nm[i] = m->m[i];
+ delete[] m->m;
+ m->m = nm;
+ }
+ int n = m->size++;
+ m->m[n+1].text = 0;
+ Fl_Menu_Item* i = &(m->m[n]);
+ i->shortcut_ = 0;
+ i->flags = 0;
+ i->labeltype_ = i->labelfont_ = i->labelsize_ = i->labelcolor_ = 0;
+ return i;
+}
+
+void glutAddMenuEntry(char *label, int value) {
+ menu *m = &menus[glut_menu];
+ Fl_Menu_Item* i = additem(m);
+ i->text = label;
+ i->callback_ = (Fl_Callback*)(m->cb);
+ i->user_data_ = (void *)value;
+}
+
+void glutAddSubMenu(char *label, int submenu) {
+ menu *m = &menus[glut_menu];
+ Fl_Menu_Item* i = additem(m);
+ i->text = label;
+ i->callback_ = 0;
+ i->user_data_ = (void *)(menus[submenu].m);
+ i->flags = FL_PUP_SUBMENU;
+}
+
+void glutChangeToMenuEntry(int item, char *label, int value) {
+ menu *m = &menus[glut_menu];
+ Fl_Menu_Item* i = &m->m[item-1];
+ i->text = label;
+ i->callback_ = (Fl_Callback*)(m->cb);
+ i->user_data_ = (void *)value;
+ i->flags = 0;
+}
+
+void glutChangeToSubMenu(int item, char *label, int submenu) {
+ menu *m = &menus[glut_menu];
+ Fl_Menu_Item* i = &m->m[item-1];
+ i->text = label;
+ i->callback_ = 0;
+ i->user_data_ = (void *)(menus[submenu].m);
+ i->flags = FL_PUP_SUBMENU;
+}
+
+void glutRemoveMenuItem(int item) {
+ menu *m = &menus[glut_menu];
+ if (item > m->size || item < 1) return;
+ for (int i = item-1; i <= m->size; i++) m->m[i] = m->m[i+1];
+ m->size--;
+}
+
+////////////////////////////////////////////////////////////////
+
+int glutGet(GLenum type) {
+ switch (type) {
+ case GLUT_RETURN_ZERO: return 0;
+ case GLUT_WINDOW_X: return glut_window->x();
+ case GLUT_WINDOW_Y: return glut_window->y();
+ case GLUT_WINDOW_WIDTH: return glut_window->w();
+ case GLUT_WINDOW_HEIGHT: return glut_window->h();
+ case GLUT_WINDOW_PARENT:
+ if (glut_window->parent())
+ return ((Fl_Glut_Window *)(glut_window->parent()))->number;
+ else
+ return 0;
+//case GLUT_WINDOW_NUM_CHILDREN:
+//case GLUT_WINDOW_CURSOR: return
+ case GLUT_SCREEN_WIDTH: return Fl::w();
+ case GLUT_SCREEN_HEIGHT: return Fl::h();
+//case GLUT_SCREEN_WIDTH_MM:
+//case GLUT_SCREEN_HEIGHT_MM:
+ case GLUT_MENU_NUM_ITEMS: return menus[glut_menu].size;
+ case GLUT_DISPLAY_MODE_POSSIBLE: return Fl_Gl_Window::can_do(glut_mode);
+ case GLUT_INIT_WINDOW_X: return initx;
+ case GLUT_INIT_WINDOW_Y: return inity;
+ case GLUT_INIT_WINDOW_WIDTH: return initw;
+ case GLUT_INIT_WINDOW_HEIGHT: return inith;
+ case GLUT_INIT_DISPLAY_MODE: return glut_mode;
+//case GLUT_ELAPSED_TIME:
+ case GLUT_WINDOW_BUFFER_SIZE:
+ if (glutGet(GLUT_WINDOW_RGBA))
+ return glutGet(GLUT_WINDOW_RED_SIZE)+
+ glutGet(GLUT_WINDOW_GREEN_SIZE)+
+ glutGet(GLUT_WINDOW_BLUE_SIZE)+
+ glutGet(GLUT_WINDOW_ALPHA_SIZE);
+ else
+ return glutGet(GLUT_WINDOW_COLORMAP_SIZE);
+ default: {GLint p; glGetIntegerv(type, &p); return p;}
+ }
+}
+
+int glutLayerGet(GLenum type) {
+ switch (type) {
+ case GLUT_OVERLAY_POSSIBLE: return glut_window->can_do_overlay();
+//case GLUT_LAYER_IN_USE:
+//case GLUT_HAS_OVERLAY:
+ case GLUT_TRANSPARENT_INDEX: return 0; // true for SGI
+ case GLUT_NORMAL_DAMAGED: return glut_window->damage();
+ case GLUT_OVERLAY_DAMAGED: return 1; // kind of works...
+ default: return 0;
+ }
+}
+
+#endif
+// End of glut.C
diff --git a/src/glut_font.cxx b/src/glut_font.cxx
new file mode 100644
index 000000000..751fd6f8c
--- /dev/null
+++ b/src/glut_font.cxx
@@ -0,0 +1,32 @@
+// glut_font.C
+
+// (sort of) emulation of Glut's bitmap drawing functions, using FL's
+// font stuff. Not all the fonts match!
+
+#include <config.h>
+#if HAVE_GL
+
+#include <FL/glut.H>
+#include <FL/gl.h>
+
+Glut_Bitmap_Font glutBitmap9By15 = {FL_SCREEN, 15};
+Glut_Bitmap_Font glutBitmap8By13 = {FL_SCREEN, 13};
+Glut_Bitmap_Font glutBitmapTimesRoman10 = {FL_TIMES, 10};
+Glut_Bitmap_Font glutBitmapTimesRoman24 = {FL_TIMES, 24};
+Glut_Bitmap_Font glutBitmapHelvetica10 = {FL_HELVETICA, 10};
+Glut_Bitmap_Font glutBitmapHelvetica12 = {FL_HELVETICA, 12};
+Glut_Bitmap_Font glutBitmapHelvetica18 = {FL_HELVETICA, 18};
+
+void glutBitmapCharacter(void *font, int character) {
+ gl_font(((Glut_Bitmap_Font *)font)->font,((Glut_Bitmap_Font *)font)->size);
+ char a[1]; a[0] = character;
+ gl_draw(a,1);
+}
+
+int glutBitmapWidth(int font, int character) {
+ gl_font(((Glut_Bitmap_Font *)font)->font,((Glut_Bitmap_Font *)font)->size);
+ return int(gl_width(character)+.5);
+}
+
+#endif
+
diff --git a/src/mediumarrow.h b/src/mediumarrow.h
new file mode 100644
index 000000000..8a1fe8cbc
--- /dev/null
+++ b/src/mediumarrow.h
@@ -0,0 +1,6 @@
+#define mediumarrow_width 16
+#define mediumarrow_height 16
+static unsigned char mediumarrow_bits[] = {
+ 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0xfc, 0x3f, 0x78, 0x00,
+ 0x70, 0x00, 0x60, 0x02, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0xfc, 0x3f,
+ 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x02};
diff --git a/src/ns.xbm b/src/ns.xbm
new file mode 100644
index 000000000..f1ea18e1b
--- /dev/null
+++ b/src/ns.xbm
@@ -0,0 +1,8 @@
+#define ns_width 16
+#define ns_height 16
+#define ns_x_hot 8
+#define ns_y_hot 8
+static unsigned char ns_bits[] = {
+ 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00};
diff --git a/src/ns_mask.xbm b/src/ns_mask.xbm
new file mode 100644
index 000000000..a69f261bb
--- /dev/null
+++ b/src/ns_mask.xbm
@@ -0,0 +1,8 @@
+#define ns_mask_width 16
+#define ns_mask_height 16
+#define ns_mask_x_hot 8
+#define ns_mask_y_hot 8
+static unsigned char ns_mask_bits[] = {
+ 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
+ 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
+ 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01};
diff --git a/src/numericsort.c b/src/numericsort.c
new file mode 100644
index 000000000..17149be6f
--- /dev/null
+++ b/src/numericsort.c
@@ -0,0 +1,53 @@
+/* My own scandir sorting function, useful for the film industry where
+ we have many files with numbers in their names: */
+
+#include <config.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <FL/filename.H>
+#else
+#if HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# define dirent direct
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+#endif
+
+int numericsort(const struct dirent **A, const struct dirent **B) {
+ const char* a = (*A)->d_name;
+ const char* b = (*B)->d_name;
+ int ret = 0;
+ for (;;) {
+ if (isdigit(*a) && isdigit(*b)) {
+ int zdiff,diff,magdiff;
+ zdiff = 0;
+ while (*a == '0') {a++; zdiff++;}
+ while (*b == '0') {b++; zdiff--;}
+ while (isdigit(*a) && *a == *b) {a++; b++;}
+ diff = (isdigit(*a) && isdigit(*b)) ? *a - *b : 0;
+ magdiff = 0;
+ while (isdigit(*a)) {magdiff++; a++;}
+ while (isdigit(*b)) {magdiff--; b++;}
+ if (ret);
+ else if (magdiff) ret = magdiff;
+ else if (diff) ret = diff;
+ else if (zdiff) ret = zdiff;
+ } else if (*a == *b) {
+ if (!*a) return ret;
+ a++; b++;
+ } else
+ return (*a-*b);
+ }
+}
diff --git a/src/scandir.c b/src/scandir.c
new file mode 100644
index 000000000..e3b60bedf
--- /dev/null
+++ b/src/scandir.c
@@ -0,0 +1,128 @@
+/* Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+USA. */
+
+#ifdef WIN32
+#include "scandir_win32.c"
+#else
+
+#include <config.h>
+
+#if HAVE_SCANDIR
+#else
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+int
+scandir (const char *dir, struct dirent ***namelist,
+ int (*select)(const struct dirent *),
+ int (*compar)(const struct dirent **, const struct dirent **))
+{
+ DIR *dp = opendir (dir);
+ struct dirent **v = NULL;
+ size_t vsize = 0, i;
+ struct dirent *d;
+ int save;
+
+ if (dp == NULL)
+ return -1;
+
+ save = errno;
+ errno = 0;
+
+ i = 0;
+ while ((d = readdir (dp)) != NULL)
+ if (select == NULL || (*select) (d))
+ {
+ size_t dsize;
+
+ if (i == vsize)
+ {
+ struct dirent **new;
+ if (vsize == 0)
+ vsize = 10;
+ else
+ vsize *= 2;
+ new = (struct dirent **) realloc (v, vsize * sizeof (*v));
+ if (new == NULL)
+ {
+ lose:
+ errno = ENOMEM;
+ break;
+ }
+ v = new;
+ }
+
+#define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name))
+#define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \
+ _D_EXACT_NAMLEN (d) + 1)
+
+ dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
+ v[i] = (struct dirent *) malloc (dsize);
+ if (v[i] == NULL)
+ goto lose;
+
+ memcpy (v[i++], d, dsize);
+ }
+
+ if (errno != 0)
+ {
+ save = errno;
+ (void) closedir (dp);
+ while (i > 0)
+ free (v[--i]);
+ free (v);
+ errno = save;
+ return -1;
+ }
+
+ (void) closedir (dp);
+ errno = save;
+
+ /* Sort the list if we have a comparison function to sort with. */
+ if (compar) qsort (v, i, sizeof (*v), compar);
+ *namelist = v;
+ return i;
+}
+
+int alphasort (const struct dirent **a, const struct dirent **b) {
+ return strcmp ((*a)->d_name, (*b)->d_name);
+}
+
+#endif
+#endif
diff --git a/src/scandir_win32.c b/src/scandir_win32.c
new file mode 100644
index 000000000..ea3d18723
--- /dev/null
+++ b/src/scandir_win32.c
@@ -0,0 +1,79 @@
+// scandir_win32.C
+
+// Emulation of posix scandir() call
+
+#include <config.h>
+#include <FL/filename.H>
+#include <string.h>
+#include <windows.h>
+
+int scandir(const char *dirname, struct dirent ***namelist,
+ int (*select)(const struct dirent *),
+ int (*compar)(const struct dirent **, const struct dirent **)) {
+
+ int len = strlen(dirname);
+ char *findIn = new char[len+5]; strcpy(findIn, dirname);
+ for (char *d = findIn; *d; d++) if (*d=='/') *d='\\';
+ if ((len==0)) { strcpy(findIn, ".\\*"); }
+ if ((len==1)&& (d[-1]=='.')) { strcpy(findIn, ".\\*"); }
+ if ((len>0) && (d[-1]=='\\')) { *d++ = '*'; *d = 0; }
+ if ((len>1) && (d[-1]=='.') && (d[-2]=='\\')) { d[-1] = '*'; }
+
+ WIN32_FIND_DATA find;
+ HANDLE h;
+ int nDir = 0, NDir = 0;
+ struct dirent **dir = 0, *selectDir;
+ /*
+ selectDir = (struct dirent*)new char[sizeof(dirent)+1];
+ strcpy(selectDir->d_name, ".");
+ dir[0] = selectDir;
+ selectDir = (struct dirent*)new char[sizeof(dirent)+2];
+ strcpy(selectDir->d_name, "..");
+ dir[1] = selectDir;
+ */
+ unsigned long ret;
+
+ if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE) {
+ ret = GetLastError();
+ if (ret != ERROR_NO_MORE_FILES) {
+ // TODO: return some error code
+ }
+ *namelist = dir;
+ return nDir;
+ }
+ do {
+ selectDir=(struct dirent*)new char[sizeof(dirent)+strlen(find.cFileName)];
+ strcpy(selectDir->d_name, find.cFileName);
+ if (!select || (*select)(selectDir)) {
+ if (nDir==NDir) {
+ struct dirent **tempDir = new struct dirent*[NDir+33];
+ if (NDir) memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
+ if (dir) delete dir;
+ dir = tempDir;
+ NDir += 32;
+ }
+ dir[nDir] = selectDir;
+ nDir++;
+ dir[nDir] = 0;
+ } else {
+ delete selectDir;
+ }
+ } while (FindNextFile(h, &find));
+ ret = GetLastError();
+ if (ret != ERROR_NO_MORE_FILES) {
+ // TODO: return some error code
+ }
+ FindClose(h);
+
+ delete findIn;
+
+ if (compar) qsort (dir, nDir, sizeof(*dir),
+ (int(*)(const void*, const void*))compar);
+
+ *namelist = dir;
+ return nDir;
+}
+
+int alphasort (const struct dirent **a, const struct dirent **b) {
+ return strcmp ((*a)->d_name, (*b)->d_name);
+}
diff --git a/src/slowarrow.h b/src/slowarrow.h
new file mode 100644
index 000000000..46a572c97
--- /dev/null
+++ b/src/slowarrow.h
@@ -0,0 +1,6 @@
+#define slowarrow_width 16
+#define slowarrow_height 16
+static unsigned char slowarrow_bits[] = {
+ 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x0f, 0x60, 0x00,
+ 0x60, 0x00, 0x40, 0x02, 0x40, 0x02, 0x00, 0x06, 0x00, 0x06, 0xf0, 0x0f,
+ 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02};
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 000000000..384a05103
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,51 @@
+ALL = adjuster arc ask bitmap boxtype browser button buttons checkers \
+ clock colbrowser color_chooser cube cursor curve demo doublebuffer \
+ file_chooser fonts forms fractals fullscreen gl_overlay glpuzzle \
+ hello iconize image input keyboard label list_visuals mandelbrot \
+ menubar message minimum navigation output overlay pixmap \
+ pixmap_browser radio resizebox scroll shape shiny subwindow \
+ symbols tabs tile valuators fast_slow resize pack inactive style
+
+all: ${ALL}
+
+include ../makeinclude
+
+${ALL} : ../lib/$(LIBNAME)
+
+.SUFFIXES : .C .c .o .do
+
+.C:
+ @echo $@:
+ @$(CXX) -I.. $(CXXFLAGS) $< -L../lib -lfltk ${LDLIBS} -o $@
+
+# Programs needing the OpenGL libraries:
+cube: cube.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} cube.C -L../lib -lfltk ${GLDLIBS} -o $@
+fullscreen: fullscreen.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} fullscreen.C -L../lib -lfltk ${GLDLIBS} -o $@
+fractals: fractals.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} fractals.C -L../lib -lfltk ${GLDLIBS} -o $@
+gl_overlay: gl_overlay.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} gl_overlay.C -L../lib -lfltk ${GLDLIBS} -o $@
+glpuzzle: glpuzzle.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} glpuzzle.C -L../lib -lfltk ${GLDLIBS} -o $@
+shape: shape.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} shape.C -L../lib -lfltk ${GLDLIBS} -o $@
+shiny: shiny.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} shiny.C -L../lib -lfltk ${GLDLIBS} -o $@
+
+# If you have libjpeg installed, you might want to try this test program:
+
+jpeg_image: jpeg_image.C
+ @echo $@:
+ @${CXX} -I.. ${CXXFLAGS} -I../../../local/jpeg-6b -L../../../local/jpeg-6b jpeg_image.C -L../lib -lfltk ${LDLIBS} -ljpeg -lXext -o $@
+
+clean:
+ -rm -f ${ALL} jpeg_image *~
diff --git a/test/README b/test/README
new file mode 100644
index 000000000..ee63859aa
--- /dev/null
+++ b/test/README
@@ -0,0 +1,32 @@
+This directory contains tests and demos of FL. In most cases you can
+learn a lot about how to program FL by looking at the source code.
+
+Type "make" to compile them all.
+
+The program "demo" is a graphical interface to run all the demos.
+(you may recognize this as a rewrite of an XForms program).
+
+Some of the more interesting programs:
+
+fractals: A GLUT program with FL controls added to it
+
+glpuzzle: A GLUT program with no modifications
+
+fullscreen: Demo of how to make your window toggle to fill screen
+
+list_visuals: necessary to debug X visual stuff
+
+mandelbrot: A true application, using panels built in Fluid
+
+menubar: Demo of how FL's menus work
+
+shiny: Demo of drawing FL's controls using OpenGL
+
+forms: An XForms program to demonstrate emulation
+
+colbrowser: Another XForms program that is actually useful
+
+The program "fl_image" can be compiled if you have the jpeg library.
+The makefile assummes that the jpeg distribution resides in
+../../jpeg-6a/. Perhaps edit the Makefile to fix this, and type
+"make fl_image" to make this jpeg file viewer.
diff --git a/test/adjuster.cxx b/test/adjuster.cxx
new file mode 100644
index 000000000..68e4c5d7d
--- /dev/null
+++ b/test/adjuster.cxx
@@ -0,0 +1,37 @@
+/* Test the adjuster */
+
+#include <stdlib.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Adjuster.H>
+#include <FL/Fl_Box.H>
+
+void adjcb(Fl_Widget *o, void *v) {
+ Fl_Adjuster *a = (Fl_Adjuster*)o;
+ Fl_Box *b = (Fl_Box *)v;
+ a->format((char *)(b->label()));
+ b->redraw();
+}
+
+int main(int, char ** argv) {
+ Fl_Window window(320,100,argv[0]);
+
+ char buf1[100];
+ Fl_Box b1(FL_DOWN_BOX,20,30,80,25,buf1);
+ b1.color(FL_WHITE);
+ Fl_Adjuster a1(20+80,30,3*25,25);
+ a1.callback(adjcb,&b1);
+ adjcb(&a1,&b1);
+
+ char buf2[100];
+ Fl_Box b2(FL_DOWN_BOX,20+80+4*25,30,80,25,buf2);
+ b2.color(FL_WHITE);
+ Fl_Adjuster a2(b2.x()+b2.w(),10,25,3*25);
+ a2.callback(adjcb,&b2);
+ adjcb(&a2,&b2);
+
+ window.resizable(window);
+ window.end();
+ window.show();
+ return Fl::run();
+}
diff --git a/test/arc.cxx b/test/arc.cxx
new file mode 100755
index 000000000..1c574cde5
--- /dev/null
+++ b/test/arc.cxx
@@ -0,0 +1,70 @@
+// Test fl_arc
+
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Hor_Value_Slider.H>
+#include <FL/fl_draw.H>
+
+double args[6] = {140, 140, 50, 0, 360, 0};
+const char* name[6] = {"X", "Y", "R", "start", "end", "rotate"};
+
+class Drawing : public Fl_Widget {
+ void draw() {
+ fl_clip(x(),y(),w(),h());
+ fl_color(FL_DARK3);
+ fl_rectf(x(),y(),w(),h());
+ fl_push_matrix();
+ if (args[5]) {
+ fl_translate(x()+w()/2.0, y()+h()/2.0);
+ fl_rotate(args[5]);
+ fl_translate(-(x()+w()/2.0), -(y()+h()/2.0));
+ }
+ fl_color(FL_WHITE);
+ fl_translate(x(),y());
+ fl_begin_complex_polygon();
+ fl_arc(args[0],args[1],args[2],args[3],args[4]);
+ fl_gap();
+ fl_arc(140,140,20,0,-360);
+ fl_end_complex_polygon();
+ fl_color(FL_RED);
+ fl_begin_line();
+ fl_arc(args[0],args[1],args[2],args[3],args[4]);
+ fl_end_line();
+ fl_pop_matrix();
+ fl_pop_clip();
+ }
+public:
+ Drawing(int X,int Y,int W,int H) : Fl_Widget(X,Y,W,H) {}
+};
+
+Drawing *d;
+
+void slider_cb(Fl_Widget* o, void* v) {
+ Fl_Slider* s = (Fl_Slider*)o;
+ args[long(v)] = s->value();
+ d->redraw();
+}
+
+int main(int argc, char** argv) {
+ Fl_Double_Window window(300,500);
+ Drawing drawing(10,10,280,280);
+ d = &drawing;
+
+ int y = 300;
+ for (int n = 0; n<6; n++) {
+ Fl_Slider* s = new Fl_Hor_Value_Slider(50,y,240,25,name[n]); y += 25;
+ if (n<3) {s->minimum(0); s->maximum(300);}
+ else if (n==5) {s->minimum(0); s->maximum(360);}
+ else {s->minimum(-360); s->maximum(360);}
+ s->step(1);
+ s->value(args[n]);
+ s->align(FL_ALIGN_LEFT);
+ s->callback(slider_cb, (void*)n);
+ }
+
+ window.end();
+ window.show(argc,argv);
+ return Fl::run();
+}
+
+
diff --git a/test/ask.cxx b/test/ask.cxx
new file mode 100644
index 000000000..304ae1d71
--- /dev/null
+++ b/test/ask.cxx
@@ -0,0 +1,90 @@
+/* ask.C
+
+ Demonstrates how to use readqueue to see if a button has been
+ pushed, and to see if a window has been closed, thus avoiding
+ the need to define callbacks.
+
+ This also demonstrates how to trap attempts by the user to
+ close the last window by overriding Fl::exit
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+
+int get_string(char*buffer) {
+ Fl_Window window(320,75);
+ Fl_Input input(60, 10, 250, 25, "Input:");
+ input.value(buffer);
+ Fl_Button cancel(60, 40, 80, 25, "cancel");
+ Fl_Return_Button ok(150, 40, 80, 25, "OK");
+ window.hotspot(&cancel); // you must position modal windows
+ window.end();
+ window.set_modal();
+ window.show();
+ for (;;) {
+ Fl::wait();
+ Fl_Widget *o;
+ while ((o = Fl::readqueue())) {
+ if (o == &ok) {
+ strcpy(buffer,input.value());
+ return 1;
+ } else if (o == &cancel || o == &window) {
+ return 0;
+ }
+ }
+ }
+}
+
+void rename_me(Fl_Widget*o) {
+ if (get_string((char*)(o->label()))) o->redraw();
+}
+
+#if 1
+#include <FL/fl_ask.H>
+#include <stdlib.h>
+
+void window_callback(Fl_Widget*, void*) {
+ if (!fl_ask("Are you sure you want to quit?")) return;
+ exit(0);
+}
+#endif
+
+int main(int argc, char **argv) {
+ char buffer[128] = "test text";
+
+#if 1
+// this is a test to make sure automatic destructors work. Pop up
+// the question dialog several times and make sure it don't crash.
+
+ Fl_Window window(200, 55);
+ Fl_Return_Button b(20, 10, 160, 35, buffer); b.callback(rename_me);
+ window.add(b);
+ window.resizable(&b);
+ window.show(argc, argv);
+
+// Also we test to see if the exit callback works:
+ window.callback(window_callback);
+
+ return Fl::run();
+
+#else
+// This is the demo as written in the documentation, it only creates
+// the popup window once:
+
+ if (get_string(buffer)) {
+ puts(buffer);
+ } else {
+ puts("cancel");
+ }
+ return 0;
+
+#endif
+
+}
+
diff --git a/test/bitmap.cxx b/test/bitmap.cxx
new file mode 100644
index 000000000..245397843
--- /dev/null
+++ b/test/bitmap.cxx
@@ -0,0 +1,114 @@
+// test how bitmap label type draws
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Bitmap.H>
+#include <stdio.h>
+
+#define sorceress_width 75
+#define sorceress_height 75
+static uchar sorceress_bits[] = {
+ 0xfc, 0x7e, 0x40, 0x20, 0x90, 0x00, 0x07, 0x80, 0x23, 0x00, 0x00, 0xc6,
+ 0xc1, 0x41, 0x98, 0xb8, 0x01, 0x07, 0x66, 0x00, 0x15, 0x9f, 0x03, 0x47,
+ 0x8c, 0xc6, 0xdc, 0x7b, 0xcc, 0x00, 0xb0, 0x71, 0x0e, 0x4d, 0x06, 0x66,
+ 0x73, 0x8e, 0x8f, 0x01, 0x18, 0xc4, 0x39, 0x4b, 0x02, 0x23, 0x0c, 0x04,
+ 0x1e, 0x03, 0x0c, 0x08, 0xc7, 0xef, 0x08, 0x30, 0x06, 0x07, 0x1c, 0x02,
+ 0x06, 0x30, 0x18, 0xae, 0xc8, 0x98, 0x3f, 0x78, 0x20, 0x06, 0x02, 0x20,
+ 0x60, 0xa0, 0xc4, 0x1d, 0xc0, 0xff, 0x41, 0x04, 0xfa, 0x63, 0x80, 0xa1,
+ 0xa4, 0x3d, 0x00, 0x84, 0xbf, 0x04, 0x0f, 0x06, 0xfc, 0xa1, 0x34, 0x6b,
+ 0x01, 0x1c, 0xc9, 0x05, 0x06, 0xc7, 0x06, 0xbe, 0x11, 0x1e, 0x43, 0x30,
+ 0x91, 0x05, 0xc3, 0x61, 0x02, 0x30, 0x1b, 0x30, 0xcc, 0x20, 0x11, 0x00,
+ 0xc1, 0x3c, 0x03, 0x20, 0x0a, 0x00, 0xe8, 0x60, 0x21, 0x00, 0x61, 0x1b,
+ 0xc1, 0x63, 0x08, 0xf0, 0xc6, 0xc7, 0x21, 0x03, 0xf8, 0x08, 0xe1, 0xcf,
+ 0x0a, 0xfc, 0x4d, 0x99, 0x43, 0x07, 0x3c, 0x0c, 0xf1, 0x9f, 0x0b, 0xfc,
+ 0x5b, 0x81, 0x47, 0x02, 0x16, 0x04, 0x31, 0x1c, 0x0b, 0x1f, 0x17, 0x89,
+ 0x4d, 0x06, 0x1a, 0x04, 0x31, 0x38, 0x02, 0x07, 0x56, 0x89, 0x49, 0x04,
+ 0x0b, 0x04, 0xb1, 0x72, 0x82, 0xa1, 0x54, 0x9a, 0x49, 0x04, 0x1d, 0x66,
+ 0x50, 0xe7, 0xc2, 0xf0, 0x54, 0x9a, 0x58, 0x04, 0x0d, 0x62, 0xc1, 0x1f,
+ 0x44, 0xfc, 0x51, 0x90, 0x90, 0x04, 0x86, 0x63, 0xe0, 0x74, 0x04, 0xef,
+ 0x31, 0x1a, 0x91, 0x00, 0x02, 0xe2, 0xc1, 0xfd, 0x84, 0xf9, 0x30, 0x0a,
+ 0x91, 0x00, 0x82, 0xa9, 0xc0, 0xb9, 0x84, 0xf9, 0x31, 0x16, 0x81, 0x00,
+ 0x42, 0xa9, 0xdb, 0x7f, 0x0c, 0xff, 0x1c, 0x16, 0x11, 0x00, 0x02, 0x28,
+ 0x0b, 0x07, 0x08, 0x60, 0x1c, 0x02, 0x91, 0x00, 0x46, 0x29, 0x0e, 0x00,
+ 0x00, 0x00, 0x10, 0x16, 0x11, 0x02, 0x06, 0x29, 0x04, 0x00, 0x00, 0x00,
+ 0x10, 0x16, 0x91, 0x06, 0xa6, 0x2a, 0x04, 0x00, 0x00, 0x00, 0x18, 0x24,
+ 0x91, 0x04, 0x86, 0x2a, 0x04, 0x00, 0x00, 0x00, 0x18, 0x27, 0x93, 0x04,
+ 0x96, 0x4a, 0x04, 0x00, 0x00, 0x00, 0x04, 0x02, 0x91, 0x04, 0x86, 0x4a,
+ 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x23, 0x93, 0x04, 0x56, 0x88, 0x08, 0x00,
+ 0x00, 0x00, 0x90, 0x21, 0x93, 0x04, 0x52, 0x0a, 0x09, 0x80, 0x01, 0x00,
+ 0xd0, 0x21, 0x95, 0x04, 0x57, 0x0a, 0x0f, 0x80, 0x27, 0x00, 0xd8, 0x20,
+ 0x9d, 0x04, 0x5d, 0x08, 0x1c, 0x80, 0x67, 0x00, 0xe4, 0x01, 0x85, 0x04,
+ 0x79, 0x8a, 0x3f, 0x00, 0x00, 0x00, 0xf4, 0x11, 0x85, 0x06, 0x39, 0x08,
+ 0x7d, 0x00, 0x00, 0x18, 0xb7, 0x10, 0x81, 0x03, 0x29, 0x12, 0xcb, 0x00,
+ 0x7e, 0x30, 0x28, 0x00, 0x85, 0x03, 0x29, 0x10, 0xbe, 0x81, 0xff, 0x27,
+ 0x0c, 0x10, 0x85, 0x03, 0x29, 0x32, 0xfa, 0xc1, 0xff, 0x27, 0x94, 0x11,
+ 0x85, 0x03, 0x28, 0x20, 0x6c, 0xe1, 0xff, 0x07, 0x0c, 0x01, 0x85, 0x01,
+ 0x28, 0x62, 0x5c, 0xe3, 0x8f, 0x03, 0x4e, 0x91, 0x80, 0x05, 0x39, 0x40,
+ 0xf4, 0xc2, 0xff, 0x00, 0x9f, 0x91, 0x84, 0x05, 0x31, 0xc6, 0xe8, 0x07,
+ 0x7f, 0x80, 0xcd, 0x00, 0xc4, 0x04, 0x31, 0x06, 0xc9, 0x0e, 0x00, 0xc0,
+ 0x48, 0x88, 0xe0, 0x04, 0x79, 0x04, 0xdb, 0x12, 0x00, 0x30, 0x0c, 0xc8,
+ 0xe4, 0x04, 0x6d, 0x06, 0xb6, 0x23, 0x00, 0x18, 0x1c, 0xc0, 0x84, 0x04,
+ 0x25, 0x0c, 0xff, 0xc2, 0x00, 0x4e, 0x06, 0xb0, 0x80, 0x04, 0x3f, 0x8a,
+ 0xb3, 0x83, 0xff, 0xc3, 0x03, 0x91, 0x84, 0x04, 0x2e, 0xd8, 0x0f, 0x3f,
+ 0x00, 0x00, 0x5f, 0x83, 0x84, 0x04, 0x2a, 0x70, 0xfd, 0x7f, 0x00, 0x00,
+ 0xc8, 0xc0, 0x84, 0x04, 0x4b, 0xe2, 0x2f, 0x01, 0x00, 0x08, 0x58, 0x60,
+ 0x80, 0x04, 0x5b, 0x82, 0xff, 0x01, 0x00, 0x08, 0xd0, 0xa0, 0x84, 0x04,
+ 0x72, 0x80, 0xe5, 0x00, 0x00, 0x08, 0xd2, 0x20, 0x44, 0x04, 0xca, 0x02,
+ 0xff, 0x00, 0x00, 0x08, 0xde, 0xa0, 0x44, 0x04, 0x82, 0x02, 0x6d, 0x00,
+ 0x00, 0x08, 0xf6, 0xb0, 0x40, 0x02, 0x82, 0x07, 0x3f, 0x00, 0x00, 0x08,
+ 0x44, 0x58, 0x44, 0x02, 0x93, 0x3f, 0x1f, 0x00, 0x00, 0x30, 0x88, 0x4f,
+ 0x44, 0x03, 0x83, 0x23, 0x3e, 0x00, 0x00, 0x00, 0x18, 0x60, 0xe0, 0x07,
+ 0xe3, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x70, 0x70, 0xe4, 0x07, 0xc7, 0x1b,
+ 0xfe, 0x01, 0x00, 0x00, 0xe0, 0x3c, 0xe4, 0x07, 0xc7, 0xe3, 0xfe, 0x1f,
+ 0x00, 0x00, 0xff, 0x1f, 0xfc, 0x07, 0xc7, 0x03, 0xf8, 0x33, 0x00, 0xc0,
+ 0xf0, 0x07, 0xff, 0x07, 0x87, 0x02, 0xfc, 0x43, 0x00, 0x60, 0xf0, 0xff,
+ 0xff, 0x07, 0x8f, 0x06, 0xbe, 0x87, 0x00, 0x30, 0xf8, 0xff, 0xff, 0x07,
+ 0x8f, 0x14, 0x9c, 0x8f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x07, 0x9f, 0x8d,
+ 0x8a, 0x0f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xbf, 0x0b, 0x80, 0x1f,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x7f, 0x3a, 0x80, 0x3f, 0x00, 0x80,
+ 0xff, 0xff, 0xff, 0x07, 0xff, 0x20, 0xc0, 0x3f, 0x00, 0x80, 0xff, 0xff,
+ 0xff, 0x07, 0xff, 0x01, 0xe0, 0x7f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x07,
+ 0xff, 0x0f, 0xf8, 0xff, 0x40, 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff,
+ 0xff, 0xff, 0x40, 0xf0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0xf0, 0xff, 0xff, 0xff, 0x07};
+
+Fl_Bitmap fl_bitmap(sorceress_bits, sorceress_width, sorceress_height);
+
+#include <FL/Fl_Toggle_Button.H>
+
+Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb;
+Fl_Button *b;
+Fl_Window *w;
+
+void button_cb(Fl_Widget *,void *) {
+ int i = 0;
+ if (leftb->value()) i |= FL_ALIGN_LEFT;
+ if (rightb->value()) i |= FL_ALIGN_RIGHT;
+ if (topb->value()) i |= FL_ALIGN_TOP;
+ if (bottomb->value()) i |= FL_ALIGN_BOTTOM;
+ if (insideb->value()) i |= FL_ALIGN_INSIDE;
+ b->align(i);
+ w->redraw();
+}
+
+int main(int argc, char **argv) {
+ Fl_Window window(400,400); ::w = &window;
+ Fl_Button b(140,160,120,120,0); ::b = &b;
+ //(new Fl_Bitmap(sorceress_bits,sorceress_width,sorceress_height))->label(&b);
+ fl_bitmap.label(&b);
+ leftb = new Fl_Toggle_Button(50,75,50,25,"left");
+ leftb->callback(button_cb);
+ rightb = new Fl_Toggle_Button(100,75,50,25,"right");
+ rightb->callback(button_cb);
+ topb = new Fl_Toggle_Button(150,75,50,25,"top");
+ topb->callback(button_cb);
+ bottomb = new Fl_Toggle_Button(200,75,50,25,"bottom");
+ bottomb->callback(button_cb);
+ insideb = new Fl_Toggle_Button(250,75,50,25,"inside");
+ insideb->callback(button_cb);
+ window.resizable(window);
+ window.end();
+ window.show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/black_1.xbm b/test/black_1.xbm
new file mode 100644
index 000000000..a9d800f98
--- /dev/null
+++ b/test/black_1.xbm
@@ -0,0 +1,60 @@
+#define black_1_width 56
+#define black_1_height 56
+static unsigned char black_1_bits[] = {
+0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00,
+0x00, 0xf8, 0xff, 0xff, 0x03, 0x00, 0x00,
+0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, 0x00,
+0x00, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00,
+0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
+0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x17, 0x00,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x2f, 0x00,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x00,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x00,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x05,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0xaf, 0x02,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x05,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0xaf, 0x02,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0x57, 0x01,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0xab, 0x02,
+0xf0, 0xff, 0xff, 0xff, 0xff, 0x55, 0x01,
+0xe0, 0xff, 0xff, 0xff, 0xff, 0xab, 0x00,
+0xc0, 0xff, 0xff, 0xff, 0xff, 0x55, 0x01,
+0x80, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00,
+0x00, 0xff, 0xff, 0xff, 0x5f, 0x55, 0x00,
+0x00, 0xfe, 0xff, 0xff, 0xaf, 0x2a, 0x00,
+0x00, 0xf4, 0xff, 0xff, 0x57, 0x15, 0x00,
+0x00, 0xe8, 0xff, 0xff, 0xaa, 0x0a, 0x00,
+0x00, 0x50, 0xff, 0x7f, 0x55, 0x05, 0x00,
+0x00, 0xa0, 0xaa, 0xaa, 0xaa, 0x02, 0x00,
+0x00, 0x40, 0x55, 0x55, 0x55, 0x01, 0x00,
+0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00,
+0x00, 0x00, 0x50, 0x55, 0x15, 0x00, 0x00,
+0x00, 0x00, 0x80, 0xaa, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/black_2.xbm b/test/black_2.xbm
new file mode 100644
index 000000000..b324fd124
--- /dev/null
+++ b/test/black_2.xbm
@@ -0,0 +1,60 @@
+#define black_2_width 56
+#define black_2_height 56
+static unsigned char black_2_bits[] = {
+0x00, 0x00, 0x0f, 0x3c, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x40, 0x81, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x49, 0x09, 0x02, 0x00, 0x00,
+0x00, 0x44, 0x52, 0x49, 0x08, 0x00, 0x00,
+0x00, 0x90, 0x52, 0x25, 0x01, 0x00, 0x00,
+0x80, 0x94, 0x54, 0x95, 0x44, 0x00, 0x00,
+0x40, 0x24, 0x01, 0x40, 0x92, 0x00, 0x00,
+0x20, 0x49, 0xfc, 0x0f, 0x09, 0x01, 0x00,
+0x00, 0x11, 0x57, 0x35, 0x64, 0x00, 0x00,
+0x40, 0xc2, 0x00, 0xc0, 0x10, 0x00, 0x00,
+0x88, 0x64, 0x55, 0x55, 0x89, 0x05, 0x00,
+0x20, 0x11, 0x00, 0x08, 0x42, 0x00, 0x00,
+0x44, 0x58, 0x55, 0x55, 0x21, 0x0b, 0x00,
+0x90, 0x04, 0x80, 0x0a, 0x80, 0x00, 0x00,
+0x22, 0x56, 0x55, 0x55, 0x45, 0x14, 0x00,
+0x48, 0x02, 0xa8, 0x2a, 0x00, 0x03, 0x00,
+0x11, 0x55, 0x55, 0x55, 0x95, 0x28, 0x00,
+0x21, 0x81, 0xaa, 0x2a, 0x00, 0x26, 0x00,
+0x8d, 0x55, 0x55, 0x55, 0x15, 0x21, 0x00,
+0xb1, 0xe0, 0xaa, 0xaa, 0x00, 0x20, 0x00,
+0x80, 0xf5, 0x55, 0x55, 0x15, 0x07, 0x00,
+0xbe, 0xf0, 0xab, 0xaa, 0x00, 0x00, 0x00,
+0x80, 0xf5, 0x55, 0x55, 0x15, 0x1f, 0x00,
+0xbe, 0xe0, 0xab, 0xaa, 0x02, 0x00, 0x00,
+0x80, 0xf5, 0x57, 0x55, 0x15, 0x1f, 0x00,
+0xb8, 0xc0, 0xaf, 0xaa, 0x00, 0x00, 0x00,
+0x81, 0xd5, 0x57, 0x15, 0x14, 0x23, 0x00,
+0xa1, 0x80, 0xaf, 0x0a, 0x00, 0x2c, 0x00,
+0x19, 0xd5, 0x5f, 0x01, 0x14, 0x21, 0x00,
+0x45, 0x01, 0xaf, 0x00, 0x00, 0x22, 0x00,
+0x30, 0x56, 0x1f, 0x40, 0x85, 0x04, 0x00,
+0x8a, 0x02, 0x0e, 0x00, 0x00, 0x11, 0x00,
+0x40, 0x54, 0x0f, 0x54, 0x45, 0x02, 0x00,
+0x34, 0x09, 0x04, 0x00, 0x80, 0x08, 0x00,
+0x80, 0x40, 0x45, 0x55, 0x21, 0x01, 0x00,
+0x68, 0x04, 0x00, 0x00, 0x48, 0x04, 0x00,
+0x00, 0x82, 0x55, 0x95, 0x90, 0x00, 0x00,
+0x80, 0x09, 0x02, 0x20, 0x22, 0x00, 0x00,
+0x20, 0x24, 0xa8, 0x8a, 0x24, 0x01, 0x00,
+0x40, 0x92, 0x00, 0x20, 0x89, 0x00, 0x00,
+0x80, 0x48, 0xaa, 0x4a, 0x4a, 0x00, 0x00,
+0x00, 0x20, 0xa9, 0x52, 0x02, 0x00, 0x00,
+0x00, 0x84, 0xa4, 0x92, 0x08, 0x00, 0x00,
+0x00, 0x10, 0xa4, 0x24, 0x02, 0x00, 0x00,
+0x00, 0x40, 0xa0, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0f, 0x3c, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/black_3.xbm b/test/black_3.xbm
new file mode 100644
index 000000000..ead6e086a
--- /dev/null
+++ b/test/black_3.xbm
@@ -0,0 +1,60 @@
+#define black_3_width 56
+#define black_3_height 56
+static unsigned char black_3_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/black_4.xbm b/test/black_4.xbm
new file mode 100644
index 000000000..4132263e6
--- /dev/null
+++ b/test/black_4.xbm
@@ -0,0 +1,60 @@
+#define black_4_width 56
+#define black_4_height 56
+static unsigned char black_4_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/blackking_1.xbm b/test/blackking_1.xbm
new file mode 100644
index 000000000..f764eade6
--- /dev/null
+++ b/test/blackking_1.xbm
@@ -0,0 +1,60 @@
+#define blackking_1_width 56
+#define blackking_1_height 56
+static unsigned char blackking_1_bits[] = {
+0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00,
+0x00, 0xf8, 0xff, 0xff, 0x03, 0x00, 0x00,
+0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, 0x00,
+0x00, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00,
+0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
+0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x17, 0x00,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x2f, 0x00,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x00,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x00,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x01,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x0a,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x15,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x0a,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x15,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x2a,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x55,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x2a,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x55,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x2a,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x55,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xaa,
+0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x55,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xaa,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x55,
+0xfe, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xaa,
+0xfc, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x55,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xaa,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0x57, 0x55,
+0xf8, 0xff, 0xff, 0xff, 0xff, 0xab, 0xaa,
+0xf0, 0xff, 0xff, 0xff, 0xff, 0x55, 0x55,
+0xe0, 0xff, 0xff, 0xff, 0xff, 0xab, 0xaa,
+0xc0, 0xff, 0xff, 0xff, 0xff, 0x55, 0x55,
+0x80, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x2a,
+0x00, 0xff, 0xff, 0xff, 0x5f, 0x55, 0x55,
+0x00, 0xfe, 0xff, 0xff, 0xaf, 0xaa, 0x2a,
+0x00, 0xf4, 0xff, 0xff, 0x57, 0x55, 0x15,
+0x00, 0xe8, 0xff, 0xff, 0xaa, 0xaa, 0x2a,
+0x00, 0x50, 0xff, 0x7f, 0x55, 0x55, 0x15,
+0x00, 0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a,
+0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x05,
+0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0x02,
+0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x01,
+0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x00,
+0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x00,
+0x00, 0x00, 0xa8, 0xaa, 0xaa, 0x2a, 0x00,
+0x00, 0x00, 0x40, 0x55, 0x55, 0x15, 0x00,
+0x00, 0x00, 0x00, 0xaa, 0xaa, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00,
+};
diff --git a/test/blackking_2.xbm b/test/blackking_2.xbm
new file mode 100644
index 000000000..9be617b5a
--- /dev/null
+++ b/test/blackking_2.xbm
@@ -0,0 +1,60 @@
+#define blackking_2_width 56
+#define blackking_2_height 56
+static unsigned char blackking_2_bits[] = {
+0x00, 0x00, 0x0f, 0x3c, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x40, 0x81, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x49, 0x09, 0x02, 0x00, 0x00,
+0x00, 0x44, 0x52, 0x49, 0x08, 0x00, 0x00,
+0x00, 0x90, 0x52, 0x25, 0x01, 0x00, 0x00,
+0x80, 0x94, 0x54, 0x95, 0x44, 0x00, 0x00,
+0x40, 0x24, 0x01, 0x40, 0x92, 0x00, 0x00,
+0x20, 0x49, 0xfc, 0x0f, 0x09, 0x01, 0x00,
+0x00, 0x11, 0x57, 0x35, 0x64, 0x00, 0x00,
+0x40, 0xc2, 0x00, 0xc0, 0x10, 0x00, 0x00,
+0x88, 0x64, 0xd5, 0x55, 0x89, 0x05, 0x00,
+0x20, 0x11, 0xc0, 0x00, 0x42, 0x00, 0x00,
+0x44, 0x58, 0x57, 0x74, 0x21, 0x0b, 0x00,
+0x90, 0x04, 0x03, 0x30, 0x80, 0x00, 0x00,
+0x22, 0x76, 0x51, 0x15, 0x47, 0x14, 0x00,
+0x48, 0x32, 0x08, 0x02, 0x03, 0x03, 0x00,
+0x11, 0x15, 0x5d, 0x57, 0x91, 0x28, 0x00,
+0x21, 0x01, 0x0c, 0x03, 0x00, 0x26, 0x00,
+0x8d, 0x55, 0xcf, 0xd3, 0x15, 0x21, 0x00,
+0xb1, 0x18, 0x86, 0xe1, 0x00, 0x20, 0x00,
+0x80, 0x5d, 0xd7, 0x75, 0x11, 0x07, 0x00,
+0xbe, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x75, 0x55, 0x55, 0x11, 0x1f, 0x00,
+0xbe, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x75, 0x55, 0x55, 0x10, 0x1f, 0x00,
+0xb8, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x81, 0x75, 0x55, 0x55, 0x14, 0x23, 0x00,
+0xa1, 0x60, 0x00, 0x00, 0x00, 0x2c, 0x00,
+0x19, 0xd5, 0x55, 0x55, 0x14, 0x21, 0x00,
+0x45, 0xc1, 0x00, 0x00, 0x00, 0x22, 0x00,
+0x30, 0xd6, 0x00, 0x00, 0x85, 0x04, 0x00,
+0x8a, 0x82, 0x00, 0x00, 0x00, 0x11, 0x00,
+0x40, 0x54, 0x00, 0x00, 0x45, 0x02, 0x00,
+0x34, 0x09, 0x00, 0x00, 0x80, 0x08, 0x00,
+0x80, 0x40, 0x55, 0x55, 0x21, 0x01, 0x00,
+0x68, 0x04, 0x00, 0x00, 0x48, 0x04, 0x00,
+0x00, 0x82, 0x55, 0x95, 0x90, 0x00, 0x00,
+0x80, 0x09, 0x02, 0x20, 0x22, 0x00, 0x00,
+0x20, 0x24, 0xa8, 0x8a, 0x24, 0x01, 0x00,
+0x40, 0x92, 0x00, 0x20, 0x89, 0x00, 0x00,
+0x80, 0x48, 0xaa, 0x4a, 0x4a, 0x00, 0x00,
+0x00, 0x20, 0xa9, 0x52, 0x02, 0x00, 0x00,
+0x00, 0x84, 0xa4, 0x92, 0x08, 0x00, 0x00,
+0x00, 0x10, 0xa4, 0x24, 0x02, 0x00, 0x00,
+0x00, 0x40, 0xa0, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0f, 0x3c, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/blackking_3.xbm b/test/blackking_3.xbm
new file mode 100644
index 000000000..b4a688360
--- /dev/null
+++ b/test/blackking_3.xbm
@@ -0,0 +1,60 @@
+#define blackking_3_width 56
+#define blackking_3_height 56
+static unsigned char blackking_3_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/blackking_4.xbm b/test/blackking_4.xbm
new file mode 100644
index 000000000..a7078623e
--- /dev/null
+++ b/test/blackking_4.xbm
@@ -0,0 +1,60 @@
+#define blackking_4_width 56
+#define blackking_4_height 56
+static unsigned char blackking_4_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/boxtype.cxx b/test/boxtype.cxx
new file mode 100644
index 000000000..b358f228e
--- /dev/null
+++ b/test/boxtype.cxx
@@ -0,0 +1,66 @@
+// produce the diagram of boxtypes for the documentation
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/Fl_Box.H>
+
+int N = 0;
+#define W 150
+#define H 50
+#define ROWS 8
+
+Fl_Window *window;
+
+void bt(const char *name, Fl_Boxtype type, int square=0) {
+ int x = N%4;
+ int y = N/4;
+ N++;
+ x = x*W+10;
+ y = y*H+10;
+ Fl_Box *b = new Fl_Box(type,x,y,square ? H-20 : W-20,H-20,name);
+ b->labelsize(11);
+ if (square) b->align(FL_ALIGN_RIGHT);
+}
+
+int main(int argc, char ** argv) {
+ window = new Fl_Single_Window(4*W,ROWS*H);
+ window->box(FL_FLAT_BOX);
+ window->color(12);// light blue
+ bt("FL_NO_BOX",FL_NO_BOX);
+ bt("FL_FLAT_BOX",FL_FLAT_BOX);
+ N += 2; // go to start of next row to line up boxes & frames
+ bt("FL_UP_BOX",FL_UP_BOX);
+ bt("FL_DOWN_BOX",FL_DOWN_BOX);
+ bt("FL_UP_FRAME",FL_UP_FRAME);
+ bt("FL_DOWN_FRAME",FL_DOWN_FRAME);
+ bt("FL_THIN_UP_BOX",FL_THIN_UP_BOX);
+ bt("FL_THIN_DOWN_BOX",FL_THIN_DOWN_BOX);
+ bt("FL_THIN_UP_FRAME",FL_THIN_UP_FRAME);
+ bt("FL_THIN_DOWN_FRAME",FL_THIN_DOWN_FRAME);
+ bt("FL_ENGRAVED_BOX",FL_ENGRAVED_BOX);
+ bt("FL_EMBOSSED_BOX",FL_EMBOSSED_BOX);
+ bt("FL_ENGRAVED_FRAME",FL_ENGRAVED_FRAME);
+ bt("FL_EMBOSSED_FRAME",FL_EMBOSSED_FRAME);
+ bt("FL_BORDER_BOX",FL_BORDER_BOX);
+ bt("FL_SHADOW_BOX",FL_SHADOW_BOX);
+ bt("FL_BORDER_FRAME",FL_BORDER_FRAME);
+ bt("FL_SHADOW_FRAME",FL_SHADOW_FRAME);
+ bt("FL_ROUNDED_BOX",FL_ROUNDED_BOX);
+ bt("FL_RSHADOW_BOX",FL_RSHADOW_BOX);
+ bt("FL_ROUNDED_FRAME",FL_ROUNDED_FRAME);
+ bt("FL_RFLAT_BOX",FL_RFLAT_BOX);
+ bt("FL_OVAL_BOX",FL_OVAL_BOX);
+ bt("FL_OSHADOW_BOX",FL_OSHADOW_BOX);
+ bt("FL_OVAL_FRAME",FL_OVAL_FRAME);
+ bt("FL_OFLAT_BOX",FL_OFLAT_BOX);
+ bt("FL_ROUND_UP_BOX",FL_ROUND_UP_BOX);
+ bt("FL_ROUND_DOWN_BOX",FL_ROUND_DOWN_BOX);
+ bt("FL_DIAMOND_UP_BOX",FL_DIAMOND_UP_BOX);
+ bt("FL_DIAMOND_DOWN_BOX",FL_DIAMOND_DOWN_BOX);
+ window->resizable(window);
+ window->end();
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/browser.cxx b/test/browser.cxx
new file mode 100644
index 000000000..3a1510185
--- /dev/null
+++ b/test/browser.cxx
@@ -0,0 +1,71 @@
+/*
+This is a test of how the browser draws lines.
+This is a second line.
+This is a third.
+
+That was a blank line above this.
+
+@r@_Right justify
+@c@_Center justify
+@_Left justify
+
+@bBold text
+@iItalic text
+@b@iBold Italic
+@fFixed width
+@f@bBold Fixed
+@f@iItalic Fixed
+@f@i@bBold Italic Fixed
+@lLarge
+@l@bLarge bold
+@sSmall
+@s@bSmall bold
+@s@iSmall italic
+@s@i@bSmall italic bold
+@uunderscore
+@C1RED
+@C2Green
+@C4Blue
+
+ You should try different browser types:
+ Fl_Browser
+ Fl_Select_Browser
+ Fl_Hold_Browser
+ Fl_Multi_Browser
+*/
+
+#include <FL/Fl.H>
+#include <FL/Fl_Select_Browser.H>
+#include <FL/Fl_Double_Window.H>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+void b_cb(Fl_Widget* o, void*) {
+ printf("callback, selection = %d, event_clicks = %d\n",
+ ((Fl_Browser*)o)->value(), Fl::event_clicks());
+}
+
+int main(int argc, char **argv) {
+ int i;
+ if (!Fl::args(argc,argv,i)) Fl::fatal(Fl::help);
+ const char* fname = (i < argc) ? argv[i] : "browser.C";
+ Fl_Window window(400,400,fname);
+ window.box(FL_NO_BOX); // because it is filled with browser
+ Fl_Select_Browser browser(0,0,400,400,0);
+ browser.type(FL_MULTI_BROWSER);
+ browser.callback(b_cb);
+ // browser.scrollbar_right();
+ //browser.has_scrollbar(Fl_Browser::BOTH_ALWAYS);
+ if (!browser.load(fname)) {
+ printf("Can't load %s, %s\n", fname, strerror(errno));
+ exit(1);
+ }
+ browser.position(0);
+ window.resizable(&browser);
+ window.show(argc,argv);
+ return Fl::run();
+}
+
+
diff --git a/test/browserop.cxx b/test/browserop.cxx
new file mode 100644
index 000000000..19f920d2b
--- /dev/null
+++ b/test/browserop.cxx
@@ -0,0 +1,81 @@
+/* This demo shows the different routines on browsers */
+
+#include "forms.h"
+
+FL_FORM *form;
+FL_OBJECT *browserobj, *inputobj, *exitobj;
+
+void addit(FL_OBJECT *, long)
+{
+ /* append and show the last line. Don't use this if you just want
+ * to add some lines. use fl_add_browser_line
+ */
+ fl_addto_browser(browserobj,fl_get_input(inputobj));
+}
+
+void insertit(FL_OBJECT *, long)
+{
+ int n;
+ if (! ( n = fl_get_browser(browserobj))) return;
+ fl_insert_browser_line(browserobj,n,fl_get_input(inputobj));
+}
+
+void replaceit(FL_OBJECT *, long)
+{
+ int n;
+ if (! (n=fl_get_browser(browserobj))) return;
+ fl_replace_browser_line(browserobj,n,fl_get_input(inputobj));
+}
+
+void deleteit(FL_OBJECT *, long)
+{
+ int n;
+ if (! (n = fl_get_browser(browserobj))) return;
+ fl_delete_browser_line(browserobj,n);
+}
+
+void clearit(FL_OBJECT *, long)
+{
+ fl_clear_browser(browserobj);
+}
+
+/*---------------------------------------*/
+
+void create_form(void)
+{
+ FL_OBJECT *obj;
+
+ form = fl_bgn_form(FL_UP_BOX,390,420);
+ browserobj = fl_add_browser(FL_HOLD_BROWSER,20,20,210,330,"");
+// fl_set_object_dblbuffer(browserobj, 1);
+ inputobj = obj = fl_add_input(FL_NORMAL_INPUT,20,370,210,30,"");
+ fl_set_object_callback(obj,addit,0);
+ obj->when(FL_WHEN_ENTER_KEY|FL_WHEN_NOT_CHANGED);
+ obj = fl_add_button(FL_NORMAL_BUTTON,250,20,120,30,"Add");
+ fl_set_object_callback(obj,addit,0);
+ obj = fl_add_button(FL_NORMAL_BUTTON,250,60,120,30,"Insert");
+ fl_set_object_callback(obj,insertit,0);
+ obj = fl_add_button(FL_NORMAL_BUTTON,250,100,120,30,"Replace");
+ fl_set_object_callback(obj,replaceit,0);
+ obj = fl_add_button(FL_NORMAL_BUTTON,250,160,120,30,"Delete");
+ fl_set_object_callback(obj,deleteit,0);
+ obj = fl_add_button(FL_NORMAL_BUTTON,250,200,120,30,"Clear");
+ fl_set_object_callback(obj,clearit,0);
+ exitobj = fl_add_button(FL_NORMAL_BUTTON,250,370,120,30,"Exit");
+ fl_end_form();
+}
+
+/*---------------------------------------*/
+
+int
+main(int argc, char *argv[])
+{
+ FL_OBJECT *obj;
+
+ fl_initialize(&argc, argv, "FormDemo", 0, 0);
+ create_form();
+ fl_show_form(form,FL_PLACE_CENTER,FL_TRANSIENT,"Browser Op");
+ do obj = fl_do_forms(); while (obj != exitobj);
+ fl_hide_form(form);
+ return 0;
+}
diff --git a/test/button.cxx b/test/button.cxx
new file mode 100644
index 000000000..78c8f135b
--- /dev/null
+++ b/test/button.cxx
@@ -0,0 +1,27 @@
+// Demonstration of how to do callbacks
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+
+void beepcb(Fl_Widget *, void *) {
+ printf("\007"); fflush(stdout);
+}
+
+void exitcb(Fl_Widget *, void *) {
+ exit(0);
+}
+
+int main(int argc, char ** argv) {
+ Fl_Window *window = new Fl_Window(320,65);
+ Fl_Button *b1 = new Fl_Button(20, 20, 80, 25, "&Beep");
+ b1->callback(beepcb,0);
+ /*Fl_Button *b2 =*/ new Fl_Button(120,20, 80, 25, "&no op");
+ Fl_Button *b3 = new Fl_Button(220,20, 80, 25, "E&xit");
+ b3->callback(exitcb,0);
+ window->end();
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/buttons.cxx b/test/buttons.cxx
new file mode 100644
index 000000000..5dfb4f4e3
--- /dev/null
+++ b/test/buttons.cxx
@@ -0,0 +1,25 @@
+// produce image for the documentation
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Repeat_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Round_Button.H>
+
+int main(int argc, char ** argv) {
+ Fl_Window *window = new Fl_Window(320,130);
+ new Fl_Button(10, 10, 130, 30, "Fl_Button");
+ new Fl_Return_Button(150, 10, 160, 30, "Fl_Return_Button");
+ new Fl_Repeat_Button(10,50,130,30,"Fl_Repeat_Button");
+ new Fl_Light_Button(10,90,130,30,"Fl_Light_Button");
+ new Fl_Round_Button(150,50,160,30,"Fl_Round_Button");
+ new Fl_Check_Button(150,90,160,30,"Fl_Check_Button");
+ window->end();
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/checkers.cxx b/test/checkers.cxx
new file mode 100644
index 000000000..fe9aa700f
--- /dev/null
+++ b/test/checkers.cxx
@@ -0,0 +1,1340 @@
+// Hours of fun: the FLTK checkers game!
+// Based on a very old algorithim, but it still works!
+
+const char* copyright =
+"Checkers game\n"
+"Copyright (C) 1997 Bill Spitzak spitzak@d2.com\n"
+"Original Pascal code:\n"
+"Copyright 1978, Oregon Minicomputer Software, Inc.\n"
+"2340 SW Canyon Road, Portland, Oregon 97201\n"
+"Written by Steve Poulsen 18-Jan-79\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify "
+"it under the terms of the GNU General Public License as published by "
+"the Free Software Foundation; either version 2 of the License, or "
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful, "
+"but WITHOUT ANY WARRANTY; without even the implied warranty of "
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU Library General Public "
+"License along with this library; if not, write to the Free Software "
+"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
+"USA.";
+
+// Define FLTK to get the fltk interface
+// Define VT100 to get the VT100 interface
+// Define both to get a program that takes a -t switch
+
+#define FLTK
+//#define VT100
+
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <time.h>
+
+////////////////////////////////////////////////////////////////
+// The algorithim:
+
+int maxevaluate=2500; // max number of moves to examine on a turn
+int maxnodes = 2500; // maximum number of nodes in search tree
+int maxply = 20; // maximum depth to look ahead
+char forcejumps = 1; // is forced jumps rule in effect?
+
+// scoring parameters: (all divided by 5 from original code)
+// some signs seem to be backwards, marked them with (-) in comment
+const int spiece = 800; // value of a piece
+const int sking = 1200; // value of a king
+const int sadvan = 160; // value of mypieces/theirpieces-1
+// const int smobil = ? // moves *enemy* can make w/o being jumped
+const int sallpin = 80; // mobil == 0
+const int sdeny = 10; // moves enemy can make that will be jumped
+const int spin = 32; // enemy pieces that have no move except jumped
+const int sthreat = -10; // enemy pieces we can jump if not moved (-)
+const int sgrad = 1; // score of piece positions
+const int sback = 10; // back row occupied so enemy can't make king
+const int smoc2 = 200; // more mobility, more center
+const int smoc3 = -8; // less mobility, less center
+const int smoc4 = -80; // more mobility, less center
+const int smode2 = -14; // less mobility, less denied
+const int smode3 = -40; // more mobility, more denied (-)
+const int sdemmo = -20; // more denied, more moves (-)
+const int scent = 10; // pieces in center
+const int skcent = 100; // kings in center
+
+const int depthpenalty=4; // guess
+const int noise=2; // values less or eq to this apart are eq
+
+// const int sattackking = 4; // not used
+// const int sattackpiece = 3;
+
+struct node {
+ node *father;
+ node *son; // best son
+ node *brother; // next brother
+ short int value; // value of this board position to player making move
+ unsigned char from,to; // the move to reach this board
+ long int jump; // bit map of locations jumped
+ unsigned char mobil;
+ unsigned char deny;
+ unsigned char pin;
+ unsigned char threat;
+ short int gradient;
+ unsigned who:1; // 0 = black's move, 1 = white's move
+ unsigned king:1; // 1 = move causes piece to be kinged
+ unsigned back:1;
+ unsigned moc2:1;
+ unsigned moc3:1;
+ unsigned moc4:1;
+ unsigned mode2:1;
+ unsigned mode3:1;
+ unsigned demmo:1;
+};
+
+int nodes; // count of nodes
+
+/* Board positions: Border positions:
+
+ WHITE 00 01 02 03 04
+ 05 06 07 08 04 XX XX XX XX
+ 09 10 11 12 XX XX XX XX 13
+ 14 15 16 17 13 XX XX XX XX
+ 18 19 20 21 XX XX XX XX 22
+ 23 24 25 26 22 XX XX XX XX
+ 27 28 29 30 XX XX XX XX 31
+ 32 33 34 36 31 XX XX XX XX
+ 36 37 38 39 XX XX XX XX 40
+ BLACK 40 41 42 43 44
+
+*/
+
+typedef char piece;
+
+// Piece values so that BLACK and WHITE are bit flags:
+#define EMPTY 0
+#define BLACK 1
+#define WHITE 2
+#define KING 4
+#define BLACKKING 5
+#define WHITEKING 6
+#define BLUE 8
+
+const piece flip[9] = {
+ EMPTY, WHITE, BLACK, 0, 0, WHITEKING, BLACKKING, 0, BLUE};
+
+const int offset[9][4] = { // legal move directions
+ {0,0,0,0},
+ {-5,-4,0,0},
+ {4,5,0,0},
+ {0,0,0,0},
+ {0,0,0,0},
+ {4,5,-4,-5},
+ {4,5,-4,-5},
+ {0,0,0,0},
+ {0,0,0,0}
+};
+
+piece b[45]; // current board position being considered
+
+int evaluated; // number of moves evaluated this turn
+
+char centralsquares[45];
+char is_protected[45];
+
+piece flipboard[45]; // swapped if enemy is black
+piece *tb; // pointer to real or swapped board
+#define FRIEND BLACK
+#define FRIENDKING BLACKKING
+#define ENEMY WHITE
+#define ENEMYKING WHITEKING
+
+char check(int target,int direction) {
+ // see if enemy at target can be jumped from direction by our piece
+ int dst = target-direction;
+ if (tb[dst]) return(0);
+ int src = target+direction;
+ if (tb[src] == FRIENDKING);
+ else if (direction < 0 || tb[src] != FRIEND) return(0);
+ piece a = tb[target]; piece b = tb[src];
+ tb[target] = EMPTY; tb[src] = EMPTY;
+ int safe =
+ (tb[src-4]&FRIEND && tb[src-8]&ENEMY
+ ||tb[src-5]&FRIEND && tb[src-10]&ENEMY
+ ||tb[dst-4]&ENEMY && !tb[dst+4]
+ ||tb[dst-5]&ENEMY && !tb[dst+5]
+ ||tb[src+4]&FRIEND && tb[src+8]==ENEMYKING
+ ||tb[src+5]&FRIEND && tb[src+10]==ENEMYKING
+ ||tb[dst+4]==ENEMYKING && !tb[dst-4]
+ ||tb[dst+5]==ENEMYKING && !tb[dst-5]);
+ tb[target] = a; tb[src] = b;
+ return(safe);
+}
+
+int deniedmoves,undeniedmoves;
+void analyzemove(int direction,int src) {
+ int target = src+direction;
+ if (!tb[target]) {
+ if (!tb[target+direction]) is_protected[target] = 1;
+ piece a = tb[src]; tb[src] = EMPTY;
+ if (check(target,4) || check(target,5) ||
+ check(target,-4) || check(target,-5) ||
+ (tb[src+4]&ENEMY && check(src+4,4)) ||
+ (tb[src+5]&ENEMY && check(src+5,5)) ||
+ (tb[src-4]&ENEMY && check(src-4,-4)) ||
+ (tb[src-5]&ENEMY && check(src-5,-5)))
+ deniedmoves++;
+ else undeniedmoves++;
+ tb[src] = a;
+ }
+}
+
+void evaluateboard(node *n,int print) {
+
+ if (!n->who) tb = b; // move was black's
+ else {
+ for (int i=0; i<45; i++) flipboard[44-i] = flip[b[i]];
+ tb = flipboard;
+ }
+
+ memset(is_protected,0,sizeof(is_protected));
+ int friendpieces = 0;
+ int enemypieces = 0;
+ int friendkings = 0;
+ int enemykings = 0;
+ int friendkcent = 0;
+ int friendcent = 0;
+ int enemykcent = 0;
+ int enemycent = 0;
+ n->mobil = n->deny = n->pin = n->threat = 0;
+
+ int i;
+ for (i=5; i<40; i++) switch(tb[i]) {
+ case ENEMYKING:
+ enemykings++;
+ enemykcent += centralsquares[i];
+ deniedmoves = 0;
+ undeniedmoves = 0;
+ if (i>8) {
+ analyzemove(-4,i);
+ analyzemove(-5,i);
+ }
+ goto J1;
+ case ENEMY:
+ deniedmoves = 0;
+ undeniedmoves = 0;
+ J1: enemypieces++;
+ enemycent += centralsquares[i];
+ if (i<36) {
+ analyzemove(4,i);
+ analyzemove(5,i);
+ }
+ if (deniedmoves && !undeniedmoves) n->pin++;
+ n->deny += deniedmoves;
+ n->mobil += undeniedmoves;
+ break;
+ case FRIENDKING:
+ friendkings++;
+ friendkcent += centralsquares[i];
+ if (tb[i+4]&ENEMY && !tb[i+8] && !(tb[i+4]==ENEMYKING && !tb[i-4]))
+ n->threat++;
+ if (tb[i+5]&ENEMY && !tb[i+10] && !(tb[i+5]==ENEMYKING && !tb[i-5]))
+ n->threat++;
+ case FRIEND:
+ friendpieces++;
+ friendcent += centralsquares[i];
+ if (tb[i-4]&ENEMY && !tb[i-8] && tb[i+4]) n->threat++;
+ if (tb[i-5]&ENEMY && !tb[i-10] && tb[i+5]) n->threat++;
+ break;
+ }
+
+ int gradient[40];
+ for (i=4; i<9; i++) gradient[i] = tb[i] ? 0 : 32;
+ int total = 0;
+ for (i=9; i<40; i++) {
+ int x = (gradient[i-4]+gradient[i-5])/2;
+ if (tb[i]==FRIEND) total += x;
+ gradient[i] = (tb[i]&FRIEND || !tb[i] && !is_protected[i]) ? x : 0;
+ }
+ n->gradient = total;
+
+ n->back = tb[39]==FRIEND && tb[37]==FRIEND && !enemykings;
+
+ node* f = n->father;
+
+ n->moc2 = f->mobil>n->mobil && friendcent>enemycent;
+ n->moc3 = f->mobil<=n->mobil && friendcent<enemycent;
+ n->moc4 = f->mobil>n->mobil && friendcent<enemycent;
+ n->mode2 = f->mobil<=n->mobil && n->deny<f->deny;
+ n->mode3 = f->mobil>n->mobil && n->deny>f->deny;
+ n->demmo = n->deny>f->deny && f->deny+f->mobil>n->deny+n->mobil;
+
+ total =
+ spiece * (friendpieces - enemypieces) +
+ (sking-spiece) * (friendkings - enemykings) +
+ // mobil?
+ sdeny * (n->deny - f->deny) +
+ spin * (n->pin - f->pin) +
+ sthreat * (n->threat - f->threat) +
+ sgrad * (n->gradient - f->gradient) +
+ sback * (n->back - f->back) +
+ smoc2 * (n->moc2 - f->moc2) +
+ smoc3 * (n->moc3 - f->moc3) +
+ smoc4 * (n->moc4 - f->moc4) +
+ smode2 * (n->mode2 - f->mode2) +
+ smode3 * (n->mode3 - f->mode3) +
+ sdemmo * (n->demmo - f->demmo) +
+ scent * (friendcent - enemycent) +
+ (skcent-scent) * (friendkcent - enemykcent);
+ if (!n->mobil) total += sallpin;
+
+ if (!enemypieces) total = 30000;
+ else if (friendpieces > enemypieces)
+ total += (sadvan*friendpieces)/enemypieces-sadvan;
+ else total -= (sadvan*enemypieces)/friendpieces-sadvan;
+
+ if (print) {
+ printf("\tParent\tNew\tScore\n");
+ printf("pieces\t%d\t%d\t%d\n",enemypieces,friendpieces,
+ spiece*(friendpieces-enemypieces));
+ printf("kings\t%d\t%d\t%d\n",enemykings,friendkings,
+ (sking-spiece)*(friendkings-enemykings));
+ printf("mobil\t%d\t%d\n",f->mobil,n->mobil);
+ printf("deny\t%d\t%d\t%d\n",f->deny,n->deny,sdeny*(n->deny-f->deny));
+ printf("pin\t%d\t%d\t%d\n",f->pin,n->pin,spin*(n->pin-f->pin));
+ printf("threat\t%d\t%d\t%d\n",f->threat,n->threat,sthreat*(n->threat-f->threat));
+ printf("grad\t%d\t%d\t%d\n",f->gradient,n->gradient,sgrad*(n->gradient-f->gradient));
+ printf("back\t%d\t%d\t%d\n",f->back,n->back,sback*(n->back-f->back));
+ printf("moc2\t%d\t%d\t%d\n",f->moc2,n->moc2,smoc2*(n->moc2-f->moc2));
+ printf("moc3\t%d\t%d\t%d\n",f->moc3,n->moc3,smoc3*(n->moc3-f->moc3));
+ printf("moc4\t%d\t%d\t%d\n",f->moc4,n->moc4,smoc4*(n->moc4-f->moc4));
+ printf("mode2\t%d\t%d\t%d\n",f->mode2,n->mode2,smode2*(n->mode2-f->mode2));
+ printf("mode3\t%d\t%d\t%d\n",f->mode3,n->mode3,smode3*(n->mode3-f->mode3));
+ printf("demmo\t%d\t%d\t%d\n",f->demmo,n->demmo,sdemmo*(n->demmo-f->demmo));
+ printf("cent\t%d\t%d\t%dn",enemycent,friendcent,scent*(friendcent-enemycent));
+ printf("kcent\t%d\t%d\t%d\n",enemykcent,friendkcent,skcent*(friendkcent-enemykcent));
+ printf("total:\t\t\t%d\n",total);
+ }
+ else {
+ n->value = total;
+ evaluated++;
+ }
+} // end of evaluateboard
+
+// --------------------- Tree management -----------------
+
+node *freelist;
+
+node *newnode(void) {
+ node *n;
+ if (freelist) {
+ n = freelist;
+ freelist = n->brother;
+ }
+ else n = (node *)malloc(sizeof(node));
+ memset(n,0,sizeof(node));
+ nodes++;
+ return(n);
+}
+
+void extract(node *n) {
+ node* i = n->father;
+ if (i) {
+ node* j = i->son;
+ if (j==n) i->son = n->brother;
+ else while (j) {
+ i = j; j = j->brother;
+ if (j==n) {i->brother = n->brother; break;}
+ }
+ }
+ n->brother = 0;
+}
+
+void killnode(node *x) {
+ if (!x) return;
+ node *y;
+ for (y = x; ; y = y->brother) {
+ nodes--;
+ killnode(y->son); y->son = 0;
+ if (!y->brother) break;
+ }
+ y->brother = freelist;
+ freelist = x;
+}
+
+int seed; // current random number
+
+void insert(node *n) {
+ int val = n->value;
+ node **pp;
+ for (pp = &(n->father->son); *pp; pp = &((*pp)->brother)) {
+ int val1 = (*pp)->value;
+ if (abs(val-val1) <= noise) {
+ seed = (seed*13077+5051)%0100000;
+ if ((seed & 070) >= 060) break;
+ }
+ else if (val > val1) break;
+ }
+ n->brother = *pp;
+ *pp = n;
+}
+
+// --------------------------------------------------------------
+
+void movepiece(node* f, int i, node* jnode) {
+ static char jumphappened;
+
+ for (int k=0; k<4; k++) {
+ int direction = offset[b[i]][k];
+ if (!direction) break;
+ int j = i+direction;
+ if (b[j] == EMPTY) {
+ if (!jnode && (!forcejumps || !f->son || !f->son->jump)) {
+ node* n = newnode();
+ n->father = f;
+ n->who = !f->who;
+ n->from = i;
+ n->to = j;
+ piece oldpiece = b[i]; b[i] = EMPTY;
+ if (!(oldpiece&KING) && n->who ? (j>=36) : (j<=8)) {
+ n->king = 1;
+ b[j] = oldpiece|KING;
+ }
+ else b[j] = oldpiece;
+ evaluateboard(n,0);
+ insert(n);
+ b[i] = oldpiece; b[j] = EMPTY;
+ }
+ } else if (((b[j]^b[i])&(WHITE|BLACK))==(WHITE|BLACK) && !b[j+direction]) {
+ if (forcejumps && f->son && !f->son->jump) {
+ killnode(f->son);
+ f->son = 0;
+ }
+ int jumploc = j;
+ j += direction;
+ node* n = newnode();
+ n->father = f;
+ n->who = !f->who;
+ n->from = i;
+ n->to = j;
+ n->jump = (1<<(jumploc-10));
+ piece oldpiece = b[i]; b[i] = EMPTY;
+ if (!(oldpiece&KING) && n->who ? (j>=36) : (j<=8)) {
+ n->king = 1;
+ b[j] = oldpiece|KING;
+ }
+ else b[j] = oldpiece;
+ if (jnode) {
+ n->from = jnode->from;
+ n->jump |= jnode->jump;
+ n->king |= jnode->king;
+ }
+ piece jumpedpiece = b[jumploc];
+ b[jumploc] = EMPTY;
+ jumphappened = 0;
+ movepiece(f,j,n);
+ if (forcejumps && jumphappened) killnode(n);
+ else {evaluateboard(n,0); insert(n);}
+ b[i] = oldpiece; b[j] = EMPTY;
+ b[jumploc] = jumpedpiece;
+ jumphappened = 1;
+ }
+ }
+}
+
+void expandnode(node *f) {
+ if (f->son || f->value > 28000) return; // already done
+ piece turn = f->who ? BLACK : WHITE;
+ for (int i=5; i<40; i++) if (b[i]&turn) movepiece(f,i,0);
+ if (f->son) {
+ f->value = -f->son->value;
+ if (f->brother) f->value -= depthpenalty;
+ }
+ else f->value = 30000;
+}
+
+void makemove(node *n) {
+ b[n->to] = b[n->from];
+ if (n->king) b[n->to] |= KING;
+ b[n->from] = EMPTY;
+ if (n->jump) for(int i=0; i<32; i++) {
+ if (n->jump & (1<<i)) b[10+i] = EMPTY;
+ }
+}
+
+int didabort(void);
+
+int fullexpand(node *f, int level) {
+ if (didabort() || nodes > maxnodes-(maxply*10) || evaluated > maxevaluate) return(0);
+ expandnode(f);
+ if (!f->son) return(1);
+ piece oldboard[45];
+ memmove(oldboard,b,sizeof(b));
+ node* n = f->son;
+ if (!n->jump && n->brother) {if (level<1) return(1); level--;}
+ int i;
+ node* sons[32]; for (i=0; (sons[i++] = n); n = n->brother);
+ int ret = 1;
+ for (i=0; ret && (n = sons[i++]);) {
+ makemove(n);
+ ret = fullexpand(n,level);
+ memmove(b,oldboard,sizeof(b));
+ extract(n);
+ insert(n);
+ }
+ f->value = -f->son->value;
+ return(ret);
+}
+
+int descend(node *f) {
+ static int depth;
+ if (didabort() || nodes > maxnodes || depth >= maxply) return(0);
+ if (f->son) {
+ node* n = f->son;
+ makemove(n);
+ depth++;
+ int ret = descend(n);
+ depth--;
+ extract(n);
+ insert(n);
+ f->value = -f->son->value;
+ return(ret);
+ }
+ else {expandnode(f); return(1);}
+}
+
+char debug;
+
+node *calcmove(node *root) { // return best move after root
+ expandnode(root);
+ if (!root->son) return(0); // no move due to loss
+ if (debug) printf("calcmove() initial nodes = %d\n",nodes);
+ evaluated = 0;
+ if (root->son->brother) {
+ int x;
+ for (x = 1; abs(root->value)<28000 && fullexpand(root,x); x++);
+ piece saveboard[45]; memmove(saveboard,b,sizeof(b));
+ while (abs(root->value)<28000) {
+ x = descend(root);
+ memmove(b,saveboard,sizeof(b));
+ if (!x) break;
+ }
+ }
+ if (debug) printf(" evaluated %d, nodes = %d\n", evaluated, nodes);
+ return(root->son);
+}
+
+// the actual game state ----------------
+
+node *root,*undoroot;
+
+piece jumpboards[24][45]; // saved boards for undoing jumps
+int nextjump;
+
+char user; // 0 = black, 1 = white
+char playing;
+char autoplay;
+
+void newgame(void) {
+
+ int n;
+ for (n=0; n<5; n++) b[n] = BLUE;
+ for (n=5; n<18; n++) b[n] = WHITE;
+ for (n=18; n<27; n++) b[n] = EMPTY;
+ for (n=27; n<40; n++) b[n] = BLACK;
+ for (n=40; n<45; n++) b[n] = BLUE;
+ b[13] = b[22] = b[31] = BLUE;
+
+ centralsquares[15] = centralsquares[16] =
+ centralsquares[19] = centralsquares[20] =
+ centralsquares[24] = centralsquares[25] =
+ centralsquares[28] = centralsquares[29] = 1;
+
+ // set up initial search tree:
+ nextjump = 0;
+ killnode(undoroot);
+ undoroot = root = newnode();
+
+ // make it white's move, so first move is black:
+ root->who = 1;
+ user = 0;
+ playing = 1;
+}
+
+void domove(node* move) {
+ if (move->jump) memmove(jumpboards[nextjump++],b,sizeof(b));
+ makemove(move);
+ extract(move);
+ killnode(root->son);
+ root->son = move;
+ root = move;
+ if (debug) evaluateboard(move,1);
+}
+
+node* undomove() {
+ node *n = root;
+ if (n == undoroot) return 0; // no more undo possible
+ if (n->jump) memmove(b,jumpboards[--nextjump],sizeof(b));
+ else {
+ b[n->from] = b[n->to];
+ if (n->king) b[n->from] &= (WHITE|BLACK);
+ b[n->to] = EMPTY;
+ }
+ root = n->father;
+ killnode(n);
+ root->son = 0;
+ root->value = 0; // prevent it from thinking game is over
+ playing = 1;
+ if (root == undoroot) user = 0;
+ return n;
+}
+
+const char _usermoves[] =
+"B1D1F1H1A2C2E2G2??B3D3F3H3A4C4E4G4??B5D5F5H5A6C6E6G6??B7D7F7H7A8C8E8G8??";
+#define usermoves(x,y) _usermoves[2*((x)-5)+(y)-1]
+
+void dumpnode(node *n, int help) {
+ int x = n->from;
+ int y = n->to;
+ if (help) printf("%c%c %c%c\t- ",
+ usermoves(x,1),usermoves(x,2),
+ usermoves(y,1),usermoves(y,2));
+ printf("%s %ss from %c%c to %c%c",
+ n->who ? "White" : "Black",
+ n->jump ? "jump" : "move",
+ usermoves(x,1),usermoves(x,2),
+ usermoves(y,1),usermoves(y,2));
+ if (n->jump) {
+ for (int i=0; i<32; i++) if (n->jump & (1<<i))
+ printf(", %c%c",usermoves(10+i,1),usermoves(10+i,2));
+ printf(" removed");
+ }
+ printf(" (%+d).\n",n->value);
+}
+
+int abortflag;
+
+////////////////////////////////////////////////////////////////
+// VT100 Interface:
+#ifdef VT100
+
+void positioncursor(int i) {
+ printf("\033[%d;%dH",
+ usermoves(i,2)-'0'+1,
+ 2*(usermoves(i,1)-'A')+1);
+}
+
+void outpiecename(piece n) {
+ printf(n&BLACK ? "\033[1;7m" : "\033[1m");
+ putchar(" BW??BW??"[n]);
+ putchar(" BW??KK??"[n]);
+ printf("\033[0m");
+}
+
+void VT100board(void) {
+ printf("\033<\033[H\033[J\033[10r");
+ int l = 0;
+ puts(" A B C D E F G H");
+ for (int i=0; i<4; i++) {
+ int j = 9*i+5;
+ int k;
+ for (k=0; k<4; k++) {
+ printf("\033[7m \033[0m");
+ outpiecename(b[j+k]);
+ }
+ l++;
+ printf("%d\n",l);
+ j += 4;
+ for (k=0; k<4; k++) {
+ outpiecename(b[j+k]);
+ printf("\033[7m \033[0m");
+ }
+ l++;
+ printf("%d\n",l);
+ }
+}
+
+void VT100move(node *n, int) {
+ if (!n) return;
+ printf("\0337");
+ positioncursor(n->from);
+ outpiecename(b[n->from]);
+ positioncursor(n->to);
+ outpiecename(b[n->to]);
+ if (n->jump) for(int i=0; i<32; i++) {
+ if (n->jump & (1<<i)) {
+ positioncursor(10+i);
+ outpiecename(b[10+i]);
+ }
+ }
+ printf("\0338");
+}
+
+int decode(char *m) {
+ int i;
+ for(i=5; i<=40; i++)
+ if (toupper(m[0])==usermoves(i,1) && m[1]==usermoves(i,2)) return(i);
+ return(0);
+}
+
+#include <signal.h>
+
+static void sigint(...) {
+ abortflag = 1;
+ signal(SIGINT,sigint);
+}
+
+void fixexit(int x) {
+ printf("\0337\033[r\0338");
+ exit(x);
+}
+
+// Returns a son, or 0 if no move specified, or root to cause "help"
+node *getusermove(void) {
+ int i,j;
+ node *t;
+ char line[100],*m1,*m2;
+
+ if (playing)
+ printf("\033[1m%s's move?\033[0m ",root->who ? "Black" : "White");
+ else
+ printf("\033[1mCommand?\033[0m ");
+ abortflag = 0;
+ if (!gets(line)) {
+ putchar('\n');
+ if (feof(stdin)) fixexit(0);
+ return 0;
+ }
+ for (m1 = line; *m1 && *m1<=' '; m1++);
+ if (!*m1) return(0);
+ m2 = m1+1;
+ if (*m2) m2++;
+ for (; *m2 && *m2<'0'; m2++);
+ if (playing && m1[1]>='0' && m1[1]<='9') {
+ i = decode(m1);
+ j = decode(m2);
+ if (i && j) for (t = root->son; t; t = t->brother)
+ if (t->from == i && t->to == j) return(t);
+ puts("Valid moves are:");
+ m1[0] = 'L';
+ }
+ switch(toupper(m1[0])) {
+ case 0: return(0);
+ case 'A':
+ if (playing) autoplay = 1;
+ return(root);
+ case 'C':
+ puts(copyright);
+ break;
+ case 'D':
+ debug = !debug;
+ printf("Debug is now %s.", debug ? "on" : "off");
+ break;
+ case 'F':
+ forcejumps = !forcejumps;
+ printf("Forced jumps rule is now %s.",forcejumps ? "on" : "off");
+ killnode(root->son); root->son = 0;
+ return(0);
+ case 'L':
+ expandnode(root);
+ if (playing) for (t = root->son; t; t = t->brother) dumpnode(t,1);
+ break;
+ case 'M':
+ return(playing ? root : 0);
+ case 'N':
+ newgame();
+ VT100board();
+ return(0);
+ case 'P':
+ printf("I expect the following moves:\n");
+ for (t = root->son; t; t = t->son) dumpnode(t,0);
+ break;
+ case 'Q':
+ fixexit(0);
+ case 'R':
+ VT100board();
+ break;
+ case 'S':
+ user = !user;
+ return(root);
+ case 'U':
+ VT100move(undomove(),1);
+ VT100move(undomove(),1);
+ return(0);
+ case '+':
+ maxevaluate = maxnodes = 2*maxevaluate;
+ goto J2;
+ case '-':
+ if (maxevaluate > 1)
+ maxevaluate = maxnodes = maxevaluate/2;
+ J2: printf("Moves evaluated set to %d.",maxevaluate);
+ break;
+ default:
+ puts(
+ "A(utoplay)\n"
+ "C(opyright)\n"
+ "D(ebug on/off)\n"
+ "F(orce jumps rule on/off)\n"
+ "L(ist legal moves)\n"
+ "M(ake a move for me)\n"
+ "N(ew game)\n"
+ "P(redict next few moves)\n"
+ "Q(uit)\n"
+ "R(edraw screen)\n"
+ "S(witch sides)\n"
+ "U(ndo)\n"
+ "+ - smarter\n"
+ "- - stupider");
+ expandnode(root);
+ for (t = root->son; t; t = t->brother) dumpnode(t,1);
+ }
+ return(0);
+}
+
+int VT100main() {
+ signal(SIGINT,sigint);
+ VT100board();
+ for (;;) {
+ if (playing) {
+ expandnode(root);
+ if (!root->son) {
+ printf("%s has no move. Game over.",root->who ? "Black" : "White");
+ playing = autoplay = 0;
+ }
+ }
+ node* move;
+ if (playing && (autoplay || root->who == user)) {
+ move = calcmove(root);
+ if (move->value <= -30000) {
+ printf("%s resigns.", move->who ? "White" : "Black");
+ move = 0;
+ playing = autoplay = 0;
+ }
+ } else {
+ move = getusermove();
+ if (move == root) move = calcmove(root);
+ }
+ if (move) {
+ dumpnode(move,0);
+ domove(move);
+ VT100move(move,0);
+ }
+ }
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////
+// fltk interface:
+#ifdef FLTK
+
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Bitmap.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/fl_ask.H>
+
+//----------------------------------------------------------------
+// old 4-level NeXT images have been seperated into bitmaps so they
+// can be drawn with arbitrary colors and real transparency. This is
+// rather tedious and perhaps fltk should provide a direct support
+// to do this:
+
+#include "black_1.xbm"
+#include "black_2.xbm"
+#include "black_3.xbm"
+#include "black_4.xbm"
+#include "white_1.xbm"
+#include "white_2.xbm"
+#include "white_3.xbm"
+#include "white_4.xbm"
+#include "blackking_1.xbm"
+#include "blackking_2.xbm"
+#include "blackking_3.xbm"
+#include "blackking_4.xbm"
+#include "whiteking_1.xbm"
+#include "whiteking_2.xbm"
+#include "whiteking_3.xbm"
+#include "whiteking_4.xbm"
+
+Fl_Bitmap *bm[4][4];
+
+void make_bitmaps() {
+ if (bm[0][0]) return;
+ bm[0][0] = new Fl_Bitmap(black_1_bits, black_1_width, black_1_height);
+ bm[0][1] = new Fl_Bitmap(black_2_bits, black_1_width, black_1_height);
+ bm[0][2] = new Fl_Bitmap(black_3_bits, black_1_width, black_1_height);
+ bm[0][3] = new Fl_Bitmap(black_4_bits, black_1_width, black_1_height);
+ bm[1][0] = new Fl_Bitmap(white_1_bits, black_1_width, black_1_height);
+ bm[1][1] = new Fl_Bitmap(white_2_bits, black_1_width, black_1_height);
+ bm[1][2] = new Fl_Bitmap(white_3_bits, black_1_width, black_1_height);
+ bm[1][3] = new Fl_Bitmap(white_4_bits, black_1_width, black_1_height);
+ bm[2][0] = new Fl_Bitmap(blackking_1_bits, black_1_width, black_1_height);
+ bm[2][1] = new Fl_Bitmap(blackking_2_bits, black_1_width, black_1_height);
+ bm[2][2] = new Fl_Bitmap(blackking_3_bits, black_1_width, black_1_height);
+ bm[2][3] = new Fl_Bitmap(blackking_4_bits, black_1_width, black_1_height);
+ bm[3][0] = new Fl_Bitmap(whiteking_1_bits, black_1_width, black_1_height);
+ bm[3][1] = new Fl_Bitmap(whiteking_2_bits, black_1_width, black_1_height);
+ bm[3][2] = new Fl_Bitmap(whiteking_3_bits, black_1_width, black_1_height);
+ bm[3][3] = new Fl_Bitmap(whiteking_4_bits, black_1_width, black_1_height);
+}
+
+#define ISIZE black_1_width
+
+void draw_piece(int which, int x, int y) {
+ if (!fl_not_clipped(x,y,ISIZE,ISIZE)) return;
+ switch (which) {
+ case BLACK: which = 0; break;
+ case WHITE: which = 1; break;
+ case BLACKKING: which = 2; break;
+ case WHITEKING: which = 3; break;
+ default: return;
+ }
+ fl_color(FL_BLACK); bm[which][0]->draw(x, y);
+ fl_color(FL_INACTIVE_COLOR); bm[which][1]->draw(x, y);
+ fl_color(FL_SELECTION_COLOR);bm[which][2]->draw(x, y);
+ fl_color(FL_WHITE); bm[which][3]->draw(x, y);
+}
+
+//----------------------------------------------------------------
+
+class Board : public Fl_Double_Window {
+ void draw();
+ int handle(int);
+public:
+ void drag_piece(int, int, int);
+ void drop_piece(int);
+ void animate(node* move, int backwards);
+ void computer_move(int);
+ Board(int w, int h) : Fl_Double_Window(w,h) {color(15);}
+};
+
+#define BOXSIZE 52
+#define BORDER 4
+#define BOARDSIZE (8*BOXSIZE+BORDER)
+#define BMOFFSET 5
+
+static int erase_this; // real location of dragging piece, don't draw it
+static int dragging; // piece being dragged
+static int dragx; // where it is
+static int dragy;
+static int showlegal; // show legal moves
+
+int squarex(int i) {return (usermoves(i,1)-'A')*BOXSIZE+BMOFFSET;}
+int squarey(int i) {return (usermoves(i,2)-'1')*BOXSIZE+BMOFFSET;}
+
+void Board::draw() {
+ make_bitmaps();
+ fl_draw_box(box(),0,0,w(),h(),color());
+ fl_color((Fl_Color)10 /*107*/);
+ int x; for (x=0; x<8; x++) for (int y=0; y<8; y++) {
+ if (!((x^y)&1)) fl_rectf(BORDER+x*BOXSIZE, BORDER+y*BOXSIZE,
+ BOXSIZE-BORDER, BOXSIZE-BORDER);
+ }
+ fl_color(FL_DARK3 /*FL_GRAY_RAMP+4*/);
+ for (x=0; x<9; x++) {
+ fl_rectf(x*BOXSIZE,0,BORDER,h());
+ fl_rectf(0,x*BOXSIZE,w(),BORDER);
+ }
+ for (int i = 5; i < 40; i++) if (i != erase_this) {
+ draw_piece(b[i], squarex(i), squarey(i));
+ }
+ if (showlegal) {
+ fl_color(FL_WHITE);
+ node* n;
+ for (n = root->son; n; n = showlegal==2 ? n->son : n->brother) {
+ int x1 = squarex(n->from)+BOXSIZE/2-5;
+ int y1 = squarey(n->from)+BOXSIZE/2-5;
+ int x2 = squarex(n->to)+BOXSIZE/2-5;
+ int y2 = squarey(n->to)+BOXSIZE/2-5;
+ fl_line(x1,y1,x2,y2);
+ fl_push_matrix();
+ fl_mult_matrix(x2-x1,y2-y1,y1-y2,x2-x1,x2,y2);
+ fl_begin_polygon();
+ fl_vertex(0,0);
+ fl_vertex(-.3, .1);
+ fl_vertex(-.3, -.1);
+ fl_end_polygon();
+ fl_pop_matrix();
+ }
+ int num = 1;
+ fl_color(FL_BLACK);
+ fl_font(FL_BOLD,10);
+ for (n = root->son; n; n = showlegal==2 ? n->son : n->brother) {
+ int x1 = squarex(n->from)+BOXSIZE/2-5;
+ int y1 = squarey(n->from)+BOXSIZE/2-5;
+ int x2 = squarex(n->to)+BOXSIZE/2-5;
+ int y2 = squarey(n->to)+BOXSIZE/2-5;
+ char buf[20]; sprintf(buf,"%d",num);
+ fl_draw(buf, x1+int((x2-x1)*.85)-3, y1+int((y2-y1)*.85)+5);
+ num++;
+ }
+ }
+ if (dragging) draw_piece(dragging, dragx, dragy);
+}
+
+// drag the piece on square i to dx dy, or undo drag if i is zero:
+void Board::drag_piece(int i, int dx, int dy) {
+ dy = (dy&-2) | dx&1; // make halftone shadows line up
+ if (i != erase_this) drop_piece(erase_this); // should not happen
+ if (!erase_this) { // pick up old piece
+ dragx = squarex(i); dragy = squarey(i);
+ erase_this = i;
+ dragging = b[i];
+ }
+ if (dx != dragx || dy != dragy) {
+ damage(4, dragx, dragy, ISIZE, ISIZE);
+ damage(4, dx, dy, ISIZE, ISIZE);
+ }
+ dragx = dx;
+ dragy = dy;
+}
+
+// drop currently dragged piece on square i
+void Board::drop_piece(int i) {
+ if (!erase_this) return; // should not happen!
+ erase_this = 0;
+ dragging = 0;
+ int x = squarex(i);
+ int y = squarey(i);
+ if (x != dragx || y != dragy) {
+ damage(4, dragx, dragy, ISIZE, ISIZE);
+ damage(4, x, y, ISIZE, ISIZE);
+ }
+}
+
+// show move (call this *before* the move, *after* undo):
+void Board::animate(node* move, int backwards) {
+ if (showlegal) {showlegal = 0; redraw();}
+ if (!move) return;
+ int f = move->from;
+ int t = move->to;
+ if (backwards) {int x = f; f = t; t = x;}
+ int x1 = squarex(f);
+ int y1 = squarey(f);
+ int x2 = squarex(t);
+ int y2 = squarey(t);
+ const int STEPS=35;
+ for (int i=0; i<STEPS; i++) {
+ int x = x1+(x2-x1)*i/STEPS;
+ int y = y1+(y2-y1)*i/STEPS;
+ drag_piece(move->from,x,y);
+ Fl::flush();
+ }
+ drop_piece(t);
+ if (move->jump) redraw();
+}
+
+int busy; // causes pop-up abort menu
+
+void message(const char* m, ...) {
+ char buffer[2048];
+ va_list a;
+ va_start(a,m);
+ vsprintf(buffer, m, a);
+ va_end(a);
+ fl_message(buffer);
+}
+
+void Board::computer_move(int help) {
+ if (!playing) return;
+ cursor(FL_CURSOR_WAIT);
+ Fl::flush();
+ busy = 1; abortflag = 0;
+ node* move = calcmove(root);
+ busy = 0;
+ if (move) {
+ if (!help && move->value <= -30000) {
+ message("%s resigns", move->who ? "White" : "Black");
+ playing = autoplay = 0;
+ cursor(FL_CURSOR_DEFAULT);
+ return;
+ }
+ animate(move,0);
+ domove(move);
+ }
+ expandnode(root);
+ if (!root->son) {
+ message("%s has no move", root->who ? "Black" : "White");
+ playing = autoplay = 0;
+ }
+ if (!autoplay) cursor(FL_CURSOR_DEFAULT);
+}
+
+extern Fl_Menu_Item menu[];
+extern Fl_Menu_Item busymenu[];
+
+int Board::handle(int e) {
+ if (busy) {
+ const Fl_Menu_Item* m;
+ switch(e) {
+ case FL_PUSH:
+ m = busymenu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
+ if (m) m->do_callback(this, (void*)m);
+ return 1;
+ case FL_SHORTCUT:
+ m = busymenu->test_shortcut();
+ if (m) {m->do_callback(this, (void*)m); return 1;}
+ return 0;
+ default:
+ return 0;
+ }
+ }
+ node *t, *n;
+ static int deltax, deltay;
+ int dist;
+ const Fl_Menu_Item* m;
+ switch (e) {
+ case FL_PUSH:
+ if (Fl::event_button() > 1) {
+ m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
+ if (m) m->do_callback(this, (void*)m);
+ return 1;
+ }
+ if (playing) {
+ expandnode(root);
+ for (t = root->son; t; t = t->brother) {
+ int x = squarex(t->from);
+ int y = squarey(t->from);
+ if (Fl::event_inside(x,y,BOXSIZE,BOXSIZE)) {
+ deltax = Fl::event_x()-x;
+ deltay = Fl::event_y()-y;
+ drag_piece(t->from,x,y);
+ return 1;
+ }
+ }
+ }
+ return 0;
+ case FL_SHORTCUT:
+ m = menu->test_shortcut();
+ if (m) {m->do_callback(this, (void*)m); return 1;}
+ return 0;
+ case FL_DRAG:
+ drag_piece(erase_this, Fl::event_x()-deltax, Fl::event_y()-deltay);
+ return 1;
+ case FL_RELEASE:
+ // find the closest legal move he dropped it on:
+ dist = 50*50; n = 0;
+ for (t = root->son; t; t = t->brother) if (t->from==erase_this) {
+ int d1 = Fl::event_x()-deltax-squarex(t->to);
+ int d = d1*d1;
+ d1 = Fl::event_y()-deltay-squarey(t->to);
+ d += d1*d1;
+ if (d < dist) {dist = d; n = t;}
+ }
+ if (!n) {drop_piece(erase_this); return 1;} // none found
+ drop_piece(n->to);
+ domove(n);
+ if (showlegal) {showlegal = 0; redraw();}
+ if (n->jump) redraw();
+ computer_move(0);
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+void quit_cb(Fl_Widget*, void*) {exit(0);}
+
+int FLTKmain(int argc, char** argv) {
+ Board b(BOARDSIZE,BOARDSIZE);
+ b.callback(quit_cb);
+ b.show(argc,argv);
+ return Fl::run();
+}
+
+void autoplay_cb(Fl_Widget*bp, void*) {
+ if (autoplay) {autoplay = 0; return;}
+ if (!playing) return;
+ Board* b = (Board*)bp;
+ autoplay = 1;
+ while (autoplay) {b->computer_move(0); b->computer_move(0);}
+}
+
+#include <FL/Fl_Box.H>
+Fl_Window *copyright_window;
+void copyright_cb(Fl_Widget*, void*) {
+ if (!copyright_window) {
+ copyright_window = new Fl_Window(400,270,"Copyright");
+ copyright_window->color(FL_WHITE);
+ Fl_Box *b = new Fl_Box(20,0,380,270,copyright);
+ b->labelsize(10);
+ b->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+ copyright_window->end();
+ }
+ copyright_window->hotspot(copyright_window);
+ copyright_window->set_non_modal();
+ copyright_window->show();
+}
+
+void debug_cb(Fl_Widget*, void*v) {
+ debug = !debug;
+ ((Fl_Menu_Item*)v)->flags =
+ debug ? FL_MENU_TOGGLE|FL_MENU_VALUE : FL_MENU_TOGGLE;
+}
+
+void forced_cb(Fl_Widget*b, void*v) {
+ forcejumps = !forcejumps;
+ ((Fl_Menu_Item*)v)->flags =
+ forcejumps ? FL_MENU_TOGGLE|FL_MENU_VALUE : FL_MENU_TOGGLE;
+ killnode(root->son); root->son = 0;
+ if (showlegal) {expandnode(root); b->redraw();}
+}
+
+void move_cb(Fl_Widget*pb, void*) {
+ Board* b = (Board*)pb;
+ if (playing) b->computer_move(1);
+ if (playing) b->computer_move(0);
+}
+
+void newgame_cb(Fl_Widget*b, void*) {
+ showlegal = 0;
+ newgame();
+ b->redraw();
+}
+
+void legal_cb(Fl_Widget*pb, void*) {
+ if (showlegal == 1) {showlegal = 0; ((Board*)pb)->redraw(); return;}
+ if (!playing) return;
+ expandnode(root);
+ showlegal = 1; ((Board*)pb)->redraw();
+}
+
+void predict_cb(Fl_Widget*pb, void*) {
+ if (showlegal == 2) {showlegal = 0; ((Board*)pb)->redraw(); return;}
+ if (playing) expandnode(root);
+ showlegal = 2; ((Board*)pb)->redraw();
+}
+
+void switch_cb(Fl_Widget*pb, void*) {
+ user = !user;
+ ((Board*)pb)->computer_move(0);
+}
+
+void undo_cb(Fl_Widget*pb, void*) {
+ Board* b = (Board*)pb;
+ b->animate(undomove(),1);
+ b->animate(undomove(),1);
+}
+
+//--------------------------
+
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Value_Output.H>
+
+Fl_Window *intel_window;
+Fl_Value_Output *intel_output;
+
+void intel_slider_cb(Fl_Widget*w, void*) {
+ double v = ((Fl_Slider*)w)->value();
+ int n = int(v*v);
+ intel_output->value(n);
+ maxevaluate = maxnodes = n;
+}
+
+void intel_cb(Fl_Widget*, void*) {
+ if (!intel_window) {
+ intel_window = new Fl_Window(200,25,"Checkers Intelligence");
+ Fl_Slider* s = new Fl_Slider(60,0,140,25);
+ s->type(FL_HOR_NICE_SLIDER);
+ s->minimum(1); s->maximum(500); s->value(50);
+ s->callback(intel_slider_cb);
+ intel_output = new Fl_Value_Output(0,0,60,25);
+ intel_output->value(maxevaluate);
+ intel_window->resizable(s);
+ }
+ intel_window->hotspot(intel_window);
+ intel_window->set_non_modal();
+ intel_window->show();
+}
+
+//---------------------------
+
+void stop_cb(Fl_Widget*, void*) {abortflag = 1;}
+
+void continue_cb(Fl_Widget*, void*) {}
+
+Fl_Menu_Item menu[] = {
+ {"Autoplay", 'a', autoplay_cb},
+ {"Legal moves", 'l', legal_cb},
+ {"Move for me", 'm', move_cb},
+ {"New game", 'n', newgame_cb},
+ {"Predict", 'p', predict_cb},
+ {"Switch sides", 's', switch_cb},
+ {"Undo", 'u', undo_cb, 0, FL_MENU_DIVIDER},
+ {"Forced jumps rule", 'f', forced_cb, 0, FL_MENU_TOGGLE|FL_MENU_VALUE},
+ {"Debug", 'd', debug_cb, "d", FL_MENU_TOGGLE},
+ {"Intelligence...", 'i', intel_cb, 0, FL_MENU_DIVIDER},
+ {"Copyright", 'c', copyright_cb},
+ {"Quit", 'q', quit_cb},
+ {0}};
+
+Fl_Menu_Item busymenu[] = {
+ {"Stop", '.', stop_cb},
+ {"Autoplay", 'a', autoplay_cb},
+ {"Continue", 0, continue_cb},
+ {"Debug", 'd', debug_cb, "d", FL_MENU_TOGGLE},
+ {"Intelligence...", 'i', intel_cb},
+ {"Copyright", 'c', copyright_cb},
+ {"Quit", 'q', quit_cb},
+ {0}};
+
+#endif
+
+////////////////////////////////////////////////////////////////
+// parts shared by both interface:
+
+#ifdef FLTK
+#ifdef VT100
+#define BOTH
+#endif
+#endif
+
+#ifdef BOTH
+int terminal;
+int arg(int, char **argv, int &i) {
+ if (argv[i][1] == 't') {terminal = 1; i++; return 1;}
+ return 0;
+}
+#endif
+
+int didabort(void) {
+#ifdef FLTK
+#ifdef BOTH
+ if (!terminal)
+#endif
+ Fl::check();
+#endif
+ if (abortflag) {
+ autoplay = 0;
+ abortflag = 0;
+ return 1;
+ }
+ return(0);
+}
+
+int main(int argc, char **argv) {
+ seed = time(0);
+ newgame();
+#ifdef BOTH
+ int i = 1;
+ if (Fl::args(argc, argv, i, arg) < argc) {
+ fprintf(stderr," -t : use VT100 display\n", Fl::help);
+ exit(1);
+ }
+ if (!getenv("DISPLAY")) terminal = 1;
+ if (!terminal)
+#endif
+#ifdef FLTK
+ return FLTKmain(argc,argv);
+#endif
+#ifdef VT100
+ return VT100main();
+#endif
+}
diff --git a/test/clock.cxx b/test/clock.cxx
new file mode 100644
index 000000000..0210a4e2a
--- /dev/null
+++ b/test/clock.cxx
@@ -0,0 +1,24 @@
+// produce images for documentation
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Clock.H>
+#include <FL/Fl_Round_Clock.H>
+
+int main(int argc, char **argv) {
+ Fl_Window window(220,220,"Fl_Clock");
+ Fl_Clock c1(0,0,220,220); // c1.color(2,1);
+ window.resizable(c1);
+ window.end();
+ Fl_Window window2(220,220,"Fl_Round_Clock");
+ Fl_Round_Clock c2(0,0,220,220); // c2.color(3,4);
+ window2.resizable(c2);
+ window2.end();
+ // my machine had a clock* Xresource set for another program, so
+ // I don't want the class to be "clock":
+ window.xclass("Fl_Clock");
+ window2.xclass("Fl_Clock");
+ window.show(argc,argv);
+ window2.show();
+ return Fl::run();
+}
diff --git a/test/colbrowser.cxx b/test/colbrowser.cxx
new file mode 100644
index 000000000..8ee56d3ee
--- /dev/null
+++ b/test/colbrowser.cxx
@@ -0,0 +1,316 @@
+// This is an XForms program from the 0.86 distribution of XForms.
+// It has been modified as little as possible to work under fltk by
+// using fltk's Forms emulation.
+// Search for "fltk" to find all the changes
+
+#include <FL/forms.H> // changed for fltk
+#include <stdlib.h>
+#include <stdio.h> // added for fltk
+#include <string.h> // added for fltk
+
+#define MAX_RGB 3000
+
+static FL_FORM *cl;
+static Fl_Widget *rescol, *dbobj, *colbr, *rs, *gs, *bs;
+char dbname[FL_PATH_MAX];
+static void create_form_cl(void);
+static int load_browser(char *);
+
+/* the RGB data file does not have a standard location on unix. */
+
+#ifdef __VMS
+ static char *rgbfile = "SYS$MANAGER:DECW$RGB.DAT";
+#else
+#ifdef __EMX__ /* OS2 */
+ static char *rgbfile = "/XFree86/lib/X11/rgb.txt";
+#else
+#ifdef __FreeBSD__
+ static char *rgbfile = "/usr/X11R6/lib/X11/rgb.txt";
+#else
+ static char *rgbfile = "/usr/lib/X11/rgb.txt";
+#endif
+#endif
+#endif
+
+typedef struct { int r, g, b; } RGBdb;
+
+static RGBdb rgbdb[MAX_RGB];
+
+int
+main(int argc, char *argv[])
+{
+
+ fl_initialize(&argc, argv, "FormDemo", 0, 0);
+
+ create_form_cl();
+ strcpy(dbname, rgbfile);
+
+ if (load_browser(dbname))
+ fl_set_object_label(dbobj, dbname);
+ else
+ fl_set_object_label(dbobj, "None");
+
+// fl_set_form_minsize(cl, cl->w , cl->h); // removed for fltk
+// fl_set_form_maxsize(cl, 2*cl->w , 2*cl->h); // removed for fltk
+ cl->size_range(cl->w(),cl->h(),2*cl->w(),2*cl->h()); // added for fltk
+ // border changed from FL_TRANSIENT for fltk:
+ // This is so Esc & the close box will close the window.
+ // (on transient windows attempting to close it just calls the callback)
+ fl_show_form(cl, FL_PLACE_FREE, 1/*FL_TRANSIENT*/, "RGB Browser");
+
+
+ while (fl_do_forms())
+ ;
+ return 0;
+}
+
+static void
+set_entry(int i)
+{
+ RGBdb *db = rgbdb + i;
+
+ fl_freeze_form(cl);
+// unclear why demo is doing this. This messes up FL:
+// fl_mapcolor(FL_FREE_COL4+i, db->r, db->g, db->b);
+ fl_mapcolor(FL_FREE_COL4, db->r, db->g, db->b);
+ fl_set_slider_value(rs, db->r);
+ fl_set_slider_value(gs, db->g);
+ fl_set_slider_value(bs, db->b);
+ fl_redraw_object(rescol);
+ fl_unfreeze_form(cl);
+}
+
+static void
+br_cb(Fl_Widget * ob, long)
+{
+ int r = fl_get_browser(ob);
+
+ if (r <= 0)
+ return;
+ set_entry(r - 1);
+}
+
+static int
+read_entry(FILE * fp, int *r, int *g, int *b, char *name)
+{
+ int n;
+ char buf[512], *p;
+
+ if (!fgets(buf, sizeof(buf) - 1, fp))
+ return 0;
+
+ if(buf[0] == '!')
+ fgets(buf,sizeof(buf)-1,fp);
+
+ if(sscanf(buf, " %d %d %d %n", r, g, b, &n) < 3)
+ return 0;
+
+ p = buf + n;
+
+ /* squeeze out all spaces */
+ while (*p)
+ {
+ if (*p != ' ' && *p != '\n')
+ *name++ = *p;
+ p++;
+ }
+ *name = 0;
+
+ return (feof(fp) || ferror(fp)) ? 0 : 1;
+}
+
+
+static int
+load_browser(char *fname)
+{
+ FILE *fp;
+ RGBdb *db = rgbdb, *dbs = db + MAX_RGB;
+ int r, g, b, lr = -1 , lg = -1, lb = -1;
+ char name[256], buf[256];
+#ifdef __EMX__
+ extern char *__XOS2RedirRoot(const char*);
+ if (!(fp = fopen(__XOS2RedirRoot(fname), "r")))
+#else
+ if (!(fp = fopen(fname, "r")))
+#endif
+ {
+ fl_show_alert("Load", fname, "Can't open", 0);
+ return 0;
+ }
+
+ /* read the items */
+
+ fl_freeze_form(cl);
+
+ for (; db < dbs && read_entry(fp, &r, &g, &b, name);)
+ {
+ db->r = r;
+ db->g = g;
+ db->b = b;
+
+ /* unique the entries on the fly */
+ if (lr != r || lg != g || lb != b)
+ {
+ db++;
+ lr = r;
+ lg = g;
+ lb = b;
+ sprintf(buf, "(%3d %3d %3d) %s", r, g, b, name);
+ fl_addto_browser(colbr, buf);
+ }
+ }
+ fclose(fp);
+
+ if (db < dbs)
+ db->r = 1000; /* sentinel */
+ else
+ {
+ db--;
+ db->r = 1000;
+ }
+
+ fl_set_browser_topline(colbr, 1);
+ fl_select_browser_line(colbr, 1);
+ set_entry(0);
+ fl_unfreeze_form(cl);
+ return 1;
+}
+
+static int
+search_entry(int r, int g, int b)
+{
+ register RGBdb *db = rgbdb;
+ int i, j, diffr, diffg, diffb;
+ unsigned int diff, mindiff;
+
+ mindiff = ~0;
+ for (i = j = 0; db->r < 256; db++, i++)
+ {
+ diffr = r - db->r;
+ diffg = g - db->g;
+ diffb = b - db->b;
+
+#ifdef FL_LINEAR
+ diff = unsigned(3.0 * (FL_abs(r - db->r)) +
+ (5.9 * FL_abs(g - db->g)) +
+ (1.1 * (FL_abs(b - db->b)));
+#else
+ diff = unsigned(3.0 * (diffr *diffr) +
+ 5.9 * (diffg *diffg) +
+ 1.1 * (diffb *diffb));
+#endif
+
+ if (mindiff > diff)
+ {
+ mindiff = diff;
+ j = i;
+ }
+ }
+
+ return j;
+}
+
+static void
+search_rgb(Fl_Widget *, long)
+{
+ int r, g, b, i;
+ int top = fl_get_browser_topline(colbr);
+
+ r = int(fl_get_slider_value(rs));
+ g = int(fl_get_slider_value(gs));
+ b = int(fl_get_slider_value(bs));
+
+ fl_freeze_form(cl);
+ fl_mapcolor(FL_FREE_COL4, r, g, b);
+ fl_redraw_object(rescol);
+ i = search_entry(r, g, b);
+ /* change topline only if necessary */
+ if(i < top || i > (top+15))
+ fl_set_browser_topline(colbr, i-8);
+ fl_select_browser_line(colbr, i + 1);
+ fl_unfreeze_form(cl);
+}
+
+/* change database */
+static void
+db_cb(Fl_Widget * ob, long)
+{
+ const char *p = fl_show_input("Enter New Database Name", dbname);
+ char buf[512];
+
+ if (!p || strcmp(p, dbname) == 0)
+ return;
+
+ strcpy(buf, p);
+ if (load_browser(buf))
+ strcpy(dbname, buf);
+ else
+ fl_set_object_label(ob, dbname);
+}
+
+static void
+done_cb(Fl_Widget *, long)
+{
+ exit(0);
+}
+
+static void
+create_form_cl(void)
+{
+ Fl_Widget *obj;
+
+ if (cl)
+ return;
+
+ cl = fl_bgn_form(FL_NO_BOX, 330, 385);
+ obj = fl_add_box(FL_UP_BOX, 0, 0, 330, 385, "");
+ fl_set_object_color(obj, FL_INDIANRED, FL_COL1);
+
+ obj = fl_add_box(FL_NO_BOX, 40, 10, 250, 30, "Color Browser");
+ fl_set_object_lcol(obj, FL_RED);
+ fl_set_object_lsize(obj, FL_HUGE_SIZE);
+ fl_set_object_lstyle(obj, FL_BOLD_STYLE + FL_SHADOW_STYLE);
+
+ dbobj = obj = fl_add_button(FL_NORMAL_BUTTON, 40, 50, 250, 25, "");
+ fl_set_object_boxtype(obj, FL_BORDER_BOX);
+ fl_set_object_color(obj, /*fl_get_visual_depth()==1 ? FL_WHITE:*/ FL_INDIANRED,
+ FL_INDIANRED);
+ fl_set_object_callback(obj, db_cb, 0);
+ rs = obj = fl_add_valslider(FL_VERT_FILL_SLIDER, 225, 130, 30, 200, "");
+ fl_set_object_color(obj, FL_INDIANRED, FL_RED);
+ fl_set_slider_bounds(obj, 0, 255);
+ fl_set_slider_precision(obj, 0);
+ fl_set_object_callback(obj, search_rgb, 0);
+ fl_set_slider_return(obj, 0);
+
+ gs = obj = fl_add_valslider(FL_VERT_FILL_SLIDER, 255, 130, 30, 200, "");
+ fl_set_object_color(obj, FL_INDIANRED, FL_GREEN);
+ fl_set_slider_bounds(obj, 0, 255);
+ fl_set_slider_precision(obj, 0);
+ fl_set_object_callback(obj, search_rgb, 1);
+ fl_set_slider_return(obj, 0);
+
+ bs = obj = fl_add_valslider(FL_VERT_FILL_SLIDER, 285, 130, 30, 200, "");
+ fl_set_object_color(obj, FL_INDIANRED, FL_BLUE);
+ fl_set_slider_bounds(obj, 0, 255);
+ fl_set_slider_precision(obj, 0);
+ fl_set_object_callback(obj, search_rgb, 2);
+ fl_set_slider_return(obj, 0);
+
+
+ colbr = obj = fl_add_browser(FL_HOLD_BROWSER, 10, 90, 205, 240, "");
+ fl_set_browser_fontstyle(obj, FL_FIXED_STYLE);
+ fl_set_object_callback(obj, br_cb, 0);
+
+
+ obj = fl_add_button(FL_NORMAL_BUTTON, 135, 345, 80, 30, "Done");
+ fl_set_object_callback(obj, done_cb, 0);
+
+ rescol = obj = fl_add_box(FL_FLAT_BOX, 225, 90, 90, 35, "");
+ fl_set_object_color(obj, FL_FREE_COL4, FL_FREE_COL4);
+ fl_set_object_boxtype(obj, FL_BORDER_BOX);
+
+
+ fl_end_form();
+ fl_scale_form(cl, 1.1, 1.0);
+}
diff --git a/test/color_chooser.cxx b/test/color_chooser.cxx
new file mode 100644
index 000000000..9cdcbd36a
--- /dev/null
+++ b/test/color_chooser.cxx
@@ -0,0 +1,125 @@
+/* Test forcing fltk to draw in different visuals:
+
+ This also tests fl_show_colormap and Fl_Color_Chooser
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/fl_show_colormap.H>
+#include <FL/Fl_Color_Chooser.H>
+#include <FL/Fl_Image.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "list_visuals.C"
+
+int width = 75;
+int height = 75;
+uchar *image;
+
+void make_image() {
+ image = new uchar[3*width*height];
+ uchar *p = image;
+ for (int y = 0; y < height; y++) {
+ double Y = double(y)/(height-1);
+ for (int x = 0; x < width; x++) {
+ double X = double(x)/(width-1);
+ *p++ = uchar(255*((1-X)*(1-Y))); // red in upper-left
+ *p++ = uchar(255*((1-X)*Y)); // green in lower-left
+ *p++ = uchar(255*(X*Y)); // blue in lower-right
+ }
+ }
+}
+
+class Pens : public Fl_Box {
+ void draw();
+public:
+ Pens(int X, int Y, int W, int H, const char* L)
+ : Fl_Box(X,Y,W,H,L) {}
+};
+void Pens::draw() {
+ // use every color in the gray ramp:
+ for (int i = 0; i < 3*8; i++) {
+ fl_color((Fl_Color)(FL_GRAY_RAMP+i));
+ fl_line(x()+i, y(), x()+i, y()+h());
+ }
+}
+
+Fl_Color c = FL_GRAY;
+#define fullcolor_cell (FL_FREE_COLOR)
+
+void cb1(Fl_Widget *, void *v) {
+ c = fl_show_colormap(c);
+ Fl_Box* b = (Fl_Box*)v;
+ b->color(c);
+ b->parent()->redraw();
+}
+
+void cb2(Fl_Widget *, void *v) {
+ uchar r,g,b;
+ Fl::get_color(c,r,g,b);
+ if (!fl_color_chooser("New color:",r,g,b)) return;
+ c = fullcolor_cell;
+ Fl::set_color(fullcolor_cell,r,g,b);
+ Fl_Box* bx = (Fl_Box*)v;
+ bx->color(fullcolor_cell);
+ bx->parent()->redraw();
+}
+
+int main(int argc, char ** argv) {
+ Fl::set_color(fullcolor_cell,145,159,170);
+ Fl_Window window(400,400);
+ Fl_Box box(50,50,300,300);
+ box.box(FL_THIN_DOWN_BOX);
+ c = fullcolor_cell;
+ box.color(c);
+ Fl_Button b1(140,120,120,30,"fl_show_colormap");
+ b1.callback(cb1,&box);
+ Fl_Button b2(140,160,120,30,"fl_choose_color");
+ b2.callback(cb2,&box);
+ Fl_Box image_box(140,200,120,120,0);
+ make_image();
+ (new Fl_Image(image, width, height))->label(&image_box);
+ Fl_Box b(140,320,120,0,"Example of fl_draw_image()");
+ Pens p(80,200,3*8,120,"lines");
+ p.align(FL_ALIGN_TOP);
+ int i = 1;
+ if (!Fl::args(argc,argv,i) || i != argc-1) {
+ printf("usage: %s <switches> visual-number\n"
+ " - : default visual\n"
+ " r : call Fl::visual(FL_RGB)\n"
+ " c : call Fl::own_colormap()\n",argv[0]);
+#ifndef WIN32
+ printf(" # : use this visual with an empty colormap:\n");
+ list_visuals();
+#endif
+ puts(Fl::help);
+ exit(1);
+ }
+ if (argv[i][0] == 'r') {
+ if (!Fl::visual(FL_RGB)) printf("Fl::visual(FL_RGB) returned false.\n");
+ } else if (argv[i][0] == 'c') {
+ Fl::own_colormap();
+ } else if (argv[i][0] != '-') {
+#ifndef WIN32
+ int visid = atoi(argv[i]);
+ fl_open_display();
+ XVisualInfo templt; int num;
+ templt.visualid = visid;
+ fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+ if (!fl_visual) Fl::fatal("No visual with id %d",visid);
+ fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ fl_xpixel(FL_BLACK); // make sure black is allocated
+#else
+ Fl::fatal("Visual id's not supported on MSWindows");
+#endif
+ }
+ window.show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/connect.cxx b/test/connect.cxx
new file mode 100644
index 000000000..26fd02d07
--- /dev/null
+++ b/test/connect.cxx
@@ -0,0 +1,47 @@
+/* connect.C
+
+ Program to make a button to turn a ppp connection on/off.
+ You must chmod +s /usr/sbin/pppd, and put all the options
+ into /etc/ppp/options.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Toggle_Button.H>
+
+int running; // actually the pid
+Fl_Toggle_Button *Button;
+
+void sigchld(int) {
+ running = 0;
+ Button->value(0);
+}
+
+void cb(Fl_Widget *o, void *) {
+ if (((Fl_Toggle_Button*)o)->value()) {
+ if (running) return;
+ running = fork();
+ if (!running) execl("/usr/sbin/pppd","pppd","-detach",0);
+ else signal(SIGCHLD, sigchld);
+ } else {
+ if (!running) return;
+ kill(running, SIGINT);
+ running = 0;
+ }
+}
+
+int main(int argc, char ** argv) {
+ Fl_Window window(100,50);
+ Fl_Toggle_Button button(0,0,100,50,"Connect");
+ Button = &button;
+ button.color(1,2);
+ button.callback(cb,0);
+ window.show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/cube.cxx b/test/cube.cxx
new file mode 100644
index 000000000..ec8ed9892
--- /dev/null
+++ b/test/cube.cxx
@@ -0,0 +1,147 @@
+/* demo08 rewritten to not use Forms compatability */
+
+// Modified to have 2 cubes to test multiple OpenGL contexts
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Radio_Light_Button.H>
+#include <FL/Fl_Slider.H>
+#include <stdlib.h>
+
+#if !HAVE_GL
+class cube_box : public Fl_Box {
+public:
+ double lasttime;
+ int wire;
+ double size;
+ double speed;
+ cube_box(int x,int y,int w,int h,const char *l=0)
+ :Fl_Box(FL_DOWN_BOX,x,y,w,h,l){
+ label("This demo does\nnot work without GL");
+ }
+};
+#else
+#include <FL/Fl_Gl_Window.H>
+#include <FL/gl.h>
+
+class cube_box : public Fl_Gl_Window {
+ void draw();
+public:
+ double lasttime;
+ int wire;
+ double size;
+ double speed;
+ cube_box(int x,int y,int w,int h,const char *l=0)
+ : Fl_Gl_Window(x,y,w,h,l) {lasttime = 0.0;}
+};
+
+/* The cube definition */
+float v0[3] = {0.0, 0.0, 0.0};
+float v1[3] = {1.0, 0.0, 0.0};
+float v2[3] = {1.0, 1.0, 0.0};
+float v3[3] = {0.0, 1.0, 0.0};
+float v4[3] = {0.0, 0.0, 1.0};
+float v5[3] = {1.0, 0.0, 1.0};
+float v6[3] = {1.0, 1.0, 1.0};
+float v7[3] = {0.0, 1.0, 1.0};
+
+#define v3f(x) glVertex3fv(x)
+
+void drawcube(int wire) {
+/* Draw a colored cube */
+ glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
+ glColor3ub(0,0,255);
+ v3f(v0); v3f(v1); v3f(v2); v3f(v3);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
+ glColor3ub(0,255,255); v3f(v4); v3f(v5); v3f(v6); v3f(v7);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
+ glColor3ub(255,0,255); v3f(v0); v3f(v1); v3f(v5); v3f(v4);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
+ glColor3ub(255,255,0); v3f(v2); v3f(v3); v3f(v7); v3f(v6);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
+ glColor3ub(0,255,0); v3f(v0); v3f(v4); v3f(v7); v3f(v3);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
+ glColor3ub(255,0,0); v3f(v1); v3f(v2); v3f(v6); v3f(v5);
+ glEnd();
+}
+
+void cube_box::draw() {
+ lasttime = lasttime+speed;
+ if (!valid()) {
+ glLoadIdentity();
+ glViewport(0,0,w(),h());
+ glEnable(GL_DEPTH_TEST);
+ glFrustum(-1,1,-1,1,2,10000);
+ glTranslatef(0,0,-10);
+ }
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glPushMatrix();
+ glRotatef(float(lasttime*1.6),0,0,1);
+ glRotatef(float(lasttime*4.2),1,0,0);
+ glRotatef(float(lasttime*2.3),0,1,0);
+ glTranslatef(-1.0, 1.2f, -1.5);
+ glScalef(float(size),float(size),float(size));
+ drawcube(wire);
+ glPopMatrix();
+}
+
+#endif
+
+Fl_Window *form;
+Fl_Slider *speed, *size;
+Fl_Button *button, *wire, *flat;
+cube_box *cube, *cube2;
+
+void makeform(const char *name) {
+ form = new Fl_Window(510+390,390,name);
+ new Fl_Box(FL_DOWN_FRAME,20,20,350,350,"");
+ new Fl_Box(FL_DOWN_FRAME,510,20,350,350,"");
+ speed = new Fl_Slider(FL_VERT_SLIDER,390,90,40,220,"Speed");
+ size = new Fl_Slider(FL_VERT_SLIDER,450,90,40,220,"Size");
+ wire = new Fl_Radio_Light_Button(390,20,100,30,"Wire");
+ flat = new Fl_Radio_Light_Button(390,50,100,30,"Flat");
+ button = new Fl_Button(390,340,100,30,"Exit");
+ cube = new cube_box(23,23,344,344, 0);
+ cube2 = new cube_box(513,23,344,344, 0);
+ Fl_Box *b = new Fl_Box(FL_NO_BOX,cube->x(),size->y(),
+ cube->w(),size->h(),0);
+ form->resizable(b);
+ b->hide();
+ form->end();
+}
+
+main(int argc, char **argv) {
+ makeform(argv[0]);
+ speed->bounds(4,0);
+ speed->value(cube->speed = cube2->speed = 1.0);
+ size->bounds(4,0.01);
+ size->value(cube->size = cube2->size = 1.0);
+ flat->value(1); cube->wire = 0; cube2->wire = 1;
+ form->label("cube");
+ form->show(argc,argv);
+ cube->show();
+ cube2->show();
+ for (;;) {
+ if (form->visible() && speed->value())
+ {if (!Fl::check()) break;} // returns immediately
+ else
+ {if (!Fl::wait()) break;} // waits until something happens
+ cube->wire = wire->value();
+ cube2->wire = !wire->value();
+ cube->size = cube2->size = size->value();
+ cube->speed = cube2->speed = speed->value();
+ cube->redraw();
+ cube2->redraw();
+ if (Fl::readqueue() == button) break;
+ }
+ return 0;
+}
+
diff --git a/test/cursor.cxx b/test/cursor.cxx
new file mode 100644
index 000000000..7eebe9da8
--- /dev/null
+++ b/test/cursor.cxx
@@ -0,0 +1,138 @@
+// cursor.C
+
+// Test the cursor setting code
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Hor_Value_Slider.H>
+#include <FL/Fl_Choice.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Box.H>
+
+Fl_Color fg = FL_BLACK;
+Fl_Color bg = FL_WHITE;
+Fl_Cursor cursor = FL_CURSOR_DEFAULT;
+
+Fl_Hor_Value_Slider *cursor_slider;
+
+void choice_cb(Fl_Widget *, void *v) {
+ cursor = (Fl_Cursor)(int)v;
+ cursor_slider->value(cursor);
+ fl_cursor(cursor,fg,bg);
+}
+
+Fl_Menu_Item choices[] = {
+ {"FL_CURSOR_DEFAULT",0,choice_cb,(void*)FL_CURSOR_DEFAULT},
+ {"FL_CURSOR_ARROW",0,choice_cb,(void*)FL_CURSOR_ARROW},
+ {"FL_CURSOR_CROSS",0,choice_cb,(void*)FL_CURSOR_CROSS},
+ {"FL_CURSOR_WAIT",0,choice_cb,(void*)FL_CURSOR_WAIT},
+ {"FL_CURSOR_INSERT",0,choice_cb,(void*)FL_CURSOR_INSERT},
+ {"FL_CURSOR_HAND",0,choice_cb,(void*)FL_CURSOR_HAND},
+ {"FL_CURSOR_HELP",0,choice_cb,(void*)FL_CURSOR_HELP},
+ {"FL_CURSOR_MOVE",0,choice_cb,(void*)FL_CURSOR_MOVE},
+ {"FL_CURSOR_NS",0,choice_cb,(void*)FL_CURSOR_NS},
+ {"FL_CURSOR_WE",0,choice_cb,(void*)FL_CURSOR_WE},
+ {"FL_CURSOR_NWSE",0,choice_cb,(void*)FL_CURSOR_NWSE},
+ {"FL_CURSOR_NESW",0,choice_cb,(void*)FL_CURSOR_NESW},
+ {"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
+#if 0
+ {"FL_CURSOR_N",0,choice_cb,(void*)FL_CURSOR_N},
+ {"FL_CURSOR_NE",0,choice_cb,(void*)FL_CURSOR_NE},
+ {"FL_CURSOR_E",0,choice_cb,(void*)FL_CURSOR_E},
+ {"FL_CURSOR_SE",0,choice_cb,(void*)FL_CURSOR_SE},
+ {"FL_CURSOR_S",0,choice_cb,(void*)FL_CURSOR_S},
+ {"FL_CURSOR_SW",0,choice_cb,(void*)FL_CURSOR_SW},
+ {"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
+ {"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
+#endif
+ {0}
+};
+
+void setcursor(Fl_Widget *o, void *) {
+ Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
+ cursor = Fl_Cursor((int)slider->value());
+ fl_cursor(cursor,fg,bg);
+}
+
+void setfg(Fl_Widget *o, void *) {
+ Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
+ fg = Fl_Color((int)slider->value());
+ fl_cursor(cursor,fg,bg);
+}
+
+void setbg(Fl_Widget *o, void *) {
+ Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
+ bg = Fl_Color((int)slider->value());
+ fl_cursor(cursor,fg,bg);
+}
+
+// draw the label without any ^C or \nnn conversions:
+class CharBox : public Fl_Box {
+ void draw() {
+ fl_font(FL_FREE_FONT,14);
+ fl_draw(label(), x()+w()/2, y()+h()/2);
+ }
+public:
+ CharBox(int X, int Y, int W, int H, const char* L) : Fl_Box(X,Y,W,H,L) {}
+};
+
+int main(int argc, char **argv) {
+ Fl_Window window(400,300);
+
+ Fl_Choice choice(80,100,200,25,"Cursor:");
+ choice.menu(choices);
+ choice.callback(choice_cb);
+ choice.when(FL_WHEN_RELEASE|FL_WHEN_NOT_CHANGED);
+
+ Fl_Hor_Value_Slider slider1(80,180,310,30,"Cursor:");
+ cursor_slider = &slider1;
+ slider1.align(FL_ALIGN_LEFT);
+ slider1.step(1);
+ slider1.precision(0);
+ slider1.bounds(0,100);
+ slider1.value(0);
+ slider1.callback(setcursor);
+ slider1.value(cursor);
+
+ Fl_Hor_Value_Slider slider2(80,220,310,30,"fgcolor:");
+ slider2.align(FL_ALIGN_LEFT);
+ slider2.step(1);
+ slider2.precision(0);
+ slider2.bounds(0,255);
+ slider2.value(0);
+ slider2.callback(setfg);
+ slider2.value(fg);
+
+ Fl_Hor_Value_Slider slider3(80,260,310,30,"bgcolor:");
+ slider3.align(FL_ALIGN_LEFT);
+ slider3.step(1);
+ slider3.precision(0);
+ slider3.bounds(0,255);
+ slider3.value(0);
+ slider3.callback(setbg);
+ slider3.value(bg);
+
+#if 0
+ // draw the manual's diagram of cursors...
+ window.size(400,800);
+ int y = 300;
+ Fl::set_font(FL_FREE_FONT, "cursor");
+ char buf[100]; char *p = buf;
+ for (Fl_Menu* m = choices; m->label(); m++) {
+ Fl_Box* b = new Fl_Box(35,y,150,25,m->label());
+ b->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+ int n = (int)(m->argument());
+ if (n == FL_CURSOR_NONE) break;
+ if (n == FL_CURSOR_DEFAULT) n = FL_CURSOR_ARROW;
+ p[0] = (char)((n-1)*2);
+ p[1] = 0;
+ b = new CharBox(15,y,20,20,p); p+=2;
+ y += 25;
+ }
+#endif
+
+ window.resizable(window);
+ window.end();
+ window.show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/curve.cxx b/test/curve.cxx
new file mode 100644
index 000000000..15d25217c
--- /dev/null
+++ b/test/curve.cxx
@@ -0,0 +1,88 @@
+// Test fl_curve
+
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Hor_Value_Slider.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Toggle_Button.H>
+
+double args[9] = {
+ 20,20, 50,200, 100,20, 200,200, 0};
+const char* name[9] = {
+ "X0", "Y0", "X1", "Y1", "X2", "Y2", "X3", "Y3", "rotate"};
+
+int points;
+
+class Drawing : public Fl_Widget {
+ void draw() {
+ fl_clip(x(),y(),w(),h());
+ fl_color(FL_DARK3);
+ fl_rectf(x(),y(),w(),h());
+ fl_push_matrix();
+ if (args[8]) {
+ fl_translate(x()+w()/2.0, y()+h()/2.0);
+ fl_rotate(args[8]);
+ fl_translate(-(x()+w()/2.0), -(y()+h()/2.0));
+ }
+ fl_translate(x(),y());
+ if (!points) {
+ fl_color(FL_WHITE);
+ fl_begin_complex_polygon();
+ fl_curve(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
+ fl_end_complex_polygon();
+ }
+ fl_color(FL_BLACK);
+ fl_begin_line();
+ fl_vertex(args[0],args[1]);
+ fl_vertex(args[2],args[3]);
+ fl_vertex(args[4],args[5]);
+ fl_vertex(args[6],args[7]);
+ fl_end_line();
+ fl_color(points ? FL_WHITE : FL_RED);
+ points ? fl_begin_points() : fl_begin_line();
+ fl_curve(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
+ points ? fl_end_points() : fl_end_line();
+ fl_pop_matrix();
+ fl_pop_clip();
+ }
+public:
+ Drawing(int X,int Y,int W,int H) : Fl_Widget(X,Y,W,H) {}
+};
+
+Drawing *d;
+
+void points_cb(Fl_Widget* o, void*) {
+ points = ((Fl_Toggle_Button*)o)->value();
+ d->redraw();
+}
+
+void slider_cb(Fl_Widget* o, void* v) {
+ Fl_Slider* s = (Fl_Slider*)o;
+ args[long(v)] = s->value();
+ d->redraw();
+}
+
+int main(int argc, char** argv) {
+ Fl_Double_Window window(300,555);
+ Drawing drawing(10,10,280,280);
+ d = &drawing;
+
+ int y = 300;
+ for (int n = 0; n<9; n++) {
+ Fl_Slider* s = new Fl_Hor_Value_Slider(50,y,240,25,name[n]); y += 25;
+ s->minimum(0); s->maximum(280);
+ if (n == 8) s->maximum(360);
+ s->step(1);
+ s->value(args[n]);
+ s->align(FL_ALIGN_LEFT);
+ s->callback(slider_cb, (void*)n);
+ }
+ Fl_Toggle_Button but(50,y,50,25,"points");
+ but.callback(points_cb);
+
+ window.end();
+ window.show(argc,argv);
+ return Fl::run();
+}
+
+
diff --git a/test/demo.cxx b/test/demo.cxx
new file mode 100644
index 000000000..75b5dc821
--- /dev/null
+++ b/test/demo.cxx
@@ -0,0 +1,255 @@
+/* demo.C
+
+ The Forms demo program, rewritten in fltk.
+ The original code compiled fine, but this version does not use
+ <forms.h>
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#if defined(WIN32) && !defined(CYGNUS)
+# include <direct.h>
+//# define chdir _chdir
+#else
+# include <unistd.h>
+#endif
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/filename.H>
+
+/* The form description */
+
+void doexit(Fl_Widget *, void *);
+void doback(Fl_Widget *, void *);
+void dobut(Fl_Widget *, long);
+
+Fl_Window *form;
+Fl_Button *but[9];
+
+void create_the_forms() {
+ Fl_Widget *obj;
+ form = new Fl_Window(370, 450);
+ obj = new Fl_Box(FL_FRAME_BOX,20,390,330,40,"Fltk Demonstration");
+ obj->color(FL_GRAY-4);
+ obj->labelsize(24);
+ obj->labelfont(FL_BOLD);
+ obj->labeltype(FL_ENGRAVED_LABEL);
+ obj = new Fl_Box(FL_FRAME_BOX,20,50,330,330,0);
+ obj->color(FL_GRAY-8);
+ obj = new Fl_Button(130,10,110,30,"Exit");
+ obj->callback(doexit);
+ obj = new Fl_Button(20,50,330,380); obj->type(FL_HIDDEN_BUTTON);
+ obj->callback(doback);
+ obj = but[0] = new Fl_Button(40,270,90,90);
+ obj = but[1] = new Fl_Button(140,270,90,90);
+ obj = but[2] = new Fl_Button(240,270,90,90);
+ obj = but[5] = new Fl_Button(240,170,90,90);
+ obj = but[4] = new Fl_Button(140,170,90,90);
+ obj = but[3] = new Fl_Button(40,170,90,90);
+ obj = but[6] = new Fl_Button(40,70,90,90);
+ obj = but[7] = new Fl_Button(140,70,90,90);
+ obj = but[8] = new Fl_Button(240,70,90,90);
+ for (int i=0; i<9; i++) {
+ but[i]->align(FL_ALIGN_WRAP);
+ but[i]->callback(dobut, i);
+ }
+ form->forms_end();
+}
+
+/* Maintaining and building up the menus. */
+
+typedef struct {
+ char name[64];
+ int numb;
+ char iname[9][64];
+ char icommand[9][64];
+} MENU;
+
+#define MAXMENU 32
+
+MENU menus[MAXMENU];
+int mennumb = 0;
+
+int find_menu(char nnn[])
+/* Returns the number of a given menu name. */
+{
+ int i;
+ for (i=0; i<mennumb; i++)
+ if (strcmp(menus[i].name,nnn) == 0) return i;
+ return -1;
+}
+
+void create_menu(char nnn[])
+/* Creates a new menu with name nnn */
+{
+ if (mennumb == MAXMENU -1) return;
+ strcpy(menus[mennumb].name,nnn);
+ menus[mennumb].numb = 0;
+ mennumb++;
+}
+
+void addto_menu(char men[], char item[], char comm[])
+/* Adds an item to a menu */
+{
+ int n = find_menu(men);
+ if (n<0) { create_menu(men); n = find_menu(men); }
+ if (menus[n].numb == 9) return;
+ strcpy(menus[n].iname[menus[n].numb],item);
+ strcpy(menus[n].icommand[menus[n].numb],comm);
+ menus[n].numb++;
+}
+
+/* Button to Item conversion and back. */
+
+int b2n[][9] = {
+ { -1, -1, -1, -1, 0, -1, -1, -1, -1},
+ { -1, -1, -1, 0, -1, 1, -1, -1, -1},
+ { 0, -1, -1, -1, 1, -1, -1, -1, 2},
+ { 0, -1, 1, -1, -1, -1, 2, -1, 3},
+ { 0, -1, 1, -1, 2, -1, 3, -1, 4},
+ { 0, -1, 1, 2, -1, 3, 4, -1, 5},
+ { 0, -1, 1, 2, 3, 4, 5, -1, 6},
+ { 0, 1, 2, 3, -1, 4, 5, 6, 7},
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8}
+ };
+int n2b[][9] = {
+ { 4, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 4, 8, -1, -1, -1, -1, -1, -1},
+ { 0, 2, 6, 8, -1, -1, -1, -1, -1},
+ { 0, 2, 4, 6, 8, -1, -1, -1, -1},
+ { 0, 2, 3, 5, 6, 8, -1, -1, -1},
+ { 0, 2, 3, 4, 5, 6, 8, -1, -1},
+ { 0, 1, 2, 3, 5, 6, 7, 8, -1},
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8}
+ };
+
+int but2numb(int bnumb, int maxnumb)
+/* Transforms a button number to an item number when there are
+ maxnumb items in total. -1 if the button should not exist. */
+ { return b2n[maxnumb][bnumb]; }
+
+int numb2but(int inumb, int maxnumb)
+/* Transforms an item number to a button number when there are
+ maxnumb items in total. -1 if the item should not exist. */
+ { return n2b[maxnumb][inumb]; }
+
+/* Pushing and Popping menus */
+
+char stack[64][32];
+char stsize = 0;
+
+void push_menu(char nnn[])
+/* Pushes a menu to be visible */
+{
+ int n,i,bn;
+ int men = find_menu(nnn);
+ if (men < 0) return;
+ n = menus[men].numb;
+ for (i=0; i<9; i++) but[i]->hide();
+ for (i=0; i<n; i++)
+ {
+ bn = numb2but(i,n-1);
+ but[bn]->show();
+ but[bn]->label(menus[men].iname[i]);
+// if (menus[men].icommand[i][0] == '@')
+// but[bn]->color(FL_GRAY-8);
+// else
+// but[bn]->color(FL_GRAY);
+ }
+ strcpy(stack[stsize],nnn);
+ stsize++;
+}
+
+void pop_menu()
+/* Pops a menu */
+{
+ if (stsize<=1) return;
+ stsize -= 2;
+ push_menu(stack[stsize]);
+}
+
+/* The callback Routines */
+
+void dobut(Fl_Widget *, long arg)
+/* handles a button push */
+{
+ int men = find_menu(stack[stsize-1]);
+ int n = menus[men].numb;
+ int bn = but2numb( (int) arg, n-1);
+ if (menus[men].icommand[bn][0] == '@')
+ push_menu(menus[men].icommand[bn]);
+ else
+ system(menus[men].icommand[bn]);
+}
+
+void doback(Fl_Widget *, void *) {pop_menu();}
+
+void doexit(Fl_Widget *, void *) {exit(0);}
+
+int load_the_menu(const char fname[])
+/* Loads the menu file. Returns whether successful. */
+{
+ FILE *fin;
+ char line[256], mname[64],iname[64],cname[64];
+ int i,j;
+ fin = fopen(fname,"r");
+ if (fin == NULL)
+ {
+// fl_show_message("ERROR","","Cannot read the menu description file.");
+ return 0;
+ }
+ for (;;) {
+ if (fgets(line,256,fin) == NULL) break;
+ j = 0; i = 0;
+ while (line[i] == ' ' || line[i] == '\t') i++;
+ if (line[i] == '\n') continue;
+ if (line[i] == '#') continue;
+ while (line[i] != ':' && line[i] != '\n') mname[j++] = line[i++];
+ mname[j] = '\0';
+ if (line[i] == ':') i++;
+ j = 0;
+ while (line[i] != ':' && line[i] != '\n')
+ {
+ if (line[i] == '\\') {
+ i++;
+ if (line[i] == 'n') iname[j++] = '\n';
+ else iname[j++] = line[i];
+ i++;
+ } else
+ iname[j++] = line[i++];
+ }
+ iname[j] = '\0';
+ if (line[i] == ':') i++;
+ j = 0;
+ while (line[i] != ':' && line[i] != '\n') cname[j++] = line[i++];
+ cname[j] = '\0';
+ addto_menu(mname,iname,cname);
+ }
+ fclose(fin);
+ return 1;
+}
+
+int main(int argc, char **argv) {
+ create_the_forms();
+ char buf[256];
+ strcpy(buf, argv[0]);
+ strcat(buf, ".menu");
+ const char *fname = buf;
+ int i = 0;
+ if (!Fl::args(argc,argv,i) || i < argc-1)
+ Fl::fatal("Usage: %s <switches> <menufile>\n%s",Fl::help);
+ if (i < argc) fname = argv[i];
+ if (!load_the_menu(fname)) Fl::fatal("Can't open %s",fname);
+ strcpy(buf,fname);
+ const char *c = filename_name(buf);
+ if (c > buf) {buf[c-buf] = 0; chdir(buf);}
+ push_menu("@main");
+ form->show(argc,argv);
+ Fl::run();
+ return 0;
+}
diff --git a/test/demo.menu b/test/demo.menu
new file mode 100644
index 000000000..3d4c74b5e
--- /dev/null
+++ b/test/demo.menu
@@ -0,0 +1,80 @@
+# Menu description file for the generic demo program
+#
+# Each line consists of three fields, separated by :
+#
+# - menu name : To which the item belongs (starts with @)
+# - item name : Placed on button. (use \n for newline)
+# - command name: To be executed. Use a menu name to define a submenu.
+#
+# @main indicates the main menu.
+#
+
+@main:Widget\nTests:@x
+ @x:Fl_Browser:./browser&
+ @x:Fl_Input:./input&
+ @x:Fl_Output:./output&
+ @x:Fl_Button:./radio&
+ @x:Fl_Tabs:./tabs&
+ @x:Fl_Tile:./tile&
+ @x:Fl_Scroll:./scroll&
+ @x:Fl_Pack:./pack&
+ @x:Fl_Menu:./menubar&
+
+@main:Window\nTests:@w
+ @w:overlay:./overlay&
+ @w:subwindow:./subwindow&
+ @w:double\nbuffer:./doublebuffer&
+ @w:GL window:./cube&
+ @w:GL overlay:./gl_overlay&
+ @w:iconize:./iconize&
+ @w:fullscreen:./fullscreen&
+ @w:resizable:./resizebox&
+ @w:resize:./resize&
+
+@main:Drawing\nTests:@d
+ @d:Fl_Bitmap:./bitmap&
+ @d:Fl_Pixmap:./pixmap&
+ @d:Fl_Image:./image&
+ @d:pixmap\nbrowser:./pixmap_browser&
+ @d:cursor:./cursor&
+ @d:labels:./label&
+ @d:fl_arc:./arc&
+ @d:fl_curve:./curve&
+ @d:fonts:./fonts&
+
+@main:Events:@u
+ @u:navigation:./navigation&
+ @u:minimum update:./minimum&
+ @u:keyboard:./keyboard&
+ @u:fast & slow widgets:./fast_slow&
+ @u:inactive:./inactive&
+
+@main:Fluid\n(UI design tool):../fluid/fluid valuators.fl&
+
+@main:Cool\nDemos:@e
+ @e:X Color\nBrowser:./colbrowser&
+ @e:Mandelbrot:./mandelbrot&
+ @e:Fractals:./fractals&
+ @e:Puzzle:./glpuzzle&
+ @e:shiny\nOpenGL\nbuttons:./shiny&
+ @e:Checkers:./checkers&
+
+@main:Other\nTests:@o
+ @o:color choosers:./color_chooser r&
+ @o:file chooser:./file_chooser&
+ @o:styles:./style&
+ @o:XForms Emulation:./forms&
+
+@main:Tutorial\nfrom\nManual:@j
+ @j:hello:./hello&
+ @j:button:./button&
+ @j:ask\n(modified):./ask&
+ @j:shape:./shape&
+
+@main:Images\nfor\nManual:@i
+ @i:valuators:./valuators&
+ @i:symbols:./symbols&
+ @i:buttons:./buttons&
+ @i:clock:./clock&
+ @i:popups:./message&
+ @i:boxtypes:./boxtype&
diff --git a/test/doublebuffer.cxx b/test/doublebuffer.cxx
new file mode 100644
index 000000000..b15bc02c3
--- /dev/null
+++ b/test/doublebuffer.cxx
@@ -0,0 +1,99 @@
+// Double-buffering test.
+
+// This demo shows how double buffering helps, by drawing the
+// window in a particularily bad way.
+
+// The single-buffered window will blink as it updates. The
+// double buffered one will not. It will take just as long
+// (or longer) to update, but often it will appear to be faster.
+
+// This demo should work for both the GL and X versions of Fl,
+// even though the double buffering mechanism is totally different.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Hor_Slider.H>
+#include <stdlib.h>
+#include <FL/math.h>
+#include <stdio.h>
+
+// this purposely draws each line 10 times to be slow:
+void star(int w, int h, int n) {
+ fl_push_matrix();
+ fl_translate(w/2, h/2);
+ fl_scale(w/2, h/2);
+ for (int i = 0; i < n; i++) {
+ for (int j = i+1; j < n; j++)/* for (int k=0; k<10; k++)*/ {
+ fl_begin_line();
+ fl_vertex(cos(2*M_PI*i/n+.1), sin(2*M_PI*i/n+.1));
+ fl_vertex(cos(2*M_PI*j/n+.1), sin(2*M_PI*j/n+.1));
+ fl_end_line();
+ }
+ }
+ fl_pop_matrix();
+}
+
+int sides[2] = {20,20};
+
+void slider_cb(Fl_Widget* o, long v) {
+ sides[v] = int(((Fl_Slider*)o)->value());
+ o->parent()->redraw();
+}
+
+void bad_draw(int w,int h,int which) {
+// for (int i=0; i<10; i++) {
+// fl_color(7); fl_rectf(0,0,w,h); fl_color(0); star(w,h);
+// fl_color(0); fl_rectf(0,0,w,h); fl_color(7); star(w,h);
+// }
+ fl_color(FL_BLACK); fl_rectf(0,0,w,h);
+ fl_color(FL_WHITE); star(w,h,sides[which]);
+ // for (int x=0; x<sides[which]; x++) for (int y=0; y<sides[which]; y++)
+ //fl_draw_box(FL_UP_BOX, 10*x, 10*y, 25,25, FL_GRAY);
+}
+
+class single_blink_window : public Fl_Single_Window {
+ void draw() {bad_draw(w(),h(),0); draw_child(*child(0));}
+public:
+ single_blink_window(int x, int y,int w,int h,const char *l)
+ : Fl_Single_Window(x,y,w,h,l) {resizable(this);}
+};
+
+class double_blink_window : public Fl_Double_Window {
+ void draw() {bad_draw(w(),h(),1); draw_child(*child(0));}
+public:
+ double_blink_window(int x, int y, int w,int h,const char *l)
+ : Fl_Double_Window(x,y,w,h,l) {resizable(this);}
+};
+
+int main() {
+ if (!Fl::visual(FL_DOUBLE))
+ printf("Xdbe not supported, faking double buffer with pixmaps.\n");
+ Fl_Window w01(420,420,"Fl_Single_Window"); w01.box(FL_FLAT_BOX);
+ single_blink_window w1(10,10,400,400,"Fl_Single_Window");
+ w1.box(FL_FLAT_BOX); w1.color(FL_BLACK); //w1.position(100,200);
+ Fl_Hor_Slider slider0(20,370,360,25);
+ slider0.range(2,30);
+ slider0.step(1);
+ slider0.value(sides[0]);
+ slider0.callback(slider_cb, 0);
+ w1.end();
+ w01.end();
+ Fl_Window w02(420,420,"Fl_Double_Window"); w02.box(FL_FLAT_BOX);
+ double_blink_window w2(10,10,400,400,"Fl_Double_Window");
+ w2.box(FL_FLAT_BOX); w2.color(FL_BLACK); //w2.position(600,200);
+ Fl_Hor_Slider slider1(20,370,360,25);
+ slider1.range(2,30);
+ slider1.step(1);
+ slider1.value(sides[0]);
+ slider1.callback(slider_cb, 1);
+ w2.end();
+ w02.end();
+ w01.show();
+ w1.show();
+ w02.show();
+ w2.show();
+ return Fl::run();
+}
diff --git a/test/fast_slow.C b/test/fast_slow.C
new file mode 100644
index 000000000..42fdff135
--- /dev/null
+++ b/test/fast_slow.C
@@ -0,0 +1,50 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "fast_slow.H"
+
+Fl_Slider *control;
+
+static void cb_control(Fl_Slider* o, void*) {
+ fast->value(o->value());
+if (!Fl::pushed()) slow->value(o->value());
+}
+
+Fl_Slider *fast;
+
+Fl_Slider *slow;
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(318, 443);
+ w = o;
+ Fl_Group::current()->resizable(o);
+ { Fl_Slider* o = new Fl_Slider(90, 200, 30, 200, "move\nthis");
+ control = o;
+ o->callback((Fl_Callback*)cb_control);
+ o->when(FL_WHEN_CHANGED|FL_WHEN_RELEASE|FL_WHEN_NOT_CHANGED);
+ }
+ { Fl_Slider* o = new Fl_Slider(140, 200, 30, 200, "fast\nredraw");
+ fast = o;
+ o->set_output();
+ }
+ { Fl_Slider* o = new Fl_Slider(190, 200, 30, 200, "slow\nredraw");
+ slow = o;
+ o->set_output();
+ }
+ { Fl_Box* o = new Fl_Box(10, 10, 300, 180, "The left slider has changed( FL_WHEN_CHANGED | FL_WHEN_RELEASE | FL_WHEN_N\
+OT_CHANGED) so it produces a callback on both drag and release mouse events\
+.\nThe middle slider (representing a widget with low overhead) is changed o\
+n every mouse movement.\nThe right slider (representing a widget with high \
+overhead) is only updated when the mouse is released, by checking if Fl::pu\
+shed() is zero.");
+ o->box(FL_DOWN_BOX);
+ o->color(53);
+ o->labelfont(4);
+ o->labelsize(12);
+ o->align(148);
+ }
+ w->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/fast_slow.H b/test/fast_slow.H
new file mode 100644
index 000000000..233a9e649
--- /dev/null
+++ b/test/fast_slow.H
@@ -0,0 +1,9 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Window.H>
+extern Fl_Slider *control;
+extern Fl_Slider *fast;
+extern Fl_Slider *slow;
diff --git a/test/fast_slow.fl b/test/fast_slow.fl
new file mode 100644
index 000000000..71ee657d1
--- /dev/null
+++ b/test/fast_slow.fl
@@ -0,0 +1,36 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 10
+snap 3
+Function {} {open
+} {
+ Fl_Window {} {open
+ xywh {143 188 318 443} resizable visible
+ } {
+ Fl_Slider control {
+ label {move
+this}
+ callback {fast->value(o->value());
+if (!Fl::pushed()) slow->value(o->value());}
+ xywh {90 200 30 200}
+ code0 {o->when(FL_WHEN_CHANGED|FL_WHEN_RELEASE|FL_WHEN_NOT_CHANGED);}
+ }
+ Fl_Slider fast {
+ label {fast
+redraw}
+ xywh {140 200 30 200} deactivate
+ }
+ Fl_Slider slow {
+ label {slow
+redraw}
+ xywh {190 200 30 200} deactivate
+ }
+ Fl_Box {} {
+ label {The left slider has changed( FL_WHEN_CHANGED | FL_WHEN_RELEASE | FL_WHEN_NOT_CHANGED) so it produces a callback on both drag and release mouse events.
+The middle slider (representing a widget with low overhead) is changed on every mouse movement.
+The right slider (representing a widget with high overhead) is only updated when the mouse is released, by checking if Fl::pushed() is zero.} selected
+ xywh {10 10 300 180} box DOWN_BOX color {53 47} labelfont 4 labelsize 12 align 148
+ }
+ }
+}
diff --git a/test/file_chooser.cxx b/test/file_chooser.cxx
new file mode 100644
index 000000000..e2b366ce2
--- /dev/null
+++ b/test/file_chooser.cxx
@@ -0,0 +1,36 @@
+/* Test fl_file_chooser() */
+
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_file_chooser.H>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+Fl_Input *pattern, *current;
+
+void pickfile(Fl_Widget *) {
+ const char *p;
+ p = fl_file_chooser("Pick a file",pattern->value(),current->value());
+ if (p) current->value(p);
+}
+
+void thecb(const char *name) {
+ printf("Callback '%s'\n",name);
+}
+
+int main(int argc, char **argv) {
+ Fl_Window window(400,200);
+ pattern = new Fl_Input(100,50,280,30,"Pattern:");
+ pattern->static_value("*");
+ current = new Fl_Input(100,90,280,30,"Current:");
+ Fl_Button button(100,120,100,30,"&Choose file");
+ button.callback(pickfile);
+ window.end();
+ window.show(argc, argv);
+ fl_file_chooser_callback(thecb);
+ return Fl::run();
+}
diff --git a/test/fl_jpeg_image.cxx b/test/fl_jpeg_image.cxx
new file mode 100644
index 000000000..960c0515c
--- /dev/null
+++ b/test/fl_jpeg_image.cxx
@@ -0,0 +1,178 @@
+/* Test fl_draw_image.
+
+ Be sure to try every visual with the -v switch and try
+ -m (monochrome) on each of them.
+
+ This program requires either the libjpeg.a library or
+ an internal DD library to read images (this is chosen
+ by the presence of the "DD" #define).
+
+ To get the jpeg library:
+
+The "official" archive site for this software is ftp.uu.net (Internet
+address 192.48.96.9). The most recent released version can always be found
+there in directory graphics/jpeg. This particular version will be archived
+as graphics/jpeg/jpegsrc.v6a.tar.gz.
+
+ The makefile assummes you decompressed and build these
+ in a directory called "jpeg-6a" in the same location as the
+ "FL" directory.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <stdio.h>
+#include <stdlib.h>
+
+void readtheimage(const char *name); // below
+int width;
+int height;
+int depth;
+int linedelta;
+uchar *ibuffer;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Window.H>
+int mono;
+
+class image_window : public Fl_Window {
+ void draw();
+public:
+ image_window(int w,int h) : Fl_Window(w,h) {box(FL_NO_BOX);}
+};
+
+void image_window::draw() {
+ if (mono)
+ fl_draw_image_mono(ibuffer+1,0,0,width,height,depth,linedelta);
+ else
+ fl_draw_image(ibuffer,0,0,width,height,depth,linedelta);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/x.H>
+#include "list_visuals.C"
+
+////////////////////////////////////////////////////////////////
+
+int visid = -1;
+int arg(int argc, char **argv, int &i) {
+ if (argv[i][1] == 'm') {mono = 1; i++; return 1;}
+
+ if (argv[i][1] == 'v') {
+ if (i+1 >= argc) return 0;
+ visid = atoi(argv[i+1]);
+ i += 2;
+ return 2;
+ }
+
+ return 0;
+}
+
+int main(int argc, char ** argv) {
+
+ int i = 1;
+ if (!Fl::args(argc,argv,i,arg) || i != argc-1) {
+ fprintf(stderr,"usage: %s <switches> image_file\n"
+" -v # : use visual\n"
+" -m : monochrome\n"
+"%s\n",
+ argv[0],Fl::help);
+ exit(1);
+ }
+
+ readtheimage(argv[i]);
+ image_window *window = new image_window(width,height);
+
+ if (visid>=0) {
+ fl_open_display();
+ XVisualInfo templt; int num;
+ templt.visualid = visid;
+ fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+ if (!fl_visual) {
+ fprintf(stderr, "No visual with id %d, use one of:\n",visid);
+ list_visuals();
+ exit(1);
+ }
+ fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ fl_xpixel(0); // make sure black is allocated
+ }
+
+ window->show(argc,argv);
+ return Fl::run();
+}
+
+////////////////////////////////////////////////////////////////
+#ifndef DD_LIBRARY
+// Read using jpeg library:
+
+extern "C" {
+#include "jpeglib.h"
+}
+
+void readtheimage(const char *name) {
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ FILE * infile = fopen(name, "rb");
+ if (!infile) {
+ fprintf(stderr, "can't open %s\n", name);
+ exit(1);
+ }
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, infile);
+ jpeg_read_header(&cinfo, TRUE);
+ jpeg_start_decompress(&cinfo);
+ width = cinfo.output_width;
+ height = cinfo.output_height;
+ depth = cinfo.output_components;
+ ibuffer = new uchar[width*height*depth];
+ uchar *rp = ibuffer;
+ for (int i=0; i<height; i++) {
+ jpeg_read_scanlines(&cinfo, &rp, 1);
+ rp += width*depth;
+ }
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ fclose(infile);
+}
+
+////////////////////////////////////////////////////////////////
+#else // Digital Domain in-house library
+
+#include "DDNewImage/DDImageOp.H"
+#include "DDNewImage/DDImgRead.H"
+#include "DDNewImage/DDImgToBuffer.H"
+
+void readtheimage(const char *name) {
+ DDImgRead reader(name);
+ width = reader.xsize();
+ height = reader.ysize();
+ depth = 4; // reader.zsize();
+ ibuffer = new uchar[width*height*depth];
+ DDImgToBuffer b(&reader,depth,ibuffer,0,0,width,height);
+ b.execute();
+ if (DDImage::haderror) {
+ fprintf(stderr,"%s\n",DDImage::errormsg());
+ exit(1);
+ }
+ // swap it around into RGBA order:
+ for (uchar *p = ibuffer+width*height*4-4; p >= ibuffer; p-=4) {
+ uchar r = p[3];
+ uchar g = p[2];
+ uchar b = p[1];
+ uchar a = p[0];
+ p[0] = r;
+ p[1] = g;
+ p[2] = b;
+ p[3] = a;
+ }
+ // make it bottom-to-top:
+ ibuffer = ibuffer + width*(height-1)*depth;
+ linedelta = -(width*depth);
+}
+#endif
+
diff --git a/test/fonts.cxx b/test/fonts.cxx
new file mode 100644
index 000000000..0b3639ae2
--- /dev/null
+++ b/test/fonts.cxx
@@ -0,0 +1,127 @@
+/* demo of Fl::set_fonts() */
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Hold_Browser.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Box.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+Fl_Window *form;
+
+Fl_Box *textobj;
+
+Fl_Hold_Browser *fontobj, *sizeobj;
+
+int *sizes[1000];
+int numsizes[1000];
+int pickedsize = 14;
+
+void font_cb(Fl_Widget *, long) {
+ int fn = fontobj->value();
+ if (!fn) return;
+ fn--;
+ textobj->labelfont(fn);
+ sizeobj->clear();
+ int n = numsizes[fn];
+ int *s = sizes[fn];
+ if (!n) {
+ // no sizes
+ } else if (s[0] == 0) {
+ // many sizes;
+ int j = 1;
+ for (int i = 1; i<64 || i<s[n-1]; i++) {
+ char buf[20];
+ if (j < n && i==s[j]) {sprintf(buf,"@b%d",i); j++;}
+ else sprintf(buf,"%d",i);
+ sizeobj->add(buf);
+ }
+ sizeobj->value(pickedsize);
+ } else {
+ // some sizes
+ int w = 0;
+ for (int i = 0; i < n; i++) {
+ if (s[i]<=pickedsize) w = i;
+ char buf[20];
+ sprintf(buf,"@b%d",s[i]);
+ sizeobj->add(buf);
+ }
+ sizeobj->value(w+1);
+ }
+ textobj->redraw();
+}
+
+void size_cb(Fl_Widget *, long) {
+ int i = sizeobj->value();
+ if (!i) return;
+ const char *c = sizeobj->text(i);
+ while (*c < '0' || *c > '9') c++;
+ pickedsize = atoi(c);
+ textobj->labelsize(pickedsize);
+ textobj->redraw();
+}
+
+char label[400];
+
+void create_the_forms() {
+ form = new Fl_Window(550,370);
+
+ strcpy(label, "Hello, world!\n");
+ int i = strlen(label);
+ uchar c;
+ for (c = ' '+1; c < 127; c++) {if (!(c&0x1f)) label[i++]='\n'; label[i++]=c;}
+ label[i++] = '\n';
+ for (c = 0xA1; c; c++) {if (!(c&0x1f)) label[i++]='\n'; label[i++]=c;}
+ label[i] = 0;
+
+ textobj = new Fl_Box(FL_FRAME_BOX,10,10,530,170,label);
+ textobj->align(FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
+ textobj->color(9,47);
+ fontobj = new Fl_Hold_Browser(10, 190, 390, 170);
+ fontobj->box(FL_FRAME_BOX);
+ fontobj->color(53,3);
+ fontobj->callback(font_cb);
+ form->resizable(fontobj);
+ sizeobj = new Fl_Hold_Browser(410, 190, 130, 170);
+ sizeobj->box(FL_FRAME_BOX);
+ sizeobj->color(53,3);
+ sizeobj->callback(size_cb);
+ form->end();
+}
+
+#include <FL/fl_ask.H>
+
+int main(int argc, char **argv) {
+ create_the_forms();
+ int i = fl_choice("Which fonts:","-*","iso8859","All");
+ int k = Fl::set_fonts(i ? (i>1 ? "*" : 0) : "-*");
+ for (i = 0; i < k; i++) {
+ int t; const char *name = Fl::get_font_name((Fl_Font)i,&t);
+ char buffer[128];
+#if 1
+ if (t) {
+ char *p = buffer;
+ if (t & FL_BOLD) {*p++ = '@'; *p++ = 'b';}
+ if (t & FL_ITALIC) {*p++ = '@'; *p++ = 'i';}
+ strcpy(p,name);
+ name = buffer;
+ }
+#else // this is neat, but really slow on some X servers:
+ sprintf(buffer, "@F%d@.%s", i, name);
+ name = buffer;
+#endif
+ fontobj->add(name);
+ int *s; int n = Fl::get_font_sizes((Fl_Font)i, s);
+ numsizes[i] = n;
+ if (n) {
+ sizes[i] = new int[n];
+ for (int j=0; j<n; j++) sizes[i][j] = s[j];
+ }
+ }
+ fontobj->value(1);
+ font_cb(fontobj,0);
+ form->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/forms.cxx b/test/forms.cxx
new file mode 100644
index 000000000..1ca2c965d
--- /dev/null
+++ b/test/forms.cxx
@@ -0,0 +1,205 @@
+// This is an XForms program with very few changes.
+// Search for "fltk" to find all changes necessary to port to fltk.
+
+/* This demo show the different boxtypes. Note that some
+ * boxtypes are not appropriate for some objects
+ */
+
+#include <FL/forms.H> // changed for fltk
+
+static int border = 1; // changed from FL_TRANSIENT for fltk
+// (this is so the close box and Esc work to close the window)
+
+typedef struct { int val; char *name; } VN_struct;
+#define VN(a) {a,#a}
+
+// static VN_struct gmode[] =
+// {
+// VN(StaticGray), VN(GrayScale), VN(StaticColor),
+// VN(PseudoColor), VN(TrueColor), VN(DirectColor),
+// };
+
+static VN_struct btypes[]=
+{
+ {FL_NO_BOX,"no box"},
+ {FL_UP_BOX, "up box"},
+ {FL_DOWN_BOX,"down box"},
+ {FL_BORDER_BOX,"border box"},
+ {FL_SHADOW_BOX,"shadow box"},
+ {FL_FLAT_BOX,"flat box"},
+ {FL_FRAME_BOX,"frame box"},
+ {FL_EMBOSSED_BOX,"embossed box"},
+ {FL_ROUNDED_BOX,"rounded box"},
+ {FL_RFLAT_BOX,"rflat box"},
+ {FL_RSHADOW_BOX,"rshadow box"}, // renamed for fltk
+ {FL_OVAL_BOX,"oval box"},
+ {FL_ROUNDED3D_UPBOX,"rounded3d upbox"},
+ {FL_ROUNDED3D_DOWNBOX,"rounded3d downbox"},
+ {FL_OVAL3D_UPBOX,"oval3d upbox"},
+ {FL_OVAL3D_DOWNBOX,"oval3d downbox"},
+ /* sentinel */
+ {-1}
+};
+
+#include "srs.xbm"
+
+/*************** Callback **********************/
+
+FL_FORM *form;
+Fl_Widget *tobj[18], *exitob, *btypeob, *modeob;
+
+void
+boxtype_cb (Fl_Widget * ob, long)
+{
+ int i, req_bt = fl_get_choice(ob) - 1;
+ static int lastbt = -1;
+
+ if(lastbt != req_bt)
+ {
+ fl_freeze_form (form);
+ fl_redraw_form (form);
+ for (i = 0; i < 18; i++)
+ fl_set_object_boxtype (tobj[i], (Fl_Boxtype)btypes[req_bt].val);
+ fl_unfreeze_form (form);
+ lastbt = req_bt;
+ fl_redraw_form(form); // added for fltk
+ }
+}
+
+void
+mode_cb (Fl_Widget *, long)
+{
+// static int lval = -1;
+// int val = fl_get_choice (ob) -1;
+// int db = 0;
+
+// if (val == lval || val < 0)
+// return;
+
+// fl_hide_form (form);
+// if (!fl_mode_capable (gmode[val].val, 0))
+// {
+// fl_set_choice(ob, lval);
+// val = lval;
+// }
+
+// fl_set_graphics_mode (gmode[val].val, db);
+// fl_show_form (form, FL_PLACE_GEOMETRY, border, "Box types");
+
+// lval = val;
+}
+
+/*************** Creation Routines *********************/
+
+void
+create_form_form (void)
+{
+ Fl_Widget *obj;
+
+ form = fl_bgn_form(FL_NO_BOX, 720, 520);
+ obj = fl_add_box(FL_UP_BOX, 0, 0, 720, 520, "");
+ fl_set_object_color(obj, FL_BLUE, FL_COL1);
+ obj = fl_add_box(FL_DOWN_BOX, 10, 90, 700, 420, "");
+ fl_set_object_color(obj, FL_COL1, FL_COL1);
+ obj = fl_add_box(FL_DOWN_BOX, 10, 10, 700, 70, "");
+ fl_set_object_color(obj, FL_SLATEBLUE, FL_COL1);
+ tobj[0] = obj = fl_add_box(FL_UP_BOX, 30, 110, 110, 110, "Box");
+ tobj[1] = obj = fl_add_text(FL_NORMAL_TEXT, 30, 240, 110, 30, "Text");
+ tobj[2] = obj = fl_add_bitmap(FL_NORMAL_BITMAP, 40, 280, 90, 80, "Bitmap");
+ fl_set_object_lcol(obj, FL_BLUE);
+ tobj[3] = obj = fl_add_chart(FL_BAR_CHART, 160, 110, 160, 110, "Chart");
+ tobj[4] = obj = fl_add_clock(FL_ANALOG_CLOCK, 40, 390, 90, 90, "Clock");
+//fl_set_object_dblbuffer(tobj[4],1); // removed for fltk
+ tobj[5]=obj=fl_add_button(FL_NORMAL_BUTTON, 340, 110, 120, 30, "Button");
+ tobj[6]=obj=fl_add_lightbutton(FL_PUSH_BUTTON,340,150,120,30,"Lightbutton");
+ tobj[7]=obj=fl_add_roundbutton(FL_PUSH_BUTTON,340,190,120,30,"Roundbutton");
+ tobj[8]=obj=fl_add_slider(FL_VERT_SLIDER, 160, 250, 40, 230, "Slider");
+ tobj[9]=obj=fl_add_valslider(FL_VERT_SLIDER, 220, 250, 40, 230, "Valslider");
+ tobj[10]=obj=fl_add_dial (FL_LINE_DIAL, 280, 250, 100, 100, "Dial");
+ tobj[11]=obj=fl_add_positioner(FL_NORMAL_POSITIONER,280,380,150,100, "Positioner");
+ tobj[12]=obj=fl_add_counter (FL_NORMAL_COUNTER,480,110,210,30, "Counter");
+ tobj[13]=obj=fl_add_input (FL_NORMAL_INPUT, 520,170,170,30, "Input");
+ tobj[14]=obj=fl_add_menu (FL_PUSH_MENU, 400, 240, 100, 30, "Menu");
+ tobj[15]=obj=fl_add_choice (FL_NORMAL_CHOICE, 580, 250, 110, 30, "Choice");
+ tobj[16]=obj=fl_add_timer (FL_VALUE_TIMER, 580, 210, 110, 30, "Timer");
+//fl_set_object_dblbuffer(tobj[16], 1); // removed for fltk
+ tobj[17]=obj=fl_add_browser (FL_NORMAL_BROWSER,450,300,240, 180, "Browser");
+ exitob=obj= fl_add_button (FL_NORMAL_BUTTON, 590, 30, 100, 30, "Exit");
+ btypeob=obj= fl_add_choice (FL_NORMAL_CHOICE,110,30, 130, 30, "Boxtype");
+ fl_set_object_callback (obj, boxtype_cb, 0);
+ modeob = obj=fl_add_choice(FL_NORMAL_CHOICE,370,30,130,30,"Graphics mode");
+ fl_set_object_callback (obj, mode_cb, 0);
+ fl_end_form ();
+}
+/*---------------------------------------*/
+
+void
+create_the_forms (void)
+{
+ create_form_form ();
+}
+
+/*************** Main Routine ***********************/
+
+char *browserlines[] = {
+ " ", "@C1@c@l@bObjects Demo", " ",
+ "This demo shows you all", "objects that currently",
+ "exist in the Forms Library.", " ",
+ "You can change the boxtype", "of the different objects",
+ "using the buttons at the", "top of the form. Note that",
+ "some combinations might not", "look too good. Also realize",
+ "that for all object classes", "many different types are",
+ "available with different", "behaviour.", " ",
+ "With this demo you can also", "see the effect of the drawing",
+ "mode on the appearance of the","objects.",
+ 0
+};
+
+
+int
+main (int argc, char *argv[])
+{
+ FL_COLOR c = FL_BLACK;
+ char **p;
+ VN_struct *vn;
+
+ fl_initialize(&argc, argv, "FormDemo", 0, 0);
+ create_the_forms ();
+ fl_set_bitmap_data (tobj[2], sorceress_width, sorceress_height, sorceress_bits);
+ fl_add_chart_value (tobj[3], 15, "item 1", c++);
+ fl_add_chart_value (tobj[3], 5, "item 2", c++);
+ fl_add_chart_value (tobj[3], -10, "item 3", c++);
+ fl_add_chart_value (tobj[3], 25, "item 4", c++);
+ fl_set_menu (tobj[14], "item 1|item 2|item 3|item 4|item 5");
+ fl_addto_choice (tobj[15], "item 1");
+ fl_addto_choice (tobj[15], "item 2");
+ fl_addto_choice (tobj[15], "item 3");
+ fl_addto_choice (tobj[15], "item 4");
+ fl_addto_choice (tobj[15], "item 5");
+ fl_set_timer (tobj[16], 1000.0);
+
+ for ( p = browserlines; *p; p++)
+ fl_add_browser_line (tobj[17], *p);
+
+ for ( vn = btypes; vn->val >= 0; vn++)
+ fl_addto_choice(btypeob, vn->name);
+
+// {
+// int i;
+// VN_struct *g = gmode, *gs = g + sizeof (gmode) / sizeof (gmode[0]);
+// for (i = 1; g < gs; g++, i++)
+// {
+// fl_addto_choice (modeob, g->name);
+// if(!fl_mode_capable(g->val, 0))
+// fl_set_choice_item_mode(modeob, i, FL_PUP_GRAY);
+// }
+// }
+// fl_set_choice (modeob, fl_vmode+1);
+
+ fl_show_form (form, FL_PLACE_MOUSE, border, "Box types");
+
+ while (fl_do_forms () != exitob)
+ ;
+
+ return 0;
+}
diff --git a/test/fractals.cxx b/test/fractals.cxx
new file mode 100644
index 000000000..5eb783e51
--- /dev/null
+++ b/test/fractals.cxx
@@ -0,0 +1,779 @@
+/* Fractal drawing program
+ This is a GLUT demo program, with modifications to
+ demonstrate how to add fltk controls to a glut program. The glut
+ code is unchanged except for the end (search for fltk to find changes).
+*/
+
+#include <config.h>
+#if !HAVE_GL
+#include <FL/Fl.H>
+#include <FL/fl_message.H>
+int main(int, char**) {
+ fl_alert("This demo does not work without GL");
+ return 1;
+}
+#else
+/*
+ * To compile: cc -o fractals fractals.c -lGL -lGLU -lX11 -lglut -lXmu -lm
+ *
+ * Usage: fractals
+ *
+ * Homework 6, Part 2: fractal mountains and fractal trees
+ * (Pretty Late)
+ *
+ * Draws fractal mountains and trees -- and an island of mountains in water
+ * (I tried having trees on the island but it didn't work too well.)
+ *
+ * Two viewer modes: polar and flying (both restrained to y>0 for up vector).
+ * Keyboard 0->9 and +/- control speed when flying.
+ *
+ * Only keyboard commands are 0-9 and +/- for speed in flying mode.
+ *
+ * Fog would make the island look much better, but I couldn't get it to work
+ * correctly. Would line up on -z axis not from eye.
+ *
+ * Philip Winston - 3/4/95
+ * pwinston@hmc.edu
+ * http://www.cs.hmc.edu/people/pwinston
+ *
+ */
+
+#include <FL/glut.H>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <limits.h> /* ULONG_MAX is defined here */
+#include <float.h> /* FLT_MAX is atleast defined here */
+
+#include <time.h> /* for random seed */
+
+#include "fracviewer.c" // changed from .h for fltk
+
+#if defined(WIN32) || defined(__EMX__)
+#define drand48() (((float) rand())/((float) RAND_MAX))
+#define srand48(x) (srand((x)))
+#endif
+
+typedef enum { NOTALLOWED, MOUNTAIN, TREE, ISLAND, BIGMTN, STEM, LEAF,
+ MOUNTAIN_MAT, WATER_MAT, LEAF_MAT, TREE_MAT, STEMANDLEAVES,
+ AXES } DisplayLists;
+
+#define MAXLEVEL 8
+
+int Rebuild = 1, /* Rebuild display list in next display? */
+ Fract = TREE, /* What fractal are we building */
+ Level = 4; /* levels of recursion for fractals */
+
+int DrawAxes = 0;
+
+/***************************************************************/
+/************************* VECTOR JUNK *************************/
+/***************************************************************/
+
+ /* print vertex to stderr */
+void printvert(float v[3])
+{
+ fprintf(stderr, "(%f, %f, %f)\n", v[0], v[1], v[2]);
+}
+
+#if 0 // removed for FL, it is in fracviewer.c
+ /* normalizes v */
+void normalize(GLfloat v[3])
+{
+ GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+
+ if (d == 0)
+ fprintf(stderr, "Zero length vector in normalize\n");
+ else
+ v[0] /= d; v[1] /= d; v[2] /= d;
+}
+
+ /* calculates a normalized crossproduct to v1, v2 */
+void ncrossprod(float v1[3], float v2[3], float cp[3])
+{
+ cp[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ cp[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ cp[2] = v1[0]*v2[1] - v1[1]*v2[0];
+ normalize(cp);
+}
+#endif
+
+ /* calculates normal to the triangle designated by v1, v2, v3 */
+void triagnormal(float v1[3], float v2[3], float v3[3], float norm[3])
+{
+ float vec1[3], vec2[3];
+
+ vec1[0] = v3[0] - v1[0]; vec2[0] = v2[0] - v1[0];
+ vec1[1] = v3[1] - v1[1]; vec2[1] = v2[1] - v1[1];
+ vec1[2] = v3[2] - v1[2]; vec2[2] = v2[2] - v1[2];
+
+ ncrossprod(vec2, vec1, norm);
+}
+
+float xzlength(float v1[3], float v2[3])
+{
+ return sqrt((v1[0] - v2[0])*(v1[0] - v2[0]) +
+ (v1[2] - v2[2])*(v1[2] - v2[2]));
+}
+
+float xzslope(float v1[3], float v2[3])
+{
+ return ((v1[0] != v2[0]) ? ((v1[2] - v2[2]) / (v1[0] - v2[0]))
+ : FLT_MAX);
+}
+
+
+/***************************************************************/
+/************************ MOUNTAIN STUFF ***********************/
+/***************************************************************/
+
+GLfloat DispFactor[MAXLEVEL]; /* Array of what to multiply random number
+ by for a given level to get midpoint
+ displacement */
+GLfloat DispBias[MAXLEVEL]; /* Array of what to add to random number
+ before multiplying it by DispFactor */
+
+#define NUMRANDS 191
+float RandTable[NUMRANDS]; /* hash table of random numbers so we can
+ raise the same midpoints by the same amount */
+
+ /* The following are for permitting an edge of a moutain to be */
+ /* pegged so it won't be displaced up or down. This makes it */
+ /* easier to setup scenes and makes a single moutain look better */
+
+GLfloat Verts[3][3], /* Vertices of outside edges of mountain */
+ Slopes[3]; /* Slopes between these outside edges */
+int Pegged[3]; /* Is this edge pegged or not */
+
+ /*
+ * Comes up with a new table of random numbers [0,1)
+ */
+void InitRandTable(unsigned int seed)
+{
+ int i;
+
+ srand48((long) seed);
+ for (i = 0; i < NUMRANDS; i++)
+ RandTable[i] = drand48() - 0.5;
+}
+
+ /* calculate midpoint and displace it if required */
+void Midpoint(GLfloat mid[3], GLfloat v1[3], GLfloat v2[3],
+ int edge, int level)
+{
+ unsigned hash;
+
+ mid[0] = (v1[0] + v2[0]) / 2;
+ mid[1] = (v1[1] + v2[1]) / 2;
+ mid[2] = (v1[2] + v2[2]) / 2;
+ if (!Pegged[edge] || (fabs(xzslope(Verts[edge], mid)
+ - Slopes[edge]) > 0.00001)) {
+ srand48((int)((v1[0]+v2[0])*23344));
+ hash = unsigned(drand48() * 7334334);
+ srand48((int)((v2[2]+v1[2])*43433));
+ hash = (unsigned)(drand48() * 634344 + hash) % NUMRANDS;
+ mid[1] += ((RandTable[hash] + DispBias[level]) * DispFactor[level]);
+ }
+}
+
+ /*
+ * Recursive moutain drawing routine -- from lecture with addition of
+ * allowing an edge to be pegged. This function requires the above
+ * globals to be set, as well as the Level global for fractal level
+ */
+static float cutoff = -1;
+
+void FMR(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int level)
+{
+ if (level == Level) {
+ GLfloat norm[3];
+ if (v1[1] <= cutoff && v2[1]<=cutoff && v3[1]<=cutoff) return;
+ triagnormal(v1, v2, v3, norm);
+ glNormal3fv(norm);
+ glVertex3fv(v1);
+ glVertex3fv(v2);
+ glVertex3fv(v3);
+
+ } else {
+ GLfloat m1[3], m2[3], m3[3];
+
+ Midpoint(m1, v1, v2, 0, level);
+ Midpoint(m2, v2, v3, 1, level);
+ Midpoint(m3, v3, v1, 2, level);
+
+ FMR(v1, m1, m3, level + 1);
+ FMR(m1, v2, m2, level + 1);
+ FMR(m3, m2, v3, level + 1);
+ FMR(m1, m2, m3, level + 1);
+ }
+}
+
+ /*
+ * sets up lookup tables and calls recursive mountain function
+ */
+void FractalMountain(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3],
+ int pegged[3])
+{
+ GLfloat lengths[MAXLEVEL];
+ GLfloat fraction[8] = { 0.3, 0.3, 0.4, 0.2, 0.3, 0.2, 0.4, 0.4 };
+ GLfloat bias[8] = { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 };
+ int i;
+ float avglen = (xzlength(v1, v2) +
+ xzlength(v2, v3) +
+ xzlength(v3, v1) / 3);
+
+ for (i = 0; i < 3; i++) {
+ Verts[0][i] = v1[i]; /* set mountain vertex globals */
+ Verts[1][i] = v2[i];
+ Verts[2][i] = v3[i];
+ Pegged[i] = pegged[i];
+ }
+
+ Slopes[0] = xzslope(Verts[0], Verts[1]); /* set edge slope globals */
+ Slopes[1] = xzslope(Verts[1], Verts[2]);
+ Slopes[2] = xzslope(Verts[2], Verts[0]);
+
+ lengths[0] = avglen;
+ for (i = 1; i < Level; i++) {
+ lengths[i] = lengths[i-1]/2; /* compute edge length for each level */
+ }
+
+ for (i = 0; i < Level; i++) { /* DispFactor and DispBias arrays */
+ DispFactor[i] = (lengths[i] * ((i <= 7) ? fraction[i] : fraction[7]));
+ DispBias[i] = ((i <= 7) ? bias[i] : bias[7]);
+ }
+
+ glBegin(GL_TRIANGLES);
+ FMR(v1, v2, v3, 0); /* issues no GL but vertex calls */
+ glEnd();
+}
+
+ /*
+ * draw a mountain and build the display list
+ */
+void CreateMountain(void)
+{
+ GLfloat v1[3] = { 0, 0, -1 }, v2[3] = { -1, 0, 1 }, v3[3] = { 1, 0, 1 };
+ int pegged[3] = { 1, 1, 1 };
+
+ glNewList(MOUNTAIN, GL_COMPILE);
+ glPushAttrib(GL_LIGHTING_BIT);
+ glCallList(MOUNTAIN_MAT);
+ FractalMountain(v1, v2, v3, pegged);
+ glPopAttrib();
+ glEndList();
+}
+
+ /*
+ * new random numbers to make a different moutain
+ */
+void NewMountain(void)
+{
+ InitRandTable(time(NULL));
+}
+
+/***************************************************************/
+/***************************** TREE ****************************/
+/***************************************************************/
+
+long TreeSeed; /* for srand48 - remember so we can build "same tree"
+ at a different level */
+
+ /*
+ * recursive tree drawing thing, fleshed out from class notes pseudocode
+ */
+void FractalTree(int level)
+{
+ long savedseed; /* need to save seeds while building tree too */
+
+ if (level == Level) {
+ glPushMatrix();
+ glRotatef(drand48()*180, 0, 1, 0);
+ glCallList(STEMANDLEAVES);
+ glPopMatrix();
+ } else {
+ glCallList(STEM);
+ glPushMatrix();
+ glRotatef(drand48()*180, 0, 1, 0);
+ glTranslatef(0, 1, 0);
+ glScalef(0.7, 0.7, 0.7);
+
+ savedseed = (long)((ulong)drand48()*ULONG_MAX);
+ glPushMatrix();
+ glRotatef(110 + drand48()*40, 0, 1, 0);
+ glRotatef(30 + drand48()*20, 0, 0, 1);
+ FractalTree(level + 1);
+ glPopMatrix();
+
+ srand48(savedseed);
+ savedseed = (long)((ulong)drand48()*ULONG_MAX);
+ glPushMatrix();
+ glRotatef(-130 + drand48()*40, 0, 1, 0);
+ glRotatef(30 + drand48()*20, 0, 0, 1);
+ FractalTree(level + 1);
+ glPopMatrix();
+
+ srand48(savedseed);
+ glPushMatrix();
+ glRotatef(-20 + drand48()*40, 0, 1, 0);
+ glRotatef(30 + drand48()*20, 0, 0, 1);
+ FractalTree(level + 1);
+ glPopMatrix();
+
+ glPopMatrix();
+ }
+}
+
+ /*
+ * Create display lists for a leaf, a set of leaves, and a stem
+ */
+void CreateTreeLists(void)
+{
+ GLUquadricObj *cylquad = gluNewQuadric();
+ int i;
+
+ glNewList(STEM, GL_COMPILE);
+ glPushMatrix();
+ glRotatef(-90, 1, 0, 0);
+ gluCylinder(cylquad, 0.1, 0.08, 1, 10, 2 );
+ glPopMatrix();
+ glEndList();
+
+ glNewList(LEAF, GL_COMPILE); /* I think this was jeff allen's leaf idea */
+ glBegin(GL_TRIANGLES);
+ glNormal3f(-0.1, 0, 0.25); /* not normalized */
+ glVertex3f(0, 0, 0);
+ glVertex3f(0.25, 0.25, 0.1);
+ glVertex3f(0, 0.5, 0);
+
+ glNormal3f(0.1, 0, 0.25);
+ glVertex3f(0, 0, 0);
+ glVertex3f(0, 0.5, 0);
+ glVertex3f(-0.25, 0.25, 0.1);
+ glEnd();
+ glEndList();
+
+ glNewList(STEMANDLEAVES, GL_COMPILE);
+ glPushMatrix();
+ glPushAttrib(GL_LIGHTING_BIT);
+ glCallList(STEM);
+ glCallList(LEAF_MAT);
+ for(i = 0; i < 3; i++) {
+ glTranslatef(0, 0.333, 0);
+ glRotatef(90, 0, 1, 0);
+ glPushMatrix();
+ glRotatef(0, 0, 1, 0);
+ glRotatef(50, 1, 0, 0);
+ glCallList(LEAF);
+ glPopMatrix();
+ glPushMatrix();
+ glRotatef(180, 0, 1, 0);
+ glRotatef(60, 1, 0, 0);
+ glCallList(LEAF);
+ glPopMatrix();
+ }
+ glPopAttrib();
+ glPopMatrix();
+ glEndList();
+}
+
+ /*
+ * draw and build display list for tree
+ */
+void CreateTree(void)
+{
+ srand48(TreeSeed);
+
+ glNewList(TREE, GL_COMPILE);
+ glPushMatrix();
+ glPushAttrib(GL_LIGHTING_BIT);
+ glCallList(TREE_MAT);
+ glTranslatef(0, -1, 0);
+ FractalTree(0);
+ glPopAttrib();
+ glPopMatrix();
+ glEndList();
+}
+
+ /*
+ * new seed for a new tree (groan)
+ */
+void NewTree(void)
+{
+ TreeSeed = time(NULL);
+}
+
+/***************************************************************/
+/*********************** FRACTAL PLANET ************************/
+/***************************************************************/
+
+void CreateIsland(void)
+{
+ cutoff = .06;
+ CreateMountain();
+ cutoff = -1;
+ glNewList(ISLAND, GL_COMPILE);
+ glPushAttrib(GL_LIGHTING_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glCallList(WATER_MAT);
+
+ glBegin(GL_QUADS);
+ glNormal3f(0, 1, 0);
+ glVertex3f(10, 0.01, 10);
+ glVertex3f(10, 0.01, -10);
+ glVertex3f(-10, 0.01, -10);
+ glVertex3f(-10, 0.01, 10);
+ glEnd();
+
+ glPushMatrix();
+ glTranslatef(0, -0.1, 0);
+ glCallList(MOUNTAIN);
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(135, 0, 1, 0);
+ glTranslatef(0.2, -0.15, -0.4);
+ glCallList(MOUNTAIN);
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(-60, 0, 1, 0);
+ glTranslatef(0.7, -0.07, 0.5);
+ glCallList(MOUNTAIN);
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(-175, 0, 1, 0);
+ glTranslatef(-0.7, -0.05, -0.5);
+ glCallList(MOUNTAIN);
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(165, 0, 1, 0);
+ glTranslatef(-0.9, -0.12, 0.0);
+ glCallList(MOUNTAIN);
+ glPopMatrix();
+
+ glPopMatrix();
+ glPopAttrib();
+ glEndList();
+}
+
+
+void NewFractals(void)
+{
+ NewMountain();
+ NewTree();
+}
+
+void Create(int fract)
+{
+ switch(fract) {
+ case MOUNTAIN:
+ CreateMountain();
+ break;
+ case TREE:
+ CreateTree();
+ break;
+ case ISLAND:
+ CreateIsland();
+ break;
+ }
+}
+
+
+
+/***************************************************************/
+/**************************** OPENGL ***************************/
+/***************************************************************/
+
+
+void SetupMaterials(void)
+{
+ GLfloat mtn_ambuse[] = { 0.426, 0.256, 0.108, 1.0 };
+ GLfloat mtn_specular[] = { 0.394, 0.272, 0.167, 1.0 };
+ GLfloat mtn_shininess[] = { 10 };
+
+ GLfloat water_ambuse[] = { 0.0, 0.1, 0.5, 1.0 };
+ GLfloat water_specular[] = { 0.0, 0.1, 0.5, 1.0 };
+ GLfloat water_shininess[] = { 10 };
+
+ GLfloat tree_ambuse[] = { 0.4, 0.25, 0.1, 1.0 };
+ GLfloat tree_specular[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat tree_shininess[] = { 0 };
+
+ GLfloat leaf_ambuse[] = { 0.0, 0.8, 0.0, 1.0 };
+ GLfloat leaf_specular[] = { 0.0, 0.8, 0.0, 1.0 };
+ GLfloat leaf_shininess[] = { 10 };
+
+ glNewList(MOUNTAIN_MAT, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mtn_ambuse);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, mtn_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, mtn_shininess);
+ glEndList();
+
+ glNewList(WATER_MAT, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, water_ambuse);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, water_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, water_shininess);
+ glEndList();
+
+ glNewList(TREE_MAT, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tree_ambuse);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, tree_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, tree_shininess);
+ glEndList();
+
+ glNewList(LEAF_MAT, GL_COMPILE);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, leaf_ambuse);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, leaf_specular);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, leaf_shininess);
+ glEndList();
+}
+
+void myGLInit(void)
+{
+ GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat light_position[] = { 0.0, 0.3, 0.3, 0.0 };
+
+ GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glEnable(GL_NORMALIZE);
+#if 0
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+#endif
+
+ glShadeModel(GL_SMOOTH);
+#if 0
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#endif
+
+ SetupMaterials();
+ CreateTreeLists();
+
+ glFlush();
+}
+
+/***************************************************************/
+/************************ GLUT STUFF ***************************/
+/***************************************************************/
+
+void reshape(int w, int h)
+{
+ glViewport(0,0,w,h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(60.0, (GLdouble)w/h, 0.01, 100);
+ glPushMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glFlush();
+}
+
+void display(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glFlush();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glPushMatrix(); /* clear of last viewing xform, leaving perspective */
+
+ agvViewTransform();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ if (Rebuild) {
+ Create(Fract);
+ Rebuild = 0;
+ }
+
+ glCallList(Fract);
+
+ if (DrawAxes)
+ glCallList(AXES);
+
+ glutSwapBuffers();
+ glFlush();
+}
+
+void visible(int v)
+{
+ if (v == GLUT_VISIBLE)
+ agvSetAllowIdle(1);
+ else {
+ glutIdleFunc(NULL);
+ agvSetAllowIdle(0);
+ }
+}
+
+void menuuse(int v)
+{
+ if (v == GLUT_MENU_NOT_IN_USE)
+ agvSetAllowIdle(1);
+ else {
+ glutIdleFunc(NULL);
+ agvSetAllowIdle(0);
+ }
+}
+
+/***************************************************************/
+/******************* MENU SETUP & HANDLING *********************/
+/***************************************************************/
+
+typedef enum { MENU_QUIT, MENU_RAND, MENU_MOVE, MENU_AXES } MenuChoices;
+
+void setlevel(int value)
+{
+ Level = value;
+ Rebuild = 1;
+ glutPostRedisplay();
+}
+
+void choosefract(int value)
+{
+ Fract = value;
+ Rebuild = 1;
+ glutPostRedisplay();
+}
+
+void handlemenu(int value)
+{
+ switch (value) {
+ case MENU_QUIT:
+ exit(0);
+ break;
+ case MENU_RAND:
+ NewFractals();
+ Rebuild = 1;
+ glutPostRedisplay();
+ break;
+ case MENU_AXES:
+ DrawAxes = !DrawAxes;
+ glutPostRedisplay();
+ break;
+ }
+}
+
+void MenuInit(void)
+{
+ int submenu3, submenu2, submenu1;
+
+ submenu1 = glutCreateMenu(setlevel);
+ glutAddMenuEntry("0", 0); glutAddMenuEntry("1", 1);
+ glutAddMenuEntry("2", 2); glutAddMenuEntry("3", 3);
+ glutAddMenuEntry("4", 4); glutAddMenuEntry("5", 5);
+ glutAddMenuEntry("6", 6); glutAddMenuEntry("7", 7);
+ glutAddMenuEntry("8", 8);
+
+ submenu2 = glutCreateMenu(choosefract);
+ glutAddMenuEntry("Moutain", MOUNTAIN);
+ glutAddMenuEntry("Tree", TREE);
+ glutAddMenuEntry("Island", ISLAND);
+
+ submenu3 = glutCreateMenu(agvSwitchMoveMode);
+ glutAddMenuEntry("Flying", FLYING);
+ glutAddMenuEntry("Polar", POLAR);
+
+ glutCreateMenu(handlemenu);
+ glutAddSubMenu("Level", submenu1);
+ glutAddSubMenu("Fractal", submenu2);
+ glutAddSubMenu("Movement", submenu3);
+ glutAddMenuEntry("New Fractal", MENU_RAND);
+ glutAddMenuEntry("Toggle Axes", MENU_AXES);
+ glutAddMenuEntry("Quit", MENU_QUIT);
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+}
+
+
+/***************************************************************/
+/**************************** MAIN *****************************/
+/***************************************************************/
+
+// fltk-style callbacks to Glut menu callback translators:
+void setlevel(Fl_Widget*, void *value) {setlevel(long(value));}
+
+void choosefract(Fl_Widget*, void *value) {choosefract(long(value));}
+
+void handlemenu(Fl_Widget*, void *value) {handlemenu(long(value));}
+
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Window.H>
+
+int main(int argc, char** argv)
+{
+// glutInit(&argc, argv); // this line removed for fltk
+
+ // create fltk window:
+ Fl_Window window(512+20, 512+100);
+ window.resizable(window);
+
+ // create a bunch of buttons:
+ Fl_Group *g = new Fl_Group(110,50,400-110,30,"Level:");
+ g->align(FL_ALIGN_LEFT);
+ g->begin();
+ Fl_Button *b;
+ b = new Fl_Button(110,50,30,30,"0"); b->callback(setlevel,(void*)0);
+ b = new Fl_Button(140,50,30,30,"1"); b->callback(setlevel,(void*)1);
+ b = new Fl_Button(170,50,30,30,"2"); b->callback(setlevel,(void*)2);
+ b = new Fl_Button(200,50,30,30,"3"); b->callback(setlevel,(void*)3);
+ b = new Fl_Button(230,50,30,30,"4"); b->callback(setlevel,(void*)4);
+ b = new Fl_Button(260,50,30,30,"5"); b->callback(setlevel,(void*)5);
+ b = new Fl_Button(290,50,30,30,"6"); b->callback(setlevel,(void*)6);
+ b = new Fl_Button(320,50,30,30,"7"); b->callback(setlevel,(void*)7);
+ b = new Fl_Button(350,50,30,30,"8"); b->callback(setlevel,(void*)8);
+ g->end();
+
+ b = new Fl_Button(400,50,100,30,"New Fractal"); b->callback(handlemenu,(void*)MENU_RAND);
+
+ b = new Fl_Button( 10,10,100,30,"Mountain"); b->callback(choosefract,(void*)MOUNTAIN);
+ b = new Fl_Button(110,10,100,30,"Tree"); b->callback(choosefract,(void*)TREE);
+ b = new Fl_Button(210,10,100,30,"Island"); b->callback(choosefract,(void*)ISLAND);
+ b = new Fl_Button(400,10,100,30,"Quit"); b->callback(handlemenu,(void*)MENU_QUIT);
+
+
+ window.show(argc,argv); // glut will die unless parent window visible
+ window.begin(); // this will cause Glut window to be a child
+ glutInitWindowSize(512, 512);
+ glutInitWindowPosition(10,90); // place it inside parent window
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
+ glutCreateWindow("Fractal Planet?");
+ window.end();
+ window.resizable(glut_window);
+
+ agvInit(1); /* 1 cause we don't have our own idle */
+
+ glutReshapeFunc(reshape);
+ glutDisplayFunc(display);
+ glutVisibilityFunc(visible);
+ glutMenuStateFunc(menuuse);
+
+ NewFractals();
+ agvMakeAxesList(AXES);
+ myGLInit();
+ MenuInit();
+
+ glutMainLoop(); // must use this rather than Fl::run if glutIdleFunc is used
+ return 0;
+}
+#endif
diff --git a/test/fracviewer.c b/test/fracviewer.c
new file mode 100644
index 000000000..9d926c175
--- /dev/null
+++ b/test/fracviewer.c
@@ -0,0 +1,496 @@
+/*
+ * fractviewer.c [from agviewer.c (version 1.0)]
+ *
+ * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut
+ *
+ * See agv_example.c and agviewer.h comments within for more info.
+ *
+ * I welcome any feedback or improved versions!
+ *
+ * Philip Winston - 4/11/95
+ * pwinston@hmc.edu
+ * http://www.cs.hmc.edu/people/pwinston
+ */
+
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "fracviewer.h"
+
+/* Some <math.h> files do not define M_PI... */
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+/***************************************************************/
+/************************** SETTINGS ***************************/
+/***************************************************************/
+
+ /* Initial polar movement settings */
+#define INIT_POLAR_AZ 0.0
+#define INIT_POLAR_EL 30.0
+#define INIT_DIST 4.0
+#define INIT_AZ_SPIN 0.5
+#define INIT_EL_SPIN 0.0
+
+ /* Initial flying movement settings */
+#define INIT_EX 0.0
+#define INIT_EY -2.0
+#define INIT_EZ -2.0
+#define INIT_MOVE 0.01
+#define MINMOVE 0.001
+
+ /* Start in this mode */
+#define INIT_MODE POLAR
+
+ /* Controls: */
+
+ /* map 0-9 to an EyeMove value when number key is hit in FLYING mode */
+#define SPEEDFUNCTION(x) ((x)*(x)*0.001)
+
+ /* Multiply EyeMove by (1+-MOVEFRACTION) when +/- hit in FLYING mode */
+#define MOVEFRACTION 0.25
+
+ /* What to multiply number of pixels mouse moved by to get rotation amount */
+#define EL_SENS 0.5
+#define AZ_SENS 0.5
+
+ /* What to multiply number of pixels mouse moved by for movement amounts */
+#define DIST_SENS 0.01
+#define E_SENS 0.01
+
+ /* Minimum spin to allow in polar (lower forced to zero) */
+#define MIN_AZSPIN 0.1
+#define MIN_ELSPIN 0.1
+
+ /* Factors used in computing dAz and dEl (which determine AzSpin, ElSpin) */
+#define SLOW_DAZ 0.90
+#define SLOW_DEL 0.90
+#define PREV_DAZ 0.80
+#define PREV_DEL 0.80
+#define CUR_DAZ 0.20
+#define CUR_DEL 0.20
+
+/***************************************************************/
+/************************** GLOBALS ****************************/
+/***************************************************************/
+
+int MoveMode = INIT_MODE; /* FLYING or POLAR mode? */
+
+GLfloat Ex = INIT_EX, /* flying parameters */
+ Ey = INIT_EY,
+ Ez = INIT_EZ,
+ EyeMove = INIT_MOVE,
+
+ EyeDist = INIT_DIST, /* polar params */
+ AzSpin = INIT_AZ_SPIN,
+ ElSpin = INIT_EL_SPIN,
+
+ EyeAz = INIT_POLAR_AZ, /* used by both */
+ EyeEl = INIT_POLAR_EL;
+
+int agvMoving; /* Currently moving? */
+
+int downx, downy, /* for tracking mouse position */
+ lastx, lasty,
+ downb = -1; /* and button status */
+
+GLfloat downDist, downEl, downAz, /* for saving state of things */
+ downEx, downEy, downEz, /* when button is pressed */
+ downEyeMove;
+
+GLfloat dAz, dEl, lastAz, lastEl; /* to calculate spinning w/ polar motion */
+int AdjustingAzEl = 0;
+
+int AllowIdle, RedisplayWindow;
+ /* If AllowIdle is 1 it means AGV will install its own idle which
+ * will update the viewpoint as needed and send glutPostRedisplay() to the
+ * window RedisplayWindow which was set in agvInit(). AllowIdle of 0
+ * means AGV won't install an idle funciton, and something like
+ * "if (agvMoving) agvMove()" should exist at the end of the running
+ * idle function.
+ */
+
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+#define TORAD(x) ((M_PI/180.0)*(x))
+#define TODEG(x) ((180.0/M_PI)*(x))
+
+/***************************************************************/
+/************************ PROTOTYPES ***************************/
+/***************************************************************/
+
+ /*
+ * these are functions meant for internal use only
+ * the other prototypes are in agviewer.h
+ */
+
+void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth);
+void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z,
+ GLfloat az, GLfloat el);
+int ConstrainEl(void);
+void MoveOn(int v);
+void SetMove(float newmove);
+static void normalize(GLfloat v[3]);
+static void ncrossprod(float v1[3], float v2[3], float cp[3]);
+
+
+/***************************************************************/
+/************************ agvInit ******************************/
+/***************************************************************/
+
+void agvInit(int window)
+{
+ glutMouseFunc(agvHandleButton);
+ glutMotionFunc(agvHandleMotion);
+ glutKeyboardFunc(agvHandleKeys);
+ RedisplayWindow = glutGetWindow();
+ agvSetAllowIdle(window);
+}
+
+/***************************************************************/
+/************************ VIEWPOINT STUFF **********************/
+/***************************************************************/
+
+ /*
+ * viewing transformation modified from page 90 of red book
+ */
+void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth)
+{
+ glTranslatef(0, 0, -dist);
+ glRotatef(elevation, 1, 0, 0);
+ glRotatef(azimuth, 0, 1, 0);
+
+}
+
+ /*
+ * I took the idea of tracking eye position in absolute
+ * coords and direction looking in Polar form from denis
+ */
+void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, GLfloat az, GLfloat el)
+{
+ float lookat[3], perp[3], up[3];
+
+ lookat[0] = sin(TORAD(az))*cos(TORAD(el));
+ lookat[1] = sin(TORAD(el));
+ lookat[2] = -cos(TORAD(az))*cos(TORAD(el));
+ normalize(lookat);
+ perp[0] = lookat[2];
+ perp[1] = 0;
+ perp[2] = -lookat[0];
+ normalize(perp);
+ ncrossprod(lookat, perp, up);
+ gluLookAt(x, y, z,
+ x+lookat[0], y+lookat[1], z+lookat[2],
+ up[0], up[1], up[2]);
+}
+
+ /*
+ * Call viewing transformation based on movement mode
+ */
+void agvViewTransform(void)
+{
+ switch (MoveMode) {
+ case FLYING:
+ FlyLookFrom(Ex, Ey, Ez, EyeAz, EyeEl);
+ break;
+ case POLAR:
+ PolarLookFrom(EyeDist, EyeEl, EyeAz);
+ break;
+ }
+}
+
+ /*
+ * keep them vertical; I think this makes a lot of things easier,
+ * but maybe it wouldn't be too hard to adapt things to let you go
+ * upside down
+ */
+int ConstrainEl(void)
+{
+ if (EyeEl <= -90) {
+ EyeEl = -89.99;
+ return 1;
+ } else if (EyeEl >= 90) {
+ EyeEl = 89.99;
+ return 1;
+ }
+ return 0;
+}
+
+ /*
+ * Idle Function - moves eyeposition
+ */
+void agvMove(void)
+{
+
+ switch (MoveMode) {
+ case FLYING:
+ Ex += EyeMove*sin(TORAD(EyeAz))*cos(TORAD(EyeEl));
+ Ey += EyeMove*sin(TORAD(EyeEl));
+ Ez -= EyeMove*cos(TORAD(EyeAz))*cos(TORAD(EyeEl));
+ break;
+
+ case POLAR:
+ EyeEl += ElSpin;
+ EyeAz += AzSpin;
+ if (ConstrainEl()) { /* weird spin thing to make things look */
+ ElSpin = -ElSpin; /* look better when you are kept from going */
+ /* upside down while spinning - Isn't great */
+ if (fabs(ElSpin) > fabs(AzSpin))
+ AzSpin = fabs(ElSpin) * ((AzSpin > 0) ? 1 : -1);
+ }
+ break;
+ }
+
+ if (AdjustingAzEl) {
+ dAz *= SLOW_DAZ;
+ dEl *= SLOW_DEL;
+ }
+
+ if (AllowIdle) {
+ glutSetWindow(RedisplayWindow);
+ glutPostRedisplay();
+ }
+}
+
+
+ /*
+ * Don't install agvMove as idle unless we will be updating the view
+ * and we've been given a RedisplayWindow
+ */
+void MoveOn(int v)
+{
+ if (v && ((MoveMode == FLYING && EyeMove != 0) ||
+ (MoveMode == POLAR &&
+ (AzSpin != 0 || ElSpin != 0 || AdjustingAzEl)))) {
+ agvMoving = 1;
+ if (AllowIdle)
+ glutIdleFunc(agvMove);
+ } else {
+ agvMoving = 0;
+ if (AllowIdle)
+ glutIdleFunc(NULL);
+ }
+}
+
+ /*
+ * set new redisplay window. If <= 0 it means we are not to install
+ * an idle function and will rely on whoever does install one to
+ * put statement like "if (agvMoving) agvMove();" at end of it
+ */
+void agvSetAllowIdle(int allowidle)
+{
+ if ((AllowIdle = allowidle))
+ MoveOn(1);
+}
+
+
+ /*
+ * when moving to flying we stay in the same spot, moving to polar we
+ * reset since we have to be looking at the origin (though a pivot from
+ * current position to look at origin might be cooler)
+ */
+void agvSwitchMoveMode(int move)
+{
+ switch (move) {
+ case FLYING:
+ if (MoveMode == FLYING) return;
+ Ex = -EyeDist*sin(TORAD(EyeAz))*cos(TORAD(EyeEl));
+ Ey = EyeDist*sin(TORAD(EyeEl));
+ Ez = EyeDist*(cos(TORAD(EyeAz))*cos(TORAD(EyeEl)));
+ EyeAz = EyeAz;
+ EyeEl = -EyeEl;
+ EyeMove = INIT_MOVE;
+ break;
+ case POLAR:
+ EyeDist = INIT_DIST;
+ EyeAz = INIT_POLAR_AZ;
+ EyeEl = INIT_POLAR_EL;
+ AzSpin = INIT_AZ_SPIN;
+ ElSpin = INIT_EL_SPIN;
+ break;
+ }
+ MoveMode = move;
+ MoveOn(1);
+ glutPostRedisplay();
+}
+
+/***************************************************************/
+/******************* MOUSE HANDLING ***********************/
+/***************************************************************/
+
+void agvHandleButton(int button, int state, int x, int y)
+{
+ if (state == GLUT_DOWN && downb == -1) {
+ lastx = downx = x;
+ lasty = downy = y;
+ downb = button;
+
+ switch (button) {
+ case GLUT_LEFT_BUTTON:
+ lastEl = downEl = EyeEl;
+ lastAz = downAz = EyeAz;
+ AzSpin = ElSpin = dAz = dEl = 0;
+ AdjustingAzEl = 1;
+ MoveOn(1);
+ break;
+
+ case GLUT_MIDDLE_BUTTON:
+ downDist = EyeDist;
+ downEx = Ex;
+ downEy = Ey;
+ downEz = Ez;
+ downEyeMove = EyeMove;
+ EyeMove = 0;
+ }
+
+ } else if (state == GLUT_UP && button == downb) {
+
+ downb = -1;
+
+ switch (button) {
+ case GLUT_LEFT_BUTTON:
+ if (MoveMode != FLYING) {
+ AzSpin = -dAz;
+ if (AzSpin < MIN_AZSPIN && AzSpin > -MIN_AZSPIN)
+ AzSpin = 0;
+ ElSpin = -dEl;
+ if (ElSpin < MIN_ELSPIN && ElSpin > -MIN_ELSPIN)
+ ElSpin = 0;
+ }
+ AdjustingAzEl = 0;
+ MoveOn(1);
+ break;
+
+ case GLUT_MIDDLE_BUTTON:
+ EyeMove = downEyeMove;
+ }
+ }
+}
+
+ /*
+ * change EyeEl and EyeAz and position when mouse is moved w/ button down
+ */
+void agvHandleMotion(int x, int y)
+{
+ int deltax = x - downx, deltay = y - downy;
+
+ switch (downb) {
+ case GLUT_LEFT_BUTTON:
+ EyeEl = downEl + EL_SENS * ((MoveMode == FLYING) ? -deltay : deltay);
+ ConstrainEl();
+ EyeAz = downAz + AZ_SENS * deltax;
+ dAz = PREV_DAZ*dAz + CUR_DAZ*(lastAz - EyeAz);
+ dEl = PREV_DEL*dEl + CUR_DEL*(lastEl - EyeEl);
+ lastAz = EyeAz;
+ lastEl = EyeEl;
+ break;
+ case GLUT_MIDDLE_BUTTON:
+ EyeDist = downDist + DIST_SENS*deltay;
+ Ex = downEx - E_SENS*deltay*sin(TORAD(EyeAz))*cos(TORAD(EyeEl));
+ Ey = downEy - E_SENS*deltay*sin(TORAD(EyeEl));
+ Ez = downEz + E_SENS*deltay*cos(TORAD(EyeAz))*cos(TORAD(EyeEl));
+ break;
+ }
+ glutPostRedisplay();
+}
+
+/***************************************************************/
+/********************* KEYBOARD HANDLING ***********************/
+/***************************************************************/
+
+ /*
+ * set EyeMove (current speed) for FLYING mode
+ */
+void SetMove(float newmove)
+{
+ if (newmove > MINMOVE) {
+ EyeMove = newmove;
+ MoveOn(1);
+ } else {
+ EyeMove = 0;
+ MoveOn(0);
+ }
+}
+
+ /*
+ * 0->9 set speed, +/- adjust current speed -- in FLYING mode
+ */
+void agvHandleKeys(unsigned char key, int, int) {
+ if (MoveMode != FLYING)
+ return;
+
+ if (key >= '0' && key <= '9')
+ SetMove(SPEEDFUNCTION((key-'0')));
+ else
+ switch(key) {
+ case '+':
+ if (EyeMove == 0)
+ SetMove(MINMOVE);
+ else
+ SetMove(EyeMove *= (1 + MOVEFRACTION));
+ break;
+ case '-':
+ SetMove(EyeMove *= (1 - MOVEFRACTION));
+ break;
+ }
+}
+
+/***************************************************************/
+/*********************** VECTOR STUFF **************************/
+/***************************************************************/
+
+ /* normalizes v */
+static void normalize(GLfloat v[3])
+{
+ GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+
+ if (d == 0)
+ fprintf(stderr, "Zero length vector in normalize\n");
+ else
+ v[0] /= d; v[1] /= d; v[2] /= d;
+}
+
+ /* calculates a normalized crossproduct to v1, v2 */
+static void ncrossprod(float v1[3], float v2[3], float cp[3])
+{
+ cp[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ cp[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ cp[2] = v1[0]*v2[1] - v1[1]*v2[0];
+ normalize(cp);
+}
+
+/***************************************************************/
+/**************************** AXES *****************************/
+/***************************************************************/
+
+
+ /* draw axes -- was helpful to debug/design things */
+void agvMakeAxesList(int displaylistnum)
+{
+ int i,j;
+ GLfloat axes_ambuse[] = { 0.5, 0.0, 0.0, 1.0 };
+ glNewList(displaylistnum, GL_COMPILE);
+ glPushAttrib(GL_LIGHTING_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, axes_ambuse);
+ glBegin(GL_LINES);
+ glVertex3f(15, 0, 0); glVertex3f(-15, 0, 0);
+ glVertex3f(0, 15, 0); glVertex3f(0, -15, 0);
+ glVertex3f(0, 0, 15); glVertex3f(0, 0, -15);
+ glEnd();
+ for (i = 0; i < 3; i++) {
+ glPushMatrix();
+ glTranslatef(-10*(i==0), -10*(i==1), -10*(i==2));
+ for (j = 0; j < 21; j++) {
+// glutSolidCube(0.1);
+ glTranslatef(i==0, i==1, i==2);
+ }
+ glPopMatrix();
+ }
+ glPopAttrib();
+ glEndList();
+}
+
+
diff --git a/test/fracviewer.h b/test/fracviewer.h
new file mode 100644
index 000000000..d217e9aa6
--- /dev/null
+++ b/test/fracviewer.h
@@ -0,0 +1,104 @@
+/*
+ * fracviewer.h [from agviewer.h (version 1.0)]
+ *
+ * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut
+ *
+ * The two view movement modes are POLAR and FLYING. Both move the eye, NOT
+ * THE OBJECT. You can never be upside down or twisted (roll) in either mode.
+ *
+ * A nice addition would be an examiner type trackball mode where you are
+ * moving the object and so could see it from any angle. Also less restricted
+ * flying and polar modes (fly upside down, do rolls, etc.).
+ *
+ * Controls for Polar are just left and middle buttons -- for flying it's
+ * those plus 0-9 number keys and +/- for speed adjustment.
+ *
+ * See agv_example.c and agviewer.c for more info. Probably want to make
+ * a copy of these and then edit for each program. This isn't meant to be
+ * a library, just something to graft onto your own programs.
+ *
+ * I welcome any feedback or improved versions.
+ *
+ * Philip Winston - 4/11/95
+ * pwinston@hmc.edu
+ * http://www.cs.hmc.edu/people/pwinston
+ */
+
+
+ /*
+ * Call agvInit() with glut's current window set to the window in
+ * which you want to run the viewer. Right after creating it is fine. It
+ * will remember that window for possible later use (see below) and
+ * registers mouse, motion, and keyboard handlers for that window (see below).
+ *
+ * allowidle is 1 or 0 depnding on whether you will let AGV install
+ * and uninstall an idle function. 0 means you will not let it (because
+ * you will be having your own idle function). In this case it is your
+ * responsibility to put a statement like:
+ *
+ * if (agvMoving)
+ * agvMove();
+ *
+ * at the end of your idle function, to let AGV update the viewpoint if it
+ * is moving.
+ *
+ * If allowidle is 1 it means AGV will install its own idle which
+ * will update the viewpoint as needed and send glutPostRedisplay() to the
+ * window which was current when agvInit() was called.
+ *
+ * agvSetIdleAllow changes this value so you can let AGV install its idle
+ * when your idle isn't installed.
+ *
+ */
+void agvInit(int allowidle);
+void agvSetAllowIdle(int allowidle);
+
+
+ /*
+ * Set which movement mode you are in.
+ */
+typedef enum { FLYING, POLAR } MovementType;
+void agvSwitchMoveMode(int move);
+
+ /*
+ * agvViewTransform basically does the appropriate gluLookAt() for the
+ * current position. So call it in your display on the projection matrix
+ */
+void agvViewTransform(void);
+
+ /*
+ * agvMoving will be set by AGV according to whether it needs you to call
+ * agvMove() at the end of your idle function. You only need these if
+ * you aren't allowing AGV to do its own idle.
+ * (Don't change the value of agvMoving)
+ */
+extern int agvMoving;
+void agvMove(void);
+
+ /*
+ * These are the routines AGV registers to deal with mouse and keyboard input.
+ * Keyboard input only matters in flying mode, and then only to set speed.
+ * Mouse input only uses left two buttons in both modes.
+ * These are all registered with agvInit(), but you could register
+ * something else which called these, or reregister these as needed
+ */
+void agvHandleButton(int button, int state, int x, int y);
+void agvHandleMotion(int x, int y);
+void agvHandleKeys(unsigned char key, int x, int y);
+
+ /*
+ * Just an extra routine which makes an x-y-z axes (about 10x10x10)
+ * which is nice for aligning things and debugging. Pass it an available
+ * displaylist number.
+ */
+void agvMakeAxesList(int displaylist);
+
+
+
+
+
+
+
+
+
+
diff --git a/test/fromdos.c b/test/fromdos.c
new file mode 100644
index 000000000..54dff5a9f
--- /dev/null
+++ b/test/fromdos.c
@@ -0,0 +1,65 @@
+/* fromdos.c : strip the stupid ^M characters without mistakes! */
+
+/* this can do in-place conversion or be used as a pipe... */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+int main(int argc, char** argv) {
+ int f,c;
+ if (argc <= 1) {
+ if (isatty(0)) {
+ fprintf(stderr,"usage : %s <files>\nStrips ^M characters.\nCan do in-place conversion of many files or can be used in a pipe\n",argv[0]);
+ return 1;
+ }
+ for (;;) {
+ c = getchar();
+ while (c == '\r') {
+ c = getchar();
+ if (c != '\n') putchar(c);
+ }
+ if (c < 0) break;
+ putchar(c);
+ }
+ return 0;
+ }
+ for (f = 1; f < argc; f++) {
+ char* fname = argv[f];
+ char tempname[1024];
+ FILE* in = fopen(fname,"rb");
+ FILE* out;
+ int mod = 0;
+ if (!in) {
+ fprintf(stderr,"%s : %s\n", fname, strerror(errno));
+ return 1;
+ }
+ strcpy(tempname, fname);
+ strcat(tempname, ".temp");
+ out = fopen(tempname, "wb");
+ if (!out) {
+ fprintf(stderr,"%s : %s\n", fname, strerror(errno));
+ return 1;
+ }
+ for (;;) {
+ c = getc(in);
+ while (c == '\r') {
+ c = getc(in);
+ if (c == '\n') mod=1; else putc(c,out);
+ }
+ if (c < 0) break;
+ putc(c,out);
+ }
+ fclose(in);
+ fclose(out);
+ if (!mod) {
+ fprintf(stderr,"%s : no change\n", fname);
+ unlink(tempname);
+ } else if (rename(tempname, fname)) {
+ fprintf(stderr,"Can't mv %s %s : %s\n",tempname,fname,strerror(errno));
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/test/fullscreen.cxx b/test/fullscreen.cxx
new file mode 100644
index 000000000..08317d315
--- /dev/null
+++ b/test/fullscreen.cxx
@@ -0,0 +1,219 @@
+/* fullscreen.C
+
+ This demo shows how to do many of the window manipulations that
+ are popular on SGI programs, even though X does not really like
+ them. You can toggle the border on/off, change the visual to
+ switch between single/double buffer, and make the window take
+ over the screen.
+
+ Normally the program makes a single window with a child GL window.
+ This simulates a program where the 3D display is surrounded by
+ control knobs. Running the program with an argument will
+ make it make a seperate GL window from the controls window. This
+ simulates a (older?) style program where the graphics display is
+ a different window than the controls.
+
+ This program reports how many times it redraws the window to
+ stdout, so you can see how much time it is wasting. It appears
+ to be impossible to prevent X from sending redundant resize
+ events, so there are extra redraws. But the way I have the
+ code arranged here seems to be keeping that to a minimu.
+
+ Apparently unavoidable bugs:
+
+ Turning the border on causes an unnecessary redraw.
+
+ Turning off full screen when the border is on causes an unnecessary
+ resize and redraw when the program turns the border on.
+
+ If it is a seperate window, turning double buffering on and off
+ will cause the window to raise, deiconize, and possibly move. You
+ can avoid this by making the Fl_Gl_Window a child of a normal
+ window.
+
+*/
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/Fl_Hor_Slider.H>
+#include <FL/Fl_Toggle_Light_Button.H>
+#include <FL/math.h>
+#include <stdio.h>
+
+#if HAVE_GL
+#include <FL/gl.h>
+#include <FL/Fl_Gl_Window.H>
+
+class shape_window : public Fl_Gl_Window {
+ void draw();
+public:
+ int sides;
+ shape_window(int x,int y,int w,int h,const char *l=0);
+};
+
+shape_window::shape_window(int x,int y,int w,int h,const char *l) :
+Fl_Gl_Window(x,y,w,h,l) {
+ sides = 3;
+}
+
+void shape_window::draw() {
+ printf("drawing size %d %d\n",w(),h());
+ if (!valid()) {
+ valid(1);
+// printf("init\n");
+ glLoadIdentity();
+ glViewport(0,0,w(),h());
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(.5,.6,.7);
+ glBegin(GL_POLYGON);
+ for (int i=0; i<sides; i++) {
+ double ang = i*2*M_PI/sides;
+ glVertex3f(cos(ang),sin(ang),0);
+ }
+ glEnd();
+}
+
+#else
+
+#include <FL/fl_draw.H>
+
+class shape_window : public Fl_Window {
+ void draw();
+public:
+ int sides;
+ shape_window(int x,int y,int w,int h,const char *l=0);
+};
+
+shape_window::shape_window(int x,int y,int w,int h,const char *l) :
+Fl_Window(x,y,w,h,l) {
+ sides = 3;
+}
+
+void shape_window::draw() {
+ fl_color(0);
+ fl_rectf(0,0,w(),h());
+ fl_font(0,20);
+ fl_color(7);
+ fl_draw("This requires GL",0,0,w(),h(),FL_ALIGN_CENTER);
+}
+
+#endif
+
+void sides_cb(Fl_Widget *o, void *p) {
+ shape_window *sw = (shape_window *)p;
+ sw->sides = int(((Fl_Slider *)o)->value());
+ sw->redraw();
+}
+
+#if HAVE_GL
+void double_cb(Fl_Widget *o, void *p) {
+ shape_window *sw = (shape_window *)p;
+ int d = ((Fl_Button *)o)->value();
+ sw->mode(d ? Fl_Mode(FL_DOUBLE|FL_RGB) : FL_RGB);
+}
+#else
+void double_cb(Fl_Widget *, void *) {}
+#endif
+
+void border_cb(Fl_Widget *o, void *p) {
+ Fl_Window *w = (Fl_Window *)p;
+ int d = ((Fl_Button *)o)->value();
+ w->border(d);
+}
+
+int px,py,pw,ph;
+Fl_Button *border_button;
+void fullscreen_cb(Fl_Widget *o, void *p) {
+ Fl_Window *w = (Fl_Window *)p;
+ int d = ((Fl_Button *)o)->value();
+ if (d) {
+ px = w->x();
+ py = w->y();
+ pw = w->w();
+ ph = w->h();
+ w->fullscreen();
+ } else {
+ w->fullscreen_off(px,py,pw,ph);
+ }
+}
+
+#include <stdlib.h>
+
+void exit_cb(Fl_Widget *, void *) {
+ exit(0);
+}
+
+#define NUMB 5
+
+int twowindow = 0;
+int initfull = 0;
+int arg(int, char **argv, int &i) {
+ if (argv[i][1] == '2') {twowindow = 1; i++; return 1;}
+ if (argv[i][1] == 'f') {initfull = 1; i++; return 1;}
+ return 0;
+}
+
+int main(int argc, char **argv) {
+
+ int i=0;
+ if (Fl::args(argc,argv,i,arg) < argc)
+ Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
+
+ Fl_Single_Window window(300,300+30*NUMB); window.end();
+
+ shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-20);
+#if HAVE_GL
+ sw.mode(FL_RGB);
+#endif
+
+ Fl_Window *w;
+ if (twowindow) { // make it's own window
+ sw.resizable(&sw);
+ w = &sw;
+ window.set_modal(); // makes controls stay on top when fullscreen pushed
+ argc--;
+ sw.show();
+ } else { // otherwise make a subwindow
+ window.add(sw);
+ window.resizable(&sw);
+ w = &window;
+ }
+
+ window.begin();
+
+ int y = window.h()-30*NUMB-5;
+ Fl_Hor_Slider slider(50,y,window.w()-60,30,"Sides:");
+ slider.align(FL_ALIGN_LEFT);
+ slider.callback(sides_cb,&sw);
+ slider.value(sw.sides);
+ slider.step(1);
+ slider.bounds(3,40);
+ y+=30;
+
+ Fl_Toggle_Light_Button b1(50,y,window.w()-60,30,"Double Buffered");
+ b1.callback(double_cb,&sw);
+ y+=30;
+
+ Fl_Toggle_Light_Button b2(50,y,window.w()-60,30,"Border");
+ b2.callback(border_cb,w);
+ b2.set();
+ border_button = &b2;
+ y+=30;
+
+ Fl_Toggle_Light_Button b3(50,y,window.w()-60,30,"FullScreen");
+ b3.callback(fullscreen_cb,w);
+ y+=30;
+
+ Fl_Button eb(50,y,window.w()-60,30,"Exit");
+ eb.callback(exit_cb);
+ y+=30;
+
+ if (initfull) {b3.set(); b3.do_callback();}
+
+ window.end();
+ window.show(argc,argv);
+
+ return Fl::run();
+}
diff --git a/test/gl_overlay.cxx b/test/gl_overlay.cxx
new file mode 100644
index 000000000..db7c0e3d8
--- /dev/null
+++ b/test/gl_overlay.cxx
@@ -0,0 +1,128 @@
+/* The simple GL demo, modified to draw the GL overlay as well */
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Hor_Slider.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/math.h>
+
+#if !HAVE_GL
+#include <FL/Fl_Box.H>
+class shape_window : public Fl_Box {
+public:
+ int sides;
+ shape_window(int x,int y,int w,int h,const char *l=0)
+ :Fl_Box(FL_DOWN_BOX,x,y,w,h,l){
+ label("This demo does\nnot work without GL");
+ }
+};
+#else
+#include <FL/gl.h>
+#include <FL/Fl_Gl_Window.H>
+
+class shape_window : public Fl_Gl_Window {
+ void draw();
+ void draw_overlay();
+public:
+ int sides;
+ int overlay_sides;
+ shape_window(int x,int y,int w,int h,const char *l=0);
+};
+
+shape_window::shape_window(int x,int y,int w,int h,const char *l) :
+Fl_Gl_Window(x,y,w,h,l) {
+ sides = overlay_sides = 3;
+}
+
+void shape_window::draw() {
+// the valid() property may be used to avoid reinitializing your
+// GL transformation for each redraw:
+ if (!valid()) {
+ valid(1);
+ glLoadIdentity();
+ glViewport(0,0,w(),h());
+ }
+// draw an amazing but slow graphic:
+ glClear(GL_COLOR_BUFFER_BIT);
+ // for (int j=1; j<=1000; j++) {
+ glBegin(GL_POLYGON);
+ for (int i=0; i<sides; i++) {
+ double ang = i*2*M_PI/sides;
+ glColor3f(float(i)/sides,float(i)/sides,float(i)/sides);
+ glVertex3f(cos(ang),sin(ang),0);
+ }
+ glEnd();
+ // }
+}
+
+void shape_window::draw_overlay() {
+// the valid() property may be used to avoid reinitializing your
+// GL transformation for each redraw:
+ if (!valid()) {
+ valid(1);
+ glLoadIdentity();
+ glViewport(0,0,w(),h());
+ }
+// draw an amazing graphic:
+ gl_color(FL_RED);
+ glBegin(GL_LINE_LOOP);
+ for (int i=0; i<overlay_sides; i++) {
+ double ang = i*2*M_PI/overlay_sides;
+ glVertex3f(cos(ang),sin(ang),0);
+ }
+ glEnd();
+}
+#endif
+
+// when you change the data, as in this callback, you must call redraw():
+void sides_cb(Fl_Widget *o, void *p) {
+ shape_window *sw = (shape_window *)p;
+ sw->sides = int(((Fl_Slider *)o)->value());
+ sw->redraw();
+}
+
+#if HAVE_GL
+void overlay_sides_cb(Fl_Widget *o, void *p) {
+ shape_window *sw = (shape_window *)p;
+ sw->overlay_sides = int(((Fl_Slider *)o)->value());
+ sw->redraw_overlay();
+}
+#endif
+#include <stdio.h>
+int main(int argc, char **argv) {
+
+ Fl_Window window(300, 370);
+
+ shape_window sw(10, 75, window.w()-20, window.h()-90);
+//sw.mode(FL_RGB);
+ window.resizable(&sw);
+
+ Fl_Hor_Slider slider(60, 5, window.w()-70, 30, "Sides:");
+ slider.align(FL_ALIGN_LEFT);
+ slider.callback(sides_cb,&sw);
+ slider.value(sw.sides);
+ slider.step(1);
+ slider.bounds(3,40);
+
+ Fl_Hor_Slider oslider(60, 40, window.w()-70, 30, "Overlay:");
+ oslider.align(FL_ALIGN_LEFT);
+#if HAVE_GL
+ oslider.callback(overlay_sides_cb,&sw);
+ oslider.value(sw.overlay_sides);
+#endif
+ oslider.step(1);
+ oslider.bounds(3,40);
+
+ window.end();
+ window.show(argc,argv);
+#if HAVE_GL
+ printf("Can do overlay = %d\n", sw.can_do_overlay());
+ sw.show();
+ sw.redraw_overlay();
+#else
+ sw.show();
+#endif
+
+ return Fl::run();
+}
diff --git a/test/glpuzzle.cxx b/test/glpuzzle.cxx
new file mode 100644
index 000000000..78d515c35
--- /dev/null
+++ b/test/glpuzzle.cxx
@@ -0,0 +1,1455 @@
+// This is a GLUT demo program to demonstrate fltk's GLUT emulation.
+// Search for "fltk" to find all the changes
+
+// this block added for fltk's distribtion so it will compile w/o OpenGL:
+#include <config.h>
+#if !HAVE_GL
+#include <FL/Fl.H>
+#include <FL/fl_message.H>
+int main(int, char**) {
+ fl_alert("This demo does not work without GL");
+ return 1;
+}
+#else
+// end of added block
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <math.h>
+#include <FL/glut.H> // changed for fltk
+#include "trackball.c" // changed from trackball.h for fltk
+
+#define WIDTH 4
+#define HEIGHT 5
+#define PIECES 10
+#define OFFSETX -2
+#define OFFSETY -2.5
+#define OFFSETZ -0.5
+
+typedef char Config[HEIGHT][WIDTH];
+
+struct puzzle {
+ struct puzzle *backptr;
+ struct puzzle *solnptr;
+ Config pieces;
+ struct puzzle *next;
+ unsigned hashvalue;
+};
+
+#define HASHSIZE 10691
+
+struct puzzlelist {
+ struct puzzle *puzzle;
+ struct puzzlelist *next;
+};
+
+static char convert[PIECES + 1] =
+{0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4};
+
+static unsigned char colors[PIECES + 1][3] =
+{
+ {0, 0, 0},
+ {255, 255, 127},
+ {255, 255, 127},
+ {255, 255, 127},
+ {255, 255, 127},
+ {255, 127, 255},
+ {255, 127, 255},
+ {255, 127, 255},
+ {255, 127, 255},
+ {255, 127, 127},
+ {255, 255, 255},
+};
+
+void changeState(void);
+
+static struct puzzle *hashtable[HASHSIZE];
+static struct puzzle *startPuzzle;
+static struct puzzlelist *puzzles;
+static struct puzzlelist *lastentry;
+
+int curX, curY, visible;
+
+#define MOVE_SPEED 0.2
+static unsigned char movingPiece;
+static float move_x, move_y;
+static float curquat[4];
+static int doubleBuffer = 1;
+static int depth = 1;
+
+static char xsize[PIECES + 1] =
+{0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
+static char ysize[PIECES + 1] =
+{0, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2};
+static float zsize[PIECES + 1] =
+{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.6};
+
+static Config startConfig =
+{
+ {8, 10, 10, 7},
+ {8, 10, 10, 7},
+ {6, 9, 9, 5},
+ {6, 4, 3, 5},
+ {2, 0, 0, 1}
+};
+
+static Config thePuzzle =
+{
+ {8, 10, 10, 7},
+ {8, 10, 10, 7},
+ {6, 9, 9, 5},
+ {6, 4, 3, 5},
+ {2, 0, 0, 1}
+};
+
+static int xadds[4] =
+{-1, 0, 1, 0};
+static int yadds[4] =
+{0, -1, 0, 1};
+
+static long W = 400, H = 300;
+static GLint viewport[4];
+
+#define srandom srand
+#define random() (rand() >> 2)
+
+unsigned
+hash(Config config)
+{
+ int i, j, value;
+
+ value = 0;
+ for (i = 0; i < HEIGHT; i++) {
+ for (j = 0; j < WIDTH; j++) {
+ value = value + convert[config[i][j]];
+ value *= 6;
+ }
+ }
+ return (value);
+}
+
+int
+solution(Config config)
+{
+ if (config[4][1] == 10 && config[4][2] == 10)
+ return (1);
+ return (0);
+}
+
+float boxcoords[][3] =
+{
+ {0.2, 0.2, 0.9},
+ {0.8, 0.2, 0.9},
+ {0.8, 0.8, 0.9},
+ {0.2, 0.8, 0.9},
+ {0.2, 0.1, 0.8},
+ {0.8, 0.1, 0.8},
+ {0.9, 0.2, 0.8},
+ {0.9, 0.8, 0.8},
+ {0.8, 0.9, 0.8},
+ {0.2, 0.9, 0.8},
+ {0.1, 0.8, 0.8},
+ {0.1, 0.2, 0.8},
+ {0.2, 0.1, 0.2},
+ {0.8, 0.1, 0.2},
+ {0.9, 0.2, 0.2},
+ {0.9, 0.8, 0.2},
+ {0.8, 0.9, 0.2},
+ {0.2, 0.9, 0.2},
+ {0.1, 0.8, 0.2},
+ {0.1, 0.2, 0.2},
+ {0.2, 0.2, 0.1},
+ {0.8, 0.2, 0.1},
+ {0.8, 0.8, 0.1},
+ {0.2, 0.8, 0.1},
+};
+
+float boxnormals[][3] =
+{
+ {0, 0, 1}, /* 0 */
+ {0, 1, 0},
+ {1, 0, 0},
+ {0, 0, -1},
+ {0, -1, 0},
+ {-1, 0, 0},
+ {0.7071, 0.7071, 0.0000}, /* 6 */
+ {0.7071, -0.7071, 0.0000},
+ {-0.7071, 0.7071, 0.0000},
+ {-0.7071, -0.7071, 0.0000},
+ {0.7071, 0.0000, 0.7071}, /* 10 */
+ {0.7071, 0.0000, -0.7071},
+ {-0.7071, 0.0000, 0.7071},
+ {-0.7071, 0.0000, -0.7071},
+ {0.0000, 0.7071, 0.7071}, /* 14 */
+ {0.0000, 0.7071, -0.7071},
+ {0.0000, -0.7071, 0.7071},
+ {0.0000, -0.7071, -0.7071},
+ {0.5774, 0.5774, 0.5774}, /* 18 */
+ {0.5774, 0.5774, -0.5774},
+ {0.5774, -0.5774, 0.5774},
+ {0.5774, -0.5774, -0.5774},
+ {-0.5774, 0.5774, 0.5774},
+ {-0.5774, 0.5774, -0.5774},
+ {-0.5774, -0.5774, 0.5774},
+ {-0.5774, -0.5774, -0.5774},
+};
+
+int boxfaces[][4] =
+{
+ {0, 1, 2, 3}, /* 0 */
+ {9, 8, 16, 17},
+ {6, 14, 15, 7},
+ {20, 23, 22, 21},
+ {12, 13, 5, 4},
+ {19, 11, 10, 18},
+ {7, 15, 16, 8}, /* 6 */
+ {13, 14, 6, 5},
+ {18, 10, 9, 17},
+ {19, 12, 4, 11},
+ {1, 6, 7, 2}, /* 10 */
+ {14, 21, 22, 15},
+ {11, 0, 3, 10},
+ {20, 19, 18, 23},
+ {3, 2, 8, 9}, /* 14 */
+ {17, 16, 22, 23},
+ {4, 5, 1, 0},
+ {20, 21, 13, 12},
+ {2, 7, 8, -1}, /* 18 */
+ {16, 15, 22, -1},
+ {5, 6, 1, -1},
+ {13, 21, 14, -1},
+ {10, 3, 9, -1},
+ {18, 17, 23, -1},
+ {11, 4, 0, -1},
+ {20, 12, 19, -1},
+};
+
+#define NBOXFACES (sizeof(boxfaces)/sizeof(boxfaces[0]))
+
+/* Draw a box. Bevel as desired. */
+void
+drawBox(int piece, float xoff, float yoff)
+{
+ int xlen, ylen;
+ int i, k;
+ float x, y, z;
+ float zlen;
+ float *v;
+
+ xlen = xsize[piece];
+ ylen = ysize[piece];
+ zlen = zsize[piece];
+
+ glColor3ubv(colors[piece]);
+ glBegin(GL_QUADS);
+ for (i = 0; i < 18; i++) {
+ glNormal3fv(boxnormals[i]);
+ for (k = 0; k < 4; k++) {
+ if (boxfaces[i][k] == -1)
+ continue;
+ v = boxcoords[boxfaces[i][k]];
+ x = v[0] + OFFSETX;
+ if (v[0] > 0.5)
+ x += xlen - 1;
+ y = v[1] + OFFSETY;
+ if (v[1] > 0.5)
+ y += ylen - 1;
+ z = v[2] + OFFSETZ;
+ if (v[2] > 0.5)
+ z += zlen - 1;
+ glVertex3f(xoff + x, yoff + y, z);
+ }
+ }
+ glEnd();
+ glBegin(GL_TRIANGLES);
+ for (i = 18; i < int(NBOXFACES); i++) {
+ glNormal3fv(boxnormals[i]);
+ for (k = 0; k < 3; k++) {
+ if (boxfaces[i][k] == -1)
+ continue;
+ v = boxcoords[boxfaces[i][k]];
+ x = v[0] + OFFSETX;
+ if (v[0] > 0.5)
+ x += xlen - 1;
+ y = v[1] + OFFSETY;
+ if (v[1] > 0.5)
+ y += ylen - 1;
+ z = v[2] + OFFSETZ;
+ if (v[2] > 0.5)
+ z += zlen - 1;
+ glVertex3f(xoff + x, yoff + y, z);
+ }
+ }
+ glEnd();
+}
+
+float containercoords[][3] =
+{
+ {-0.1, -0.1, 1.0},
+ {-0.1, -0.1, -0.1},
+ {4.1, -0.1, -0.1},
+ {4.1, -0.1, 1.0},
+ {1.0, -0.1, 0.6}, /* 4 */
+ {3.0, -0.1, 0.6},
+ {1.0, -0.1, 0.0},
+ {3.0, -0.1, 0.0},
+ {1.0, 0.0, 0.0}, /* 8 */
+ {3.0, 0.0, 0.0},
+ {3.0, 0.0, 0.6},
+ {1.0, 0.0, 0.6},
+ {0.0, 0.0, 1.0}, /* 12 */
+ {4.0, 0.0, 1.0},
+ {4.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0},
+ {0.0, 5.0, 0.0}, /* 16 */
+ {0.0, 5.0, 1.0},
+ {4.0, 5.0, 1.0},
+ {4.0, 5.0, 0.0},
+ {-0.1, 5.1, -0.1}, /* 20 */
+ {4.1, 5.1, -0.1},
+ {4.1, 5.1, 1.0},
+ {-0.1, 5.1, 1.0},
+};
+
+float containernormals[][3] =
+{
+ {0, -1, 0},
+ {0, -1, 0},
+ {0, -1, 0},
+ {0, -1, 0},
+ {0, -1, 0},
+ {0, 1, 0},
+ {0, 1, 0},
+ {0, 1, 0},
+ {1, 0, 0},
+ {1, 0, 0},
+ {1, 0, 0},
+ {-1, 0, 0},
+ {-1, 0, 0},
+ {-1, 0, 0},
+ {0, 1, 0},
+ {0, 0, -1},
+ {0, 0, -1},
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1},
+};
+
+int containerfaces[][4] =
+{
+ {1, 6, 4, 0},
+ {0, 4, 5, 3},
+ {1, 2, 7, 6},
+ {7, 2, 3, 5},
+ {16, 19, 18, 17},
+
+ {23, 22, 21, 20},
+ {12, 11, 8, 15},
+ {10, 13, 14, 9},
+
+ {15, 16, 17, 12},
+ {2, 21, 22, 3},
+ {6, 8, 11, 4},
+
+ {1, 0, 23, 20},
+ {14, 13, 18, 19},
+ {9, 7, 5, 10},
+
+ {12, 13, 10, 11},
+
+ {1, 20, 21, 2},
+ {4, 11, 10, 5},
+
+ {15, 8, 19, 16},
+ {19, 8, 9, 14},
+ {8, 6, 7, 9},
+ {0, 3, 13, 12},
+ {13, 3, 22, 18},
+ {18, 22, 23, 17},
+ {17, 23, 0, 12},
+};
+
+#define NCONTFACES (sizeof(containerfaces)/sizeof(containerfaces[0]))
+
+/* Draw the container */
+void
+drawContainer(void)
+{
+ int i, k;
+ float *v;
+
+ /* Y is reversed here because the model has it reversed */
+
+ /* Arbitrary bright wood-like color */
+ glColor3ub(209, 103, 23);
+ glBegin(GL_QUADS);
+ for (i = 0; i < int(NCONTFACES); i++) {
+ v = containernormals[i];
+ glNormal3f(v[0], -v[1], v[2]);
+ for (k = 3; k >= 0; k--) {
+ v = containercoords[containerfaces[i][k]];
+ glVertex3f(v[0] + OFFSETX, -(v[1] + OFFSETY), v[2] + OFFSETZ);
+ }
+ }
+ glEnd();
+}
+
+void
+drawAll(void)
+{
+ int i, j;
+ int piece;
+ char done[PIECES + 1];
+ float m[4][4];
+
+ build_rotmatrix(m, curquat);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -10);
+ glMultMatrixf(&(m[0][0]));
+ glRotatef(180, 0, 0, 1);
+
+ if (depth) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ } else {
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ for (i = 1; i <= PIECES; i++) {
+ done[i] = 0;
+ }
+ glLoadName(0);
+ drawContainer();
+ for (i = 0; i < HEIGHT; i++) {
+ for (j = 0; j < WIDTH; j++) {
+ piece = thePuzzle[i][j];
+ if (piece == 0)
+ continue;
+ if (done[piece])
+ continue;
+ done[piece] = 1;
+ glLoadName(piece);
+ if (piece == movingPiece) {
+ drawBox(piece, move_x, move_y);
+ } else {
+ drawBox(piece, j, i);
+ }
+ }
+ }
+}
+
+void
+redraw(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(45, 1.0, 0.1, 100.0);
+
+ drawAll();
+
+ if (doubleBuffer)
+ glutSwapBuffers();
+ else
+ glFinish();
+}
+
+void
+solidifyChain(struct puzzle *puzzle)
+{
+ int i;
+ char buf[256];
+
+ i = 0;
+ while (puzzle->backptr) {
+ i++;
+ puzzle->backptr->solnptr = puzzle;
+ puzzle = puzzle->backptr;
+ }
+ sprintf(buf, "%d moves to complete!", i);
+ glutSetWindowTitle(buf);
+}
+
+int
+addConfig(Config config, struct puzzle *back)
+{
+ unsigned hashvalue;
+ struct puzzle *newpiece;
+ struct puzzlelist *newlistentry;
+
+ hashvalue = hash(config);
+
+ newpiece = hashtable[hashvalue % HASHSIZE];
+ while (newpiece != NULL) {
+ if (newpiece->hashvalue == hashvalue) {
+ int i, j;
+
+ for (i = 0; i < WIDTH; i++) {
+ for (j = 0; j < HEIGHT; j++) {
+ if (convert[config[j][i]] !=
+ convert[newpiece->pieces[j][i]])
+ goto nomatch;
+ }
+ }
+ return 0;
+ }
+ nomatch:
+ newpiece = newpiece->next;
+ }
+
+ newpiece = (struct puzzle *) malloc(sizeof(struct puzzle));
+ newpiece->next = hashtable[hashvalue % HASHSIZE];
+ newpiece->hashvalue = hashvalue;
+ memcpy(newpiece->pieces, config, HEIGHT * WIDTH);
+ newpiece->backptr = back;
+ newpiece->solnptr = NULL;
+ hashtable[hashvalue % HASHSIZE] = newpiece;
+
+ newlistentry = (struct puzzlelist *) malloc(sizeof(struct puzzlelist));
+ newlistentry->puzzle = newpiece;
+ newlistentry->next = NULL;
+
+ if (lastentry) {
+ lastentry->next = newlistentry;
+ } else {
+ puzzles = newlistentry;
+ }
+ lastentry = newlistentry;
+
+ if (back == NULL) {
+ startPuzzle = newpiece;
+ }
+ if (solution(config)) {
+ solidifyChain(newpiece);
+ return 1;
+ }
+ return 0;
+}
+
+/* Checks if a space can move */
+int
+canmove0(Config pieces, int x, int y, int dir, Config newpieces)
+{
+ char piece;
+ int xadd, yadd;
+ int l, m;
+
+ xadd = xadds[dir];
+ yadd = yadds[dir];
+
+ if (x + xadd < 0 || x + xadd >= WIDTH ||
+ y + yadd < 0 || y + yadd >= HEIGHT)
+ return 0;
+ piece = pieces[y + yadd][x + xadd];
+ if (piece == 0)
+ return 0;
+ memcpy(newpieces, pieces, HEIGHT * WIDTH);
+ for (l = 0; l < WIDTH; l++) {
+ for (m = 0; m < HEIGHT; m++) {
+ if (newpieces[m][l] == piece)
+ newpieces[m][l] = 0;
+ }
+ }
+ xadd = -xadd;
+ yadd = -yadd;
+ for (l = 0; l < WIDTH; l++) {
+ for (m = 0; m < HEIGHT; m++) {
+ if (pieces[m][l] == piece) {
+ int newx, newy;
+
+ newx = l + xadd;
+ newy = m + yadd;
+ if (newx < 0 || newx >= WIDTH ||
+ newy < 0 || newy >= HEIGHT)
+ return 0;
+ if (newpieces[newy][newx] != 0)
+ return 0;
+ newpieces[newy][newx] = piece;
+ }
+ }
+ }
+ return 1;
+}
+
+/* Checks if a piece can move */
+int
+canmove(Config pieces, int x, int y, int dir, Config newpieces)
+{
+ int xadd, yadd;
+
+ xadd = xadds[dir];
+ yadd = yadds[dir];
+
+ if (x + xadd < 0 || x + xadd >= WIDTH ||
+ y + yadd < 0 || y + yadd >= HEIGHT)
+ return 0;
+ if (pieces[y + yadd][x + xadd] == pieces[y][x]) {
+ return canmove(pieces, x + xadd, y + yadd, dir, newpieces);
+ }
+ if (pieces[y + yadd][x + xadd] != 0)
+ return 0;
+ return canmove0(pieces, x + xadd, y + yadd, (dir + 2) % 4, newpieces);
+}
+
+int
+generateNewConfigs(struct puzzle *puzzle)
+{
+ int i, j, k;
+ Config pieces;
+ Config newpieces;
+
+ memcpy(pieces, puzzle->pieces, HEIGHT * WIDTH);
+ for (i = 0; i < WIDTH; i++) {
+ for (j = 0; j < HEIGHT; j++) {
+ if (pieces[j][i] == 0) {
+ for (k = 0; k < 4; k++) {
+ if (canmove0(pieces, i, j, k, newpieces)) {
+ if (addConfig(newpieces, puzzle))
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void
+freeSolutions(void)
+{
+ struct puzzlelist *nextpuz;
+ struct puzzle *puzzle, *next;
+ int i;
+
+ while (puzzles) {
+ nextpuz = puzzles->next;
+ free((char *) puzzles);
+ puzzles = nextpuz;
+ }
+ lastentry = NULL;
+ for (i = 0; i < HASHSIZE; i++) {
+ puzzle = hashtable[i];
+ hashtable[i] = NULL;
+ while (puzzle) {
+ next = puzzle->next;
+ free((char *) puzzle);
+ puzzle = next;
+ }
+ }
+ startPuzzle = NULL;
+}
+
+int
+continueSolving(void)
+{
+ struct puzzle *nextpuz;
+ int i, j;
+ int movedPiece;
+ int movedir;
+ int fromx, fromy;
+ int tox, toy;
+
+ if (startPuzzle == NULL)
+ return 0;
+ if (startPuzzle->solnptr == NULL) {
+ freeSolutions();
+ return 0;
+ }
+ nextpuz = startPuzzle->solnptr;
+ movedPiece = 0;
+ movedir = 0;
+ for (i = 0; i < HEIGHT; i++) {
+ for (j = 0; j < WIDTH; j++) {
+ if (startPuzzle->pieces[i][j] != nextpuz->pieces[i][j]) {
+ if (startPuzzle->pieces[i][j]) {
+ movedPiece = startPuzzle->pieces[i][j];
+ fromx = j;
+ fromy = i;
+ if (i < HEIGHT - 1 && nextpuz->pieces[i + 1][j] == movedPiece) {
+ movedir = 3;
+ } else {
+ movedir = 2;
+ }
+ goto found_piece;
+ } else {
+ movedPiece = nextpuz->pieces[i][j];
+ if (i < HEIGHT - 1 &&
+ startPuzzle->pieces[i + 1][j] == movedPiece) {
+ fromx = j;
+ fromy = i + 1;
+ movedir = 1;
+ } else {
+ fromx = j + 1;
+ fromy = i;
+ movedir = 0;
+ }
+ goto found_piece;
+ }
+ }
+ }
+ }
+ glutSetWindowTitle("What! No change?");
+ freeSolutions();
+ return 0;
+
+found_piece:
+ if (!movingPiece) {
+ movingPiece = movedPiece;
+ move_x = fromx;
+ move_y = fromy;
+ }
+ move_x += xadds[movedir] * MOVE_SPEED;
+ move_y += yadds[movedir] * MOVE_SPEED;
+
+ tox = fromx + xadds[movedir];
+ toy = fromy + yadds[movedir];
+
+ if (move_x > tox - MOVE_SPEED / 2 && move_x < tox + MOVE_SPEED / 2 &&
+ move_y > toy - MOVE_SPEED / 2 && move_y < toy + MOVE_SPEED / 2) {
+ startPuzzle = nextpuz;
+ movingPiece = 0;
+ }
+ memcpy(thePuzzle, startPuzzle->pieces, HEIGHT * WIDTH);
+ changeState();
+ return 1;
+}
+
+int
+solvePuzzle(void)
+{
+ struct puzzlelist *nextpuz;
+ char buf[256];
+ int i;
+
+ if (solution(thePuzzle)) {
+ glutSetWindowTitle("Puzzle already solved!");
+ return 0;
+ }
+ addConfig(thePuzzle, NULL);
+ i = 0;
+
+ while (puzzles) {
+ i++;
+ if (generateNewConfigs(puzzles->puzzle))
+ break;
+ nextpuz = puzzles->next;
+ free((char *) puzzles);
+ puzzles = nextpuz;
+ }
+ if (puzzles == NULL) {
+ freeSolutions();
+ sprintf(buf, "I can't solve it! (%d positions examined)", i);
+ glutSetWindowTitle(buf);
+ return 1;
+ }
+ return 1;
+}
+
+int
+selectPiece(int mousex, int mousey)
+{
+ long hits;
+ GLuint selectBuf[1024];
+ GLuint closest;
+ GLuint dist;
+
+ glSelectBuffer(1024, selectBuf);
+ (void) glRenderMode(GL_SELECT);
+ glInitNames();
+
+ /* Because LoadName() won't work with no names on the stack */
+ glPushName(0);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPickMatrix(mousex, H - mousey, 4, 4, viewport);
+ gluPerspective(45, 1.0, 0.1, 100.0);
+
+ drawAll();
+
+ hits = glRenderMode(GL_RENDER);
+ if (hits <= 0) {
+ return 0;
+ }
+ closest = 0;
+ dist = 4294967295;
+ while (hits) {
+ if (selectBuf[(hits - 1) * 4 + 1] < dist) {
+ dist = selectBuf[(hits - 1) * 4 + 1];
+ closest = selectBuf[(hits - 1) * 4 + 3];
+ }
+ hits--;
+ }
+ return closest;
+}
+
+void
+nukePiece(int piece)
+{
+ int i, j;
+
+ for (i = 0; i < HEIGHT; i++) {
+ for (j = 0; j < WIDTH; j++) {
+ if (thePuzzle[i][j] == piece) {
+ thePuzzle[i][j] = 0;
+ }
+ }
+ }
+}
+
+void
+multMatrices(const GLfloat a[16], const GLfloat b[16], GLfloat r[16])
+{
+ int i, j;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ r[i * 4 + j] =
+ a[i * 4 + 0] * b[0 * 4 + j] +
+ a[i * 4 + 1] * b[1 * 4 + j] +
+ a[i * 4 + 2] * b[2 * 4 + j] +
+ a[i * 4 + 3] * b[3 * 4 + j];
+ }
+ }
+}
+
+void
+makeIdentity(GLfloat m[16])
+{
+ m[0 + 4 * 0] = 1;
+ m[0 + 4 * 1] = 0;
+ m[0 + 4 * 2] = 0;
+ m[0 + 4 * 3] = 0;
+ m[1 + 4 * 0] = 0;
+ m[1 + 4 * 1] = 1;
+ m[1 + 4 * 2] = 0;
+ m[1 + 4 * 3] = 0;
+ m[2 + 4 * 0] = 0;
+ m[2 + 4 * 1] = 0;
+ m[2 + 4 * 2] = 1;
+ m[2 + 4 * 3] = 0;
+ m[3 + 4 * 0] = 0;
+ m[3 + 4 * 1] = 0;
+ m[3 + 4 * 2] = 0;
+ m[3 + 4 * 3] = 1;
+}
+
+/*
+ ** inverse = invert(src)
+ */
+int
+invertMatrix(const GLfloat src[16], GLfloat inverse[16])
+{
+ int i, j, k, swap;
+ double t;
+ GLfloat temp[4][4];
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp[i][j] = src[i * 4 + j];
+ }
+ }
+ makeIdentity(inverse);
+
+ for (i = 0; i < 4; i++) {
+ /*
+ ** Look for largest element in column */
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (fabs(temp[j][i]) > fabs(temp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ /*
+ ** Swap rows. */
+ for (k = 0; k < 4; k++) {
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
+ t = inverse[i * 4 + k];
+ inverse[i * 4 + k] = inverse[swap * 4 + k];
+ inverse[swap * 4 + k] = t;
+ }
+ }
+ if (temp[i][i] == 0) {
+ /*
+ ** No non-zero pivot. The matrix is singular, which
+ shouldn't ** happen. This means the user gave us a
+ bad matrix. */
+ return 0;
+ }
+ t = temp[i][i];
+ for (k = 0; k < 4; k++) {
+ temp[i][k] /= t;
+ inverse[i * 4 + k] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp[j][i];
+ for (k = 0; k < 4; k++) {
+ temp[j][k] -= temp[i][k] * t;
+ inverse[j * 4 + k] -= inverse[i * 4 + k] * t;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+/*
+ ** This is a screwball function. What it does is the following:
+ ** Given screen x and y coordinates, compute the corresponding object space
+ ** x and y coordinates given that the object space z is 0.9 + OFFSETZ.
+ ** Since the tops of (most) pieces are at z = 0.9 + OFFSETZ, we use that
+ ** number.
+ */
+int
+computeCoords(int piece, int mousex, int mousey,
+ GLfloat * selx, GLfloat * sely)
+{
+ GLfloat modelMatrix[16];
+ GLfloat projMatrix[16];
+ GLfloat finalMatrix[16];
+ GLfloat in[4];
+ GLfloat a, b, c, d;
+ GLfloat top, bot;
+ GLfloat z;
+ GLfloat w;
+ GLfloat height;
+
+ if (piece == 0)
+ return 0;
+ height = zsize[piece] - 0.1 + OFFSETZ;
+
+ glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
+ glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
+ multMatrices(modelMatrix, projMatrix, finalMatrix);
+ if (!invertMatrix(finalMatrix, finalMatrix))
+ return 0;
+
+ in[0] = (2.0 * (mousex - viewport[0]) / viewport[2]) - 1;
+ in[1] = (2.0 * ((H - mousey) - viewport[1]) / viewport[3]) - 1;
+
+ a = in[0] * finalMatrix[0 * 4 + 2] +
+ in[1] * finalMatrix[1 * 4 + 2] +
+ finalMatrix[3 * 4 + 2];
+ b = finalMatrix[2 * 4 + 2];
+ c = in[0] * finalMatrix[0 * 4 + 3] +
+ in[1] * finalMatrix[1 * 4 + 3] +
+ finalMatrix[3 * 4 + 3];
+ d = finalMatrix[2 * 4 + 3];
+
+ /*
+ ** Ok, now we need to solve for z: ** (a + b z) / (c + d
+
+ z) = height. ** ("height" is the height in object space we
+
+ want to solve z for) ** ** ==> a + b z = height c +
+ height d z ** bz - height d z = height c - a ** z =
+ (height c - a) / (b - height d) */
+ top = height * c - a;
+ bot = b - height * d;
+ if (bot == 0.0)
+ return 0;
+
+ z = top / bot;
+
+ /*
+ ** Ok, no problem. ** Now we solve for x and y. We know
+ that w = c + d z, so we compute it. */
+ w = c + d * z;
+
+ /*
+ ** Now for x and y: */
+ *selx = (in[0] * finalMatrix[0 * 4 + 0] +
+ in[1] * finalMatrix[1 * 4 + 0] +
+ z * finalMatrix[2 * 4 + 0] +
+ finalMatrix[3 * 4 + 0]) / w - OFFSETX;
+ *sely = (in[0] * finalMatrix[0 * 4 + 1] +
+ in[1] * finalMatrix[1 * 4 + 1] +
+ z * finalMatrix[2 * 4 + 1] +
+ finalMatrix[3 * 4 + 1]) / w - OFFSETY;
+ return 1;
+}
+
+static int selected;
+static int selectx, selecty;
+static float selstartx, selstarty;
+
+void
+grabPiece(int piece, float selx, float sely)
+{
+ int hit;
+
+ selectx = int(selx);
+ selecty = int(sely);
+ if (selectx < 0 || selecty < 0 || selectx >= WIDTH || selecty >= HEIGHT) {
+ return;
+ }
+ hit = thePuzzle[selecty][selectx];
+ if (hit != piece)
+ return;
+ if (hit) {
+ movingPiece = hit;
+ while (selectx > 0 && thePuzzle[selecty][selectx - 1] == movingPiece) {
+ selectx--;
+ }
+ while (selecty > 0 && thePuzzle[selecty - 1][selectx] == movingPiece) {
+ selecty--;
+ }
+ move_x = selectx;
+ move_y = selecty;
+ selected = 1;
+ selstartx = selx;
+ selstarty = sely;
+ } else {
+ selected = 0;
+ }
+ changeState();
+}
+
+void
+moveSelection(float selx, float sely)
+{
+ float deltax, deltay;
+ int dir;
+ Config newpieces;
+
+ if (!selected)
+ return;
+ deltax = selx - selstartx;
+ deltay = sely - selstarty;
+
+ if (fabs(deltax) > fabs(deltay)) {
+ deltay = 0;
+ if (deltax > 0) {
+ if (deltax > 1)
+ deltax = 1;
+ dir = 2;
+ } else {
+ if (deltax < -1)
+ deltax = -1;
+ dir = 0;
+ }
+ } else {
+ deltax = 0;
+ if (deltay > 0) {
+ if (deltay > 1)
+ deltay = 1;
+ dir = 3;
+ } else {
+ if (deltay < -1)
+ deltay = -1;
+ dir = 1;
+ }
+ }
+ if (canmove(thePuzzle, selectx, selecty, dir, newpieces)) {
+ move_x = deltax + selectx;
+ move_y = deltay + selecty;
+ if (deltax > 0.5) {
+ memcpy(thePuzzle, newpieces, HEIGHT * WIDTH);
+ selectx++;
+ selstartx++;
+ } else if (deltax < -0.5) {
+ memcpy(thePuzzle, newpieces, HEIGHT * WIDTH);
+ selectx--;
+ selstartx--;
+ } else if (deltay > 0.5) {
+ memcpy(thePuzzle, newpieces, HEIGHT * WIDTH);
+ selecty++;
+ selstarty++;
+ } else if (deltay < -0.5) {
+ memcpy(thePuzzle, newpieces, HEIGHT * WIDTH);
+ selecty--;
+ selstarty--;
+ }
+ } else {
+ if (deltay > 0 && thePuzzle[selecty][selectx] == 10 &&
+ selectx == 1 && selecty == 3) {
+ /* Allow visual movement of solution piece outside of the
+
+ box */
+ move_x = selectx;
+ move_y = sely - selstarty + selecty;
+ } else {
+ move_x = selectx;
+ move_y = selecty;
+ }
+ }
+}
+
+void
+dropSelection(void)
+{
+ if (!selected)
+ return;
+ movingPiece = 0;
+ selected = 0;
+ changeState();
+}
+
+static int left_mouse, middle_mouse;
+static int mousex, mousey;
+static int solving;
+static int spinning;
+static float lastquat[4];
+static int sel_piece;
+
+static void
+Reshape(int width, int height)
+{
+
+ W = width;
+ H = height;
+ glViewport(0, 0, W, H);
+ glGetIntegerv(GL_VIEWPORT, viewport);
+}
+
+void
+toggleSolve(void)
+{
+ if (solving) {
+ freeSolutions();
+ solving = 0;
+ glutChangeToMenuEntry(1, "Solving", 1);
+ glutSetWindowTitle("glpuzzle");
+ movingPiece = 0;
+ } else {
+ glutChangeToMenuEntry(1, "Stop solving", 1);
+ glutSetWindowTitle("Solving...");
+ if (solvePuzzle()) {
+ solving = 1;
+ }
+ }
+ changeState();
+ glutPostRedisplay();
+}
+
+void reset(void)
+{
+ if (solving) {
+ freeSolutions();
+ solving = 0;
+ glutChangeToMenuEntry(1, "Solving", 1);
+ glutSetWindowTitle("glpuzzle");
+ movingPiece = 0;
+ changeState();
+ }
+ memcpy(thePuzzle, startConfig, HEIGHT * WIDTH);
+ glutPostRedisplay();
+}
+
+void
+keyboard(unsigned char c, int x, int y)
+{
+ int piece;
+
+ switch (c) {
+ case 27:
+ exit(0);
+ break;
+ case 'D':
+ case 'd':
+ if (solving) {
+ freeSolutions();
+ solving = 0;
+ glutChangeToMenuEntry(1, "Solving", 1);
+ glutSetWindowTitle("glpuzzle");
+ movingPiece = 0;
+ changeState();
+ }
+ piece = selectPiece(x, y);
+ if (piece) {
+ nukePiece(piece);
+ }
+ glutPostRedisplay();
+ break;
+ case 'R':
+ case 'r':
+ reset();
+ break;
+ case 'S':
+ case 's':
+ toggleSolve();
+ break;
+ case 'b':
+ case 'B':
+ depth = 1 - depth;
+ if (depth) {
+ glEnable(GL_DEPTH_TEST);
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ }
+ glutPostRedisplay();
+ break;
+ default:
+ break;
+ }
+}
+
+void
+motion(int x, int y)
+{
+ float selx, sely;
+
+ if (middle_mouse && !left_mouse) {
+ if (mousex != x || mousey != y) {
+ trackball(lastquat,
+ (2.0*mousex - W) / W,
+ (H - 2.0*mousey) / H,
+ (2.0*x - W) / W,
+ (H - 2.0*y) / H);
+ spinning = 1;
+ } else {
+ spinning = 0;
+ }
+ changeState();
+ } else {
+ computeCoords(sel_piece, x, y, &selx, &sely);
+ moveSelection(selx, sely);
+ }
+ mousex = x;
+ mousey = y;
+ glutPostRedisplay();
+}
+
+void
+mouse(int b, int s, int x, int y)
+{
+ float selx, sely;
+
+ mousex = x;
+ mousey = y;
+ curX = x;
+ curY = y;
+ if (s == GLUT_DOWN) {
+ switch (b) {
+ case GLUT_LEFT_BUTTON:
+ if (solving) {
+ freeSolutions();
+ solving = 0;
+ glutChangeToMenuEntry(1, "Solving", 1);
+ glutSetWindowTitle("glpuzzle");
+ movingPiece = 0;
+ }
+ left_mouse = GL_TRUE;
+ sel_piece = selectPiece(mousex, mousey);
+ if (computeCoords(sel_piece, mousex, mousey, &selx, &sely)) {
+ grabPiece(sel_piece, selx, sely);
+ }
+ glutPostRedisplay();
+ break;
+ case GLUT_MIDDLE_BUTTON:
+ middle_mouse = GL_TRUE;
+ glutPostRedisplay();
+ break;
+ }
+ } else {
+ switch (b) {
+ case GLUT_LEFT_BUTTON:
+ left_mouse = GL_FALSE;
+ dropSelection();
+ glutPostRedisplay();
+ break;
+ case GLUT_MIDDLE_BUTTON:
+ middle_mouse = GL_FALSE;
+ glutPostRedisplay();
+ break;
+ }
+ }
+ motion(x, y);
+}
+
+void
+animate(void)
+{
+ if (spinning) {
+ add_quats(lastquat, curquat, curquat);
+ }
+ glutPostRedisplay();
+ if (solving) {
+ if (!continueSolving()) {
+ solving = 0;
+ glutChangeToMenuEntry(1, "Solving", 1);
+ glutSetWindowTitle("glpuzzle");
+ }
+ }
+ if (!solving && !spinning && !visible) {
+ glutIdleFunc(NULL);
+ }
+}
+
+void
+changeState(void)
+{
+ if (visible) {
+ if (!solving && !spinning) {
+ glutIdleFunc(NULL);
+ } else {
+ glutIdleFunc(animate);
+ }
+ } else {
+ glutIdleFunc(NULL);
+ }
+}
+
+void
+init(void)
+{
+ static float lmodel_ambient[] =
+ {0.0, 0.0, 0.0, 0.0};
+ static float lmodel_twoside[] =
+ {GL_FALSE};
+ static float lmodel_local[] =
+ {GL_FALSE};
+ static float light0_ambient[] =
+ {0.1, 0.1, 0.1, 1.0};
+ static float light0_diffuse[] =
+ {1.0, 1.0, 1.0, 0.0};
+ static float light0_position[] =
+ {0.8660254, 0.5, 1, 0};
+ static float light0_specular[] =
+ {0.0, 0.0, 0.0, 0.0};
+ static float bevel_mat_ambient[] =
+ {0.0, 0.0, 0.0, 1.0};
+ static float bevel_mat_shininess[] =
+ {40.0};
+ static float bevel_mat_specular[] =
+ {0.0, 0.0, 0.0, 0.0};
+ static float bevel_mat_diffuse[] =
+ {1.0, 0.0, 0.0, 0.0};
+
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ glEnable(GL_DEPTH_TEST);
+ glClearDepth(1.0);
+
+ glClearColor(0.5, 0.5, 0.5, 0.0);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
+ glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
+ glEnable(GL_LIGHT0);
+
+ glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local);
+ glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+ glEnable(GL_LIGHTING);
+
+ glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient);
+ glMaterialfv(GL_FRONT, GL_SHININESS, bevel_mat_shininess);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, bevel_mat_specular);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, bevel_mat_diffuse);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ glShadeModel(GL_FLAT);
+
+ trackball(curquat, 0.0, 0.0, 0.0, 0.0);
+ srandom(time(NULL));
+}
+
+static void
+Usage(void)
+{
+ printf("Usage: puzzle [-s]\n");
+ printf(" -s: Run in single buffered mode\n");
+ exit(-1);
+}
+
+void
+visibility(int v)
+{
+ if (v == GLUT_VISIBLE) {
+ visible = 1;
+ } else {
+ visible = 0;
+ }
+ changeState();
+}
+
+void
+menu(int choice)
+{
+ switch(choice) {
+ case 1:
+ toggleSolve();
+ break;
+ case 2:
+ reset();
+ break;
+ case 3:
+ exit(0);
+ break;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ long i;
+
+ glutInit(&argc, argv);
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 's':
+ doubleBuffer = 0;
+ break;
+ default:
+ Usage();
+ }
+ } else {
+ Usage();
+ }
+ }
+
+ glutInitWindowSize(W, H);
+ if (doubleBuffer) {
+ glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE);
+ } else {
+ glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_SINGLE | GLUT_MULTISAMPLE);
+ }
+
+ glutCreateWindow("glpuzzle");
+ visible = 1; // added for fltk, bug in original program?
+
+ init();
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+
+ printf("\n");
+ printf("r Reset puzzle\n");
+ printf("s Solve puzzle (may take a few seconds to compute)\n");
+ printf("d Destroy a piece - makes the puzzle easier\n");
+ printf("b Toggles the depth buffer on and off\n");
+ printf("\n");
+ printf("Left mouse moves pieces\n");
+ printf("Middle mouse spins the puzzle\n");
+ printf("Right mouse has menu\n");
+
+ glutReshapeFunc(Reshape);
+ glutDisplayFunc(redraw);
+ glutKeyboardFunc(keyboard);
+ glutMotionFunc(motion);
+ glutMouseFunc(mouse);
+ glutVisibilityFunc(visibility);
+ glutCreateMenu(menu);
+ glutAddMenuEntry("Solve", 1);
+ glutAddMenuEntry("Reset", 2);
+ glutAddMenuEntry("Quit", 3);
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+ glutMainLoop();
+ return 0; /* ANSI C requires main to return int. */
+}
+
+#endif // added for fltk's distribution
+
diff --git a/test/hello.cxx b/test/hello.cxx
new file mode 100644
index 000000000..eb6adb082
--- /dev/null
+++ b/test/hello.cxx
@@ -0,0 +1,16 @@
+/* Example program from the documentation */
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+
+int main(int argc, char **argv) {
+ Fl_Window *window = new Fl_Window(300,180);
+ Fl_Box *box = new Fl_Box(FL_UP_BOX,20,40,260,100,"Hello, World!");
+ box->labelfont(FL_BOLD+FL_ITALIC);
+ box->labelsize(36);
+ box->labeltype(FL_SHADOW_LABEL);
+ window->end();
+ window->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/iconize.cxx b/test/iconize.cxx
new file mode 100644
index 000000000..5511ac66a
--- /dev/null
+++ b/test/iconize.cxx
@@ -0,0 +1,54 @@
+// Fl_Window::iconize() test
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Box.H>
+#include <stdlib.h>
+
+void iconize_cb(Fl_Widget *, void *v) {
+ Fl_Window *w = (Fl_Window *)v;
+ w->iconize();
+}
+
+void show_cb(Fl_Widget *, void *v) {
+ Fl_Window *w = (Fl_Window *)v;
+ w->show();
+}
+
+void hide_cb(Fl_Widget *, void *v) {
+ Fl_Window *w = (Fl_Window *)v;
+ w->hide();
+}
+
+void window_cb(Fl_Widget*, void*) {
+ exit(0);
+}
+
+int main(int argc, char **argv) {
+
+ Fl_Window mainw(200,200);
+ mainw.end();
+ mainw.show(argc,argv);
+
+ Fl_Window control(120,120);
+
+ Fl_Button hide_button(0,0,120,30,"hide()");
+ hide_button.callback(hide_cb, &mainw);
+
+ Fl_Button iconize_button(0,30,120,30,"iconize()");
+ iconize_button.callback(iconize_cb, &mainw);
+
+ Fl_Button show_button(0,60,120,30,"show()");
+ show_button.callback(show_cb, &mainw);
+
+ Fl_Button show_button2(0,90,120,30,"show this");
+ show_button2.callback(show_cb, &control);
+
+ // Fl_Box box(FL_NO_BOX,0,60,120,30,"Also try running\nwith -i switch");
+
+ control.end();
+ control.show();
+ control.callback(window_cb);
+ return Fl::run();
+}
diff --git a/test/image.cxx b/test/image.cxx
new file mode 100644
index 000000000..3a2e79c44
--- /dev/null
+++ b/test/image.cxx
@@ -0,0 +1,108 @@
+// Test of class Fl_Image
+//
+// Notice that Fl_Image is for a static, multiple-reuse image, such
+// as an icon or postage stamp. Use fl_draw_image to go directly
+// from an buffered image that changes often.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+
+int width = 75;
+int height = 75;
+uchar *image;
+
+void make_image() {
+ image = new uchar[3*width*height];
+ uchar *p = image;
+ for (int y = 0; y < height; y++) {
+ double Y = double(y)/(height-1);
+ for (int x = 0; x < width; x++) {
+ double X = double(x)/(width-1);
+ *p++ = uchar(255*((1-X)*(1-Y))); // red in upper-left
+ *p++ = uchar(255*((1-X)*Y)); // green in lower-left
+ *p++ = uchar(255*(X*Y)); // blue in lower-right
+ }
+ }
+}
+
+#include <FL/Fl_Toggle_Button.H>
+
+Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb;
+Fl_Button *b;
+Fl_Window *w;
+
+void button_cb(Fl_Widget *,void *) {
+ int i = 0;
+ if (leftb->value()) i |= FL_ALIGN_LEFT;
+ if (rightb->value()) i |= FL_ALIGN_RIGHT;
+ if (topb->value()) i |= FL_ALIGN_TOP;
+ if (bottomb->value()) i |= FL_ALIGN_BOTTOM;
+ if (insideb->value()) i |= FL_ALIGN_INSIDE;
+ b->align(i);
+ w->redraw();
+}
+
+#include <FL/x.H>
+#include "list_visuals.C"
+
+int visid = -1;
+int arg(int argc, char **argv, int &i) {
+ if (argv[i][1] == 'v') {
+ if (i+1 >= argc) return 0;
+ visid = atoi(argv[i+1]);
+ i += 2;
+ return 2;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv) {
+
+#ifndef WIN32
+ int i = 1;
+ if (Fl::args(argc,argv,i,arg) < argc) {
+ fprintf(stderr," -v # : use visual\n%s\n",Fl::help);
+ exit(1);
+ }
+
+ if (visid >= 0) {
+ fl_open_display();
+ XVisualInfo templt; int num;
+ templt.visualid = visid;
+ fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+ if (!fl_visual) {
+ fprintf(stderr, "No visual with id %d, use one of:\n",visid);
+ list_visuals();
+ exit(1);
+ }
+ fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ fl_xpixel(FL_BLACK); // make sure black is allocated in overlay visuals
+ } else {
+ Fl::visual(FL_RGB);
+ }
+#endif
+
+ Fl_Window window(400,400); ::w = &window;
+ Fl_Button b(140,160,120,120,0); ::b = &b;
+ make_image();
+ (new Fl_Image(image, width, height))->label(&b);
+ leftb = new Fl_Toggle_Button(50,75,50,25,"left");
+ leftb->callback(button_cb);
+ rightb = new Fl_Toggle_Button(100,75,50,25,"right");
+ rightb->callback(button_cb);
+ topb = new Fl_Toggle_Button(150,75,50,25,"top");
+ topb->callback(button_cb);
+ bottomb = new Fl_Toggle_Button(200,75,50,25,"bottom");
+ bottomb->callback(button_cb);
+ insideb = new Fl_Toggle_Button(250,75,50,25,"inside");
+ insideb->callback(button_cb);
+ window.resizable(window);
+ window.end();
+ window.show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/inactive.C b/test/inactive.C
new file mode 100644
index 000000000..f78782124
--- /dev/null
+++ b/test/inactive.C
@@ -0,0 +1,99 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "inactive.H"
+
+Fl_Group *the_group;
+
+Fl_Menu_Item menu_menu[] = {
+ {"item", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"item", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"item", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"item", 0, 0, 0, 0, 0, 3, 14, 0},
+ {"item", 0, 0, 0, 0, 0, 3, 14, 0},
+ {0}
+};
+
+static void cb_active(Fl_Button*, void*) {
+ the_group->activate();
+}
+
+static void cb_inactive(Fl_Button*, void*) {
+ the_group->deactivate();
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ { Fl_Window* o = w = new Fl_Window(420, 295);
+ { Fl_Group* o = the_group = new Fl_Group(25, 25, 375, 235, "activate()/deactivate() called on this Fl_Group");
+ o->box(FL_ENGRAVED_FRAME);
+ o->align(17);
+ new Fl_Button(50, 50, 105, 25, "button");
+ { Fl_Group* o = new Fl_Group(50, 100, 105, 85, "Child group");
+ o->box(FL_DOWN_FRAME);
+ { Fl_Check_Button* o = new Fl_Check_Button(50, 100, 105, 25, "red");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ o->labelcolor(1);
+ }
+ { Fl_Check_Button* o = new Fl_Check_Button(50, 120, 105, 25, "green");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ o->selection_color(2);
+ o->labelcolor(2);
+ }
+ { Fl_Check_Button* o = new Fl_Check_Button(50, 140, 105, 25, "blue");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ o->selection_color(4);
+ o->labelcolor(4);
+ }
+ { Fl_Check_Button* o = new Fl_Check_Button(50, 160, 105, 25, "white");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ o->selection_color(7);
+ o->labelcolor(7);
+ }
+ o->end();
+ }
+ { Fl_Slider* o = new Fl_Slider(165, 50, 24, 150, "Fl_Slider");
+ o->value(0.5);
+ }
+ { Fl_Input* o = new Fl_Input(195, 50, 195, 30);
+ o->static_value("Fl_Input");
+ }
+ { Fl_Menu_Button* o = new Fl_Menu_Button(235, 105, 110, 30, "menu");
+ o->menu(menu_menu);
+ }
+ { Fl_Box* o = new Fl_Box(240, 205, 145, 50, "Fl_Box");
+ o->box(FL_EMBOSSED_FRAME);
+ o->labeltype(FL_SHADOW_LABEL);
+ o->labelfont(3);
+ o->labelsize(38);
+ }
+ { Fl_Value_Output* o = new Fl_Value_Output(255, 165, 130, 30, "value:");
+ o->maximum(10000);
+ o->step(1);
+ o->textfont(5);
+ o->textsize(24);
+ o->textcolor(4);
+ }
+ { Fl_Scrollbar* o = new Fl_Scrollbar(40, 220, 180, 20, "scrollbar");
+ o->type(1);
+ o->maximum(100);
+ }
+ o->end();
+ }
+ { Fl_Button* o = new Fl_Button(25, 265, 185, 25, "active");
+ o->type(102);
+ o->value(1);
+ o->callback((Fl_Callback*)cb_active);
+ }
+ { Fl_Button* o = new Fl_Button(220, 265, 180, 25, "inactive");
+ o->type(102);
+ o->callback((Fl_Callback*)cb_inactive);
+ }
+ o->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/inactive.H b/test/inactive.H
new file mode 100644
index 000000000..c811f6c2f
--- /dev/null
+++ b/test/inactive.H
@@ -0,0 +1,15 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Scrollbar.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Value_Output.H>
+#include <FL/Fl_Window.H>
+extern Fl_Group *the_group;
+extern Fl_Menu_Item menu_menu[];
diff --git a/test/inactive.fl b/test/inactive.fl
new file mode 100644
index 000000000..0335158a8
--- /dev/null
+++ b/test/inactive.fl
@@ -0,0 +1,99 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+header_name {.H}
+code_name {.C}
+gridx 5
+gridy 5
+snap 3
+Function {} {open
+} {
+ Fl_Window {} {open
+ xywh {470 454 420 295} visible
+ } {
+ Fl_Group the_group {
+ label {activate()/deactivate() called on this Fl_Group} open
+ xywh {25 25 375 235} box ENGRAVED_FRAME align 17
+ } {
+ Fl_Button {} {
+ label button
+ xywh {50 50 105 25}
+ }
+ Fl_Group {} {
+ label {Child group} open
+ xywh {50 100 105 85} box DOWN_FRAME
+ } {
+ Fl_Check_Button {} {
+ label red
+ xywh {50 100 105 25} type Radio down_box DIAMOND_DOWN_BOX labelcolor 1
+ }
+ Fl_Check_Button {} {
+ label green
+ xywh {50 120 105 25} type Radio down_box DIAMOND_DOWN_BOX selection_color 2 labelcolor 2
+ }
+ Fl_Check_Button {} {
+ label blue
+ xywh {50 140 105 25} type Radio down_box DIAMOND_DOWN_BOX selection_color 4 labelcolor 4
+ }
+ Fl_Check_Button {} {
+ label white
+ xywh {50 160 105 25} type Radio down_box DIAMOND_DOWN_BOX selection_color 7 labelcolor 7
+ }
+ }
+ Fl_Slider {} {
+ label Fl_Slider
+ xywh {165 50 24 150} value 0.5
+ }
+ Fl_Input {} {
+ xywh {195 50 195 30}
+ code0 {o->static_value("Fl_Input");}
+ }
+ Fl_Menu_Button {} {
+ label menu open
+ xywh {235 105 110 30}
+ } {
+ menuitem {} {
+ label item
+ xywh {0 0 100 20}
+ }
+ menuitem {} {
+ label item
+ xywh {10 10 100 20}
+ }
+ menuitem {} {
+ label item
+ xywh {20 20 100 20}
+ }
+ menuitem {} {
+ label item
+ xywh {30 30 100 20}
+ }
+ menuitem {} {
+ label item
+ xywh {40 40 100 20}
+ }
+ }
+ Fl_Box {} {
+ label Fl_Box
+ xywh {240 205 145 50} box EMBOSSED_FRAME labeltype SHADOW_LABEL labelfont 3 labelsize 38
+ }
+ Fl_Value_Output {} {
+ label {value:}
+ xywh {255 165 130 30} maximum 10000 step 1 textfont 5 textsize 24 textcolor 4
+ }
+ Fl_Scrollbar {} {
+ label scrollbar selected
+ xywh {40 220 180 20} type Horizontal maximum 100
+ }
+ }
+ Fl_Button {} {
+ label active
+ callback {the_group->activate();}
+ xywh {25 265 185 25} type Radio value 1
+ }
+ Fl_Button {} {
+ label inactive
+ callback {the_group->deactivate();}
+ xywh {220 265 180 25} type Radio
+ }
+ }
+}
diff --git a/test/input.cxx b/test/input.cxx
new file mode 100644
index 000000000..a29d82b58
--- /dev/null
+++ b/test/input.cxx
@@ -0,0 +1,92 @@
+/* Test input fields */
+
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Float_Input.H>
+#include <FL/Fl_Int_Input.H>
+#include <FL/Fl_Secret_Input.H>
+#include <FL/Fl_Multiline_Input.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Color_Chooser.H>
+
+void cb(Fl_Widget *ob) {
+ printf("Callback for %s\n",ob->label());
+}
+
+int when = 0;
+Fl_Input *input[5];
+
+void toggle_cb(Fl_Widget *o, long v) {
+ if (((Fl_Toggle_Button*)o)->value()) when |= v; else when &= ~v;
+ for (int i=0; i<5; i++) input[i]->when(when);
+}
+
+void test(Fl_Input *i) {
+ if (i->changed()) {i->clear_changed(); printf("%s\n",i->label());}
+}
+
+void button_cb(Fl_Widget *,void *) {
+ for (int i=0; i<5; i++) test(input[i]);
+}
+
+void color_cb(Fl_Widget* button, void* v) {
+ Fl_Color c;
+ switch ((int)v) {
+ case 0: c = FL_WHITE; break;
+ case 1: c = FL_SELECTION_COLOR; break;
+ default: c = FL_BLACK; break;
+ }
+ uchar r,g,b; Fl::get_color(c, r,g,b);
+ if (fl_color_chooser(0,r,g,b)) {
+ Fl::set_color(c,r,g,b); Fl::redraw();
+ button->labelcolor(contrast(FL_BLACK,c));
+ button->redraw();
+ }
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *window = new Fl_Window(400,400);
+
+ int y = 10;
+ input[0] = new Fl_Input(70,y,300,30,"Normal:"); y += 35;
+ // input[0]->cursor_color(FL_SELECTION_COLOR);
+ // input[0]->maximum_size(20);
+ // input[0]->static_value("this is a testgarbage");
+ input[1] = new Fl_Float_Input(70,y,300,30,"Float:"); y += 35;
+ input[2] = new Fl_Int_Input(70,y,300,30,"Int:"); y += 35;
+ input[3] = new Fl_Secret_Input(70,y,300,30,"Secret:"); y += 35;
+ input[4] = new Fl_Multiline_Input(70,y,300,100,"Multiline:"); y += 105;
+
+ for (int i = 0; i < 4; i++) {
+ input[i]->when(0); input[i]->callback(cb);
+ }
+ int y1 = y;
+
+ Fl_Button *b;
+ b = new Fl_Toggle_Button(10,y,200,25,"FL_WHEN_&CHANGED");
+ b->callback(toggle_cb, FL_WHEN_CHANGED); y += 25;
+ b = new Fl_Toggle_Button(10,y,200,25,"FL_WHEN_&RELEASE");
+ b->callback(toggle_cb, FL_WHEN_RELEASE); y += 25;
+ b = new Fl_Toggle_Button(10,y,200,25,"FL_WHEN_&ENTER_KEY");
+ b->callback(toggle_cb, FL_WHEN_ENTER_KEY); y += 25;
+ b = new Fl_Toggle_Button(10,y,200,25,"FL_WHEN_&NOT_CHANGED");
+ b->callback(toggle_cb, FL_WHEN_NOT_CHANGED); y += 25;
+ y += 5;
+ b = new Fl_Button(10,y,200,25,"&print changed()");
+ b->callback(button_cb);
+
+ b = new Fl_Button(220,y1,100,25,"color"); y1 += 25;
+ b->color(input[0]->color()); b->callback(color_cb, (void*)0);
+ b = new Fl_Button(220,y1,100,25,"selection_color"); y1 += 25;
+ b->color(input[0]->selection_color()); b->callback(color_cb, (void*)1);
+ b = new Fl_Button(220,y1,100,25,"textcolor"); y1 += 25;
+ b->color(input[0]->textcolor()); b->callback(color_cb, (void*)2);
+ b->labelcolor(contrast(FL_BLACK,b->color()));
+
+ window->end();
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/jpeg_image.cxx b/test/jpeg_image.cxx
new file mode 100644
index 000000000..c788250fb
--- /dev/null
+++ b/test/jpeg_image.cxx
@@ -0,0 +1,179 @@
+/* Test fl_draw_image.
+
+ Be sure to try every visual with the -v switch and try
+ -m (monochrome) on each of them.
+
+ This program requires either the libjpeg.a library or
+ an internal DD library to read images (this is chosen
+ by the presence of the "DD" #define).
+
+ To get the jpeg library:
+
+The "official" archive site for this software is ftp.uu.net (Internet
+address 192.48.96.9). The most recent released version can always be found
+there in directory graphics/jpeg. This particular version will be archived
+as graphics/jpeg/jpegsrc.v6a.tar.gz.
+
+ The makefile assummes you decompressed and build these
+ in a directory called "jpeg-6a" in the same location as the
+ "FL" directory.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <stdio.h>
+#include <stdlib.h>
+
+void readtheimage(const char *name); // below
+int width;
+int height;
+int depth;
+int linedelta;
+uchar *ibuffer;
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/Fl_Window.H>
+int mono;
+
+class image_window : public Fl_Window {
+ void draw();
+public:
+ image_window(int w,int h) : Fl_Window(w,h) {box(FL_NO_BOX);}
+};
+
+void image_window::draw() {
+ if (mono)
+ fl_draw_image_mono(ibuffer+1,0,0,width,height,depth,linedelta);
+ else
+ fl_draw_image(ibuffer,0,0,width,height,depth,linedelta);
+}
+
+////////////////////////////////////////////////////////////////
+
+#include <FL/x.H>
+#include "list_visuals.C"
+
+////////////////////////////////////////////////////////////////
+
+int visid = -1;
+int arg(int argc, char **argv, int &i) {
+ if (argv[i][1] == 'm') {mono = 1; i++; return 1;}
+
+ if (argv[i][1] == 'v') {
+ if (i+1 >= argc) return 0;
+ visid = atoi(argv[i+1]);
+ i += 2;
+ return 2;
+ }
+
+ return 0;
+}
+
+int main(int argc, char ** argv) {
+
+ int i = 1;
+ if (!Fl::args(argc,argv,i,arg) || i != argc-1) {
+ fprintf(stderr,"usage: %s <switches> image_file\n"
+" -v # : use visual\n"
+" -m : monochrome\n"
+"%s\n",
+ argv[0],Fl::help);
+ exit(1);
+ }
+
+ readtheimage(argv[i]);
+ image_window *window = new image_window(width,height);
+
+ if (visid>=0) {
+ fl_open_display();
+ XVisualInfo templt; int num;
+ templt.visualid = visid;
+ fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
+ if (!fl_visual) {
+ fprintf(stderr, "No visual with id %d, use one of:\n",visid);
+ list_visuals();
+ exit(1);
+ }
+ fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ fl_xpixel(FL_BLACK); // make sure black is allocated
+ }
+
+ window->show(argc,argv);
+ return Fl::run();
+}
+
+////////////////////////////////////////////////////////////////
+#ifndef DD_LIBRARY
+// Read using jpeg library:
+
+extern "C" {
+#include "jpeglib.h"
+}
+
+void readtheimage(const char *name) {
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ FILE * infile = fopen(name, "rb");
+ if (!infile) {
+ fprintf(stderr, "can't open %s\n", name);
+ exit(1);
+ }
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, infile);
+ jpeg_read_header(&cinfo, TRUE);
+ jpeg_start_decompress(&cinfo);
+ width = cinfo.output_width;
+ height = cinfo.output_height;
+ depth = cinfo.output_components;
+ ibuffer = new uchar[width*height*depth];
+ uchar *rp = ibuffer;
+ // for (int i=0; i<height; i++) {
+ for (int i=height; i--; ) {
+ jpeg_read_scanlines(&cinfo, &rp, 1);
+ rp += width*depth;
+ }
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ fclose(infile);
+}
+
+////////////////////////////////////////////////////////////////
+#else // Digital Domain in-house library
+
+#include "DDNewImage/DDImageOp.H"
+#include "DDNewImage/DDImgRead.H"
+#include "DDNewImage/DDImgToBuffer.H"
+
+void readtheimage(const char *name) {
+ DDImgRead reader(name);
+ width = reader.xsize();
+ height = reader.ysize();
+ depth = 4; // reader.zsize();
+ ibuffer = new uchar[width*height*depth];
+ DDImgToBuffer b(&reader,depth,ibuffer,0,0,width,height);
+ b.execute();
+ if (DDImage::haderror) {
+ fprintf(stderr,"%s\n",DDImage::errormsg());
+ exit(1);
+ }
+ // swap it around into RGBA order:
+ for (uchar *p = ibuffer+width*height*4-4; p >= ibuffer; p-=4) {
+ uchar r = p[3];
+ uchar g = p[2];
+ uchar b = p[1];
+ uchar a = p[0];
+ p[0] = r;
+ p[1] = g;
+ p[2] = b;
+ p[3] = a;
+ }
+ // make it bottom-to-top:
+ ibuffer = ibuffer + width*(height-1)*depth;
+ linedelta = -(width*depth);
+}
+#endif
+
diff --git a/test/keyboard.cxx b/test/keyboard.cxx
new file mode 100644
index 000000000..6f6fd58a3
--- /dev/null
+++ b/test/keyboard.cxx
@@ -0,0 +1,102 @@
+// Continuously display FLTK's event state.
+
+// Known bugs:
+
+// X insists on reporting the state *before* the shift key was
+// pressed, rather than after, on shift key events. I fixed this for
+// the mouse buttons, but it did not seem worth it for shift.
+
+// X servers do not agree about any shift flags after except shift, ctrl,
+// lock, and alt. They may also not agree about the symbols for the extra
+// keys Micro$oft put on the keyboard.
+
+// On Irix the backslash key does not work. A bug in XKeysymToKeycode?
+
+#include "keyboard_ui.C"
+#include <stdio.h>
+
+// these are used to identify which buttons are which:
+void key_cb(Fl_Button*, void*) {}
+void shift_cb(Fl_Button*, void*) {}
+
+// this is used to stop Esc from exiting the program:
+int handle(int e) {
+ return (e == FL_SHORTCUT); // eat all keystrokes
+}
+
+struct {int n; const char* text;} table[] = {
+ {FL_Escape, "FL_Escape"},
+ {FL_BackSpace, "FL_BackSpace"},
+ {FL_Tab, "FL_Tab"},
+ {FL_Enter, "FL_Enter"},
+ {FL_Print, "FL_Print"},
+ {FL_Scroll_Lock, "FL_Scroll_Lock"},
+ {FL_Pause, "FL_Pause"},
+ {FL_Insert, "FL_Insert"},
+ {FL_Home, "FL_Home"},
+ {FL_Page_Up, "FL_Page_Up"},
+ {FL_Delete, "FL_Delete"},
+ {FL_End, "FL_End"},
+ {FL_Page_Down, "FL_Page_Down"},
+ {FL_Left, "FL_Left"},
+ {FL_Up, "FL_Up"},
+ {FL_Right, "FL_Right"},
+ {FL_Down, "FL_Down"},
+ {FL_Shift_L, "FL_Shift_L"},
+ {FL_Shift_R, "FL_Shift_R"},
+ {FL_Control_L, "FL_Control_L"},
+ {FL_Control_R, "FL_Control_R"},
+ {FL_Caps_Lock, "FL_Caps_Lock"},
+ {FL_Alt_L, "FL_Alt_L"},
+ {FL_Alt_R, "FL_Alt_R"},
+ {FL_Meta_L, "FL_Meta_L"},
+ {FL_Meta_R, "FL_Meta_R"},
+ {FL_Menu, "FL_Menu"},
+ {FL_Num_Lock, "FL_Num_Lock"},
+ {FL_KP_Enter, "FL_KP_Enter"}
+};
+
+int main(int argc, char** argv) {
+ Fl::add_handler(handle);
+ Fl_Window *window = make_window();
+ window->show(argc,argv);
+ while (Fl::wait()) {
+
+ // update all the buttons with the current key and shift state:
+ for (int i = 0; i < window->children(); i++) {
+ Fl_Widget* b = window->child(i);
+ if (b->callback() == (Fl_Callback*)key_cb) {
+ int i = int(b->user_data());
+ if (!i) i = b->label()[0];
+ ((Fl_Button*)b)->value(Fl::event_key(i));
+ } else if (b->callback() == (Fl_Callback*)shift_cb) {
+ int i = int(b->user_data());
+ ((Fl_Button*)b)->value(Fl::event_state(i));
+ }
+ }
+
+ // figure out the keyname:
+ char buffer[100];
+ const char *keyname = buffer;
+ int k = Fl::event_key();
+ if (!k)
+ keyname = "0";
+ else if (k < 256) {
+ sprintf(buffer, "'%c'", k);
+ } else if (k >= FL_F && k <= FL_F_Last) {
+ sprintf(buffer, "FL_F+%d", k - FL_F);
+ } else if (k >= FL_KP && k <= FL_KP_Last) {
+ sprintf(buffer, "FL_KP+'%c'", k-FL_KP);
+ } else if (k >= FL_Button && k <= FL_Button+7) {
+ sprintf(buffer, "FL_Button+%d", k-FL_Button);
+ } else {
+ sprintf(buffer, "0x%04x", k);
+ for (int i = 0; i < int(sizeof(table)/sizeof(*table)); i++)
+ if (table[i].n == k) {keyname = table[i].text; break;}
+ }
+ key_output->value(keyname);
+
+ text_output->value(Fl::event_text());
+ }
+ return 0;
+}
diff --git a/test/keyboard_ui.C b/test/keyboard_ui.C
new file mode 100644
index 000000000..cf35760bd
--- /dev/null
+++ b/test/keyboard_ui.C
@@ -0,0 +1,558 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "keyboard_ui.H"
+Fl_Output *key_output;
+Fl_Output *text_output;
+
+Fl_Window* make_window() {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(494, 193);
+ w = o;
+ {Fl_Button* o = new Fl_Button(15, 50, 20, 20, "Esc ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Escape));
+ }
+ {Fl_Button* o = new Fl_Button(50, 50, 20, 20, "F1");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+1));
+ }
+ {Fl_Button* o = new Fl_Button(70, 50, 20, 20, "F2");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+2));
+ }
+ {Fl_Button* o = new Fl_Button(90, 50, 20, 20, "F3");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+3));
+ }
+ {Fl_Button* o = new Fl_Button(110, 50, 20, 20, "F4");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+4));
+ }
+ {Fl_Button* o = new Fl_Button(140, 50, 20, 20, "F5");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+5));
+ }
+ {Fl_Button* o = new Fl_Button(160, 50, 20, 20, "F6");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+6));
+ }
+ {Fl_Button* o = new Fl_Button(180, 50, 20, 20, "F7");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+7));
+ }
+ {Fl_Button* o = new Fl_Button(200, 50, 20, 20, "F8");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+8));
+ }
+ {Fl_Button* o = new Fl_Button(230, 50, 20, 20, "F9");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+9));
+ }
+ {Fl_Button* o = new Fl_Button(250, 50, 20, 20, "F10");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+10));
+ }
+ {Fl_Button* o = new Fl_Button(270, 50, 20, 20, "F11");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+11));
+ }
+ {Fl_Button* o = new Fl_Button(290, 50, 20, 20, "F12");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_F+12));
+ }
+ {Fl_Button* o = new Fl_Button(325, 50, 20, 20, "Print ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Print));
+ }
+ {Fl_Button* o = new Fl_Button(345, 50, 20, 20, "Sclk ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Scroll_Lock));
+ }
+ {Fl_Button* o = new Fl_Button(365, 50, 20, 20, "Paus ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Pause));
+ }
+ {Fl_Button* o = new Fl_Button(15, 80, 20, 20, "`");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(35, 80, 20, 20, "1");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(55, 80, 20, 20, "2");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(75, 80, 20, 20, "3");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(95, 80, 20, 20, "4");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(115, 80, 20, 20, "5");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(135, 80, 20, 20, "6");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(155, 80, 20, 20, "7");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(175, 80, 20, 20, "8");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(195, 80, 20, 20, "9");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(215, 80, 20, 20, "0");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(235, 80, 20, 20, "-");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(255, 80, 20, 20, "=");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(275, 80, 35, 20, "Bksp");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_BackSpace));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(325, 80, 20, 20, "Ins ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Insert));
+ }
+ {Fl_Button* o = new Fl_Button(345, 80, 20, 20, "Home");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Home));
+ }
+ {Fl_Button* o = new Fl_Button(365, 80, 20, 20, "pgup ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Page_Up));
+ }
+ {Fl_Button* o = new Fl_Button(400, 80, 20, 20, "Num");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Num_Lock));
+ }
+ {Fl_Button* o = new Fl_Button(420, 80, 20, 20, "/");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'/'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 80, 20, 20, "*");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'*'));
+ }
+ {Fl_Button* o = new Fl_Button(460, 80, 20, 20, "-");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'-'));
+ }
+ {Fl_Button* o = new Fl_Button(15, 100, 27, 20, "Tab");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Tab));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(42, 100, 20, 20, "Q");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(62, 100, 20, 20, "W");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(82, 100, 20, 20, "E");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(102, 100, 20, 20, "R");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(122, 100, 20, 20, "T");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(142, 100, 20, 20, "Y");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(162, 100, 20, 20, "U");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(182, 100, 20, 20, "I");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(202, 100, 20, 20, "O");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(222, 100, 20, 20, "P");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(242, 100, 20, 20, "[");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(262, 100, 20, 20, "]");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(282, 100, 28, 20, "\\");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)('|'));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(325, 100, 20, 20, "Del ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Delete));
+ }
+ {Fl_Button* o = new Fl_Button(345, 100, 20, 20, "End ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_End));
+ }
+ {Fl_Button* o = new Fl_Button(365, 100, 20, 20, "pgdn ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Page_Down));
+ }
+ {Fl_Button* o = new Fl_Button(400, 100, 20, 20, "7");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'7'));
+ }
+ {Fl_Button* o = new Fl_Button(420, 100, 20, 20, "8");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'8'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 100, 20, 20, "9");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'9'));
+ }
+ {Fl_Button* o = new Fl_Button(460, 100, 20, 40, "+");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'+'));
+ o->align(17);
+ }
+ {Fl_Button* o = new Fl_Button(15, 120, 36, 20, "Lock");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Caps_Lock));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(51, 120, 20, 20, "A");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(71, 120, 20, 20, "S");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(91, 120, 20, 20, "D");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(111, 120, 20, 20, "F");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(131, 120, 20, 20, "G");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(151, 120, 20, 20, "H");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(171, 120, 20, 20, "J");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(191, 120, 20, 20, "K");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(211, 120, 20, 20, "L");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(231, 120, 20, 20, ";");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(251, 120, 20, 20, "\'");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(271, 120, 39, 20, "Enter");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Enter));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(400, 120, 20, 20, "4");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'4'));
+ }
+ {Fl_Button* o = new Fl_Button(420, 120, 20, 20, "5");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'5'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 120, 20, 20, "6");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'6'));
+ }
+ {Fl_Button* o = new Fl_Button(15, 140, 45, 20, "Shift");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Shift_L));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(60, 140, 20, 20, "Z");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(80, 140, 20, 20, "X");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(100, 140, 20, 20, "C");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(120, 140, 20, 20, "V");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(140, 140, 20, 20, "B");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(160, 140, 20, 20, "N");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(180, 140, 20, 20, "M");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(200, 140, 20, 20, ",");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(220, 140, 20, 20, ".");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(240, 140, 20, 20, "/");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb);
+ }
+ {Fl_Button* o = new Fl_Button(260, 140, 50, 20, "Shift");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Shift_R));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(345, 140, 20, 20, "@8->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Up));
+ }
+ {Fl_Button* o = new Fl_Button(400, 140, 20, 20, "1");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'1'));
+ }
+ {Fl_Button* o = new Fl_Button(420, 140, 20, 20, "2");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'2'));
+ }
+ {Fl_Button* o = new Fl_Button(440, 140, 20, 20, "3");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'3'));
+ }
+ {Fl_Button* o = new Fl_Button(460, 140, 20, 40);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP_Enter));
+ }
+ {Fl_Button* o = new Fl_Button(15, 160, 30, 20, "Ctrl");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Control_L));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(45, 160, 30, 20, "Meta ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Meta_L));
+ }
+ {Fl_Button* o = new Fl_Button(75, 160, 30, 20, "Alt ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Alt_L));
+ }
+ {Fl_Button* o = new Fl_Button(105, 160, 85, 20);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(' '));
+ }
+ {Fl_Button* o = new Fl_Button(190, 160, 30, 20, "Alt ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Alt_R));
+ }
+ {Fl_Button* o = new Fl_Button(220, 160, 30, 20, "Meta ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Meta_R));
+ }
+ {Fl_Button* o = new Fl_Button(250, 160, 30, 20, "Menu ");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Menu));
+ }
+ {Fl_Button* o = new Fl_Button(280, 160, 30, 20, "Ctrl");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Control_R));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(325, 160, 20, 20, "@4->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Left));
+ }
+ {Fl_Button* o = new Fl_Button(345, 160, 20, 20, "@2->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Down));
+ }
+ {Fl_Button* o = new Fl_Button(365, 160, 20, 20, "@6->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelsize(10);
+ o->labelcolor(47);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_Right));
+ }
+ {Fl_Button* o = new Fl_Button(400, 160, 40, 20, "0");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'0'));
+ o->align(20);
+ }
+ {Fl_Button* o = new Fl_Button(440, 160, 20, 20, ".");
+ o->labelsize(10);
+ o->callback((Fl_Callback*)key_cb, (void*)(FL_KP+'.'));
+ }
+ {Fl_Button* o = new Fl_Button(400, 15, 20, 10, "shift ");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_SHIFT));
+ }
+ {Fl_Button* o = new Fl_Button(420, 15, 20, 10, "lock ");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_CAPS_LOCK));
+ }
+ {Fl_Button* o = new Fl_Button(440, 15, 20, 10, "ctrl");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_CTRL));
+ }
+ {Fl_Button* o = new Fl_Button(460, 15, 20, 10, "alt");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_ALT));
+ }
+ {Fl_Button* o = new Fl_Button(400, 25, 20, 10, "num");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_NUM_LOCK));
+ }
+ {Fl_Button* o = new Fl_Button(420, 25, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x20));
+ }
+ {Fl_Button* o = new Fl_Button(440, 25, 20, 10, "meta ");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_META));
+ }
+ {Fl_Button* o = new Fl_Button(460, 25, 20, 10, "sclk");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_SCROLL_LOCK));
+ }
+ {Fl_Button* o = new Fl_Button(400, 35, 20, 10, "b1");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_BUTTON1));
+ }
+ {Fl_Button* o = new Fl_Button(420, 35, 20, 10, "b2");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_BUTTON2));
+ }
+ {Fl_Button* o = new Fl_Button(440, 35, 20, 10, "b3");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(FL_BUTTON3));
+ }
+ {Fl_Button* o = new Fl_Button(460, 35, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x800));
+ }
+ {Fl_Button* o = new Fl_Button(400, 45, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x1000));
+ }
+ {Fl_Button* o = new Fl_Button(420, 45, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x2000));
+ }
+ {Fl_Button* o = new Fl_Button(440, 45, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x4000));
+ }
+ {Fl_Button* o = new Fl_Button(460, 45, 20, 10, "?");
+ o->box(FL_THIN_UP_BOX);
+ o->color2(3);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)shift_cb, (void*)(0x8000));
+ }
+ {Fl_Output* o = new Fl_Output(15, 15, 170, 30, "Fl::event_key():");
+ key_output = o;
+ o->labelsize(8);
+ o->align(5);
+ }
+ {Fl_Box* o = new Fl_Box(395, 15, 85, 40, "Fl::event_state():");
+ o->labelsize(8);
+ o->align(5);
+ }
+ {Fl_Output* o = new Fl_Output(195, 15, 190, 30, "Fl::event_text():");
+ text_output = o;
+ o->labelsize(8);
+ o->align(5);
+ }
+ w->end();
+ }
+ return w;
+}
diff --git a/test/keyboard_ui.H b/test/keyboard_ui.H
new file mode 100644
index 000000000..365d2dbc5
--- /dev/null
+++ b/test/keyboard_ui.H
@@ -0,0 +1,11 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Window.H>
+extern void key_cb(Fl_Button*, void*);
+extern void shift_cb(Fl_Button*, void*);
+extern Fl_Output *key_output;
+extern Fl_Output *text_output;
+Fl_Window* make_window();
diff --git a/test/keyboard_ui.fl b/test/keyboard_ui.fl
new file mode 100644
index 000000000..791cdce5f
--- /dev/null
+++ b/test/keyboard_ui.fl
@@ -0,0 +1,696 @@
+# data file for FL User Interface Designer (fluid)
+version 0.99
+gridx 5
+gridy 5
+snap 3
+Function {make_window()} {open
+} {
+ Fl_Window {} {open
+ xywh {118 466 494 193}
+ } {
+ Fl_Button {} {
+ label {Esc }
+ user_data FL_Escape user_data_type {void*}
+ callback key_cb open
+ xywh {15 50 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label F1
+ user_data {FL_F+1} user_data_type {void*}
+ callback key_cb open
+ xywh {50 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F2
+ user_data {FL_F+2} user_data_type {void*}
+ callback key_cb open
+ xywh {70 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F3
+ user_data {FL_F+3} user_data_type {void*}
+ callback key_cb open
+ xywh {90 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F4
+ user_data {FL_F+4} user_data_type {void*}
+ callback key_cb open
+ xywh {110 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F5
+ user_data {FL_F+5} user_data_type {void*}
+ callback key_cb open
+ xywh {140 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F6
+ user_data {FL_F+6} user_data_type {void*}
+ callback key_cb open
+ xywh {160 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F7
+ user_data {FL_F+7} user_data_type {void*}
+ callback key_cb open
+ xywh {180 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F8
+ user_data {FL_F+8} user_data_type {void*}
+ callback key_cb open
+ xywh {200 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F9
+ user_data {FL_F+9} user_data_type {void*}
+ callback key_cb open
+ xywh {230 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F10
+ user_data {FL_F+10} user_data_type {void*}
+ callback key_cb open
+ xywh {250 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F11
+ user_data {FL_F+11} user_data_type {void*}
+ callback key_cb open
+ xywh {270 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F12
+ user_data {FL_F+12} user_data_type {void*}
+ callback key_cb open
+ xywh {290 50 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {Print }
+ user_data FL_Print user_data_type {void*}
+ callback key_cb open
+ xywh {325 50 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {Sclk }
+ user_data FL_Scroll_Lock user_data_type {void*}
+ callback key_cb open
+ xywh {345 50 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {Paus }
+ user_data FL_Pause user_data_type {void*}
+ callback key_cb open
+ xywh {365 50 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {`}
+ callback key_cb open
+ xywh {15 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 1
+ callback key_cb open
+ xywh {35 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 2
+ callback key_cb open
+ xywh {55 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 3
+ callback key_cb open
+ xywh {75 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 4
+ callback key_cb open
+ xywh {95 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 5
+ callback key_cb open
+ xywh {115 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 6
+ callback key_cb open
+ xywh {135 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 7
+ callback key_cb open
+ xywh {155 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 8
+ callback key_cb open
+ xywh {175 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 9
+ callback key_cb open
+ xywh {195 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 0
+ callback key_cb open
+ xywh {215 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {-}
+ callback key_cb open
+ xywh {235 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {=}
+ callback key_cb open
+ xywh {255 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label Bksp
+ user_data FL_BackSpace user_data_type {void*}
+ callback key_cb open
+ xywh {275 80 35 20} labeltype 2 labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label {Ins }
+ user_data FL_Insert user_data_type {void*}
+ callback key_cb open
+ xywh {325 80 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label Home
+ user_data FL_Home user_data_type {void*}
+ callback key_cb open
+ xywh {345 80 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {pgup }
+ user_data FL_Page_Up user_data_type {void*}
+ callback key_cb open
+ xywh {365 80 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label Num
+ user_data FL_Num_Lock user_data_type {void*}
+ callback key_cb open
+ xywh {400 80 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {/}
+ user_data {FL_KP+'/'} user_data_type {void*}
+ callback key_cb open
+ xywh {420 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {*}
+ user_data {FL_KP+'*'} user_data_type {void*}
+ callback key_cb open
+ xywh {440 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {-}
+ user_data {FL_KP+'-'} user_data_type {void*}
+ callback key_cb open
+ xywh {460 80 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label Tab
+ user_data FL_Tab user_data_type {void*}
+ callback key_cb open
+ xywh {15 100 27 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label Q
+ callback key_cb open
+ xywh {42 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label W
+ callback key_cb open
+ xywh {62 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label E
+ callback key_cb open
+ xywh {82 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label R
+ callback key_cb open
+ xywh {102 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label T
+ callback key_cb open
+ xywh {122 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label Y
+ callback key_cb open
+ xywh {142 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label U
+ callback key_cb open
+ xywh {162 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label I
+ callback key_cb open
+ xywh {182 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label O
+ callback key_cb open
+ xywh {202 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label P
+ callback key_cb open
+ xywh {222 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {[}
+ callback key_cb open
+ xywh {242 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {]}
+ callback key_cb open
+ xywh {262 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {\\}
+ user_data {'|'}
+ callback key_cb open
+ xywh {282 100 28 20} labelsize 10 align 20
+ }
+ Fl_Button {} {
+ label {Del }
+ user_data FL_Delete user_data_type {void*}
+ callback key_cb open
+ xywh {325 100 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {End }
+ user_data FL_End user_data_type {void*}
+ callback key_cb open
+ xywh {345 100 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {pgdn }
+ user_data FL_Page_Down user_data_type {void*}
+ callback key_cb open
+ xywh {365 100 20 20} labelsize 8
+ }
+ Fl_Button {} {
+ label 7
+ user_data {FL_KP+'7'} user_data_type {void*}
+ callback key_cb open
+ xywh {400 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 8
+ user_data {FL_KP+'8'} user_data_type {void*}
+ callback key_cb open
+ xywh {420 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 9
+ user_data {FL_KP+'9'} user_data_type {void*}
+ callback key_cb open
+ xywh {440 100 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {+}
+ user_data {FL_KP+'+'} user_data_type {void*}
+ callback key_cb open
+ xywh {460 100 20 40} labelsize 10 align 17
+ }
+ Fl_Button {} {
+ label Lock
+ user_data FL_Caps_Lock user_data_type {void*}
+ callback key_cb open
+ xywh {15 120 36 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label A
+ callback key_cb open
+ xywh {51 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label S
+ callback key_cb open
+ xywh {71 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label D
+ callback key_cb open
+ xywh {91 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label F
+ callback key_cb open
+ xywh {111 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label G
+ callback key_cb open
+ xywh {131 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label H
+ callback key_cb open
+ xywh {151 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label J
+ callback key_cb open
+ xywh {171 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label K
+ callback key_cb open
+ xywh {191 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label L
+ callback key_cb open
+ xywh {211 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {;}
+ callback key_cb open
+ xywh {231 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {'}
+ callback key_cb open
+ xywh {251 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label Enter
+ user_data FL_Enter user_data_type {void*}
+ callback key_cb open
+ xywh {271 120 39 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label 4
+ user_data {FL_KP+'4'} user_data_type {void*}
+ callback key_cb open
+ xywh {400 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 5
+ user_data {FL_KP+'5'} user_data_type {void*}
+ callback key_cb open
+ xywh {420 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 6
+ user_data {FL_KP+'6'} user_data_type {void*}
+ callback key_cb open
+ xywh {440 120 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label Shift
+ user_data FL_Shift_L user_data_type {void*}
+ callback key_cb open
+ xywh {15 140 45 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label Z
+ callback key_cb open
+ xywh {60 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label X
+ callback key_cb open
+ xywh {80 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label C
+ callback key_cb open
+ xywh {100 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label V
+ callback key_cb open
+ xywh {120 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label B
+ callback key_cb open
+ xywh {140 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label N
+ callback key_cb open
+ xywh {160 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label M
+ callback key_cb open
+ xywh {180 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {,}
+ callback key_cb open
+ xywh {200 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {.}
+ callback key_cb open
+ xywh {220 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {/}
+ callback key_cb open
+ xywh {240 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label Shift
+ user_data FL_Shift_R user_data_type {void*}
+ callback key_cb open
+ xywh {260 140 50 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label {@8->}
+ user_data FL_Up user_data_type {void*}
+ callback key_cb open
+ xywh {345 140 20 20} labeltype 2 labelsize 10 labelcolor 47
+ }
+ Fl_Button {} {
+ label 1
+ user_data {FL_KP+'1'} user_data_type {void*}
+ callback key_cb open
+ xywh {400 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 2
+ user_data {FL_KP+'2'} user_data_type {void*}
+ callback key_cb open
+ xywh {420 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label 3
+ user_data {FL_KP+'3'} user_data_type {void*}
+ callback key_cb open
+ xywh {440 140 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ user_data FL_KP_Enter user_data_type {void*}
+ callback key_cb open
+ xywh {460 140 20 40}
+ }
+ Fl_Button {} {
+ label Ctrl
+ user_data FL_Control_L user_data_type {void*}
+ callback key_cb open
+ xywh {15 160 30 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label {Meta }
+ user_data FL_Meta_L user_data_type {void*}
+ callback key_cb open
+ xywh {45 160 30 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {Alt }
+ user_data FL_Alt_L user_data_type {void*}
+ callback key_cb open
+ xywh {75 160 30 20} labelsize 8
+ }
+ Fl_Button {} {
+ user_data {' '} user_data_type {void*}
+ callback key_cb open
+ xywh {105 160 85 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {Alt }
+ user_data FL_Alt_R user_data_type {void*}
+ callback key_cb open
+ xywh {190 160 30 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {Meta }
+ user_data FL_Meta_R user_data_type {void*}
+ callback key_cb open
+ xywh {220 160 30 20} labelsize 8
+ }
+ Fl_Button {} {
+ label {Menu }
+ user_data FL_Menu user_data_type {void*}
+ callback key_cb open
+ xywh {250 160 30 20} labelsize 8
+ }
+ Fl_Button {} {
+ label Ctrl
+ user_data FL_Control_R user_data_type {void*}
+ callback key_cb open
+ xywh {280 160 30 20} labelsize 8 align 20
+ }
+ Fl_Button {} {
+ label {@4->}
+ user_data FL_Left user_data_type {void*}
+ callback key_cb open
+ xywh {325 160 20 20} labeltype 2 labelsize 10 labelcolor 47
+ }
+ Fl_Button {} {
+ label {@2->}
+ user_data FL_Down user_data_type {void*}
+ callback key_cb open
+ xywh {345 160 20 20} labeltype 2 labelsize 10 labelcolor 47
+ }
+ Fl_Button {} {
+ label {@6->}
+ user_data FL_Right user_data_type {void*}
+ callback key_cb open
+ xywh {365 160 20 20} labeltype 2 labelsize 10 labelcolor 47
+ }
+ Fl_Button {} {
+ label 0
+ user_data {FL_KP+'0'} user_data_type {void*}
+ callback key_cb open
+ xywh {400 160 40 20} labelsize 10 align 20
+ }
+ Fl_Button {} {
+ label {.}
+ user_data {FL_KP+'.'} user_data_type {void*}
+ callback key_cb open
+ xywh {440 160 20 20} labelsize 10
+ }
+ Fl_Button {} {
+ label {shift }
+ user_data FL_SHIFT user_data_type {void*}
+ callback shift_cb open
+ xywh {400 15 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {lock }
+ user_data FL_CAPS_LOCK user_data_type {void*}
+ callback shift_cb open
+ xywh {420 15 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label ctrl
+ user_data FL_CTRL user_data_type {void*}
+ callback shift_cb open
+ xywh {440 15 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label alt
+ user_data FL_ALT user_data_type {void*}
+ callback shift_cb open
+ xywh {460 15 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label num
+ user_data FL_NUM_LOCK user_data_type {void*}
+ callback shift_cb open
+ xywh {400 25 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {?}
+ user_data 0x20 user_data_type {void*}
+ callback shift_cb open
+ xywh {420 25 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {meta }
+ user_data FL_META user_data_type {void*}
+ callback shift_cb open
+ xywh {440 25 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label sclk
+ user_data FL_SCROLL_LOCK user_data_type {void*}
+ callback shift_cb open
+ xywh {460 25 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label b1
+ user_data FL_BUTTON1 user_data_type {void*}
+ callback shift_cb open
+ xywh {400 35 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label b2
+ user_data FL_BUTTON2 user_data_type {void*}
+ callback shift_cb open
+ xywh {420 35 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label b3
+ user_data FL_BUTTON3 user_data_type {void*}
+ callback shift_cb open
+ xywh {440 35 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {?}
+ user_data 0x800 user_data_type {void*}
+ callback shift_cb open
+ xywh {460 35 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {?}
+ user_data 0x1000 user_data_type {void*}
+ callback shift_cb open
+ xywh {400 45 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {?}
+ user_data 0x2000 user_data_type {void*}
+ callback shift_cb open
+ xywh {420 45 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {?}
+ user_data 0x4000 user_data_type {void*}
+ callback shift_cb open
+ xywh {440 45 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Button {} {
+ label {?}
+ user_data 0x8000 user_data_type {void*}
+ callback shift_cb open
+ xywh {460 45 20 10} box 6 color {47 3} labelsize 8
+ }
+ Fl_Output key_output {
+ label {Fl::event_key():} open
+ xywh {15 15 170 30} labelsize 8 align 5
+ }
+ Fl_Box {} {
+ label {Fl::event_state():} open
+ xywh {395 15 85 40} labelsize 8 align 5
+ }
+ Fl_Output text_output {
+ label {Fl::event_text():} open selected
+ xywh {195 15 190 30} labelsize 8 align 5
+ }
+ }
+}
diff --git a/test/label.cxx b/test/label.cxx
new file mode 100644
index 000000000..d1ca5be10
--- /dev/null
+++ b/test/label.cxx
@@ -0,0 +1,137 @@
+/* Test all the built-in labeltypes, and fl_font
+
+ This is also a good double-buffering test.
+
+*/
+
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Hor_Value_Slider.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Choice.H>
+#include <FL/fl_draw.H>
+
+Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb,*clipb,*wrapb;
+Fl_Box *text;
+Fl_Input *input;
+Fl_Hor_Value_Slider *fonts;
+Fl_Hor_Value_Slider *sizes;
+Fl_Double_Window *window;
+
+void button_cb(Fl_Widget *,void *) {
+ int i = 0;
+ if (leftb->value()) i |= FL_ALIGN_LEFT;
+ if (rightb->value()) i |= FL_ALIGN_RIGHT;
+ if (topb->value()) i |= FL_ALIGN_TOP;
+ if (bottomb->value()) i |= FL_ALIGN_BOTTOM;
+ if (insideb->value()) i |= FL_ALIGN_INSIDE;
+ if (clipb->value()) i |= FL_ALIGN_CLIP;
+ if (wrapb->value()) i |= FL_ALIGN_WRAP;
+ text->align(i);
+ window->redraw();
+}
+
+void font_cb(Fl_Widget *,void *) {
+ text->labelfont(int(fonts->value()));
+ window->redraw();
+}
+
+void size_cb(Fl_Widget *,void *) {
+ text->labelsize(int(sizes->value()));
+ window->redraw();
+}
+
+void input_cb(Fl_Widget *,void *) {
+ text->label(input->value());
+ window->redraw();
+}
+
+void normal_cb(Fl_Widget *,void *) {
+ text->labeltype(FL_NORMAL_LABEL);
+ window->redraw();
+}
+
+void symbol_cb(Fl_Widget *,void *) {
+ text->labeltype(FL_SYMBOL_LABEL);
+ if (input->value()[0] != '@') {
+ input->static_value("@->");
+ text->label("@->");
+ }
+ window->redraw();
+}
+
+void shadow_cb(Fl_Widget *,void *) {
+ text->labeltype(FL_SHADOW_LABEL);
+ window->redraw();
+}
+
+void embossed_cb(Fl_Widget *,void *) {
+ text->labeltype(FL_EMBOSSED_LABEL);
+ window->redraw();
+}
+
+void engraved_cb(Fl_Widget *,void *) {
+ text->labeltype(FL_ENGRAVED_LABEL);
+ window->redraw();
+}
+
+Fl_Menu_Item choices[] = {
+ {"FL_NORMAL_LABEL",0,normal_cb},
+ {"FL_SYMBOL_LABEL",0,symbol_cb},
+ {"FL_SHADOW_LABEL",0,shadow_cb},
+ {"FL_ENGRAVED_LABEL",0,engraved_cb},
+ {"FL_EMBOSSED_LABEL",0,embossed_cb},
+ {0}};
+
+int main(int argc, char **argv) {
+ window = new Fl_Double_Window(400,400);
+
+ input = new Fl_Input(50,0,350,25);
+ input->static_value("The quick brown fox jumped over the lazy dog.");
+ input->when(FL_WHEN_CHANGED);
+ input->callback(input_cb);
+
+ sizes= new Fl_Hor_Value_Slider(50,25,350,25,"Size:");
+ sizes->align(FL_ALIGN_LEFT);
+ sizes->bounds(1,64);
+ sizes->step(1);
+ sizes->value(14);
+ sizes->callback(size_cb);
+
+ fonts=new Fl_Hor_Value_Slider(50,50,350,25,"Font:");
+ fonts->align(FL_ALIGN_LEFT);
+ fonts->bounds(0,15);
+ fonts->step(1);
+ fonts->value(0);
+ fonts->callback(font_cb);
+
+ Fl_Group *g = new Fl_Group(0,0,0,0);
+ leftb = new Fl_Toggle_Button(50,75,50,25,"left");
+ leftb->callback(button_cb);
+ rightb = new Fl_Toggle_Button(100,75,50,25,"right");
+ rightb->callback(button_cb);
+ topb = new Fl_Toggle_Button(150,75,50,25,"top");
+ topb->callback(button_cb);
+ bottomb = new Fl_Toggle_Button(200,75,50,25,"bottom");
+ bottomb->callback(button_cb);
+ insideb = new Fl_Toggle_Button(250,75,50,25,"inside");
+ insideb->callback(button_cb);
+ wrapb = new Fl_Toggle_Button(300,75,50,25,"wrap");
+ wrapb->callback(button_cb);
+ clipb = new Fl_Toggle_Button(350,75,50,25,"clip");
+ clipb->callback(button_cb);
+ g->resizable(insideb);
+ g->forms_end();
+
+ Fl_Choice *c = new Fl_Choice(50,100,200,25);
+ c->menu(choices);
+
+ text= new Fl_Box(FL_FRAME_BOX,100,225,200,100,input->value());
+ text->align(FL_ALIGN_CENTER);
+ window->resizable(text);
+ window->forms_end();
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/list_visuals.cxx b/test/list_visuals.cxx
new file mode 100644
index 000000000..57b1e7e74
--- /dev/null
+++ b/test/list_visuals.cxx
@@ -0,0 +1,205 @@
+// List all the visuals on the screen, and dumps anything interesting
+// about them to stdout.
+//
+// Does not use fltk.
+//
+// This file may be #included in another program to make a function to
+// call to list the visuals. Fl.H must be included first to indicate this.
+
+#ifdef WIN32
+void list_visuals() {;}
+#else
+
+#include <config.h>
+
+#ifndef Fl_H
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+Display *fl_display;
+int fl_screen;
+const char *dname;
+void fl_open_display() {
+ fl_display = XOpenDisplay(dname);
+ if (!fl_display) {
+ fprintf(stderr,"Can't open display: %s\n",XDisplayName(dname));
+ exit(1);
+ }
+ fl_screen = DefaultScreen(fl_display);
+}
+
+#endif
+
+const char *ClassNames[] = {
+ "StaticGray ",
+ "GrayScale ",
+ "StaticColor",
+ "PseudoColor",
+ "TrueColor ",
+ "DirectColor"
+};
+
+// SERVER_OVERLAY_VISUALS property element:
+typedef struct _OverlayInfo {
+ long overlay_visual;
+ long transparent_type;
+ long value;
+ long layer;
+} OverlayInfo;
+
+#if HAVE_MULTIBUF
+#include <X11/extensions/multibuf.h>
+#endif
+
+#if HAVE_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+
+static void print_mask(XVisualInfo* p) {
+ int n = 0;
+ int what = 0;
+ int print_anything = 0;
+ char buf[20];
+ char *q = buf;
+ *q = 0;
+ int b; unsigned int m; for (b=32,m=0x80000000; ; b--,m>>=1) {
+ int new_what = 0;
+ if (p->red_mask&m) new_what = 'r';
+ else if (p->green_mask&m) new_what = 'g';
+ else if (p->blue_mask&m) new_what = 'b';
+ else new_what = '?';
+ if (new_what != what) {
+ if (what && (what != '?' || print_anything)) {
+ q += sprintf(q,"%d%c", n, what);
+ print_anything = 1;
+ }
+ what = new_what;
+ n = 1;
+ } else {
+ n++;
+ }
+ if (!b) break;
+ }
+ printf("%7s", buf);
+}
+
+void list_visuals() {
+ fl_open_display();
+ XVisualInfo vTemplate;
+ int num;
+ XVisualInfo *visualList = XGetVisualInfo(fl_display,0,&vTemplate,&num);
+
+ XPixmapFormatValues *pfvlist;
+ static int numpfv;
+ pfvlist = XListPixmapFormats(fl_display, &numpfv);
+
+ OverlayInfo *overlayInfo = 0;
+ int numoverlayinfo = 0;
+ Atom overlayVisualsAtom = XInternAtom(fl_display,"SERVER_OVERLAY_VISUALS",1);
+ if (overlayVisualsAtom) {
+ unsigned long sizeData, bytesLeft;
+ Atom actualType;
+ int actualFormat;
+ if (!XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
+ overlayVisualsAtom, 0L, 10000L, False,
+ overlayVisualsAtom, &actualType, &actualFormat,
+ &sizeData, &bytesLeft,
+ (unsigned char **) &overlayInfo))
+ numoverlayinfo = int(sizeData/4);
+ }
+
+#if HAVE_MULTIBUF
+ int event_base, error_base;
+ XmbufBufferInfo *mbuf, *sbuf;
+ int nmbuf = 0, nsbuf = 0;
+ if (XmbufQueryExtension(fl_display,&event_base, &error_base)) {
+ XmbufGetScreenInfo(fl_display,RootWindow(fl_display,fl_screen),
+ &nmbuf, &mbuf, &nsbuf, &sbuf);
+ }
+#endif
+
+#if HAVE_XDBE
+ int event_base, error_base;
+ int numdouble = 0;
+ XdbeVisualInfo *dbe = 0;
+ if (XdbeQueryExtension(fl_display, &event_base, &error_base)) {
+ Drawable root = RootWindow(fl_display,fl_screen);
+ int numscreens = 1;
+ XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+ if (!a) printf("error getting double buffer visuals\n");
+ else {
+ dbe = a->visinfo;
+ numdouble = a->count;
+ }
+ }
+#endif
+
+ for (int i=0; i<num; i++) {
+ XVisualInfo *p = visualList+i;
+
+ XPixmapFormatValues *pfv;
+ for (pfv = pfvlist; ; pfv++) {
+ if (pfv >= pfvlist+numpfv) {pfv = 0; break;} // should not happen!
+ if (pfv->depth == p->depth) break;
+ }
+
+ int j = pfv ? pfv->bits_per_pixel : 0;
+ printf(" %2ld: %s %2d/%d", p->visualid, ClassNames[p->c_class],
+ p->depth, j);
+ if (j < 10) putchar(' ');
+
+ print_mask(p);
+
+ for (j=0; j<numoverlayinfo; j++) {
+ OverlayInfo *o = &overlayInfo[j];
+ if (o->overlay_visual == long(p->visualid)) {
+ printf(" overlay(");
+ if (o->transparent_type==1) printf("transparent pixel %ld, ",o->value);
+ else if (o->transparent_type==2) printf("transparent mask %ld, ",o->value);
+ else printf("opaque, ");
+ printf("layer %ld)", o->layer);
+ }
+ }
+
+#if HAVE_MULTIBUF
+ for (j=0; j<nmbuf; j++) {
+ XmbufBufferInfo *m = &mbuf[j];
+ if (m->visualid == p->visualid)
+ printf(" multibuffer(%d)", m->max_buffers);
+ }
+ for (j=0; j<nsbuf; j++) {
+ XmbufBufferInfo *m = &sbuf[j];
+ if (m->visualid == p->visualid)
+ printf(" stereo multibuffer(%d)", m->max_buffers);
+ }
+#endif
+
+#if HAVE_XDBE
+ for (j = 0; j < numdouble; j++) if (dbe[j].visual == p->visualid)
+ printf(" doublebuf(perflevel %d)",dbe[j].perflevel);
+#endif
+
+ if (p->visualid==XVisualIDFromVisual(DefaultVisual(fl_display,fl_screen)))
+ printf(" (default visual)");
+
+ putchar('\n');
+ }
+}
+
+#endif
+
+#ifndef Fl_H
+int main(int argc, char **argv) {
+ if (argc == 1);
+ else if (argc == 2 && argv[1][0]!='-') dname = argv[1];
+ else {fprintf(stderr,"usage: %s <display>\n",argv[0]); exit(1);}
+ list_visuals();
+ return 0;
+}
+#endif
+
+// end of list_visuals.C
diff --git a/test/mandelbrot.cxx b/test/mandelbrot.cxx
new file mode 100644
index 000000000..b325736b2
--- /dev/null
+++ b/test/mandelbrot.cxx
@@ -0,0 +1,200 @@
+#include "mandelbrot_ui.C"
+#include <FL/fl_draw.H>
+#include <stdio.h>
+#include <stdlib.h>
+
+Drawing_Window mbrot;
+Drawing_Window jbrot;
+
+void idle() {
+ if (!mbrot.d->idle() && !(jbrot.d && jbrot.d->idle())) Fl::set_idle(0);
+}
+
+void set_idle() {
+ Fl::set_idle(idle);
+}
+
+static void window_callback(Fl_Widget*, void*) {exit(0);}
+
+int main(int argc, char **argv) {
+ make_window(mbrot);
+ mbrot.d->X = -.75;
+ mbrot.d->scale = 2.5;
+ mbrot.update_label();
+ int i = 0;
+ if (Fl::args(argc,argv,i) < argc) Fl::fatal(Fl::help);
+ Fl::visual(FL_RGB);
+ mbrot.window->callback(window_callback);
+ mbrot.window->show(argc,argv);
+ Fl::run();
+ return 0;
+}
+
+void Drawing_Window::update_label() {
+ char buffer[128];
+ sprintf(buffer, "%+.10f", d->X); x_input->value(buffer);
+ sprintf(buffer, "%+.10f", d->Y); y_input->value(buffer);
+ sprintf(buffer, "%.2g", d->scale); w_input->value(buffer);
+}
+
+void Drawing_Area::draw() {
+ draw_box();
+ drawn = 0;
+ set_idle();
+}
+
+int Drawing_Area::idle() {
+ if (!window()->visible()) return 0;
+ if (drawn < nextline) {
+ window()->make_current();
+ int yy = drawn+y()+4;
+ if (yy >= sy && yy <= sy+sh) erase_box();
+ fl_draw_image_mono(buffer+drawn*W,x()+3,yy,W,1,1,W);
+ drawn++;
+ return 1;
+ }
+ if (nextline < H) {
+ if (!buffer) buffer = new uchar[W*H];
+ double yy = Y+(H/2-nextline)*scale/W;
+ double yi = yy; if (julia) yy = jY;
+ uchar *p = buffer+nextline*W;
+ for (int xi = 0; xi < W; xi++) {
+ double xx = X+(xi-W/2)*scale/W;
+ double wx = xx; double wy = yi;
+ if (julia) xx = jX;
+ for (int i=0; ; i++) {
+ if (i >= iterations) {*p = 0; break;}
+ double t = wx*wx - wy*wy + xx;
+ wy = 2*wx*wy + yy;
+ wx = t;
+ if (wx*wx + wy*wy > 4) {
+ wx = t = 1-double(i)/(1<<10);
+ if (t <= 0) t = 0; else for (i=brightness; i--;) t*=wx;
+ *p = 255-int(254*t);
+ break;
+ }
+ }
+ p++;
+ }
+ nextline++;
+ return nextline < H;
+ }
+ return 0;
+}
+
+void Drawing_Area::erase_box() {
+ window()->make_current();
+ fl_overlay_clear();
+}
+
+int Drawing_Area::handle(int event) {
+ static int ix, iy;
+ static int dragged;
+ static int button;
+ int x2,y2;
+ switch (event) {
+ case FL_PUSH:
+ erase_box();
+ ix = Fl::event_x(); if (ix<x()) ix=x(); if (ix>=x()+w()) ix=x()+w()-1;
+ iy = Fl::event_y(); if (iy<y()) iy=y(); if (iy>=y()+h()) iy=y()+h()-1;
+ dragged = 0;
+ button = Fl::event_button();
+ return 1;
+ case FL_DRAG:
+ dragged = 1;
+ erase_box();
+ x2 = Fl::event_x(); if (x2<x()) x2=x(); if (x2>=x()+w()) x2=x()+w()-1;
+ y2 = Fl::event_y(); if (y2<y()) y2=y(); if (y2>=y()+h()) y2=y()+h()-1;
+ if (button != 1) {ix = x2; iy = y2; return 1;}
+ if (ix < x2) {sx = ix; sw = x2-ix;} else {sx = x2; sw = ix-x2;}
+ if (iy < y2) {sy = iy; sh = y2-iy;} else {sy = y2; sh = iy-y2;}
+ window()->make_current();
+ fl_overlay_rect(sx,sy,sw,sh);
+ return 1;
+ case FL_RELEASE:
+ if (button == 1) {
+ erase_box();
+ if (dragged && sw > 3 && sh > 3) {
+ X = X + (sx+sw/2-x()-W/2)*scale/W;
+ Y = Y + (-sy-sh/2+y()+H/2)*scale/W;
+ scale = sw*scale/W;
+ } else if (!dragged) {
+ scale = 2*scale;
+ if (julia) {
+ if (scale >= 4) {
+ scale = 4;
+ X = Y = 0;
+ }
+ } else {
+ if (scale >= 2.5) {
+ scale = 2.5;
+ X = -.75;
+ Y = 0;
+ }
+ }
+ } else return 1;
+ ((Drawing_Window*)(user_data()))->update_label();
+ new_display();
+ } else if (!julia) {
+ if (!jbrot.d) {
+ make_window(jbrot);
+ jbrot.d->julia = 1;
+ jbrot.d->X = 0;
+ jbrot.d->Y = 0;
+ jbrot.d->scale = 4;
+ jbrot.update_label();
+ }
+ jbrot.d->jX = X + (ix-x()-W/2)*scale/W;
+ jbrot.d->jY = Y + (H/2-iy+y())*scale/W;
+ static char buffer[128];
+ sprintf(buffer, "Julia %.7f %.7f",jbrot.d->jX,jbrot.d->jY);
+ jbrot.window->label(buffer);
+ jbrot.window->show();
+ jbrot.d->new_display();
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void Drawing_Area::new_display() {
+ drawn = nextline = 0;
+ set_idle();
+}
+
+void Drawing_Area::resize(int X,int Y,int W,int H) {
+ if (W != w() || H != h()) {
+ this->W = W-6;
+ this->H = H-8;
+ if (buffer) {delete[] buffer; buffer = 0; new_display();}
+ }
+ Fl_Box::resize(X,Y,W,H);
+}
+
+void brightness_slider_cb(Fl_Slider* o, Drawing_Window* s) {
+ s->d->brightness = int(o->value());
+ s->d->new_display();
+}
+
+void iterations_slider_cb(Fl_Slider* o, Drawing_Window* s) {
+ s->d->iterations = 1<<int(o->value());
+ s->d->new_display();
+}
+
+void x_callback(Fl_Input* o, Drawing_Window* s) {
+ double v = atof(o->value());
+ s->d->X = v;
+ s->d->new_display();
+}
+
+void y_callback(Fl_Input* o, Drawing_Window* s) {
+ double v = atof(o->value());
+ s->d->Y = v;
+ s->d->new_display();
+}
+
+void w_callback(Fl_Input* o, Drawing_Window* s) {
+ double v = atof(o->value());
+ s->d->scale = v;
+ s->d->new_display();
+}
diff --git a/test/mandelbrot.h b/test/mandelbrot.h
new file mode 100644
index 000000000..fb1f25ddb
--- /dev/null
+++ b/test/mandelbrot.h
@@ -0,0 +1,54 @@
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+
+class Drawing_Window;
+
+class Drawing_Area : public Fl_Box {
+ void draw();
+public:
+ uchar *buffer;
+ int W,H;
+ int nextline;
+ int drawn;
+ int julia;
+ int iterations;
+ int brightness;
+ double jX, jY;
+ double X,Y,scale;
+ int sx, sy, sw, sh; // selection box
+ void erase_box();
+ int handle(int);
+ void resize(int,int,int,int);
+ void new_display();
+ enum {
+ MAX_BRIGHTNESS = 16,
+ DEFAULT_BRIGHTNESS = 16,
+ MAX_ITERATIONS = 14,
+ DEFAULT_ITERATIONS = 7
+ };
+ Drawing_Area(int x,int y,int w,int h) : Fl_Box(x,y,w,h) {
+ buffer = 0;
+ W = w-6;
+ H = h-8;
+ nextline = 0;
+ drawn = 0;
+ julia = 0;
+ X = Y = 0;
+ scale = 4.0;
+ iterations = 1<<DEFAULT_ITERATIONS;
+ brightness = DEFAULT_BRIGHTNESS;
+ }
+ int idle();
+};
+
+class Drawing_Window {
+public:
+ Drawing_Area *d;
+ Fl_Slider *gamma_slider;
+ Fl_Input *x_input, *y_input, *w_input;
+ Fl_Window *window;
+ void update_label();
+};
diff --git a/test/mandelbrot_ui.C b/test/mandelbrot_ui.C
new file mode 100644
index 000000000..4e81970ac
--- /dev/null
+++ b/test/mandelbrot_ui.C
@@ -0,0 +1,87 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "mandelbrot_ui.H"
+
+Fl_Window* make_window(Drawing_Window& s) {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(429, 510);
+ w = s.window = o;
+ {Drawing_Area* o = new Drawing_Area(10, 70, 410, 430);
+ s.d = o;
+ o->box(FL_DOWN_BOX);
+ o->color(0);
+ o->user_data((void*)(&s));
+ Fl_Group::current()->resizable(o);
+ }
+ {Fl_Input* o = new Fl_Input(20, 5, 125, 30, "x:");
+ s.x_input = o;
+ o->type(1);
+ o->box(FL_THIN_DOWN_BOX);
+ o->color(8);
+ o->color2(7);
+ o->labelfont(11);
+ o->labelsize(20);
+ o->textfont(11);
+ o->textsize(20);
+ o->callback((Fl_Callback*)x_callback, (void*)(&s));
+ o->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE);
+ }
+ {Fl_Input* o = new Fl_Input(165, 5, 125, 30, "y:");
+ s.y_input = o;
+ o->type(1);
+ o->box(FL_THIN_DOWN_BOX);
+ o->color(8);
+ o->color2(7);
+ o->labelfont(11);
+ o->labelsize(20);
+ o->textfont(11);
+ o->textsize(20);
+ o->callback((Fl_Callback*)y_callback, (void*)(&s));
+ o->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE);
+ }
+ {Fl_Input* o = new Fl_Input(315, 5, 105, 30, "w:");
+ s.w_input = o;
+ o->type(1);
+ o->box(FL_THIN_DOWN_BOX);
+ o->color(8);
+ o->color2(7);
+ o->labelfont(11);
+ o->labelsize(20);
+ o->textfont(11);
+ o->textsize(20);
+ o->callback((Fl_Callback*)w_callback, (void*)(&s));
+ o->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE);
+ }
+ {Fl_Slider* o = new Fl_Slider(70, 40, 160, 15, "brightness:");
+ o->type(1);
+ o->box(FL_THIN_DOWN_BOX);
+ o->labelsize(10);
+ o->step(1);
+ o->slider_size(0.1);
+ o->callback((Fl_Callback*)brightness_slider_cb, (void*)(&s));
+ o->align(4);
+ o->bounds(0,s.d->MAX_BRIGHTNESS);
+ o->value(s.d->DEFAULT_BRIGHTNESS);
+ o->slider(FL_UP_BOX);
+ }
+ {Fl_Box* o = new Fl_Box(230, 40, 190, 30, "left: click = zoom out, drag = zoom in\nright click: Julia set");
+ o->labelsize(10);
+ o->align(24);
+ o->deactivate();
+ }
+ {Fl_Slider* o = new Fl_Slider(70, 55, 160, 15, "iterations:");
+ o->type(1);
+ o->box(FL_THIN_DOWN_BOX);
+ o->labelsize(10);
+ o->step(1);
+ o->slider_size(0.1);
+ o->callback((Fl_Callback*)iterations_slider_cb, (void*)(&s));
+ o->align(4);
+ o->bounds(1,s.d->MAX_ITERATIONS);
+ o->value(s.d->DEFAULT_ITERATIONS);
+ o->slider(FL_UP_BOX);
+ }
+ w->end();
+ o->size_range(220,220);
+ }
+ return w;
+}
diff --git a/test/mandelbrot_ui.H b/test/mandelbrot_ui.H
new file mode 100644
index 000000000..7cac8ea28
--- /dev/null
+++ b/test/mandelbrot_ui.H
@@ -0,0 +1,13 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "mandelbrot.H"
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Window.H>
+extern void brightness_slider_cb(Fl_Slider*, Drawing_Window*);
+extern void iterations_slider_cb(Fl_Slider*, Drawing_Window*);
+extern void w_callback(Fl_Input*, Drawing_Window*);
+extern void x_callback(Fl_Input*, Drawing_Window*);
+extern void y_callback(Fl_Input*, Drawing_Window*);
+Fl_Window* make_window(Drawing_Window& s);
diff --git a/test/mandelbrot_ui.fl b/test/mandelbrot_ui.fl
new file mode 100644
index 000000000..2c864aaad
--- /dev/null
+++ b/test/mandelbrot_ui.fl
@@ -0,0 +1,63 @@
+# data file for FL User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 10
+snap 3
+Function {make_window(Drawing_Window& s)} {open
+} {
+ Fl_Window {s.window} {open
+ xywh {92 109 429 510}
+ code0 {o->size_range(220,220);}
+ } {
+ Fl_Box {s.d} {
+ user_data {&s} user_data_type {Drawing_Window*} open
+ xywh {10 70 410 430} box 3 color {0 47} resizable
+ code0 {\#include "mandelbrot.H"}
+ class Drawing_Area
+ }
+ Fl_Input {s.x_input} {
+ label {x:}
+ user_data {&s} user_data_type {Drawing_Window*}
+ callback x_callback open
+ xywh {20 5 125 30} type 1 box 7 color {8 7} labelfont 11 labelsize 20 textfont 11 textsize 20
+ code0 {o->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE);}
+ }
+ Fl_Input {s.y_input} {
+ label {y:}
+ user_data {&s} user_data_type {Drawing_Window*}
+ callback y_callback open
+ xywh {165 5 125 30} type 1 box 7 color {8 7} labelfont 11 labelsize 20 textfont 11 textsize 20
+ code0 {o->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE);}
+ }
+ Fl_Input {s.w_input} {
+ label {w:}
+ user_data {&s} user_data_type {Drawing_Window*}
+ callback w_callback open
+ xywh {315 5 105 30} type 1 box 7 color {8 7} labelfont 11 labelsize 20 textfont 11 textsize 20
+ code0 {o->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE);}
+ }
+ Fl_Slider {} {
+ label {brightness:}
+ user_data {&s} user_data_type {Drawing_Window*}
+ callback brightness_slider_cb open
+ xywh {70 40 160 15} type 1 box 7 labelsize 10 align 4 step 1 slider_size 0.1
+ code0 {o->bounds(0,s.d->MAX_BRIGHTNESS);}
+ code2 {o->value(s.d->DEFAULT_BRIGHTNESS);}
+ code3 {o->slider(FL_UP_BOX);}
+ }
+ Fl_Box {} {
+ label {left: click = zoom out, drag = zoom in
+right click: Julia set} open
+ xywh {230 40 190 30} labelsize 10 align 24 deactivate
+ }
+ Fl_Slider {} {
+ label {iterations:}
+ user_data {&s} user_data_type {Drawing_Window*}
+ callback iterations_slider_cb open selected
+ xywh {70 55 160 15} type 1 box 7 labelsize 10 align 4 step 1 slider_size 0.1
+ code0 {o->bounds(1,s.d->MAX_ITERATIONS);}
+ code2 {o->value(s.d->DEFAULT_ITERATIONS);}
+ code3 {o->slider(FL_UP_BOX);}
+ }
+ }
+}
diff --git a/test/menubar.cxx b/test/menubar.cxx
new file mode 100644
index 000000000..f1a8945e9
--- /dev/null
+++ b/test/menubar.cxx
@@ -0,0 +1,182 @@
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Choice.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <FL/fl_draw.H>
+
+void test_cb(Fl_Widget* w, void*) {
+ Fl_Menu_* mw = (Fl_Menu_*)w;
+ const Fl_Menu_Item* m = mw->mvalue();
+ if (!m)
+ printf("NULL\n");
+ else if (m->shortcut())
+ printf("%s - %s\n", m->label(), fl_shortcut_label(m->shortcut()));
+ else
+ printf("%s\n", m->label());
+}
+
+void quit_cb(Fl_Widget*, void*) {exit(0);}
+
+Fl_Menu_Item hugemenu[100];
+
+Fl_Menu_Item menutable[] = {
+ {"foo",0,0,0,FL_MENU_INACTIVE},
+ {"&File",0,0,0,FL_SUBMENU},
+ {"&Open", FL_ALT+'o', 0, 0, FL_MENU_INACTIVE},
+ {"&Close", 0, 0},
+ {"&Quit", FL_ALT+'q', quit_cb, 0, FL_MENU_DIVIDER},
+ {"shortcut",'a'},
+ {"shortcut",FL_SHIFT+'a'},
+ {"shortcut",FL_CTRL+'a'},
+ {"shortcut",FL_CTRL+FL_SHIFT+'a'},
+ {"shortcut",FL_ALT+'a'},
+ {"shortcut",FL_ALT+FL_SHIFT+'a'},
+ {"shortcut",FL_ALT+FL_CTRL+'a'},
+ {"shortcut",FL_ALT+FL_SHIFT+FL_CTRL+'a', 0,0, FL_MENU_DIVIDER},
+ {"shortcut",'\r'/*FL_Enter*/},
+ {"shortcut",FL_CTRL+FL_Enter, 0,0, FL_MENU_DIVIDER},
+ {"shortcut",FL_F+1},
+ {"shortcut",FL_SHIFT+FL_F+1},
+ {"shortcut",FL_CTRL+FL_F+1},
+ {"shortcut",FL_SHIFT+FL_CTRL+FL_F+1},
+ {"shortcut",FL_ALT+FL_F+1},
+ {"shortcut",FL_ALT+FL_SHIFT+FL_F+1},
+ {"shortcut",FL_ALT+FL_CTRL+FL_F+1},
+ {"shortcut",FL_ALT+FL_SHIFT+FL_CTRL+FL_F+1, 0,0, FL_MENU_DIVIDER},
+ {"&Submenus", FL_ALT+'S', 0, (void*)"Submenu1", FL_SUBMENU},
+ {"A very long menu item"},
+ {"&submenu",FL_CTRL+'S', 0, (void*)"submenu2", FL_SUBMENU},
+ {"item 1"},
+ {"item 2"},
+ {"item 3"},
+ {"item 4"},
+ {0},
+ {"after submenu"},
+ {0},
+ {0},
+ {"&Edit",0,0,0,FL_SUBMENU},
+ {"Undo", FL_ALT+'z', 0},
+ {"Redo", FL_ALT+'r', 0, 0, FL_MENU_DIVIDER},
+ {"Cut", FL_ALT+'x', 0},
+ {"Copy", FL_ALT+'c', 0},
+ {"Paste", FL_ALT+'v', 0},
+ {"Inactive",FL_ALT+'d', 0, 0, FL_MENU_INACTIVE},
+ {"Clear", 0, 0, 0, FL_MENU_DIVIDER},
+ {"Invisible",FL_ALT+'e', 0, 0, FL_MENU_INVISIBLE},
+ {"Preferences",0, 0},
+ {"Size", 0, 0},
+ {0},
+ {"&Checkbox",0,0,0,FL_SUBMENU},
+ {"&Alpha", 0, 0, (void *)1, FL_MENU_TOGGLE},
+ {"&Beta", 0, 0, (void *)2, FL_MENU_TOGGLE},
+ {"&Gamma", 0, 0, (void *)3, FL_MENU_TOGGLE},
+ {"&Delta", 0, 0, (void *)4, FL_MENU_TOGGLE|FL_MENU_VALUE},
+ {"&Epsilon",0, 0, (void *)5, FL_MENU_TOGGLE},
+ {"&Pi", 0, 0, (void *)6, FL_MENU_TOGGLE},
+ {"&Mu", 0, 0, (void *)7, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
+ {"Red", 0, 0, (void *)1, FL_MENU_TOGGLE, 0, 0, 0, 1},
+ {"Black", 0, 0, (void *)1, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
+ {"00", 0, 0, (void *)1, FL_MENU_TOGGLE},
+ {"000", 0, 0, (void *)1, FL_MENU_TOGGLE},
+ {0},
+ {"&Radio",0,0,0,FL_SUBMENU},
+ {"&Alpha", 0, 0, (void *)1, FL_MENU_RADIO},
+ {"&Beta", 0, 0, (void *)2, FL_MENU_RADIO},
+ {"&Gamma", 0, 0, (void *)3, FL_MENU_RADIO},
+ {"&Delta", 0, 0, (void *)4, FL_MENU_RADIO|FL_MENU_VALUE},
+ {"&Epsilon",0, 0, (void *)5, FL_MENU_RADIO},
+ {"&Pi", 0, 0, (void *)6, FL_MENU_RADIO},
+ {"&Mu", 0, 0, (void *)7, FL_MENU_RADIO|FL_MENU_DIVIDER},
+ {"Red", 0, 0, (void *)1, FL_MENU_RADIO},
+ {"Black", 0, 0, (void *)1, FL_MENU_RADIO|FL_MENU_DIVIDER},
+ {"00", 0, 0, (void *)1, FL_MENU_RADIO},
+ {"000", 0, 0, (void *)1, FL_MENU_RADIO},
+ {0},
+ {"&Font",0,0,0,FL_SUBMENU /*, 0, FL_BOLD, 20*/},
+ {"Normal", 0, 0, 0, 0, 0, 0, 14},
+ {"Bold", 0, 0, 0, 0, 0, FL_BOLD, 14},
+ {"Italic", 0, 0, 0, 0, 0, FL_ITALIC, 14},
+ {"BoldItalic",0,0,0, 0, 0, FL_BOLD+FL_ITALIC, 14},
+ {"Small", 0, 0, 0, 0, 0, FL_BOLD+FL_ITALIC, 10},
+ {"Emboss", 0, 0, 0, 0, FL_EMBOSSED_LABEL},
+ {"Engrave", 0, 0, 0, 0, FL_ENGRAVED_LABEL},
+ {"Shadow", 0, 0, 0, 0, FL_SHADOW_LABEL},
+ {"@->", 0, 0, 0, 0, FL_SYMBOL_LABEL},
+ {0},
+ {"E&mpty",0,0,0,FL_SUBMENU},
+ {0},
+ {"&Inactive", 0, 0, 0, FL_MENU_INACTIVE|FL_SUBMENU},
+ {"A very long menu item"},
+ {"A very long menu item"},
+ {0},
+ {"Invisible",0, 0, 0, FL_MENU_INVISIBLE|FL_SUBMENU},
+ {"A very long menu item"},
+ {"A very long menu item"},
+ {0},
+ {"&Huge", 0, 0, (void*)hugemenu, FL_SUBMENU_POINTER},
+ {"button",0, 0, 0, FL_MENU_TOGGLE},
+ {0}
+};
+
+Fl_Menu_Item pulldown[] = {
+ {"Red", FL_ALT+'r'},
+ {"Green", FL_ALT+'g'},
+ {"Blue", FL_ALT+'b'},
+ {"Strange", FL_ALT+'s'},
+ {"&Charm", FL_ALT+'c'},
+ {"Truth", FL_ALT+'t'},
+ {"Beauty", FL_ALT+'b'},
+ {0}
+};
+
+#define WIDTH 600
+
+Fl_Menu_* menus[4];
+
+// turn MicroSoft style on/off
+void button_cb(Fl_Widget* w, void*) {
+ if (((Fl_Button*)w)->value()) {
+ Fl::set_color(FL_SELECTION_COLOR, 0, 36, 127);
+ Fl_Menu_::default_font(FL_HELVETICA);
+ } else {
+ Fl::set_color(FL_SELECTION_COLOR, 170, 170, 170);
+ Fl_Menu_::default_font(FL_HELVETICA_BOLD_ITALIC);
+ }
+ menus[0]->parent()->redraw();
+}
+
+int main(int argc, char **argv) {
+ for (int i=0; i<99; i++) {
+ char buf[100];
+ sprintf(buf,"item %d",i);
+ hugemenu[i].text = strdup(buf);
+ }
+ Fl_Window window(WIDTH,400);
+ Fl_Menu_Bar menubar(0,0,WIDTH,30); menubar.menu(menutable);
+ menubar.callback(test_cb);
+ menus[0] = &menubar;
+ Fl_Menu_Button mb1(100,100,120,25,"&menubutton"); mb1.menu(pulldown);
+ mb1.callback(test_cb);
+ menus[1] = &mb1;
+ Fl_Choice ch(300,100,80,25,"&choice:"); ch.menu(pulldown);
+ ch.callback(test_cb);
+ menus[2] = &ch;
+ Fl_Menu_Button mb(0,0,WIDTH,400,"&popup");
+ mb.type(Fl_Menu_Button::POPUP3);
+ mb.menu(menutable);
+ mb.callback(test_cb);
+ menus[3] = &mb;
+ Fl_Box b(200,200,200,100,"Press right button\nfor a pop-up menu");
+ Fl_Toggle_Button t(250,50,150,25,"MicroSoft Style");
+ t.callback(button_cb);
+ window.resizable(&mb);
+ window.end();
+ window.show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/message.cxx b/test/message.cxx
new file mode 100644
index 000000000..1f339320d
--- /dev/null
+++ b/test/message.cxx
@@ -0,0 +1,18 @@
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_ask.H>
+#include <stdio.h>
+
+int main(int, char **) {
+ fl_message("Spelling check sucessfull.");
+ fl_alert("Quantum fluctuations in the space-time continuim detected.");
+ printf("fl_ask returned %d\n",
+ fl_ask("Do you really want to?"));
+ printf("fl_choice returned %d\n",
+ fl_choice("Choose one of the following:","choice0","choice1","choice2"));
+ printf("fl_show_input returned \"%s\"\n",
+ fl_show_input("Please enter a string:", "this is the default value"));
+ printf("fl_password returned \"%s\"\n",
+ fl_password("Enter your password:"));
+ return 0;
+}
diff --git a/test/minimum.cxx b/test/minimum.cxx
new file mode 100644
index 000000000..f946639a6
--- /dev/null
+++ b/test/minimum.cxx
@@ -0,0 +1,49 @@
+// This is a test of the minimal update code. The right slider has a
+// label that extends outside it's border, and the minimal update
+// assummes this does not happen. Thus there is *supposed* to be
+// display errors when you move the right-most or any other slider.
+// If you *don't* see these errors, then the minimal update is
+// broken!!!
+
+// I cannot emphasize how important it is to test this and make sure
+// any changes have not broken the minimal update. These sort of bugs
+// are extremely hard to fix and must be detected right away!
+
+// The reason it is important to fix this is that otherwise you will
+// swiftly end up with a toolkit that thinks it has to draw the window
+// 20 times each time the display changes. I don't care how fast the
+// machine is, this is an insane waste of resources, and should be
+// stopped!
+
+#include <stdlib.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Return_Button.H>
+
+int main(int argc, char **argv) {
+ Fl_Window *window = new Fl_Window(400,320,argv[0]);
+ window->resizable(*(new Fl_Box(FL_ENGRAVED_FRAME,10,10,300,300,
+"MINIMUM UPDATE TEST\n"
+"\n"
+"The slider on the right purposely\n"
+"draws outside it's boundaries.\n"
+"Moving it should leave old copies\n"
+"of the label. These copies should\n"
+"*not* be erased by any actions\n"
+"other than hiding and showing\n"
+"of that portion of the window\n"
+"or changing the button that\n"
+"intesects them.")));
+
+ Fl_Slider *s;
+ s = new Fl_Slider(320,10,20,300,"Too_Big_Label");
+ s->align(0);
+
+ new Fl_Button(20,270,100,30,"Button");
+ new Fl_Return_Button(200,270,100,30,"Button");
+
+ window->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/navigation.cxx b/test/navigation.cxx
new file mode 100644
index 000000000..e6477852c
--- /dev/null
+++ b/test/navigation.cxx
@@ -0,0 +1,42 @@
+/* Silly test of navigation keys.
+ This is not a recommended method of laying out your panels!
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+
+#define WIDTH 600
+#define HEIGHT 300
+#define GRID 25
+
+int main(int argc, char **argv) {
+ if (argc > 1) srand(atoi(argv[1]));
+ Fl_Window window(WIDTH,HEIGHT,argv[0]);
+ window.end(); // don't auto-add children
+ for (int i = 0; i<10000; i++) {
+ // make up a random size of widget:
+ int x = rand()%(WIDTH/GRID+1) * GRID;
+ int y = rand()%(HEIGHT/GRID+1) * GRID;
+ int w = rand()%(WIDTH/GRID+1) * GRID;
+ if (w < x) {w = x-w; x-=w;} else {w = w-x;}
+ int h = rand()%(HEIGHT/GRID+1) * GRID;
+ if (h < y) {h = y-h; y-=h;} else {h = h-y;}
+ if (w < GRID || h < GRID || w < h) continue;
+ // find where to insert it and see if it intersects something:
+ Fl_Widget *i = 0;
+ int n; for (n=0; n < window.children(); n++) {
+ Fl_Widget *o = window.child(n);
+ if (x<o->x()+o->w() && x+w>o->x() &&
+ y<o->y()+o->h() && y+h>o->y()) break;
+ if (!i && (y < o->y() || y == o->y() && x < o->x())) i = o;
+ }
+ // skip if intersection:
+ if (n < window.children()) continue;
+ window.insert(*(new Fl_Input(x,y,w,h)),i);
+ }
+ window.show();
+ return Fl::run();
+}
diff --git a/test/output.cxx b/test/output.cxx
new file mode 100644
index 000000000..5158f6311
--- /dev/null
+++ b/test/output.cxx
@@ -0,0 +1,74 @@
+// Test of Fl_Output and Fl_Multiline_Output
+
+#include <FL/Fl.H>
+#include <FL/Fl_Value_Input.H> // necessary for bug in mingw32?
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Hor_Value_Slider.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Multiline_Output.H>
+
+Fl_Output *text;
+Fl_Multiline_Output *text2;
+Fl_Input *input;
+Fl_Value_Slider *fonts;
+Fl_Value_Slider *sizes;
+Fl_Window *window;
+
+void font_cb(Fl_Widget *,void *) {
+ text->textfont(int(fonts->value()));
+ text->redraw();
+ text2->textfont(int(fonts->value()));
+ text2->redraw();
+}
+
+void size_cb(Fl_Widget *,void *) {
+ text->textsize(int(sizes->value()));
+ text->redraw();
+ text2->textsize(int(sizes->value()));
+ text2->redraw();
+}
+
+void input_cb(Fl_Widget *,void *) {
+ text->value(input->value());
+ text2->value(input->value());
+}
+
+int main(int argc, char **argv) {
+ window = new Fl_Window(400,400);
+
+ input = new Fl_Input(50,0,350,25);
+ input->static_value("The quick brown fox\njumped over\nthe lazy dog.");
+ input->when(FL_WHEN_CHANGED);
+ input->callback(input_cb);
+
+ sizes = new Fl_Hor_Value_Slider(50,25,350,25,"Size");
+ sizes->align(FL_ALIGN_LEFT);
+ sizes->bounds(1,64);
+ sizes->step(1);
+ sizes->value(14);
+ sizes->callback(size_cb);
+
+ fonts = new Fl_Hor_Value_Slider(50,50,350,25,"Font");
+ fonts->align(FL_ALIGN_LEFT);
+ fonts->bounds(0,15);
+ fonts->step(1);
+ fonts->value(0);
+ fonts->callback(font_cb);
+
+ text2 = new Fl_Multiline_Output(100,150,200,100,"Fl_Multiline_Output");
+ text2->value(input->value());
+ text2->align(FL_ALIGN_BOTTOM);
+ window->resizable(text2);
+
+ text = new Fl_Output(100,280,200,30,"Fl_Output");
+ text->value(input->value());
+ text->align(FL_ALIGN_BOTTOM);
+
+ window->forms_end();
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/overlay.cxx b/test/overlay.cxx
new file mode 100644
index 000000000..0fd52315e
--- /dev/null
+++ b/test/overlay.cxx
@@ -0,0 +1,57 @@
+/* Test the Fl_Overlay_Window */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Overlay_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/fl_draw.H>
+
+int width=10,height=10;
+
+class overlay : public Fl_Overlay_Window {
+public:
+ overlay(int w,int h) : Fl_Overlay_Window(w,h) {}
+ void draw_overlay();
+};
+
+void overlay::draw_overlay() {
+ fl_color(FL_RED); fl_rect((w()-width)/2,(h()-height)/2,width,height);
+}
+
+overlay *ovl;
+
+void bcb1(Fl_Widget *,void *) {width+=20; ovl->redraw_overlay();}
+void bcb2(Fl_Widget *,void *) {width-=20; ovl->redraw_overlay();}
+void bcb3(Fl_Widget *,void *) {height+=20; ovl->redraw_overlay();}
+void bcb4(Fl_Widget *,void *) {height-=20; ovl->redraw_overlay();}
+
+int arg(int, char **argv, int& i) {
+ Fl_Color n = (Fl_Color)atoi(argv[i]);
+ if (n<=0) return 0;
+ i++;
+ uchar r,g,b;
+ Fl::get_color(n,r,g,b);
+ Fl::set_color(FL_RED,r,g,b);
+ return i;
+}
+
+int main(int argc, char **argv) {
+ int i=0; Fl::args(argc,argv,i,arg);
+ ovl = new overlay(400,400);
+ Fl_Button *b;
+ b = new Fl_Button(50,50,100,100,"wider\n(a)");
+ b->callback(bcb1); b->shortcut('a');
+ b = new Fl_Button(250,50,100,100,"narrower\n(b)");
+ b->callback(bcb2); b->shortcut('b');
+ b = new Fl_Button(50,250,100,100,"taller\n(c)");
+ b->callback(bcb3); b->shortcut('c');
+ b = new Fl_Button(250,250,100,100,"shorter\n(d)");
+ b->callback(bcb4); b->shortcut('d');
+ ovl->resizable(ovl);
+ ovl->end();
+ ovl->show(argc,argv);
+ ovl->redraw_overlay();
+ return Fl::run();
+}
diff --git a/test/pack.cxx b/test/pack.cxx
new file mode 100644
index 000000000..72c715a04
--- /dev/null
+++ b/test/pack.cxx
@@ -0,0 +1,89 @@
+// Rather crude test of the Fl_Pack object.
+// Changing the type() of an Fl_Pack after it is displayed is not supported
+// so I have to do a lot of resizing of things before that.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/Fl_Value_Slider.H>
+#include <FL/Fl_Pack.H>
+
+Fl_Pack *pack;
+Fl_Scroll *scroll;
+
+void type_cb(Fl_Light_Button*, long v) {
+ for (int i = 0; i < pack->children(); i++) {
+ Fl_Widget* o = pack->child(i);
+ o->resize(0,0,25,25);
+ }
+ pack->resize(scroll->x(),scroll->y(),scroll->w(),scroll->h());
+ pack->parent()->redraw();
+ pack->type(uchar(v));
+ pack->redraw();
+}
+
+void spacing_cb(Fl_Value_Slider*o, long) {
+ pack->spacing(int(o->value()));
+ scroll->redraw();
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(365, 525);
+ w = o;
+ scroll = new Fl_Scroll(10,10,345,285);
+ {Fl_Pack* o = new Fl_Pack(10, 10, 345, 285);
+ pack = o;
+ o->box(FL_DOWN_FRAME);
+ //o->box(FL_ENGRAVED_FRAME);
+ new Fl_Button(35, 35, 25, 25, "b1");
+ new Fl_Button(45, 45, 25, 25, "b2");
+ new Fl_Button(55, 55, 25, 25, "b3");
+ new Fl_Button(65, 65, 25, 25, "b4");
+ new Fl_Button(75, 75, 25, 25, "b5");
+ new Fl_Button(85, 85, 25, 25, "b6");
+ new Fl_Button(95, 95, 25, 25, "b7");
+ new Fl_Button(105, 105, 25, 25, "b8");
+ new Fl_Button(115, 115, 25, 25, "b9");
+ new Fl_Button(125, 125, 25, 25, "b10");
+ new Fl_Button(135, 135, 25, 25, "b11");
+ new Fl_Button(145, 145, 25, 25, "b12");
+ new Fl_Button(155, 155, 25, 25, "b13");
+ new Fl_Button(165, 165, 25, 25, "b14");
+ new Fl_Button(175, 175, 25, 25, "b15");
+ new Fl_Button(185, 185, 25, 25, "b16");
+ new Fl_Button(195, 195, 25, 25, "b17");
+ new Fl_Button(205, 205, 25, 25, "b18");
+ new Fl_Button(215, 215, 25, 25, "b19");
+ new Fl_Button(225, 225, 25, 25, "b20");
+ new Fl_Button(235, 235, 25, 25, "b21");
+ new Fl_Button(245, 245, 25, 25, "b22");
+ new Fl_Button(255, 255, 25, 25, "b23");
+ new Fl_Button(265, 265, 25, 25, "b24");
+ o->end();
+ w->resizable(o);
+ }
+ scroll->end();
+ {Fl_Light_Button* o = new Fl_Light_Button(10, 325, 175, 25, "HORIZONTAL");
+ o->type(FL_RADIO_BUTTON);
+ o->callback((Fl_Callback*)type_cb, (void*)(Fl_Pack::HORIZONTAL));
+ }
+ {Fl_Light_Button* o = new Fl_Light_Button(10, 350, 175, 25, "VERTICAL");
+ o->type(FL_RADIO_BUTTON);
+ o->value(1);
+ o->callback((Fl_Callback*)type_cb, (void*)(Fl_Pack::VERTICAL));
+ }
+ {Fl_Value_Slider* o = new Fl_Value_Slider(50,375, 295,25,"spacing:");
+ o->align(FL_ALIGN_LEFT);
+ o->type(FL_HORIZONTAL);
+ o->range(0,30);
+ o->step(1);
+ o->callback((Fl_Callback*)spacing_cb);
+ }
+ w->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/pixmap.cxx b/test/pixmap.cxx
new file mode 100644
index 000000000..d0ced9c4f
--- /dev/null
+++ b/test/pixmap.cxx
@@ -0,0 +1,64 @@
+// test how pixmap label type draws
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Pixmap.H>
+#include <stdio.h>
+
+#include "porsche.xpm"
+
+#include <FL/Fl_Toggle_Button.H>
+
+Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb;
+Fl_Button *b;
+Fl_Window *w;
+
+void button_cb(Fl_Widget *,void *) {
+ int i = 0;
+ if (leftb->value()) i |= FL_ALIGN_LEFT;
+ if (rightb->value()) i |= FL_ALIGN_RIGHT;
+ if (topb->value()) i |= FL_ALIGN_TOP;
+ if (bottomb->value()) i |= FL_ALIGN_BOTTOM;
+ if (insideb->value()) i |= FL_ALIGN_INSIDE;
+ b->align(i);
+ w->redraw();
+}
+
+int dvisual = 0;
+int arg(int, char **argv, int &i) {
+ if (argv[i][1] == '8') {dvisual = 1; i++; return 1;}
+ return 0;
+}
+
+#include <FL/Fl_Multi_Label.H>
+
+Fl_Multi_Label multi = {
+ 0, "This is the text", 0, FL_NORMAL_LABEL
+};
+
+int main(int argc, char **argv) {
+ int i = 1;
+ if (Fl::args(argc,argv,i,arg) < argc)
+ Fl::fatal(" -8 # : use default visual\n%s\n",Fl::help);
+
+ Fl_Window window(400,400); ::w = &window;
+ Fl_Button b(140,160,120,120,0); ::b = &b;
+ (new Fl_Pixmap(porsche_xpm))->label(&b);
+ multi.labela = b.label(); multi.typea = b.labeltype(); multi.label(&b);
+ leftb = new Fl_Toggle_Button(50,75,50,25,"left");
+ leftb->callback(button_cb);
+ rightb = new Fl_Toggle_Button(100,75,50,25,"right");
+ rightb->callback(button_cb);
+ topb = new Fl_Toggle_Button(150,75,50,25,"top");
+ topb->callback(button_cb);
+ bottomb = new Fl_Toggle_Button(200,75,50,25,"bottom");
+ bottomb->callback(button_cb);
+ insideb = new Fl_Toggle_Button(250,75,50,25,"inside");
+ insideb->callback(button_cb);
+ if (!dvisual) Fl::visual(FL_RGB);
+ window.resizable(window);
+ window.end();
+ window.show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/pixmap_browser.cxx b/test/pixmap_browser.cxx
new file mode 100644
index 000000000..ae5e6345d
--- /dev/null
+++ b/test/pixmap_browser.cxx
@@ -0,0 +1,141 @@
+// More complex and hacked pixmap demo.
+
+// On purpose, I do NOT provide a fltk method to turn a file
+// into a pixmap. This program uses a rather simplistic one.
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Pixmap.H>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <FL/fl_file_chooser.H>
+#include <FL/fl_message.H>
+
+Fl_Box *b;
+Fl_Window *w;
+
+char **data;
+int sizeofdata;
+int numlines;
+
+static int hexdigit(int x) {
+ if (isdigit(x)) return x-'0';
+ if (isupper(x)) return x-'A'+10;
+ if (islower(x)) return x-'a'+10;
+ return 20;
+}
+
+int load_file(const char *name) {
+ FILE *f = fopen(name,"r");
+ if (!f) {
+ fl_show_message("Can't open",name,strerror(errno));
+ return 0;
+ }
+ if (data) {
+ for (int i=numlines; i--;) delete[] data[i];
+ }
+ char buffer[1024];
+ int i = 0;
+ while (fgets(buffer,1024,f)) {
+ if (buffer[0] != '\"') continue;
+ char *p = buffer;
+ char *q = buffer+1;
+ while (*q != '\"') {
+ if (*q == '\\') switch (*++q) {
+ case '\n':
+ fgets(q,(buffer+1024)-q,f); break;
+ case 0:
+ break;
+ case 'x': {
+ q++;
+ int n = 0;
+ for (int x = 0; x < 3; x++) {
+ int d = hexdigit(*q);
+ if (d > 15) break;
+ n = (n<<4)+d;
+ q++;
+ }
+ *p++ = n;
+ } break;
+ default: {
+ int c = *q++;
+ if (c>='0' && c<='7') {
+ c -= '0';
+ for (int x=0; x<2; x++) {
+ int d = hexdigit(*q);
+ if (d>7) break;
+ c = (c<<3)+d;
+ q++;
+ }
+ }
+ *p++ = c;
+ } break;
+ } else {
+ *p++ = *q++;
+ }
+ }
+ *p++ = 0;
+ if (i >= sizeofdata) {
+ sizeofdata = 2*sizeofdata+100;
+ char **newdata = new char *[sizeofdata];
+ for (int j=0; j<i; j++) newdata[j] = data[j];
+ delete[] data;
+ data = newdata;
+ }
+ data[i] = new char[p-buffer];
+ memcpy(data[i],buffer,p-buffer);
+ i++;
+ }
+ numlines = i;
+ fclose(f);
+ return i;
+}
+
+Fl_Pixmap *pixmap;
+void newpixmap() {
+ delete pixmap;
+ pixmap = new Fl_Pixmap(data);
+ pixmap->label(b);
+ w->redraw();
+}
+
+static char name[1024];
+
+void file_cb(const char *n) {
+ if (!strcmp(name,n)) return;
+ if (!load_file(n)) return;
+ strcpy(name,n);
+ w->label(name);
+ newpixmap();
+}
+
+void button_cb(Fl_Widget *,void *) {
+ fl_file_chooser_callback(file_cb);
+ fl_file_chooser("XPM file","*.xpm",name);
+ fl_file_chooser_callback(0);
+}
+
+int dvisual = 0;
+int arg(int, char **argv, int &i) {
+ if (argv[i][1] == '8') {dvisual = 1; i++; return 1;}
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int i = 1;
+ if (Fl::args(argc,argv,i,arg) < argc)
+ Fl::fatal(" -8 # : use default visual\n%s\n",Fl::help);
+
+ Fl_Window window(400,400); ::w = &window;
+ Fl_Box b(0,0,window.w(),window.h()); ::b = &b;
+ Fl_Button button(5,5,100,35,"load");
+ button.callback(button_cb);
+ if (!dvisual) Fl::visual(FL_RGB);
+ window.resizable(window);
+ window.show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/porsche.xpm b/test/porsche.xpm
new file mode 100644
index 000000000..1dc60e9b6
--- /dev/null
+++ b/test/porsche.xpm
@@ -0,0 +1,71 @@
+/* XPM */
+static char * porsche_xpm[] = {
+"64 64 4 1",
+" c #background",
+". c #000000000000",
+"X c #ffd100",
+"o c #FFFF00000000",
+" ",
+" .......................... ",
+" ..................................... ",
+" ............XXXXXXXXXXXXXXXXXXXXXXXX............ ",
+" ......XXXXXXX...XX...XXXXXXXX...XXXXXXXXXX...... ",
+" ..XXXXXXXXXX..X..XX..XXXX.XXXX..XXXXXXXXXXXXXX.. ",
+" ..XXXXXXXXXX..X..XX..XXX..XXXX..X...XXXXXXXXXX.. ",
+" ..XXXXXXXXXX..XXXXX..XX.....XX..XX.XXXXXXXXXXX.. ",
+" ..XXXXXXXXX.....XXX..XXX..XXXX..X.XXXXXXXXXXXX.. ",
+" ..XXXXXXXXXX..XXXXX..XXX..XXXX....XXXXXXXXXXXX.. ",
+" ..XXXXXXXXXX..XXXXX..XXX..XXXX..X..XXXXXXXXXXX.. ",
+" ..XXXXXXXXXX..XXXXX..XXX..X.XX..XX..XXXXXXXXXX.. ",
+" ..XXXXXXXXX....XXX....XXX..XX....XX..XXXXXXXXX.. ",
+" ..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.. ",
+" ..XXXXXXXXX..........................XXXXXXXXX.. ",
+" ..XXX.......XXXXXXXXXXX...................XXXX.. ",
+" ......XX.XXX.XXX..XXXXX......................... ",
+" ..XXXXX.XXX.XXX.XXXX.XX......................... ",
+" ..XXXX.XXX.XX.......XXX......................... ",
+" ..XXXX.......XXXXXX..XX..ooooooooooooooooooooo.. ",
+" ..X.....XXXXXXXXXXXXXXX..ooooooooooooooooooooo.. ",
+" ..X...XXXXXXXXXXXXXXXXX..ooooooooooooooooooooo.. ",
+" ..X..XXXXXXX.XX.XXXXXXX..ooooooooooooooooooooo.. ",
+" ..XXXXX.XXX.XX.XXXXXXXX..ooooooooooooooooooooo.. ",
+" ..XXXX.XXX.XX.XX................................ ",
+" ..XXXX.X.........X....X.X.X..................... ",
+" ..XXXX...XXXXXXX.X..X...X.X.X.X................. ",
+" ..X....XXXXXXXXXX.X...X.X.X..................... ",
+" ..X...XXXXXXXXXX.XXXXXXXXXXXXXX................. ",
+" ..X..XXXXXX.XX.X.XXX...XXXXXXXX................. ",
+" ..XXXXX.XX.XX.XX.XX.....XXXXXXX.oooooooooooooo.. ",
+" ..XXXX.XX.XX.XX..XX.X...XXXXX.X.oooooooooooooo.. ",
+" ..XXXX.X.......X.XXXX...XXXX..X.oooooooooooooo.. ",
+" ..X......XXXXXX..XXXX...XXXX..X.oooooooooooooo.. ",
+" ..X...XXXXXXXXXX.XXX.....XXX.XX.oooooooooooooo.. ",
+" ..X..XXXXXXXXXXX.X...........XX.oooooooooooooo.. ",
+" .................X.X.........XX................. ",
+" .................X.X.XXXX....XX.XXXXXXXXXXXXXX.. ",
+" .................XXX.XXXXX.X.XX.XXX.XX.XXXXXXX.. ",
+" ................XXXX.XXX..X..X.XX.XX.XXX.XXX.. ",
+" ................XXXXXXXX.XX.XX.X.XX.XXX.XXXX.. ",
+" .................XXXXXX.XX.XX.X..........XXX.. ",
+" ..oooooooooooooo.XXXXXXXXXX....XXXXXXXX..X.. ",
+" ..ooooooooooooooo.XXXXXXXX....XXXXXXXXXXXX.. ",
+" ..ooooooooooooooo........XXXXXXX.XX.XXXX.. ",
+" ..oooooooooooooooooo..XXXXX.XXX.XX.XX.XX.. ",
+" ..ooooooooooooooooo..XXXX.XXX.XX.XX.XX.. ",
+" ..ooooooooooooooooo..XXX.XX........XXX.. ",
+" ....................XXX....XXXXXX..X.. ",
+" ...................XX...XXXXXXXXXXX. ",
+" ...................X...XXXXXXXXXXX.. ",
+" ..................X..XXXX.XXXXXX.. ",
+" .................XXX.XX.XX.XXX.. ",
+" ................XX.XX.XX.XXX.. ",
+" ..ooooooooooo..XX.......XX.. ",
+" ..oooooooooo..X...XXXX.X.. ",
+" ..ooooooooo..X..XXXXXX.. ",
+" ...ooooooo..X..XXXX... ",
+" ....ooooo..XXXXX.... ",
+" ....ooo..XXX.... ",
+" ....o..X.... ",
+" ........ ",
+" .... ",
+" "};
diff --git a/test/porsche1.xpm b/test/porsche1.xpm
new file mode 100644
index 000000000..cb53d0e4b
--- /dev/null
+++ b/test/porsche1.xpm
@@ -0,0 +1,76 @@
+/* XPM */
+static char * porsche[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 -4 1 ",
+/* colormap */
+"\
+ \x50\x50\x80\
+.\xff\xff\0\
+r\xff\x00\0\
+b\0\0\0",
+/* pixels */
+" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb............................................bb ",
+" bb.......................bbbbbbb.bb...........bb ",
+" bb.......................bbbbbbb.bb...........bb ",
+" bb......bbb...bb..bb.....bb......bb...........bb ",
+" bb......bbb...bb..bb.....bb......bb...........bb ",
+" bb.......bb.......bbbb...bbbbb...bb...........bb ",
+" bb.......bb...bb..bbbbb..bbbbb...bb...........bb ",
+" bb.......bb...bb..bb.bb..bb......bb...........bb ",
+" bb......bbbb..bb..bbbbb..bb......bbbbbb.......bb ",
+" bb......bbbb..bb..bbbb...bb......bbbbbb.......bb ",
+" bb............................................bb ",
+" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb.....................bbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb......b...b...bb.....bbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb.....b...b...b....b..bbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb....bb..bb.bbbbbbb...bbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb...bbbbbbbb......bb..bbrrrrrrrrrrrrrrrrrrrrrbb ",
+" bb..bbbb...............bbrrrrrrrrrrrrrrrrrrrrrbb ",
+" bb.bbb.................bbrrrrrrrrrrrrrrrrrrrrrbb ",
+" bb..........b..b.......bbrrrrrrrrrrrrrrrrrrrrrbb ",
+" bb.....b...b..b........bbrrrrrrrrrrrrrrrrrrrrrbb ",
+" bb....b...b..b..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb....b.bbbbbbbbb..............bbbbbbbbbbbbbbbbb ",
+" bb...bbbb.......bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb..bbb.........b..............bbbbbbbbbbbbbbbbb ",
+" bb.bbb..........b...bbb........bbbbbbbbbbbbbbbbb ",
+" bb.........b..b.b..bbbbb.......bbbbbbbbbbbbbbbbb ",
+" bb.....b..b..b..b..b.bbb.....b.brrrrrrrrrrrrrrbb ",
+" bb....b..b..b..bb....bbb....bb.brrrrrrrrrrrrrrbb ",
+" bb...bb.bbbbbbb.b....bbb....bb.brrrrrrrrrrrrrrbb ",
+" bb..bbbbb......bb...bbbbb...b..brrrrrrrrrrrrrrbb ",
+" bb.bbb..........b.bbbbbbbbbbb..brrrrrrrrrrrrrrbb ",
+" bb..............b.b.bbbbbbbbb..brrrrrrrrrrrrrrbb ",
+" bbbbbbbbbbbbbbbbb.b.b....bbbb..bbbbbbbbbbbbbbbbb ",
+" bbbbbbbbbbbbbbbbb...b.....b.b..b..............bb ",
+" bbbbbbbbbbbbbbbbb........bb.bb.b...b..b.......bb ",
+" bbbbbbbbbbbbbbbb........b..b..b..b..b...b...bb ",
+" bbbbbbbbbbbbbbbb.......b..b...b.b..b...b....bb ",
+" bbbbbbbbbbbbbbbbb............b.bbbbbbbbbb...bb ",
+" bbrrrrrrrrrrrrrrb..........bbbb........bb.bb ",
+" bbrrrrrrrrrrrrrrrb........bbbb............bb ",
+" bbrrrrrrrrrrrrrrrbbbbbbbb.......b..b....bb ",
+" bbrrrrrrrrrrrrrrrrrrbb.....b...b..b..b..bb ",
+" bbrrrrrrrrrrrrrrrrrbb....b...b..b..b..bb ",
+" bbrrrrrrrrrrrrrrrrrbb...bb.bbbbbbbb...bb ",
+" bbbbbbbbbbbbbbbbbbbb...bbbb......bb.bb ",
+" bbbbbbbbbbbbbbbbbbb..bbb...........b ",
+" bbbbbbbbbbbbbbbbbbb.bbb...........bb ",
+" bbbbbbbbbbbbbbbbbb..............bb ",
+" bbbbbbbbbbbbbbbbb...b.b.b.....bb ",
+" bbbbbbbbbbbbbbbb..b.b.b..b..bb ",
+" bbrrrrrrrrrrrbb..bbbbbbb..bb ",
+" bbrrrrrrrrrrbb.bbb....b.bb ",
+" bbrrrrrrrrrbb.bb......bb ",
+" bbbrrrrrrrbb.......bbb ",
+" bbbbrrrrrbb.....bbbb ",
+" bbbbrrrbb...bbbb ",
+" bbbbrbb.bbbb ",
+" bbbbbbbb ",
+" bbbb ",
+" bb ",
+" "
+} ;
diff --git a/test/radio.C b/test/radio.C
new file mode 100644
index 000000000..ab15d3e8f
--- /dev/null
+++ b/test/radio.C
@@ -0,0 +1,67 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "radio.H"
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(462, 453);
+ w = o;
+ new Fl_Button(20, 10, 160, 30, "Fl_Button");
+ new Fl_Return_Button(20, 50, 160, 30, "Fl_Return_Button");
+ new Fl_Light_Button(20, 90, 160, 30, "Fl_Light_Button");
+ {Fl_Check_Button* o = new Fl_Check_Button(20, 130, 160, 30, "Fl_Check_Button");
+ o->box(FL_UP_BOX);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ }
+ {Fl_Round_Button* o = new Fl_Round_Button(20, 170, 160, 30, "Fl_Round_Button");
+ o->box(FL_UP_BOX);
+ o->down_box(FL_ROUND_DOWN_BOX);
+ }
+ {Fl_Group* o = new Fl_Group(190, 10, 70, 120);
+ o->box(FL_THIN_UP_FRAME);
+ {Fl_Check_Button* o = new Fl_Check_Button(190, 10, 70, 30, "radio");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ }
+ {Fl_Check_Button* o = new Fl_Check_Button(190, 40, 70, 30, "radio");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ }
+ {Fl_Check_Button* o = new Fl_Check_Button(190, 70, 70, 30, "radio");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ }
+ {Fl_Check_Button* o = new Fl_Check_Button(190, 100, 70, 30, "radio");
+ o->type(102);
+ o->down_box(FL_DIAMOND_DOWN_BOX);
+ }
+ o->end();
+ }
+ {Fl_Group* o = new Fl_Group(270, 10, 90, 115);
+ o->box(FL_THIN_UP_BOX);
+ {Fl_Button* o = new Fl_Button(280, 20, 20, 20, "radio");
+ o->type(102);
+ o->color2(1);
+ o->align(8);
+ }
+ {Fl_Button* o = new Fl_Button(280, 45, 20, 20, "radio");
+ o->type(102);
+ o->color2(1);
+ o->align(8);
+ }
+ {Fl_Button* o = new Fl_Button(280, 70, 20, 20, "radio");
+ o->type(102);
+ o->color2(1);
+ o->align(8);
+ }
+ {Fl_Button* o = new Fl_Button(280, 95, 20, 20, "radio");
+ o->type(102);
+ o->color2(1);
+ o->align(8);
+ }
+ o->end();
+ }
+ w->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/radio.H b/test/radio.H
new file mode 100644
index 000000000..534a8870a
--- /dev/null
+++ b/test/radio.H
@@ -0,0 +1,9 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Round_Button.H>
+#include <FL/Fl_Window.H>
diff --git a/test/radio.fl b/test/radio.fl
new file mode 100644
index 000000000..360ed58fc
--- /dev/null
+++ b/test/radio.fl
@@ -0,0 +1,72 @@
+# data file for FL User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 5
+snap 3
+Function {} {open
+} {
+ Fl_Window {} {open selected
+ xywh {447 255 462 453}
+ } {
+ Fl_Button {} {
+ label Fl_Button open
+ xywh {20 10 160 30}
+ }
+ Fl_Return_Button {} {
+ label Fl_Return_Button open
+ xywh {20 50 160 30}
+ }
+ Fl_Light_Button {} {
+ label Fl_Light_Button open
+ xywh {20 90 160 30}
+ }
+ Fl_Check_Button {} {
+ label Fl_Check_Button open
+ xywh {20 130 160 30} box 2
+ }
+ Fl_Round_Button {} {
+ label Fl_Round_Button open
+ xywh {20 170 160 30} box 2
+ }
+ Fl_Group {} {
+ xywh {190 10 70 120} box 8
+ } {
+ Fl_Check_Button {} {
+ label radio open
+ xywh {190 10 70 30} type 102
+ }
+ Fl_Check_Button {} {
+ label radio open
+ xywh {190 40 70 30} type 102
+ }
+ Fl_Check_Button {} {
+ label radio open
+ xywh {190 70 70 30} type 102
+ }
+ Fl_Check_Button {} {
+ label radio open
+ xywh {190 100 70 30} type 102
+ }
+ }
+ Fl_Group {} {open
+ xywh {270 10 90 115} box 6
+ } {
+ Fl_Button {} {
+ label radio open
+ xywh {280 20 20 20} type 102 color {47 1} align 8
+ }
+ Fl_Button {} {
+ label radio open
+ xywh {280 45 20 20} type 102 color {47 1} align 8
+ }
+ Fl_Button {} {
+ label radio open
+ xywh {280 70 20 20} type 102 color {47 1} align 8
+ }
+ Fl_Button {} {
+ label radio open
+ xywh {280 95 20 20} type 102 color {47 1} align 8
+ }
+ }
+ }
+}
diff --git a/test/resize.C b/test/resize.C
new file mode 100644
index 000000000..11185a2d0
--- /dev/null
+++ b/test/resize.C
@@ -0,0 +1,71 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "resize.H"
+
+static void callback_1008ed30(Fl_Button* o, void*) {
+Fl_Window* w = o->window();
+w->position(w->x()-50,w->y());
+}
+
+static void callback_1008ee58(Fl_Button* o, void*) {
+Fl_Window* w = o->window();
+w->position(w->x(),w->y()+50);
+}
+
+static void callback_1008ef40(Fl_Button* o, void*) {
+Fl_Window* w = o->window();
+w->position(w->x()+50,w->y());
+}
+
+static void callback_1008f048(Fl_Button* o, void*) {
+Fl_Window* w = o->window();
+w->position(w->x(),w->y()-50);
+}
+
+static void callback_1008f130(Fl_Button* o, void*) {
+Fl_Window* w = o->window();
+w->size(w->w()+50, w->h()+50);
+}
+
+static void callback_1008f360(Fl_Button* o, void*) {
+Fl_Window* w = o->window();
+w->size(w->w()/2+1, w->h()/2+1);
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(366, 261);
+ w = o;
+ Fl_Group::current()->resizable(o);
+ {Fl_Button* o = new Fl_Button(20, 40, 40, 40, "@<-");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)callback_1008ed30);
+ }
+ {Fl_Button* o = new Fl_Button(60, 80, 40, 40, "@2->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)callback_1008ee58);
+ }
+ {Fl_Button* o = new Fl_Button(100, 40, 40, 40, "@->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)callback_1008ef40);
+ }
+ {Fl_Button* o = new Fl_Button(60, 0, 40, 40, "@8->");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)callback_1008f048);
+ }
+ {Fl_Button* o = new Fl_Button(30, 130, 110, 40, "grow");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelfont(1);
+ o->labelsize(18);
+ o->callback((Fl_Callback*)callback_1008f130);
+ }
+ {Fl_Button* o = new Fl_Button(30, 190, 110, 40, "shrink");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelfont(1);
+ o->labelsize(18);
+ o->callback((Fl_Callback*)callback_1008f360);
+ }
+ w->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/resize.H b/test/resize.H
new file mode 100644
index 000000000..e728ef05f
--- /dev/null
+++ b/test/resize.H
@@ -0,0 +1,4 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Window.H>
diff --git a/test/resize.fl b/test/resize.fl
new file mode 100644
index 000000000..7524bc79e
--- /dev/null
+++ b/test/resize.fl
@@ -0,0 +1,48 @@
+# data file for FL User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 10
+snap 3
+Function {} {open
+} {
+ Fl_Window {} {open selected
+ xywh {490 248 366 261} resizable
+ } {
+ Fl_Button {} {
+ label {@<-}
+ callback {Fl_Window* w = o->window();
+w->position(w->x()-50,w->y());} open
+ xywh {20 40 40 40} labeltype 2
+ }
+ Fl_Button {} {
+ label {@2->}
+ callback {Fl_Window* w = o->window();
+w->position(w->x(),w->y()+50);} open
+ xywh {60 80 40 40} labeltype 2
+ }
+ Fl_Button {} {
+ label {@->}
+ callback {Fl_Window* w = o->window();
+w->position(w->x()+50,w->y());} open
+ xywh {100 40 40 40} labeltype 2
+ }
+ Fl_Button {} {
+ label {@8->}
+ callback {Fl_Window* w = o->window();
+w->position(w->x(),w->y()-50);} open
+ xywh {60 0 40 40} labeltype 2
+ }
+ Fl_Button {} {
+ label grow
+ callback {Fl_Window* w = o->window();
+w->size(w->w()+50, w->h()+50);} open
+ xywh {30 130 110 40} labeltype 2 labelfont 1 labelsize 18
+ }
+ Fl_Button {} {
+ label shrink
+ callback {Fl_Window* w = o->window();
+w->size(w->w()/2+1, w->h()/2+1);} open
+ xywh {30 190 110 40} labeltype 2 labelfont 1 labelsize 18
+ }
+ }
+}
diff --git a/test/resizebox.cxx b/test/resizebox.cxx
new file mode 100644
index 000000000..a8184e380
--- /dev/null
+++ b/test/resizebox.cxx
@@ -0,0 +1,74 @@
+// Test the position of the resizebox
+
+#define W1 (big ? 60 : 40)
+#define B 0
+#define W3 (5*W1+6*B)
+
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Radio_Button.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_message.H>
+
+Fl_Single_Window *window;
+Fl_Box *box;
+
+int big = 0;
+
+void b_cb(Fl_Widget *,long w) {
+ if (window->w() != W3 || window->h() != W3) {
+ fl_message("Put window back to minimum size before changing");
+ return;
+ }
+ window->init_sizes();
+ switch (w) {
+ case 0: box->hide(); window->box(FL_FLAT_BOX); window->resizable(0); return;
+ case 8: box->resize(W1+B,W1,2*W1,B); break;
+ case 2: box->resize(W1+B,W1+B+2*W1,2*W1,B); break;
+ case 4: box->resize(W1+B,W1,B,2*W1); break;
+ case 6: box->resize(W1+B+2*W1,W1+B,B,2*W1); break;
+ }
+ window->box(FL_NO_BOX);
+ if (w == 6 || w == 4)
+ box->label("re\nsiz\nab\nle");
+ else box->label("resizable");
+ box->show();
+ window->resizable(box);
+ window->redraw();
+}
+
+int main(int argc, char **argv) {
+ window = new Fl_Single_Window(W3,W3);
+ window->box(FL_NO_BOX);
+ Fl_Box *n;
+ for (int x = 0; x<4; x++) for (int y = 0; y<4; y++) {
+ if ((x==1 || x==2) && (y==1 || y==2)) continue;
+ n = new Fl_Box(FL_FRAME_BOX,x*(B+W1)+B,y*(B+W1)+B,W1,W1,0);
+ n->color(x+y+8);
+ }
+ n = new Fl_Box(FL_FRAME_BOX,B,4*W1+5*B,4*W1+3*B,W1,0);
+ n->color(12);
+ n = new Fl_Box(FL_FRAME_BOX,4*W1+5*B,B,W1,5*W1+4*B,0);
+ n->color(13);
+ n = new Fl_Box(FL_FRAME_BOX,W1+B+B,W1+B+B,2*W1+B,2*W1+B,0);
+ n->color(8);
+
+ Fl::enable_symbols();
+ Fl_Button *b = new Fl_Radio_Button(W1+B+50,W1+B+30,20,20,"@6>");
+ b->callback(b_cb,6);
+ (new Fl_Radio_Button(W1+B+30,W1+B+10,20,20,"@8>"))->callback(b_cb,8);
+ (new Fl_Radio_Button(W1+B+10,W1+B+30,20,20,"@4>"))->callback(b_cb,4);
+ (new Fl_Radio_Button(W1+B+30,W1+B+50,20,20,"@2>"))->callback(b_cb,2);
+ (new Fl_Radio_Button(W1+B+30,W1+B+30,20,20,"off"))->callback(b_cb,0);
+
+ box = new Fl_Box(FL_FLAT_BOX,0,0,0,0,"resizable");
+ box->color(FL_DARK2);
+ b->set();
+ b->do_callback();
+ window->end();
+
+ window->size_range(W3,W3);
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/scroll.cxx b/test/scroll.cxx
new file mode 100644
index 000000000..d74321444
--- /dev/null
+++ b/test/scroll.cxx
@@ -0,0 +1,112 @@
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Box.H>
+#include <string.h>
+#include <stdio.h>
+#include <FL/fl_draw.H>
+#include <FL/math.h>
+
+class Drawing : public Fl_Widget {
+ void draw();
+public:
+ Drawing(int X,int Y,int W,int H,const char* L) : Fl_Widget(X,Y,W,H,L) {
+ align(FL_ALIGN_TOP);
+ box(FL_FLAT_BOX);
+ color(FL_WHITE);
+ }
+};
+
+void Drawing::draw() {
+ draw_box();
+ fl_push_matrix();
+ fl_translate(x()+w()/2, y()+h()/2);
+ fl_scale(w()/2, h()/2);
+ fl_color(FL_BLACK);
+ for (int i = 0; i < 20; i++) {
+ for (int j = i+1; j < 20; j++) {
+ fl_begin_line();
+ fl_vertex(cos(M_PI*i/10+.1), sin(M_PI*i/10+.1));
+ fl_vertex(cos(M_PI*j/10+.1), sin(M_PI*j/10+.1));
+ fl_end_line();
+ }
+ }
+ fl_pop_matrix();
+}
+
+Fl_Scroll* thescroll;
+
+void box_cb(Fl_Widget* o, void*) {
+ thescroll->box(((Fl_Button*)o)->value() ? FL_DOWN_FRAME : FL_NO_BOX);
+ thescroll->redraw();
+}
+
+void type_cb(Fl_Widget*, void* v) {
+ thescroll->type(int(v));
+ thescroll->redraw();
+}
+
+Fl_Menu_Item choices[] = {
+ {"0", 0, type_cb, (void*)0},
+ {"HORIZONTAL", 0, type_cb, (void*)Fl_Scroll::HORIZONTAL},
+ {"VERTICAL", 0, type_cb, (void*)Fl_Scroll::VERTICAL},
+ {"BOTH", 0, type_cb, (void*)Fl_Scroll::BOTH},
+ {"HORIZONTAL_ALWAYS", 0, type_cb, (void*)Fl_Scroll::HORIZONTAL_ALWAYS},
+ {"VERTICAL_ALWAYS", 0, type_cb, (void*)Fl_Scroll::VERTICAL_ALWAYS},
+ {"BOTH_ALWAYS", 0, type_cb, (void*)Fl_Scroll::BOTH_ALWAYS},
+ {0}
+};
+
+void align_cb(Fl_Widget*, void* v) {
+ thescroll->scrollbar.align(int(v));
+ thescroll->redraw();
+}
+
+Fl_Menu_Item align_choices[] = {
+ {"left+top", 0, align_cb, (void*)(FL_ALIGN_LEFT+FL_ALIGN_TOP)},
+ {"left+bottom", 0, align_cb, (void*)(FL_ALIGN_LEFT+FL_ALIGN_BOTTOM)},
+ {"right+top", 0, align_cb, (void*)(FL_ALIGN_RIGHT+FL_ALIGN_TOP)},
+ {"right+bottom", 0, align_cb, (void*)(FL_ALIGN_RIGHT+FL_ALIGN_BOTTOM)},
+ {0}
+};
+
+int main(int argc, char** argv) {
+ Fl_Window window(5*75,400);
+ window.box(FL_NO_BOX);
+ Fl_Scroll scroll(0,0,5*75,300);
+
+ int n = 0;
+ for (int y=0; y<16; y++) for (int x=0; x<5; x++) {
+ char buf[20]; sprintf(buf,"%d",n++);
+ Fl_Button* b = new Fl_Button(x*75,y*25+(y>=8?5*75:0),75,25,strdup(buf));
+ b->color(n);
+ b->labelcolor(FL_WHITE);
+ }
+ Drawing drawing(0,8*25,5*75,5*75,0);
+ scroll.end();
+ window.resizable(scroll);
+
+ Fl_Box box(0,300,5*75,window.h()-300); // gray area below the scroll
+ box.box(FL_FLAT_BOX);
+
+ Fl_Toggle_Button but1(150, 310, 200, 25, "box");
+ but1.callback(box_cb);
+
+ Fl_Choice choice(150, 335, 200, 25, "type():");
+ choice.menu(choices);
+ choice.value(3);
+
+ Fl_Choice achoice(150, 360, 200, 25, "scrollbar.align():");
+ achoice.menu(align_choices);
+ achoice.value(3);
+
+ thescroll = &scroll;
+
+ //scroll.box(FL_DOWN_BOX);
+ //scroll.type(Fl_Scroll::VERTICAL);
+ window.end();
+ window.show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/shape.cxx b/test/shape.cxx
new file mode 100644
index 000000000..1451c241e
--- /dev/null
+++ b/test/shape.cxx
@@ -0,0 +1,91 @@
+/* Tiny GL-drawing demo from documentation */
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Hor_Slider.H>
+#include <FL/math.h>
+
+#if HAVE_GL
+
+#include <FL/gl.h>
+#include <FL/Fl_Gl_Window.H>
+
+class shape_window : public Fl_Gl_Window {
+ void draw();
+public:
+ int sides;
+ shape_window(int x,int y,int w,int h,const char *l=0);
+};
+
+shape_window::shape_window(int x,int y,int w,int h,const char *l) :
+Fl_Gl_Window(x,y,w,h,l) {
+ sides = 3;
+}
+
+void shape_window::draw() {
+// the valid() property may be used to avoid reinitializing your
+// GL transformation for each redraw:
+ if (!valid()) {
+ valid(1);
+ glLoadIdentity();
+ glViewport(0,0,w(),h());
+ }
+// draw an amazing graphic:
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(.5,.6,.7);
+ glBegin(GL_POLYGON);
+ for (int i=0; i<sides; i++) {
+ double ang = i*2*M_PI/sides;
+ glVertex3f(cos(ang),sin(ang),0);
+ }
+ glEnd();
+}
+
+#else
+
+#include <FL/Fl_Box.H>
+class shape_window : public Fl_Box {
+public:
+ int sides;
+ shape_window(int x,int y,int w,int h,const char *l=0)
+ :Fl_Box(FL_DOWN_BOX,x,y,w,h,l){
+ label("This demo does\nnot work without GL");
+ }
+};
+
+#endif
+
+// when you change the data, as in this callback, you must call redraw():
+void sides_cb(Fl_Widget *o, void *p) {
+ shape_window *sw = (shape_window *)p;
+ sw->sides = int(((Fl_Slider *)o)->value());
+ sw->redraw();
+}
+
+int main(int argc, char **argv) {
+
+ Fl_Window window(300, 330);
+
+// the shape window could be it's own window, but here we make it
+// a child window:
+ shape_window sw(10, 10, 280, 280);
+// make it resize:
+ window.resizable(&sw);
+ // window.size_range(300,330,0,0,1,1,1);
+// add a knob to control it:
+ Fl_Hor_Slider slider(50, 295, window.w()-60, 30, "Sides:");
+ slider.align(FL_ALIGN_LEFT);
+ slider.callback(sides_cb,&sw);
+ slider.value(sw.sides);
+ slider.step(1);
+ slider.bounds(3,40);
+
+ window.end();
+ window.show(argc,argv);
+// in the X version you must show() all Fl_Window's in top/down order
+// other systems may not require this, but it will be harmless:
+ //sw.show();
+
+ return Fl::run();
+}
diff --git a/test/shiny.cxx b/test/shiny.cxx
new file mode 100644
index 000000000..24846e218
--- /dev/null
+++ b/test/shiny.cxx
@@ -0,0 +1,281 @@
+// Test of gl_start() and gl_finish()
+// Also sample code of using OpenGL to draw a boxtype.
+
+#include <config.h>
+#include "shiny_panel.C"
+#include <FL/fl_message.H>
+#include <stdio.h>
+
+static uchar color[8][3] = {
+ {128,136,149},
+ {63,54,21},
+ {128,136,146},
+ {223,223,223},
+ {121,128,128},
+ {192,206,220},
+ {137,143,145},
+ {99,81,64}
+};
+static int thickness = 3;
+
+int which = 0;
+
+static Fl_Color pcolor;
+
+Fl_Window *window;
+
+void color_slider_cb(Fl_Value_Slider *o, long i) {
+ int v = int(o->value());
+ if (!i) {
+ color[which][0] = color[which][1] = color[which][2] = v;
+ color_slider[1]->value(v);
+ color_slider[2]->value(v);
+ color_slider[3]->value(v);
+ } else {
+ color[which][i-1] = v;
+ }
+ for (int n=0; n<window->children(); n++) window->child(n)->redraw();
+ pcolor = FL_BLACK; // make it recalculate actual colors
+// test_box[0]->redraw();
+// test_box[1]->redraw();
+// test_box[2]->redraw();
+}
+
+void set_sliders() {
+ color_slider[0]->value(color[which][0]);
+ color_slider[1]->value(color[which][0]);
+ color_slider[2]->value(color[which][1]);
+ color_slider[3]->value(color[which][2]);
+}
+
+void thickness_cb(Fl_Slider* s,void*) {
+ thickness = int(s->value());
+ for (int n=0; n<window->children(); n++) window->child(n)->redraw();
+}
+
+void which_cb(Fl_Button *, long i) {
+ which = which&(~3) | i;
+ set_sliders();
+}
+
+void inside_cb(Fl_Button *b, void*) {
+ if (b->value()) which = which | 4;
+ else which = which & (3|8);
+ set_sliders();
+}
+
+void dump_cb(Fl_Button *, void*) {
+ printf("static uchar color[8][3] = {\n");
+ for (int i=0; i<8; i++) {
+ printf(" {%d,%d,%d}",color[i][0],color[i][1],color[i][2]);
+ if (i<7) printf(",\n");
+ }
+ printf("\n};\nstatic int thickness = %d;\n",thickness);
+}
+
+#include <FL/fl_draw.H>
+
+#if HAVE_GL
+#include <FL/gl.h>
+
+static uchar C[8][3]; // actual colors for current button
+
+static void calc_color(Fl_Color c) {
+ uchar r[3];
+ pcolor = c;
+ Fl::get_color(c,r[0],r[1],r[2]);
+ for (int x = 0; x<8; x++) for (int y=0; y<3; y++) {
+ int i = r[y]-166+color[x][y];
+ if (i<0) i = 0; else if (i>255) i = 255;
+ C[x][y] = i;
+ }
+}
+void shiny_up_box(int x1, int y1, int w1, int h1, Fl_Color c) {
+ if (c != pcolor) calc_color(c);
+ int x = x1+1;
+ int y = Fl_Window::current()->h()-(y1+h1-1);
+ int w = w1-2;
+ int h = h1-2;
+ gl_start();
+
+ // left edge:
+ glBegin(GL_POLYGON);
+ glColor3ub(C[0][0],C[0][1],C[0][2]);
+ glVertex2i(x,y);
+ glVertex2i(x+thickness,y+thickness);
+ glColor3ub(C[3][0],C[3][1],C[3][2]);
+ glVertex2i(x+thickness,y+h-thickness);
+ glVertex2i(x,y+h);
+ glEnd();
+
+ // top edge:
+ glBegin(GL_POLYGON);
+ glVertex2i(x,y+h);
+ glVertex2i(x+thickness,y+h-thickness);
+ glColor3ub(C[2][0],C[2][1],C[2][2]);
+ glVertex2i(x+w-thickness,y+h-thickness);
+ glVertex2i(x+w,y+h);
+ glEnd();
+
+ // right edge:
+ glColor3ub(C[1][0],C[1][1],C[1][2]);
+ glBegin(GL_POLYGON);
+ glVertex2i(x+w-thickness,y+thickness);
+ glVertex2i(x+w,y+thickness);
+ glVertex2i(x+w,y+h);
+ glVertex2i(x+w-thickness,y+h-thickness);
+ glEnd();
+
+ // bottom edge:
+ glBegin(GL_POLYGON);
+ glVertex2i(x,y);
+ glVertex2i(x+w,y);
+ glVertex2i(x+w,y+thickness);
+ glVertex2i(x+thickness,y+thickness);
+ glEnd();
+
+ glBegin(GL_POLYGON);
+ glColor3ub(C[4][0],C[4][1],C[4][2]);
+ glVertex2i(x+thickness,y+thickness);
+ glColor3ub(C[5][0],C[5][1],C[5][2]);
+ glVertex2i(x+w-thickness,y+thickness);
+ glColor3ub(C[6][0],C[6][1],C[6][2]);
+ glVertex2i(x+w-thickness,y+h-thickness);
+ glColor3ub(C[7][0],C[7][1],C[7][2]);
+ glVertex2i(x+thickness,y+h-thickness);
+ glEnd();
+
+ gl_finish();
+ fl_color(FL_BLACK);
+ fl_rect(x1,y1,w1,h1);
+}
+
+void shiny_down_box(int x1, int y1, int w1, int h1, Fl_Color c) {
+ if (c != pcolor) calc_color(c);
+ int x = x1+1;
+ int y = Fl_Window::current()->h()-(y1+h1-1);
+ int w = w1-2;
+ int h = h1-2;
+ gl_start();
+
+ // left edge:
+ glColor3ub(C[1][0],C[1][1],C[1][2]);
+ glBegin(GL_POLYGON);
+ glVertex2i(x,y);
+ glVertex2i(x+thickness,y+thickness);
+ glVertex2i(x+thickness,y+h-thickness);
+ glVertex2i(x,y+h);
+ glEnd();
+
+ // top edge:
+ glBegin(GL_POLYGON);
+ glVertex2i(x,y+h);
+ glVertex2i(x+thickness,y+h-thickness);
+ glVertex2i(x+w-thickness,y+h-thickness);
+ glVertex2i(x+w,y+h);
+ glEnd();
+
+ // bottom edge:
+ glBegin(GL_POLYGON);
+ glColor3ub(C[0][0],C[0][1],C[0][2]);
+ glVertex2i(x+thickness,y+thickness);
+ glVertex2i(x,y);
+ glColor3ub(C[1][0],C[1][1],C[1][2]);
+ glVertex2i(x+w,y);
+ glVertex2i(x+w-thickness,y+thickness);
+ glEnd();
+
+ // right edge:
+ glBegin(GL_POLYGON);
+ glVertex2i(x+w-thickness,y+thickness);
+ glVertex2i(x+w,y);
+ glColor3ub(C[2][0],C[2][1],C[2][2]);
+ glVertex2i(x+w,y+h);
+ glVertex2i(x+w-thickness,y+h-thickness);
+ glEnd();
+
+ // inside:
+ glBegin(GL_POLYGON);
+ glColor3ub(C[4][0],C[4][1],C[4][2]);
+ glVertex2i(x+thickness,y+thickness);
+ glColor3ub(C[5][0],C[5][1],C[5][2]);
+ glVertex2i(x+w-thickness,y+thickness);
+ glColor3ub(C[6][0],C[6][1],C[6][2]);
+ glVertex2i(x+w-thickness,y+h-thickness);
+ glColor3ub(C[7][0],C[7][1],C[7][2]);
+ glVertex2i(x+thickness,y+h-thickness);
+ glEnd();
+
+ gl_finish();
+ fl_color(FL_BLACK);
+ fl_rect(x1,y1,w1,h1);
+}
+
+// It looks interesting if you use this for the window's boxtype,
+// but it is way too slow under MESA:
+void shiny_flat_box(int x, int y1, int w, int h, Fl_Color c) {
+ if (c != pcolor) calc_color(c);
+ int y = Fl_Window::current()->h()-(y1+h);
+ gl_start();
+ glBegin(GL_POLYGON);
+ glColor3ub(C[4][0],C[4][1],C[4][2]);
+ glVertex2i(x,y);
+ glColor3ub(C[5][0],C[5][1],C[5][2]);
+ glVertex2i(x+w,y);
+ glColor3ub(C[6][0],C[6][1],C[6][2]);
+ glVertex2i(x+w,y+h);
+ glColor3ub(C[7][0],C[7][1],C[7][2]);
+ glVertex2i(x,y+h);
+ glEnd();
+ gl_finish();
+}
+#endif
+
+// If you use a shiny box as a background, things like the sliders that
+// expect to erase a flat area will not work, as you will see the edges
+// of the area. This "box type" clips to the area and then draws the
+// parent's box. Perhaps sliders should be fixed to do this automatically?
+void invisible_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_clip(x,y,w,h);
+ Fl_Window *W = Fl_Window::current();
+ fl_draw_box(W->box(),0,0,W->w(),W->h(),c);
+ fl_pop_clip();
+}
+
+#define SHINY_BOX (Fl_Boxtype)30
+#define INVISIBLE_BOX (Fl_Boxtype)31
+
+int main(int argc, char **argv) {
+ window = make_panels();
+#if HAVE_GL
+ // This will cause all buttons to be shiny:
+ Fl::set_boxtype(FL_UP_BOX, shiny_up_box,3,3,6,6);
+ Fl::set_boxtype(FL_DOWN_BOX, shiny_down_box,3,3,6,6);
+ // replacing FL_FLAT_BOX does not work! Fl_Window makes assumptions
+ // about what FL_FLAT_BOX does, and sets the X background pixel.
+//Fl::set_boxtype(FL_FLAT_BOX, shiny_flat_box, 0,0,0,0);
+ // Instead you must change box() on Fl_Window to a different value:
+ Fl::set_boxtype(SHINY_BOX, shiny_flat_box, 0,0,0,0);
+ window->box(SHINY_BOX);
+ Fl::set_boxtype(INVISIBLE_BOX, invisible_box, 0,0,0,0);
+#endif
+ set_sliders();
+//color_slider[0]->box(INVISIBLE_BOX);
+//color_slider[1]->box(INVISIBLE_BOX);
+//color_slider[2]->box(INVISIBLE_BOX);
+//color_slider[3]->box(INVISIBLE_BOX);
+ thickness_slider->value(thickness);
+ thickness_slider->box(INVISIBLE_BOX);
+ thickness_slider->slider(FL_UP_BOX);
+ // we must eat the switches first so -display is done before trying
+ // to set the visual:
+ int i = 0;
+ if (Fl::args(argc,argv,i) < argc) Fl::fatal(Fl::help);
+#if HAVE_GL
+ if (!Fl::gl_visual(FL_RGB)) Fl::fatal("Display does not do OpenGL");
+#else
+ fl_message("This demo does not work without OpenGL");
+#endif
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/shiny_panel.C b/test/shiny_panel.C
new file mode 100644
index 000000000..f568a7d90
--- /dev/null
+++ b/test/shiny_panel.C
@@ -0,0 +1,103 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include "shiny_panel.H"
+Fl_Box *test_box[3];
+Fl_Value_Slider *color_slider[4];
+Fl_Slider *thickness_slider;
+
+Fl_Window* make_panels() {
+ Fl_Window *w;
+ {Fl_Window* o = new Fl_Window(452, 320);
+ w = o;
+ {Fl_Box* o = new Fl_Box(130, 80, 180, 30, "label");
+ test_box[0] = o;
+ o->box(FL_UP_BOX);
+ }
+ {Fl_Box* o = new Fl_Box(130, 120, 180, 30, "label");
+ test_box[1] = o;
+ o->box(FL_UP_BOX);
+ }
+ {Fl_Box* o = new Fl_Box(130, 150, 180, 70, "label");
+ test_box[2] = o;
+ o->box(FL_UP_BOX);
+ Fl_Group::current()->resizable(o);
+ }
+ {Fl_Group* o = new Fl_Group(10, 70, 80, 80);
+ {Fl_Button* o = new Fl_Button(10, 70, 40, 40, "@7->");
+ o->type(102);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)which_cb, (void*)(3));
+ }
+ {Fl_Button* o = new Fl_Button(50, 70, 40, 40, "@9->");
+ o->type(102);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)which_cb, (void*)(2));
+ }
+ {Fl_Button* o = new Fl_Button(10, 110, 40, 40, "@1->");
+ o->type(102);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)which_cb, (void*)(0));
+ o->set();
+ }
+ {Fl_Button* o = new Fl_Button(50, 110, 40, 40, "@3->");
+ o->type(102);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->callback((Fl_Callback*)which_cb, (void*)(1));
+ }
+ o->end();
+ }
+ {Fl_Button* o = new Fl_Button(10, 150, 80, 40, "INSIDE");
+ o->type(1);
+ o->callback((Fl_Callback*)inside_cb);
+ }
+ {Fl_Value_Slider* o = new Fl_Value_Slider(320, 0, 30, 320);
+ color_slider[0] = o;
+ o->type(4);
+ o->box(FL_FLAT_BOX);
+ o->color(7);
+ o->callback((Fl_Callback*)color_slider_cb, (void*)(0));
+ o->minimum(255); o->maximum(0);;
+ o->precision(0);
+ }
+ {Fl_Value_Slider* o = new Fl_Value_Slider(350, 0, 30, 320);
+ color_slider[1] = o;
+ o->type(4);
+ o->box(FL_FLAT_BOX);
+ o->color(9);
+ o->callback((Fl_Callback*)color_slider_cb, (void*)(1));
+ o->minimum(255); o->maximum(0);;
+ o->precision(0);
+ }
+ {Fl_Value_Slider* o = new Fl_Value_Slider(380, 0, 30, 320);
+ color_slider[2] = o;
+ o->type(4);
+ o->box(FL_FLAT_BOX);
+ o->color(10);
+ o->callback((Fl_Callback*)color_slider_cb, (void*)(2));
+ o->minimum(255); o->maximum(0);;
+ o->precision(0);
+ }
+ {Fl_Value_Slider* o = new Fl_Value_Slider(410, 0, 30, 320);
+ color_slider[3] = o;
+ o->type(4);
+ o->box(FL_FLAT_BOX);
+ o->color(12);
+ o->callback((Fl_Callback*)color_slider_cb, (void*)(3));
+ o->minimum(255); o->maximum(0);;
+ o->precision(0);
+ }
+ {Fl_Slider* o = new Fl_Slider(130, 240, 180, 30, "thickness");
+ thickness_slider = o;
+ o->type(5);
+ o->box(FL_FLAT_BOX);
+ o->callback((Fl_Callback*)thickness_cb);
+ o->minimum(1);
+ o->maximum(10);
+ o->step(1);
+ }
+ {Fl_Button* o = new Fl_Button(10, 230, 80, 30, "dump");
+ o->callback((Fl_Callback*)dump_cb);
+ }
+ w->end();
+ }
+ return w;
+}
diff --git a/test/shiny_panel.H b/test/shiny_panel.H
new file mode 100644
index 000000000..9e86fc52f
--- /dev/null
+++ b/test/shiny_panel.H
@@ -0,0 +1,17 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Value_Slider.H>
+#include <FL/Fl_Window.H>
+extern void color_slider_cb(Fl_Value_Slider*, long);
+extern void dump_cb(Fl_Button*, void*);
+extern void inside_cb(Fl_Button*, void*);
+extern void thickness_cb(Fl_Slider*, void*);
+extern void which_cb(Fl_Button*, long);
+extern Fl_Box *test_box[3];
+extern Fl_Value_Slider *color_slider[4];
+extern Fl_Slider *thickness_slider;
+Fl_Window* make_panels();
diff --git a/test/shiny_panel.fl b/test/shiny_panel.fl
new file mode 100644
index 000000000..a4d5dfa4f
--- /dev/null
+++ b/test/shiny_panel.fl
@@ -0,0 +1,96 @@
+# data file for FL User Interface Designer (fluid)
+version 0.97
+Function {make_panels()} {open
+} {
+ Fl_Window {} {open
+ xywh {594 419 452 320}
+ } {
+ Fl_Box {test_box[0]} {
+ label label open
+ xywh {130 80 180 30} box 2
+ }
+ Fl_Box {test_box[1]} {
+ label label open
+ xywh {130 120 180 30} box 2
+ }
+ Fl_Box {test_box[2]} {
+ label label open
+ xywh {130 150 180 70} box 2 resizable
+ }
+ Fl_Group {} {open
+ xywh {10 70 80 80}
+ } {
+ Fl_Button {} {
+ label {@7->}
+ user_data 3 user_data_type long
+ callback which_cb open
+ xywh {10 70 40 40} type 102 labeltype 2
+ }
+ Fl_Button {} {
+ label {@9->}
+ user_data 2 user_data_type long
+ callback which_cb open
+ xywh {50 70 40 40} type 102 labeltype 2
+ }
+ Fl_Button {} {
+ label {@1->}
+ user_data 0 user_data_type long
+ callback which_cb open
+ xywh {10 110 40 40} type 102 labeltype 2
+ code0 {o->set();}
+ }
+ Fl_Button {} {
+ label {@3->}
+ user_data 1 user_data_type long
+ callback which_cb open
+ xywh {50 110 40 40} type 102 labeltype 2
+ }
+ }
+ Fl_Button {} {
+ label INSIDE
+ callback inside_cb open
+ xywh {10 150 80 40} type 1
+ }
+ Fl_Value_Slider {color_slider[0]} {
+ user_data 0 user_data_type long
+ callback color_slider_cb open
+ xywh {320 0 30 320} type 4 box 1 color {7 47}
+ code0 {o->minimum(255); o->maximum(0);;}
+ code1 {o->precision(0);}
+ }
+ Fl_Value_Slider {color_slider[1]} {
+ user_data 1 user_data_type long
+ callback color_slider_cb open
+ xywh {350 0 30 320} type 4 box 1 color {9 47}
+ code0 {o->minimum(255); o->maximum(0);;}
+ code1 {o->precision(0);}
+ }
+ Fl_Value_Slider {color_slider[2]} {
+ user_data 2 user_data_type long
+ callback color_slider_cb open
+ xywh {380 0 30 320} type 4 box 1 color {10 47}
+ code0 {o->minimum(255); o->maximum(0);;}
+ code1 {o->precision(0);}
+ }
+ Fl_Value_Slider {color_slider[3]} {
+ user_data 3 user_data_type long
+ callback color_slider_cb open
+ xywh {410 0 30 320} type 4 box 1 color {12 47}
+ code0 {o->minimum(255); o->maximum(0);;}
+ code1 {o->precision(0);}
+ }
+ Fl_Slider thickness_slider {
+ label thickness
+ callback thickness_cb open
+ xywh {130 240 180 30} type 5 box 1
+ code0 {o->minimum(1);}
+ code1 {o->maximum(10);}
+ code2 {o->step(1);}
+ }
+ Fl_Button {} {
+ label dump
+ callback dump_cb open selected
+ xywh {10 230 80 30}
+ }
+ }
+}
diff --git a/test/srs.xbm b/test/srs.xbm
new file mode 100644
index 000000000..b6a9c7440
--- /dev/null
+++ b/test/srs.xbm
@@ -0,0 +1,67 @@
+#define sorceress_width 75
+#define sorceress_height 75
+static unsigned char sorceress_bits[] =
+{
+ 0xfc, 0x7e, 0x40, 0x20, 0x90, 0x00, 0x07, 0x80, 0x23, 0x00, 0x00, 0xc6,
+ 0xc1, 0x41, 0x98, 0xb8, 0x01, 0x07, 0x66, 0x00, 0x15, 0x9f, 0x03, 0x47,
+ 0x8c, 0xc6, 0xdc, 0x7b, 0xcc, 0x00, 0xb0, 0x71, 0x0e, 0x4d, 0x06, 0x66,
+ 0x73, 0x8e, 0x8f, 0x01, 0x18, 0xc4, 0x39, 0x4b, 0x02, 0x23, 0x0c, 0x04,
+ 0x1e, 0x03, 0x0c, 0x08, 0xc7, 0xef, 0x08, 0x30, 0x06, 0x07, 0x1c, 0x02,
+ 0x06, 0x30, 0x18, 0xae, 0xc8, 0x98, 0x3f, 0x78, 0x20, 0x06, 0x02, 0x20,
+ 0x60, 0xa0, 0xc4, 0x1d, 0xc0, 0xff, 0x41, 0x04, 0xfa, 0x63, 0x80, 0xa1,
+ 0xa4, 0x3d, 0x00, 0x84, 0xbf, 0x04, 0x0f, 0x06, 0xfc, 0xa1, 0x34, 0x6b,
+ 0x01, 0x1c, 0xc9, 0x05, 0x06, 0xc7, 0x06, 0xbe, 0x11, 0x1e, 0x43, 0x30,
+ 0x91, 0x05, 0xc3, 0x61, 0x02, 0x30, 0x1b, 0x30, 0xcc, 0x20, 0x11, 0x00,
+ 0xc1, 0x3c, 0x03, 0x20, 0x0a, 0x00, 0xe8, 0x60, 0x21, 0x00, 0x61, 0x1b,
+ 0xc1, 0x63, 0x08, 0xf0, 0xc6, 0xc7, 0x21, 0x03, 0xf8, 0x08, 0xe1, 0xcf,
+ 0x0a, 0xfc, 0x4d, 0x99, 0x43, 0x07, 0x3c, 0x0c, 0xf1, 0x9f, 0x0b, 0xfc,
+ 0x5b, 0x81, 0x47, 0x02, 0x16, 0x04, 0x31, 0x1c, 0x0b, 0x1f, 0x17, 0x89,
+ 0x4d, 0x06, 0x1a, 0x04, 0x31, 0x38, 0x02, 0x07, 0x56, 0x89, 0x49, 0x04,
+ 0x0b, 0x04, 0xb1, 0x72, 0x82, 0xa1, 0x54, 0x9a, 0x49, 0x04, 0x1d, 0x66,
+ 0x50, 0xe7, 0xc2, 0xf0, 0x54, 0x9a, 0x58, 0x04, 0x0d, 0x62, 0xc1, 0x1f,
+ 0x44, 0xfc, 0x51, 0x90, 0x90, 0x04, 0x86, 0x63, 0xe0, 0x74, 0x04, 0xef,
+ 0x31, 0x1a, 0x91, 0x00, 0x02, 0xe2, 0xc1, 0xfd, 0x84, 0xf9, 0x30, 0x0a,
+ 0x91, 0x00, 0x82, 0xa9, 0xc0, 0xb9, 0x84, 0xf9, 0x31, 0x16, 0x81, 0x00,
+ 0x42, 0xa9, 0xdb, 0x7f, 0x0c, 0xff, 0x1c, 0x16, 0x11, 0x00, 0x02, 0x28,
+ 0x0b, 0x07, 0x08, 0x60, 0x1c, 0x02, 0x91, 0x00, 0x46, 0x29, 0x0e, 0x00,
+ 0x00, 0x00, 0x10, 0x16, 0x11, 0x02, 0x06, 0x29, 0x04, 0x00, 0x00, 0x00,
+ 0x10, 0x16, 0x91, 0x06, 0xa6, 0x2a, 0x04, 0x00, 0x00, 0x00, 0x18, 0x24,
+ 0x91, 0x04, 0x86, 0x2a, 0x04, 0x00, 0x00, 0x00, 0x18, 0x27, 0x93, 0x04,
+ 0x96, 0x4a, 0x04, 0x00, 0x00, 0x00, 0x04, 0x02, 0x91, 0x04, 0x86, 0x4a,
+ 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x23, 0x93, 0x04, 0x56, 0x88, 0x08, 0x00,
+ 0x00, 0x00, 0x90, 0x21, 0x93, 0x04, 0x52, 0x0a, 0x09, 0x80, 0x01, 0x00,
+ 0xd0, 0x21, 0x95, 0x04, 0x57, 0x0a, 0x0f, 0x80, 0x27, 0x00, 0xd8, 0x20,
+ 0x9d, 0x04, 0x5d, 0x08, 0x1c, 0x80, 0x67, 0x00, 0xe4, 0x01, 0x85, 0x04,
+ 0x79, 0x8a, 0x3f, 0x00, 0x00, 0x00, 0xf4, 0x11, 0x85, 0x06, 0x39, 0x08,
+ 0x7d, 0x00, 0x00, 0x18, 0xb7, 0x10, 0x81, 0x03, 0x29, 0x12, 0xcb, 0x00,
+ 0x7e, 0x30, 0x28, 0x00, 0x85, 0x03, 0x29, 0x10, 0xbe, 0x81, 0xff, 0x27,
+ 0x0c, 0x10, 0x85, 0x03, 0x29, 0x32, 0xfa, 0xc1, 0xff, 0x27, 0x94, 0x11,
+ 0x85, 0x03, 0x28, 0x20, 0x6c, 0xe1, 0xff, 0x07, 0x0c, 0x01, 0x85, 0x01,
+ 0x28, 0x62, 0x5c, 0xe3, 0x8f, 0x03, 0x4e, 0x91, 0x80, 0x05, 0x39, 0x40,
+ 0xf4, 0xc2, 0xff, 0x00, 0x9f, 0x91, 0x84, 0x05, 0x31, 0xc6, 0xe8, 0x07,
+ 0x7f, 0x80, 0xcd, 0x00, 0xc4, 0x04, 0x31, 0x06, 0xc9, 0x0e, 0x00, 0xc0,
+ 0x48, 0x88, 0xe0, 0x04, 0x79, 0x04, 0xdb, 0x12, 0x00, 0x30, 0x0c, 0xc8,
+ 0xe4, 0x04, 0x6d, 0x06, 0xb6, 0x23, 0x00, 0x18, 0x1c, 0xc0, 0x84, 0x04,
+ 0x25, 0x0c, 0xff, 0xc2, 0x00, 0x4e, 0x06, 0xb0, 0x80, 0x04, 0x3f, 0x8a,
+ 0xb3, 0x83, 0xff, 0xc3, 0x03, 0x91, 0x84, 0x04, 0x2e, 0xd8, 0x0f, 0x3f,
+ 0x00, 0x00, 0x5f, 0x83, 0x84, 0x04, 0x2a, 0x70, 0xfd, 0x7f, 0x00, 0x00,
+ 0xc8, 0xc0, 0x84, 0x04, 0x4b, 0xe2, 0x2f, 0x01, 0x00, 0x08, 0x58, 0x60,
+ 0x80, 0x04, 0x5b, 0x82, 0xff, 0x01, 0x00, 0x08, 0xd0, 0xa0, 0x84, 0x04,
+ 0x72, 0x80, 0xe5, 0x00, 0x00, 0x08, 0xd2, 0x20, 0x44, 0x04, 0xca, 0x02,
+ 0xff, 0x00, 0x00, 0x08, 0xde, 0xa0, 0x44, 0x04, 0x82, 0x02, 0x6d, 0x00,
+ 0x00, 0x08, 0xf6, 0xb0, 0x40, 0x02, 0x82, 0x07, 0x3f, 0x00, 0x00, 0x08,
+ 0x44, 0x58, 0x44, 0x02, 0x93, 0x3f, 0x1f, 0x00, 0x00, 0x30, 0x88, 0x4f,
+ 0x44, 0x03, 0x83, 0x23, 0x3e, 0x00, 0x00, 0x00, 0x18, 0x60, 0xe0, 0x07,
+ 0xe3, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x70, 0x70, 0xe4, 0x07, 0xc7, 0x1b,
+ 0xfe, 0x01, 0x00, 0x00, 0xe0, 0x3c, 0xe4, 0x07, 0xc7, 0xe3, 0xfe, 0x1f,
+ 0x00, 0x00, 0xff, 0x1f, 0xfc, 0x07, 0xc7, 0x03, 0xf8, 0x33, 0x00, 0xc0,
+ 0xf0, 0x07, 0xff, 0x07, 0x87, 0x02, 0xfc, 0x43, 0x00, 0x60, 0xf0, 0xff,
+ 0xff, 0x07, 0x8f, 0x06, 0xbe, 0x87, 0x00, 0x30, 0xf8, 0xff, 0xff, 0x07,
+ 0x8f, 0x14, 0x9c, 0x8f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x07, 0x9f, 0x8d,
+ 0x8a, 0x0f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xbf, 0x0b, 0x80, 0x1f,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x7f, 0x3a, 0x80, 0x3f, 0x00, 0x80,
+ 0xff, 0xff, 0xff, 0x07, 0xff, 0x20, 0xc0, 0x3f, 0x00, 0x80, 0xff, 0xff,
+ 0xff, 0x07, 0xff, 0x01, 0xe0, 0x7f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x07,
+ 0xff, 0x0f, 0xf8, 0xff, 0x40, 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff,
+ 0xff, 0xff, 0x40, 0xf0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0xf0, 0xff, 0xff, 0xff, 0x07};
diff --git a/test/style.C b/test/style.C
new file mode 100644
index 000000000..9e8d24535
--- /dev/null
+++ b/test/style.C
@@ -0,0 +1,141 @@
+// style.C
+
+// Demo of a control panel for Fltk "style" changes.
+
+// You can use this as-is, or modify it to your needs.
+
+// To save & restore a style you should write the data to a file of
+// your own design. Most likely your program has it's own configuration
+// that you want to save as well, and it is user friendly to put all
+// this into the same file.
+
+////////////////////////////////////////////////////////////////
+// This is the part you want to copy to another program. The
+// program should call "show_style_panel()" in response to a button
+// that the user presses.
+
+#include "style_ui.C"
+
+#include <string.h>
+
+Fl_Menu_Item* font_menu() {
+ static Fl_Menu_Item* menu;
+ if (menu) return menu;
+ int k = Fl::set_fonts(/*"*"*/);
+ menu = new Fl_Menu_Item[k+1];
+ memset(menu, 0, (k+1)*sizeof(Fl_Menu_Item));
+ for (int i = 0; i < k; i++) {
+ int t; const char *name = Fl::get_font_name((Fl_Font)i,&t);
+ char buf[256];
+ strcpy(buf, name);
+ if (t & FL_BOLD) strcat(buf," bold");
+ if (t & FL_ITALIC) strcat(buf," italic");
+ menu[i].text = strdup(buf);
+ }
+ return menu;
+}
+
+void font_cb(Fl_Choice* c, long i) {
+ Fl_Font n = Fl_Font(c->value());
+ switch (i) {
+ case 2: Fl_Menu_::default_font(n); break;
+ case 1: Fl_Input_::default_font(n); break;
+ default: Fl_Widget::default_font(n); break;
+ }
+ Fl::redraw();
+}
+
+void font_size_cb(Fl_Value_Input* c, long i) {
+ int n = int(c->value()); if (n <= 0) n = 1; n -= FL_NORMAL_SIZE;
+ switch (i) {
+ case 2: Fl_Menu_::default_size(n); break;
+ case 1: Fl_Input_::default_size(n); break;
+ default: Fl_Widget::default_size(n); break;
+ }
+ Fl::redraw();
+}
+
+#include <FL/Fl_Color_Chooser.H>
+
+void color_button_cb(Fl_Button* w, void*) {
+ Fl_Color c = w->color();
+ uchar r,g,b; Fl::get_color(c, r,g,b);
+ if (fl_color_chooser(0,r,g,b)) {
+ if (c == FL_GRAY) Fl::background(r,g,b);
+ else Fl::set_color(c,r,g,b);
+ Fl::redraw();
+ }
+}
+
+// functions hidden inside fl_boxtype.C:
+void fl_thin_down_frame(int, int, int, int, Fl_Color);
+void fl_thin_up_frame(int, int, int, int, Fl_Color);
+void fl_thin_down_box(int, int, int, int, Fl_Color);
+void fl_thin_up_box(int, int, int, int, Fl_Color);
+void fl_down_frame(int, int, int, int, Fl_Color);
+void fl_up_frame(int, int, int, int, Fl_Color);
+void fl_down_box(int, int, int, int, Fl_Color);
+void fl_up_box(int, int, int, int, Fl_Color);
+
+// define the 2-pixel boxes:
+#include <FL/fl_draw.H>
+void fl_2_up_frame(int x, int y, int w, int h, Fl_Color) {
+ fl_frame2("AAPPMMWU",x,y,w,h);
+}
+void fl_2_up_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_2_up_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+2, y+2, w-4, h-4);
+}
+void fl_2_down_frame(int x, int y, int w, int h, Fl_Color) {
+ fl_frame2("UWMMPPAA",x,y,w,h);
+}
+void fl_2_down_box(int x, int y, int w, int h, Fl_Color c) {
+ fl_2_down_frame(x,y,w,h,c);
+ fl_color(c); fl_rectf(x+2, y+2, w-4, h-4);
+}
+
+void box_thickness_cb(Fl_Value_Slider*v, void*) {
+ switch (int(v->value())) {
+ case 1:
+ Fl::set_boxtype(FL_UP_BOX, fl_thin_up_box, 1,1,2,2);
+ Fl::set_boxtype(FL_DOWN_BOX, fl_thin_down_box, 1,1,2,2);
+ Fl::set_boxtype(FL_UP_FRAME, fl_thin_up_frame, 1,1,2,2);
+ Fl::set_boxtype(FL_DOWN_FRAME, fl_thin_down_frame, 1,1,2,2);
+ break;
+ case 2:
+ Fl::set_boxtype(FL_UP_BOX, fl_2_up_box, 2,2,4,4);
+ Fl::set_boxtype(FL_DOWN_BOX, fl_2_down_box, 2,2,4,4);
+ Fl::set_boxtype(FL_UP_FRAME, fl_2_up_frame, 2,2,4,4);
+ Fl::set_boxtype(FL_DOWN_FRAME, fl_2_down_frame, 2,2,4,4);
+ break;
+ default:
+ Fl::set_boxtype(FL_UP_BOX, fl_up_box, 3,3,6,6);
+ Fl::set_boxtype(FL_DOWN_BOX, fl_down_box, 3,3,6,6);
+ Fl::set_boxtype(FL_UP_FRAME, fl_up_frame, 3,3,6,6);
+ Fl::set_boxtype(FL_DOWN_FRAME, fl_down_frame, 3,3,6,6);
+ break;
+ }
+ Fl::redraw();
+}
+
+void text_box_thickness_cb(Fl_Value_Slider* v, void*) {
+ int n = int(v->value());
+ switch (n) {
+ case 0: Fl_Input_::default_box(FL_FLAT_BOX); break;
+ case 1: Fl_Input_::default_box(FL_THIN_DOWN_BOX); break;
+ case 2: Fl_Input_::default_box(FL_DOWN_BOX); break;
+ }
+ Fl::redraw();
+}
+
+void scrollbar_thickness_cb(Fl_Value_Slider* v, void*) {
+ Fl_Browser::scrollbar_width(int(v->value()));
+ Fl::redraw();
+}
+
+#include <FL/fl_ask.H>
+
+void defaults_cb(Fl_Button*, void*) {
+ fl_alert("Sorry, I didn't implement that");
+}
+
diff --git a/test/style_ui.C b/test/style_ui.C
new file mode 100644
index 000000000..65d52b883
--- /dev/null
+++ b/test/style_ui.C
@@ -0,0 +1,273 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "style_ui.H"
+
+Fl_Window *style_panel;
+
+static void cb_OK(Fl_Return_Button* o, void*) {
+ o->window()->hide();
+}
+
+static void cb_Quit(Fl_Menu_*, void*) {
+ exit(0);
+}
+
+Fl_Menu_Item menu_[] = {
+ {"File", 0, 0, 0, 64, 0, 0, 14, 0},
+ {"Open", 0x8006f, 0, 0, 0, 0, 0, 14, 0},
+ {"Save", 0x80073, 0, 0, 0, 0, 0, 14, 0},
+ {"Merge", 0, 0, 0, 0, 0, 0, 14, 0},
+ {"Quit", 0x80071, (Fl_Callback*)cb_Quit, 0, 0, 0, 0, 14, 0},
+ {0},
+ {"Edit", 0, 0, 0, 64, 0, 0, 14, 0},
+ {"Undo", 0x8007a, 0, 0, 0, 0, 0, 14, 0},
+ {"Cut", 0x80078, 0, 0, 0, 0, 0, 14, 0},
+ {"Copy", 0x80076, 0, 0, 0, 0, 0, 14, 0},
+ {"Paste", 0x80076, 0, 0, 0, 0, 0, 14, 0},
+ {0},
+ {"Font", 0, 0, 0, 64, 0, 0, 14, 0},
+ {"Normal", 0, 0, 0, 0, 0, 0, 14, 0},
+ {"Bold", 0, 0, 0, 0, 0, 1, 14, 0},
+ {"Italic", 0, 0, 0, 0, 0, 2, 14, 0},
+ {"Bold Italic", 0, 0, 0, 0, 0, 0, 14, 0},
+ {"Engrave", 0, 0, 0, 0, 4, 0, 14, 0},
+ {"Emboss", 0, 0, 0, 0, 5, 0, 14, 0},
+ {"@->", 0, 0, 0, 0, 2, 0, 14, 0},
+ {"Small", 0, 0, 0, 0, 0, 0, 10, 0},
+ {0},
+ {"Other", 0, 0, 0, 64, 0, 0, 14, 0},
+ {"help!", 0, 0, 0, 0, 0, 0, 14, 0},
+ {0},
+ {0}
+};
+
+static void cb_click(Fl_Button*, void*) {
+ show_style_panel();
+}
+static Fl_Menu_Item* font_menu();
+
+void show_style_panel() {
+ Fl_Window *w;
+ if (!style_panel) {
+ { Fl_Window* o = style_panel = w = new Fl_Double_Window(335, 425, "style");
+ { Fl_Choice* o = new Fl_Choice(60, 155, 220, 25, "labels:");
+ o->callback((Fl_Callback*)font_cb, (void*)(0));
+ o->menu(font_menu());
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(280, 155, 50, 25);
+ o->minimum(1);
+ o->maximum(128);
+ o->step(1);
+ o->value(14);
+ o->callback((Fl_Callback*)font_size_cb, (void*)(0));
+ o->when(4);
+ }
+ { Fl_Choice* o = new Fl_Choice(60, 190, 220, 25, "text:");
+ o->callback((Fl_Callback*)font_cb, (void*)(1));
+ o->menu(font_menu());
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(280, 190, 50, 25);
+ o->minimum(1);
+ o->maximum(128);
+ o->step(1);
+ o->value(14);
+ o->callback((Fl_Callback*)font_size_cb, (void*)(1));
+ o->when(4);
+ }
+ { Fl_Choice* o = new Fl_Choice(60, 225, 220, 25, "menus:");
+ o->callback((Fl_Callback*)font_cb, (void*)(2));
+ o->menu(font_menu());
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(280, 225, 50, 25);
+ o->minimum(1);
+ o->maximum(128);
+ o->step(1);
+ o->value(14);
+ o->callback((Fl_Callback*)font_size_cb, (void*)(2));
+ o->when(4);
+ }
+ { Fl_Button* o = new Fl_Button(255, 30, 75, 25, "background:");
+ o->box(FL_ENGRAVED_BOX);
+ o->callback((Fl_Callback*)color_button_cb);
+ o->align(4);
+ }
+ { Fl_Button* o = new Fl_Button(255, 60, 75, 25, "foreground:");
+ o->box(FL_ENGRAVED_BOX);
+ o->color(0);
+ o->callback((Fl_Callback*)color_button_cb);
+ o->align(4);
+ }
+ { Fl_Button* o = new Fl_Button(255, 90, 75, 25, "text background:");
+ o->box(FL_ENGRAVED_BOX);
+ o->color(7);
+ o->callback((Fl_Callback*)color_button_cb);
+ o->align(4);
+ }
+ { Fl_Button* o = new Fl_Button(255, 120, 75, 25, "selection:");
+ o->box(FL_ENGRAVED_BOX);
+ o->color(15);
+ o->callback((Fl_Callback*)color_button_cb);
+ o->align(4);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(260, 395, 70, 25, "OK");
+ o->callback((Fl_Callback*)cb_OK);
+ }
+ { Fl_Button* o = new Fl_Button(175, 395, 70, 25, "defaults");
+ o->callback((Fl_Callback*)defaults_cb);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(235, 260, 95, 25, "box thickness:");
+ o->type(1);
+ o->minimum(1);
+ o->maximum(3);
+ o->step(1);
+ o->value(3);
+ o->slider_size(0.3333);
+ o->callback((Fl_Callback*)box_thickness_cb);
+ o->align(4);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(235, 295, 95, 25, "text box thickness:");
+ o->type(1);
+ o->maximum(2);
+ o->step(1);
+ o->value(2);
+ o->slider_size(0.3333);
+ o->callback((Fl_Callback*)text_box_thickness_cb);
+ o->align(4);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(235, 335, 95, 25, "scrollbar thickness:");
+ o->type(1);
+ o->minimum(3);
+ o->maximum(30);
+ o->step(1);
+ o->value(17);
+ o->callback((Fl_Callback*)scrollbar_thickness_cb);
+ o->align(4);
+ }
+ o->end();
+ }
+ }
+ style_panel->show();
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ { Fl_Window* o = w = new Fl_Double_Window(445, 435);
+ { Fl_Group* o = new Fl_Group(270, 35, 140, 75, "Packed buttons:");
+ o->align(4);
+ { Fl_Button* o = new Fl_Button(270, 35, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(305, 35, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(340, 35, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(375, 35, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(270, 60, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(305, 60, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(340, 60, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(375, 60, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(270, 85, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(305, 85, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(340, 85, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(375, 85, 35, 25, "A");
+ o->type(102);
+ }
+ o->end();
+ }
+ { Fl_Adjuster* o = new Fl_Adjuster(105, 90, 75, 25);
+ o->labeltype(FL_ENGRAVED_LABEL);
+ o->align(4);
+ }
+ { Fl_Counter* o = new Fl_Counter(20, 120, 170, 25, "counter");
+ o->minimum(-1e+06);
+ o->maximum(1e+06);
+ }
+ { Fl_Adjuster* o = new Fl_Adjuster(80, 40, 25, 75, "adjuster:");
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->align(4);
+ }
+ { Fl_Group* o = new Fl_Group(270, 130, 140, 75, "Inactive buttons:");
+ o->align(4);
+ o->deactivate();
+ { Fl_Button* o = new Fl_Button(270, 130, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(305, 130, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(340, 130, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(375, 130, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(270, 155, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(305, 155, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(340, 155, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(375, 155, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(270, 180, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(305, 180, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(340, 180, 35, 25, "A");
+ o->type(102);
+ }
+ { Fl_Button* o = new Fl_Button(375, 180, 35, 25, "A");
+ o->type(102);
+ }
+ o->end();
+ }
+ { Fl_Input* o = new Fl_Input(65, 175, 200, 25, "input:");
+ o->static_value("This is a text input field");
+ }
+ { Fl_Output* o = new Fl_Output(65, 200, 200, 25, "output:");
+ o->static_value("This is a text output field");
+ }
+ { Fl_Menu_Bar* o = new Fl_Menu_Bar(0, 0, 445, 30);
+ o->menu(menu_);
+ }
+ { Fl_Browser* o = new Fl_Browser(0, 235, 440, 200);
+ o->type(3);
+ Fl_Group::current()->resizable(o);
+ o->load("browser.C");
+ o->position(0);
+ }
+ { Fl_Button* o = new Fl_Button(235, 2, 170, 25, "click this to set style");
+ o->color(12);
+ o->selection_color(12);
+ o->callback((Fl_Callback*)cb_click);
+ }
+ o->end();
+ }
+ Fl::visual(FL_RGB);
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/style_ui.H b/test/style_ui.H
new file mode 100644
index 000000000..78a9f55d7
--- /dev/null
+++ b/test/style_ui.H
@@ -0,0 +1,27 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Adjuster.H>
+#include <FL/Fl_Browser.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Counter.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Value_Input.H>
+#include <FL/Fl_Value_Slider.H>
+#include <stdlib.h>
+extern void box_thickness_cb(Fl_Value_Slider*, void*);
+extern void color_button_cb(Fl_Button*, void*);
+extern void defaults_cb(Fl_Button*, void*);
+extern void font_cb(Fl_Choice*, long);
+extern void font_size_cb(Fl_Value_Input*, long);
+extern void scrollbar_thickness_cb(Fl_Value_Slider*, void*);
+extern void text_box_thickness_cb(Fl_Value_Slider*, void*);
+extern Fl_Window *style_panel;
+void show_style_panel();
+extern Fl_Menu_Item menu_[];
diff --git a/test/style_ui.fl b/test/style_ui.fl
new file mode 100644
index 000000000..7eb67ef15
--- /dev/null
+++ b/test/style_ui.fl
@@ -0,0 +1,343 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+header_name {.H}
+code_name {.C}
+gridx 5
+gridy 5
+snap 3
+decl {Fl_Menu_Item* font_menu();} {}
+
+Function {show_style_panel()} {open
+} {
+ codeblock {if (!style_panel)} {open
+ } {
+ Fl_Window style_panel {
+ label style
+ xywh {767 205 335 425} type Double visible
+ } {
+ Fl_Choice {} {
+ label {labels:}
+ user_data 0 user_data_type long
+ callback font_cb open
+ xywh {60 155 220 25}
+ code0 {o->menu(font_menu());}
+ } {}
+ Fl_Value_Input {} {
+ user_data 0 user_data_type long
+ callback font_size_cb
+ xywh {280 155 50 25} when 4 minimum 1 maximum 128 step 1 value 14
+ }
+ Fl_Choice {} {
+ label {text:}
+ user_data 1 user_data_type long
+ callback font_cb open
+ xywh {60 190 220 25}
+ code0 {o->menu(font_menu());}
+ } {}
+ Fl_Value_Input {} {
+ user_data 1 user_data_type long
+ callback font_size_cb
+ xywh {280 190 50 25} when 4 minimum 1 maximum 128 step 1 value 14
+ }
+ Fl_Choice {} {
+ label {menus:}
+ user_data 2 user_data_type long
+ callback font_cb open
+ xywh {60 225 220 25}
+ code0 {o->menu(font_menu());}
+ } {}
+ Fl_Value_Input {} {
+ user_data 2 user_data_type long
+ callback font_size_cb
+ xywh {280 225 50 25} when 4 minimum 1 maximum 128 step 1 value 14
+ }
+ Fl_Button {} {
+ label {background:}
+ callback color_button_cb
+ xywh {255 30 75 25} box ENGRAVED_BOX align 4
+ }
+ Fl_Button {} {
+ label {foreground:}
+ callback color_button_cb
+ xywh {255 60 75 25} box ENGRAVED_BOX color 0 align 4
+ }
+ Fl_Button {} {
+ label {text background:}
+ callback color_button_cb
+ xywh {255 90 75 25} box ENGRAVED_BOX color 7 align 4
+ }
+ Fl_Button {} {
+ label {selection:}
+ callback color_button_cb
+ xywh {255 120 75 25} box ENGRAVED_BOX color 15 align 4
+ }
+ Fl_Return_Button {} {
+ label OK
+ callback {o->window()->hide();}
+ xywh {260 395 70 25}
+ }
+ Fl_Button {} {
+ label defaults
+ callback defaults_cb
+ xywh {175 395 70 25}
+ }
+ Fl_Value_Slider {} {
+ label {box thickness:}
+ callback box_thickness_cb
+ xywh {235 260 95 25} type Horizontal align 4 minimum 1 maximum 3 step 1 value 3 slider_size 0.3333
+ }
+ Fl_Value_Slider {} {
+ label {text box thickness:}
+ callback text_box_thickness_cb
+ xywh {235 295 95 25} type Horizontal align 4 maximum 2 step 1 value 2 slider_size 0.3333
+ }
+ Fl_Value_Slider {} {
+ label {scrollbar thickness:}
+ callback scrollbar_thickness_cb
+ xywh {235 335 95 25} type Horizontal align 4 minimum 3 maximum 30 step 1 value 17
+ }
+ }
+ }
+ code {style_panel->show();} {}
+}
+
+Function {} {open
+} {
+ Fl_Window {} {open
+ xywh {356 409 445 435} type Double resizable visible
+ } {
+ Fl_Group {} {
+ label {Packed buttons:}
+ xywh {270 35 140 75} align 4
+ } {
+ Fl_Button {} {
+ label A
+ xywh {270 35 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {305 35 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {340 35 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {375 35 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {270 60 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {305 60 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {340 60 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {375 60 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {270 85 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {305 85 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {340 85 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {375 85 35 25} type Radio
+ }
+ }
+ Fl_Adjuster {} {
+ xywh {105 90 75 25} labeltype ENGRAVED_LABEL align 4
+ }
+ Fl_Counter {} {
+ label counter
+ xywh {20 120 170 25} minimum -1e+06 maximum 1e+06
+ }
+ Fl_Adjuster {} {
+ label {adjuster:}
+ xywh {80 40 25 75} labeltype SYMBOL_LABEL align 4
+ }
+ Fl_Group {} {
+ label {Inactive buttons:}
+ xywh {270 130 140 75} align 4 deactivate
+ } {
+ Fl_Button {} {
+ label A
+ xywh {270 130 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {305 130 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {340 130 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {375 130 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {270 155 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {305 155 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {340 155 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {375 155 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {270 180 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {305 180 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {340 180 35 25} type Radio
+ }
+ Fl_Button {} {
+ label A
+ xywh {375 180 35 25} type Radio
+ }
+ }
+ Fl_Input {} {
+ label {input:}
+ xywh {65 175 200 25}
+ code0 {o->static_value("This is a text input field");}
+ }
+ Fl_Output {} {
+ label {output:}
+ xywh {65 200 200 25}
+ code0 {o->static_value("This is a text output field");}
+ }
+ Fl_Menu_Bar {} {
+ xywh {0 0 445 30}
+ } {
+ submenu {} {
+ label File
+ xywh {0 0 100 20}
+ } {
+ menuitem {} {
+ label Open
+ xywh {0 0 100 20} shortcut 0x8006f
+ }
+ menuitem {} {
+ label Save
+ xywh {10 10 100 20} shortcut 0x80073
+ }
+ menuitem {} {
+ label Merge
+ xywh {20 20 100 20}
+ }
+ menuitem {} {
+ label Quit
+ callback {exit(0);}
+ xywh {30 30 100 20} shortcut 0x80071
+ code0 {\#include <stdlib.h>}
+ }
+ }
+ submenu {} {
+ label Edit open
+ xywh {0 0 100 20}
+ } {
+ menuitem {} {
+ label Undo
+ xywh {75 75 100 20} shortcut 0x8007a
+ }
+ menuitem {} {
+ label Cut
+ xywh {45 45 100 20} shortcut 0x80078
+ }
+ menuitem {} {
+ label Copy
+ xywh {55 55 100 20} shortcut 0x80076
+ }
+ menuitem {} {
+ label Paste
+ xywh {65 65 100 20} shortcut 0x80076
+ }
+ }
+ submenu {} {
+ label Font
+ xywh {10 10 100 20}
+ } {
+ menuitem {} {
+ label Normal
+ xywh {0 0 100 20}
+ }
+ menuitem {} {
+ label Bold
+ xywh {10 10 100 20} labelfont 1
+ }
+ menuitem {} {
+ label Italic
+ xywh {20 20 100 20} labelfont 2
+ }
+ menuitem {} {
+ label {Bold Italic}
+ xywh {30 30 100 20}
+ }
+ menuitem {} {
+ label Engrave
+ xywh {40 40 100 20} labeltype ENGRAVED_LABEL
+ }
+ menuitem {} {
+ label Emboss
+ xywh {50 50 100 20} labeltype EMBOSSED_LABEL
+ }
+ menuitem {} {
+ label {@->}
+ xywh {60 60 100 20} labeltype SYMBOL_LABEL
+ }
+ menuitem {} {
+ label Small
+ xywh {70 70 100 20} labelsize 10
+ }
+ }
+ submenu {} {
+ label Other
+ xywh {20 20 100 20}
+ } {
+ menuitem {} {
+ label {help!}
+ xywh {0 0 100 20}
+ }
+ }
+ }
+ Fl_Browser {} {
+ xywh {0 235 440 200} type Multi resizable
+ code0 {o->load("browser.C");}
+ code1 {o->position(0);}
+ }
+ Fl_Button {} {
+ label {click this to set style}
+ callback {show_style_panel();}
+ xywh {235 2 170 25} color 12 selection_color 12
+ }
+ }
+ code {Fl::visual(FL_RGB);} {selected
+ }
+}
diff --git a/test/subwindow.cxx b/test/subwindow.cxx
new file mode 100644
index 000000000..9644b457d
--- /dev/null
+++ b/test/subwindow.cxx
@@ -0,0 +1,107 @@
+// Test to make sure nested windows work.
+// Events should be reported for enter/exit and all mouse operations
+// Buttons and pop-up menu should work, indicating that mouse positions
+// are being correctly translated.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+
+class testwindow : public Fl_Window {
+ int handle(int);
+ void draw();
+public:
+ testwindow(Fl_Boxtype b,int x,int y,const char *l)
+ : Fl_Window(x,y,l) {box(b);}
+ testwindow(Fl_Boxtype b,int x,int y,int w,int h,const char *l)
+ : Fl_Window(x,y,w,h,l) {box(b);}
+};
+
+void testwindow::draw() {
+#ifdef DEBUG
+ printf("%s : draw\n",label());
+#endif
+ Fl_Window::draw();
+}
+
+class EnterExit : public Fl_Box {
+ int handle(int);
+public:
+ EnterExit(int x, int y, int w, int h, const char *l) : Fl_Box(FL_BORDER_BOX,x,y,w,h,l) {}
+};
+
+int EnterExit::handle(int e) {
+ if (e == FL_ENTER) {color(FL_RED); redraw(); return 1;}
+ else if (e == FL_LEAVE) {color(FL_GRAY); redraw(); return 1;}
+ else return 0;
+}
+
+#ifdef DEBUG
+const char *eventnames[] = {
+"zero",
+"FL_PUSH",
+"FL_RELEASE",
+"FL_ENTER",
+"FL_LEAVE",
+"FL_DRAG",
+"FL_FOCUS",
+"FL_UNFOCUS",
+"FL_KEYBOARD",
+"9",
+"FL_MOVE",
+"FL_SHORTCUT",
+"12",
+"FL_DEACTIVATE",
+"FL_ACTIVATE",
+"FL_HIDE",
+"FL_SHOW",
+"FL_PASTE",
+"FL_SELECTIONCLEAR",
+};
+#endif
+
+Fl_Menu_Button* popup;
+
+int testwindow::handle(int e) {
+#ifdef DEBUG
+ if (e != FL_MOVE) printf("%s : %s\n",label(),eventnames[e]);
+#endif
+ if (Fl_Window::handle(e)) return 1;
+ // if (e==FL_PUSH) return popup->handle(e);
+ return 0;
+}
+
+int main(int, char **) {
+ testwindow *window =
+ new testwindow(FL_UP_BOX,400,400,"outer");
+ new Fl_Toggle_Button(310,310,80,80,"&outer");
+ new EnterExit(10,310,80,80,"enterexit");
+ new Fl_Input(150,310,150,25,"input:");
+ (new Fl_Menu_Button(5,150,80,25,"menu&1"))->add("this|is|only|a test");
+ testwindow *subwindow =
+ new testwindow(FL_DOWN_BOX,100,100,200,200,"inner");
+ new Fl_Toggle_Button(110,110,80,80,"&inner");
+ new EnterExit(10,110,80,80,"enterexit");
+ (new Fl_Menu_Button(50,50,80,25,"menu&2"))->add("this|is|only|a test");
+ new Fl_Input(45,80,150,25,"input:");
+ subwindow->resizable(subwindow);
+ window->resizable(subwindow);
+ subwindow->end();
+ (new Fl_Box(FL_NO_BOX,0,0,400,100,
+ "A child Fl_Window with children of it's own may "
+ "be useful for imbedding controls into a GL or display "
+ "that needs a different visual. There are bugs with the "
+ "origins being different between drawing and events, "
+ "which I hope I have solved."
+ )) -> align(FL_ALIGN_WRAP);
+ popup = new Fl_Menu_Button(0,0,400,400);
+ popup->type(Fl_Menu_Button::POPUP3);
+ popup->add("This|is|a popup|menu");
+ window->show();
+ return Fl::run();
+}
diff --git a/test/symbols.cxx b/test/symbols.cxx
new file mode 100644
index 000000000..b66e6e142
--- /dev/null
+++ b/test/symbols.cxx
@@ -0,0 +1,62 @@
+// produce diagram used in the documentation:
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Single_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/fl_draw.H>
+
+int N = 0;
+#define W 60
+#define H 60
+#define ROWS 5
+#define COLS 5
+
+Fl_Window *window;
+
+void bt(const char *name) {
+ int x = N%COLS;
+ int y = N/COLS;
+ N++;
+ x = x*W+10;
+ y = y*H+10;
+ Fl_Box *a = new Fl_Box(FL_NO_BOX,x,y,W-20,H-20,name);
+ a->align(FL_ALIGN_BOTTOM);
+ a->labelsize(11);
+ Fl_Box *b = new Fl_Box(FL_UP_BOX,x,y,W-20,H-20,name);
+ b->labeltype(FL_SYMBOL_LABEL);
+ b->labelcolor(FL_DARK3);
+}
+
+int main(int argc, char ** argv) {
+ window = new Fl_Single_Window(COLS*W,ROWS*H+20);
+bt("@->");
+bt("@>");
+bt("@>>");
+bt("@>|");
+bt("@>[]");
+bt("@|>");
+bt("@<-");
+bt("@<");
+bt("@<<");
+bt("@|<");
+bt("@[]<");
+bt("@<|");
+bt("@<->");
+bt("@-->");
+bt("@+");
+bt("@->|");
+bt("@||");
+bt("@arrow");
+bt("@returnarrow");
+bt("@square");
+bt("@circle");
+bt("@line");
+bt("@menu");
+bt("@UpArrow");
+bt("@DnArrow");
+ window->resizable(window);
+ window->show(argc,argv);
+ return Fl::run();
+}
diff --git a/test/tabs.C b/test/tabs.C
new file mode 100644
index 000000000..239510458
--- /dev/null
+++ b/test/tabs.C
@@ -0,0 +1,84 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "tabs.H"
+
+Fl_Window *foo_window;
+
+static void cb_cancel(Fl_Button*, void*) {
+ exit(1);
+}
+
+static void cb_OK(Fl_Return_Button*, void*) {
+ exit(0);
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ { Fl_Window* o = new Fl_Window(321, 324);
+ w = foo_window = o;
+ Fl_Group::current()->resizable(o);
+ { Fl_Tabs* o = new Fl_Tabs(10, 10, 300, 200);
+ o->color2(15);
+ Fl_Group::current()->resizable(o);
+ { Fl_Group* o = new Fl_Group(10, 30, 300, 180, "Label1");
+ o->hide();
+ Fl_Group::current()->resizable(o);
+ new Fl_Input(60, 50, 240, 40, "input:");
+ new Fl_Input(60, 90, 240, 30, "input2:");
+ new Fl_Input(60, 120, 240, 80, "input3:");
+ o->end();
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Group* o = new Fl_Group(10, 30, 300, 180, "tab2");
+ o->hide();
+ new Fl_Button(20, 60, 100, 30, "button1");
+ new Fl_Input(140, 100, 100, 30, "input in box2");
+ new Fl_Button(30, 140, 260, 30, "This is stuff inside the Fl_Group \"tab2\"");
+ o->end();
+ }
+ { Fl_Group* o = new Fl_Group(10, 30, 300, 180, "tab3");
+ o->hide();
+ new Fl_Button(20, 60, 60, 80, "button2");
+ new Fl_Button(80, 60, 60, 80, "button");
+ new Fl_Button(140, 60, 60, 80, "button");
+ o->end();
+ }
+ { Fl_Group* o = new Fl_Group(10, 30, 300, 180, "tab4");
+ o->labelfont(2);
+ o->hide();
+ new Fl_Button(20, 50, 60, 110, "button2");
+ new Fl_Button(80, 50, 60, 110, "button");
+ new Fl_Button(140, 50, 60, 110, "button");
+ o->end();
+ }
+ { Fl_Group* o = new Fl_Group(10, 30, 300, 180, " tab5 ");
+ o->labeltype(FL_ENGRAVED_LABEL);
+ new Fl_Button(20, 80, 60, 80, "button2");
+ new Fl_Button(90, 90, 60, 80, "button");
+ { Fl_Clock* o = new Fl_Clock(160, 50, 100, 100, "Make sure this clock does not use processor time when this tab is hidden o\
+r window is iconized");
+ o->box(FL_OSHADOW_BOX);
+ o->color(238);
+ o->color2(0);
+ o->labelfont(8);
+ o->labelsize(10);
+ o->align(130);
+ }
+ o->end();
+ }
+ o->end();
+ Fl_Group::current()->resizable(o);
+ }
+ new Fl_Input(60, 220, 130, 30, "inputA:");
+ new Fl_Input(60, 250, 250, 30, "inputB:");
+ { Fl_Button* o = new Fl_Button(180, 290, 60, 30, "cancel");
+ o->callback((Fl_Callback*)cb_cancel);
+ }
+ { Fl_Return_Button* o = new Fl_Return_Button(250, 290, 60, 30, "OK");
+ o->callback((Fl_Callback*)cb_OK);
+ }
+ w->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/tabs.H b/test/tabs.H
new file mode 100644
index 000000000..2ec7bc12c
--- /dev/null
+++ b/test/tabs.H
@@ -0,0 +1,12 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Clock.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Window.H>
+#include <stdlib.h>
+extern Fl_Window *foo_window;
diff --git a/test/tabs.fl b/test/tabs.fl
new file mode 100644
index 000000000..13b97796a
--- /dev/null
+++ b/test/tabs.fl
@@ -0,0 +1,121 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+gridx 10
+gridy 10
+snap 3
+Function {} {open
+} {
+ Fl_Window foo_window {open
+ xywh {329 266 321 324} hide resizable
+ } {
+ Fl_Tabs {} {open
+ xywh {10 10 300 200} color {47 15} resizable
+ } {
+ Fl_Group {} {
+ label Label1 open
+ xywh {10 30 300 180} hide resizable
+ } {
+ Fl_Input {} {
+ label {input:}
+ xywh {60 50 240 40}
+ }
+ Fl_Input {} {
+ label {input2:}
+ xywh {60 90 240 30}
+ }
+ Fl_Input {} {
+ label {input3:}
+ xywh {60 120 240 80}
+ }
+ }
+ Fl_Group {} {
+ label tab2 open
+ xywh {10 30 300 180} hide
+ } {
+ Fl_Button {} {
+ label button1
+ xywh {20 60 100 30}
+ }
+ Fl_Input {} {
+ label {input in box2}
+ xywh {140 100 100 30}
+ }
+ Fl_Button {} {
+ label {This is stuff inside the Fl_Group "tab2"} selected
+ xywh {30 140 260 30}
+ }
+ }
+ Fl_Group {} {
+ label tab3 open
+ xywh {10 30 300 180} hide
+ } {
+ Fl_Button {} {
+ label button2
+ xywh {20 60 60 80}
+ }
+ Fl_Button {} {
+ label button
+ xywh {80 60 60 80}
+ }
+ Fl_Button {} {
+ label button
+ xywh {140 60 60 80}
+ }
+ }
+ Fl_Group {} {
+ label tab4 open
+ xywh {10 30 300 180} labelfont 2 hide
+ } {
+ Fl_Button {} {
+ label button2
+ xywh {20 50 60 110}
+ }
+ Fl_Button {} {
+ label button
+ xywh {80 50 60 110}
+ }
+ Fl_Button {} {
+ label button
+ xywh {140 50 60 110}
+ }
+ }
+ Fl_Group {} {
+ label { tab5 } open
+ xywh {10 30 300 180} labeltype ENGRAVED_LABEL
+ } {
+ Fl_Button {} {
+ label button2
+ xywh {20 80 60 80}
+ }
+ Fl_Button {} {
+ label button
+ xywh {90 90 60 80}
+ }
+ Fl_Clock {} {
+ label {Make sure this clock does not use processor time when this tab is hidden or window is iconized}
+ xywh {160 50 100 100} box OSHADOW_BOX color {238 0} labelfont 8 labelsize 10 align 130
+ }
+ }
+ }
+ Fl_Input {} {
+ label {inputA:}
+ xywh {60 220 130 30}
+ }
+ Fl_Input {} {
+ label {inputB:}
+ xywh {60 250 250 30}
+ }
+ Fl_Button {} {
+ label cancel
+ callback {exit(1);}
+ xywh {180 290 60 30}
+ code0 {\#include <stdlib.h>}
+ }
+ Fl_Return_Button {} {
+ label OK
+ callback {exit(0);}
+ xywh {250 290 60 30}
+ code0 {\#include <stdlib.h>}
+ }
+ }
+}
diff --git a/test/tile.cxx b/test/tile.cxx
new file mode 100755
index 000000000..e5364fe1b
--- /dev/null
+++ b/test/tile.cxx
@@ -0,0 +1,61 @@
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_Box.H>
+
+int main(int argc, char** argv) {
+ Fl_Window window(300,300);
+ window.box(FL_NO_BOX);
+ window.resizable(window);
+ Fl_Tile tile(0,0,300,300);
+ Fl_Box box0(0,0,150,150,"0");
+ box0.box(FL_DOWN_BOX);
+ box0.color(9);
+ box0.labelsize(36);
+ box0.align(FL_ALIGN_CLIP);
+ Fl_Window w1(150,0,150,150,"1");
+ w1.box(FL_NO_BOX);
+ Fl_Box box1(0,0,150,150,"1\nThis is a\nchild\nX window");
+ box1.box(FL_DOWN_BOX);
+ box1.color(19);
+ box1.labelsize(18);
+ box1.align(FL_ALIGN_CLIP);
+ w1.resizable(box1);
+ w1.end();
+
+ // Fl_Tile tile2(0,150,150,150);
+ Fl_Box box2a(0,150,70,150,"2a");
+ box2a.box(FL_DOWN_BOX);
+ box2a.color(12);
+ box2a.labelsize(36);
+ box2a.align(FL_ALIGN_CLIP);
+ Fl_Box box2b(70,150,80,150,"2b");
+ box2b.box(FL_DOWN_BOX);
+ box2b.color(13);
+ box2b.labelsize(36);
+ box2b.align(FL_ALIGN_CLIP);
+ //tile2.end();
+
+ //Fl_Tile tile3(150,150,150,150);
+ Fl_Box box3a(150,150,150,70,"3a");
+ box3a.box(FL_DOWN_BOX);
+ box3a.color(12);
+ box3a.labelsize(36);
+ box3a.align(FL_ALIGN_CLIP);
+ Fl_Box box3b(150,150+70,150,80,"3b");
+ box3b.box(FL_DOWN_BOX);
+ box3b.color(13);
+ box3b.labelsize(36);
+ box3b.align(FL_ALIGN_CLIP);
+ //tile3.end();
+
+ Fl_Box r(10,0,300-10,300-10);
+ tile.resizable(r);
+ // r.box(FL_BORDER_FRAME);
+
+ tile.end();
+ window.end();
+ window.show(argc,argv);
+ w1.show();
+ return Fl::run();
+}
diff --git a/test/trackball.c b/test/trackball.c
new file mode 100644
index 000000000..f23d3db30
--- /dev/null
+++ b/test/trackball.c
@@ -0,0 +1,324 @@
+/*
+ * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States. Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * Trackball code:
+ *
+ * Implementation of a virtual trackball.
+ * Implemented by Gavin Bell, lots of ideas from Thant Tessman and
+ * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
+ *
+ * Vector manip code:
+ *
+ * Original code from:
+ * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
+ *
+ * Much mucking with by:
+ * Gavin Bell
+ */
+#include <math.h>
+#include "trackball.h"
+
+/*
+ * This size should really be based on the distance from the center of
+ * rotation to the point on the object underneath the mouse. That
+ * point would then track the mouse as closely as possible. This is a
+ * simple example, though, so that is left as an Exercise for the
+ * Programmer.
+ */
+#define TRACKBALLSIZE (0.8)
+
+/*
+ * Local function prototypes (not defined in trackball.h)
+ */
+static float tb_project_to_sphere(float, float, float);
+static void normalize_quat(float [4]);
+
+void
+vzero(float *v)
+{
+ v[0] = 0.0;
+ v[1] = 0.0;
+ v[2] = 0.0;
+}
+
+void
+vset(float *v, float x, float y, float z)
+{
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+}
+
+void
+vsub(const float *src1, const float *src2, float *dst)
+{
+ dst[0] = src1[0] - src2[0];
+ dst[1] = src1[1] - src2[1];
+ dst[2] = src1[2] - src2[2];
+}
+
+void
+vcopy(const float *v1, float *v2)
+{
+ register int i;
+ for (i = 0 ; i < 3 ; i++)
+ v2[i] = v1[i];
+}
+
+void
+vcross(const float *v1, const float *v2, float *cross)
+{
+ float temp[3];
+
+ temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
+ temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
+ temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
+ vcopy(temp, cross);
+}
+
+float
+vlength(const float *v)
+{
+ return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+}
+
+void
+vscale(float *v, float div)
+{
+ v[0] *= div;
+ v[1] *= div;
+ v[2] *= div;
+}
+
+void
+vnormal(float *v)
+{
+ vscale(v,1.0/vlength(v));
+}
+
+float
+vdot(const float *v1, const float *v2)
+{
+ return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
+}
+
+void
+vadd(const float *src1, const float *src2, float *dst)
+{
+ dst[0] = src1[0] + src2[0];
+ dst[1] = src1[1] + src2[1];
+ dst[2] = src1[2] + src2[2];
+}
+
+/*
+ * Ok, simulate a track-ball. Project the points onto the virtual
+ * trackball, then figure out the axis of rotation, which is the cross
+ * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
+ * Note: This is a deformed trackball-- is a trackball in the center,
+ * but is deformed into a hyperbolic sheet of rotation away from the
+ * center. This particular function was chosen after trying out
+ * several variations.
+ *
+ * It is assumed that the arguments to this routine are in the range
+ * (-1.0 ... 1.0)
+ */
+void
+trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
+{
+ float a[3]; /* Axis of rotation */
+ float phi; /* how much to rotate about axis */
+ float p1[3], p2[3], d[3];
+ float t;
+
+ if (p1x == p2x && p1y == p2y) {
+ /* Zero rotation */
+ vzero(q);
+ q[3] = 1.0;
+ return;
+ }
+
+ /*
+ * First, figure out z-coordinates for projection of P1 and P2 to
+ * deformed sphere
+ */
+ vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
+ vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
+
+ /*
+ * Now, we want the cross product of P1 and P2
+ */
+ vcross(p2,p1,a);
+
+ /*
+ * Figure out how much to rotate around that axis.
+ */
+ vsub(p1,p2,d);
+ t = vlength(d) / (2.0*TRACKBALLSIZE);
+
+ /*
+ * Avoid problems with out-of-control values...
+ */
+ if (t > 1.0) t = 1.0;
+ if (t < -1.0) t = -1.0;
+ phi = 2.0 * asin(t);
+
+ axis_to_quat(a,phi,q);
+}
+
+/*
+ * Given an axis and angle, compute quaternion.
+ */
+void
+axis_to_quat(float a[3], float phi, float q[4])
+{
+ vnormal(a);
+ vcopy(a,q);
+ vscale(q,sin(phi/2.0));
+ q[3] = cos(phi/2.0);
+}
+
+/*
+ * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
+ * if we are away from the center of the sphere.
+ */
+static float
+tb_project_to_sphere(float r, float x, float y)
+{
+ float d, t, z;
+
+ d = sqrt(x*x + y*y);
+ if (d < r * 0.70710678118654752440) { /* Inside sphere */
+ z = sqrt(r*r - d*d);
+ } else { /* On hyperbola */
+ t = r / 1.41421356237309504880;
+ z = t*t / d;
+ }
+ return z;
+}
+
+/*
+ * Given two rotations, e1 and e2, expressed as quaternion rotations,
+ * figure out the equivalent single rotation and stuff it into dest.
+ *
+ * This routine also normalizes the result every RENORMCOUNT times it is
+ * called, to keep error from creeping in.
+ *
+ * NOTE: This routine is written so that q1 or q2 may be the same
+ * as dest (or each other).
+ */
+
+#define RENORMCOUNT 97
+
+void
+add_quats(float q1[4], float q2[4], float dest[4])
+{
+ static int count=0;
+ float t1[4], t2[4], t3[4];
+ float tf[4];
+
+ vcopy(q1,t1);
+ vscale(t1,q2[3]);
+
+ vcopy(q2,t2);
+ vscale(t2,q1[3]);
+
+ vcross(q2,q1,t3);
+ vadd(t1,t2,tf);
+ vadd(t3,tf,tf);
+ tf[3] = q1[3] * q2[3] - vdot(q1,q2);
+
+ dest[0] = tf[0];
+ dest[1] = tf[1];
+ dest[2] = tf[2];
+ dest[3] = tf[3];
+
+ if (++count > RENORMCOUNT) {
+ count = 0;
+ normalize_quat(dest);
+ }
+}
+
+/*
+ * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
+ * If they don't add up to 1.0, dividing by their magnitued will
+ * renormalize them.
+ *
+ * Note: See the following for more information on quaternions:
+ *
+ * - Shoemake, K., Animating rotation with quaternion curves, Computer
+ * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
+ * - Pletinckx, D., Quaternion calculus as a basic tool in computer
+ * graphics, The Visual Computer 5, 2-13, 1989.
+ */
+static void
+normalize_quat(float q[4])
+{
+ int i;
+ float mag;
+
+ mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
+ for (i = 0; i < 4; i++) q[i] /= mag;
+}
+
+/*
+ * Build a rotation matrix, given a quaternion rotation.
+ *
+ */
+void
+build_rotmatrix(float m[4][4], float q[4])
+{
+ m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
+ m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
+ m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
+ m[0][3] = 0.0;
+
+ m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
+ m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
+ m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
+ m[1][3] = 0.0;
+
+ m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
+ m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
+ m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
+ m[2][3] = 0.0;
+
+ m[3][0] = 0.0;
+ m[3][1] = 0.0;
+ m[3][2] = 0.0;
+ m[3][3] = 1.0;
+}
+
diff --git a/test/trackball.h b/test/trackball.h
new file mode 100644
index 000000000..b676fb4e5
--- /dev/null
+++ b/test/trackball.h
@@ -0,0 +1,78 @@
+/*
+ * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States. Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * trackball.h
+ * A virtual trackball implementation
+ * Written by Gavin Bell for Silicon Graphics, November 1988.
+ */
+
+/*
+ * Pass the x and y coordinates of the last and current positions of
+ * the mouse, scaled so they are from (-1.0 ... 1.0).
+ *
+ * The resulting rotation is returned as a quaternion rotation in the
+ * first paramater.
+ */
+void
+trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
+
+/*
+ * Given two quaternions, add them together to get a third quaternion.
+ * Adding quaternions to get a compound rotation is analagous to adding
+ * translations to get a compound translation. When incrementally
+ * adding rotations, the first argument here should be the new
+ * rotation, the second and third the total rotation (which will be
+ * over-written with the resulting new total rotation).
+ */
+void
+add_quats(float *q1, float *q2, float *dest);
+
+/*
+ * A useful function, builds a rotation matrix in Matrix based on
+ * given quaternion.
+ */
+void
+build_rotmatrix(float m[4][4], float q[4]);
+
+/*
+ * This function computes a quaternion based on an axis (defined by
+ * the given vector) and an angle about which to rotate. The angle is
+ * expressed in radians. The result is put into the third argument.
+ */
+void
+axis_to_quat(float a[3], float phi, float q[4]);
+
diff --git a/test/valuators.C b/test/valuators.C
new file mode 100644
index 000000000..b71c932d4
--- /dev/null
+++ b/test/valuators.C
@@ -0,0 +1,358 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include "valuators.H"
+
+static void cb_0(Fl_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_VERT_FILL_SLIDER(Fl_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_VERT_NICE_SLIDER(Fl_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_01(Fl_Value_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_VERT_FILL_SLIDER1(Fl_Value_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_VERT_NICE_SLIDER1(Fl_Value_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HORIZONTAL(Fl_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HOR_FILL_SLIDER(Fl_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HOR_NICE_SLIDER(Fl_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HOR_SLIDER(Fl_Value_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HOR_FILL_SLIDER1(Fl_Value_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HOR_NICE_SLIDER1(Fl_Value_Slider* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_w(Fl_Adjuster* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_w1(Fl_Adjuster* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_02(Fl_Counter* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_SIMPLE_COUNTER(Fl_Counter* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_03(Fl_Dial* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_LINE_DIAL(Fl_Dial* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_FILL_DIAL(Fl_Dial* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_04(Fl_Roller* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HORIZONTAL1(Fl_Roller* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_05(Fl_Value_Input* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_06(Fl_Value_Output* o, void*) {
+ printf("%g \r",o->value());
+fflush(stdout);
+}
+
+static void cb_07(Fl_Scrollbar* o, void*) {
+ printf("%d \r",o->value());
+fflush(stdout);
+}
+
+static void cb_FL_HORIZONTAL2(Fl_Scrollbar* o, void*) {
+ printf("%d \r",o->value());
+fflush(stdout);
+}
+
+int main(int argc, char **argv) {
+ Fl_Window *w;
+ { Fl_Window* o = w = new Fl_Window(567, 506, "Valuator classes, showing values for type()");
+ o->color(43);
+ o->selection_color(43);
+ { Fl_Box* o = new Fl_Box(10, 10, 280, 210, "Fl_Slider");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Slider* o = new Fl_Slider(30, 45, 20, 145, "0");
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_0);
+ o->align(1);
+ }
+ { Fl_Slider* o = new Fl_Slider(70, 55, 20, 145, "FL_VERT_FILL_SLIDER");
+ o->type(2);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_VERT_FILL_SLIDER);
+ }
+ { Fl_Slider* o = new Fl_Slider(105, 45, 20, 145, "FL_VERT_NICE_SLIDER");
+ o->type(4);
+ o->box(FL_FLAT_BOX);
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_VERT_NICE_SLIDER);
+ o->align(1);
+ }
+ { Fl_Box* o = new Fl_Box(10, 230, 280, 205, "Fl_Value_Slider");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(30, 260, 30, 145, "0");
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_01);
+ o->align(1);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(70, 275, 30, 140, "FL_VERT_FILL_SLIDER");
+ o->type(2);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_VERT_FILL_SLIDER1);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(110, 260, 20, 145, "FL_VERT_NICE_SLIDER");
+ o->type(4);
+ o->box(FL_FLAT_BOX);
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_VERT_NICE_SLIDER1);
+ o->align(1);
+ }
+ { Fl_Slider* o = new Fl_Slider(140, 80, 130, 20, "FL_HORIZONTAL");
+ o->type(1);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HORIZONTAL);
+ }
+ { Fl_Slider* o = new Fl_Slider(140, 120, 130, 20, "FL_HOR_FILL_SLIDER");
+ o->type(3);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HOR_FILL_SLIDER);
+ }
+ { Fl_Slider* o = new Fl_Slider(140, 160, 130, 20, "FL_HOR_NICE_SLIDER");
+ o->type(5);
+ o->box(FL_FLAT_BOX);
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HOR_NICE_SLIDER);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(140, 290, 130, 20, "FL_HOR_SLIDER");
+ o->type(1);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HOR_SLIDER);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(140, 330, 130, 20, "FL_HOR_FILL_SLIDER");
+ o->type(3);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HOR_FILL_SLIDER1);
+ }
+ { Fl_Box* o = new Fl_Box(430, 10, 125, 120, "Fl_Adjuster");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Value_Slider* o = new Fl_Value_Slider(140, 370, 130, 20, "FL_HOR_NICE_SLIDER");
+ o->type(5);
+ o->box(FL_FLAT_BOX);
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HOR_NICE_SLIDER1);
+ }
+ { Fl_Adjuster* o = new Fl_Adjuster(440, 60, 75, 25, "w()>h()");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_w);
+ }
+ { Fl_Adjuster* o = new Fl_Adjuster(520, 35, 25, 75, "w()<h()");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_w1);
+ }
+ { Fl_Box* o = new Fl_Box(345, 135, 210, 115, "Fl_Counter");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Counter* o = new Fl_Counter(360, 160, 180, 30, "0");
+ o->labelsize(8);
+ o->minimum(-1e+06);
+ o->maximum(1e+06);
+ o->callback((Fl_Callback*)cb_02);
+ }
+ { Fl_Counter* o = new Fl_Counter(360, 205, 180, 30, "FL_SIMPLE_COUNTER");
+ o->type(1);
+ o->labelsize(8);
+ o->minimum(-1e+06);
+ o->maximum(1e+06);
+ o->callback((Fl_Callback*)cb_FL_SIMPLE_COUNTER);
+ }
+ { Fl_Box* o = new Fl_Box(300, 260, 255, 105, "Fl_Dial");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Dial* o = new Fl_Dial(315, 280, 65, 65, "0");
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_03);
+ }
+ { Fl_Dial* o = new Fl_Dial(395, 280, 65, 65, "FL_LINE_DIAL");
+ o->type(1);
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_LINE_DIAL);
+ }
+ { Fl_Dial* o = new Fl_Dial(475, 280, 65, 65, "FL_FILL_DIAL");
+ o->type(2);
+ o->color(10);
+ o->selection_color(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_FILL_DIAL);
+ }
+ { Fl_Box* o = new Fl_Box(300, 375, 145, 120, "Fl_Roller");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Roller* o = new Fl_Roller(315, 390, 20, 95, "0");
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_04);
+ }
+ { Fl_Roller* o = new Fl_Roller(340, 430, 90, 20, "FL_HORIZONTAL");
+ o->type(1);
+ o->labelsize(8);
+ o->callback((Fl_Callback*)cb_FL_HORIZONTAL1);
+ }
+ { Fl_Box* o = new Fl_Box(10, 445, 140, 50, "Fl_Value_Input");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Box* o = new Fl_Box(455, 375, 100, 120, "Some widgets have color(FL_GREEN) and color2(FL_RED) to show the areas the\
+se effect.");
+ o->box(FL_BORDER_FRAME);
+ o->color(0);
+ o->selection_color(0);
+ o->labelsize(10);
+ o->align(128);
+ }
+ { Fl_Box* o = new Fl_Box(155, 445, 135, 50, "Fl_Value_Output");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(17);
+ }
+ { Fl_Value_Input* o = new Fl_Value_Input(30, 460, 110, 30, "0");
+ o->labelsize(8);
+ o->maximum(100);
+ o->step(0.1);
+ o->callback((Fl_Callback*)cb_05);
+ o->when(4);
+ }
+ { Fl_Value_Output* o = new Fl_Value_Output(170, 460, 110, 30, "0");
+ o->labelsize(8);
+ o->maximum(100);
+ o->step(0.1);
+ o->callback((Fl_Callback*)cb_06);
+ }
+ { Fl_Box* o = new Fl_Box(295, 10, 130, 120, " Fl_Scrollbar");
+ o->box(FL_ENGRAVED_BOX);
+ o->labelfont(1);
+ o->labelsize(12);
+ o->align(21);
+ }
+ { Fl_Scrollbar* o = new Fl_Scrollbar(395, 20, 20, 105, "0");
+ o->labelsize(8);
+ o->maximum(100);
+ o->callback((Fl_Callback*)cb_07);
+ o->align(1);
+ }
+ { Fl_Scrollbar* o = new Fl_Scrollbar(300, 65, 95, 20, "FL_HORIZONTAL");
+ o->type(1);
+ o->labelsize(8);
+ o->maximum(100);
+ o->callback((Fl_Callback*)cb_FL_HORIZONTAL2);
+ }
+ o->end();
+ }
+ w->show(argc, argv);
+ return Fl::run();
+}
diff --git a/test/valuators.H b/test/valuators.H
new file mode 100644
index 000000000..acd872b9b
--- /dev/null
+++ b/test/valuators.H
@@ -0,0 +1,15 @@
+// generated by Fast Light User Interface Designer (fluid) version 0.99
+
+#include <FL/Fl.H>
+#include <FL/Fl_Adjuster.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Counter.H>
+#include <FL/Fl_Dial.H>
+#include <FL/Fl_Roller.H>
+#include <FL/Fl_Scrollbar.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Value_Input.H>
+#include <FL/Fl_Value_Output.H>
+#include <FL/Fl_Value_Slider.H>
+#include <FL/Fl_Window.H>
+#include <stdio.h>
diff --git a/test/valuators.fl b/test/valuators.fl
new file mode 100644
index 000000000..8aca64f4e
--- /dev/null
+++ b/test/valuators.fl
@@ -0,0 +1,206 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 0.99
+header_name {.H}
+code_name {.C}
+gridx 5
+gridy 5
+snap 3
+Function {} {open
+} {
+ Fl_Window {} {
+ label {Valuator classes, showing values for type()} open
+ xywh {548 340 567 506} color 43 selection_color 43
+ code0 {\#include <stdio.h>} visible
+ } {
+ Fl_Box {} {
+ label Fl_Slider
+ xywh {10 10 280 210} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Slider {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {30 45 20 145} selection_color 1 labelsize 8 align 1
+ }
+ Fl_Slider {} {
+ label FL_VERT_FILL_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {70 55 20 145} type {Vert Fill} selection_color 1 labelsize 8
+ }
+ Fl_Slider {} {
+ label FL_VERT_NICE_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {105 45 20 145} type {Vert Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 align 1
+ }
+ Fl_Box {} {
+ label Fl_Value_Slider
+ xywh {10 230 280 205} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Value_Slider {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {30 260 30 145} selection_color 1 labelsize 8 align 1
+ }
+ Fl_Value_Slider {} {
+ label FL_VERT_FILL_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {70 275 30 140} type {Vert Fill} selection_color 1 labelsize 8
+ }
+ Fl_Value_Slider {} {
+ label FL_VERT_NICE_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {110 260 20 145} type {Vert Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 align 1
+ }
+ Fl_Slider {} {
+ label FL_HORIZONTAL
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {140 80 130 20} type Horizontal selection_color 1 labelsize 8
+ }
+ Fl_Slider {} {
+ label FL_HOR_FILL_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {140 120 130 20} type {Horz Fill} selection_color 1 labelsize 8
+ }
+ Fl_Slider {} {
+ label FL_HOR_NICE_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {140 160 130 20} type {Horz Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8
+ }
+ Fl_Value_Slider {} {
+ label FL_HOR_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {140 290 130 20} type Horizontal selection_color 1 labelsize 8
+ }
+ Fl_Value_Slider {} {
+ label FL_HOR_FILL_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {140 330 130 20} type {Horz Fill} selection_color 1 labelsize 8
+ }
+ Fl_Box {} {
+ label Fl_Adjuster
+ xywh {430 10 125 120} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Value_Slider {} {
+ label FL_HOR_NICE_SLIDER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {140 370 130 20} type {Horz Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8
+ }
+ Fl_Adjuster {} {
+ label {w()>h()}
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {440 60 75 25} labelsize 8
+ }
+ Fl_Adjuster {} {
+ label {w()<h()}
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {520 35 25 75} labelsize 8
+ }
+ Fl_Box {} {
+ label Fl_Counter
+ xywh {345 135 210 115} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Counter {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {360 160 180 30} labelsize 8 minimum -1e+06 maximum 1e+06
+ }
+ Fl_Counter {} {
+ label FL_SIMPLE_COUNTER
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {360 205 180 30} type Simple labelsize 8 minimum -1e+06 maximum 1e+06
+ }
+ Fl_Box {} {
+ label Fl_Dial
+ xywh {300 260 255 105} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Dial {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {315 280 65 65} color 10 selection_color 1 labelsize 8
+ }
+ Fl_Dial {} {
+ label FL_LINE_DIAL
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {395 280 65 65} type Line color 10 selection_color 1 labelsize 8
+ }
+ Fl_Dial {} {
+ label FL_FILL_DIAL
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {475 280 65 65} type Fill color 10 selection_color 1 labelsize 8
+ }
+ Fl_Box {} {
+ label Fl_Roller
+ xywh {300 375 145 120} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Roller {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {315 390 20 95} labelsize 8
+ }
+ Fl_Roller {} {
+ label FL_HORIZONTAL
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {340 430 90 20} type Horizontal labelsize 8
+ }
+ Fl_Box {} {
+ label Fl_Value_Input
+ xywh {10 445 140 50} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Box {} {
+ label {Some widgets have color(FL_GREEN) and color2(FL_RED) to show the areas these effect.}
+ xywh {455 375 100 120} box BORDER_FRAME color 0 selection_color 0 labelsize 10 align 128
+ }
+ Fl_Box {} {
+ label Fl_Value_Output
+ xywh {155 445 135 50} box ENGRAVED_BOX labelfont 1 labelsize 12 align 17
+ }
+ Fl_Value_Input {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);} selected
+ xywh {30 460 110 30} labelsize 8 maximum 100 step 0.1
+ }
+ Fl_Value_Output {} {
+ label 0
+ callback {printf("%g \\r",o->value());
+fflush(stdout);}
+ xywh {170 460 110 30} labelsize 8 maximum 100 step 0.1
+ }
+ Fl_Box {} {
+ label { Fl_Scrollbar}
+ xywh {295 10 130 120} box ENGRAVED_BOX labelfont 1 labelsize 12 align 21
+ }
+ Fl_Scrollbar {} {
+ label 0
+ callback {printf("%d \\r",o->value());
+fflush(stdout);}
+ xywh {395 20 20 105} labelsize 8 align 1 maximum 100
+ }
+ Fl_Scrollbar {} {
+ label FL_HORIZONTAL
+ callback {printf("%d \\r",o->value());
+fflush(stdout);}
+ xywh {300 65 95 20} type Horizontal labelsize 8 maximum 100
+ }
+ }
+}
diff --git a/test/white_1.xbm b/test/white_1.xbm
new file mode 100644
index 000000000..0ade331f6
--- /dev/null
+++ b/test/white_1.xbm
@@ -0,0 +1,60 @@
+#define white_1_width 56
+#define white_1_height 56
+static unsigned char white_1_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01,
+0x80, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x00,
+0x00, 0x01, 0x00, 0x00, 0x40, 0x55, 0x00,
+0x00, 0x02, 0x00, 0x00, 0xa8, 0x2a, 0x00,
+0x00, 0x14, 0x00, 0x00, 0x54, 0x15, 0x00,
+0x00, 0x28, 0x00, 0x80, 0xaa, 0x0a, 0x00,
+0x00, 0x50, 0x05, 0x54, 0x55, 0x05, 0x00,
+0x00, 0xa0, 0xaa, 0xaa, 0xaa, 0x02, 0x00,
+0x00, 0x40, 0x55, 0x55, 0x55, 0x01, 0x00,
+0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00,
+0x00, 0x00, 0x50, 0x55, 0x15, 0x00, 0x00,
+0x00, 0x00, 0x80, 0xaa, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/white_2.xbm b/test/white_2.xbm
new file mode 100644
index 000000000..b916d1226
--- /dev/null
+++ b/test/white_2.xbm
@@ -0,0 +1,60 @@
+#define white_2_width 56
+#define white_2_height 56
+static unsigned char white_2_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x90, 0x04, 0x00, 0x00,
+0x00, 0x20, 0x01, 0x40, 0x12, 0x00, 0x00,
+0x00, 0x48, 0xfc, 0x0f, 0x09, 0x00, 0x00,
+0x00, 0x10, 0x07, 0x30, 0x04, 0x00, 0x00,
+0x40, 0xc2, 0x00, 0xc0, 0x10, 0x00, 0x00,
+0x80, 0x24, 0x00, 0x00, 0x09, 0x00, 0x00,
+0x20, 0x11, 0x00, 0x00, 0x42, 0x00, 0x00,
+0x40, 0x08, 0x00, 0x00, 0x20, 0x00, 0x00,
+0x90, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00,
+0x20, 0x02, 0x00, 0x00, 0x40, 0x04, 0x00,
+0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x01, 0x00, 0x00, 0x80, 0x08, 0x00,
+0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x84, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
+0xa0, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x54, 0x01, 0x01, 0x00,
+0x44, 0x01, 0x00, 0xaa, 0x00, 0x02, 0x00,
+0x00, 0x02, 0x40, 0x55, 0x80, 0x04, 0x00,
+0x88, 0x02, 0xa0, 0x0a, 0x00, 0x01, 0x00,
+0x40, 0x04, 0x50, 0x05, 0x40, 0x02, 0x00,
+0x00, 0x09, 0xa0, 0x00, 0x80, 0x00, 0x00,
+0x80, 0x00, 0x50, 0x00, 0x20, 0x01, 0x00,
+0x00, 0x04, 0x08, 0x00, 0x48, 0x00, 0x00,
+0x00, 0x02, 0x00, 0x00, 0x90, 0x00, 0x00,
+0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x24, 0x00, 0x80, 0x04, 0x00, 0x00,
+0x00, 0x92, 0x00, 0x20, 0x01, 0x00, 0x00,
+0x00, 0x48, 0x02, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/white_3.xbm b/test/white_3.xbm
new file mode 100644
index 000000000..9b721d25b
--- /dev/null
+++ b/test/white_3.xbm
@@ -0,0 +1,60 @@
+#define white_3_width 56
+#define white_3_height 56
+static unsigned char white_3_bits[] = {
+0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x40, 0x81, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x40, 0x09, 0x00, 0x00, 0x00,
+0x00, 0x06, 0x52, 0x09, 0x00, 0x00, 0x00,
+0x00, 0x91, 0x52, 0x05, 0x00, 0x00, 0x00,
+0x80, 0x94, 0x50, 0x05, 0x00, 0x00, 0x00,
+0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x01, 0x50, 0x05, 0x60, 0x00, 0x00,
+0x08, 0x00, 0xaa, 0x2a, 0x00, 0x00, 0x00,
+0x08, 0x40, 0x55, 0x55, 0x80, 0x01, 0x00,
+0x04, 0xa0, 0xaa, 0xa0, 0x00, 0x00, 0x00,
+0x04, 0x50, 0x55, 0x55, 0x05, 0x03, 0x00,
+0x02, 0xa8, 0x0a, 0xa0, 0x0a, 0x00, 0x00,
+0x02, 0x54, 0x55, 0x55, 0x15, 0x00, 0x00,
+0x00, 0xa8, 0x00, 0x80, 0x1a, 0x03, 0x00,
+0x00, 0x54, 0x55, 0x55, 0x35, 0x00, 0x00,
+0x00, 0x0a, 0x00, 0x80, 0x2a, 0x06, 0x00,
+0x0d, 0x45, 0x55, 0x55, 0x55, 0x00, 0x00,
+0x31, 0x0a, 0x00, 0x00, 0x6a, 0x00, 0x00,
+0x00, 0x05, 0x55, 0x55, 0x55, 0x07, 0x00,
+0x3e, 0x02, 0x00, 0x00, 0x6a, 0x00, 0x00,
+0x00, 0x05, 0x55, 0x55, 0x55, 0x1f, 0x00,
+0x3e, 0x0a, 0x00, 0x00, 0x68, 0x00, 0x00,
+0x00, 0x15, 0x54, 0x55, 0x55, 0x1f, 0x00,
+0x38, 0x0a, 0x00, 0x00, 0x69, 0x00, 0x00,
+0x01, 0x15, 0x54, 0x95, 0x56, 0x03, 0x00,
+0x01, 0x2a, 0x00, 0x50, 0x69, 0x0c, 0x00,
+0x18, 0x54, 0x50, 0xa9, 0x34, 0x00, 0x00,
+0x00, 0x2a, 0x00, 0x55, 0x2b, 0x00, 0x00,
+0x30, 0x54, 0x90, 0x2a, 0x15, 0x00, 0x00,
+0x02, 0xa8, 0x40, 0xb5, 0x1a, 0x00, 0x00,
+0x00, 0x50, 0xa1, 0x52, 0x0d, 0x00, 0x00,
+0x30, 0xa0, 0x50, 0xab, 0x06, 0x00, 0x00,
+0x00, 0x50, 0x29, 0x55, 0x03, 0x00, 0x00,
+0x60, 0xa0, 0xb2, 0xaa, 0x01, 0x00, 0x00,
+0x00, 0xc0, 0x55, 0xd5, 0x00, 0x00, 0x00,
+0x80, 0x01, 0xab, 0x3a, 0x20, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x0f, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0xa8, 0x42, 0x0a, 0x00, 0x00,
+0x00, 0x00, 0xa8, 0x52, 0x02, 0x00, 0x00,
+0x00, 0x00, 0xa4, 0x12, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/white_4.xbm b/test/white_4.xbm
new file mode 100644
index 000000000..189f497a8
--- /dev/null
+++ b/test/white_4.xbm
@@ -0,0 +1,60 @@
+#define white_4_width 56
+#define white_4_height 56
+static unsigned char white_4_bits[] = {
+0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x80, 0xbf, 0x7e, 0x00, 0x00, 0x00,
+0x00, 0xe0, 0xb6, 0xf6, 0x01, 0x00, 0x00,
+0x00, 0xb8, 0xad, 0xb6, 0x07, 0x00, 0x00,
+0x00, 0x6e, 0xad, 0xda, 0x1e, 0x00, 0x00,
+0x00, 0x6b, 0xab, 0x6a, 0x3b, 0x00, 0x00,
+0x80, 0xdb, 0xfe, 0xbf, 0x6d, 0x00, 0x00,
+0xc0, 0xb6, 0x03, 0xf0, 0xf6, 0x00, 0x00,
+0xe0, 0xee, 0xa8, 0xca, 0x9b, 0x01, 0x00,
+0xb0, 0x3d, 0x55, 0x15, 0xef, 0x03, 0x00,
+0x70, 0x9b, 0xaa, 0xaa, 0x76, 0x02, 0x00,
+0xd8, 0x4e, 0x55, 0x5f, 0xbd, 0x07, 0x00,
+0xb8, 0xa7, 0xaa, 0xaa, 0xda, 0x04, 0x00,
+0x6c, 0x53, 0xf5, 0x5f, 0x75, 0x0f, 0x00,
+0xdc, 0xa9, 0xaa, 0xaa, 0xaa, 0x0b, 0x00,
+0xb6, 0x55, 0xff, 0x7f, 0xe5, 0x1c, 0x00,
+0xee, 0xaa, 0xaa, 0xaa, 0x4a, 0x17, 0x00,
+0xde, 0xf4, 0xff, 0x7f, 0xd5, 0x19, 0x00,
+0x72, 0xba, 0xaa, 0xaa, 0xaa, 0x1e, 0x00,
+0x4e, 0xf5, 0xff, 0xff, 0x95, 0x17, 0x00,
+0x7f, 0xfa, 0xaa, 0xaa, 0xaa, 0x38, 0x00,
+0x41, 0xfd, 0xff, 0xff, 0x95, 0x3f, 0x00,
+0x7f, 0xfa, 0xaa, 0xaa, 0xaa, 0x20, 0x00,
+0x41, 0xf5, 0xff, 0xff, 0x97, 0x3f, 0x00,
+0x7f, 0xea, 0xab, 0xaa, 0xaa, 0x20, 0x00,
+0x47, 0xf5, 0xff, 0xff, 0x94, 0x3f, 0x00,
+0x7a, 0xea, 0xab, 0x2a, 0xa8, 0x1c, 0x00,
+0x5e, 0xd5, 0xff, 0x0f, 0x94, 0x13, 0x00,
+0xe6, 0xaa, 0xaf, 0x02, 0xca, 0x1e, 0x00,
+0xba, 0xd4, 0xff, 0x00, 0xd4, 0x1d, 0x00,
+0xce, 0xa9, 0x2f, 0x80, 0x6a, 0x1b, 0x00,
+0x74, 0x55, 0x1f, 0x40, 0xe5, 0x0e, 0x00,
+0xbc, 0xab, 0x0e, 0xa8, 0xb2, 0x0d, 0x00,
+0xc8, 0x56, 0x0f, 0x54, 0x79, 0x07, 0x00,
+0x78, 0xaf, 0x86, 0xaa, 0xdc, 0x06, 0x00,
+0x90, 0x5b, 0x45, 0x55, 0xb6, 0x03, 0x00,
+0xf0, 0x3d, 0xaa, 0x2a, 0x6f, 0x03, 0x00,
+0x60, 0xf6, 0x54, 0xc5, 0xdd, 0x01, 0x00,
+0xc0, 0xdb, 0x03, 0x70, 0xdb, 0x00, 0x00,
+0x80, 0x6d, 0xff, 0xdf, 0x76, 0x00, 0x00,
+0x00, 0xb7, 0x55, 0xb5, 0x35, 0x00, 0x00,
+0x00, 0xde, 0x56, 0xad, 0x1d, 0x00, 0x00,
+0x00, 0x78, 0x5b, 0x6d, 0x07, 0x00, 0x00,
+0x00, 0xe0, 0x5b, 0xdb, 0x01, 0x00, 0x00,
+0x00, 0x80, 0x5f, 0x7f, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/whiteking_1.xbm b/test/whiteking_1.xbm
new file mode 100644
index 000000000..2a3fd088b
--- /dev/null
+++ b/test/whiteking_1.xbm
@@ -0,0 +1,60 @@
+#define whiteking_1_width 56
+#define whiteking_1_height 56
+static unsigned char whiteking_1_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2a,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2a,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x2a,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55,
+0x80, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a,
+0x00, 0x01, 0x00, 0x00, 0x40, 0x55, 0x55,
+0x00, 0x02, 0x00, 0x00, 0xa8, 0xaa, 0x2a,
+0x00, 0x14, 0x00, 0x00, 0x54, 0x55, 0x15,
+0x00, 0x28, 0x00, 0x80, 0xaa, 0xaa, 0x2a,
+0x00, 0x50, 0x05, 0x54, 0x55, 0x55, 0x15,
+0x00, 0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a,
+0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x05,
+0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0x02,
+0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x01,
+0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x00,
+0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x00,
+0x00, 0x00, 0xa8, 0xaa, 0xaa, 0x2a, 0x00,
+0x00, 0x00, 0x40, 0x55, 0x55, 0x15, 0x00,
+0x00, 0x00, 0x00, 0xaa, 0xaa, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00,
+};
diff --git a/test/whiteking_2.xbm b/test/whiteking_2.xbm
new file mode 100644
index 000000000..9f2e24d23
--- /dev/null
+++ b/test/whiteking_2.xbm
@@ -0,0 +1,60 @@
+#define whiteking_2_width 56
+#define whiteking_2_height 56
+static unsigned char whiteking_2_bits[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x90, 0x04, 0x00, 0x00,
+0x00, 0x20, 0x01, 0x40, 0x12, 0x00, 0x00,
+0x00, 0x48, 0xfc, 0x0f, 0x09, 0x00, 0x00,
+0x00, 0x10, 0x07, 0x30, 0x04, 0x00, 0x00,
+0x40, 0xc2, 0x00, 0xc0, 0x10, 0x00, 0x00,
+0x80, 0x24, 0x00, 0x00, 0x09, 0x00, 0x00,
+0x20, 0x11, 0x00, 0x00, 0x42, 0x00, 0x00,
+0x40, 0x08, 0x80, 0x00, 0x20, 0x00, 0x00,
+0x90, 0x04, 0xc4, 0x10, 0x80, 0x00, 0x00,
+0x20, 0x02, 0x06, 0x18, 0x40, 0x04, 0x00,
+0x48, 0x42, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x10, 0x61, 0x00, 0x88, 0x81, 0x08, 0x00,
+0x20, 0x01, 0x10, 0x10, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x20, 0x08, 0x00, 0x01, 0x00,
+0x80, 0x40, 0x40, 0x10, 0x04, 0x08, 0x00,
+0x80, 0x80, 0x00, 0x20, 0x02, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x84, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+0xa0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x00,
+0x44, 0x01, 0x00, 0x40, 0x01, 0x02, 0x00,
+0x00, 0x02, 0xaa, 0xaa, 0x80, 0x04, 0x00,
+0x88, 0x02, 0x54, 0x55, 0x00, 0x01, 0x00,
+0x40, 0x04, 0xaa, 0x2a, 0x40, 0x02, 0x00,
+0x00, 0x09, 0x54, 0x15, 0x80, 0x00, 0x00,
+0x80, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00,
+0x00, 0x04, 0x00, 0x00, 0x48, 0x00, 0x00,
+0x00, 0x02, 0x00, 0x00, 0x90, 0x00, 0x00,
+0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x24, 0x00, 0x80, 0x04, 0x00, 0x00,
+0x00, 0x92, 0x00, 0x20, 0x01, 0x00, 0x00,
+0x00, 0x48, 0x02, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/whiteking_3.xbm b/test/whiteking_3.xbm
new file mode 100644
index 000000000..95b017d4e
--- /dev/null
+++ b/test/whiteking_3.xbm
@@ -0,0 +1,60 @@
+#define whiteking_3_width 56
+#define whiteking_3_height 56
+static unsigned char whiteking_3_bits[] = {
+0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x40, 0x81, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x40, 0x09, 0x00, 0x00, 0x00,
+0x00, 0x06, 0x52, 0x09, 0x00, 0x00, 0x00,
+0x00, 0x91, 0x52, 0x05, 0x00, 0x00, 0x00,
+0x80, 0x94, 0x50, 0x05, 0x00, 0x00, 0x00,
+0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x01, 0x50, 0x05, 0x60, 0x00, 0x00,
+0x08, 0x00, 0xaa, 0x2a, 0x00, 0x00, 0x00,
+0x08, 0x40, 0x55, 0x55, 0x80, 0x01, 0x00,
+0x04, 0xa0, 0x0a, 0xaa, 0x00, 0x00, 0x00,
+0x04, 0x50, 0x10, 0x41, 0x05, 0x03, 0x00,
+0x02, 0xa8, 0x08, 0xa2, 0x0a, 0x00, 0x00,
+0x02, 0x04, 0x50, 0x01, 0x14, 0x00, 0x00,
+0x00, 0x88, 0xaa, 0x2a, 0x1a, 0x03, 0x00,
+0x00, 0x04, 0x59, 0x11, 0x34, 0x00, 0x00,
+0x01, 0xaa, 0xa8, 0xa8, 0x2a, 0x06, 0x00,
+0x0d, 0x55, 0x51, 0x54, 0x55, 0x00, 0x00,
+0x31, 0xa2, 0x28, 0x2a, 0x6a, 0x00, 0x00,
+0x00, 0x45, 0x54, 0x15, 0x55, 0x07, 0x00,
+0x3e, 0xa2, 0xa8, 0xaa, 0x6b, 0x00, 0x00,
+0x00, 0x45, 0x55, 0x55, 0x55, 0x1f, 0x00,
+0x3e, 0x8a, 0xaa, 0xaa, 0x6a, 0x00, 0x00,
+0x00, 0x45, 0x55, 0xd5, 0x55, 0x1f, 0x00,
+0x38, 0x8a, 0xaa, 0xaa, 0x6a, 0x00, 0x00,
+0x01, 0x15, 0x55, 0x55, 0x55, 0x03, 0x00,
+0x01, 0x2a, 0xaa, 0xea, 0x6a, 0x0c, 0x00,
+0x19, 0x14, 0x54, 0x55, 0x35, 0x00, 0x00,
+0x00, 0x2a, 0xaa, 0xaa, 0x2a, 0x00, 0x00,
+0x30, 0x54, 0x54, 0x55, 0x15, 0x00, 0x00,
+0x02, 0xa8, 0xaa, 0xaa, 0x1a, 0x00, 0x00,
+0x00, 0x50, 0x55, 0xd5, 0x0d, 0x00, 0x00,
+0x30, 0xa0, 0xaa, 0xea, 0x06, 0x00, 0x00,
+0x00, 0x50, 0x55, 0x55, 0x03, 0x00, 0x00,
+0x60, 0xa0, 0xaa, 0xaa, 0x01, 0x00, 0x00,
+0x00, 0xc0, 0x55, 0xd5, 0x00, 0x00, 0x00,
+0x80, 0x01, 0xab, 0x3a, 0x20, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x0f, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0xa8, 0x42, 0x0a, 0x00, 0x00,
+0x00, 0x00, 0xa8, 0x52, 0x02, 0x00, 0x00,
+0x00, 0x00, 0xa4, 0x12, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/test/whiteking_4.xbm b/test/whiteking_4.xbm
new file mode 100644
index 000000000..6257a5db4
--- /dev/null
+++ b/test/whiteking_4.xbm
@@ -0,0 +1,60 @@
+#define whiteking_4_width 56
+#define whiteking_4_height 56
+static unsigned char whiteking_4_bits[] = {
+0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x80, 0xbf, 0x7e, 0x00, 0x00, 0x00,
+0x00, 0xe0, 0xb6, 0xf6, 0x01, 0x00, 0x00,
+0x00, 0xb8, 0xad, 0xb6, 0x07, 0x00, 0x00,
+0x00, 0x6e, 0xad, 0xda, 0x1e, 0x00, 0x00,
+0x00, 0x6b, 0xab, 0x6a, 0x3b, 0x00, 0x00,
+0x80, 0xdb, 0xfe, 0xbf, 0x6d, 0x00, 0x00,
+0xc0, 0xb6, 0x03, 0xf0, 0xf6, 0x00, 0x00,
+0xe0, 0xee, 0xa8, 0xca, 0x9b, 0x01, 0x00,
+0xb0, 0x3d, 0x55, 0x15, 0xef, 0x03, 0x00,
+0x70, 0x9b, 0xaa, 0xaa, 0x76, 0x02, 0x00,
+0xd8, 0x4e, 0xf5, 0x55, 0xbd, 0x07, 0x00,
+0xb8, 0xa7, 0x6f, 0xbe, 0xda, 0x04, 0x00,
+0x6c, 0x53, 0x33, 0x4d, 0x75, 0x0f, 0x00,
+0xdc, 0xf9, 0xa9, 0xe6, 0xab, 0x0b, 0x00,
+0xb6, 0x35, 0x55, 0xd5, 0xe4, 0x1c, 0x00,
+0xee, 0x9a, 0xa6, 0x66, 0x4a, 0x17, 0x00,
+0xde, 0x54, 0x47, 0x47, 0xd5, 0x19, 0x00,
+0x72, 0xaa, 0x8e, 0xa3, 0xaa, 0x1e, 0x00,
+0x4e, 0x1d, 0x97, 0xc5, 0x91, 0x17, 0x00,
+0x7f, 0x3a, 0xab, 0xca, 0xa8, 0x38, 0x00,
+0x41, 0x5d, 0x57, 0x55, 0x90, 0x3f, 0x00,
+0x7f, 0xba, 0xaa, 0xaa, 0xa8, 0x20, 0x00,
+0x41, 0x75, 0x55, 0x55, 0x94, 0x3f, 0x00,
+0x7f, 0xba, 0xaa, 0x2a, 0xa8, 0x20, 0x00,
+0x47, 0x75, 0x55, 0x55, 0x94, 0x3f, 0x00,
+0x7a, 0xea, 0xaa, 0x2a, 0xaa, 0x1c, 0x00,
+0x5e, 0xd5, 0x55, 0x15, 0x94, 0x13, 0x00,
+0xe6, 0xea, 0xab, 0x2a, 0xca, 0x1e, 0x00,
+0xba, 0xd4, 0x55, 0x15, 0xd4, 0x1d, 0x00,
+0xce, 0xa9, 0x01, 0x00, 0x6a, 0x1b, 0x00,
+0x74, 0x55, 0x01, 0x00, 0xe5, 0x0e, 0x00,
+0xbc, 0xab, 0x00, 0x00, 0xb2, 0x0d, 0x00,
+0xc8, 0x56, 0x01, 0x00, 0x79, 0x07, 0x00,
+0x78, 0xaf, 0xaa, 0xaa, 0xdc, 0x06, 0x00,
+0x90, 0x5b, 0x55, 0x55, 0xb6, 0x03, 0x00,
+0xf0, 0x3d, 0xaa, 0x2a, 0x6f, 0x03, 0x00,
+0x60, 0xf6, 0x54, 0xc5, 0xdd, 0x01, 0x00,
+0xc0, 0xdb, 0x03, 0x70, 0xdb, 0x00, 0x00,
+0x80, 0x6d, 0xff, 0xdf, 0x76, 0x00, 0x00,
+0x00, 0xb7, 0x55, 0xb5, 0x35, 0x00, 0x00,
+0x00, 0xde, 0x56, 0xad, 0x1d, 0x00, 0x00,
+0x00, 0x78, 0x5b, 0x6d, 0x07, 0x00, 0x00,
+0x00, 0xe0, 0x5b, 0xdb, 0x01, 0x00, 0x00,
+0x00, 0x80, 0x5f, 0x7f, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/version b/version
new file mode 100644
index 000000000..1b8671e4f
--- /dev/null
+++ b/version
@@ -0,0 +1,2 @@
+VERSION =0
+REVISION =99
diff --git a/visualc/README b/visualc/README
new file mode 100644
index 000000000..9c0bd2fc2
--- /dev/null
+++ b/visualc/README
@@ -0,0 +1,198 @@
+How to compile for Windoze:
+
+Fltk has been reported to compile with GNU GCC compilers, with
+MicroSoft Visual C++ version 4 and 5, and with Borland's C++ compiler
+(sorry no info on that here).
+
+----------------------------------------------------------------
+Using GNU C compilers (MingW32 and/or Cygnus):
+----------------------------------------------------------------
+
+Edited from mail from Carl Thompson:
+
+MINGW32 and Cygnus are both ports of the GNU compiler to win32. The
+difference is that Cygnus will emulate a complete Unix development
+environment including nearly all of the standard Unix system calls. This
+allows Unix programs to be ported to win32 possibly without changing a
+single line of source code. However, the applications it generates are big,
+very slow, depend on the Cygnus DLL, and currently somewhat unstable. For
+straight Windows applications / Libraries like FLTK that do not require Unix
+system call emulation, MINGW32 is the superior choice. MINGW32 produces a
+plain Windows binary that is only dependent on the normal Windows DLLs.
+
+Some links for getting MINGW32:
+
+http://agnes.dida.physik.uni-essen.de/~janjaap/mingw32/download.html
+http://www.cygnus.com/misc/gnu-win32/index.html
+ftp://objectcentral.com/mingw32
+
+You will of course need GNU make for MINGW32 in addition to the regular
+MINGW32 utilities. You also need the OpenGL header files which
+apparently are not always included with mingw32, get them from the
+above ftp site.
+
+More instructions from Rick Sayre (at Pixar):
+
+BTW, for what it's worth, here's the list of changes I have to make to get
+fltk and the examples to build under MINGW32 (which I've switched to from
+CYGWIN, since programs compiled under it use standard DLL's rather than the
+extremely bugging cygwin.dll, and it just otherwise seems to work better):
+
+Run ./configure
+-
+In makeinclude - change the CFLAGS and CXXFLAGS to add "-O2 -DWIN32"
+change the libraries to "-lgdi32 -luser32" (add "-mwindows" to not get
+a console)
+-
+In config.h - set HAVE_SCANDIR to 0. ./configure seems to do this
+correctly now, but it was occasionally in the past setting it to 1
+-
+in src/Makefile:
+ change the "ar" command to use the "ar -M < ar.script" form. This
+is needed only because I compile under Cygwin's B19 bash, which blows up in
+all sorts of bad ways (hard resets[!]) on long command lines. More details
+if you care, but most people might not. Just a warning.
+-
+in test/demo.menu
+ Change the paths to DOS form [blech!], don't use "&"
+[A better idea would be to replace system() with a call that knows how
+to fake a fork on Winblows]
+-
+in fluid/Makefile
+Change the make install rules to reference "fluid.exe" for installing and
+strip'ing, rather than "fluid"
+
+I suspect that it is very likely not a good idea to try "make install" under
+Windows. Instead, copy "libfltk.a" to "C:\MINGW32\LIB" (replace
+"C:\MINGW32" with the directory in which you installed MINGW32). Then copy
+the entire "FL" directory to "C:\MINGW32\INCLUDE".
+
+From Gustavo Hime:
+
+First, thank you for the nice piece of software, and congratulations
+on the quality source code. Fltk compiles (and runs) beautifully on
+all the systems I use (Irix 6.4,Solaris 2.5, RedHat Linux 5.0): the
+exception was Windows, where compilation was rather hard.
+
+I have just now managed to compile (satisfactorily) fltk on Win95
+using Mingw32: I do not have MSVC (I don't believe in Microsoft
+compilers :)), and we (the project I am engaged in) are going to use
+mingw32 to port unix code to windows anyway, so mingw32 was the way to
+go. Here is a list of what I had to do:
+
+Modify ar -mwindows to ar -ruv in your makeinclude.mingw32.
+
+Added -DCYGNUS to your *FLAGS variables (I am new to mingw32, I don't
+know what it defines to id itself, but they are so close I don't think
+it matters much).
+
+Disable GL overlay in win32/config.h (shouldn't this be the default?).
+
+Added dummy makedepend files to directories fluid and src.
+
+Created empty lib directory.
+
+Fixed scroll.C line 83 (implicit typecast from int to const char * in
+function call, mingw32 has a problem with this)
+
+Did not fix list_visuals.C (weird code there, where is the main
+functionfor win32?)
+
+And finally, the hardest: downloaded the OpenGL headers for mingw32
+fromftp://objectcentral.com/mingw32. These are not included in the
+mingw32 distribution, and it took me a couple of hours to find them on
+the net. It would be nice to add a note about this in the fltk
+documentation, and I'll send an e-mail asking them to add these
+headers to the mingw32 distribution.
+
+Once again, great code. With mingw32, fltk and opengl, I can
+imediatellyport all my old windows code to unix, and I no longer need
+to waste 300+ mb of hard-drive on stupid borland compilers.
+
+----------------------------------------------------------------
+Using MSVC++:
+----------------------------------------------------------------
+
+If you have MSVC++ 5.0, double click the "fltk.dsw". Make the "fltk"
+project current, and build it. This will create the library in
+../lib/fltkd.lib. To build the demo programs, select the "demo"
+project and build it. To run the demos run the demo project.
+
+I only have Pentium and Alpha NT machines running MSVC++ 5.0. Other
+users have reported success compiling fltk on Windowe95, and using
+version 4 of MSVC++, Borland's C++ compiler, and various ports of GCC
+to windows (to use these, look at the "makeinclude" files in
+../makefiles).
+
+If you want to make non-console apps you have to do something special,
+and that differs on each compiler/linker package. For MSVC++ the
+secret switch is:
+
+ /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup
+
+For cygwin/mingw32 and perhaps some other compilers based on gcc put
+this in the makeinclude file:
+
+ LDLIBS =-lgdi32 -luser32 -mwindows
+
+There are no makefiles, for MSVC++ or any other compiler, because I
+don't know how to write them (the ones dumped by MSVC++ are useless
+and unreadable).
+
+----------------------------------------------------------------
+Other compilers:
+----------------------------------------------------------------
+
+I have heard that Borland C++ is usable.
+
+You probably need to start with the Unix Makefiles. There is one in
+../src, one in ../fluid, and one in ../test. Edit these as necessary
+and compile. You must add "-DWIN32" to your compiler switches.
+
+The biggest problem seems to be differences in the windows.h header
+files (MicroSoft copyrighted theirs?). Some functions and macros have
+different names or are missing.
+
+The MSVC++ "makefiles" are totally useless. Ignore that crap.
+
+Start with the Unix makefiles, which list all the necessary source
+files. Don't try to compile the files ending in _win32.C, they are
+#included by other files if WIN32 is defined.
+
+When compiling the symbol WIN32 must be defined (most compilers do
+this?) and you have to set the include path so the file win32/config.h
+is seen when the code does #include <config.h>. You may need to use
+some sort of switch to force the compiler to compile the files with
+C++ rather than C. On MSVC++ this is the obvious acronym "/TP" :-)
+Not doing these steps will result in lots of cryptic errors.
+
+----------------------------------------------------------------
+Known problems and ToDo list:
+----------------------------------------------------------------
+
+It does not work if you turn on full optimizations in VC++. I have
+been told this is due to bugs in VC++, but if anybody can find a way
+around them it would be nice... (the "optimize" settings in the
+project files only do partial optimization and work ok).
+
+If program is deactivated, Fl::wait() does not return until it is
+activated again, even though things happen, like redraws. This could
+break some programs that rely on executing code after Fl::wait().
+
+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.
+
+Fl_Window::fullscreen() not implemented (should take over the screen
+without a title bar). Currently does maximize instead.
+
+Reports of clipping problems on '95. Can't reproduce on NT.
+
+Need to import .bmp files into fluid. Wonko has the specs.
+
+Can't set icon of windows.
+
+Transparent parts of pixmaps do not really work.
diff --git a/visualc/adjuster.dsp b/visualc/adjuster.dsp
new file mode 100644
index 000000000..8d07a0c3a
--- /dev/null
+++ b/visualc/adjuster.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="adjuster" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=adjuster - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "adjuster.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "adjuster.mak" CFG="adjuster - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "adjuster - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "adjuster - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "adjuster - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/adjuster.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "adjuster - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "adjuster_"
+# PROP BASE Intermediate_Dir "adjuster_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "adjuster_"
+# PROP Intermediate_Dir "adjuster_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/adjuster.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "adjuster - Win32 Release"
+# Name "adjuster - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\adjuster.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/arc.dsp b/visualc/arc.dsp
new file mode 100644
index 000000000..c278178e6
--- /dev/null
+++ b/visualc/arc.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="arc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=arc - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "arc.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "arc.mak" CFG="arc - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "arc - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "arc - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "arc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/arc.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "arc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "arc_"
+# PROP BASE Intermediate_Dir "arc_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "arc_"
+# PROP Intermediate_Dir "arc_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/arc.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "arc - Win32 Release"
+# Name "arc - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\arc.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/ask.dsp b/visualc/ask.dsp
new file mode 100644
index 000000000..356b857a5
--- /dev/null
+++ b/visualc/ask.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="ask" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=ask - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "ask.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "ask.mak" CFG="ask - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "ask - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "ask - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "ask - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/ask.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "ask - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ask_"
+# PROP BASE Intermediate_Dir "ask_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "ask_"
+# PROP Intermediate_Dir "ask_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/ask.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "ask - Win32 Release"
+# Name "ask - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\ask.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/bitmap.dsp b/visualc/bitmap.dsp
new file mode 100644
index 000000000..1513b2caa
--- /dev/null
+++ b/visualc/bitmap.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="bitmap" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=bitmap - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "bitmap.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "bitmap.mak" CFG="bitmap - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "bitmap - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "bitmap - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "bitmap - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/bitmap.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "bitmap - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "bitmap_"
+# PROP BASE Intermediate_Dir "bitmap_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "bitmap_"
+# PROP Intermediate_Dir "bitmap_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/bitmap.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "bitmap - Win32 Release"
+# Name "bitmap - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\bitmap.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/boxtype.dsp b/visualc/boxtype.dsp
new file mode 100644
index 000000000..e6272cfac
--- /dev/null
+++ b/visualc/boxtype.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="boxtype" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=boxtype - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "boxtype.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "boxtype.mak" CFG="boxtype - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "boxtype - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "boxtype - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "boxtype - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/boxtype.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "boxtype - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "boxtype_"
+# PROP BASE Intermediate_Dir "boxtype_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "boxtype_"
+# PROP Intermediate_Dir "boxtype_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/boxtype.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "boxtype - Win32 Release"
+# Name "boxtype - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\boxtype.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/browser.dsp b/visualc/browser.dsp
new file mode 100644
index 000000000..5367a0594
--- /dev/null
+++ b/visualc/browser.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="browser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=browser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "browser.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "browser.mak" CFG="browser - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "browser - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "browser - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "browser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/browser.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "browser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "browser_"
+# PROP BASE Intermediate_Dir "browser_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "browser_"
+# PROP Intermediate_Dir "browser_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/browser.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "browser - Win32 Release"
+# Name "browser - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\browser.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/button.dsp b/visualc/button.dsp
new file mode 100644
index 000000000..d38bc6f71
--- /dev/null
+++ b/visualc/button.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="button" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=button - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "button.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "button.mak" CFG="button - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "button - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "button - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "button - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/button.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "button - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "button_"
+# PROP BASE Intermediate_Dir "button_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "button_"
+# PROP Intermediate_Dir "button_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/button.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "button - Win32 Release"
+# Name "button - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\button.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/buttons.dsp b/visualc/buttons.dsp
new file mode 100644
index 000000000..b91b8abe8
--- /dev/null
+++ b/visualc/buttons.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="buttons" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=buttons - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "buttons.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "buttons.mak" CFG="buttons - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "buttons - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "buttons - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "buttons - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/buttons.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "buttons - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "buttons_"
+# PROP BASE Intermediate_Dir "buttons_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "buttons_"
+# PROP Intermediate_Dir "buttons_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/buttons.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "buttons - Win32 Release"
+# Name "buttons - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\buttons.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/checkers.dsp b/visualc/checkers.dsp
new file mode 100644
index 000000000..fe9e63e04
--- /dev/null
+++ b/visualc/checkers.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="checkers" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=checkers - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "checkers.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "checkers.mak" CFG="checkers - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "checkers - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "checkers - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "checkers - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/checkers.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "checkers - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "checkers_"
+# PROP BASE Intermediate_Dir "checkers_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "checkers_"
+# PROP Intermediate_Dir "checkers_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/checkers.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "checkers - Win32 Release"
+# Name "checkers - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\checkers.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/clock.dsp b/visualc/clock.dsp
new file mode 100644
index 000000000..a36c39e7f
--- /dev/null
+++ b/visualc/clock.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="clock" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=clock - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "clock.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "clock.mak" CFG="clock - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "clock - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "clock - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "clock - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/clock.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "clock - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "clock_"
+# PROP BASE Intermediate_Dir "clock_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "clock_"
+# PROP Intermediate_Dir "clock_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/clock.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "clock - Win32 Release"
+# Name "clock - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\clock.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/colbrowser.dsp b/visualc/colbrowser.dsp
new file mode 100644
index 000000000..e3e4c957c
--- /dev/null
+++ b/visualc/colbrowser.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="colbrowser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=colbrowser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "colbrowser.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "colbrowser.mak" CFG="colbrowser - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "colbrowser - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "colbrowser - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "colbrowser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/colbrowser.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "colbrowser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "colbrowser_"
+# PROP BASE Intermediate_Dir "colbrowser_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "colbrowser_"
+# PROP Intermediate_Dir "colbrowser_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/colbrowser.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "colbrowser - Win32 Release"
+# Name "colbrowser - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\colbrowser.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/color_chooser.dsp b/visualc/color_chooser.dsp
new file mode 100644
index 000000000..91d089702
--- /dev/null
+++ b/visualc/color_chooser.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="color_chooser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=color_chooser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "color_chooser.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "color_chooser.mak" CFG="color_chooser - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "color_chooser - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "color_chooser - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "color_chooser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/color_chooser.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "color_chooser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "color_chooser_"
+# PROP BASE Intermediate_Dir "color_chooser_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "color_chooser_"
+# PROP Intermediate_Dir "color_chooser_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/color_chooser.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "color_chooser - Win32 Release"
+# Name "color_chooser - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\color_chooser.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/config.h b/visualc/config.h
new file mode 100644
index 000000000..fa8d6db76
--- /dev/null
+++ b/visualc/config.h
@@ -0,0 +1,52 @@
+/* config.h
+ This is a replacement for the file ../config.h which is produced by
+ the GNU configure script on Unix systems. Most of these symbols
+ cannot be turned on as they will turn on X-specific code. Some
+ should work, however. */
+
+/* Thickness of FL_UP_BOX and FL_DOWN_BOX. Current 1,2, and 3 are
+ supported. 3 is the historic fltk look. 2 looks more like windoze
+ (and KDE and Qt). 1 is a plausible future evolution... Notice
+ that this may be simulated at runtime by redefining the boxtypes
+ using Fl::set_boxtype() */
+#define BORDER_WIDTH 3
+
+/* Do you have OpenGL?
+ Set this to 0 if you don't plan to use OpenGL, and fltk will be smaller */
+#define HAVE_GL 1
+/* Turn this on if your GL card has overlay hardware: */
+#define HAVE_GL_OVERLAY 1
+
+/* Turning this on causes fltk to use it's own palette on 8-bit displays.
+ Currently the result is similar to the X version with Fl::own_colormap,
+ in that it may produce colormap flashing if only one palette is
+ supported at a time (I could not test this because my driver supports
+ a very large number of palettes!).
+ Current bugs:
+ Fl::set_color() does not work after first window shown()
+ Probably causes colormap flashing.
+ Turning this off will save a chunk of code, and it will still "sort of"
+ work on an 8-bit display (you get dithering) */
+#define USE_COLORMAP 1
+
+/* X specific, leave off: */
+#define HAVE_XDBE 0
+#define USE_XDBE 0
+
+/* X specific, leave off: */
+#define HAVE_OVERLAY 0
+
+/* Byte order of your machine: (not used by win32 code) */
+#define WORDS_BIGENDIAN 0
+
+/* Types that are 32 bits and 16 bits long. Used by fl_draw_image only: */
+#define U16 unsigned short
+#define U32 unsigned
+/* #undef U64 */
+
+/* Where is <dirent.h> (used only by fl_file_chooser and scandir): */
+#define HAVE_DIRENT_H 1
+#define HAVE_SYS_NDIR_H 0
+#define HAVE_SYS_DIR_H 0
+#define HAVE_NDIR_H 0
+#define HAVE_SCANDIR 0
diff --git a/visualc/cube.dsp b/visualc/cube.dsp
new file mode 100644
index 000000000..1ecd444b1
--- /dev/null
+++ b/visualc/cube.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="cube" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=cube - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cube.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cube.mak" CFG="cube - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cube - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "cube - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cube - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/cube.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "cube - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "cube_"
+# PROP BASE Intermediate_Dir "cube_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "cube_"
+# PROP Intermediate_Dir "cube_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 opengl32.lib ..\lib\fltkd.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/cube.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "cube - Win32 Release"
+# Name "cube - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\cube.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/cursor.dsp b/visualc/cursor.dsp
new file mode 100644
index 000000000..a9da2a91c
--- /dev/null
+++ b/visualc/cursor.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="cursor" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=cursor - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cursor.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cursor.mak" CFG="cursor - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cursor - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "cursor - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cursor - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/cursor.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "cursor - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "cursor_"
+# PROP BASE Intermediate_Dir "cursor_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "cursor_"
+# PROP Intermediate_Dir "cursor_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/cursor.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "cursor - Win32 Release"
+# Name "cursor - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\cursor.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/curve.dsp b/visualc/curve.dsp
new file mode 100644
index 000000000..f26b07f7d
--- /dev/null
+++ b/visualc/curve.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="curve" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=curve - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "curve.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "curve.mak" CFG="curve - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "curve - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "curve - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "curve - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/curve.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "curve - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "curve_"
+# PROP BASE Intermediate_Dir "curve_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "curve_"
+# PROP Intermediate_Dir "curve_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/curve.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "curve - Win32 Release"
+# Name "curve - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\curve.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/demo.dsp b/visualc/demo.dsp
new file mode 100644
index 000000000..daa5dfdaa
--- /dev/null
+++ b/visualc/demo.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="demo" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=demo - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "demo.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "demo.mak" CFG="demo - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "demo - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "demo - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "demo - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/demo.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "demo - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "demo_"
+# PROP BASE Intermediate_Dir "demo_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "demo_"
+# PROP Intermediate_Dir "demo_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/demo.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "demo - Win32 Release"
+# Name "demo - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\demo.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/doublebuffer.dsp b/visualc/doublebuffer.dsp
new file mode 100644
index 000000000..54794442b
--- /dev/null
+++ b/visualc/doublebuffer.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="doublebuffer" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=doublebuffer - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "doublebuffer.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "doublebuffer.mak" CFG="doublebuffer - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "doublebuffer - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "doublebuffer - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "doublebuffer - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/doublebuffer.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "doublebuffer - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "doublebuffer_"
+# PROP BASE Intermediate_Dir "doublebuffer_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "doublebuffer_"
+# PROP Intermediate_Dir "doublebuffer_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/doublebuffer.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "doublebuffer - Win32 Release"
+# Name "doublebuffer - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\doublebuffer.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/fast_slow.dsp b/visualc/fast_slow.dsp
new file mode 100644
index 000000000..85f969095
--- /dev/null
+++ b/visualc/fast_slow.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="fast_slow" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fast_slow - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "fast_slow.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "fast_slow.mak" CFG="fast_slow - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "fast_slow - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fast_slow - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "fast_slow - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/fast_slow.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "fast_slow - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "fast_slow_"
+# PROP BASE Intermediate_Dir "fast_slow_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "fast_slow_"
+# PROP Intermediate_Dir "fast_slow_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/fast_slow.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "fast_slow - Win32 Release"
+# Name "fast_slow - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\fast_slow.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/file_chooser.dsp b/visualc/file_chooser.dsp
new file mode 100644
index 000000000..ea47fe127
--- /dev/null
+++ b/visualc/file_chooser.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="file_chooser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=file_chooser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "file_chooser.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "file_chooser.mak" CFG="file_chooser - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "file_chooser - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "file_chooser - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "file_chooser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/file_chooser.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "file_chooser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "file_chooser_"
+# PROP BASE Intermediate_Dir "file_chooser_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "file_chooser_"
+# PROP Intermediate_Dir "file_chooser_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/file_chooser.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "file_chooser - Win32 Release"
+# Name "file_chooser - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\file_chooser.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/fltk.dsw b/visualc/fltk.dsw
new file mode 100644
index 000000000..c9bfed2b3
--- /dev/null
+++ b/visualc/fltk.dsw
@@ -0,0 +1,1013 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "adjuster"=".\adjuster.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "arc"=".\arc.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "ask"=".\ask.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "bitmap"=".\bitmap.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "boxtype"=".\boxtype.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "browser"=".\browser.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "button"=".\button.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "buttons"=".\buttons.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "checkers"=".\checkers.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "clock"=".\clock.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "colbrowser"=".\colbrowser.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "color_chooser"=".\color_chooser.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "cube"=".\cube.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "cursor"=".\cursor.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "curve"=".\curve.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "demo"=".\demo.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name adjuster
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name arc
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name ask
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name bitmap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name boxtype
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name browser
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name button
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name buttons
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name checkers
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name clock
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name colbrowser
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name color_chooser
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name cube
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name cursor
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name curve
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name doublebuffer
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name fast_slow
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name file_chooser
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name fluid
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name fonts
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name forms
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name fractals
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name fullscreen
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name gl_overlay
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name glpuzzle
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name hello
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name iconize
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name image
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name input
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name keyboard
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name label
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mandelbrot
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name menubar
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name message
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name minimum
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name navigation
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name output
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name overlay
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name pixmap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name pixmap_browser
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name radio
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name resize
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name resizebox
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name scroll
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name shape
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name shiny
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name subwindow
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name symbols
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name tabs
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name tile
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name valuators
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name pack
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name style
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name inactive
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "doublebuffer"=".\doublebuffer.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "fast_slow"=".\fast_slow.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "file_chooser"=".\file_chooser.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "fltk"=".\fltk.lib.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "fluid"=".\fluid.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "fonts"=".\fonts.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "forms"=".\forms.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "fractals"=".\fractals.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "fullscreen"=".\fullscreen.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "gl_overlay"=".\gl_overlay.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "glpuzzle"=".\glpuzzle.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "hello"=".\hello.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "iconize"=".\iconize.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "image"=".\image.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "inactive"=".\inactive.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "input"=".\input.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "keyboard"=".\keyboard.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "label"=".\label.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mandelbrot"=".\mandelbrot.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "menubar"=".\menubar.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "message"=".\message.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "minimum"=".\minimum.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "navigation"=".\navigation.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "output"=".\output.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "overlay"=".\overlay.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "pack"=".\pack.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "pixmap"=".\pixmap.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "pixmap_browser"=".\pixmap_browser.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "radio"=".\radio.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "resize"=".\resize.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "resizebox"=".\resizebox.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "scroll"=".\scroll.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "shape"=".\shape.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "shiny"=".\shiny.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "style"=".\style.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "subwindow"=".\subwindow.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "symbols"=".\symbols.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "tabs"=".\tabs.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "tile"=".\tile.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "valuators"=".\valuators.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name fltk
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/visualc/fltk.lib.dsp b/visualc/fltk.lib.dsp
new file mode 100644
index 000000000..fdd50d21f
--- /dev/null
+++ b/visualc/fltk.lib.dsp
@@ -0,0 +1,534 @@
+# Microsoft Developer Studio Project File - Name="fltk" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=fltk - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "fltk.lib.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "fltk.lib.mak" CFG="fltk - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "fltk - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "fltk - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF "$(CFG)" == "fltk - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /Os /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\fltk.lib"
+
+!ELSEIF "$(CFG)" == "fltk - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /TP /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\fltkd.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "fltk - Win32 Release"
+# Name "fltk - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\src\filename_absolute.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\filename_expand.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\filename_ext.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\filename_isdir.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\filename_list.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\filename_match.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\filename_setext.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_abort.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Adjuster.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_arc.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_arci.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_arg.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_ask.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Bitmap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Box.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_boxtype.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Browser.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Browser_.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Browser_load.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Chart.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Check_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Choice.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Clock.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_color.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Color_Chooser.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Counter.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_cursor.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_curve.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_cutpaste.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Dial.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_diamond_box.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_display.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Double_Window.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_draw.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_draw_image.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_draw_pixmap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_engraved_label.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_file_chooser.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_font.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_get_key.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_get_system_colors.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Gl_Choice.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Gl_Choice.H
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Gl_Overlay.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Gl_Window.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Group.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Image.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Input.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Input_.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_labeltype.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Light_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu_.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu_add.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu_Bar.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu_global.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Menu_Window.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Multi_Label.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Output.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_oval_box.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_overlay.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_overlay_visual.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Overlay_Window.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_own_colormap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Pack.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Pixmap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Positioner.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_rect.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Repeat_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Return_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Roller.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_round_box.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Round_Button.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_rounded_box.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Scroll.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_scroll_area.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Scrollbar.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_set_font.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_set_fonts.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_shadow_box.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_shortcut.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_show_colormap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Single_Window.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Slider.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_symbols.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Tabs.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Tile.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Valuator.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Value_Input.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Value_Output.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Value_Slider.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\fl_vertex.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_visual.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Widget.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Window.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Window_fullscreen.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Window_hotspot.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Window_iconize.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_x.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\forms_bitmap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\forms_compatability.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\forms_free.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\forms_fselect.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\forms_pixmap.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\forms_timer.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\gl_draw.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\gl_start.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\glut_compatability.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\glut_font.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\numericsort.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\scandir.c
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/fluid.dsp b/visualc/fluid.dsp
new file mode 100644
index 000000000..386047ad2
--- /dev/null
+++ b/visualc/fluid.dsp
@@ -0,0 +1,156 @@
+# Microsoft Developer Studio Project File - Name="fluid" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fluid - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "fluid.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "fluid.mak" CFG="fluid - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "fluid - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fluid - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "fluid - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "fluid___"
+# PROP BASE Intermediate_Dir "fluid___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "fluid___"
+# PROP Intermediate_Dir "fluid___"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /Os /Ob2 /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../fluid/fluid.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "fluid - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "fluid__0"
+# PROP BASE Intermediate_Dir "fluid__0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "fluid__0"
+# PROP Intermediate_Dir "fluid__0"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../fluid/fluid.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "fluid - Win32 Release"
+# Name "fluid - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\fluid\about_panel.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\alignment_panel.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\code.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\factory.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\file.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fl_Function_Type.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fl_Group_Type.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fl_Menu_Type.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fl_Type.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fl_Widget_Type.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fl_Window_Type.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\fluid.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\Fluid_Image.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\function_panel.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\gif.C
+# End Source File
+# Begin Source File
+
+SOURCE=..\fluid\widget_panel.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/fonts.dsp b/visualc/fonts.dsp
new file mode 100644
index 000000000..b64c50209
--- /dev/null
+++ b/visualc/fonts.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="fonts" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fonts - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "fonts.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "fonts.mak" CFG="fonts - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "fonts - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fonts - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "fonts - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/fonts.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "fonts - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "fonts_"
+# PROP BASE Intermediate_Dir "fonts_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "fonts_"
+# PROP Intermediate_Dir "fonts_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/fonts.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "fonts - Win32 Release"
+# Name "fonts - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\fonts.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/forms.dsp b/visualc/forms.dsp
new file mode 100644
index 000000000..58206ba2d
--- /dev/null
+++ b/visualc/forms.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="forms" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=forms - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "forms.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "forms.mak" CFG="forms - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "forms - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "forms - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "forms - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/forms.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "forms - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "forms_"
+# PROP BASE Intermediate_Dir "forms_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "forms_"
+# PROP Intermediate_Dir "forms_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/forms.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "forms - Win32 Release"
+# Name "forms - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\forms.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/fractals.dsp b/visualc/fractals.dsp
new file mode 100644
index 000000000..0d35ed605
--- /dev/null
+++ b/visualc/fractals.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="fractals" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fractals - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "fractals.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "fractals.mak" CFG="fractals - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "fractals - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fractals - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "fractals - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 glu32.lib opengl32.lib ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/fractals.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "fractals - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "fractals_"
+# PROP BASE Intermediate_Dir "fractals_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "fractals_"
+# PROP Intermediate_Dir "fractals_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 glu32.lib opengl32.lib ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/fractals.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "fractals - Win32 Release"
+# Name "fractals - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\fractals.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/fullscreen.dsp b/visualc/fullscreen.dsp
new file mode 100644
index 000000000..d2948bcba
--- /dev/null
+++ b/visualc/fullscreen.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="fullscreen" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fullscreen - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "fullscreen.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "fullscreen.mak" CFG="fullscreen - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "fullscreen - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fullscreen - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "fullscreen - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 opengl32.lib ..\lib\fltk.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/fullscreen.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "fullscreen - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "fullscreen_"
+# PROP BASE Intermediate_Dir "fullscreen_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "fullscreen_"
+# PROP Intermediate_Dir "fullscreen_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 opengl32.lib ..\lib\fltkd.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/fullscreen.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "fullscreen - Win32 Release"
+# Name "fullscreen - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\fullscreen.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/gl_overlay.dsp b/visualc/gl_overlay.dsp
new file mode 100644
index 000000000..38ed3579c
--- /dev/null
+++ b/visualc/gl_overlay.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="gl_overlay" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=gl_overlay - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "gl_overlay.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "gl_overlay.mak" CFG="gl_overlay - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "gl_overlay - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "gl_overlay - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "gl_overlay - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/gl_overlay.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "gl_overlay - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "gl_overlay_"
+# PROP BASE Intermediate_Dir "gl_overlay_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "gl_overlay_"
+# PROP Intermediate_Dir "gl_overlay_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 opengl32.lib ..\lib\fltkd.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/gl_overlay.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "gl_overlay - Win32 Release"
+# Name "gl_overlay - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\gl_overlay.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/glpuzzle.dsp b/visualc/glpuzzle.dsp
new file mode 100644
index 000000000..3b08be277
--- /dev/null
+++ b/visualc/glpuzzle.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="glpuzzle" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=glpuzzle - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "glpuzzle.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "glpuzzle.mak" CFG="glpuzzle - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "glpuzzle - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "glpuzzle - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "glpuzzle - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 opengl32.lib ..\lib\fltk.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/glpuzzle.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "glpuzzle - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "glpuzzle_"
+# PROP BASE Intermediate_Dir "glpuzzle_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "glpuzzle_"
+# PROP Intermediate_Dir "glpuzzle_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 opengl32.lib glu32.lib ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/glpuzzle.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "glpuzzle - Win32 Release"
+# Name "glpuzzle - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\glpuzzle.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/hello.dsp b/visualc/hello.dsp
new file mode 100644
index 000000000..69503f922
--- /dev/null
+++ b/visualc/hello.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="hello" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=hello - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "hello.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "hello.mak" CFG="hello - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "hello - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "hello - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "hello - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/hello.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "hello - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "hello_"
+# PROP BASE Intermediate_Dir "hello_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "hello_"
+# PROP Intermediate_Dir "hello_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/hello.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "hello - Win32 Release"
+# Name "hello - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\hello.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/iconize.dsp b/visualc/iconize.dsp
new file mode 100644
index 000000000..f9db4c909
--- /dev/null
+++ b/visualc/iconize.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="iconize" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=iconize - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "iconize.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "iconize.mak" CFG="iconize - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "iconize - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "iconize - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "iconize - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/iconize.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "iconize - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "iconize_"
+# PROP BASE Intermediate_Dir "iconize_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "iconize_"
+# PROP Intermediate_Dir "iconize_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/iconize.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "iconize - Win32 Release"
+# Name "iconize - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\iconize.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/image.dsp b/visualc/image.dsp
new file mode 100644
index 000000000..864354510
--- /dev/null
+++ b/visualc/image.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="image" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=image - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "image.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "image.mak" CFG="image - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "image - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "image - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "image - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/image.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "image - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "image_"
+# PROP BASE Intermediate_Dir "image_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "image_"
+# PROP Intermediate_Dir "image_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/image.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "image - Win32 Release"
+# Name "image - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\image.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/inactive.dsp b/visualc/inactive.dsp
new file mode 100755
index 000000000..3cb067bce
--- /dev/null
+++ b/visualc/inactive.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="inactive" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=inactive - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "inactive.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "inactive.mak" CFG="inactive - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "inactive - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "inactive - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "inactive - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/inactive.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "inactive - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "inactive_"
+# PROP BASE Intermediate_Dir "inactive_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "inactive_"
+# PROP Intermediate_Dir "inactive_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/inactive.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "inactive - Win32 Release"
+# Name "inactive - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\inactive.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/input.dsp b/visualc/input.dsp
new file mode 100644
index 000000000..ea895d102
--- /dev/null
+++ b/visualc/input.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="input" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=input - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "input.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "input.mak" CFG="input - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "input - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "input - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "input - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/input.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "input - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "input_"
+# PROP BASE Intermediate_Dir "input_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "input_"
+# PROP Intermediate_Dir "input_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/input.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "input - Win32 Release"
+# Name "input - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\input.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/keyboard.dsp b/visualc/keyboard.dsp
new file mode 100644
index 000000000..ef5a68b00
--- /dev/null
+++ b/visualc/keyboard.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="keyboard" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=keyboard - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "keyboard.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "keyboard.mak" CFG="keyboard - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "keyboard - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "keyboard - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "keyboard - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/keyboard.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "keyboard - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "keyboard_"
+# PROP BASE Intermediate_Dir "keyboard_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "keyboard_"
+# PROP Intermediate_Dir "keyboard_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/keyboard.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "keyboard - Win32 Release"
+# Name "keyboard - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\keyboard.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/label.dsp b/visualc/label.dsp
new file mode 100644
index 000000000..1a1e22e26
--- /dev/null
+++ b/visualc/label.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="label" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=label - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "label.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "label.mak" CFG="label - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "label - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "label - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "label - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/label.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "label - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "label_"
+# PROP BASE Intermediate_Dir "label_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "label_"
+# PROP Intermediate_Dir "label_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/label.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "label - Win32 Release"
+# Name "label - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\label.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/mandelbrot.dsp b/visualc/mandelbrot.dsp
new file mode 100644
index 000000000..e7e5ee19d
--- /dev/null
+++ b/visualc/mandelbrot.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="mandelbrot" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=mandelbrot - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mandelbrot.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mandelbrot.mak" CFG="mandelbrot - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mandelbrot - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "mandelbrot - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mandelbrot - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/mandelbrot.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "mandelbrot - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mandelbrot_"
+# PROP BASE Intermediate_Dir "mandelbrot_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "mandelbrot_"
+# PROP Intermediate_Dir "mandelbrot_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/mandelbrot.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "mandelbrot - Win32 Release"
+# Name "mandelbrot - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\mandelbrot.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/menubar.dsp b/visualc/menubar.dsp
new file mode 100644
index 000000000..4c495e6c0
--- /dev/null
+++ b/visualc/menubar.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="menubar" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=menubar - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "menubar.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "menubar.mak" CFG="menubar - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "menubar - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "menubar - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "menubar - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/menubar.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "menubar - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "menubar_"
+# PROP BASE Intermediate_Dir "menubar_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "menubar_"
+# PROP Intermediate_Dir "menubar_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/menubar.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "menubar - Win32 Release"
+# Name "menubar - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\menubar.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/message.dsp b/visualc/message.dsp
new file mode 100644
index 000000000..145a13ebf
--- /dev/null
+++ b/visualc/message.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="message" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=message - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "message.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "message.mak" CFG="message - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "message - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "message - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "message - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/message.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "message - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "message_"
+# PROP BASE Intermediate_Dir "message_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "message_"
+# PROP Intermediate_Dir "message_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/message.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "message - Win32 Release"
+# Name "message - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\message.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/minimum.dsp b/visualc/minimum.dsp
new file mode 100644
index 000000000..efae55c22
--- /dev/null
+++ b/visualc/minimum.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="minimum" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=minimum - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "minimum.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "minimum.mak" CFG="minimum - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "minimum - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "minimum - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "minimum - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/minimum.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "minimum - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "minimum_"
+# PROP BASE Intermediate_Dir "minimum_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "minimum_"
+# PROP Intermediate_Dir "minimum_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/minimum.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "minimum - Win32 Release"
+# Name "minimum - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\minimum.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/navigation.dsp b/visualc/navigation.dsp
new file mode 100644
index 000000000..8e868bf83
--- /dev/null
+++ b/visualc/navigation.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="navigation" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=navigation - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "navigation.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "navigation.mak" CFG="navigation - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "navigation - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "navigation - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "navigation - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/navigation.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "navigation - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "navigation_"
+# PROP BASE Intermediate_Dir "navigation_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "navigation_"
+# PROP Intermediate_Dir "navigation_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/navigation.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "navigation - Win32 Release"
+# Name "navigation - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\navigation.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/output.dsp b/visualc/output.dsp
new file mode 100644
index 000000000..693eb0236
--- /dev/null
+++ b/visualc/output.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="output" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=output - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "output.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "output.mak" CFG="output - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "output - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "output - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "output - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/output.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "output - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "output_"
+# PROP BASE Intermediate_Dir "output_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "output_"
+# PROP Intermediate_Dir "output_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/output.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "output - Win32 Release"
+# Name "output - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\output.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/overlay.dsp b/visualc/overlay.dsp
new file mode 100644
index 000000000..b6662c64a
--- /dev/null
+++ b/visualc/overlay.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="overlay" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=overlay - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "overlay.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "overlay.mak" CFG="overlay - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "overlay - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "overlay - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "overlay - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/overlay.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "overlay - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "overlay_"
+# PROP BASE Intermediate_Dir "overlay_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "overlay_"
+# PROP Intermediate_Dir "overlay_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/overlay.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "overlay - Win32 Release"
+# Name "overlay - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\overlay.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/pack.dsp b/visualc/pack.dsp
new file mode 100755
index 000000000..d2d9dbb38
--- /dev/null
+++ b/visualc/pack.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="pack" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=pack - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pack.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pack.mak" CFG="pack - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pack - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "pack - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pack - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/pack.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "pack - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "pack_"
+# PROP BASE Intermediate_Dir "pack_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "pack_"
+# PROP Intermediate_Dir "pack_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/pack.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "pack - Win32 Release"
+# Name "pack - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\pack.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/pixmap.dsp b/visualc/pixmap.dsp
new file mode 100644
index 000000000..6c4d7e603
--- /dev/null
+++ b/visualc/pixmap.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="pixmap" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=pixmap - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pixmap.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pixmap.mak" CFG="pixmap - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pixmap - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "pixmap - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pixmap - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/pixmap.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "pixmap - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "pixmap_"
+# PROP BASE Intermediate_Dir "pixmap_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "pixmap_"
+# PROP Intermediate_Dir "pixmap_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/pixmap.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "pixmap - Win32 Release"
+# Name "pixmap - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\pixmap.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/pixmap_browser.dsp b/visualc/pixmap_browser.dsp
new file mode 100644
index 000000000..96e1224c7
--- /dev/null
+++ b/visualc/pixmap_browser.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="pixmap_browser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=pixmap_browser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pixmap_browser.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pixmap_browser.mak" CFG="pixmap_browser - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pixmap_browser - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "pixmap_browser - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pixmap_browser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/pixmap_browser.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "pixmap_browser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "pixmap_browser_"
+# PROP BASE Intermediate_Dir "pixmap_browser_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "pixmap_browser_"
+# PROP Intermediate_Dir "pixmap_browser_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/pixmap_browser.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "pixmap_browser - Win32 Release"
+# Name "pixmap_browser - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\pixmap_browser.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/radio.dsp b/visualc/radio.dsp
new file mode 100644
index 000000000..b5f86032a
--- /dev/null
+++ b/visualc/radio.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="radio" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=radio - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "radio.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "radio.mak" CFG="radio - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "radio - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "radio - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "radio - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/radio.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "radio - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "radio_"
+# PROP BASE Intermediate_Dir "radio_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "radio_"
+# PROP Intermediate_Dir "radio_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/radio.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "radio - Win32 Release"
+# Name "radio - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\radio.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/resize.dsp b/visualc/resize.dsp
new file mode 100644
index 000000000..4b4305a7b
--- /dev/null
+++ b/visualc/resize.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="resize" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=resize - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "resize.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "resize.mak" CFG="resize - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "resize - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "resize - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "resize - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/resize.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "resize - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "resize_"
+# PROP BASE Intermediate_Dir "resize_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "resize_"
+# PROP Intermediate_Dir "resize_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/resize.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "resize - Win32 Release"
+# Name "resize - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\resize.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/resizebox.dsp b/visualc/resizebox.dsp
new file mode 100644
index 000000000..b464684d3
--- /dev/null
+++ b/visualc/resizebox.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="resizebox" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=resizebox - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "resizebox.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "resizebox.mak" CFG="resizebox - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "resizebox - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "resizebox - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "resizebox - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/resizebox.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "resizebox - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "resizebox_"
+# PROP BASE Intermediate_Dir "resizebox_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "resizebox_"
+# PROP Intermediate_Dir "resizebox_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/resizebox.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "resizebox - Win32 Release"
+# Name "resizebox - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\resizebox.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/scroll.dsp b/visualc/scroll.dsp
new file mode 100644
index 000000000..7970793dd
--- /dev/null
+++ b/visualc/scroll.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="scroll" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=scroll - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "scroll.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "scroll.mak" CFG="scroll - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "scroll - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "scroll - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "scroll - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/scroll.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "scroll - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "scroll_"
+# PROP BASE Intermediate_Dir "scroll_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "scroll_"
+# PROP Intermediate_Dir "scroll_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/scroll.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "scroll - Win32 Release"
+# Name "scroll - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\scroll.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/shape.dsp b/visualc/shape.dsp
new file mode 100644
index 000000000..65cacca35
--- /dev/null
+++ b/visualc/shape.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="shape" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=shape - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "shape.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "shape.mak" CFG="shape - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "shape - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "shape - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "shape - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 opengl32.lib ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/shape.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "shape - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "shape_"
+# PROP BASE Intermediate_Dir "shape_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "shape_"
+# PROP Intermediate_Dir "shape_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 opengl32.lib ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/shape.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "shape - Win32 Release"
+# Name "shape - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\shape.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/shiny.dsp b/visualc/shiny.dsp
new file mode 100644
index 000000000..3da8adce5
--- /dev/null
+++ b/visualc/shiny.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="shiny" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=shiny - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "shiny.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "shiny.mak" CFG="shiny - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "shiny - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "shiny - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "shiny - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/shiny.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "shiny - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "shiny_"
+# PROP BASE Intermediate_Dir "shiny_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "shiny_"
+# PROP Intermediate_Dir "shiny_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 opengl32.lib ..\lib\fltkd.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/shiny.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "shiny - Win32 Release"
+# Name "shiny - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\shiny.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/style.dsp b/visualc/style.dsp
new file mode 100755
index 000000000..bd3d1688d
--- /dev/null
+++ b/visualc/style.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="style" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=style - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "style.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "style.mak" CFG="style - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "style - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "style - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "style - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/style.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "style - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "style_"
+# PROP BASE Intermediate_Dir "style_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "style_"
+# PROP Intermediate_Dir "style_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/style.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "style - Win32 Release"
+# Name "style - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\style.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/subwindow.dsp b/visualc/subwindow.dsp
new file mode 100644
index 000000000..d97b30a64
--- /dev/null
+++ b/visualc/subwindow.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="subwindow" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=subwindow - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "subwindow.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "subwindow.mak" CFG="subwindow - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "subwindow - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "subwindow - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "subwindow - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/subwindow.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "subwindow - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "subwindow_"
+# PROP BASE Intermediate_Dir "subwindow_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "subwindow_"
+# PROP Intermediate_Dir "subwindow_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/subwindow.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "subwindow - Win32 Release"
+# Name "subwindow - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\subwindow.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/symbols.dsp b/visualc/symbols.dsp
new file mode 100644
index 000000000..c6f7f5c6c
--- /dev/null
+++ b/visualc/symbols.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="symbols" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=symbols - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "symbols.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "symbols.mak" CFG="symbols - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "symbols - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "symbols - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "symbols - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/symbols.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "symbols - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "symbols_"
+# PROP BASE Intermediate_Dir "symbols_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "symbols_"
+# PROP Intermediate_Dir "symbols_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/symbols.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "symbols - Win32 Release"
+# Name "symbols - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\symbols.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/tabs.dsp b/visualc/tabs.dsp
new file mode 100644
index 000000000..f88f68f32
--- /dev/null
+++ b/visualc/tabs.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="tabs" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=tabs - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "tabs.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "tabs.mak" CFG="tabs - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "tabs - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "tabs - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "tabs - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/tabs.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "tabs - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "tabs_"
+# PROP BASE Intermediate_Dir "tabs_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "tabs_"
+# PROP Intermediate_Dir "tabs_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/tabs.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "tabs - Win32 Release"
+# Name "tabs - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\tabs.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/tile.dsp b/visualc/tile.dsp
new file mode 100644
index 000000000..42c7c23fc
--- /dev/null
+++ b/visualc/tile.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="tile" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=tile - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "tile.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "tile.mak" CFG="tile - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "tile - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "tile - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "tile - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/tile.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "tile - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "tile_"
+# PROP BASE Intermediate_Dir "tile_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "tile_"
+# PROP Intermediate_Dir "tile_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/tile.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "tile - Win32 Release"
+# Name "tile - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\tile.C
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/valuators.dsp b/visualc/valuators.dsp
new file mode 100644
index 000000000..8949d1eca
--- /dev/null
+++ b/visualc/valuators.dsp
@@ -0,0 +1,96 @@
+# Microsoft Developer Studio Project File - Name="valuators" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=valuators - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "valuators.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "valuators.mak" CFG="valuators - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "valuators - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "valuators - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "valuators - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 ..\lib\fltk.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /incremental:yes /machine:I386 /nodefaultlib:"libcd" /out:"../test/valuators.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "valuators - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "valuators_"
+# PROP BASE Intermediate_Dir "valuators_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "valuators_"
+# PROP Intermediate_Dir "valuators_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /TP /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\fltkd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"mainCRTStartup" /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd" /out:"../test/valuators.exe" /pdbtype:sept /libpath:"../win32/Debug"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "valuators - Win32 Release"
+# Name "valuators - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\test\valuators.C
+# End Source File
+# End Target
+# End Project