Replaced GLFW_MOUSE_CURSOR enable with glfwSetCursorMode.

This commit is contained in:
Camilla Berglund 2011-09-06 13:55:29 +02:00
parent 4fb55781f1
commit b1656d7323
14 changed files with 221 additions and 184 deletions

View File

@ -465,7 +465,7 @@ int main(void)
glfwEnable(window, GLFW_STICKY_KEYS);
// Enable mouse cursor (only needed for fullscreen mode)
glfwEnable(window, GLFW_MOUSE_CURSOR);
glfwSetCursorMode(window, GLFW_CURSOR_NORMAL);
// Set callback functions
glfwSetWindowSizeCallback(windowSizeFun);

View File

@ -309,13 +309,13 @@ void mouse_button_callback(GLFWwindow window, int button, int action)
if (action == GLFW_PRESS)
{
glfwDisable(window, GLFW_MOUSE_CURSOR);
glfwSetCursorMode(window, GLFW_CURSOR_CAPTURED);
locked = GL_TRUE;
}
else
{
locked = GL_FALSE;
glfwEnable(window, GLFW_MOUSE_CURSOR);
glfwSetCursorMode(window, GLFW_CURSOR_NORMAL);
}
}

8
include/GL/glfw3.h Executable file → Normal file
View File

@ -430,12 +430,16 @@ extern "C" {
#define GLFW_OPENGL_ES2_PROFILE 0x00000004
/* glfwEnable/glfwDisable tokens */
#define GLFW_MOUSE_CURSOR 0x00030001
#define GLFW_STICKY_KEYS 0x00030002
#define GLFW_STICKY_MOUSE_BUTTONS 0x00030003
#define GLFW_SYSTEM_KEYS 0x00030004
#define GLFW_KEY_REPEAT 0x00030005
/* glfwSetCursorMode tokens */
#define GLFW_CURSOR_NORMAL 0x00040001
#define GLFW_CURSOR_HIDDEN 0x00040002
#define GLFW_CURSOR_CAPTURED 0x00040003
/* glfwGetJoystickParam tokens */
#define GLFW_PRESENT 0x00050001
#define GLFW_AXES 0x00050002
@ -451,6 +455,7 @@ extern "C" {
#define GLFW_OPENGL_UNAVAILABLE 0x00070006
#define GLFW_VERSION_UNAVAILABLE 0x00070007
#define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
@ -564,6 +569,7 @@ GLFWAPI int glfwGetKey(GLFWwindow window, int key);
GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button);
GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos);
GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos);
GLFWAPI void glfwSetCursorMode(GLFWwindow window, int mode);
GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* xoffset, int* yoffset);
GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun);
GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun);

View File

@ -274,6 +274,7 @@ version of GLFW.</p>
<li>Added <code>glfwGetCurrentContext</code> function for retrieving the window whose OpenGL context is current</li>
<li>Added <code>glfwInitWithModels</code> function and <code>GLFWallocator</code> and <code>GLFWthreadmodel</code> types for pluggable memory allocation and threading models</li>
<li>Added <code>glfwCopyContext</code> function for copying OpenGL state categories between contexts</li>
<li>Added <code>glfwSetCursorMode</code> function for controlling per-window cursor mode, replacing <code>GLFW_MOUSE_CURSOR</code></li>
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
<li>Added <code>GLFW_OPENGL_ROBUSTNESS</code> window hint and associated strategy tokens for <code>GL_ARB_robustness</code> support</li>
<li>Added <code>GLFW_OPENGL_REVISION</code> window parameter to make up for removal of <code>glfwGetGLVersion</code></li>

View File

