|
|
|
@ -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, |
|
|
|
|