#include <GL/freeglut.h>
#include "freeglut_internal.h"
-#if TARGET_HOST_WINCE
-#include <aygshell.h>
-#pragma comment( lib, "Aygshell.lib" )
+#if defined(_WIN32_WCE)
+# include <Aygshell.h>
+# ifdef FREEGLUT_LIB_PRAGMAS
+# pragma comment( lib, "Aygshell.lib" )
+# endif
static wchar_t* fghWstrFromStr(const char* str)
{
return wstr;
}
-
-#endif /* TARGET_HOST_WINCE */
+#endif /* defined(_WIN32_WCE) */
/*
* TODO BEFORE THE STABLE RELEASE:
/*
* Chooses a visual basing on the current display mode settings
*/
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XVisualInfo* fgChooseVisual( void )
{
ATTRIB_VAL( GLX_AUX_BUFFERS, 3 );
if( fgState.DisplayMode & GLUT_AUX4 )
ATTRIB_VAL( GLX_AUX_BUFFERS, 4 );
+ if ( fgState.DisplayMode & GLUT_MULTISAMPLE )
+ ATTRIB_VAL( GLX_SAMPLES_SGIS, 4 );
/* Push a null at the end of the list */
/*
* Setup the pixel format for a Win32 window
*/
-#if TARGET_HOST_WIN32
+#if TARGET_HOST_MS_WINDOWS
+/* The following include file is available from SGI but is not standard:
+ * #include <GL/wglext.h>
+ * So we copy the necessary parts out of it.
+ * XXX: should local definitions for extensions be put in a separate include file?
+ */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+
+
GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
unsigned char layer_type )
{
-#if TARGET_HOST_WINCE
+#if defined(_WIN32_WCE)
return GL_TRUE;
#else
PIXELFORMATDESCRIPTOR* ppfd, pfd;
if( fgState.DisplayMode & GLUT_DOUBLE )
flags |= PFD_DOUBLEBUFFER;
+ if( fgState.DisplayMode & GLUT_STEREO )
+ flags |= PFD_STEREO;
+
#if defined(_MSC_VER)
#pragma message( "fgSetupPixelFormat(): there is still some work to do here!" )
#endif
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = flags;
- pfd.iPixelType = PFD_TYPE_RGBA;
+
+ if( fgState.DisplayMode & GLUT_INDEX )
+ {
+ pfd.iPixelType = PFD_TYPE_COLORINDEX;
+ pfd.cRedBits = 0;
+ pfd.cGreenBits = 0;
+ pfd.cBlueBits = 0;
+ pfd.cAlphaBits = 0;
+ }
+ else
+ {
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cRedBits = 8;
+ pfd.cGreenBits = 8;
+ pfd.cBlueBits = 8;
+ if ( fgState.DisplayMode & GLUT_ALPHA )
+ pfd.cAlphaBits = 8;
+ else
+ pfd.cAlphaBits = 0;
+ }
+
pfd.cColorBits = 24;
- pfd.cRedBits = 0;
pfd.cRedShift = 0;
- pfd.cGreenBits = 0;
pfd.cGreenShift = 0;
- pfd.cBlueBits = 0;
pfd.cBlueShift = 0;
- pfd.cAlphaBits = 0;
pfd.cAlphaShift = 0;
pfd.cAccumBits = 0;
pfd.cAccumRedBits = 0;
ppfd = &pfd;
pixelformat = ChoosePixelFormat( window->Window.Device, ppfd );
+
+ /* windows hack for multismapling */
+ if (fgState.DisplayMode&GLUT_MULTISAMPLE)
+ {
+ PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetEntensionsStringARB=NULL;
+ HGLRC rc, rc_before=wglGetCurrentContext();
+ HWND hWnd;
+ HDC hDC, hDC_before=wglGetCurrentDC();
+ WNDCLASS wndCls;
+ ATOM atom;
+
+ /* create a dummy window */
+ ZeroMemory(&wndCls, sizeof(wndCls));
+ wndCls.lpfnWndProc = DefWindowProc;
+ wndCls.hInstance = fgDisplay.Instance;
+ wndCls.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ wndCls.lpszClassName = _T("FREEGLUT_dummy");
+ atom = RegisterClass( &wndCls );
+
+ hWnd=CreateWindow((LPCSTR)atom, _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.Instance, 0 );
+ hDC=GetDC(hWnd);
+ SetPixelFormat( hDC, pixelformat, ppfd );
+
+ rc = wglCreateContext( hDC );
+ wglMakeCurrent(hDC, rc);
+
+ wglGetEntensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
+ if (wglGetEntensionsStringARB)
+ {
+ const char * pWglExtString=wglGetEntensionsStringARB(hDC);
+ if (pWglExtString)
+ {
+ if (strstr(pWglExtString, "WGL_ARB_multisample"))
+ {
+ int pAttributes[100];
+ int iCounter=0;
+ int iPixelFormat;
+ BOOL bValid;
+ float fAttributes[] = {0,0};
+ UINT numFormats;
+ PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARBProc=NULL;
+
+ wglChoosePixelFormatARBProc=(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
+ if ( wglChoosePixelFormatARBProc )
+ {
+ pAttributes[iCounter++]=WGL_DRAW_TO_WINDOW_ARB; pAttributes[iCounter++]=GL_TRUE;
+ pAttributes[iCounter++]=WGL_SUPPORT_OPENGL_ARB; pAttributes[iCounter++]=GL_TRUE;
+ pAttributes[iCounter++]=WGL_ACCELERATION_ARB; pAttributes[iCounter++]=WGL_FULL_ACCELERATION_ARB;
+
+ pAttributes[iCounter++]=WGL_COLOR_BITS_ARB; pAttributes[iCounter++]=pfd.cColorBits ;
+ pAttributes[iCounter++]=WGL_ALPHA_BITS_ARB; pAttributes[iCounter++]=pfd.cAlphaBits;
+ pAttributes[iCounter++]=WGL_DEPTH_BITS_ARB; pAttributes[iCounter++]=pfd.cDepthBits;
+ pAttributes[iCounter++]=WGL_STENCIL_BITS_ARB; pAttributes[iCounter++]=pfd.cStencilBits;
+
+ pAttributes[iCounter++]=WGL_DOUBLE_BUFFER_ARB; pAttributes[iCounter++]=(fgState.DisplayMode & GLUT_DOUBLE)!=0;
+ pAttributes[iCounter++]=WGL_SAMPLE_BUFFERS_ARB; pAttributes[iCounter++]=GL_TRUE;
+ pAttributes[iCounter++]=WGL_SAMPLES_ARB; pAttributes[iCounter++]=4;
+ pAttributes[iCounter++]=0; pAttributes[iCounter++]=0; /* terminator */
+
+ bValid = wglChoosePixelFormatARBProc(window->Window.Device,pAttributes,fAttributes,1,&iPixelFormat,&numFormats);
+
+ if (bValid && numFormats>0)
+ pixelformat=iPixelFormat;
+ }
+ }
+ wglMakeCurrent( hDC_before, rc_before);
+ wglDeleteContext(rc);
+ ReleaseDC(hWnd, hDC);
+ DestroyWindow(hWnd);
+ UnregisterClass(_T("FREEGLUT_dummy"), fgDisplay.Instance);
+ }
+ }
+ }
+
if( pixelformat == 0 )
return GL_FALSE;
if( checkOnly )
return GL_TRUE;
return SetPixelFormat( window->Window.Device, pixelformat, ppfd );
-#endif /* TARGET_HOST_WINCE */
+#endif /* defined(_WIN32_WCE) */
}
-#endif
+#endif /* TARGET_HOST_MS_WINDOWS */
/*
* Sets the OpenGL context and the fgStructure "Current Window" pointer to
*/
void fgSetWindow ( SFG_Window *window )
{
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
if ( window )
glXMakeCurrent(
fgDisplay.Display,
window->Window.Handle,
window->Window.Context
);
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
if( fgStructure.CurrentWindow )
ReleaseDC( fgStructure.CurrentWindow->Window.Handle,
fgStructure.CurrentWindow->Window.Device );
* to the freeglut structure. OpenGL context is created here.
*/
void fgOpenWindow( SFG_Window* window, const char* title,
- int x, int y, int w, int h,
+ GLboolean positionUse, int x, int y,
+ GLboolean sizeUse, int w, int h,
GLboolean gameMode, GLboolean isSubWindow )
{
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XSetWindowAttributes winAttr;
XTextProperty textProperty;
XSizeHints sizeHints;
fgState.DisplayMode &= ~GLUT_DOUBLE;
}
- /*
- * GLUT also checks for multi-sampling, but I don't see that
- * anywhere else in FREEGLUT so I won't bother with it for the moment.
- */
+ if( fgState.DisplayMode & GLUT_MULTISAMPLE )
+ {
+ fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
+ window->Window.VisualInfo = fgChooseVisual( );
+ fgState.DisplayMode |= GLUT_MULTISAMPLE;
+ }
}
FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL,
mask |= CWOverrideRedirect;
}
+ if( ! positionUse )
+ x = y = -1; /* default window position */
+ if( ! sizeUse )
+ w = h = 300; /* default window size */
+
window->Window.Handle = XCreateWindow(
fgDisplay.Display,
window->Parent == NULL ? fgDisplay.RootWindow :
{
fgStructure.MenuContext =
(SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) );
- fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo;
- fgStructure.MenuContext->Context = glXCreateContext(
- fgDisplay.Display, fgStructure.MenuContext->VisualInfo,
+ fgStructure.MenuContext->MVisualInfo = window->Window.VisualInfo;
+ fgStructure.MenuContext->MContext = glXCreateContext(
+ fgDisplay.Display, fgStructure.MenuContext->MVisualInfo,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
);
}
- /* window->Window.Context = fgStructure.MenuContext->Context; */
+ /* window->Window.Context = fgStructure.MenuContext->MContext; */
window->Window.Context = glXCreateContext(
fgDisplay.Display, window->Window.VisualInfo,
NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT )
window->State.Visible = GL_TRUE;
sizeHints.flags = 0;
- if ( fgState.Position.Use )
+ if ( positionUse )
sizeHints.flags |= USPosition;
- if ( fgState.Size.Use )
+ if ( sizeUse )
sizeHints.flags |= USSize;
/*
XMapWindow( fgDisplay.Display, window->Window.Handle );
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
WNDCLASS wc;
DWORD flags;
}
else
{
-#if !TARGET_HOST_WINCE
+ int worig = w, horig = h;
+
+#if !defined(_WIN32_WCE)
if ( ( ! isSubWindow ) && ( ! window->IsMenu ) )
{
/*
h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 +
GetSystemMetrics( SM_CYCAPTION );
}
-#endif /* TARGET_HOST_WINCE */
+#endif /* defined(_WIN32_WCE) */
- if( ! fgState.Position.Use )
+ if( ! positionUse )
{
x = CW_USEDEFAULT;
y = CW_USEDEFAULT;
}
- if( ! fgState.Size.Use )
+ /* setting State.Width/Height to call resize callback later */
+ if( ! sizeUse )
+ {
+ if( ! window->IsMenu )
+ {
+ w = CW_USEDEFAULT;
+ h = CW_USEDEFAULT;
+ }
+ else /* fail safe - Windows can make a window of size (0, 0) */
+ w = h = 300; /* default window size */
+ window->State.Width = window->State.Height = -1;
+ }
+ else
{
- w = CW_USEDEFAULT;
- h = CW_USEDEFAULT;
+ window->State.Width = worig;
+ window->State.Height = horig;
}
/*
flags |= WS_POPUP;
exFlags |= WS_EX_TOOLWINDOW;
}
-#if !TARGET_HOST_WINCE
+#if !defined(_WIN32_WCE)
else if( window->Parent == NULL )
flags |= WS_OVERLAPPEDWINDOW;
#endif
flags |= WS_CHILD;
}
-#if TARGET_HOST_WINCE
+#if defined(_WIN32_WCE)
{
wchar_t* wstr = fghWstrFromStr(title);
#else
window->Window.Handle = CreateWindowEx(
exFlags,
- "FREEGLUT",
+ _T("FREEGLUT"),
title,
flags,
x, y, w, h,
fgDisplay.Instance,
(LPVOID) window
);
-#endif /* TARGET_HOST_WINCE */
+#endif /* defined(_WIN32_WCE) */
if( !( window->Window.Handle ) )
fgError( "Failed to create a window (%s)!", title );
-#if TARGET_HOST_WINCE
+#if defined(_WIN32_WCE)
ShowWindow( window->Window.Handle, SW_SHOW );
#else
ShowWindow( window->Window.Handle,
fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW );
-#endif /* TARGET_HOST_WINCE */
+#endif /* defined(_WIN32_WCE) */
UpdateWindow( window->Window.Handle );
ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */
*/
void fgCloseWindow( SFG_Window* window )
{
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
glXDestroyContext( fgDisplay.Display, window->Window.Context );
+ XFree( window->Window.VisualInfo );
XDestroyWindow( fgDisplay.Display, window->Window.Handle );
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
/* Make sure we don't close a window with current context active */
if( fgStructure.CurrentWindow == window )
*/
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" );
- return fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y,
- fgState.Size.X, fgState.Size.Y, GL_FALSE,
- GL_FALSE )->ID;
+ 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;
}
/*
h = -h ;
}
- window = fgCreateWindow( parent, "", x, y, 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;
*/
int FGAPIENTRY glutGetWindow( void )
{
+ SFG_Window *win = fgStructure.CurrentWindow;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetWindow" );
- if( fgStructure.CurrentWindow == NULL )
- return 0;
- return fgStructure.CurrentWindow->ID;
+ while ( win && win->IsMenu )
+ win = win->Parent;
+ return win ? win->ID : 0;
}
/*
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutShowWindow" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutShowWindow" );
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XMapWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_SHOW );
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutHideWindow" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutHideWindow" );
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
if( fgStructure.CurrentWindow->Parent == NULL )
XWithdrawWindow( fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle );
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_HIDE );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIconifyWindow" );
fgStructure.CurrentWindow->State.Visible = GL_FALSE;
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XIconifyWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
fgDisplay.Screen );
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowTitle" );
if( ! fgStructure.CurrentWindow->Parent )
{
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XTextProperty text;
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32
-
- SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
-
-#elif TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
+# ifdef _WIN32_WCE
{
wchar_t* wstr = fghWstrFromStr(title);
-
SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
-
free(wstr);
}
+# else
+ SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
+# endif
+
#endif
}
}
if( ! fgStructure.CurrentWindow->Parent )
{
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XTextProperty text;
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32
-
- SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
-
-#elif TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
+# ifdef _WIN32_WCE
{
wchar_t* wstr = fghWstrFromStr(title);
-
SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
-
free(wstr);
}
+# else
+ SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
+# endif
+
#endif
}
}
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPositionWindow" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPositionWindow" );
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XMoveWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
x, y );
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
{
RECT winRect;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPushWindow" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPushWindow" );
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XLowerWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
SetWindowPos(
fgStructure.CurrentWindow->Window.Handle,
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPopWindow" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPopWindow" );
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
XRaiseWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
SetWindowPos(
fgStructure.CurrentWindow->Window.Handle,
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
{
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
int x, y;
Window w;
);
XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
}
-#elif TARGET_HOST_WIN32
+#elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: what about WinCE */
RECT rect;
/* For fullscreen mode, force the top-left corner to 0,0