From 95f893643050ecc00bdffa08e3d4cb1148af3e20 Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Sun, 14 Nov 1999 01:01:50 +0100
Subject: [PATCH] Here we go..

Rev: src/post_modules/GLUT/.cvsignore:1.1
Rev: src/post_modules/GLUT/Makefile.in:1.1
Rev: src/post_modules/GLUT/acconfig.h:1.1
Rev: src/post_modules/GLUT/auto.c.in:1.1
Rev: src/post_modules/GLUT/configure.in:1.1
Rev: src/post_modules/GLUT/constants.pike:1.1
Rev: src/post_modules/GLUT/features.pike:1.1
Rev: src/post_modules/GLUT/gen.pike:1.1
Rev: src/post_modules/GLUT/top.c:1.1
---
 .gitattributes                       |   5 +
 src/post_modules/GLUT/.cvsignore     |  16 +
 src/post_modules/GLUT/.gitignore     |  16 +
 src/post_modules/GLUT/Makefile.in    |  13 +
 src/post_modules/GLUT/acconfig.h     |   5 +
 src/post_modules/GLUT/auto.c.in      |  49 +++
 src/post_modules/GLUT/configure.in   |  51 +++
 src/post_modules/GLUT/constants.pike | 166 ++++++++++
 src/post_modules/GLUT/features.pike  | 338 ++++++++++++++++++++
 src/post_modules/GLUT/gen.pike       | 452 +++++++++++++++++++++++++++
 src/post_modules/GLUT/top.c          |  38 +++
 11 files changed, 1149 insertions(+)
 create mode 100644 src/post_modules/GLUT/.cvsignore
 create mode 100644 src/post_modules/GLUT/.gitignore
 create mode 100644 src/post_modules/GLUT/Makefile.in
 create mode 100644 src/post_modules/GLUT/acconfig.h
 create mode 100644 src/post_modules/GLUT/auto.c.in
 create mode 100755 src/post_modules/GLUT/configure.in
 create mode 100644 src/post_modules/GLUT/constants.pike
 create mode 100644 src/post_modules/GLUT/features.pike
 create mode 100755 src/post_modules/GLUT/gen.pike
 create mode 100644 src/post_modules/GLUT/top.c

diff --git a/.gitattributes b/.gitattributes
index 0dbee791cc..1ced9d96be 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -465,6 +465,11 @@ testfont binary
 /src/post_modules/GL/auto.c.in foreign_ident
 /src/post_modules/GL/configure.in foreign_ident
 /src/post_modules/GL/top.c foreign_ident
+/src/post_modules/GLUT/Makefile.in foreign_ident
+/src/post_modules/GLUT/acconfig.h foreign_ident
+/src/post_modules/GLUT/auto.c.in foreign_ident
+/src/post_modules/GLUT/configure.in foreign_ident
+/src/post_modules/GLUT/top.c foreign_ident
 /src/post_modules/GTK/acconfig.h foreign_ident
 /src/post_modules/GTK/dummy.c foreign_ident
 /src/post_modules/GTK/source/gladexml.pre foreign_ident
