summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>1998-10-06 18:21:25 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>1998-10-06 18:21:25 +0000
commitf9039b2ae21988783feae9b362818e7923e82d14 (patch)
tree6d6fe3679d73448758f9794e7d4d4f6b22a4adad /test
parent67e89232f9ba067825a158734a09e0fa21aacbe3 (diff)
Initial revision
git-svn-id: file:///fltk/svn/fltk/trunk@2 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'test')
-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
111 files changed, 15145 insertions, 0 deletions
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,
+};