mirror of
https://github.com/glfw/glfw.git
synced 2025-10-04 21:56:36 +00:00
Merge branch 'master' into single-GLRC
This commit is contained in:
commit
c1b208d42c
@ -1,15 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(GLFW C)
|
project(GLFW C)
|
||||||
|
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||||
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS "3.0")
|
|
||||||
# Until all major package systems have moved to CMake 3,
|
|
||||||
# we stick with the older INSTALL_NAME_DIR mechanism
|
|
||||||
cmake_policy(SET CMP0042 OLD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS "3.1")
|
if (NOT CMAKE_VERSION VERSION_LESS "3.1")
|
||||||
cmake_policy(SET CMP0054 NEW)
|
cmake_policy(SET CMP0054 NEW)
|
||||||
endif()
|
endif()
|
||||||
|
@ -365,10 +365,10 @@ allow calls from any thread in future releases.
|
|||||||
|
|
||||||
@subsection compatibility Version compatibility
|
@subsection compatibility Version compatibility
|
||||||
|
|
||||||
GLFW guarantees source and binary backward compatibility with earlier minor
|
GLFW uses [Semantic Versioning](https://semver.org/). This guarantees source
|
||||||
versions of the API. This means that you can drop in a newer version of the
|
and binary backward compatibility with earlier minor versions of the API. This
|
||||||
library and existing programs will continue to compile and existing binaries
|
means that you can drop in a newer version of the library and existing programs
|
||||||
will continue to run.
|
will continue to compile and existing binaries will continue to run.
|
||||||
|
|
||||||
Once a function or constant has been added, the signature of that function or
|
Once a function or constant has been added, the signature of that function or
|
||||||
value of that constant will remain unchanged until the next major version of
|
value of that constant will remain unchanged until the next major version of
|
||||||
|
@ -455,6 +455,7 @@ int main(int argc, char* argv[])
|
|||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4697,7 +4697,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid);
|
|||||||
* This function may be called from the joystick callback, even for a joystick
|
* This function may be called from the joystick callback, even for a joystick
|
||||||
* that is being disconnected.
|
* that is being disconnected.
|
||||||
*
|
*
|
||||||
* @param[in] joystick The joystick whose pointer to set.
|
* @param[in] jid The joystick whose pointer to set.
|
||||||
* @param[in] pointer The new value.
|
* @param[in] pointer The new value.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
@ -4722,7 +4722,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
|
|||||||
* This function may be called from the joystick callback, even for a joystick
|
* This function may be called from the joystick callback, even for a joystick
|
||||||
* that is being disconnected.
|
* that is being disconnected.
|
||||||
*
|
*
|
||||||
* @param[in] joystick The joystick whose pointer to return.
|
* @param[in] jid The joystick whose pointer to return.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
*
|
*
|
||||||
|
@ -128,6 +128,32 @@ static void updateCursorImage(_GLFWwindow* window)
|
|||||||
hideCursor(window);
|
hideCursor(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply chosen cursor mode to a focused window
|
||||||
|
//
|
||||||
|
static void updateCursorMode(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
|
{
|
||||||
|
_glfw.ns.disabledCursorWindow = window;
|
||||||
|
_glfwPlatformGetCursorPos(window,
|
||||||
|
&_glfw.ns.restoreCursorPosX,
|
||||||
|
&_glfw.ns.restoreCursorPosY);
|
||||||
|
centerCursor(window);
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(false);
|
||||||
|
}
|
||||||
|
else if (_glfw.ns.disabledCursorWindow == window)
|
||||||
|
{
|
||||||
|
_glfw.ns.disabledCursorWindow = NULL;
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
|
_glfwPlatformSetCursorPos(window,
|
||||||
|
_glfw.ns.restoreCursorPosX,
|
||||||
|
_glfw.ns.restoreCursorPosY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursorInClientArea(window))
|
||||||
|
updateCursorImage(window);
|
||||||
|
}
|
||||||
|
|
||||||
// Transforms the specified y-coordinate between the CG display and NS screen
|
// Transforms the specified y-coordinate between the CG display and NS screen
|
||||||
// coordinate systems
|
// coordinate systems
|
||||||
//
|
//
|
||||||
@ -321,7 +347,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
centerCursor(window);
|
centerCursor(window);
|
||||||
|
|
||||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||||
_glfwPlatformSetCursorMode(window, window->cursorMode);
|
updateCursorMode(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidResignKey:(NSNotification *)notification
|
- (void)windowDidResignKey:(NSNotification *)notification
|
||||||
@ -1638,26 +1664,8 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
|||||||
|
|
||||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||||
{
|
{
|
||||||
if (mode == GLFW_CURSOR_DISABLED)
|
if (_glfwPlatformWindowFocused(window))
|
||||||
{
|
updateCursorMode(window);
|
||||||
_glfw.ns.disabledCursorWindow = window;
|
|
||||||
_glfwPlatformGetCursorPos(window,
|
|
||||||
&_glfw.ns.restoreCursorPosX,
|
|
||||||
&_glfw.ns.restoreCursorPosY);
|
|
||||||
centerCursor(window);
|
|
||||||
CGAssociateMouseAndMouseCursorPosition(false);
|
|
||||||
}
|
|
||||||
else if (_glfw.ns.disabledCursorWindow == window)
|
|
||||||
{
|
|
||||||
_glfw.ns.disabledCursorWindow = NULL;
|
|
||||||
CGAssociateMouseAndMouseCursorPosition(true);
|
|
||||||
_glfwPlatformSetCursorPos(window,
|
|
||||||
_glfw.ns.restoreCursorPosX,
|
|
||||||
_glfw.ns.restoreCursorPosY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursorInClientArea(window))
|
|
||||||
updateCursorImage(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
|
56
src/init.c
56
src/init.c
@ -57,37 +57,6 @@ static _GLFWinitconfig _glfwInitHints =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a generic string representation of the specified error
|
|
||||||
//
|
|
||||||
static const char* getErrorString(int code)
|
|
||||||
{
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case GLFW_NOT_INITIALIZED:
|
|
||||||
return "The GLFW library is not initialized";
|
|
||||||
case GLFW_NO_CURRENT_CONTEXT:
|
|
||||||
return "There is no current context";
|
|
||||||
case GLFW_INVALID_ENUM:
|
|
||||||
return "Invalid argument for enum parameter";
|
|
||||||
case GLFW_INVALID_VALUE:
|
|
||||||
return "Invalid value for parameter";
|
|
||||||
case GLFW_OUT_OF_MEMORY:
|
|
||||||
return "Out of memory";
|
|
||||||
case GLFW_API_UNAVAILABLE:
|
|
||||||
return "The requested API is unavailable";
|
|
||||||
case GLFW_VERSION_UNAVAILABLE:
|
|
||||||
return "The requested API version is unavailable";
|
|
||||||
case GLFW_PLATFORM_ERROR:
|
|
||||||
return "An undocumented platform-specific error occurred";
|
|
||||||
case GLFW_FORMAT_UNAVAILABLE:
|
|
||||||
return "The requested format is unavailable";
|
|
||||||
case GLFW_NO_WINDOW_CONTEXT:
|
|
||||||
return "The specified window has no context";
|
|
||||||
default:
|
|
||||||
return "ERROR: UNKNOWN GLFW ERROR";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate the library
|
// Terminate the library
|
||||||
//
|
//
|
||||||
static void terminate(void)
|
static void terminate(void)
|
||||||
@ -173,7 +142,30 @@ void _glfwInputError(int code, const char* format, ...)
|
|||||||
description[sizeof(description) - 1] = '\0';
|
description[sizeof(description) - 1] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strcpy(description, getErrorString(code));
|
{
|
||||||
|
if (code == GLFW_NOT_INITIALIZED)
|
||||||
|
strcpy(description, "The GLFW library is not initialized");
|
||||||
|
else if (code == GLFW_NO_CURRENT_CONTEXT)
|
||||||
|
strcpy(description, "There is no current context");
|
||||||
|
else if (code == GLFW_INVALID_ENUM)
|
||||||
|
strcpy(description, "Invalid argument for enum parameter");
|
||||||
|
else if (code == GLFW_INVALID_VALUE)
|
||||||
|
strcpy(description, "Invalid value for parameter");
|
||||||
|
else if (code == GLFW_OUT_OF_MEMORY)
|
||||||
|
strcpy(description, "Out of memory");
|
||||||
|
else if (code == GLFW_API_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested API is unavailable");
|
||||||
|
else if (code == GLFW_VERSION_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested API version is unavailable");
|
||||||
|
else if (code == GLFW_PLATFORM_ERROR)
|
||||||
|
strcpy(description, "A platform-specific error occurred");
|
||||||
|
else if (code == GLFW_FORMAT_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested format is unavailable");
|
||||||
|
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
||||||
|
strcpy(description, "The specified window has no context");
|
||||||
|
else
|
||||||
|
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.initialized)
|
if (_glfw.initialized)
|
||||||
{
|
{
|
||||||
|
@ -509,9 +509,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
_glfwPlatformGetCursorPos(window,
|
_glfwPlatformGetCursorPos(window,
|
||||||
&window->virtualCursorPosX,
|
&window->virtualCursorPosX,
|
||||||
&window->virtualCursorPosY);
|
&window->virtualCursorPosY);
|
||||||
|
_glfwPlatformSetCursorMode(window, value);
|
||||||
if (_glfwPlatformWindowFocused(window))
|
|
||||||
_glfwPlatformSetCursorMode(window, value);
|
|
||||||
}
|
}
|
||||||
else if (mode == GLFW_STICKY_KEYS)
|
else if (mode == GLFW_STICKY_KEYS)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,8 @@ typedef struct
|
|||||||
HRGN hRgnBlur;
|
HRGN hRgnBlur;
|
||||||
BOOL fTransitionOnMaximized;
|
BOOL fTransitionOnMaximized;
|
||||||
} DWM_BLURBEHIND;
|
} DWM_BLURBEHIND;
|
||||||
|
#else
|
||||||
|
#include <dwmapi.h>
|
||||||
#endif /*Windows Vista*/
|
#endif /*Windows Vista*/
|
||||||
|
|
||||||
#ifndef DPI_ENUMS_DECLARED
|
#ifndef DPI_ENUMS_DECLARED
|
||||||
|
@ -235,26 +235,6 @@ static void centerCursor(_GLFWwindow* window)
|
|||||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the cursor is in the client area of the specified window
|
|
||||||
//
|
|
||||||
static GLFWbool cursorInClientArea(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
RECT area;
|
|
||||||
POINT pos;
|
|
||||||
|
|
||||||
if (!GetCursorPos(&pos))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (WindowFromPoint(pos) != window->win32.handle)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
GetClientRect(window->win32.handle, &area);
|
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &area.left);
|
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &area.right);
|
|
||||||
|
|
||||||
return PtInRect(&area, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates the cursor image according to its cursor mode
|
// Updates the cursor image according to its cursor mode
|
||||||
//
|
//
|
||||||
static void updateCursorImage(_GLFWwindow* window)
|
static void updateCursorImage(_GLFWwindow* window)
|
||||||
@ -286,6 +266,67 @@ static void updateClipRect(_GLFWwindow* window)
|
|||||||
ClipCursor(NULL);
|
ClipCursor(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply disabled cursor mode to a focused window
|
||||||
|
//
|
||||||
|
static void disableCursor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
|
||||||
|
|
||||||
|
_glfw.win32.disabledCursorWindow = window;
|
||||||
|
_glfwPlatformGetCursorPos(window,
|
||||||
|
&_glfw.win32.restoreCursorPosX,
|
||||||
|
&_glfw.win32.restoreCursorPosY);
|
||||||
|
updateCursorImage(window);
|
||||||
|
centerCursor(window);
|
||||||
|
updateClipRect(window);
|
||||||
|
|
||||||
|
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to register raw input device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit disabled cursor mode for the specified window
|
||||||
|
//
|
||||||
|
static void enableCursor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
||||||
|
|
||||||
|
_glfw.win32.disabledCursorWindow = NULL;
|
||||||
|
updateClipRect(NULL);
|
||||||
|
_glfwPlatformSetCursorPos(window,
|
||||||
|
_glfw.win32.restoreCursorPosX,
|
||||||
|
_glfw.win32.restoreCursorPosY);
|
||||||
|
updateCursorImage(window);
|
||||||
|
|
||||||
|
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to remove raw input device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether the cursor is in the client area of the specified window
|
||||||
|
//
|
||||||
|
static GLFWbool cursorInClientArea(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
RECT area;
|
||||||
|
POINT pos;
|
||||||
|
|
||||||
|
if (!GetCursorPos(&pos))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (WindowFromPoint(pos) != window->win32.handle)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
GetClientRect(window->win32.handle, &area);
|
||||||
|
ClientToScreen(window->win32.handle, (POINT*) &area.left);
|
||||||
|
ClientToScreen(window->win32.handle, (POINT*) &area.right);
|
||||||
|
|
||||||
|
return PtInRect(&area, pos);
|
||||||
|
}
|
||||||
|
|
||||||
// Update native window styles to match attributes
|
// Update native window styles to match attributes
|
||||||
//
|
//
|
||||||
static void updateWindowStyles(const _GLFWwindow* window)
|
static void updateWindowStyles(const _GLFWwindow* window)
|
||||||
@ -575,7 +616,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
if (lParam == 0 && window->win32.frameAction)
|
if (lParam == 0 && window->win32.frameAction)
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
disableCursor(window);
|
||||||
|
|
||||||
window->win32.frameAction = GLFW_FALSE;
|
window->win32.frameAction = GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@ -593,7 +634,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
disableCursor(window);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -601,7 +642,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
enableCursor(window);
|
||||||
|
|
||||||
if (window->monitor && window->autoIconify)
|
if (window->monitor && window->autoIconify)
|
||||||
_glfwPlatformIconifyWindow(window);
|
_glfwPlatformIconifyWindow(window);
|
||||||
@ -857,10 +898,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
case WM_ENTERMENULOOP:
|
case WM_ENTERMENULOOP:
|
||||||
{
|
{
|
||||||
// HACK: Postpone cursor disabling while the user is moving or
|
// HACK: Enable the cursor while the user is moving or
|
||||||
// resizing the window or using the menu
|
// resizing the window or using the window menu
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
enableCursor(window);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -871,7 +912,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
// HACK: Disable the cursor once the user is done moving or
|
// HACK: Disable the cursor once the user is done moving or
|
||||||
// resizing the window or using the menu
|
// resizing the window or using the menu
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
disableCursor(window);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1772,39 +1813,12 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
{
|
{
|
||||||
if (mode == GLFW_CURSOR_DISABLED)
|
if (mode == GLFW_CURSOR_DISABLED)
|
||||||
{
|
{
|
||||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
|
if (_glfwPlatformWindowFocused(window))
|
||||||
|
disableCursor(window);
|
||||||
_glfw.win32.disabledCursorWindow = window;
|
|
||||||
_glfwPlatformGetCursorPos(window,
|
|
||||||
&_glfw.win32.restoreCursorPosX,
|
|
||||||
&_glfw.win32.restoreCursorPosY);
|
|
||||||
centerCursor(window);
|
|
||||||
updateClipRect(window);
|
|
||||||
|
|
||||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to register raw input device");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_glfw.win32.disabledCursorWindow == window)
|
else if (_glfw.win32.disabledCursorWindow == window)
|
||||||
{
|
enableCursor(window);
|
||||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
else if (cursorInClientArea(window))
|
||||||
|
|
||||||
_glfw.win32.disabledCursorWindow = NULL;
|
|
||||||
updateClipRect(NULL);
|
|
||||||
_glfwPlatformSetCursorPos(window,
|
|
||||||
_glfw.win32.restoreCursorPosX,
|
|
||||||
_glfw.win32.restoreCursorPosY);
|
|
||||||
|
|
||||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to remove raw input device");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursorInClientArea(window))
|
|
||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,11 @@ static GLFWbool initExtensions(void)
|
|||||||
&_glfw.x11.vidmode.errorBase);
|
&_glfw.x11.vidmode.errorBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so");
|
||||||
|
#else
|
||||||
_glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
|
_glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
|
||||||
|
#endif
|
||||||
if (_glfw.x11.xi.handle)
|
if (_glfw.x11.xi.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||||
@ -505,7 +509,11 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so");
|
||||||
|
#else
|
||||||
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
|
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
|
||||||
|
#endif
|
||||||
if (_glfw.x11.randr.handle)
|
if (_glfw.x11.randr.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
||||||
@ -593,7 +601,11 @@ static GLFWbool initExtensions(void)
|
|||||||
RROutputChangeNotifyMask);
|
RROutputChangeNotifyMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so");
|
||||||
|
#else
|
||||||
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
|
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
|
||||||
|
#endif
|
||||||
if (_glfw.x11.xcursor.handle)
|
if (_glfw.x11.xcursor.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
|
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
|
||||||
@ -604,7 +616,11 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so");
|
||||||
|
#else
|
||||||
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
|
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
|
||||||
|
#endif
|
||||||
if (_glfw.x11.xinerama.handle)
|
if (_glfw.x11.xinerama.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
|
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
|
||||||
@ -644,14 +660,22 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so");
|
||||||
|
#else
|
||||||
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
|
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
|
||||||
|
#endif
|
||||||
if (_glfw.x11.x11xcb.handle)
|
if (_glfw.x11.x11xcb.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
|
_glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
|
||||||
_glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
_glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so");
|
||||||
|
#else
|
||||||
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
|
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
|
||||||
|
#endif
|
||||||
if (_glfw.x11.xrender.handle)
|
if (_glfw.x11.xrender.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
|
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
|
||||||
@ -1024,6 +1048,24 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfw.x11.xinerama.handle = NULL;
|
_glfw.x11.xinerama.handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.xrender.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.x11.xrender.handle);
|
||||||
|
_glfw.x11.xrender.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.vidmode.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.x11.vidmode.handle);
|
||||||
|
_glfw.x11.vidmode.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.xi.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.x11.xi.handle);
|
||||||
|
_glfw.x11.xi.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
||||||
// cleanup callbacks that get called by that function
|
// cleanup callbacks that get called by that function
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
|
110
src/x11_window.c
110
src/x11_window.c
@ -571,6 +571,61 @@ static void updateCursorImage(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply disabled cursor mode to a focused window
|
||||||
|
//
|
||||||
|
static void disableCursor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.xi.available)
|
||||||
|
{
|
||||||
|
XIEventMask em;
|
||||||
|
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
|
||||||
|
|
||||||
|
em.deviceid = XIAllMasterDevices;
|
||||||
|
em.mask_len = sizeof(mask);
|
||||||
|
em.mask = mask;
|
||||||
|
XISetMask(mask, XI_RawMotion);
|
||||||
|
|
||||||
|
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.x11.disabledCursorWindow = window;
|
||||||
|
_glfwPlatformGetCursorPos(window,
|
||||||
|
&_glfw.x11.restoreCursorPosX,
|
||||||
|
&_glfw.x11.restoreCursorPosY);
|
||||||
|
updateCursorImage(window);
|
||||||
|
centerCursor(window);
|
||||||
|
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
|
||||||
|
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||||
|
GrabModeAsync, GrabModeAsync,
|
||||||
|
window->x11.handle,
|
||||||
|
_glfw.x11.hiddenCursorHandle,
|
||||||
|
CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit disabled cursor mode for the specified window
|
||||||
|
//
|
||||||
|
static void enableCursor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.xi.available)
|
||||||
|
{
|
||||||
|
XIEventMask em;
|
||||||
|
unsigned char mask[] = { 0 };
|
||||||
|
|
||||||
|
em.deviceid = XIAllMasterDevices;
|
||||||
|
em.mask_len = sizeof(mask);
|
||||||
|
em.mask = mask;
|
||||||
|
|
||||||
|
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.x11.disabledCursorWindow = NULL;
|
||||||
|
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
||||||
|
_glfwPlatformSetCursorPos(window,
|
||||||
|
_glfw.x11.restoreCursorPosX,
|
||||||
|
_glfw.x11.restoreCursorPosY);
|
||||||
|
updateCursorImage(window);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the X11 window (and its colormap)
|
// Create the X11 window (and its colormap)
|
||||||
//
|
//
|
||||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||||
@ -1432,7 +1487,7 @@ static void processEvent(XEvent *event)
|
|||||||
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
|
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
|
||||||
// ignore the defined cursor for hidden cursor mode
|
// ignore the defined cursor for hidden cursor mode
|
||||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_HIDDEN);
|
updateCursorImage(window);
|
||||||
|
|
||||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||||
return;
|
return;
|
||||||
@ -1725,7 +1780,7 @@ static void processEvent(XEvent *event)
|
|||||||
case FocusIn:
|
case FocusIn:
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
disableCursor(window);
|
||||||
|
|
||||||
if (event->xfocus.mode == NotifyGrab ||
|
if (event->xfocus.mode == NotifyGrab ||
|
||||||
event->xfocus.mode == NotifyUngrab)
|
event->xfocus.mode == NotifyUngrab)
|
||||||
@ -1745,7 +1800,7 @@ static void processEvent(XEvent *event)
|
|||||||
case FocusOut:
|
case FocusOut:
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
enableCursor(window);
|
||||||
|
|
||||||
if (event->xfocus.mode == NotifyGrab ||
|
if (event->xfocus.mode == NotifyGrab ||
|
||||||
event->xfocus.mode == NotifyUngrab)
|
event->xfocus.mode == NotifyUngrab)
|
||||||
@ -2708,53 +2763,14 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
{
|
{
|
||||||
if (mode == GLFW_CURSOR_DISABLED)
|
if (mode == GLFW_CURSOR_DISABLED)
|
||||||
{
|
{
|
||||||
if (_glfw.x11.xi.available)
|
if (_glfwPlatformWindowFocused(window))
|
||||||
{
|
disableCursor(window);
|
||||||
XIEventMask em;
|
|
||||||
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
|
|
||||||
|
|
||||||
em.deviceid = XIAllMasterDevices;
|
|
||||||
em.mask_len = sizeof(mask);
|
|
||||||
em.mask = mask;
|
|
||||||
XISetMask(mask, XI_RawMotion);
|
|
||||||
|
|
||||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.x11.disabledCursorWindow = window;
|
|
||||||
_glfwPlatformGetCursorPos(window,
|
|
||||||
&_glfw.x11.restoreCursorPosX,
|
|
||||||
&_glfw.x11.restoreCursorPosY);
|
|
||||||
centerCursor(window);
|
|
||||||
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
|
|
||||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
|
||||||
GrabModeAsync, GrabModeAsync,
|
|
||||||
window->x11.handle,
|
|
||||||
_glfw.x11.hiddenCursorHandle,
|
|
||||||
CurrentTime);
|
|
||||||
}
|
}
|
||||||
else if (_glfw.x11.disabledCursorWindow == window)
|
else if (_glfw.x11.disabledCursorWindow == window)
|
||||||
{
|
enableCursor(window);
|
||||||
if (_glfw.x11.xi.available)
|
else
|
||||||
{
|
updateCursorImage(window);
|
||||||
XIEventMask em;
|
|
||||||
unsigned char mask[] = { 0 };
|
|
||||||
|
|
||||||
em.deviceid = XIAllMasterDevices;
|
|
||||||
em.mask_len = sizeof(mask);
|
|
||||||
em.mask = mask;
|
|
||||||
|
|
||||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.x11.disabledCursorWindow = NULL;
|
|
||||||
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
|
||||||
_glfwPlatformSetCursorPos(window,
|
|
||||||
_glfw.x11.restoreCursorPosX,
|
|
||||||
_glfw.x11.restoreCursorPosY);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateCursorImage(window);
|
|
||||||
XFlush(_glfw.x11.display);
|
XFlush(_glfw.x11.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user