Merge branch 'master' into clipboard

This commit is contained in:
Camilla Berglund 2012-04-09 15:33:03 +02:00
commit 952c6b7e82
14 changed files with 331 additions and 441 deletions

View File

@ -54,7 +54,6 @@ if (_GLFW_WIN32_WGL)
list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR}) list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY}) list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY})
set(_GLFW_NO_DLOAD_GDI32 ${BUILD_SHARED_LIBS})
set(_GLFW_NO_DLOAD_WINMM ${BUILD_SHARED_LIBS}) set(_GLFW_NO_DLOAD_WINMM ${BUILD_SHARED_LIBS})
if (BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)

View File

@ -311,6 +311,13 @@ static void pollJoystickEvents(void)
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j); (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j);
axes->value = getElementValue(joystick, axes); axes->value = getElementValue(joystick, axes);
} }
for (j = 0; j < joystick->numHats; j++)
{
_glfwJoystickElement* hat =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, j);
hat->value = getElementValue(joystick, hat);
}
} }
} }
} }
@ -502,7 +509,7 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return (int) CFArrayGetCount(_glfwJoysticks[joy].axes); return (int) CFArrayGetCount(_glfwJoysticks[joy].axes);
case GLFW_BUTTONS: case GLFW_BUTTONS:
return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons); return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons) + ((int) CFArrayGetCount(_glfwJoysticks[joy].hats)) * 4;
default: default:
break; break;
@ -565,7 +572,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
int numbuttons) int numbuttons)
{ {
int i; int button;
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST) if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
return 0; return 0;
@ -578,17 +585,31 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
return 0; return 0;
} }
numbuttons = numbuttons < joystick.numButtons ? numbuttons : joystick.numButtons;
// Update joystick state // Update joystick state
pollJoystickEvents(); pollJoystickEvents();
for (i = 0; i < numbuttons; i++) for (button = 0; button < numbuttons && button < joystick.numButtons; button++)
{ {
_glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, i); _glfwJoystickElement* element = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, button);
buttons[i] = button->value ? GLFW_PRESS : GLFW_RELEASE; buttons[button] = element->value ? GLFW_PRESS : GLFW_RELEASE;
} }
return numbuttons; // Virtual buttons - Inject data from hats
} // Each hat is exposed as 4 buttons which exposes 8 directions with concurrent button presses
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; // Bit fields of button presses for each direction, including nil
for (int i = 0; i < joystick.numHats; i++)
{
_glfwJoystickElement* hat = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.hats, i);
int value = hat->value;
if (value < 0 || value > 8) value = 8;
for (int j = 0; j < 4 && button < numbuttons; j++)
{
buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
}
}
return button;
}

View File

@ -45,8 +45,6 @@
// Define this to 1 if building as a shared library / dynamic library / DLL // Define this to 1 if building as a shared library / dynamic library / DLL
#cmakedefine _GLFW_BUILD_DLL 1 #cmakedefine _GLFW_BUILD_DLL 1
// Define this to 1 to disable dynamic loading of gdi32
#cmakedefine _GLFW_NO_DLOAD_GDI32 1
// Define this to 1 to disable dynamic loading of winmm // Define this to 1 to disable dynamic loading of winmm
#cmakedefine _GLFW_NO_DLOAD_WINMM 1 #cmakedefine _GLFW_NO_DLOAD_WINMM 1

View File

@ -277,6 +277,8 @@ const char* _glfwPlatformGetVersionString(void);
// Input // Input
void _glfwPlatformEnableSystemKeys(_GLFWwindow* window); void _glfwPlatformEnableSystemKeys(_GLFWwindow* window);
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window); void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Fullscreen // Fullscreen
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount); int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount);
@ -307,8 +309,6 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y); void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformIconifyWindow(_GLFWwindow* window); void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window); void _glfwPlatformRestoreWindow(_GLFWwindow* window);
void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Event management // Event management
void _glfwPlatformPollEvents(void); void _glfwPlatformPollEvents(void);

View File

@ -42,7 +42,7 @@
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
{ {
_glfw_GetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp); GetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
} }
@ -52,6 +52,6 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
{ {
_glfw_SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp); SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
} }

View File