@ -348,7 +348,7 @@ static int convertMacKeyCode(unsigned int macKeyCode)
- (void)mouseMoved:(NSEvent *)event
{
if (window == _glfwLibrary.cursorLockWindow)
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
window->mousePosX += [event deltaX];
window->mousePosY += [event deltaY];

View File

@ -31,58 +31,6 @@
#include "internal.h"
//========================================================================
// Enable and disable locked cursor mode
//========================================================================
static void enableMouseCursor(_GLFWwindow* window)
{
int centerPosX, centerPosY;
if (_glfwLibrary.cursorLockWindow != window)
return;
_glfwPlatformShowMouseCursor(window);
centerPosX = window->width / 2;
centerPosY = window->height / 2;
if (centerPosX != window->mousePosX || centerPosY != window->mousePosY)
{
_glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY);
window->mousePosX = centerPosX;
window->mousePosY = centerPosY;
if (_glfwLibrary.mousePosCallback)
{
_glfwLibrary.mousePosCallback(window,
window->mousePosX,
window->mousePosY);
}
}
// From now on the mouse is unlocked
_glfwLibrary.cursorLockWindow = NULL;
}
static void disableMouseCursor(_GLFWwindow* window)
{
if (_glfwLibrary.cursorLockWindow)
return;
_glfwPlatformHideMouseCursor(window);
// Move cursor to the middle of the window
_glfwPlatformSetMouseCursorPos(window,
window->width / 2,
window->height / 2);
// From now on the mouse is locked
_glfwLibrary.cursorLockWindow = window;
}
//========================================================================
// Enable and disable sticky keys mode
//========================================================================
@ -191,9 +139,6 @@ GLFWAPI void glfwEnable(GLFWwindow window, int token)
switch (token)
{
case GLFW_MOUSE_CURSOR:
enableMouseCursor(window);
break;
case GLFW_STICKY_KEYS:
enableStickyKeys(window);
break;
@ -226,9 +171,6 @@ GLFWAPI void glfwDisable(GLFWwindow window, int token)
switch (token)
{
case GLFW_MOUSE_CURSOR:
disableMouseCursor(window);
break;
case GLFW_STICKY_KEYS:
disableStickyKeys(window);
break;

View File

@ -140,6 +140,12 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
return;
}
if (_glfwLibrary.activeWindow != window)
{
_glfwSetError(GLFW_WINDOW_NOT_ACTIVE, NULL);
return;
}
// Don't do anything if the mouse position did not change
if (xpos == window->mousePosX && ypos == window->mousePosY)
return;
@ -148,8 +154,8 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
window->mousePosX = xpos;
window->mousePosY = ypos;
// If we have a locked mouse, do not change cursor position
if (_glfwLibrary.cursorLockWindow == window)
// Do not move physical cursor in locked cursor mode
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
return;
// Update physical cursor position
@ -179,6 +185,62 @@ GLFWAPI void glfwGetScrollOffset(GLFWwindow handle, int* xoffset, int* yoffset)
}
//========================================================================
// Sets the cursor mode for the specified window
//========================================================================
GLFWAPI void glfwSetCursorMode(GLFWwindow handle, int mode)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
if (mode != GLFW_CURSOR_NORMAL &&
mode != GLFW_CURSOR_HIDDEN &&
mode != GLFW_CURSOR_CAPTURED)
{
_glfwSetError(GLFW_INVALID_ENUM, NULL);
return;
}
if (window->cursorMode == mode)
return;
int centerPosX = window->width / 2;
int centerPosY = window->height / 2;
if (mode == GLFW_CURSOR_CAPTURED)
{
_glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY);
}
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
if (centerPosX != window->mousePosX || centerPosY != window->mousePosY)
{
_glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY);
window->mousePosX = centerPosX;
window->mousePosY = centerPosY;
if (_glfwLibrary.mousePosCallback)
{
_glfwLibrary.mousePosCallback(window,
window->mousePosX,
window->mousePosY);
}
}
}
_glfwPlatformSetCursorMode(window, mode);
window->cursorMode = mode;
}
//========================================================================
// Set callback function for keyboard input
//========================================================================

View File

@ -181,6 +181,7 @@ struct _GLFWwindow
GLboolean keyRepeat;
GLboolean sysKeysDisabled; // system keys disabled flag
int mousePosX, mousePosY;
int cursorMode;
int scrollX, scrollY;
char mouseButton[GLFW_MOUSE_BUTTON_LAST + 1];
char key[GLFW_KEY_LAST + 1];
@ -224,7 +225,6 @@ struct _GLFWlibrary
_GLFWwindow* windowListHead;
_GLFWwindow* currentWindow;
_GLFWwindow* activeWindow;
_GLFWwindow* cursorLockWindow;
GLFWerrorfun errorCallback;
GLFWwindowsizefun windowSizeCallback;
@ -302,9 +302,8 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
void _glfwPlatformHideMouseCursor(_GLFWwindow* window);
void _glfwPlatformShowMouseCursor(_GLFWwindow* window);
void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Event management
void _glfwPlatformPollEvents(void);

View File

