mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Added glfwCreateStandardCursor.
This function allows the creation of cursor objects using one of several standard cursor shapes from the current system cursor theme.
This commit is contained in:
parent
1495134398
commit
2a1375e97c
@ -63,8 +63,8 @@ GLFW bundles a number of dependencies in the `deps/` directory.
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- Added `GLFWcursor` custom system cursor handle
|
- Added `GLFWcursor` custom system cursor handle
|
||||||
- Added `glfwCreateCursor`, `glfwDestroyCursor` and `glfwSetCursor` for
|
- Added `glfwCreateCursor`, `glfwCreateStandardCursor`, `glfwDestroyCursor` and
|
||||||
managing custom system cursors
|
`glfwSetCursor` for managing system cursor images
|
||||||
- Added `GLFWimage` struct for passing 32-bit RGBA images
|
- Added `GLFWimage` struct for passing 32-bit RGBA images
|
||||||
- Added monitor and adapter identifier access to native API
|
- Added monitor and adapter identifier access to native API
|
||||||
- Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files
|
- Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files
|
||||||
|
@ -343,6 +343,20 @@ When a cursor is destroyed, it is removed from any window where it is set. This
|
|||||||
does not affect the cursor modes of those windows.
|
does not affect the cursor modes of those windows.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection input_cursor_standard Standard cursor shapes
|
||||||
|
|
||||||
|
Cursor objects with platform-specific variants of the
|
||||||
|
[standard shapes](@ref shapes) can be created with @ref
|
||||||
|
glfwCreateStandardCursor.
|
||||||
|
|
||||||
|
@code
|
||||||
|
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
These cursor objects behave in the exact same way as those created with @ref
|
||||||
|
glfwCreateCursor except that the platform provides the cursor image data.
|
||||||
|
|
||||||
|
|
||||||
@subsection input_cursor_enter Cursor enter/leave events
|
@subsection input_cursor_enter Cursor enter/leave events
|
||||||
|
|
||||||
If you wish to be notified when the cursor enters or leaves the client area of
|
If you wish to be notified when the cursor enters or leaves the client area of
|
||||||
|
@ -9,10 +9,9 @@
|
|||||||
|
|
||||||
@subsection news_31_cursor Custom system cursor support
|
@subsection news_31_cursor Custom system cursor support
|
||||||
|
|
||||||
GLFW now supports creating and setting custom system cursors. They can be
|
GLFW now supports creating and setting both custom and standard system cursors.
|
||||||
created with @ref glfwCreateCursor, set with @ref glfwSetCursor and destroyed
|
They can be created with @ref glfwCreateCursor or @ref glfwCreateStandardCursor,
|
||||||
with @ref glfwDestroyCursor. Custom cursors are only visible in normal cursor
|
set with @ref glfwSetCursor and destroyed with @ref glfwDestroyCursor.
|
||||||
mode.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_31_drop File drop event support
|
@subsection news_31_drop File drop event support
|
||||||
|
@ -672,6 +672,42 @@ extern "C" {
|
|||||||
#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
|
#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
|
||||||
#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
|
#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
|
||||||
|
|
||||||
|
/*! @defgroup shapes Standard cursor shapes
|
||||||
|
* @ingroup input
|
||||||
|
* @{ */
|
||||||
|
|
||||||
|
/*! @brief The regular arrow cursor shape.
|
||||||
|
*
|
||||||
|
* The regular arrow cursor.
|
||||||
|
*/
|
||||||
|
#define GLFW_ARROW_CURSOR 0x00036001
|
||||||
|
/*! @brief The text input I-beam cursor shape.
|
||||||
|
*
|
||||||
|
* The text input I-beam cursor shape.
|
||||||
|
*/
|
||||||
|
#define GLFW_IBEAM_CURSOR 0x00036002
|
||||||
|
/*! @brief The crosshair shape.
|
||||||
|
*
|
||||||
|
* The crosshair shape.
|
||||||
|
*/
|
||||||
|
#define GLFW_CROSSHAIR_CURSOR 0x00036003
|
||||||
|
/*! @brief The hand shape.
|
||||||
|
*
|
||||||
|
* The hand shape.
|
||||||
|
*/
|
||||||
|
#define GLFW_HAND_CURSOR 0x00036004
|
||||||
|
/*! @brief The horizontal resize arrow shape.
|
||||||
|
*
|
||||||
|
* The horizontal resize arrow shape.
|
||||||
|
*/
|
||||||
|
#define GLFW_HRESIZE_CURSOR 0x00036005
|
||||||
|
/*! @brief The vertical resize arrow shape.
|
||||||
|
*
|
||||||
|
* The vertical resize arrow shape.
|
||||||
|
*/
|
||||||
|
#define GLFW_VRESIZE_CURSOR 0x00036006
|
||||||
|
/*! @} */
|
||||||
|
|
||||||
#define GLFW_CONNECTED 0x00040001
|
#define GLFW_CONNECTED 0x00040001
|
||||||
#define GLFW_DISCONNECTED 0x00040002
|
#define GLFW_DISCONNECTED 0x00040002
|
||||||
|
|
||||||
@ -2606,7 +2642,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
|
GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
|
||||||
|
|
||||||
/*! @brief Creates a cursor.
|
/*! @brief Creates a custom cursor.
|
||||||
*
|
*
|
||||||
* Creates a new cursor that can be made the system cursor for a window with
|
* Creates a new cursor that can be made the system cursor for a window with
|
||||||
* @ref glfwSetCursor. The cursor can be destroyed with @ref
|
* @ref glfwSetCursor. The cursor can be destroyed with @ref
|
||||||
@ -2633,6 +2669,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
|
|||||||
*
|
*
|
||||||
* @sa @ref input_cursor
|
* @sa @ref input_cursor
|
||||||
* @sa glfwDestroyCursor
|
* @sa glfwDestroyCursor
|
||||||
|
* @sa glfwCreateStandardCursor
|
||||||
*
|
*
|
||||||
* @par History
|
* @par History
|
||||||
* Added in GLFW 3.1.
|
* Added in GLFW 3.1.
|
||||||
@ -2641,6 +2678,31 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
|
GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
|
||||||
|
|
||||||
|
/*! @brief Creates a cursor with a standard shape.
|
||||||
|
*
|
||||||
|
* Returns a cursor with a [standard shape](@ref shapes), which can be made the
|
||||||
|
* system cursor for a window with @ref glfwSetCursor.
|
||||||
|
*
|
||||||
|
* @param[in] shape One of the [standard shapes](@ref shapes).
|
||||||
|
*
|
||||||
|
* @return A new cursor ready to use or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @note This function may not be called from a callback.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* This function may only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref input_cursor
|
||||||
|
* @sa glfwCreateCursor
|
||||||
|
*
|
||||||
|
* @par History
|
||||||
|
* Added in GLFW 3.1.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
|
||||||
|
|
||||||
/*! @brief Destroys a cursor.
|
/*! @brief Destroys a cursor.
|
||||||
*
|
*
|
||||||
* This function destroys a cursor previously created with @ref
|
* This function destroys a cursor previously created with @ref
|
||||||
|
@ -32,6 +32,29 @@
|
|||||||
#include <crt_externs.h>
|
#include <crt_externs.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the specified standard cursor
|
||||||
|
//
|
||||||
|
static NSCursor* getStandardCursor(int shape)
|
||||||
|
{
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case GLFW_ARROW_CURSOR:
|
||||||
|
return [NSCursor arrowCursor];
|
||||||
|
case GLFW_IBEAM_CURSOR:
|
||||||
|
return [NSCursor IBeamCursor];
|
||||||
|
case GLFW_CROSSHAIR_CURSOR:
|
||||||
|
return [NSCursor crosshairCursor];
|
||||||
|
case GLFW_HAND_CURSOR:
|
||||||
|
return [NSCursor pointingHandCursor];
|
||||||
|
case GLFW_HRESIZE_CURSOR:
|
||||||
|
return [NSCursor resizeLeftRightCursor];
|
||||||
|
case GLFW_VRESIZE_CURSOR:
|
||||||
|
return [NSCursor resizeUpDownCursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
// Center the cursor in the view of the window
|
// Center the cursor in the view of the window
|
||||||
//
|
//
|
||||||
static void centerCursor(_GLFWwindow *window)
|
static void centerCursor(_GLFWwindow *window)
|
||||||
@ -1161,6 +1184,19 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
|
{
|
||||||
|
cursor->ns.object = getStandardCursor(shape);
|
||||||
|
if (!cursor->ns.object)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "Cocoa: Invalid standard cursor");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[cursor->ns.object retain];
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
if (cursor->ns.object)
|
if (cursor->ns.object)
|
||||||
|
19
src/input.c
19
src/input.c
@ -382,6 +382,25 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
|||||||
return (GLFWcursor*) cursor;
|
return (GLFWcursor*) cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
||||||
|
{
|
||||||
|
_GLFWcursor* cursor;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
cursor = calloc(1, sizeof(_GLFWcursor));
|
||||||
|
cursor->next = _glfw.cursorListHead;
|
||||||
|
_glfw.cursorListHead = cursor;
|
||||||
|
|
||||||
|
if (!_glfwPlatformCreateStandardCursor(cursor, shape))
|
||||||
|
{
|
||||||
|
glfwDestroyCursor((GLFWcursor*) cursor);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GLFWcursor*) cursor;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
|
GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
|
||||||
{
|
{
|
||||||
_GLFWcursor* cursor = (_GLFWcursor*) handle;
|
_GLFWcursor* cursor = (_GLFWcursor*) handle;
|
||||||
|
@ -625,6 +625,11 @@ GLFWglproc _glfwPlatformGetProcAddress(const char* procname);
|
|||||||
*/
|
*/
|
||||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
||||||
|
|
||||||
|
/*! @copydoc glfwCreateStandardCursor
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
|
||||||
|
|
||||||
/*! @copydoc glfwDestroyCursor
|
/*! @copydoc glfwDestroyCursor
|
||||||
* @ingroup platform
|
* @ingroup platform
|
||||||
*/
|
*/
|
||||||
|
@ -610,6 +610,14 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Mir: Unsupported Function %s!", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
@ -112,6 +112,29 @@ static void restoreCursor(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translates a GLFW standard cursor to a resource ID
|
||||||
|
//
|
||||||
|
static LPWSTR translateCursorShape(int shape)
|
||||||
|
{
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case GLFW_ARROW_CURSOR:
|
||||||
|
return IDC_ARROW;
|
||||||
|
case GLFW_IBEAM_CURSOR:
|
||||||
|
return IDC_IBEAM;
|
||||||
|
case GLFW_CROSSHAIR_CURSOR:
|
||||||
|
return IDC_CROSS;
|
||||||
|
case GLFW_HAND_CURSOR:
|
||||||
|
return IDC_HAND;
|
||||||
|
case GLFW_HRESIZE_CURSOR:
|
||||||
|
return IDC_SIZEWE;
|
||||||
|
case GLFW_VRESIZE_CURSOR:
|
||||||
|
return IDC_SIZENS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieves and translates modifier keys
|
// Retrieves and translates modifier keys
|
||||||
//
|
//
|
||||||
static int getKeyMods(void)
|
static int getKeyMods(void)
|
||||||
@ -1176,6 +1199,26 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
|
{
|
||||||
|
LPCWSTR native = translateCursorShape(shape);
|
||||||
|
if (!native)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "Win32: Invalid standard cursor");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->win32.handle = CopyCursor(LoadCursorW(NULL, native));
|
||||||
|
if (!cursor->win32.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to retrieve shared cursor");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
if (cursor->win32.handle)
|
if (cursor->win32.handle)
|
||||||
|
@ -422,6 +422,13 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
fprintf(stderr, "_glfwPlatformCreateStandardCursor not implemented yet\n");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
wl_buffer_destroy(cursor->wl.buffer);
|
wl_buffer_destroy(cursor->wl.buffer);
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
|
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -66,6 +68,29 @@ static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointe
|
|||||||
event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;
|
event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translates a GLFW standard cursor to a font cursor shape
|
||||||
|
//
|
||||||
|
static int translateCursorShape(int shape)
|
||||||
|
{
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case GLFW_ARROW_CURSOR:
|
||||||
|
return XC_arrow;
|
||||||
|
case GLFW_IBEAM_CURSOR:
|
||||||
|
return XC_xterm;
|
||||||
|
case GLFW_CROSSHAIR_CURSOR:
|
||||||
|
return XC_crosshair;
|
||||||
|
case GLFW_HAND_CURSOR:
|
||||||
|
return XC_hand1;
|
||||||
|
case GLFW_HRESIZE_CURSOR:
|
||||||
|
return XC_sb_h_double_arrow;
|
||||||
|
case GLFW_VRESIZE_CURSOR:
|
||||||
|
return XC_sb_v_double_arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Translates an X event modifier state mask
|
// Translates an X event modifier state mask
|
||||||
//
|
//
|
||||||
static int translateState(int state)
|
static int translateState(int state)
|
||||||
@ -1731,12 +1756,32 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
int xhot, int yhot)
|
int xhot, int yhot)
|
||||||
{
|
{
|
||||||
cursor->x11.handle = _glfwCreateCursor(image, xhot, yhot);
|
cursor->x11.handle = _glfwCreateCursor(image, xhot, yhot);
|
||||||
if (cursor->x11.handle == None)
|
if (!cursor->x11.handle)
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
|
{
|
||||||
|
const unsigned int native = translateCursorShape(shape);
|
||||||
|
if (!native)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "X11: Invalid standard cursor");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||||
|
if (!cursor->x11.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to create standard cursor");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
if (cursor->x11.handle)
|
if (cursor->x11.handle)
|
||||||
|
Loading…
Reference in New Issue
Block a user