Merge pull request #39 from rcmaniac25/feature/negative_window_coordinates

Support for negative window position coordinates
This commit is contained in:
Diederick C. Niehorster 2015-12-14 17:20:39 +01:00
commit 8dd4743e55
8 changed files with 187 additions and 93 deletions

View File

@ -90,6 +90,8 @@
#define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */ #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. * New tokens for glutInitDisplayMode.
* Only one GLUT_AUXn bit may be used at a time. * Only one GLUT_AUXn bit may be used at a time.

View File

@ -88,6 +88,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
4, /* SampleNumber */ 4, /* SampleNumber */
GL_FALSE, /* SkipStaleMotion */ GL_FALSE, /* SkipStaleMotion */
GL_FALSE, /* StrokeFontDrawJoinDots */ GL_FALSE, /* StrokeFontDrawJoinDots */
GL_FALSE, /* AllowNegativeWindowPosition */
1, /* OpenGL context MajorVersion */ 1, /* OpenGL context MajorVersion */
0, /* OpenGL context MinorVersion */ 0, /* OpenGL context MinorVersion */
0, /* OpenGL ContextFlags */ 0, /* OpenGL ContextFlags */
@ -357,7 +358,7 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
* size. * size.
*/ */
if (geometry ) if ( geometry )
{ {
unsigned int parsedWidth, parsedHeight; unsigned int parsedWidth, parsedHeight;
int mask = XParseGeometry( geometry, int mask = XParseGeometry( geometry,
@ -370,10 +371,10 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) ) if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
fgState.Size.Use = GL_TRUE; fgState.Size.Use = GL_TRUE;
if( mask & XNegative ) if( ( mask & XNegative ) && !fgState.AllowNegativeWindowPosition )
fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X; fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
if( mask & YNegative ) if( ( mask & YNegative ) && !fgState.AllowNegativeWindowPosition )
fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y; fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
if( (mask & (XValue|YValue)) == (XValue|YValue) ) if( (mask & (XValue|YValue)) == (XValue|YValue) )
@ -397,7 +398,7 @@ void FGAPIENTRY glutInitWindowPosition( int x, int y )
fgState.Position.X = x; fgState.Position.X = x;
fgState.Position.Y = y; fgState.Position.Y = y;
if( ( x >= 0 ) && ( y >= 0 ) ) if( ( ( x >= 0 ) && ( y >= 0 ) ) || fgState.AllowNegativeWindowPosition )
fgState.Position.Use = GL_TRUE; fgState.Position.Use = GL_TRUE;
else else
fgState.Position.Use = GL_FALSE; fgState.Position.Use = GL_FALSE;

View File

@ -354,6 +354,7 @@ struct tagSFG_State
GLboolean SkipStaleMotion; /* skip stale motion events */ GLboolean SkipStaleMotion; /* skip stale motion events */
GLboolean StrokeFontDrawJoinDots;/* Draw dots between line segments of stroke fonts? */ 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 MajorVersion; /* Major OpenGL context version */
int MinorVersion; /* Minor OpenGL context version */ int MinorVersion; /* Minor OpenGL context version */

View File

@ -122,6 +122,10 @@ void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
fgState.StrokeFontDrawJoinDots = !!value; fgState.StrokeFontDrawJoinDots = !!value;
break; break;
case GLUT_ALLOW_NEGATIVE_WINDOW_POSITION:
fgState.AllowNegativeWindowPosition = !!value;
break;
default: default:
fgWarning( "glutSetOption(): missing enum handle %d", eWhat ); fgWarning( "glutSetOption(): missing enum handle %d", eWhat );
break; break;
@ -225,6 +229,9 @@ int FGAPIENTRY glutGet( GLenum eWhat )
case GLUT_STROKE_FONT_DRAW_JOIN_DOTS: case GLUT_STROKE_FONT_DRAW_JOIN_DOTS:
return fgState.StrokeFontDrawJoinDots; return fgState.StrokeFontDrawJoinDots;
case GLUT_ALLOW_NEGATIVE_WINDOW_POSITION:
return fgState.AllowNegativeWindowPosition;
default: default:
return fgPlatformGlutGet ( eWhat ); return fgPlatformGlutGet ( eWhat );
break; break;

View File

@ -75,6 +75,11 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
/* Have the window object created */ /* Have the window object created */
SFG_Window *window = (SFG_Window *)calloc( 1, sizeof(SFG_Window) ); SFG_Window *window = (SFG_Window *)calloc( 1, sizeof(SFG_Window) );
if( !window )
{
fgError( "Out of memory. Could not create window." );
}
fgPlatformCreateWindow ( window ); fgPlatformCreateWindow ( window );
fghClearCallBacks( window ); fghClearCallBacks( window );

View File

@ -177,12 +177,12 @@ int FGAPIENTRY glutCreateWindow( const char* title )
* XXX application has not already done so. The "freeglut" community * XXX application has not already done so. The "freeglut" community
* XXX decided not to go this route (freeglut-developer e-mail from * 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 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" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" );
return fgCreateWindow( NULL, title, fgState.Position.Use, return fgCreateWindow( NULL, title,
fgState.Position.X, fgState.Position.Y, fgState.Position.Use, fgState.Position.X, fgState.Position.Y,
fgState.Size.Use, fgState.Size.X, fgState.Size.Y, fgState.Size.Use, fgState.Size.X, fgState.Size.Y,
GL_FALSE, GL_FALSE )->ID; GL_FALSE, GL_FALSE )->ID;
} }
@ -199,10 +199,24 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" );
parent = fgWindowByID( parentID ); parent = fgWindowByID( parentID );
freeglut_return_val_if_fail( parent != NULL, 0 ); freeglut_return_val_if_fail( parent != NULL, 0 );
if ( x < 0 )
if ( fgState.AllowNegativeWindowPosition )
{
/* 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 ; x = parent->State.Width + x ;
if ( w >= 0 ) x -= w ; if ( w > 0 ) x -= w ;
} }
if ( w < 0 ) w = parent->State.Width - x + w ; if ( w < 0 ) w = parent->State.Width - x + w ;
@ -212,10 +226,10 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
w = -w ; w = -w ;
} }
if ( y < 0 ) if ( ( y < 0 ) )
{ {
y = parent->State.Height + y ; y = parent->State.Height + y ;
if ( h >= 0 ) y -= h ; if ( h > 0 ) y -= h ;
} }
if ( h < 0 ) h = parent->State.Height - y + h ; if ( h < 0 ) h = parent->State.Height - y + h ;
@ -224,8 +238,12 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
y += h ; y += h ;
h = -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; ret = window->ID;
return ret; return ret;

View File

@ -64,6 +64,7 @@ void fgPlatformInitializeSpaceball(void)
} }
hwnd = fgStructure.CurrentWindow->Window.Handle; hwnd = fgStructure.CurrentWindow->Window.Handle;
{
BOOL ok; BOOL ok;
UINT cbSize = sizeof(__fgSpaceball); UINT cbSize = sizeof(__fgSpaceball);
__fgSpaceball.hwndTarget = hwnd; __fgSpaceball.hwndTarget = hwnd;
@ -73,6 +74,7 @@ void fgPlatformInitializeSpaceball(void)
__fgSpaceball.hwndTarget = NULL; __fgSpaceball.hwndTarget = NULL;
sball_initialized = 0; sball_initialized = 0;
} }
}
} }
void fgPlatformSpaceballClose(void) void fgPlatformSpaceballClose(void)
@ -138,7 +140,7 @@ void fgSpaceballHandleWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
res = GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &sRidDeviceInfo, &size); res = GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &sRidDeviceInfo, &size);
if (res == -1) if (res == -1)
return; return;
{
SFG_Window* window = fgWindowByHandle(hwnd); SFG_Window* window = fgWindowByHandle(hwnd);
if ((window == NULL)) if ((window == NULL))
return; return;
@ -191,6 +193,7 @@ void fgSpaceballHandleWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
__fgSpaceKeystate = dwKeystate; __fgSpaceKeystate = dwKeystate;
} }
} }
}
} }
#endif #endif

View File

@ -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). area) is at (x,y) and the size of the drawable (client) area is (w,h).
The coordinates taken by <tt>glutInitPosition</tt> and The coordinates taken by <tt>glutInitPosition</tt> and
<tt>glutPositionWindow</tt>, as well as the coordinates provided by <tt>glutPositionWindow</tt>, as well as the coordinates provided by
<i>FreeGLUT</i> when it calls the <tt>glutPositionFunc</tt> callback, <i>freeglut</i> when it calls the <tt>glutPositionFunc</tt> callback,
specify the top-left of the non-client area of the window.</li> 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 <tt>glutPositionWindow</tt> exists as it's always supported negative
window coordinates.</li>
<li>When you query the size and position of the window using <li>When you query the size and position of the window using
<tt>glutGet</tt>, <i>FreeGLUT</i> will return the size of the drawable <tt>glutGet</tt>, <i>freeglut</i> will return the size of the drawable
area--the (w,h) that you specified when you created the window--and the area--the (w,h) that you specified when you created the window--and the
coordinates of the upper left hand corner of the drawable (client) coordinates of the upper left hand corner of the drawable (client)
area--which is <u>NOT</u> the (x,y) position of the window you specified area--which is <u>NOT</u> the (x,y) position of the window you specified
@ -457,7 +461,14 @@ With <tt>glutGet</tt> information can be acquired about the current
window's size, position and decorations. Note however that according to window's size, position and decorations. Note however that according to
<a href="#Conventions">FreeGLUT's conventions</a>, the information <a href="#Conventions">FreeGLUT's conventions</a>, the information
returned about the window coordinates does not correspond to the returned about the window coordinates does not correspond to the
coordinates used when setting window position. coordinates used when setting window position. In addition, GLUT only
accepts positive window coordinates, and ignores all negative window
coordinates. But if GLUT_ALLOW_NEGATIVE_WINDOW_POSITION is enabled,
then negative window coordinates can be used. This is useful for
multi-montitor setups where the second monitor may be in the negative
desktop space of the primary monitor, as now the window can be placed
on the additional monitors. Furthermore, this flag also determines how
negative coordinates and sizes are interpreted for subwindows.
</p> </p>
<p> <p>
@ -479,6 +490,11 @@ the window will immediately snap out to this width, but the application can
call <tt>glutReshapeWindow</tt> and make a window narrower again. call <tt>glutReshapeWindow</tt> and make a window narrower again.
</p> </p>
<p>
If GLUT_ALLOW_NEGATIVE_WINDOW_POSITION is enabled, <tt>glutInitWindowPosition</tt>
will accept negative window coordinates.
</p>
<h2>4.3 glutInitDisplayMode</h2> <h2>4.3 glutInitDisplayMode</h2>
<h2>4.4 glutInitDisplayString</h2> <h2>4.4 glutInitDisplayString</h2>
@ -634,9 +650,9 @@ will exit.
<p> <p>
If the application has two nested calls to <tt>glutMainLoop</tt> and calls If the application has two nested calls to <tt>glutMainLoop</tt> and calls
<tt>glutLeaveMainLoop</tt>, the behaviour <tt>glutLeaveMainLoop</tt>, the behaviour
of <i>freeglut</i> is undefined. It may leave only the inner nested of <i>FreeGLUT</i> is undefined. It may leave only the inner nested
loop or it may leave both loops. If the reader has a strong preference loop or it may leave both loops. If the reader has a strong preference
for one behaviour over the other he should contact the <i>freeglut</i> Programming for one behaviour over the other he should contact the <i>FreeGLUT</i> Programming
Consortium and ask for the code to be fixed. Consortium and ask for the code to be fixed.
</p> </p>
@ -650,6 +666,44 @@ Consortium and ask for the code to be fixed.
<h2>6.2 glutCreateSubwindow</h2> <h2>6.2 glutCreateSubwindow</h2>
<p>
The <tt>glutCreateSubwindow</tt> function creates a subwindow of an existing window.
</p>
<p><b>Usage</b></p>
<p>
<tt>int glutCreateSubwindow(int window, int x, int y, int width, int height);</tt>
</p>
<p><b>Description</b></p>
<p>
Creates a subwindow of <i>window</i> that is at location <i>x</i> and <i>y</i>
relative to the window's upper-left corner, and is of the specified <i>width</i> and <i>height</i>. The newly created
window ID is returned by <tt>glutCreateSubwindow</tt>. 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 <i>x</i> is 10, and <i>width</i> is 20, the subwindow will be located at <tt>x = 10</tt>.
If <i>x</i> is -10, then the subwindow will be located at 70 <tt>(parent - abs(pos) - dim)</tt>. If the <i>width</i> or <i>height</i> 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 <i>x</i> is 10, and <i>width</i> is 20, the
subwindow will have a size of 20. If <i>width</i> is -20, then the subwindow will have a width of 70 <tt>(parent - pos - abs(dim))</tt>.
</p>
<p>
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 <i>width</i> and <i>height</i> are still used as a subtraction of the parent window dimension,
but they do not take <i>x</i> or <i>y</i> into account. For example, if the parent window is 100 pixels wide, and the <i>x</i> is 10, and <i>width</i> is 20, the
subwindow will be located at <tt>x = 10</tt>. If <i>x</i> is -10, then the subwindow will be located at <tt>x = -10</tt>. If the parent window is 100 pixels wide,
and the <i>x</i> is 10, and <i>width</i> is 20, the subwindow will have a size of 20. If <i>width</i> is -20, then the subwindow will have a width of 80 <tt>(parent - abs(dim))</tt>.
</p>
<p><b>Changes From GLUT</b></p>
<p>
GLUT does not support negative <i>x</i> or <i>y</i>. Nor does it have GLUT_ALLOW_NEGATIVE_WINDOW_POSITION
which changes the the functionality of <tt>glutCreateSubwindow</tt>.
</p>
<h2>6.3 glutDestroyWindow</h2> <h2>6.3 glutDestroyWindow</h2>
<h2>6.4 glutSetWindow, glutGetWindow</h2> <h2>6.4 glutSetWindow, glutGetWindow</h2>
@ -1528,6 +1582,8 @@ href="#GeometricObject"><i>FreeGLUT</i>'s geometric object rendering
functions</a> also visualize the object's normals or not.</li> functions</a> also visualize the object's normals or not.</li>
<li>GLUT_STROKE_FONT_DRAW_JOIN_DOTS - Set whether join dots are drawn <li>GLUT_STROKE_FONT_DRAW_JOIN_DOTS - Set whether join dots are drawn
between line segments when drawing letters of stroke fonts or not.</li> between line segments when drawing letters of stroke fonts or not.</li>
<li>GLUT_ALLOW_NEGATIVE_WINDOW_POSITION - Set if negative positions can be
used for window coordinates.</li>
</ul> </ul>
</p> </p>
@ -1606,6 +1662,7 @@ glutInitDisplayMode or glutSetOption(GLUT_INIT_DISPLAY_MODE, value)</li>
<li>GLUT_VERSION - Return value will be X*10000+Y*100+Z where X is the <li>GLUT_VERSION - Return value will be X*10000+Y*100+Z where X is the
major version, Y is the minor version and Z is the patch level. major version, Y is the minor version and Z is the patch level.
This query is only supported in <i>freeglut</i> (version 2.0.0 or later).</li> This query is only supported in <i>freeglut</i> (version 2.0.0 or later).</li>
<li>GLUT_ALLOW_NEGATIVE_WINDOW_POSITION - 1 if negative window positions are enabled, 0 otherwise</li>
</ul> </ul>
<h2>13.3 glutDeviceGet</h2> <h2>13.3 glutDeviceGet</h2>