diff --git a/freeglut/freeglut/include/GL/freeglut_ext.h b/freeglut/freeglut/include/GL/freeglut_ext.h index 0c22c4f..4fc33ec 100644 --- a/freeglut/freeglut/include/GL/freeglut_ext.h +++ b/freeglut/freeglut/include/GL/freeglut_ext.h @@ -90,6 +90,8 @@ #define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */ +#define GLUT_ALLOW_NEGATIVE_WINDOW_POSITION 0x0207 /* GLUT doesn't allow negative window positions by default */ + /* * New tokens for glutInitDisplayMode. * Only one GLUT_AUXn bit may be used at a time. diff --git a/freeglut/freeglut/src/fg_init.c b/freeglut/freeglut/src/fg_init.c index ed9f8d3..b72c74f 100644 --- a/freeglut/freeglut/src/fg_init.c +++ b/freeglut/freeglut/src/fg_init.c @@ -88,6 +88,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ 4, /* SampleNumber */ GL_FALSE, /* SkipStaleMotion */ GL_FALSE, /* StrokeFontDrawJoinDots */ + GL_FALSE, /* AllowNegativeWindowPosition */ 1, /* OpenGL context MajorVersion */ 0, /* OpenGL context MinorVersion */ 0, /* OpenGL ContextFlags */ @@ -357,7 +358,7 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) * size. */ - if (geometry ) + if ( geometry ) { unsigned int parsedWidth, parsedHeight; int mask = XParseGeometry( geometry, @@ -370,10 +371,10 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) ) fgState.Size.Use = GL_TRUE; - if( mask & XNegative ) + if( ( mask & XNegative ) && !fgState.AllowNegativeWindowPosition ) fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X; - if( mask & YNegative ) + if( ( mask & YNegative ) && !fgState.AllowNegativeWindowPosition ) fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y; if( (mask & (XValue|YValue)) == (XValue|YValue) ) @@ -397,7 +398,7 @@ void FGAPIENTRY glutInitWindowPosition( int x, int y ) fgState.Position.X = x; fgState.Position.Y = y; - if( ( x >= 0 ) && ( y >= 0 ) ) + if( ( ( x >= 0 ) && ( y >= 0 ) ) || fgState.AllowNegativeWindowPosition ) fgState.Position.Use = GL_TRUE; else fgState.Position.Use = GL_FALSE; diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h index 8006196..a0f2b95 100644 --- a/freeglut/freeglut/src/fg_internal.h +++ b/freeglut/freeglut/src/fg_internal.h @@ -354,6 +354,7 @@ struct tagSFG_State GLboolean SkipStaleMotion; /* skip stale motion events */ GLboolean StrokeFontDrawJoinDots;/* Draw dots between line segments of stroke fonts? */ + GLboolean AllowNegativeWindowPosition; /* GLUT, by default, doesn't allow negative window positions. Enable it? */ int MajorVersion; /* Major OpenGL context version */ int MinorVersion; /* Minor OpenGL context version */ diff --git a/freeglut/freeglut/src/fg_state.c b/freeglut/freeglut/src/fg_state.c index cc93892..7f8d3be 100644 --- a/freeglut/freeglut/src/fg_state.c +++ b/freeglut/freeglut/src/fg_state.c @@ -122,6 +122,10 @@ void FGAPIENTRY glutSetOption( GLenum eWhat, int value ) fgState.StrokeFontDrawJoinDots = !!value; break; + case GLUT_ALLOW_NEGATIVE_WINDOW_POSITION: + fgState.AllowNegativeWindowPosition = !!value; + break; + default: fgWarning( "glutSetOption(): missing enum handle %d", eWhat ); break; @@ -225,6 +229,9 @@ int FGAPIENTRY glutGet( GLenum eWhat ) case GLUT_STROKE_FONT_DRAW_JOIN_DOTS: return fgState.StrokeFontDrawJoinDots; + case GLUT_ALLOW_NEGATIVE_WINDOW_POSITION: + return fgState.AllowNegativeWindowPosition; + default: return fgPlatformGlutGet ( eWhat ); break; diff --git a/freeglut/freeglut/src/fg_structure.c b/freeglut/freeglut/src/fg_structure.c index 6fbcc57..f0bc9a2 100644 --- a/freeglut/freeglut/src/fg_structure.c +++ b/freeglut/freeglut/src/fg_structure.c @@ -75,6 +75,11 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, /* Have the window object created */ SFG_Window *window = (SFG_Window *)calloc( 1, sizeof(SFG_Window) ); + if( !window ) + { + fgError( "Out of memory. Could not create window." ); + } + fgPlatformCreateWindow ( window ); fghClearCallBacks( window ); diff --git a/freeglut/freeglut/src/fg_window.c b/freeglut/freeglut/src/fg_window.c index 09fcddf..366bbf3 100644 --- a/freeglut/freeglut/src/fg_window.c +++ b/freeglut/freeglut/src/fg_window.c @@ -177,12 +177,12 @@ int FGAPIENTRY glutCreateWindow( const char* title ) * XXX application has not already done so. The "freeglut" community * XXX decided not to go this route (freeglut-developer e-mail from * XXX Steve Baker, 12/16/04, 4:22 PM CST, "Re: [Freeglut-developer] - * XXX Desired 'freeglut' behaviour when there is no current window" + * XXX Desired 'freeglut' behaviour when there is no current window") */ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" ); - return fgCreateWindow( NULL, title, fgState.Position.Use, - fgState.Position.X, fgState.Position.Y, + return fgCreateWindow( NULL, title, + fgState.Position.Use, fgState.Position.X, fgState.Position.Y, fgState.Size.Use, fgState.Size.X, fgState.Size.Y, GL_FALSE, GL_FALSE )->ID; } @@ -199,33 +199,51 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" ); parent = fgWindowByID( parentID ); freeglut_return_val_if_fail( parent != NULL, 0 ); - if ( x < 0 ) + + if ( fgState.AllowNegativeWindowPosition ) { - x = parent->State.Width + x ; - if ( w >= 0 ) x -= w ; + /* XXX This results in different widths/heights than if AllowNegativeWindowPosition + * XXX was false. The "freeglut" community defined this logic. + * XXX (freeglut-developer e-mail from Diederick C. Niehorster, 11/15/2015, 4:06 PM EST. + * XXX "Re: [Freeglut-developer] glutInitWindowPosition with negative coordinate(s)") + */ + + if ( w < 0 ) w = parent->State.Width + w ; + if ( h < 0 ) h = parent->State.Height + h ; + } + else + { + if ( ( x < 0 ) ) + { + x = parent->State.Width + x ; + if ( w > 0 ) x -= w ; + } + + if ( w < 0 ) w = parent->State.Width - x + w ; + if ( w < 0 ) + { + x += w ; + w = -w ; + } + + if ( ( y < 0 ) ) + { + y = parent->State.Height + y ; + if ( h > 0 ) y -= h ; + } + + if ( h < 0 ) h = parent->State.Height - y + h ; + if ( h < 0 ) + { + y += h ; + h = -h ; + } } - if ( w < 0 ) w = parent->State.Width - x + w ; - if ( w < 0 ) - { - x += w ; - w = -w ; - } - - if ( y < 0 ) - { - y = parent->State.Height + y ; - if ( h >= 0 ) y -= h ; - } - - if ( h < 0 ) h = parent->State.Height - y + h ; - if ( h < 0 ) - { - y += h ; - h = -h ; - } - - window = fgCreateWindow( parent, "", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_FALSE ); + window = fgCreateWindow( parent, "", + GL_TRUE, x, y, + GL_TRUE, w, h, + GL_FALSE, GL_FALSE ); ret = window->ID; return ret; diff --git a/freeglut/freeglut/src/mswin/fg_spaceball_mswin.c b/freeglut/freeglut/src/mswin/fg_spaceball_mswin.c index 84d848d..00e42f6 100644 --- a/freeglut/freeglut/src/mswin/fg_spaceball_mswin.c +++ b/freeglut/freeglut/src/mswin/fg_spaceball_mswin.c @@ -64,14 +64,16 @@ void fgPlatformInitializeSpaceball(void) } hwnd = fgStructure.CurrentWindow->Window.Handle; - BOOL ok; - UINT cbSize = sizeof(__fgSpaceball); - __fgSpaceball.hwndTarget = hwnd; - ok = RegisterRawInputDevices(&__fgSpaceball, 1, cbSize); + { + BOOL ok; + UINT cbSize = sizeof(__fgSpaceball); + __fgSpaceball.hwndTarget = hwnd; + ok = RegisterRawInputDevices(&__fgSpaceball, 1, cbSize); - if (!ok){ - __fgSpaceball.hwndTarget = NULL; - sball_initialized = 0; + if (!ok){ + __fgSpaceball.hwndTarget = NULL; + sball_initialized = 0; + } } } @@ -138,57 +140,58 @@ void fgSpaceballHandleWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam) res = GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &sRidDeviceInfo, &size); if (res == -1) return; - - SFG_Window* window = fgWindowByHandle(hwnd); - if ((window == NULL)) - return; - - if (sRidDeviceInfo.hid.dwVendorId == LOGITECH_VENDOR_ID) { - // Motion data comes in two parts: motion type and - // displacement/rotation along three axis. - // Orientation is a right handed coordinate system with - // X goes right, Y goes up and Z goes towards viewer, e.g. - // the one used in OpenGL - if (pRawInput->data.hid.bRawData[0] == - SPNAV_EVENT_MOTION_TRANSLATION) - { // Translation vector - short* pnData = (short*)(&pRawInput->data.hid.bRawData[1]); - short X = pnData[0]; - short Y = -pnData[2]; - short Z = pnData[1]; - INVOKE_WCB(*window, SpaceMotion, (X, Y, Z)); - } - else if (pRawInput->data.hid.bRawData[0] == - SPNAV_EVENT_MOTION_ROTATION) - { // Axis aligned rotation vector - short* pnData = (short*)(&pRawInput->data.hid.bRawData[1]); - short rX = pnData[0]; - short rY = -pnData[2]; - short rZ = pnData[1]; - INVOKE_WCB(*window, SpaceRotation, (rX, rY, rZ)); - } - else if (pRawInput->data.hid.bRawData[0] == - SPNAV_EVENT_BUTTON) - { // State of the keys - unsigned long dwKeystate = *(unsigned long*)(&pRawInput->data.hid.bRawData[1]); - unsigned int state = GLUT_UP; - if (FETCH_WCB(*window, SpaceButton)) - { - int i; - for (i = 0; i < 32; i++) - { - unsigned long stateBefore = __fgSpaceKeystate&(1 << i); - unsigned long stateNow = dwKeystate&(1 << i); + SFG_Window* window = fgWindowByHandle(hwnd); + if ((window == NULL)) + return; - if (stateBefore && !stateNow) - INVOKE_WCB(*window, SpaceButton, (stateBefore, GLUT_DOWN)); - if (!stateBefore && stateNow) - INVOKE_WCB(*window, SpaceButton, (stateNow, GLUT_UP)); - - } + if (sRidDeviceInfo.hid.dwVendorId == LOGITECH_VENDOR_ID) + { + // Motion data comes in two parts: motion type and + // displacement/rotation along three axis. + // Orientation is a right handed coordinate system with + // X goes right, Y goes up and Z goes towards viewer, e.g. + // the one used in OpenGL + if (pRawInput->data.hid.bRawData[0] == + SPNAV_EVENT_MOTION_TRANSLATION) + { // Translation vector + short* pnData = (short*)(&pRawInput->data.hid.bRawData[1]); + short X = pnData[0]; + short Y = -pnData[2]; + short Z = pnData[1]; + INVOKE_WCB(*window, SpaceMotion, (X, Y, Z)); + } + else if (pRawInput->data.hid.bRawData[0] == + SPNAV_EVENT_MOTION_ROTATION) + { // Axis aligned rotation vector + short* pnData = (short*)(&pRawInput->data.hid.bRawData[1]); + short rX = pnData[0]; + short rY = -pnData[2]; + short rZ = pnData[1]; + INVOKE_WCB(*window, SpaceRotation, (rX, rY, rZ)); + } + else if (pRawInput->data.hid.bRawData[0] == + SPNAV_EVENT_BUTTON) + { // State of the keys + unsigned long dwKeystate = *(unsigned long*)(&pRawInput->data.hid.bRawData[1]); + unsigned int state = GLUT_UP; + if (FETCH_WCB(*window, SpaceButton)) + { + int i; + for (i = 0; i < 32; i++) + { + unsigned long stateBefore = __fgSpaceKeystate&(1 << i); + unsigned long stateNow = dwKeystate&(1 << i); + + if (stateBefore && !stateNow) + INVOKE_WCB(*window, SpaceButton, (stateBefore, GLUT_DOWN)); + if (!stateBefore && stateNow) + INVOKE_WCB(*window, SpaceButton, (stateNow, GLUT_UP)); + + } + } + __fgSpaceKeystate = dwKeystate; } - __fgSpaceKeystate = dwKeystate; } } } diff --git a/freeglut/web-src/docs/api.php b/freeglut/web-src/docs/api.php index 9146ef0..37d75e5 100644 --- a/freeglut/web-src/docs/api.php +++ b/freeglut/web-src/docs/api.php @@ -313,10 +313,14 @@ upper left hand corner of the outside of the window (the non-client area) is at (x,y) and the size of the drawable (client) area is (w,h). The coordinates taken by glutInitPosition and glutPositionWindow, as well as the coordinates provided by -FreeGLUT when it calls the glutPositionFunc callback, -specify the top-left of the non-client area of the window. +freeglut when it calls the glutPositionFunc callback, +specify the top-left of the non-client area of the window. By default +only positive-signed coordinates are supported. If GLUT_ALLOW_NEGATIVE_WINDOW_POSITION +is enabled, then negative coordinates are supported. An exception +for glutPositionWindow exists as it's always supported negative +window coordinates.
@@ -479,6 +490,11 @@ the window will immediately snap out to this width, but the application can call glutReshapeWindow and make a window narrower again.
++If GLUT_ALLOW_NEGATIVE_WINDOW_POSITION is enabled, glutInitWindowPosition +will accept negative window coordinates. +
+If the application has two nested calls to glutMainLoop and calls glutLeaveMainLoop, the behaviour -of freeglut is undefined. It may leave only the inner nested +of FreeGLUT is undefined. It may leave only the inner nested loop or it may leave both loops. If the reader has a strong preference -for one behaviour over the other he should contact the freeglut Programming +for one behaviour over the other he should contact the FreeGLUT Programming Consortium and ask for the code to be fixed.
@@ -650,6 +666,44 @@ Consortium and ask for the code to be fixed.+The glutCreateSubwindow function creates a subwindow of an existing window. +
+ +Usage
+ ++int glutCreateSubwindow(int window, int x, int y, int width, int height); +
+ +Description
+ ++Creates a subwindow of window that is at location x and y +relative to the window's upper-left corner, and is of the specified width and height. The newly created +window ID is returned by glutCreateSubwindow. By default, the position coordinates will only allow windows within the bounds of the parent. +Negative coordinates be treated as coordinates from the opposite edge for a given axis. In addition, the width of the window will be taken into account. +For example, if the parent window is 100 pixels wide, and the x is 10, and width is 20, the subwindow will be located at x = 10. +If x is -10, then the subwindow will be located at 70 (parent - abs(pos) - dim). If the width or height are negative, then the dimension is taken as a +subtraction of the parent dimension. For example, if the parent window is 100 pixels wide, and the x is 10, and width is 20, the +subwindow will have a size of 20. If width is -20, then the subwindow will have a width of 70 (parent - pos - abs(dim)). +
+ ++If GLUT_ALLOW_NEGATIVE_WINDOW_POSITION is enabled, the window behavior differs. Negative window coordinates are now accepted and may result in windows outside +of the viewing area, depending on the platform of operation. Negative width and height are still used as a subtraction of the parent window dimension, +but they do not take x or y into account. For example, if the parent window is 100 pixels wide, and the x is 10, and width is 20, the +subwindow will be located at x = 10. If x is -10, then the subwindow will be located at x = -10. If the parent window is 100 pixels wide, +and the x is 10, and width is 20, the subwindow will have a size of 20. If width is -20, then the subwindow will have a width of 80 (parent - abs(dim)). +
+ +Changes From GLUT
+ ++GLUT does not support negative x or y. Nor does it have GLUT_ALLOW_NEGATIVE_WINDOW_POSITION +which changes the the functionality of glutCreateSubwindow. +
+