示例#1
0
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
{
    _GLFWwindow* window = (_GLFWwindow*) handle;

    _GLFW_REQUIRE_INIT();

    // Allow closing of NULL (to match the behavior of free)
    if (window == NULL)
        return;

    // Clear all callbacks to avoid exposing a half torn-down window object
    memset(&window->callbacks, 0, sizeof(window->callbacks));

    // The window's context must not be current on another thread when the
    // window is destroyed
    if (window == _glfwPlatformGetCurrentContext())
        glfwMakeContextCurrent(NULL);

    _glfwPlatformDestroyWindow(window);

    // Unlink window from global linked list
    {
        _GLFWwindow** prev = &_glfw.windowListHead;

        while (*prev != window)
            prev = &((*prev)->next);

        *prev = window->next;
    }

    free(window);
}
示例#2
0
static int extensionSupported(const char* extension)
{
    const char* extensions;

    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    if (_glfw.wgl.GetExtensionsStringEXT)
    {
        extensions = _glfw.wgl.GetExtensionsStringEXT();
        if (extensions)
        {
            if (_glfwStringInExtensionString(extension, extensions))
                return GLFW_TRUE;
        }
    }

    if (_glfw.wgl.GetExtensionsStringARB)
    {
        extensions = _glfw.wgl.GetExtensionsStringARB(window->context.wgl.dc);
        if (extensions)
        {
            if (_glfwStringInExtensionString(extension, extensions))
                return GLFW_TRUE;
        }
    }

    return GLFW_FALSE;
}
示例#3
0
int _glfwPlatformExtensionSupported(const char* extension)
{
    const GLubyte* extensions;

    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    if (window->wgl.GetExtensionsStringEXT != NULL)
    {
        extensions = (GLubyte*) window->wgl.GetExtensionsStringEXT();
        if (extensions != NULL)
        {
            if (_glfwStringInExtensionString(extension, extensions))
                return GL_TRUE;
        }
    }

    if (window->wgl.GetExtensionsStringARB != NULL)
    {
        extensions = (GLubyte*) window->wgl.GetExtensionsStringARB(window->wgl.dc);
        if (extensions != NULL)
        {
            if (_glfwStringInExtensionString(extension, extensions))
                return GL_TRUE;
        }
    }

    return GL_FALSE;
}
示例#4
0
文件: context.c 项目: keithpitt/glfw
GLFWAPI int glfwExtensionSupported(const char* extension)
{
    const GLubyte* extensions;
    _GLFWwindow* window;

    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return GL_FALSE;
    }

    window = _glfwPlatformGetCurrentContext();
    if (!window)
    {
        _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
        return GL_FALSE;
    }

    if (extension == NULL || *extension == '\0')
    {
        _glfwInputError(GLFW_INVALID_VALUE, NULL);
        return GL_FALSE;
    }

    if (window->glMajor < 3)
    {
        // Check if extension is in the old style OpenGL extensions string

        extensions = glGetString(GL_EXTENSIONS);
        if (extensions != NULL)
        {
            if (_glfwStringInExtensionString(extension, extensions))
                return GL_TRUE;
        }
    }
#if defined(_GLFW_USE_OPENGL)
    else
    {
        int i;
        GLint count;

        // Check if extension is in the modern OpenGL extensions string list

        glGetIntegerv(GL_NUM_EXTENSIONS, &count);

        for (i = 0;  i < count;  i++)
        {
             if (strcmp((const char*) window->GetStringi(GL_EXTENSIONS, i),
                         extension) == 0)
             {
                 return GL_TRUE;
             }
        }
    }
#endif // _GLFW_USE_OPENGL

    // Check if extension is in the platform-specific string
    return _glfwPlatformExtensionSupported(extension);
}
示例#5
0
文件: context.c 项目: keithpitt/glfw
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return NULL;
    }

    return (GLFWwindow*) _glfwPlatformGetCurrentContext();
}
示例#6
0
static void swapBuffers(_GLFWwindow* window)
{
    if (window != _glfwPlatformGetCurrentContext())
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "EGL: The context must be current on the calling thread when swapping buffers");
        return;
    }

    eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
}
示例#7
0
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
    _GLFWwindow* window = (_GLFWwindow*) handle;

    _GLFW_REQUIRE_INIT();

    if (_glfwPlatformGetCurrentContext() == window)
        return;

    _glfwPlatformMakeContextCurrent(window);
}
GLFWAPI void glfwSwapInterval(int interval)
{
    _GLFW_REQUIRE_INIT();

    if (!_glfwPlatformGetCurrentContext())
    {
        _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
        return;
    }

    _glfwPlatformSwapInterval(interval);
}
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{
    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);

    if (!_glfwPlatformGetCurrentContext())
    {
        _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
        return NULL;
    }

    return _glfwPlatformGetProcAddress(procname);
}
示例#10
0
文件: window.c 项目: Bloodknight/glfw
GLFWAPI void glfwDestroyWindow(GLFWwindow handle)
{
    _GLFWwindow* window = (_GLFWwindow*) handle;

    if (!_glfwInitialized)
    {
        _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
        return;
    }

    // Allow closing of NULL (to match the behavior of free)
    if (window == NULL)
        return;

    // Clear all callbacks to avoid exposing a half torn-down window object
    window->windowPosCallback = NULL;
    window->windowSizeCallback = NULL;
    window->windowCloseCallback = NULL;
    window->windowRefreshCallback = NULL;
    window->windowFocusCallback = NULL;
    window->windowIconifyCallback = NULL;
    window->mouseButtonCallback = NULL;
    window->cursorPosCallback = NULL;
    window->cursorEnterCallback = NULL;
    window->scrollCallback = NULL;
    window->keyCallback = NULL;
    window->charCallback = NULL;

    // The window's context must not be current on another thread when the
    // window is destroyed
    if (window == _glfwPlatformGetCurrentContext())
        _glfwPlatformMakeContextCurrent(NULL);

    // Clear the focused window pointer if this is the focused window
    if (window == _glfwLibrary.focusedWindow)
        _glfwLibrary.focusedWindow = NULL;

    _glfwPlatformDestroyWindow(window);

    // Unlink window from global linked list
    {
        _GLFWwindow** prev = &_glfwLibrary.windowListHead;

        while (*prev != window)
            prev = &((*prev)->next);

        *prev = window->next;
    }

    free(window);
}
示例#11
0
void _glfwPlatformSwapInterval(int interval)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    window->wgl.interval = interval;

    // HACK: Disable WGL swap interval when desktop composition is enabled to
    //       avoid interfering with DWM vsync
    if (_glfwIsCompositionEnabled() && !window->monitor)
        interval = 0;

    if (window->wgl.EXT_swap_control)
        window->wgl.SwapIntervalEXT(interval);
}
void _glfwPlatformSwapInterval(int interval)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

