-/* 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
-\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
-\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(¤tDm->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(¤tDm->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
-\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
-\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
-/* 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
-\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
-/* 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