Index: README
===================================================================
--- README	(revision 170)
+++ README	(revision 171)
@@ -0,0 +1,11 @@
+(my)glut is an alternative to "real" GLUT, providing a small subset
+of the original API, up to Raydium needs.
+
+This code is heavily based on PW, the PLIB windowing library
+(http://plib.sourceforge.net/. Huge thanks to Steve Baker for his huge work.
+
+Xf.
+---
+Raydium - CQFD Corp.
+http://raydium.org/
+License: GPL - GNU General Public License, see "gpl.txt" file.
Index: myglut-win32.c
===================================================================
--- myglut-win32.c	(revision 170)
+++ myglut-win32.c	(revision 171)
@@ -0,0 +1,444 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    License: GPL - GNU General Public License, see "gpl.txt" file.
+*/
+
+#include "myglut.h"
+
+#include <windows.h>
+#include <gl/glaux.h>
+
+static HINSTANCE       currInstance;
+static HWND            currWnd;
+static HDC             currDC;
+static HGLRC           currGLRC;
+int _glutWindowSize[2];
+
+LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+
+// ---------------------- public API
+
+void glutInit(int *argc, char **argv)
+{
+currInstance = NULL ;
+currWnd      = NULL ;
+currDC       = NULL ;
+currGLRC     = NULL ;
+
+glutReshapeFuncCB=NULL;
+glutKeyboardFuncCB=NULL;
+glutSpecialUpFuncCB=NULL;
+glutSpecialFuncCB=NULL;
+glutMotionFuncCB=NULL;
+glutPassiveMotionFuncCB=NULL;
+glutMouseFuncCB=NULL;
+glutDisplayFuncCB=NULL;
+glutIdleFuncCB=NULL;
+}
+
+
+void mylgutCloseWindow(void)
+{
+wglMakeCurrent ( NULL, NULL ) ;
+wglDeleteContext ( currGLRC ) ;
+DestroyWindow ( currWnd ) ;
+}
+
+
+
+//glutSetCursor
+void glutSetCursor(int cursor)
+{
+LPCSTR wcursor;
+    
+switch(cursor)
+    {
+    case GLUT_CURSOR_LEFT_ARROW:
+        wcursor = IDC_ARROW;
+	    break;
+    case GLUT_CURSOR_NONE:	
+    default:
+        wcursor = 0;
+        break;
+    break;
+    }
+SetCursor( LoadCursor ( NULL, wcursor ) ) ;
+}
+
+//glutWarpPointer (move mouse)
+void glutWarpPointer(int x, int y)
+{
+POINT point;
+
+point.x = x;
+point.y = y;
+ClientToScreen(currWnd /* ? */, &point);
+SetCursorPos(point.x, point.y);
+}
+
+//glutSwapBuffers
+void glutSwapBuffers(void)
+{
+  glFlush () ;
+  SwapBuffers ( currDC ) ;
+}
+
+
+//glutMainLoop is generic (myglut.c)
+
+// ------------- private part
+
+
+
+
+void myglutGetEvents (void)
+{
+MSG msg;
+while ( PeekMessage( &msg, currWnd, 0, 0, PM_REMOVE ) )
+    {
+    TranslateMessage( &msg ) ;
+    DispatchMessage ( &msg ) ;
+    }
+}
+
+void pwInit ( int x, int y, int w, int h, int multisample,
+              char *title, int border, int num_samples )
+{
+  WNDCLASS wc;
+  signed char fullscn;
+  RECT rect;
+  DWORD style = 0;
+  int iPixelFormat;
+  int origin [2] = {   0,   0 };
+  int size   [2] = { 640, 480 };
+  PIXELFORMATDESCRIPTOR pfd;
+
+  
+  
+  currInstance = GetModuleHandleA( NULL ) ;
+  /* Register the window class */
+  wc.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW ;
+  wc.lpfnWndProc   = WndProc ;
+  wc.cbClsExtra    = 0 ;
+  wc.cbWndExtra    = 0 ;
+  wc.hInstance     = currInstance ;
+  wc.hIcon         = LoadIcon ( NULL, IDI_APPLICATION ) ;
+  wc.hCursor       = LoadCursor ( NULL, 0 ) ;
+  wc.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 ) ;
+  wc.lpszMenuName  = NULL ;
+  wc.lpszClassName = "RaydiumAppClass" ;
+  if ( !RegisterClass( &wc ) )
+  {
+    raydium_log("(my)glut: ERROR: Can't register window class" ) ;
+    exit ( 1 ) ;
+  }
+
+  /* Setup window style */
+  fullscn = (w == -1 && h == -1 ) ? 1 : 0 ;
+
+  if ( w == -1 ) w = GetSystemMetrics( SM_CXSCREEN ) ;
+  if ( h == -1 ) h = GetSystemMetrics( SM_CYSCREEN ) ;
+
+  if ( x == -1 ) x = (GetSystemMetrics( SM_CXSCREEN ) / 2) - (w/2) ;
+  if ( y == -1 ) y = (GetSystemMetrics( SM_CYSCREEN ) / 2) - (h/2);
+  
+  origin [ 0 ] = x ;
+  origin [ 1 ] = y ;
+  size   [ 0 ] = w ;
+  size   [ 1 ] = h ;
+
+
+  rect.left   = x ;
+  rect.top    = y ;
+  rect.right  = rect.left + w ;
+  rect.bottom = rect.top + h ;
+
+
+  if ( !fullscn )
+    style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ;
+  else
+    style = WS_POPUP ;
+
+  AdjustWindowRect( &rect, style, 0 ) ;
+
+  /* Create the window */
+  currWnd = CreateWindow(
+    "RaydiumAppClass", title, style,
+    rect.left, rect.top,
+    rect.right - rect.left, rect.bottom - rect.top,
+    NULL, NULL, currInstance, NULL ) ;
+
+  if ( !currWnd )
+  {
+    raydium_log("(my)glut: ERROR: Can't create window" ) ;
+    exit ( 1 ) ;
+  }
+
+  /* Get DC for this window */
+  currDC = GetDC ( currWnd ) ;
+  if ( !currDC )
+  {
+    raydium_log("(my)glut: ERROR: Can't get window DC" ) ;
+    exit ( 1 ) ;
+  }
+
+//  wglGetExtensionsStringARBtype *wglGetExtensionsStringARB = (wglGetExtensionsStringARBtype *)wglGetProcAddress ( "wglGetExtensionsStringARB" ) ;
+//  const char *extensionsString = wglGetExtensionsStringARB ( currDC ) ;
+
+//  printf ( "%s %x %s\n", glGetString ( GL_EXTENSIONS ), wglGetExtensionsStringARB, extensionsString ) ;
+
+//  if (!GLExtensionExists("WGL_ARB_multisample "))
+//    return suggestedFormat;
+
+
+  pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
+  pfd.nVersion=1;
+  pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+  pfd.iPixelType=PFD_TYPE_RGBA;
+  pfd.cColorBits=24;
+  pfd.cRedBits=0; 
+  pfd.cRedShift=0; 
+  pfd.cGreenBits=0; 
+  pfd.cGreenShift=0; 
+  pfd.cBlueBits=0; 
+  pfd.cBlueShift=0;
+  pfd.cAlphaBits=0; 
+  pfd.cAlphaShift=0; 
+  pfd.cAccumBits=0; 
+  pfd.cAccumRedBits=0; 
+  pfd.cAccumGreenBits=0; 
+  pfd.cAccumBlueBits=0; 
+  pfd.cAccumAlphaBits=0;
+  pfd.cDepthBits=32;
+  pfd.cStencilBits=0;
+  pfd.cAuxBuffers=0;
+  pfd.iLayerType=PFD_MAIN_PLANE;
+  pfd.bReserved=0; 
+  pfd.dwLayerMask=0; 
+  pfd.dwVisibleMask=0; 
+  pfd.dwDamageMask=0; 
+
+  
+  /* Get best available match of pixel format for DC */
+  iPixelFormat = ChoosePixelFormat ( currDC, &pfd ) ;
+  if ( iPixelFormat == 0 )
+  {
+    raydium_log("(my)glut: ERROR: Can't get OpenGL pixel format" ) ;
+    exit ( 1 ) ;
+  }
+
+  /* Set the pixel format of the DC */
+  if ( !SetPixelFormat( currDC, iPixelFormat, &pfd ) )
+  {
+    raydium_log("(my)glut: ERROR: Can't set OpenGL pixel format" ) ;
+    exit ( 1 ) ;
+  }
+
+  /* Show the window and paint its contents */
+  ShowWindow ( currWnd, SW_SHOW ) ;
+  UpdateWindow ( currWnd ) ;
+
+  /* Create openGL context and make it current */
+  currGLRC = wglCreateContext ( currDC ) ;
+  if ( !currGLRC )
+  {
+    raydium_log("(my)glut: ERROR: Unable to open a suitable window");
+    exit ( 1 ) ;
+  }
+  if ( !wglMakeCurrent ( currDC, currGLRC ) )
+  {
+    raydium_log("(my)glut: ERROR: Unable to open a suitable window");
+    exit ( 1 ) ;
+  }
+  
+
+  glClear ( GL_COLOR_BUFFER_BIT ) ;
+  glutSwapBuffers () ;
+  glClear ( GL_COLOR_BUFFER_BIT ) ;
+  glutSwapBuffers () ;
+  
+  if (glutReshapeFuncCB)
+      glutReshapeFuncCB(w, h);
+}
+
+
+
+LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+  static int key = -1 ;
+  static int updown = GLUT_UP ;
+  static int old_key = -1 ;  // We need this because "key" changes case
+  int button = -1 ;
+  static int mb = 0 ;
+  static int lastx = 0 ;
+  static int lasty = 0 ;
+  BYTE state[256];
+  WORD code[2];
+  signed char b;
+  signed char special=0;
+  signed char repeating=0;
+  int size[2];
+
+  switch (uMsg)
+  {
+    case WM_LBUTTONDOWN:
+    case WM_MBUTTONDOWN:
+    case WM_RBUTTONDOWN:
+      updown = GLUT_DOWN ;
+      if      ( uMsg == WM_LBUTTONDOWN ) { button = GLUT_LEFT_BUTTON   ; mb |= 1 ; }
+      else if ( uMsg == WM_MBUTTONDOWN ) { button = GLUT_MIDDLE_BUTTON ; mb |= 2 ; }
+      else                               { button = GLUT_RIGHT_BUTTON  ; mb |= 4 ; }
+      SetCapture ( hWnd ) ;
+      lastx = (LOWORD( lParam ) ) ;
+      lasty = (HIWORD( lParam ) ) ;
+      if ( button != -1 && glutMouseFuncCB )
+        (*glutMouseFuncCB) ( button, updown, lastx, lasty ) ;
+      break;
+
+    case WM_LBUTTONUP:
+    case WM_MBUTTONUP:
+    case WM_RBUTTONUP:
+      updown = GLUT_UP ;
+      if      ( uMsg == WM_LBUTTONUP ) { button = GLUT_LEFT_BUTTON   ; mb &= ~1 ; }
+      else if ( uMsg == WM_MBUTTONUP ) { button = GLUT_MIDDLE_BUTTON ; mb &= ~2 ; }
+      else                             { button = GLUT_RIGHT_BUTTON  ; mb &= ~4 ; }
+      if ( mb == 0 ) ReleaseCapture () ;
+      lastx = (LOWORD( lParam ) ) ;
+      lasty = (HIWORD( lParam ) ) ;
+      if ( button != -1 && glutMouseFuncCB )
+        (*glutMouseFuncCB) ( button, updown, lastx, lasty ) ;
+      break;
+
+    case WM_MOUSEMOVE:
+      lastx = (LOWORD( lParam ) );
+      lasty = (HIWORD( lParam ) );
+      if ( glutPassiveMotionFuncCB )
+        (*glutPassiveMotionFuncCB) ( lastx, lasty ) ;
+      break;
+
+    case WM_MOUSEWHEEL:
+    if ( ( short ) HIWORD( wParam ) > 0 )
+    {
+    if ( glutPassiveMotionFuncCB )    
+        (*glutMouseFuncCB) ( 3, GLUT_DOWN, lastx, lasty ) ;
+    if ( glutPassiveMotionFuncCB )    
+        (*glutMouseFuncCB) ( 3, GLUT_UP, lastx, lasty ) ;
+    }
+    else
+    {
+    if ( glutPassiveMotionFuncCB )    
+        (*glutMouseFuncCB) ( 4, GLUT_DOWN, lastx, lasty ) ;
+    if ( glutPassiveMotionFuncCB )    
+        (*glutMouseFuncCB) ( 4, GLUT_UP, lastx, lasty ) ;
+    }
+      
+    case WM_KEYDOWN:
+      // If the key is already down, we are on auto-repeat.  Break if the autorepeat is disabled.
+      if ( ( updown == GLUT_DOWN ) && ( (int)wParam == old_key ) )
+      {
+/*        if ( autoRepeat )
+        {*/
+          // Disable CTRL, SHIFT, CapsLock keys from making a callback
+          if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) )
+            break ;
+
+/*          if ( key != -1 && kbCB )  // Autorepeat enabled, call the callback with an "up" setting
+            (*kbCB) ( key, PW_UP, lastx, lasty ) ;
+        }
+        else*/
+          repeating=1;
+        }
+
+      updown = GLUT_DOWN ;
+      old_key = wParam ;
+      // FALLTHROUGH
+    case WM_KEYUP:
+      if ( uMsg == WM_KEYUP ) updown = GLUT_UP ;
+      key = wParam ;
+
+      // Disable CTRL, SHIFT, CapsLock keys from making a callback
+      if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) )
+        break ;
+
+      switch ( key )
+      {
+        case VK_F1:     key = GLUT_KEY_F1;   special=1;     break;
+        case VK_F2:     key = GLUT_KEY_F2;   special=1;     break;
+        case VK_F3:     key = GLUT_KEY_F3;   special=1;     break;
+        case VK_F4:     key = GLUT_KEY_F4;   special=1;     break;
+        case VK_F5:     key = GLUT_KEY_F5;   special=1;     break;
+        case VK_F6:     key = GLUT_KEY_F6;   special=1;     break;
+        case VK_F7:     key = GLUT_KEY_F7;   special=1;     break;
+        case VK_F8:     key = GLUT_KEY_F8;   special=1;     break;
+        case VK_F9:     key = GLUT_KEY_F9;   special=1;     break;
+        case VK_F10:    key = GLUT_KEY_F10;  special=1;     break;
+        case VK_F11:    key = GLUT_KEY_F11;  special=1;     break;
+        case VK_F12:    key = GLUT_KEY_F12;  special=1;     break;
+
+        case VK_LEFT:   key = GLUT_KEY_LEFT;   special=1;   break;
+        case VK_RIGHT:  key = GLUT_KEY_RIGHT;  special=1;   break;
+        case VK_UP:     key = GLUT_KEY_UP;     special=1;   break;
+        case VK_DOWN:   key = GLUT_KEY_DOWN;   special=1;   break;
+
+        case VK_PRIOR:  key = GLUT_KEY_PAGE_UP;   special=1; break;
+        case VK_NEXT:   key = GLUT_KEY_PAGE_DOWN; special=1; break;
+        case VK_HOME:   key = GLUT_KEY_HOME;      special=1; break;
+        case VK_END:    key = GLUT_KEY_END;       special=1; break;
+        case VK_INSERT: key = GLUT_KEY_INSERT;    special=1; break;
+
+				default:
+					// don't do this for WinCE
+
+
+          b = GetKeyboardState( state );
+					assert(b);
+
+					code [ 0 ] = 0; // WK: I need to do this, or on my Win2k box, the upper bits remain unchanged.
+          if( ToAscii( key, 0, state, code, 0 ) == 1 )
+						if((0xFF00 & code[0]) == 0) // setting a high bit in key causes crashes later on (out of range array access)
+							key=code[ 0 ];
+
+      }
+      if ( key != -1)
+        {
+
+	    // special down
+	    if(special && updown==GLUT_DOWN && glutSpecialFuncCB && !repeating)
+		glutSpecialFuncCB(key,lastx,lasty);
+
+	    // special up
+	    if(special && updown==GLUT_UP && glutSpecialUpFuncCB && !repeating)
+		glutSpecialUpFuncCB(key,lastx,lasty);
+        
+        // normal
+	    if(!special && updown==GLUT_DOWN && glutKeyboardFuncCB)
+		glutKeyboardFuncCB(key,lastx,lasty);
+
+        
+        /*if(!special && repeating && glutKeyboardFuncCB)
+        glutKeyboardFuncCB(key,lastx,lasty);*/
+        
+        //(*kbCB) ( key, updown, lastx, lasty ) ;
+        }
+      break;
+
+    case WM_SIZE:
+      size[0] = LOWORD(lParam) ;
+      size[1] = HIWORD(lParam) ;
+      _glutWindowSize[0]=size[0];
+      _glutWindowSize[1]=size[1];    
+      if (glutReshapeFuncCB)
+    	    glutReshapeFuncCB(size[0], size[1]);
+      break;
+
+    case WM_CLOSE:
+      exit(0);
+      break;
+
+    default:
+      return ( DefWindowProc ( hWnd, uMsg, wParam, lParam ) ) ;
+  }
+
+  return 0;
+}
Index: myglut.c
===================================================================
--- myglut.c	(revision 170)
+++ myglut.c	(revision 171)
@@ -0,0 +1,145 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    License: GPL - GNU General Public License, see "gpl.txt" file.
+*/
+
+// avoid "real GLUT"
+#ifndef GLUT_API_VERSION
+
+#ifndef DONT_INCLUDE_HEADERS
+#include "../index.h"
+#else
+#include "myglut.h"
+#endif
+
+
+void raydium_log(char *format, ...);
+
+#ifdef WIN32
+#include "myglut-win32.c"
+#else
+#include "myglut-x11.c"
+#endif
+
+//glutInitDisplayMode
+//glutGameModeString
+//glutEnterGameMode
+//glutInitWindowSize
+//glutCreateWindow
+// are replaced by .. myglutCreateWindow
+void myglutCreateWindow(GLuint tx, GLuint ty, signed char rendering, char *name)
+{
+switch(rendering)
+    {
+    case RAYDIUM_RENDERING_NONE:
+	return;
+    case RAYDIUM_RENDERING_WINDOW:
+	pwInit(-1,-1,tx,ty,0,name,1,0);
+	break;
+    case RAYDIUM_RENDERING_FULLSCREEN:
+	pwInit(0,0,-1,-1,0,name,0,0);
+	break;    
+    }
+}
+
+//glutMainLoop
+void glutMainLoop(void)
+{
+#ifdef WIN32
+    // since windows is firing WM_SIZE too quickly ...
+    if(glutReshapeFuncCB)
+        glutReshapeFuncCB(_glutWindowSize[0],_glutWindowSize[1]);
+#endif
+do{
+    glutIdleFuncCB();
+    myglutGetEvents();
+  }while(1);
+}
+
+// glutWireSphere
+void glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
+{
+  static GLUquadricObj *quadObj=NULL;
+
+  if(!quadObj)
+    quadObj=gluNewQuadric();
+
+  gluQuadricDrawStyle(quadObj, GLU_LINE);
+  gluQuadricNormals(quadObj, GLU_SMOOTH);
+  gluSphere(quadObj, radius, slices, stacks);
+}
+
+//glutGet
+int glutGet(int enu)
+{
+switch(enu)
+    {
+    default:
+	raydium_log("(my)glutGet: ERROR: unknown 'enu' %i",enu);
+    }
+return 0;
+}
+
+
+//glutIgnoreKeyRepeat (1 = yes)
+void glutIgnoreKeyRepeat(int ignore)
+{
+//glutIgnoreKeyRepeatFlag=(ignore?1:0);
+}
+
+//glutReshapeFunc - void (GLUTCALLBACK *func)(int width, int height)
+void glutReshapeFunc(void *func)
+{
+glutReshapeFuncCB=func;
+}
+
+//glutKeyboardFunc - void (GLUTCALLBACK *func)(unsigned char key, int x, int y)
+void glutKeyboardFunc(void *func)
+{
+glutKeyboardFuncCB=func;
+}
+
+//glutSpecialUpFunc - void (GLUTCALLBACK *func)(int key, int x, int y)
+void glutSpecialUpFunc(void *func)
+{
+glutSpecialUpFuncCB=func;
+}
+
+//glutSpecialFunc - void (GLUTCALLBACK *func)(int key, int x, int y)
+void glutSpecialFunc(void *func)
+{
+glutSpecialFuncCB=func;
+}
+
+//glutMotionFunc - void (GLUTCALLBACK *func)(int x, int y)
+void glutMotionFunc(void *func)
+{
+glutMotionFuncCB=func;
+}
+
+//glutPassiveMotionFunc - void (GLUTCALLBACK *func)(int x, int y)
+void glutPassiveMotionFunc(void *func)
+{
+glutPassiveMotionFuncCB=func;
+}
+
+//glutMouseFunc - void (GLUTCALLBACK *func)(int button, int state, int x, int y)
+void glutMouseFunc(void *func)
+{
+glutMouseFuncCB=func;
+}
+
+//glutDisplayFunc - void (GLUTCALLBACK *func)(void)
+void glutDisplayFunc(void *func)
+{
+glutDisplayFuncCB=func;
+}
+
+//glutIdleFunc - void (GLUTCALLBACK *func)(void)
+void glutIdleFunc(void *func)
+{
+glutIdleFuncCB=func;
+}
+
+#endif
Index: myglut.h
===================================================================
--- myglut.h	(revision 170)
+++ myglut.h	(revision 171)
@@ -0,0 +1,93 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    License: GPL - GNU General Public License, see "gpl.txt" file.
+*/
+
+// avoid "real GLUT"
+#ifndef GLUT_API_VERSION
+#ifndef MYGLUT
+#define MYGLUT
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#define GLUT_LEFT_BUTTON		0
+#define GLUT_MIDDLE_BUTTON		1
+#define GLUT_RIGHT_BUTTON		2
+
+#define GLUT_DOWN			0
+#define GLUT_UP				1
+
+#define GLUT_KEY_F1			1
+#define GLUT_KEY_F2			2
+#define GLUT_KEY_F3			3
+#define GLUT_KEY_F4			4
+#define GLUT_KEY_F5			5
+#define GLUT_KEY_F6			6
+#define GLUT_KEY_F7			7
+#define GLUT_KEY_F8			8
+#define GLUT_KEY_F9			9
+#define GLUT_KEY_F10			10
+#define GLUT_KEY_F11			11
+#define GLUT_KEY_F12			12
+#define GLUT_KEY_LEFT			100
+#define GLUT_KEY_UP			101
+#define GLUT_KEY_RIGHT			102
+#define GLUT_KEY_DOWN			103
+#define GLUT_KEY_PAGE_UP		104
+#define GLUT_KEY_PAGE_DOWN		105
+#define GLUT_KEY_HOME			106
+#define GLUT_KEY_END			107
+#define GLUT_KEY_INSERT			108
+
+#define GLUT_WINDOW_WIDTH		102
+#define GLUT_WINDOW_HEIGHT		103
+#define GLUT_WINDOW_DEPTH_SIZE		106
+#define GLUT_WINDOW_CURSOR		122
+
+#define GLUT_CURSOR_LEFT_ARROW		1
+#define GLUT_CURSOR_NONE		101
+
+#define GLUT_RGB			0
+#define GLUT_DOUBLE			2
+#define GLUT_DEPTH			16
+
+#define GLUT_GAME_MODE_POSSIBLE         1
+
+// ------------------- variables
+
+// callbacks:
+void (*glutReshapeFuncCB)(int width, int height);
+void (*glutKeyboardFuncCB)(unsigned char key, int x, int y);
+void (*glutSpecialUpFuncCB)(int key, int x, int y);
+void (*glutSpecialFuncCB)(int key, int x, int y);
+void (*glutMotionFuncCB)(int x, int y);
+void (*glutPassiveMotionFuncCB)(int x, int y);
+void (*glutMouseFuncCB)(int button, int state, int x, int y);
+void (*glutDisplayFuncCB)(void);
+void (*glutIdleFuncCB)(void);
+
+// protos
+void glutInit(int *argc, char **argv);
+int glutGet(int enu);
+void glutSetCursor(int cursor);
+void glutWarpPointer(int x, int y);
+void glutSwapBuffers(void);
+void glutIgnoreKeyRepeat(int ignore);
+void glutReshapeFunc(void *func);
+void glutKeyboardFunc(void *func);
+void glutSpecialUpFunc(void *func);
+void glutSpecialFunc(void *func);
+void glutMotionFunc(void *func);
+void glutPassiveMotionFunc(void *func);
+void glutMouseFunc(void *func);
+void glutDisplayFunc(void *func);
+void glutIdleFunc(void *func);
+void glutMainLoop(void);
+void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+void myglutCreateWindow(GLuint tx, GLuint ty, signed char rendering, char *name);
+
+
+#endif
+#endif
Index: myglut-x11.c
===================================================================
--- myglut-x11.c	(revision 170)
+++ myglut-x11.c	(revision 171)
@@ -0,0 +1,548 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    License: GPL - GNU General Public License, see "gpl.txt" file.
+*/
+
+#include "myglut.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/cursorfont.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+//#include <X11/Xutil.h> // provided by glx
+
+#include <GL/glx.h>
+
+#ifdef HAVE_MOTIF
+#include <X11/Xm/MwmUtil.h>
+#else
+/* bit definitions for MwmHints.flags */
+#define MWM_HINTS_FUNCTIONS	(1L << 0)
+#define MWM_HINTS_DECORATIONS	(1L << 1)
+#define MWM_HINTS_INPUT_MODE	(1L << 2)
+#define MWM_HINTS_STATUS	(1L << 3)
+
+/* bit definitions for MwmHints.decorations */
+#define MWM_DECOR_ALL		(1L << 0)
+#define MWM_DECOR_BORDER	(1L << 1)
+#define MWM_DECOR_RESIZEH	(1L << 2)
+#define MWM_DECOR_TITLE		(1L << 3)
+#define MWM_DECOR_MENU		(1L << 4)
+#define MWM_DECOR_MINIMIZE	(1L << 5)
+#define MWM_DECOR_MAXIMIZE	(1L << 6)
+
+typedef struct
+{
+  unsigned long flags       ;
+  unsigned long functions   ;
+  unsigned long decorations ;
+           long inputMode   ;
+  unsigned long status      ;
+} PropMotifWmHints ;
+
+#define PROP_MOTIF_WM_HINTS_ELEMENTS	5
+
+#endif
+
+#ifndef GLX_SAMPLE_BUFFERS_ARB
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB        100001
+#endif
+
+
+Display     *currDisplay ;
+XVisualInfo *visualInfo  ;
+Window       currHandle  ;
+GLXContext   currContext ;
+Window       rootWindow  ;
+Atom         delWinAtom  ;
+
+int currScreen;
+int currConnect;
+
+typedef struct PixelFormat
+{
+  int num_samples ;
+  int bits_per_pixel ; ;
+  int z_bits ;
+} PixelFormat;
+
+
+PixelFormat preferred_pixel_formats [] =
+{
+  /* NumSamples, RGB_bits, Z_bits */
+
+  {  0, 24, 24 },  /* Progressively nastier image formats */
+  {  0, 16, 24 },
+  {  0, 16, 16 },
+  { -1, -1, -1 }   /* Magic end marker */
+} ;
+
+void pwInit ( int x, int y, int w, int h, int multisample,
+              char *title, int border, int num_samples );
+
+
+// ---------------------- public API
+
+void glutInit(int *argc, char **argv)
+{
+currDisplay = NULL ;
+visualInfo  = NULL ;
+
+currScreen  = 0;
+currConnect = 0;
+
+glutReshapeFuncCB=NULL;
+glutKeyboardFuncCB=NULL;
+glutSpecialUpFuncCB=NULL;
+glutSpecialFuncCB=NULL;
+glutMotionFuncCB=NULL;
+glutPassiveMotionFuncCB=NULL;
+glutMouseFuncCB=NULL;
+glutDisplayFuncCB=NULL;
+glutIdleFuncCB=NULL;
+}
+
+
+
+
+void mylgutCloseWindow(void)
+{
+  glXDestroyContext ( currDisplay, currContext ) ;
+  XDestroyWindow    ( currDisplay, currHandle  ) ;
+  XFlush            ( currDisplay ) ;
+}
+
+
+
+//glutSetCursor
+void glutSetCursor(int cursor)
+{
+int currCursor;
+Pixmap pix ;
+char   blank_cursor[16*16];
+XColor bcol = { 0 } ;
+
+switch(cursor)
+    {
+    case GLUT_CURSOR_LEFT_ARROW:
+	currCursor = XC_left_ptr;
+	XDefineCursor( currDisplay, currHandle,
+                 XCreateFontCursor ( currDisplay, currCursor ) ) ;
+	break;
+    case GLUT_CURSOR_NONE:	
+    default:
+	memset(blank_cursor,0,16*16);
+      
+        pix = XCreateBitmapFromData ( currDisplay,
+                                      rootWindow,
+                                      blank_cursor, 16, 16 ) ;
+        XDefineCursor ( currDisplay, currHandle,
+                        XCreatePixmapCursor ( currDisplay,
+                            pix, pix, &bcol, &bcol, 0, 0 ) ) ;
+        XFreePixmap   ( currDisplay, pix ) ;
+        currCursor = 0 ;
+    }
+}
+
+//glutWarpPointer (move mouse)
+void glutWarpPointer(int x, int y)
+{
+  XWarpPointer(currDisplay, None, currHandle, 0, 0, 0, 0, x, y);
+  XFlush(currDisplay);
+}
+
+//glutSwapBuffers
+void glutSwapBuffers(void)
+{
+  glFlush () ;
+  glXSwapBuffers ( currDisplay, currHandle ) ;
+  // get events ?
+}
+
+
+//glutMainLoop is generic (myglut.c)
+
+// ------------- private part
+
+void chooseVisual (PixelFormat *pf)
+{
+  int attribs [ 100 ] ;
+  int n = 0 ;
+
+  attribs [n++] = GLX_RGBA ;
+
+  switch ( pf->bits_per_pixel )
+  {
+    case 3 :
+      attribs [n++] = GLX_RED_SIZE   ; attribs [n++] = 1 ;
+      attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 1 ;
+      attribs [n++] = GLX_BLUE_SIZE  ; attribs [n++] = 1 ;
+      break ;
+
+    case 16 :
+      attribs [n++] = GLX_RED_SIZE   ; attribs [n++] = 5 ;
+      attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 6 ;
+      attribs [n++] = GLX_BLUE_SIZE  ; attribs [n++] = 5 ;
+      break ;
+
+    case 24 :
+      attribs [n++] = GLX_RED_SIZE   ; attribs [n++] = 8 ;
+      attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 8 ;
+      attribs [n++] = GLX_BLUE_SIZE  ; attribs [n++] = 8 ;
+      break ;
+  }
+
+  switch ( pf->z_bits )
+  {
+    case  1 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] =  1 ; break ; 
+    case 16 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 16 ; break ; 
+    case 24 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 24 ; break ;
+    case 32 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 32 ; break ;
+  }
+
+  if ( pf->num_samples > 0 )
+  {
+    attribs [n++] = GLX_SAMPLE_BUFFERS_ARB ; attribs [n++] = 1 ;
+    attribs [n++] = GLX_SAMPLES_ARB        ; attribs [n++] = pf->num_samples ;
+  }
+
+  attribs [n++] = GLX_DOUBLEBUFFER ;
+  attribs [n++] = None ;
+
+  visualInfo = glXChooseVisual ( currDisplay, currScreen, attribs ) ;
+}
+
+
+
+void pwInit ( int x, int y, int w, int h, int multisample,
+              char *title, int border, int num_samples )
+{
+  char *displayName;
+  int i;
+  int origin[2];
+  int size[2];
+
+  XSetWindowAttributes attribs ;
+  XTextProperty   textProperty ;
+  XSizeHints         sizeHints ;
+  XWMHints             wmHints ;
+  unsigned int            mask ;
+  PixelFormat               pf ;
+  
+
+  displayName=getenv ( "DISPLAY" ) ;
+
+  if ( displayName == NULL ) displayName = ":0.0" ;
+
+  currDisplay = XOpenDisplay ( displayName ) ;
+
+  if ( currDisplay == NULL )
+  {
+    raydium_log("(my)glut: ERROR: Can't open display '%s'",
+                            XDisplayName ( displayName ) ) ;
+    exit ( 1 ) ;
+  }
+
+  /* OpenGL GLX extension availability? */
+
+  if ( ! glXQueryExtension ( currDisplay, NULL, NULL ) )
+  {
+    raydium_log("(my)glut: ERROR: GLX extension not available on display '%s'",
+                                             XDisplayName ( displayName ) ) ;
+    exit ( 1 ) ;
+  }
+
+  currScreen   = DefaultScreen    ( currDisplay ) ;
+  rootWindow   = RootWindow       ( currDisplay, currScreen ) ;
+  currConnect  = ConnectionNumber ( currDisplay ) ;
+  delWinAtom   = XInternAtom      ( currDisplay, "WM_DELETE_WINDOW", 0 ) ;
+
+  if ( w == -1 ) w = DisplayWidth  ( currDisplay, currScreen ) ;
+  if ( h == -1 ) h = DisplayHeight ( currDisplay, currScreen ) ;
+
+  origin [ 0 ] = x ;
+  origin [ 1 ] = y ;
+  size   [ 0 ] = w ;
+  size   [ 1 ] = h ;
+
+
+  for (i = 0 ; preferred_pixel_formats [ i ] . num_samples >= 0 ; i++ )
+  {
+    pf = preferred_pixel_formats [ i ] ;
+    pf . num_samples = num_samples ;
+
+    chooseVisual ( &pf ) ;
+
+    if ( visualInfo != NULL )
+      break ;
+  }
+
+  if ( visualInfo == NULL )
+  {
+    num_samples = 0 ;
+
+    for (i = 0 ; preferred_pixel_formats [ i ] . num_samples >= 0 ; i++ )
+    {
+      pf = preferred_pixel_formats [ i ] ;
+      pf . num_samples = num_samples ;
+
+      chooseVisual ( &pf ) ;
+
+      if ( visualInfo != NULL )
+        break ;
+    }
+
+    if ( visualInfo == NULL )
+    {
+      raydium_log("(my)glut: ERROR: Unable to open a suitable window");
+      exit ( 1 ) ;
+    }
+  }
+
+
+  attribs.event_mask = StructureNotifyMask | ExposureMask         |
+                       ButtonPressMask     | ButtonReleaseMask    |
+                       KeyPressMask        | KeyReleaseMask       |
+		       EnterWindowMask     | LeaveWindowMask      |
+                       PointerMotionMask   | ButtonMotionMask     |
+                       VisibilityChangeMask ;
+
+  attribs.background_pixmap = None ;
+  attribs.background_pixel  = 0    ;
+  attribs.border_pixel      = 0    ;
+
+  attribs.colormap = XCreateColormap ( currDisplay, rootWindow,
+                                       visualInfo->visual, AllocNone ) ;
+
+  mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
+
+  currHandle = XCreateWindow ( currDisplay, rootWindow,
+                           x, y, w, h, 0, visualInfo->depth,
+                           InputOutput, visualInfo->visual,
+                           mask, &attribs ) ;
+
+  currContext = glXCreateContext ( currDisplay, visualInfo, NULL, 1 ) ;
+
+  glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
+
+  if ( ! glXIsDirect ( currDisplay, glXGetCurrentContext() ) )
+  {
+    raydium_log("(my)glut: WARNING: This is an *INDIRECT* rendering context.") ;
+  }
+
+  sizeHints.flags = 0 ;
+
+  if ( x >= 0 && y >= 0 )
+    sizeHints.flags |= USPosition ;
+
+  sizeHints.flags |= USSize ;
+
+  sizeHints.x      = x ; sizeHints.y      = y ;
+  sizeHints.width  = w ; sizeHints.height = h ;
+
+  wmHints.flags = StateHint;
+  wmHints.initial_state = NormalState ;
+
+  PropMotifWmHints hints  ;
+  Atom prop_t ;
+  Atom prop   ;
+
+  hints . flags = MWM_HINTS_DECORATIONS ;
+  hints . decorations = border ? MWM_DECOR_ALL : 0 ;
+
+  prop_t = prop = XInternAtom ( currDisplay, "_MOTIF_WM_HINTS", True ) ;
+
+  if ( prop != 0 )
+    XChangeProperty ( currDisplay, currHandle, prop, prop_t, 32,
+                      PropModeReplace, (unsigned char *) &hints,
+                      PROP_MOTIF_WM_HINTS_ELEMENTS) ;
+
+  XStringListToTextProperty ( (char **) &title, 1, &textProperty ) ;
+
+  XSetWMProperties ( currDisplay, currHandle,
+	                  &textProperty, &textProperty, 0, 0,
+                          &sizeHints, &wmHints, NULL ) ;
+  XSetWMProtocols  ( currDisplay, currHandle, &delWinAtom  , 1 );
+  XMapWindow       ( currDisplay, currHandle ) ;
+  glXMakeCurrent   ( currDisplay, currHandle, currContext ) ;
+
+  glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
+
+  glClear ( GL_COLOR_BUFFER_BIT ) ;
+  glutSwapBuffers();
+  glClear ( GL_COLOR_BUFFER_BIT ) ;
+  glutSwapBuffers();
+
+  raydium_log("Found %ix%i with %i bits color buffer and %i bits zbuffer",sizeHints.width,sizeHints.height,pf.bits_per_pixel,pf.z_bits);
+}
+
+
+void myglutGetEvents (void)
+{
+  static int size[2]={-1,-1};
+  signed char repeating = 0 ;
+  char keyflags [ 32 ] ;
+  XEvent event ;
+
+  XComposeStatus composeStatus ;
+  char           asciiCode [ 32 ] ;
+  KeySym         keySym ;
+
+  int len,result;
+  signed char special=0;
+
+//  insideCallback = true ;
+
+  while ( XPending ( currDisplay ) )
+  {
+    int updown = GLUT_DOWN ;
+
+    XNextEvent ( currDisplay, &event ) ;
+
+//    refreshModifiers ( &event ) ;
+
+    switch ( event.type )
+    {
+      case ClientMessage   : exit(0) ; break ;
+      case DestroyNotify   : exit(0) ; break ;
+
+      case ConfigureNotify :
+        if ( currHandle == event.xconfigure.window &&
+              ( size[0] != event.xconfigure.width ||
+                size[1] != event.xconfigure.height ) )
+        {
+          size[0] = event.xconfigure.width ;
+          size[1] = event.xconfigure.height ;
+
+          glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
+          glXWaitX    () ;
+
+          if (glutReshapeFuncCB)
+    	    glutReshapeFuncCB(size[0], size[1]);
+        }
+	break;
+
+      case MappingNotify:
+	XRefreshKeyboardMapping ( (XMappingEvent *) &event ) ;
+	break;
+
+      case EnterNotify     :
+      case LeaveNotify     :
+      case VisibilityNotify:
+      case Expose          : break ;
+
+      case MotionNotify    :
+        if (glutPassiveMotionFuncCB)
+         glutPassiveMotionFuncCB( event.xmotion.x, event.xmotion.y);
+        break ;
+
+      case ButtonRelease   :
+        updown = GLUT_UP ;
+        // FALLTHROUGH
+
+      case ButtonPress     :
+        {
+/*          int button = -1 ;
+
+          switch ( event.xbutton.button )
+          {
+            case 1 : button = PW_LEFT_BUTTON   ; break ;
+            case 2 : button = PW_MIDDLE_BUTTON ; break ;
+            case 3 : button = PW_RIGHT_BUTTON  ; break ;
+          }
+*/
+          if (glutMouseFuncCB)
+            glutMouseFuncCB(event.xbutton.button-1, updown, event.xbutton.x, event.xbutton.y ) ;
+        }
+        break ;
+
+      case KeyRelease      :
+        updown = GLUT_UP ;
+
+        XQueryKeymap ( currDisplay, keyflags ) ;
+
+        repeating = ( ( keyflags [ event.xkey.keycode >> 3 ] &
+                          ( 1 << ( event.xkey.keycode & 7 ) ) ) != 0 ) ;
+
+        // FALLTHROUGH 
+
+      case KeyPress        :
+        
+        //  Only generate a key up callback if the key is actually up
+        //  and not repeating.
+
+//        if ( ! autoRepeat && repeating )
+    //      break ;
+
+
+        len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode),
+                                 &keySym, &composeStatus ) ;
+        result = -1 ;
+
+        if( len > 0 )
+          result = asciiCode[ 0 ] ;
+        else
+        {
+	special=1;
+          switch( keySym )
+          {
+            case XK_F1:     result = GLUT_KEY_F1;     break;
+            case XK_F2:     result = GLUT_KEY_F2;     break;
+            case XK_F3:     result = GLUT_KEY_F3;     break;
+            case XK_F4:     result = GLUT_KEY_F4;     break;
+            case XK_F5:     result = GLUT_KEY_F5;     break;
+            case XK_F6:     result = GLUT_KEY_F6;     break;
+            case XK_F7:     result = GLUT_KEY_F7;     break;
+            case XK_F8:     result = GLUT_KEY_F8;     break;
+            case XK_F9:     result = GLUT_KEY_F9;     break;
+            case XK_F10:    result = GLUT_KEY_F10;    break;
+            case XK_F11:    result = GLUT_KEY_F11;    break;
+            case XK_F12:    result = GLUT_KEY_F12;    break;
+
+            case XK_Left:   result = GLUT_KEY_LEFT;   break;
+            case XK_Right:  result = GLUT_KEY_RIGHT;  break;
+            case XK_Up:     result = GLUT_KEY_UP;     break;
+            case XK_Down:   result = GLUT_KEY_DOWN;   break;
+
+            case XK_KP_Prior:
+            case XK_Prior:  result = GLUT_KEY_PAGE_UP; break;
+            case XK_KP_Next:
+            case XK_Next:   result = GLUT_KEY_PAGE_DOWN; break;
+            case XK_KP_Home:
+            case XK_Home:   result = GLUT_KEY_HOME;   break;
+            case XK_KP_End:
+            case XK_End:    result = GLUT_KEY_END;    break;
+            case XK_KP_Insert:
+            case XK_Insert: result = GLUT_KEY_INSERT; break;
+          }
+        }
+
+	if(result!=-1)
+	    {
+	    // special down
+	    if(special && updown==GLUT_DOWN && glutSpecialFuncCB && !repeating)
+		glutSpecialFuncCB(result,event.xkey.x, event.xkey.y);
+
+	    // special up
+	    if(special && updown==GLUT_UP && glutSpecialUpFuncCB && !repeating)
+		glutSpecialUpFuncCB(result,event.xkey.x, event.xkey.y);
+
+	    // normal
+	    if(!special && updown==GLUT_DOWN && glutKeyboardFuncCB)
+		glutKeyboardFuncCB(result,event.xkey.x, event.xkey.y);
+	    
+	    }
+
+        break ;
+    }
+  }
+
+//  insideCallback = false ;
+
+  glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
+}
+