From ae18cbcfc51314c17d4fb7a2b4d44cd4a43adca4 Mon Sep 17 00:00:00 2001 From: Jose Fonseca Date: Sat, 7 Jun 2008 12:34:45 +0900 Subject: Fix CRLF line endings. --- src/glut/os2/WarpWin.cpp | 838 ++++++------- src/glut/os2/glut_cindex.cpp | 516 ++++---- src/glut/os2/glut_gamemode.cpp | 1358 ++++++++++----------- src/glut/os2/glut_win.cpp | 2440 ++++++++++++++++++------------------- src/glut/os2/glut_winmisc.cpp | 252 ++-- src/glut/os2/os2_glx.cpp | 290 ++--- src/glut/os2/os2_menu.cpp | 1064 ++++++++--------- src/glut/os2/os2_winproc.cpp | 2592 ++++++++++++++++++++-------------------- 8 files changed, 4675 insertions(+), 4675 deletions(-) (limited to 'src/glut') diff --git a/src/glut/os2/WarpWin.cpp b/src/glut/os2/WarpWin.cpp index ee746ecc76..bd5a6e80c7 100644 --- a/src/glut/os2/WarpWin.cpp +++ b/src/glut/os2/WarpWin.cpp @@ -1,420 +1,420 @@ -/* WarpWin.c */ -/* glut for Warp */ -#include -#include - -#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 - * "=x{+-}{+-}", 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 +#include + +#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 + * "=x{+-}{+-}", 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 0897a3cf85..3484185051 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 -#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 +#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 50185d7b9d..39918fdf39 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 -#include -#include -#include - -#include "glutint.h" - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#include - -/* 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 -#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[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 +#include +#include +#include + +#include "glutint.h" + +#if !defined(_WIN32) && !defined(__OS2__) +#include +#include + +/* 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 +#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[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 82abba87e4..53ff5d5d95 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 -#endif - -#include -#include -#include -#include -#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 -#include -#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 +#endif + +#include +#include +#include +#include +#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 +#include +#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 ffa31c021c..456d19a8c1 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 -#include -#include -#include - - -#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 +#include +#include +#include + + +#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 ca345ea05b..5e135bc17e 100644 --- a/src/glut/os2/os2_glx.cpp +++ b/src/glut/os2/os2_glx.cpp @@ -1,146 +1,146 @@ -/* os2_glx.c */ - -#include -#include -#include -#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 +#include +#include +#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 4eef308e5a..56f2cdef8b 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 -#include -#include -#include -#include - -#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 +#include +#include +#include +#include + +#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 e2d4ba9d55..6ffe0d4624 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 /* It is from MMPM toolkit */ -#include -#include - - -#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 /* It is from MMPM toolkit */ +#include +#include + + +#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 -- cgit v1.2.3