@ -44,40 +44,6 @@
static GLboolean initLibraries(void) static GLboolean initLibraries(void)
{ {
#ifndef _GLFW_NO_DLOAD_GDI32
// gdi32.dll (OpenGL pixel format functions & SwapBuffers)
_glfwLibrary.Win32.gdi.instance = LoadLibrary(L"gdi32.dll");
if (!_glfwLibrary.Win32.gdi.instance)
return GL_FALSE;
_glfwLibrary.Win32.gdi.ChoosePixelFormat = (CHOOSEPIXELFORMAT_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "ChoosePixelFormat");
_glfwLibrary.Win32.gdi.DescribePixelFormat = (DESCRIBEPIXELFORMAT_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "DescribePixelFormat");
_glfwLibrary.Win32.gdi.GetPixelFormat = (GETPIXELFORMAT_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "GetPixelFormat");
_glfwLibrary.Win32.gdi.SetPixelFormat = (SETPIXELFORMAT_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "SetPixelFormat");
_glfwLibrary.Win32.gdi.SwapBuffers = (SWAPBUFFERS_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "SwapBuffers");
_glfwLibrary.Win32.gdi.GetDeviceGammaRamp = (GETDEVICEGAMMARAMP_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "GetDeviceGammaRamp");
_glfwLibrary.Win32.gdi.SetDeviceGammaRamp = (SETDEVICEGAMMARAMP_T)
GetProcAddress(_glfwLibrary.Win32.gdi.instance, "SetDeviceGammaRamp");
if (!_glfwLibrary.Win32.gdi.ChoosePixelFormat ||
!_glfwLibrary.Win32.gdi.DescribePixelFormat ||
!_glfwLibrary.Win32.gdi.GetPixelFormat ||
!_glfwLibrary.Win32.gdi.SetPixelFormat ||
!_glfwLibrary.Win32.gdi.SwapBuffers ||
!_glfwLibrary.Win32.gdi.GetDeviceGammaRamp ||
!_glfwLibrary.Win32.gdi.SetDeviceGammaRamp)
{
return GL_FALSE;
}
#endif // _GLFW_NO_DLOAD_GDI32
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
// winmm.dll (for joystick and timer support) // winmm.dll (for joystick and timer support)
@ -113,14 +79,6 @@ static GLboolean initLibraries(void)
static void freeLibraries(void) static void freeLibraries(void)
{ {
#ifndef _GLFW_NO_DLOAD_GDI32
if (_glfwLibrary.Win32.gdi.instance != NULL)
{
FreeLibrary(_glfwLibrary.Win32.gdi.instance);
_glfwLibrary.Win32.gdi.instance = NULL;
}
#endif // _GLFW_NO_DLOAD_GDI32
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
if (_glfwLibrary.Win32.winmm.instance != NULL) if (_glfwLibrary.Win32.winmm.instance != NULL)
{ {
@ -274,9 +232,6 @@ const char* _glfwPlatformGetVersionString(void)
#if defined(_GLFW_BUILD_DLL) #if defined(_GLFW_BUILD_DLL)
" DLL" " DLL"
#endif #endif
#if !defined(_GLFW_NO_DLOAD_GDI32)
" load(gdi32)"
#endif
#if !defined(_GLFW_NO_DLOAD_WINMM) #if !defined(_GLFW_NO_DLOAD_WINMM)
" load(winmm)" " load(winmm)"
#endif #endif

View File

@ -91,6 +91,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
// Get joystick capabilities // Get joystick capabilities
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS)); _glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
const int hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
switch (param) switch (param)
{ {
case GLFW_AXES: case GLFW_AXES:
@ -98,8 +100,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return jc.wNumAxes; return jc.wNumAxes;
case GLFW_BUTTONS: case GLFW_BUTTONS:
// Return number of joystick axes // Return number of joystick buttons
return jc.wNumButtons; return jc.wNumButtons + hats * 4;
default: default:
break; break;
@ -174,7 +176,7 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
// Get joystick state // Get joystick state
ji.dwSize = sizeof(JOYINFOEX); ji.dwSize = sizeof(JOYINFOEX);
ji.dwFlags = JOY_RETURNBUTTONS; ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV;
_glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji); _glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji);
// Get states of all requested buttons // Get states of all requested buttons
@ -184,6 +186,24 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
(ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE); (ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE);
} }
// Virtual buttons - Inject data from hats
// Each hat is exposed as 4 buttons which exposes 8 directions with concurrent button presses
// (Note: This API only exposes one hat)
const int hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; // Bit fields of button presses for each direction, including nil
if (hats > 0)
{
int j;
int value = ji.dwPOV / 100 / 45;
if (value < 0 || value > 8) value = 8;
for (j = 0; j < 4 && button < numbuttons; j++)
{
buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
}
}
return button; return button;
} }

View File

@ -56,7 +56,7 @@ void _glfwPlatformSwapBuffers(void)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwLibrary.currentWindow;
_glfw_SwapBuffers(window->WGL.DC); SwapBuffers(window->WGL.DC);
} }

View File

