mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 19:42:00 +00:00
parent
8d170c7f47
commit
25204b1ec7
@ -27,21 +27,23 @@ IF (NOT WIN32)
|
|||||||
# Use pkg-config to get the directories and then use these values
|
# Use pkg-config to get the directories and then use these values
|
||||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||||
FIND_PACKAGE(PkgConfig)
|
FIND_PACKAGE(PkgConfig)
|
||||||
PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl)
|
PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
|
||||||
|
|
||||||
SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
|
SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
|
||||||
|
|
||||||
FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||||
FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||||
FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||||
|
FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||||
|
|
||||||
FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||||
FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||||
FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||||
|
FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||||
|
|
||||||
set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR})
|
set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR})
|
||||||
|
|
||||||
set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES})
|
set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
|
||||||
|
|
||||||
list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
|
list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
|
||||||
|
|
||||||
@ -50,6 +52,7 @@ IF (NOT WIN32)
|
|||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR)
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR)
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR)
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR)
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR)
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR)
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR)
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR)
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
MARK_AS_ADVANCED(
|
||||||
@ -57,6 +60,7 @@ IF (NOT WIN32)
|
|||||||
WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
|
WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
|
||||||
WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
|
WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
|
||||||
WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
|
WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
|
||||||
|
WAYLAND_CURSOR_INCLUDE_DIR WAYLAND_CURSOR_LIBRARIES
|
||||||
)
|
)
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
@ -46,7 +46,10 @@ static void pointerHandleEnter(void* data,
|
|||||||
{
|
{
|
||||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||||
|
|
||||||
|
_glfw.wl.pointerSerial = serial;
|
||||||
_glfw.wl.pointerFocus = window;
|
_glfw.wl.pointerFocus = window;
|
||||||
|
|
||||||
|
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
||||||
_glfwInputCursorEnter(window, GL_TRUE);
|
_glfwInputCursorEnter(window, GL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +63,7 @@ static void pointerHandleLeave(void* data,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_glfw.wl.pointerSerial = serial;
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
_glfwInputCursorEnter(window, GL_FALSE);
|
_glfwInputCursorEnter(window, GL_FALSE);
|
||||||
}
|
}
|
||||||
@ -491,6 +495,11 @@ static void registryHandleGlobal(void* data,
|
|||||||
_glfw.wl.compositor =
|
_glfw.wl.compositor =
|
||||||
wl_registry_bind(registry, name, &wl_compositor_interface, 1);
|
wl_registry_bind(registry, name, &wl_compositor_interface, 1);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(interface, "wl_shm") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.shm =
|
||||||
|
wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
||||||
|
}
|
||||||
else if (strcmp(interface, "wl_shell") == 0)
|
else if (strcmp(interface, "wl_shell") == 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.shell =
|
_glfw.wl.shell =
|
||||||
@ -564,6 +573,20 @@ int _glfwPlatformInit(void)
|
|||||||
_glfwInitTimer();
|
_glfwInitTimer();
|
||||||
_glfwInitJoysticks();
|
_glfwInitJoysticks();
|
||||||
|
|
||||||
|
if (_glfw.wl.pointer && _glfw.wl.shm){
|
||||||
|
_glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 24, _glfw.wl.shm);
|
||||||
|
if (!_glfw.wl.cursorTheme) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unable to load default cursor theme\n");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
_glfw.wl.defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr");
|
||||||
|
if (!_glfw.wl.defaultCursor) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Unable to load default left pointer\n");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
_glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||||
|
}
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,6 +594,10 @@ void _glfwPlatformTerminate(void)
|
|||||||
{
|
{
|
||||||
_glfwTerminateContextAPI();
|
_glfwTerminateContextAPI();
|
||||||
|
|
||||||
|
if (_glfw.wl.cursorTheme)
|
||||||
|
wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
|
||||||
|
if (_glfw.wl.cursorSurface)
|
||||||
|
wl_surface_destroy(_glfw.wl.cursorSurface);
|
||||||
if (_glfw.wl.registry)
|
if (_glfw.wl.registry)
|
||||||
wl_registry_destroy(_glfw.wl.registry);
|
wl_registry_destroy(_glfw.wl.registry);
|
||||||
if (_glfw.wl.display)
|
if (_glfw.wl.display)
|
||||||
|
@ -66,7 +66,7 @@ typedef struct _GLFWwindowWayland
|
|||||||
struct wl_shell_surface* shell_surface;
|
struct wl_shell_surface* shell_surface;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
struct wl_callback* callback;
|
struct wl_callback* callback;
|
||||||
|
_GLFWcursor* currentCursor;
|
||||||
} _GLFWwindowWayland;
|
} _GLFWwindowWayland;
|
||||||
|
|
||||||
|
|
||||||
@ -78,10 +78,16 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct wl_registry* registry;
|
struct wl_registry* registry;
|
||||||
struct wl_compositor* compositor;
|
struct wl_compositor* compositor;
|
||||||
struct wl_shell* shell;
|
struct wl_shell* shell;
|
||||||
|
struct wl_shm* shm;
|
||||||
struct wl_seat* seat;
|
struct wl_seat* seat;
|
||||||
struct wl_pointer* pointer;
|
struct wl_pointer* pointer;
|
||||||
struct wl_keyboard* keyboard;
|
struct wl_keyboard* keyboard;
|
||||||
|
|
||||||
|
struct wl_cursor_theme* cursorTheme;
|
||||||
|
struct wl_cursor* defaultCursor;
|
||||||
|
struct wl_surface* cursorSurface;
|
||||||
|
uint32_t pointerSerial;
|
||||||
|
|
||||||
_GLFWmonitor** monitors;
|
_GLFWmonitor** monitors;
|
||||||
int monitorsCount;
|
int monitorsCount;
|
||||||
int monitorsSize;
|
int monitorsSize;
|
||||||
@ -124,8 +130,9 @@ typedef struct _GLFWmonitorWayland
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWcursorWayland
|
typedef struct _GLFWcursorWayland
|
||||||
{
|
{
|
||||||
int dummy;
|
struct wl_buffer* buffer;
|
||||||
|
int width, height;
|
||||||
|
int xhot, yhot;
|
||||||
} _GLFWcursorWayland;
|
} _GLFWcursorWayland;
|
||||||
|
|
||||||
|
|
||||||
|
219
src/wl_window.c
219
src/wl_window.c
@ -27,9 +27,16 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <wayland-egl.h>
|
#include <wayland-egl.h>
|
||||||
|
#include <wayland-cursor.h>
|
||||||
|
|
||||||
|
|
||||||
static void handlePing(void* data,
|
static void handlePing(void* data,
|
||||||
@ -93,6 +100,105 @@ static GLboolean createSurface(_GLFWwindow* window,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_cloexec_or_close(int fd)
|
||||||
|
{
|
||||||
|
long flags;
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
flags = fcntl(fd, F_GETFD);
|
||||||
|
if (flags == -1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
err:
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_tmpfile_cloexec(char *tmpname)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
#ifdef HAVE_MKOSTEMP
|
||||||
|
fd = mkostemp(tmpname, O_CLOEXEC);
|
||||||
|
if (fd >= 0)
|
||||||
|
unlink(tmpname);
|
||||||
|
#else
|
||||||
|
fd = mkstemp(tmpname);
|
||||||
|
if (fd >= 0) {
|
||||||
|
fd = set_cloexec_or_close(fd);
|
||||||
|
unlink(tmpname);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new, unique, anonymous file of the given size, and
|
||||||
|
* return the file descriptor for it. The file descriptor is set
|
||||||
|
* CLOEXEC. The file is immediately suitable for mmap()'ing
|
||||||
|
* the given size at offset zero.
|
||||||
|
*
|
||||||
|
* The file should not have a permanent backing store like a disk,
|
||||||
|
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
|
||||||
|
*
|
||||||
|
* The file name is deleted from the file system.
|
||||||
|
*
|
||||||
|
* The file is suitable for buffer sharing between processes by
|
||||||
|
* transmitting the file descriptor over Unix sockets using the
|
||||||
|
* SCM_RIGHTS methods.
|
||||||
|
*
|
||||||
|
* If the C library implements posix_fallocate(), it is used to
|
||||||
|
* guarantee that disk space is available for the file at the
|
||||||
|
* given size. If disk space is insufficent, errno is set to ENOSPC.
|
||||||
|
* If posix_fallocate() is not supported, program may receive
|
||||||
|
* SIGBUS on accessing mmap()'ed file contents instead.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
os_create_anonymous_file(off_t size)
|
||||||
|
{
|
||||||
|
static const char template[] = "/glfw-shared-XXXXXX";
|
||||||
|
const char *path;
|
||||||
|
char *name;
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
path = getenv("XDG_RUNTIME_DIR");
|
||||||
|
if (!path) {
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = malloc(strlen(path) + sizeof(template));
|
||||||
|
if (!name)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
strcpy(name, path);
|
||||||
|
strcat(name, template);
|
||||||
|
|
||||||
|
fd = create_tmpfile_cloexec(name);
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
ret = posix_fallocate(fd, 0, size);
|
||||||
|
if (ret != 0) {
|
||||||
|
close(fd);
|
||||||
|
errno = ret;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -122,6 +228,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
wl_shell_surface_set_toplevel(window->wl.shell_surface);
|
wl_shell_surface_set_toplevel(window->wl.shell_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->wl.currentCursor = NULL;
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,37 +387,116 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
|||||||
|
|
||||||
void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
|
void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "_glfwPlatformApplyCursorMode not implemented yet\n");
|
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
||||||
switch (window->cursorMode)
|
|
||||||
{
|
|
||||||
case GLFW_CURSOR_NORMAL:
|
|
||||||
// TODO: enable showing cursor
|
|
||||||
break;
|
|
||||||
case GLFW_CURSOR_HIDDEN:
|
|
||||||
// TODO: enable not showing cursor
|
|
||||||
break;
|
|
||||||
case GLFW_CURSOR_DISABLED:
|
|
||||||
// TODO: enable pointer lock and hide cursor
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||||
const GLFWimage* image,
|
const GLFWimage* image,
|
||||||
int xhot, int yhot)
|
int xhot, int yhot)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "_glfwPlatformCreateCursor not implemented yet\n");
|
struct wl_shm_pool *pool;
|
||||||
|
int stride = image->width * 4;
|
||||||
|
int length = image->width * image->height * 4;
|
||||||
|
void *data;
|
||||||
|
int fd, i;
|
||||||
|
|
||||||
|
fd = os_create_anonymous_file(length);
|
||||||
|
if (fd < 0) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Creating a buffer file for %d B failed: %m\n",
|
||||||
|
length);
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (data == MAP_FAILED) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Cursor mmap failed: %m\n");
|
||||||
|
close(fd);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
unsigned char* source = (unsigned char*) image->pixels;
|
||||||
|
unsigned char* target = data;
|
||||||
|
for (i = 0; i < image->width * image->height; i++, source += 4)
|
||||||
|
{
|
||||||
|
*target++ = source[2];
|
||||||
|
*target++ = source[1];
|
||||||
|
*target++ = source[0];
|
||||||
|
*target++ = source[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->wl.buffer = wl_shm_pool_create_buffer(pool, 0,
|
||||||
|
image->width,
|
||||||
|
image->height,
|
||||||
|
stride, WL_SHM_FORMAT_ARGB8888);
|
||||||
|
munmap(data, length);
|
||||||
|
wl_shm_pool_destroy(pool);
|
||||||
|
|
||||||
|
cursor->wl.width = image->width;
|
||||||
|
cursor->wl.height = image->height;
|
||||||
|
cursor->wl.xhot = xhot;
|
||||||
|
cursor->wl.yhot = yhot;
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "_glfwPlatformDestroyCursor not implemented yet\n");
|
wl_buffer_destroy(cursor->wl.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "_glfwPlatformSetCursor not implemented yet\n");
|
struct wl_buffer *buffer;
|
||||||
|
struct wl_cursor_image *image;
|
||||||
|
struct wl_surface *surface = _glfw.wl.cursorSurface;
|
||||||
|
|
||||||
|
if (!_glfw.wl.pointer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window->wl.currentCursor = cursor;
|
||||||
|
|
||||||
|
// If we're not in the correct window just save the cursor
|
||||||
|
// the next time the pointer enters the window the cursor will change
|
||||||
|
if (window != _glfw.wl.pointerFocus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
||||||
|
{
|
||||||
|
if (cursor == NULL)
|
||||||
|
{
|
||||||
|
image = _glfw.wl.defaultCursor->images[0];
|
||||||
|
buffer = wl_cursor_image_get_buffer(image);
|
||||||
|
if (!buffer)
|
||||||
|
return;
|
||||||
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
||||||
|
surface,
|
||||||
|
image->hotspot_x,
|
||||||
|
image->hotspot_y);
|
||||||
|
wl_surface_attach(surface, buffer, 0, 0);
|
||||||
|
wl_surface_damage(surface, 0, 0,
|
||||||
|
image->width, image->height);
|
||||||
|
wl_surface_commit(surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
|
||||||
|
surface,
|
||||||
|
cursor->wl.xhot,
|
||||||
|
cursor->wl.yhot);
|
||||||
|
wl_surface_attach(surface, cursor->wl.buffer, 0, 0);
|
||||||
|
wl_surface_damage(surface, 0, 0,
|
||||||
|
cursor->wl.width, cursor->wl.height);
|
||||||
|
wl_surface_commit(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Cursor is hidden set cursor surface to NULL */
|
||||||
|
{
|
||||||
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, NULL, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||||
|
Loading…
Reference in New Issue
Block a user