diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-10-06 18:21:25 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-10-06 18:21:25 +0000 |
| commit | f9039b2ae21988783feae9b362818e7923e82d14 (patch) | |
| tree | 6d6fe3679d73448758f9794e7d4d4f6b22a4adad /test | |
| parent | 67e89232f9ba067825a158734a09e0fa21aacbe3 (diff) | |
Initial revision
git-svn-id: file:///fltk/svn/fltk/trunk@2 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'test')
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, +}; |
