X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_init.c;h=d602a71b7d73fedca2fdd69b71f5857ccf87cce8;hb=027fcf9e66356b06563140740f8d1c7bc05c9987;hp=702f1e5557d222cfa1f6a49cffe4f1507365f213;hpb=796957d75280b0b50fb2c41a0f90fc25522b9a3a;p=freeglut diff --git a/src/freeglut_init.c b/src/freeglut_init.c index 702f1e5..d602a71 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: * @@ -65,11 +69,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ 0, /* FPSInterval */ 0, /* SwapCount */ 0, /* SwapTime */ -#if TARGET_HOST_MS_WINDOWS - { 0, GL_FALSE }, /* Time */ -#else - { { 0, 0 }, GL_FALSE }, -#endif + 0, /* Time */ { NULL, NULL }, /* Timers */ { NULL, NULL }, /* FreeTimers */ NULL, /* IdleCallback */ @@ -83,12 +83,152 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ GLUT_EXEC_STATE_INIT, /* ExecState */ NULL, /* ProgramName */ GL_FALSE, /* JoysticksInitialised */ - GL_FALSE /* InputDevsInitialised */ + GL_FALSE, /* InputDevsInitialised */ + 0, /* AuxiliaryBufferNumber */ + 0 /* SampleNumber */ }; /* -- 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... */ @@ -131,11 +271,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 @@ -285,8 +446,6 @@ void fgDeinitialize( void ) fgState.GameModeDepth = 16; fgState.GameModeRefresh = 72; - fgState.Time.Set = GL_FALSE; - fgListInit( &fgState.Timers ); fgListInit( &fgState.FreeTimers ); @@ -524,7 +683,8 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) fgCreateStructure( ); - fgElapsedTime( ); + /* Get start time */ + fgState.Time = fgSystemTime(); /* check if GLUT_FPS env var is set */ #ifndef _WIN32_WCE @@ -658,6 +818,14 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) } /* + * Undoes all the "glutInit" stuff + */ +void FGAPIENTRY glutExit ( void ) +{ + fgDeinitialize (); +} + +/* * Sets the default initial window position for new windows */ void FGAPIENTRY glutInitWindowPosition( int x, int y ) @@ -717,7 +885,7 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode ) * delimited by blanks or tabs. */ char *token ; - int len = strlen ( displayMode ); + size_t len = strlen ( displayMode ); char *buffer = (char *)malloc ( (len+1) * sizeof(char) ); memcpy ( buffer, displayMode, len ); buffer[len] = '\0'; @@ -890,7 +1058,7 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode ) break ; case 36 : /* "aux": some number of aux buffers */ - glut_state_flag |= GLUT_AUX1; + glut_state_flag |= GLUT_AUX; break ; case 37 : /* Unrecognized */