Merge branch 'master' into gallium-0.2
[mesa.git] / src / glut / os2 / glut_win.cpp
index 82abba87e48ae04c20c25a0523f6f7d0dbcfef18..63757d71522b87a8c7b85619a033178344a6d8f8 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
-\1a
\ No newline at end of file
+
+/* 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;
+  }
+}