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