summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/glut.H225
-rw-r--r--src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx2
-rw-r--r--src/glut_compatibility.cxx26
-rw-r--r--test/CMakeLists.txt6
-rw-r--r--test/Makefile7
-rw-r--r--test/glut_test.cxx172
6 files changed, 351 insertions, 87 deletions
diff --git a/FL/glut.H b/FL/glut.H
index 2d4a196c2..6ddf27016 100644
--- a/FL/glut.H
+++ b/FL/glut.H
@@ -26,6 +26,17 @@
// Commented out lines indicate parts of GLUT that are not emulated.
+// Notes: as pointed out in STR #3458 the current GLUT window,
+// i.e. the global static variable 'glut_window' can be NULL ...
+// (a) if not (yet) initialized
+// (b) if the current GLUT window is deleted at any time.
+// The FLTK implementation silently ignores function calls if the current
+// window is NULL to avoid dereferencing a NULL pointer. This is obviously
+// compatible with GLUT version 3.7 according to comment #5 on STR #3458.
+// According to the same comment FreeGLUT 3.0 would issue an error message
+// and quit.
+// Albrecht-S, Oct 2023
+
#ifndef _FL_glut_H_
# define _FL_glut_H_
@@ -81,18 +92,18 @@ FL_EXPORT void glutInit(int *argcp, char **argv); // creates first window
FL_EXPORT void glutInitDisplayMode(unsigned int mode);
// the FL_ symbols have the same value as the GLUT ones:
-# define GLUT_RGB FL_RGB
-# define GLUT_RGBA FL_RGB
-# define GLUT_INDEX FL_INDEX
-# define GLUT_SINGLE FL_SINGLE
-# define GLUT_DOUBLE FL_DOUBLE
-# define GLUT_ACCUM FL_ACCUM
-# define GLUT_ALPHA FL_ALPHA
-# define GLUT_DEPTH FL_DEPTH
-# define GLUT_STENCIL FL_STENCIL
-# define GLUT_MULTISAMPLE FL_MULTISAMPLE
-# define GLUT_STEREO FL_STEREO
-// # define GLUT_LUMINANCE 512
+# define GLUT_RGB FL_RGB
+# define GLUT_RGBA FL_RGB
+# define GLUT_INDEX FL_INDEX
+# define GLUT_SINGLE FL_SINGLE
+# define GLUT_DOUBLE FL_DOUBLE
+# define GLUT_ACCUM FL_ACCUM
+# define GLUT_ALPHA FL_ALPHA
+# define GLUT_DEPTH FL_DEPTH
+# define GLUT_STENCIL FL_STENCIL
+# define GLUT_MULTISAMPLE FL_MULTISAMPLE
+# define GLUT_STEREO FL_STEREO
+// # define GLUT_LUMINANCE 512
FL_EXPORT void glutInitWindowPosition(int x, int y);
@@ -107,37 +118,62 @@ FL_EXPORT int glutCreateSubWindow(int win, int x, int y, int width, int height);
FL_EXPORT void glutDestroyWindow(int win);
-inline void glutPostRedisplay() {glut_window->redraw();}
+inline void glutPostRedisplay() {
+ if (glut_window) glut_window->redraw();
+}
FL_EXPORT void glutPostWindowRedisplay(int win);
FL_EXPORT void glutSwapBuffers();
-inline int glutGetWindow() {return glut_window->number;}
+inline int glutGetWindow() {
+ return glut_window ? glut_window->number : 0;
+}
FL_EXPORT void glutSetWindow(int win);
-inline void glutSetWindowTitle(char *t) {glut_window->label(t);}
+inline void glutSetWindowTitle(char *t) {
+ if (glut_window) glut_window->label(t);
+}
-inline void glutSetIconTitle(char *t) {glut_window->iconlabel(t);}
+inline void glutSetIconTitle(char *t) {
+ if (glut_window) glut_window->iconlabel(t);
+}
-inline void glutPositionWindow(int x, int y) {glut_window->position(x,y);}
+inline void glutPositionWindow(int x, int y) {
+ if (glut_window) glut_window->position(x,y);
+}
-inline void glutReshapeWindow(int w, int h) {glut_window->size(w,h);}
+inline void glutReshapeWindow(int w, int h) {
+ if (glut_window) glut_window->size(w,h);
+}
-inline void glutPopWindow() {glut_window->show();}
+inline void glutPopWindow() {
+ if (glut_window) glut_window->show();
+}
inline void glutPushWindow() { /* do nothing */ }
-inline void glutIconifyWindow() {glut_window->iconize();}
+inline void glutIconifyWindow() {
+ if (glut_window) glut_window->iconize();
+}
-inline void glutShowWindow() {glut_window->show();}
+inline void glutShowWindow() {
+ if (glut_window) glut_window->show();
+}
-inline void glutHideWindow() {glut_window->hide();}
+inline void glutHideWindow() {
+ if (glut_window) glut_window->hide();
+}
-inline void glutFullScreen() {glut_window->fullscreen();}
+inline void glutFullScreen() {
+ if (glut_window) glut_window->fullscreen();
+}
+
+inline void glutSetCursor(Fl_Cursor cursor) {
+ if (glut_window) glut_window->cursor(cursor);
+}
-inline void glutSetCursor(Fl_Cursor cursor) {glut_window->cursor(cursor);}
// notice that the numeric values are different than glut:
# define GLUT_CURSOR_RIGHT_ARROW ((Fl_Cursor)2)
# define GLUT_CURSOR_LEFT_ARROW ((Fl_Cursor)67)
@@ -165,19 +201,33 @@ inline void glutSetCursor(Fl_Cursor cursor) {glut_window->cursor(cursor);}
inline void glutWarpPointer(int, int) { /* do nothing */ }
-inline void glutEstablishOverlay() {glut_window->make_overlay_current();}
+inline void glutEstablishOverlay() {
+ if (glut_window) glut_window->make_overlay_current();
+}
-inline void glutRemoveOverlay() {glut_window->hide_overlay();}
+inline void glutRemoveOverlay() {
+ if (glut_window) glut_window->hide_overlay();
+}
inline void glutUseLayer(GLenum layer) {
- layer ? glut_window->make_overlay_current() : glut_window->make_current();}
+ if (!glut_window)
+ return;
+ layer ? glut_window->make_overlay_current() : glut_window->make_current();
+}
+
enum {GLUT_NORMAL, GLUT_OVERLAY};
-inline void glutPostOverlayRedisplay() {glut_window->redraw_overlay();}
+inline void glutPostOverlayRedisplay() {
+ if (glut_window) glut_window->redraw_overlay();
+}
-inline void glutShowOverlay() {glut_window->redraw_overlay();}
+inline void glutShowOverlay() {
+ if (glut_window) glut_window->redraw_overlay();
+}
-inline void glutHideOverlay() {glut_window->hide_overlay();}
+inline void glutHideOverlay() {
+ if (glut_window) glut_window->hide_overlay();
+}
FL_EXPORT int glutCreateMenu(void (*)(int));
@@ -197,34 +247,53 @@ FL_EXPORT void glutChangeToSubMenu(int item, char *label, int submenu);
FL_EXPORT void glutRemoveMenuItem(int item);
-inline void glutAttachMenu(int b) {glut_window->menu[b] = glut_menu;}
+inline void glutAttachMenu(int b) {
+ if (glut_window) glut_window->menu[b] = glut_menu;
+}
-inline void glutDetachMenu(int b) {glut_window->menu[b] = 0;}
+inline void glutDetachMenu(int b) {
+ if (glut_window) glut_window->menu[b] = 0;
+}
-inline void glutDisplayFunc(void (*f)()) {glut_window->display = f;}
+inline void glutDisplayFunc(void (*f)()) {
+ if (glut_window) glut_window->display = f;
+}
-inline void glutReshapeFunc(void (*f)(int w, int h)) {glut_window->reshape=f;}
+inline void glutReshapeFunc(void (*f)(int w, int h)) {
+ if (glut_window) glut_window->reshape = f;
+}
inline void glutKeyboardFunc(void (*f)(uchar key, int x, int y)) {
- glut_window->keyboard = f;}
+ if (glut_window) glut_window->keyboard = f;
+}
inline void glutMouseFunc(void (*f)(int b, int state, int x, int y)) {
- glut_window->mouse = f;}
+ if (glut_window) glut_window->mouse = f;
+}
+
# define GLUT_LEFT_BUTTON 0
# define GLUT_MIDDLE_BUTTON 1
# define GLUT_RIGHT_BUTTON 2
# define GLUT_DOWN 0
# define GLUT_UP 1
-inline void glutMotionFunc(void (*f)(int x, int y)) {glut_window->motion= f;}
+inline void glutMotionFunc(void (*f)(int x, int y)) {
+ if (glut_window) glut_window->motion = f;
+}
inline void glutPassiveMotionFunc(void (*f)(int x, int y)) {
- glut_window->passivemotion= f;}
+ if (glut_window) glut_window->passivemotion = f;
+}
+
+inline void glutEntryFunc(void (*f)(int s)) {
+ if (glut_window) glut_window->entry = f;
+}
-inline void glutEntryFunc(void (*f)(int s)) {glut_window->entry = f;}
enum {GLUT_LEFT, GLUT_ENTERED};
-inline void glutVisibilityFunc(void (*f)(int s)) {glut_window->visibility=f;}
+inline void glutVisibilityFunc(void (*f)(int s)) {
+ if (glut_window) glut_window->visibility = f;
+}
enum {GLUT_NOT_VISIBLE, GLUT_VISIBLE};
FL_EXPORT void glutIdleFunc(void (*f)());
@@ -241,7 +310,9 @@ inline void glutMenuStatusFunc(void (*f)(int status, int x, int y)) {
enum {GLUT_MENU_NOT_IN_USE, GLUT_MENU_IN_USE};
inline void glutSpecialFunc(void (*f)(int key, int x, int y)) {
- glut_window->special = f;}
+ if (glut_window) glut_window->special = f;
+}
+
# define GLUT_KEY_F1 1
# define GLUT_KEY_F2 2
# define GLUT_KEY_F3 3
@@ -265,35 +336,36 @@ inline void glutSpecialFunc(void (*f)(int key, int x, int y)) {
# define GLUT_KEY_END FL_End
# define GLUT_KEY_INSERT FL_Insert
-//inline void glutSpaceballMotionFunc(void (*)(int x, int y, int z));
+// inline void glutSpaceballMotionFunc(void (*)(int x, int y, int z));
-//inline void glutSpaceballRotateFunc(void (*)(int x, int y, int z));
+// inline void glutSpaceballRotateFunc(void (*)(int x, int y, int z));
-//inline void glutSpaceballButtonFunc(void (*)(int button, int state));
+// inline void glutSpaceballButtonFunc(void (*)(int button, int state));
-//inline void glutButtonBoxFunc(void (*)(int button, int state));
+// inline void glutButtonBoxFunc(void (*)(int button, int state));
-//inline void glutDialsFunc(void (*)(int dial, int value));
+// inline void glutDialsFunc(void (*)(int dial, int value));
-//inline void glutTabletMotionFunc(void (*)(int x, int y));
+// inline void glutTabletMotionFunc(void (*)(int x, int y));
-//inline void glutTabletButtonFunc(void (*)(int button, int state, int x, int y));
+// inline void glutTabletButtonFunc(void (*)(int button, int state, int x, int y));
inline void glutOverlayDisplayFunc(void (*f)()) {
- glut_window->overlaydisplay = f;}
+ if (glut_window) glut_window->overlaydisplay = f;
+}
-//inline void glutWindowStatusFunc(void (*)(int state));
-//enum {GLUT_HIDDEN, GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED,
-// GLUT_FULLY_COVERED};
+// inline void glutWindowStatusFunc(void (*)(int state));
+// enum {GLUT_HIDDEN, GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED,
+// GLUT_FULLY_COVERED};
-//inline void glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+// inline void glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
-//inline GLfloat glutGetColor(int ndx, int component);
-//#define GLUT_RED 0
-//#define GLUT_GREEN 1
-//#define GLUT_BLUE 2
+// inline GLfloat glutGetColor(int ndx, int component);
+// #define GLUT_RED 0
+// #define GLUT_GREEN 1
+// #define GLUT_BLUE 2
-//inline void glutCopyColormap(int win);
+// inline void glutCopyColormap(int win);
// Warning: values are changed from GLUT!
// Also relies on the GL_ symbols having values greater than 100
@@ -359,13 +431,16 @@ FL_EXPORT int glutDeviceGet(GLenum type);
# define GLUT_ACTIVE_SHIFT FL_SHIFT
# define GLUT_ACTIVE_CTRL FL_CTRL
# define GLUT_ACTIVE_ALT FL_ALT
-inline int glutGetModifiers() {return Fl::event_state() & (GLUT_ACTIVE_SHIFT | GLUT_ACTIVE_CTRL | GLUT_ACTIVE_ALT);}
+
+inline int glutGetModifiers() {
+ return Fl::event_state() & (GLUT_ACTIVE_SHIFT | GLUT_ACTIVE_CTRL | GLUT_ACTIVE_ALT);
+}
FL_EXPORT int glutLayerGet(GLenum);
# define GLUT_OVERLAY_POSSIBLE 800
//#define GLUT_LAYER_IN_USE 801
//#define GLUT_HAS_OVERLAY 802
-# define GLUT_TRANSPARENT_INDEX 803
+# define GLUT_TRANSPARENT_INDEX 803
# define GLUT_NORMAL_DAMAGED 804
# define GLUT_OVERLAY_DAMAGED 805
@@ -375,25 +450,25 @@ typedef void (*GLUTproc)();
FL_EXPORT GLUTproc glutGetProcAddress(const char *procName);
-//inline int glutVideoResizeGet(GLenum param);
-//#define GLUT_VIDEO_RESIZE_POSSIBLE 900
-//#define GLUT_VIDEO_RESIZE_IN_USE 901
-//#define GLUT_VIDEO_RESIZE_X_DELTA 902
-//#define GLUT_VIDEO_RESIZE_Y_DELTA 903
-//#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904
-//#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905
-//#define GLUT_VIDEO_RESIZE_X 906
-//#define GLUT_VIDEO_RESIZE_Y 907
-//#define GLUT_VIDEO_RESIZE_WIDTH 908
-//#define GLUT_VIDEO_RESIZE_HEIGHT 909
+// inline int glutVideoResizeGet(GLenum param);
+// #define GLUT_VIDEO_RESIZE_POSSIBLE 900
+// #define GLUT_VIDEO_RESIZE_IN_USE 901
+// #define GLUT_VIDEO_RESIZE_X_DELTA 902
+// #define GLUT_VIDEO_RESIZE_Y_DELTA 903
+// #define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904
+// #define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905
+// #define GLUT_VIDEO_RESIZE_X 906
+// #define GLUT_VIDEO_RESIZE_Y 907
+// #define GLUT_VIDEO_RESIZE_WIDTH 908
+// #define GLUT_VIDEO_RESIZE_HEIGHT 909
-//inline void glutSetupVideoResizing();
+// inline void glutSetupVideoResizing();
-//inline void glutStopVideoResizing();
+// inline void glutStopVideoResizing();
-//inline void glutVideoResize(int x, int y, int width, int height);
+// inline void glutVideoResize(int x, int y, int width, int height);
-//inline void glutVideoPan(int x, int y, int width, int height);
+// inline void glutVideoPan(int x, int y, int width, int height);
// Font argument must be a void* for compatibility, so...
/** fltk glut font/size attributes used in the glutXXX functions */
diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
index bbcebbd84..3f09edae2 100644
--- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
@@ -388,6 +388,8 @@ int Fl_X11_Gl_Window_Driver::mode_(int m, const int *a) {
}
void Fl_X11_Gl_Window_Driver::swap_buffers() {
+ if (!fl_xid(pWindow)) // window not shown
+ return;
glXSwapBuffers(fl_display, fl_xid(pWindow));
}
diff --git a/src/glut_compatibility.cxx b/src/glut_compatibility.cxx
index adcac1b7a..df25c456b 100644
--- a/src/glut_compatibility.cxx
+++ b/src/glut_compatibility.cxx
@@ -1,7 +1,7 @@
//
// GLUT emulation routines for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2016 by Bill Spitzak and others.
+// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -14,11 +14,11 @@
// https://www.fltk.org/bugs.php
//
-// Emulation of Glut using fltk.
+// Emulation of Glut using FLTK.
// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996.
-// "This program is freely distributable without licensing fees and is
-// provided without guarantee or warrantee expressed or implied. This
+// "This program is freely distributable without licensing fees and is
+// provided without guarantee or warrantee expressed or implied. This
// program is -not- in the public domain."
// Although I have copied the GLUT API, none of my code is based on
@@ -35,6 +35,7 @@ static Fl_Glut_Window *windows[MAXWINDOWS+1];
static void (*glut_idle_func)() = 0; // global glut idle function
+// The current GLUT window, may be NULL. See also STR #3458.
Fl_Glut_Window *glut_window;
int glut_menu;
void (*glut_menustate_function)(int);
@@ -61,7 +62,8 @@ void Fl_Glut_Window::draw() {
}
void glutSwapBuffers() {
- if (!indraw) glut_window->swap_buffers();
+ if (!indraw && glut_window)
+ glut_window->swap_buffers();
}
void Fl_Glut_Window::draw_overlay() {
@@ -389,12 +391,12 @@ void glutRemoveMenuItem(int item) {
int glutGet(GLenum type) {
switch (type) {
case GLUT_RETURN_ZERO: return 0;
- case GLUT_WINDOW_X: return glut_window->x();
- case GLUT_WINDOW_Y: return glut_window->y();
- case GLUT_WINDOW_WIDTH: return glut_window->pixel_w();
- case GLUT_WINDOW_HEIGHT: return glut_window->pixel_h();
+ case GLUT_WINDOW_X: return glut_window ? glut_window->x() : 0;
+ case GLUT_WINDOW_Y: return glut_window ? glut_window->y() : 0;
+ case GLUT_WINDOW_WIDTH: return glut_window ? glut_window->pixel_w() : 0;
+ case GLUT_WINDOW_HEIGHT: return glut_window ? glut_window->pixel_h() : 0;
case GLUT_WINDOW_PARENT:
- if (glut_window->parent())
+ if (glut_window && glut_window->parent())
return ((Fl_Glut_Window *)(glut_window->parent()))->number;
else
return 0;
@@ -432,11 +434,11 @@ int glutGet(GLenum type) {
int glutLayerGet(GLenum type) {
switch (type) {
- case GLUT_OVERLAY_POSSIBLE: return glut_window->can_do_overlay();
+ case GLUT_OVERLAY_POSSIBLE: return glut_window ? glut_window->can_do_overlay() : 0;
//case GLUT_LAYER_IN_USE:
//case GLUT_HAS_OVERLAY:
case GLUT_TRANSPARENT_INDEX: return 0; // true for SGI
- case GLUT_NORMAL_DAMAGED: return glut_window->damage();
+ case GLUT_NORMAL_DAMAGED: return glut_window ? glut_window->damage() : 0;
case GLUT_OVERLAY_DAMAGED: return 1; // kind of works...
default: return 0;
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1687ebfb8..a44498c4d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -87,11 +87,17 @@ CREATE_EXAMPLE (flex_login flex_login.cxx fltk)
CREATE_EXAMPLE (fltk-versions fltk-versions.cxx fltk)
CREATE_EXAMPLE (fonts fonts.cxx fltk)
CREATE_EXAMPLE (forms forms.cxx "fltk_forms;fltk")
+
+if (OPENGL_FOUND)
+ CREATE_EXAMPLE (glut_test glut_test.cxx "fltk_gl;fltk")
+endif()
+
if (OPENGL_FOUND)
CREATE_EXAMPLE (handle_events handle_events.cxx "fltk_gl;fltk") # opt. Fl_Gl_Window
else()
CREATE_EXAMPLE (handle_events handle_events.cxx fltk) # w/o Fl_Gl_Window
endif()
+
CREATE_EXAMPLE (hello hello.cxx fltk)
CREATE_EXAMPLE (help_dialog help_dialog.cxx "fltk_images;fltk")
CREATE_EXAMPLE (icon icon.cxx fltk)
diff --git a/test/Makefile b/test/Makefile
index b79a9f766..e73431b03 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -75,6 +75,7 @@ CPPFILES =\
fullscreen.cxx \
gl_overlay.cxx \
glpuzzle.cxx \
+ glut_test.cxx \
hello.cxx \
help_dialog.cxx \
icon.cxx \
@@ -226,6 +227,7 @@ GLALL = \
fullscreen$(EXEEXT) \
gl_overlay$(EXEEXT) \
glpuzzle$(EXEEXT) \
+ glut_test$(EXEEXT) \
shape$(EXEEXT) \
unittests$(EXEEXT)
@@ -661,6 +663,11 @@ gl_overlay$(EXEEXT): gl_overlay.o
$(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ gl_overlay.o $(LINKFLTKGL) $(LINKFLTK) $(GLDLIBS)
$(OSX_ONLY) ../fltk-config --post $@
+glut_test$(EXEEXT): glut_test.o
+ echo Linking $@...
+ $(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ glut_test.o $(LINKFLTKGL) $(LINKFLTK) $(GLDLIBS)
+ $(OSX_ONLY) ../fltk-config --post $@
+
unittests$(EXEEXT): $(OBJUNITTEST)
echo Linking $@...
$(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJUNITTEST) $(LINKFLTKGL) $(LINKFLTK) $(GLDLIBS)
diff --git a/test/glut_test.cxx b/test/glut_test.cxx
new file mode 100644
index 000000000..0a7facc86
--- /dev/null
+++ b/test/glut_test.cxx
@@ -0,0 +1,172 @@
+//
+// GLUT test program for the Fast Light Tool Kit (FLTK).
+//
+// Provided by Brian Schack (STR #3458, see "big.cxx").
+// Copyright 2023 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+// Thanks to the original author Brian Schack for this test program.
+// This program has been extended to test several GLUT functions with
+// (1) a valid and (2) an invalid (destroyed) GLUT window.
+// The test program opens two GLUT windows, runs the tests, prints
+// diagnostics on stdout, and exits immediately. This is intended.
+
+// To compile (examples with different GLUT implementations)
+// as of Apr 03, 2018 provided Brian Schack, slightly modified
+//
+// macOS GLUT:
+// g++ -o glut_test glut_test.cxx -framework OpenGL -framework GLUT
+//
+// FreeGLUT (on macOS, with Macport's FreeGLUT):
+// g++ -o glut_test glut_test.cxx -framework OpenGL -I/opt/local/include -L/opt/local/lib -lglut
+//
+// FLTK
+// fltk-config --use-gl --compile glut_test.cxx
+
+// Enable one of the following two #include's depending on the GLUT implementation
+
+// #include <GLUT/glut.h> // GLUT and FreeGLUT version
+#include <FL/glut.H> // FLTK version
+
+#include <stdio.h>
+
+// Empty callback functions for testing.
+void displayFunc() {}
+void reshapeFunc(int w, int h) {}
+void keyboardFunc(unsigned char key, int x, int y) {}
+void mouseFunc(int b, int state, int x, int y) {}
+void motionFunc(int x, int y) {}
+void passiveMotionFunc(int x, int y) {}
+void entryFunc(int s) {}
+void visibilityFunc(int s) {}
+void idleFunc() {}
+void timerFunc(int value) {}
+void menuStateFunc(int state) {}
+void menuStatusFunc(int status, int x, int y) {}
+void specialFunc(int key, int x, int y) {}
+void overlayDisplayFunc() {}
+
+int main(int argc, char **argv) {
+ glutInit(&argc, argv);
+
+ // Create 2 windows.
+ int win1 = glutCreateWindow("Window 1");
+ int win2 = glutCreateWindow("Window 2");
+ printf("Window 1 created, number = %d\n", win1);
+ printf("Window 2 created, number = %d\n", win2);
+
+ // Run tests twice, with (1) a valid and (2) an invalid current window
+
+ for (int i = 0; i < 2; i++) {
+
+ // Find out which window is current.
+ int current = glutGetWindow();
+ printf("Window %d is current\n", current);
+
+ // Ask GLUT to redisplay things.
+ glutPostRedisplay();
+
+ // Set window title
+ glutSetWindowTitle((char *)"Non-existent");
+
+ // Set icon title
+ glutSetIconTitle((char *)"Non-existent");
+
+ // Position window
+ glutPositionWindow(10, 20);
+
+ // Reshape window
+ glutReshapeWindow(100, 200);
+
+ // Pop window
+ glutPopWindow();
+
+ // Iconify window
+ glutIconifyWindow();
+
+ // Show window
+ glutShowWindow();
+
+ // Hide window
+ glutHideWindow();
+
+ // Go to full screen mode
+ glutFullScreen();
+
+ // Set the cursor
+ glutSetCursor(GLUT_CURSOR_INFO);
+
+ // Establish an overlay
+ glutEstablishOverlay();
+
+ // Remove overlay
+ glutRemoveOverlay();
+
+ // Choose a layer
+ glutUseLayer(GLUT_NORMAL);
+ glutUseLayer(GLUT_OVERLAY);
+
+ // Post display on a layer
+ glutPostOverlayRedisplay();
+
+ // Show overlay
+ glutShowOverlay();
+
+ // Hide overlay
+ glutHideOverlay();
+
+ // Attach a menu
+ glutAttachMenu(0);
+
+ // Detach a menu
+ glutDetachMenu(0);
+
+ // Specify callbacks
+ glutDisplayFunc(displayFunc);
+ glutReshapeFunc(reshapeFunc);
+ glutKeyboardFunc(keyboardFunc);
+ glutMouseFunc(mouseFunc);
+ glutMotionFunc(motionFunc);
+ glutPassiveMotionFunc(passiveMotionFunc);
+ glutEntryFunc(entryFunc);
+ glutVisibilityFunc(visibilityFunc);
+ glutIdleFunc(idleFunc);
+ glutTimerFunc(1000, timerFunc, 42);
+ glutMenuStateFunc(menuStateFunc);
+ glutMenuStatusFunc(menuStatusFunc);
+ glutSpecialFunc(specialFunc);
+ glutOverlayDisplayFunc(overlayDisplayFunc);
+
+ // Swap buffers
+ glutSwapBuffers();
+
+ // GLUT gets
+ printf("GLUT_WINDOW_X = %d\n", glutGet(GLUT_WINDOW_X));
+ printf("GLUT_WINDOW_Y = %d\n", glutGet(GLUT_WINDOW_Y));
+ printf("GLUT_WINDOW_WIDTH = %d\n", glutGet(GLUT_WINDOW_WIDTH));
+ printf("GLUT_WINDOW_HEIGHT = %d\n", glutGet(GLUT_WINDOW_HEIGHT));
+ printf("GLUT_WINDOW_PARENT = %d\n", glutGet(GLUT_WINDOW_PARENT));
+
+ // GLUT layer gets
+ printf("GLUT_OVERLAY_POSSIBLE = %d\n", glutLayerGet(GLUT_OVERLAY_POSSIBLE));
+ printf("GLUT_NORMAL_DAMAGED = %d\n", glutLayerGet(GLUT_NORMAL_DAMAGED));
+
+ // Destroy the current window - this sets glut_window to NULL
+ printf("Destroy the current window (%d)\n\n", glutGetWindow());
+ glutDestroyWindow(current);
+
+ } // loop with current window
+
+ printf("All tests done, exiting.\n");
+ return 0;
+}