swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 45df267d3c6fdc4e2939d8d6dca95f1e0e6066cb
parent 0c3f36c5ac561cd2adcc9fc09fc8ad0abe6f371a
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Fri, 14 May 2021 22:39:25 -0500

initial touch support

Diffstat:
Mlibswc/compositor.c | 20+++++++++++++++++---
Mlibswc/compositor.h | 1+
Mlibswc/drm.c | 1+
Mlibswc/local.mk | 1+
Mlibswc/seat.c | 63++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mlibswc/seat.h | 1+
Mlibswc/swc.c | 2++
Alibswc/touch.c | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibswc/touch.h | 32++++++++++++++++++++++++++++++++
9 files changed, 214 insertions(+), 10 deletions(-)

diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -41,6 +41,7 @@ #include "seat.h" #include "shm.h" #include "surface.h" +#include "touch.h" #include "util.h" #include "view.h" @@ -62,11 +63,16 @@ struct target { struct wl_listener screen_destroy_listener; }; -static bool handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t x, wl_fixed_t y); +static bool handle_pointer_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t x, wl_fixed_t y); +static bool handle_touch_down(struct touch_handler *handler, uint32_t time, int32_t slot, wl_fixed_t x, wl_fixed_t y); static void perform_update(void *data); static struct pointer_handler pointer_handler = { - .motion = handle_motion, + .motion = handle_pointer_motion, +}; + +static struct touch_handler touch_handler = { + .down = handle_touch_down, }; static struct { @@ -86,6 +92,7 @@ static struct { struct swc_compositor swc_compositor = { .pointer_handler = &pointer_handler, + .touch_handler = &touch_handler, }; static void @@ -698,7 +705,7 @@ perform_update(void *data) } bool -handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx, wl_fixed_t fy) +handle_pointer_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx, wl_fixed_t fy) { struct compositor_view *view; bool found = false; @@ -726,6 +733,13 @@ handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx, wl_ return false; } +bool +handle_touch_down(struct touch_handler *handler, uint32_t time, int32_t slot, wl_fixed_t x, wl_fixed_t y) +{ + fprintf(stderr, "touch down\n"); + return false; +} + static void handle_terminate(void *data, uint32_t time, uint32_t value, uint32_t state) { diff --git a/libswc/compositor.h b/libswc/compositor.h @@ -32,6 +32,7 @@ struct swc_compositor { struct pointer_handler *const pointer_handler; + struct touch_handler *const touch_handler; struct { /** * Emitted when a new surface is created. diff --git a/libswc/drm.c b/libswc/drm.c @@ -301,6 +301,7 @@ drm_initialize(void) ERROR("Could not find valid DRM device\n"); goto error0; } + fprintf(stderr, "primary device: %s\n", primary); swc.drm->fd = launch_open_device(primary, O_RDWR | O_CLOEXEC); if (swc.drm->fd == -1) { diff --git a/libswc/local.mk b/libswc/local.mk @@ -49,6 +49,7 @@ SWC_SOURCES = \ libswc/subsurface.c \ libswc/surface.c \ libswc/swc.c \ + libswc/touch.c \ libswc/util.c \ libswc/view.c \ libswc/wayland_buffer.c \ diff --git a/libswc/seat.c b/libswc/seat.c @@ -31,6 +31,7 @@ #include "pointer.h" #include "screen.h" #include "surface.h" +#include "touch.h" #include "util.h" #include <dirent.h> @@ -144,7 +145,10 @@ get_keyboard(struct wl_client *client, struct wl_resource *resource, uint32_t id static void get_touch(struct wl_client *client, struct wl_resource *resource, uint32_t id) { - /* XXX: Implement */ + struct seat *seat = wl_resource_get_user_data(resource); + + if (!touch_bind(seat->base.touch, client, wl_resource_get_version(resource), id)) + wl_resource_post_no_memory(resource); } static const struct wl_seat_interface seat_impl = { @@ -212,10 +216,9 @@ device_capabilities(struct libinput_device *device) capabilities |= WL_SEAT_CAPABILITY_KEYBOARD; if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) capabilities |= WL_SEAT_CAPABILITY_POINTER; - /* TODO: Add touch device support - * if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) - * capabilities |= WL_SEAT_CAPABILITY_TOUCH; - */ + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) + capabilities |= WL_SEAT_CAPABILITY_TOUCH; + return capabilities; } @@ -243,9 +246,10 @@ handle_libinput_data(int fd, uint32_t mask, void *data) union { struct libinput_event_keyboard *k; struct libinput_event_pointer *p; + struct libinput_event_touch *t; } event; wl_fixed_t x, y; - uint32_t time, key, state; + uint32_t time, key, slot, state; if (libinput_dispatch(seat->libinput) != 0) { WARNING("libinput_dispatch failed: %s\n", strerror(errno)); @@ -307,6 +311,43 @@ handle_libinput_data(int fd, uint32_t mask, void *data) handle_libinput_axis_event(seat, event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); handle_libinput_axis_event(seat, event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); break; + case LIBINPUT_EVENT_TOUCH_DOWN: + screen = wl_container_of(swc.screens.next, screen, link); + rect = &screen->base.geometry; + event.t = libinput_event_get_touch_event(generic_event); + time = libinput_event_touch_get_time(event.t); + slot = libinput_event_touch_get_seat_slot(event.t); + x = wl_fixed_from_double(libinput_event_touch_get_x_transformed(event.t, rect->width)); + y = wl_fixed_from_double(libinput_event_touch_get_y_transformed(event.t, rect->height)); + touch_handle_down(seat->base.touch, time, slot, x, y); + break; + case LIBINPUT_EVENT_TOUCH_UP: + event.t = libinput_event_get_touch_event(generic_event); + time = libinput_event_touch_get_time(event.t); + slot = libinput_event_touch_get_seat_slot(event.t); + touch_handle_up(seat->base.touch, time, slot); + break; + case LIBINPUT_EVENT_TOUCH_MOTION: + screen = wl_container_of(swc.screens.next, screen, link); + rect = &screen->base.geometry; + event.t = libinput_event_get_touch_event(generic_event); + time = libinput_event_touch_get_time(event.t); + slot = libinput_event_touch_get_seat_slot(event.t); + x = wl_fixed_from_double(libinput_event_touch_get_x_transformed(event.t, rect->width)); + y = wl_fixed_from_double(libinput_event_touch_get_y_transformed(event.t, rect->height)); + touch_handle_motion(seat->base.touch, time, slot, x, y); + break; + case LIBINPUT_EVENT_TOUCH_CANCEL: + event.t = libinput_event_get_touch_event(generic_event); + time = libinput_event_touch_get_time(event.t); + slot = libinput_event_touch_get_seat_slot(event.t); + touch_handle_cancel(seat->base.touch, time); + break; + case LIBINPUT_EVENT_TOUCH_FRAME: + event.t = libinput_event_get_touch_event(generic_event); + time = libinput_event_touch_get_time(event.t); + touch_handle_frame(seat->base.touch, time); + break; default: break; } @@ -413,11 +454,19 @@ seat_create(struct wl_display *display, const char *seat_name) } seat->base.pointer = &seat->pointer; - if (!initialize_libinput(seat)) + seat->base.touch = touch_create(); + if (!seat->base.touch) { + ERROR("Could not initialize touch\n"); goto error6; + } + + if (!initialize_libinput(seat)) + goto error7; return &seat->base; +error7: + touch_destroy(seat->base.touch); error6: pointer_finalize(&seat->pointer); error5: diff --git a/libswc/seat.h b/libswc/seat.h @@ -29,6 +29,7 @@ struct wl_display; struct swc_seat { struct pointer *pointer; struct keyboard *keyboard; + struct touch *touch; struct data_device *data_device; }; diff --git a/libswc/swc.c b/libswc/swc.c @@ -38,6 +38,7 @@ #include "shell.h" #include "shm.h" #include "subcompositor.h" +#include "touch.h" #include "util.h" #include "window.h" #include "xdg_decoration.h" @@ -77,6 +78,7 @@ setup_compositor(void) wl_list_insert(&swc.seat->pointer->handlers, &swc.compositor->pointer_handler->link); wl_list_insert(&swc.seat->pointer->handlers, &screens_pointer_handler.link); wl_signal_add(&swc.seat->pointer->focus.event_signal, &window_enter_listener); + wl_list_insert(&swc.seat->touch->handlers, &swc.compositor->touch_handler->link); /* Calculate pointer region */ pixman_region32_init(&pointer_region); diff --git a/libswc/touch.c b/libswc/touch.c @@ -0,0 +1,103 @@ +#include <wayland-server.h> + +#include "touch.h" +#include "util.h" + +void +touch_handle_down(struct touch *touch, uint32_t time, int32_t slot, uint32_t x, uint32_t y) +{ + struct touch_handler *handler; + + wl_list_for_each (handler, &touch->handlers, link) { + + if (handler->down && handler->down(handler, time, slot, x, y)) + break; + } +} + +void +touch_handle_up(struct touch *touch, uint32_t time, int32_t slot) +{ + struct touch_handler *handler; + + wl_list_for_each (handler, &touch->handlers, link) { + if (handler->up && handler->up(handler, time, slot)) + break; + } +} + +void +touch_handle_motion(struct touch *touch, uint32_t time, int32_t slot, uint32_t x, uint32_t y) +{ + struct touch_handler *handler; + + wl_list_for_each (handler, &touch->handlers, link) { + if (handler->motion && handler->motion(handler, time, slot, x, y)) + break; + } +} + +void +touch_handle_frame(struct touch *touch, uint32_t time) +{ + struct touch_handler *handler; + + wl_list_for_each (handler, &touch->handlers, link) { + if (handler->frame && handler->frame(handler, time)) + break; + } +} + +void +touch_handle_cancel(struct touch *touch, uint32_t time) +{ + struct touch_handler *handler; + + wl_list_for_each (handler, &touch->handlers, link) { + if (handler->cancel && handler->cancel(handler, time)) + break; + } +} + +void +touch_destroy(struct touch *touch) +{ + wl_array_release(&touch->points); + /* TODO free handlers? */ + free(touch); +} + +struct touch * +touch_create() +{ + struct touch *touch; + + touch = malloc(sizeof(*touch)); + if (!touch) + goto error0; + + wl_list_init(&touch->handlers); + wl_array_init(&touch->points); + + return touch; + +error0: + return NULL; +} + +static const struct wl_touch_interface touch_impl = { + .release = destroy_resource +}; + +struct wl_resource * +touch_bind(struct touch *touch, struct wl_client *client, uint32_t version, uint32_t id) +{ + struct wl_resource *client_resource; + + client_resource = wl_resource_create(client, &wl_touch_interface, version, id); + if (!client_resource) + return NULL; + wl_resource_set_implementation(client_resource, &touch_impl, touch, NULL); + + return client_resource; +} diff --git a/libswc/touch.h b/libswc/touch.h @@ -0,0 +1,32 @@ +#ifndef SWC_TOUCH_H +#define SWC_TOUCH_H + +struct touch_handler { + bool (*down)(struct touch_handler *handler, uint32_t time, int32_t slot, wl_fixed_t x, wl_fixed_t y); + bool (*up)(struct touch_handler *handler, uint32_t time, int32_t slot); + bool (*motion)(struct touch_handler *handler, uint32_t time, int32_t slot, wl_fixed_t x, wl_fixed_t y); + bool (*frame)(struct touch_handler *handler, uint32_t time); + bool (*cancel)(struct touch_handler *handler, uint32_t time); + + struct wl_list link; +}; + +struct point { + wl_fixed_t x, y; +}; + +struct touch { + struct wl_list handlers; + struct wl_array points; +}; + +void touch_handle_down(struct touch *touch, uint32_t time, int32_t slot, uint32_t x, uint32_t y); +void touch_handle_up(struct touch *touch, uint32_t time, int32_t slot); +void touch_handle_motion(struct touch *touch, uint32_t time, int32_t slot, uint32_t x, uint32_t y); +void touch_handle_frame(struct touch *touch, uint32_t time); +void touch_handle_cancel(struct touch *touch, uint32_t time); +void touch_destroy(struct touch *touch); +struct touch *touch_create(); +struct wl_resource *touch_bind(struct touch *touch, struct wl_client *client, uint32_t version, uint32_t id); + +#endif