From 6a33ab528956933deb2c90467e5762b33a7e0ae6 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 15 Apr 2022 16:11:57 +0900 Subject: [PATCH 01/16] Add missing header for alloca Change-Id: I87ff3dbbfe27a387c835ca2602b011e3dd866733 --- src/libds/backend/wayland/seat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libds/backend/wayland/seat.c b/src/libds/backend/wayland/seat.c index b799e66..c569947 100644 --- a/src/libds/backend/wayland/seat.c +++ b/src/libds/backend/wayland/seat.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "libds/log.h" -- 2.7.4 From cbae7a73a2da444633c693dd64fec6ef81ab0c14 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 18 Apr 2022 10:29:23 +0900 Subject: [PATCH 02/16] Add ds_keyboard A ds_keyboard is for abstracting phisical keyboard device. Change-Id: I382ea96db01679f036283b213c4e540e36687c9d --- include/libds/input_device.h | 5 + include/libds/interfaces/input_device.h | 2 + include/libds/interfaces/keyboard.h | 89 ++++++++++ include/libds/keyboard.h | 45 +++++ packaging/libds.spec | 1 + src/libds/input_device.c | 15 ++ src/libds/keyboard.c | 304 ++++++++++++++++++++++++++++++++ src/libds/meson.build | 5 + src/libds/util.h | 3 + src/libds/util/shm.c | 76 +++++++- 10 files changed, 544 insertions(+), 1 deletion(-) create mode 100644 include/libds/interfaces/keyboard.h create mode 100644 include/libds/keyboard.h create mode 100644 src/libds/keyboard.c diff --git a/include/libds/input_device.h b/include/libds/input_device.h index 45e125b..6143e00 100644 --- a/include/libds/input_device.h +++ b/include/libds/input_device.h @@ -5,6 +5,8 @@ struct ds_input_device; struct ds_pointer; +struct ds_keyboard; + enum ds_button_state { DS_BUTTON_RELEASED, @@ -24,6 +26,9 @@ ds_input_device_get_type(struct ds_input_device *dev); struct ds_pointer * ds_input_device_get_pointer(struct ds_input_device *dev); +struct ds_keyboard * +ds_input_device_get_keyboard(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 f31594b..7828503 100644 --- a/include/libds/interfaces/input_device.h +++ b/include/libds/interfaces/input_device.h @@ -4,6 +4,7 @@ #include #include #include +#include struct ds_input_device_interface { @@ -22,6 +23,7 @@ struct ds_input_device union { void *_device; struct ds_pointer *pointer; + struct ds_keyboard *keyboard; }; struct { diff --git a/include/libds/interfaces/keyboard.h b/include/libds/interfaces/keyboard.h new file mode 100644 index 0000000..f68c9a7 --- /dev/null +++ b/include/libds/interfaces/keyboard.h @@ -0,0 +1,89 @@ +#ifndef LIBDS_INTERFACES_KEYBOARD_H +#define LIBDS_INTERFACES_KEYBOARD_H + +#include +#include + +#include + +#define DS_LED_COUNT 3 + +enum ds_keyboard_led { + DS_LED_NUM_LOCK = 1 << 0, + DS_LED_CAPS_LOCK = 1 << 1, + DS_LED_SCROLL_LOCK = 1 << 2, +}; + +#define DS_MODIFIER_COUNT 8 + +enum ds_keyboard_modifier { + DS_MODIFIER_SHIFT = 1 << 0, + DS_MODIFIER_CAPS = 1 << 1, + DS_MODIFIER_CTRL = 1 << 2, + DS_MODIFIER_ALT = 1 << 3, + DS_MODIFIER_MOD2 = 1 << 4, + DS_MODIFIER_MOD3 = 1 << 5, + DS_MODIFIER_LOGO = 1 << 6, + DS_MODIFIER_MOD5 = 1 << 7, +}; + +#define DS_KEYBOARD_KEYS_CAP 32 + +struct ds_keyboard; + +struct ds_keyboard_interface +{ + void (*destroy)(struct ds_keyboard *keyboard); +}; + +struct ds_keyboard_modifiers +{ + xkb_mod_mask_t depressed; + xkb_mod_mask_t latched; + xkb_mod_mask_t locked; + xkb_mod_mask_t group; +}; + +struct ds_keyboard +{ + const struct ds_keyboard_interface *iface; + + char *keymap_string; + size_t keymap_size; + int keymap_fd; + struct xkb_keymap *keymap; + struct xkb_state *xkb_state; + xkb_led_index_t led_indexes[DS_LED_COUNT]; + xkb_mod_index_t mod_indexes[DS_MODIFIER_COUNT]; + + uint32_t keycodes[DS_KEYBOARD_KEYS_CAP]; + size_t num_keycodes; + struct ds_keyboard_modifiers modifiers; + + struct { + int32_t rate; + int32_t delay; + } repeat_info; + + struct { + struct wl_signal destroy; + struct wl_signal key; + struct wl_signal modifiers; + struct wl_signal keymap; + struct wl_signal repeat_info; + } events; +}; + +void ds_keyboard_init(struct ds_keyboard *keyboard, + const struct ds_keyboard_interface *iface); + +void ds_keyboard_destroy(struct ds_keyboard *keyboard); + +void ds_keyboard_notify_key(struct ds_keyboard *keyboard, + struct ds_event_keyboard_key *event); + +void ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard, + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group); + +#endif diff --git a/include/libds/keyboard.h b/include/libds/keyboard.h new file mode 100644 index 0000000..e226cb4 --- /dev/null +++ b/include/libds/keyboard.h @@ -0,0 +1,45 @@ +#ifndef LIBDS_KEYBOARD_H +#define LIBDS_KEYBOARD_H + +#include +#include + +#include +#include + +struct ds_keyboard; + +struct ds_event_keyboard_key +{ + uint32_t time_msec; + uint32_t keycode; + bool update_state; + enum wl_keyboard_key_state state; +}; + +bool ds_keyboard_set_keymap(struct ds_keyboard *keyboard, + struct xkb_keymap *keymap); + +void ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard, + int32_t rate, int32_t delay); + +uint32_t ds_keyboard_get_modifiers(struct ds_keyboard *keyboard); + +struct xkb_state *ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard); + +void ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener); + +void ds_keyboard_add_key_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener); + +void ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener); + +void ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener); + +void ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener); + +#endif diff --git a/packaging/libds.spec b/packaging/libds.spec index 879a87d..806c75b 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -13,6 +13,7 @@ BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-protocols) BuildRequires: pkgconfig(pixman-1) BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(xkbcommon) BuildRequires: pkgconfig(libtdm) BuildRequires: pkgconfig(libtbm) diff --git a/src/libds/input_device.c b/src/libds/input_device.c index db84100..351361f 100644 --- a/src/libds/input_device.c +++ b/src/libds/input_device.c @@ -6,6 +6,7 @@ #include "libds/log.h" #include "libds/interfaces/input_device.h" #include "libds/interfaces/pointer.h" +#include "libds/interfaces/keyboard.h" WL_EXPORT enum ds_input_device_type ds_input_device_get_type(struct ds_input_device *dev) @@ -24,6 +25,17 @@ ds_input_device_get_pointer(struct ds_input_device *dev) return dev->pointer; } +WL_EXPORT struct ds_keyboard * +ds_input_device_get_keyboard(struct ds_input_device *dev) +{ + if (dev->type != DS_INPUT_DEVICE_KEYBOARD) { + ds_err("Given ds_input_device is not a keyboard device"); + return NULL; + } + + return dev->keyboard; +} + WL_EXPORT void ds_input_device_add_destroy_listener(struct ds_input_device *dev, struct wl_listener *listener) @@ -54,6 +66,9 @@ ds_input_device_destroy(struct ds_input_device *dev) case DS_INPUT_DEVICE_POINTER: ds_pointer_destroy(dev->pointer); break; + case DS_INPUT_DEVICE_KEYBOARD: + ds_keyboard_destroy(dev->keyboard); + break; default: ds_err("Warning: leaking memory %p %p %d", dev->_device, dev, dev->type); diff --git a/src/libds/keyboard.c b/src/libds/keyboard.c new file mode 100644 index 0000000..d122e81 --- /dev/null +++ b/src/libds/keyboard.c @@ -0,0 +1,304 @@ +#include +#include +#include +#include + +#include + +#include "libds/log.h" +#include "libds/interfaces/keyboard.h" +#include "util.h" + +static bool keyboard_modifier_update(struct ds_keyboard *keyboard); +static void keyboard_key_update(struct ds_keyboard *keyboard, + struct ds_event_keyboard_key *event); +static void keyboard_led_update(struct ds_keyboard *keyboard); + +WL_EXPORT bool +ds_keyboard_set_keymap(struct ds_keyboard *keyboard, struct xkb_keymap *keymap) +{ + char *tmp_keymap_string; + void *dst; + int rw_fd, ro_fd; + xkb_keycode_t keycode; + const char *led_names[DS_LED_COUNT] = { + XKB_LED_NAME_NUM, + XKB_LED_NAME_CAPS, + XKB_LED_NAME_SCROLL, + }; + const char *mod_names[DS_MODIFIER_COUNT] = { + XKB_MOD_NAME_SHIFT, + XKB_MOD_NAME_CAPS, + XKB_MOD_NAME_CTRL, + XKB_MOD_NAME_ALT, + XKB_MOD_NAME_NUM, + "Mod3", + XKB_MOD_NAME_LOGO, + "Mod5", + }; + + if (keyboard->keymap) + xkb_keymap_unref(keyboard->keymap); + + keyboard->keymap = xkb_keymap_ref(keymap); + + if (keyboard->xkb_state) + xkb_state_unref(keyboard->xkb_state); + + keyboard->xkb_state = xkb_state_new(keyboard->keymap); + if (!keyboard->xkb_state) { + ds_err("Failed to create XKB state"); + goto err_state; + } + + for (size_t i = 0; i < DS_LED_COUNT; i++) { + keyboard->led_indexes[i] = + xkb_map_led_get_index(keyboard->keymap, led_names[i]); + } + + for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) { + keyboard->mod_indexes[i] = + xkb_map_mod_get_index(keyboard->keymap, mod_names[i]); + } + + tmp_keymap_string = xkb_keymap_get_as_string(keyboard->keymap, + XKB_KEYMAP_FORMAT_TEXT_V1); + if (!tmp_keymap_string) { + ds_err("Failed to get string version of keymap"); + goto err_keymap_string; + } + + if (keyboard->keymap_string) + free(keyboard->keymap_string); + keyboard->keymap_string = tmp_keymap_string; + keyboard->keymap_size = strlen(keyboard->keymap_string) + 1; + + if (!allocate_shm_file_pair(keyboard->keymap_size, &rw_fd, &ro_fd)) { + ds_err("Failed to allocate shm_file for keymap"); + goto err_shm_file; + } + + dst = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE, + MAP_SHARED, rw_fd, 0); + if (dst == MAP_FAILED) { + ds_log_errno(DS_ERR, "mmap failed"); + goto err_mmap; + } + + memcpy(dst, keyboard->keymap_string, keyboard->keymap_size); + munmap(dst, keyboard->keymap_size); + close(rw_fd); + + if (keyboard->keymap_fd >= 0) + close(keyboard->keymap_fd); + keyboard->keymap_fd = ro_fd; + + for (size_t i = 0; i < keyboard->num_keycodes; i++) { + keycode = keyboard->keycodes[i] + 8; + xkb_state_update_key(keyboard->xkb_state, keycode, XKB_KEY_DOWN); + } + + keyboard_modifier_update(keyboard); + + wl_signal_emit(&keyboard->events.keymap, keyboard); + + return true; + +err_mmap: + close(rw_fd); + close(ro_fd); +err_shm_file: + free(keyboard->keymap_string); + keyboard->keymap_string = NULL; +err_keymap_string: + xkb_state_unref(keyboard->xkb_state); + keyboard->xkb_state = NULL; +err_state: + xkb_keymap_unref(keymap); + keyboard->keymap = NULL; + + return false; +} + +WL_EXPORT void +ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard, + int32_t rate, int32_t delay) +{ + if (keyboard->repeat_info.rate == rate && + keyboard->repeat_info.delay == delay) + return; + keyboard->repeat_info.rate = rate; + keyboard->repeat_info.delay = delay; + + wl_signal_emit(&keyboard->events.repeat_info, keyboard); +} + +WL_EXPORT uint32_t +ds_keyboard_get_modifiers(struct ds_keyboard *keyboard) +{ + xkb_mod_mask_t mask; + uint32_t modifiers = 0; + + mask = keyboard->modifiers.depressed | keyboard->modifiers.latched; + for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) { + if (keyboard->mod_indexes[i] != XKB_MOD_INVALID && + (mask & (1 << keyboard->mod_indexes[i]))) + modifiers |= (1 << i); + } + + return modifiers; +} + +WL_EXPORT struct xkb_state * +ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard) +{ + return keyboard->xkb_state; +} + +WL_EXPORT void +ds_keyboard_notify_key(struct ds_keyboard *keyboard, + struct ds_event_keyboard_key *event) +{ + uint32_t keycode; + enum xkb_key_direction dir; + bool updated; + + keyboard_key_update(keyboard, event); + + wl_signal_emit(&keyboard->events.key, event); + + if (!keyboard->xkb_state) + return; + + if (event->update_state) { + keycode = event->keycode + 8; + dir = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) ? + XKB_KEY_DOWN : XKB_KEY_UP; + xkb_state_update_key(keyboard->xkb_state, keycode, dir); + } + + updated = keyboard_modifier_update(keyboard); + if (updated) + wl_signal_emit(&keyboard->events.modifiers, keyboard); + + keyboard_led_update(keyboard); +} + +WL_EXPORT void +ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard, + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + bool updated; + + if (!keyboard->xkb_state) + return; + + xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); + + updated = keyboard_modifier_update(keyboard); + if (updated) + wl_signal_emit(&keyboard->events.modifiers, keyboard); + + keyboard_led_update(keyboard); +} + +WL_EXPORT void +ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener) +{ + wl_signal_add(&keyboard->events.destroy, listener); +} + +WL_EXPORT void +ds_keyboard_add_key_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener) +{ + wl_signal_add(&keyboard->events.key, listener); +} + +WL_EXPORT void +ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener) +{ + wl_signal_add(&keyboard->events.modifiers, listener); +} + +WL_EXPORT void +ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener) +{ + wl_signal_add(&keyboard->events.keymap, listener); +} + +WL_EXPORT void +ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard, + struct wl_listener *listener) +{ + wl_signal_add(&keyboard->events.repeat_info, listener); +} + +void +ds_keyboard_init(struct ds_keyboard *keyboard, + const struct ds_keyboard_interface *iface) +{ + keyboard->iface = iface; + keyboard->keymap_fd = -1; + + wl_signal_init(&keyboard->events.destroy); + wl_signal_init(&keyboard->events.key); + wl_signal_init(&keyboard->events.modifiers); + wl_signal_init(&keyboard->events.keymap); + wl_signal_init(&keyboard->events.repeat_info); +} + +void +ds_keyboard_destroy(struct ds_keyboard *keyboard) +{ + if (keyboard->iface && keyboard->iface->destroy) + keyboard->iface->destroy(keyboard); + else + free(keyboard); +} + +static bool +keyboard_modifier_update(struct ds_keyboard *keyboard) +{ + xkb_mod_mask_t depressed, latched, locked, group; + + if (!keyboard->xkb_state) + return false; + + depressed = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_DEPRESSED); + latched = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_LATCHED); + locked = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_LOCKED); + group = xkb_state_serialize_layout(keyboard->xkb_state, + XKB_STATE_LAYOUT_EFFECTIVE); + if (depressed == keyboard->modifiers.depressed && + latched == keyboard->modifiers.latched && + locked == keyboard->modifiers.locked && + group == keyboard->modifiers.group) + return false; + + keyboard->modifiers.depressed = depressed; + keyboard->modifiers.latched = latched; + keyboard->modifiers.locked = locked; + keyboard->modifiers.group = group; + + return true; +} + +static void keyboard_key_update(struct ds_keyboard *keyboard, + struct ds_event_keyboard_key *event) +{ + // TODO +} + +static void keyboard_led_update(struct ds_keyboard *keyboard) +{ + // TODO +} diff --git a/src/libds/meson.build b/src/libds/meson.build index a08dfdc..4d1ae39 100644 --- a/src/libds/meson.build +++ b/src/libds/meson.build @@ -20,6 +20,7 @@ libds_files = [ 'backend.c', 'input_device.c', 'pointer.c', + 'keyboard.c', ] protocols = { @@ -52,12 +53,16 @@ math = meson.get_compiler('c').find_library('m') wayland_server = dependency('wayland-server', required: true) pixman = dependency('pixman-1', required: true) libdrm = dependency('libdrm', required: true) +xkbcommon = dependency('xkbcommon', required: true) +rt = meson.get_compiler('c').find_library('rt') libds_deps = [ math, wayland_server, pixman, libdrm, + xkbcommon, + rt, ] subdir('backend') diff --git a/src/libds/util.h b/src/libds/util.h index 3b7448b..1c9326a 100644 --- a/src/libds/util.h +++ b/src/libds/util.h @@ -10,4 +10,7 @@ timespec_to_msec(const struct timespec *a); int allocate_shm_file(size_t size); +bool +allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr); + #endif diff --git a/src/libds/util/shm.c b/src/libds/util/shm.c index c8c84e3..4abd229 100644 --- a/src/libds/util/shm.c +++ b/src/libds/util/shm.c @@ -24,13 +24,18 @@ */ #define _POSIX_C_SOURCE 200809L - +#include #include #include #include #include #include +#include #include +#include +#include + +#define RANDNAME_PATTERN "/libds-XXXXXX" int os_fd_set_cloexec(int fd) @@ -172,3 +177,72 @@ allocate_shm_file(off_t size) return fd; } + +static void +randname(char *buf) +{ + struct timespec ts; + long r; + + clock_gettime(CLOCK_REALTIME, &ts); + r = ts.tv_nsec; + for (int i = 0; i < 6; i++) { + buf[i] = 'A' + (r & 15) + (r & 16) * 2; + r >>= 5; + } +} + +static int +excl_shm_open(char *name) +{ + int retries = 100; + int fd; + + do { + randname(name + strlen(RANDNAME_PATTERN) - 6); + + --retries; + + fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd >= 0) + return fd; + } while (retries > 0 && errno == EEXIST); + + return -1; +} + +bool +allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr) +{ + char name[] = RANDNAME_PATTERN; + int rw_fd, ro_fd; + int ret; + + rw_fd = excl_shm_open(name); + if (rw_fd < 0) + return false; + + ro_fd = shm_open(name, O_RDONLY, 0); + if (ro_fd < 0) { + shm_unlink(name); + close(rw_fd); + return false; + } + + shm_unlink(name); + + do { + ret = ftruncate(rw_fd, size); + } while (ret < 0 && errno == EINTR); + + if (ret < 0) { + close(rw_fd); + close(ro_fd); + return false; + } + + *rw_fd_ptr = rw_fd; + *ro_fd_ptr = ro_fd; + + return true; +} -- 2.7.4 From 22c42edd55619b8291c56d2710a57b73a38026f3 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 18 Apr 2022 10:33:19 +0900 Subject: [PATCH 03/16] backend/wayland: Support ds_keyboard Change-Id: I30a6a86e79f34abb22b789dee9ffe50d9d121a88 --- src/libds/backend/wayland/backend.h | 8 ++ src/libds/backend/wayland/seat.c | 196 ++++++++++++++++++++++++++++++++++++ src/libds/util.h | 3 + src/libds/util/time.c | 9 ++ 4 files changed, 216 insertions(+) diff --git a/src/libds/backend/wayland/backend.h b/src/libds/backend/wayland/backend.h index 12e594a..c35f7d1 100644 --- a/src/libds/backend/wayland/backend.h +++ b/src/libds/backend/wayland/backend.h @@ -5,6 +5,7 @@ #include "libds/interfaces/output.h" #include "libds/interfaces/input_device.h" #include "libds/interfaces/pointer.h" +#include "libds/interfaces/keyboard.h" struct ds_wl_backend_server { @@ -103,6 +104,13 @@ struct ds_wl_pointer struct wl_pointer *wl_pointer; }; +struct ds_wl_keyboard +{ + struct ds_keyboard base; + + struct wl_keyboard *wl_keyboard; +}; + 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 c569947..966bf77 100644 --- a/src/libds/backend/wayland/seat.c +++ b/src/libds/backend/wayland/seat.c @@ -3,11 +3,14 @@ #include #include #include +#include #include +#include #include "libds/log.h" #include "libds/pointer.h" +#include "util.h" #include "backend.h" #ifdef MIN @@ -25,6 +28,7 @@ static struct ds_input_device * 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); struct ds_wl_seat * create_wl_seat(struct ds_wl_backend *backend, uint32_t id, @@ -151,6 +155,10 @@ seat_update_capabilities(struct ds_wl_seat *seat, enum wl_seat_capability caps) seat->keyboard_dev = create_wl_input_device(seat, DS_INPUT_DEVICE_KEYBOARD); + seat->keyboard_dev->keyboard = create_wl_keyboard(seat); + + wl_signal_emit(&seat->backend->base.events.new_input, + seat->keyboard_dev); } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard_dev != NULL) { @@ -405,3 +413,191 @@ create_wl_pointer(struct ds_wl_seat *seat) return &pointer->base; } + +static const struct ds_keyboard_interface keyboard_iface; + +static struct ds_wl_keyboard * +get_wl_keyboard_from_keyboard(struct ds_keyboard *ds_keyboard) +{ + assert(ds_keyboard->iface == &keyboard_iface); + return (struct ds_wl_keyboard *)ds_keyboard; +} + +static void +keyboard_iface_destroy(struct ds_keyboard *ds_keyboard) +{ + struct ds_wl_keyboard *keyboard; + + keyboard = get_wl_keyboard_from_keyboard(ds_keyboard); + + wl_keyboard_release(keyboard->wl_keyboard); + + free(keyboard); +} + +static const struct ds_keyboard_interface keyboard_iface = { + .destroy = keyboard_iface_destroy, +}; + +static void +keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, + uint32_t format, int fd, uint32_t size) +{ + struct ds_wl_seat *seat = data; + struct xkb_context *context; + struct xkb_keymap *keymap; + char *map_str; + + ds_dbg("wl_keyboard: keymap"); + + if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) { + ds_log_errno(DS_ERR, "mmap failed"); + goto end; + } + + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + keymap = xkb_keymap_new_from_string(context, map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, 0); + munmap(map_str, size); + + if (!keymap) { + ds_err("Failed to compile keymap"); + goto end; + } + + ds_keyboard_set_keymap(seat->keyboard_dev->keyboard, keymap); + + xkb_keymap_unref(keymap); + xkb_context_unref(context); + } + + // TODO More case? + +end: + close(fd); +} + +static void +keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, + uint32_t serial, struct wl_surface *surface, struct wl_array *keys) +{ + struct ds_wl_seat *seat = data; + uint32_t *keycode_ptr; + uint32_t time; + + ds_dbg("wl_keyboard: enter"); + + time = get_current_time_msec(); + + wl_array_for_each(keycode_ptr, keys) { + struct ds_event_keyboard_key event = { + .keycode = *keycode_ptr, + .state = WL_KEYBOARD_KEY_STATE_PRESSED, + .time_msec = time, + .update_state = false, + }; + + ds_keyboard_notify_key(seat->keyboard_dev->keyboard, &event); + } +} + +static void +keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, + uint32_t serial, struct wl_surface *surface) +{ + struct ds_wl_seat *seat = data; + struct ds_keyboard *keyboard = seat->keyboard_dev->keyboard; + uint32_t *pressed; + uint32_t time, keycode; + size_t num_keycodes; + + ds_dbg("wl_keyboard: leave"); + + time = get_current_time_msec(); + + num_keycodes = keyboard->num_keycodes; + pressed = alloca(num_keycodes + 1); + memcpy(pressed, keyboard->keycodes, num_keycodes * sizeof(uint32_t)); + + for (size_t i = 0; i < num_keycodes; i++) { + keycode = pressed[i]; + + struct ds_event_keyboard_key event = { + .keycode = keycode, + .state = WL_KEYBOARD_KEY_STATE_RELEASED, + .time_msec = time, + .update_state = false, + }; + + ds_keyboard_notify_key(keyboard, &event); + } +} + +static void +keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + struct ds_wl_seat *seat = data; + + ds_dbg("wl_keyboard: key"); + + struct ds_event_keyboard_key event = { + .keycode = key, + .state = state, + .time_msec = time, + .update_state = false, + }; + + ds_keyboard_notify_key(seat->keyboard_dev->keyboard, &event); +} + +static void +keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, + uint32_t serial_in, uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) +{ + struct ds_wl_seat *seat = data; + + ds_dbg("wl_keyboard: modifiers"); + + ds_keyboard_notify_modifiers(seat->keyboard_dev->keyboard, + mods_depressed, mods_latched, mods_locked, group); +} + +static void +keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, + int32_t rate, int32_t delay) +{ + ds_dbg("wl_keyboard: repeat_info"); + + // This space is intentionally left blank +} + +static const struct wl_keyboard_listener wl_keyboard_listener = { + .keymap = keyboard_handle_keymap, + .enter = keyboard_handle_enter, + .leave = keyboard_handle_leave, + .key = keyboard_handle_key, + .modifiers = keyboard_handle_modifiers, + .repeat_info = keyboard_handle_repeat_info, +}; + +static struct ds_keyboard * +create_wl_keyboard(struct ds_wl_seat *seat) +{ + struct ds_wl_keyboard *keyboard; + + keyboard = calloc(1, sizeof *keyboard); + if (!keyboard) + return NULL; + + ds_keyboard_init(&keyboard->base, &keyboard_iface); + + keyboard->wl_keyboard = wl_seat_get_keyboard(seat->wl_seat); + wl_keyboard_add_listener(keyboard->wl_keyboard, + &wl_keyboard_listener, seat); + + return &keyboard->base; +} diff --git a/src/libds/util.h b/src/libds/util.h index 1c9326a..4603544 100644 --- a/src/libds/util.h +++ b/src/libds/util.h @@ -7,6 +7,9 @@ int64_t timespec_to_msec(const struct timespec *a); +uint32_t +get_current_time_msec(void); + int allocate_shm_file(size_t size); diff --git a/src/libds/util/time.c b/src/libds/util/time.c index afb0e89..2461cb7 100644 --- a/src/libds/util/time.c +++ b/src/libds/util/time.c @@ -8,3 +8,12 @@ timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; } + +uint32_t +get_current_time_msec(void) +{ + struct timespec now; + + clock_gettime(CLOCK_MONOTONIC, &now); + return timespec_to_msec(&now); +} -- 2.7.4 From 2026e03cbcc2076dad9418dc91330938e5078931 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 18 Apr 2022 10:35:14 +0900 Subject: [PATCH 04/16] examples: Rename pointer-test to input-device-test This patch also adds code for ds_keyboard in input-device-test. Change-Id: I0e37a9a11beca9c38afc51e6841a08330e4852ab --- .../{pointer-test.c => input-device-test.c} | 105 +++++++++++++++++++-- src/examples/meson.build | 4 +- 2 files changed, 101 insertions(+), 8 deletions(-) rename src/examples/{pointer-test.c => input-device-test.c} (70%) diff --git a/src/examples/pointer-test.c b/src/examples/input-device-test.c similarity index 70% rename from src/examples/pointer-test.c rename to src/examples/input-device-test.c index d669a03..237d0b5 100644 --- a/src/examples/pointer-test.c +++ b/src/examples/input-device-test.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,17 @@ struct pointer_device { struct wl_listener frame; }; +struct server; + +struct keyboard_device { + struct server *server; + struct ds_keyboard *ds_keyboard; + + struct wl_listener destroy; + struct wl_listener modifiers; + struct wl_listener key; +}; + struct output { struct server *server; @@ -202,20 +214,101 @@ add_pointer(struct ds_input_device *dev) } static void +keyboard_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct keyboard_device *keyboard; + + keyboard = wl_container_of(listener, keyboard, destroy); + + wl_list_remove(&keyboard->destroy.link); + wl_list_remove(&keyboard->modifiers.link); + wl_list_remove(&keyboard->key.link); + + free(keyboard); +} + +static void +keyboard_handle_modifiers(struct wl_listener *listener, void *data) +{ + struct keyboard_device *keyboard; + struct ds_keyboard *ds_keyboard = data; + + keyboard = wl_container_of(listener, keyboard, destroy); + + ds_inf("Keyboard(%p) event modifiers", ds_keyboard); +} + +static void +keyboard_handle_key(struct wl_listener *listener, void *data) +{ + struct ds_event_keyboard_key *event = data; + struct keyboard_device *keyboard; + struct xkb_state *xkb_state; + const xkb_keysym_t *syms; + int nsyms = 0; + + keyboard = wl_container_of(listener, keyboard, key); + + ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), " + "update_state(%d)", keyboard->ds_keyboard, + event->keycode, event->state, event->time_msec, + event->update_state); + + xkb_state = ds_keyboard_get_xkb_state(keyboard->ds_keyboard); + if (!xkb_state) + return; + + nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, &syms); + + for (int i = 0; i < nsyms; i++) { + if (syms[i] == XKB_KEY_Escape) + wl_display_terminate(keyboard->server->display); + } +} + +static void +add_keyboard(struct server *server, struct ds_input_device *dev) +{ + struct keyboard_device *keyboard; + + keyboard = calloc(1, sizeof *keyboard); + if (!keyboard) + return; + + keyboard->server = server; + keyboard->ds_keyboard = ds_input_device_get_keyboard(dev); + + ds_inf("Keyboard(%p) added", keyboard->ds_keyboard); + + keyboard->destroy.notify = keyboard_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &keyboard->destroy); + + keyboard->modifiers.notify = keyboard_handle_modifiers; + ds_keyboard_add_modifiers_listener(keyboard->ds_keyboard, + &keyboard->modifiers); + + keyboard->key.notify = keyboard_handle_key; + ds_keyboard_add_key_listener(keyboard->ds_keyboard, + &keyboard->key); +} + +static void handle_new_input(struct wl_listener *listener, void *data) { + struct server *server; struct ds_input_device *dev = data; enum ds_input_device_type type; type = ds_input_device_get_type(dev); - if (type != DS_INPUT_DEVICE_POINTER) - return; + ds_inf("New device(%p) type(%s)", dev, device_type_to_string(type)); - ds_inf("New pointer device(%p) type(%s)", dev, - device_type_to_string(type)); - - add_pointer(dev); + if (type == DS_INPUT_DEVICE_POINTER) + add_pointer(dev); + else if (type == DS_INPUT_DEVICE_KEYBOARD) { + server = wl_container_of(listener, server, new_input); + add_keyboard(server, dev); + } } static void diff --git a/src/examples/meson.build b/src/examples/meson.build index f19f139..c568eb6 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -23,9 +23,9 @@ executable('tinyds', install : true ) -executable('pointer-test', +executable('input-device-test', [ - 'pointer-test.c', + 'input-device-test.c', 'pixman-helper.c', ], dependencies: common_deps, -- 2.7.4 From 418c71edde3b957e493912cb04a00729b0e1575e Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 18 Apr 2022 10:37:06 +0900 Subject: [PATCH 05/16] Enable user to get keyboard modifiers input-device-test take modifiers into account when handling key. Change-Id: Iec87c300323d891e18873afcf9b1eabf886ee068 --- include/libds/interfaces/keyboard.h | 13 ------------- include/libds/keyboard.h | 13 +++++++++++++ src/examples/input-device-test.c | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/include/libds/interfaces/keyboard.h b/include/libds/interfaces/keyboard.h index f68c9a7..3602fe5 100644 --- a/include/libds/interfaces/keyboard.h +++ b/include/libds/interfaces/keyboard.h @@ -14,19 +14,6 @@ enum ds_keyboard_led { DS_LED_SCROLL_LOCK = 1 << 2, }; -#define DS_MODIFIER_COUNT 8 - -enum ds_keyboard_modifier { - DS_MODIFIER_SHIFT = 1 << 0, - DS_MODIFIER_CAPS = 1 << 1, - DS_MODIFIER_CTRL = 1 << 2, - DS_MODIFIER_ALT = 1 << 3, - DS_MODIFIER_MOD2 = 1 << 4, - DS_MODIFIER_MOD3 = 1 << 5, - DS_MODIFIER_LOGO = 1 << 6, - DS_MODIFIER_MOD5 = 1 << 7, -}; - #define DS_KEYBOARD_KEYS_CAP 32 struct ds_keyboard; diff --git a/include/libds/keyboard.h b/include/libds/keyboard.h index e226cb4..2a515e3 100644 --- a/include/libds/keyboard.h +++ b/include/libds/keyboard.h @@ -9,6 +9,19 @@ struct ds_keyboard; +#define DS_MODIFIER_COUNT 8 + +enum ds_keyboard_modifier { + DS_MODIFIER_SHIFT = 1 << 0, + DS_MODIFIER_CAPS = 1 << 1, + DS_MODIFIER_CTRL = 1 << 2, + DS_MODIFIER_ALT = 1 << 3, + DS_MODIFIER_MOD2 = 1 << 4, + DS_MODIFIER_MOD3 = 1 << 5, + DS_MODIFIER_LOGO = 1 << 6, + DS_MODIFIER_MOD5 = 1 << 7, +}; + struct ds_event_keyboard_key { uint32_t time_msec; diff --git a/src/examples/input-device-test.c b/src/examples/input-device-test.c index 237d0b5..62fe8b0 100644 --- a/src/examples/input-device-test.c +++ b/src/examples/input-device-test.c @@ -230,12 +230,26 @@ keyboard_handle_device_destroy(struct wl_listener *listener, void *data) static void keyboard_handle_modifiers(struct wl_listener *listener, void *data) { - struct keyboard_device *keyboard; struct ds_keyboard *ds_keyboard = data; - - keyboard = wl_container_of(listener, keyboard, destroy); - - ds_inf("Keyboard(%p) event modifiers", ds_keyboard); + uint32_t modifiers; + + modifiers = ds_keyboard_get_modifiers(ds_keyboard); + if (modifiers & DS_MODIFIER_CTRL) + ds_inf("Keyboard(%p) modifier: Ctrl", ds_keyboard); + if (modifiers & DS_MODIFIER_SHIFT) + ds_inf("Keyboard(%p) modifier: Shift", ds_keyboard); + if (modifiers & DS_MODIFIER_CAPS) + ds_inf("Keyboard(%p) modifier: Caps", ds_keyboard); + if (modifiers & DS_MODIFIER_ALT) + ds_inf("Keyboard(%p) modifier: Alt", ds_keyboard); + if (modifiers & DS_MODIFIER_MOD2) + ds_inf("Keyboard(%p) modifier: Mod2", ds_keyboard); + if (modifiers & DS_MODIFIER_MOD3) + ds_inf("Keyboard(%p) modifier: Mod3", ds_keyboard); + if (modifiers & DS_MODIFIER_LOGO) + ds_inf("Keyboard(%p) modifier: Logo", ds_keyboard); + if (modifiers & DS_MODIFIER_MOD5) + ds_inf("Keyboard(%p) modifier: Mod5", ds_keyboard); } static void @@ -245,6 +259,7 @@ keyboard_handle_key(struct wl_listener *listener, void *data) struct keyboard_device *keyboard; struct xkb_state *xkb_state; const xkb_keysym_t *syms; + uint32_t modifiers; int nsyms = 0; keyboard = wl_container_of(listener, keyboard, key); @@ -260,9 +275,14 @@ keyboard_handle_key(struct wl_listener *listener, void *data) nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, &syms); - for (int i = 0; i < nsyms; i++) { - if (syms[i] == XKB_KEY_Escape) - wl_display_terminate(keyboard->server->display); + modifiers = ds_keyboard_get_modifiers(keyboard->ds_keyboard); + if ((modifiers & DS_MODIFIER_CTRL) && + (modifiers & DS_MODIFIER_ALT) && + event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + for (int i = 0; i < nsyms; i++) { + if (syms[i] == XKB_KEY_BackSpace) + wl_display_terminate(keyboard->server->display); + } } } -- 2.7.4 From 292c034ac292876b58d449e30d29e7e8f313d8fe Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 18 Apr 2022 13:27:17 +0900 Subject: [PATCH 06/16] packaging: Add missing file mistakenly unpacked Change-Id: Ib2a1b45b4dc9a7d3fdeeb47cfce74d0bb552f48c --- packaging/libds.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/libds.spec b/packaging/libds.spec index 806c75b..efba8cb 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -69,6 +69,7 @@ ninja -C builddir install %{_libdir}/libds.so %{_bindir}/wl-backend %{_bindir}/tinyds +%{_bindir}/input-device-test %files tizen-devel %manifest %{name}.manifest -- 2.7.4 From 464a27127ea22e7cf95e1546204ad57c9a5cc6d8 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 11:29:17 +0900 Subject: [PATCH 07/16] examples/tinyds: Handle ds_keyboard tinyds now handles ds_keyboard, and it may be terminated by pressing Alt + Ctrl + Shift + BackSapce. Change-Id: I06ba652cd4103df9bc7a60fdc6d7b3a8fca56621 --- src/examples/tinyds.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index a4c1042..cfa55a6 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -17,12 +17,25 @@ #include #include #include +#include +#include #define TINYDS_UNUSED __attribute__((unused)) #define OUTPUT_WIDTH 1280 #define OUTPUT_HEIGHT 720 +struct tinyds_server; + +struct tinyds_keyboard +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener key; +}; + struct tinyds_output { struct tinyds_server *server; @@ -54,6 +67,7 @@ struct tinyds_server struct wl_list views; struct wl_list outputs; + struct wl_listener new_input; struct wl_listener new_xdg_surface; }; @@ -77,6 +91,7 @@ struct tinyds_server _tinyds; static bool init_server(struct tinyds_server *server, struct wl_display *display); static void fini_server(struct tinyds_server *server); +static void server_handle_new_input(struct wl_listener *listener, void *data); static bool init_output(struct tinyds_output *output, struct tinyds_server *server, int width, int height); static void fini_output(struct tinyds_output *output); @@ -240,6 +255,9 @@ init_server(struct tinyds_server *server, struct wl_display *display) if (!server->backend) return false; + server->new_input.notify = server_handle_new_input; + ds_backend_add_new_input_listener(server->backend, &server->new_input); + server->compositor = ds_compositor_create(display); if (!server->compositor) { ds_backend_destroy(server->backend); @@ -439,3 +457,103 @@ view_send_frame_done(struct tinyds_view *view) ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), &now); } + +static void +keyboard_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + + kbd = wl_container_of(listener, kbd, destroy); + + ds_inf("Keyboard(%p) destroyed", kbd); + + wl_list_remove(&kbd->destroy.link); + wl_list_remove(&kbd->key.link); + + free(kbd); +} + +static bool +server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) +{ + switch (sym) { + case XKB_KEY_BackSpace: + wl_display_terminate(server->display); + break; + default: + return false; + } + + return true; +} + +static void +keyboard_handle_key(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + struct ds_event_keyboard_key *event = data; + struct ds_keyboard *ds_keyboard; + struct xkb_state *xkb_state; + const xkb_keysym_t *syms; + uint32_t modifiers; + int nsyms; + + kbd = wl_container_of(listener, kbd, key); + + ds_keyboard = ds_input_device_get_keyboard(kbd->dev); + + modifiers = ds_keyboard_get_modifiers(ds_keyboard); + if ((modifiers & DS_MODIFIER_CTRL) && + (modifiers & DS_MODIFIER_ALT) && + (modifiers & DS_MODIFIER_SHIFT) && + event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); + if (xkb_state) { + nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, + &syms); + for (int i = 0; i < nsyms; i++) { + server_handle_keybinding(kbd->server, syms[i]); + } + } + } +} + +static void +server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_keyboard *kbd; + + kbd = calloc(1, sizeof *kbd); + assert(kbd); + + kbd->dev = dev; + kbd->server = server; + + kbd->destroy.notify = keyboard_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &kbd->destroy); + + kbd->key.notify = keyboard_handle_key; + ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); + + ds_inf("Keyboard(%p) added", kbd); +} + +static void +server_handle_new_input(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct ds_input_device *dev = data; + enum ds_input_device_type dev_type; + + server = wl_container_of(listener, server, new_input); + + dev_type = ds_input_device_get_type(dev); + switch (dev_type) { + case DS_INPUT_DEVICE_KEYBOARD: + server_add_keyboard(server, dev); + break; + default: + ds_err("Unknown type(%d) of ds_input_device", dev_type); + break; + } +} -- 2.7.4 From 9cbe14ff64360116b7b367930e3cd66f66bbd319 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 15:45:55 +0900 Subject: [PATCH 08/16] xdg_shell: Destroy ds_xdg_surfaces when cleaning up client This patch fixes memory corruption caused by removing ds_xdg_surfaces's link in destroy_xdg_surface(). When wl_client is destroyed, ds_xdg_shell_client can be destroyed before its own ds_xdg_surfaces. This led to memory corruption because of illegal access to a freed memory when trying to remove list of ds_xdg_surface.link. Change-Id: I2558e445af25e85a84f761f845dae22eb10eeab4 --- src/libds/xdg_shell/xdg_shell.c | 4 ++++ src/libds/xdg_shell/xdg_shell.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/libds/xdg_shell/xdg_shell.c b/src/libds/xdg_shell/xdg_shell.c index a53684a..0b5252c 100644 --- a/src/libds/xdg_shell/xdg_shell.c +++ b/src/libds/xdg_shell/xdg_shell.c @@ -140,9 +140,13 @@ static void xdg_client_handle_resource_destroy(struct wl_resource *resource) { struct ds_xdg_client *client; + struct ds_xdg_surface *surface, *tmp; client = wl_resource_get_user_data(resource); + wl_list_for_each_safe(surface, tmp, &client->surfaces, link) + destroy_xdg_surface(surface); + if (client->ping_timer != NULL) wl_event_source_remove(client->ping_timer); diff --git a/src/libds/xdg_shell/xdg_shell.h b/src/libds/xdg_shell/xdg_shell.h index ea67be7..dc50d37 100644 --- a/src/libds/xdg_shell/xdg_shell.h +++ b/src/libds/xdg_shell/xdg_shell.h @@ -168,6 +168,8 @@ struct ds_xdg_surface * create_xdg_surface(struct ds_xdg_client *client, struct ds_surface *surface, uint32_t id); +void destroy_xdg_surface(struct ds_xdg_surface *surface); + void reset_xdg_surface(struct ds_xdg_surface *surface); -- 2.7.4 From b55ac8623425da31ac709e50aa740051110ab2d8 Mon Sep 17 00:00:00 2001 From: Duna Oh Date: Wed, 20 Apr 2022 20:57:38 +0900 Subject: [PATCH 09/16] 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 From 7f713ccb038a36c8fc8043693ce4f40e9f8f1d17 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 18:10:04 +0900 Subject: [PATCH 10/16] examples/tinyds: Remove redundant referencing ds_buffer ds_buffer is supposed to be referenced by ds_output while using it, so tinyds doesn't have any reasons to reference a ds_buffer for the output. Change-Id: I7f4aacd9263f4b70c57d269f118605b743d5b847 --- src/examples/tinyds.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index 61366fb..ed3ed01 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -54,7 +54,6 @@ struct tinyds_output struct ds_output *ds_output; struct ds_allocator *allocator; struct ds_swapchain *swapchain; - struct ds_buffer *front_buffer; struct wl_listener output_destroy; struct wl_listener output_frame; @@ -325,7 +324,6 @@ init_output(struct tinyds_output *output, struct tinyds_server *server, output->server = server; output->width = width; output->height = height; - output->front_buffer = NULL; output->drawable = true; output->damaged = true; @@ -365,8 +363,6 @@ static void fini_output(struct tinyds_output *output) { wl_list_remove(&output->link); - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); if (output->ds_output) ds_output_destroy(output->ds_output); ds_swapchain_destroy(output->swapchain); @@ -411,10 +407,8 @@ draw_output(struct tinyds_output *output) output_image = pixman_image_from_buffer(output_buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE); - if (!output_image) { - ds_buffer_unlock(output_buffer); - return; - } + if (!output_image) + goto out; pixman_image_fill_color(output_image, 80, 80, 80); @@ -428,12 +422,11 @@ draw_output(struct tinyds_output *output) ds_output_attach_buffer(output->ds_output, output_buffer); ds_output_commit(output->ds_output); - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - output->front_buffer = output_buffer; - output->drawable = false; output->damaged = false; + +out: + ds_buffer_unlock(output_buffer); } static void -- 2.7.4 From 699c1a95136501d82c9905cfbfdb1598c98280d4 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 19:54:19 +0900 Subject: [PATCH 11/16] examples/tinyds: Clarify single output support tinyds doesn't support multiple outputs for now, so don't pretend to support multiple outputs. Change-Id: Icf8dcdeb89ff256d5d827f3dc67cb3d08b4f9a2a --- src/examples/tinyds.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index ed3ed01..0c88849 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -57,7 +57,6 @@ struct tinyds_output struct wl_listener output_destroy; struct wl_listener output_frame; - struct wl_list link; // tinyds_server::outputs int width, height; @@ -73,10 +72,9 @@ struct tinyds_server struct ds_compositor *compositor; struct ds_xdg_shell *xdg_shell; - struct tinyds_output primary_output; + struct tinyds_output output; struct wl_list views; - struct wl_list outputs; struct wl_listener new_input; struct wl_listener new_xdg_surface; @@ -127,7 +125,7 @@ main(void) assert(init_server(server, display) == true); - assert(init_output(&server->primary_output, server, + assert(init_output(&server->output, server, OUTPUT_WIDTH, OUTPUT_HEIGHT) == true); socket = wl_display_add_socket_auto(display); @@ -143,7 +141,7 @@ main(void) wl_display_run(server->display); - fini_output(&server->primary_output); + fini_output(&server->output); fini_server(server); wl_display_destroy(display); @@ -256,7 +254,6 @@ init_server(struct tinyds_server *server, struct wl_display *display) { server->display = display; - wl_list_init(&server->outputs); wl_list_init(&server->views); if (wl_display_init_shm(display) != 0) @@ -347,8 +344,6 @@ init_output(struct tinyds_output *output, struct tinyds_server *server, output->output_frame.notify = output_handle_frame; ds_output_add_frame_listener(output->ds_output, &output->output_frame); - wl_list_insert(&server->outputs, &output->link); - return true; err_output: @@ -362,7 +357,6 @@ err_swapchain: static void fini_output(struct tinyds_output *output) { - wl_list_remove(&output->link); if (output->ds_output) ds_output_destroy(output->ds_output); ds_swapchain_destroy(output->swapchain); @@ -372,21 +366,16 @@ fini_output(struct tinyds_output *output) static void draw_server(struct tinyds_server *server) { - struct tinyds_output *output; - - wl_list_for_each(output, &server->outputs, link) - draw_output(output); + draw_output(&server->output); } static void draw_server_with_damage(struct tinyds_server *server) { - struct tinyds_output *output; + struct tinyds_output *output = &server->output; - wl_list_for_each(output, &server->outputs, link) { - output->damaged = true; - draw_output(output); - } + output->damaged = true; + draw_output(output); } static void view_send_frame_done(struct tinyds_view *view); -- 2.7.4 From 86edb5721a331f314fad9e81492f119f30260f0e Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 20:11:59 +0900 Subject: [PATCH 12/16] examples/tinyds: Clean up all views when finish server Even though all view would have been cleaned up by an destroy event of xdg_surface, this is just to clean up views explicitly just in case. No functional changes. Change-Id: If92f6ee73d1b8a4043f93105478b8fc3e7e78c68 --- src/examples/tinyds.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index 0c88849..64aac83 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -109,6 +109,7 @@ static void output_handle_frame(struct wl_listener *listener, void *data); static void draw_server(struct tinyds_server *server); static void draw_server_with_damage(struct tinyds_server *server); static void draw_output(struct tinyds_output *output); +static void view_destroy(struct tinyds_view *view); static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); int @@ -195,12 +196,7 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener, draw_server_with_damage(view->server); - wl_list_remove(&view->xdg_surface_destroy.link); - wl_list_remove(&view->xdg_surface_map.link); - wl_list_remove(&view->xdg_surface_unmap.link); - wl_list_remove(&view->surface_commit.link); - wl_list_remove(&view->link); - free(view); + view_destroy(view); } static void @@ -288,6 +284,11 @@ init_server(struct tinyds_server *server, struct wl_display *display) static void fini_server(struct tinyds_server *server) { + struct tinyds_view *view, *tmp; + + wl_list_for_each_safe(view, tmp, &server->views, link) + view_destroy(view); + wl_list_remove(&server->new_xdg_surface.link); } @@ -419,6 +420,19 @@ out: } static void +view_destroy(struct tinyds_view *view) +{ + ds_inf("View(%p) destroyed", view); + + wl_list_remove(&view->xdg_surface_destroy.link); + wl_list_remove(&view->xdg_surface_map.link); + wl_list_remove(&view->xdg_surface_unmap.link); + wl_list_remove(&view->surface_commit.link); + wl_list_remove(&view->link); + free(view); +} + +static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image) { struct ds_buffer *buffer; -- 2.7.4 From 2eb39431791e63281c3e48381e7c00d82e21c330 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 20:16:37 +0900 Subject: [PATCH 13/16] examples/tinyds: Enhance readability No functional changes - Use a first argument of function as a prefix of function name. - Rename some of function name more clearly. - Remove forward declaration of event handlers. Change-Id: I73bc409fe7d33233cf7d5482923ea52ea142ee4e --- src/examples/tinyds.c | 512 +++++++++++++++++++++++++------------------------- 1 file changed, 255 insertions(+), 257 deletions(-) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index 64aac83..77ede91 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -96,26 +96,24 @@ struct tinyds_view bool mapped; }; -struct tinyds_server _tinyds; - -static bool init_server(struct tinyds_server *server, struct wl_display *display); -static void fini_server(struct tinyds_server *server); -static void server_handle_new_input(struct wl_listener *listener, void *data); -static bool init_output(struct tinyds_output *output, struct tinyds_server *server, - int width, int height); -static void fini_output(struct tinyds_output *output); -static void output_handle_destroy(struct wl_listener *listener, void *data); -static void output_handle_frame(struct wl_listener *listener, void *data); -static void draw_server(struct tinyds_server *server); -static void draw_server_with_damage(struct tinyds_server *server); -static void draw_output(struct tinyds_output *output); +static bool server_init(struct tinyds_server *server, + struct wl_display *display); +static void server_fini(struct tinyds_server *server); +static void server_add_view(struct tinyds_server *server, + struct ds_xdg_surface *xdg_surface); +static bool output_init(struct tinyds_output *output, + struct tinyds_server *server, int width, int height); +static void output_fini(struct tinyds_output *output); +static void output_damage(struct tinyds_output *output); +static void output_redraw(struct tinyds_output *output); static void view_destroy(struct tinyds_view *view); -static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); +static void view_composite(struct tinyds_view *view, + pixman_image_t *dst_image); int main(void) { - struct tinyds_server *server = &_tinyds; + struct tinyds_server server; struct wl_display *display; const char *socket; @@ -124,33 +122,30 @@ main(void) display = wl_display_create(); assert(display); - assert(init_server(server, display) == true); - - assert(init_output(&server->output, server, - OUTPUT_WIDTH, OUTPUT_HEIGHT) == true); + assert(server_init(&server, display) == true); socket = wl_display_add_socket_auto(display); assert(socket); - ds_backend_start(server->backend); + ds_backend_start(server.backend); - draw_server(server); + output_damage(&server.output); + output_redraw(&server.output); setenv("WAYLAND_DISPLAY", socket, true); ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); - wl_display_run(server->display); + wl_display_run(server.display); - fini_output(&server->output); - fini_server(server); + server_fini(&server); wl_display_destroy(display); return 0; } static struct ds_backend * -tinyds_create_backend_auto(struct wl_display *display) +create_wl_backend(struct wl_display *display) { struct ds_backend *backend = NULL; char name[512]; @@ -167,6 +162,170 @@ tinyds_create_backend_auto(struct wl_display *display) } static void +keyboard_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + + kbd = wl_container_of(listener, kbd, destroy); + + ds_inf("Keyboard(%p) destroyed", kbd); + + wl_list_remove(&kbd->destroy.link); + wl_list_remove(&kbd->key.link); + + free(kbd); +} + +static bool +server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) +{ + switch (sym) { + case XKB_KEY_BackSpace: + wl_display_terminate(server->display); + break; + default: + return false; + } + + return true; +} + +static void +keyboard_handle_key(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + struct ds_event_keyboard_key *event = data; + struct ds_keyboard *ds_keyboard; + struct xkb_state *xkb_state; + const xkb_keysym_t *syms; + uint32_t modifiers; + int nsyms; + + kbd = wl_container_of(listener, kbd, key); + + ds_keyboard = ds_input_device_get_keyboard(kbd->dev); + + modifiers = ds_keyboard_get_modifiers(ds_keyboard); + if ((modifiers & DS_MODIFIER_CTRL) && + (modifiers & DS_MODIFIER_ALT) && + (modifiers & DS_MODIFIER_SHIFT) && + event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); + if (xkb_state) { + nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, + &syms); + for (int i = 0; i < nsyms; i++) { + server_handle_keybinding(kbd->server, syms[i]); + } + } + } +} + +static void +server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_keyboard *kbd; + + kbd = calloc(1, sizeof *kbd); + assert(kbd); + + kbd->dev = dev; + kbd->server = server; + + kbd->destroy.notify = keyboard_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &kbd->destroy); + + kbd->key.notify = keyboard_handle_key; + ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); + + ds_inf("Keyboard(%p) added", kbd); +} + +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; + struct ds_input_device *dev = data; + enum ds_input_device_type dev_type; + + server = wl_container_of(listener, server, new_input); + + dev_type = ds_input_device_get_type(dev); + switch (dev_type) { + 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; + } +} + +static void view_handle_xdg_surface_map(struct wl_listener *listener, void *data TINYDS_UNUSED) { @@ -194,7 +353,8 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener, view = wl_container_of(listener, view, xdg_surface_destroy); - draw_server_with_damage(view->server); + output_damage(&view->server->output); + output_redraw(&view->server->output); view_destroy(view); } @@ -206,47 +366,23 @@ view_handle_surface_commit(struct wl_listener *listener, struct tinyds_view *view; view = wl_container_of(listener, view, surface_commit); - draw_server_with_damage(view->server); + + output_damage(&view->server->output); + output_redraw(&view->server->output); } static void server_new_xdg_surface(struct wl_listener *listener, void *data) { struct tinyds_server *server; - struct tinyds_view *view; - struct ds_xdg_surface *xdg_surface; server = wl_container_of(listener, server, new_xdg_surface); - xdg_surface = data; - - ds_inf("New xdg_surface(%p)", (void *)xdg_surface); - - view = calloc(1, sizeof *view); - view->server = server; - view->xdg_surface = xdg_surface; - - view->xdg_surface_map.notify = view_handle_xdg_surface_map; - ds_xdg_surface_add_map_listener(xdg_surface, - &view->xdg_surface_map); - - view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap; - ds_xdg_surface_add_unmap_listener(xdg_surface, - &view->xdg_surface_unmap); - - view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy; - ds_xdg_surface_add_destroy_listener(xdg_surface, - &view->xdg_surface_destroy); - view->surface_commit.notify = view_handle_surface_commit; - ds_surface_add_commit_listener( - ds_xdg_surface_get_surface(xdg_surface), - &view->surface_commit); - - wl_list_insert(server->views.prev, &view->link); + server_add_view(server, (struct ds_xdg_surface *)data); } static bool -init_server(struct tinyds_server *server, struct wl_display *display) +server_init(struct tinyds_server *server, struct wl_display *display) { server->display = display; @@ -255,40 +391,46 @@ init_server(struct tinyds_server *server, struct wl_display *display) if (wl_display_init_shm(display) != 0) return false; - server->backend = tinyds_create_backend_auto(display); + server->backend = create_wl_backend(display); if (!server->backend) return false; server->new_input.notify = server_handle_new_input; ds_backend_add_new_input_listener(server->backend, &server->new_input); + if (!output_init(&server->output, server, OUTPUT_WIDTH, OUTPUT_HEIGHT)) + goto err; + server->compositor = ds_compositor_create(display); - if (!server->compositor) { - ds_backend_destroy(server->backend); - return false; - } + if (!server->compositor) + goto err; server->xdg_shell = ds_xdg_shell_create(display); - if (!server->xdg_shell) { - ds_backend_destroy(server->backend); - return false; - } + if (!server->xdg_shell) + goto err; server->new_xdg_surface.notify = server_new_xdg_surface; ds_xdg_shell_add_new_surface_listener(server->xdg_shell, &server->new_xdg_surface); return true; + +err: + ds_backend_destroy(server->backend); + + return false; } static void -fini_server(struct tinyds_server *server) +server_fini(struct tinyds_server *server) { struct tinyds_view *view, *tmp; wl_list_for_each_safe(view, tmp, &server->views, link) view_destroy(view); + output_fini(&server->output); + wl_list_remove(&server->new_xdg_surface.link); } @@ -312,18 +454,17 @@ output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) wl_container_of(listener, output, output_frame); output->drawable = true; - draw_output(output); + output_redraw(output); } static bool -init_output(struct tinyds_output *output, struct tinyds_server *server, +output_init(struct tinyds_output *output, struct tinyds_server *server, int width, int height) { output->server = server; output->width = width; output->height = height; output->drawable = true; - output->damaged = true; output->allocator = ds_shm_allocator_create(); if (!output->allocator) @@ -356,7 +497,7 @@ err_swapchain: } static void -fini_output(struct tinyds_output *output) +output_fini(struct tinyds_output *output) { if (output->ds_output) ds_output_destroy(output->ds_output); @@ -365,24 +506,13 @@ fini_output(struct tinyds_output *output) } static void -draw_server(struct tinyds_server *server) +output_damage(struct tinyds_output *output) { - draw_output(&server->output); -} - -static void -draw_server_with_damage(struct tinyds_server *server) -{ - struct tinyds_output *output = &server->output; - output->damaged = true; - draw_output(output); } -static void view_send_frame_done(struct tinyds_view *view); - static void -draw_output(struct tinyds_output *output) +output_redraw(struct tinyds_output *output) { struct ds_buffer *output_buffer; pixman_image_t *output_image; @@ -405,7 +535,7 @@ draw_output(struct tinyds_output *output) wl_list_for_each(view, &output->server->views, link) { if (!view->mapped) continue; - draw_view(view, output_image); + view_composite(view, output_image); } pixman_image_unref(output_image); @@ -420,6 +550,37 @@ out: } static void +server_add_view(struct tinyds_server *server, struct ds_xdg_surface *xdg_surface) +{ + struct tinyds_view *view; + + view = calloc(1, sizeof *view); + view->server = server; + view->xdg_surface = xdg_surface; + + view->xdg_surface_map.notify = view_handle_xdg_surface_map; + ds_xdg_surface_add_map_listener(xdg_surface, + &view->xdg_surface_map); + + view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap; + ds_xdg_surface_add_unmap_listener(xdg_surface, + &view->xdg_surface_unmap); + + view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy; + ds_xdg_surface_add_destroy_listener(xdg_surface, + &view->xdg_surface_destroy); + + view->surface_commit.notify = view_handle_surface_commit; + ds_surface_add_commit_listener( + ds_xdg_surface_get_surface(xdg_surface), + &view->surface_commit); + + wl_list_insert(server->views.prev, &view->link); + + ds_inf("View(%p) added", view); +} + +static void view_destroy(struct tinyds_view *view) { ds_inf("View(%p) destroyed", view); @@ -433,7 +594,17 @@ view_destroy(struct tinyds_view *view) } static void -draw_view(struct tinyds_view *view, pixman_image_t *dst_image) +view_send_frame_done(struct tinyds_view *view) +{ + struct timespec now; + + clock_gettime(CLOCK_MONOTONIC, &now); + ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), + &now); +} + +static void +view_composite(struct tinyds_view *view, pixman_image_t *dst_image) { struct ds_buffer *buffer; pixman_image_t *src_image; @@ -456,176 +627,3 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) view_send_frame_done(view); } - -static void -view_send_frame_done(struct tinyds_view *view) -{ - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), - &now); -} - -static void -keyboard_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_keyboard *kbd; - - kbd = wl_container_of(listener, kbd, destroy); - - ds_inf("Keyboard(%p) destroyed", kbd); - - wl_list_remove(&kbd->destroy.link); - wl_list_remove(&kbd->key.link); - - free(kbd); -} - -static bool -server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) -{ - switch (sym) { - case XKB_KEY_BackSpace: - wl_display_terminate(server->display); - break; - default: - return false; - } - - return true; -} - -static void -keyboard_handle_key(struct wl_listener *listener, void *data) -{ - struct tinyds_keyboard *kbd; - struct ds_event_keyboard_key *event = data; - struct ds_keyboard *ds_keyboard; - struct xkb_state *xkb_state; - const xkb_keysym_t *syms; - uint32_t modifiers; - int nsyms; - - kbd = wl_container_of(listener, kbd, key); - - ds_keyboard = ds_input_device_get_keyboard(kbd->dev); - - modifiers = ds_keyboard_get_modifiers(ds_keyboard); - if ((modifiers & DS_MODIFIER_CTRL) && - (modifiers & DS_MODIFIER_ALT) && - (modifiers & DS_MODIFIER_SHIFT) && - event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); - if (xkb_state) { - nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, - &syms); - for (int i = 0; i < nsyms; i++) { - server_handle_keybinding(kbd->server, syms[i]); - } - } - } -} - -static void -server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_keyboard *kbd; - - kbd = calloc(1, sizeof *kbd); - assert(kbd); - - kbd->dev = dev; - kbd->server = server; - - kbd->destroy.notify = keyboard_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &kbd->destroy); - - kbd->key.notify = keyboard_handle_key; - ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); - - ds_inf("Keyboard(%p) added", kbd); -} - -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; - struct ds_input_device *dev = data; - enum ds_input_device_type dev_type; - - server = wl_container_of(listener, server, new_input); - - dev_type = ds_input_device_get_type(dev); - switch (dev_type) { - 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; - } -} -- 2.7.4 From 346f9e405874123151e86e7959f62e5800dbe999 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 21 Apr 2022 14:05:11 +0900 Subject: [PATCH 14/16] examples/tinyds: Handle ds_pointer This adds listeners of ds_pointer and prints logs. Change-Id: I2eb47fc87958859fad5ad3b10d6a0608e7c2bce5 --- src/examples/tinyds.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index 77ede91..735fc30 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -20,6 +20,7 @@ #include #include #include +#include #define TINYDS_UNUSED __attribute__((unused)) @@ -28,6 +29,18 @@ struct tinyds_server; +struct tinyds_pointer +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener motion; + struct wl_listener motion_absolute; + struct wl_listener button; + struct wl_listener frame; +}; + struct tinyds_keyboard { struct ds_input_device *dev; @@ -303,6 +316,103 @@ server_add_touch(struct tinyds_server *server, struct ds_input_device *dev) } static void +pointer_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + + pointer = wl_container_of(listener, pointer, destroy); + + ds_inf("Pointer(%p) destroyed", pointer); + + wl_list_remove(&pointer->destroy.link); + wl_list_remove(&pointer->motion.link); + wl_list_remove(&pointer->motion_absolute.link); + wl_list_remove(&pointer->button.link); + wl_list_remove(&pointer->frame.link); + + free(pointer); +} + +static void +pointer_handle_motion(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + + pointer = wl_container_of(listener, pointer, motion); + + ds_inf("Pointer(%p) motion", pointer); +} + +static void +pointer_handle_motion_absolute(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + struct ds_event_pointer_motion_absolute *event = data; + + pointer = wl_container_of(listener, pointer, motion_absolute); + + ds_inf("Pointer(%p) motion absolute: (x %f y %f) time(%d)", + pointer, event->x, event->y, event->time_msec); +} + +static void +pointer_handle_button(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + struct ds_event_pointer_button *event = data; + + pointer = wl_container_of(listener, pointer, button); + + ds_inf("Pointer(%p) button(%d): state(%s) time(%d)", + pointer, event->button, + (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released", + event->time_msec); +} + +static void +pointer_handle_frame(struct wl_listener *listener, void *data) +{ + struct tinyds_pointer *pointer; + + pointer = wl_container_of(listener, pointer, motion); + + ds_inf("Pointer(%p) frame", pointer); +} + +static void +server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_pointer *pointer; + + pointer = calloc(1, sizeof *pointer); + assert(pointer); + + pointer->dev = dev; + pointer->server = server; + + pointer->destroy.notify = pointer_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &pointer->destroy); + + pointer->motion.notify = pointer_handle_motion; + ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev), + &pointer->motion); + + pointer->motion_absolute.notify = pointer_handle_motion_absolute; + ds_pointer_add_motion_absolute_listener(ds_input_device_get_pointer(dev), + &pointer->motion_absolute); + + pointer->button.notify = pointer_handle_button; + ds_pointer_add_button_listener(ds_input_device_get_pointer(dev), + &pointer->button); + + pointer->frame.notify = pointer_handle_frame; + ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev), + &pointer->frame); + + ds_inf("Pointer(%p) added", pointer); +} + +static void server_handle_new_input(struct wl_listener *listener, void *data) { struct tinyds_server *server; @@ -319,6 +429,9 @@ server_handle_new_input(struct wl_listener *listener, void *data) case DS_INPUT_DEVICE_TOUCH: server_add_touch(server, dev); break; + case DS_INPUT_DEVICE_POINTER: + server_add_pointer(server, dev); + break; default: ds_err("Unknown type(%d) of ds_input_device", dev_type); break; -- 2.7.4 From 9d2bfe8b43d1f7130a5e503f2956ffee3bcfd18d Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 21 Apr 2022 16:56:48 +0900 Subject: [PATCH 15/16] backend/wayland: Remove writable flag from event source Instead of having a writable flag on event source, it just marks wayland event source as needing a post-dispatch check. The event loop will call dispatch function again after all dispatching is done, with mask = 0. Change-Id: I183122d602626079137fbd34870dca1844f8ecd5 --- src/libds/backend/wayland/backend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libds/backend/wayland/backend.c b/src/libds/backend/wayland/backend.c index d956aa0..3b5d6ab 100644 --- a/src/libds/backend/wayland/backend.c +++ b/src/libds/backend/wayland/backend.c @@ -49,12 +49,13 @@ ds_wl_backend_create(struct wl_display *display, const char *server_name) fd = wl_display_get_fd(wl_backend->server.display); wl_backend->server_event_source = - wl_event_loop_add_fd(loop, fd, WL_EVENT_WRITABLE | WL_EVENT_READABLE, + wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wl_backend_handle_dispatch_events, wl_backend); if (!wl_backend->server_event_source) { ds_err("Failed to create event source"); goto err_src; } + wl_event_source_check(wl_backend->server_event_source); wl_backend->display_destroy.notify = wl_backend_handle_display_destroy; wl_display_add_destroy_listener(display, &wl_backend->display_destroy); -- 2.7.4 From 683a9056098d62a74ff56d2c1af0cddb24547423 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 25 Apr 2022 16:06:21 +0900 Subject: [PATCH 16/16] tinyds: Use WAYLAND_DISPLAY and WAYLAND_SOCKET for wl backend Instead of assuming the name of wayland display server by iterating arbitrary number of names, it uses values of WAYLAND_DISPLAY and WAYLAND_SOCKET environments. The library of wayland-client uses these values when trying to connect to wayland server. Change-Id: I0579dab7eadcd3580b0ee0ebadb9175fc0bcd0a5 --- src/examples/tinyds.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index 735fc30..1c5ca4f 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -160,18 +160,10 @@ main(void) static struct ds_backend * create_wl_backend(struct wl_display *display) { - struct ds_backend *backend = NULL; - char name[512]; - int i; - - for (i = 0; i < 5; i++) { - snprintf(name, sizeof name, "wayland-%d", i); - backend = ds_wl_backend_create(display, name); - if (backend) - break; - } + if (!getenv("WAYLAND_DISPLAY") && !getenv("WAYLAND_SOCKET")) + return NULL; - return backend; + return ds_wl_backend_create(display, NULL); } static void -- 2.7.4