void fgPlatformInitialize( const char* displayName ) { fgDisplay.pDisplay.display = wl_display_connect( NULL ); if( fgDisplay.pDisplay.display == NULL ) fgError( "failed to connect to a Wayland compositor" ); fgDisplay.pDisplay.registry = wl_display_get_registry( fgDisplay.pDisplay.display ); wl_registry_add_listener( fgDisplay.pDisplay.registry, &fghRegistryListener, &fgDisplay.pDisplay ); wl_display_roundtrip( fgDisplay.pDisplay.display ); if( fgDisplay.pDisplay.compositor == NULL || fgDisplay.pDisplay.shell == NULL || fgDisplay.pDisplay.seat == NULL || fgDisplay.pDisplay.shm == NULL ) fgError( "failed to discover all needed compositor interfaces" ); fghInitialiseCursorTheme(); fghPlatformInitializeEGL(); /* Get start time */ fgState.Time = fgSystemTime(); fgState.Initialised = GL_TRUE; atexit(fgDeinitialize); /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */ fgPlatformInitialiseInputDevices(); }
/* * Perform initialization. This usually happens on the program startup * and restarting after glutMainLoop termination... */ void FGAPIENTRY glutInit( int* pargc, char** argv ) { char* displayName = NULL; char* geometry = NULL; int i, j, argc = *pargc; if( fgState.Initialised ) fgError( "illegal glutInit() reinitialization attempt" ); if (pargc && *pargc && argv && *argv && **argv) { fgState.ProgramName = strdup (*argv); if( !fgState.ProgramName ) fgError ("Could not allocate space for the program's name."); } fgCreateStructure( ); /* Get start time */ fgState.Time = fgSystemTime(); /* check if GLUT_FPS env var is set */ #ifndef _WIN32_WCE { const char *fps = getenv( "GLUT_FPS" ); if( fps ) { int interval; sscanf( fps, "%d", &interval ); if( interval <= 0 ) fgState.FPSInterval = 5000; /* 5000 millisecond default */ else fgState.FPSInterval = interval; } } displayName = getenv( "DISPLAY" ); for( i = 1; i < argc; i++ ) { if( strcmp( argv[ i ], "-display" ) == 0 ) { if( ++i >= argc ) fgError( "-display parameter must be followed by display name" ); displayName = argv[ i ]; argv[ i - 1 ] = NULL; argv[ i ] = NULL; ( *pargc ) -= 2; } else if( strcmp( argv[ i ], "-geometry" ) == 0 ) { if( ++i >= argc ) fgError( "-geometry parameter must be followed by window " "geometry settings" ); geometry = argv[ i ]; argv[ i - 1 ] = NULL; argv[ i ] = NULL; ( *pargc ) -= 2; } else if( strcmp( argv[ i ], "-direct" ) == 0) { if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT ) fgError( "parameters ambiguity, -direct and -indirect " "cannot be both specified" ); fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT; argv[ i ] = NULL; ( *pargc )--; } else if( strcmp( argv[ i ], "-indirect" ) == 0 ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "parameters ambiguity, -direct and -indirect " "cannot be both specified" ); fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT; argv[ i ] = NULL; (*pargc)--; } else if( strcmp( argv[ i ], "-iconic" ) == 0 ) { fgState.ForceIconic = GL_TRUE; argv[ i ] = NULL; ( *pargc )--; } else if( strcmp( argv[ i ], "-gldebug" ) == 0 ) { fgState.GLDebugSwitch = GL_TRUE; argv[ i ] = NULL; ( *pargc )--; } else if( strcmp( argv[ i ], "-sync" ) == 0 ) { fgState.XSyncSwitch = GL_TRUE; argv[ i ] = NULL; ( *pargc )--; } } /* Compact {argv}. */ for( i = j = 1; i < *pargc; i++, j++ ) { /* Guaranteed to end because there are "*pargc" arguments left */ while ( argv[ j ] == NULL ) j++; if ( i != j ) argv[ i ] = argv[ j ]; } #endif /* _WIN32_WCE */ /* * Have the display created now. If there wasn't a "-display" * in the program arguments, we will use the DISPLAY environment * variable for opening the X display (see code above): */ fghInitialize( displayName ); /* * Geometry parsing deffered until here because we may need the screen * size. */ if (geometry ) { unsigned int parsedWidth, parsedHeight; int mask = XParseGeometry( geometry, &fgState.Position.X, &fgState.Position.Y, &parsedWidth, &parsedHeight ); /* TODO: Check for overflow? */ fgState.Size.X = parsedWidth; fgState.Size.Y = parsedHeight; if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) ) fgState.Size.Use = GL_TRUE; if( mask & XNegative ) fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X; if( mask & YNegative ) fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y; if( (mask & (XValue|YValue)) == (XValue|YValue) ) fgState.Position.Use = GL_TRUE; } }
/* * Elapsed Time */ fg_time_t fgElapsedTime( void ) { return fgSystemTime() - fgState.Time; }
/* * A call to this function should initialize all the display stuff... */ void fgPlatformInitialize( const char* displayName ) { fgDisplay.pDisplay.Display = XOpenDisplay( displayName ); if( fgDisplay.pDisplay.Display == NULL ) fgError( "failed to open display '%s'", XDisplayName( displayName ) ); if ( fgState.XSyncSwitch ) XSynchronize(fgDisplay.pDisplay.Display, True); #ifdef EGL_VERSION_1_0 fghPlatformInitializeEGL(); #else if( !glXQueryExtension( fgDisplay.pDisplay.Display, NULL, NULL ) ) fgError( "OpenGL GLX extension not supported by display '%s'", XDisplayName( displayName ) ); /* This forces AMD Catalyst drivers to initialize and register a shutdown * function, which must be done before our own call to atexit to prevent * a crash if glutMainLoop is not called or is not exited cleanly. * (see bug #206) */ glXQueryExtensionsString( fgDisplay.pDisplay.Display, DefaultScreen( fgDisplay.pDisplay.Display )); #endif fgDisplay.pDisplay.Screen = DefaultScreen( fgDisplay.pDisplay.Display ); fgDisplay.pDisplay.RootWindow = RootWindow( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenWidth = DisplayWidth( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenHeight = DisplayHeight( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenWidthMM = DisplayWidthMM( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenHeightMM = DisplayHeightMM( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.pDisplay.Connection = ConnectionNumber( fgDisplay.pDisplay.Display ); /* Create the window deletion atom */ fgDisplay.pDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW"); /* Create the state and full screen atoms */ fgDisplay.pDisplay.State = None; fgDisplay.pDisplay.StateFullScreen = None; fgDisplay.pDisplay.NetWMPid = None; fgDisplay.pDisplay.ClientMachine = None; fgDisplay.pDisplay.NetWMSupported = fghNetWMSupported(); if (fgDisplay.pDisplay.NetWMSupported) { const Atom supported = fghGetAtom("_NET_SUPPORTED"); const Atom state = fghGetAtom("_NET_WM_STATE"); /* Check if the state hint is supported. */ if (fgHintPresent(fgDisplay.pDisplay.RootWindow, supported, state)) { const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN"); fgDisplay.pDisplay.State = state; /* Check if the window manager supports full screen. */ /** Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/ if (fgHintPresent(fgDisplay.pDisplay.RootWindow, supported, full_screen)) { fgDisplay.pDisplay.StateFullScreen = full_screen; } } fgDisplay.pDisplay.NetWMPid = fghGetAtom("_NET_WM_PID"); fgDisplay.pDisplay.ClientMachine = fghGetAtom("WM_CLIENT_MACHINE"); } /* Get start time */ fgState.Time = fgSystemTime(); fgState.Initialised = GL_TRUE; atexit(fgDeinitialize); /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */ fgInitialiseInputDevices(); }
/* * A call to this function should initialize all the display stuff... */ void fgPlatformInitialize( const char* displayName ) { fgDisplay.pDisplay.Display = XOpenDisplay( displayName ); if( fgDisplay.pDisplay.Display == NULL ) fgError( "failed to open display '%s'", XDisplayName( displayName ) ); #ifdef EGL_VERSION_1_0 fghPlatformInitializeEGL(); #else if( !glXQueryExtension( fgDisplay.pDisplay.Display, NULL, NULL ) ) fgError( "OpenGL GLX extension not supported by display '%s'", XDisplayName( displayName ) ); #endif fgDisplay.pDisplay.Screen = DefaultScreen( fgDisplay.pDisplay.Display ); fgDisplay.pDisplay.RootWindow = RootWindow( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenWidth = DisplayWidth( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenHeight = DisplayHeight( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenWidthMM = DisplayWidthMM( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.ScreenHeightMM = DisplayHeightMM( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen ); fgDisplay.pDisplay.Connection = ConnectionNumber( fgDisplay.pDisplay.Display ); /* Create the window deletion atom */ fgDisplay.pDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW"); /* Create the state and full screen atoms */ fgDisplay.pDisplay.State = None; fgDisplay.pDisplay.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.pDisplay.RootWindow, supported, state)) { const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN"); fgDisplay.pDisplay.State = state; /* Check if the window manager supports full screen. */ /** Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/ if (fgHintPresent(fgDisplay.pDisplay.RootWindow, supported, full_screen)) { fgDisplay.pDisplay.StateFullScreen = full_screen; } } } /* Get start time */ fgState.Time = fgSystemTime(); fgState.Initialised = GL_TRUE; atexit(fgDeinitialize); /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */ fgInitialiseInputDevices(); }