mirror of
https://github.com/glfw/glfw.git
synced 2026-09-20 08:23:13 +00:00
Merge branch 'master' into EGL
Conflicts: src/glx_opengl.c src/opengl.c tests/glfwinfo.c
This commit is contained in:
@@ -103,6 +103,9 @@ int _glfwPlatformInit(void)
|
||||
|
||||
_glfwInitJoysticks();
|
||||
|
||||
if (!_glfwInitOpenGL())
|
||||
return GL_FALSE;
|
||||
|
||||
_glfwLibrary.NS.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
if (!_glfwLibrary.NS.eventSource)
|
||||
return GL_FALSE;
|
||||
@@ -143,6 +146,8 @@ int _glfwPlatformTerminate(void)
|
||||
|
||||
_glfwTerminateJoysticks();
|
||||
|
||||
_glfwTerminateOpenGL();
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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];
|
||||
|
||||
@@ -123,4 +123,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_
|
||||
|
||||
+2
-2
@@ -686,7 +686,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;
|
||||
@@ -1100,7 +1100,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);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,24 @@
|
||||
#include <stdlib.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;
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Returns the specified attribute of the specified EGLConfig
|
||||
//========================================================================
|
||||
@@ -508,6 +526,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
eglMakeCurrent(_glfwLibrary.EGL.display,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
_glfwCurrentWindow = window;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Return the window object whose context is current
|
||||
//========================================================================
|
||||
|
||||
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
|
||||
{
|
||||
return _glfwCurrentWindow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-4
@@ -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
|
||||
|
||||
|
||||
|
||||
+33
-1
@@ -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
|
||||
@@ -611,6 +627,10 @@ void _glfwDestroyContext(_GLFWwindow* window)
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//========================================================================
|
||||
// Make the OpenGL context associated with the specified window current
|
||||
//========================================================================
|
||||
@@ -625,6 +645,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -644,7 +676,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
|
||||
void _glfwPlatformSwapInterval(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||
_GLFWwindow* window = _glfwCurrentWindow;
|
||||
|
||||
if (_glfwLibrary.GLX.EXT_swap_control)
|
||||
{
|
||||
|
||||
+1
-1
@@ -208,7 +208,6 @@ struct _GLFWlibrary
|
||||
_GLFWhints hints;
|
||||
|
||||
_GLFWwindow* windowListHead;
|
||||
_GLFWwindow* currentWindow;
|
||||
_GLFWwindow* activeWindow;
|
||||
|
||||
GLFWwindowsizefun windowSizeCallback;
|
||||
@@ -298,6 +297,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);
|
||||
|
||||
+8
-9
@@ -392,7 +392,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
|
||||
|
||||
GLboolean _glfwRefreshContextParams(void)
|
||||
{
|
||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (!parseGLVersion(&window->clientAPI,
|
||||
&window->glMajor,
|
||||
@@ -460,7 +460,7 @@ GLboolean _glfwRefreshContextParams(void)
|
||||
|
||||
GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig)
|
||||
{
|
||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (window->glMajor < wndconfig->glMajor ||
|
||||
(window->glMajor == wndconfig->glMajor &&
|
||||
@@ -535,11 +535,10 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow handle)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_glfwLibrary.currentWindow == window)
|
||||
if (_glfwPlatformGetCurrentContext() == window)
|
||||
return;
|
||||
|
||||
_glfwPlatformMakeContextCurrent(window);
|
||||
_glfwLibrary.currentWindow = window;
|
||||
}
|
||||
|
||||
|
||||
@@ -555,7 +554,7 @@ GLFWAPI GLFWwindow glfwGetCurrentContext(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _glfwLibrary.currentWindow;
|
||||
return _glfwPlatformGetCurrentContext();
|
||||
}
|
||||
|
||||
|
||||
@@ -589,7 +588,7 @@ GLFWAPI void glfwSwapInterval(int interval)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_glfwLibrary.currentWindow)
|
||||
if (!_glfwPlatformGetCurrentContext())
|
||||
{
|
||||
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||
return;
|
||||
@@ -614,7 +613,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
window = _glfwLibrary.currentWindow;
|
||||
window = _glfwPlatformGetCurrentContext();
|
||||
if (!window)
|
||||
{
|
||||
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||
@@ -675,7 +674,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_glfwLibrary.currentWindow)
|
||||
if (!_glfwPlatformGetCurrentContext())
|
||||
{
|
||||
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||
return NULL;
|
||||
@@ -703,7 +702,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
@@ -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
|
||||
@@ -447,7 +465,7 @@ static GLboolean createContext(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
_glfwPlatformMakeContextCurrent(window);
|
||||
initWGLExtensions(window);
|
||||
|
||||
return GL_TRUE;
|
||||
@@ -512,8 +530,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)
|
||||
{
|
||||
@@ -543,6 +561,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -562,7 +592,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);
|
||||
@@ -577,7 +607,7 @@ int _glfwPlatformExtensionSupported(const char* extension)
|
||||
{
|
||||
const GLubyte* extensions;
|
||||
|
||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||
_GLFWwindow* window = _glfwCurrentWindow;
|
||||
|
||||
if (window->WGL.GetExtensionsStringEXT != NULL)
|
||||
{
|
||||
|
||||
+5
-6
@@ -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
|
||||
|
||||
|
||||
@@ -468,8 +466,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)
|
||||
|
||||
+4
-1
@@ -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;
|
||||
|
||||
// Start the timer
|
||||
_glfwInitTimer();
|
||||
|
||||
+38
-15
@@ -37,7 +37,8 @@
|
||||
#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
|
||||
@@ -53,7 +54,7 @@ static int openJoystickDevice(int joy, const char* path)
|
||||
char numAxes, numButtons;
|
||||
int fd, version;
|
||||
|
||||
fd = open(path, O_NONBLOCK);
|
||||
fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
if (fd == -1)
|
||||
return GL_FALSE;
|
||||
|
||||
@@ -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
|
||||
@@ -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[] =
|
||||
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(®ex, "^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(®ex, 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);
|
||||
}
|
||||
|
||||
regfree(®ex);
|
||||
#endif // _GLFW_USE_LINUX_JOYSTICKS
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -235,7 +235,7 @@ void _glfwSetVideoMode(int* width, int* height, int* rate);
|
||||
void _glfwRestoreVideoMode(void);
|
||||
|
||||
// Joystick input
|
||||
void _glfwInitJoysticks(void);
|
||||
int _glfwInitJoysticks(void);
|
||||
void _glfwTerminateJoysticks(void);
|
||||
|
||||
// Unicode support
|
||||
|
||||
+83
-75
@@ -30,6 +30,8 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -460,34 +462,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 +500,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 +516,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 +552,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 +580,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 +594,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 +608,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 +624,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 +646,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 +664,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 +676,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,7 +695,7 @@ static void processSingleEvent(void)
|
||||
case MapNotify:
|
||||
{
|
||||
// The window was mapped
|
||||
window = findWindow(event.xmap.window);
|
||||
window = findWindow(event->xmap.window);
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
@@ -707,7 +706,7 @@ static void processSingleEvent(void)
|
||||
case UnmapNotify:
|
||||
{
|
||||
// The window was unmapped
|
||||
window = findWindow(event.xmap.window);
|
||||
window = findWindow(event->xmap.window);
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
@@ -718,7 +717,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 +732,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 +747,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 +768,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 +782,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 +807,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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -957,7 +956,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;
|
||||
|
||||
@@ -971,14 +969,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?
|
||||
@@ -1093,13 +1091,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)
|
||||
{
|
||||
@@ -1126,13 +1129,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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user