diff --git a/src/post_modules/GLUT/.cvsignore b/src/post_modules/GLUT/.cvsignore
new file mode 100644
index 0000000000..ae2922eca1
--- /dev/null
+++ b/src/post_modules/GLUT/.cvsignore
@@ -0,0 +1,16 @@
+.pure
+Makefile
+config.h
+config.h.in
+config.log
+config.cache
+config.status
+configure
+dependencies
+linker_options
+modlist_headers
+modlist_segment
+module_testsuite
+stamp-h
+stamp-h.in
+auto.c
diff --git a/src/post_modules/GLUT/.gitignore b/src/post_modules/GLUT/.gitignore
new file mode 100644
index 0000000000..1d89051b2f
--- /dev/null
+++ b/src/post_modules/GLUT/.gitignore
@@ -0,0 +1,16 @@
+/.pure
+/Makefile
+/config.h
+/config.h.in
+/config.log
+/config.cache
+/config.status
+/configure
+/dependencies
+/linker_options
+/modlist_headers
+/modlist_segment
+/module_testsuite
+/stamp-h
+/stamp-h.in
+/auto.c
diff --git a/src/post_modules/GLUT/Makefile.in b/src/post_modules/GLUT/Makefile.in
new file mode 100644
index 0000000000..cdd69f900c
--- /dev/null
+++ b/src/post_modules/GLUT/Makefile.in
@@ -0,0 +1,13 @@
+# $Id: Makefile.in,v 1.1 1999/11/14 00:01:49 per Exp $
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+OBJS=top.o @AUTO@
+MODULE_LDFLAGS=@LDFLAGS@ @LIBS@
+CONFIG_HEADERS=@CONFIG_HEADERS@
+
+@dynamic_module_makefile@
+
+$(SRCDIR)/auto.c : $(SRCDIR)/auto.c.in $(SRCDIR)/features.pike $(SRCDIR)/constants.pike $(SRCDIR)/gen.pike
+	$(RUNPIKE) $(SRCDIR)/gen.pike < $(SRCDIR)/auto.c.in > $(SRCDIR)/auto.c
+
+@dependencies@
diff --git a/src/post_modules/GLUT/acconfig.h b/src/post_modules/GLUT/acconfig.h
new file mode 100644
index 0000000000..896ad947bf
--- /dev/null
+++ b/src/post_modules/GLUT/acconfig.h
@@ -0,0 +1,5 @@
+/* $Id: acconfig.h,v 1.1 1999/11/14 00:01:49 per Exp $ */
+
+/* Define if you have libGL */
+#undef HAVE_LIBGLUT
+
diff --git a/src/post_modules/GLUT/auto.c.in b/src/post_modules/GLUT/auto.c.in
new file mode 100644
index 0000000000..3a4fcb3e7f
--- /dev/null
+++ b/src/post_modules/GLUT/auto.c.in
@@ -0,0 +1,49 @@
+/*
+ * $Id: auto.c.in,v 1.1 1999/11/14 00:01:49 per Exp $
+ *
+ */
+
+#include "global.h"
+
+#include "config.h"
+
+RCSID("$Id: auto.c.in,v 1.1 1999/11/14 00:01:49 per Exp $");
+#include "stralloc.h"
+#include "pike_macros.h"
+#include "object.h"
+#include "program.h"
+#include "interpret.h"
+#include "builtin_functions.h"
+#include "error.h"
+#include "module_support.h"
+#include "operators.h"
+
+#define GLUT_API_VERSION 4
+
+#ifdef HAVE_GL_GLUT_H
+#include <GL/glut.h>
+#endif
+
+static void pre_init()
+{
+}
+
+static void f_glutInit(INT32 args)
+{
+  int argc = 1;
+  extern char ** ARGV;
+  glutInit(&argc,ARGV);
+  pop_n_elems(args);
+}
+
+static void post_init()
+{
+  add_function_constant("glutInit", f_glutInit,
+			"function(void:void)", OPT_SIDE_EFFECT);
+}
+
+
+
+
+@@
+
diff --git a/src/post_modules/GLUT/configure.in b/src/post_modules/GLUT/configure.in
new file mode 100755
index 0000000000..162bf41adb
--- /dev/null
+++ b/src/post_modules/GLUT/configure.in
@@ -0,0 +1,51 @@
+# $Id: configure.in,v 1.1 1999/11/14 00:01:49 per Exp $
+AC_INIT(top.c)
+AC_CONFIG_HEADER(config.h)
+
+AC_MODULE_INIT()
+
+AC_SUBST(AUTO)
+AC_PATH_XTRA()
+AC_ARG_WITH(GLUT,  [  --without-GLUT    no support for GLUT],[without_GLUT=yes],[without_GLUT=no])
+
+if test x$without_GLUT = xyes; then
+  :
+else
+
+AC_CHECK_LIB(X11, main)
+AC_CHECK_LIB(Xmu, main)
+AC_CHECK_LIB(GL,  main)
+AC_CHECK_LIB(OpenGL,  main)
+AC_CHECK_LIB(MesaGL,  main)
+AC_CHECK_LIB(MesaGLU,  main)
+AC_CHECK_LIB(Xinput, main)
+AC_CHECK_LIB(Xi, main)
+AC_CHECK_LIB(Xext, main)
+
+AC_CHECK_HEADERS(GL/glut.h)
+
+oldLIBS="$LIBS"
+AC_MSG_CHECKING(for glutSolidTeapot in -lglut)
+AC_CACHE_VAL(pike_cv_lib_glut, [
+  LIBS="$oldLIBS -lglut"
+  AC_TRY_LINK([
+#ifdef HAVE_GL_GLUT_H
+#include <GL/glut.h>
+#endif /* HAVE_GL_GLUT_H */
+], [ glutSolidTeapot(1.0) ], [ pike_cv_lib_glut=yes ], [ pike_cv_lib_glut=no ])
+])
+LIBS="$oldLIBS"
+if test x"$pike_cv_lib_glut" = xyes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE_UNQUOTED(HAVE_LIBGLUT)
+  LIBS="-lglut $LIBS"
+  AUTO=auto.o
+else
+  AC_MSG_RESULT(no)
+  AUTO=""
+fi
+else
+  AUTO=""
+fi
+
+AC_OUTPUT(Makefile,echo FOO >stamp-h )
diff --git a/src/post_modules/GLUT/constants.pike b/src/post_modules/GLUT/constants.pike
new file mode 100644
index 0000000000..94f6b56fa2
--- /dev/null
+++ b/src/post_modules/GLUT/constants.pike
@@ -0,0 +1,166 @@
+ mapping constants = ([
+ "GLUT_RGB":			0,
+ "GLUT_RGBA":			0,
+ "GLUT_INDEX":			1,
+ "GLUT_SINGLE":			0,
+ "GLUT_DOUBLE":			2,
+ "GLUT_ACCUM":			4,
+ "GLUT_ALPHA":			8,
+ "GLUT_DEPTH":			16,
+ "GLUT_STENCIL":		32,
+ "GLUT_MULTISAMPLE":		128,
+ "GLUT_STEREO":			256,
+ "GLUT_LUMINANCE":		512,
+ "GLUT_LEFT_BUTTON":		0,
+ "GLUT_MIDDLE_BUTTON":		1,
+ "GLUT_RIGHT_BUTTON":		2,
+ "GLUT_DOWN":			0,
+ "GLUT_UP":			1,
+ "GLUT_KEY_F1":			1,
+ "GLUT_KEY_F2":			2,
+ "GLUT_KEY_F3":			3,
+ "GLUT_KEY_F4":			4,
+ "GLUT_KEY_F5":			5,
+ "GLUT_KEY_F6":			6,
+ "GLUT_KEY_F7":			7,
+ "GLUT_KEY_F8":			8,
+ "GLUT_KEY_F9":			9,
+ "GLUT_KEY_F10":		10,
+ "GLUT_KEY_F11":		11,
+ "GLUT_KEY_F12":		12,
+ "GLUT_KEY_LEFT":		100,
+ "GLUT_KEY_UP":			101,
+ "GLUT_KEY_RIGHT":		102,
+ "GLUT_KEY_DOWN":		103,
+ "GLUT_KEY_PAGE_UP":		104,
+ "GLUT_KEY_PAGE_DOWN":		105,
+ "GLUT_KEY_HOME":		106,
+ "GLUT_KEY_END":		107,
+ "GLUT_KEY_INSERT":		108,
+ "GLUT_LEFT":			0,
+ "GLUT_ENTERED":		1,
+ "GLUT_MENU_NOT_IN_USE":	0,
+ "GLUT_MENU_IN_USE":		1,
+ "GLUT_NOT_VISIBLE":		0,
+ "GLUT_VISIBLE":		1,
+ "GLUT_HIDDEN":			0,
+ "GLUT_FULLY_RETAINED":		1,
+ "GLUT_PARTIALLY_RETAINED":	2,
+ "GLUT_FULLY_COVERED":		3,
+ "GLUT_RED":			0,
+ "GLUT_GREEN":			1,
+ "GLUT_BLUE":			2,
+ "GLUT_NORMAL":			0,
+ "GLUT_OVERLAY":		1,
+ "GLUT_WINDOW_X":		100,
+ "GLUT_WINDOW_Y":		101,
+ "GLUT_WINDOW_WIDTH":		102,
+ "GLUT_WINDOW_HEIGHT":		103,
+ "GLUT_WINDOW_BUFFER_SIZE":	104,
+ "GLUT_WINDOW_STENCIL_SIZE":	105,
+ "GLUT_WINDOW_DEPTH_SIZE":	106,
+ "GLUT_WINDOW_RED_SIZE":	107,
+ "GLUT_WINDOW_GREEN_SIZE":	108,
+ "GLUT_WINDOW_BLUE_SIZE":	109,
+ "GLUT_WINDOW_ALPHA_SIZE":	110,
+ "GLUT_WINDOW_ACCUM_RED_SIZE":	111,
+ "GLUT_WINDOW_ACCUM_GREEN_SIZE":112,
+ "GLUT_WINDOW_ACCUM_BLUE_SIZE":	113,
+ "GLUT_WINDOW_ACCUM_ALPHA_SIZE":114,
+ "GLUT_WINDOW_DOUBLEBUFFER":	115,
+ "GLUT_WINDOW_RGBA":		116,
+ "GLUT_WINDOW_PARENT":		117,
+ "GLUT_WINDOW_NUM_CHILDREN":	118,
+ "GLUT_WINDOW_COLORMAP_SIZE":	119,
+ "GLUT_WINDOW_NUM_SAMPLES":	120,
+ "GLUT_WINDOW_STEREO":		121,
+ "GLUT_WINDOW_CURSOR":		122,
+ "GLUT_SCREEN_WIDTH":		200,
+ "GLUT_SCREEN_HEIGHT":		201,
+ "GLUT_SCREEN_WIDTH_MM":	202,
+ "GLUT_SCREEN_HEIGHT_MM":	203,
+ "GLUT_MENU_NUM_ITEMS":		300,
+ "GLUT_DISPLAY_MODE_POSSIBLE":	400,
+ "GLUT_INIT_WINDOW_X":		500,
+ "GLUT_INIT_WINDOW_Y":		501,
+ "GLUT_INIT_WINDOW_WIDTH":	502,
+ "GLUT_INIT_WINDOW_HEIGHT":	503,
+ "GLUT_INIT_DISPLAY_MODE":	504,
+ "GLUT_ELAPSED_TIME":		700,
+ "GLUT_WINDOW_FORMAT_ID":	123,
+ "GLUT_HAS_KEYBOARD":		600,
+ "GLUT_HAS_MOUSE":		601,
+ "GLUT_HAS_SPACEBALL":		602,
+ "GLUT_HAS_DIAL_AND_BUTTON_BOX":603,
+ "GLUT_HAS_TABLET":		604,
+ "GLUT_NUM_MOUSE_BUTTONS":	605,
+ "GLUT_NUM_SPACEBALL_BUTTONS":	606,
+ "GLUT_NUM_BUTTON_BOX_BUTTONS":	607,
+ "GLUT_NUM_DIALS":		608,
+ "GLUT_NUM_TABLET_BUTTONS":	609,
+ "GLUT_DEVICE_IGNORE_KEY_REPEAT":  610,
+ "GLUT_DEVICE_KEY_REPEAT":      611,
+ "GLUT_HAS_JOYSTICK":		612,
+ "GLUT_OWNS_JOYSTICK":		613,
+ "GLUT_JOYSTICK_BUTTONS":	614,
+ "GLUT_JOYSTICK_AXES":		615,
+ "GLUT_JOYSTICK_POLL_RATE":	616,
+ "GLUT_OVERLAY_POSSIBLE":       800,
+ "GLUT_LAYER_IN_USE":		801,
+ "GLUT_HAS_OVERLAY":		802,
+ "GLUT_TRANSPARENT_INDEX":	803,
+ "GLUT_NORMAL_DAMAGED":		804,
+ "GLUT_OVERLAY_DAMAGED":	805,
+ "GLUT_VIDEO_RESIZE_POSSIBLE":	900,
+ "GLUT_VIDEO_RESIZE_IN_USE":	901,
+ "GLUT_VIDEO_RESIZE_X_DELTA":	902,
+ "GLUT_VIDEO_RESIZE_Y_DELTA":	903,
+ "GLUT_VIDEO_RESIZE_WIDTH_DELTA":	904,
+ "GLUT_VIDEO_RESIZE_HEIGHT_DELTA":	905,
+ "GLUT_VIDEO_RESIZE_X":		906,
+ "GLUT_VIDEO_RESIZE_Y":		907,
+ "GLUT_VIDEO_RESIZE_WIDTH":	908,
+ "GLUT_VIDEO_RESIZE_HEIGHT":	909,
+ "GLUT_NORMAL":			0,
+ "GLUT_OVERLAY":		1,
+ "GLUT_ACTIVE_SHIFT":           1,
+ "GLUT_ACTIVE_CTRL":            2,
+ "GLUT_ACTIVE_ALT":             4,
+ "GLUT_CURSOR_RIGHT_ARROW":	0,
+ "GLUT_CURSOR_LEFT_ARROW":	1,
+ "GLUT_CURSOR_INFO":		2,
+ "GLUT_CURSOR_DESTROY":		3,
+ "GLUT_CURSOR_HELP":		4,
+ "GLUT_CURSOR_CYCLE":		5,
+ "GLUT_CURSOR_SPRAY":		6,
+ "GLUT_CURSOR_WAIT":		7,
+ "GLUT_CURSOR_TEXT":		8,
+ "GLUT_CURSOR_CROSSHAIR":	9,
+ "GLUT_CURSOR_UP_DOWN":		10,
+ "GLUT_CURSOR_LEFT_RIGHT":	11,
+ "GLUT_CURSOR_TOP_SIDE":	12,
+ "GLUT_CURSOR_BOTTOM_SIDE":	13,
+ "GLUT_CURSOR_LEFT_SIDE":	14,
+ "GLUT_CURSOR_RIGHT_SIDE":	15,
+ "GLUT_CURSOR_TOP_LEFT_CORNER":	16,
+ "GLUT_CURSOR_TOP_RIGHT_CORNER":17,
+ "GLUT_CURSOR_BOTTOM_RIGHT_CORNER":	18,
+ "GLUT_CURSOR_BOTTOM_LEFT_CORNER":	19,
+ "GLUT_CURSOR_INHERIT":		100,
+ "GLUT_CURSOR_NONE":		101,
+ "GLUT_CURSOR_FULL_CROSSHAIR":	102,
+ "GLUT_KEY_REPEAT_OFF":		0,
+ "GLUT_KEY_REPEAT_ON":		1,
+ "GLUT_KEY_REPEAT_DEFAULT":	2,
+ "GLUT_JOYSTICK_BUTTON_A":	1,
+ "GLUT_JOYSTICK_BUTTON_B":	2,
+ "GLUT_JOYSTICK_BUTTON_C":	4,
+ "GLUT_JOYSTICK_BUTTON_D":	8,
+ "GLUT_GAME_MODE_ACTIVE":       0,
+ "GLUT_GAME_MODE_POSSIBLE":     1,
+ "GLUT_GAME_MODE_WIDTH":        2,
+ "GLUT_GAME_MODE_HEIGHT":       3,
+ "GLUT_GAME_MODE_PIXEL_DEPTH":  4,
+ "GLUT_GAME_MODE_REFRESH_RATE":     5,
+ "GLUT_GAME_MODE_DISPLAY_CHANGED":  6,
+]);
diff --git a/src/post_modules/GLUT/features.pike b/src/post_modules/GLUT/features.pike
new file mode 100644
index 0000000000..be1e8bc0a3
--- /dev/null
+++ b/src/post_modules/GLUT/features.pike
@@ -0,0 +1,338 @@
+array func_misc = 
+({
+   ({ "glutGetColor","FII" }),             
+   // GLfloat glutGetColor(int ndx, int component);
+
+   ({ "glutCreateMenu", "IC(I)" }),        
+   // int glutCreateMenu(void (GLUTCALLBACK *)(int));
+
+   ({ "glutCreateSubWindow", "IIIIII" }),  
+   // int glutCreateSubWindow(int win, int x, int y, int width, int height);
+
+   ({ "glutCreateWindow", "IS" }),         
+   // int glutCreateWindow(const char *title);
+
+   ({ "glutDeviceGet", "IE" }),            
+   // int glutDeviceGet(GLenum type);
+
+   ({ "glutEnterGameMode", "I" }),         
+   // int glutEnterGameMode(void);
+
+   ({ "glutExtensionSupported","IS" }),    
+   // int glutExtensionSupported(const char *name);
+
+   ({ "glutGameModeGet","IE" }),           
+   // int glutGameModeGet(GLenum mode);
+
+   ({ "glutGet","IE" }),                   
+   // int glutGet(GLenum type);
+
+   ({ "glutGetMenu","I" }),                
+   // int glutGetMenu(void);
+
+   ({ "glutGetModifiers","I" }),           
+   // int glutGetModifiers(void);
+
+   ({ "glutGetWindow","I" }),             
+   // int glutGetWindow(void);
+
+   ({ "glutLayerGet","IE" }),              
+   // int glutLayerGet(GLenum type);
+
+   ({ "glutVideoResizeGet","IE" }),        
+   // int glutVideoResizeGet(GLenum param);
+
+   ({ "glutAddMenuEntry","VSI" }),         
+   // void glutAddMenuEntry(const char *label, int value);
+
+   ({ "glutAddSubMenu","VSI" }),           
+   // void glutAddSubMenu(const char *label, int submenu);
+
+   ({ "glutAttachMenu","VI" }),            
+   // void glutAttachMenu(int button);
+
+   ({ "glutButtonBoxFunc","VC(II)" }),     
+   // void glutButtonBoxFunc(void (GLUTCALLBACK * func)(int button, int state));
+
+   ({ "glutChangeToMenuEntry","VISI" }),   
+   // void glutChangeToMenuEntry(int item, const char *label, int value);
+
+   ({ "glutChangeToSubMenu","VISI" }),     
+   // void glutChangeToSubMenu(int item, const char *label, int submenu);
+
+   ({ "glutCopyColormap","VI" }),          
+   // void glutCopyColormap(int win);
+
+   ({ "glutDestroyMenu","VI" }),           
+   // void glutDestroyMenu(int menu);
+
+   ({ "glutDestroyWindow","VI" }),         
+   // void glutDestroyWindow(int win);
+
+   ({ "glutDetachMenu","VI" }),            
+   // void glutDetachMenu(int button);
+
+   ({ "glutDialsFunc","VC(II)" }),         
+   // void glutDialsFunc(void (GLUTCALLBACK * func)(int dial, int value));
+
+   ({ "glutDisplayFunc","VC()" }),        
+   // void glutDisplayFunc(void (GLUTCALLBACK * func)(void));
+
+   ({ "glutEntryFunc","VC(I)" }),             
+   // void glutEntryFunc(void (GLUTCALLBACK * func)(int state));
+
+   ({ "glutEstablishOverlay","V" }),       
+   // void glutEstablishOverlay(void);
+
+   ({ "glutForceJoystickFunc","V" }),      
+   // void glutForceJoystickFunc(void);
+
+   ({ "glutFullScreen","V" }),             
+   // void glutFullScreen(void);
+
+   ({ "glutGameModeString","VS" }),        
+   // void glutGameModeString(const char *string);
+
+   ({ "glutHideOverlay","V" }),            
+   // void glutHideOverlay(void);
+
+   ({ "glutHideWindow","V" }),            
+   // void glutHideWindow(void);
+
+   ({ "glutIconifyWindow","V" }),          
+   // void glutIconifyWindow(void);
+
+   ({ "glutIdleFunc","VC()" }),           
+   // void glutIdleFunc(void (GLUTCALLBACK * func)(void));
+
+   ({ "glutIgnoreKeyRepeat","VI" }),       
+   // void glutIgnoreKeyRepeat(int ignore);
+
+//   ({ "glutInit","VII" }),                 
+   // void glutInit(int *argcp, char **argv);
+
+   ({ "glutInitDisplayMode","VU" }),       
+   // void glutInitDisplayMode(unsigned int mode);
+
+   ({ "glutInitDisplayString","VS" }),     
+   // void glutInitDisplayString(const char *string);
+
+   ({ "glutInitWindowPosition","VII" }),   
+   // void glutInitWindowPosition(int x, int y);
+
+   ({ "glutInitWindowSize","VII" }),       
+   // void glutInitWindowSize(int width, int height);
+
+   ({ "glutJoystickFunc","VC(UIII)I" }),   
+   // void glutJoystickFunc(void (GLUTCALLBACK * func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
+
+   ({ "glutKeyboardFunc","VC(UII)" }),     
+   // void glutKeyboardFunc(void (GLUTCALLBACK * func)(unsigned char key, int x, int y));
+
+   ({ "glutKeyboardUpFunc","VC(UII)" }),  
+   // void glutKeyboardUpFunc(void (GLUTCALLBACK * func)(unsigned char key, int x, int y));
+
+   ({ "glutLeaveGameMode","V" }),          
+   // void glutLeaveGameMode(void);
+
+   ({ "glutMainLoop","V" }),               
+   // void glutMainLoop(void);
+
+   ({ "glutMenuStateFunc","VC(I)" }),      
+   // void glutMenuStateFunc(void (GLUTCALLBACK * func)(int state));
+
+   ({ "glutMenuStatusFunc","VC(III)" }),   
+   // void glutMenuStatusFunc(void (GLUTCALLBACK * func)(int status, int x, int y));
+
+   ({ "glutMotionFunc","VC(II)" }),        
+   // void glutMotionFunc(void (GLUTCALLBACK * func)(int x, int y));
+
+   ({ "glutMouseFunc","VC(IIII)" }),       
+   // void glutMouseFunc(void (GLUTCALLBACK * func)(int button, int state, int x, int y));
+
+   ({ "glutOverlayDisplayFunc","VC()" }), 
+   // void glutOverlayDisplayFunc(void (GLUTCALLBACK * func)(void));
+
+   ({ "glutPassiveMotionFunc","VC(II)" }), 
+   // void glutPassiveMotionFunc(void (GLUTCALLBACK * func)(int x, int y));
+
+   ({ "glutPopWindow","V" }),              
+   // void glutPopWindow(void);
+
+   ({ "glutPositionWindow","VII" }),       
+   // void glutPositionWindow(int x, int y);
+
+   ({ "glutPostOverlayRedisplay","V" }),   
+   // void glutPostOverlayRedisplay(void);
+
+   ({ "glutPostRedisplay","V" }),          
+   // void glutPostRedisplay(void);
+
+   ({ "glutPostWindowOverlayRedisplay","VI" }),    
+   // void glutPostWindowOverlayRedisplay(int win);
+
+   ({ "glutPostWindowRedisplay","VI" }),   
+   // void glutPostWindowRedisplay(int win);
+
+   ({ "glutPushWindow","V" }),             
+   // void glutPushWindow(void);
+
+   ({ "glutRemoveMenuItem","VI" }),        
+   // void glutRemoveMenuItem(int item);
+
+   ({ "glutRemoveOverlay","V" }),          
+   // void glutRemoveOverlay(void);
+
+   ({ "glutReportErrors","V" }),           
+   // void glutReportErrors(void);
+
+   ({ "glutReshapeFunc","VC(II)" }),       
+   // void glutReshapeFunc(void (GLUTCALLBACK * func)(int width, int height));
+
+   ({ "glutReshapeWindow","VII" }),      
+   // void glutReshapeWindow(int width, int height);
+
+   ({ "glutSetColor","VIFFF" }),           
+   // void glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+
+   ({ "glutSetCursor","VI" }),             
+   // void glutSetCursor(int cursor);
+
+   ({ "glutSetIconTitle","VS" }),          
+   // void glutSetIconTitle(const char *title);
+
+   ({ "glutSetKeyRepeat","VI" }),          
+   // void glutSetKeyRepeat(int repeatMode);
+
+   ({ "glutSetMenu","VI" }),               
+   // void glutSetMenu(int menu);
+
+   ({ "glutSetWindow","VI" }),             
+   // void glutSetWindow(int win);
+
+   ({ "glutSetWindowTitle","VS" }),        
+   // void glutSetWindowTitle(const char *title);
+
+   ({ "glutSetupVideoResizing","V" }),     
+   // void glutSetupVideoResizing(void);
+
+   ({ "glutShowOverlay","V" }),            
+   // void glutShowOverlay(void);
+
+   ({ "glutShowWindow","V" }),             
+   // void glutShowWindow(void);
+
+   ({ "glutSolidCone","VRRII" }),          
+   // void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+
+   ({ "glutSolidCube","VR" }),             
+   // void glutSolidCube(GLdouble size);
+
+   ({ "glutSolidDodecahedron","V" }),      
+   // void glutSolidDodecahedron(void);
+
+   ({ "glutSolidIcosahedron","V" }),       
+   // void glutSolidIcosahedron(void);
+
+   ({ "glutSolidOctahedron","V" }),        
+   // void glutSolidOctahedron(void);
+
+   ({ "glutSolidSphere","VRII" }),         
+   // void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+
+   ({ "glutSolidTeapot","VR" }),           
+   // void glutSolidTeapot(GLdouble size);
+
+   ({ "glutSolidTetrahedron","V" }),       
+   // void glutSolidTetrahedron(void);
+
+   ({ "glutSolidTorus","VRRII" }),         
+   // void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+
+   ({ "glutSpaceballButtonFunc","VC(II)"}),        
+   // void glutSpaceballButtonFunc(void (GLUTCALLBACK * func)(int button, int state));
+
+   ({ "glutSpaceballMotionFunc","VC(III)" }),      
+   // void glutSpaceballMotionFunc(void (GLUTCALLBACK * func)(int x, int y, int z));
+
+   ({ "glutSpaceballRotateFunc","VC(III)" }),      
+   // void glutSpaceballRotateFunc(void (GLUTCALLBACK * func)(int x, int y, int z));
+
+   ({ "glutSpecialFunc","VC(III)" }),      
+   // void glutSpecialFunc(void (GLUTCALLBACK * func)(int key, int x, int y));
+
+   ({ "glutSpecialUpFunc","VC(III)" }),    
+   // void glutSpecialUpFunc(void (GLUTCALLBACK * func)(int key, int x, int y));
+
+   ({ "glutStopVideoResizing","V" }),      
+   // void glutStopVideoResizing(void);
+
+   ({ "glutSwapBuffers","V" }),            
+   // void glutSwapBuffers(void);
+
+   ({ "glutTabletButtonFunc","VC(IIII)" }),
+   // void glutTabletButtonFunc(void (GLUTCALLBACK * func)(int button, int state, int x, int y));
+
+   ({ "glutTabletMotionFunc","VC(II)" }),  
+   // void glutTabletMotionFunc(void (GLUTCALLBACK * func)(int x, int y));
+
+   ({ "glutTimerFunc","VUC(I)I" }),        
+   // void glutTimerFunc(unsigned int millis, void (GLUTCALLBACK * func)(int value), int value);
+
+   ({ "glutUseLayer","VE" }),              
+   // void glutUseLayer(GLenum layer);
+
+   ({ "glutVideoPan","VIIII" }),         
+   // void glutVideoPan(int x, int y, int width, int height);
+
+   ({ "glutVideoResize","VIIII" }),      
+   // void glutVideoResize(int x, int y, int width, int height);
+
+   ({ "glutVisibilityFunc","VC(I)" }),     
+   // void glutVisibilityFunc(void (GLUTCALLBACK * func)(int state));
+
+   ({ "glutWarpPointer","VII" }),        
+   // void glutWarpPointer(int x, int y);
+
+   ({ "glutWindowStatusFunc","VC(I)" }),   
+   // void glutWindowStatusFunc(void (GLUTCALLBACK * func)(int state));
+
+   ({ "glutWireCone","VRRII" }),           
+   // void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+
+   ({ "glutWireCube","VR" }),              
+   // void glutWireCube(GLdouble size);
+
+   ({ "glutWireDodecahedron","V" }),       
+   // void glutWireDodecahedron(void);
+
+   ({ "glutWireIcosahedron","V" }),        
+   // void glutWireIcosahedron(void);
+
+   ({ "glutWireOctahedron","V" }),         
+   // void glutWireOctahedron(void);
+
+   ({ "glutWireSphere","VRII" }),          
+   // void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+
+   ({ "glutWireTeapot","VR" }),            
+   // void glutWireTeapot(GLdouble size);
+
+   ({ "glutWireTetrahedron","V" }),        
+   // void glutWireTetrahedron(void);
+
+   ({ "glutWireTorus","VRRII" }),          
+   // void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+});
+
+
+/* Not implemented:
+
+int glutBitmapLength(void *font, const unsigned char *string);
+int glutBitmapWidth(void *font, int character);
+int glutStrokeLength(void *font, const unsigned char *string);
+int glutStrokeWidth(void *font, int character);
+void glutBitmapCharacter(void *font, int character);
+void glutStrokeCharacter(void *font, int character);
+
+*/
diff --git a/src/post_modules/GLUT/gen.pike b/src/post_modules/GLUT/gen.pike
new file mode 100755
index 0000000000..df1401af36
--- /dev/null
+++ b/src/post_modules/GLUT/gen.pike
@@ -0,0 +1,452 @@
+#!/usr/local/bin/pike
+/*
+   C(...)=callback function
+   V=void
+   I=int
+   D=double
+   F=float
+   U=unsigned int/int
+   E=enum
+   B=bitfield
+   O=bool
+   R=double/float
+   Q=int/float
+   Z=(byte/)double/float/int/short
+
+   +XXXX = 3/4/array(3/4)
+   +XXX  = 2/3/4/array(2/3/4)
+   +XX   = 1/2/array(1/2)
+   +X    = 1/2/3/4/array(1/2/3/4)
+   =XXXX = 4/array(4)
+   =XXX  = 3/array(3)
+   @X    = 1/array(n)
+
+   #     = like =, but add count
+   !     = like =, but no vector version available
+
+   image object support:
+
+   w     = width of image
+   h     = height of image
+   f     = format of image
+   t     = type of image
+   i     = image data
+
+*/
+
+#include "features.pike";
+#include "constants.pike";
+
+void error(string msg, mixed ... args)
+{
+  if(sizeof(args))
+    msg = sprintf(msg, @args);
+  werror(msg+"\n");
+  exit(1);
+}
+
+array(string|array(string)) special_234(int mi, int mx, string ty)
+{
+  string tm="BIT_FLOAT|BIT_INT", baset="float|int", rt="if";
+  array(string) typ=({});
+  int i, ad;
+  if(sizeof(Array.uniq(values(ty)))!=1)
+    error("Unparsable 234 type '%s'.", ty);
+  switch(ty[0]) {
+  case 'E':
+  case 'B':
+  case 'I':
+  case 'O':
+    baset="int";
+    tm="BIT_INT";
+    rt="i";
+    break;
+  case 'D':
+    ad=1;  /* fallthrough */
+  case 'F':
+    baset="float";
+    tm="BIT_FLOAT";
+    rt=(ad?"":"f");
+    break;
+  case 'R':
+    rt="f";
+  case 'Z':
+    ad=1;
+    break;
+  case 'Q':
+    break;
+  default:
+    error("Unknown 234 type '%s'.", ty[0..0]);
+  }
+  if(ad)
+    rt+="d";
+  for(i=0; i<mx; i++) {
+    string t = baset;
+    if(!i)
+      t+="|array("+baset+")";
+    if(i>=mi || i>0)
+      t+="|void";
+    typ+=({t});
+  }
+  return ({typ,tm,rows((['i':"ZT_INT",'f':"ZT_FLOAT",'d':"ZT_DOUBLE"]),
+		       values(rt))*"|",rt});
+}
+
+
+array(string) gen_func(string name, string ty)
+{
+  string res="", got="", prot, vdec, vret, fu=name;
+  array novec, args=({}), argt=({});
+  int r234, argt_cut=-1, img_obj=0;
+  string rtypes;
+  string callback,after_variables;
+
+  switch(ty[0]) {
+  case 'V':
+    prot=":void";
+    break;
+  case 'I':
+  case 'O':
+  case 'E':
+    prot=":int";
+    vdec="INT32";
+    vret="push_int";
+    break;
+  case 'F':
+    prot=":float";
+    vdec="float";
+    vret="push_float";
+    break;
+  default:
+    error("%s: Unknown return type '%c'.", name, ty[0]);
+  }
+
+  res += "static void f_"+name+"(INT32 args)\n{\n"+
+    (vdec?("  "+vdec+" res;\n"):"");
+
+  int a=1;
+  for(int i=1; i<sizeof(ty); i++)
+  {
+    switch(ty[i]) {
+
+    case 'C':
+      string internal_args;
+      sscanf(ty[i..],"C(%s)",internal_args);
+      if(!args)
+	error("First character after C must be '(' (%s).",ty);
+
+      callback=
+	"struct svalue "+name+"_fun;\n\n"
+	"void "+name+"_cb_wrapper(";
+      int n;
+      array a1=({}),a2=({});;
+      if(!sizeof(internal_args))
+	a1+=({"void"});
+      else
+	foreach(internal_args/"",string s)
+	  switch(s) {
+	  case "I":
+	    a1 += ({ "int arg"+(++n) });
+	    a2 += ({ "  push_int(arg"+n+");" });
+	    break;
+	  case "U":
+	    a1 += ({ "unsigned int arg"+(++n) });
+	    a2 += ({ "  push_int((int)arg"+n+");" });
+	    break;
+	  }
+      callback += a1*", " +")\n{\n";
+      callback += a2*"\n";
+      callback += "\n  apply_svalue(&"+name+"_fun, "+sizeof(internal_args)+");\n";
+      callback += "  pop_stack();\n";
+      callback += "}";
+
+      argt += ({"function"});
+      args += ({ "(void *)&"+name+"_cb_wrapper" });
+
+      after_variables =
+	"  if("+name+"_fun.type)\n"
+	"    free_svalue(&"+name+"_fun);\n"
+	"  assign_svalue_no_free(&"+name+"_fun, &sp[-args+"+(a-1)+"]);\n";
+
+      i+=sizeof(internal_args)+2;
+      break;
+
+    case 'S':
+      argt += ({"string"});
+      args += ({ "arg"+a });
+      res += "  char *arg"+a+";\n";
+      got += "  arg"+a+"=sp["+(a-1)+"-args].u.string->str;\n";
+      a++;
+      break;
+
+      
+    case 'U':
+    case 'B':
+    case 'E':
+    case 'O':
+    case 'I':
+      argt += ({"int"});
+      args += ({ "arg"+a });
+      res += "  INT32 arg"+a+";\n";
+      got += "  arg"+a+"=sp["+(a-1)+"-args].u.integer;\n";
+      a++;
+      break;
+    case 'D':
+      argt += ({"float"});
+      args += ({ "arg"+a });
+      res += "  double arg"+a+";\n";
+      got += "  arg"+a+"=sp["+(a-1)+"-args].u.float_number;\n";
+      a++;
+      break;
+    case 'F':
+      argt += ({"float"});
+      args += ({ "arg"+a });
+      res += "  float arg"+a+";\n";
+      got += "  arg"+a+"=sp["+(a-1)+"-args].u.float_number;\n";
+      a++;
+      break;
+    case 'R':
+      argt += ({"float"});
+      args += ({ "arg"+a });
+      res += "  double arg"+a+";\n";
+      got += "  arg"+a+"=(double)sp["+(a-1)+"-args].u.float_number;\n";
+      a++;
+      break;
+    case '+':
+      int mi, mx;
+      switch(sizeof(ty[i+1..])) {
+      case 1:
+	mi = 1; mx = 4; break;
+      case 2:
+	mi = 1; mx = 2; break;
+      case 3:
+	mi = 2; mx = 4; break;
+      case 4:
+	mi = 3; mx = 4; break;
+      default:
+	error("Can't understand + followed by %d chars.\n", sizeof(ty[i+1..]));
+      }
+      array plusfix = special_234(mi, mx, ty[i+1..]);
+      res += "  struct zvalue4 zv4;\n";
+      argt_cut = sizeof(argt);
+      argt += plusfix[0];
+      res += "\n  int r234=check_234_args(\""+name+"\", args-"+(a-1)+", "+
+	mi+", "+mx+", "+plusfix[1]+", "+plusfix[2]+", &zv4);\n";
+      r234=1;
+      rtypes=plusfix[3];
+      i=sizeof(ty);
+      novec=indices(allocate(mx+1))[mi..];
+      break;
+    case '#':
+      fu += sizeof(ty[i+1..]);
+      /* fallthrough */
+    case '!':
+    case '=':
+      array eqfix = special_234(sizeof(ty[i+1..]), sizeof(ty[i+1..]),
+				ty[i+1..]);
+      res += "  struct zvalue4 zv4;\n";
+      argt_cut = sizeof(argt);
+      argt += eqfix[0];
+      res += "\n  check_234_args(\""+name+"\", args-"+(a-1)+", "+
+	sizeof(ty[i+1..])+", "+sizeof(ty[i+1..])+", "+eqfix[1]+", "+
+	eqfix[2]+", &zv4);\n";
+      r234=2;
+      rtypes=eqfix[3];
+      if(ty[i]=='!')
+	novec=indices(ty[i+1..]);
+      i=sizeof(ty);
+      break;
+    case '@':
+      array atfix = special_234(1, 1, ty[i+1..]);
+      res += "  union zvalue16 zv16;\n";
+      argt_cut = sizeof(argt);
+      argt += atfix[0];
+      res += "\n  int r1n=check_1n_args(\""+name+"\", args-"+(a-1)+", "+
+	atfix[1]+", "+atfix[2]+", &zv16);\n";
+      r234=3;
+      rtypes=atfix[3];
+      i=sizeof(ty);
+      break;
+    case 'w':
+      img_obj=1;
+      args += ({ "img.width" });
+      break;
+    case 'h':
+      img_obj=1;
+      args += ({ "img.height" });
+      break;
+    case 'f':
+      img_obj=1;
+      args += ({ "img.format" });
+      break;
+    case 't':
+      img_obj=1;
+      args += ({ "img.type" });
+      break;
+    case 'i':
+      img_obj=1;
+      args += ({ "img.pixels" });
+      break;
+
+    default:
+      error("%s: Unknown parameter type '%c'.", name, ty[i]);
+    }
+}
+
+  if(img_obj) {
+    argt += ({"object"});
+    res += "  struct zimage img;\n";
+    got += "  check_img_arg(sp["+(a-1)+"-args].u.object, &img, "+a+
+      ", \""+name+"\");\n";
+  }
+
+  if(after_variables)
+    res+=after_variables;
+    
+  prot = (argt*",")+prot;
+
+  if(sizeof(argt))
+    res += "\n  check_all_args(\""+name+"\", args, "+
+      ((Array.map((argt_cut<0?argt:argt[..argt_cut-1]),
+		  lambda(string t) {
+		    return Array.map(t/"|",
+				     lambda(string t) {
+				       return "BIT_"+upper_case(t);
+				     })*"|";
+		  }))+
+       (r234?({"BIT_MANY|BIT_MIXED|BIT_VOID"}):({}))+({"0"}))*", "+");\n";
+
+  if(sizeof(got))
+    res += "\n"+got+"\n";
+
+  switch(r234)
+  {
+  case 0:
+    res += (vret?"  res=":"  ")+fu+"("+(args*",")+");\n";
+    break;
+  case 1:
+    if(sizeof(rtypes)==1)
+      res += "  switch(r234) {\n"+Array.map(novec, lambda(int i, string vret,
+							  string r, string fu,
+							  array(string) args) {
+						     return "    case "+i+": "+
+						       (vret?"res=":"")+
+						       fu+i+"v("+
+						       (args+({"zv4.v."+r}))*
+						       ","+"); break;";
+						   }, vret, rtypes, fu, args)*
+	"\n"+"\n  }\n";
+    else
+      res += "  switch(zv4.ty) {\n"+
+	Array.map(indices(rtypes),
+		  lambda(int i, string r, string fu, string vret,
+			 array(string) args, array(int) novec) {
+		    return "    case ZT_"+
+		    (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+
+		      ": switch(r234) {\n"+
+		      Array.map(novec, lambda(int i, string vret, string r,
+					      string fu, array(string) args) {
+					 return "      case "+i+": "+
+					   (vret?"res=":"")+
+					   fu+i+r+"v("+
+					   (args+({"zv4.v."+r}))*
+					   ","+"); break;";
+				       }, vret, r[i..i], fu, args)*
+		      "\n"+"\n    }\n    break;";
+		  }, rtypes, fu, vret, args, novec)*"\n"+
+	"\n  }\n";
+    break;
+  case 2:
+    if(sizeof(rtypes)==1)
+      res += (vret?"  res=":"  ")+fu+"("+
+	((args+(novec? Array.map(novec, lambda(int i, string rtypes) {
+					  return "zv4.v."+rtypes+"["+i+"]";
+					}, rtypes):({"zv4.v."+rtypes})))*",")+
+	");\n";
+    else
+      res += "  switch(zv4.ty) {\n"+
+	Array.map(indices(rtypes),
+		  lambda(int i, string r, string fu, string vret,
+			 array(string) args, array(int) novec) {
+		    return "    case ZT_"+
+		    (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+": "+
+		      (vret?"res=":"")+fu+r[i..i]+(novec?"(":"v(")+
+		      ((args+(novec? Array.map(novec, lambda(int i, string r) {
+							return "zv4.v."+r+
+							  "["+i+"]";
+						      }, r[i..i]):
+			      ({"zv4.v."+r[i..i]})))*",")+"); break;";
+		  }, rtypes, fu, vret, args, novec)*"\n"+
+	"\n  }\n";
+    break;
+  case 3:
+    if(sizeof(rtypes)==1)
+      res += "  if(r1n&ZT_ARRAY)\n"+
+	(vret?"    res=":"    ")+fu+"v("+(args+({"zv16."+rtypes}))*","+
+	");\n  else\n"+
+	(vret?"    res=":"    ")+fu+"("+(args+({"zv16."+rtypes+"[0]"}))*","+
+	");\n";
+    else
+      res += "  switch(r1n) {\n"+
+	Array.map(indices(rtypes),
+		  lambda(int i, string r, string fu, string vret,
+			 array(string) args, array(int) novec) {
+		    return "    case ZT_"+
+		    (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+": "+
+		      (vret?"res=":"")+fu+r[i..i]+"("+
+		      ((args+({"zv16."+r[i..i]+"[0]"}))*",")+"); break;\n"+
+		      "    case ZT_ARRAY|ZT_"+
+		    (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+": "+
+		      (vret?"res=":"")+fu+r[i..i]+"v("+
+		      ((args+({"zv16."+r[i..i]}))*",")+"); break;";
+		  }, rtypes, fu, vret, args, novec)*"\n"+
+	"\n  }\n";
+    break;
+  }
+
+  if(img_obj) {
+    res += "  release_img(&img);\n";
+  }
+  res += "  pop_n_elems(args);\n";
+  res += (vret? "  "+vret+"(res);\n":/*"  push_int(0);\n"*/"");
+  res += "}\n\n";
+  if(callback)
+    res = callback+"\n\n"+res;
+  return ({res,prot});
+}
+
+string gen()
+{
+  string res = "";
+  array t = Array.transpose(func_misc);
+  array fn=t[0];
+  mapping ty = mkmapping(@t);
+  mapping prot = ([]);
+//   foreach(indices(func_cat), string cat) {
+//     fn += func_cat[cat];
+//     ty |= mkmapping(func_cat[cat],
+// 		    rows(({cat}), allocate(sizeof(func_cat[cat]))));
+//   }
+  sort(fn);
+  foreach(fn, string f) {
+    array(string) r = gen_func(f, ty[f]);
+    res += r[0];
+    prot[f]=r[1];
+  }
+  res += "void add_auto_funcs_glut()\n{\n";
+  res += "  pre_init();\n";
+  foreach(fn, string f)
+    res += "  add_function_constant(\""+f+"\", f_"+f+",\n\t\t\t\"function("+
+      prot[f]+")\", OPT_SIDE_EFFECT);\n";
+  foreach(sort(indices(constants)), string co)
+    res += "  add_integer_constant(\""+co+"\", "+constants[co]+", 0);\n";
+  res += "  post_init();\n";
+  res += "}\n";
+  return res;
+}
+
+void main(int argc, array(string) argv)
+{
+  array(string) f = Stdio.File("stdin")->read()/"@@";
+  write(({f[0],gen(),@f[1..]})*"");
+}
diff --git a/src/post_modules/GLUT/top.c b/src/post_modules/GLUT/top.c
new file mode 100644
index 0000000000..b548217d59
--- /dev/null
+++ b/src/post_modules/GLUT/top.c
@@ -0,0 +1,38 @@
+/*
+ * $Id: top.c,v 1.1 1999/11/14 00:01:50 per Exp $
+ *
+ */
+
+#include "global.h"
+
+#include "config.h"
+
+RCSID("$Id: top.c,v 1.1 1999/11/14 00:01:50 per Exp $");
+#include "stralloc.h"
+#include "pike_macros.h"
+#include "object.h"
+#include "program.h"
+#include "interpret.h"
+#include "builtin_functions.h"
+#include "error.h"
+
+
+#ifdef HAVE_GL_GLUT_H
+#define GLUT_API_VERSION 4
+#include <GL/glut.h>
+#endif
+
+
+void pike_module_init( void )
+{
+#ifdef HAVE_GL_GLUT_H
+  extern void add_auto_funcs_glut(void);
+  add_auto_funcs_glut();
+#endif
+}
+
+
+void pike_module_exit( void )
+{
+}
+
-- 
GitLab