wayland: Add basic input support
This commit is contained in:
parent
4c68049d86
commit
a75cf5a163
204
src/wl_init.c
204
src/wl_init.c
@ -26,6 +26,7 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -59,6 +60,200 @@ static const struct wl_shell_surface_listener shellSurfaceListener = {
|
||||
handlePopupDone
|
||||
};
|
||||
|
||||
static void pointerHandleEnter(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
{
|
||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||
|
||||
_glfw.wl.pointerFocus = window;
|
||||
_glfwInputCursorEnter(window, GL_TRUE);
|
||||
}
|
||||
|
||||
static void pointerHandleLeave(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface)
|
||||
{
|
||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||
|
||||
_glfw.wl.pointerFocus = NULL;
|
||||
_glfwInputCursorEnter(window, GL_FALSE);
|
||||
}
|
||||
|
||||
static void pointerHandleMotion(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t time,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
/* TODO */
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: GLFW_CURSOR_DISABLED not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputCursorMotion(window,
|
||||
wl_fixed_to_double(sx),
|
||||
wl_fixed_to_double(sy));
|
||||
}
|
||||
|
||||
static void pointerHandleButton(void* data,
|
||||
struct wl_pointer* wl_pointer,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
int glfwButton;
|
||||
|
||||
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
|
||||
* codes. */
|
||||
glfwButton = button - BTN_LEFT;
|
||||
|
||||
/* TODO: modifiers */
|
||||
_glfwInputMouseClick(window,
|
||||
glfwButton,
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED
|
||||
? GLFW_PRESS
|
||||
: GLFW_RELEASE,
|
||||
0);
|
||||
}
|
||||
|
||||
static void pointerHandleAxis(void* data,
|
||||
struct wl_pointer* wl_pointer,
|
||||
uint32_t time,
|
||||
uint32_t axis,
|
||||
wl_fixed_t value)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
double scroll_factor;
|
||||
double x, y;
|
||||
|
||||
/* Wayland scroll events are in pointer motion coordinate space (think
|
||||
* two finger scroll). The factor 10 is commonly used to convert to
|
||||
* "scroll step means 1.0. */
|
||||
scroll_factor = 1.0/10.0;
|
||||
|
||||
switch (axis)
|
||||
{
|
||||
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
|
||||
x = wl_fixed_to_double(value) * scroll_factor;
|
||||
y = 0.0;
|
||||
break;
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
x = 0.0;
|
||||
y = wl_fixed_to_double(value) * scroll_factor;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_glfwInputScroll(window, x, y);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointerListener = {
|
||||
pointerHandleEnter,
|
||||
pointerHandleLeave,
|
||||
pointerHandleMotion,
|
||||
pointerHandleButton,
|
||||
pointerHandleAxis,
|
||||
};
|
||||
|
||||
static void keyboardHandleKeymap(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t format,
|
||||
int fd,
|
||||
uint32_t size)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void keyboardHandleEnter(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface,
|
||||
struct wl_array* keys)
|
||||
{
|
||||
_glfwInputWindowFocus(wl_surface_get_user_data(surface), GL_TRUE);
|
||||
}
|
||||
|
||||
static void keyboardHandleLeave(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface)
|
||||
{
|
||||
_glfwInputWindowFocus(wl_surface_get_user_data(surface), GL_FALSE);
|
||||
}
|
||||
|
||||
static void keyboardHandleKey(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void keyboardHandleModifiers(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t modsDepressed,
|
||||
uint32_t modsLatched,
|
||||
uint32_t modsLocked,
|
||||
uint32_t group)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static const struct wl_keyboard_listener keyboardListener = {
|
||||
keyboardHandleKeymap,
|
||||
keyboardHandleEnter,
|
||||
keyboardHandleLeave,
|
||||
keyboardHandleKey,
|
||||
keyboardHandleModifiers,
|
||||
};
|
||||
|
||||
static void seatHandleCapabilities(void* data,
|
||||
struct wl_seat* seat,
|
||||
enum wl_seat_capability caps)
|
||||
{
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)
|
||||
{
|
||||
_glfw.wl.pointer = wl_seat_get_pointer(seat);
|
||||
wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
|
||||
{
|
||||
wl_pointer_destroy(_glfw.wl.pointer);
|
||||
_glfw.wl.pointer = NULL;
|
||||
}
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)
|
||||
{
|
||||
_glfw.wl.keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
|
||||
{
|
||||
wl_keyboard_destroy(_glfw.wl.keyboard);
|
||||
_glfw.wl.keyboard = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seatListener = {
|
||||
seatHandleCapabilities
|
||||
};
|
||||
|
||||
static void registryHandleGlobal(void* data,
|
||||
struct wl_registry* registry,
|
||||
uint32_t name,
|
||||
@ -79,6 +274,15 @@ static void registryHandleGlobal(void* data,
|
||||
{
|
||||
_glfwAddOutput(name, version);
|
||||
}
|
||||
else if (strcmp(interface, "wl_seat") == 0)
|
||||
{
|
||||
if (!_glfw.wl.seat)
|
||||
{
|
||||
_glfw.wl.seat =
|
||||
wl_registry_bind(registry, name, &wl_seat_interface, 1);
|
||||
wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void registryHandleGlobalRemove(void *data,
|
||||
|
@ -68,11 +68,16 @@ typedef struct _GLFWlibraryWayland
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_shell* shell;
|
||||
struct wl_seat* seat;
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_keyboard* keyboard;
|
||||
|
||||
_GLFWmonitor** monitors;
|
||||
int monitorsCount;
|
||||
int monitorsSize;
|
||||
|
||||
_GLFWwindow* pointerFocus;
|
||||
_GLFWwindow* keyboardFocus;
|
||||
} _GLFWlibraryWayland;
|
||||
|
||||
typedef struct _GLFWmonitorWayland
|
||||
|
@ -65,6 +65,8 @@ static GLboolean createSurface(_GLFWwindow* window,
|
||||
if (!window->wl.surface)
|
||||
return GL_FALSE;
|
||||
|
||||
wl_surface_set_user_data(window->wl.surface, window);
|
||||
|
||||
window->wl.native = wl_egl_window_create(window->wl.surface,
|
||||
wndconfig->width,
|
||||
wndconfig->height);
|
||||
|
Loading…
Reference in New Issue
Block a user