Merge branch 'master' into multi-monitor

Conflicts:
	.gitignore
	src/CMakeLists.txt
	src/x11_window.c
This commit is contained in:
Camilla Berglund
2012-09-12 06:04:17 +02:00
31 changed files with 1706 additions and 279 deletions
+17 -5
View File
@@ -10,7 +10,11 @@ if (_GLFW_COCOA_NSGL)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.m
cocoa_native.m cocoa_opengl.m cocoa_time.c cocoa_window.m)
cocoa_opengl.m cocoa_time.c cocoa_window.m)
if (GLFW_NATIVE_API)
list(APPEND glfw_SOURCES cocoa_native.m)
endif()
# For some reason, CMake doesn't know about .m
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
@@ -18,14 +22,22 @@ elseif (_GLFW_WIN32_WGL)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c
win32_gamma.c win32_init.c win32_input.c win32_joystick.c
win32_monitor.c win32_native.c win32_opengl.c win32_time.c
win32_window.c win32_dllmain.c)
win32_monitor.c win32_opengl.c win32_time.c win32_window.c
win32_dllmain.c)
if (GLFW_NATIVE_API)
list(APPEND glfw_SOURCES win32_native.c)
endif()
elseif (_GLFW_X11_GLX)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c
x11_gamma.c x11_init.c x11_input.c x11_joystick.c
x11_keysym2unicode.c x11_monitor.c x11_native.c
x11_opengl.c x11_time.c x11_window.c)
x11_keysym2unicode.c x11_monitor.c x11_opengl.c x11_time.c
x11_window.c)
if (GLFW_NATIVE_API)
list(APPEND glfw_SOURCES x11_native.c)
endif()
endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
+5
View File
@@ -101,6 +101,9 @@ int _glfwPlatformInit(void)
_glfwInitJoysticks();
if (!_glfwInitOpenGL())
return GL_FALSE;
_glfwLibrary.NS.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfwLibrary.NS.eventSource)
return GL_FALSE;
@@ -139,6 +142,8 @@ int _glfwPlatformTerminate(void)
_glfwTerminateJoysticks();
_glfwTerminateOpenGL();
return GL_TRUE;
}
+4 -4
View File
@@ -550,15 +550,15 @@ int _glfwPlatformGetJoystickAxes(int joy, float* axes, int numaxes)
for (i = 0; i < numaxes; i++)
{
_glfwJoystickElement* axes =
_glfwJoystickElement* elements =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.axes, i);
long readScale = axes->maxReport - axes->minReport;
long readScale = elements->maxReport - elements->minReport;
if (readScale == 0)
axes[i] = axes->value;
axes[i] = elements->value;
else
axes[i] = (2.0f * (axes->value - axes->minReport) / readScale) - 1.0f;
axes[i] = (2.0f * (elements->value - elements->minReport) / readScale) - 1.0f;
if (i & 1)
axes[i] = -axes[i];
+48 -1
View File
@@ -29,11 +29,46 @@
#include "internal.h"
#include <pthread.h>
//========================================================================
// The per-thread current context/window pointer
//========================================================================
static pthread_key_t _glfwCurrentTLS;
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Initialize OpenGL support
//========================================================================
int _glfwInitOpenGL(void)
{
if (pthread_key_create(&_glfwCurrentTLS, NULL) != 0)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"Cocoa/NSGL: Failed to create context TLS");
return GL_FALSE;
}
return GL_TRUE;
}
//========================================================================
// Terminate OpenGL support
//========================================================================
void _glfwTerminateOpenGL(void)
{
pthread_key_delete(_glfwCurrentTLS);
}
//========================================================================
// Make the OpenGL context associated with the specified window current
//========================================================================
@@ -44,6 +79,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
[window->NSGL.context makeCurrentContext];
else
[NSOpenGLContext clearCurrentContext];
pthread_setspecific(_glfwCurrentTLS, window);
}
//========================================================================
// Return the window object whose context is current
//========================================================================
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return (_GLFWwindow*) pthread_getspecific(_glfwCurrentTLS);
}
@@ -64,7 +111,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window)
void _glfwPlatformSwapInterval(int interval)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
GLint sync = interval;
[window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];
+4
View File
@@ -124,4 +124,8 @@ void _glfwTerminateJoysticks(void);
GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate);
void _glfwRestoreVideoMode(void);
// OpenGL support
int _glfwInitOpenGL(void);
void _glfwTerminateOpenGL(void);
#endif // _platform_h_
+42 -3
View File
@@ -131,6 +131,25 @@
return NSTerminateCancel;
}
- (void)applicationDidHide:(NSNotification *)notification
{
_GLFWwindow* window;
for (window = _glfwLibrary.windowListHead; window; window = window->next)
_glfwInputWindowVisibility(window, GL_FALSE);
}
- (void)applicationDidUnhide:(NSNotification *)notification
{
_GLFWwindow* window;
for (window = _glfwLibrary.windowListHead; window; window = window->next)
{
if ([window->NS.object isVisible])
_glfwInputWindowVisibility(window, GL_TRUE);
}
}
@end
@@ -686,7 +705,7 @@ static GLboolean createWindow(_GLFWwindow* window,
[window->NS.object setAcceptsMouseMovedEvents:YES];
[window->NS.object center];
if ([window->NS.object respondsToSelector:@selector(setRestorable)])
if ([window->NS.object respondsToSelector:@selector(setRestorable:)])
[window->NS.object setRestorable:NO];
return GL_TRUE;
@@ -898,7 +917,6 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!createContext(window, wndconfig, fbconfig))
return GL_FALSE;
[window->NS.object makeKeyAndOrderFront:nil];
[window->NSGL.context setView:[window->NS.object contentView]];
if (wndconfig->mode == GLFW_FULLSCREEN)
@@ -1022,6 +1040,27 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
}
//========================================================================
// Show window
//========================================================================
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
[window->NS.object makeKeyAndOrderFront:nil];
_glfwInputWindowVisibility(window, GL_TRUE);
}
//========================================================================
// Hide window
//========================================================================
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
[window->NS.object orderOut:nil];
_glfwInputWindowVisibility(window, GL_FALSE);
}
//========================================================================
// Write back window parameters into GLFW window structure
//========================================================================
@@ -1093,7 +1132,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y)
CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin;
double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
CGPoint targetPoint = CGPointMake(globalPoint.x - mainScreenOrigin.x,
mainScreenHeight - globalPoint.y -
mainScreenHeight - globalPoint.y -
mainScreenOrigin.y);
CGDisplayMoveCursorToPoint(CGMainDisplayID(), targetPoint);
}
+1 -1
View File
@@ -64,7 +64,7 @@
#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT
// Define this to 1 if the Linux joystick API is available
#cmakedefine _GLFW_USE_LINUX_JOYSTICKS
#cmakedefine _GLFW_HAS_LINUX_JOYSTICKS
// The GLFW version as used by glfwGetVersionString
#define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@"
+2 -4
View File
@@ -32,10 +32,8 @@
#include "internal.h"
#include <stdlib.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#if _WIN32
#include <malloc.h>
#endif
+7 -1
View File
@@ -99,6 +99,7 @@ struct _GLFWhints
int auxBuffers;
GLboolean stereo;
GLboolean resizable;
GLboolean visible;
int samples;
int glMajor;
int glMinor;
@@ -121,6 +122,7 @@ struct _GLFWwndconfig
const char* title;
int refreshRate;
GLboolean resizable;
GLboolean visible;
int glMajor;
int glMinor;
GLboolean glForward;
@@ -171,6 +173,7 @@ struct _GLFWwindow
int positionX, positionY;
int mode; // GLFW_WINDOW or GLFW_FULLSCREEN
GLboolean resizable; // GL_TRUE if user may resize this window
GLboolean visible; // GL_TRUE if this window is visible
int refreshRate; // monitor refresh rate
void* userPointer;
@@ -229,7 +232,6 @@ struct _GLFWlibrary
_GLFWhints hints;
_GLFWwindow* windowListHead;
_GLFWwindow* currentWindow;
_GLFWwindow* activeWindow;
_GLFWwindow* cursorLockWindow;
_GLFWmonitor* monitorListHead;
@@ -313,6 +315,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 _glfwPlatformShowWindow(_GLFWwindow* window);
void _glfwPlatformHideWindow(_GLFWwindow* window);
// Event processing
void _glfwPlatformPollEvents(void);
@@ -320,6 +324,7 @@ void _glfwPlatformWaitEvents(void);
// OpenGL context management
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window);
_GLFWwindow* _glfwPlatformGetCurrentContext(void);
void _glfwPlatformSwapBuffers(_GLFWwindow* window);
void _glfwPlatformSwapInterval(int interval);
void _glfwPlatformRefreshWindowParams(_GLFWwindow* window);
@@ -340,6 +345,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean activated);
void _glfwInputWindowPos(_GLFWwindow* window, int x, int y);
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
void _glfwInputWindowIconify(_GLFWwindow* window, int iconified);
void _glfwInputWindowVisibility(_GLFWwindow* window, int visible);
void _glfwInputWindowDamage(_GLFWwindow* window);
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
+9 -10
View File
@@ -350,7 +350,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
GLboolean _glfwRefreshContextParams(void)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (!parseGLVersion(&window->glMajor,
&window->glMinor,
@@ -417,7 +417,7 @@ GLboolean _glfwRefreshContextParams(void)
GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (window->glMajor < wndconfig->glMajor ||
(window->glMajor == wndconfig->glMajor &&
@@ -492,16 +492,15 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow handle)
return;
}
if (_glfwLibrary.currentWindow == window)
if (_glfwPlatformGetCurrentContext() == window)
return;
_glfwPlatformMakeContextCurrent(window);
_glfwLibrary.currentWindow = window;
}
//========================================================================
// Returns the window whose OpenGL context is current
// Return the window object whose context is current
//========================================================================
GLFWAPI GLFWwindow glfwGetCurrentContext(void)
@@ -512,7 +511,7 @@ GLFWAPI GLFWwindow glfwGetCurrentContext(void)
return NULL;
}
return _glfwLibrary.currentWindow;
return _glfwPlatformGetCurrentContext();
}
@@ -546,7 +545,7 @@ GLFWAPI void glfwSwapInterval(int interval)
return;
}
if (!_glfwLibrary.currentWindow)
if (!_glfwPlatformGetCurrentContext())
{
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
return;
@@ -571,7 +570,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
return GL_FALSE;
}
window = _glfwLibrary.currentWindow;
window = _glfwPlatformGetCurrentContext();
if (!window)
{
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
@@ -632,7 +631,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return NULL;
}
if (!_glfwLibrary.currentWindow)
if (!_glfwPlatformGetCurrentContext())
{
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
return NULL;
@@ -660,7 +659,7 @@ GLFWAPI void glfwCopyContext(GLFWwindow hsrc, GLFWwindow hdst, unsigned long mas
src = (_GLFWwindow*) hsrc;
dst = (_GLFWwindow*) hdst;
if (_glfwLibrary.currentWindow == dst)
if (_glfwPlatformGetCurrentContext() == dst)
{
_glfwSetError(GLFW_INVALID_VALUE,
"glfwCopyContext: Cannot copy OpenGL state to a current context");
+35 -5
View File
@@ -34,6 +34,24 @@
#include <malloc.h>
//========================================================================
// Thread local storage attribute macro
//========================================================================
#if defined(_MSC_VER)
#define _GLFW_TLS __declspec(thread)
#elif defined(__GNUC__)
#define _GLFW_TLS __thread
#else
#define _GLFW_TLS
#endif
//========================================================================
// The per-thread current context/window pointer
//========================================================================
static _GLFW_TLS _GLFWwindow* _glfwCurrentWindow = NULL;
//========================================================================
// Initialize WGL-specific extensions
// This function is called once before initial context creation, i.e. before
@@ -443,7 +461,7 @@ static GLboolean createContext(_GLFWwindow* window,
}
}
glfwMakeContextCurrent(window);
_glfwPlatformMakeContextCurrent(window);
initWGLExtensions(window);
return GL_TRUE;
@@ -508,8 +526,8 @@ void _glfwDestroyContext(_GLFWwindow* window)
{
// This is duplicated from glfwDestroyWindow
// TODO: Stop duplicating code
if (window == _glfwLibrary.currentWindow)
glfwMakeContextCurrent(NULL);
if (window == _glfwCurrentWindow)
_glfwPlatformMakeContextCurrent(NULL);
if (window->WGL.context)
{
@@ -539,6 +557,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
wglMakeCurrent(window->WGL.DC, window->WGL.context);
else
wglMakeCurrent(NULL, NULL);
_glfwCurrentWindow = window;
}
//========================================================================
// Return the window object whose context is current
//========================================================================
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return _glfwCurrentWindow;
}
@@ -558,7 +588,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window)
void _glfwPlatformSwapInterval(int interval)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
_GLFWwindow* window = _glfwCurrentWindow;
if (window->WGL.EXT_swap_control)
window->WGL.SwapIntervalEXT(interval);
@@ -573,7 +603,7 @@ int _glfwPlatformExtensionSupported(const char* extension)
{
const GLubyte* extensions;
_GLFWwindow* window = _glfwLibrary.currentWindow;
_GLFWwindow* window = _glfwCurrentWindow;
if (window->WGL.GetExtensionsStringEXT != NULL)
{
+1 -1
View File
@@ -195,7 +195,7 @@ typedef struct _GLFWlibraryWin32
// Timer data
struct {
GLboolean hasPerformanceCounter;
GLboolean hasPC;
double resolution;
unsigned int t0_32;
__int64 t0_64;
+4 -4
View File
@@ -45,13 +45,13 @@ void _glfwInitTimer(void)
if (QueryPerformanceFrequency((LARGE_INTEGER*) &freq))
{
_glfwLibrary.Win32.timer.hasPerformanceCounter = GL_TRUE;
_glfwLibrary.Win32.timer.hasPC = GL_TRUE;
_glfwLibrary.Win32.timer.resolution = 1.0 / (double) freq;
QueryPerformanceCounter((LARGE_INTEGER*) &_glfwLibrary.Win32.timer.t0_64);
}
else
{
_glfwLibrary.Win32.timer.hasPerformanceCounter = GL_FALSE;
_glfwLibrary.Win32.timer.hasPC = GL_FALSE;
_glfwLibrary.Win32.timer.resolution = 0.001; // winmm resolution is 1 ms
_glfwLibrary.Win32.timer.t0_32 = _glfw_timeGetTime();
}
@@ -71,7 +71,7 @@ double _glfwPlatformGetTime(void)
double t;
__int64 t_64;
if (_glfwLibrary.Win32.timer.hasPerformanceCounter)
if (_glfwLibrary.Win32.timer.hasPC)
{
QueryPerformanceCounter((LARGE_INTEGER*) &t_64);
t = (double)(t_64 - _glfwLibrary.Win32.timer.t0_64);
@@ -91,7 +91,7 @@ void _glfwPlatformSetTime(double t)
{
__int64 t_64;
if (_glfwLibrary.Win32.timer.hasPerformanceCounter)
if (_glfwLibrary.Win32.timer.hasPC)
{
QueryPerformanceCounter((LARGE_INTEGER*) &t_64);
_glfwLibrary.Win32.timer.t0_64 = t_64 - (__int64) (t / _glfwLibrary.Win32.timer.resolution);
+29 -93
View File
@@ -33,95 +33,6 @@
#include <stdlib.h>
#include <malloc.h>
//========================================================================
// Enable/disable minimize/restore animations
//========================================================================
static int setMinMaxAnimations(int enable)
{
ANIMATIONINFO AI;
int old_enable;
// Get old animation setting
AI.cbSize = sizeof(ANIMATIONINFO);
SystemParametersInfo(SPI_GETANIMATION, AI.cbSize, &AI, 0);
old_enable = AI.iMinAnimate;
// If requested, change setting
if (old_enable != enable)
{
AI.iMinAnimate = enable;
SystemParametersInfo(SPI_SETANIMATION, AI.cbSize, &AI,
SPIF_SENDCHANGE);
}
return old_enable;
}
//========================================================================
// Focus the window and bring it to the top of the stack
// Due to some nastiness with how XP handles SetForegroundWindow we have
// to go through some really bizarre measures to achieve this
//========================================================================
static void setForegroundWindow(HWND hWnd)
{
int try_count = 0;
int old_animate;
// Try the standard approach first...
BringWindowToTop(hWnd);
SetForegroundWindow(hWnd);
// If it worked, return now
if (hWnd == GetForegroundWindow())
{
// Try to modify the system settings (since this is the foreground
// process, we are allowed to do this)
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0,
SPIF_SENDCHANGE);
return;
}
// For other Windows versions than 95 & NT4.0, the standard approach
// may not work, so if we failed we have to "trick" Windows into
// making our window the foureground window: Iconify and restore
// again. It is ugly, but it seems to work (we turn off those annoying
// zoom animations to make it look a bit better at least).
// Turn off minimize/restore animations
old_animate = setMinMaxAnimations(0);
// We try this a few times, just to be on the safe side of things...
do
{
// Iconify & restore
ShowWindow(hWnd, SW_HIDE);
ShowWindow(hWnd, SW_SHOWMINIMIZED);
ShowWindow(hWnd, SW_SHOWNORMAL);
// Try to get focus
BringWindowToTop(hWnd);
SetForegroundWindow(hWnd);
// We do not want to keep going on forever, so we keep track of
// how many times we tried
try_count++;
}
while (hWnd != GetForegroundWindow() && try_count <= 3);
// Restore the system minimize/restore animation setting
setMinMaxAnimations(old_animate);
// Try to modify the system settings (since this is now hopefully the
// foreground process, we are probably allowed to do this)
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0,
SPIF_SENDCHANGE);
}
//========================================================================
// Hide mouse cursor
//========================================================================
@@ -506,6 +417,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0;
}
case WM_SHOWWINDOW:
{
_glfwInputWindowVisibility(window, wParam ? GL_TRUE : GL_FALSE);
break;
}
case WM_SYSCOMMAND:
{
switch (wParam & 0xfff0)
@@ -845,7 +762,7 @@ static int createWindow(_GLFWwindow* window,
WCHAR* wideTitle;
// Set common window styles
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
dwExStyle = WS_EX_APPWINDOW;
// Set window style, depending on fullscreen mode
@@ -1080,9 +997,6 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
SWP_NOMOVE | SWP_NOSIZE);
}
setForegroundWindow(window->Win32.handle);
SetFocus(window->Win32.handle);
return GL_TRUE;
}
@@ -1202,6 +1116,28 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
}
//========================================================================
// Show or hide window
//========================================================================
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
ShowWindow(window->Win32.handle, SW_SHOWNORMAL);
BringWindowToTop(window->Win32.handle);
SetForegroundWindow(window->Win32.handle);
SetFocus(window->Win32.handle);
}
//========================================================================
// Show or hide window
//========================================================================
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
ShowWindow(window->Win32.handle, SW_HIDE);
}
//========================================================================
// Write back window parameters into GLFW window structure
//========================================================================
+71 -10
View File
@@ -33,10 +33,8 @@
#include <string.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#if _WIN32
#include <malloc.h>
#endif
@@ -82,8 +80,9 @@ void _glfwSetDefaultWindowHints(void)
_glfwLibrary.hints.glMajor = 1;
_glfwLibrary.hints.glMinor = 0;
// The default is to allow window resizing
// The default is to show the window and allow window resizing
_glfwLibrary.hints.resizable = GL_TRUE;
_glfwLibrary.hints.visible = GL_TRUE;
// The default is 24 bits of depth, 8 bits of color
_glfwLibrary.hints.depthBits = 24;
@@ -182,6 +181,16 @@ void _glfwInputWindowIconify(_GLFWwindow* window, int iconified)
}
//========================================================================
// Register window visibility events
//========================================================================
void _glfwInputWindowVisibility(_GLFWwindow* window, int visible)
{
window->visible = visible;
}
//========================================================================
// Register window damage events
//========================================================================
@@ -252,6 +261,7 @@ GLFWAPI GLFWwindow glfwCreateWindow(int width, int height,
wndconfig.title = title;
wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0);
wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE;
wndconfig.visible = _glfwLibrary.hints.visible ? GL_TRUE : GL_FALSE;
wndconfig.glMajor = _glfwLibrary.hints.glMajor;
wndconfig.glMinor = _glfwLibrary.hints.glMinor;
wndconfig.glForward = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE;
@@ -356,6 +366,9 @@ GLFWAPI GLFWwindow glfwCreateWindow(int width, int height,
glClear(GL_COLOR_BUFFER_BIT);
_glfwPlatformSwapBuffers(window);
if (wndconfig.visible || mode == GLFW_FULLSCREEN)
glfwShowWindow(window);
return window;
}
@@ -413,9 +426,12 @@ GLFWAPI void glfwWindowHint(int target, int hint)
case GLFW_STEREO:
_glfwLibrary.hints.stereo = hint;
break;
case GLFW_WINDOW_RESIZABLE:
case GLFW_RESIZABLE:
_glfwLibrary.hints.resizable = hint;
break;
case GLFW_VISIBLE:
_glfwLibrary.hints.visible = hint;
break;
case GLFW_FSAA_SAMPLES:
_glfwLibrary.hints.samples = hint;
break;
@@ -463,8 +479,9 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow handle)
return;
// Clear the current context if this window's context is current
if (window == _glfwLibrary.currentWindow)
glfwMakeContextCurrent(NULL);
// TODO: Re-examine this in light of multithreading
if (window == _glfwPlatformGetCurrentContext())
_glfwPlatformMakeContextCurrent(NULL);
// Clear the active window pointer if this is the active window
if (window == _glfwLibrary.activeWindow)
@@ -652,6 +669,48 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow handle)
}
//========================================================================
// Window show
//========================================================================
GLFWAPI void glfwShowWindow(GLFWwindow handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
if (window->mode == GLFW_FULLSCREEN)
return;
_glfwPlatformShowWindow(window);
}
//========================================================================
// Window hide
//========================================================================
GLFWAPI void glfwHideWindow(GLFWwindow handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
if (window->mode == GLFW_FULLSCREEN)
return;
_glfwPlatformHideWindow(window);
}
//========================================================================
// Get window parameter
//========================================================================
@@ -676,8 +735,10 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow handle, int param)
return window->closeRequested;
case GLFW_REFRESH_RATE:
return window->refreshRate;
case GLFW_WINDOW_RESIZABLE:
case GLFW_RESIZABLE:
return window->resizable;
case GLFW_VISIBLE:
return window->visible;
case GLFW_OPENGL_VERSION_MAJOR:
return window->glMajor;
case GLFW_OPENGL_VERSION_MINOR:
@@ -816,7 +877,7 @@ GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindowiconifyfun cbfun)
//========================================================================
// Poll for new window and input events and close any flagged windows
// Poll for new window and input events
//========================================================================
GLFWAPI void glfwPollEvents(void)
+5 -2
View File
@@ -634,6 +634,8 @@ static void terminateDisplay(void)
int _glfwPlatformInit(void)
{
XInitThreads();
if (!initDisplay())
return GL_FALSE;
@@ -646,7 +648,8 @@ int _glfwPlatformInit(void)
_glfwLibrary.X11.cursor = createNULLCursor();
_glfwInitJoysticks();
if (!_glfwInitJoysticks())
return GL_FALSE;
_glfwInitMonitors();
@@ -720,7 +723,7 @@ const char* _glfwPlatformGetVersionString(void)
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
" clock_gettime"
#endif
#if defined(_GLFW_USE_LINUX_JOYSTICKS)
#if defined(_GLFW_HAS_LINUX_JOYSTICKS)
" Linux-joystick-API"
#else
" no-joystick-support"
+48 -25
View File
@@ -30,17 +30,18 @@
#include "internal.h"
#ifdef _GLFW_USE_LINUX_JOYSTICKS
#ifdef _GLFW_HAS_LINUX_JOYSTICKS
#include <linux/joystick.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <regex.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#endif // _GLFW_USE_LINUX_JOYSTICKS
#endif // _GLFW_HAS_LINUX_JOYSTICKS
//========================================================================
@@ -49,11 +50,11 @@
static int openJoystickDevice(int joy, const char* path)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
#ifdef _GLFW_HAS_LINUX_JOYSTICKS
char numAxes, numButtons;
int fd, version;
fd = open(path, O_NONBLOCK);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd == -1)
return GL_FALSE;
@@ -96,7 +97,7 @@ static int openJoystickDevice(int joy, const char* path)
}
_glfwLibrary.X11.joystick[joy].present = GL_TRUE;
#endif // _GLFW_USE_LINUX_JOYSTICKS
#endif // _GLFW_HAS_LINUX_JOYSTICKS
return GL_TRUE;
}
@@ -108,7 +109,7 @@ static int openJoystickDevice(int joy, const char* path)
static void pollJoystickEvents(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
#ifdef _GLFW_HAS_LINUX_JOYSTICKS
int i;
ssize_t result;
struct js_event e;
@@ -127,7 +128,7 @@ static void pollJoystickEvents(void)
if (errno == ENODEV)
_glfwLibrary.X11.joystick[i].present = GL_FALSE;
if (result < sizeof(e))
if (result == -1)
break;
// We don't care if it's an init event or not
@@ -159,7 +160,7 @@ static void pollJoystickEvents(void)
}
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
#endif // _GLFW_HAS_LINUX_JOYSTICKS
}
@@ -171,30 +172,52 @@ static void pollJoystickEvents(void)
// Initialize joystick interface
//========================================================================
void _glfwInitJoysticks(void)
int _glfwInitJoysticks(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
int i, j, joy = 0;
char path[20];
const char* bases[] =
#ifdef _GLFW_HAS_LINUX_JOYSTICKS
int i, joy = 0;
regex_t regex;
DIR* dir;
const char* dirs[] =
{
"/dev/input/js",
"/dev/js"
"/dev/input",
"/dev"
};
for (i = 0; i < sizeof(bases) / sizeof(bases[0]); i++)
if (regcomp(&regex, "^js[0-9]\\+$", 0) != 0)
{
for (j = 0; j < 50; j++)
{
if (joy > GLFW_JOYSTICK_LAST)
break;
_glfwSetError(GLFW_PLATFORM_ERROR, "X11: Failed to compile regex");
return GL_FALSE;
}
sprintf(path, "%s%i", bases[i], j);
for (i = 0; i < sizeof(dirs) / sizeof(dirs[0]); i++)
{
struct dirent* entry;
dir = opendir(dirs[i]);
if (!dir)
continue;
while ((entry = readdir(dir)))
{
char path[20];
regmatch_t match;
if (regexec(&regex, entry->d_name, 1, &match, 0) != 0)
continue;
snprintf(path, sizeof(path), "%s/%s", dirs[i], entry->d_name);
if (openJoystickDevice(joy, path))
joy++;
}
closedir(dir);
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
regfree(&regex);
#endif // _GLFW_HAS_LINUX_JOYSTICKS
return GL_TRUE;
}
@@ -204,7 +227,7 @@ void _glfwInitJoysticks(void)
void _glfwTerminateJoysticks(void)
{
#ifdef _GLFW_USE_LINUX_JOYSTICKS
#ifdef _GLFW_HAS_LINUX_JOYSTICKS
int i;
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++)
@@ -218,7 +241,7 @@ void _glfwTerminateJoysticks(void)
_glfwLibrary.X11.joystick[i].present = GL_FALSE;
}
}
#endif // _GLFW_USE_LINUX_JOYSTICKS
#endif // _GLFW_HAS_LINUX_JOYSTICKS
}
+33 -1
View File
@@ -38,6 +38,22 @@
void (*glXGetProcAddressEXT(const GLubyte* procName))();
//========================================================================
// Thread local storage attribute macro
//========================================================================
#if defined(__GNUC__)
#define _GLFW_TLS __thread
#else
#define _GLFW_TLS
#endif
//========================================================================
// The per-thread current context/window pointer
//========================================================================
static _GLFW_TLS _GLFWwindow* _glfwCurrentWindow = NULL;
//========================================================================
// Returns the specified attribute of the specified GLXFBConfig
// NOTE: Do not call this unless we have found GLX 1.3+ or GLX_SGIX_fbconfig
@@ -616,6 +632,10 @@ XVisualInfo* _glfwGetContextVisual(_GLFWwindow* window)
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Make the OpenGL context associated with the specified window current
//========================================================================
@@ -630,6 +650,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
}
else
glXMakeCurrent(_glfwLibrary.X11.display, None, NULL);
_glfwCurrentWindow = window;
}
//========================================================================
// Return the window object whose context is current
//========================================================================
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return _glfwCurrentWindow;
}
@@ -649,7 +681,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window)
void _glfwPlatformSwapInterval(int interval)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
_GLFWwindow* window = _glfwCurrentWindow;
if (_glfwLibrary.GLX.EXT_swap_control)
{
+1 -1
View File
@@ -322,7 +322,7 @@ void _glfwSetVideoMode(int* width, int* height, int* rate);
void _glfwRestoreVideoMode(void);
// Joystick input
void _glfwInitJoysticks(void);
int _glfwInitJoysticks(void);
void _glfwTerminateJoysticks(void);
// Monitors
+107 -79
View File
@@ -30,6 +30,8 @@
#include "internal.h"
#include <sys/select.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -226,10 +228,6 @@ static GLboolean createWindow(_GLFWwindow* window,
_glfwPlatformSetWindowTitle(window, wndconfig->title);
// Make sure the window is mapped before proceeding
XMapWindow(_glfwLibrary.X11.display, window->X11.handle);
XFlush(_glfwLibrary.X11.display);
return GL_TRUE;
}
@@ -460,34 +458,31 @@ static _GLFWwindow* findWindow(Window handle)
//========================================================================
// Get and process next X event (called by _glfwPlatformPollEvents)
// Process the specified X event
//========================================================================
static void processSingleEvent(void)
static void processEvent(XEvent *event)
{
_GLFWwindow* window;
XEvent event;
XNextEvent(_glfwLibrary.X11.display, &event);
switch (event.type)
switch (event->type)
{
case KeyPress:
{
// A keyboard key was pressed
window = findWindow(event.xkey.window);
window = findWindow(event->xkey.window);
if (window == NULL)
return;
_glfwInputKey(window, translateKey(event.xkey.keycode), GLFW_PRESS);
_glfwInputChar(window, translateChar(&event.xkey));
_glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_PRESS);
_glfwInputChar(window, translateChar(&event->xkey));
break;
}
case KeyRelease:
{
// A keyboard key was released
window = findWindow(event.xkey.window);
window = findWindow(event->xkey.window);
if (window == NULL)
return;
@@ -501,15 +496,15 @@ static void processSingleEvent(void)
XPeekEvent(_glfwLibrary.X11.display, &nextEvent);
if (nextEvent.type == KeyPress &&
nextEvent.xkey.window == event.xkey.window &&
nextEvent.xkey.keycode == event.xkey.keycode)
nextEvent.xkey.window == event->xkey.window &&
nextEvent.xkey.keycode == event->xkey.keycode)
{
// This last check is a hack to work around key repeats
// leaking through due to some sort of time drift
// Toshiyuki Takahashi can press a button 16 times per
// second so it's fairly safe to assume that no human is
// pressing the key 50 times per second (value is ms)
if ((nextEvent.xkey.time - event.xkey.time) < 20)
if ((nextEvent.xkey.time - event->xkey.time) < 20)
{
// Do not report anything for this event
break;
@@ -517,34 +512,34 @@ static void processSingleEvent(void)
}
}
_glfwInputKey(window, translateKey(event.xkey.keycode), GLFW_RELEASE);
_glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_RELEASE);
break;
}
case ButtonPress:
{
// A mouse button was pressed or a scrolling event occurred
window = findWindow(event.xbutton.window);
window = findWindow(event->xbutton.window);
if (window == NULL)
return;
if (event.xbutton.button == Button1)
if (event->xbutton.button == Button1)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
else if (event.xbutton.button == Button2)
else if (event->xbutton.button == Button2)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS);
else if (event.xbutton.button == Button3)
else if (event->xbutton.button == Button3)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);
// XFree86 3.3.2 and later translates mouse wheel up/down into
// mouse button 4 & 5 presses
else if (event.xbutton.button == Button4)
else if (event->xbutton.button == Button4)
_glfwInputScroll(window, 0.0, 1.0);
else if (event.xbutton.button == Button5)
else if (event->xbutton.button == Button5)
_glfwInputScroll(window, 0.0, -1.0);
else if (event.xbutton.button == Button6)
else if (event->xbutton.button == Button6)
_glfwInputScroll(window, -1.0, 0.0);
else if (event.xbutton.button == Button7)
else if (event->xbutton.button == Button7)
_glfwInputScroll(window, 1.0, 0.0);
break;
@@ -553,23 +548,23 @@ static void processSingleEvent(void)
case ButtonRelease:
{
// A mouse button was released
window = findWindow(event.xbutton.window);
window = findWindow(event->xbutton.window);
if (window == NULL)
return;
if (event.xbutton.button == Button1)
if (event->xbutton.button == Button1)
{
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_RELEASE);
}
else if (event.xbutton.button == Button2)
else if (event->xbutton.button == Button2)
{
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_MIDDLE,
GLFW_RELEASE);
}
else if (event.xbutton.button == Button3)
else if (event->xbutton.button == Button3)
{
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
@@ -581,7 +576,7 @@ static void processSingleEvent(void)
case EnterNotify:
{
// The cursor entered the window
window = findWindow(event.xcrossing.window);
window = findWindow(event->xcrossing.window);
if (window == NULL)
return;
@@ -595,7 +590,7 @@ static void processSingleEvent(void)
case LeaveNotify:
{
// The cursor left the window
window = findWindow(event.xcrossing.window);
window = findWindow(event->xcrossing.window);
if (window == NULL)
return;
@@ -609,12 +604,12 @@ static void processSingleEvent(void)
case MotionNotify:
{
// The cursor was moved
window = findWindow(event.xmotion.window);
window = findWindow(event->xmotion.window);
if (window == NULL)
return;
if (event.xmotion.x != window->X11.cursorPosX ||
event.xmotion.y != window->X11.cursorPosY)
if (event->xmotion.x != window->X11.cursorPosX ||
event->xmotion.y != window->X11.cursorPosY)
{
// The cursor was moved by something other than GLFW
@@ -625,17 +620,17 @@ static void processSingleEvent(void)
if (_glfwLibrary.activeWindow != window)
break;
x = event.xmotion.x - window->X11.cursorPosX;
y = event.xmotion.y - window->X11.cursorPosY;
x = event->xmotion.x - window->X11.cursorPosX;
y = event->xmotion.y - window->X11.cursorPosY;
}
else
{
x = event.xmotion.x;
y = event.xmotion.y;
x = event->xmotion.x;
y = event->xmotion.y;
}
window->X11.cursorPosX = event.xmotion.x;
window->X11.cursorPosY = event.xmotion.y;
window->X11.cursorPosX = event->xmotion.x;
window->X11.cursorPosY = event->xmotion.y;
window->X11.cursorCentered = GL_FALSE;
_glfwInputCursorMotion(window, x, y);
@@ -647,17 +642,17 @@ static void processSingleEvent(void)
case ConfigureNotify:
{
// The window configuration changed somehow
window = findWindow(event.xconfigure.window);
window = findWindow(event->xconfigure.window);
if (window == NULL)
return;
_glfwInputWindowSize(window,
event.xconfigure.width,
event.xconfigure.height);
event->xconfigure.width,
event->xconfigure.height);
_glfwInputWindowPos(window,
event.xconfigure.x,
event.xconfigure.y);
event->xconfigure.x,
event->xconfigure.y);
break;
}
@@ -665,11 +660,11 @@ static void processSingleEvent(void)
case ClientMessage:
{
// Custom client message, probably from the window manager
window = findWindow(event.xclient.window);
window = findWindow(event->xclient.window);
if (window == NULL)
return;
if ((Atom) event.xclient.data.l[0] == _glfwLibrary.X11.wmDeleteWindow)
if ((Atom) event->xclient.data.l[0] == _glfwLibrary.X11.wmDeleteWindow)
{
// The window manager was asked to close the window, for example by
// the user pressing a 'close' window decoration button
@@ -677,17 +672,17 @@ static void processSingleEvent(void)
_glfwInputWindowCloseRequest(window);
}
else if (_glfwLibrary.X11.wmPing != None &&
(Atom) event.xclient.data.l[0] == _glfwLibrary.X11.wmPing)
(Atom) event->xclient.data.l[0] == _glfwLibrary.X11.wmPing)
{
// The window manager is pinging the application to ensure it's
// still responding to events
event.xclient.window = _glfwLibrary.X11.root;
event->xclient.window = _glfwLibrary.X11.root;
XSendEvent(_glfwLibrary.X11.display,
event.xclient.window,
event->xclient.window,
False,
SubstructureNotifyMask | SubstructureRedirectMask,
&event);
event);
}
break;
@@ -696,10 +691,11 @@ static void processSingleEvent(void)
case MapNotify:
{
// The window was mapped
window = findWindow(event.xmap.window);
window = findWindow(event->xmap.window);
if (window == NULL)
return;
_glfwInputWindowVisibility(window, GL_TRUE);
_glfwInputWindowIconify(window, GL_FALSE);
break;
}
@@ -707,10 +703,11 @@ static void processSingleEvent(void)
case UnmapNotify:
{
// The window was unmapped
window = findWindow(event.xmap.window);
window = findWindow(event->xmap.window);
if (window == NULL)
return;
_glfwInputWindowVisibility(window, GL_FALSE);
_glfwInputWindowIconify(window, GL_TRUE);
break;
}
@@ -718,7 +715,7 @@ static void processSingleEvent(void)
case FocusIn:
{
// The window gained focus
window = findWindow(event.xfocus.window);
window = findWindow(event->xfocus.window);
if (window == NULL)
return;
@@ -733,7 +730,7 @@ static void processSingleEvent(void)
case FocusOut:
{
// The window lost focus
window = findWindow(event.xfocus.window);
window = findWindow(event->xfocus.window);
if (window == NULL)
return;
@@ -748,7 +745,7 @@ static void processSingleEvent(void)
case Expose:
{
// The window's contents was damaged
window = findWindow(event.xexpose.window);
window = findWindow(event->xexpose.window);
if (window == NULL)
return;
@@ -769,7 +766,7 @@ static void processSingleEvent(void)
{
// The selection conversion status is available
XSelectionEvent* request = &event.xselection;
XSelectionEvent* request = &event->xselection;
if (_glfwReadSelection(request))
_glfwLibrary.X11.selection.status = _GLFW_CONVERSION_SUCCEEDED;
@@ -783,7 +780,7 @@ static void processSingleEvent(void)
{
// The contents of the selection was requested
XSelectionRequestEvent* request = &event.xselectionrequest;
XSelectionRequestEvent* request = &event->xselectionrequest;
XEvent response;
memset(&response, 0, sizeof(response));
@@ -808,11 +805,11 @@ static void processSingleEvent(void)
default:
{
#if defined(_GLFW_HAS_XRANDR)
switch (event.type - _glfwLibrary.X11.RandR.eventBase)
switch (event->type - _glfwLibrary.X11.RandR.eventBase)
{
case RRScreenChangeNotify:
{
XRRUpdateConfiguration(&event);
XRRUpdateConfiguration(event);
_glfwRefreshMonitors();
break;
}
@@ -958,7 +955,6 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
int mode = 0, rate, sizeChanged = GL_FALSE;
XSizeHints* sizehints;
rate = window->refreshRate;
@@ -972,14 +968,14 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
// Update window size restrictions to match new window size
sizehints = XAllocSizeHints();
sizehints->flags = 0;
XSizeHints* hints = XAllocSizeHints();
sizehints->min_width = sizehints->max_width = width;
sizehints->min_height = sizehints->max_height = height;
hints->flags |= (PMinSize | PMaxSize);
hints->min_width = hints->max_width = width;
hints->min_height = hints->max_height = height;
XSetWMNormalHints(_glfwLibrary.X11.display, window->X11.handle, sizehints);
XFree(sizehints);
XSetWMNormalHints(_glfwLibrary.X11.display, window->X11.handle, hints);
XFree(hints);
}
// Change window size before changing fullscreen mode?
@@ -1047,6 +1043,28 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
}
//========================================================================
// Show window
//========================================================================
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
XMapRaised(_glfwLibrary.X11.display, window->X11.handle);
XFlush(_glfwLibrary.X11.display);
}
//========================================================================
// Hide window
//========================================================================
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
XUnmapWindow(_glfwLibrary.X11.display, window->X11.handle);
XFlush(_glfwLibrary.X11.display);
}
//========================================================================
// Read back framebuffer parameters from the context
//========================================================================
@@ -1094,13 +1112,18 @@ void _glfwPlatformRefreshWindowParams(_GLFWwindow* window)
void _glfwPlatformPollEvents(void)
{
XEvent event;
while (XCheckMaskEvent(_glfwLibrary.X11.display, ~0, &event) ||
XCheckTypedEvent(_glfwLibrary.X11.display, ClientMessage, &event))
{
processEvent(&event);
}
// Check whether the cursor has moved inside an active window that has
// captured the cursor (because then it needs to be re-centered)
_GLFWwindow* window;
// Process all pending events
while (XPending(_glfwLibrary.X11.display))
processSingleEvent();
// Did the cursor move in an active window that has captured the cursor
window = _glfwLibrary.activeWindow;
if (window)
{
@@ -1127,13 +1150,18 @@ void _glfwPlatformPollEvents(void)
void _glfwPlatformWaitEvents(void)
{
XEvent event;
int fd;
fd_set fds;
// Block waiting for an event to arrive
XNextEvent(_glfwLibrary.X11.display, &event);
XPutBackEvent(_glfwLibrary.X11.display, &event);
fd = ConnectionNumber(_glfwLibrary.X11.display);
_glfwPlatformPollEvents();
FD_ZERO(&fds);
FD_SET(fd, &fds);
XFlush(_glfwLibrary.X11.display);
if (select(fd + 1, &fds, NULL, NULL, NULL) > 0)
_glfwPlatformPollEvents();
}