/* * This private function creates a menu and adds it to the menus list */ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) { int x = 100, y = 100, w = 1, h = 1; SFG_Window *current_window = fgStructure.CurrentWindow; /* Have the menu object created */ SFG_Menu* menu = (SFG_Menu *)calloc( sizeof(SFG_Menu), 1 ); menu->ParentWindow = NULL; /* Create a window for the menu to reside in. */ fgCreateWindow( NULL, "freeglut menu", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_TRUE ); menu->Window = fgStructure.CurrentWindow; glutDisplayFunc( fgDisplayMenu ); glutHideWindow( ); /* Hide the window for now */ fgSetWindow( current_window ); /* Initialize the object properties: */ menu->ID = ++fgStructure.MenuID; menu->Callback = menuCallback; menu->ActiveEntry = NULL; fgListInit( &menu->Entries ); fgListAppend( &fgStructure.Menus, &menu->Node ); /* Newly created menus implicitly become current ones */ fgStructure.CurrentMenu = menu; return menu; }
/* * Creates a new top-level freeglut window */ int FGAPIENTRY glutCreateWindow( const char* title ) { /* XXX GLUT does not exit; it simply calls "glutInit" quietly if the * 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" */ 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; }
/* * This function creates a sub window. */ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) { int ret = 0; SFG_Window* window = NULL; SFG_Window* parent = NULL; freeglut_assert_ready; parent = fgWindowByID( parentID ); freeglut_return_val_if_fail( parent != NULL, 0 ); window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE, GL_FALSE ); ret = window->ID; return ret; }
/* * This function creates a sub window. */ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) { int ret = 0; SFG_Window* window = NULL; SFG_Window* parent = NULL; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" ); parent = fgWindowByID( parentID ); freeglut_return_val_if_fail( parent != NULL, 0 ); 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 ; } window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE, GL_FALSE ); ret = window->ID; return ret; }
/* * Enters the game mode */ int FGAPIENTRY glutEnterGameMode( void ) { FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEnterGameMode" ); if( fgStructure.GameMode ) fgAddToWindowDestroyList( fgStructure.GameMode ); else fghRememberState( ); if( ! fghChangeDisplayMode( GL_FALSE ) ) { fgWarning( "failed to change screen settings" ); return 0; } fgStructure.GameMode = fgCreateWindow( NULL, "FREEGLUT", 0, 0, fgState.GameModeSize.X, fgState.GameModeSize.Y, GL_TRUE, GL_FALSE ); fgStructure.GameMode->State.Width = fgState.GameModeSize.X; fgStructure.GameMode->State.Height = fgState.GameModeSize.Y; fgStructure.GameMode->State.NeedToResize = GL_TRUE; fgStructure.GameMode->State.IsGameMode = GL_TRUE; #if TARGET_HOST_UNIX_X11 /* * Sync needed to avoid a real race, the Xserver must have really created * the window before we can grab the pointer into it: */ XSync( fgDisplay.Display, False ); /* * Grab the pointer to confine it into the window after the calls to * XWrapPointer() which ensure that the pointer really enters the window. * * We also need to wait here until XGrabPointer() returns GrabSuccess, * otherwise the new window is not viewable yet and if the next function * (XSetInputFocus) is called with a not yet viewable window, it will exit * the application which we have to aviod, so wait until it's viewable: */ while( GrabSuccess != XGrabPointer( fgDisplay.Display, fgStructure.GameMode->Window.Handle, TRUE, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, fgStructure.GameMode->Window.Handle, None, CurrentTime) ) usleep( 100 ); /* * Change input focus to the new window. This will exit the application * if the new window is not viewable yet, see the XGrabPointer loop above. */ XSetInputFocus( fgDisplay.Display, fgStructure.GameMode->Window.Handle, RevertToNone, CurrentTime ); /* Move the Pointer to the middle of the fullscreen window */ XWarpPointer( fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0, fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2 ); # ifdef X_XF86VidModeSetViewPort if( fgDisplay.DisplayModeValid ) { int x, y; Window child; /* Change to viewport to the window topleft edge: */ if( !XF86VidModeSetViewPort( fgDisplay.Display, fgDisplay.Screen, 0, 0 ) ) fgWarning( "XF86VidModeSetViewPort failed" ); /* * Final window repositioning: It could be avoided using an undecorated * window using override_redirect, but this * would possily require * more changes and investigation. */ /* Get the current postion of the drawable area on screen */ XTranslateCoordinates( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, fgDisplay.RootWindow, 0, 0, &x, &y, &child ); /* Move the decorataions out of the topleft corner of the display */ XMoveWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, -x, -y); } #endif /* Grab the keyboard, too */ XGrabKeyboard( fgDisplay.Display, fgStructure.GameMode->Window.Handle, FALSE, GrabModeAsync, GrabModeAsync, CurrentTime ); #endif return fgStructure.GameMode->ID; }
/* * Creates a new top-level freeglut window */ int FGAPIENTRY glutCreateWindow( const char* title ) { return fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y, fgState.Size.X, fgState.Size.Y, GL_FALSE, GL_FALSE )->ID; }