diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b47b2354..0f714b5a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,6 +79,9 @@ if (_GLFW_WAYLAND) wayland_generate( ${WAYLAND_PROTOCOLS_BASE}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml ${CMAKE_BINARY_DIR}/src/wayland-pointer-constraints-unstable-v1-client-protocol) + wayland_generate( + ${WAYLAND_PROTOCOLS_BASE}/unstable/tablet/tablet-unstable-v2.xml + ${CMAKE_BINARY_DIR}/src/wayland-tablet-unstable-v2-client-protocol) wayland_generate( ${WAYLAND_PROTOCOLS_BASE}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml ${CMAKE_BINARY_DIR}/src/wayland-idle-inhibit-unstable-v1-client-protocol) diff --git a/src/wl_init.c b/src/wl_init.c index 21a808aa..f4bca62e 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -769,6 +769,390 @@ static const struct wl_data_device_listener dataDeviceListener = { dataDeviceHandleSelection, }; +void tabletName(void *data, + struct zwp_tablet_v2 *zwp_tablet_v2, + const char *name) +{ + printf("Tablet name: %s\n", name); +} + +void tabletId(void *data, + struct zwp_tablet_v2 *zwp_tablet_v2, + uint32_t vid, + uint32_t pid) +{ + printf("Tablet id: %04u:%04u\n", vid, pid); +} + +void tabletPath(void *data, + struct zwp_tablet_v2 *zwp_tablet_v2, + const char *path) +{ + printf("Tablet path: %s\n", path); +} + +void tabletDone(void *data, + struct zwp_tablet_v2 *zwp_tablet_v2) +{ + printf("Tablet done\n"); +} + +void tabletRemoved(void *data, + struct zwp_tablet_v2 *zwp_tablet_v2) +{ + printf("Tablet removed\n"); + _glfw.wl.tablet = NULL; +} + +static const struct zwp_tablet_v2_listener tabletListener = { + tabletName, + tabletId, + tabletPath, + tabletDone, + tabletRemoved, +}; + +void tabletToolType(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t toolType) +{ + const char *name; + switch (toolType) + { + case ZWP_TABLET_TOOL_V2_TYPE_PEN: + name = "pen"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_ERASER: + name = "eraser"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_BRUSH: + name = "brush"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_PENCIL: + name = "pencil"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_AIRBRUSH: + name = "airbrush"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_FINGER: + name = "finger"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_MOUSE: + name = "mouse"; + break; + case ZWP_TABLET_TOOL_V2_TYPE_LENS: + name = "lens"; + break; + default: + name = "unknown"; + break; + } + printf("Tablet tool type: %s\n", name); +} + +void tabletToolHardwareSerial(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t hardwareSerialHi, + uint32_t hardwareSerialLo) +{ + uint64_t hardwareSerial = (uint64_t)hardwareSerialHi << 32 | (uint64_t)hardwareSerialLo; + printf("Tablet tool hardware serial: %"PRId64"\n", hardwareSerial); +} + +void tabletToolHardwareIdWacom(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t hardwareIdHi, + uint32_t hardwareIdLo) +{ + uint64_t hardwareId = (uint64_t)hardwareIdHi << 32 | (uint64_t)hardwareIdLo; + printf("Tablet tool hardware id Wacom: %"PRId64"\n", hardwareId); +} + +void tabletToolCapability(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t capability) +{ + const char *name; + switch (capability) + { + case ZWP_TABLET_TOOL_V2_CAPABILITY_TILT: + name = "tilt"; + break; + case ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE: + name = "pressure"; + break; + case ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE: + name = "distance"; + break; + case ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION: + name = "rotation"; + break; + case ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER: + name = "slider"; + break; + case ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL: + name = "wheel"; + break; + default: + name = "unknown"; + break; + } + printf("Tablet tool capability: %s\n", name); +} + +void tabletToolDone(void *data, + struct zwp_tablet_tool_v2 *tool) +{ + printf("Tablet tool done\n"); +} + +void tabletToolRemoved(void *data, + struct zwp_tablet_tool_v2 *tool) +{ + printf("Tablet tool removed (unimplemented)\n"); +} + +void tabletToolProximityIn(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t serial, + struct zwp_tablet_v2 *tablet, + struct wl_surface *surface) +{ + printf("Tablet tool proximity in: %p %p\n", tablet, surface); +} + +void tabletToolProximityOut(void *data, + struct zwp_tablet_tool_v2 *tool) +{ + printf("Tablet tool proximity out\n"); +} + +void tabletToolDown(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t serial) +{ + printf("Tablet tool down\n"); +} + +void tabletToolUp(void *data, + struct zwp_tablet_tool_v2 *tool) +{ + printf("Tablet tool up\n"); +} + +void tabletToolMotion(void *data, + struct zwp_tablet_tool_v2 *tool, + wl_fixed_t x, + wl_fixed_t y) +{ + printf("Tablet tool motion: %f %f\n", wl_fixed_to_double(x), wl_fixed_to_double(y)); +} + +void tabletToolPressure(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t pressure) +{ + printf("Tablet tool pressure: %u\n", pressure); +} + +void tabletToolDistance(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t distance) +{ + printf("Tablet tool distance: %u\n", distance); +} + +void tabletToolTilt(void *data, + struct zwp_tablet_tool_v2 *tool, + wl_fixed_t tiltX, + wl_fixed_t tiltY) +{ + printf("Tablet tool tilt: %f %f\n", wl_fixed_to_double(tiltX), wl_fixed_to_double(tiltY)); +} + +void tabletToolRotation(void *data, + struct zwp_tablet_tool_v2 *tool, + wl_fixed_t degrees) +{ + printf("Tablet tool rotation: %f°\n", wl_fixed_to_double(degrees)); +} + +void tabletToolSlider(void *data, + struct zwp_tablet_tool_v2 *tool, + int32_t position) +{ + printf("Tablet tool slider: %d\n", position); +} + +void tabletToolWheel(void *data, + struct zwp_tablet_tool_v2 *tool, + wl_fixed_t degrees, + int32_t clicks) +{ + printf("Tablet tool wheel: %f° %d\n", wl_fixed_to_double(degrees), clicks); +} + +void tabletToolButton(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t serial, + uint32_t button, + uint32_t state) +{ + printf("Tablet tool button: %u %u\n", button, state); +} + +void tabletToolFrame(void *data, + struct zwp_tablet_tool_v2 *tool, + uint32_t time) +{ + printf("Tablet tool frame: %u\n", time); +} + +struct zwp_tablet_tool_v2_listener tabletToolListener = { + tabletToolType, + tabletToolHardwareSerial, + tabletToolHardwareIdWacom, + tabletToolCapability, + tabletToolDone, + tabletToolRemoved, + tabletToolProximityIn, + tabletToolProximityOut, + tabletToolDown, + tabletToolUp, + tabletToolMotion, + tabletToolPressure, + tabletToolDistance, + tabletToolTilt, + tabletToolRotation, + tabletToolSlider, + tabletToolWheel, + tabletToolButton, + tabletToolFrame, +}; + +void tabletPadGroup(void *data, + struct zwp_tablet_pad_v2 *pad, + struct zwp_tablet_pad_group_v2 *padGroup) +{ + printf("New pad group: %p\n", padGroup); +} + +void tabletPadPath(void *data, + struct zwp_tablet_pad_v2 *pad, + const char *path) +{ + printf("Tablet pad path: %s\n", path); +} + +void tabletPadButtons(void *data, + struct zwp_tablet_pad_v2 *pad, + uint32_t buttons) +{ + printf("Tablet pad buttons: %u\n", buttons); +} + +void tabletPadDone(void *data, + struct zwp_tablet_pad_v2 *pad) +{ + printf("Tablet pad done\n"); +} + +void tabletPadButton(void *data, + struct zwp_tablet_pad_v2 *pad, + uint32_t time, + uint32_t button, + uint32_t state) +{ + printf("Tablet pad button: %u %u %u\n", time, button, state); +} + +void tabletPadEnter(void *data, + struct zwp_tablet_pad_v2 *pad, + uint32_t serial, + struct zwp_tablet_v2 *tablet, + struct wl_surface *surface) +{ + printf("Tablet pad enter: %p %p\n", tablet, surface); +} + +void tabletPadLeave(void *data, + struct zwp_tablet_pad_v2 *pad, + uint32_t serial, + struct wl_surface *surface) +{ + printf("Tablet pad leave: %p\n", surface); +} + +void tabletPadRemoved(void *data, + struct zwp_tablet_pad_v2 *pad) +{ + printf("Tablet pad removed (unimplemented)\n"); +} + +struct zwp_tablet_pad_v2_listener tabletPadListener = { + tabletPadGroup, + tabletPadPath, + tabletPadButtons, + tabletPadDone, + tabletPadButton, + tabletPadEnter, + tabletPadLeave, + tabletPadRemoved, +}; + +void tabletSeatTabletAdded(void *data, + struct zwp_tablet_seat_v2 *seat, + struct zwp_tablet_v2 *tablet) +{ + printf("New tablet %p!\n", tablet); + if (_glfw.wl.tablet) { + printf("Already there, skipping…\n"); + return; + } + + _glfw.wl.tablet = tablet; + zwp_tablet_v2_add_listener(_glfw.wl.tablet, &tabletListener, NULL); +} + +void tabletSeatToolAdded(void *data, + struct zwp_tablet_seat_v2 *seat, + struct zwp_tablet_tool_v2 *tool) +{ + printf("New tool %p!\n", tool); + + if (_glfw.wl.tabletToolsCount + 1 > _glfw.wl.tabletToolsSize) + { + ++_glfw.wl.tabletToolsSize; + _glfw.wl.tabletTools = + realloc(_glfw.wl.tabletTools, + _glfw.wl.tabletToolsSize * sizeof(struct zwp_tablet_tool_v2 *)); + } + + zwp_tablet_tool_v2_add_listener(tool, &tabletToolListener, NULL); + _glfw.wl.tabletTools[_glfw.wl.tabletToolsCount++] = tool; +} + +void tabletSeatPadAdded(void *data, + struct zwp_tablet_seat_v2 *seat, + struct zwp_tablet_pad_v2 *pad) +{ + // TODO: Do we really want to implement that now? + printf("New pad %p\n", pad); + if (_glfw.wl.tabletPad) { + printf("Already there, skipping…\n"); + return; + } + + _glfw.wl.tabletPad = pad; + zwp_tablet_pad_v2_add_listener(_glfw.wl.tabletPad, &tabletPadListener, NULL); +} + +static const struct zwp_tablet_seat_v2_listener tabletSeatListener = { + tabletSeatTabletAdded, + tabletSeatToolAdded, + tabletSeatPadAdded, +}; + static void wmBaseHandlePing(void* data, struct xdg_wm_base* wmBase, uint32_t serial) @@ -859,6 +1243,13 @@ static void registryHandleGlobal(void* data, &zwp_pointer_constraints_v1_interface, 1); } + else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) + { + _glfw.wl.tabletManager = + wl_registry_bind(registry, name, + &zwp_tablet_manager_v2_interface, + 1); + } else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) { _glfw.wl.idleInhibitManager = @@ -1203,6 +1594,14 @@ int _glfwPlatformInit(void) _glfw.wl.clipboardSize = 4096; } + if (_glfw.wl.seat && _glfw.wl.tabletManager) + { + _glfw.wl.tabletSeat = + zwp_tablet_manager_v2_get_tablet_seat(_glfw.wl.tabletManager, + _glfw.wl.seat); + zwp_tablet_seat_v2_add_listener(_glfw.wl.tabletSeat, &tabletSeatListener, NULL); + } + return GLFW_TRUE; } @@ -1273,6 +1672,10 @@ void _glfwPlatformTerminate(void) zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager); if (_glfw.wl.pointerConstraints) zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); + if (_glfw.wl.tabletSeat) + zwp_tablet_seat_v2_destroy(_glfw.wl.tabletSeat); + if (_glfw.wl.tabletManager) + zwp_tablet_manager_v2_destroy(_glfw.wl.tabletManager); if (_glfw.wl.idleInhibitManager) zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager); if (_glfw.wl.registry) diff --git a/src/wl_platform.h b/src/wl_platform.h index 966155fd..bae72a00 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -59,6 +59,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR #include "wayland-viewporter-client-protocol.h" #include "wayland-relative-pointer-unstable-v1-client-protocol.h" #include "wayland-pointer-constraints-unstable-v1-client-protocol.h" +#include "wayland-tablet-unstable-v2-client-protocol.h" #include "wayland-idle-inhibit-unstable-v1-client-protocol.h" #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) @@ -234,6 +235,13 @@ typedef struct _GLFWlibraryWayland struct wp_viewporter* viewporter; struct zwp_relative_pointer_manager_v1* relativePointerManager; struct zwp_pointer_constraints_v1* pointerConstraints; + struct zwp_tablet_manager_v2* tabletManager; + struct zwp_tablet_seat_v2* tabletSeat; + struct zwp_tablet_v2* tablet; + struct zwp_tablet_tool_v2** tabletTools; + int tabletToolsCount; + int tabletToolsSize; + struct zwp_tablet_pad_v2* tabletPad; struct zwp_idle_inhibit_manager_v1* idleInhibitManager; int compositorVersion;