@ -766,8 +766,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{
// The window was deactivated (or iconified, see above)
if (window == _glfwLibrary.cursorLockWindow)
_glfwPlatformShowMouseCursor(window);
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
showMouseCursor(window);
if (window->mode == GLFW_FULLSCREEN)
{
@ -789,8 +789,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{
// The window was activated
if (window == _glfwLibrary.cursorLockWindow)
_glfwPlatformHideMouseCursor(window);
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureMouseCursor(window);
if (window->mode == GLFW_FULLSCREEN)
{
@ -962,8 +962,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (newMouseX != window->Win32.oldMouseX ||
newMouseY != window->Win32.oldMouseY)
{
if (window == _glfwLibrary.cursorLockWindow)
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
if (_glfwLibrary.activeWindow != window)
return 0;
window->mousePosX += newMouseX -
window->Win32.oldMouseX;
window->mousePosY += newMouseY -
@ -977,7 +980,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
window->Win32.oldMouseX = newMouseX;
window->Win32.oldMouseY = newMouseY;
window->Win32.mouseMoved = GL_TRUE;
window->Win32.cursorCentered = GL_FALSE;
if (_glfwLibrary.mousePosCallback)
{
@ -1009,8 +1012,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
window->width = LOWORD(lParam);
window->height = HIWORD(lParam);
// If the mouse is locked, update the clipping rect
if (window == _glfwLibrary.cursorLockWindow)
// If window is in cursor capture mode, update clipping rect
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
RECT ClipWindowRect;
if (GetWindowRect(window->Win32.handle, &ClipWindowRect))
@ -1032,8 +1035,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
window->positionX = LOWORD(lParam);
window->positionY = HIWORD(lParam);
// If the mouse is locked, update the clipping rect
if (window == _glfwLibrary.cursorLockWindow)
// If window is in cursor capture mode, update clipping rect
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
RECT ClipWindowRect;
if (GetWindowRect(window->Win32.handle, &ClipWindowRect))
@ -1755,7 +1758,7 @@ void _glfwPlatformPollEvents(void)
MSG msg;
_GLFWwindow* window;
window = _glfwLibrary.cursorLockWindow;
window = _glfwLibrary.activeWindow;
if (window)
{
window->Win32.mouseMoved = GL_FALSE;
@ -1815,13 +1818,18 @@ void _glfwPlatformPollEvents(void)
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE);
}
// Did we have mouse movement in locked cursor mode?
window = _glfwLibrary.cursorLockWindow;
if (window && window->Win32.mouseMoved)
// Did the cursor move in an active window that has captured the cursor
window = _glfwLibrary.activeWindow;
if (window)
{
if (window->cursorMode == GLFW_CURSOR_CAPTURED &&
!window->Win32.cursorCentered)
{
_glfwPlatformSetMouseCursorPos(window,
window->width / 2,
window->height / 2);
window->Win32.cursorCentered = GL_TRUE;
}
}
}

View File

@ -329,6 +329,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
window->width = width;
window->height = height;
window->mode = mode;
window->cursorMode = GLFW_CURSOR_NORMAL;
// Open the actual window and create its context
if (!_glfwPlatformOpenWindow(window, &wndconfig, &fbconfig))
@ -348,9 +349,9 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
}
// The GLFW specification states that fullscreen windows have the cursor
// locked by default
// captured by default
if (mode == GLFW_FULLSCREEN)
glfwDisable(window, GLFW_MOUSE_CURSOR);
glfwSetCursorMode(window, GLFW_CURSOR_CAPTURED);
// Clearing the front buffer to black to avoid garbage pixels left over
// from previous uses of our bit of VRAM
@ -490,10 +491,6 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle)
if (window == NULL)
return;
// Show mouse pointer again (if hidden)
if (window == _glfwLibrary.cursorLockWindow)
glfwEnable(window, GLFW_MOUSE_CURSOR);
// Clear the current context if this window's context is current
if (window == _glfwLibrary.currentWindow)
glfwMakeContextCurrent(NULL);

View File

@ -131,9 +131,9 @@ typedef struct _GLFWwindowX11
GLboolean hasEWMH; // True if window manager supports EWMH
GLboolean overrideRedirect; // True if window is OverrideRedirect
GLboolean keyboardGrabbed; // True if keyboard is currently grabbed
GLboolean pointerGrabbed; // True if pointer is currently grabbed
GLboolean pointerHidden; // True if pointer is currently hidden
GLboolean mouseMoved;
GLboolean cursorGrabbed; // True if cursor is currently grabbed
GLboolean cursorHidden; // True if cursor is currently hidden
GLboolean cursorCentered; // True if cursor was moved since last poll
int cursorPosX, cursorPosY;
} _GLFWwindowX11;

View File

@ -828,6 +828,69 @@ static GLboolean createWindow(_GLFWwindow* window,
}
//========================================================================
// Hide mouse cursor
//========================================================================
static void hideMouseCursor(_GLFWwindow* window)
{
if (!window->X11.cursorHidden)
{
XDefineCursor(_glfwLibrary.X11.display,
window->X11.handle,
_glfwLibrary.X11.cursor);
window->X11.cursorHidden = GL_TRUE;
}
}
//========================================================================
// Capture mouse cursor
//========================================================================
static void captureMouseCursor(_GLFWwindow* window)
{
hideMouseCursor(window);
if (!window->X11.cursorGrabbed)
{
if (XGrabPointer(_glfwLibrary.X11.display, window->X11.handle, True,
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask, GrabModeAsync, GrabModeAsync,
window->X11.handle, None, CurrentTime) ==
GrabSuccess)
{
window->X11.cursorGrabbed = GL_TRUE;
window->X11.cursorCentered = GL_FALSE;
}
}
}
//========================================================================
// Show mouse cursor
//========================================================================
static void showMouseCursor(_GLFWwindow* window)
{
// Un-grab cursor (only in windowed mode: in fullscreen mode we still
// want the mouse grabbed in order to confine the cursor to the window
// area)
if (window->X11.cursorGrabbed)
{
XUngrabPointer(_glfwLibrary.X11.display, CurrentTime);
window->X11.cursorGrabbed = GL_FALSE;
}
// Show cursor
if (window->X11.cursorHidden)
{
XUndefineCursor(_glfwLibrary.X11.display, window->X11.handle);
window->X11.cursorHidden = GL_FALSE;
}
}
//========================================================================
// Enter fullscreen mode
//========================================================================
@ -916,9 +979,6 @@ static void enterFullscreenMode(_GLFWwindow* window)
window->width, window->height);
}
if (_glfwLibrary.cursorLockWindow == window)
_glfwPlatformHideMouseCursor(window);
// HACK: Try to get window inside viewport (for virtual displays) by moving
// the mouse cursor to the upper left corner (and then to the center)
// This hack should be harmless on saner systems as well
@ -973,9 +1033,6 @@ static void leaveFullscreenMode(_GLFWwindow* window)
SubstructureNotifyMask | SubstructureRedirectMask,
&event);
}
if (_glfwLibrary.cursorLockWindow == window)
_glfwPlatformShowMouseCursor(window);
}
@ -1149,16 +1206,16 @@ static void processSingleEvent(void)
{
// The mouse cursor was moved and we didn't do it
if (_glfwLibrary.cursorLockWindow == window)
{
if (window->X11.pointerHidden)
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
if (_glfwLibrary.activeWindow != window)
break;
window->mousePosX += event.xmotion.x -
window->X11.cursorPosX;
window->mousePosY += event.xmotion.y -
window->X11.cursorPosY;
}
}
else
{
window->mousePosX = event.xmotion.x;
@ -1167,7 +1224,7 @@ static void processSingleEvent(void)
window->X11.cursorPosX = event.xmotion.x;
window->X11.cursorPosY = event.xmotion.y;
window->X11.mouseMoved = GL_TRUE;
window->X11.cursorCentered = GL_FALSE;
if (_glfwLibrary.mousePosCallback)
{
@ -1176,6 +1233,7 @@ static void processSingleEvent(void)
window->mousePosY);
}
}
break;
}
@ -1296,8 +1354,8 @@ static void processSingleEvent(void)
_glfwInputWindowFocus(window, GL_TRUE);
if (_glfwLibrary.cursorLockWindow == window)
_glfwPlatformHideMouseCursor(window);
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureMouseCursor(window);
break;
}
@ -1314,8 +1372,8 @@ static void processSingleEvent(void)
_glfwInputWindowFocus(window, GL_FALSE);
if (_glfwLibrary.cursorLockWindow == window)
_glfwPlatformShowMouseCursor(window);
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
showMouseCursor(window);
break;
}
@ -1704,24 +1762,21 @@ void _glfwPlatformPollEvents(void)
{
_GLFWwindow* window;
// Flag that the cursor has not moved
window = _glfwLibrary.cursorLockWindow;
if (window)
window->X11.mouseMoved = GL_FALSE;
// Process all pending events
while (XPending(_glfwLibrary.X11.display))
processSingleEvent();
// Did we get mouse movement in fully enabled hidden cursor mode?
window = _glfwLibrary.cursorLockWindow;
// Did the cursor move in an active window that has captured the cursor
window = _glfwLibrary.activeWindow;
if (window)
{
if (window->X11.mouseMoved && window->X11.pointerHidden)
if (window->cursorMode == GLFW_CURSOR_CAPTURED &&
!window->X11.cursorCentered)
{
_glfwPlatformSetMouseCursorPos(window,
window->width / 2,
window->height / 2);
window->X11.cursorCentered = GL_TRUE;
}
}
}
@ -1743,60 +1798,6 @@ void _glfwPlatformWaitEvents(void)
}
//========================================================================
// Hide mouse cursor (lock it)
//========================================================================
void _glfwPlatformHideMouseCursor(_GLFWwindow* window)
{
// Hide cursor
if (!window->X11.pointerHidden)
{
XDefineCursor(_glfwLibrary.X11.display,
window->X11.handle,
_glfwLibrary.X11.cursor);
window->X11.pointerHidden = GL_TRUE;
}
// Grab cursor to user window
if (!window->X11.pointerGrabbed)
{
if (XGrabPointer(_glfwLibrary.X11.display, window->X11.handle, True,
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask, GrabModeAsync, GrabModeAsync,
window->X11.handle, None, CurrentTime) ==
GrabSuccess)
{
window->X11.pointerGrabbed = GL_TRUE;
}
}
}
//========================================================================
// Show mouse cursor (unlock it)
//========================================================================
void _glfwPlatformShowMouseCursor(_GLFWwindow* window)
{
// Un-grab cursor (only in windowed mode: in fullscreen mode we still
// want the mouse grabbed in order to confine the cursor to the window
// area)
if (window->X11.pointerGrabbed)
{
XUngrabPointer(_glfwLibrary.X11.display, CurrentTime);
window->X11.pointerGrabbed = GL_FALSE;
}
// Show cursor
if (window->X11.pointerHidden)
{
XUndefineCursor(_glfwLibrary.X11.display, window->X11.handle);
window->X11.pointerHidden = GL_FALSE;
}
}
//========================================================================
// Set physical mouse cursor position
//========================================================================
@ -1810,3 +1811,24 @@ void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y)
XWarpPointer(_glfwLibrary.X11.display, None, window->X11.handle, 0,0,0,0, x, y);
}
//========================================================================
// Set physical mouse cursor mode
//========================================================================
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
switch (mode)
{
case GLFW_CURSOR_NORMAL:
showMouseCursor(window);
break;
case GLFW_CURSOR_HIDDEN:
hideMouseCursor(window);
break;
case GLFW_CURSOR_CAPTURED:
captureMouseCursor(window);
break;
}
}

View File

@ -91,7 +91,7 @@ int main(void)
}
glfwSwapInterval(1);
glfwEnable(window, GLFW_MOUSE_CURSOR);
glfwSetCursorMode(window, GLFW_CURSOR_NORMAL);
glfwSetWindowFocusCallback(window_focus_callback);
glfwSetKeyCallback(window_key_callback);

View File

@ -35,19 +35,19 @@
#include <stdio.h>
#include <stdlib.h>
static GLboolean cursor_enabled = GL_TRUE;
static GLboolean cursor_captured = GL_FALSE;
static GLFWwindow window_handle = NULL;
static GLboolean open_window(void);
static void toggle_mouse_cursor(GLFWwindow window)
{
if (cursor_enabled)
glfwDisable(window, GLFW_MOUSE_CURSOR);
if (cursor_captured)
glfwSetCursorMode(window, GLFW_CURSOR_NORMAL);
else
glfwEnable(window, GLFW_MOUSE_CURSOR);
glfwSetCursorMode(window, GLFW_CURSOR_CAPTURED);
cursor_enabled = !cursor_enabled;
cursor_captured = !cursor_captured;
}
static void mouse_position_callback(GLFWwindow window, int x, int y)