From b55ac8623425da31ac709e50aa740051110ab2d8 Mon Sep 17 00:00:00 2001 From: Duna Oh Date: Wed, 20 Apr 2022 20:57:38 +0900 Subject: [PATCH] Add ds_touch Change-Id: I8236a20c3b29dfcca82e8d5734858dce94bb17ad --- include/libds/input_device.h | 5 ++ include/libds/interfaces/input_device.h | 2 + include/libds/interfaces/touch.h | 30 +++++++++ include/libds/touch.h | 46 +++++++++++++ src/examples/tinyds.c | 76 +++++++++++++++++++++ src/libds/backend/wayland/backend.h | 8 +++ src/libds/backend/wayland/seat.c | 113 ++++++++++++++++++++++++++++++++ src/libds/input_device.c | 12 ++++ src/libds/meson.build | 1 + src/libds/touch.c | 55 ++++++++++++++++ 10 files changed, 348 insertions(+) create mode 100644 include/libds/interfaces/touch.h create mode 100644 include/libds/touch.h create mode 100644 src/libds/touch.c diff --git a/include/libds/input_device.h b/include/libds/input_device.h index 6143e00..1a3652b 100644 --- a/include/libds/input_device.h +++ b/include/libds/input_device.h @@ -7,6 +7,8 @@ struct ds_pointer; struct ds_keyboard; +struct ds_touch; + enum ds_button_state { DS_BUTTON_RELEASED, @@ -29,6 +31,9 @@ ds_input_device_get_pointer(struct ds_input_device *dev); struct ds_keyboard * ds_input_device_get_keyboard(struct ds_input_device *dev); +struct ds_touch * +ds_input_device_get_touch(struct ds_input_device *dev); + void ds_input_device_add_destroy_listener(struct ds_input_device *dev, struct wl_listener *listener); diff --git a/include/libds/interfaces/input_device.h b/include/libds/interfaces/input_device.h index 7828503..e39fecc 100644 --- a/include/libds/interfaces/input_device.h +++ b/include/libds/interfaces/input_device.h @@ -5,6 +5,7 @@ #include #include #include +#include struct ds_input_device_interface { @@ -24,6 +25,7 @@ struct ds_input_device void *_device; struct ds_pointer *pointer; struct ds_keyboard *keyboard; + struct ds_touch *touch; }; struct { diff --git a/include/libds/interfaces/touch.h b/include/libds/interfaces/touch.h new file mode 100644 index 0000000..25ff4e6 --- /dev/null +++ b/include/libds/interfaces/touch.h @@ -0,0 +1,30 @@ +#ifndef LIBDS_INTERFACES_TOUCH_H +#define LIBDS_INTERFACES_TOUCH_H + +#include + +struct ds_touch; + +struct ds_touch_interface +{ + void (*destroy)(struct ds_touch *touch); +}; + +struct ds_touch +{ + const struct ds_touch_interface *iface; + + struct { + struct wl_signal down; + struct wl_signal up; + struct wl_signal motion; + struct wl_signal frame; + } events; +}; + +void ds_touch_init(struct ds_touch *touch, + const struct ds_touch_interface *iface); + +void ds_touch_destroy(struct ds_touch *touch); + +#endif diff --git a/include/libds/touch.h b/include/libds/touch.h new file mode 100644 index 0000000..4b69b90 --- /dev/null +++ b/include/libds/touch.h @@ -0,0 +1,46 @@ +#ifndef LIBDS_TOUCH_H +#define LIBDS_TOUCH_H + +#include +#include +#include + +struct ds_touch; + +struct ds_event_touch_down +{ + struct ds_input_device *device; + uint32_t time_msec; + //wl_surface surface; + uint32_t id; + double x, y; +}; + +struct ds_event_touch_up +{ + struct ds_input_device *device; + uint32_t time_msec; + uint32_t id; +}; + +struct ds_event_touch_motion +{ + struct ds_input_device *device; + uint32_t time_msec; + uint32_t id; + double x, y; +}; + +void ds_touch_add_down_listener(struct ds_touch *touch, + struct wl_listener *listener); + +void ds_touch_add_up_listener(struct ds_touch *touch, + struct wl_listener *listener); + +void ds_touch_add_motion_listener(struct ds_touch *touch, + struct wl_listener *listener); + +void ds_touch_add_frame_listener(struct ds_touch *touch, + struct wl_listener *listener); + +#endif diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index cfa55a6..61366fb 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -19,6 +19,7 @@ #include #include #include +#include #define TINYDS_UNUSED __attribute__((unused)) @@ -36,6 +37,17 @@ struct tinyds_keyboard struct wl_listener key; }; +struct tinyds_touch +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener down; + struct wl_listener up; + struct wl_listener motion; +}; + struct tinyds_output { struct tinyds_server *server; @@ -539,6 +551,67 @@ server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) } static void +touch_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_touch *touch; + + touch = wl_container_of(listener, touch, destroy); + + ds_inf("Touch(%p) destroyed", touch); + + wl_list_remove(&touch->destroy.link); + wl_list_remove(&touch->down.link); + wl_list_remove(&touch->up.link); + wl_list_remove(&touch->motion.link); + + free(touch); +} + +static void +touch_handle_down(struct wl_listener *listener, void *data) +{ + ds_inf("Touch device(%p): down", data); +} + +static void +touch_handle_up(struct wl_listener *listener, void *data) +{ + ds_inf("Touch device(%p): up", data); +} + +static void +touch_handle_motion(struct wl_listener *listener, void *data) +{ + ds_inf("Touch device(%p): motion", data); +} + +static void +server_add_touch(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_touch *touch; + + touch = calloc(1, sizeof *touch); + assert(touch); + + touch->dev = dev; + touch->server = server; + + touch->destroy.notify = touch_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &touch->destroy); + + touch->down.notify = touch_handle_down; + ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down); + + touch->up.notify = touch_handle_up; + ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up); + + touch->motion.notify = touch_handle_motion; + ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion); + + ds_inf("Touch(%p) added", touch); +} + +static void server_handle_new_input(struct wl_listener *listener, void *data) { struct tinyds_server *server; @@ -552,6 +625,9 @@ server_handle_new_input(struct wl_listener *listener, void *data) case DS_INPUT_DEVICE_KEYBOARD: server_add_keyboard(server, dev); break; + case DS_INPUT_DEVICE_TOUCH: + server_add_touch(server, dev); + break; default: ds_err("Unknown type(%d) of ds_input_device", dev_type); break; diff --git a/src/libds/backend/wayland/backend.h b/src/libds/backend/wayland/backend.h index c35f7d1..804fa22 100644 --- a/src/libds/backend/wayland/backend.h +++ b/src/libds/backend/wayland/backend.h @@ -6,6 +6,7 @@ #include "libds/interfaces/input_device.h" #include "libds/interfaces/pointer.h" #include "libds/interfaces/keyboard.h" +#include "libds/interfaces/touch.h" struct ds_wl_backend_server { @@ -111,6 +112,13 @@ struct ds_wl_keyboard struct wl_keyboard *wl_keyboard; }; +struct ds_wl_touch +{ + struct ds_touch base; + + struct wl_touch *wl_touch; +}; + struct ds_wl_backend * wl_backend_from_backend(struct ds_backend *backend); diff --git a/src/libds/backend/wayland/seat.c b/src/libds/backend/wayland/seat.c index 966bf77..6948efc 100644 --- a/src/libds/backend/wayland/seat.c +++ b/src/libds/backend/wayland/seat.c @@ -9,6 +9,7 @@ #include "libds/log.h" #include "libds/pointer.h" +#include "libds/touch.h" #include "util.h" #include "backend.h" @@ -29,6 +30,7 @@ create_wl_input_device(struct ds_wl_seat *seat, enum ds_input_device_type type); static struct ds_pointer *create_wl_pointer(struct ds_wl_seat *seat); static struct ds_keyboard *create_wl_keyboard(struct ds_wl_seat *seat); +static struct ds_touch *create_wl_touch(struct ds_wl_seat *seat); struct ds_wl_seat * create_wl_seat(struct ds_wl_backend *backend, uint32_t id, @@ -171,6 +173,9 @@ seat_update_capabilities(struct ds_wl_seat *seat, enum wl_seat_capability caps) ds_dbg("wl_backend: Seat(%p) offered touch", seat); seat->touch_dev = create_wl_input_device(seat, DS_INPUT_DEVICE_TOUCH); + seat->touch_dev->touch = create_wl_touch(seat); + wl_signal_emit(&seat->backend->base.events.new_input, + seat->touch_dev); } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch_dev != NULL) { @@ -601,3 +606,111 @@ create_wl_keyboard(struct ds_wl_seat *seat) return &keyboard->base; } + +static const struct ds_touch_interface touch_iface; + +static struct ds_wl_touch * +get_wl_touch_from_touch(struct ds_touch *ds_touch) +{ + assert(ds_touch->iface == &touch_iface); + return (struct ds_wl_touch *)ds_touch; +} + +static void +touch_iface_destroy(struct ds_touch *ds_touch) +{ + struct ds_wl_touch *touch; + + touch = get_wl_touch_from_touch(ds_touch); + + wl_touch_release(touch->wl_touch); + + free(touch); +} + +static const struct ds_touch_interface touch_iface = { + .destroy = touch_iface_destroy, +}; + +static void +touch_handle_down(void *data, struct wl_touch *wl_touch, + uint32_t serial, uint32_t time, + struct wl_surface *surface, int32_t id, + wl_fixed_t fixed_x, wl_fixed_t fixed_y) +{ + struct ds_wl_seat *seat = data; + + ds_dbg("wl_touch: down"); + + struct ds_event_touch_down event = { + .device = seat->touch_dev, + .id = id, + .x = fixed_x, + .y = fixed_y, + }; + + wl_signal_emit(&seat->touch_dev->touch->events.down, &event); +} + +static void +touch_handle_up(void *data, struct wl_touch *wl_touch, + uint32_t serial, uint32_t time, int32_t id) +{ + struct ds_wl_seat *seat = data; + + ds_dbg("wl_touch: up"); + + struct ds_event_touch_up event = { + .device = seat->touch_dev, + .id = id, + }; + + wl_signal_emit(&seat->touch_dev->touch->events.up, &event); +} + +static void +touch_handle_motion(void *data, struct wl_touch *wl_touch, + uint32_t time, int32_t id, + wl_fixed_t fixed_x, wl_fixed_t fixed_y) +{ + ds_dbg("wl_touch: motion"); +} + +static void +touch_handle_frame(void *data, struct wl_touch *wl_touch) +{ + ds_dbg("wl_touch: frame"); +} + +static void +touch_handle_cancel(void *data, struct wl_touch *wl_touch) +{ + ds_dbg("wl_touch: cancel"); +} + +static const struct wl_touch_listener wl_touch_listener = { + .down = touch_handle_down, + .up = touch_handle_up, + .motion = touch_handle_motion, + .frame = touch_handle_frame, + .cancel = touch_handle_cancel, +}; + +static struct ds_touch * +create_wl_touch(struct ds_wl_seat *seat) +{ + struct ds_wl_touch *touch; + + touch = calloc(1, sizeof *touch); + if (!touch) { + ds_err("Could not allocate memory"); + return NULL; + } + + ds_touch_init(&touch->base, &touch_iface); + + touch->wl_touch = wl_seat_get_touch(seat->wl_seat); + wl_touch_add_listener(touch->wl_touch, &wl_touch_listener, seat); + + return &touch->base; +} diff --git a/src/libds/input_device.c b/src/libds/input_device.c index 351361f..ad18e71 100644 --- a/src/libds/input_device.c +++ b/src/libds/input_device.c @@ -7,6 +7,7 @@ #include "libds/interfaces/input_device.h" #include "libds/interfaces/pointer.h" #include "libds/interfaces/keyboard.h" +#include "libds/interfaces/touch.h" WL_EXPORT enum ds_input_device_type ds_input_device_get_type(struct ds_input_device *dev) @@ -36,6 +37,17 @@ ds_input_device_get_keyboard(struct ds_input_device *dev) return dev->keyboard; } +WL_EXPORT struct ds_touch * +ds_input_device_get_touch(struct ds_input_device *dev) +{ + if (dev->type != DS_INPUT_DEVICE_TOUCH) { + ds_err("Given ds_input_device is not a touch device"); + return NULL; + } + + return dev->touch; +} + WL_EXPORT void ds_input_device_add_destroy_listener(struct ds_input_device *dev, struct wl_listener *listener) diff --git a/src/libds/meson.build b/src/libds/meson.build index 4d1ae39..be07132 100644 --- a/src/libds/meson.build +++ b/src/libds/meson.build @@ -21,6 +21,7 @@ libds_files = [ 'input_device.c', 'pointer.c', 'keyboard.c', + 'touch.c', ] protocols = { diff --git a/src/libds/touch.c b/src/libds/touch.c new file mode 100644 index 0000000..72a3660 --- /dev/null +++ b/src/libds/touch.c @@ -0,0 +1,55 @@ +#include +#include +#include "libds/interfaces/touch.h" + +void +ds_touch_init(struct ds_touch *touch, + const struct ds_touch_interface *iface) +{ + touch->iface = iface; + + wl_signal_init(&touch->events.down); + wl_signal_init(&touch->events.up); + wl_signal_init(&touch->events.motion); + wl_signal_init(&touch->events.frame); +} + +void +ds_touch_destroy(struct ds_touch *touch) +{ + if (!touch) + return; + + if (touch->iface && touch->iface->destroy) + touch->iface->destroy(touch); + else + free(touch); +} + +WL_EXPORT void +ds_touch_add_down_listener(struct ds_touch *touch, + struct wl_listener *listener) +{ + wl_signal_add(&touch->events.down, listener); +} + +WL_EXPORT void +ds_touch_add_up_listener(struct ds_touch *touch, + struct wl_listener *listener) +{ + wl_signal_add(&touch->events.up, listener); +} + +WL_EXPORT void +ds_touch_add_motion_listener(struct ds_touch *touch, + struct wl_listener *listener) +{ + wl_signal_add(&touch->events.motion, listener); +} + +WL_EXPORT void +ds_touch_add_frame_listener(struct ds_touch *touch, + struct wl_listener *listener) +{ + wl_signal_add(&touch->events.frame, listener); +} -- 2.7.4