#if !defined(_GLFW_USE_DWM_SWAP_INTERVAL)
    // HACK: Don't enabled vsync when desktop compositing is enabled, as it
    //       leads to severe frame jitter on some cards
    if (_glfwIsCompositionEnabled() && interval)
        return;
#endif

    if (window->wgl.EXT_swap_control)
        window->wgl.SwapIntervalEXT(interval);
}
示例#13
0
void _glfwPlatformSwapInterval(int interval)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    if (_glfwIsCompositionEnabled())
    {
        // Don't enabled vsync when desktop compositing is enabled, as it leads
        // to frame jitter
        return;
    }

    if (window->wgl.EXT_swap_control)
        window->wgl.SwapIntervalEXT(interval);
}
示例#14
0
static GLFWglproc getProcAddress(const char* procname)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    if (window->context.egl.client)
    {
        GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
                                                   procname);
        if (proc)
            return proc;
    }

    return eglGetProcAddress(procname);
}
示例#15
0
文件: context.c 项目: keithpitt/glfw
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
    _GLFWwindow* window = (_GLFWwindow*) handle;

    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return;
    }

    if (_glfwPlatformGetCurrentContext() == window)
        return;

    _glfwPlatformMakeContextCurrent(window);
}
示例#16
0
void _glfwPlatformSwapInterval(int interval) {
    _GLFWwindow *window = _glfwPlatformGetCurrentContext();

    if (_glfw.glx.EXT_swap_control) {
        _glfw.glx.SwapIntervalEXT(_glfw.x11.display,
                                  window->x11.handle,
                                  interval);
    }
    else if (_glfw.glx.MESA_swap_control)
        _glfw.glx.SwapIntervalMESA(interval);
    else if (_glfw.glx.SGI_swap_control) {
        if (interval > 0)
            _glfw.glx.SwapIntervalSGI(interval);
    }
}
示例#17
0
文件: context.c 项目: keithpitt/glfw
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{
    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return NULL;
    }

    if (!_glfwPlatformGetCurrentContext())
    {
        _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
        return NULL;
    }

    return _glfwPlatformGetProcAddress(procname);
}
示例#18
0
文件: context.c 项目: keithpitt/glfw
GLFWAPI void glfwSwapInterval(int interval)
{
    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return;
    }

    if (!_glfwPlatformGetCurrentContext())
    {
        _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
        return;
    }

    _glfwPlatformSwapInterval(interval);
}
示例#19
0
void _glfwPlatformSwapInterval(int interval)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

#if !defined(_GLFW_USE_DWM_SWAP_INTERVAL)
    if (_glfwIsCompositionEnabled() && interval)
    {
        // Don't enabled vsync when desktop compositing is enabled, as it leads
        // to frame jitter
        return;
    }
