Fix CRLF line endings.
authorJose Fonseca <jrfonseca@tungstengraphics.com>
Sat, 7 Jun 2008 03:34:45 +0000 (12:34 +0900)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Sat, 7 Jun 2008 03:40:39 +0000 (12:40 +0900)
src/glut/os2/WarpWin.cpp
src/glut/os2/glut_cindex.cpp
src/glut/os2/glut_gamemode.cpp
src/glut/os2/glut_win.cpp
src/glut/os2/glut_winmisc.cpp
src/glut/os2/os2_glx.cpp
src/glut/os2/os2_menu.cpp
src/glut/os2/os2_winproc.cpp

index ee746ecc764666874ce4abcfd9d86b3a4bcb3e54..bd5a6e80c7fa9036cf438bd3b23f3225ea86e958 100644 (file)
-/* WarpWin.c     */\r
-/* glut for Warp */\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#include "WarpWin.h"\r
-#include "WarpGL.h"\r
-\r
-#define POKA 0\r
-\r
-/* global variables that must be set for some functions to operate\r
-   correctly. */\r
-HDC XHDC;\r
-HWND XHWND;\r
-\r
-\r
-void\r
-XStoreColor(Display* display, Colormap colormap, XColor* color)\r
-{\r
-  /* KLUDGE: set XHDC to 0 if the palette should NOT be realized after\r
-     setting the color.  set XHDC to the correct HDC if it should. */\r
-\r
-  LONG pe;\r
-  ULONG cclr;\r
-  int r,g,b;\r
-  /* X11 stores color from 0-65535, Win32 expects them to be 0-256, so\r
-     twiddle the bits ( / 256). */\r
-  r = color->red / 256;\r
-  g = color->green / 256;\r
-  b = color->blue / 256;\r
-  pe = LONGFromRGB(r,g,b);\r
-  /* make sure we use this flag, otherwise the colors might get mapped\r
-     to another place in the colormap, and when we glIndex() that\r
-     color, it may have moved (argh!!) */\r
-  pe |= (PC_NOCOLLAPSE<<24);\r
-/* This function changes the entries in a palette.  */\r
-#if POKA\r
-OS2:\r
- rc = GpiSetPaletteEntries(colormap,LCOLF_CONSECRGB, color->pixel, 1, &pe);\r
- GpiSelectPalette(hps,colormap);\r
- WinRealizePalette(hwnd,hps,&cclr);\r
-source Win:\r
-  if (XHDC) {\r
-    UnrealizeObject(colormap);\r
-    SelectPalette(XHDC, colormap, FALSE);\r
-    RealizePalette(XHDC);\r
-\r
-   }\r
-#endif\r
-}\r
-\r
-void\r
-XSetWindowColormap(Display* display, Window window, Colormap colormap)\r
-{\r
-#if POKA\r
-  HDC hdc = GetDC(window);\r
-\r
-  /* if the third parameter is FALSE, the logical colormap is copied\r
-     into the device palette when the application is in the\r
-     foreground, if it is TRUE, the colors are mapped into the current\r
-     palette in the best possible way. */\r
-  SelectPalette(hdc, colormap, FALSE);\r
-  RealizePalette(hdc);\r
-\r
-  /* note that we don't have to release the DC, since our window class\r
-     uses the WC_OWNDC flag! */\r
-#endif\r
-}\r
-\r
-\r
-/* display, root and visual - don't used at all */\r
-Colormap\r
-XCreateColormap(Display* display, Window root, Visual* visual, int alloc)\r
-{\r
-  /* KLUDGE: this function needs XHDC to be set to the HDC currently\r
-     being operated on before it is invoked! */\r
-\r
-  HPAL    palette;\r
-  int n;\r
-#if POKA\r
-  PIXELFORMATDESCRIPTOR pfd;\r
-  LOGPALETTE *logical;\r
-\r
-  /* grab the pixel format */\r
-  memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));\r
-  DescribePixelFormat(XHDC, GetPixelFormat(XHDC),\r
-                     sizeof(PIXELFORMATDESCRIPTOR), &pfd);\r
-\r
-  if (!(pfd.dwFlags & PFD_NEED_PALETTE ||\r
-      pfd.iPixelType == PFD_TYPE_COLORINDEX))\r
-  {\r
-    return 0;\r
-  }\r
-\r
-  n = 1 << pfd.cColorBits;\r
-\r
-  /* allocate a bunch of memory for the logical palette (assume 256\r
-     colors in a Win32 palette */\r
-  logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +\r
-                               sizeof(PALETTEENTRY) * n);\r
-  memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);\r
-\r
-  /* set the entries in the logical palette */\r
-  logical->palVersion = 0x300;\r
-  logical->palNumEntries = n;\r
-\r
-  /* start with a copy of the current system palette */\r
-  GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]);\r
-\r
-  if (pfd.iPixelType == PFD_TYPE_RGBA) {\r
-    int redMask = (1 << pfd.cRedBits) - 1;\r
-    int greenMask = (1 << pfd.cGreenBits) - 1;\r
-    int blueMask = (1 << pfd.cBlueBits) - 1;\r
-    int i;\r
-\r
-    /* fill in an RGBA color palette */\r
-    for (i = 0; i < n; ++i) {\r
-      logical->palPalEntry[i].peRed =\r
-       (((i >> pfd.cRedShift)   & redMask)   * 255) / redMask;\r
-      logical->palPalEntry[i].peGreen =\r
-       (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;\r
-       logical->palPalEntry[i].peBlue =\r
-       (((i >> pfd.cBlueShift)  & blueMask)  * 255) / blueMask;\r
-      logical->palPalEntry[i].peFlags = 0;\r
-    }\r
-  }\r
-\r
-  palette = CreatePalette(logical);\r
-  free(logical);\r
-\r
-  SelectPalette(XHDC, palette, FALSE);\r
-  RealizePalette(XHDC);\r
-#endif /* POKA */\r
-\r
-  return palette;\r
-}\r
-\r
-\r
-\r
-int  GetSystemMetrics( int mode)\r
-{  RECTL rect;\r
-\r
-   switch(mode)\r
-   {   case   SM_CXSCREEN:\r
-        WinQueryWindowRect(HWND_DESKTOP,&rect);\r
-        return (rect.xRight-rect.xLeft);\r
-      break;\r
-       case   SM_CYSCREEN:\r
-        WinQueryWindowRect(HWND_DESKTOP,&rect);\r
-        return (rect.yTop-rect.yBottom);\r
-      break;\r
-       default: ;\r
-   }\r
-   return 0;\r
-}\r
-/*\r
- *    XParseGeometry parses strings of the form\r
- *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where\r
- *   width, height, xoffset, and yoffset are unsigned integers.\r
- *   Example:  "=80x24+300-49"\r
- *   The equal sign is optional.\r
- *   It returns a bitmask that indicates which of the four values\r
- *   were actually found in the string.  For each value found,\r
- *   the corresponding argument is updated;  for each value\r
- *   not found, the corresponding argument is left unchanged.\r
- */\r
-\r
-static int\r
-ReadInteger(char *string, char **NextString)\r
-{\r
-    register int Result = 0;\r
-    int Sign = 1;\r
-\r
-    if (*string == '+')\r
-       string++;\r
-    else if (*string == '-')\r
-    {\r
-       string++;\r
-       Sign = -1;\r
-    }\r
-    for (; (*string >= '0') && (*string <= '9'); string++)\r
-    {\r
-       Result = (Result * 10) + (*string - '0');\r
-    }\r
-    *NextString = string;\r
-    if (Sign >= 0)\r
-       return (Result);\r
-    else\r
-       return (-Result);\r
-}\r
-\r
-int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height)\r
-{\r
-       int mask = NoValue;\r
-       register char *strind;\r
-       unsigned int tempWidth, tempHeight;\r
-       int tempX, tempY;\r
-       char *nextCharacter;\r
-\r
-       if ( (string == NULL) || (*string == '\0')) return(mask);\r
-       if (*string == '=')\r
-               string++;  /* ignore possible '=' at beg of geometry spec */\r
-\r
-       strind = (char *)string;\r
-       if (*strind != '+' && *strind != '-' && *strind != 'x') {\r
-               tempWidth = ReadInteger(strind, &nextCharacter);\r
-               if (strind == nextCharacter)\r
-                   return (0);\r
-               strind = nextCharacter;\r
-               mask |= WidthValue;\r
-       }\r
-\r
-       if (*strind == 'x' || *strind == 'X') {\r
-               strind++;\r
-               tempHeight = ReadInteger(strind, &nextCharacter);\r
-               if (strind == nextCharacter)\r
-                   return (0);\r
-               strind = nextCharacter;\r
-               mask |= HeightValue;\r
-       }\r
-\r
-       if ((*strind == '+') || (*strind == '-')) {\r
-               if (*strind == '-') {\r
-                       strind++;\r
-                       tempX = -ReadInteger(strind, &nextCharacter);\r
-                       if (strind == nextCharacter)\r
-                           return (0);\r
-                       strind = nextCharacter;\r
-                       mask |= XNegative;\r
-\r
-               }\r
-               else\r
-               {       strind++;\r
-                       tempX = ReadInteger(strind, &nextCharacter);\r
-                       if (strind == nextCharacter)\r
-                           return(0);\r
-                       strind = nextCharacter;\r
-               }\r
-               mask |= XValue;\r
-               if ((*strind == '+') || (*strind == '-')) {\r
-                       if (*strind == '-') {\r
-                               strind++;\r
-                               tempY = -ReadInteger(strind, &nextCharacter);\r
-                               if (strind == nextCharacter)\r
-                                   return(0);\r
-                               strind = nextCharacter;\r
-                               mask |= YNegative;\r
-\r
-                       }\r
-                       else\r
-                       {\r
-                               strind++;\r
-                               tempY = ReadInteger(strind, &nextCharacter);\r
-                               if (strind == nextCharacter)\r
-                                   return(0);\r
-                               strind = nextCharacter;\r
-                       }\r
-                       mask |= YValue;\r
-               }\r
-       }\r
-\r
-       /* If strind isn't at the end of the string the it's an invalid\r
-               geometry specification. */\r
-\r
-       if (*strind != '\0') return (0);\r
-\r
-       if (mask & XValue)\r
-           *x = tempX;\r
-       if (mask & YValue)\r
-           *y = tempY;\r
-       if (mask & WidthValue)\r
-            *width = tempWidth;\r
-       if (mask & HeightValue)\r
-            *height = tempHeight;\r
-       return (mask);\r
-}\r
-\r
-int gettimeofday(struct timeval* tp, void* tzp)\r
-{\r
- DATETIME    DateTime;\r
- APIRET       ulrc;  /*  Return Code. */\r
-\r
- ulrc = DosGetDateTime(&DateTime);\r
- tp->tv_sec  = 60 * (60*DateTime.hours + DateTime.minutes) + DateTime.seconds;\r
- tp->tv_usec = DateTime.hundredths * 10000;\r
- return 0;\r
-}\r
-\r
-\r
-int\r
-XPending(Display* display)\r
-{\r
-  /* similar functionality...I don't think that it is exact, but this\r
-     will have to do. */\r
-  QMSG msg;\r
-  extern HAB   hab;      /* PM anchor block handle         */\r
-\r
-//?? WinPeekMsg(hab\r
-  return WinPeekMsg(hab, &msg, NULLHANDLE, 0, 0, PM_NOREMOVE);\r
-}\r
-\r
-void\r
-__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height)\r
-{\r
-  RECTL rect;\r
-\r
-  /* adjust the window rectangle because Win32 thinks that the x, y,\r
-     width & height are the WHOLE window (including decorations),\r
-     whereas GLUT treats the x, y, width & height as only the CLIENT\r
-     area of the window. */\r
-  rect.xLeft = *x; rect.yTop = *y;\r
-  rect.xRight = *x + *width; rect.yBottom = *y + *height;\r
-\r
-  /* must adjust the coordinates according to the correct style\r
-     because depending on the style, there may or may not be\r
-     borders. */\r
-//??  AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN |\r
-//??              (parent ? WS_CHILD : WS_OVERLAPPEDWINDOW),\r
-//??              FALSE);\r
-  /* FALSE in the third parameter = window has no menu bar */\r
-\r
-  /* readjust if the x and y are offscreen */\r
-  if(rect.xLeft < 0) {\r
-    *x = 0;\r
-  } else {\r
-    *x = rect.xLeft;\r
-  }\r
-\r
-  if(rect.yTop < 0) {\r
-    *y = 0;\r
-  } else {\r
-    *y = rect.yTop;\r
-  }\r
-\r
-  *width = rect.xRight - rect.xLeft;     /* adjusted width */\r
-  *height = -(rect.yBottom - rect.yTop);    /* adjusted height */\r
-}\r
-\r
-\r
-int\r
-__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)\r
-{\r
-  /* the transparent pixel on Win32 is always index number 0.  So if\r
-     we put this routine in this file, we can avoid compiling the\r
-     whole of layerutil.c which is where this routine normally comes\r
-     from. */\r
-  return 0;\r
-}\r
-\r
-/* Translate point coordinates src_x and src_y from src to dst */\r
-\r
-Bool\r
-XTranslateCoordinates(Display *display, Window src, Window dst,\r
-                     int src_x, int src_y,\r
-                     int* dest_x_return, int* dest_y_return,\r
-                     Window* child_return)\r
-{\r
-  SWP swp_src,swp_dst;\r
-\r
-  WinQueryWindowPos(src,&swp_src);\r
-  WinQueryWindowPos(dst,&swp_dst);\r
-\r
-  *dest_x_return =  src_x + swp_src.x - swp_dst.x;\r
-  *dest_y_return =  src_y + swp_src.y - swp_dst.y;\r
-\r
-  /* just to make compilers happy...we don't use the return value. */\r
-  return True;\r
-}\r
-\r
-Status\r
-XGetGeometry(Display* display, Window window, Window* root_return,\r
-            int* x_return, int* y_return,\r
-            unsigned int* width_return, unsigned int* height_return,\r
-            unsigned int *border_width_return, unsigned int* depth_return)\r
-{\r
-  /* KLUDGE: doesn't return the border_width or depth or root, x & y\r
-     are in screen coordinates. */\r
-  SWP swp_src;\r
-  WinQueryWindowPos(window,&swp_src);\r
-\r
-  *x_return = swp_src.x;\r
-  *y_return = swp_src.y;\r
-  *width_return = swp_src.cx;\r
-  *height_return = swp_src.cy;\r
-\r
-  /* just to make compilers happy...we don't use the return value. */\r
-  return 1;\r
-}\r
-\r
-/* Get Display Width in millimeters */\r
-int\r
-DisplayWidthMM(Display* display, int screen)\r
-{\r
-  int width;\r
-  LONG *pVC_Caps;\r
-  pVC_Caps = GetVideoConfig(NULLHANDLE);\r
-  width = (int)( 0.001 * pVC_Caps[CAPS_WIDTH]  / pVC_Caps[CAPS_HORIZONTAL_RESOLUTION]);/* mm */\r
-  return width;\r
-}\r
-\r
-/* Get Display Height in millimeters */\r
-int\r
-DisplayHeightMM(Display* display, int screen)\r
-{\r
-  int height;\r
-  LONG *pVC_Caps;\r
-  pVC_Caps = GetVideoConfig(NULLHANDLE);\r
-  height = (int)( 0.001 * pVC_Caps[CAPS_HEIGHT] / pVC_Caps[CAPS_VERTICAL_RESOLUTION]); /* mm */\r
-  return height;\r
-}\r
-\r
-void ScreenToClient( HWND hwnd,   POINTL *point)\r
-{\r
-  SWP swp_src;\r
-  WinQueryWindowPos(hwnd,&swp_src);\r
-  point->x -= swp_src.x;\r
-  point->y -= swp_src.y;\r
-}\r
-\r
+/* WarpWin.c     */
+/* glut for Warp */
+#include <stdio.h>
+#include <string.h>
+
+#include "WarpWin.h"
+#include "WarpGL.h"
+
+#define POKA 0
+
+/* global variables that must be set for some functions to operate
+   correctly. */
+HDC XHDC;
+HWND XHWND;
+
+
+void
+XStoreColor(Display* display, Colormap colormap, XColor* color)
+{
+  /* KLUDGE: set XHDC to 0 if the palette should NOT be realized after
+     setting the color.  set XHDC to the correct HDC if it should. */
+
+  LONG pe;
+  ULONG cclr;
+  int r,g,b;
+  /* X11 stores color from 0-65535, Win32 expects them to be 0-256, so
+     twiddle the bits ( / 256). */
+  r = color->red / 256;
+  g = color->green / 256;
+  b = color->blue / 256;
+  pe = LONGFromRGB(r,g,b);
+  /* make sure we use this flag, otherwise the colors might get mapped
+     to another place in the colormap, and when we glIndex() that
+     color, it may have moved (argh!!) */
+  pe |= (PC_NOCOLLAPSE<<24);
+/* This function changes the entries in a palette.  */
+#if POKA
+OS2:
+ rc = GpiSetPaletteEntries(colormap,LCOLF_CONSECRGB, color->pixel, 1, &pe);
+ GpiSelectPalette(hps,colormap);
+ WinRealizePalette(hwnd,hps,&cclr);
+source Win:
+  if (XHDC) {
+    UnrealizeObject(colormap);
+    SelectPalette(XHDC, colormap, FALSE);
+    RealizePalette(XHDC);
+
+   }
+#endif
+}
+
+void
+XSetWindowColormap(Display* display, Window window, Colormap colormap)
+{
+#if POKA
+  HDC hdc = GetDC(window);
+
+  /* if the third parameter is FALSE, the logical colormap is copied
+     into the device palette when the application is in the
+     foreground, if it is TRUE, the colors are mapped into the current
+     palette in the best possible way. */
+  SelectPalette(hdc, colormap, FALSE);
+  RealizePalette(hdc);
+
+  /* note that we don't have to release the DC, since our window class
+     uses the WC_OWNDC flag! */
+#endif
+}
+
+
+/* display, root and visual - don't used at all */
+Colormap
+XCreateColormap(Display* display, Window root, Visual* visual, int alloc)
+{
+  /* KLUDGE: this function needs XHDC to be set to the HDC currently
+     being operated on before it is invoked! */
+
+  HPAL    palette;
+  int n;
+#if POKA
+  PIXELFORMATDESCRIPTOR pfd;
+  LOGPALETTE *logical;
+
+  /* grab the pixel format */
+  memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+  DescribePixelFormat(XHDC, GetPixelFormat(XHDC),
+                     sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+
+  if (!(pfd.dwFlags & PFD_NEED_PALETTE ||
+      pfd.iPixelType == PFD_TYPE_COLORINDEX))
+  {
+    return 0;
+  }
+
+  n = 1 << pfd.cColorBits;
+
+  /* allocate a bunch of memory for the logical palette (assume 256
+     colors in a Win32 palette */
+  logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
+                               sizeof(PALETTEENTRY) * n);
+  memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
+
+  /* set the entries in the logical palette */
+  logical->palVersion = 0x300;
+  logical->palNumEntries = n;
+
+  /* start with a copy of the current system palette */
+  GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]);
+
+  if (pfd.iPixelType == PFD_TYPE_RGBA) {
+    int redMask = (1 << pfd.cRedBits) - 1;
+    int greenMask = (1 << pfd.cGreenBits) - 1;
+    int blueMask = (1 << pfd.cBlueBits) - 1;
+    int i;
+
+    /* fill in an RGBA color palette */
+    for (i = 0; i < n; ++i) {
+      logical->palPalEntry[i].peRed =
+       (((i >> pfd.cRedShift)   & redMask)   * 255) / redMask;
+      logical->palPalEntry[i].peGreen =
+       (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
+       logical->palPalEntry[i].peBlue =
+       (((i >> pfd.cBlueShift)  & blueMask)  * 255) / blueMask;
+      logical->palPalEntry[i].peFlags = 0;
+    }
+  }
+
+  palette = CreatePalette(logical);
+  free(logical);
+
+  SelectPalette(XHDC, palette, FALSE);
+  RealizePalette(XHDC);
+#endif /* POKA */
+
+  return palette;
+}
+
+
+
+int  GetSystemMetrics( int mode)
+{  RECTL rect;
+
+   switch(mode)
+   {   case   SM_CXSCREEN:
+        WinQueryWindowRect(HWND_DESKTOP,&rect);
+        return (rect.xRight-rect.xLeft);
+      break;
+       case   SM_CYSCREEN:
+        WinQueryWindowRect(HWND_DESKTOP,&rect);
+        return (rect.yTop-rect.yBottom);
+      break;
+       default: ;
+   }
+   return 0;
+}
+/*
+ *    XParseGeometry parses strings of the form
+ *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ *   width, height, xoffset, and yoffset are unsigned integers.
+ *   Example:  "=80x24+300-49"
+ *   The equal sign is optional.
+ *   It returns a bitmask that indicates which of the four values
+ *   were actually found in the string.  For each value found,
+ *   the corresponding argument is updated;  for each value
+ *   not found, the corresponding argument is left unchanged.
+ */
+
+static int
+ReadInteger(char *string, char **NextString)
+{
+    register int Result = 0;
+    int Sign = 1;
+
+    if (*string == '+')
+       string++;
+    else if (*string == '-')
+    {
+       string++;
+       Sign = -1;
+    }
+    for (; (*string >= '0') && (*string <= '9'); string++)
+    {
+       Result = (Result * 10) + (*string - '0');
+    }
+    *NextString = string;
+    if (Sign >= 0)
+       return (Result);
+    else
+       return (-Result);
+}
+
+int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height)
+{
+       int mask = NoValue;
+       register char *strind;
+       unsigned int tempWidth, tempHeight;
+       int tempX, tempY;
+       char *nextCharacter;
+
+       if ( (string == NULL) || (*string == '\0')) return(mask);
+       if (*string == '=')
+               string++;  /* ignore possible '=' at beg of geometry spec */
+
+       strind = (char *)string;
+       if (*strind != '+' && *strind != '-' && *strind != 'x') {
+               tempWidth = ReadInteger(strind, &nextCharacter);
+               if (strind == nextCharacter)
+                   return (0);
+               strind = nextCharacter;
+               mask |= WidthValue;
+       }
+
+       if (*strind == 'x' || *strind == 'X') {
+               strind++;
+               tempHeight = ReadInteger(strind, &nextCharacter);
+               if (strind == nextCharacter)
+                   return (0);
+               strind = nextCharacter;
+               mask |= HeightValue;
+       }
+
+       if ((*strind == '+') || (*strind == '-')) {
+               if (*strind == '-') {
+                       strind++;
+                       tempX = -ReadInteger(strind, &nextCharacter);
+                       if (strind == nextCharacter)
+                           return (0);
+                       strind = nextCharacter;
+                       mask |= XNegative;
+
+               }
+               else
+               {       strind++;
+                       tempX = ReadInteger(strind, &nextCharacter);
+                       if (strind == nextCharacter)
+                           return(0);
+                       strind = nextCharacter;
+               }
+               mask |= XValue;
+               if ((*strind == '+') || (*strind == '-')) {
+                       if (*strind == '-') {
+                               strind++;
+                               tempY = -ReadInteger(strind, &nextCharacter);
+                               if (strind == nextCharacter)
+                                   return(0);
+                               strind = nextCharacter;
+                               mask |= YNegative;
+
+                       }
+                       else
+                       {
+                               strind++;
+                               tempY = ReadInteger(strind, &nextCharacter);
+                               if (strind == nextCharacter)
+                                   return(0);
+                               strind = nextCharacter;
+                       }
+                       mask |= YValue;
+               }
+       }
+
+       /* If strind isn't at the end of the string the it's an invalid
+               geometry specification. */
+
+       if (*strind != '\0') return (0);
+
+       if (mask & XValue)
+           *x = tempX;
+       if (mask & YValue)
+           *y = tempY;
+       if (mask & WidthValue)
+            *width = tempWidth;
+       if (mask & HeightValue)
+            *height = tempHeight;
+       return (mask);
+}
+
+int gettimeofday(struct timeval* tp, void* tzp)
+{
+ DATETIME    DateTime;
+ APIRET       ulrc;  /*  Return Code. */
+
+ ulrc = DosGetDateTime(&DateTime);
+ tp->tv_sec  = 60 * (60*DateTime.hours + DateTime.minutes) + DateTime.seconds;
+ tp->tv_usec = DateTime.hundredths * 10000;
+ return 0;
+}
+
+
+int
+XPending(Display* display)
+{
+  /* similar functionality...I don't think that it is exact, but this
+     will have to do. */
+  QMSG msg;
+  extern HAB   hab;      /* PM anchor block handle         */
+
+//?? WinPeekMsg(hab
+  return WinPeekMsg(hab, &msg, NULLHANDLE, 0, 0, PM_NOREMOVE);
+}
+
+void
+__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height)
+{
+  RECTL rect;
+
+  /* adjust the window rectangle because Win32 thinks that the x, y,
+     width & height are the WHOLE window (including decorations),
+     whereas GLUT treats the x, y, width & height as only the CLIENT
+     area of the window. */
+  rect.xLeft = *x; rect.yTop = *y;
+  rect.xRight = *x + *width; rect.yBottom = *y + *height;
+
+  /* must adjust the coordinates according to the correct style
+     because depending on the style, there may or may not be
+     borders. */
+//??  AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
+//??              (parent ? WS_CHILD : WS_OVERLAPPEDWINDOW),
+//??              FALSE);
+  /* FALSE in the third parameter = window has no menu bar */
+
+  /* readjust if the x and y are offscreen */
+  if(rect.xLeft < 0) {
+    *x = 0;
+  } else {
+    *x = rect.xLeft;
+  }
+
+  if(rect.yTop < 0) {
+    *y = 0;
+  } else {
+    *y = rect.yTop;
+  }
+
+  *width = rect.xRight - rect.xLeft;     /* adjusted width */
+  *height = -(rect.yBottom - rect.yTop);    /* adjusted height */
+}
+
+
+int
+__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)
+{
+  /* the transparent pixel on Win32 is always index number 0.  So if
+     we put this routine in this file, we can avoid compiling the
+     whole of layerutil.c which is where this routine normally comes
+     from. */
+  return 0;
+}
+
+/* Translate point coordinates src_x and src_y from src to dst */
+
+Bool
+XTranslateCoordinates(Display *display, Window src, Window dst,
+                     int src_x, int src_y,
+                     int* dest_x_return, int* dest_y_return,
+                     Window* child_return)
+{
+  SWP swp_src,swp_dst;
+
+  WinQueryWindowPos(src,&swp_src);
+  WinQueryWindowPos(dst,&swp_dst);
+
+  *dest_x_return =  src_x + swp_src.x - swp_dst.x;
+  *dest_y_return =  src_y + swp_src.y - swp_dst.y;
+
+  /* just to make compilers happy...we don't use the return value. */
+  return True;
+}
+
+Status
+XGetGeometry(Display* display, Window window, Window* root_return,
+            int* x_return, int* y_return,
+            unsigned int* width_return, unsigned int* height_return,
+            unsigned int *border_width_return, unsigned int* depth_return)
+{
+  /* KLUDGE: doesn't return the border_width or depth or root, x & y
+     are in screen coordinates. */
+  SWP swp_src;
+  WinQueryWindowPos(window,&swp_src);
+
+  *x_return = swp_src.x;
+  *y_return = swp_src.y;
+  *width_return = swp_src.cx;
+  *height_return = swp_src.cy;
+
+  /* just to make compilers happy...we don't use the return value. */
+  return 1;
+}
+
+/* Get Display Width in millimeters */
+int
+DisplayWidthMM(Display* display, int screen)
+{
+  int width;
+  LONG *pVC_Caps;
+  pVC_Caps = GetVideoConfig(NULLHANDLE);
+  width = (int)( 0.001 * pVC_Caps[CAPS_WIDTH]  / pVC_Caps[CAPS_HORIZONTAL_RESOLUTION]);/* mm */
+  return width;
+}
+
+/* Get Display Height in millimeters */
+int
+DisplayHeightMM(Display* display, int screen)
+{
+  int height;
+  LONG *pVC_Caps;
+  pVC_Caps = GetVideoConfig(NULLHANDLE);
+  height = (int)( 0.001 * pVC_Caps[CAPS_HEIGHT] / pVC_Caps[CAPS_VERTICAL_RESOLUTION]); /* mm */
+  return height;
+}
+
+void ScreenToClient( HWND hwnd,   POINTL *point)
+{
+  SWP swp_src;
+  WinQueryWindowPos(hwnd,&swp_src);
+  point->x -= swp_src.x;
+  point->y -= swp_src.y;
+}
+
 \1a
\ No newline at end of file
index 0897a3cf85c4aae39aec2380ac3571b47c7e04f6..34841850519996b200f77e7dedb0380835c261c7 100644 (file)
-\r
-/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */\r
-\r
-/* This program is freely distributable without licensing fees\r
-   and is provided without guarantee or warrantee expressed or\r
-   implied. This program is -not- in the public domain. */\r
-\r
-#include <stdlib.h>\r
-#include "glutint.h"\r
-\r
-#if defined(__OS2PM__)\r
-   #define IsWindowVisible WinIsWindowVisible\r
-#endif\r
-\r
-#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))\r
-\r
-/* CENTRY */\r
-void GLUTAPIENTRY\r
-glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)\r
-{\r
-  GLUTcolormap *cmap, *newcmap;\r
-  XVisualInfo *vis;\r
-  XColor color;\r
-  int i;\r
-\r
-  if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {\r
-    cmap = __glutCurrentWindow->colormap;\r
-    vis = __glutCurrentWindow->vis;\r
-  } else {\r
-    cmap = __glutCurrentWindow->overlay->colormap;\r
-    vis = __glutCurrentWindow->overlay->vis;\r
-    if (ndx == __glutCurrentWindow->overlay->transparentPixel) {\r
-      __glutWarning(\r
-        "glutSetColor: cannot set color of overlay transparent index %d\n",\r
-        ndx);\r
-      return;\r
-    }\r
-  }\r
-\r
-  if (!cmap) {\r
-    __glutWarning("glutSetColor: current window is RGBA");\r
-    return;\r
-  }\r
-#if defined(_WIN32) || defined(__OS2PM__)\r
-  if (ndx >= 256 ||     /* always assume 256 colors on Win32 */\r
-#else\r
-  if (ndx >= vis->visual->map_entries ||\r
-#endif\r
-    ndx < 0) {\r
-    __glutWarning("glutSetColor: index %d out of range", ndx);\r
-    return;\r
-  }\r
-  if (cmap->refcnt > 1) {\r
-    newcmap = __glutAssociateNewColormap(vis);\r
-    cmap->refcnt--;\r
-    /* Wouldn't it be nice if XCopyColormapAndFree could be\r
-       told not to free the old colormap's entries! */\r
-    for (i = cmap->size - 1; i >= 0; i--) {\r
-      if (i == ndx) {\r
-        /* We are going to set this cell shortly! */\r
-        continue;\r
-      }\r
-      if (cmap->cells[i].component[GLUT_RED] >= 0.0) {\r
-        color.pixel = i;\r
-        newcmap->cells[i].component[GLUT_RED] =\r
-          cmap->cells[i].component[GLUT_RED];\r
-        color.red = (GLfloat) 0xffff *\r
-          cmap->cells[i].component[GLUT_RED];\r
-        newcmap->cells[i].component[GLUT_GREEN] =\r
-          cmap->cells[i].component[GLUT_GREEN];\r
-        color.green = (GLfloat) 0xffff *\r
-          cmap->cells[i].component[GLUT_GREEN];\r
-        newcmap->cells[i].component[GLUT_BLUE] =\r
-          cmap->cells[i].component[GLUT_BLUE];\r
-        color.blue = (GLfloat) 0xffff *\r
-          cmap->cells[i].component[GLUT_BLUE];\r
-        color.flags = DoRed | DoGreen | DoBlue;\r
-#if defined(_WIN32) || defined(__OS2PM__)\r
-        if (IsWindowVisible(__glutCurrentWindow->win)) {\r
-          XHDC = __glutCurrentWindow->hdc;\r
-        } else {\r
-          XHDC = 0;\r
-        }\r
-#endif\r
-        XStoreColor(__glutDisplay, newcmap->cmap, &color);\r
-      } else {\r
-        /* Leave unallocated entries unallocated. */\r
-      }\r
-    }\r
-    cmap = newcmap;\r
-    if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {\r
-      __glutCurrentWindow->colormap = cmap;\r
-      __glutCurrentWindow->cmap = cmap->cmap;\r
-    } else {\r
-      __glutCurrentWindow->overlay->colormap = cmap;\r
-      __glutCurrentWindow->overlay->cmap = cmap->cmap;\r
-    }\r
-    XSetWindowColormap(__glutDisplay,\r
-      __glutCurrentWindow->renderWin, cmap->cmap);\r
-\r
-#if !defined(_WIN32) && !defined(__OS2PM__)\r
-    {\r
-      GLUTwindow *toplevel;\r
-\r
-      toplevel = __glutToplevelOf(__glutCurrentWindow);\r
-      if (toplevel->cmap != cmap->cmap) {\r
-        __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);\r
-      }\r
-    }\r
-#endif\r
-  }\r
-  color.pixel = ndx;\r
-  red = CLAMP(red);\r
-  cmap->cells[ndx].component[GLUT_RED] = red;\r
-  color.red = (GLfloat) 0xffff *red;\r
-  green = CLAMP(green);\r
-  cmap->cells[ndx].component[GLUT_GREEN] = green;\r
-  color.green = (GLfloat) 0xffff *green;\r
-  blue = CLAMP(blue);\r
-  cmap->cells[ndx].component[GLUT_BLUE] = blue;\r
-  color.blue = (GLfloat) 0xffff *blue;\r
-  color.flags = DoRed | DoGreen | DoBlue;\r
-#if defined(_WIN32) || defined(__OS2PM__)\r
-  if (IsWindowVisible(__glutCurrentWindow->win)) {\r
-    XHDC = __glutCurrentWindow->hdc;\r
-  } else {\r
-    XHDC = 0;\r
-  }\r
-#endif\r
-  XStoreColor(__glutDisplay, cmap->cmap, &color);\r
-}\r
-\r
-GLfloat GLUTAPIENTRY\r
-glutGetColor(int ndx, int comp)\r
-{\r
-  GLUTcolormap *colormap;\r
-  XVisualInfo *vis;\r
-\r
-  if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {\r
-    colormap = __glutCurrentWindow->colormap;\r
-    vis = __glutCurrentWindow->vis;\r
-  } else {\r
-    colormap = __glutCurrentWindow->overlay->colormap;\r
-    vis = __glutCurrentWindow->overlay->vis;\r
-    if (ndx == __glutCurrentWindow->overlay->transparentPixel) {\r
-      __glutWarning("glutGetColor: requesting overlay transparent index %d\n",\r
-        ndx);\r
-      return -1.0;\r
-    }\r
-  }\r
-\r
-  if (!colormap) {\r
-    __glutWarning("glutGetColor: current window is RGBA");\r
-    return -1.0;\r
-  }\r
-#if defined(_WIN32) || defined(__OS2PM__)\r
-#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)\r
-#else\r
-#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)\r
-#endif\r
-  if (OUT_OF_RANGE_NDX(ndx)) {\r
-    __glutWarning("glutGetColor: index %d out of range", ndx);\r
-    return -1.0;\r
-  }\r
-  return colormap->cells[ndx].component[comp];\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutCopyColormap(int winnum)\r
-{\r
-  GLUTwindow *window = __glutWindowList[winnum - 1];\r
-  GLUTcolormap *oldcmap, *newcmap;\r
-  XVisualInfo *dstvis;\r
-\r
-  if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {\r
-    oldcmap = __glutCurrentWindow->colormap;\r
-    dstvis = __glutCurrentWindow->vis;\r
-    newcmap = window->colormap;\r
-  } else {\r
-    oldcmap = __glutCurrentWindow->overlay->colormap;\r
-    dstvis = __glutCurrentWindow->overlay->vis;\r
-    if (!window->overlay) {\r
-      __glutWarning("glutCopyColormap: window %d has no overlay", winnum);\r
-      return;\r
-    }\r
-    newcmap = window->overlay->colormap;\r
-  }\r
-\r
-  if (!oldcmap) {\r
-    __glutWarning("glutCopyColormap: destination colormap must be color index");\r
-    return;\r
-  }\r
-  if (!newcmap) {\r
-    __glutWarning(\r
-      "glutCopyColormap: source colormap of window %d must be color index",\r
-      winnum);\r
-    return;\r
-  }\r
-  if (newcmap == oldcmap) {\r
-    /* Source and destination are the same; now copy needed. */\r
-    return;\r
-  }\r
-#if !defined(_WIN32) && !defined(__OS2PM__)\r
-  /* Play safe: compare visual IDs, not Visual*'s. */\r
-  if (newcmap->visual->visualid == oldcmap->visual->visualid) {\r
-#endif\r
-    /* Visuals match!  "Copy" by reference...  */\r
-    __glutFreeColormap(oldcmap);\r
-    newcmap->refcnt++;\r
-    if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {\r
-      __glutCurrentWindow->colormap = newcmap;\r
-      __glutCurrentWindow->cmap = newcmap->cmap;\r
-    } else {\r
-      __glutCurrentWindow->overlay->colormap = newcmap;\r
-      __glutCurrentWindow->overlay->cmap = newcmap->cmap;\r
-    }\r
-    XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,\r
-      newcmap->cmap);\r
-#if !defined(_WIN32) && !defined(__OS2PM__)\r
-    __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);\r
-bla bla bla\r
-\r
-  } else {\r
-    GLUTcolormap *copycmap;\r
-    XColor color;\r
-    int i, last;\r
-\r
-    /* Visuals different - need a distinct X colormap! */\r
-    copycmap = __glutAssociateNewColormap(dstvis);\r
-    /* Wouldn't it be nice if XCopyColormapAndFree could be\r
-       told not to free the old colormap's entries! */\r
-    last = newcmap->size;\r
-    if (last > copycmap->size) {\r
-      last = copycmap->size;\r
-    }\r
-    for (i = last - 1; i >= 0; i--) {\r
-      if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {\r
-        color.pixel = i;\r
-        copycmap->cells[i].component[GLUT_RED] =\r
-          newcmap->cells[i].component[GLUT_RED];\r
-        color.red = (GLfloat) 0xffff *\r
-          newcmap->cells[i].component[GLUT_RED];\r
-        copycmap->cells[i].component[GLUT_GREEN] =\r
-          newcmap->cells[i].component[GLUT_GREEN];\r
-        color.green = (GLfloat) 0xffff *\r
-          newcmap->cells[i].component[GLUT_GREEN];\r
-        copycmap->cells[i].component[GLUT_BLUE] =\r
-          newcmap->cells[i].component[GLUT_BLUE];\r
-        color.blue = (GLfloat) 0xffff *\r
-          newcmap->cells[i].component[GLUT_BLUE];\r
-        color.flags = DoRed | DoGreen | DoBlue;\r
-        XStoreColor(__glutDisplay, copycmap->cmap, &color);\r
-      }\r
-    }\r
-  }\r
-#endif\r
-}\r
-/* ENDCENTRY */\r
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
+
+/* 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. */
+
+#include <stdlib.h>
+#include "glutint.h"
+
+#if defined(__OS2PM__)
+   #define IsWindowVisible WinIsWindowVisible
+#endif
+
+#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
+
+/* CENTRY */
+void GLUTAPIENTRY
+glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
+{
+  GLUTcolormap *cmap, *newcmap;
+  XVisualInfo *vis;
+  XColor color;
+  int i;
+
+  if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
+    cmap = __glutCurrentWindow->colormap;
+    vis = __glutCurrentWindow->vis;
+  } else {
+    cmap = __glutCurrentWindow->overlay->colormap;
+    vis = __glutCurrentWindow->overlay->vis;
+    if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
+      __glutWarning(
+        "glutSetColor: cannot set color of overlay transparent index %d\n",
+        ndx);
+      return;
+    }
+  }
+
+  if (!cmap) {
+    __glutWarning("glutSetColor: current window is RGBA");
+    return;
+  }
+#if defined(_WIN32) || defined(__OS2PM__)
+  if (ndx >= 256 ||     /* always assume 256 colors on Win32 */
+#else
+  if (ndx >= vis->visual->map_entries ||
+#endif
+    ndx < 0) {
+    __glutWarning("glutSetColor: index %d out of range", ndx);
+    return;
+  }
+  if (cmap->refcnt > 1) {
+    newcmap = __glutAssociateNewColormap(vis);
+    cmap->refcnt--;
+    /* Wouldn't it be nice if XCopyColormapAndFree could be
+       told not to free the old colormap's entries! */
+    for (i = cmap->size - 1; i >= 0; i--) {
+      if (i == ndx) {
+        /* We are going to set this cell shortly! */
+        continue;
+      }
+      if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
+        color.pixel = i;
+        newcmap->cells[i].component[GLUT_RED] =
+          cmap->cells[i].component[GLUT_RED];
+        color.red = (GLfloat) 0xffff *
+          cmap->cells[i].component[GLUT_RED];
+        newcmap->cells[i].component[GLUT_GREEN] =
+          cmap->cells[i].component[GLUT_GREEN];
+        color.green = (GLfloat) 0xffff *
+          cmap->cells[i].component[GLUT_GREEN];
+        newcmap->cells[i].component[GLUT_BLUE] =
+          cmap->cells[i].component[GLUT_BLUE];
+        color.blue = (GLfloat) 0xffff *
+          cmap->cells[i].component[GLUT_BLUE];
+        color.flags = DoRed | DoGreen | DoBlue;
+#if defined(_WIN32) || defined(__OS2PM__)
+        if (IsWindowVisible(__glutCurrentWindow->win)) {
+          XHDC = __glutCurrentWindow->hdc;
+        } else {
+          XHDC = 0;
+        }
+#endif
+        XStoreColor(__glutDisplay, newcmap->cmap, &color);
+      } else {
+        /* Leave unallocated entries unallocated. */
+      }
+    }
+    cmap = newcmap;
+    if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
+      __glutCurrentWindow->colormap = cmap;
+      __glutCurrentWindow->cmap = cmap->cmap;
+    } else {
+      __glutCurrentWindow->overlay->colormap = cmap;
+      __glutCurrentWindow->overlay->cmap = cmap->cmap;
+    }
+    XSetWindowColormap(__glutDisplay,
+      __glutCurrentWindow->renderWin, cmap->cmap);
+
+#if !defined(_WIN32) && !defined(__OS2PM__)
+    {
+      GLUTwindow *toplevel;
+
+      toplevel = __glutToplevelOf(__glutCurrentWindow);
+      if (toplevel->cmap != cmap->cmap) {
+        __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
+      }
+    }
+#endif
+  }
+  color.pixel = ndx;
+  red = CLAMP(red);
+  cmap->cells[ndx].component[GLUT_RED] = red;
+  color.red = (GLfloat) 0xffff *red;
+  green = CLAMP(green);
+  cmap->cells[ndx].component[GLUT_GREEN] = green;
+  color.green = (GLfloat) 0xffff *green;
+  blue = CLAMP(blue);
+  cmap->cells[ndx].component[GLUT_BLUE] = blue;
+  color.blue = (GLfloat) 0xffff *blue;
+  color.flags = DoRed | DoGreen | DoBlue;
+#if defined(_WIN32) || defined(__OS2PM__)
+  if (IsWindowVisible(__glutCurrentWindow->win)) {
+    XHDC = __glutCurrentWindow->hdc;
+  } else {
+    XHDC = 0;
+  }
+#endif
+  XStoreColor(__glutDisplay, cmap->cmap, &color);
+}
+
+GLfloat GLUTAPIENTRY
+glutGetColor(int ndx, int comp)
+{
+  GLUTcolormap *colormap;
+  XVisualInfo *vis;
+
+  if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
+    colormap = __glutCurrentWindow->colormap;
+    vis = __glutCurrentWindow->vis;
+  } else {
+    colormap = __glutCurrentWindow->overlay->colormap;
+    vis = __glutCurrentWindow->overlay->vis;
+    if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
+      __glutWarning("glutGetColor: requesting overlay transparent index %d\n",
+        ndx);
+      return -1.0;
+    }
+  }
+
+  if (!colormap) {
+    __glutWarning("glutGetColor: current window is RGBA");
+    return -1.0;
+  }
+#if defined(_WIN32) || defined(__OS2PM__)
+#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)
+#else
+#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)
+#endif
+  if (OUT_OF_RANGE_NDX(ndx)) {
+    __glutWarning("glutGetColor: index %d out of range", ndx);
+    return -1.0;
+  }
+  return colormap->cells[ndx].component[comp];
+}
+
+void GLUTAPIENTRY
+glutCopyColormap(int winnum)
+{
+  GLUTwindow *window = __glutWindowList[winnum - 1];
+  GLUTcolormap *oldcmap, *newcmap;
+  XVisualInfo *dstvis;
+
+  if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
+    oldcmap = __glutCurrentWindow->colormap;
+    dstvis = __glutCurrentWindow->vis;
+    newcmap = window->colormap;
+  } else {
+    oldcmap = __glutCurrentWindow->overlay->colormap;
+    dstvis = __glutCurrentWindow->overlay->vis;
+    if (!window->overlay) {
+      __glutWarning("glutCopyColormap: window %d has no overlay", winnum);
+      return;
+    }
+    newcmap = window->overlay->colormap;
+  }
+
+  if (!oldcmap) {
+    __glutWarning("glutCopyColormap: destination colormap must be color index");
+    return;
+  }
+  if (!newcmap) {
+    __glutWarning(
+      "glutCopyColormap: source colormap of window %d must be color index",
+      winnum);
+    return;
+  }
+  if (newcmap == oldcmap) {
+    /* Source and destination are the same; now copy needed. */
+    return;
+  }
+#if !defined(_WIN32) && !defined(__OS2PM__)
+  /* Play safe: compare visual IDs, not Visual*'s. */
+  if (newcmap->visual->visualid == oldcmap->visual->visualid) {
+#endif
+    /* Visuals match!  "Copy" by reference...  */
+    __glutFreeColormap(oldcmap);
+    newcmap->refcnt++;
+    if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
+      __glutCurrentWindow->colormap = newcmap;
+      __glutCurrentWindow->cmap = newcmap->cmap;
+    } else {
+      __glutCurrentWindow->overlay->colormap = newcmap;
+      __glutCurrentWindow->overlay->cmap = newcmap->cmap;
+    }
+    XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
+      newcmap->cmap);
+#if !defined(_WIN32) && !defined(__OS2PM__)
+    __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
+bla bla bla
+
+  } else {
+    GLUTcolormap *copycmap;
+    XColor color;
+    int i, last;
+
+    /* Visuals different - need a distinct X colormap! */
+    copycmap = __glutAssociateNewColormap(dstvis);
+    /* Wouldn't it be nice if XCopyColormapAndFree could be
+       told not to free the old colormap's entries! */
+    last = newcmap->size;
+    if (last > copycmap->size) {
+      last = copycmap->size;
+    }
+    for (i = last - 1; i >= 0; i--) {
+      if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
+        color.pixel = i;
+        copycmap->cells[i].component[GLUT_RED] =
+          newcmap->cells[i].component[GLUT_RED];
+        color.red = (GLfloat) 0xffff *
+          newcmap->cells[i].component[GLUT_RED];
+        copycmap->cells[i].component[GLUT_GREEN] =
+          newcmap->cells[i].component[GLUT_GREEN];
+        color.green = (GLfloat) 0xffff *
+          newcmap->cells[i].component[GLUT_GREEN];
+        copycmap->cells[i].component[GLUT_BLUE] =
+          newcmap->cells[i].component[GLUT_BLUE];
+        color.blue = (GLfloat) 0xffff *
+          newcmap->cells[i].component[GLUT_BLUE];
+        color.flags = DoRed | DoGreen | DoBlue;
+        XStoreColor(__glutDisplay, copycmap->cmap, &color);
+      }
+    }
+  }
+#endif
+}
+/* ENDCENTRY */
 \1a
\ No newline at end of file
index 50185d7b9d48f36ab14b1bab533d26f4d0ff1589..39918fdf39b36cb53f3b477f2b4517c9ebb2e80f 100644 (file)
-\r
-/* Copyright (c) Mark J. Kilgard, 1998. */\r
-\r
-/* This program is freely distributable without licensing fees\r
-   and is provided without guarantee or warrantee expressed or\r
-   implied. This program is -not- in the public domain. */\r
-\r
-\r
-#include <assert.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include "glutint.h"\r
-\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-#include <X11/Xlib.h>\r
-#include <X11/Xatom.h>\r
-\r
-/* SGI optimization introduced in IRIX 6.3 to avoid X server\r
-   round trips for interning common X atoms. */\r
-#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)\r
-#include <X11/SGIFastAtom.h>\r
-#else\r
-#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)\r
-#endif\r
-#endif  /* not _WIN32 */\r
-\r
-int __glutDisplaySettingsChanged = 0;\r
-static DisplayMode *dmodes, *currentDm = NULL;\r
-static int ndmodes = -1;\r
-GLUTwindow *__glutGameModeWindow = NULL;\r
-\r
-#ifdef TEST\r
-static char *compstr[] =\r
-{\r
-  "none", "=", "!=", "<=", ">=", ">", "<", "~"\r
-};\r
-static char *capstr[] =\r
-{\r
-  "width", "height", "bpp", "hertz", "num"\r
-};\r
-#endif\r
-\r
-#if defined(__OS2__)\r
-void\r
-#else\r
-void __cdecl\r
-#endif\r
-__glutCloseDownGameMode(void)\r
-{\r
-  if (__glutDisplaySettingsChanged) {\r
-#ifdef _WIN32\r
-    /* Assumes that display settings have been changed, that\r
-       is __glutDisplaySettingsChanged is true. */\r
-    ChangeDisplaySettings(NULL, 0);\r
-#endif\r
-    __glutDisplaySettingsChanged = 0;\r
-  }\r
-  __glutGameModeWindow = NULL;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutLeaveGameMode(void)\r
-{\r
-  if (__glutGameModeWindow == NULL) {\r
-    __glutWarning("not in game mode so cannot leave game mode");\r
-    return;\r
-  }\r
-  __glutDestroyWindow(__glutGameModeWindow,\r
-    __glutGameModeWindow);\r
-  XFlush(__glutDisplay);\r
-  __glutGameModeWindow = NULL;\r
-}\r
-\r
-#ifdef _WIN32\r
-\r
-/* Same values as from MSDN's SetDisp.c example. */\r
-#define MIN_WIDTH 400\r
-#define MIN_FREQUENCY 60\r
-\r
-static void\r
-initGameModeSupport(void)\r
-{\r
-  DEVMODE dm;\r
-  DWORD mode;\r
-  int i;\r
-\r
-  if (ndmodes >= 0) {\r
-    /* ndmodes is initially -1 to indicate no\r
-       dmodes allocated yet. */\r
-    return;\r
-  }\r
-\r
-  /* Determine how many display modes there are. */\r
-  ndmodes = 0;\r
-  mode = 0;\r
-  while (EnumDisplaySettings(NULL, mode, &dm)) {\r
-    if (dm.dmPelsWidth >= MIN_WIDTH &&\r
-      (dm.dmDisplayFrequency == 0 ||\r
-      dm.dmDisplayFrequency >= MIN_FREQUENCY)) {\r
-      ndmodes++;\r
-    }\r
-    mode++;\r
-  }\r
-\r
-  /* Allocate memory for a list of all the display modes. */\r
-  dmodes = (DisplayMode*)\r
-    malloc(ndmodes * sizeof(DisplayMode));\r
-\r
-  /* Now that we know how many display modes to expect,\r
-     enumerate them again and save the information in\r
-     the list we allocated above. */\r
-  i = 0;\r
-  mode = 0;\r
-  while (EnumDisplaySettings(NULL, mode, &dm)) {\r
-    /* Try to reject any display settings that seem unplausible. */\r
-    if (dm.dmPelsWidth >= MIN_WIDTH &&\r
-      (dm.dmDisplayFrequency == 0 ||\r
-      dm.dmDisplayFrequency >= MIN_FREQUENCY)) {\r
-      dmodes[i].devmode = dm;\r
-      dmodes[i].valid = 1;  /* XXX Not used for now. */\r
-      dmodes[i].cap[DM_WIDTH] = dm.dmPelsWidth;\r
-      dmodes[i].cap[DM_HEIGHT] = dm.dmPelsHeight;\r
-      dmodes[i].cap[DM_PIXEL_DEPTH] = dm.dmBitsPerPel;\r
-      if (dm.dmDisplayFrequency == 0) {\r
-       /* Guess a reasonable guess. */\r
-       /* Lame Windows 95 version of EnumDisplaySettings. */\r
-        dmodes[i].cap[DM_HERTZ] = 60;\r
-      } else {\r
-       dmodes[i].cap[DM_HERTZ] = dm.dmDisplayFrequency;\r
-      }\r
-      i++;\r
-    }\r
-    mode++;\r
-  }\r
-\r
-  assert(i == ndmodes);\r
-}\r
-\r
-#else\r
-\r
-/* X Windows version of initGameModeSupport. */\r
-static void\r
-initGameModeSupport(void)\r
-{\r
-  if (ndmodes >= 0) {\r
-    /* ndmodes is initially -1 to indicate no\r
-       dmodes allocated yet. */\r
-    return;\r
-  }\r
-\r
-  /* Determine how many display modes there are. */\r
-  ndmodes = 0;\r
-}\r
-\r
-#endif\r
-\r
-/* This routine is based on similiar code in glut_dstr.c */\r
-static DisplayMode *\r
-findMatch(DisplayMode * dmodes, int ndmodes,\r
-  Criterion * criteria, int ncriteria)\r
-{\r
-  DisplayMode *found;\r
-  int *bestScore, *thisScore;\r
-  int i, j, numok, result = 0, worse, better;\r
-\r
-  found = NULL;\r
-  numok = 1;            /* "num" capability is indexed from 1,\r
-                           not 0. */\r
-\r
-  /* XXX alloca canidate. */\r
-  bestScore = (int *) malloc(ncriteria * sizeof(int));\r
-  if (!bestScore) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  for (j = 0; j < ncriteria; j++) {\r
-    /* Very negative number. */\r
-    bestScore[j] = -32768;\r
-  }\r
-\r
-  /* XXX alloca canidate. */\r
-  thisScore = (int *) malloc(ncriteria * sizeof(int));\r
-  if (!thisScore) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-\r
-  for (i = 0; i < ndmodes; i++) {\r
-    if (dmodes[i].valid) {\r
-      worse = 0;\r
-      better = 0;\r
-\r
-      for (j = 0; j < ncriteria; j++) {\r
-        int cap, cvalue, dvalue;\r
-\r
-        cap = criteria[j].capability;\r
-        cvalue = criteria[j].value;\r
-        if (cap == NUM) {\r
-          dvalue = numok;\r
-        } else {\r
-          dvalue = dmodes[i].cap[cap];\r
-        }\r
-#ifdef TEST\r
-        if (verbose)\r
-          printf("  %s %s %d to %d\n",\r
-            capstr[cap], compstr[criteria[j].comparison], cvalue, dvalue);\r
-#endif\r
-        switch (criteria[j].comparison) {\r
-        case EQ:\r
-          result = cvalue == dvalue;\r
-          thisScore[j] = 1;\r
-          break;\r
-        case NEQ:\r
-          result = cvalue != dvalue;\r
-          thisScore[j] = 1;\r
-          break;\r
-        case LT:\r
-          result = dvalue < cvalue;\r
-          thisScore[j] = dvalue - cvalue;\r
-          break;\r
-        case GT:\r
-          result = dvalue > cvalue;\r
-          thisScore[j] = dvalue - cvalue;\r
-          break;\r
-        case LTE:\r
-          result = dvalue <= cvalue;\r
-          thisScore[j] = dvalue - cvalue;\r
-          break;\r
-        case GTE:\r
-          result = (dvalue >= cvalue);\r
-          thisScore[j] = dvalue - cvalue;\r
-          break;\r
-        case MIN:\r
-          result = dvalue >= cvalue;\r
-          thisScore[j] = cvalue - dvalue;\r
-          break;\r
-        }\r
-\r
-#ifdef TEST\r
-        if (verbose)\r
-          printf("                result=%d   score=%d   bestScore=%d\n", result, thisScore[j], bestScore[j]);\r
-#endif\r
-\r
-        if (result) {\r
-          if (better || thisScore[j] > bestScore[j]) {\r
-            better = 1;\r
-          } else if (thisScore[j] == bestScore[j]) {\r
-            /* Keep looking. */\r
-          } else {\r
-            goto nextDM;\r
-          }\r
-        } else {\r
-          if (cap == NUM) {\r
-            worse = 1;\r
-          } else {\r
-            goto nextDM;\r
-          }\r
-        }\r
-\r
-      }\r
-\r
-      if (better && !worse) {\r
-        found = &dmodes[i];\r
-        for (j = 0; j < ncriteria; j++) {\r
-          bestScore[j] = thisScore[j];\r
-        }\r
-      }\r
-      numok++;\r
-\r
-    nextDM:;\r
-\r
-    }\r
-  }\r
-  free(bestScore);\r
-  free(thisScore);\r
-  return found;\r
-}\r
-\r
-/**\r
- * Parses strings in the form of:\r
- *  800x600\r
- *  800x600:16\r
- *  800x600@60\r
- *  800x600:16@60\r
- *  @60\r
- *  :16\r
- *  :16@60\r
- * NOTE that @ before : is not parsed.\r
- */\r
-static int\r
-specialCaseParse(char *word, Criterion * criterion, int mask)\r
-{\r
-  char *xstr, *response;\r
-  int got;\r
-  int width, height, bpp, hertz;\r
-\r
-  switch(word[0]) {\r
-  case '0':\r
-  case '1':\r
-  case '2':\r
-  case '3':\r
-  case '4':\r
-  case '5':\r
-  case '6':\r
-  case '7':\r
-  case '8':\r
-  case '9':\r
-    /* The WWWxHHH case. */\r
-    if (mask & (1 << DM_WIDTH)) {\r
-      return -1;\r
-    }\r
-    xstr = strpbrk(&word[1], "x");\r
-    if (xstr) {\r
-      width = (int) strtol(word, &response, 0);\r
-      if (response == word || response[0] != 'x') {\r
-        /* Not a valid number OR needs to be followed by 'x'. */\r
-       return -1;\r
-      }\r
-      height = (int) strtol(&xstr[1], &response, 0);\r
-      if (response == &xstr[1]) {\r
-        /* Not a valid number. */\r
-       return -1;\r
-      }\r
-      criterion[0].capability = DM_WIDTH;\r
-      criterion[0].comparison = EQ;\r
-      criterion[0].value = width;\r
-      criterion[1].capability = DM_HEIGHT;\r
-      criterion[1].comparison = EQ;\r
-      criterion[1].value = height;\r
-      got = specialCaseParse(response,\r
-        &criterion[2], 1 << DM_WIDTH);\r
-      if (got >= 0) {\r
-        return got + 2;\r
-      } else {\r
-        return -1;\r
-      }\r
-    }\r
-    return -1;\r
-  case ':':\r
-    /* The :BPP case. */\r
-    if (mask & (1 << DM_PIXEL_DEPTH)) {\r
-      return -1;\r
-    }\r
-    bpp = (int) strtol(&word[1], &response, 0);\r
-    if (response == &word[1]) {\r
-      /* Not a valid number. */\r
-      return -1;\r
-    }\r
-    criterion[0].capability = DM_PIXEL_DEPTH;\r
-    criterion[0].comparison = EQ;\r
-    criterion[0].value = bpp;\r
-    got = specialCaseParse(response,\r
-      &criterion[1], (1 << DM_WIDTH) | (1 << DM_PIXEL_DEPTH));\r
-    if (got >= 0) {\r
-      return got + 1;\r
-    } else {\r
-      return -1;\r
-    }\r
-  case '@':\r
-    /* The @HZ case. */\r
-    if (mask & (1 << DM_HERTZ)) {\r
-      return -1;\r
-    }\r
-    hertz = (int) strtol(&word[1], &response, 0);\r
-    if (response == &word[1]) {\r
-      /* Not a valid number. */\r
-      return -1;\r
-    }\r
-    criterion[0].capability = DM_HERTZ;\r
-    criterion[0].comparison = EQ;\r
-    criterion[0].value = hertz;\r
-    got = specialCaseParse(response,\r
-      &criterion[1], ~DM_HERTZ);\r
-    if (got >= 0) {\r
-      return got + 1;\r
-    } else {\r
-      return -1;\r
-    }\r
-  case '\0':\r
-    return 0;\r
-  }\r
-  return -1;\r
-}\r
-\r
-/* This routine is based on similiar code in glut_dstr.c */\r
-static int\r
-parseCriteria(char *word, Criterion * criterion)\r
-{\r
-  char *cstr, *vstr, *response;\r
-  int comparator, value = 0;\r
-\r
-  cstr = strpbrk(word, "=><!~");\r
-  if (cstr) {\r
-    switch (cstr[0]) {\r
-    case '=':\r
-      comparator = EQ;\r
-      vstr = &cstr[1];\r
-      break;\r
-    case '~':\r
-      comparator = MIN;\r
-      vstr = &cstr[1];\r
-      break;\r
-    case '>':\r
-      if (cstr[1] == '=') {\r
-        comparator = GTE;\r
-        vstr = &cstr[2];\r
-      } else {\r
-        comparator = GT;\r
-        vstr = &cstr[1];\r
-      }\r
-      break;\r
-    case '<':\r
-      if (cstr[1] == '=') {\r
-        comparator = LTE;\r
-        vstr = &cstr[2];\r
-      } else {\r
-        comparator = LT;\r
-        vstr = &cstr[1];\r
-      }\r
-      break;\r
-    case '!':\r
-      if (cstr[1] == '=') {\r
-        comparator = NEQ;\r
-        vstr = &cstr[2];\r
-      } else {\r
-        return -1;\r
-      }\r
-      break;\r
-    default:\r
-      return -1;\r
-    }\r
-    value = (int) strtol(vstr, &response, 0);\r
-    if (response == vstr) {\r
-      /* Not a valid number. */\r
-      return -1;\r
-    }\r
-    *cstr = '\0';\r
-  } else {\r
-    comparator = NONE;\r
-  }\r
-  switch (word[0]) {\r
-  case 'b':\r
-    if (!strcmp(word, "bpp")) {\r
-      criterion[0].capability = DM_PIXEL_DEPTH;\r
-      if (comparator == NONE) {\r
-        return -1;\r
-      } else {\r
-        criterion[0].comparison = comparator;\r
-        criterion[0].value = value;\r
-        return 1;\r
-      }\r
-    }\r
-    return -1;\r
-  case 'h':\r
-    if (!strcmp(word, "height")) {\r
-      criterion[0].capability = DM_HEIGHT;\r
-      if (comparator == NONE) {\r
-        return -1;\r
-      } else {\r
-        criterion[0].comparison = comparator;\r
-        criterion[0].value = value;\r
-        return 1;\r
-      }\r
-    }\r
-    if (!strcmp(word, "hertz")) {\r
-      criterion[0].capability = DM_HERTZ;\r
-      if (comparator == NONE) {\r
-        return -1;\r
-      } else {\r
-        criterion[0].comparison = comparator;\r
-        criterion[0].value = value;\r
-        return 1;\r
-      }\r
-    }\r
-    return -1;\r
-  case 'n':\r
-    if (!strcmp(word, "num")) {\r
-      criterion[0].capability = DM_NUM;\r
-      if (comparator == NONE) {\r
-        return -1;\r
-      } else {\r
-        criterion[0].comparison = comparator;\r
-        criterion[0].value = value;\r
-        return 1;\r
-      }\r
-    }\r
-    return -1;\r
-  case 'w':\r
-    if (!strcmp(word, "width")) {\r
-      criterion[0].capability = DM_WIDTH;\r
-      if (comparator == NONE) {\r
-        return -1;\r
-      } else {\r
-        criterion[0].comparison = comparator;\r
-        criterion[0].value = value;\r
-        return 1;\r
-      }\r
-    }\r
-    return -1;\r
-  }\r
-  if (comparator == NONE) {\r
-    return specialCaseParse(word, criterion, 0);\r
-  }\r
-  return -1;\r
-}\r
-\r
-/* This routine is based on similiar code in glut_dstr.c */\r
-static Criterion *\r
-parseDisplayString(const char *display, int *ncriteria)\r
-{\r
-  Criterion *criteria = NULL;\r
-  int n, parsed;\r
-  char *copy, *word;\r
-\r
-  copy = __glutStrdup(display);\r
-  /* Attempt to estimate how many criteria entries should be\r
-     needed. */\r
-  n = 0;\r
-  word = strtok(copy, " \t");\r
-  while (word) {\r
-    n++;\r
-    word = strtok(NULL, " \t");\r
-  }\r
-  /* Allocate number of words of criteria.  A word\r
-     could contain as many as four criteria in the\r
-     worst case.  Example: 800x600:16@60 */\r
-  criteria = (Criterion *) malloc(4 * n * sizeof(Criterion));\r
-  if (!criteria) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-\r
-  /* Re-copy the copy of the display string. */\r
-  strcpy(copy, display);\r
-\r
-  n = 0;\r
-  word = strtok(copy, " \t");\r
-  while (word) {\r
-    parsed = parseCriteria(word, &criteria[n]);\r
-    if (parsed >= 0) {\r
-      n += parsed;\r
-    } else {\r
-      __glutWarning("Unrecognized game mode string word: %s (ignoring)\n", word);\r
-    }\r
-    word = strtok(NULL, " \t");\r
-  }\r
-\r
-  free(copy);\r
-  *ncriteria = n;\r
-  return criteria;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutGameModeString(const char *string)\r
-{\r
-  Criterion *criteria;\r
-  int ncriteria;\r
-\r
-  initGameModeSupport();\r
-  criteria = parseDisplayString(string, &ncriteria);\r
-  currentDm = findMatch(dmodes, ndmodes, criteria, ncriteria);\r
-  free(criteria);\r
-}\r
-\r
-int GLUTAPIENTRY\r
-glutEnterGameMode(void)\r
-{\r
-  GLUTwindow *window;\r
-  int width, height;\r
-  Window win;\r
-\r
-  if (__glutMappedMenu) {\r
-    __glutFatalUsage("entering game mode not allowed while menus in use");\r
-  }\r
-  if (__glutGameModeWindow) {\r
-    /* Already in game mode, so blow away game mode\r
-       window so apps can change resolutions. */\r
-    window = __glutGameModeWindow;\r
-    /* Setting the game mode window to NULL tricks\r
-       the window destroy code into not undoing the\r
-       screen display change since we plan on immediately\r
-       doing another mode change. */\r
-    __glutGameModeWindow = NULL;\r
-    __glutDestroyWindow(window, window);\r
-  }\r
-\r
-  /* Assume default screen size until we find out if we\r
-     can actually change the display settings. */\r
-  width = __glutScreenWidth;\r
-  height = __glutScreenHeight;\r
-\r
-  if (currentDm) {\r
-#ifdef _WIN32\r
-    LONG status;\r
-    static int registered = 0;\r
-\r
-    status = ChangeDisplaySettings(&currentDm->devmode,\r
-      CDS_FULLSCREEN);\r
-    if (status == DISP_CHANGE_SUCCESSFUL) {\r
-      __glutDisplaySettingsChanged = 1;\r
-      width = currentDm->cap[DM_WIDTH];\r
-      height = currentDm->cap[DM_HEIGHT];\r
-      if (!registered) {\r
-        atexit(__glutCloseDownGameMode);\r
-        registered = 1;\r
-      }\r
-    } else {\r
-      /* Switch back to default resolution. */\r
-      ChangeDisplaySettings(NULL, 0);\r
-    }\r
-#endif\r
-  }\r
-\r
-  window = __glutCreateWindow(NULL, 0, 0,\r
-    width, height, /* game mode */ 1);\r
-  win = window->win;\r
-\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-  if (__glutMotifHints == None) {\r
-    __glutMotifHints = XSGIFastInternAtom(__glutDisplay, "_MOTIF_WM_HINTS",\r
-      SGI_XA__MOTIF_WM_HINTS, 0);\r
-    if (__glutMotifHints == None) {\r
-      __glutWarning("Could not intern X atom for _MOTIF_WM_HINTS.");\r
-    }\r
-  }\r
-\r
-  /* Game mode window is a toplevel window. */\r
-  XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);\r
-#endif\r
-\r
-  /* Schedule the fullscreen property to be added and to\r
-     make sure the window is configured right.  Win32\r
-     doesn't need this. */\r
-  window->desiredX = 0;\r
-  window->desiredY = 0;\r
-  window->desiredWidth = width;\r
-  window->desiredHeight = height;\r
-  window->desiredConfMask |= CWX | CWY | CWWidth | CWHeight;\r
-#ifdef _WIN32\r
-  /* Win32 does not want to use GLUT_FULL_SCREEN_WORK\r
-     for game mode because we need to be maximizing\r
-     the window in game mode, not just sizing it to\r
-     take up the full screen.  The Win32-ness of game\r
-     mode happens when you pass 1 in the gameMode parameter\r
-     to __glutCreateWindow above.  A gameMode of creates\r
-     a WS_POPUP window, not a standard WS_OVERLAPPEDWINDOW\r
-     window.  WS_POPUP ensures the taskbar is hidden. */\r
-  __glutPutOnWorkList(window,\r
-    GLUT_CONFIGURE_WORK);\r
-#else\r
-  __glutPutOnWorkList(window,\r
-    GLUT_CONFIGURE_WORK | GLUT_FULL_SCREEN_WORK);\r
-#endif\r
-\r
-  __glutGameModeWindow = window;\r
-  return window->num + 1;\r
-}\r
-\r
-int GLUTAPIENTRY\r
-glutGameModeGet(GLenum mode)\r
-{\r
-  switch (mode) {\r
-  case GLUT_GAME_MODE_ACTIVE:\r
-    return __glutGameModeWindow != NULL;\r
-  case GLUT_GAME_MODE_POSSIBLE:\r
-    return currentDm != NULL;\r
-  case GLUT_GAME_MODE_WIDTH:\r
-    return currentDm ? currentDm->cap[DM_WIDTH] : -1;\r
-  case GLUT_GAME_MODE_HEIGHT:\r
-    return currentDm ? currentDm->cap[DM_HEIGHT] : -1;\r
-  case GLUT_GAME_MODE_PIXEL_DEPTH:\r
-    return currentDm ? currentDm->cap[DM_PIXEL_DEPTH] : -1;\r
-  case GLUT_GAME_MODE_REFRESH_RATE:\r
-    return currentDm ? currentDm->cap[DM_HERTZ] : -1;\r
-  case GLUT_GAME_MODE_DISPLAY_CHANGED:\r
-    return __glutDisplaySettingsChanged;\r
-  default:\r
-    return -1;\r
-  }\r
-}\r
+
+/* Copyright (c) Mark J. Kilgard, 1998. */
+
+/* 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. */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "glutint.h"
+
+#if !defined(_WIN32) && !defined(__OS2__)
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+/* SGI optimization introduced in IRIX 6.3 to avoid X server
+   round trips for interning common X atoms. */
+#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
+#include <X11/SGIFastAtom.h>
+#else
+#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
+#endif
+#endif  /* not _WIN32 */
+
+int __glutDisplaySettingsChanged = 0;
+static DisplayMode *dmodes, *currentDm = NULL;
+static int ndmodes = -1;
+GLUTwindow *__glutGameModeWindow = NULL;
+
+#ifdef TEST
+static char *compstr[] =
+{
+  "none", "=", "!=", "<=", ">=", ">", "<", "~"
+};
+static char *capstr[] =
+{
+  "width", "height", "bpp", "hertz", "num"
+};
+#endif
+
+#if defined(__OS2__)
+void
+#else
+void __cdecl
+#endif
+__glutCloseDownGameMode(void)
+{
+  if (__glutDisplaySettingsChanged) {
+#ifdef _WIN32
+    /* Assumes that display settings have been changed, that
+       is __glutDisplaySettingsChanged is true. */
+    ChangeDisplaySettings(NULL, 0);
+#endif
+    __glutDisplaySettingsChanged = 0;
+  }
+  __glutGameModeWindow = NULL;
+}
+
+void GLUTAPIENTRY
+glutLeaveGameMode(void)
+{
+  if (__glutGameModeWindow == NULL) {
+    __glutWarning("not in game mode so cannot leave game mode");
+    return;
+  }
+  __glutDestroyWindow(__glutGameModeWindow,
+    __glutGameModeWindow);
+  XFlush(__glutDisplay);
+  __glutGameModeWindow = NULL;
+}
+
+#ifdef _WIN32
+
+/* Same values as from MSDN's SetDisp.c example. */
+#define MIN_WIDTH 400
+#define MIN_FREQUENCY 60
+
+static void
+initGameModeSupport(void)
+{
+  DEVMODE dm;
+  DWORD mode;
+  int i;
+
+  if (ndmodes >= 0) {
+    /* ndmodes is initially -1 to indicate no
+       dmodes allocated yet. */
+    return;
+  }
+
+  /* Determine how many display modes there are. */
+  ndmodes = 0;
+  mode = 0;
+  while (EnumDisplaySettings(NULL, mode, &dm)) {
+    if (dm.dmPelsWidth >= MIN_WIDTH &&
+      (dm.dmDisplayFrequency == 0 ||
+      dm.dmDisplayFrequency >= MIN_FREQUENCY)) {
+      ndmodes++;
+    }
+    mode++;
+  }
+
+  /* Allocate memory for a list of all the display modes. */
+  dmodes = (DisplayMode*)
+    malloc(ndmodes * sizeof(DisplayMode));
+
+  /* Now that we know how many display modes to expect,
+     enumerate them again and save the information in
+     the list we allocated above. */
+  i = 0;
+  mode = 0;
+  while (EnumDisplaySettings(NULL, mode, &dm)) {
+    /* Try to reject any display settings that seem unplausible. */
+    if (dm.dmPelsWidth >= MIN_WIDTH &&
+      (dm.dmDisplayFrequency == 0 ||
+      dm.dmDisplayFrequency >= MIN_FREQUENCY)) {
+      dmodes[i].devmode = dm;
+      dmodes[i].valid = 1;  /* XXX Not used for now. */
+      dmodes[i].cap[DM_WIDTH] = dm.dmPelsWidth;
+      dmodes[i].cap[DM_HEIGHT] = dm.dmPelsHeight;
+      dmodes[i].cap[DM_PIXEL_DEPTH] = dm.dmBitsPerPel;
+      if (dm.dmDisplayFrequency == 0) {
+       /* Guess a reasonable guess. */
+       /* Lame Windows 95 version of EnumDisplaySettings. */
+        dmodes[i].cap[DM_HERTZ] = 60;
+      } else {
+       dmodes[i].cap[DM_HERTZ] = dm.dmDisplayFrequency;
+      }
+      i++;
+    }
+    mode++;
+  }
+
+  assert(i == ndmodes);
+}
+
+#else
+
+/* X Windows version of initGameModeSupport. */
+static void
+initGameModeSupport(void)
+{
+  if (ndmodes >= 0) {
+    /* ndmodes is initially -1 to indicate no
+       dmodes allocated yet. */
+    return;
+  }
+
+  /* Determine how many display modes there are. */
+  ndmodes = 0;
+}
+
+#endif
+
+/* This routine is based on similiar code in glut_dstr.c */
+static DisplayMode *
+findMatch(DisplayMode * dmodes, int ndmodes,
+  Criterion * criteria, int ncriteria)
+{
+  DisplayMode *found;
+  int *bestScore, *thisScore;
+  int i, j, numok, result = 0, worse, better;
+
+  found = NULL;
+  numok = 1;            /* "num" capability is indexed from 1,
+                           not 0. */
+
+  /* XXX alloca canidate. */
+  bestScore = (int *) malloc(ncriteria * sizeof(int));
+  if (!bestScore) {
+    __glutFatalError("out of memory.");
+  }
+  for (j = 0; j < ncriteria; j++) {
+    /* Very negative number. */
+    bestScore[j] = -32768;
+  }
+
+  /* XXX alloca canidate. */
+  thisScore = (int *) malloc(ncriteria * sizeof(int));
+  if (!thisScore) {
+    __glutFatalError("out of memory.");
+  }
+
+  for (i = 0; i < ndmodes; i++) {
+    if (dmodes[i].valid) {
+      worse = 0;
+      better = 0;
+
+      for (j = 0; j < ncriteria; j++) {
+        int cap, cvalue, dvalue;
+
+        cap = criteria[j].capability;
+        cvalue = criteria[j].value;
+        if (cap == NUM) {
+          dvalue = numok;
+        } else {
+          dvalue = dmodes[i].cap[cap];
+        }
+#ifdef TEST
+        if (verbose)
+          printf("  %s %s %d to %d\n",
+            capstr[cap], compstr[criteria[j].comparison], cvalue, dvalue);
+#endif
+        switch (criteria[j].comparison) {
+        case EQ:
+          result = cvalue == dvalue;
+          thisScore[j] = 1;
+          break;
+        case NEQ:
+          result = cvalue != dvalue;
+          thisScore[j] = 1;
+          break;
+        case LT:
+          result = dvalue < cvalue;
+          thisScore[j] = dvalue - cvalue;
+          break;
+        case GT:
+          result = dvalue > cvalue;
+          thisScore[j] = dvalue - cvalue;
+          break;
+        case LTE:
+          result = dvalue <= cvalue;
+          thisScore[j] = dvalue - cvalue;
+          break;
+        case GTE:
+          result = (dvalue >= cvalue);
+          thisScore[j] = dvalue - cvalue;
+          break;
+        case MIN:
+          result = dvalue >= cvalue;
+          thisScore[j] = cvalue - dvalue;
+          break;
+        }
+
+#ifdef TEST
+        if (verbose)
+          printf("                result=%d   score=%d   bestScore=%d\n", result, thisScore[j], bestScore[j]);
+#endif
+
+        if (result) {
+          if (better || thisScore[j] > bestScore[j]) {
+            better = 1;
+          } else if (thisScore[j] == bestScore[j]) {
+            /* Keep looking. */
+          } else {
+            goto nextDM;
+          }
+        } else {
+          if (cap == NUM) {
+            worse = 1;
+          } else {
+            goto nextDM;
+          }
+        }
+
+      }
+
+      if (better && !worse) {
+        found = &dmodes[i];
+        for (j = 0; j < ncriteria; j++) {
+          bestScore[j] = thisScore[j];
+        }
+      }
+      numok++;
+
+    nextDM:;
+
+    }
+  }
+  free(bestScore);
+  free(thisScore);
+  return found;
+}
+
+/**
+ * Parses strings in the form of:
+ *  800x600
+ *  800x600:16
+ *  800x600@60
+ *  800x600:16@60
+ *  @60
+ *  :16
+ *  :16@60
+ * NOTE that @ before : is not parsed.
+ */
+static int
+specialCaseParse(char *word, Criterion * criterion, int mask)
+{
+  char *xstr, *response;
+  int got;
+  int width, height, bpp, hertz;
+
+  switch(word[0]) {
+  case '0':
+  case '1':
+  case '2':
+  case '3':
+  case '4':
+  case '5':
+  case '6':
+  case '7':
+  case '8':
+  case '9':
+    /* The WWWxHHH case. */
+    if (mask & (1 << DM_WIDTH)) {
+      return -1;
+    }
+    xstr = strpbrk(&word[1], "x");
+    if (xstr) {
+      width = (int) strtol(word, &response, 0);
+      if (response == word || response[0] != 'x') {
+        /* Not a valid number OR needs to be followed by 'x'. */
+       return -1;
+      }
+      height = (int) strtol(&xstr[1], &response, 0);
+      if (response == &xstr[1]) {
+        /* Not a valid number. */
+       return -1;
+      }
+      criterion[0].capability = DM_WIDTH;
+      criterion[0].comparison = EQ;
+      criterion[0].value = width;
+      criterion[1].capability = DM_HEIGHT;
+      criterion[1].comparison = EQ;
+      criterion[1].value = height;
+      got = specialCaseParse(response,
+        &criterion[2], 1 << DM_WIDTH);
+      if (got >= 0) {
+        return got + 2;
+      } else {
+        return -1;
+      }
+    }
+    return -1;
+  case ':':
+    /* The :BPP case. */
+    if (mask & (1 << DM_PIXEL_DEPTH)) {
+      return -1;
+    }
+    bpp = (int) strtol(&word[1], &response, 0);
+    if (response == &word[1]) {
+      /* Not a valid number. */
+      return -1;
+    }
+    criterion[0].capability = DM_PIXEL_DEPTH;
+    criterion[0].comparison = EQ;
+    criterion[0].value = bpp;
+    got = specialCaseParse(response,
+      &criterion[1], (1 << DM_WIDTH) | (1 << DM_PIXEL_DEPTH));
+    if (got >= 0) {
+      return got + 1;
+    } else {
+      return -1;
+    }
+  case '@':
+    /* The @HZ case. */
+    if (mask & (1 << DM_HERTZ)) {
+      return -1;
+    }
+    hertz = (int) strtol(&word[1], &response, 0);
+    if (response == &word[1]) {
+      /* Not a valid number. */
+      return -1;
+    }
+    criterion[0].capability = DM_HERTZ;
+    criterion[0].comparison = EQ;
+    criterion[0].value = hertz;
+    got = specialCaseParse(response,
+      &criterion[1], ~DM_HERTZ);
+    if (got >= 0) {
+      return got + 1;
+    } else {
+      return -1;
+    }
+  case '\0':
+    return 0;
+  }
+  return -1;
+}
+
+/* This routine is based on similiar code in glut_dstr.c */
+static int
+parseCriteria(char *word, Criterion * criterion)
+{
+  char *cstr, *vstr, *response;
+  int comparator, value = 0;
+
+  cstr = strpbrk(word, "=><!~");
+  if (cstr) {
+    switch (cstr[0]) {
+    case '=':
+      comparator = EQ;
+      vstr = &cstr[1];
+      break;
+    case '~':
+      comparator = MIN;
+      vstr = &cstr[1];
+      break;
+    case '>':
+      if (cstr[1] == '=') {
+        comparator = GTE;
+        vstr = &cstr[2];
+      } else {
+        comparator = GT;
+        vstr = &cstr[1];
+      }
+      break;
+    case '<':
+      if (cstr[1] == '=') {
+        comparator = LTE;
+        vstr = &cstr[2];
+      } else {
+        comparator = LT;
+        vstr = &cstr[1];
+      }
+      break;
+    case '!':
+      if (cstr[1] == '=') {
+        comparator = NEQ;
+        vstr = &cstr[2];
+      } else {
+        return -1;
+      }
+      break;
+    default:
+      return -1;
+    }
+    value = (int) strtol(vstr, &response, 0);
+    if (response == vstr) {
+      /* Not a valid number. */
+      return -1;
+    }
+    *cstr = '\0';
+  } else {
+    comparator = NONE;
+  }
+  switch (word[0]) {
+  case 'b':
+    if (!strcmp(word, "bpp")) {
+      criterion[0].capability = DM_PIXEL_DEPTH;
+      if (comparator == NONE) {
+        return -1;
+      } else {
+        criterion[0].comparison = comparator;
+        criterion[0].value = value;
+        return 1;
+      }
+    }
+    return -1;
+  case 'h':
+    if (!strcmp(word, "height")) {
+      criterion[0].capability = DM_HEIGHT;
+      if (comparator == NONE) {
+        return -1;
+      } else {
+        criterion[0].comparison = comparator;
+        criterion[0].value = value;
+        return 1;
+      }
+    }
+    if (!strcmp(word, "hertz")) {
+      criterion[0].capability = DM_HERTZ;
+      if (comparator == NONE) {
+        return -1;
+      } else {
+        criterion[0].comparison = comparator;
+        criterion[0].value = value;
+        return 1;
+      }
+    }
+    return -1;
+  case 'n':
+    if (!strcmp(word, "num")) {
+      criterion[0].capability = DM_NUM;
+      if (comparator == NONE) {
+        return -1;
+      } else {
+        criterion[0].comparison = comparator;
+        criterion[0].value = value;
+        return 1;
+      }
+    }
+    return -1;
+  case 'w':
+    if (!strcmp(word, "width")) {
+      criterion[0].capability = DM_WIDTH;
+      if (comparator == NONE) {
+        return -1;
+      } else {
+        criterion[0].comparison = comparator;
+        criterion[0].value = value;
+        return 1;
+      }
+    }
+    return -1;
+  }
+  if (comparator == NONE) {
+    return specialCaseParse(word, criterion, 0);
+  }
+  return -1;
+}
+
+/* This routine is based on similiar code in glut_dstr.c */
+static Criterion *
+parseDisplayString(const char *display, int *ncriteria)
+{
+  Criterion *criteria = NULL;
+  int n, parsed;
+  char *copy, *word;
+
+  copy = __glutStrdup(display);
+  /* Attempt to estimate how many criteria entries should be
+     needed. */
+  n = 0;
+  word = strtok(copy, " \t");
+  while (word) {
+    n++;
+    word = strtok(NULL, " \t");
+  }
+  /* Allocate number of words of criteria.  A word
+     could contain as many as four criteria in the
+     worst case.  Example: 800x600:16@60 */
+  criteria = (Criterion *) malloc(4 * n * sizeof(Criterion));
+  if (!criteria) {
+    __glutFatalError("out of memory.");
+  }
+
+  /* Re-copy the copy of the display string. */
+  strcpy(copy, display);
+
+  n = 0;
+  word = strtok(copy, " \t");
+  while (word) {
+    parsed = parseCriteria(word, &criteria[n]);
+    if (parsed >= 0) {
+      n += parsed;
+    } else {
+      __glutWarning("Unrecognized game mode string word: %s (ignoring)\n", word);
+    }
+    word = strtok(NULL, " \t");
+  }
+
+  free(copy);
+  *ncriteria = n;
+  return criteria;
+}
+
+void GLUTAPIENTRY
+glutGameModeString(const char *string)
+{
+  Criterion *criteria;
+  int ncriteria;
+
+  initGameModeSupport();
+  criteria = parseDisplayString(string, &ncriteria);
+  currentDm = findMatch(dmodes, ndmodes, criteria, ncriteria);
+  free(criteria);
+}
+
+int GLUTAPIENTRY
+glutEnterGameMode(void)
+{
+  GLUTwindow *window;
+  int width, height;
+  Window win;
+
+  if (__glutMappedMenu) {
+    __glutFatalUsage("entering game mode not allowed while menus in use");
+  }
+  if (__glutGameModeWindow) {
+    /* Already in game mode, so blow away game mode
+       window so apps can change resolutions. */
+    window = __glutGameModeWindow;
+    /* Setting the game mode window to NULL tricks
+       the window destroy code into not undoing the
+       screen display change since we plan on immediately
+       doing another mode change. */
+    __glutGameModeWindow = NULL;
+    __glutDestroyWindow(window, window);
+  }
+
+  /* Assume default screen size until we find out if we
+     can actually change the display settings. */
+  width = __glutScreenWidth;
+  height = __glutScreenHeight;
+
+  if (currentDm) {
+#ifdef _WIN32
+    LONG status;
+    static int registered = 0;
+
+    status = ChangeDisplaySettings(&currentDm->devmode,
+      CDS_FULLSCREEN);
+    if (status == DISP_CHANGE_SUCCESSFUL) {
+      __glutDisplaySettingsChanged = 1;
+      width = currentDm->cap[DM_WIDTH];
+      height = currentDm->cap[DM_HEIGHT];
+      if (!registered) {
+        atexit(__glutCloseDownGameMode);
+        registered = 1;
+      }
+    } else {
+      /* Switch back to default resolution. */
+      ChangeDisplaySettings(NULL, 0);
+    }
+#endif
+  }
+
+  window = __glutCreateWindow(NULL, 0, 0,
+    width, height, /* game mode */ 1);
+  win = window->win;
+
+#if !defined(_WIN32) && !defined(__OS2__)
+  if (__glutMotifHints == None) {
+    __glutMotifHints = XSGIFastInternAtom(__glutDisplay, "_MOTIF_WM_HINTS",
+      SGI_XA__MOTIF_WM_HINTS, 0);
+    if (__glutMotifHints == None) {
+      __glutWarning("Could not intern X atom for _MOTIF_WM_HINTS.");
+    }
+  }
+
+  /* Game mode window is a toplevel window. */
+  XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);
+#endif
+
+  /* Schedule the fullscreen property to be added and to
+     make sure the window is configured right.  Win32
+     doesn't need this. */
+  window->desiredX = 0;
+  window->desiredY = 0;
+  window->desiredWidth = width;
+  window->desiredHeight = height;
+  window->desiredConfMask |= CWX | CWY | CWWidth | CWHeight;
+#ifdef _WIN32
+  /* Win32 does not want to use GLUT_FULL_SCREEN_WORK
+     for game mode because we need to be maximizing
+     the window in game mode, not just sizing it to
+     take up the full screen.  The Win32-ness of game
+     mode happens when you pass 1 in the gameMode parameter
+     to __glutCreateWindow above.  A gameMode of creates
+     a WS_POPUP window, not a standard WS_OVERLAPPEDWINDOW
+     window.  WS_POPUP ensures the taskbar is hidden. */
+  __glutPutOnWorkList(window,
+    GLUT_CONFIGURE_WORK);
+#else
+  __glutPutOnWorkList(window,
+    GLUT_CONFIGURE_WORK | GLUT_FULL_SCREEN_WORK);
+#endif
+
+  __glutGameModeWindow = window;
+  return window->num + 1;
+}
+
+int GLUTAPIENTRY
+glutGameModeGet(GLenum mode)
+{
+  switch (mode) {
+  case GLUT_GAME_MODE_ACTIVE:
+    return __glutGameModeWindow != NULL;
+  case GLUT_GAME_MODE_POSSIBLE:
+    return currentDm != NULL;
+  case GLUT_GAME_MODE_WIDTH:
+    return currentDm ? currentDm->cap[DM_WIDTH] : -1;
+  case GLUT_GAME_MODE_HEIGHT:
+    return currentDm ? currentDm->cap[DM_HEIGHT] : -1;
+  case GLUT_GAME_MODE_PIXEL_DEPTH:
+    return currentDm ? currentDm->cap[DM_PIXEL_DEPTH] : -1;
+  case GLUT_GAME_MODE_REFRESH_RATE:
+    return currentDm ? currentDm->cap[DM_HERTZ] : -1;
+  case GLUT_GAME_MODE_DISPLAY_CHANGED:
+    return __glutDisplaySettingsChanged;
+  default:
+    return -1;
+  }
+}
 \1a
\ No newline at end of file
index 82abba87e48ae04c20c25a0523f6f7d0dbcfef18..53ff5d5d953861d87cdcc73efff3f0d5eb0d8051 100644 (file)
-\r
-/* Copyright (c) Mark J. Kilgard, 1994, 1997.  */\r
-\r
-/* This program is freely distributable without licensing fees\r
-   and is provided without guarantee or warrantee expressed or\r
-   implied. This program is -not- in the public domain. */\r
-\r
-#ifdef __VMS\r
-#include <GL/vms_x_fix.h>\r
-#endif\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <assert.h>\r
-#if defined(__OS2__)\r
-#define POKA 0\r
-  #include "WarpGL.h"\r
-  #include "glutos2.h"\r
-  #include "glutint.h"\r
-\r
-  #include "gl\os2mesa.h"\r
-\r
-//\r
-//define for resource id for main GLUT window, in samples it is  defined in GL_TEST.h\r
-   #define ID_WINDOW            256\r
-\r
-   int evglSetPixelFormat(int iPixelFormat);\r
-   HPS   hpsCurrent;\r
-\r
-#elif !defined(_WIN32)\r
-\r
-#include <X11/Xlib.h>\r
-#include <X11/Xatom.h>\r
-#endif\r
-\r
-#include "glutint.h"\r
-\r
-GLUTwindow *__glutCurrentWindow = NULL;\r
-GLUTwindow **__glutWindowList = NULL;\r
-int __glutWindowListSize = 0;\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-GLUTstale *__glutStaleWindowList = NULL;\r
-#endif\r
-GLUTwindow *__glutMenuWindow = NULL;\r
-\r
-void (*__glutFreeOverlayFunc) (GLUToverlay *);\r
-XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle,\r
-  Criterion * requiredCriteria, int nRequired, int requiredMask, void** fbc) = NULL;\r
-\r
-static Criterion requiredWindowCriteria[] =\r
-{\r
-  {LEVEL, EQ, 0},\r
-  {TRANSPARENT, EQ, 0}\r
-};\r
-static int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion);\r
-static int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT);\r
-\r
-static void\r
-cleanWindowWorkList(GLUTwindow * window)\r
-{\r
-  GLUTwindow **pEntry = &__glutWindowWorkList;\r
-  GLUTwindow *entry = __glutWindowWorkList;\r
-\r
-  /* Tranverse singly-linked window work list look for the\r
-     window. */\r
-  while (entry) {\r
-    if (entry == window) {\r
-      /* Found it; delete it. */\r
-      *pEntry = entry->prevWorkWin;\r
-      return;\r
-    } else {\r
-      pEntry = &entry->prevWorkWin;\r
-      entry = *pEntry;\r
-    }\r
-  }\r
-}\r
-\r
-#if !defined(_WIN32)  && !defined(__OS2PM__)\r
-\r
-static void\r
-cleanStaleWindowList(GLUTwindow * window)\r
-{\r
-  GLUTstale **pEntry = &__glutStaleWindowList;\r
-  GLUTstale *entry = __glutStaleWindowList;\r
-\r
-  /* Tranverse singly-linked stale window list look for the\r
-     window ID. */\r
-  while (entry) {\r
-    if (entry->window == window) {\r
-      /* Found it; delete it. */\r
-      *pEntry = entry->next;\r
-      free(entry);\r
-      return;\r
-    } else {\r
-      pEntry = &entry->next;\r
-      entry = *pEntry;\r
-    }\r
-  }\r
-}\r
-\r
-#endif\r
-\r
-static GLUTwindow *__glutWindowCache = NULL;\r
-\r
-GLUTwindow *\r
-__glutGetWindow(Window win)\r
-{\r
-  int i;\r
-\r
-  /* Does win belong to the last window ID looked up? */\r
-  if (__glutWindowCache && (win == __glutWindowCache->win ||\r
-      (__glutWindowCache->overlay && win ==\r
-        __glutWindowCache->overlay->win))) {\r
-    return\r
-      __glutWindowCache;\r
-  }\r
-  /* Otherwise scan the window list looking for the window ID. */\r
-  for (i = 0; i < __glutWindowListSize; i++) {\r
-    if (__glutWindowList[i]) {\r
-      if (win == __glutWindowList[i]->win) {\r
-        __glutWindowCache = __glutWindowList[i];\r
-        return __glutWindowCache;\r
-      }\r
-      if (__glutWindowList[i]->overlay) {\r
-        if (win == __glutWindowList[i]->overlay->win) {\r
-          __glutWindowCache = __glutWindowList[i];\r
-          return __glutWindowCache;\r
-        }\r
-      }\r
-    }\r
-  }\r
-#if !defined(_WIN32)  && !defined(__OS2PM__)\r
-  {\r
-    GLUTstale *entry;\r
-\r
-    /* Scan through destroyed overlay window IDs for which no\r
-       DestroyNotify has yet been received. */\r
-    for (entry = __glutStaleWindowList; entry; entry = entry->next) {\r
-      if (entry->win == win)\r
-        return entry->window;\r
-    }\r
-  }\r
-#endif\r
-  return NULL;\r
-}\r
-\r
-/* CENTRY */\r
-int GLUTAPIENTRY\r
-glutGetWindow(void)\r
-{\r
-  if (__glutCurrentWindow) {\r
-    return __glutCurrentWindow->num + 1;\r
-  } else {\r
-    return 0;\r
-  }\r
-}\r
-/* ENDCENTRY */\r
-\r
-void\r
-__glutSetWindow(GLUTwindow * window)\r
-{\r
-  /* It is tempting to try to short-circuit the call to\r
-     glXMakeCurrent if we "know" we are going to make current\r
-     to a window we are already current to.  In fact, this\r
-     assumption breaks when GLUT is expected to integrated with\r
-     other OpenGL windowing APIs that also make current to\r
-     OpenGL contexts.  Since glXMakeCurrent short-circuits the\r
-     "already bound" case, GLUT avoids the temptation to do so\r
-     too. */\r
-  __glutCurrentWindow = window;\r
-\r
-  MAKE_CURRENT_LAYER(__glutCurrentWindow);\r
-\r
-#if !defined(_WIN32)  && !defined(__OS2__)\r
-  /* We should be careful to force a finish between each\r
-     iteration through the GLUT main loop if indirect OpenGL\r
-     contexts are in use; indirect contexts tend to have  much\r
-     longer latency because lots of OpenGL extension requests\r
-     can queue up in the X protocol stream.  We accomplish this\r
-     by posting GLUT_FINISH_WORK to be done. */\r
-  if (!__glutCurrentWindow->isDirect)\r
-    __glutPutOnWorkList(__glutCurrentWindow, GLUT_FINISH_WORK);\r
-#endif\r
-\r
-  /* If debugging is enabled, we'll want to check this window\r
-     for any OpenGL errors every iteration through the GLUT\r
-     main loop.  To accomplish this, we post the\r
-     GLUT_DEBUG_WORK to be done on this window. */\r
-  if (__glutDebug) {\r
-    __glutPutOnWorkList(__glutCurrentWindow, GLUT_DEBUG_WORK);\r
-  }\r
-}\r
-\r
-/* CENTRY */\r
-void GLUTAPIENTRY\r
-glutSetWindow(int win)\r
-{\r
-  GLUTwindow *window;\r
-\r
-  if (win < 1 || win > __glutWindowListSize) {\r
-    __glutWarning("glutSetWindow attempted on bogus window.");\r
-    return;\r
-  }\r
-  window = __glutWindowList[win - 1];\r
-  if (!window) {\r
-    __glutWarning("glutSetWindow attempted on bogus window.");\r
-    return;\r
-  }\r
-  __glutSetWindow(window);\r
-}\r
-/* ENDCENTRY */\r
-\r
-static int\r
-getUnusedWindowSlot(void)\r
-{\r
-  int i;\r
-\r
-  /* Look for allocated, unused slot. */\r
-  for (i = 0; i < __glutWindowListSize; i++) {\r
-    if (!__glutWindowList[i]) {\r
-      return i;\r
-    }\r
-  }\r
-  /* Allocate a new slot. */\r
-  __glutWindowListSize++;\r
-  if (__glutWindowList) {\r
-    __glutWindowList = (GLUTwindow **)\r
-      realloc(__glutWindowList,\r
-      __glutWindowListSize * sizeof(GLUTwindow *));\r
-  } else {\r
-    /* XXX Some realloc's do not correctly perform a malloc\r
-       when asked to perform a realloc on a NULL pointer,\r
-       though the ANSI C library spec requires this. */\r
-    __glutWindowList = (GLUTwindow **)\r
-      malloc(sizeof(GLUTwindow *));\r
-  }\r
-  if (!__glutWindowList)\r
-    __glutFatalError("out of memory.");\r
-  __glutWindowList[__glutWindowListSize - 1] = NULL;\r
-  return __glutWindowListSize - 1;\r
-}\r
-\r
-static XVisualInfo *\r
-getVisualInfoCI(unsigned int mode)\r
-{\r
-#if POKA\r
-  static int bufSizeList[] =\r
-  {16, 12, 8, 4, 2, 1, 0};\r
-  XVisualInfo *vi;\r
-  int list[32];\r
-  int i, n = 0;\r
-\r
-  /* Should not be looking at display mode mask if\r
-     __glutDisplayString is non-NULL. */\r
-  assert(!__glutDisplayString);\r
-\r
-  list[n++] = GLX_BUFFER_SIZE;\r
-  list[n++] = 1;\r
-  if (GLUT_WIND_IS_DOUBLE(mode)) {\r
-    list[n++] = GLX_DOUBLEBUFFER;\r
-  }\r
-  if (GLUT_WIND_IS_STEREO(mode)) {\r
-    list[n++] = GLX_STEREO;\r
-  }\r
-  if (GLUT_WIND_HAS_DEPTH(mode)) {\r
-    list[n++] = GLX_DEPTH_SIZE;\r
-    list[n++] = 1;\r
-  }\r
-  if (GLUT_WIND_HAS_STENCIL(mode)) {\r
-    list[n++] = GLX_STENCIL_SIZE;\r
-    list[n++] = 1;\r
-  }\r
-  list[n] = (int) None; /* terminate list */\r
-\r
-  /* glXChooseVisual specify GLX_BUFFER_SIZE prefers the\r
-     "smallest index buffer of at least the specified size".\r
-     This would be reasonable if GLUT allowed the user to\r
-     specify the required buffe size, but GLUT's display mode\r
-     is too simplistic (easy to use?). GLUT should try to find\r
-     the "largest".  So start with a large buffer size and\r
-     shrink until we find a matching one that exists. */\r
-\r
-  for (i = 0; bufSizeList[i]; i++) {\r
-    /* XXX Assumes list[1] is where GLX_BUFFER_SIZE parameter\r
-       is. */\r
-    list[1] = bufSizeList[i];\r
-    vi = glXChooseVisual(__glutDisplay,\r
-      __glutScreen, list);\r
-    if (vi)\r
-      return vi;\r
-  }\r
-  return NULL;\r
-#else\r
-    return\r
-         glXChooseVisual(mode);\r
-\r
-#endif\r
-}\r
-\r
-static XVisualInfo *\r
-getVisualInfoRGB(unsigned int mode)\r
-{\r
-#if POKA\r
-  int list[32];\r
-  int n = 0;\r
-\r
-  /* Should not be looking at display mode mask if\r
-     __glutDisplayString is non-NULL. */\r
-  assert(!__glutDisplayString);\r
-\r
-  /* XXX Would a caching mechanism to minize the calls to\r
-     glXChooseVisual? You'd have to reference count\r
-     XVisualInfo* pointers.  Would also have to properly\r
-     interact with glutInitDisplayString. */\r
-\r
-  list[n++] = GLX_RGBA;\r
-  list[n++] = GLX_RED_SIZE;\r
-  list[n++] = 1;\r
-  list[n++] = GLX_GREEN_SIZE;\r
-  list[n++] = 1;\r
-  list[n++] = GLX_BLUE_SIZE;\r
-  list[n++] = 1;\r
-  if (GLUT_WIND_HAS_ALPHA(mode)) {\r
-    list[n++] = GLX_ALPHA_SIZE;\r
-    list[n++] = 1;\r
-  }\r
-  if (GLUT_WIND_IS_DOUBLE(mode)) {\r
-    list[n++] = GLX_DOUBLEBUFFER;\r
-  }\r
-  if (GLUT_WIND_IS_STEREO(mode)) {\r
-    list[n++] = GLX_STEREO;\r
-  }\r
-  if (GLUT_WIND_HAS_DEPTH(mode)) {\r
-    list[n++] = GLX_DEPTH_SIZE;\r
-    list[n++] = 1;\r
-  }\r
-  if (GLUT_WIND_HAS_STENCIL(mode)) {\r
-    list[n++] = GLX_STENCIL_SIZE;\r
-    list[n++] = 1;\r
-  }\r
-  if (GLUT_WIND_HAS_ACCUM(mode)) {\r
-    list[n++] = GLX_ACCUM_RED_SIZE;\r
-    list[n++] = 1;\r
-    list[n++] = GLX_ACCUM_GREEN_SIZE;\r
-    list[n++] = 1;\r
-    list[n++] = GLX_ACCUM_BLUE_SIZE;\r
-    list[n++] = 1;\r
-    if (GLUT_WIND_HAS_ALPHA(mode)) {\r
-      list[n++] = GLX_ACCUM_ALPHA_SIZE;\r
-      list[n++] = 1;\r
-    }\r
-  }\r
-#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample))\r
-  if (GLUT_WIND_IS_MULTISAMPLE(mode)) {\r
-    if (!__glutIsSupportedByGLX("GLX_SGIS_multisample") &&\r
-        !__glutIsSupportedByGLX("GLX_ARB_multisample"))\r
-      return NULL;\r
-#if defined(GLX_ARB_multisample)\r
-    list[n++] = GLX_SAMPLES_ARB;\r
-#elif defined(GLX_SGIS_multisample)\r
-    list[n++] = GLX_SAMPLES_SGIS;\r
-#endif\r
-    /* XXX Is 4 a reasonable minimum acceptable number of\r
-       samples? */\r
-    list[n++] = 4;\r
-  }\r
-#endif\r
-  list[n] = (int) None; /* terminate list */\r
-\r
-  return glXChooseVisual(__glutDisplay,\r
-    __glutScreen, list);\r
-#else  /* POKA */\r
-\r
-    return\r
-         glXChooseVisual(mode);\r
-\r
-#endif\r
-}\r
-\r
-XVisualInfo *\r
-__glutGetVisualInfo(unsigned int mode)\r
-{\r
-  /* XXX GLUT_LUMINANCE not implemented for GLUT 3.0. */\r
-  if (GLUT_WIND_IS_LUMINANCE(mode))\r
-    return NULL;\r
-\r
-  if (GLUT_WIND_IS_RGB(mode))\r
-    return getVisualInfoRGB(mode);\r
-  else\r
-    return getVisualInfoCI(mode);\r
-}\r
-\r
-XVisualInfo *\r
-__glutDetermineVisual(\r
-  unsigned int displayMode,\r
-  Bool * treatAsSingle,\r
-  XVisualInfo * (getVisualInfo) (unsigned int))\r
-{\r
-  XVisualInfo *vis;\r
-\r
-  /* Should not be looking at display mode mask if\r
-     __glutDisplayString is non-NULL. */\r
-  assert(!__glutDisplayString);\r
-\r
-  *treatAsSingle = GLUT_WIND_IS_SINGLE(displayMode);\r
-  vis = getVisualInfo(displayMode);\r
-  if (!vis) {\r
-    /* Fallback cases when can't get exactly what was asked\r
-       for... */\r
-    if (GLUT_WIND_IS_SINGLE(displayMode)) {\r
-      /* If we can't find a single buffered visual, try looking\r
-         for a double buffered visual.  We can treat a double\r
-         buffered visual as a single buffer visual by changing\r
-         the draw buffer to GL_FRONT and treating any swap\r
-         buffers as no-ops. */\r
-      displayMode |= GLUT_DOUBLE;\r
-      vis = getVisualInfo(displayMode);\r
-      *treatAsSingle = True;\r
-    }\r
-    if (!vis && GLUT_WIND_IS_MULTISAMPLE(displayMode)) {\r
-      /* If we can't seem to get multisampling (ie, not Reality\r
-         Engine class graphics!), go without multisampling.  It\r
-         is up to the application to query how many multisamples\r
-         were allocated (0 equals no multisampling) if the\r
-         application is going to use multisampling for more than\r
-         just antialiasing. */\r
-      displayMode &= ~GLUT_MULTISAMPLE;\r
-      vis = getVisualInfo(displayMode);\r
-    }\r
-  }\r
-  return vis;\r
-}\r
-\r
-static void GLUTCALLBACK\r
-__glutDefaultDisplay(void)\r
-{\r
-  /* XXX Remove the warning after GLUT 3.0. */\r
-  __glutWarning("The following is a new check for GLUT 3.0; update your code.");\r
-  __glutFatalError(\r
-    "redisplay needed for window %d, but no display callback.",\r
-    __glutCurrentWindow->num + 1);\r
-}\r
-\r
-void GLUTCALLBACK\r
-__glutDefaultReshape(int width, int height)\r
-{\r
-  GLUToverlay *overlay;\r
-\r
-  /* Adjust the viewport of the window (and overlay if one\r
-     exists). */\r
-  MAKE_CURRENT_WINDOW(__glutCurrentWindow);\r
-  glViewport(0, 0, (GLsizei) width, (GLsizei) height);\r
-  overlay = __glutCurrentWindow->overlay;\r
-  if (overlay) {\r
-    MAKE_CURRENT_OVERLAY(overlay);\r
-    glViewport(0, 0, (GLsizei) width, (GLsizei) height);\r
-  }\r
-  /* Make sure we are current to the current layer (application\r
-     should be able to count on the current layer not changing\r
-     unless the application explicitly calls glutUseLayer). */\r
-  MAKE_CURRENT_LAYER(__glutCurrentWindow);\r
-}\r
-\r
-XVisualInfo *\r
-__glutDetermineWindowVisual(Bool * treatAsSingle, Bool * visAlloced, void **fbc)\r
-{\r
-  if (__glutDisplayString) {\r
-\r
-    /* __glutDisplayString should be NULL except if\r
-       glutInitDisplayString has been called to register a\r
-       different display string.  Calling glutInitDisplayString\r
-       means using a string instead of an integer mask determine\r
-       the visual to use. Using the function pointer variable\r
-       __glutDetermineVisualFromString below avoids linking in\r
-       the code for implementing glutInitDisplayString (ie,\r
-       glut_dstr.o) unless glutInitDisplayString gets called by\r
-       the application. */\r
-\r
-    assert(__glutDetermineVisualFromString);\r
-    *visAlloced = False;\r
-    *fbc = NULL;\r
-    return __glutDetermineVisualFromString(__glutDisplayString, treatAsSingle,\r
-      requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, fbc);\r
-  } else {\r
-    *visAlloced = True;\r
-    *fbc = NULL;\r
-    return __glutDetermineVisual(__glutDisplayMode,\r
-      treatAsSingle, __glutGetVisualInfo);\r
-  }\r
-}\r
-\r
-/* ARGSUSED5 */  /* Only Win32 uses gameMode parameter. */\r
-GLUTwindow *\r
-__glutCreateWindow(GLUTwindow * parent,\r
-  int x, int y, int width, int height, int gameMode)\r
-{\r
-  GLUTwindow *window;\r
-  XSetWindowAttributes wa;\r
-  unsigned long attribMask;\r
-  int winnum;\r
-  int i;\r
-#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)\r
-  GLXFBConfigSGIX fbc;\r
-#else\r
-  void *fbc;\r
-#endif\r
-\r
-#if defined(__OS2PM__)\r
- {\r
-    extern HAB   hab;      /* PM anchor block handle         */\r
-    CLASSINFO classinfo;\r
-\r
-    if(!WinQueryClassInfo(hab,"GLUT", &classinfo) )\r
-                               __glutOpenOS2Connection(NULL);\r
-  }\r
-#elif defined(_WIN32)\r
-  WNDCLASS wc;\r
-  int style;\r
-\r
-  if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) {\r
-    __glutOpenWin32Connection(NULL);\r
-  }\r
-#else\r
-  if (!__glutDisplay) {\r
-    __glutOpenXConnection(NULL);\r
-  }\r
-#endif\r
-\r
-#ifndef __OS2PM__\r
-  if (__glutGameModeWindow) {\r
-    __glutFatalError("cannot create windows in game mode.");\r
-  }\r
-#endif\r
-\r
-  winnum = getUnusedWindowSlot();\r
-  window = (GLUTwindow *) malloc(sizeof(GLUTwindow));\r
-  if (!window) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  window->num = winnum;\r
-\r
-#if defined(__OS2PM__)\r
-  /* Add this new window to the window list. */\r
-  __glutWindowList[winnum] = window;\r
-  window->shownState = -1;\r
-#endif\r
-\r
-#if !defined(_WIN32)  && !defined(__OS2PM__)\r
-  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,\r
-    &window->visAlloced, (void**) &fbc);\r
-  if (!window->vis) {\r
-    __glutFatalError(\r
-      "visual with necessary capabilities not found.");\r
-  }\r
-  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);\r
-#endif\r
-  window->eventMask = StructureNotifyMask | ExposureMask;\r
-\r
-  attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;\r
-  wa.background_pixmap = None;\r
-  wa.border_pixel = 0;\r
-  wa.colormap = window->cmap;\r
-  wa.event_mask = window->eventMask;\r
-  if (parent) {\r
-    if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)\r
-      wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK;\r
-    attribMask |= CWDontPropagate;\r
-    wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;\r
-  } else {\r
-    wa.do_not_propagate_mask = 0;\r
-  }\r
-\r
-  /* Stash width and height before Win32's __glutAdjustCoords\r
-     possibly overwrites the values. */\r
-  window->width = width;\r
-  window->height = height;\r
-  window->forceReshape = True;\r
-  window->ignoreKeyRepeat = False;\r
-\r
-#if defined(__OS2PM__)\r
-\r
- {  ULONG flStyle=0;\r
-    int ii;\r
-    ERRORID  erridErrorCode;/* last error id code */\r
-    extern HAB   hab;      /* PM anchor block handle         */\r
-\r
-  if (parent) {\r
-    flStyle = WS_CLIPCHILDREN|WS_VISIBLE;\r
-  } else {\r
-    if (gameMode) {\r
-      /* Game mode window should be a WS_POPUP window to\r
-         ensure that the taskbar is hidden by it.  A standard\r
-         WS_OVERLAPPEDWINDOW does not hide the task bar. */\r
-      flStyle = FCF_STANDARD |  WS_MAXIMIZED;\r
-    } else {\r
-      /* A standard toplevel window with borders and such. */\r
-      flStyle = FCF_STANDARD | WS_CLIPCHILDREN;\r
-//      flStyle = WS_OVERLAPPEDWINDOW;\r
-    }\r
-  }\r
-{\r
- HWND  hwnd;                           /* Window     */\r
- ULONG ListBoxId;                      /* Window id  */\r
-                                       /* (supplied by application) */\r
-\r
-\r
- HWND hwndClient;        /* handle to the client                 */\r
- HWND hwndFrame;         /* handle to the frame                  */\r
- PFNWP GenericWndProc;\r
- FRAMECDATA  fcd;\r
- RECTL  rect;     /* Boundary rectangle                   */\r
-\r
-\r
-\r
-/************************************************/\r
-// flCreate = (FCF_STANDARD) & ~FCF_TASKLIST;\r
-/**********************************/\r
-  if (parent)\r
-  {   window->frame = NULL;\r
-\r
- hwnd = WinCreateWindow(parent->win,  /* Parent window             */\r
-                        "GLUTCHILD",        /* Class name                */\r
-                        "",    /* Window text               */\r
-                        flStyle,       /* Window style              */\r
-                        x, y,          /* Position (x,y)            */\r
-                        width, height,      /* Size (width,height)       */\r
-                        parent->win,    /* Owner window              */\r
-                        HWND_TOP,      /* Sibling window            */\r
-                        0,             /* Window id                 */\r
-                        NULL,          /* Control data              */\r
-                        NULL);         /* Pres parameters           */\r
-\r
- erridErrorCode = WinGetLastError(hab);\r
-    window->win = hwnd;\r
-\r
-  window->hdc = WinOpenWindowDC(window->win);\r
-  window->hpsBuffer = hpsCurrent;\r
-\r
-\r
- rect.xLeft = x;\r
- rect.xRight = x+width;\r
- rect.yBottom = y;\r
- rect.yTop = y + height;\r
-\r
-/***** else parent *****************************/\r
-  } else {\r
-        hwnd = WinCreateStdWindow(HWND_DESKTOP,\r
-           0,       /* WS_VISIBLE frame-window style        */\r
-           &flStyle,        /* window style                 */\r
-           "GLUT",          /* class name                   */\r
-           "GLUT",/* window title                  */\r
-            0L,                  /* default client style          */\r
-            NULLHANDLE,          /* resource in executable file   */\r
-            ID_WINDOW,           /* resource id                   */\r
-            &hwndClient);        /* receives client window handle */\r
-\r
- erridErrorCode = WinGetLastError(hab);\r
-       window->win = hwndClient;\r
-       window->frame = hwnd;\r
-  window->hdc = WinOpenWindowDC(window->win);\r
-\r
-  window->hpsBuffer = hpsCurrent;\r
-\r
-\r
-/* converts a client window's boundaries into  an equivalent frame rectangle */\r
- rect.xLeft = x;\r
- rect.xRight = x+width;\r
- rect.yBottom = y;\r
- rect.yTop = y + height;\r
-\r
- /* calculate equivalent frame boundary from boundary data */\r
-  WinCalcFrameRect(window->frame, &rect, FALSE);\r
- }\r
-/***** endof if(parent) *****************************/\r
-\r
-  /* Must set the XHDC for fake glXChooseVisual & fake\r
-     glXCreateContext & fake XAllocColorCells. */\r
-  XHDC = window->hdc;\r
-  XHWND = window->win;\r
-  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,\r
-    &window->visAlloced, &fbc);\r
-    if (!window->vis)\r
-    {   __glutFatalError(\r
-        "pixel format with necessary capabilities not found.");\r
-    }\r
-    { int rc;\r
-      rc = wglChoosePixelFormat(window->hdc, window->vis),\r
-\r
-//     evglSetPixelFormat(2); /* int iPixelFormat 1 - doublebuffer/2 - single buffer ??*/\r
-      wglSetPixelFormat(window->hdc,rc,window->vis);\r
-    }\r
-   __glutSetupColormap(window->vis, &window->colormap, &window->cmap);\r
-\r
-  window->ctx = glXCreateContext(window->hpsBuffer, window->vis,\r
-    None, __glutTryDirect);\r
-\r
-  WinSetWindowPos(hwnd,\r
-                  HWND_TOP,rect.xLeft,rect.yBottom,\r
-                  rect.xRight-rect.xLeft, rect.yTop-rect.yBottom,\r
-      SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW|SWP_ZORDER); /* flags*/\r
-\r
-  /* Make sure subwindows get a windowStatus callback. */\r
-  if (parent)\r
-       WinPostMsg(parent->win, WM_ACTIVATE, 0, 0);\r
-\r
-  }\r
-}\r
-\r
-#elif defined(_WIN32)\r
-\r
-  __glutAdjustCoords(parent ? parent->win : NULL,\r
-    &x, &y, &width, &height);\r
-  if (parent) {\r
-    style = WS_CHILD;\r
-  } else {\r
-    if (gameMode) {\r
-      /* Game mode window should be a WS_POPUP window to\r
-         ensure that the taskbar is hidden by it.  A standard\r
-         WS_OVERLAPPEDWINDOW does not hide the task bar. */\r
-      style = WS_POPUP | WS_MAXIMIZE;\r
-    } else {\r
-      /* A standard toplevel window with borders and such. */\r
-      style = WS_OVERLAPPEDWINDOW;\r
-    }\r
-  }\r
-  window->win = CreateWindow("GLUT", "GLUT",\r
-    WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,\r
-    x, y, width, height, parent ? parent->win : __glutRoot,\r
-    NULL, GetModuleHandle(NULL), 0);\r
-  window->hdc = GetDC(window->win);\r
-  /* Must set the XHDC for fake glXChooseVisual & fake\r
-     glXCreateContext & fake XAllocColorCells. */\r
-  XHDC = window->hdc;\r
-  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,\r
-    &window->visAlloced, &fbc);\r
-  if (!window->vis) {\r
-    __glutFatalError(\r
-      "pixel format with necessary capabilities not found.");\r
-  }\r
-  if (!SetPixelFormat(window->hdc,\r
-      ChoosePixelFormat(window->hdc, window->vis),\r
-      window->vis)) {\r
-    __glutFatalError("SetPixelFormat failed during window create.");\r
-  }\r
-  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);\r
-  /* Make sure subwindows get a windowStatus callback. */\r
-  if (parent) {\r
-    PostMessage(parent->win, WM_ACTIVATE, 0, 0);\r
-  }\r
-  window->renderDc = window->hdc;\r
-#else\r
-  window->win = XCreateWindow(__glutDisplay,\r
-    parent == NULL ? __glutRoot : parent->win,\r
-    x, y, width, height, 0,\r
-    window->vis->depth, InputOutput, window->vis->visual,\r
-    attribMask, &wa);\r
-#endif\r
-  window->renderWin = window->win;\r
-#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)\r
-  if (fbc) {\r
-    window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc,\r
-      GLX_RGBA_TYPE_SGIX, None, __glutTryDirect);\r
-  } else\r
-#endif\r
-#if defined(__OS2PM__)\r
-//    window->ctx = glXCreateContext(window->hpsBuffer, window->vis,\r
-//      None, __glutTryDirect);\r
-#else\r
-    window->ctx = glXCreateContext(__glutDisplay, window->vis,\r
-      None, __glutTryDirect);\r
-#endif\r
-  if (!window->ctx) {\r
-    __glutFatalError(\r
-      "failed to create OpenGL rendering context.");\r
-  }\r
-  window->renderCtx = window->ctx;\r
-#if !defined(_WIN32) && !defined(__OS2PM__)\r
-  window->isDirect = glXIsDirect(__glutDisplay, window->ctx);\r
-  if (__glutForceDirect) {\r
-    if (!window->isDirect)\r
-      __glutFatalError("direct rendering not possible.");\r
-  }\r
-#endif\r
-\r
-  window->parent = parent;\r
-  if (parent) {\r
-    window->siblings = parent->children;\r
-    parent->children = window;\r
-  } else {\r
-    window->siblings = NULL;\r
-  }\r
-  window->overlay = NULL;\r
-  window->children = NULL;\r
-  window->display = __glutDefaultDisplay;\r
-  window->reshape = __glutDefaultReshape;\r
-  window->mouse = NULL;\r
-  window->motion = NULL;\r
-  window->passive = NULL;\r
-  window->entry = NULL;\r
-  window->keyboard = NULL;\r
-  window->keyboardUp = NULL;\r
-  window->windowStatus = NULL;\r
-  window->visibility = NULL;\r
-  window->special = NULL;\r
-  window->specialUp = NULL;\r
-  window->buttonBox = NULL;\r
-  window->dials = NULL;\r
-  window->spaceMotion = NULL;\r
-  window->spaceRotate = NULL;\r
-  window->spaceButton = NULL;\r
-  window->tabletMotion = NULL;\r
-  window->tabletButton = NULL;\r
-#ifdef _WIN32\r
-  window->joystick = NULL;\r
-  window->joyPollInterval = 0;\r
-#endif\r
-\r
-#if defined(__OS2PM__)\r
-  window->wm_command = NULL;\r
-#endif\r
-\r
-  window->tabletPos[0] = -1;\r
-  window->tabletPos[1] = -1;\r
-#if defined(__OS2PM__)\r
-  if(window->shownState == -1)\r
-           window->shownState = 0;\r
-   window->visState =  window->shownState;\r
-#else\r
-  window->shownState = 0;\r
-  window->visState = -1;  /* not VisibilityUnobscured,\r
-                             VisibilityPartiallyObscured, or\r
-                             VisibilityFullyObscured */\r
-#endif\r
-  window->entryState = -1;  /* not EnterNotify or LeaveNotify */\r
-\r
-  window->desiredConfMask = 0;\r
-  window->buttonUses = 0;\r
-  window->cursor = GLUT_CURSOR_INHERIT;\r
-\r
-  /* Setup window to be mapped when glutMainLoop starts. */\r
-  window->workMask = GLUT_MAP_WORK;\r
-#ifdef _WIN32\r
-  if (gameMode) {\r
-    /* When mapping a game mode window, just show\r
-       the window.  We have already created the game\r
-       mode window with a maximize flag at creation\r
-       time.  Doing a ShowWindow(window->win, SW_SHOWNORMAL)\r
-       would be wrong for a game mode window since it\r
-       would unmaximize the window. */\r
-    window->desiredMapState = GameModeState;\r
-  } else {\r
-    window->desiredMapState = NormalState;\r
-  }\r
-#else\r
-  window->desiredMapState = NormalState;\r
-#endif\r
-  window->prevWorkWin = __glutWindowWorkList;\r
-  __glutWindowWorkList = window;\r
-\r
-  /* Initially, no menus attached. */\r
-  for (i = 0; i < GLUT_MAX_MENUS; i++) {\r
-    window->menu[i] = 0;\r
-  }\r
-\r
-  /* Add this new window to the window list. */\r
-  __glutWindowList[winnum] = window;\r
-\r
-  /* Make the new window the current window. */\r
-  __glutSetWindow(window);\r
-\r
-  __glutDetermineMesaSwapHackSupport();\r
-\r
-  if (window->treatAsSingle) {\r
-    /* We do this because either the window really is single\r
-       buffered (in which case this is redundant, but harmless,\r
-       because this is the initial single-buffered context\r
-       state); or we are treating a double buffered window as a\r
-       single-buffered window because the system does not appear\r
-       to export any suitable single- buffered visuals (in which\r
-       the following are necessary). */\r
-    glDrawBuffer(GL_FRONT);\r
-    glReadBuffer(GL_FRONT);\r
-  }\r
-  return window;\r
-}\r
-\r
-/* CENTRY */\r
-int GLUTAPIENTRY\r
-glutCreateWindow(const char *title)\r
-{\r
-  static int firstWindow = 1;\r
-  GLUTwindow *window;\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-  XWMHints *wmHints;\r
-#endif\r
-  Window win;\r
-  XTextProperty textprop;\r
-\r
-  if (__glutGameModeWindow) {\r
-    __glutFatalError("cannot create windows in game mode.");\r
-  }\r
-  window = __glutCreateWindow(NULL,\r
-    __glutSizeHints.x, __glutSizeHints.y,\r
-    __glutInitWidth, __glutInitHeight,\r
-    /* not game mode */ 0);\r
-  win = window->win;\r
-  /* Setup ICCCM properties. */\r
-  textprop.value = (unsigned char *) title;\r
-  textprop.encoding = XA_STRING;\r
-  textprop.format = 8;\r
-  textprop.nitems = strlen(title);\r
-#if defined(__OS2__)\r
-  WinSetWindowText(window->frame, (PCSZ)title);\r
-  if (__glutIconic) {\r
-    window->desiredMapState = IconicState;\r
-  }\r
-#elif defined(_WIN32)\r
-  SetWindowText(win, title);\r
-  if (__glutIconic) {\r
-    window->desiredMapState = IconicState;\r
-  }\r
-#else\r
-  wmHints = XAllocWMHints();\r
-  wmHints->initial_state =\r
-    __glutIconic ? IconicState : NormalState;\r
-  wmHints->flags = StateHint;\r
-  XSetWMProperties(__glutDisplay, win, &textprop, &textprop,\r
-  /* Only put WM_COMMAND property on first window. */\r
-    firstWindow ? __glutArgv : NULL,\r
-    firstWindow ? __glutArgc : 0,\r
-    &__glutSizeHints, wmHints, NULL);\r
-  XFree(wmHints);\r
-  XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);\r
-#endif\r
-  firstWindow = 0;\r
-  return window->num + 1;\r
-}\r
-\r
-#ifdef _WIN32\r
-int GLUTAPIENTRY\r
-__glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int))\r
-{\r
-  __glutExitFunc = exitfunc;\r
-  return glutCreateWindow(title);\r
-}\r
-#endif\r
-\r
-int GLUTAPIENTRY\r
-glutCreateSubWindow(int win, int x, int y, int width, int height)\r
-{\r
-  GLUTwindow *window;\r
-\r
-  window = __glutCreateWindow(__glutWindowList[win - 1],\r
-    x, y, width, height, /* not game mode */ 0);\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-  {\r
-    GLUTwindow *toplevel;\r
-\r
-    toplevel = __glutToplevelOf(window);\r
-    if (toplevel->cmap != window->cmap) {\r
-      __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);\r
-    }\r
-  }\r
-#endif\r
-  return window->num + 1;\r
-}\r
-/* ENDCENTRY */\r
-\r
-void\r
-__glutDestroyWindow(GLUTwindow * window,\r
-  GLUTwindow * initialWindow)\r
-{\r
-  GLUTwindow **prev, *cur, *parent, *siblings;\r
-\r
-  /* Recursively destroy any children. */\r
-  cur = window->children;\r
-  while (cur) {\r
-    siblings = cur->siblings;\r
-    __glutDestroyWindow(cur, initialWindow);\r
-    cur = siblings;\r
-  }\r
-  /* Remove from parent's children list (only necessary for\r
-     non-initial windows and subwindows!). */\r
-  parent = window->parent;\r
-  if (parent && parent == initialWindow->parent) {\r
-    prev = &parent->children;\r
-    cur = parent->children;\r
-    while (cur) {\r
-      if (cur == window) {\r
-        *prev = cur->siblings;\r
-        break;\r
-      }\r
-      prev = &(cur->siblings);\r
-      cur = cur->siblings;\r
-    }\r
-  }\r
-  /* Unbind if bound to this window. */\r
-  if (window == __glutCurrentWindow) {\r
-    UNMAKE_CURRENT();\r
-    __glutCurrentWindow = NULL;\r
-  }\r
-  /* Begin tearing down window itself. */\r
-  if (window->overlay) {\r
-    __glutFreeOverlayFunc(window->overlay);\r
-  }\r
-  XDestroyWindow(__glutDisplay, window->win);\r
-  glXDestroyContext(__glutDisplay, window->ctx);\r
-  if (window->colormap) {\r
-    /* Only color index windows have colormap data structure. */\r
-    __glutFreeColormap(window->colormap);\r
-  }\r
-  /* NULLing the __glutWindowList helps detect is a window\r
-     instance has been destroyed, given a window number. */\r
-  __glutWindowList[window->num] = NULL;\r
-\r
-  /* Cleanup data structures that might contain window. */\r
-  cleanWindowWorkList(window);\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-  cleanStaleWindowList(window);\r
-#endif\r
-  /* Remove window from the "get window cache" if it is there. */\r
-  if (__glutWindowCache == window)\r
-    __glutWindowCache = NULL;\r
-\r
-  if (window->visAlloced) {\r
-    /* Only free XVisualInfo* gotten from glXChooseVisual. */\r
-    XFree(window->vis);\r
-  }\r
-\r
-  if (window == __glutGameModeWindow) {\r
-    /* Destroying the game mode window should implicitly\r
-       have GLUT leave game mode. */\r
-    __glutCloseDownGameMode();\r
-  }\r
-\r
-  free(window);\r
-}\r
-\r
-/* CENTRY */\r
-void GLUTAPIENTRY\r
-glutDestroyWindow(int win)\r
-{\r
-  GLUTwindow *window = __glutWindowList[win - 1];\r
-\r
-  if (__glutMappedMenu && __glutMenuWindow == window) {\r
-    __glutFatalUsage("destroying menu window not allowed while menus in use");\r
-  }\r
-#if !defined(_WIN32) && !defined(__OS2__)\r
-  /* If not a toplevel window... */\r
-  if (window->parent) {\r
-    /* Destroying subwindows may change colormap requirements;\r
-       recalculate toplevel window's WM_COLORMAP_WINDOWS\r
-       property. */\r
-    __glutPutOnWorkList(__glutToplevelOf(window->parent),\r
-      GLUT_COLORMAP_WORK);\r
-  }\r
-#endif\r
-  __glutDestroyWindow(window, window);\r
-  XFlush(__glutDisplay);\r
-}\r
-/* ENDCENTRY */\r
-\r
-void\r
-__glutChangeWindowEventMask(long eventMask, Bool add)\r
-{\r
-  if (add) {\r
-    /* Add eventMask to window's event mask. */\r
-    if ((__glutCurrentWindow->eventMask & eventMask) !=\r
-      eventMask) {\r
-      __glutCurrentWindow->eventMask |= eventMask;\r
-      __glutPutOnWorkList(__glutCurrentWindow,\r
-        GLUT_EVENT_MASK_WORK);\r
-    }\r
-  } else {\r
-    /* Remove eventMask from window's event mask. */\r
-    if (__glutCurrentWindow->eventMask & eventMask) {\r
-      __glutCurrentWindow->eventMask &= ~eventMask;\r
-      __glutPutOnWorkList(__glutCurrentWindow,\r
-        GLUT_EVENT_MASK_WORK);\r
-    }\r
-  }\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutDisplayFunc(GLUTdisplayCB displayFunc)\r
-{\r
-  /* XXX Remove the warning after GLUT 3.0. */\r
-  if (!displayFunc)\r
-    __glutFatalError("NULL display callback not allowed in GLUT 3.0; update your code.");\r
-  __glutCurrentWindow->display = displayFunc;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutMouseFunc(GLUTmouseCB mouseFunc)\r
-{\r
-  if (__glutCurrentWindow->mouse) {\r
-    if (!mouseFunc) {\r
-      /* Previous mouseFunc being disabled. */\r
-      __glutCurrentWindow->buttonUses--;\r
-      __glutChangeWindowEventMask(\r
-        ButtonPressMask | ButtonReleaseMask,\r
-        __glutCurrentWindow->buttonUses > 0);\r
-    }\r
-  } else {\r
-    if (mouseFunc) {\r
-      /* Previously no mouseFunc, new one being installed. */\r
-      __glutCurrentWindow->buttonUses++;\r
-      __glutChangeWindowEventMask(\r
-        ButtonPressMask | ButtonReleaseMask, True);\r
-    }\r
-  }\r
-  __glutCurrentWindow->mouse = mouseFunc;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutMotionFunc(GLUTmotionCB motionFunc)\r
-{\r
-  /* Hack.  Some window managers (4Dwm by default) will mask\r
-     motion events if the client is not selecting for button\r
-     press and release events. So we select for press and\r
-     release events too (being careful to use reference\r
-     counting).  */\r
-  if (__glutCurrentWindow->motion) {\r
-    if (!motionFunc) {\r
-      /* previous mouseFunc being disabled */\r
-      __glutCurrentWindow->buttonUses--;\r
-      __glutChangeWindowEventMask(\r
-        ButtonPressMask | ButtonReleaseMask,\r
-        __glutCurrentWindow->buttonUses > 0);\r
-    }\r
-  } else {\r
-    if (motionFunc) {\r
-      /* Previously no mouseFunc, new one being installed. */\r
-      __glutCurrentWindow->buttonUses++;\r
-      __glutChangeWindowEventMask(\r
-        ButtonPressMask | ButtonReleaseMask, True);\r
-    }\r
-  }\r
-  /* Real work of selecting for passive mouse motion.  */\r
-  __glutChangeWindowEventMask(\r
-    Button1MotionMask | Button2MotionMask | Button3MotionMask,\r
-    motionFunc != NULL);\r
-  __glutCurrentWindow->motion = motionFunc;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutPassiveMotionFunc(GLUTpassiveCB passiveMotionFunc)\r
-{\r
-  __glutChangeWindowEventMask(PointerMotionMask,\r
-    passiveMotionFunc != NULL);\r
-\r
-  /* Passive motion also requires watching enters and leaves so\r
-     that a fake passive motion event can be generated on an\r
-     enter. */\r
-  __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask,\r
-    __glutCurrentWindow->entry != NULL || passiveMotionFunc != NULL);\r
-\r
-  __glutCurrentWindow->passive = passiveMotionFunc;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutEntryFunc(GLUTentryCB entryFunc)\r
-{\r
-  __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask,\r
-    entryFunc != NULL || __glutCurrentWindow->passive);\r
-  __glutCurrentWindow->entry = entryFunc;\r
-  if (!entryFunc) {\r
-    __glutCurrentWindow->entryState = -1;\r
-  }\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutWindowStatusFunc(GLUTwindowStatusCB windowStatusFunc)\r
-{\r
-  __glutChangeWindowEventMask(VisibilityChangeMask,\r
-    windowStatusFunc != NULL);\r
-  __glutCurrentWindow->windowStatus = windowStatusFunc;\r
-  if (!windowStatusFunc) {\r
-    /* Make state invalid. */\r
-    __glutCurrentWindow->visState = -1;\r
-  }\r
-}\r
-\r
-static void GLUTCALLBACK\r
-visibilityHelper(int status)\r
-{\r
-  if (status == GLUT_HIDDEN || status == GLUT_FULLY_COVERED)\r
-    __glutCurrentWindow->visibility(GLUT_NOT_VISIBLE);\r
-  else\r
-    __glutCurrentWindow->visibility(GLUT_VISIBLE);\r
-}\r
-\r
-\r
-void GLUTAPIENTRY\r
-glutVisibilityFunc(GLUTvisibilityCB visibilityFunc)\r
-{\r
-  __glutCurrentWindow->visibility = visibilityFunc;\r
-\r
-  if (visibilityFunc)\r
-  {    glutWindowStatusFunc(visibilityHelper);\r
-#if defined(__OS2PM__)\r
-       if(__glutCurrentWindow->shownState >= 0)\r
-       {  visibilityHelper(__glutCurrentWindow->shownState);\r
-       }\r
-#endif\r
-  }\r
-  else\r
-    glutWindowStatusFunc(NULL);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutReshapeFunc(GLUTreshapeCB reshapeFunc)\r
-{\r
-  if (reshapeFunc) {\r
-    __glutCurrentWindow->reshape = reshapeFunc;\r
-  } else {\r
-    __glutCurrentWindow->reshape = __glutDefaultReshape;\r
-  }\r
-}\r
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1997.  */
+
+/* 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. */
+
+#ifdef __VMS
+#include <GL/vms_x_fix.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#if defined(__OS2__)
+#define POKA 0
+  #include "WarpGL.h"
+  #include "glutos2.h"
+  #include "glutint.h"
+
+  #include "gl\os2mesa.h"
+
+//
+//define for resource id for main GLUT window, in samples it is  defined in GL_TEST.h
+   #define ID_WINDOW            256
+
+   int evglSetPixelFormat(int iPixelFormat);
+   HPS   hpsCurrent;
+
+#elif !defined(_WIN32)
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#endif
+
+#include "glutint.h"
+
+GLUTwindow *__glutCurrentWindow = NULL;
+GLUTwindow **__glutWindowList = NULL;
+int __glutWindowListSize = 0;
+#if !defined(_WIN32) && !defined(__OS2__)
+GLUTstale *__glutStaleWindowList = NULL;
+#endif
+GLUTwindow *__glutMenuWindow = NULL;
+
+void (*__glutFreeOverlayFunc) (GLUToverlay *);
+XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle,
+  Criterion * requiredCriteria, int nRequired, int requiredMask, void** fbc) = NULL;
+
+static Criterion requiredWindowCriteria[] =
+{
+  {LEVEL, EQ, 0},
+  {TRANSPARENT, EQ, 0}
+};
+static int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion);
+static int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT);
+
+static void
+cleanWindowWorkList(GLUTwindow * window)
+{
+  GLUTwindow **pEntry = &__glutWindowWorkList;
+  GLUTwindow *entry = __glutWindowWorkList;
+
+  /* Tranverse singly-linked window work list look for the
+     window. */
+  while (entry) {
+    if (entry == window) {
+      /* Found it; delete it. */
+      *pEntry = entry->prevWorkWin;
+      return;
+    } else {
+      pEntry = &entry->prevWorkWin;
+      entry = *pEntry;
+    }
+  }
+}
+
+#if !defined(_WIN32)  && !defined(__OS2PM__)
+
+static void
+cleanStaleWindowList(GLUTwindow * window)
+{
+  GLUTstale **pEntry = &__glutStaleWindowList;
+  GLUTstale *entry = __glutStaleWindowList;
+
+  /* Tranverse singly-linked stale window list look for the
+     window ID. */
+  while (entry) {
+    if (entry->window == window) {
+      /* Found it; delete it. */
+      *pEntry = entry->next;
+      free(entry);
+      return;
+    } else {
+      pEntry = &entry->next;
+      entry = *pEntry;
+    }
+  }
+}
+
+#endif
+
+static GLUTwindow *__glutWindowCache = NULL;
+
+GLUTwindow *
+__glutGetWindow(Window win)
+{
+  int i;
+
+  /* Does win belong to the last window ID looked up? */
+  if (__glutWindowCache && (win == __glutWindowCache->win ||
+      (__glutWindowCache->overlay && win ==
+        __glutWindowCache->overlay->win))) {
+    return
+      __glutWindowCache;
+  }
+  /* Otherwise scan the window list looking for the window ID. */
+  for (i = 0; i < __glutWindowListSize; i++) {
+    if (__glutWindowList[i]) {
+      if (win == __glutWindowList[i]->win) {
+        __glutWindowCache = __glutWindowList[i];
+        return __glutWindowCache;
+      }
+      if (__glutWindowList[i]->overlay) {
+        if (win == __glutWindowList[i]->overlay->win) {
+          __glutWindowCache = __glutWindowList[i];
+          return __glutWindowCache;
+        }
+      }
+    }
+  }
+#if !defined(_WIN32)  && !defined(__OS2PM__)
+  {
+    GLUTstale *entry;
+
+    /* Scan through destroyed overlay window IDs for which no
+       DestroyNotify has yet been received. */
+    for (entry = __glutStaleWindowList; entry; entry = entry->next) {
+      if (entry->win == win)
+        return entry->window;
+    }
+  }
+#endif
+  return NULL;
+}
+
+/* CENTRY */
+int GLUTAPIENTRY
+glutGetWindow(void)
+{
+  if (__glutCurrentWindow) {
+    return __glutCurrentWindow->num + 1;
+  } else {
+    return 0;
+  }
+}
+/* ENDCENTRY */
+
+void
+__glutSetWindow(GLUTwindow * window)
+{
+  /* It is tempting to try to short-circuit the call to
+     glXMakeCurrent if we "know" we are going to make current
+     to a window we are already current to.  In fact, this
+     assumption breaks when GLUT is expected to integrated with
+     other OpenGL windowing APIs that also make current to
+     OpenGL contexts.  Since glXMakeCurrent short-circuits the
+     "already bound" case, GLUT avoids the temptation to do so
+     too. */
+  __glutCurrentWindow = window;
+
+  MAKE_CURRENT_LAYER(__glutCurrentWindow);
+
+#if !defined(_WIN32)  && !defined(__OS2__)
+  /* We should be careful to force a finish between each
+     iteration through the GLUT main loop if indirect OpenGL
+     contexts are in use; indirect contexts tend to have  much
+     longer latency because lots of OpenGL extension requests
+     can queue up in the X protocol stream.  We accomplish this
+     by posting GLUT_FINISH_WORK to be done. */
+  if (!__glutCurrentWindow->isDirect)
+    __glutPutOnWorkList(__glutCurrentWindow, GLUT_FINISH_WORK);
+#endif
+
+  /* If debugging is enabled, we'll want to check this window
+     for any OpenGL errors every iteration through the GLUT
+     main loop.  To accomplish this, we post the
+     GLUT_DEBUG_WORK to be done on this window. */
+  if (__glutDebug) {
+    __glutPutOnWorkList(__glutCurrentWindow, GLUT_DEBUG_WORK);
+  }
+}
+
+/* CENTRY */
+void GLUTAPIENTRY
+glutSetWindow(int win)
+{
+  GLUTwindow *window;
+
+  if (win < 1 || win > __glutWindowListSize) {
+    __glutWarning("glutSetWindow attempted on bogus window.");
+    return;
+  }
+  window = __glutWindowList[win - 1];
+  if (!window) {
+    __glutWarning("glutSetWindow attempted on bogus window.");
+    return;
+  }
+  __glutSetWindow(window);
+}
+/* ENDCENTRY */
+
+static int
+getUnusedWindowSlot(void)
+{
+  int i;
+
+  /* Look for allocated, unused slot. */
+  for (i = 0; i < __glutWindowListSize; i++) {
+    if (!__glutWindowList[i]) {
+      return i;
+    }
+  }
+  /* Allocate a new slot. */
+  __glutWindowListSize++;
+  if (__glutWindowList) {
+    __glutWindowList = (GLUTwindow **)
+      realloc(__glutWindowList,
+      __glutWindowListSize * sizeof(GLUTwindow *));
+  } else {
+    /* XXX Some realloc's do not correctly perform a malloc
+       when asked to perform a realloc on a NULL pointer,
+       though the ANSI C library spec requires this. */
+    __glutWindowList = (GLUTwindow **)
+      malloc(sizeof(GLUTwindow *));
+  }
+  if (!__glutWindowList)
+    __glutFatalError("out of memory.");
+  __glutWindowList[__glutWindowListSize - 1] = NULL;
+  return __glutWindowListSize - 1;
+}
+
+static XVisualInfo *
+getVisualInfoCI(unsigned int mode)
+{
+#if POKA
+  static int bufSizeList[] =
+  {16, 12, 8, 4, 2, 1, 0};
+  XVisualInfo *vi;
+  int list[32];
+  int i, n = 0;
+
+  /* Should not be looking at display mode mask if
+     __glutDisplayString is non-NULL. */
+  assert(!__glutDisplayString);
+
+  list[n++] = GLX_BUFFER_SIZE;
+  list[n++] = 1;
+  if (GLUT_WIND_IS_DOUBLE(mode)) {
+    list[n++] = GLX_DOUBLEBUFFER;
+  }
+  if (GLUT_WIND_IS_STEREO(mode)) {
+    list[n++] = GLX_STEREO;
+  }
+  if (GLUT_WIND_HAS_DEPTH(mode)) {
+    list[n++] = GLX_DEPTH_SIZE;
+    list[n++] = 1;
+  }
+  if (GLUT_WIND_HAS_STENCIL(mode)) {
+    list[n++] = GLX_STENCIL_SIZE;
+    list[n++] = 1;
+  }
+  list[n] = (int) None; /* terminate list */
+
+  /* glXChooseVisual specify GLX_BUFFER_SIZE prefers the
+     "smallest index buffer of at least the specified size".
+     This would be reasonable if GLUT allowed the user to
+     specify the required buffe size, but GLUT's display mode
+     is too simplistic (easy to use?). GLUT should try to find
+     the "largest".  So start with a large buffer size and
+     shrink until we find a matching one that exists. */
+
+  for (i = 0; bufSizeList[i]; i++) {
+    /* XXX Assumes list[1] is where GLX_BUFFER_SIZE parameter
+       is. */
+    list[1] = bufSizeList[i];
+    vi = glXChooseVisual(__glutDisplay,
+      __glutScreen, list);
+    if (vi)
+      return vi;
+  }
+  return NULL;
+#else
+    return
+         glXChooseVisual(mode);
+
+#endif
+}
+
+static XVisualInfo *
+getVisualInfoRGB(unsigned int mode)
+{
+#if POKA
+  int list[32];
+  int n = 0;
+
+  /* Should not be looking at display mode mask if
+     __glutDisplayString is non-NULL. */
+  assert(!__glutDisplayString);
+
+  /* XXX Would a caching mechanism to minize the calls to
+     glXChooseVisual? You'd have to reference count
+     XVisualInfo* pointers.  Would also have to properly
+     interact with glutInitDisplayString. */
+
+  list[n++] = GLX_RGBA;
+  list[n++] = GLX_RED_SIZE;
+  list[n++] = 1;
+  list[n++] = GLX_GREEN_SIZE;
+  list[n++] = 1;
+  list[n++] = GLX_BLUE_SIZE;
+  list[n++] = 1;
+  if (GLUT_WIND_HAS_ALPHA(mode)) {
+    list[n++] = GLX_ALPHA_SIZE;
+    list[n++] = 1;
+  }
+  if (GLUT_WIND_IS_DOUBLE(mode)) {
+    list[n++] = GLX_DOUBLEBUFFER;
+  }
+  if (GLUT_WIND_IS_STEREO(mode)) {
+    list[n++] = GLX_STEREO;
+  }
+  if (GLUT_WIND_HAS_DEPTH(mode)) {
+    list[n++] = GLX_DEPTH_SIZE;
+    list[n++] = 1;
+  }
+  if (GLUT_WIND_HAS_STENCIL(mode)) {
+    list[n++] = GLX_STENCIL_SIZE;
+    list[n++] = 1;
+  }
+  if (GLUT_WIND_HAS_ACCUM(mode)) {
+    list[n++] = GLX_ACCUM_RED_SIZE;
+    list[n++] = 1;
+    list[n++] = GLX_ACCUM_GREEN_SIZE;
+    list[n++] = 1;
+    list[n++] = GLX_ACCUM_BLUE_SIZE;
+    list[n++] = 1;
+    if (GLUT_WIND_HAS_ALPHA(mode)) {
+      list[n++] = GLX_ACCUM_ALPHA_SIZE;
+      list[n++] = 1;
+    }
+  }
+#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample))
+  if (GLUT_WIND_IS_MULTISAMPLE(mode)) {
+    if (!__glutIsSupportedByGLX("GLX_SGIS_multisample") &&
+        !__glutIsSupportedByGLX("GLX_ARB_multisample"))
+      return NULL;
+#if defined(GLX_ARB_multisample)
+    list[n++] = GLX_SAMPLES_ARB;
+#elif defined(GLX_SGIS_multisample)
+    list[n++] = GLX_SAMPLES_SGIS;
+#endif
+    /* XXX Is 4 a reasonable minimum acceptable number of
+       samples? */
+    list[n++] = 4;
+  }
+#endif
+  list[n] = (int) None; /* terminate list */
+
+  return glXChooseVisual(__glutDisplay,
+    __glutScreen, list);
+#else  /* POKA */
+
+    return
+         glXChooseVisual(mode);
+
+#endif
+}
+
+XVisualInfo *
+__glutGetVisualInfo(unsigned int mode)
+{
+  /* XXX GLUT_LUMINANCE not implemented for GLUT 3.0. */
+  if (GLUT_WIND_IS_LUMINANCE(mode))
+    return NULL;
+
+  if (GLUT_WIND_IS_RGB(mode))
+    return getVisualInfoRGB(mode);
+  else
+    return getVisualInfoCI(mode);
+}
+
+XVisualInfo *
+__glutDetermineVisual(
+  unsigned int displayMode,
+  Bool * treatAsSingle,
+  XVisualInfo * (getVisualInfo) (unsigned int))
+{
+  XVisualInfo *vis;
+
+  /* Should not be looking at display mode mask if
+     __glutDisplayString is non-NULL. */
+  assert(!__glutDisplayString);
+
+  *treatAsSingle = GLUT_WIND_IS_SINGLE(displayMode);
+  vis = getVisualInfo(displayMode);
+  if (!vis) {
+    /* Fallback cases when can't get exactly what was asked
+       for... */
+    if (GLUT_WIND_IS_SINGLE(displayMode)) {
+      /* If we can't find a single buffered visual, try looking
+         for a double buffered visual.  We can treat a double
+         buffered visual as a single buffer visual by changing
+         the draw buffer to GL_FRONT and treating any swap
+         buffers as no-ops. */
+      displayMode |= GLUT_DOUBLE;
+      vis = getVisualInfo(displayMode);
+      *treatAsSingle = True;
+    }
+    if (!vis && GLUT_WIND_IS_MULTISAMPLE(displayMode)) {
+      /* If we can't seem to get multisampling (ie, not Reality
+         Engine class graphics!), go without multisampling.  It
+         is up to the application to query how many multisamples
+         were allocated (0 equals no multisampling) if the
+         application is going to use multisampling for more than
+         just antialiasing. */
+      displayMode &= ~GLUT_MULTISAMPLE;
+      vis = getVisualInfo(displayMode);
+    }
+  }
+  return vis;
+}
+
+static void GLUTCALLBACK
+__glutDefaultDisplay(void)
+{
+  /* XXX Remove the warning after GLUT 3.0. */
+  __glutWarning("The following is a new check for GLUT 3.0; update your code.");
+  __glutFatalError(
+    "redisplay needed for window %d, but no display callback.",
+    __glutCurrentWindow->num + 1);
+}
+
+void GLUTCALLBACK
+__glutDefaultReshape(int width, int height)
+{
+  GLUToverlay *overlay;
+
+  /* Adjust the viewport of the window (and overlay if one
+     exists). */
+  MAKE_CURRENT_WINDOW(__glutCurrentWindow);
+  glViewport(0, 0, (GLsizei) width, (GLsizei) height);
+  overlay = __glutCurrentWindow->overlay;
+  if (overlay) {
+    MAKE_CURRENT_OVERLAY(overlay);
+    glViewport(0, 0, (GLsizei) width, (GLsizei) height);
+  }
+  /* Make sure we are current to the current layer (application
+     should be able to count on the current layer not changing
+     unless the application explicitly calls glutUseLayer). */
+  MAKE_CURRENT_LAYER(__glutCurrentWindow);
+}
+
+XVisualInfo *
+__glutDetermineWindowVisual(Bool * treatAsSingle, Bool * visAlloced, void **fbc)
+{
+  if (__glutDisplayString) {
+
+    /* __glutDisplayString should be NULL except if
+       glutInitDisplayString has been called to register a
+       different display string.  Calling glutInitDisplayString
+       means using a string instead of an integer mask determine
+       the visual to use. Using the function pointer variable
+       __glutDetermineVisualFromString below avoids linking in
+       the code for implementing glutInitDisplayString (ie,
+       glut_dstr.o) unless glutInitDisplayString gets called by
+       the application. */
+
+    assert(__glutDetermineVisualFromString);
+    *visAlloced = False;
+    *fbc = NULL;
+    return __glutDetermineVisualFromString(__glutDisplayString, treatAsSingle,
+      requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, fbc);
+  } else {
+    *visAlloced = True;
+    *fbc = NULL;
+    return __glutDetermineVisual(__glutDisplayMode,
+      treatAsSingle, __glutGetVisualInfo);
+  }
+}
+
+/* ARGSUSED5 */  /* Only Win32 uses gameMode parameter. */
+GLUTwindow *
+__glutCreateWindow(GLUTwindow * parent,
+  int x, int y, int width, int height, int gameMode)
+{
+  GLUTwindow *window;
+  XSetWindowAttributes wa;
+  unsigned long attribMask;
+  int winnum;
+  int i;
+#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
+  GLXFBConfigSGIX fbc;
+#else
+  void *fbc;
+#endif
+
+#if defined(__OS2PM__)
+ {
+    extern HAB   hab;      /* PM anchor block handle         */
+    CLASSINFO classinfo;
+
+    if(!WinQueryClassInfo(hab,"GLUT", &classinfo) )
+                               __glutOpenOS2Connection(NULL);
+  }
+#elif defined(_WIN32)
+  WNDCLASS wc;
+  int style;
+
+  if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) {
+    __glutOpenWin32Connection(NULL);
+  }
+#else
+  if (!__glutDisplay) {
+    __glutOpenXConnection(NULL);
+  }
+#endif
+
+#ifndef __OS2PM__
+  if (__glutGameModeWindow) {
+    __glutFatalError("cannot create windows in game mode.");
+  }
+#endif
+
+  winnum = getUnusedWindowSlot();
+  window = (GLUTwindow *) malloc(sizeof(GLUTwindow));
+  if (!window) {
+    __glutFatalError("out of memory.");
+  }
+  window->num = winnum;
+
+#if defined(__OS2PM__)
+  /* Add this new window to the window list. */
+  __glutWindowList[winnum] = window;
+  window->shownState = -1;
+#endif
+
+#if !defined(_WIN32)  && !defined(__OS2PM__)
+  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
+    &window->visAlloced, (void**) &fbc);
+  if (!window->vis) {
+    __glutFatalError(
+      "visual with necessary capabilities not found.");
+  }
+  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
+#endif
+  window->eventMask = StructureNotifyMask | ExposureMask;
+
+  attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
+  wa.background_pixmap = None;
+  wa.border_pixel = 0;
+  wa.colormap = window->cmap;
+  wa.event_mask = window->eventMask;
+  if (parent) {
+    if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)
+      wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK;
+    attribMask |= CWDontPropagate;
+    wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;
+  } else {
+    wa.do_not_propagate_mask = 0;
+  }
+
+  /* Stash width and height before Win32's __glutAdjustCoords
+     possibly overwrites the values. */
+  window->width = width;
+  window->height = height;
+  window->forceReshape = True;
+  window->ignoreKeyRepeat = False;
+
+#if defined(__OS2PM__)
+
+ {  ULONG flStyle=0;
+    int ii;
+    ERRORID  erridErrorCode;/* last error id code */
+    extern HAB   hab;      /* PM anchor block handle         */
+
+  if (parent) {
+    flStyle = WS_CLIPCHILDREN|WS_VISIBLE;
+  } else {
+    if (gameMode) {
+      /* Game mode window should be a WS_POPUP window to
+         ensure that the taskbar is hidden by it.  A standard
+         WS_OVERLAPPEDWINDOW does not hide the task bar. */
+      flStyle = FCF_STANDARD |  WS_MAXIMIZED;
+    } else {
+      /* A standard toplevel window with borders and such. */
+      flStyle = FCF_STANDARD | WS_CLIPCHILDREN;
+//      flStyle = WS_OVERLAPPEDWINDOW;
+    }
+  }
+{
+ HWND  hwnd;                           /* Window     */
+ ULONG ListBoxId;                      /* Window id  */
+                                       /* (supplied by application) */
+
+
+ HWND hwndClient;        /* handle to the client                 */
+ HWND hwndFrame;         /* handle to the frame                  */
+ PFNWP GenericWndProc;
+ FRAMECDATA  fcd;
+ RECTL  rect;     /* Boundary rectangle                   */
+
+
+
+/************************************************/
+// flCreate = (FCF_STANDARD) & ~FCF_TASKLIST;
+/**********************************/
+  if (parent)
+  {   window->frame = NULL;
+
+ hwnd = WinCreateWindow(parent->win,  /* Parent window             */
+                        "GLUTCHILD",        /* Class name                */
+                        "",    /* Window text               */
+                        flStyle,       /* Window style              */
+                        x, y,          /* Position (x,y)            */
+                        width, height,      /* Size (width,height)       */
+                        parent->win,    /* Owner window              */
+                        HWND_TOP,      /* Sibling window            */
+                        0,             /* Window id                 */
+                        NULL,          /* Control data              */
+                        NULL);         /* Pres parameters           */
+
+ erridErrorCode = WinGetLastError(hab);
+    window->win = hwnd;
+
+  window->hdc = WinOpenWindowDC(window->win);
+  window->hpsBuffer = hpsCurrent;
+
+
+ rect.xLeft = x;
+ rect.xRight = x+width;
+ rect.yBottom = y;
+ rect.yTop = y + height;
+
+/***** else parent *****************************/
+  } else {
+        hwnd = WinCreateStdWindow(HWND_DESKTOP,
+           0,       /* WS_VISIBLE frame-window style        */
+           &flStyle,        /* window style                 */
+           "GLUT",          /* class name                   */
+           "GLUT",/* window title                  */
+            0L,                  /* default client style          */
+            NULLHANDLE,          /* resource in executable file   */
+            ID_WINDOW,           /* resource id                   */
+            &hwndClient);        /* receives client window handle */
+
+ erridErrorCode = WinGetLastError(hab);
+       window->win = hwndClient;
+       window->frame = hwnd;
+  window->hdc = WinOpenWindowDC(window->win);
+
+  window->hpsBuffer = hpsCurrent;
+
+
+/* converts a client window's boundaries into  an equivalent frame rectangle */
+ rect.xLeft = x;
+ rect.xRight = x+width;
+ rect.yBottom = y;
+ rect.yTop = y + height;
+
+ /* calculate equivalent frame boundary from boundary data */
+  WinCalcFrameRect(window->frame, &rect, FALSE);
+ }
+/***** endof if(parent) *****************************/
+
+  /* Must set the XHDC for fake glXChooseVisual & fake
+     glXCreateContext & fake XAllocColorCells. */
+  XHDC = window->hdc;
+  XHWND = window->win;
+  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
+    &window->visAlloced, &fbc);
+    if (!window->vis)
+    {   __glutFatalError(
+        "pixel format with necessary capabilities not found.");
+    }
+    { int rc;
+      rc = wglChoosePixelFormat(window->hdc, window->vis),
+
+//     evglSetPixelFormat(2); /* int iPixelFormat 1 - doublebuffer/2 - single buffer ??*/
+      wglSetPixelFormat(window->hdc,rc,window->vis);
+    }
+   __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
+
+  window->ctx = glXCreateContext(window->hpsBuffer, window->vis,
+    None, __glutTryDirect);
+
+  WinSetWindowPos(hwnd,
+                  HWND_TOP,rect.xLeft,rect.yBottom,
+                  rect.xRight-rect.xLeft, rect.yTop-rect.yBottom,
+      SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW|SWP_ZORDER); /* flags*/
+
+  /* Make sure subwindows get a windowStatus callback. */
+  if (parent)
+       WinPostMsg(parent->win, WM_ACTIVATE, 0, 0);
+
+  }
+}
+
+#elif defined(_WIN32)
+
+  __glutAdjustCoords(parent ? parent->win : NULL,
+    &x, &y, &width, &height);
+  if (parent) {
+    style = WS_CHILD;
+  } else {
+    if (gameMode) {
+      /* Game mode window should be a WS_POPUP window to
+         ensure that the taskbar is hidden by it.  A standard
+         WS_OVERLAPPEDWINDOW does not hide the task bar. */
+      style = WS_POPUP | WS_MAXIMIZE;
+    } else {
+      /* A standard toplevel window with borders and such. */
+      style = WS_OVERLAPPEDWINDOW;
+    }
+  }
+  window->win = CreateWindow("GLUT", "GLUT",
+    WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
+    x, y, width, height, parent ? parent->win : __glutRoot,
+    NULL, GetModuleHandle(NULL), 0);
+  window->hdc = GetDC(window->win);
+  /* Must set the XHDC for fake glXChooseVisual & fake
+     glXCreateContext & fake XAllocColorCells. */
+  XHDC = window->hdc;
+  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
+    &window->visAlloced, &fbc);
+  if (!window->vis) {
+    __glutFatalError(
+      "pixel format with necessary capabilities not found.");
+  }
+  if (!SetPixelFormat(window->hdc,
+      ChoosePixelFormat(window->hdc, window->vis),
+      window->vis)) {
+    __glutFatalError("SetPixelFormat failed during window create.");
+  }
+  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
+  /* Make sure subwindows get a windowStatus callback. */
+  if (parent) {
+    PostMessage(parent->win, WM_ACTIVATE, 0, 0);
+  }
+  window->renderDc = window->hdc;
+#else
+  window->win = XCreateWindow(__glutDisplay,
+    parent == NULL ? __glutRoot : parent->win,
+    x, y, width, height, 0,
+    window->vis->depth, InputOutput, window->vis->visual,
+    attribMask, &wa);
+#endif
+  window->renderWin = window->win;
+#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
+  if (fbc) {
+    window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc,
+      GLX_RGBA_TYPE_SGIX, None, __glutTryDirect);
+  } else
+#endif
+#if defined(__OS2PM__)
+//    window->ctx = glXCreateContext(window->hpsBuffer, window->vis,
+//      None, __glutTryDirect);
+#else
+    window->ctx = glXCreateContext(__glutDisplay, window->vis,
+      None, __glutTryDirect);
+#endif
+  if (!window->ctx) {
+    __glutFatalError(
+      "failed to create OpenGL rendering context.");
+  }
+  window->renderCtx = window->ctx;
+#if !defined(_WIN32) && !defined(__OS2PM__)
+  window->isDirect = glXIsDirect(__glutDisplay, window->ctx);
+  if (__glutForceDirect) {
+    if (!window->isDirect)
+      __glutFatalError("direct rendering not possible.");
+  }
+#endif
+
+  window->parent = parent;
+  if (parent) {
+    window->siblings = parent->children;
+    parent->children = window;
+  } else {
+    window->siblings = NULL;
+  }
+  window->overlay = NULL;
+  window->children = NULL;
+  window->display = __glutDefaultDisplay;
+  window->reshape = __glutDefaultReshape;
+  window->mouse = NULL;
+  window->motion = NULL;
+  window->passive = NULL;
+  window->entry = NULL;
+  window->keyboard = NULL;
+  window->keyboardUp = NULL;
+  window->windowStatus = NULL;
+  window->visibility = NULL;
+  window->special = NULL;
+  window->specialUp = NULL;
+  window->buttonBox = NULL;
+  window->dials = NULL;
+  window->spaceMotion = NULL;
+  window->spaceRotate = NULL;
+  window->spaceButton = NULL;
+  window->tabletMotion = NULL;
+  window->tabletButton = NULL;
+#ifdef _WIN32
+  window->joystick = NULL;
+  window->joyPollInterval = 0;
+#endif
+
+#if defined(__OS2PM__)
+  window->wm_command = NULL;
+#endif
+
+  window->tabletPos[0] = -1;
+  window->tabletPos[1] = -1;
+#if defined(__OS2PM__)
+  if(window->shownState == -1)
+           window->shownState = 0;
+   window->visState =  window->shownState;
+#else
+  window->shownState = 0;
+  window->visState = -1;  /* not VisibilityUnobscured,
+                             VisibilityPartiallyObscured, or
+                             VisibilityFullyObscured */
+#endif
+  window->entryState = -1;  /* not EnterNotify or LeaveNotify */
+
+  window->desiredConfMask = 0;
+  window->buttonUses = 0;
+  window->cursor = GLUT_CURSOR_INHERIT;
+
+  /* Setup window to be mapped when glutMainLoop starts. */
+  window->workMask = GLUT_MAP_WORK;
+#ifdef _WIN32
+  if (gameMode) {
+    /* When mapping a game mode window, just show
+       the window.  We have already created the game
+       mode window with a maximize flag at creation
+       time.  Doing a ShowWindow(window->win, SW_SHOWNORMAL)
+       would be wrong for a game mode window since it
+       would unmaximize the window. */
+    window->desiredMapState = GameModeState;
+  } else {
+    window->desiredMapState = NormalState;
+  }
+#else
+  window->desiredMapState = NormalState;
+#endif
+  window->prevWorkWin = __glutWindowWorkList;
+  __glutWindowWorkList = window;
+
+  /* Initially, no menus attached. */
+  for (i = 0; i < GLUT_MAX_MENUS; i++) {
+    window->menu[i] = 0;
+  }
+
+  /* Add this new window to the window list. */
+  __glutWindowList[winnum] = window;
+
+  /* Make the new window the current window. */
+  __glutSetWindow(window);
+
+  __glutDetermineMesaSwapHackSupport();
+
+  if (window->treatAsSingle) {
+    /* We do this because either the window really is single
+       buffered (in which case this is redundant, but harmless,
+       because this is the initial single-buffered context
+       state); or we are treating a double buffered window as a
+       single-buffered window because the system does not appear
+       to export any suitable single- buffered visuals (in which
+       the following are necessary). */
+    glDrawBuffer(GL_FRONT);
+    glReadBuffer(GL_FRONT);
+  }
+  return window;
+}
+
+/* CENTRY */
+int GLUTAPIENTRY
+glutCreateWindow(const char *title)
+{
+  static int firstWindow = 1;
+  GLUTwindow *window;
+#if !defined(_WIN32) && !defined(__OS2__)
+  XWMHints *wmHints;
+#endif
+  Window win;
+  XTextProperty textprop;
+
+  if (__glutGameModeWindow) {
+    __glutFatalError("cannot create windows in game mode.");
+  }
+  window = __glutCreateWindow(NULL,
+    __glutSizeHints.x, __glutSizeHints.y,
+    __glutInitWidth, __glutInitHeight,
+    /* not game mode */ 0);
+  win = window->win;
+  /* Setup ICCCM properties. */
+  textprop.value = (unsigned char *) title;
+  textprop.encoding = XA_STRING;
+  textprop.format = 8;
+  textprop.nitems = strlen(title);
+#if defined(__OS2__)
+  WinSetWindowText(window->frame, (PCSZ)title);
+  if (__glutIconic) {
+    window->desiredMapState = IconicState;
+  }
+#elif defined(_WIN32)
+  SetWindowText(win, title);
+  if (__glutIconic) {
+    window->desiredMapState = IconicState;
+  }
+#else
+  wmHints = XAllocWMHints();
+  wmHints->initial_state =
+    __glutIconic ? IconicState : NormalState;
+  wmHints->flags = StateHint;
+  XSetWMProperties(__glutDisplay, win, &textprop, &textprop,
+  /* Only put WM_COMMAND property on first window. */
+    firstWindow ? __glutArgv : NULL,
+    firstWindow ? __glutArgc : 0,
+    &__glutSizeHints, wmHints, NULL);
+  XFree(wmHints);
+  XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);
+#endif
+  firstWindow = 0;
+  return window->num + 1;
+}
+
+#ifdef _WIN32
+int GLUTAPIENTRY
+__glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int))
+{
+  __glutExitFunc = exitfunc;
+  return glutCreateWindow(title);
+}
+#endif
+
+int GLUTAPIENTRY
+glutCreateSubWindow(int win, int x, int y, int width, int height)
+{
+  GLUTwindow *window;
+
+  window = __glutCreateWindow(__glutWindowList[win - 1],
+    x, y, width, height, /* not game mode */ 0);
+#if !defined(_WIN32) && !defined(__OS2__)
+  {
+    GLUTwindow *toplevel;
+
+    toplevel = __glutToplevelOf(window);
+    if (toplevel->cmap != window->cmap) {
+      __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
+    }
+  }
+#endif
+  return window->num + 1;
+}
+/* ENDCENTRY */
+
+void
+__glutDestroyWindow(GLUTwindow * window,
+  GLUTwindow * initialWindow)
+{
+  GLUTwindow **prev, *cur, *parent, *siblings;
+
+  /* Recursively destroy any children. */
+  cur = window->children;
+  while (cur) {
+    siblings = cur->siblings;
+    __glutDestroyWindow(cur, initialWindow);
+    cur = siblings;
+  }
+  /* Remove from parent's children list (only necessary for
+     non-initial windows and subwindows!). */
+  parent = window->parent;
+  if (parent && parent == initialWindow->parent) {
+    prev = &parent->children;
+    cur = parent->children;
+    while (cur) {
+      if (cur == window) {
+        *prev = cur->siblings;
+        break;
+      }
+      prev = &(cur->siblings);
+      cur = cur->siblings;
+    }
+  }
+  /* Unbind if bound to this window. */
+  if (window == __glutCurrentWindow) {
+    UNMAKE_CURRENT();
+    __glutCurrentWindow = NULL;
+  }
+  /* Begin tearing down window itself. */
+  if (window->overlay) {
+    __glutFreeOverlayFunc(window->overlay);
+  }
+  XDestroyWindow(__glutDisplay, window->win);
+  glXDestroyContext(__glutDisplay, window->ctx);
+  if (window->colormap) {
+    /* Only color index windows have colormap data structure. */
+    __glutFreeColormap(window->colormap);
+  }
+  /* NULLing the __glutWindowList helps detect is a window
+     instance has been destroyed, given a window number. */
+  __glutWindowList[window->num] = NULL;
+
+  /* Cleanup data structures that might contain window. */
+  cleanWindowWorkList(window);
+#if !defined(_WIN32) && !defined(__OS2__)
+  cleanStaleWindowList(window);
+#endif
+  /* Remove window from the "get window cache" if it is there. */
+  if (__glutWindowCache == window)
+    __glutWindowCache = NULL;
+
+  if (window->visAlloced) {
+    /* Only free XVisualInfo* gotten from glXChooseVisual. */
+    XFree(window->vis);
+  }
+
+  if (window == __glutGameModeWindow) {
+    /* Destroying the game mode window should implicitly
+       have GLUT leave game mode. */
+    __glutCloseDownGameMode();
+  }
+
+  free(window);
+}
+
+/* CENTRY */
+void GLUTAPIENTRY
+glutDestroyWindow(int win)
+{
+  GLUTwindow *window = __glutWindowList[win - 1];
+
+  if (__glutMappedMenu && __glutMenuWindow == window) {
+    __glutFatalUsage("destroying menu window not allowed while menus in use");
+  }
+#if !defined(_WIN32) && !defined(__OS2__)
+  /* If not a toplevel window... */
+  if (window->parent) {
+    /* Destroying subwindows may change colormap requirements;
+       recalculate toplevel window's WM_COLORMAP_WINDOWS
+       property. */
+    __glutPutOnWorkList(__glutToplevelOf(window->parent),
+      GLUT_COLORMAP_WORK);
+  }
+#endif
+  __glutDestroyWindow(window, window);
+  XFlush(__glutDisplay);
+}
+/* ENDCENTRY */
+
+void
+__glutChangeWindowEventMask(long eventMask, Bool add)
+{
+  if (add) {
+    /* Add eventMask to window's event mask. */
+    if ((__glutCurrentWindow->eventMask & eventMask) !=
+      eventMask) {
+      __glutCurrentWindow->eventMask |= eventMask;
+      __glutPutOnWorkList(__glutCurrentWindow,
+        GLUT_EVENT_MASK_WORK);
+    }
+  } else {
+    /* Remove eventMask from window's event mask. */
+    if (__glutCurrentWindow->eventMask & eventMask) {
+      __glutCurrentWindow->eventMask &= ~eventMask;
+      __glutPutOnWorkList(__glutCurrentWindow,
+        GLUT_EVENT_MASK_WORK);
+    }
+  }
+}
+
+void GLUTAPIENTRY
+glutDisplayFunc(GLUTdisplayCB displayFunc)
+{
+  /* XXX Remove the warning after GLUT 3.0. */
+  if (!displayFunc)
+    __glutFatalError("NULL display callback not allowed in GLUT 3.0; update your code.");
+  __glutCurrentWindow->display = displayFunc;
+}
+
+void GLUTAPIENTRY
+glutMouseFunc(GLUTmouseCB mouseFunc)
+{
+  if (__glutCurrentWindow->mouse) {
+    if (!mouseFunc) {
+      /* Previous mouseFunc being disabled. */
+      __glutCurrentWindow->buttonUses--;
+      __glutChangeWindowEventMask(
+        ButtonPressMask | ButtonReleaseMask,
+        __glutCurrentWindow->buttonUses > 0);
+    }
+  } else {
+    if (mouseFunc) {
+      /* Previously no mouseFunc, new one being installed. */
+      __glutCurrentWindow->buttonUses++;
+      __glutChangeWindowEventMask(
+        ButtonPressMask | ButtonReleaseMask, True);
+    }
+  }
+  __glutCurrentWindow->mouse = mouseFunc;
+}
+
+void GLUTAPIENTRY
+glutMotionFunc(GLUTmotionCB motionFunc)
+{
+  /* Hack.  Some window managers (4Dwm by default) will mask
+     motion events if the client is not selecting for button
+     press and release events. So we select for press and
+     release events too (being careful to use reference
+     counting).  */
+  if (__glutCurrentWindow->motion) {
+    if (!motionFunc) {
+      /* previous mouseFunc being disabled */
+      __glutCurrentWindow->buttonUses--;
+      __glutChangeWindowEventMask(
+        ButtonPressMask | ButtonReleaseMask,
+        __glutCurrentWindow->buttonUses > 0);
+    }
+  } else {
+    if (motionFunc) {
+      /* Previously no mouseFunc, new one being installed. */
+      __glutCurrentWindow->buttonUses++;
+      __glutChangeWindowEventMask(
+        ButtonPressMask | ButtonReleaseMask, True);
+    }
+  }
+  /* Real work of selecting for passive mouse motion.  */
+  __glutChangeWindowEventMask(
+    Button1MotionMask | Button2MotionMask | Button3MotionMask,
+    motionFunc != NULL);
+  __glutCurrentWindow->motion = motionFunc;
+}
+
+void GLUTAPIENTRY
+glutPassiveMotionFunc(GLUTpassiveCB passiveMotionFunc)
+{
+  __glutChangeWindowEventMask(PointerMotionMask,
+    passiveMotionFunc != NULL);
+
+  /* Passive motion also requires watching enters and leaves so
+     that a fake passive motion event can be generated on an
+     enter. */
+  __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask,
+    __glutCurrentWindow->entry != NULL || passiveMotionFunc != NULL);
+
+  __glutCurrentWindow->passive = passiveMotionFunc;
+}
+
+void GLUTAPIENTRY
+glutEntryFunc(GLUTentryCB entryFunc)
+{
+  __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask,
+    entryFunc != NULL || __glutCurrentWindow->passive);
+  __glutCurrentWindow->entry = entryFunc;
+  if (!entryFunc) {
+    __glutCurrentWindow->entryState = -1;
+  }
+}
+
+void GLUTAPIENTRY
+glutWindowStatusFunc(GLUTwindowStatusCB windowStatusFunc)
+{
+  __glutChangeWindowEventMask(VisibilityChangeMask,
+    windowStatusFunc != NULL);
+  __glutCurrentWindow->windowStatus = windowStatusFunc;
+  if (!windowStatusFunc) {
+    /* Make state invalid. */
+    __glutCurrentWindow->visState = -1;
+  }
+}
+
+static void GLUTCALLBACK
+visibilityHelper(int status)
+{
+  if (status == GLUT_HIDDEN || status == GLUT_FULLY_COVERED)
+    __glutCurrentWindow->visibility(GLUT_NOT_VISIBLE);
+  else
+    __glutCurrentWindow->visibility(GLUT_VISIBLE);
+}
+
+
+void GLUTAPIENTRY
+glutVisibilityFunc(GLUTvisibilityCB visibilityFunc)
+{
+  __glutCurrentWindow->visibility = visibilityFunc;
+
+  if (visibilityFunc)
+  {    glutWindowStatusFunc(visibilityHelper);
+#if defined(__OS2PM__)
+       if(__glutCurrentWindow->shownState >= 0)
+       {  visibilityHelper(__glutCurrentWindow->shownState);
+       }
+#endif
+  }
+  else
+    glutWindowStatusFunc(NULL);
+}
+
+void GLUTAPIENTRY
+glutReshapeFunc(GLUTreshapeCB reshapeFunc)
+{
+  if (reshapeFunc) {
+    __glutCurrentWindow->reshape = reshapeFunc;
+  } else {
+    __glutCurrentWindow->reshape = __glutDefaultReshape;
+  }
+}
 \1a
\ No newline at end of file
index ffa31c021c0b9bc6c1ac8c0c813db2f641115070..456d19a8c18a06dd068c5194f892e8b6f8a70b21 100644 (file)
-\r
-/* Copyright (c) Mark J. Kilgard, 1994.  */\r
-\r
-/* This program is freely distributable without licensing fees\r
-   and is provided without guarantee or warrantee expressed or\r
-   implied. This program is -not- in the public domain. */\r
-\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <assert.h>\r
-\r
-\r
-#include "glutint.h"\r
-\r
-/* CENTRY */\r
-void GLUTAPIENTRY\r
-glutSetWindowTitle(const char *title)\r
-{\r
-#if defined(__OS2PM__)\r
-   __glutSetWindowText(__glutCurrentWindow->win, (char *)title);\r
-\r
-#else\r
-  XTextProperty textprop;\r
-\r
-  assert(!__glutCurrentWindow->parent);\r
-  IGNORE_IN_GAME_MODE();\r
-  textprop.value = (unsigned char *) title;\r
-  textprop.encoding = XA_STRING;\r
-  textprop.format = 8;\r
-  textprop.nitems = strlen(title);\r
-  XSetWMName(__glutDisplay,\r
-    __glutCurrentWindow->win, &textprop);\r
-  XFlush(__glutDisplay);\r
-#endif\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutSetIconTitle(const char *title)\r
-{\r
-#if defined(__OS2PM__)\r
-//todo ?\r
-#else\r
-\r
-  XTextProperty textprop;\r
-\r
-  assert(!__glutCurrentWindow->parent);\r
-  IGNORE_IN_GAME_MODE();\r
-  textprop.value = (unsigned char *) title;\r
-  textprop.encoding = XA_STRING;\r
-  textprop.format = 8;\r
-  textprop.nitems = strlen(title);\r
-  XSetWMIconName(__glutDisplay,\r
-    __glutCurrentWindow->win, &textprop);\r
-  XFlush(__glutDisplay);\r
-#endif\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutPositionWindow(int x, int y)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  __glutCurrentWindow->desiredX = x;\r
-  __glutCurrentWindow->desiredY = y;\r
-  __glutCurrentWindow->desiredConfMask |= CWX | CWY;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutReshapeWindow(int w, int h)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  if (w <= 0 || h <= 0)\r
-    __glutWarning("glutReshapeWindow: non-positive width or height not allowed");\r
-\r
-  __glutCurrentWindow->desiredWidth = w;\r
-  __glutCurrentWindow->desiredHeight = h;\r
-  __glutCurrentWindow->desiredConfMask |= CWWidth | CWHeight;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutPopWindow(void)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  __glutCurrentWindow->desiredStack = Above;\r
-  __glutCurrentWindow->desiredConfMask |= CWStackMode;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutPushWindow(void)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  __glutCurrentWindow->desiredStack = Below;\r
-  __glutCurrentWindow->desiredConfMask |= CWStackMode;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutIconifyWindow(void)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  assert(!__glutCurrentWindow->parent);\r
-  __glutCurrentWindow->desiredMapState = IconicState;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutShowWindow(void)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  __glutCurrentWindow->desiredMapState = NormalState;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutHideWindow(void)\r
-{\r
-  IGNORE_IN_GAME_MODE();\r
-  __glutCurrentWindow->desiredMapState = WithdrawnState;\r
-  __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);\r
-}\r
-\r
-/* ENDCENTRY */\r
+
+/* Copyright (c) Mark J. Kilgard, 1994.  */
+
+/* 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. */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+
+#include "glutint.h"
+
+/* CENTRY */
+void GLUTAPIENTRY
+glutSetWindowTitle(const char *title)
+{
+#if defined(__OS2PM__)
+   __glutSetWindowText(__glutCurrentWindow->win, (char *)title);
+
+#else
+  XTextProperty textprop;
+
+  assert(!__glutCurrentWindow->parent);
+  IGNORE_IN_GAME_MODE();
+  textprop.value = (unsigned char *) title;
+  textprop.encoding = XA_STRING;
+  textprop.format = 8;
+  textprop.nitems = strlen(title);
+  XSetWMName(__glutDisplay,
+    __glutCurrentWindow->win, &textprop);
+  XFlush(__glutDisplay);
+#endif
+}
+
+void GLUTAPIENTRY
+glutSetIconTitle(const char *title)
+{
+#if defined(__OS2PM__)
+//todo ?
+#else
+
+  XTextProperty textprop;
+
+  assert(!__glutCurrentWindow->parent);
+  IGNORE_IN_GAME_MODE();
+  textprop.value = (unsigned char *) title;
+  textprop.encoding = XA_STRING;
+  textprop.format = 8;
+  textprop.nitems = strlen(title);
+  XSetWMIconName(__glutDisplay,
+    __glutCurrentWindow->win, &textprop);
+  XFlush(__glutDisplay);
+#endif
+}
+
+void GLUTAPIENTRY
+glutPositionWindow(int x, int y)
+{
+  IGNORE_IN_GAME_MODE();
+  __glutCurrentWindow->desiredX = x;
+  __glutCurrentWindow->desiredY = y;
+  __glutCurrentWindow->desiredConfMask |= CWX | CWY;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
+}
+
+void GLUTAPIENTRY
+glutReshapeWindow(int w, int h)
+{
+  IGNORE_IN_GAME_MODE();
+  if (w <= 0 || h <= 0)
+    __glutWarning("glutReshapeWindow: non-positive width or height not allowed");
+
+  __glutCurrentWindow->desiredWidth = w;
+  __glutCurrentWindow->desiredHeight = h;
+  __glutCurrentWindow->desiredConfMask |= CWWidth | CWHeight;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
+}
+
+void GLUTAPIENTRY
+glutPopWindow(void)
+{
+  IGNORE_IN_GAME_MODE();
+  __glutCurrentWindow->desiredStack = Above;
+  __glutCurrentWindow->desiredConfMask |= CWStackMode;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
+}
+
+void GLUTAPIENTRY
+glutPushWindow(void)
+{
+  IGNORE_IN_GAME_MODE();
+  __glutCurrentWindow->desiredStack = Below;
+  __glutCurrentWindow->desiredConfMask |= CWStackMode;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
+}
+
+void GLUTAPIENTRY
+glutIconifyWindow(void)
+{
+  IGNORE_IN_GAME_MODE();
+  assert(!__glutCurrentWindow->parent);
+  __glutCurrentWindow->desiredMapState = IconicState;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
+}
+
+void GLUTAPIENTRY
+glutShowWindow(void)
+{
+  IGNORE_IN_GAME_MODE();
+  __glutCurrentWindow->desiredMapState = NormalState;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
+}
+
+void GLUTAPIENTRY
+glutHideWindow(void)
+{
+  IGNORE_IN_GAME_MODE();
+  __glutCurrentWindow->desiredMapState = WithdrawnState;
+  __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
+}
+
+/* ENDCENTRY */
 \1a
\ No newline at end of file
index ca345ea05b5ca65649b9984d3019ca199b0e0936..5e135bc17e91f16d22ad7fb351f0ed76327b2ea8 100644 (file)
-/* os2_glx.c */\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <malloc.h>\r
-#include "gl/gl.h"\r
-#include "WarpGL.h"\r
-#include "GL/os2mesa.h"\r
-\r
-#define POKA 0\r
-/* global current HDC */\r
-\r
-XVisualInfo *wglDescribePixelFormat(int iPixelFormat);\r
-\r
-extern HDC XHDC;\r
-extern HWND XHWND;\r
-//extern HPS hpsCurrent;\r
-extern HAB   hab;      /* PM anchor block handle */\r
-\r
-GLXContext\r
-glXCreateContext(HPS hps, XVisualInfo * visinfo,\r
-  GLXContext share, Bool direct)\r
-{\r
-  /* KLUDGE: GLX really expects a display pointer to be passed\r
-     in as the first parameter, but Win32 needs an HDC instead,\r
-     so BE SURE that the global XHDC is set before calling this\r
-     routine. */\r
-  HGLRC context;\r
-\r
-  context = wglCreateContext(XHDC,hps,hab);\r
-\r
-\r
-  /* Since direct rendering is implicit, the direct flag is\r
-     ignored. */\r
-\r
-  return context;\r
-}\r
-\r
-\r
-int\r
-glXGetConfig(XVisualInfo * visual, int attrib, int *value)\r
-{\r
-  if (!visual)\r
-    return GLX_BAD_VISUAL;\r
-\r
-  switch (attrib) {\r
-  case GLX_USE_GL:\r
-    if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) {\r
-      /* XXX Brad's Matrix Millenium II has problems creating\r
-         color index windows in 24-bit mode (lead to GDI crash)\r
-         and 32-bit mode (lead to black window).  The cColorBits\r
-         filed of the PIXELFORMATDESCRIPTOR returned claims to\r
-         have 24 and 32 bits respectively of color indices. 2^24\r
-         and 2^32 are ridiculously huge writable colormaps.\r
-         Assume that if we get back a color index\r
-         PIXELFORMATDESCRIPTOR with 24 or more bits, the\r
-         PIXELFORMATDESCRIPTOR doesn't really work and skip it.\r
-         -mjk */\r
-      if (visual->iPixelType == PFD_TYPE_COLORINDEX\r
-        && visual->cColorBits >= 24) {\r
-        *value = 0;\r
-      } else {\r
-       *value = 1;\r
-      }\r
-    } else {\r
-      *value = 0;\r
-    }\r
-    break;\r
-  case GLX_BUFFER_SIZE:\r
-    /* KLUDGE: if we're RGBA, return the number of bits/pixel,\r
-       otherwise, return 8 (we guessed at 256 colors in CI\r
-       mode). */\r
-    if (visual->iPixelType == PFD_TYPE_RGBA)\r
-      *value = visual->cColorBits;\r
-    else\r
-      *value = 8;\r
-    break;\r
-  case GLX_LEVEL:\r
-    /* The bReserved flag of the pfd contains the\r
-       overlay/underlay info. */\r
-    *value = visual->bReserved;\r
-    break;\r
-  case GLX_RGBA:\r
-    *value = visual->iPixelType == PFD_TYPE_RGBA;\r
-    break;\r
-  case GLX_DOUBLEBUFFER:\r
-    *value = visual->dwFlags & PFD_DOUBLEBUFFER;\r
-    break;\r
-  case GLX_STEREO:\r
-    *value = visual->dwFlags & PFD_STEREO;\r
-    break;\r
-  case GLX_AUX_BUFFERS:\r
-    *value = visual->cAuxBuffers;\r
-    break;\r
-  case GLX_RED_SIZE:\r
-    *value = visual->cRedBits;\r
-    break;\r
-  case GLX_GREEN_SIZE:\r
-    *value = visual->cGreenBits;\r
-    break;\r
-  case GLX_BLUE_SIZE:\r
-    *value = visual->cBlueBits;\r
-    break;\r
-  case GLX_ALPHA_SIZE:\r
-    *value = visual->cAlphaBits;\r
-    break;\r
-  case GLX_DEPTH_SIZE:\r
-    *value = visual->cDepthBits;\r
-    break;\r
-  case GLX_STENCIL_SIZE:\r
-    *value = visual->cStencilBits;\r
-    break;\r
-  case GLX_ACCUM_RED_SIZE:\r
-    *value = visual->cAccumRedBits;\r
-    break;\r
-  case GLX_ACCUM_GREEN_SIZE:\r
-    *value = visual->cAccumGreenBits;\r
-    break;\r
-  case GLX_ACCUM_BLUE_SIZE:\r
-    *value = visual->cAccumBlueBits;\r
-    break;\r
-  case GLX_ACCUM_ALPHA_SIZE:\r
-    *value = visual->cAccumAlphaBits;\r
-    break;\r
-#if POKA == 100\r
-#endif /*  POKA == 100 */\r
-  default:\r
-    return GLX_BAD_ATTRIB;\r
-  }\r
-  return 0;\r
-}\r
-\r
-\r
-XVisualInfo * glXChooseVisual(int mode)\r
-{  int imode = 2;\r
-   if(mode & GLUT_DOUBLE)\r
-            imode = 1;\r
-   return\r
-         wglDescribePixelFormat(imode);\r
-}\r
-\r
-\r
-#if POKA\r
-#endif /* POKA */\r
-\r
+/* os2_glx.c */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "gl/gl.h"
+#include "WarpGL.h"
+#include "GL/os2mesa.h"
+
+#define POKA 0
+/* global current HDC */
+
+XVisualInfo *wglDescribePixelFormat(int iPixelFormat);
+
+extern HDC XHDC;
+extern HWND XHWND;
+//extern HPS hpsCurrent;
+extern HAB   hab;      /* PM anchor block handle */
+
+GLXContext
+glXCreateContext(HPS hps, XVisualInfo * visinfo,
+  GLXContext share, Bool direct)
+{
+  /* KLUDGE: GLX really expects a display pointer to be passed
+     in as the first parameter, but Win32 needs an HDC instead,
+     so BE SURE that the global XHDC is set before calling this
+     routine. */
+  HGLRC context;
+
+  context = wglCreateContext(XHDC,hps,hab);
+
+
+  /* Since direct rendering is implicit, the direct flag is
+     ignored. */
+
+  return context;
+}
+
+
+int
+glXGetConfig(XVisualInfo * visual, int attrib, int *value)
+{
+  if (!visual)
+    return GLX_BAD_VISUAL;
+
+  switch (attrib) {
+  case GLX_USE_GL:
+    if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) {
+      /* XXX Brad's Matrix Millenium II has problems creating
+         color index windows in 24-bit mode (lead to GDI crash)
+         and 32-bit mode (lead to black window).  The cColorBits
+         filed of the PIXELFORMATDESCRIPTOR returned claims to
+         have 24 and 32 bits respectively of color indices. 2^24
+         and 2^32 are ridiculously huge writable colormaps.
+         Assume that if we get back a color index
+         PIXELFORMATDESCRIPTOR with 24 or more bits, the
+         PIXELFORMATDESCRIPTOR doesn't really work and skip it.
+         -mjk */
+      if (visual->iPixelType == PFD_TYPE_COLORINDEX
+        && visual->cColorBits >= 24) {
+        *value = 0;
+      } else {
+       *value = 1;
+      }
+    } else {
+      *value = 0;
+    }
+    break;
+  case GLX_BUFFER_SIZE:
+    /* KLUDGE: if we're RGBA, return the number of bits/pixel,
+       otherwise, return 8 (we guessed at 256 colors in CI
+       mode). */
+    if (visual->iPixelType == PFD_TYPE_RGBA)
+      *value = visual->cColorBits;
+    else
+      *value = 8;
+    break;
+  case GLX_LEVEL:
+    /* The bReserved flag of the pfd contains the
+       overlay/underlay info. */
+    *value = visual->bReserved;
+    break;
+  case GLX_RGBA:
+    *value = visual->iPixelType == PFD_TYPE_RGBA;
+    break;
+  case GLX_DOUBLEBUFFER:
+    *value = visual->dwFlags & PFD_DOUBLEBUFFER;
+    break;
+  case GLX_STEREO:
+    *value = visual->dwFlags & PFD_STEREO;
+    break;
+  case GLX_AUX_BUFFERS:
+    *value = visual->cAuxBuffers;
+    break;
+  case GLX_RED_SIZE:
+    *value = visual->cRedBits;
+    break;
+  case GLX_GREEN_SIZE:
+    *value = visual->cGreenBits;
+    break;
+  case GLX_BLUE_SIZE:
+    *value = visual->cBlueBits;
+    break;
+  case GLX_ALPHA_SIZE:
+    *value = visual->cAlphaBits;
+    break;
+  case GLX_DEPTH_SIZE:
+    *value = visual->cDepthBits;
+    break;
+  case GLX_STENCIL_SIZE:
+    *value = visual->cStencilBits;
+    break;
+  case GLX_ACCUM_RED_SIZE:
+    *value = visual->cAccumRedBits;
+    break;
+  case GLX_ACCUM_GREEN_SIZE:
+    *value = visual->cAccumGreenBits;
+    break;
+  case GLX_ACCUM_BLUE_SIZE:
+    *value = visual->cAccumBlueBits;
+    break;
+  case GLX_ACCUM_ALPHA_SIZE:
+    *value = visual->cAccumAlphaBits;
+    break;
+#if POKA == 100
+#endif /*  POKA == 100 */
+  default:
+    return GLX_BAD_ATTRIB;
+  }
+  return 0;
+}
+
+
+XVisualInfo * glXChooseVisual(int mode)
+{  int imode = 2;
+   if(mode & GLUT_DOUBLE)
+            imode = 1;
+   return
+         wglDescribePixelFormat(imode);
+}
+
+
+#if POKA
+#endif /* POKA */
+
 \1a
\ No newline at end of file
index 4eef308e5a950cde7e1cf2281aaafd2715b4235f..56f2cdef8b2b101ae7524b69f4ed324fdeab9d96 100644 (file)
-\r
-/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */\r
-/* Copyright (c) Nate Robins, 1997. */\r
-\r
-/* This program is freely distributable without licensing fees\r
-   and is provided without guarantee or warrantee expressed or\r
-   implied. This program is -not- in the public domain. */\r
-\r
-/* This file completely re-implements glut_menu.c and glut_menu2.c\r
-   for Win32.  Note that neither glut_menu.c nor glut_menu2.c are\r
-   compiled into Win32 GLUT. */\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <stdio.h>\r
-#include <errno.h>\r
-#include <assert.h>\r
-\r
-#include "glutint.h"\r
-\r
-void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);\r
-//GLUTmenu *__glutMappedMenu;\r
-//GLUTwindow *__glutMenuWindow;\r
-GLUTmenuItem *__glutItemSelected;\r
-unsigned __glutMenuButton;\r
-\r
-static GLUTmenu **menuList = NULL;\r
-static int menuListSize = 0;\r
-static UINT uniqueMenuHandler = 1;\r
-\r
-/* DEPRICATED, use glutMenuStatusFunc instead. */\r
-void GLUTAPIENTRY\r
-glutMenuStateFunc(GLUTmenuStateCB menuStateFunc)\r
-{\r
-  __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc)\r
-{\r
-  __glutMenuStatusFunc = menuStatusFunc;\r
-}\r
-\r
-void\r
-__glutSetMenu(GLUTmenu * menu)\r
-{\r
-  __glutCurrentMenu = menu;\r
-}\r
-\r
-static void\r
-unmapMenu(GLUTmenu * menu)\r
-{\r
-  if (menu->cascade) {\r
-    unmapMenu(menu->cascade);\r
-    menu->cascade = NULL;\r
-  }\r
-  menu->anchor = NULL;\r
-  menu->highlighted = NULL;\r
-}\r
-\r
-void\r
-__glutFinishMenu(Window win, int x, int y)\r
-{\r
-\r
-  unmapMenu(__glutMappedMenu);\r
-\r
-  /* XXX Put in a GdiFlush just in case.  Probably unnecessary. -mjk  */\r
-//  GdiFlush();\r
-\r
-  if (__glutMenuStatusFunc) {\r
-    __glutSetWindow(__glutMenuWindow);\r
-    __glutSetMenu(__glutMappedMenu);\r
-\r
-    /* Setting __glutMappedMenu to NULL permits operations that\r
-       change menus or destroy the menu window again. */\r
-    __glutMappedMenu = NULL;\r
-\r
-    __glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y);\r
-  }\r
-  /* Setting __glutMappedMenu to NULL permits operations that\r
-     change menus or destroy the menu window again. */\r
-  __glutMappedMenu = NULL;\r
-\r
-  /* If an item is selected and it is not a submenu trigger,\r
-     generate menu callback. */\r
-  if (__glutItemSelected && !__glutItemSelected->isTrigger) {\r
-    __glutSetWindow(__glutMenuWindow);\r
-    /* When menu callback is triggered, current menu should be\r
-       set to the callback menu. */\r
-    __glutSetMenu(__glutItemSelected->menu);\r
-    __glutItemSelected->menu->select(__glutItemSelected->value);\r
-  }\r
-  __glutMenuWindow = NULL;\r
-}\r
-\r
-static void\r
-mapMenu(GLUTmenu * menu, int x, int y)\r
-{\r
-//todo\r
-//  TrackPopupMenu((HMENU) menu->win, TPM_LEFTALIGN |\r
-//    (__glutMenuButton == TPM_RIGHTBUTTON) ? TPM_RIGHTBUTTON : TPM_LEFTBUTTON,\r
-//    x, y, 0, __glutCurrentWindow->win, NULL);\r
-}\r
-\r
-void\r
-__glutStartMenu(GLUTmenu * menu, GLUTwindow * window,\r
-               int x, int y, int x_win, int y_win)\r
-{\r
-  assert(__glutMappedMenu == NULL);\r
-  __glutMappedMenu = menu;\r
-  __glutMenuWindow = window;\r
-  __glutItemSelected = NULL;\r
-  if (__glutMenuStatusFunc) {\r
-    __glutSetMenu(menu);\r
-    __glutSetWindow(window);\r
-    __glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win);\r
-  }\r
-  mapMenu(menu, x, y);\r
-}\r
-\r
-GLUTmenuItem *\r
-__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique)\r
-{\r
-  GLUTmenuItem *item;\r
-  int i;\r
-\r
-  i = menu->num;\r
-  item = menu->list;\r
-  while (item) {\r
-    if (item->unique == unique) {\r
-      return item;\r
-    }\r
-    if (item->isTrigger) {\r
-      GLUTmenuItem *subitem;\r
-      subitem = __glutGetUniqueMenuItem(menuList[item->value], unique);\r
-      if (subitem) {\r
-        return subitem;\r
-      }\r
-    }\r
-    i--;\r
-    item = item->next;\r
-  }\r
-  return NULL;\r
-}\r
-\r
-GLUTmenuItem *\r
-__glutGetMenuItem(GLUTmenu * menu, Window win, int *which)\r
-{\r
-  GLUTmenuItem *item;\r
-  int i;\r
-\r
-  i = menu->num;\r
-  item = menu->list;\r
-  while (item) {\r
-    if (item->win == win) {\r
-      *which = i;\r
-      return item;\r
-    }\r
-    if (item->isTrigger) {\r
-      GLUTmenuItem *subitem;\r
-\r
-      subitem = __glutGetMenuItem(menuList[item->value],\r
-        win, which);\r
-      if (subitem) {\r
-        return subitem;\r
-      }\r
-    }\r
-    i--;\r
-    item = item->next;\r
-  }\r
-  return NULL;\r
-}\r
-\r
-GLUTmenu *\r
-__glutGetMenu(Window win)\r
-{\r
-  GLUTmenu *menu;\r
-\r
-  menu = __glutMappedMenu;\r
-  while (menu) {\r
-    if (win == menu->win) {\r
-      return menu;\r
-    }\r
-    menu = menu->cascade;\r
-  }\r
-  return NULL;\r
-}\r
-\r
-GLUTmenu *\r
-__glutGetMenuByNum(int menunum)\r
-{\r
-  if (menunum < 1 || menunum > menuListSize) {\r
-    return NULL;\r
-  }\r
-  return menuList[menunum - 1];\r
-}\r
-\r
-static int\r
-getUnusedMenuSlot(void)\r
-{\r
-  int i;\r
-\r
-  /* Look for allocated, unused slot. */\r
-  for (i = 0; i < menuListSize; i++) {\r
-    if (!menuList[i]) {\r
-      return i;\r
-    }\r
-  }\r
-  /* Allocate a new slot. */\r
-  menuListSize++;\r
-  if (menuList) {\r
-    menuList = (GLUTmenu **)\r
-      realloc(menuList, menuListSize * sizeof(GLUTmenu *));\r
-  } else {\r
-    /* XXX Some realloc's do not correctly perform a malloc\r
-       when asked to perform a realloc on a NULL pointer,\r
-       though the ANSI C library spec requires this. */\r
-    menuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *));\r
-  }\r
-  if (!menuList) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  menuList[menuListSize - 1] = NULL;\r
-  return menuListSize - 1;\r
-}\r
-\r
-static void\r
-menuModificationError(void)\r
-{\r
-  /* XXX Remove the warning after GLUT 3.0. */\r
-  __glutWarning("The following is a new check for GLUT 3.0; update your code.");\r
-  __glutFatalError("menu manipulation not allowed while menus in use.");\r
-}\r
-\r
-int GLUTAPIENTRY\r
-glutCreateMenu(GLUTselectCB selectFunc)\r
-{\r
-  GLUTmenu *menu;\r
-  int menuid;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  menuid = getUnusedMenuSlot();\r
-  menu = (GLUTmenu *) malloc(sizeof(GLUTmenu));\r
-  if (!menu) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  menu->id = menuid;\r
-  menu->num = 0;\r
-  menu->submenus = 0;\r
-  menu->select = selectFunc;\r
-  menu->list = NULL;\r
-  menu->cascade = NULL;\r
-  menu->highlighted = NULL;\r
-  menu->anchor = NULL;\r
-//todo\r
-//  menu->win = (HWND) CreatePopupMenu();\r
-  menuList[menuid] = menu;\r
-  __glutSetMenu(menu);\r
-  return menuid + 1;\r
-}\r
-\r
-\r
-void GLUTAPIENTRY\r
-glutDestroyMenu(int menunum)\r
-{\r
-  GLUTmenu *menu = __glutGetMenuByNum(menunum);\r
-  GLUTmenuItem *item, *next;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  assert(menu->id == menunum - 1);\r
-//todo  DestroyMenu( (HMENU) menu->win);\r
-  menuList[menunum - 1] = NULL;\r
-  /* free all menu entries */\r
-  item = menu->list;\r
-  while (item) {\r
-    assert(item->menu == menu);\r
-    next = item->next;\r
-    free(item->label);\r
-    free(item);\r
-    item = next;\r
-  }\r
-  if (__glutCurrentMenu == menu) {\r
-    __glutCurrentMenu = NULL;\r
-  }\r
-  free(menu);\r
-}\r
-\r
-int GLUTAPIENTRY\r
-glutGetMenu(void)\r
-{\r
-  if (__glutCurrentMenu) {\r
-    return __glutCurrentMenu->id + 1;\r
-  } else {\r
-    return 0;\r
-  }\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutSetMenu(int menuid)\r
-{\r
-  GLUTmenu *menu;\r
-\r
-  if (menuid < 1 || menuid > menuListSize) {\r
-    __glutWarning("glutSetMenu attempted on bogus menu.");\r
-    return;\r
-  }\r
-  menu = menuList[menuid - 1];\r
-  if (!menu) {\r
-    __glutWarning("glutSetMenu attempted on bogus menu.");\r
-    return;\r
-  }\r
-  __glutSetMenu(menu);\r
-}\r
-\r
-static void\r
-setMenuItem(GLUTmenuItem * item, const char *label,\r
-           int value, Bool isTrigger)\r
-{\r
-  GLUTmenu *menu;\r
-\r
-  menu = item->menu;\r
-  item->label = __glutStrdup(label);\r
-  if (!item->label) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  item->isTrigger = isTrigger;\r
-  item->len = (int) strlen(label);\r
-  item->value = value;\r
-  item->unique = uniqueMenuHandler++;\r
-//todo\r
-//  if (isTrigger) {\r
-//    AppendMenu((HMENU) menu->win, MF_POPUP, (UINT)item->win, label);\r
-//  } else {\r
-//    AppendMenu((HMENU) menu->win, MF_STRING, item->unique, label);\r
-//  }\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutAddMenuEntry(const char *label, int value)\r
-{\r
-  GLUTmenuItem *entry;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));\r
-  if (!entry) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  entry->menu = __glutCurrentMenu;\r
-  setMenuItem(entry, label, value, FALSE);\r
-  __glutCurrentMenu->num++;\r
-  entry->next = __glutCurrentMenu->list;\r
-  __glutCurrentMenu->list = entry;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutAddSubMenu(const char *label, int menu)\r
-{\r
-  GLUTmenuItem *submenu;\r
-  GLUTmenu     *popupmenu;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));\r
-  if (!submenu) {\r
-    __glutFatalError("out of memory.");\r
-  }\r
-  __glutCurrentMenu->submenus++;\r
-  submenu->menu = __glutCurrentMenu;\r
-  popupmenu = __glutGetMenuByNum(menu);\r
-  if (popupmenu) {\r
-    submenu->win = popupmenu->win;\r
-  }\r
-  setMenuItem(submenu, label, /* base 0 */ menu - 1, TRUE);\r
-  __glutCurrentMenu->num++;\r
-  submenu->next = __glutCurrentMenu->list;\r
-  __glutCurrentMenu->list = submenu;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutChangeToMenuEntry(int num, const char *label, int value)\r
-{\r
-  GLUTmenuItem *item;\r
-  int i;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  i = __glutCurrentMenu->num;\r
-  item = __glutCurrentMenu->list;\r
-  while (item) {\r
-    if (i == num) {\r
-      if (item->isTrigger) {\r
-        /* If changing a submenu trigger to a menu entry, we\r
-           need to account for submenus.  */\r
-        item->menu->submenus--;\r
-       /* Nuke the Win32 menu. */\r
-//todo\r
-//       DestroyMenu((HMENU) item->win);\r
-      }\r
-      free(item->label);\r
-\r
-      item->label = strdup(label);\r
-      if (!item->label)\r
-       __glutFatalError("out of memory");\r
-      item->isTrigger = FALSE;\r
-      item->len = (int) strlen(label);\r
-      item->value = value;\r
-      item->unique = uniqueMenuHandler++;\r
-//todo\r
-//      ModifyMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1,\r
-//        MF_BYPOSITION | MFT_STRING, item->unique, label);\r
-\r
-      return;\r
-    }\r
-    i--;\r
-    item = item->next;\r
-  }\r
-  __glutWarning("Current menu has no %d item.", num);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutChangeToSubMenu(int num, const char *label, int menu)\r
-{\r
-  GLUTmenu *popupmenu;\r
-  GLUTmenuItem *item;\r
-  int i;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  i = __glutCurrentMenu->num;\r
-  item = __glutCurrentMenu->list;\r
-  while (item) {\r
-    if (i == num) {\r
-      if (!item->isTrigger) {\r
-        /* If changing a menu entry to as submenu trigger, we\r
-           need to account for submenus.  */\r
-        item->menu->submenus++;\r
-//todo\r
-//       item->win = (HWND) CreatePopupMenu();\r
-      }\r
-      free(item->label);\r
-\r
-      item->label = strdup(label);\r
-      if (!item->label)\r
-       __glutFatalError("out of memory");\r
-      item->isTrigger = TRUE;\r
-      item->len = (int) strlen(label);\r
-      item->value = menu - 1;\r
-      item->unique = uniqueMenuHandler++;\r
-      popupmenu = __glutGetMenuByNum(menu);\r
-      if (popupmenu)\r
-       item->win = popupmenu->win;\r
-//todo\r
-//      ModifyMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1,\r
-//        MF_BYPOSITION | MF_POPUP, (UINT) item->win, label);\r
-      return;\r
-    }\r
-    i--;\r
-    item = item->next;\r
-  }\r
-  __glutWarning("Current menu has no %d item.", num);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutRemoveMenuItem(int num)\r
-{\r
-  GLUTmenuItem *item, **prev;\r
-  int i;\r
-\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  i = __glutCurrentMenu->num;\r
-  prev = &__glutCurrentMenu->list;\r
-  item = __glutCurrentMenu->list;\r
-  while (item) {\r
-    if (i == num) {\r
-      /* Found the menu item in list to remove. */\r
-      __glutCurrentMenu->num--;\r
-\r
-      /* Patch up menu's item list. */\r
-      *prev = item->next;\r
-//todo\r
-//      RemoveMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION);\r
-\r
-      free(item->label);\r
-      free(item);\r
-      return;\r
-    }\r
-    i--;\r
-    prev = &item->next;\r
-    item = item->next;\r
-  }\r
-  __glutWarning("Current menu has no %d item.", num);\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutAttachMenu(int button)\r
-{\r
-  if (__glutCurrentWindow == __glutGameModeWindow) {\r
-    __glutWarning("cannot attach menus in game mode.");\r
-    return;\r
-  }\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  if (__glutCurrentWindow->menu[button] < 1) {\r
-    __glutCurrentWindow->buttonUses++;\r
-  }\r
-  __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1;\r
-}\r
-\r
-void GLUTAPIENTRY\r
-glutDetachMenu(int button)\r
-{\r
-  if (__glutMappedMenu) {\r
-    menuModificationError();\r
-  }\r
-  if (__glutCurrentWindow->menu[button] > 0) {\r
-    __glutCurrentWindow->buttonUses--;\r
-    __glutCurrentWindow->menu[button] = 0;\r
-  }\r
-}\r
-\r
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
+/* Copyright (c) Nate Robins, 1997. */
+
+/* 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. */
+
+/* This file completely re-implements glut_menu.c and glut_menu2.c
+   for Win32.  Note that neither glut_menu.c nor glut_menu2.c are
+   compiled into Win32 GLUT. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "glutint.h"
+
+void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);
+//GLUTmenu *__glutMappedMenu;
+//GLUTwindow *__glutMenuWindow;
+GLUTmenuItem *__glutItemSelected;
+unsigned __glutMenuButton;
+
+static GLUTmenu **menuList = NULL;
+static int menuListSize = 0;
+static UINT uniqueMenuHandler = 1;
+
+/* DEPRICATED, use glutMenuStatusFunc instead. */
+void GLUTAPIENTRY
+glutMenuStateFunc(GLUTmenuStateCB menuStateFunc)
+{
+  __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;
+}
+
+void GLUTAPIENTRY
+glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc)
+{
+  __glutMenuStatusFunc = menuStatusFunc;
+}
+
+void
+__glutSetMenu(GLUTmenu * menu)
+{
+  __glutCurrentMenu = menu;
+}
+
+static void
+unmapMenu(GLUTmenu * menu)
+{
+  if (menu->cascade) {
+    unmapMenu(menu->cascade);
+    menu->cascade = NULL;
+  }
+  menu->anchor = NULL;
+  menu->highlighted = NULL;
+}
+
+void
+__glutFinishMenu(Window win, int x, int y)
+{
+
+  unmapMenu(__glutMappedMenu);
+
+  /* XXX Put in a GdiFlush just in case.  Probably unnecessary. -mjk  */
+//  GdiFlush();
+
+  if (__glutMenuStatusFunc) {
+    __glutSetWindow(__glutMenuWindow);
+    __glutSetMenu(__glutMappedMenu);
+
+    /* Setting __glutMappedMenu to NULL permits operations that
+       change menus or destroy the menu window again. */
+    __glutMappedMenu = NULL;
+
+    __glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y);
+  }
+  /* Setting __glutMappedMenu to NULL permits operations that
+     change menus or destroy the menu window again. */
+  __glutMappedMenu = NULL;
+
+  /* If an item is selected and it is not a submenu trigger,
+     generate menu callback. */
+  if (__glutItemSelected && !__glutItemSelected->isTrigger) {
+    __glutSetWindow(__glutMenuWindow);
+    /* When menu callback is triggered, current menu should be
+       set to the callback menu. */
+    __glutSetMenu(__glutItemSelected->menu);
+    __glutItemSelected->menu->select(__glutItemSelected->value);
+  }
+  __glutMenuWindow = NULL;
+}
+
+static void
+mapMenu(GLUTmenu * menu, int x, int y)
+{
+//todo
+//  TrackPopupMenu((HMENU) menu->win, TPM_LEFTALIGN |
+//    (__glutMenuButton == TPM_RIGHTBUTTON) ? TPM_RIGHTBUTTON : TPM_LEFTBUTTON,
+//    x, y, 0, __glutCurrentWindow->win, NULL);
+}
+
+void
+__glutStartMenu(GLUTmenu * menu, GLUTwindow * window,
+               int x, int y, int x_win, int y_win)
+{
+  assert(__glutMappedMenu == NULL);
+  __glutMappedMenu = menu;
+  __glutMenuWindow = window;
+  __glutItemSelected = NULL;
+  if (__glutMenuStatusFunc) {
+    __glutSetMenu(menu);
+    __glutSetWindow(window);
+    __glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win);
+  }
+  mapMenu(menu, x, y);
+}
+
+GLUTmenuItem *
+__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique)
+{
+  GLUTmenuItem *item;
+  int i;
+
+  i = menu->num;
+  item = menu->list;
+  while (item) {
+    if (item->unique == unique) {
+      return item;
+    }
+    if (item->isTrigger) {
+      GLUTmenuItem *subitem;
+      subitem = __glutGetUniqueMenuItem(menuList[item->value], unique);
+      if (subitem) {
+        return subitem;
+      }
+    }
+    i--;
+    item = item->next;
+  }
+  return NULL;
+}
+
+GLUTmenuItem *
+__glutGetMenuItem(GLUTmenu * menu, Window win, int *which)
+{
+  GLUTmenuItem *item;
+  int i;
+
+  i = menu->num;
+  item = menu->list;
+  while (item) {
+    if (item->win == win) {
+      *which = i;
+      return item;
+    }
+    if (item->isTrigger) {
+      GLUTmenuItem *subitem;
+
+      subitem = __glutGetMenuItem(menuList[item->value],
+        win, which);
+      if (subitem) {
+        return subitem;
+      }
+    }
+    i--;
+    item = item->next;
+  }
+  return NULL;
+}
+
+GLUTmenu *
+__glutGetMenu(Window win)
+{
+  GLUTmenu *menu;
+
+  menu = __glutMappedMenu;
+  while (menu) {
+    if (win == menu->win) {
+      return menu;
+    }
+    menu = menu->cascade;
+  }
+  return NULL;
+}
+
+GLUTmenu *
+__glutGetMenuByNum(int menunum)
+{
+  if (menunum < 1 || menunum > menuListSize) {
+    return NULL;
+  }
+  return menuList[menunum - 1];
+}
+
+static int
+getUnusedMenuSlot(void)
+{
+  int i;
+
+  /* Look for allocated, unused slot. */
+  for (i = 0; i < menuListSize; i++) {
+    if (!menuList[i]) {
+      return i;
+    }
+  }
+  /* Allocate a new slot. */
+  menuListSize++;
+  if (menuList) {
+    menuList = (GLUTmenu **)
+      realloc(menuList, menuListSize * sizeof(GLUTmenu *));
+  } else {
+    /* XXX Some realloc's do not correctly perform a malloc
+       when asked to perform a realloc on a NULL pointer,
+       though the ANSI C library spec requires this. */
+    menuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *));
+  }
+  if (!menuList) {
+    __glutFatalError("out of memory.");
+  }
+  menuList[menuListSize - 1] = NULL;
+  return menuListSize - 1;
+}
+
+static void
+menuModificationError(void)
+{
+  /* XXX Remove the warning after GLUT 3.0. */
+  __glutWarning("The following is a new check for GLUT 3.0; update your code.");
+  __glutFatalError("menu manipulation not allowed while menus in use.");
+}
+
+int GLUTAPIENTRY
+glutCreateMenu(GLUTselectCB selectFunc)
+{
+  GLUTmenu *menu;
+  int menuid;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  menuid = getUnusedMenuSlot();
+  menu = (GLUTmenu *) malloc(sizeof(GLUTmenu));
+  if (!menu) {
+    __glutFatalError("out of memory.");
+  }
+  menu->id = menuid;
+  menu->num = 0;
+  menu->submenus = 0;
+  menu->select = selectFunc;
+  menu->list = NULL;
+  menu->cascade = NULL;
+  menu->highlighted = NULL;
+  menu->anchor = NULL;
+//todo
+//  menu->win = (HWND) CreatePopupMenu();
+  menuList[menuid] = menu;
+  __glutSetMenu(menu);
+  return menuid + 1;
+}
+
+
+void GLUTAPIENTRY
+glutDestroyMenu(int menunum)
+{
+  GLUTmenu *menu = __glutGetMenuByNum(menunum);
+  GLUTmenuItem *item, *next;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  assert(menu->id == menunum - 1);
+//todo  DestroyMenu( (HMENU) menu->win);
+  menuList[menunum - 1] = NULL;
+  /* free all menu entries */
+  item = menu->list;
+  while (item) {
+    assert(item->menu == menu);
+    next = item->next;
+    free(item->label);
+    free(item);
+    item = next;
+  }
+  if (__glutCurrentMenu == menu) {
+    __glutCurrentMenu = NULL;
+  }
+  free(menu);
+}
+
+int GLUTAPIENTRY
+glutGetMenu(void)
+{
+  if (__glutCurrentMenu) {
+    return __glutCurrentMenu->id + 1;
+  } else {
+    return 0;
+  }
+}
+
+void GLUTAPIENTRY
+glutSetMenu(int menuid)
+{
+  GLUTmenu *menu;
+
+  if (menuid < 1 || menuid > menuListSize) {
+    __glutWarning("glutSetMenu attempted on bogus menu.");
+    return;
+  }
+  menu = menuList[menuid - 1];
+  if (!menu) {
+    __glutWarning("glutSetMenu attempted on bogus menu.");
+    return;
+  }
+  __glutSetMenu(menu);
+}
+
+static void
+setMenuItem(GLUTmenuItem * item, const char *label,
+           int value, Bool isTrigger)
+{
+  GLUTmenu *menu;
+
+  menu = item->menu;
+  item->label = __glutStrdup(label);
+  if (!item->label) {
+    __glutFatalError("out of memory.");
+  }
+  item->isTrigger = isTrigger;
+  item->len = (int) strlen(label);
+  item->value = value;
+  item->unique = uniqueMenuHandler++;
+//todo
+//  if (isTrigger) {
+//    AppendMenu((HMENU) menu->win, MF_POPUP, (UINT)item->win, label);
+//  } else {
+//    AppendMenu((HMENU) menu->win, MF_STRING, item->unique, label);
+//  }
+}
+
+void GLUTAPIENTRY
+glutAddMenuEntry(const char *label, int value)
+{
+  GLUTmenuItem *entry;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));
+  if (!entry) {
+    __glutFatalError("out of memory.");
+  }
+  entry->menu = __glutCurrentMenu;
+  setMenuItem(entry, label, value, FALSE);
+  __glutCurrentMenu->num++;
+  entry->next = __glutCurrentMenu->list;
+  __glutCurrentMenu->list = entry;
+}
+
+void GLUTAPIENTRY
+glutAddSubMenu(const char *label, int menu)
+{
+  GLUTmenuItem *submenu;
+  GLUTmenu     *popupmenu;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));
+  if (!submenu) {
+    __glutFatalError("out of memory.");
+  }
+  __glutCurrentMenu->submenus++;
+  submenu->menu = __glutCurrentMenu;
+  popupmenu = __glutGetMenuByNum(menu);
+  if (popupmenu) {
+    submenu->win = popupmenu->win;
+  }
+  setMenuItem(submenu, label, /* base 0 */ menu - 1, TRUE);
+  __glutCurrentMenu->num++;
+  submenu->next = __glutCurrentMenu->list;
+  __glutCurrentMenu->list = submenu;
+}
+
+void GLUTAPIENTRY
+glutChangeToMenuEntry(int num, const char *label, int value)
+{
+  GLUTmenuItem *item;
+  int i;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  i = __glutCurrentMenu->num;
+  item = __glutCurrentMenu->list;
+  while (item) {
+    if (i == num) {
+      if (item->isTrigger) {
+        /* If changing a submenu trigger to a menu entry, we
+           need to account for submenus.  */
+        item->menu->submenus--;
+       /* Nuke the Win32 menu. */
+//todo
+//       DestroyMenu((HMENU) item->win);
+      }
+      free(item->label);
+
+      item->label = strdup(label);
+      if (!item->label)
+       __glutFatalError("out of memory");
+      item->isTrigger = FALSE;
+      item->len = (int) strlen(label);
+      item->value = value;
+      item->unique = uniqueMenuHandler++;
+//todo
+//      ModifyMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1,
+//        MF_BYPOSITION | MFT_STRING, item->unique, label);
+
+      return;
+    }
+    i--;
+    item = item->next;
+  }
+  __glutWarning("Current menu has no %d item.", num);
+}
+
+void GLUTAPIENTRY
+glutChangeToSubMenu(int num, const char *label, int menu)
+{
+  GLUTmenu *popupmenu;
+  GLUTmenuItem *item;
+  int i;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  i = __glutCurrentMenu->num;
+  item = __glutCurrentMenu->list;
+  while (item) {
+    if (i == num) {
+      if (!item->isTrigger) {
+        /* If changing a menu entry to as submenu trigger, we
+           need to account for submenus.  */
+        item->menu->submenus++;
+//todo
+//       item->win = (HWND) CreatePopupMenu();
+      }
+      free(item->label);
+
+      item->label = strdup(label);
+      if (!item->label)
+       __glutFatalError("out of memory");
+      item->isTrigger = TRUE;
+      item->len = (int) strlen(label);
+      item->value = menu - 1;
+      item->unique = uniqueMenuHandler++;
+      popupmenu = __glutGetMenuByNum(menu);
+      if (popupmenu)
+       item->win = popupmenu->win;
+//todo
+//      ModifyMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1,
+//        MF_BYPOSITION | MF_POPUP, (UINT) item->win, label);
+      return;
+    }
+    i--;
+    item = item->next;
+  }
+  __glutWarning("Current menu has no %d item.", num);
+}
+
+void GLUTAPIENTRY
+glutRemoveMenuItem(int num)
+{
+  GLUTmenuItem *item, **prev;
+  int i;
+
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  i = __glutCurrentMenu->num;
+  prev = &__glutCurrentMenu->list;
+  item = __glutCurrentMenu->list;
+  while (item) {
+    if (i == num) {
+      /* Found the menu item in list to remove. */
+      __glutCurrentMenu->num--;
+
+      /* Patch up menu's item list. */
+      *prev = item->next;
+//todo
+//      RemoveMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION);
+
+      free(item->label);
+      free(item);
+      return;
+    }
+    i--;
+    prev = &item->next;
+    item = item->next;
+  }
+  __glutWarning("Current menu has no %d item.", num);
+}
+
+void GLUTAPIENTRY
+glutAttachMenu(int button)
+{
+  if (__glutCurrentWindow == __glutGameModeWindow) {
+    __glutWarning("cannot attach menus in game mode.");
+    return;
+  }
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  if (__glutCurrentWindow->menu[button] < 1) {
+    __glutCurrentWindow->buttonUses++;
+  }
+  __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1;
+}
+
+void GLUTAPIENTRY
+glutDetachMenu(int button)
+{
+  if (__glutMappedMenu) {
+    menuModificationError();
+  }
+  if (__glutCurrentWindow->menu[button] > 0) {
+    __glutCurrentWindow->buttonUses--;
+    __glutCurrentWindow->menu[button] = 0;
+  }
+}
+
 \1a
\ No newline at end of file
index e2d4ba9d55028942edcd1aa73f6e7251ef5dfc54..6ffe0d4624be220873cf7f89beb41c3db852e2c7 100644 (file)
-/* os2_winproc.c */\r
-\r
-\r
-#define INCL_DEV\r
-#include "WarpGL.h"\r
-#include "GL/os2mesa.h"\r
-\r
-\r
-#define  _MEERROR_H_\r
-#include <mmioos2.h>                   /* It is from MMPM toolkit           */\r
-#include <dive.h>\r
-#include <fourcc.h>\r
-\r
-\r
-#include "os2mesadef.h"\r
-#include "glutint.h"\r
-\r
-\r
-#define POKA 0\r
-\r
-#if POKA\r
-\r
-extern unsigned __glutMenuButton;\r
-extern GLUTidleCB __glutIdleFunc;\r
-extern GLUTtimer *__glutTimerList;\r
-extern void handleTimeouts(void);\r
-extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique);\r
-static HMENU __glutHMenu;\r
-\r
-#endif\r
-\r
-extern void _mesa_ResizeBuffersMESA( void );\r
-\r
-\r
-MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );\r
-MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );\r
-void updateWindowState(GLUTwindow *window, int visState);\r
-\r
-volatile extern HAB   hab;      /* PM anchor block handle         */\r
-volatile extern HPS   hpsCurrent;\r
-\r
-RECTL     rCtls[52];\r
-ULONG     ulNumRcls;\r
-\r
-MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )\r
-{   MRESULT rc;\r
-    rc = GlutWindowProc(hwnd, msg, mp1, mp2 );\r
-    return rc;\r
-}\r
-\r
-MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )\r
-{\r
-  HPS   hps = NULLHANDLE; /* presentation space handle */\r
-  GLUTwindow*   window;   /* GLUT window associated with message. */\r
-  GLUTmenu*     menu;     /* GLUT menu associated with message. */\r
-  RECTL rclClient;\r
-  POINTL point;\r
-  int button = -1,rc,key;\r
-\r
-\r
-/* Process the message. */\r
-\r
-   switch( msg )\r
-   {\r
-      case WM_CREATE:\r
-     {\r
-      SIZEL sizl = { 0L, 0L };\r
-      LONG  *alCaps;\r
-      HDC hdc;\r
-\r
-      /*+-----------------------------------------------------------------+*/\r
-      /*| The client window is being created.  Create the semaphore to    |*/\r
-      /*| control access to the presentation space.  Then create the      |*/\r
-      /*| thread that will draw the lines.                                |*/\r
-      /*+-----------------------------------------------------------------+*/\r
- //    DosCreateMutexSem( (PSZ)NULL, &hmtxPS, 0UL, FALSE );\r
-\r
-      hdc = WinOpenWindowDC(hwnd);\r
-\r
-      /*+-----------------------------------------------------------------+*/\r
-      /*| Create a non-cached presentation space.  We will not release    |*/\r
-      /*| this PS, as we will be Selecting a Palette to this PS and then  |*/\r
-      /*| animating the palette.  Upon releasing a PS the palette is no   |*/\r
-      /*| longer selected for obvious reasons.                            |*/\r
-      /*+-----------------------------------------------------------------+*/\r
-      hpsCurrent = GpiCreatePS( hab,\r
-                  hdc,\r
-                  &sizl,\r
-                  PU_PELS | GPIF_DEFAULT |\r
-                  GPIT_MICRO | GPIA_ASSOC );\r
-//      DevQueryCaps( hdc, lStart, lCount, alCaps );\r
-//      fPaletteCaps = alCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER;\r
-//      PaletteInit(3);\r
-       /* Â¯Â¥p¥¢®¤ hpsBuffer Â¢ p¥¦¨¬ RGB color table  */\r
-\r
-        GpiCreateLogColorTable(hpsCurrent,0 ,LCOLF_RGB,0,0,NULL);\r
-        GpiSetPattern(hpsCurrent,PATSYM_SOLID);\r
-        GpiSetPatternSet(hpsCurrent,LCID_DEFAULT);\r
-\r
-     }\r
-    break;\r
-\r
-         return 0;\r
-      case WM_CLOSE:\r
-        WinPostMsg( hwnd, WM_QUIT, NULL, NULL );\r
-\r
-        return 0;\r
-\r
-      case WM_PAINT:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window)\r
-    {\r
-       PWMC ctx;\r
-//   hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);\r
-    hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);\r
-       // blit Dive buffer to screen.\r
-\r
-     {\r
-         SWP    swp;            // Window position\r
-         POINTL pointl;         // Point to offset from Desktop\r
-\r
-             // Convert the point to offset from desktop lower left.\r
-             pointl.x = 0;\r
-             pointl.y = 0;\r
-             WinMapWindowPoints ( hwnd, HWND_DESKTOP, &pointl, 1 );\r
-\r
-\r
-//            ctx = window->ctx;\r
-//            ctx->xDiveScr = pointl.x;\r
-//            ctx->yDiveScr = pointl.y;\r
-      }\r
-//      rc = DiveBlitImage (ctx->hDive,\r
-//                          ctx->ulDiveBufferNumber,\r
-//                      DIVE_BUFFER_SCREEN );\r
-//\r
-\r
-        if (window->win == hwnd) {\r
-          __glutPostRedisplay(window, GLUT_REPAIR_WORK);\r
-        } else if (window->overlay && window->overlay->win == hwnd) {\r
-         __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);\r
-        }\r
-        WinEndPaint(hps);\r
-    } else {\r
-\r
-        hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);\r
-        WinFillRect(hps, &rclClient, CLR_WHITE);\r
-        WinEndPaint(hps);\r
-    }\r
-        break;\r
-\r
-    case WM_VRNDISABLED:\r
-\r
-//           pwinData->fDataInProcess = TRUE;\r
-//           DiveSetupBlitter ( pwinData->hDive, 0 );\r
-//           pwinData->fVrnDisabled = TRUE;\r
-        break;\r
-\r
-    case WM_VRNENABLED:\r
-      {    HRGN      hrgn;      /* Region handle  */\r
-           RGNRECT   rgnCtl;    /* Processing control structure  */\r
-//           RECTL     rCtls[52];\r
-//           ULONG     ulNumRcls;\r
-\r
-//            pwinData->fDataInProcess = TRUE;\r
-            hps = WinGetPS ( hwnd );\r
-            if ( !hps )\r
-                  break;\r
-            hrgn = GpiCreateRegion ( hps, 0L, NULL );\r
-            if ( hrgn )\r
-            {  /* NOTE: If mp1 is zero, then this was just a move message.\r
-               ** Illustrate the visible region on a WM_VRNENABLE.\r
-               */\r
-               WinQueryVisibleRegion ( hwnd, hrgn );\r
-               rgnCtl.ircStart     = 0;\r
-               rgnCtl.crc          = 50;\r
-               rgnCtl.ulDirection  = 1;\r
-\r
-               /* Get the all ORed rectangles */\r
-               if ( GpiQueryRegionRects ( hps, hrgn, NULL,\r
-                                          &rgnCtl, rCtls) )\r
-               {\r
-                  ulNumRcls = rgnCtl.crcReturned;\r
-\r
-                  /* Now find the window position and size, relative to parent.\r
-                  */\r
-//                  WinQueryWindowPos ( pwinData->hwndClient, &pwinData->swp );\r
-\r
-//                  rcl.xLeft   = 0;\r
-//                  rcl.yBottom = 0;\r
-\r
-                  /* Convert the point to offset from desktop lower left.\r
-                  */\r
-//                  pointl.x = pwinData->swp.x;\r
-//                  pointl.y = pwinData->swp.y;\r
-\r
-//                  WinMapWindowPoints ( pwinData->hwndFrame,\r
-//                                       HWND_DESKTOP, &pointl, 1 );\r
-\r
-//                  pwinData->cxWindowPos = pointl.x;\r
-//                  pwinData->cyWindowPos = pointl.y;\r
-\r
-               }\r
-               GpiDestroyRegion( hps, hrgn );\r
-            }\r
-            WinReleasePS( hps );\r
-\r
-      }\r
-        break;\r
-\r
-  case WM_SIZE:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window)\r
-    {  int width,height;\r
-       width = SHORT1FROMMP(mp2);\r
-      height = SHORT2FROMMP(mp2);\r
-      if (width != window->width || height != window->height) {\r
-#if 0  /* Win32 GLUT does not support overlays for now. */\r
-       if (window->overlay) {\r
-         XResizeWindow(__glutDisplay, window->overlay->win, width, height);\r
-       }\r
-#endif\r
-       window->width = width;\r
-       window->height = height;\r
-       __glutSetWindow(window);\r
-       if(width <= 0 || height <= 0)\r
-                            break;\r
-       _mesa_ResizeBuffersMESA();\r
-\r
-       /* Do not execute OpenGL out of sequence with respect\r
-          to the SetWindowPos request! */\r
-       window->reshape(width, height);\r
-       window->forceReshape = FALSE;\r
-       /* A reshape should be considered like posting a\r
-          repair request. */\r
-       __glutPostRedisplay(window, GLUT_REPAIR_WORK);\r
-      }\r
-    }\r
-    return 0;\r
-  case WM_SHOW:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-       int visState;\r
-       visState = SHORT1FROMMP( mp1 );\r
-       updateWindowState(window, visState);\r
-    }\r
-    return 0;\r
-\r
-  case WM_ACTIVATE:\r
-    window = __glutGetWindow(hwnd);\r
-//    /* Make sure we re-select the correct palette if needed. */\r
-//    if (LOWORD(wParam)) {\r
-//      PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);\r
-//    }\r
-    if (window) {\r
-       int visState;\r
-       visState = SHORT1FROMMP( mp1 );\r
-       updateWindowState(window, visState);\r
-    }\r
-    return 0;\r
-\r
-  case WM_CHAR:\r
-  { USHORT fsflags;\r
-    window = __glutGetWindow(hwnd);\r
-    if (!window) {\r
-      break;\r
-    }\r
-    fsflags = SHORT1FROMMP(mp1);\r
-/* ?? */\r
-    if((fsflags & KC_KEYUP) )  /* Â¨Â£Â­Â®p¨p㥬 Â®Ã¢Â¦Â Ã¢Â¨Â¥ ÂªÂ­Â®Â¯ÂªÂ¨, p¥ £¨p㥬 Ã¢Â®Â«Ã¬ÂªÂ® Â­Â  Â­Â Â¦Â Ã¢Â¨Â¥  */\r
-            break;\r
-///////////////////////////////////////////////////\r
-   if(!(fsflags & KC_CHAR) )\r
-   {\r
-        if (!(fsflags & KC_VIRTUALKEY))\r
-                             break;\r
-        key = 0;\r
-         /* Get the virtual key from mp2.       */\r
-         switch (SHORT2FROMMP(mp2))\r
-         {\r
-/* directional keys */\r
-          case VK_LEFT:  key = GLUT_KEY_LEFT;  break;\r
-          case VK_UP:    key = GLUT_KEY_UP;    break;\r
-          case VK_RIGHT: key = GLUT_KEY_RIGHT; break;\r
-          case VK_DOWN:  key = GLUT_KEY_DOWN;  break;\r
-\r
-          case VK_PAGEUP:  key = GLUT_KEY_PAGE_UP;    break;\r
-          case VK_PAGEDOWN:key = GLUT_KEY_PAGE_DOWN;  break;\r
-          case VK_HOME:    key = GLUT_KEY_HOME;break;\r
-          case VK_END:     key = GLUT_KEY_END; break;\r
-          case VK_INSERT:  key = GLUT_KEY_INSERT;     break;\r
-\r
-/* function keys */\r
-          case VK_F1 : key = GLUT_KEY_F1;  break;\r
-          case VK_F2 : key = GLUT_KEY_F2; break;\r
-          case VK_F3 : key = GLUT_KEY_F3; break;\r
-          case VK_F4 : key = GLUT_KEY_F4; break;\r
-          case VK_F5 : key = GLUT_KEY_F5; break;\r
-          case VK_F6 : key = GLUT_KEY_F6; break;\r
-          case VK_F7 : key = GLUT_KEY_F7; break;\r
-          case VK_F8 : key = GLUT_KEY_F8; break;\r
-          case VK_F9 : key = GLUT_KEY_F9; break;\r
-          case VK_F10: key = GLUT_KEY_F10;break;\r
-          case VK_F11: key = GLUT_KEY_F11; break;\r
-          case VK_F12: key = GLUT_KEY_F12; break;\r
-          case VK_ESC:   key = -1; break;  /* Character codes */\r
-          case VK_SPACE: key = -1; break;\r
-          case VK_TAB:   key = -1; break;\r
-         }\r
-         if(!key)\r
-         {     break; /* Key Not implemented  */\r
-         }\r
-         if(key > 0)\r
-         {   if (!window->special)  /* Â­Â¥ Ã£Ã¡Ã¢Â Â­Â®Â¢Â«Â¥Â­Â® Â®Â¡Ã Â Â¡Â®Ã¢Ã§Â¨ÂªÂ  */\r
-                             break;\r
-\r
-               WinQueryPointerPos(HWND_DESKTOP,&point);\r
-               ScreenToClient(window->win, &point);\r
-               __glutSetWindow(window);\r
-               __glutModifierMask = 0;\r
-               if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)   /*  high order bit is on */\r
-                          __glutModifierMask |= ShiftMask;\r
-               if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)\r
-                          __glutModifierMask |= ControlMask;\r
-               if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)\r
-                          __glutModifierMask |= Mod1Mask;\r
-               window->special(key, point.x, point.y);\r
-               __glutModifierMask = (unsigned int) ~0;\r
-               return 0;\r
-         }\r
-\r
-   }\r
-/////////////////////////////////////////////////////\r
-    /* If  we are ignoring auto repeated key strokes for the window, bail. */\r
-    if (window->ignoreKeyRepeat && (CHAR3FROMMP(mp1)) )\r
-                                                   break;\r
-     if(!((unsigned char)SHORT1FROMMP(mp2))  )  /* Â¨Â£Â­Â®p¨p㥬 Â­Â¥Ã¡Â¨Â¬Â¢Â®Â«Ã¬Â­Ã«Â¥ ÂªÂ®Â¤Ã« */\r
-                                            break;\r
-    if (window->keyboard) {\r
-       WinQueryPointerPos(HWND_DESKTOP,&point);\r
-\r
-      ScreenToClient(window->win, &point);\r
-      __glutSetWindow(window);\r
-      __glutModifierMask = 0;\r
-      if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)   /*  high order bit is on */\r
-           __glutModifierMask |= ShiftMask;\r
-      if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)\r
-           __glutModifierMask |= ControlMask;\r
-      if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)\r
-           __glutModifierMask |= Mod1Mask;\r
-      window->keyboard((unsigned char)SHORT1FROMMP(mp2), point.x, point.y);\r
-      __glutModifierMask = (unsigned int) ~0;\r
-    }\r
-    return 0;\r
-  } /* endof case WM_CHAR: */\r
-////////////////////////////////////////////////\r
-  case WM_BUTTON1DOWN:\r
-    button = GLUT_LEFT_BUTTON;\r
-  case WM_BUTTON3DOWN:\r
-    if (button < 0)\r
-      button = GLUT_MIDDLE_BUTTON;\r
-  case WM_BUTTON2DOWN:\r
-    if (button < 0)\r
-      button = GLUT_RIGHT_BUTTON;\r
-    {  POINTS psh;\r
-       psh = *((POINTS *)&mp1);\r
-       point.x = psh.x;\r
-       point.y = psh.y;\r
-    }\r
-    /* finish the menu if we get a button down message (user must have\r
-       cancelled the menu). */\r
-    if (__glutMappedMenu) {\r
-      /* TODO: take this out once the menu on middle mouse stuff works\r
-        properly. */\r
-      if (button == GLUT_MIDDLE_BUTTON)\r
-       return 0;\r
- /* get current mouse pointer position */\r
-//      WinQueryPointerPos(HWND_DESKTOP,&point);\r
- /* map from desktop to client window */\r
-//      WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);\r
-      __glutItemSelected = NULL;\r
-      __glutFinishMenu(hwnd, point.x, point.y);\r
-      return 0;\r
-    }\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      window->buttonDownState = button+1;\r
-      menu = __glutGetMenuByNum(window->menu[button]);\r
-      if (menu) {\r
-//todo\r
-//   __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :\r
-//                           button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :\r
-//                           0x0001;\r
-//   __glutStartMenu(menu, window, point.x, point.y, x, y);\r
-      } else if (window->mouse) {\r
-\r
-       __glutSetWindow(window);\r
-       __glutModifierMask = 0;\r
-       if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)  /* < 0 = high order bit is on. */\r
-            __glutModifierMask |= ShiftMask;\r
-       if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)\r
-            __glutModifierMask |= ControlMask;\r
-       if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)\r
-            __glutModifierMask |= Mod1Mask;\r
-      window->mouse(button, GLUT_DOWN, point.x, point.y);\r
-      __glutModifierMask = (unsigned int)~0;\r
-      } else {\r
-   /* Stray mouse events.  Ignore. */\r
-      }\r
-    }\r
-    return 0;\r
-\r
-    break;\r
-/********************************************/\r
-  case WM_BUTTON1UP:\r
-    button = GLUT_LEFT_BUTTON;\r
-  case WM_BUTTON3UP:\r
-    if (button < 0)\r
-      button = GLUT_MIDDLE_BUTTON;\r
-  case WM_BUTTON2UP:\r
-    if (button < 0)\r
-      button = GLUT_RIGHT_BUTTON;\r
-    {  POINTS psh;\r
-       psh = *((POINTS *)&mp1);\r
-       point.x = psh.x;\r
-       point.y = psh.y;\r
-    }\r
-    /* Bail out if we're processing a menu. */\r
-    /* Bail out = Â¢Ã«Â¡Ã Â®Ã¡Â¨Ã¢Ã¬Ã¡Ã¯ Ã¡ Â¯Â Ã Â Ã¨Ã£Ã¢Â®Â¬   */\r
-    if (__glutMappedMenu) {\r
-      WinQueryPointerPos(HWND_DESKTOP,&point);\r
-      WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);\r
-      /* if we're getting the middle button up signal, then something\r
-        on the menu was selected. */\r
-      if (button == GLUT_MIDDLE_BUTTON) {\r
-       return 0;\r
-       /* For some reason, the code below always returns -1 even\r
-          though the point IS IN THE ITEM!  Therefore, just bail out if\r
-          we get a middle mouse up.  The user must select using the\r
-          left mouse button.  Stupid Win32. */\r
-#if 0\r
-       int item = MenuItemFromPoint(hwnd, __glutHMenu, point);\r
-       if (item != -1)\r
-         __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);\r
-       else\r
-         __glutItemSelected = NULL;\r
-       __glutFinishMenu(hwnd, point.x, point.y);\r
-#endif\r
-      } else {\r
-       __glutItemSelected = NULL;\r
-       __glutFinishMenu(hwnd, point.x, point.y);\r
-      }\r
-      return 0;\r
-    }\r
-\r
-    window = __glutGetWindow(hwnd);\r
-    if(window)\r
-           window->buttonDownState = 0;\r
-\r
-    if (window && window->mouse) {\r
-      __glutSetWindow(window);\r
-      __glutModifierMask = 0;\r
-      if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)   /* < 0 = high order bit is on */\r
-                          __glutModifierMask |= ShiftMask;\r
-      if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)\r
-   __glutModifierMask |= ControlMask;\r
-      if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)\r
-   __glutModifierMask |= Mod1Mask;\r
-      window->mouse(button, GLUT_UP, point.x, point.y);\r
-\r
-      __glutModifierMask = (unsigned int)~0;\r
-    } else {\r
-      /* Window might have been destroyed and all the\r
-    events for the window may not yet be received. */\r
-    }\r
-    return 0;\r
-\r
-\r
-    break;\r
-//////////////////////////////////////////////////\r
-  case WM_COMMAND:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window)\r
-    {   if (window->wm_command)\r
-            window->wm_command(hwnd,mp1,mp2);\r
-    }\r
-    break;\r
-\r
-  case WM_MOUSEMOVE:\r
-    if (!__glutMappedMenu) {\r
-      window = __glutGetWindow(hwnd);\r
-      if (window) {\r
-          /* If motion function registered _and_ buttons held *\r
-             down, call motion function...  */\r
-          {  POINTS psh;\r
-             psh = *((POINTS *)&mp1);\r
-             point.x = psh.x;\r
-             point.y = psh.y;\r
-          }\r
-\r
-         if (window->motion && window->buttonDownState) {\r
-           __glutSetWindow(window);\r
-           window->motion(point.x, point.y);\r
-         }\r
-   /* If passive motion function registered _and_\r
-      buttons not held down, call passive motion\r
-      function...  */\r
-         else if (window->passive && !window->buttonDownState) {\r
-           __glutSetWindow(window);\r
-           window->passive(point.x, point.y);\r
-         }\r
-      }\r
-    } else {\r
-      /* Motion events are thrown away when a pop up menu is\r
-    active. */\r
-    }\r
-    return 0;\r
-\r
-\r
-      default:\r
- /* For all other messages, let the default window procedure process them. */\r
-       return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );\r
-\r
-   } //endof switch( msg )\r
-   return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );\r
-//   return NULL;\r
-}\r
-\r
-void APIENTRY glutCommandFunc(GLUTcommandCB Func)\r
-{\r
-extern GLUTwindow *__glutCurrentWindow;\r
-    __glutCurrentWindow->wm_command = Func;\r
-}\r
-\r
-\r
-\r
-\r
-void\r
-updateWindowState(GLUTwindow *window, int visState)\r
-{\r
-  GLUTwindow* child;\r
-\r
-  /* XXX shownState and visState are the same in Win32. */\r
-  window->shownState = visState;\r
-  if (visState != window->visState) {\r
-    if (window->windowStatus) {\r
-      window->visState = visState;\r
-      __glutSetWindow(window);\r
-      window->windowStatus(visState);\r
-    }\r
-  }\r
-  /* Since Win32 only sends an activate for the toplevel window,\r
-     update the visibility for all the child windows. */\r
-  child = window->children;\r
-  while (child) {\r
-    updateWindowState(child, visState);\r
-    child = child->siblings;\r
-  }\r
-}\r
-\r
-#if POKA\r
-\r
-LONG WINAPI\r
-__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
-{\r
-  POINT         point;                 /* Point structure. */\r
-  PAINTSTRUCT   ps;                    /* Paint structure. */\r
-  LPMINMAXINFO  minmax;                        /* Minimum/maximum info structure. */\r
-  GLUTwindow*   window;                        /* GLUT window associated with message. */\r
-  GLUTmenu*     menu;                  /* GLUT menu associated with message. */\r
-  int x, y, width, height, key;\r
-  int button = -1;\r
-\r
-  switch(msg) {\r
-  case WM_CREATE:\r
-    return 0;\r
-  case WM_CLOSE:\r
-    PostQuitMessage(0);\r
-    return 0;\r
-#if 0\r
-  case WM_DESTROY:\r
-    /* XXX NVidia's NT OpenGL can have problems closing down\r
-       its OpenGL internal data structures if we just allow\r
-       the process to terminate without unbinding and deleting\r
-       the windows context.  Apparently, DirectDraw unloads\r
-       before OPENGL32.DLL in the close down sequence, but\r
-       NVidia's NT OpenGL needs DirectDraw to close down its\r
-       data structures. */\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      if (window->ctx) {\r
-        wglMakeCurrent(NULL, NULL);\r
-        wglDeleteContext(window->ctx);\r
-      }\r
-    }\r
-    return 0;\r
-#endif\r
-\r
-  case WM_SYSKEYUP:\r
-  case WM_KEYUP:\r
-    window = __glutGetWindow(hwnd);\r
-    if (!window) {\r
-      break;\r
-    }\r
-    /* Win32 is dumb and sends these messages only to the parent\r
-       window.  Therefore, find out if we're in a child window and\r
-       call the child windows keyboard callback if we are. */\r
-    if (window->parent) {\r
-      GetCursorPos(&point);\r
-      ScreenToClient(hwnd, &point);\r
-      hwnd = ChildWindowFromPoint(hwnd, point);\r
-      window = __glutGetWindow(hwnd);\r
-    }\r
-    if (window->specialUp || window->keyboardUp) {\r
-      GetCursorPos(&point);\r
-      ScreenToClient(window->win, &point);\r
-      __glutSetWindow(window);\r
-      __glutModifierMask = 0;\r
-      if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */\r
-       __glutModifierMask |= ShiftMask;\r
-      if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */\r
-       __glutModifierMask |= ControlMask;\r
-      if (GetKeyState(VK_MENU) < 0)\r
-       __glutModifierMask |= Mod1Mask;\r
-      switch (wParam) {\r
-      /* *INDENT-OFF* */\r
-      case VK_F1:     key = GLUT_KEY_F1; break;\r
-      case VK_F2:     key = GLUT_KEY_F2; break;\r
-      case VK_F3:     key = GLUT_KEY_F3; break;\r
-      case VK_F4:     key = GLUT_KEY_F4; break;\r
-      case VK_F5:     key = GLUT_KEY_F5; break;\r
-      case VK_F6:     key = GLUT_KEY_F6; break;\r
-      case VK_F7:     key = GLUT_KEY_F7; break;\r
-      case VK_F8:     key = GLUT_KEY_F8; break;\r
-      case VK_F9:     key = GLUT_KEY_F9; break;\r
-      case VK_F10:    key = GLUT_KEY_F10; break;\r
-      case VK_F11:    key = GLUT_KEY_F11; break;\r
-      case VK_F12:    key = GLUT_KEY_F12; break;\r
-      case VK_LEFT:   key = GLUT_KEY_LEFT; break;\r
-      case VK_UP:     key = GLUT_KEY_UP; break;\r
-      case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;\r
-      case VK_DOWN:   key = GLUT_KEY_DOWN; break;\r
-      case VK_PRIOR:  key = GLUT_KEY_PAGE_UP; break;\r
-      case VK_NEXT:   key = GLUT_KEY_PAGE_DOWN; break;\r
-      case VK_HOME:   key = GLUT_KEY_HOME; break;\r
-      case VK_END:    key = GLUT_KEY_END; break;\r
-      case VK_INSERT: key = GLUT_KEY_INSERT; break;\r
-      case VK_DELETE:\r
-        /* Delete is an ASCII character. */\r
-       if (window->keyboardUp) {\r
-         window->keyboardUp((unsigned char) 127, point.x, point.y);\r
-       }\r
-       return 0;\r
-      /* *INDENT-ON* */\r
-      default:\r
-       if (window->keyboardUp) {\r
-         key = MapVirtualKey(wParam, 2);  /* Map to ASCII. */\r
-         if (isascii(key) && (key != 0)) {\r
-\r
-           /* XXX Attempt to determine modified ASCII character\r
-              is quite incomplete.  Digits, symbols, CapsLock,\r
-              Ctrl, and numeric keypad are all ignored.  Fix this. */\r
-\r
-           if (!(__glutModifierMask & ShiftMask))\r
-             key = tolower(key);\r
-           window->keyboardUp((unsigned char) key, point.x, point.y);\r
-          }\r
-        }\r
-       __glutModifierMask = (unsigned int) ~0;\r
-       return 0;\r
-      }\r
-      if (window->specialUp) {\r
-        window->specialUp(key, point.x, point.y);\r
-      }\r
-      __glutModifierMask = (unsigned int) ~0;\r
-    }\r
-    return 0;\r
-\r
-  case WM_SYSCHAR:\r
-  case WM_CHAR:\r
-    window = __glutGetWindow(hwnd);\r
-    if (!window) {\r
-      break;\r
-    }\r
-\r
-    /* Bit 30 of lParam is set if key already held down.  If\r
-       we are ignoring auto repeated key strokes for the window, bail. */\r
-    if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {\r
-      break;\r
-    }\r
-\r
-    /* Win32 is dumb and sends these messages only to the parent\r
-       window.  Therefore, find out if we're in a child window and\r
-       call the child windows keyboard callback if we are. */\r
-    if (window->parent) {\r
-       GetCursorPos(&point);\r
-       ScreenToClient(hwnd, &point);\r
-       hwnd = ChildWindowFromPoint(hwnd, point);\r
-       window = __glutGetWindow(hwnd);\r
-    }\r
-    if (window->keyboard) {\r
-      GetCursorPos(&point);\r
-      ScreenToClient(window->win, &point);\r
-      __glutSetWindow(window);\r
-      __glutModifierMask = 0;\r
-      if (GetKeyState(VK_SHIFT) < 0)   /* < 0 = high order bit is on */\r
-       __glutModifierMask |= ShiftMask;\r
-      if (GetKeyState(VK_CONTROL) < 0)\r
-       __glutModifierMask |= ControlMask;\r
-      if (GetKeyState(VK_MENU) < 0)\r
-       __glutModifierMask |= Mod1Mask;\r
-      window->keyboard((unsigned char)wParam, point.x, point.y);\r
-      __glutModifierMask = (unsigned int) ~0;\r
-    }\r
-    return 0;\r
-\r
-  case WM_SYSKEYDOWN:\r
-  case WM_KEYDOWN:\r
-    window = __glutGetWindow(hwnd);\r
-    if (!window) {\r
-      break;\r
-    }\r
-\r
-    /* Bit 30 of lParam is set if key already held down.  If\r
-       we are ignoring auto repeated key strokes for the window, bail. */\r
-    if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {\r
-      break;\r
-    }\r
-\r
-    /* Win32 is dumb and sends these messages only to the parent\r
-       window.  Therefore, find out if we're in a child window and\r
-       call the child windows keyboard callback if we are. */\r
-    if (window->parent) {\r
-       GetCursorPos(&point);\r
-       ScreenToClient(hwnd, &point);\r
-       hwnd = ChildWindowFromPoint(hwnd, point);\r
-       window = __glutGetWindow(hwnd);\r
-    }\r
-    if (window->special) {\r
-      switch (wParam) {\r
-       /* *INDENT-OFF* */\r
-       /* function keys */\r
-       case VK_F1:     key = GLUT_KEY_F1; break;\r
-       case VK_F2:     key = GLUT_KEY_F2; break;\r
-       case VK_F3:     key = GLUT_KEY_F3; break;\r
-       case VK_F4:     key = GLUT_KEY_F4; break;\r
-       case VK_F5:     key = GLUT_KEY_F5; break;\r
-       case VK_F6:     key = GLUT_KEY_F6; break;\r
-       case VK_F7:     key = GLUT_KEY_F7; break;\r
-       case VK_F8:     key = GLUT_KEY_F8; break;\r
-       case VK_F9:     key = GLUT_KEY_F9; break;\r
-       case VK_F10:    key = GLUT_KEY_F10; break;\r
-       case VK_F11:    key = GLUT_KEY_F11; break;\r
-       case VK_F12:    key = GLUT_KEY_F12; break;\r
-       /* directional keys */\r
-       case VK_LEFT:   key = GLUT_KEY_LEFT; break;\r
-       case VK_UP:     key = GLUT_KEY_UP; break;\r
-       case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;\r
-       case VK_DOWN:   key = GLUT_KEY_DOWN; break;\r
-       /* *INDENT-ON* */\r
-\r
-       case VK_PRIOR:\r
-         /* VK_PRIOR is Win32's Page Up */\r
-         key = GLUT_KEY_PAGE_UP;\r
-         break;\r
-       case VK_NEXT:\r
-         /* VK_NEXT is Win32's Page Down */\r
-         key = GLUT_KEY_PAGE_DOWN;\r
-         break;\r
-       case VK_HOME:\r
-         key = GLUT_KEY_HOME;\r
-         break;\r
-       case VK_END:\r
-         key = GLUT_KEY_END;\r
-         break;\r
-       case VK_INSERT:\r
-         key = GLUT_KEY_INSERT;\r
-         break;\r
-        case VK_DELETE:\r
-         goto handleDelete;\r
-       default:\r
-         goto defproc;\r
-      }\r
-      GetCursorPos(&point);\r
-      ScreenToClient(window->win, &point);\r
-      __glutSetWindow(window);\r
-      __glutModifierMask = 0;\r
-      if (GetKeyState(VK_SHIFT) < 0)   /* < 0 = high order bit is on */\r
-       __glutModifierMask |= ShiftMask;\r
-      if (GetKeyState(VK_CONTROL) < 0)\r
-       __glutModifierMask |= ControlMask;\r
-      if (GetKeyState(VK_MENU) < 0)\r
-       __glutModifierMask |= Mod1Mask;\r
-      window->special(key, point.x, point.y);\r
-      __glutModifierMask = (unsigned int) ~0;\r
-    } else if (window->keyboard) {\r
-      /* Specially handle any keys that match ASCII values but\r
-         do not generate Windows WM_SYSCHAR or WM_CHAR messages. */\r
-      switch (wParam) {\r
-      case VK_DELETE:\r
-      handleDelete:\r
-        /* Delete is an ASCII character. */\r
-        GetCursorPos(&point);\r
-        ScreenToClient(window->win, &point);\r
-        __glutSetWindow(window);\r
-        __glutModifierMask = 0;\r
-        if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */\r
-          __glutModifierMask |= ShiftMask;\r
-        if (GetKeyState(VK_CONTROL) < 0)\r
-          __glutModifierMask |= ControlMask;\r
-        if (GetKeyState(VK_MENU) < 0)\r
-          __glutModifierMask |= Mod1Mask;\r
-       window->keyboard((unsigned char) 127, point.x, point.y);\r
-        __glutModifierMask = (unsigned int) ~0;\r
-       return 0;\r
-      default:\r
-        /* Let the following WM_SYSCHAR or WM_CHAR message generate\r
-          the keyboard callback. */\r
-        break;\r
-      }\r
-    }\r
-    return 0;\r
-\r
-  case WM_LBUTTONDOWN:\r
-    button = GLUT_LEFT_BUTTON;\r
-  case WM_MBUTTONDOWN:\r
-    if (button < 0)\r
-      button = GLUT_MIDDLE_BUTTON;\r
-  case WM_RBUTTONDOWN:\r
-    if (button < 0)\r
-      button = GLUT_RIGHT_BUTTON;\r
-\r
-    /* finish the menu if we get a button down message (user must have\r
-       cancelled the menu). */\r
-    if (__glutMappedMenu) {\r
-      /* TODO: take this out once the menu on middle mouse stuff works\r
-        properly. */\r
-      if (button == GLUT_MIDDLE_BUTTON)\r
-       return 0;\r
-      GetCursorPos(&point);\r
-      ScreenToClient(hwnd, &point);\r
-      __glutItemSelected = NULL;\r
-      __glutFinishMenu(hwnd, point.x, point.y);\r
-      return 0;\r
-    }\r
-\r
-    /* set the capture so we can get mouse events outside the window */\r
-    SetCapture(hwnd);\r
-\r
-    /* Win32 doesn't return the same numbers as X does when the mouse\r
-       goes beyond the upper or left side of the window.  roll the\r
-       Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */\r
-    x = LOWORD(lParam);\r
-    y = HIWORD(lParam);\r
-    if(x & 1 << 15) x -= (1 << 16);\r
-    if(y & 1 << 15) y -= (1 << 16);\r
-\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      menu = __glutGetMenuByNum(window->menu[button]);\r
-      if (menu) {\r
-       point.x = LOWORD(lParam); point.y = HIWORD(lParam);\r
-       ClientToScreen(window->win, &point);\r
-       __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :\r
-                           button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :\r
-                           0x0001;\r
-       __glutStartMenu(menu, window, point.x, point.y, x, y);\r
-      } else if (window->mouse) {\r
-\r
-        __glutSetWindow(window);\r
-       __glutModifierMask = 0;\r
-       if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on. */\r
-         __glutModifierMask |= ShiftMask;\r
-       if (GetKeyState(VK_CONTROL) < 0)\r
-         __glutModifierMask |= ControlMask;\r
-       if (GetKeyState(VK_MENU) < 0)\r
-         __glutModifierMask |= Mod1Mask;\r
-       window->mouse(button, GLUT_DOWN, x, y);\r
-       __glutModifierMask = (unsigned int)~0;\r
-      } else {\r
-       /* Stray mouse events.  Ignore. */\r
-      }\r
-    }\r
-    return 0;\r
-\r
-  case WM_LBUTTONUP:\r
-    button = GLUT_LEFT_BUTTON;\r
-  case WM_MBUTTONUP:\r
-    if (button < 0)\r
-      button = GLUT_MIDDLE_BUTTON;\r
-  case WM_RBUTTONUP:\r
-    if (button < 0)\r
-      button = GLUT_RIGHT_BUTTON;\r
-\r
-    /* Bail out if we're processing a menu. */\r
-    if (__glutMappedMenu) {\r
-      GetCursorPos(&point);\r
-      ScreenToClient(hwnd, &point);\r
-      /* if we're getting the middle button up signal, then something\r
-        on the menu was selected. */\r
-      if (button == GLUT_MIDDLE_BUTTON) {\r
-       return 0;\r
-       /* For some reason, the code below always returns -1 even\r
-          though the point IS IN THE ITEM!  Therefore, just bail out if\r
-          we get a middle mouse up.  The user must select using the\r
-          left mouse button.  Stupid Win32. */\r
-#if 0\r
-       int item = MenuItemFromPoint(hwnd, __glutHMenu, point);\r
-       if (item != -1)\r
-         __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);\r
-       else\r
-         __glutItemSelected = NULL;\r
-       __glutFinishMenu(hwnd, point.x, point.y);\r
-#endif\r
-      } else {\r
-       __glutItemSelected = NULL;\r
-       __glutFinishMenu(hwnd, point.x, point.y);\r
-      }\r
-      return 0;\r
-    }\r
-\r
-    /* Release the mouse capture. */\r
-    ReleaseCapture();\r
-\r
-    window = __glutGetWindow(hwnd);\r
-    if (window && window->mouse) {\r
-      /* Win32 doesn't return the same numbers as X does when the\r
-        mouse goes beyond the upper or left side of the window.  roll\r
-        the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */\r
-      x = LOWORD(lParam);\r
-      y = HIWORD(lParam);\r
-      if(x & 1 << 15) x -= (1 << 16);\r
-      if(y & 1 << 15) y -= (1 << 16);\r
-\r
-      __glutSetWindow(window);\r
-      __glutModifierMask = 0;\r
-      if (GetKeyState(VK_SHIFT) < 0)   /* < 0 = high order bit is on */\r
-       __glutModifierMask |= ShiftMask;\r
-      if (GetKeyState(VK_CONTROL) < 0)\r
-       __glutModifierMask |= ControlMask;\r
-      if (GetKeyState(VK_MENU) < 0)\r
-       __glutModifierMask |= Mod1Mask;\r
-      window->mouse(button, GLUT_UP, x, y);\r
-      __glutModifierMask = (unsigned int)~0;\r
-    } else {\r
-      /* Window might have been destroyed and all the\r
-        events for the window may not yet be received. */\r
-    }\r
-    return 0;\r
-\r
-  case WM_ENTERMENULOOP:\r
-    /* KLUDGE: create a timer that fires every 100 ms when we start a\r
-       menu so that we can still process the idle & timer events (that\r
-       way, the timers will fire during a menu pick and so will the\r
-       idle func. */\r
-    SetTimer(hwnd, 1, 1, NULL);\r
-    return 0;\r
-\r
-  case WM_TIMER:\r
-#if 0\r
-    /* If the timer id is 2, then this is the timer that is set up in\r
-       the main glut message processing loop, and we don't want to do\r
-       anything but acknowledge that we got it.  It is used to prevent\r
-       CPU spiking when an idle function is installed. */\r
-    if (wParam == 2)\r
-      return 0;\r
-#endif\r
-\r
-    /* only worry about the idle function and the timeouts, since\r
-       these are the only events we expect to process during\r
-       processing of a menu. */\r
-    /* we no longer process the idle functions (as outlined in the\r
-       README), since drawing can't be done until the menu has\r
-       finished...it's pretty lame when the animation goes on, but\r
-       doesn't update, so you get this weird jerkiness. */\r
-#if 0\r
-     if (__glutIdleFunc)\r
-       __glutIdleFunc();\r
-#endif\r
-    if (__glutTimerList)\r
-      handleTimeouts();\r
-    return 0;\r
-\r
-  case WM_EXITMENULOOP:\r
-    /* nuke the above created timer...we don't need it anymore, since\r
-       the menu is gone now. */\r
-    KillTimer(hwnd, 1);\r
-    return 0;\r
-\r
-  case WM_MENUSELECT:\r
-    if (lParam != 0)\r
-      __glutHMenu = (HMENU)lParam;\r
-    return 0;\r
-\r
-  case WM_COMMAND:\r
-    if (__glutMappedMenu) {\r
-      if (GetSubMenu(__glutHMenu, LOWORD(wParam)))\r
-       __glutItemSelected = NULL;\r
-      else\r
-       __glutItemSelected =\r
-         __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));\r
-      GetCursorPos(&point);\r
-      ScreenToClient(hwnd, &point);\r
-      __glutFinishMenu(hwnd, point.x, point.y);\r
-    }\r
-    return 0;\r
-\r
-  case WM_MOUSEMOVE:\r
-    if (!__glutMappedMenu) {\r
-      window = __glutGetWindow(hwnd);\r
-      if (window) {\r
-          /* If motion function registered _and_ buttons held *\r
-             down, call motion function...  */\r
-       x = LOWORD(lParam);\r
-       y = HIWORD(lParam);\r
-\r
-       /* Win32 doesn't return the same numbers as X does when the\r
-          mouse goes beyond the upper or left side of the window.\r
-          roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */\r
-       if(x & 1 << 15) x -= (1 << 16);\r
-       if(y & 1 << 15) y -= (1 << 16);\r
-\r
-       if (window->motion && wParam &\r
-            (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {\r
-         __glutSetWindow(window);\r
-         window->motion(x, y);\r
-       }\r
-       /* If passive motion function registered _and_\r
-          buttons not held down, call passive motion\r
-          function...  */\r
-       else if (window->passive &&\r
-                ((wParam &\r
-                  (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==\r
-                 0)) {\r
-         __glutSetWindow(window);\r
-         window->passive(x, y);\r
-       }\r
-      }\r
-    } else {\r
-      /* Motion events are thrown away when a pop up menu is\r
-        active. */\r
-    }\r
-    return 0;\r
-\r
-  case WM_GETMINMAXINFO:\r
-    /* this voodoo is brought to you by Win32 (again).  It allows the\r
-       window to be bigger than the screen, and smaller than 100x100\r
-       (although it doesn't seem to help the y minimum). */\r
-    minmax = (LPMINMAXINFO)lParam;\r
-    minmax->ptMaxSize.x = __glutScreenWidth;\r
-    minmax->ptMaxSize.y = __glutScreenHeight;\r
-    minmax->ptMinTrackSize.x = 0;\r
-    minmax->ptMinTrackSize.y = 0;\r
-    minmax->ptMaxTrackSize.x = __glutScreenWidth +\r
-      GetSystemMetrics(SM_CXSIZE) * 2;\r
-    minmax->ptMaxTrackSize.y = __glutScreenHeight +\r
-      GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);\r
-    return 0;\r
-\r
-  case WM_SIZE:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      width = LOWORD(lParam);\r
-      height = HIWORD(lParam);\r
-      if (width != window->width || height != window->height) {\r
-#if 0  /* Win32 GLUT does not support overlays for now. */\r
-       if (window->overlay) {\r
-         XResizeWindow(__glutDisplay, window->overlay->win, width, height);\r
-       }\r
-#endif\r
-       window->width = width;\r
-       window->height = height;\r
-       __glutSetWindow(window);\r
-       /* Do not execute OpenGL out of sequence with respect\r
-          to the SetWindowPos request! */\r
-       GdiFlush();\r
-       window->reshape(width, height);\r
-       window->forceReshape = FALSE;\r
-       /* A reshape should be considered like posting a\r
-          repair request. */\r
-       __glutPostRedisplay(window, GLUT_REPAIR_WORK);\r
-      }\r
-    }\r
-    return 0;\r
-\r
-  case WM_SETCURSOR:\r
-    /* If the cursor is not in the client area, then we want to send\r
-       this message to the default window procedure ('cause its\r
-       probably in the border or title, and we don't handle that\r
-       cursor.  otherwise, set our cursor.  Win32 makes us set the\r
-       cursor every time the mouse moves (DUMB!). */\r
-    if(LOWORD(lParam) != HTCLIENT) {\r
-      goto defproc;\r
-    }\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      __glutSetCursor(window);\r
-    }\r
-    /* TODO: check out the info in DevStudio on WM_SETCURSOR in the\r
-       DefaultAction section. */\r
-    return 1;\r
-\r
-  case WM_SETFOCUS:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      window->entryState = WM_SETFOCUS;\r
-      if (window->entry) {\r
-       __glutSetWindow(window);\r
-       window->entry(GLUT_ENTERED);\r
-       /* XXX Generation of fake passive notify?  See how much\r
-          work the X11 code does to support fake passive notify\r
-          callbacks. */\r
-      }\r
-      if (window->joystick && __glutCurrentWindow) {\r
-        if (__glutCurrentWindow->joyPollInterval > 0) {\r
-         MMRESULT result;\r
-\r
-         /* Because Win32 will only let one window capture the\r
-            joystick at a time, we must capture it when we get the\r
-            focus and release it when we lose the focus. */\r
-         result = joySetCapture(__glutCurrentWindow->win,\r
-           JOYSTICKID1, 0, TRUE);\r
-         if (result != JOYERR_NOERROR) {\r
-           return 0;\r
-          }\r
-         (void) joySetThreshold(JOYSTICKID1,\r
-            __glutCurrentWindow->joyPollInterval);\r
-        }\r
-      }\r
-    }\r
-    return 0;\r
-\r
-  case WM_KILLFOCUS:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window) {\r
-      window->entryState = WM_KILLFOCUS;\r
-      if (window->entry) {\r
-       __glutSetWindow(window);\r
-       window->entry(GLUT_LEFT);\r
-      }\r
-      if (window->joystick && __glutCurrentWindow) {\r
-       if (__glutCurrentWindow->joyPollInterval > 0) {\r
-         /* Because Win32 will only let one window capture the\r
-            joystick at a time, we must capture it when we get the\r
-            focus and release it when we lose the focus. */\r
-           (void) joyReleaseCapture(JOYSTICKID1);\r
-        }\r
-      }\r
-    }\r
-    return 0;\r
-  case WM_ACTIVATE:\r
-    window = __glutGetWindow(hwnd);\r
-    /* Make sure we re-select the correct palette if needed. */\r
-    if (LOWORD(wParam)) {\r
-      PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);\r
-    }\r
-    if (window) {\r
-      int visState;\r
-\r
-      /* HIWORD(wParam) is the minimized flag. */\r
-      visState = !HIWORD(wParam);\r
-      updateWindowState(window, visState);\r
-    }\r
-    return 0;\r
-\r
-  /* Colour Palette Management */\r
-  case WM_PALETTECHANGED:\r
-    if (hwnd == (HWND)wParam) {\r
-      /* Don't respond to the message that we sent! */\r
-      break;\r
-    }\r
-    /* fall through to WM_QUERYNEWPALETTE */\r
-\r
-  case WM_QUERYNEWPALETTE:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window && window->colormap) {\r
-      UnrealizeObject(window->colormap->cmap);\r
-      SelectPalette(window->hdc, window->colormap->cmap, FALSE);\r
-      RealizePalette(window->hdc);\r
-      return TRUE;\r
-    }\r
-    return FALSE;\r
-\r
-  case MM_JOY1MOVE:\r
-  case MM_JOY1ZMOVE:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window->joystick) {\r
-      JOYINFOEX jix;\r
-      int x, y, z;\r
-\r
-      /* Because WIN32 only supports messages for X, Y, and Z\r
-         translations, we must poll for the rest */\r
-      jix.dwSize = sizeof(jix);\r
-      jix.dwFlags = JOY_RETURNALL;\r
-      joyGetPosEx(JOYSTICKID1,&jix);\r
-\r
-#define SCALE(v)  ((int) ((v - 32767)/32.768))\r
-\r
-      /* Convert to integer for scaling. */\r
-      x = jix.dwXpos;\r
-      y = jix.dwYpos;\r
-      z = jix.dwZpos;\r
-      window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));\r
-\r
-      return TRUE;\r
-    }\r
-    return FALSE;\r
-  case MM_JOY1BUTTONDOWN:\r
-  case MM_JOY1BUTTONUP:\r
-    window = __glutGetWindow(hwnd);\r
-    if (window->joystick) {\r
-      JOYINFOEX jix;\r
-\r
-      /* Because WIN32 only supports messages for X, Y, and Z\r
-         translations, we must poll for the rest */\r
-      jix.dwSize = sizeof(jix);\r
-      jix.dwFlags = JOY_RETURNALL;\r
-      joyGetPosEx(JOYSTICKID1,&jix);\r
-\r
-      return TRUE;\r
-    }\r
-    return FALSE;\r
-\r
-#if 0\r
-  /* Miscellaneous messages (don't really need to enumerate them,\r
-     but it's good to know what you're not getting sometimes). */\r
-  case WM_DISPLAYCHANGE:\r
-    break;\r
-  case WM_NCHITTEST:\r
-    /* This event is generated by every mouse move event. */\r
-    goto defproc;\r
-  case WM_NCMOUSEMOVE:\r
-    goto defproc;\r
-  case WM_NCACTIVATE:\r
-    goto defproc;\r
-  case WM_NCPAINT:\r
-    goto defproc;\r
-  case WM_NCCALCSIZE:\r
-    goto defproc;\r
-  case WM_NCCREATE:\r
-    goto defproc;\r
-  case WM_NCDESTROY:\r
-    goto defproc;\r
-  case WM_NCLBUTTONDOWN:\r
-    goto defproc;\r
-  case WM_SETTEXT:\r
-    goto defproc;\r
-  case WM_GETTEXT:\r
-    goto defproc;\r
-  case WM_ACTIVATEAPP:\r
-    goto defproc;\r
-  case WM_GETICON:\r
-    goto defproc;\r
-  case WM_ERASEBKGND:\r
-    goto defproc;\r
-  case WM_WINDOWPOSCHANGING:\r
-    goto defproc;\r
-  case WM_WINDOWPOSCHANGED:\r
-    goto defproc;\r
-  case WM_MOUSEACTIVATE:\r
-    goto defproc;\r
-  case WM_SHOWWINDOW:\r
-    goto defproc;\r
-  case WM_MOVING:\r
-    goto defproc;\r
-  case WM_MOVE:\r
-    goto defproc;\r
-  case WM_KEYUP:\r
-    goto defproc;\r
-  case WM_CAPTURECHANGED:\r
-    goto defproc;\r
-  case WM_SYSCOMMAND:\r
-    goto defproc;\r
-  case WM_ENTERSIZEMOVE:\r
-    goto defproc;\r
-  case WM_ENTERIDLE:\r
-    goto defproc;\r
-#endif\r
-\r
-  default:\r
-    goto defproc;\r
-  }\r
-\r
-defproc:\r
-  return DefWindowProc(hwnd, msg, wParam, lParam);\r
-}\r
-\r
-#endif\r
-\r
-#if defined(__OS2PM__)\r
-Bool __glutSetWindowText(Window window, char *text)\r
-{\r
-  return WinSetWindowText(window, (PCSZ)text);\r
-\r
-}\r
-\r
-#endif\r
+/* os2_winproc.c */
+
+
+#define INCL_DEV
+#include "WarpGL.h"
+#include "GL/os2mesa.h"
+
+
+#define  _MEERROR_H_
+#include <mmioos2.h>                   /* It is from MMPM toolkit           */
+#include <dive.h>
+#include <fourcc.h>
+
+
+#include "os2mesadef.h"
+#include "glutint.h"
+
+
+#define POKA 0
+
+#if POKA
+
+extern unsigned __glutMenuButton;
+extern GLUTidleCB __glutIdleFunc;
+extern GLUTtimer *__glutTimerList;
+extern void handleTimeouts(void);
+extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique);
+static HMENU __glutHMenu;
+
+#endif
+
+extern void _mesa_ResizeBuffersMESA( void );
+
+
+MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
+MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
+void updateWindowState(GLUTwindow *window, int visState);
+
+volatile extern HAB   hab;      /* PM anchor block handle         */
+volatile extern HPS   hpsCurrent;
+
+RECTL     rCtls[52];
+ULONG     ulNumRcls;
+
+MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
+{   MRESULT rc;
+    rc = GlutWindowProc(hwnd, msg, mp1, mp2 );
+    return rc;
+}
+
+MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
+{
+  HPS   hps = NULLHANDLE; /* presentation space handle */
+  GLUTwindow*   window;   /* GLUT window associated with message. */
+  GLUTmenu*     menu;     /* GLUT menu associated with message. */
+  RECTL rclClient;
+  POINTL point;
+  int button = -1,rc,key;
+
+
+/* Process the message. */
+
+   switch( msg )
+   {
+      case WM_CREATE:
+     {
+      SIZEL sizl = { 0L, 0L };
+      LONG  *alCaps;
+      HDC hdc;
+
+      /*+-----------------------------------------------------------------+*/
+      /*| The client window is being created.  Create the semaphore to    |*/
+      /*| control access to the presentation space.  Then create the      |*/
+      /*| thread that will draw the lines.                                |*/
+      /*+-----------------------------------------------------------------+*/
+ //    DosCreateMutexSem( (PSZ)NULL, &hmtxPS, 0UL, FALSE );
+
+      hdc = WinOpenWindowDC(hwnd);
+
+      /*+-----------------------------------------------------------------+*/
+      /*| Create a non-cached presentation space.  We will not release    |*/
+      /*| this PS, as we will be Selecting a Palette to this PS and then  |*/
+      /*| animating the palette.  Upon releasing a PS the palette is no   |*/
+      /*| longer selected for obvious reasons.                            |*/
+      /*+-----------------------------------------------------------------+*/
+      hpsCurrent = GpiCreatePS( hab,
+                  hdc,
+                  &sizl,
+                  PU_PELS | GPIF_DEFAULT |
+                  GPIT_MICRO | GPIA_ASSOC );
+//      DevQueryCaps( hdc, lStart, lCount, alCaps );
+//      fPaletteCaps = alCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER;
+//      PaletteInit(3);
+       /* Â¯Â¥p¥¢®¤ hpsBuffer Â¢ p¥¦¨¬ RGB color table  */
+
+        GpiCreateLogColorTable(hpsCurrent,0 ,LCOLF_RGB,0,0,NULL);
+        GpiSetPattern(hpsCurrent,PATSYM_SOLID);
+        GpiSetPatternSet(hpsCurrent,LCID_DEFAULT);
+
+     }
+    break;
+
+         return 0;
+      case WM_CLOSE:
+        WinPostMsg( hwnd, WM_QUIT, NULL, NULL );
+
+        return 0;
+
+      case WM_PAINT:
+    window = __glutGetWindow(hwnd);
+    if (window)
+    {
+       PWMC ctx;
+//   hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
+    hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
+       // blit Dive buffer to screen.
+
+     {
+         SWP    swp;            // Window position
+         POINTL pointl;         // Point to offset from Desktop
+
+             // Convert the point to offset from desktop lower left.
+             pointl.x = 0;
+             pointl.y = 0;
+             WinMapWindowPoints ( hwnd, HWND_DESKTOP, &pointl, 1 );
+
+
+//            ctx = window->ctx;
+//            ctx->xDiveScr = pointl.x;
+//            ctx->yDiveScr = pointl.y;
+      }
+//      rc = DiveBlitImage (ctx->hDive,
+//                          ctx->ulDiveBufferNumber,
+//                      DIVE_BUFFER_SCREEN );
+//
+
+        if (window->win == hwnd) {
+          __glutPostRedisplay(window, GLUT_REPAIR_WORK);
+        } else if (window->overlay && window->overlay->win == hwnd) {
+         __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
+        }
+        WinEndPaint(hps);
+    } else {
+
+        hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
+        WinFillRect(hps, &rclClient, CLR_WHITE);
+        WinEndPaint(hps);
+    }
+        break;
+
+    case WM_VRNDISABLED:
+
+//           pwinData->fDataInProcess = TRUE;
+//           DiveSetupBlitter ( pwinData->hDive, 0 );
+//           pwinData->fVrnDisabled = TRUE;
+        break;
+
+    case WM_VRNENABLED:
+      {    HRGN      hrgn;      /* Region handle  */
+           RGNRECT   rgnCtl;    /* Processing control structure  */
+//           RECTL     rCtls[52];
+//           ULONG     ulNumRcls;
+
+//            pwinData->fDataInProcess = TRUE;
+            hps = WinGetPS ( hwnd );
+            if ( !hps )
+                  break;
+            hrgn = GpiCreateRegion ( hps, 0L, NULL );
+            if ( hrgn )
+            {  /* NOTE: If mp1 is zero, then this was just a move message.
+               ** Illustrate the visible region on a WM_VRNENABLE.
+               */
+               WinQueryVisibleRegion ( hwnd, hrgn );
+               rgnCtl.ircStart     = 0;
+               rgnCtl.crc          = 50;
+               rgnCtl.ulDirection  = 1;
+
+               /* Get the all ORed rectangles */
+               if ( GpiQueryRegionRects ( hps, hrgn, NULL,
+                                          &rgnCtl, rCtls) )
+               {
+                  ulNumRcls = rgnCtl.crcReturned;
+
+                  /* Now find the window position and size, relative to parent.
+                  */
+//                  WinQueryWindowPos ( pwinData->hwndClient, &pwinData->swp );
+
+//                  rcl.xLeft   = 0;
+//                  rcl.yBottom = 0;
+
+                  /* Convert the point to offset from desktop lower left.
+                  */
+//                  pointl.x = pwinData->swp.x;
+//                  pointl.y = pwinData->swp.y;
+
+//                  WinMapWindowPoints ( pwinData->hwndFrame,
+//                                       HWND_DESKTOP, &pointl, 1 );
+
+//                  pwinData->cxWindowPos = pointl.x;
+//                  pwinData->cyWindowPos = pointl.y;
+
+               }
+               GpiDestroyRegion( hps, hrgn );
+            }
+            WinReleasePS( hps );
+
+      }
+        break;
+
+  case WM_SIZE:
+    window = __glutGetWindow(hwnd);
+    if (window)
+    {  int width,height;
+       width = SHORT1FROMMP(mp2);
+      height = SHORT2FROMMP(mp2);
+      if (width != window->width || height != window->height) {
+#if 0  /* Win32 GLUT does not support overlays for now. */
+       if (window->overlay) {
+         XResizeWindow(__glutDisplay, window->overlay->win, width, height);
+       }
+#endif
+       window->width = width;
+       window->height = height;
+       __glutSetWindow(window);
+       if(width <= 0 || height <= 0)
+                            break;
+       _mesa_ResizeBuffersMESA();
+
+       /* Do not execute OpenGL out of sequence with respect
+          to the SetWindowPos request! */
+       window->reshape(width, height);
+       window->forceReshape = FALSE;
+       /* A reshape should be considered like posting a
+          repair request. */
+       __glutPostRedisplay(window, GLUT_REPAIR_WORK);
+      }
+    }
+    return 0;
+  case WM_SHOW:
+    window = __glutGetWindow(hwnd);
+    if (window) {
+       int visState;
+       visState = SHORT1FROMMP( mp1 );
+       updateWindowState(window, visState);
+    }
+    return 0;
+
+  case WM_ACTIVATE:
+    window = __glutGetWindow(hwnd);
+//    /* Make sure we re-select the correct palette if needed. */
+//    if (LOWORD(wParam)) {
+//      PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
+//    }
+    if (window) {
+       int visState;
+       visState = SHORT1FROMMP( mp1 );
+       updateWindowState(window, visState);
+    }
+    return 0;
+
+  case WM_CHAR:
+  { USHORT fsflags;
+    window = __glutGetWindow(hwnd);
+    if (!window) {
+      break;
+    }
+    fsflags = SHORT1FROMMP(mp1);
+/* ?? */
+    if((fsflags & KC_KEYUP) )  /* Â¨Â£Â­Â®p¨p㥬 Â®Ã¢Â¦Â Ã¢Â¨Â¥ ÂªÂ­Â®Â¯ÂªÂ¨, p¥ £¨p㥬 Ã¢Â®Â«Ã¬ÂªÂ® Â­Â  Â­Â Â¦Â Ã¢Â¨Â¥  */
+            break;
+///////////////////////////////////////////////////
+   if(!(fsflags & KC_CHAR) )
+   {
+        if (!(fsflags & KC_VIRTUALKEY))
+                             break;
+        key = 0;
+         /* Get the virtual key from mp2.       */
+         switch (SHORT2FROMMP(mp2))
+         {
+/* directional keys */
+          case VK_LEFT:  key = GLUT_KEY_LEFT;  break;
+          case VK_UP:    key = GLUT_KEY_UP;    break;
+          case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
+          case VK_DOWN:  key = GLUT_KEY_DOWN;  break;
+
+          case VK_PAGEUP:  key = GLUT_KEY_PAGE_UP;    break;
+          case VK_PAGEDOWN:key = GLUT_KEY_PAGE_DOWN;  break;
+          case VK_HOME:    key = GLUT_KEY_HOME;break;
+          case VK_END:     key = GLUT_KEY_END; break;
+          case VK_INSERT:  key = GLUT_KEY_INSERT;     break;
+
+/* function keys */
+          case VK_F1 : key = GLUT_KEY_F1;  break;
+          case VK_F2 : key = GLUT_KEY_F2; break;
+          case VK_F3 : key = GLUT_KEY_F3; break;
+          case VK_F4 : key = GLUT_KEY_F4; break;
+          case VK_F5 : key = GLUT_KEY_F5; break;
+          case VK_F6 : key = GLUT_KEY_F6; break;
+          case VK_F7 : key = GLUT_KEY_F7; break;
+          case VK_F8 : key = GLUT_KEY_F8; break;
+          case VK_F9 : key = GLUT_KEY_F9; break;
+          case VK_F10: key = GLUT_KEY_F10;break;
+          case VK_F11: key = GLUT_KEY_F11; break;
+          case VK_F12: key = GLUT_KEY_F12; break;
+          case VK_ESC:   key = -1; break;  /* Character codes */
+          case VK_SPACE: key = -1; break;
+          case VK_TAB:   key = -1; break;
+         }
+         if(!key)
+         {     break; /* Key Not implemented  */
+         }
+         if(key > 0)
+         {   if (!window->special)  /* Â­Â¥ Ã£Ã¡Ã¢Â Â­Â®Â¢Â«Â¥Â­Â® Â®Â¡Ã Â Â¡Â®Ã¢Ã§Â¨ÂªÂ  */
+                             break;
+
+               WinQueryPointerPos(HWND_DESKTOP,&point);
+               ScreenToClient(window->win, &point);
+               __glutSetWindow(window);
+               __glutModifierMask = 0;
+               if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)   /*  high order bit is on */
+                          __glutModifierMask |= ShiftMask;
+               if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+                          __glutModifierMask |= ControlMask;
+               if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+                          __glutModifierMask |= Mod1Mask;
+               window->special(key, point.x, point.y);
+               __glutModifierMask = (unsigned int) ~0;
+               return 0;
+         }
+
+   }
+/////////////////////////////////////////////////////
+    /* If  we are ignoring auto repeated key strokes for the window, bail. */
+    if (window->ignoreKeyRepeat && (CHAR3FROMMP(mp1)) )
+                                                   break;
+     if(!((unsigned char)SHORT1FROMMP(mp2))  )  /* Â¨Â£Â­Â®p¨p㥬 Â­Â¥Ã¡Â¨Â¬Â¢Â®Â«Ã¬Â­Ã«Â¥ ÂªÂ®Â¤Ã« */
+                                            break;
+    if (window->keyboard) {
+       WinQueryPointerPos(HWND_DESKTOP,&point);
+
+      ScreenToClient(window->win, &point);
+      __glutSetWindow(window);
+      __glutModifierMask = 0;
+      if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)   /*  high order bit is on */
+           __glutModifierMask |= ShiftMask;
+      if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+           __glutModifierMask |= ControlMask;
+      if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+           __glutModifierMask |= Mod1Mask;
+      window->keyboard((unsigned char)SHORT1FROMMP(mp2), point.x, point.y);
+      __glutModifierMask = (unsigned int) ~0;
+    }
+    return 0;
+  } /* endof case WM_CHAR: */
+////////////////////////////////////////////////
+  case WM_BUTTON1DOWN:
+    button = GLUT_LEFT_BUTTON;
+  case WM_BUTTON3DOWN:
+    if (button < 0)
+      button = GLUT_MIDDLE_BUTTON;
+  case WM_BUTTON2DOWN:
+    if (button < 0)
+      button = GLUT_RIGHT_BUTTON;
+    {  POINTS psh;
+       psh = *((POINTS *)&mp1);
+       point.x = psh.x;
+       point.y = psh.y;
+    }
+    /* finish the menu if we get a button down message (user must have
+       cancelled the menu). */
+    if (__glutMappedMenu) {
+      /* TODO: take this out once the menu on middle mouse stuff works
+        properly. */
+      if (button == GLUT_MIDDLE_BUTTON)
+       return 0;
+ /* get current mouse pointer position */
+//      WinQueryPointerPos(HWND_DESKTOP,&point);
+ /* map from desktop to client window */
+//      WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);
+      __glutItemSelected = NULL;
+      __glutFinishMenu(hwnd, point.x, point.y);
+      return 0;
+    }
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      window->buttonDownState = button+1;
+      menu = __glutGetMenuByNum(window->menu[button]);
+      if (menu) {
+//todo
+//   __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
+//                           button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :
+//                           0x0001;
+//   __glutStartMenu(menu, window, point.x, point.y, x, y);
+      } else if (window->mouse) {
+
+       __glutSetWindow(window);
+       __glutModifierMask = 0;
+       if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)  /* < 0 = high order bit is on. */
+            __glutModifierMask |= ShiftMask;
+       if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+            __glutModifierMask |= ControlMask;
+       if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+            __glutModifierMask |= Mod1Mask;
+      window->mouse(button, GLUT_DOWN, point.x, point.y);
+      __glutModifierMask = (unsigned int)~0;
+      } else {
+   /* Stray mouse events.  Ignore. */
+      }
+    }
+    return 0;
+
+    break;
+/********************************************/
+  case WM_BUTTON1UP:
+    button = GLUT_LEFT_BUTTON;
+  case WM_BUTTON3UP:
+    if (button < 0)
+      button = GLUT_MIDDLE_BUTTON;
+  case WM_BUTTON2UP:
+    if (button < 0)
+      button = GLUT_RIGHT_BUTTON;
+    {  POINTS psh;
+       psh = *((POINTS *)&mp1);
+       point.x = psh.x;
+       point.y = psh.y;
+    }
+    /* Bail out if we're processing a menu. */
+    /* Bail out = Â¢Ã«Â¡Ã Â®Ã¡Â¨Ã¢Ã¬Ã¡Ã¯ Ã¡ Â¯Â Ã Â Ã¨Ã£Ã¢Â®Â¬   */
+    if (__glutMappedMenu) {
+      WinQueryPointerPos(HWND_DESKTOP,&point);
+      WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);
+      /* if we're getting the middle button up signal, then something
+        on the menu was selected. */
+      if (button == GLUT_MIDDLE_BUTTON) {
+       return 0;
+       /* For some reason, the code below always returns -1 even
+          though the point IS IN THE ITEM!  Therefore, just bail out if
+          we get a middle mouse up.  The user must select using the
+          left mouse button.  Stupid Win32. */
+#if 0
+       int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
+       if (item != -1)
+         __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
+       else
+         __glutItemSelected = NULL;
+       __glutFinishMenu(hwnd, point.x, point.y);
+#endif
+      } else {
+       __glutItemSelected = NULL;
+       __glutFinishMenu(hwnd, point.x, point.y);
+      }
+      return 0;
+    }
+
+    window = __glutGetWindow(hwnd);
+    if(window)
+           window->buttonDownState = 0;
+
+    if (window && window->mouse) {
+      __glutSetWindow(window);
+      __glutModifierMask = 0;
+      if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000)   /* < 0 = high order bit is on */
+                          __glutModifierMask |= ShiftMask;
+      if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+   __glutModifierMask |= ControlMask;
+      if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+   __glutModifierMask |= Mod1Mask;
+      window->mouse(button, GLUT_UP, point.x, point.y);
+
+      __glutModifierMask = (unsigned int)~0;
+    } else {
+      /* Window might have been destroyed and all the
+    events for the window may not yet be received. */
+    }
+    return 0;
+
+
+    break;
+//////////////////////////////////////////////////
+  case WM_COMMAND:
+    window = __glutGetWindow(hwnd);
+    if (window)
+    {   if (window->wm_command)
+            window->wm_command(hwnd,mp1,mp2);
+    }
+    break;
+
+  case WM_MOUSEMOVE:
+    if (!__glutMappedMenu) {
+      window = __glutGetWindow(hwnd);
+      if (window) {
+          /* If motion function registered _and_ buttons held *
+             down, call motion function...  */
+          {  POINTS psh;
+             psh = *((POINTS *)&mp1);
+             point.x = psh.x;
+             point.y = psh.y;
+          }
+
+         if (window->motion && window->buttonDownState) {
+           __glutSetWindow(window);
+           window->motion(point.x, point.y);
+         }
+   /* If passive motion function registered _and_
+      buttons not held down, call passive motion
+      function...  */
+         else if (window->passive && !window->buttonDownState) {
+           __glutSetWindow(window);
+           window->passive(point.x, point.y);
+         }
+      }
+    } else {
+      /* Motion events are thrown away when a pop up menu is
+    active. */
+    }
+    return 0;
+
+
+      default:
+ /* For all other messages, let the default window procedure process them. */
+       return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
+
+   } //endof switch( msg )
+   return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
+//   return NULL;
+}
+
+void APIENTRY glutCommandFunc(GLUTcommandCB Func)
+{
+extern GLUTwindow *__glutCurrentWindow;
+    __glutCurrentWindow->wm_command = Func;
+}
+
+
+
+
+void
+updateWindowState(GLUTwindow *window, int visState)
+{
+  GLUTwindow* child;
+
+  /* XXX shownState and visState are the same in Win32. */
+  window->shownState = visState;
+  if (visState != window->visState) {
+    if (window->windowStatus) {
+      window->visState = visState;
+      __glutSetWindow(window);
+      window->windowStatus(visState);
+    }
+  }
+  /* Since Win32 only sends an activate for the toplevel window,
+     update the visibility for all the child windows. */
+  child = window->children;
+  while (child) {
+    updateWindowState(child, visState);
+    child = child->siblings;
+  }
+}
+
+#if POKA
+
+LONG WINAPI
+__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  POINT         point;                 /* Point structure. */
+  PAINTSTRUCT   ps;                    /* Paint structure. */
+  LPMINMAXINFO  minmax;                        /* Minimum/maximum info structure. */
+  GLUTwindow*   window;                        /* GLUT window associated with message. */
+  GLUTmenu*     menu;                  /* GLUT menu associated with message. */
+  int x, y, width, height, key;
+  int button = -1;
+
+  switch(msg) {
+  case WM_CREATE:
+    return 0;
+  case WM_CLOSE:
+    PostQuitMessage(0);
+    return 0;
+#if 0
+  case WM_DESTROY:
+    /* XXX NVidia's NT OpenGL can have problems closing down
+       its OpenGL internal data structures if we just allow
+       the process to terminate without unbinding and deleting
+       the windows context.  Apparently, DirectDraw unloads
+       before OPENGL32.DLL in the close down sequence, but
+       NVidia's NT OpenGL needs DirectDraw to close down its
+       data structures. */
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      if (window->ctx) {
+        wglMakeCurrent(NULL, NULL);
+        wglDeleteContext(window->ctx);
+      }
+    }
+    return 0;
+#endif
+
+  case WM_SYSKEYUP:
+  case WM_KEYUP:
+    window = __glutGetWindow(hwnd);
+    if (!window) {
+      break;
+    }
+    /* Win32 is dumb and sends these messages only to the parent
+       window.  Therefore, find out if we're in a child window and
+       call the child windows keyboard callback if we are. */
+    if (window->parent) {
+      GetCursorPos(&point);
+      ScreenToClient(hwnd, &point);
+      hwnd = ChildWindowFromPoint(hwnd, point);
+      window = __glutGetWindow(hwnd);
+    }
+    if (window->specialUp || window->keyboardUp) {
+      GetCursorPos(&point);
+      ScreenToClient(window->win, &point);
+      __glutSetWindow(window);
+      __glutModifierMask = 0;
+      if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */
+       __glutModifierMask |= ShiftMask;
+      if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */
+       __glutModifierMask |= ControlMask;
+      if (GetKeyState(VK_MENU) < 0)
+       __glutModifierMask |= Mod1Mask;
+      switch (wParam) {
+      /* *INDENT-OFF* */
+      case VK_F1:     key = GLUT_KEY_F1; break;
+      case VK_F2:     key = GLUT_KEY_F2; break;
+      case VK_F3:     key = GLUT_KEY_F3; break;
+      case VK_F4:     key = GLUT_KEY_F4; break;
+      case VK_F5:     key = GLUT_KEY_F5; break;
+      case VK_F6:     key = GLUT_KEY_F6; break;
+      case VK_F7:     key = GLUT_KEY_F7; break;
+      case VK_F8:     key = GLUT_KEY_F8; break;
+      case VK_F9:     key = GLUT_KEY_F9; break;
+      case VK_F10:    key = GLUT_KEY_F10; break;
+      case VK_F11:    key = GLUT_KEY_F11; break;
+      case VK_F12:    key = GLUT_KEY_F12; break;
+      case VK_LEFT:   key = GLUT_KEY_LEFT; break;
+      case VK_UP:     key = GLUT_KEY_UP; break;
+      case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;
+      case VK_DOWN:   key = GLUT_KEY_DOWN; break;
+      case VK_PRIOR:  key = GLUT_KEY_PAGE_UP; break;
+      case VK_NEXT:   key = GLUT_KEY_PAGE_DOWN; break;
+      case VK_HOME:   key = GLUT_KEY_HOME; break;
+      case VK_END:    key = GLUT_KEY_END; break;
+      case VK_INSERT: key = GLUT_KEY_INSERT; break;
+      case VK_DELETE:
+        /* Delete is an ASCII character. */
+       if (window->keyboardUp) {
+         window->keyboardUp((unsigned char) 127, point.x, point.y);
+       }
+       return 0;
+      /* *INDENT-ON* */
+      default:
+       if (window->keyboardUp) {
+         key = MapVirtualKey(wParam, 2);  /* Map to ASCII. */
+         if (isascii(key) && (key != 0)) {
+
+           /* XXX Attempt to determine modified ASCII character
+              is quite incomplete.  Digits, symbols, CapsLock,
+              Ctrl, and numeric keypad are all ignored.  Fix this. */
+
+           if (!(__glutModifierMask & ShiftMask))
+             key = tolower(key);
+           window->keyboardUp((unsigned char) key, point.x, point.y);
+          }
+        }
+       __glutModifierMask = (unsigned int) ~0;
+       return 0;
+      }
+      if (window->specialUp) {
+        window->specialUp(key, point.x, point.y);
+      }
+      __glutModifierMask = (unsigned int) ~0;
+    }
+    return 0;
+
+  case WM_SYSCHAR:
+  case WM_CHAR:
+    window = __glutGetWindow(hwnd);
+    if (!window) {
+      break;
+    }
+
+    /* Bit 30 of lParam is set if key already held down.  If
+       we are ignoring auto repeated key strokes for the window, bail. */
+    if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
+      break;
+    }
+
+    /* Win32 is dumb and sends these messages only to the parent
+       window.  Therefore, find out if we're in a child window and
+       call the child windows keyboard callback if we are. */
+    if (window->parent) {
+       GetCursorPos(&point);
+       ScreenToClient(hwnd, &point);
+       hwnd = ChildWindowFromPoint(hwnd, point);
+       window = __glutGetWindow(hwnd);
+    }
+    if (window->keyboard) {
+      GetCursorPos(&point);
+      ScreenToClient(window->win, &point);
+      __glutSetWindow(window);
+      __glutModifierMask = 0;
+      if (GetKeyState(VK_SHIFT) < 0)   /* < 0 = high order bit is on */
+       __glutModifierMask |= ShiftMask;
+      if (GetKeyState(VK_CONTROL) < 0)
+       __glutModifierMask |= ControlMask;
+      if (GetKeyState(VK_MENU) < 0)
+       __glutModifierMask |= Mod1Mask;
+      window->keyboard((unsigned char)wParam, point.x, point.y);
+      __glutModifierMask = (unsigned int) ~0;
+    }
+    return 0;
+
+  case WM_SYSKEYDOWN:
+  case WM_KEYDOWN:
+    window = __glutGetWindow(hwnd);
+    if (!window) {
+      break;
+    }
+
+    /* Bit 30 of lParam is set if key already held down.  If
+       we are ignoring auto repeated key strokes for the window, bail. */
+    if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
+      break;
+    }
+
+    /* Win32 is dumb and sends these messages only to the parent
+       window.  Therefore, find out if we're in a child window and
+       call the child windows keyboard callback if we are. */
+    if (window->parent) {
+       GetCursorPos(&point);
+       ScreenToClient(hwnd, &point);
+       hwnd = ChildWindowFromPoint(hwnd, point);
+       window = __glutGetWindow(hwnd);
+    }
+    if (window->special) {
+      switch (wParam) {
+       /* *INDENT-OFF* */
+       /* function keys */
+       case VK_F1:     key = GLUT_KEY_F1; break;
+       case VK_F2:     key = GLUT_KEY_F2; break;
+       case VK_F3:     key = GLUT_KEY_F3; break;
+       case VK_F4:     key = GLUT_KEY_F4; break;
+       case VK_F5:     key = GLUT_KEY_F5; break;
+       case VK_F6:     key = GLUT_KEY_F6; break;
+       case VK_F7:     key = GLUT_KEY_F7; break;
+       case VK_F8:     key = GLUT_KEY_F8; break;
+       case VK_F9:     key = GLUT_KEY_F9; break;
+       case VK_F10:    key = GLUT_KEY_F10; break;
+       case VK_F11:    key = GLUT_KEY_F11; break;
+       case VK_F12:    key = GLUT_KEY_F12; break;
+       /* directional keys */
+       case VK_LEFT:   key = GLUT_KEY_LEFT; break;
+       case VK_UP:     key = GLUT_KEY_UP; break;
+       case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;
+       case VK_DOWN:   key = GLUT_KEY_DOWN; break;
+       /* *INDENT-ON* */
+
+       case VK_PRIOR:
+         /* VK_PRIOR is Win32's Page Up */
+         key = GLUT_KEY_PAGE_UP;
+         break;
+       case VK_NEXT:
+         /* VK_NEXT is Win32's Page Down */
+         key = GLUT_KEY_PAGE_DOWN;
+         break;
+       case VK_HOME:
+         key = GLUT_KEY_HOME;
+         break;
+       case VK_END:
+         key = GLUT_KEY_END;
+         break;
+       case VK_INSERT:
+         key = GLUT_KEY_INSERT;
+         break;
+        case VK_DELETE:
+         goto handleDelete;
+       default:
+         goto defproc;
+      }
+      GetCursorPos(&point);
+      ScreenToClient(window->win, &point);
+      __glutSetWindow(window);
+      __glutModifierMask = 0;
+      if (GetKeyState(VK_SHIFT) < 0)   /* < 0 = high order bit is on */
+       __glutModifierMask |= ShiftMask;
+      if (GetKeyState(VK_CONTROL) < 0)
+       __glutModifierMask |= ControlMask;
+      if (GetKeyState(VK_MENU) < 0)
+       __glutModifierMask |= Mod1Mask;
+      window->special(key, point.x, point.y);
+      __glutModifierMask = (unsigned int) ~0;
+    } else if (window->keyboard) {
+      /* Specially handle any keys that match ASCII values but
+         do not generate Windows WM_SYSCHAR or WM_CHAR messages. */
+      switch (wParam) {
+      case VK_DELETE:
+      handleDelete:
+        /* Delete is an ASCII character. */
+        GetCursorPos(&point);
+        ScreenToClient(window->win, &point);
+        __glutSetWindow(window);
+        __glutModifierMask = 0;
+        if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+          __glutModifierMask |= ShiftMask;
+        if (GetKeyState(VK_CONTROL) < 0)
+          __glutModifierMask |= ControlMask;
+        if (GetKeyState(VK_MENU) < 0)
+          __glutModifierMask |= Mod1Mask;
+       window->keyboard((unsigned char) 127, point.x, point.y);
+        __glutModifierMask = (unsigned int) ~0;
+       return 0;
+      default:
+        /* Let the following WM_SYSCHAR or WM_CHAR message generate
+          the keyboard callback. */
+        break;
+      }
+    }
+    return 0;
+
+  case WM_LBUTTONDOWN:
+    button = GLUT_LEFT_BUTTON;
+  case WM_MBUTTONDOWN:
+    if (button < 0)
+      button = GLUT_MIDDLE_BUTTON;
+  case WM_RBUTTONDOWN:
+    if (button < 0)
+      button = GLUT_RIGHT_BUTTON;
+
+    /* finish the menu if we get a button down message (user must have
+       cancelled the menu). */
+    if (__glutMappedMenu) {
+      /* TODO: take this out once the menu on middle mouse stuff works
+        properly. */
+      if (button == GLUT_MIDDLE_BUTTON)
+       return 0;
+      GetCursorPos(&point);
+      ScreenToClient(hwnd, &point);
+      __glutItemSelected = NULL;
+      __glutFinishMenu(hwnd, point.x, point.y);
+      return 0;
+    }
+
+    /* set the capture so we can get mouse events outside the window */
+    SetCapture(hwnd);
+
+    /* Win32 doesn't return the same numbers as X does when the mouse
+       goes beyond the upper or left side of the window.  roll the
+       Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
+    x = LOWORD(lParam);
+    y = HIWORD(lParam);
+    if(x & 1 << 15) x -= (1 << 16);
+    if(y & 1 << 15) y -= (1 << 16);
+
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      menu = __glutGetMenuByNum(window->menu[button]);
+      if (menu) {
+       point.x = LOWORD(lParam); point.y = HIWORD(lParam);
+       ClientToScreen(window->win, &point);
+       __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
+                           button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :
+                           0x0001;
+       __glutStartMenu(menu, window, point.x, point.y, x, y);
+      } else if (window->mouse) {
+
+        __glutSetWindow(window);
+       __glutModifierMask = 0;
+       if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on. */
+         __glutModifierMask |= ShiftMask;
+       if (GetKeyState(VK_CONTROL) < 0)
+         __glutModifierMask |= ControlMask;
+       if (GetKeyState(VK_MENU) < 0)
+         __glutModifierMask |= Mod1Mask;
+       window->mouse(button, GLUT_DOWN, x, y);
+       __glutModifierMask = (unsigned int)~0;
+      } else {
+       /* Stray mouse events.  Ignore. */
+      }
+    }
+    return 0;
+
+  case WM_LBUTTONUP:
+    button = GLUT_LEFT_BUTTON;
+  case WM_MBUTTONUP:
+    if (button < 0)
+      button = GLUT_MIDDLE_BUTTON;
+  case WM_RBUTTONUP:
+    if (button < 0)
+      button = GLUT_RIGHT_BUTTON;
+
+    /* Bail out if we're processing a menu. */
+    if (__glutMappedMenu) {
+      GetCursorPos(&point);
+      ScreenToClient(hwnd, &point);
+      /* if we're getting the middle button up signal, then something
+        on the menu was selected. */
+      if (button == GLUT_MIDDLE_BUTTON) {
+       return 0;
+       /* For some reason, the code below always returns -1 even
+          though the point IS IN THE ITEM!  Therefore, just bail out if
+          we get a middle mouse up.  The user must select using the
+          left mouse button.  Stupid Win32. */
+#if 0
+       int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
+       if (item != -1)
+         __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
+       else
+         __glutItemSelected = NULL;
+       __glutFinishMenu(hwnd, point.x, point.y);
+#endif
+      } else {
+       __glutItemSelected = NULL;
+       __glutFinishMenu(hwnd, point.x, point.y);
+      }
+      return 0;
+    }
+
+    /* Release the mouse capture. */
+    ReleaseCapture();
+
+    window = __glutGetWindow(hwnd);
+    if (window && window->mouse) {
+      /* Win32 doesn't return the same numbers as X does when the
+        mouse goes beyond the upper or left side of the window.  roll
+        the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
+      x = LOWORD(lParam);
+      y = HIWORD(lParam);
+      if(x & 1 << 15) x -= (1 << 16);
+      if(y & 1 << 15) y -= (1 << 16);
+
+      __glutSetWindow(window);
+      __glutModifierMask = 0;
+      if (GetKeyState(VK_SHIFT) < 0)   /* < 0 = high order bit is on */
+       __glutModifierMask |= ShiftMask;
+      if (GetKeyState(VK_CONTROL) < 0)
+       __glutModifierMask |= ControlMask;
+      if (GetKeyState(VK_MENU) < 0)
+       __glutModifierMask |= Mod1Mask;
+      window->mouse(button, GLUT_UP, x, y);
+      __glutModifierMask = (unsigned int)~0;
+    } else {
+      /* Window might have been destroyed and all the
+        events for the window may not yet be received. */
+    }
+    return 0;
+
+  case WM_ENTERMENULOOP:
+    /* KLUDGE: create a timer that fires every 100 ms when we start a
+       menu so that we can still process the idle & timer events (that
+       way, the timers will fire during a menu pick and so will the
+       idle func. */
+    SetTimer(hwnd, 1, 1, NULL);
+    return 0;
+
+  case WM_TIMER:
+#if 0
+    /* If the timer id is 2, then this is the timer that is set up in
+       the main glut message processing loop, and we don't want to do
+       anything but acknowledge that we got it.  It is used to prevent
+       CPU spiking when an idle function is installed. */
+    if (wParam == 2)
+      return 0;
+#endif
+
+    /* only worry about the idle function and the timeouts, since
+       these are the only events we expect to process during
+       processing of a menu. */
+    /* we no longer process the idle functions (as outlined in the
+       README), since drawing can't be done until the menu has
+       finished...it's pretty lame when the animation goes on, but
+       doesn't update, so you get this weird jerkiness. */
+#if 0
+     if (__glutIdleFunc)
+       __glutIdleFunc();
+#endif
+    if (__glutTimerList)
+      handleTimeouts();
+    return 0;
+
+  case WM_EXITMENULOOP:
+    /* nuke the above created timer...we don't need it anymore, since
+       the menu is gone now. */
+    KillTimer(hwnd, 1);
+    return 0;
+
+  case WM_MENUSELECT:
+    if (lParam != 0)
+      __glutHMenu = (HMENU)lParam;
+    return 0;
+
+  case WM_COMMAND:
+    if (__glutMappedMenu) {
+      if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
+       __glutItemSelected = NULL;
+      else
+       __glutItemSelected =
+         __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
+      GetCursorPos(&point);
+      ScreenToClient(hwnd, &point);
+      __glutFinishMenu(hwnd, point.x, point.y);
+    }
+    return 0;
+
+  case WM_MOUSEMOVE:
+    if (!__glutMappedMenu) {
+      window = __glutGetWindow(hwnd);
+      if (window) {
+          /* If motion function registered _and_ buttons held *
+             down, call motion function...  */
+       x = LOWORD(lParam);
+       y = HIWORD(lParam);
+
+       /* Win32 doesn't return the same numbers as X does when the
+          mouse goes beyond the upper or left side of the window.
+          roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
+       if(x & 1 << 15) x -= (1 << 16);
+       if(y & 1 << 15) y -= (1 << 16);
+
+       if (window->motion && wParam &
+            (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
+         __glutSetWindow(window);
+         window->motion(x, y);
+       }
+       /* If passive motion function registered _and_
+          buttons not held down, call passive motion
+          function...  */
+       else if (window->passive &&
+                ((wParam &
+                  (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
+                 0)) {
+         __glutSetWindow(window);
+         window->passive(x, y);
+       }
+      }
+    } else {
+      /* Motion events are thrown away when a pop up menu is
+        active. */
+    }
+    return 0;
+
+  case WM_GETMINMAXINFO:
+    /* this voodoo is brought to you by Win32 (again).  It allows the
+       window to be bigger than the screen, and smaller than 100x100
+       (although it doesn't seem to help the y minimum). */
+    minmax = (LPMINMAXINFO)lParam;
+    minmax->ptMaxSize.x = __glutScreenWidth;
+    minmax->ptMaxSize.y = __glutScreenHeight;
+    minmax->ptMinTrackSize.x = 0;
+    minmax->ptMinTrackSize.y = 0;
+    minmax->ptMaxTrackSize.x = __glutScreenWidth +
+      GetSystemMetrics(SM_CXSIZE) * 2;
+    minmax->ptMaxTrackSize.y = __glutScreenHeight +
+      GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
+    return 0;
+
+  case WM_SIZE:
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      width = LOWORD(lParam);
+      height = HIWORD(lParam);
+      if (width != window->width || height != window->height) {
+#if 0  /* Win32 GLUT does not support overlays for now. */
+       if (window->overlay) {
+         XResizeWindow(__glutDisplay, window->overlay->win, width, height);
+       }
+#endif
+       window->width = width;
+       window->height = height;
+       __glutSetWindow(window);
+       /* Do not execute OpenGL out of sequence with respect
+          to the SetWindowPos request! */
+       GdiFlush();
+       window->reshape(width, height);
+       window->forceReshape = FALSE;
+       /* A reshape should be considered like posting a
+          repair request. */
+       __glutPostRedisplay(window, GLUT_REPAIR_WORK);
+      }
+    }
+    return 0;
+
+  case WM_SETCURSOR:
+    /* If the cursor is not in the client area, then we want to send
+       this message to the default window procedure ('cause its
+       probably in the border or title, and we don't handle that
+       cursor.  otherwise, set our cursor.  Win32 makes us set the
+       cursor every time the mouse moves (DUMB!). */
+    if(LOWORD(lParam) != HTCLIENT) {
+      goto defproc;
+    }
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      __glutSetCursor(window);
+    }
+    /* TODO: check out the info in DevStudio on WM_SETCURSOR in the
+       DefaultAction section. */
+    return 1;
+
+  case WM_SETFOCUS:
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      window->entryState = WM_SETFOCUS;
+      if (window->entry) {
+       __glutSetWindow(window);
+       window->entry(GLUT_ENTERED);
+       /* XXX Generation of fake passive notify?  See how much
+          work the X11 code does to support fake passive notify
+          callbacks. */
+      }
+      if (window->joystick && __glutCurrentWindow) {
+        if (__glutCurrentWindow->joyPollInterval > 0) {
+         MMRESULT result;
+
+         /* Because Win32 will only let one window capture the
+            joystick at a time, we must capture it when we get the
+            focus and release it when we lose the focus. */
+         result = joySetCapture(__glutCurrentWindow->win,
+           JOYSTICKID1, 0, TRUE);
+         if (result != JOYERR_NOERROR) {
+           return 0;
+          }
+         (void) joySetThreshold(JOYSTICKID1,
+            __glutCurrentWindow->joyPollInterval);
+        }
+      }
+    }
+    return 0;
+
+  case WM_KILLFOCUS:
+    window = __glutGetWindow(hwnd);
+    if (window) {
+      window->entryState = WM_KILLFOCUS;
+      if (window->entry) {
+       __glutSetWindow(window);
+       window->entry(GLUT_LEFT);
+      }
+      if (window->joystick && __glutCurrentWindow) {
+       if (__glutCurrentWindow->joyPollInterval > 0) {
+         /* Because Win32 will only let one window capture the
+            joystick at a time, we must capture it when we get the
+            focus and release it when we lose the focus. */
+           (void) joyReleaseCapture(JOYSTICKID1);
+        }
+      }
+    }
+    return 0;
+  case WM_ACTIVATE:
+    window = __glutGetWindow(hwnd);
+    /* Make sure we re-select the correct palette if needed. */
+    if (LOWORD(wParam)) {
+      PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
+    }
+    if (window) {
+      int visState;
+
+      /* HIWORD(wParam) is the minimized flag. */
+      visState = !HIWORD(wParam);
+      updateWindowState(window, visState);
+    }
+    return 0;
+
+  /* Colour Palette Management */
+  case WM_PALETTECHANGED:
+    if (hwnd == (HWND)wParam) {
+      /* Don't respond to the message that we sent! */
+      break;
+    }
+    /* fall through to WM_QUERYNEWPALETTE */
+
+  case WM_QUERYNEWPALETTE:
+    window = __glutGetWindow(hwnd);
+    if (window && window->colormap) {
+      UnrealizeObject(window->colormap->cmap);
+      SelectPalette(window->hdc, window->colormap->cmap, FALSE);
+      RealizePalette(window->hdc);
+      return TRUE;
+    }
+    return FALSE;
+
+  case MM_JOY1MOVE:
+  case MM_JOY1ZMOVE:
+    window = __glutGetWindow(hwnd);
+    if (window->joystick) {
+      JOYINFOEX jix;
+      int x, y, z;
+
+      /* Because WIN32 only supports messages for X, Y, and Z
+         translations, we must poll for the rest */
+      jix.dwSize = sizeof(jix);
+      jix.dwFlags = JOY_RETURNALL;
+      joyGetPosEx(JOYSTICKID1,&jix);
+
+#define SCALE(v)  ((int) ((v - 32767)/32.768))
+
+      /* Convert to integer for scaling. */
+      x = jix.dwXpos;
+      y = jix.dwYpos;
+      z = jix.dwZpos;
+      window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
+
+      return TRUE;
+    }
+    return FALSE;
+  case MM_JOY1BUTTONDOWN:
+  case MM_JOY1BUTTONUP:
+    window = __glutGetWindow(hwnd);
+    if (window->joystick) {
+      JOYINFOEX jix;
+
+      /* Because WIN32 only supports messages for X, Y, and Z
+         translations, we must poll for the rest */
+      jix.dwSize = sizeof(jix);
+      jix.dwFlags = JOY_RETURNALL;
+      joyGetPosEx(JOYSTICKID1,&jix);
+
+      return TRUE;
+    }
+    return FALSE;
+
+#if 0
+  /* Miscellaneous messages (don't really need to enumerate them,
+     but it's good to know what you're not getting sometimes). */
+  case WM_DISPLAYCHANGE:
+    break;
+  case WM_NCHITTEST:
+    /* This event is generated by every mouse move event. */
+    goto defproc;
+  case WM_NCMOUSEMOVE:
+    goto defproc;
+  case WM_NCACTIVATE:
+    goto defproc;
+  case WM_NCPAINT:
+    goto defproc;
+  case WM_NCCALCSIZE:
+    goto defproc;
+  case WM_NCCREATE:
+    goto defproc;
+  case WM_NCDESTROY:
+    goto defproc;
+  case WM_NCLBUTTONDOWN:
+    goto defproc;
+  case WM_SETTEXT:
+    goto defproc;
+  case WM_GETTEXT:
+    goto defproc;
+  case WM_ACTIVATEAPP:
+    goto defproc;
+  case WM_GETICON:
+    goto defproc;
+  case WM_ERASEBKGND:
+    goto defproc;
+  case WM_WINDOWPOSCHANGING:
+    goto defproc;
+  case WM_WINDOWPOSCHANGED:
+    goto defproc;
+  case WM_MOUSEACTIVATE:
+    goto defproc;
+  case WM_SHOWWINDOW:
+    goto defproc;
+  case WM_MOVING:
+    goto defproc;
+  case WM_MOVE:
+    goto defproc;
+  case WM_KEYUP:
+    goto defproc;
+  case WM_CAPTURECHANGED:
+    goto defproc;
+  case WM_SYSCOMMAND:
+    goto defproc;
+  case WM_ENTERSIZEMOVE:
+    goto defproc;
+  case WM_ENTERIDLE:
+    goto defproc;
+#endif
+
+  default:
+    goto defproc;
+  }
+
+defproc:
+  return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+#endif
+
+#if defined(__OS2PM__)
+Bool __glutSetWindowText(Window window, char *text)
+{
+  return WinSetWindowText(window, (PCSZ)text);
+
+}
+
+#endif
 \1a
\ No newline at end of file