@ -33,8 +33,13 @@
// We don't need all the fancy stuff // We don't need all the fancy stuff
#define NOMINMAX #ifndef NOMINMAX
#define VC_EXTRALEAN #define NOMINMAX
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -52,7 +57,7 @@
// GLFW requires Windows XP // GLFW requires Windows XP
#ifndef WINVER #ifndef WINVER
#define WINVER 0x0501 #define WINVER 0x0501
#endif #endif
#include <windows.h> #include <windows.h>
@ -68,108 +73,15 @@
// Hack: Define things that some windows.h variants don't // Hack: Define things that some windows.h variants don't
//======================================================================== //========================================================================
// Some old versions of w32api (used by MinGW and Cygwin) define
// WH_KEYBOARD_LL without typedef:ing KBDLLHOOKSTRUCT (!)
#if defined(__MINGW32__) || defined(__CYGWIN__)
#include <w32api.h>
#if defined(WH_KEYBOARD_LL) && (__W32API_MAJOR_VERSION == 1) && (__W32API_MINOR_VERSION <= 2)
#undef WH_KEYBOARD_LL
#endif
#endif
//------------------------------------------------------------------------
// ** NOTE ** If this gives you compiler errors and you are using MinGW
// (or Dev-C++), update to w32api version 1.3 or later:
// http://sourceforge.net/project/showfiles.php?group_id=2435
//------------------------------------------------------------------------
#ifndef WH_KEYBOARD_LL
#define WH_KEYBOARD_LL 13
typedef struct tagKBDLLHOOKSTRUCT {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
DWORD dwExtraInfo;
} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
#endif // WH_KEYBOARD_LL
#ifndef LLKHF_ALTDOWN
#define LLKHF_ALTDOWN 0x00000020
#endif
#ifndef SPI_SETSCREENSAVERRUNNING
#define SPI_SETSCREENSAVERRUNNING 97
#endif
#ifndef SPI_GETANIMATION
#define SPI_GETANIMATION 72
#endif
#ifndef SPI_SETANIMATION
#define SPI_SETANIMATION 73
#endif
#ifndef SPI_GETFOREGROUNDLOCKTIMEOUT
#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
#endif
#ifndef SPI_SETFOREGROUNDLOCKTIMEOUT
#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
#endif
#ifndef CDS_FULLSCREEN
#define CDS_FULLSCREEN 4
#endif
#ifndef PFD_GENERIC_ACCELERATED
#define PFD_GENERIC_ACCELERATED 0x00001000
#endif
#ifndef PFD_DEPTH_DONTCARE
#define PFD_DEPTH_DONTCARE 0x20000000
#endif
#ifndef ENUM_CURRENT_SETTINGS
#define ENUM_CURRENT_SETTINGS -1
#endif
#ifndef ENUM_REGISTRY_SETTINGS
#define ENUM_REGISTRY_SETTINGS -2
#endif
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
#ifndef WHEEL_DELTA
#define WHEEL_DELTA 120
#endif
#ifndef WM_MOUSEHWHEEL #ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E #define WM_MOUSEHWHEEL 0x020E
#endif #endif
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x020B
#endif
#ifndef WM_XBUTTONUP
#define WM_XBUTTONUP 0x020C
#endif
#ifndef XBUTTON1
#define XBUTTON1 1
#endif
#ifndef XBUTTON2
#define XBUTTON2 2
#endif
//======================================================================== //========================================================================
// DLLs that are loaded at glfwInit() // DLLs that are loaded at glfwInit()
//======================================================================== //========================================================================
// gdi32.dll function pointer typedefs
#ifndef _GLFW_NO_DLOAD_GDI32
typedef int (WINAPI * CHOOSEPIXELFORMAT_T) (HDC,CONST PIXELFORMATDESCRIPTOR*);
typedef int (WINAPI * DESCRIBEPIXELFORMAT_T) (HDC,int,UINT,LPPIXELFORMATDESCRIPTOR);
typedef int (WINAPI * GETPIXELFORMAT_T) (HDC);
typedef BOOL (WINAPI * SETPIXELFORMAT_T) (HDC,int,const PIXELFORMATDESCRIPTOR*);
typedef BOOL (WINAPI * SWAPBUFFERS_T) (HDC);
typedef BOOL (WINAPI * GETDEVICEGAMMARAMP_T) (HDC,PVOID);
typedef BOOL (WINAPI * SETDEVICEGAMMARAMP_T) (HDC,PVOID);
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll function pointer typedefs // winmm.dll function pointer typedefs
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT);
@ -179,25 +91,6 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
#endif // _GLFW_NO_DLOAD_WINMM #endif // _GLFW_NO_DLOAD_WINMM
// gdi32.dll shortcuts
#ifndef _GLFW_NO_DLOAD_GDI32
#define _glfw_ChoosePixelFormat _glfwLibrary.Win32.gdi.ChoosePixelFormat
#define _glfw_DescribePixelFormat _glfwLibrary.Win32.gdi.DescribePixelFormat
#define _glfw_GetPixelFormat _glfwLibrary.Win32.gdi.GetPixelFormat
#define _glfw_SetPixelFormat _glfwLibrary.Win32.gdi.SetPixelFormat
#define _glfw_SwapBuffers _glfwLibrary.Win32.gdi.SwapBuffers
#define _glfw_GetDeviceGammaRamp _glfwLibrary.Win32.gdi.GetDeviceGammaRamp
#define _glfw_SetDeviceGammaRamp _glfwLibrary.Win32.gdi.SetDeviceGammaRamp
#else
#define _glfw_ChoosePixelFormat ChoosePixelFormat
#define _glfw_DescribePixelFormat DescribePixelFormat
#define _glfw_GetPixelFormat GetPixelFormat
#define _glfw_SetPixelFormat SetPixelFormat
#define _glfw_SwapBuffers SwapBuffers
#define _glfw_GetDeviceGammaRamp GetDeviceGammaRamp
#define _glfw_SetDeviceGammaRamp SetDeviceGammaRamp
#endif // _GLFW_NO_DLOAD_GDI32
// winmm.dll shortcuts // winmm.dll shortcuts
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
#define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps #define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps
@ -302,20 +195,6 @@ typedef struct _GLFWlibraryWin32
__int64 t0_64; __int64 t0_64;
} timer; } timer;
#ifndef _GLFW_NO_DLOAD_GDI32
// gdi32.dll
struct {
HINSTANCE instance;
CHOOSEPIXELFORMAT_T ChoosePixelFormat;
DESCRIBEPIXELFORMAT_T DescribePixelFormat;
GETPIXELFORMAT_T GetPixelFormat;
SETPIXELFORMAT_T SetPixelFormat;
SWAPBUFFERS_T SwapBuffers;
GETDEVICEGAMMARAMP_T GetDeviceGammaRamp;
SETDEVICEGAMMARAMP_T SetDeviceGammaRamp;
} gdi;
#endif // _GLFW_NO_DLOAD_GDI32
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
// winmm.dll // winmm.dll
struct { struct {

View File

@ -159,10 +159,10 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
count = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB); count = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB);
else else
{ {
count = _glfw_DescribePixelFormat(window->WGL.DC, count = DescribePixelFormat(window->WGL.DC,
1, 1,
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
NULL); NULL);
} }
if (!count) if (!count)
@ -243,10 +243,10 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
{ {
// Get pixel format attributes through old-fashioned PFDs // Get pixel format attributes through old-fashioned PFDs
if (!_glfw_DescribePixelFormat(window->WGL.DC, if (!DescribePixelFormat(window->WGL.DC,
i, i,
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
&pfd)) &pfd))
{ {
continue; continue;
} }
@ -311,14 +311,14 @@ static GLboolean createContext(_GLFWwindow* window,
if (wndconfig->share) if (wndconfig->share)
share = wndconfig->share->WGL.context; share = wndconfig->share->WGL.context;
if (!_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd)) if (!DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd))
{ {
_glfwSetError(GLFW_OPENGL_UNAVAILABLE, _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
"Win32/WGL: Failed to retrieve PFD for selected pixel format"); "Win32/WGL: Failed to retrieve PFD for selected pixel format");
return GL_FALSE; return GL_FALSE;
} }
if (!_glfw_SetPixelFormat(window->WGL.DC, pixelFormat, &pfd)) if (!SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
{ {
_glfwSetError(GLFW_OPENGL_UNAVAILABLE, _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
"Win32/WGL: Failed to set selected pixel format"); "Win32/WGL: Failed to set selected pixel format");
@ -1673,7 +1673,7 @@ void _glfwPlatformRefreshWindowParams(void)
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwLibrary.currentWindow;
// Obtain a detailed description of current pixel format // Obtain a detailed description of current pixel format
pixelFormat = _glfw_GetPixelFormat(window->WGL.DC); pixelFormat = GetPixelFormat(window->WGL.DC);
if (window->WGL.ARB_pixel_format) if (window->WGL.ARB_pixel_format)
{ {
@ -1727,8 +1727,8 @@ void _glfwPlatformRefreshWindowParams(void)
} }
else else
{ {
_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat, DescribePixelFormat(window->WGL.DC, pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &pfd); sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Is current OpenGL context accelerated? // Is current OpenGL context accelerated?
window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||

View File

@ -42,7 +42,7 @@
// Finds the video mode closest in size to the specified desired size // Finds the video mode closest in size to the specified desired size
//======================================================================== //========================================================================
int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate) int _glfwGetClosestVideoMode(int* width, int* height, int* rate)
{ {
int i, match, bestmatch; int i, match, bestmatch;
@ -55,8 +55,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
XRRScreenConfiguration* sc; XRRScreenConfiguration* sc;
XRRScreenSize* sizelist; XRRScreenSize* sizelist;
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
RootWindow(_glfwLibrary.X11.display, screen));
sizelist = XRRConfigSizes(sc, &sizecount); sizelist = XRRConfigSizes(sc, &sizecount);
@ -116,7 +115,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
int bestmode, modecount; int bestmode, modecount;
// Get a list of all available display modes // Get a list of all available display modes
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
&modecount, &modelist); &modecount, &modelist);
// Find the best matching mode // Find the best matching mode
@ -150,8 +150,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
} }
// Default: Simply use the screen resolution // Default: Simply use the screen resolution
*width = DisplayWidth(_glfwLibrary.X11.display, screen); *width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
*height = DisplayHeight(_glfwLibrary.X11.display, screen); *height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
return 0; return 0;
} }
@ -161,7 +161,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
// Change the current video mode // Change the current video mode
//======================================================================== //========================================================================
void _glfwSetVideoModeMODE(int screen, int mode, int rate) void _glfwSetVideoModeMODE(int mode, int rate)
{ {
if (_glfwLibrary.X11.RandR.available) if (_glfwLibrary.X11.RandR.available)
{ {
@ -169,15 +169,17 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
XRRScreenConfiguration* sc; XRRScreenConfiguration* sc;
Window root; Window root;
root = RootWindow(_glfwLibrary.X11.display, screen); root = _glfwLibrary.X11.root;
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root); sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root);
// Remember old size and flag that we have changed the mode // Remember old size and flag that we have changed the mode
if (!_glfwLibrary.X11.FS.modeChanged) if (!_glfwLibrary.X11.FS.modeChanged)
{ {
_glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation); _glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation);
_glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display, screen); _glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display,
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display, screen); _glfwLibrary.X11.screen);
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen);
_glfwLibrary.X11.FS.modeChanged = GL_TRUE; _glfwLibrary.X11.FS.modeChanged = GL_TRUE;
} }
@ -214,21 +216,32 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
int modecount; int modecount;
// Get a list of all available display modes // Get a list of all available display modes
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
&modecount, &modelist); &modecount, &modelist);
// Unlock mode switch if necessary // Unlock mode switch if necessary
if (_glfwLibrary.X11.FS.modeChanged) if (_glfwLibrary.X11.FS.modeChanged)
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 0); {
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
0);
}
// Change the video mode to the desired mode // Change the video mode to the desired mode
XF86VidModeSwitchToMode(_glfwLibrary.X11.display, screen, modelist[mode]); XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
modelist[mode]);
// Set viewport to upper left corner (where our window will be) // Set viewport to upper left corner (where our window will be)
XF86VidModeSetViewPort(_glfwLibrary.X11.display, screen, 0, 0); XF86VidModeSetViewPort(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
0, 0);
// Lock mode switch // Lock mode switch
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 1); XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
1);
// Remember old mode and flag that we have changed the mode // Remember old mode and flag that we have changed the mode
if (!_glfwLibrary.X11.FS.modeChanged) if (!_glfwLibrary.X11.FS.modeChanged)
@ -247,15 +260,15 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
// Change the current video mode // Change the current video mode
//======================================================================== //========================================================================
void _glfwSetVideoMode(int screen, int* width, int* height, int* rate) void _glfwSetVideoMode(int* width, int* height, int* rate)
{ {
int bestmode; int bestmode;
// Find a best match mode // Find a best match mode
bestmode = _glfwGetClosestVideoMode(screen, width, height, rate); bestmode = _glfwGetClosestVideoMode(width, height, rate);
// Change mode // Change mode
_glfwSetVideoModeMODE(screen, bestmode, *rate); _glfwSetVideoModeMODE(bestmode, *rate);
} }
@ -263,7 +276,7 @@ void _glfwSetVideoMode(int screen, int* width, int* height, int* rate)
// Restore the previously saved (original) video mode // Restore the previously saved (original) video mode
//======================================================================== //========================================================================
void _glfwRestoreVideoMode(int screen) void _glfwRestoreVideoMode(void)
{ {
if (_glfwLibrary.X11.FS.modeChanged) if (_glfwLibrary.X11.FS.modeChanged)
{ {
@ -292,11 +305,13 @@ void _glfwRestoreVideoMode(int screen)
{ {
#if defined(_GLFW_HAS_XF86VIDMODE) #if defined(_GLFW_HAS_XF86VIDMODE)
// Unlock mode switch // Unlock mode switch
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 0); XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
0);
// Change the video mode back to the old mode // Change the video mode back to the old mode
XF86VidModeSwitchToMode(_glfwLibrary.X11.display, XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
screen, _glfwLibrary.X11.screen,
&_glfwLibrary.X11.FS.oldMode); &_glfwLibrary.X11.FS.oldMode);
#endif /*_GLFW_HAS_XF86VIDMODE*/ #endif /*_GLFW_HAS_XF86VIDMODE*/
} }
@ -323,7 +338,7 @@ struct _glfwResolution
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
{ {
int count, k, l, r, g, b, rgba, gl; int count, k, l, r, g, b, rgba, gl;
int depth, screen = DefaultScreen(_glfwLibrary.X11.display); int depth;
XVisualInfo* vislist; XVisualInfo* vislist;
XVisualInfo dummy; XVisualInfo dummy;
int viscount, rgbcount, rescount; int viscount, rgbcount, rescount;
@ -407,7 +422,9 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
XF86VidModeModeInfo** modelist; XF86VidModeModeInfo** modelist;
int modecount, width, height; int modecount, width, height;
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist); XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
&modecount, &modelist);
resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount); resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount);
@ -440,8 +457,10 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
rescount = 1; rescount = 1;
resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount); resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount);
resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, screen); resarray[0].width = DisplayWidth(_glfwLibrary.X11.display,
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen); _glfwLibrary.X11.screen);
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen);
} }
// Build permutations of colors and resolutions // Build permutations of colors and resolutions

