mirror of
https://github.com/glfw/glfw.git
synced 2024-11-11 13:03:52 +00:00
Merge branch 'master' into clipboard
This commit is contained in:
commit
952c6b7e82
@ -54,7 +54,6 @@ if (_GLFW_WIN32_WGL)
|
||||
list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
|
||||
list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY})
|
||||
|
||||
set(_GLFW_NO_DLOAD_GDI32 ${BUILD_SHARED_LIBS})
|
||||
set(_GLFW_NO_DLOAD_WINMM ${BUILD_SHARED_LIBS})
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
|
@ -311,6 +311,13 @@ static void pollJoystickEvents(void)
|
||||
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j);
|
||||
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);
|
||||
|
||||
case GLFW_BUTTONS:
|
||||
return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons);
|
||||
return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons) + ((int) CFArrayGetCount(_glfwJoysticks[joy].hats)) * 4;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -565,7 +572,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
|
||||
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
int numbuttons)
|
||||
{
|
||||
int i;
|
||||
int button;
|
||||
|
||||
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
|
||||
return 0;
|
||||
@ -578,17 +585,31 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
return 0;
|
||||
}
|
||||
|
||||
numbuttons = numbuttons < joystick.numButtons ? numbuttons : joystick.numButtons;
|
||||
|
||||
// Update joystick state
|
||||
pollJoystickEvents();
|
||||
|
||||
for (i = 0; i < numbuttons; i++)
|
||||
for (button = 0; button < numbuttons && button < joystick.numButtons; button++)
|
||||
{
|
||||
_glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, i);
|
||||
buttons[i] = button->value ? GLFW_PRESS : GLFW_RELEASE;
|
||||
_glfwJoystickElement* element = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, button);
|
||||
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;
|
||||
}
|
||||
|
@ -45,8 +45,6 @@
|
||||
// Define this to 1 if building as a shared library / dynamic library / DLL
|
||||
#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
|
||||
#cmakedefine _GLFW_NO_DLOAD_WINMM 1
|
||||
|
||||
|
@ -277,6 +277,8 @@ const char* _glfwPlatformGetVersionString(void);
|
||||
// Input
|
||||
void _glfwPlatformEnableSystemKeys(_GLFWwindow* window);
|
||||
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
|
||||
void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||
|
||||
// Fullscreen
|
||||
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 _glfwPlatformIconifyWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||
|
||||
// Event management
|
||||
void _glfwPlatformPollEvents(void);
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
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)
|
||||
{
|
||||
_glfw_SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
|
||||
SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
|
||||
}
|
||||
|
||||
|
@ -44,40 +44,6 @@
|
||||
|
||||
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
|
||||
// winmm.dll (for joystick and timer support)
|
||||
|
||||
@ -113,14 +79,6 @@ static GLboolean initLibraries(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
|
||||
if (_glfwLibrary.Win32.winmm.instance != NULL)
|
||||
{
|
||||
@ -274,9 +232,6 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
" DLL"
|
||||
#endif
|
||||
#if !defined(_GLFW_NO_DLOAD_GDI32)
|
||||
" load(gdi32)"
|
||||
#endif
|
||||
#if !defined(_GLFW_NO_DLOAD_WINMM)
|
||||
" load(winmm)"
|
||||
#endif
|
||||
|
@ -91,6 +91,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
|
||||
// Get joystick capabilities
|
||||
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
|
||||
|
||||
const int hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case GLFW_AXES:
|
||||
@ -98,8 +100,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
|
||||
return jc.wNumAxes;
|
||||
|
||||
case GLFW_BUTTONS:
|
||||
// Return number of joystick axes
|
||||
return jc.wNumButtons;
|
||||
// Return number of joystick buttons
|
||||
return jc.wNumButtons + hats * 4;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -174,7 +176,7 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
|
||||
// Get joystick state
|
||||
ji.dwSize = sizeof(JOYINFOEX);
|
||||
ji.dwFlags = JOY_RETURNBUTTONS;
|
||||
ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV;
|
||||
_glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ void _glfwPlatformSwapBuffers(void)
|
||||
{
|
||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||
|
||||
_glfw_SwapBuffers(window->WGL.DC);
|
||||
SwapBuffers(window->WGL.DC);
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,8 +33,13 @@
|
||||
|
||||
|
||||
// We don't need all the fancy stuff
|
||||
#define NOMINMAX
|
||||
#define VC_EXTRALEAN
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@ -52,7 +57,7 @@
|
||||
|
||||
// GLFW requires Windows XP
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0501
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
@ -68,108 +73,15 @@
|
||||
// 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
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#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()
|
||||
//========================================================================
|
||||
|
||||
// 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
|
||||
#ifndef _GLFW_NO_DLOAD_WINMM
|
||||
typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT);
|
||||
@ -179,25 +91,6 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
|
||||
#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
|
||||
#ifndef _GLFW_NO_DLOAD_WINMM
|
||||
#define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps
|
||||
@ -302,20 +195,6 @@ typedef struct _GLFWlibraryWin32
|
||||
__int64 t0_64;
|
||||
} 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
|
||||
// winmm.dll
|
||||
struct {
|
||||
|
@ -159,10 +159,10 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
|
||||
count = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB);
|
||||
else
|
||||
{
|
||||
count = _glfw_DescribePixelFormat(window->WGL.DC,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
count = DescribePixelFormat(window->WGL.DC,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!count)
|
||||
@ -243,10 +243,10 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
|
||||
{
|
||||
// Get pixel format attributes through old-fashioned PFDs
|
||||
|
||||
if (!_glfw_DescribePixelFormat(window->WGL.DC,
|
||||
i,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
&pfd))
|
||||
if (!DescribePixelFormat(window->WGL.DC,
|
||||
i,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
&pfd))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -311,14 +311,14 @@ static GLboolean createContext(_GLFWwindow* window,
|
||||
if (wndconfig->share)
|
||||
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,
|
||||
"Win32/WGL: Failed to retrieve PFD for selected pixel format");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfw_SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
|
||||
if (!SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
|
||||
{
|
||||
_glfwSetError(GLFW_OPENGL_UNAVAILABLE,
|
||||
"Win32/WGL: Failed to set selected pixel format");
|
||||
@ -1673,7 +1673,7 @@ void _glfwPlatformRefreshWindowParams(void)
|
||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||
|
||||
// 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)
|
||||
{
|
||||
@ -1727,8 +1727,8 @@ void _glfwPlatformRefreshWindowParams(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat,
|
||||
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
DescribePixelFormat(window->WGL.DC, pixelFormat,
|
||||
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
// Is current OpenGL context accelerated?
|
||||
window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
|
||||
|
@ -42,7 +42,7 @@
|
||||
// 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;
|
||||
|
||||
@ -55,8 +55,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
|
||||
XRRScreenConfiguration* sc;
|
||||
XRRScreenSize* sizelist;
|
||||
|
||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display,
|
||||
RootWindow(_glfwLibrary.X11.display, screen));
|
||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
|
||||
|
||||
sizelist = XRRConfigSizes(sc, &sizecount);
|
||||
|
||||
@ -116,7 +115,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
|
||||
int bestmode, modecount;
|
||||
|
||||
// Get a list of all available display modes
|
||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen,
|
||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen,
|
||||
&modecount, &modelist);
|
||||
|
||||
// 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
|
||||
*width = DisplayWidth(_glfwLibrary.X11.display, screen);
|
||||
*height = DisplayHeight(_glfwLibrary.X11.display, screen);
|
||||
*width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
|
||||
*height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -161,7 +161,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
|
||||
// Change the current video mode
|
||||
//========================================================================
|
||||
|
||||
void _glfwSetVideoModeMODE(int screen, int mode, int rate)
|
||||
void _glfwSetVideoModeMODE(int mode, int rate)
|
||||
{
|
||||
if (_glfwLibrary.X11.RandR.available)
|
||||
{
|
||||
@ -169,15 +169,17 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
|
||||
XRRScreenConfiguration* sc;
|
||||
Window root;
|
||||
|
||||
root = RootWindow(_glfwLibrary.X11.display, screen);
|
||||
root = _glfwLibrary.X11.root;
|
||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root);
|
||||
|
||||
// Remember old size and flag that we have changed the mode
|
||||
if (!_glfwLibrary.X11.FS.modeChanged)
|
||||
{
|
||||
_glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation);
|
||||
_glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display, screen);
|
||||
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display, screen);
|
||||
_glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen);
|
||||
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen);
|
||||
|
||||
_glfwLibrary.X11.FS.modeChanged = GL_TRUE;
|
||||
}
|
||||
@ -214,21 +216,32 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
|
||||
int modecount;
|
||||
|
||||
// Get a list of all available display modes
|
||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen,
|
||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen,
|
||||
&modecount, &modelist);
|
||||
|
||||
// Unlock mode switch if necessary
|
||||
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
|
||||
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)
|
||||
XF86VidModeSetViewPort(_glfwLibrary.X11.display, screen, 0, 0);
|
||||
XF86VidModeSetViewPort(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen,
|
||||
0, 0);
|
||||
|
||||
// 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
|
||||
if (!_glfwLibrary.X11.FS.modeChanged)
|
||||
@ -247,15 +260,15 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
|
||||
// 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;
|
||||
|
||||
// Find a best match mode
|
||||
bestmode = _glfwGetClosestVideoMode(screen, width, height, rate);
|
||||
bestmode = _glfwGetClosestVideoMode(width, height, rate);
|
||||
|
||||
// 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
|
||||
//========================================================================
|
||||
|
||||
void _glfwRestoreVideoMode(int screen)
|
||||
void _glfwRestoreVideoMode(void)
|
||||
{
|
||||
if (_glfwLibrary.X11.FS.modeChanged)
|
||||
{
|
||||
@ -292,11 +305,13 @@ void _glfwRestoreVideoMode(int screen)
|
||||
{
|
||||
#if defined(_GLFW_HAS_XF86VIDMODE)
|
||||
// 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
|
||||
XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
|
||||
screen,
|
||||
_glfwLibrary.X11.screen,
|
||||
&_glfwLibrary.X11.FS.oldMode);
|
||||
#endif /*_GLFW_HAS_XF86VIDMODE*/
|
||||
}
|
||||
@ -323,7 +338,7 @@ struct _glfwResolution
|
||||
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
||||
{
|
||||
int count, k, l, r, g, b, rgba, gl;
|
||||
int depth, screen = DefaultScreen(_glfwLibrary.X11.display);
|
||||
int depth;
|
||||
XVisualInfo* vislist;
|
||||
XVisualInfo dummy;
|
||||
int viscount, rgbcount, rescount;
|
||||
@ -407,7 +422,9 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
||||
XF86VidModeModeInfo** modelist;
|
||||
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);
|
||||
|
||||
@ -440,8 +457,10 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
||||
rescount = 1;
|
||||
resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount);
|
||||
|
||||
resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, screen);
|
||||
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen);
|
||||
resarray[0].width = DisplayWidth(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen);
|
||||
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display,
|
||||
_glfwLibrary.X11.screen);
|
||||
}
|
||||
|
||||
// Build permutations of colors and resolutions
|
||||
|
165
src/x11_init.c
165
src/x11_init.c
@ -33,6 +33,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//========================================================================
|
||||
@ -52,7 +53,6 @@ static void initLibraries(void)
|
||||
NULL
|
||||
};
|
||||
|
||||
_glfwLibrary.X11.libGL = NULL;
|
||||
for (i = 0; libGL_names[i] != NULL; i++)
|
||||
{
|
||||
_glfwLibrary.X11.libGL = dlopen(libGL_names[i], RTLD_LAZY | RTLD_GLOBAL);
|
||||
@ -261,10 +261,8 @@ static void updateKeyCodeLUT(void)
|
||||
int keyCode;
|
||||
|
||||
// Clear the LUT
|
||||
for (keyCode = 0; keyCode < 256; ++keyCode)
|
||||
{
|
||||
for (keyCode = 0; keyCode < 256; keyCode++)
|
||||
_glfwLibrary.X11.keyCodeLUT[keyCode] = -1;
|
||||
}
|
||||
|
||||
#if defined(_GLFW_HAS_XKB)
|
||||
// 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)
|
||||
{
|
||||
int i, keyCodeGLFW;
|
||||
char name[XkbKeyNameLength+1];
|
||||
char name[XkbKeyNameLength + 1];
|
||||
XkbDescPtr descr;
|
||||
|
||||
// Get keyboard description
|
||||
@ -284,10 +282,9 @@ static void updateKeyCodeLUT(void)
|
||||
for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode)
|
||||
{
|
||||
// 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[XkbKeyNameLength] = 0;
|
||||
|
||||
// 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
|
||||
if ((keyCode >= 0) && (keyCode < 256))
|
||||
{
|
||||
_glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the keyboard description
|
||||
@ -358,7 +353,7 @@ static void updateKeyCodeLUT(void)
|
||||
|
||||
// Translate the un-translated key codes using traditional X11 KeySym
|
||||
// lookups
|
||||
for (keyCode = 0; keyCode < 256; ++keyCode)
|
||||
for (keyCode = 0; keyCode < 256; keyCode++)
|
||||
{
|
||||
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
|
||||
//========================================================================
|
||||
@ -592,6 +733,8 @@ int _glfwPlatformInit(void)
|
||||
|
||||
initGammaRamp();
|
||||
|
||||
initEWMH();
|
||||
|
||||
_glfwLibrary.X11.cursor = createNULLCursor();
|
||||
|
||||
// Try to load libGL.so if necessary
|
||||
|
@ -138,16 +138,8 @@ typedef struct _GLFWwindowX11
|
||||
// Platform specific window resources
|
||||
Colormap colormap; // Window colormap
|
||||
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
|
||||
GLboolean hasEWMH; // True if window manager supports EWMH
|
||||
GLboolean overrideRedirect; // True if window is OverrideRedirect
|
||||
GLboolean keyboardGrabbed; // True if keyboard is currently grabbed
|
||||
GLboolean cursorGrabbed; // True if cursor is currently grabbed
|
||||
@ -168,6 +160,17 @@ typedef struct _GLFWlibraryX11
|
||||
Window root;
|
||||
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
|
||||
int glxMajor, glxMinor;
|
||||
|
||||
@ -265,10 +268,10 @@ GLFWGLOBAL struct {
|
||||
void _glfwInitTimer(void);
|
||||
|
||||
// Fullscreen support
|
||||
int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate);
|
||||
void _glfwSetVideoModeMODE(int screen, int mode, int rate);
|
||||
void _glfwSetVideoMode(int screen, int* width, int* height, int* rate);
|
||||
void _glfwRestoreVideoMode(int screen);
|
||||
int _glfwGetClosestVideoMode(int* width, int* height, int* rate);
|
||||
void _glfwSetVideoModeMODE(int mode, int rate);
|
||||
void _glfwSetVideoMode(int* width, int* height, int* rate);
|
||||
void _glfwRestoreVideoMode(void);
|
||||
|
||||
// Joystick input
|
||||
void _glfwInitJoysticks(void);
|
||||
|
223
src/x11_window.c
223
src/x11_window.c
@ -30,7 +30,6 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdio.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
|
||||
//========================================================================
|
||||
@ -721,10 +572,7 @@ static GLboolean createWindow(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether an EWMH-compliant window manager is running
|
||||
window->X11.hasEWMH = hasEWMH(window);
|
||||
|
||||
if (window->mode == GLFW_FULLSCREEN && !window->X11.hasEWMH)
|
||||
if (window->mode == GLFW_FULLSCREEN && !_glfwLibrary.X11.hasEWMH)
|
||||
{
|
||||
// This is the butcher's way of removing window decorations
|
||||
// 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
|
||||
window->X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display,
|
||||
"WM_DELETE_WINDOW",
|
||||
False);
|
||||
_glfwLibrary.X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display,
|
||||
"WM_DELETE_WINDOW",
|
||||
False);
|
||||
|
||||
// Declare the WM protocols we support
|
||||
{
|
||||
@ -756,14 +604,14 @@ static GLboolean createWindow(_GLFWwindow* window,
|
||||
|
||||
// The WM_DELETE_WINDOW ICCCM protocol
|
||||
// Basic window close notification protocol
|
||||
if (window->X11.wmDeleteWindow != None)
|
||||
protocols[count++] = window->X11.wmDeleteWindow;
|
||||
if (_glfwLibrary.X11.wmDeleteWindow != None)
|
||||
protocols[count++] = _glfwLibrary.X11.wmDeleteWindow;
|
||||
|
||||
// The _NET_WM_PING EWMH protocol
|
||||
// Tells the WM to ping our window and flag us as unresponsive if we
|
||||
// don't reply within a few seconds
|
||||
if (window->X11.wmPing != None)
|
||||
protocols[count++] = window->X11.wmPing;
|
||||
if (_glfwLibrary.X11.wmPing != None)
|
||||
protocols[count++] = _glfwLibrary.X11.wmPing;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
@ -908,15 +756,14 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
||||
_glfwLibrary.X11.saver.changed = GL_TRUE;
|
||||
}
|
||||
|
||||
_glfwSetVideoMode(_glfwLibrary.X11.screen,
|
||||
&window->width, &window->height,
|
||||
_glfwSetVideoMode(&window->width, &window->height,
|
||||
&window->refreshRate);
|
||||
|
||||
if (window->X11.hasEWMH &&
|
||||
window->X11.wmState != None &&
|
||||
window->X11.wmStateFullscreen != None)
|
||||
if (_glfwLibrary.X11.hasEWMH &&
|
||||
_glfwLibrary.X11.wmState != 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
|
||||
// Only focused windows with the _NET_WM_STATE_FULLSCREEN state end
|
||||
@ -928,7 +775,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->X11.handle;
|
||||
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[1] = 0; // We don't really know the timestamp
|
||||
|
||||
@ -949,9 +796,9 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->X11.handle;
|
||||
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[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[3] = 1; // Sender is a normal application
|
||||
|
||||
@ -989,7 +836,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
||||
|
||||
static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
{
|
||||
_glfwRestoreVideoMode(_glfwLibrary.X11.screen);
|
||||
_glfwRestoreVideoMode();
|
||||
|
||||
// Did we change the screen saver setting?
|
||||
if (_glfwLibrary.X11.saver.changed)
|
||||
@ -1004,9 +851,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
_glfwLibrary.X11.saver.changed = GL_FALSE;
|
||||
}
|
||||
|
||||
if (window->X11.hasEWMH &&
|
||||
window->X11.wmState != None &&
|
||||
window->X11.wmStateFullscreen != None)
|
||||
if (_glfwLibrary.X11.hasEWMH &&
|
||||
_glfwLibrary.X11.wmState != None &&
|
||||
_glfwLibrary.X11.wmStateFullscreen != None)
|
||||
{
|
||||
// Ask the window manager to make the GLFW window a normal window
|
||||
// Normal windows usually have frames and other decorations
|
||||
@ -1017,9 +864,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->X11.handle;
|
||||
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[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[3] = 1; // Sender is a normal application
|
||||
|
||||
@ -1292,15 +1139,15 @@ static void processSingleEvent(void)
|
||||
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 user pressing a 'close' window decoration button
|
||||
|
||||
window->closeRequested = GL_TRUE;
|
||||
}
|
||||
else if (window->X11.wmPing != None &&
|
||||
(Atom) event.xclient.data.l[0] == window->X11.wmPing)
|
||||
else if (_glfwLibrary.X11.wmPing != None &&
|
||||
(Atom) event.xclient.data.l[0] == _glfwLibrary.X11.wmPing)
|
||||
{
|
||||
// The window manager is pinging us to make sure we are still
|
||||
// responding to events
|
||||
@ -1480,11 +1327,18 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
|
||||
|
||||
fbconfigs = getFBConfigs(window, &fbcount);
|
||||
if (!fbconfigs)
|
||||
{
|
||||
_glfwSetError(GLFW_PLATFORM_ERROR,
|
||||
"X11/GLX: No usable GLXFBConfigs found");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
|
||||
if (!result)
|
||||
{
|
||||
_glfwSetError(GLFW_PLATFORM_ERROR,
|
||||
"X11/GLX: No GLXFBConfig matched the criteria");
|
||||
|
||||
free(fbconfigs);
|
||||
return GL_FALSE;
|
||||
}
|
||||
@ -1603,18 +1457,18 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
NULL, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (window->X11.wmName != None)
|
||||
if (_glfwLibrary.X11.wmName != None)
|
||||
{
|
||||
XChangeProperty(_glfwLibrary.X11.display, window->X11.handle,
|
||||
window->X11.wmName, type, 8,
|
||||
_glfwLibrary.X11.wmName, type, 8,
|
||||
PropModeReplace,
|
||||
(unsigned char*) title, strlen(title));
|
||||
}
|
||||
|
||||
if (window->X11.wmIconName != None)
|
||||
if (_glfwLibrary.X11.wmIconName != None)
|
||||
{
|
||||
XChangeProperty(_glfwLibrary.X11.display, window->X11.handle,
|
||||
window->X11.wmIconName, type, 8,
|
||||
_glfwLibrary.X11.wmIconName, type, 8,
|
||||
PropModeReplace,
|
||||
(unsigned char*) title, strlen(title));
|
||||
}
|
||||
@ -1635,8 +1489,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
if (window->mode == GLFW_FULLSCREEN)
|
||||
{
|
||||
// Get the closest matching video mode for the specified window size
|
||||
mode = _glfwGetClosestVideoMode(_glfwLibrary.X11.screen,
|
||||
&width, &height, &rate);
|
||||
mode = _glfwGetClosestVideoMode(&width, &height, &rate);
|
||||
}
|
||||
|
||||
if (!window->resizable)
|
||||
@ -1663,7 +1516,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
if (window->mode == GLFW_FULLSCREEN)
|
||||
{
|
||||
// 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)
|
||||
|
Loading…
Reference in New Issue
Block a user