Merge pull request #39 from rcmaniac25/feature/negative_window_coordinates
Support for negative window position coordinates
This commit is contained in:
commit
8dd4743e55
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 <tt>glutInitPosition</tt> and
|
||||
<tt>glutPositionWindow</tt>, as well as the coordinates provided by
|
||||
<i>FreeGLUT</i> when it calls the <tt>glutPositionFunc</tt> callback,
|
||||
specify the top-left of the non-client area of the window.</li>
|
||||
<i>freeglut</i> when it calls the <tt>glutPositionFunc</tt> 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 <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
|
||||
<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
|
||||
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
|
||||
@ -440,7 +444,7 @@ functions specify a desired position and size for windows that
|
||||
<i>freeglut</i> will create in the future.
|
||||
The position is measured in pixels from the upper left hand corner of the
|
||||
screen, with "x" increasing to the right and "y" increasing towards the bottom
|
||||
of the screen. The size is measured in pixels. <i>Freeglut</i>
|
||||
of the screen. The size is measured in pixels. <i>Freeglut</i>
|
||||
does not promise to follow these specifications in creating its windows,
|
||||
but it certainly makes an attempt to.
|
||||
</p>
|
||||
@ -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
|
||||
<a href="#Conventions">FreeGLUT's conventions</a>, the information
|
||||
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>
|
||||
@ -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.
|
||||
</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.4 glutInitDisplayString</h2>
|
||||
@ -634,9 +650,9 @@ will exit.
|
||||
<p>
|
||||
If the application has two nested calls to <tt>glutMainLoop</tt> and calls
|
||||
<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
|
||||
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.
|
||||
</p>
|
||||
|
||||
@ -650,6 +666,44 @@ Consortium and ask for the code to be fixed.
|
||||
|
||||
<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.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>
|
||||
<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>
|
||||
<li>GLUT_ALLOW_NEGATIVE_WINDOW_POSITION - Set if negative positions can be
|
||||
used for window coordinates.</li>
|
||||
</ul>
|
||||
</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
|
||||
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>
|
||||
<li>GLUT_ALLOW_NEGATIVE_WINDOW_POSITION - 1 if negative window positions are enabled, 0 otherwise</li>
|
||||
</ul>
|
||||
|
||||
<h2>13.3 glutDeviceGet</h2>
|
||||
|
Reference in New Issue
Block a user