View File

@ -33,6 +33,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
//======================================================================== //========================================================================
@ -52,7 +53,6 @@ static void initLibraries(void)
NULL NULL
}; };
_glfwLibrary.X11.libGL = NULL;
for (i = 0; libGL_names[i] != NULL; i++) for (i = 0; libGL_names[i] != NULL; i++)
{ {
_glfwLibrary.X11.libGL = dlopen(libGL_names[i], RTLD_LAZY | RTLD_GLOBAL); _glfwLibrary.X11.libGL = dlopen(libGL_names[i], RTLD_LAZY | RTLD_GLOBAL);
@ -261,10 +261,8 @@ static void updateKeyCodeLUT(void)
int keyCode; int keyCode;
// Clear the LUT // Clear the LUT
for (keyCode = 0; keyCode < 256; ++keyCode) for (keyCode = 0; keyCode < 256; keyCode++)
{
_glfwLibrary.X11.keyCodeLUT[keyCode] = -1; _glfwLibrary.X11.keyCodeLUT[keyCode] = -1;
}
#if defined(_GLFW_HAS_XKB) #if defined(_GLFW_HAS_XKB)
// If the Xkb extension is available, use it to determine physical key // If the Xkb extension is available, use it to determine physical key
@ -272,7 +270,7 @@ static void updateKeyCodeLUT(void)
if (_glfwLibrary.X11.Xkb.available) if (_glfwLibrary.X11.Xkb.available)
{ {
int i, keyCodeGLFW; int i, keyCodeGLFW;
char name[XkbKeyNameLength+1]; char name[XkbKeyNameLength + 1];
XkbDescPtr descr; XkbDescPtr descr;
// Get keyboard description // Get keyboard description
@ -284,10 +282,9 @@ static void updateKeyCodeLUT(void)
for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode) for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode)
{ {
// Get the key name // Get the key name
for (i = 0; i < XkbKeyNameLength; ++i) for (i = 0; i < XkbKeyNameLength; i++)
{
name[i] = descr->names->keys[keyCode].name[i]; name[i] = descr->names->keys[keyCode].name[i];
}
name[XkbKeyNameLength] = 0; name[XkbKeyNameLength] = 0;
// Map the key name to a GLFW key code. Note: We only map printable // Map the key name to a GLFW key code. Note: We only map printable
@ -346,9 +343,7 @@ static void updateKeyCodeLUT(void)
// Update the key code LUT // Update the key code LUT
if ((keyCode >= 0) && (keyCode < 256)) if ((keyCode >= 0) && (keyCode < 256))
{
_glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW; _glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW;
}
} }
// Free the keyboard description // Free the keyboard description
@ -358,7 +353,7 @@ static void updateKeyCodeLUT(void)
// Translate the un-translated key codes using traditional X11 KeySym // Translate the un-translated key codes using traditional X11 KeySym
// lookups // lookups
for (keyCode = 0; keyCode < 256; ++keyCode) for (keyCode = 0; keyCode < 256; keyCode++)
{ {
if (_glfwLibrary.X11.keyCodeLUT[keyCode] < 0) if (_glfwLibrary.X11.keyCodeLUT[keyCode] < 0)
{ {
@ -369,6 +364,152 @@ static void updateKeyCodeLUT(void)
} }
//========================================================================
// Retrieve a single window property of the specified type
// Inspired by fghGetWindowProperty from freeglut
//========================================================================
static unsigned long getWindowProperty(Window window,
Atom property,
Atom type,
unsigned char** value)
{
Atom actualType;
int actualFormat;
unsigned long itemCount, bytesAfter;
XGetWindowProperty(_glfwLibrary.X11.display,
window,
property,
0,
LONG_MAX,
False,
type,
&actualType,
&actualFormat,
&itemCount,
&bytesAfter,
value);
if (actualType != type)
return 0;
return itemCount;
}
//========================================================================
// Check whether the specified atom is supported
//========================================================================
static Atom getSupportedAtom(Atom* supportedAtoms,
unsigned long atomCount,
const char* atomName)
{
Atom atom = XInternAtom(_glfwLibrary.X11.display, atomName, True);
if (atom != None)
{
unsigned long i;
for (i = 0; i < atomCount; i++)
{
if (supportedAtoms[i] == atom)
return atom;
}
}
return None;
}
//========================================================================
// Check whether the running window manager is EWMH-compliant
//========================================================================
static void initEWMH(void)
{
Window* windowFromRoot = NULL;
Window* windowFromChild = NULL;
// First we need a couple of atoms, which should already be there
Atom supportingWmCheck =
XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTING_WM_CHECK", True);
Atom wmSupported =
XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTED", True);
if (supportingWmCheck == None || wmSupported == None)
return;
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
if (getWindowProperty(_glfwLibrary.X11.root,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromRoot) != 1)
{
XFree(windowFromRoot);
return;
}
// It should be the ID of a child window (of the root)
// Then we look for the same property on the child window
if (getWindowProperty(*windowFromRoot,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromChild) != 1)
{
XFree(windowFromRoot);
XFree(windowFromChild);
return;
}
// It should be the ID of that same child window
if (*windowFromRoot != *windowFromChild)
{
XFree(windowFromRoot);
XFree(windowFromChild);
return;
}
XFree(windowFromRoot);
XFree(windowFromChild);
// We are now fairly sure that an EWMH-compliant window manager is running
Atom* supportedAtoms;
unsigned long atomCount;
// Now we need to check the _NET_SUPPORTED property of the root window
// It should be a list of supported WM protocol and state atoms
atomCount = getWindowProperty(_glfwLibrary.X11.root,
wmSupported,
XA_ATOM,
(unsigned char**) &supportedAtoms);
// See which of the atoms we support that are supported by the WM
_glfwLibrary.X11.wmState =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
_glfwLibrary.X11.wmStateFullscreen =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
_glfwLibrary.X11.wmName =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
_glfwLibrary.X11.wmIconName =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME");
_glfwLibrary.X11.wmPing =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");
_glfwLibrary.X11.wmActiveWindow =
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
XFree(supportedAtoms);
_glfwLibrary.X11.hasEWMH = GL_TRUE;
}
//======================================================================== //========================================================================
// Initialize X11 display and look for supported X11 extensions // Initialize X11 display and look for supported X11 extensions
//======================================================================== //========================================================================
@ -592,6 +733,8 @@ int _glfwPlatformInit(void)
initGammaRamp(); initGammaRamp();
initEWMH();
_glfwLibrary.X11.cursor = createNULLCursor(); _glfwLibrary.X11.cursor = createNULLCursor();
// Try to load libGL.so if necessary // Try to load libGL.so if necessary

View File

@ -138,16 +138,8 @@ typedef struct _GLFWwindowX11
// Platform specific window resources // Platform specific window resources
Colormap colormap; // Window colormap Colormap colormap; // Window colormap
Window handle; // Window handle Window handle; // Window handle
Atom wmDeleteWindow; // WM_DELETE_WINDOW atom
Atom wmName; // _NET_WM_NAME atom
Atom wmIconName; // _NET_WM_ICON_NAME atom
Atom wmPing; // _NET_WM_PING atom
Atom wmState; // _NET_WM_STATE atom
Atom wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom
Atom wmActiveWindow; // _NET_ACTIVE_WINDOW atom
// Various platform specific internal variables // Various platform specific internal variables
GLboolean hasEWMH; // True if window manager supports EWMH
GLboolean overrideRedirect; // True if window is OverrideRedirect GLboolean overrideRedirect; // True if window is OverrideRedirect
GLboolean keyboardGrabbed; // True if keyboard is currently grabbed GLboolean keyboardGrabbed; // True if keyboard is currently grabbed
GLboolean cursorGrabbed; // True if cursor is currently grabbed GLboolean cursorGrabbed; // True if cursor is currently grabbed
@ -168,6 +160,17 @@ typedef struct _GLFWlibraryX11
Window root; Window root;
Cursor cursor; // Invisible cursor for hidden cursor Cursor cursor; // Invisible cursor for hidden cursor
Atom wmDeleteWindow; // WM_DELETE_WINDOW atom
Atom wmName; // _NET_WM_NAME atom
Atom wmIconName; // _NET_WM_ICON_NAME atom
Atom wmPing; // _NET_WM_PING atom
Atom wmState; // _NET_WM_STATE atom
Atom wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom
Atom wmActiveWindow; // _NET_ACTIVE_WINDOW atom
// True if window manager supports EWMH
GLboolean hasEWMH;
// Server-side GLX version // Server-side GLX version
int glxMajor, glxMinor; int glxMajor, glxMinor;
@ -265,10 +268,10 @@ GLFWGLOBAL struct {
void _glfwInitTimer(void); void _glfwInitTimer(void);
// Fullscreen support // Fullscreen support
int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate); int _glfwGetClosestVideoMode(int* width, int* height, int* rate);
void _glfwSetVideoModeMODE(int screen, int mode, int rate); void _glfwSetVideoModeMODE(int mode, int rate);
void _glfwSetVideoMode(int screen, int* width, int* height, int* rate); void _glfwSetVideoMode(int* width, int* height, int* rate);
void _glfwRestoreVideoMode(int screen); void _glfwRestoreVideoMode(void);
// Joystick input // Joystick input
void _glfwInitJoysticks(void); void _glfwInitJoysticks(void);

View File

@ -30,7 +30,6 @@
#include "internal.h" #include "internal.h"
#include <limits.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -65,154 +64,6 @@ static Bool isMapNotify(Display* d, XEvent* e, char* arg)
} }
//========================================================================
// Retrieve a single window property of the specified type
// Inspired by fghGetWindowProperty from freeglut
//========================================================================
static unsigned long getWindowProperty(Window window,
Atom property,
Atom type,
unsigned char** value)
{
Atom actualType;
int actualFormat;
unsigned long itemCount, bytesAfter;
XGetWindowProperty(_glfwLibrary.X11.display,
window,
property,
0,
LONG_MAX,
False,
type,
&actualType,
&actualFormat,
&itemCount,
&bytesAfter,
value);
if (actualType != type)
return 0;
return itemCount;
}
//========================================================================
// Check whether the specified atom is supported
//========================================================================
static Atom getSupportedAtom(Atom* supportedAtoms,
unsigned long atomCount,
const char* atomName)
{
Atom atom = XInternAtom(_glfwLibrary.X11.display, atomName, True);
if (atom != None)
{
unsigned long i;
for (i = 0; i < atomCount; i++)
{
if (supportedAtoms[i] == atom)
return atom;
}
}
return None;
}
//========================================================================
// Check whether the running window manager is EWMH-compliant
//========================================================================
static GLboolean hasEWMH(_GLFWwindow* window)
{
Window* windowFromRoot = NULL;
Window* windowFromChild = NULL;
// Hey kids; let's see if the window manager supports EWMH!
// First we need a couple of atoms, which should already be there
Atom supportingWmCheck =
XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTING_WM_CHECK", True);
Atom wmSupported =
XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTED", True);
if (supportingWmCheck == None || wmSupported == None)
return GL_FALSE;
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
if (getWindowProperty(_glfwLibrary.X11.root,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromRoot) != 1)
{
XFree(windowFromRoot);
return GL_FALSE;
}
// It should be the ID of a child window (of the root)
// Then we look for the same property on the child window
if (getWindowProperty(*windowFromRoot,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromChild) != 1)
{
XFree(windowFromRoot);
XFree(windowFromChild);
return GL_FALSE;
}
// It should be the ID of that same child window
if (*windowFromRoot != *windowFromChild)
{
XFree(windowFromRoot);
XFree(windowFromChild);
return GL_FALSE;
}
XFree(windowFromRoot);
XFree(windowFromChild);
// We are now fairly sure that an EWMH-compliant window manager is running
Atom* supportedAtoms;
unsigned long atomCount;
// Now we need to check the _NET_SUPPORTED property of the root window
// It should be a list of supported WM protocol and state atoms
atomCount = getWindowProperty(_glfwLibrary.X11.root,
wmSupported,
XA_ATOM,
(unsigned char**) &supportedAtoms);
// See which of the atoms we support that are supported by the WM
window->X11.wmState =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
window->X11.wmStateFullscreen =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
window->X11.wmName =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
window->X11.wmIconName =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME");
window->X11.wmPing =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");
window->X11.wmActiveWindow =
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
XFree(supportedAtoms);
return GL_TRUE;
}
//======================================================================== //========================================================================
// Translates an X Window key to internal coding // Translates an X Window key to internal coding
//======================================================================== //========================================================================
@ -721,10 +572,7 @@ static GLboolean createWindow(_GLFWwindow* window,
} }
} }
// Check whether an EWMH-compliant window manager is running if (window->mode == GLFW_FULLSCREEN && !_glfwLibrary.X11.hasEWMH)
window->X11.hasEWMH = hasEWMH(window);
if (window->mode == GLFW_FULLSCREEN && !window->X11.hasEWMH)
{ {
// This is the butcher's way of removing window decorations // This is the butcher's way of removing window decorations
// Setting the override-redirect attribute on a window makes the window // Setting the override-redirect attribute on a window makes the window
@ -745,9 +593,9 @@ static GLboolean createWindow(_GLFWwindow* window,
} }
// Find or create the protocol atom for window close notifications // Find or create the protocol atom for window close notifications
window->X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display, _glfwLibrary.X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display,
"WM_DELETE_WINDOW", "WM_DELETE_WINDOW",
False); False);
// Declare the WM protocols we support // Declare the WM protocols we support
{ {
@ -756,14 +604,14 @@ static GLboolean createWindow(_GLFWwindow* window,
// The WM_DELETE_WINDOW ICCCM protocol // The WM_DELETE_WINDOW ICCCM protocol
// Basic window close notification protocol // Basic window close notification protocol
if (window->X11.wmDeleteWindow != None) if (_glfwLibrary.X11.wmDeleteWindow != None)
protocols[count++] = window->X11.wmDeleteWindow; protocols[count++] = _glfwLibrary.X11.wmDeleteWindow;
// The _NET_WM_PING EWMH protocol // The _NET_WM_PING EWMH protocol
// Tells the WM to ping our window and flag us as unresponsive if we // Tells the WM to ping our window and flag us as unresponsive if we
// don't reply within a few seconds // don't reply within a few seconds
if (window->X11.wmPing != None) if (_glfwLibrary.X11.wmPing != None)
protocols[count++] = window->X11.wmPing; protocols[count++] = _glfwLibrary.X11.wmPing;
if (count > 0) if (count > 0)
{ {
@ -908,15 +756,14 @@ static void enterFullscreenMode(_GLFWwindow* window)
_glfwLibrary.X11.saver.changed = GL_TRUE; _glfwLibrary.X11.saver.changed = GL_TRUE;
} }
_glfwSetVideoMode(_glfwLibrary.X11.screen, _glfwSetVideoMode(&window->width, &window->height,
&window->width, &window->height,
&window->refreshRate); &window->refreshRate);
if (window->X11.hasEWMH && if (_glfwLibrary.X11.hasEWMH &&
window->X11.wmState != None && _glfwLibrary.X11.wmState != None &&
window->X11.wmStateFullscreen != None) _glfwLibrary.X11.wmStateFullscreen != None)
{ {
if (window->X11.wmActiveWindow != None) if (_glfwLibrary.X11.wmActiveWindow != None)
{ {
// Ask the window manager to raise and focus the GLFW window // Ask the window manager to raise and focus the GLFW window
// Only focused windows with the _NET_WM_STATE_FULLSCREEN state end // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end
@ -928,7 +775,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
event.type = ClientMessage; event.type = ClientMessage;
event.xclient.window = window->X11.handle; event.xclient.window = window->X11.handle;
event.xclient.format = 32; // Data is 32-bit longs event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = window->X11.wmActiveWindow; event.xclient.message_type = _glfwLibrary.X11.wmActiveWindow;
event.xclient.data.l[0] = 1; // Sender is a normal application event.xclient.data.l[0] = 1; // Sender is a normal application
event.xclient.data.l[1] = 0; // We don't really know the timestamp event.xclient.data.l[1] = 0; // We don't really know the timestamp
@ -949,9 +796,9 @@ static void enterFullscreenMode(_GLFWwindow* window)
event.type = ClientMessage; event.type = ClientMessage;
event.xclient.window = window->X11.handle; event.xclient.window = window->X11.handle;
event.xclient.format = 32; // Data is 32-bit longs event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = window->X11.wmState; event.xclient.message_type = _glfwLibrary.X11.wmState;
event.xclient.data.l[0] = _NET_WM_STATE_ADD; event.xclient.data.l[0] = _NET_WM_STATE_ADD;
event.xclient.data.l[1] = window->X11.wmStateFullscreen; event.xclient.data.l[1] = _glfwLibrary.X11.wmStateFullscreen;
event.xclient.data.l[2] = 0; // No secondary property event.xclient.data.l[2] = 0; // No secondary property
event.xclient.data.l[3] = 1; // Sender is a normal application event.xclient.data.l[3] = 1; // Sender is a normal application
@ -989,7 +836,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
static void leaveFullscreenMode(_GLFWwindow* window) static void leaveFullscreenMode(_GLFWwindow* window)
{ {
_glfwRestoreVideoMode(_glfwLibrary.X11.screen); _glfwRestoreVideoMode();
// Did we change the screen saver setting? // Did we change the screen saver setting?
if (_glfwLibrary.X11.saver.changed) if (_glfwLibrary.X11.saver.changed)
@ -1004,9 +851,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
_glfwLibrary.X11.saver.changed = GL_FALSE; _glfwLibrary.X11.saver.changed = GL_FALSE;
} }
if (window->X11.hasEWMH && if (_glfwLibrary.X11.hasEWMH &&
window->X11.wmState != None && _glfwLibrary.X11.wmState != None &&
window->X11.wmStateFullscreen != None) _glfwLibrary.X11.wmStateFullscreen != None)
{ {
// Ask the window manager to make the GLFW window a normal window // Ask the window manager to make the GLFW window a normal window
// Normal windows usually have frames and other decorations // Normal windows usually have frames and other decorations
@ -1017,9 +864,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
event.type = ClientMessage; event.type = ClientMessage;
event.xclient.window = window->X11.handle; event.xclient.window = window->X11.handle;
event.xclient.format = 32; // Data is 32-bit longs event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = window->X11.wmState; event.xclient.message_type = _glfwLibrary.X11.wmState;
event.xclient.data.l[0] = _NET_WM_STATE_REMOVE; event.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
event.xclient.data.l[1] = window->X11.wmStateFullscreen; event.xclient.data.l[1] = _glfwLibrary.X11.wmStateFullscreen;
event.xclient.data.l[2] = 0; // No secondary property event.xclient.data.l[2] = 0; // No secondary property
event.xclient.data.l[3] = 1; // Sender is a normal application event.xclient.data.l[3] = 1; // Sender is a normal application
@ -1292,15 +1139,15 @@ static void processSingleEvent(void)
return; return;
} }
if ((Atom) event.xclient.data.l[0] == window->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 window manager was asked to close the window, for example by
// the user pressing a 'close' window decoration button // the user pressing a 'close' window decoration button
window->closeRequested = GL_TRUE; window->closeRequested = GL_TRUE;
} }
else if (window->X11.wmPing != None && else if (_glfwLibrary.X11.wmPing != None &&
(Atom) event.xclient.data.l[0] == window->X11.wmPing) (Atom) event.xclient.data.l[0] == _glfwLibrary.X11.wmPing)
{ {
// The window manager is pinging us to make sure we are still // The window manager is pinging us to make sure we are still
// responding to events // responding to events
@ -1480,11 +1327,18 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
fbconfigs = getFBConfigs(window, &fbcount); fbconfigs = getFBConfigs(window, &fbcount);
if (!fbconfigs) if (!fbconfigs)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"X11/GLX: No usable GLXFBConfigs found");
return GL_FALSE; return GL_FALSE;
}
result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!result) if (!result)
{ {
_glfwSetError(GLFW_PLATFORM_ERROR,
"X11/GLX: No GLXFBConfig matched the criteria");
free(fbconfigs); free(fbconfigs);
return GL_FALSE; return GL_FALSE;
} }
@ -1603,18 +1457,18 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
NULL, NULL, NULL); NULL, NULL, NULL);
#endif #endif
if (window->X11.wmName != None) if (_glfwLibrary.X11.wmName != None)
{ {
XChangeProperty(_glfwLibrary.X11.display, window->X11.handle, XChangeProperty(_glfwLibrary.X11.display, window->X11.handle,
window->X11.wmName, type, 8, _glfwLibrary.X11.wmName, type, 8,
PropModeReplace, PropModeReplace,
(unsigned char*) title, strlen(title)); (unsigned char*) title, strlen(title));
} }
if (window->X11.wmIconName != None) if (_glfwLibrary.X11.wmIconName != None)
{ {
XChangeProperty(_glfwLibrary.X11.display, window->X11.handle, XChangeProperty(_glfwLibrary.X11.display, window->X11.handle,
window->X11.wmIconName, type, 8, _glfwLibrary.X11.wmIconName, type, 8,
PropModeReplace, PropModeReplace,
(unsigned char*) title, strlen(title)); (unsigned char*) title, strlen(title));
} }
@ -1635,8 +1489,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
if (window->mode == GLFW_FULLSCREEN) if (window->mode == GLFW_FULLSCREEN)
{ {
// Get the closest matching video mode for the specified window size // Get the closest matching video mode for the specified window size
mode = _glfwGetClosestVideoMode(_glfwLibrary.X11.screen, mode = _glfwGetClosestVideoMode(&width, &height, &rate);
&width, &height, &rate);
} }
if (!window->resizable) if (!window->resizable)
@ -1663,7 +1516,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
if (window->mode == GLFW_FULLSCREEN) if (window->mode == GLFW_FULLSCREEN)
{ {
// Change video mode, keeping current refresh rate // Change video mode, keeping current refresh rate
_glfwSetVideoModeMODE(_glfwLibrary.X11.screen, mode, window->refreshRate); _glfwSetVideoModeMODE(mode, window->refreshRate);
} }
// Set window size (if not already changed) // Set window size (if not already changed)