#endif

    if (window->wgl.EXT_swap_control)
        window->wgl.SwapIntervalEXT(interval);
}
示例#20
0
// Parses the client API version string and extracts the version number
//
static GLboolean parseVersionString(int* api, int* major, int* minor, int* rev)
{
    int i;
    _GLFWwindow* window;
    const char* version;
    const char* prefixes[] =
    {
        "OpenGL ES-CM ",
        "OpenGL ES-CL ",
        "OpenGL ES ",
        NULL
    };

    *api = GLFW_OPENGL_API;

    window = _glfwPlatformGetCurrentContext();

    version = (const char*) window->GetString(GL_VERSION);
    if (!version)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Failed to retrieve context version string");
        return GL_FALSE;
    }

    for (i = 0;  prefixes[i];  i++)
    {
        const size_t length = strlen(prefixes[i]);

        if (strncmp(version, prefixes[i], length) == 0)
        {
            version += length;
            *api = GLFW_OPENGL_ES_API;
            break;
        }
    }

    if (!sscanf(version, "%d.%d.%d", major, minor, rev))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "No version found in context version string");
        return GL_FALSE;
    }

    return GL_TRUE;
}
示例#21
0
GLboolean _glfwIsValidContext(const _GLFWctxconfig* ctxconfig)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    if (window->context.major < ctxconfig->major ||
        (window->context.major == ctxconfig->major &&
         window->context.minor < ctxconfig->minor))
    {
        // The desired OpenGL version is greater than the actual version
        // This only happens if the machine lacks {GLX|WGL}_ARB_create_context
        // /and/ the user has requested an OpenGL version greater than 1.0

        // For API consistency, we emulate the behavior of the
        // {GLX|WGL}_ARB_create_context extension and fail here

        _glfwInputError(GLFW_VERSION_UNAVAILABLE, NULL);
        return GL_FALSE;
    }

    return GL_TRUE;
}
示例#22
0
文件: window.c 项目: kayson/glfw
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
{
    _GLFWwindow* window = (_GLFWwindow*) handle;

    if (!_glfwInitialized)
    {
        _glfwInputError(GLFW_NOT_INITIALIZED, NULL);
        return;
    }

    // Allow closing of NULL (to match the behavior of free)
    if (window == NULL)
        return;

    // Clear all callbacks to avoid exposing a half torn-down window object
    memset(&window->callbacks, 0, sizeof(window->callbacks));

    // The window's context must not be current on another thread when the
    // window is destroyed
    if (window == _glfwPlatformGetCurrentContext())
        _glfwPlatformMakeContextCurrent(NULL);

    // Clear the focused window pointer if this is the focused window
    if (window == _glfw.focusedWindow)
        _glfw.focusedWindow = NULL;

    _glfwPlatformDestroyWindow(window);

    // Unlink window from global linked list
    {
        _GLFWwindow** prev = &_glfw.windowListHead;

        while (*prev != window)
            prev = &((*prev)->next);

        *prev = window->next;
    }

    free(window);
}
示例#23
0
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
                                     const char* title,
                                     GLFWmonitor* monitor,
                                     GLFWwindow* share)
{
    _GLFWfbconfig fbconfig;
    _GLFWctxconfig ctxconfig;
    _GLFWwndconfig wndconfig;
    _GLFWwindow* window;
    _GLFWwindow* previous;

    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);

    if (width <= 0 || height <= 0)
    {
        _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size");
        return NULL;
    }

    // Set up desired framebuffer config
    fbconfig.redBits        = _glfw.hints.redBits;
    fbconfig.greenBits      = _glfw.hints.greenBits;
    fbconfig.blueBits       = _glfw.hints.blueBits;
    fbconfig.alphaBits      = _glfw.hints.alphaBits;
    fbconfig.depthBits      = _glfw.hints.depthBits;
    fbconfig.stencilBits    = _glfw.hints.stencilBits;
    fbconfig.accumRedBits   = _glfw.hints.accumRedBits;
    fbconfig.accumGreenBits = _glfw.hints.accumGreenBits;
    fbconfig.accumBlueBits  = _glfw.hints.accumBlueBits;
    fbconfig.accumAlphaBits = _glfw.hints.accumAlphaBits;
    fbconfig.auxBuffers     = _glfw.hints.auxBuffers;
    fbconfig.stereo         = _glfw.hints.stereo ? GL_TRUE : GL_FALSE;
    fbconfig.samples        = _glfw.hints.samples;
    fbconfig.sRGB           = _glfw.hints.sRGB;
    fbconfig.doublebuffer   = _glfw.hints.doublebuffer ? GL_TRUE : GL_FALSE;
    fbconfig.alphaMask      = _glfw.hints.alphaMask ? GL_TRUE : GL_FALSE;

    // Set up desired window config
    wndconfig.width         = width;
    wndconfig.height        = height;
    wndconfig.title         = title;
    wndconfig.resizable     = _glfw.hints.resizable ? GL_TRUE : GL_FALSE;
    wndconfig.visible       = _glfw.hints.visible ? GL_TRUE : GL_FALSE;
    wndconfig.decorated     = _glfw.hints.decorated ? GL_TRUE : GL_FALSE;
    wndconfig.focused       = _glfw.hints.focused ? GL_TRUE : GL_FALSE;
    wndconfig.autoIconify   = _glfw.hints.autoIconify ? GL_TRUE : GL_FALSE;
    wndconfig.floating      = _glfw.hints.floating ? GL_TRUE : GL_FALSE;
    wndconfig.monitor       = (_GLFWmonitor*) monitor;
    wndconfig.alphaMask     = _glfw.hints.alphaMask ? GL_TRUE : GL_FALSE;

    // Set up desired context config
    ctxconfig.api           = _glfw.hints.api;
    ctxconfig.major         = _glfw.hints.major;
    ctxconfig.minor         = _glfw.hints.minor;
    ctxconfig.forward       = _glfw.hints.forward ? GL_TRUE : GL_FALSE;
    ctxconfig.debug         = _glfw.hints.debug ? GL_TRUE : GL_FALSE;
    ctxconfig.profile       = _glfw.hints.profile;
    ctxconfig.robustness    = _glfw.hints.robustness;
    ctxconfig.release       = _glfw.hints.release;
    ctxconfig.share         = (_GLFWwindow*) share;

    // Check the OpenGL bits of the window config
    if (!_glfwIsValidContextConfig(&ctxconfig))
        return NULL;

    window = calloc(1, sizeof(_GLFWwindow));
    window->next = _glfw.windowListHead;
    _glfw.windowListHead = window;

    if (wndconfig.monitor)
    {
        wndconfig.resizable = GL_TRUE;
        wndconfig.visible   = GL_TRUE;
        wndconfig.focused   = GL_TRUE;

        // Set up desired video mode
        window->videoMode.width       = width;
        window->videoMode.height      = height;
        window->videoMode.redBits     = _glfw.hints.redBits;
        window->videoMode.greenBits   = _glfw.hints.greenBits;
        window->videoMode.blueBits    = _glfw.hints.blueBits;
        window->videoMode.refreshRate = _glfw.hints.refreshRate;
    }

    // Transfer window hints that are persistent settings and not
    // just initial states
    window->monitor     = wndconfig.monitor;
    window->resizable   = wndconfig.resizable;
    window->decorated   = wndconfig.decorated;
    window->autoIconify = wndconfig.autoIconify;
    window->floating    = wndconfig.floating;
    window->transparent = wndconfig.alphaMask;
    window->cursorMode  = GLFW_CURSOR_NORMAL;

    // Save the currently current context so it can be restored later
    previous = _glfwPlatformGetCurrentContext();

    // Open the actual window and create its context
    if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    _glfwPlatformMakeContextCurrent(window);

    // Retrieve the actual (as opposed to requested) context attributes
    if (!_glfwRefreshContextAttribs(&ctxconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    // Verify the context against the requested parameters
    if (!_glfwIsValidContext(&ctxconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    // Clearing the front buffer to black to avoid garbage pixels left over
    // from previous uses of our bit of VRAM
    glClear(GL_COLOR_BUFFER_BIT);
    _glfwPlatformSwapBuffers(window);

    // Restore the previously current context (or NULL)
    _glfwPlatformMakeContextCurrent(previous);

    if (wndconfig.monitor)
    {
        int width, height;
        _glfwPlatformGetWindowSize(window, &width, &height);

        window->cursorPosX = width / 2;
        window->cursorPosY = height / 2;

        _glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY);
    }
    else
    {
        if (wndconfig.visible)
        {
            if (wndconfig.focused)
                _glfwPlatformShowWindow(window);
            else
                _glfwPlatformUnhideWindow(window);
        }
    }

    return (GLFWwindow*) window;
}
示例#24
0
文件: window.c 项目: notetau/glfw
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
                                     const char* title,
                                     GLFWmonitor* monitor,
                                     GLFWwindow* share)
{
    _GLFWfbconfig fbconfig;
    _GLFWctxconfig ctxconfig;
    _GLFWwndconfig wndconfig;
    _GLFWwindow* window;
    _GLFWwindow* previous;

    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);

    if (width <= 0 || height <= 0)
    {
        _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size");
        return NULL;
    }

    fbconfig  = _glfw.hints.framebuffer;
    ctxconfig = _glfw.hints.context;
    wndconfig = _glfw.hints.window;

    wndconfig.width   = width;
    wndconfig.height  = height;
    wndconfig.title   = title;
    wndconfig.monitor = (_GLFWmonitor*) monitor;
    ctxconfig.share   = (_GLFWwindow*) share;

    if (wndconfig.monitor)
    {
        wndconfig.resizable = GLFW_TRUE;
        wndconfig.visible   = GLFW_TRUE;
        wndconfig.focused   = GLFW_TRUE;
    }

    // Check the OpenGL bits of the window config
    if (!_glfwIsValidContextConfig(&ctxconfig))
        return NULL;

    window = calloc(1, sizeof(_GLFWwindow));
    window->next = _glfw.windowListHead;
    _glfw.windowListHead = window;

    window->videoMode.width       = width;
    window->videoMode.height      = height;
    window->videoMode.redBits     = fbconfig.redBits;
    window->videoMode.greenBits   = fbconfig.greenBits;
    window->videoMode.blueBits    = fbconfig.blueBits;
    window->videoMode.refreshRate = _glfw.hints.refreshRate;

    window->monitor     = wndconfig.monitor;
    window->resizable   = wndconfig.resizable;
    window->decorated   = wndconfig.decorated;
    window->autoIconify = wndconfig.autoIconify;
    window->floating    = wndconfig.floating;
    window->cursorMode  = GLFW_CURSOR_NORMAL;

    // Save the currently current context so it can be restored later
    previous = _glfwPlatformGetCurrentContext();

    // Open the actual window and create its context
    if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    _glfwPlatformMakeContextCurrent(window);

    // Retrieve the actual (as opposed to requested) context attributes
    if (!_glfwRefreshContextAttribs(&ctxconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    // Verify the context against the requested parameters
    if (!_glfwIsValidContext(&ctxconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    // Clearing the front buffer to black to avoid garbage pixels left over
    // from previous uses of our bit of VRAM
    window->Clear(GL_COLOR_BUFFER_BIT);
    _glfwPlatformSwapBuffers(window);

    // Restore the previously current context (or NULL)
    _glfwPlatformMakeContextCurrent(previous);

    if (wndconfig.monitor)
    {
        int width, height;
        _glfwPlatformGetWindowSize(window, &width, &height);

        window->cursorPosX = width / 2;
        window->cursorPosY = height / 2;

        _glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY);
    }
    else
    {
        if (wndconfig.visible)
        {
            if (wndconfig.focused)
                _glfwPlatformShowWindow(window);
            else
                _glfwPlatformUnhideWindow(window);
        }
    }

    return (GLFWwindow*) window;
}
示例#25
0
文件: context.c 项目: 028396/Craft
GLboolean _glfwRefreshContextAttribs(void)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    if (!parseGLVersion(&window->clientAPI,
                        &window->glMajor,
                        &window->glMinor,
                        &window->glRevision))
    {
        return GL_FALSE;
    }

#if defined(_GLFW_USE_OPENGL)
    if (window->glMajor > 2)
    {
        // OpenGL 3.0+ uses a different function for extension string retrieval
        // We cache it here instead of in glfwExtensionSupported mostly to alert
        // users as early as possible that their build may be broken

        window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
        if (!window->GetStringi)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Entry point retrieval is broken");
            return GL_FALSE;
        }
    }

    if (window->clientAPI == GLFW_OPENGL_API)
    {
        // Read back context flags (OpenGL 3.0 and above)
        if (window->glMajor >= 3)
        {
            GLint flags;
            glGetIntegerv(GL_CONTEXT_FLAGS, &flags);

            if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
                window->glForward = GL_TRUE;

            if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
                window->glDebug = GL_TRUE;
            else if (glfwExtensionSupported("GL_ARB_debug_output"))
            {
                // HACK: This is a workaround for older drivers (pre KHR_debug)
                // not setting the debug bit in the context flags for debug
                // contexts
                window->glDebug = GL_TRUE;
            }
        }

        // Read back OpenGL context profile (OpenGL 3.2 and above)
        if (window->glMajor > 3 ||
            (window->glMajor == 3 && window->glMinor >= 2))
        {
            GLint mask;
            glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);

            if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
                window->glProfile = GLFW_OPENGL_COMPAT_PROFILE;
            else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
                window->glProfile = GLFW_OPENGL_CORE_PROFILE;
        }

        // Read back robustness strategy
        if (glfwExtensionSupported("GL_ARB_robustness"))
        {
            // NOTE: We avoid using the context flags for detection, as they are
            // only present from 3.0 while the extension applies from 1.1

            GLint strategy;
            glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);

            if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
                window->glRobustness = GLFW_LOSE_CONTEXT_ON_RESET;
            else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
                window->glRobustness = GLFW_NO_RESET_NOTIFICATION;
        }
    }
    else
    {
        // Read back robustness strategy
        if (glfwExtensionSupported("GL_EXT_robustness"))
        {
            // NOTE: The values of these constants match those of the OpenGL ARB
            // one, so we can reuse them here

            GLint strategy;
            glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);

            if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
                window->glRobustness = GLFW_LOSE_CONTEXT_ON_RESET;
            else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
                window->glRobustness = GLFW_NO_RESET_NOTIFICATION;
        }
    }
