void fgAndroidTryCreateContextAndSurface(SFG_Window* window) { if (!window->Window.Context) { window->State.WorkMask |= GLUT_INIT_WORK; /* Create context */ fghChooseConfig(&window->Window.pContext.egl.Config); window->Window.Context = fghCreateNewContextEGL(window); } if (!window->Window.pContext.egl.Surface) { EGLDisplay display = fgDisplay.pDisplay.egl.Display; /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). * As soon as we picked a EGLConfig, we can safely reconfigure the * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ EGLint vid; eglGetConfigAttrib(display, window->Window.pContext.egl.Config, EGL_NATIVE_VISUAL_ID, &vid); int32_t err = ANativeWindow_setBuffersGeometry(*window->Window.Handle, 0, 0, vid); assert(!err); fghPlatformOpenWindowEGL(window); window->State.Visible = GL_TRUE; } }
int fghPlatformGlutGetGLX ( GLenum eWhat ) { switch( eWhat ) { /* * The window/context specific queries are handled mostly by * fgPlatformGetConfig(). */ case GLUT_WINDOW_NUM_SAMPLES: { int nsamples = 0; #ifdef GLX_VERSION_1_3 glGetIntegerv(GL_SAMPLES, &nsamples); #endif return nsamples; } /* * The rest of GLX queries under X are general enough to use a macro to * check them */ # define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b ); GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA ); GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER ); GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE ); GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE ); GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE ); GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE ); GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE ); GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE ); GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE ); GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE ); GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO ); # undef GLX_QUERY /* I do not know yet if there will be a fgChooseVisual() function for Win32 */ case GLUT_DISPLAY_MODE_POSSIBLE: { /* We should not have to call fghChooseConfig again here. */ GLXFBConfig config; return fghChooseConfig(&config); } /* This is system-dependent */ case GLUT_WINDOW_FORMAT_ID: if( fgStructure.CurrentWindow == NULL ) return 0; return fgPlatformGetConfig( GLX_VISUAL_ID ); default: fgWarning( "glutGet(): missing enum handle %d", eWhat ); break; } return -1; }
void fgPlatformOpenWindow( SFG_Window* window, const char* title, GLboolean positionUse, int x, int y, GLboolean sizeUse, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { /* Save the display mode if we are creating a menu window */ if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; fghChooseConfig( &window->Window.pContext.egl.Config ); if( ! window->Window.pContext.egl.Config ) { /* * The "fghChooseConfig" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ if( fgState.DisplayMode & GLUT_MULTISAMPLE ) { fgState.DisplayMode &= ~GLUT_MULTISAMPLE ; fghChooseConfig( &window->Window.pContext.egl.Config ); fgState.DisplayMode |= GLUT_MULTISAMPLE; } } FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.egl.Config != NULL, "EGL configuration with necessary capabilities " "not found", "fgOpenWindow" ); if( ! positionUse ) x = y = -1; /* default window position */ if( ! sizeUse ) w = h = 300; /* default window size */ /* Create the cursor */ window->Window.pContext.cursor = wl_cursor_theme_get_cursor( fgDisplay.pDisplay.cursor_theme, "left_ptr" ); window->Window.pContext.cursor_surface = wl_compositor_create_surface( fgDisplay.pDisplay.compositor ); /* Create the main surface */ window->Window.pContext.surface = wl_compositor_create_surface( fgDisplay.pDisplay.compositor ); /* Create the shell surface with respects to the parent/child tree */ window->Window.pContext.shsurface = wl_shell_get_shell_surface( fgDisplay.pDisplay.shell, window->Window.pContext.surface ); wl_shell_surface_add_listener( window->Window.pContext.shsurface, &fghShSurfaceListener, window ); if( title) wl_shell_surface_set_title( window->Window.pContext.shsurface, title ); if( gameMode ) { window->State.IsFullscreen = GL_TRUE; wl_shell_surface_set_fullscreen( window->Window.pContext.shsurface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL ); } else if( !isSubWindow && !window->IsMenu ) { wl_shell_surface_set_toplevel( window->Window.pContext.shsurface ); } else { wl_shell_surface_set_transient( window->Window.pContext.shsurface, window->Parent->Window.pContext.surface, x, y, 0 ); } /* Create the Wl_EGL_Window */ window->Window.Context = fghCreateNewContext( window ); window->Window.pContext.egl_window = wl_egl_window_create( window->Window.pContext.surface, w, h); window->Window.pContext.egl.Surface = eglCreateWindowSurface( fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Config, (EGLNativeWindowType)window->Window.pContext.egl_window, NULL ); eglMakeCurrent( fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Surface, window->Window.pContext.egl.Surface, window->Window.Context ); window->Window.pContext.pointer_button_pressed = GL_FALSE; }
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgPlatformOpenWindow( SFG_Window* window, const char* title, GLboolean positionUse, int x, int y, GLboolean sizeUse, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { XVisualInfo * visualInfo = NULL; XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; XWMHints wmHints; XEvent eventReturnBuffer; /* return buffer required for a call */ unsigned long mask; unsigned int current_DisplayMode = fgState.DisplayMode ; XConfigureEvent fakeEvent = {0}; /* Save the display mode if we are creating a menu window */ if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; #ifdef EGL_VERSION_1_0 #define WINDOW_CONFIG window->Window.pContext.egl.Config #else #define WINDOW_CONFIG window->Window.pContext.FBConfig #endif fghChooseConfig(&WINDOW_CONFIG); if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = current_DisplayMode ; if( ! WINDOW_CONFIG ) { /* * The "fghChooseConfig" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ #ifndef EGL_VERSION_1_0 if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; fghChooseConfig(&WINDOW_CONFIG); fgState.DisplayMode &= ~GLUT_DOUBLE; } #endif if( fgState.DisplayMode & GLUT_MULTISAMPLE ) { fgState.DisplayMode &= ~GLUT_MULTISAMPLE ; fghChooseConfig(&WINDOW_CONFIG); fgState.DisplayMode |= GLUT_MULTISAMPLE; } } FREEGLUT_INTERNAL_ERROR_EXIT( WINDOW_CONFIG != NULL, "FBConfig with necessary capabilities not found", "fgOpenWindow" ); /* Get the X visual. */ #ifdef EGL_VERSION_1_0 EGLint vid = 0; XVisualInfo visualTemplate; int num_visuals; if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Config, EGL_NATIVE_VISUAL_ID, &vid)) fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed"); visualTemplate.visualid = vid; visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals); #else visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, window->Window.pContext.FBConfig ); #endif FREEGLUT_INTERNAL_ERROR_EXIT( visualInfo != NULL, "visualInfo could not be retrieved from FBConfig", "fgOpenWindow" ); /* * XXX HINT: the masks should be updated when adding/removing callbacks. * XXX This might speed up message processing. Is that true? * XXX * XXX A: Not appreciably, but it WILL make it easier to debug. * XXX Try tracing old GLUT and try tracing freeglut. Old GLUT * XXX turns off events that it doesn't need and is a whole lot * XXX more pleasant to trace. (Think mouse-motion! Tons of * XXX ``bonus'' GUI events stream in.) */ winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask; winAttr.background_pixmap = None; winAttr.background_pixel = 0; winAttr.border_pixel = 0; winAttr.colormap = XCreateColormap( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow, visualInfo->visual, AllocNone ); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; if( window->IsMenu || ( gameMode == GL_TRUE ) ) { winAttr.override_redirect = True; mask |= CWOverrideRedirect; } if( ! positionUse ) x = y = -1; /* default window position */ if( ! sizeUse ) w = h = 300; /* default window size */ window->Window.Handle = XCreateWindow( fgDisplay.pDisplay.Display, window->Parent == NULL ? fgDisplay.pDisplay.RootWindow : window->Parent->Window.Handle, x, y, w, h, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &winAttr ); /* Fake configure event to force viewport setup * even with no window manager. */ fakeEvent.type = ConfigureNotify; fakeEvent.display = fgDisplay.pDisplay.Display; fakeEvent.window = window->Window.Handle; fakeEvent.x = x; fakeEvent.y = y; fakeEvent.width = w; fakeEvent.height = h; XPutBackEvent(fgDisplay.pDisplay.Display, (XEvent*)&fakeEvent); /* * The GLX context creation, possibly trying the direct context rendering * or else use the current context if the user has so specified */ if( window->IsMenu ) { /* * If there isn't already an OpenGL rendering context for menu * windows, make one */ if( !fgStructure.MenuContext ) { fgStructure.MenuContext = (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); fgStructure.MenuContext->MContext = fghCreateNewContext( window ); } /* window->Window.Context = fgStructure.MenuContext->MContext; */ window->Window.Context = fghCreateNewContext( window ); } else if( fgState.UseCurrentContext ) { #ifdef EGL_VERSION_1_0 window->Window.Context = eglGetCurrentContext( ); #else window->Window.Context = glXGetCurrentContext( ); #endif if( ! window->Window.Context ) window->Window.Context = fghCreateNewContext( window ); } else window->Window.Context = fghCreateNewContext( window ); #if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) && !defined(EGL_VERSION_1_0) if( !glXIsDirect( fgDisplay.pDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); } #endif sizeHints.flags = 0; if ( positionUse ) sizeHints.flags |= USPosition; if ( sizeUse ) sizeHints.flags |= USSize; /* * Fill in the size hints values now (the x, y, width and height * settings are obsolete, are there any more WMs that support them?) * Unless the X servers actually stop supporting these, we should * continue to fill them in. It is *not* our place to tell the user * that they should replace a window manager that they like, and which * works, just because *we* think that it's not "modern" enough. */ sizeHints.x = x; sizeHints.y = y; sizeHints.width = w; sizeHints.height = h; wmHints.flags = StateHint; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; /* Prepare the window and iconified window names... */ XStringListToTextProperty( (char **) &title, 1, &textProperty ); XSetWMProperties( fgDisplay.pDisplay.Display, window->Window.Handle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ); XFree( textProperty.value ); XSetWMProtocols( fgDisplay.pDisplay.Display, window->Window.Handle, &fgDisplay.pDisplay.DeleteWindow, 1 ); #ifdef EGL_VERSION_1_0 fghPlatformOpenWindowEGL(window); #else glXMakeContextCurrent( fgDisplay.pDisplay.Display, window->Window.Handle, window->Window.Handle, window->Window.Context ); #endif #ifdef FREEGLUT_REGAL RegalMakeCurrent(window->Window.Context); #endif /* register extension events _before_ window is mapped */ #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H fgRegisterDevices( fgDisplay.pDisplay.Display, &(window->Window.Handle) ); #endif if (!window->IsMenu) /* Don't show window after creation if its a menu */ { XMapWindow( fgDisplay.pDisplay.Display, window->Window.Handle ); window->State.Visible = GL_TRUE; } XFree(visualInfo); /* wait till window visible */ if( !isSubWindow && !window->IsMenu) XPeekIfEvent( fgDisplay.pDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, (XPointer)(window->Window.Handle) ); #undef WINDOW_CONFIG }