diff options
-rw-r--r-- | src/glut/os2/WarpWin.cpp | 838 | ||||
-rw-r--r-- | src/glut/os2/glut_cindex.cpp | 516 | ||||
-rw-r--r-- | src/glut/os2/glut_gamemode.cpp | 1358 | ||||
-rw-r--r-- | src/glut/os2/glut_win.cpp | 2440 | ||||
-rw-r--r-- | src/glut/os2/glut_winmisc.cpp | 252 | ||||
-rw-r--r-- | src/glut/os2/os2_glx.cpp | 290 | ||||
-rw-r--r-- | src/glut/os2/os2_menu.cpp | 1064 | ||||
-rw-r--r-- | src/glut/os2/os2_winproc.cpp | 2592 |
8 files changed, 4675 insertions, 4675 deletions
diff --git a/src/glut/os2/WarpWin.cpp b/src/glut/os2/WarpWin.cpp index ee746ecc764..bd5a6e80c7f 100644 --- a/src/glut/os2/WarpWin.cpp +++ b/src/glut/os2/WarpWin.cpp @@ -1,420 +1,420 @@ -/* 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;
-}
-
+/* 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; +} +
\ No newline at end of file diff --git a/src/glut/os2/glut_cindex.cpp b/src/glut/os2/glut_cindex.cpp index 0897a3cf85c..34841850519 100644 --- a/src/glut/os2/glut_cindex.cpp +++ b/src/glut/os2/glut_cindex.cpp @@ -1,259 +1,259 @@ -
-/* 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 */
+ +/* 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 */
\ No newline at end of file diff --git a/src/glut/os2/glut_gamemode.cpp b/src/glut/os2/glut_gamemode.cpp index 50185d7b9d4..39918fdf39b 100644 --- a/src/glut/os2/glut_gamemode.cpp +++ b/src/glut/os2/glut_gamemode.cpp @@ -1,680 +1,680 @@ -
-/* 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;
- }
-}
+ +/* 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; + } +}
\ No newline at end of file diff --git a/src/glut/os2/glut_win.cpp b/src/glut/os2/glut_win.cpp index 82abba87e48..53ff5d5d953 100644 --- a/src/glut/os2/glut_win.cpp +++ b/src/glut/os2/glut_win.cpp @@ -1,1221 +1,1221 @@ -
-/* 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;
- }
-}
+ +/* 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; + } +}
\ No newline at end of file diff --git a/src/glut/os2/glut_winmisc.cpp b/src/glut/os2/glut_winmisc.cpp index ffa31c021c0..456d19a8c18 100644 --- a/src/glut/os2/glut_winmisc.cpp +++ b/src/glut/os2/glut_winmisc.cpp @@ -1,127 +1,127 @@ -
-/* 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 */
+ +/* 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 */
\ No newline at end of file diff --git a/src/glut/os2/os2_glx.cpp b/src/glut/os2/os2_glx.cpp index ca345ea05b5..5e135bc17e9 100644 --- a/src/glut/os2/os2_glx.cpp +++ b/src/glut/os2/os2_glx.cpp @@ -1,146 +1,146 @@ -/* 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 */
-
+/* 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 */ +
\ No newline at end of file diff --git a/src/glut/os2/os2_menu.cpp b/src/glut/os2/os2_menu.cpp index 4eef308e5a9..56f2cdef8b2 100644 --- a/src/glut/os2/os2_menu.cpp +++ b/src/glut/os2/os2_menu.cpp @@ -1,533 +1,533 @@ -
-/* 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;
- }
-}
-
+ +/* 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; + } +} +
\ No newline at end of file diff --git a/src/glut/os2/os2_winproc.cpp b/src/glut/os2/os2_winproc.cpp index e2d4ba9d550..6ffe0d4624b 100644 --- a/src/glut/os2/os2_winproc.cpp +++ b/src/glut/os2/os2_winproc.cpp @@ -1,1297 +1,1297 @@ -/* 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
+/* 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
\ No newline at end of file |