X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_init.c;h=01dabc788242936791f2b513015ec6037c1a4b4e;hb=a213b9a3476de760b52f9661de8900787255322c;hp=054285e81ff4568e7fa50cf47f9877f44ac80c3c;hpb=30971e75717f3d7b826714fbbb1171dfaf9164cf;p=freeglut diff --git a/src/freeglut_init.c b/src/freeglut_init.c index 054285e..01dabc7 100644 --- a/src/freeglut_init.c +++ b/src/freeglut_init.c @@ -28,6 +28,10 @@ #include #include "freeglut_internal.h" +#if TARGET_HOST_POSIX_X11 +#include /* LONG_MAX */ +#endif + /* * TODO BEFORE THE STABLE RELEASE: * @@ -80,13 +84,154 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ NULL, /* ProgramName */ GL_FALSE, /* JoysticksInitialised */ GL_FALSE, /* InputDevsInitialised */ - 0, /* AuxiliaryBufferNumber */ - 0 /* SampleNumber */ + 1, /* AuxiliaryBufferNumber */ + 4, /* SampleNumber */ + 1, /* MajorVersion */ + 0, /* MajorVersion */ + 0 /* ContextFlags */ }; /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ +#if TARGET_HOST_POSIX_X11 + +/* Return the atom associated with "name". */ +static Atom fghGetAtom(const char * name) +{ + return XInternAtom(fgDisplay.Display, name, False); +} + +/* + * Check if "property" is set on "window". The property's values are returned + * through "data". If the property is set and is of type "type", return the + * number of elements in "data". Return zero otherwise. In both cases, use + * "Xfree()" to free "data". + */ +static int fghGetWindowProperty(Window window, + Atom property, + Atom type, + unsigned char ** data) +{ + /* + * Caller always has to use "Xfree()" to free "data", since + * "XGetWindowProperty() always allocates one extra byte in prop_return + * [i.e. "data"] (even if the property is zero length) [..]". + */ + + int status; /* Returned by "XGetWindowProperty". */ + + Atom type_returned; + int temp_format; /* Not used. */ + unsigned long number_of_elements; + unsigned long temp_bytes_after; /* Not used. */ + + + status = XGetWindowProperty(fgDisplay.Display, + window, + property, + 0, + LONG_MAX, + False, + type, + &type_returned, + &temp_format, + &number_of_elements, + &temp_bytes_after, + data); + + FREEGLUT_INTERNAL_ERROR_EXIT(status == Success, + "XGetWindowProperty failled", + "fghGetWindowProperty"); + + if (type_returned != type) + { + number_of_elements = 0; + } + + return number_of_elements; +} + +/* Check if the window manager is NET WM compliant. */ +static int fghNetWMSupported(void) +{ + Atom wm_check; + Window ** window_ptr_1; + + int number_of_windows; + int net_wm_supported; + + + net_wm_supported = 0; + + wm_check = fghGetAtom("_NET_SUPPORTING_WM_CHECK"); + window_ptr_1 = malloc(sizeof(Window *)); + + /* + * Check that the window manager has set this property on the root window. + * The property must be the ID of a child window. + */ + number_of_windows = fghGetWindowProperty(fgDisplay.RootWindow, + wm_check, + XA_WINDOW, + (unsigned char **) window_ptr_1); + if (number_of_windows == 1) + { + Window ** window_ptr_2; + + window_ptr_2 = malloc(sizeof(Window *)); + + /* Check that the window has the same property set to the same value. */ + number_of_windows = fghGetWindowProperty(**window_ptr_1, + wm_check, + XA_WINDOW, + (unsigned char **) window_ptr_2); + if ((number_of_windows == 1) && (**window_ptr_1 == **window_ptr_2)) + { + /* NET WM compliant */ + net_wm_supported = 1; + } + + XFree(*window_ptr_2); + free(window_ptr_2); + } + + XFree(*window_ptr_1); + free(window_ptr_1); + + return net_wm_supported; +} + +/* Check if "hint" is present in "property" for "window". */ +int fgHintPresent(Window window, Atom property, Atom hint) +{ + Atom ** atoms_ptr; + int number_of_atoms; + int supported; + int i; + + supported = 0; + + atoms_ptr = malloc(sizeof(Atom *)); + number_of_atoms = fghGetWindowProperty(window, + property, + XA_ATOM, + (unsigned char **) atoms_ptr); + for (i = 0; i < number_of_atoms; i++) + { + if ((*atoms_ptr)[i] == hint) + { + supported = 1; + break; + } + } + + return supported; +} + +#endif /* TARGET_HOST_POSIX_X11 */ + + /* * A call to this function should initialize all the display stuff... */ @@ -129,11 +274,32 @@ static void fghInitialize( const char* displayName ) fgDisplay.Connection = ConnectionNumber( fgDisplay.Display ); /* Create the window deletion atom */ - fgDisplay.DeleteWindow = XInternAtom( - fgDisplay.Display, - "WM_DELETE_WINDOW", - FALSE - ); + fgDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW"); + + /* Create the state and full screen atoms */ + fgDisplay.State = None; + fgDisplay.StateFullScreen = None; + + if (fghNetWMSupported()) + { + const Atom supported = fghGetAtom("_NET_SUPPORTED"); + const Atom state = fghGetAtom("_NET_WM_STATE"); + + /* Check if the state hint is supported. */ + if (fgHintPresent(fgDisplay.RootWindow, supported, state)) + { + const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN"); + + fgDisplay.State = state; + + /* Check if the window manager supports full screen. */ + /** Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/ + if (fgHintPresent(fgDisplay.RootWindow, supported, full_screen)) + { + fgDisplay.StateFullScreen = full_screen; + } + } + } #elif TARGET_HOST_MS_WINDOWS @@ -255,6 +421,10 @@ void fgDeinitialize( void ) fgState.JoysticksInitialised = GL_FALSE; fgState.InputDevsInitialised = GL_FALSE; + fgState.MajorVersion = 1; + fgState.MinorVersion = 0; + fgState.ContextFlags = 0; + fgState.Initialised = GL_FALSE; fgState.Position.X = -1; @@ -507,6 +677,12 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) char* geometry = NULL; int i, j, argc = *pargc; + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + size_t sLen; + errno_t err; +#endif + if( fgState.Initialised ) fgError( "illegal glutInit() reinitialization attempt" ); @@ -526,7 +702,15 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) /* check if GLUT_FPS env var is set */ #ifndef _WIN32_WCE { + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + char* fps = NULL; + err = _dupenv_s( &fps, &sLen, "GLUT_FPS" ); + if (err) + fgError("Error getting GLUT_FPS environment variable"); +#else const char *fps = getenv( "GLUT_FPS" ); +#endif if( fps ) { int interval; @@ -537,9 +721,20 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) else fgState.FPSInterval = interval; } + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + free ( fps ); fps = NULL; /* dupenv_s allocates a string that we must free */ +#endif } - displayName = getenv( "DISPLAY"); + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + err = _dupenv_s( &displayName, &sLen, "DISPLAY" ); + if (err) + fgError("Error getting DISPLAY environment variable"); +#else + displayName = getenv( "DISPLAY" ); +#endif for( i = 1; i < argc; i++ ) { @@ -624,6 +819,10 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) * variable for opening the X display (see code above): */ fghInitialize( displayName ); + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + free ( displayName ); displayName = NULL; /* dupenv_s allocates a string that we must free */ +#endif /* * Geometry parsing deffered until here because we may need the screen @@ -722,12 +921,21 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode ) * delimited by blanks or tabs. */ char *token ; + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + char *next_token = NULL; +#endif size_t len = strlen ( displayMode ); char *buffer = (char *)malloc ( (len+1) * sizeof(char) ); memcpy ( buffer, displayMode, len ); buffer[len] = '\0'; + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + token = strtok_s ( buffer, " \t", &next_token ); +#else token = strtok ( buffer, " \t" ); +#endif while ( token ) { /* Process this token */ @@ -904,7 +1112,12 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode ) break ; } + /* will return true for VC8 (VC2005) and higher */ +#if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 ) + token = strtok_s ( NULL, " \t", &next_token ); +#else token = strtok ( NULL, " \t" ); +#endif } free ( buffer ); @@ -913,4 +1126,20 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode ) fgState.DisplayMode = glut_state_flag; } +/* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */ + +void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion ) +{ + /* We will make use of these valuse when creating a new OpenGL context... */ + fgState.MajorVersion = majorVersion; + fgState.MinorVersion = minorVersion; +} + + +void FGAPIENTRY glutInitContextFlags( int flags ) +{ + /* We will make use of this value when creating a new OpenGL context... */ + fgState.ContextFlags = flags; +} + /*** END OF FILE ***/