#endif // _GLFW_USE_OPENGL

    return GL_TRUE;
}
示例#26
0
GLFWAPI int glfwExtensionSupported(const char* extension)
{
    _GLFWwindow* window;

    _GLFW_REQUIRE_INIT_OR_RETURN(GL_FALSE);

    window = _glfwPlatformGetCurrentContext();
    if (!window)
    {
        _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
        return GL_FALSE;
    }

    if (*extension == '\0')
    {
        _glfwInputError(GLFW_INVALID_VALUE, NULL);
        return GL_FALSE;
    }

#if defined(_GLFW_USE_OPENGL)
    if (window->context.major >= 3)
    {
        int i;
        GLint count;

        // Check if extension is in the modern OpenGL extensions string list

        window->GetIntegerv(GL_NUM_EXTENSIONS, &count);

        for (i = 0;  i < count;  i++)
        {
            const char* en = (const char*) window->GetStringi(GL_EXTENSIONS, i);
            if (!en)
            {
                _glfwInputError(GLFW_PLATFORM_ERROR,
                                "Failed to retrieve extension string %i", i);
                return GL_FALSE;
            }

            if (strcmp(en, extension) == 0)
                return GL_TRUE;
        }
    }
    else
#endif // _GLFW_USE_OPENGL
    {
        // Check if extension is in the old style OpenGL extensions string

        const char* extensions = (const char*) window->GetString(GL_EXTENSIONS);
        if (!extensions)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Failed to retrieve extension string");
            return GL_FALSE;
        }

        if (_glfwStringInExtensionString(extension, extensions))
            return GL_TRUE;
    }

    // Check if extension is in the platform-specific string
    return _glfwPlatformExtensionSupported(extension);
}
// Window callback function (handles window events)
//
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
                                   WPARAM wParam, LPARAM lParam)
{
    _GLFWwindow* window = (_GLFWwindow*) GetWindowLongPtrW(hWnd, 0);

    switch (uMsg)
    {
        case WM_NCCREATE:
        {
            CREATESTRUCTW* cs = (CREATESTRUCTW*) lParam;
            SetWindowLongPtrW(hWnd, 0, (LONG_PTR) cs->lpCreateParams);
            break;
        }

        case WM_SETFOCUS:
        {
            if (window->cursorMode != GLFW_CURSOR_NORMAL)
                _glfwPlatformApplyCursorMode(window);

            if (window->monitor && window->autoIconify)
                enterFullscreenMode(window);

            _glfwInputWindowFocus(window, GL_TRUE);
            return 0;
        }

        case WM_KILLFOCUS:
        {
            if (window->cursorMode != GLFW_CURSOR_NORMAL)
                restoreCursor(window);

            if (window->monitor && window->autoIconify)
            {
                _glfwPlatformIconifyWindow(window);
                leaveFullscreenMode(window);
            }

            _glfwInputWindowFocus(window, GL_FALSE);
            return 0;
        }

        case WM_SYSCOMMAND:
        {
            switch (wParam & 0xfff0)
            {
                case SC_SCREENSAVE:
                case SC_MONITORPOWER:
                {
                    if (window->monitor)
                    {
                        // We are running in full screen mode, so disallow
                        // screen saver and screen blanking
                        return 0;
                    }
                    else
                        break;
                }

                // User trying to access application menu using ALT?
                case SC_KEYMENU:
                    return 0;
            }
            break;
        }

        case WM_CLOSE:
        {
            _glfwInputWindowCloseRequest(window);
            return 0;
        }

        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        {
            const int scancode = (lParam >> 16) & 0x1ff;
            const int key = translateKey(wParam, lParam);
            if (key == _GLFW_KEY_INVALID)
                break;

            _glfwInputKey(window, key, scancode, GLFW_PRESS, getKeyMods());
            break;
        }

        case WM_CHAR:
        {
            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);
            return 0;
        }

        case WM_SYSCHAR:
        {
            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE);
            return 0;
        }

        case WM_UNICHAR:
        {
            // This message is not sent by Windows, but is sent by some
            // third-party input method engines

            if (wParam == UNICODE_NOCHAR)
            {
                // Returning TRUE here announces support for this message
                return TRUE;
            }

            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);
            return FALSE;
        }

        case WM_KEYUP:
        case WM_SYSKEYUP:
        {
            const int mods = getKeyMods();
            const int scancode = (lParam >> 16) & 0x1ff;
            const int key = translateKey(wParam, lParam);
            if (key == _GLFW_KEY_INVALID)
                break;

            if (wParam == VK_SHIFT)
            {
                // Release both Shift keys on Shift up event, as only one event
                // is sent even if both keys are released
                _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
                _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
            }
            else if (wParam == VK_SNAPSHOT)
            {
                // Key down is not reported for the print screen key
                _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
            }
            else
                _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);

            break;
        }

        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
        case WM_MBUTTONDOWN:
        case WM_XBUTTONDOWN:
        {
            const int mods = getKeyMods();

            SetCapture(hWnd);

            if (uMsg == WM_LBUTTONDOWN)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
            else if (uMsg == WM_RBUTTONDOWN)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);
            else if (uMsg == WM_MBUTTONDOWN)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
            else
            {
                if (HIWORD(wParam) == XBUTTON1)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods);
                else if (HIWORD(wParam) == XBUTTON2)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods);

                return TRUE;
            }

            return 0;
        }

        case WM_LBUTTONUP:
        case WM_RBUTTONUP:
        case WM_MBUTTONUP:
        case WM_XBUTTONUP:
        {
            const int mods = getKeyMods();

            ReleaseCapture();

            if (uMsg == WM_LBUTTONUP)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods);
            else if (uMsg == WM_RBUTTONUP)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods);
            else if (uMsg == WM_MBUTTONUP)
                _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods);
            else
            {
                if (HIWORD(wParam) == XBUTTON1)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods);
                else if (HIWORD(wParam) == XBUTTON2)
                    _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods);

                return TRUE;
            }

            return 0;
        }

        case WM_MOUSEMOVE:
        {
            const int x = GET_X_LPARAM(lParam);
            const int y = GET_Y_LPARAM(lParam);

            if (window->cursorMode == GLFW_CURSOR_DISABLED)
            {
                if (_glfw.focusedWindow != window)
                    break;

                _glfwInputCursorMotion(window,
                                        x - window->win32.cursorPosX,
                                        y - window->win32.cursorPosY);
            }
            else
                _glfwInputCursorMotion(window, x, y);

            window->win32.cursorPosX = x;
            window->win32.cursorPosY = y;

            if (!window->win32.cursorInside)
            {
                TRACKMOUSEEVENT tme;
                ZeroMemory(&tme, sizeof(tme));
                tme.cbSize = sizeof(tme);
                tme.dwFlags = TME_LEAVE;
                tme.hwndTrack = window->win32.handle;
                TrackMouseEvent(&tme);

                window->win32.cursorInside = GL_TRUE;
                _glfwInputCursorEnter(window, GL_TRUE);
            }

            return 0;
        }

        case WM_MOUSELEAVE:
        {
            window->win32.cursorInside = GL_FALSE;
            _glfwInputCursorEnter(window, GL_FALSE);
            return 0;
        }

        case WM_MOUSEWHEEL:
        {
            _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
            return 0;
        }

        case WM_MOUSEHWHEEL:
        {
            // This message is only sent on Windows Vista and later
            // NOTE: The X-axis is inverted for consistency with OS X and X11.
            _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
            return 0;
        }

        case WM_SIZE:
        {
            if (_glfw.focusedWindow == window)
            {
                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                    updateClipRect(window);
            }

            if (!window->win32.iconified && wParam == SIZE_MINIMIZED)
            {
                window->win32.iconified = GL_TRUE;
                _glfwInputWindowIconify(window, GL_TRUE);
            }
            else if (window->win32.iconified &&
                     (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))
            {
                window->win32.iconified = GL_FALSE;
                _glfwInputWindowIconify(window, GL_FALSE);
            }

            _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));
            _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));
            return 0;
        }

        case WM_MOVE:
        {
            if (_glfw.focusedWindow == window)
            {
                if (window->cursorMode == GLFW_CURSOR_DISABLED)
                    updateClipRect(window);
            }

            // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
            // those macros do not handle negative window positions correctly
            _glfwInputWindowPos(window,
                                GET_X_LPARAM(lParam),
                                GET_Y_LPARAM(lParam));
            return 0;
        }

        case WM_PAINT:
        {
            _glfwInputWindowDamage(window);
            break;
        }

        case WM_ERASEBKGND:
        {
            return TRUE;
        }

        case WM_SETCURSOR:
        {
            if (_glfw.focusedWindow == window && LOWORD(lParam) == HTCLIENT)
            {
                if (window->cursorMode == GLFW_CURSOR_HIDDEN ||
                    window->cursorMode == GLFW_CURSOR_DISABLED)
                {
                    SetCursor(NULL);
                    return TRUE;
                }
                else if (window->cursor)
                {
                    SetCursor(window->cursor->win32.handle);
                    return TRUE;
                }
            }

            break;
        }

        case WM_DEVICECHANGE:
        {
            if (DBT_DEVNODES_CHANGED == wParam)
            {
                _glfwInputMonitorChange();
                return TRUE;
            }
            break;
        }

        case WM_DWMCOMPOSITIONCHANGED:
        {
            if (_glfwIsCompositionEnabled())
            {
                _GLFWwindow* previous = _glfwPlatformGetCurrentContext();
                _glfwPlatformMakeContextCurrent(window);
                _glfwPlatformSwapInterval(0);
                _glfwPlatformMakeContextCurrent(previous);
            }

            // TODO: Restore vsync if compositing was disabled
            break;
        }

        case WM_DROPFILES:
        {
            HDROP hDrop = (HDROP) wParam;
            POINT pt;
            int i;

            const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0);
            char** paths = calloc(count, sizeof(char*));

            // Move the mouse to the position of the drop
            DragQueryPoint(hDrop, &pt);
            _glfwInputCursorMotion(window, pt.x, pt.y);

            for (i = 0;  i < count;  i++)
            {
                const UINT length = DragQueryFileW(hDrop, i, NULL, 0);
                WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));

                DragQueryFileW(hDrop, i, buffer, length + 1);
                paths[i] = _glfwCreateUTF8FromWideString(buffer);

                free(buffer);
            }

            _glfwInputDrop(window, count, (const char**) paths);

            for (i = 0;  i < count;  i++)
                free(paths[i]);
            free(paths);

            DragFinish(hDrop);
            return 0;
        }
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
示例#28
0
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    return (GLFWwindow*) _glfwPlatformGetCurrentContext();
}
示例#29
0
文件: window.c 项目: coolexp/glfw
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
                                     const char* title,
                                     GLFWmonitor* monitor,
                                     GLFWwindow* share)
{
    _GLFWfbconfig fbconfig;
    _GLFWctxconfig ctxconfig;
    _GLFWwndconfig wndconfig;
    _GLFWwindow* window;
    _GLFWwindow* previous;

    assert(title != NULL);

    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);

    if (width <= 0 || height <= 0)
    {
        _glfwInputError(GLFW_INVALID_VALUE,
                        "Invalid window size %ix%i",
                        width, height);

        return NULL;
    }

    fbconfig  = _glfw.hints.framebuffer;
    ctxconfig = _glfw.hints.context;
    wndconfig = _glfw.hints.window;

    wndconfig.width   = width;
    wndconfig.height  = height;
    wndconfig.title   = title;
    ctxconfig.share   = (_GLFWwindow*) share;

    if (ctxconfig.share)
    {
        if (ctxconfig.share->context.api == GLFW_NO_API)
        {
            _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
            return NULL;
        }
    }

    if (!_glfwIsValidContextConfig(&ctxconfig))
        return NULL;

    window = calloc(1, sizeof(_GLFWwindow));
    window->next = _glfw.windowListHead;
    _glfw.windowListHead = window;

    window->videoMode.width       = width;
    window->videoMode.height      = height;
    window->videoMode.redBits     = fbconfig.redBits;
    window->videoMode.greenBits   = fbconfig.greenBits;
    window->videoMode.blueBits    = fbconfig.blueBits;
    window->videoMode.refreshRate = _glfw.hints.refreshRate;

    window->monitor     = (_GLFWmonitor*) monitor;
    window->resizable   = wndconfig.resizable;
    window->decorated   = wndconfig.decorated;
    window->autoIconify = wndconfig.autoIconify;
    window->floating    = wndconfig.floating;
    window->cursorMode  = GLFW_CURSOR_NORMAL;

    window->minwidth    = GLFW_DONT_CARE;
    window->minheight   = GLFW_DONT_CARE;
    window->maxwidth    = GLFW_DONT_CARE;
    window->maxheight   = GLFW_DONT_CARE;
    window->numer       = GLFW_DONT_CARE;
    window->denom       = GLFW_DONT_CARE;

    // Save the currently current context so it can be restored later
    previous = _glfwPlatformGetCurrentContext();

    // Open the actual window and create its context
    if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        _glfwPlatformMakeContextCurrent(previous);
        return NULL;
    }

    if (ctxconfig.api != GLFW_NO_API)
    {
        _glfwPlatformMakeContextCurrent(window);

        // Retrieve the actual (as opposed to requested) context attributes
        if (!_glfwRefreshContextAttribs(&ctxconfig))
        {
            glfwDestroyWindow((GLFWwindow*) window);
            _glfwPlatformMakeContextCurrent(previous);
            return NULL;
        }

        // Restore the previously current context (or NULL)
        _glfwPlatformMakeContextCurrent(previous);
    }

    if (window->monitor)
    {
        int width, height;
        _glfwPlatformGetWindowSize(window, &width, &height);

        window->cursorPosX = width / 2;
        window->cursorPosY = height / 2;

        _glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY);
    }
    else
    {
        if (wndconfig.visible)
        {
            _glfwPlatformShowWindow(window);
            if (wndconfig.focused)
                _glfwPlatformFocusWindow(window);
        }
    }

    return (GLFWwindow*) window;
}
示例#30
0
GLboolean _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
{
    _GLFWwindow* window = _glfwPlatformGetCurrentContext();

    window->GetIntegerv = (PFNGLGETINTEGERVPROC) glfwGetProcAddress("glGetIntegerv");
    window->GetString = (PFNGLGETSTRINGPROC) glfwGetProcAddress("glGetString");
    window->Clear = (PFNGLCLEARPROC) glfwGetProcAddress("glClear");

    if (!parseVersionString(&window->context.api,
                            &window->context.major,
                            &window->context.minor,
                            &window->context.revision))
    {
        return GL_FALSE;
    }

#if defined(_GLFW_USE_OPENGL)
    if (window->context.major > 2)
    {
        // OpenGL 3.0+ uses a different function for extension string retrieval
        // We cache it here instead of in glfwExtensionSupported mostly to alert
        // users as early as possible that their build may be broken

        window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
        if (!window->GetStringi)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Entry point retrieval is broken");
            return GL_FALSE;
        }
    }

    if (window->context.api == GLFW_OPENGL_API)
    {
        // Read back context flags (OpenGL 3.0 and above)
        if (window->context.major >= 3)
        {
            GLint flags;
            window->GetIntegerv(GL_CONTEXT_FLAGS, &flags);

            if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
                window->context.forward = GL_TRUE;

            if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
                window->context.debug = GL_TRUE;
            else if (glfwExtensionSupported("GL_ARB_debug_output") &&
                     ctxconfig->debug)
            {
                // HACK: This is a workaround for older drivers (pre KHR_debug)
                //       not setting the debug bit in the context flags for
                //       debug contexts
                window->context.debug = GL_TRUE;
            }
        }

        // Read back OpenGL context profile (OpenGL 3.2 and above)
        if (window->context.major > 3 ||
            (window->context.major == 3 && window->context.minor >= 2))
        {
            GLint mask;
            window->GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);

            if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
                window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
            else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
                window->context.profile = GLFW_OPENGL_CORE_PROFILE;
            else if (glfwExtensionSupported("GL_ARB_compatibility"))
            {
                // HACK: This is a workaround for the compatibility profile bit
                //       not being set in the context flags if an OpenGL 3.2+
                //       context was created without having requested a specific
                //       version
                window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
            }
        }

        // Read back robustness strategy
        if (glfwExtensionSupported("GL_ARB_robustness"))
        {
            // NOTE: We avoid using the context flags for detection, as they are
            //       only present from 3.0 while the extension applies from 1.1

            GLint strategy;
            window->GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);

            if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
                window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
            else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
                window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
        }
    }
    else
    {
        // Read back robustness strategy
        if (glfwExtensionSupported("GL_EXT_robustness"))
        {
            // NOTE: The values of these constants match those of the OpenGL ARB
            //       one, so we can reuse them here

            GLint strategy;
            window->GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);

            if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
                window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
            else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
                window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
        }
    }

    if (glfwExtensionSupported("GL_KHR_context_flush_control"))
    {
        GLint behavior;
        window->GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);

        if (behavior == GL_NONE)
            window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;
        else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)
            window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
    }
#endif // _GLFW_USE_OPENGL

    return GL_TRUE;
}