Пример #1
0
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;
  }
}
Пример #2
0
/*
 * 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
}