23#include "uwac-utils.h"
35#include <sys/timerfd.h>
38#include <winpr/cast.h>
41#include "wayland-cursor.h"
42#include "wayland-client-protocol.h"
44static struct wl_buffer* create_pointer_buffer(UwacSeat* seat,
const void* src,
size_t size)
46 struct wl_buffer* buffer =
nullptr;
47 struct wl_shm_pool* pool =
nullptr;
51 const int fd = uwac_create_anonymous_file(WINPR_ASSERTING_INT_CAST(off_t, size));
56 void* data = mmap(
nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
58 if (data == MAP_FAILED)
62 memcpy(data, src, size);
64 pool = wl_shm_create_pool(seat->display->shm, fd, WINPR_ASSERTING_INT_CAST(int32_t, size));
72 buffer = wl_shm_pool_create_buffer(
73 pool, 0, WINPR_ASSERTING_INT_CAST(int32_t, seat->pointer_image->width),
74 WINPR_ASSERTING_INT_CAST(int32_t, seat->pointer_image->height),
75 WINPR_ASSERTING_INT_CAST(int32_t, seat->pointer_image->width * 4), WL_SHM_FORMAT_ARGB8888);
76 wl_shm_pool_destroy(pool);
78 if (munmap(data, size) < 0)
80 char buffer[256] = WINPR_C_ARRAY_INIT;
81 (void)fprintf(stderr,
"%s: munmap(%p, %zu) failed with [%d] %s\n", __func__, data, size,
82 errno, uwac_strerror(errno, buffer,
sizeof(buffer)));
90static void on_buffer_release(
void* data,
struct wl_buffer* wl_buffer)
93 wl_buffer_destroy(wl_buffer);
96static const struct wl_buffer_listener buffer_release_listener = { on_buffer_release };
98static UwacReturnCode set_cursor_image(UwacSeat* seat, uint32_t serial)
100 struct wl_buffer* buffer =
nullptr;
101 struct wl_cursor* cursor =
nullptr;
102 struct wl_cursor_image* image =
nullptr;
103 struct wl_surface* surface =
nullptr;
107 if (!seat || !seat->display || !seat->default_cursor || !seat->default_cursor->images)
108 return UWAC_ERROR_INTERNAL;
111 if (seat->pointer_focus)
112 scale = seat->pointer_focus->display->actual_scale;
114 switch (seat->pointer_type)
117 image = seat->pointer_image;
118 buffer = create_pointer_buffer(seat, seat->pointer_data, seat->pointer_size);
120 return UWAC_ERROR_INTERNAL;
121 if (wl_buffer_add_listener(buffer, &buffer_release_listener, seat) < 0)
122 return UWAC_ERROR_INTERNAL;
124 surface = seat->pointer_surface;
125 x = WINPR_ASSERTING_INT_CAST(int32_t, image->hotspot_x / scale);
126 y = WINPR_ASSERTING_INT_CAST(int32_t, image->hotspot_y / scale);
131 cursor = seat->default_cursor;
133 return UWAC_ERROR_INTERNAL;
134 image = cursor->images[0];
136 return UWAC_ERROR_INTERNAL;
137 x = WINPR_ASSERTING_INT_CAST(int32_t, image->hotspot_x);
138 y = WINPR_ASSERTING_INT_CAST(int32_t, image->hotspot_y);
139 buffer = wl_cursor_image_get_buffer(image);
141 return UWAC_ERROR_INTERNAL;
142 surface = seat->pointer_surface;
146 if (surface && buffer)
148 wl_surface_set_buffer_scale(surface, scale);
149 wl_surface_attach(surface, buffer, 0, 0);
150 wl_surface_damage(surface, 0, 0, WINPR_ASSERTING_INT_CAST(int32_t, image->width),
151 WINPR_ASSERTING_INT_CAST(int32_t, image->height));
152 wl_surface_commit(surface);
155 wl_pointer_set_cursor(seat->pointer, serial, surface, x, y);
160static void keyboard_repeat_func(UwacTask* task, uint32_t events)
162 UwacSeat* input = container_of(task, UwacSeat, repeat_task);
164 UwacWindow* window = input->keyboard_focus;
167 if (read(input->repeat_timer_fd, &exp,
sizeof exp) !=
sizeof exp)
175 UwacKeyEvent* key =
nullptr;
177 key = (UwacKeyEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_KEY);
181 key->window = window;
182 key->sym = input->repeat_sym;
183 key->raw_key = input->repeat_key;
185 key->repeated =
true;
189static void keyboard_handle_keymap(
void* data,
struct wl_keyboard* keyboard, uint32_t format,
190 int fd, uint32_t size)
192 UwacSeat* input = data;
193 struct xkb_keymap* keymap =
nullptr;
194 struct xkb_state* state =
nullptr;
195 char* map_str =
nullptr;
196 int mapFlags = MAP_SHARED;
204 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
210 if (input->seat_version >= 7)
211 mapFlags = MAP_PRIVATE;
213 map_str = mmap(
nullptr, size, PROT_READ, mapFlags, fd, 0);
214 if (map_str == MAP_FAILED)
220 keymap = xkb_keymap_new_from_string(input->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
221 munmap(map_str, size);
226 assert(uwacErrorHandler(input->display, UWAC_ERROR_INTERNAL,
"failed to compile keymap\n"));
230 state = xkb_state_new(keymap);
234 uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
"failed to create XKB state\n"));
235 xkb_keymap_unref(keymap);
239 xkb_keymap_unref(input->xkb.keymap);
240 xkb_state_unref(input->xkb.state);
241 input->xkb.keymap = keymap;
242 input->xkb.state = state;
244 input->xkb.control_mask = 1u << xkb_keymap_mod_get_index(input->xkb.keymap,
"Control");
245 input->xkb.alt_mask = 1u << xkb_keymap_mod_get_index(input->xkb.keymap,
"Mod1");
246 input->xkb.shift_mask = 1u << xkb_keymap_mod_get_index(input->xkb.keymap,
"Shift");
247 input->xkb.caps_mask = 1u << xkb_keymap_mod_get_index(input->xkb.keymap,
"Lock");
248 input->xkb.num_mask = 1u << xkb_keymap_mod_get_index(input->xkb.keymap,
"Mod2");
251static void keyboard_handle_key(
void* data,
struct wl_keyboard* keyboard, uint32_t serial,
252 uint32_t time, uint32_t key, uint32_t state_w);
254static void keyboard_handle_enter(
void* data,
struct wl_keyboard* keyboard, uint32_t serial,
255 struct wl_surface* surface,
struct wl_array* keys)
257 UwacSeat* input = (UwacSeat*)data;
260 UwacKeyboardEnterLeaveEvent*
event = (UwacKeyboardEnterLeaveEvent*)UwacDisplayNewEvent(
261 input->display, UWAC_EVENT_KEYBOARD_ENTER);
265 event->window = input->keyboard_focus = (UwacWindow*)wl_surface_get_user_data(surface);
278static void keyboard_handle_leave(
void* data,
struct wl_keyboard* keyboard, uint32_t serial,
279 struct wl_surface* surface)
281 struct itimerspec its = WINPR_C_ARRAY_INIT;
282 uint32_t* pressedKey =
nullptr;
285 UwacSeat* input = (UwacSeat*)data;
288 its.it_interval.tv_sec = 0;
289 its.it_interval.tv_nsec = 0;
290 its.it_value.tv_sec = 0;
291 its.it_value.tv_nsec = 0;
292 (void)timerfd_settime(input->repeat_timer_fd, 0, &its,
nullptr);
294 UwacPointerEnterLeaveEvent*
event =
295 (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
299 event->window = input->keyboard_focus;
305 for (pressedKey = input->pressed_keys.data, i = 0; i < input->pressed_keys.size;
306 i +=
sizeof(uint32_t))
308 keyboard_handle_key(data, keyboard, serial, 0, *pressedKey, WL_KEYBOARD_KEY_STATE_RELEASED);
313static int update_key_pressed(UwacSeat* seat, uint32_t key)
315 uint32_t* keyPtr =
nullptr;
319 wl_array_for_each(keyPtr, &seat->pressed_keys)
325 keyPtr = wl_array_add(&seat->pressed_keys,
sizeof(uint32_t));
333static int update_key_released(UwacSeat* seat, uint32_t key)
341 uint32_t* keyPtr = seat->pressed_keys.data;
342 for (; i < seat->pressed_keys.size; i++, keyPtr++)
353 toMove = seat->pressed_keys.size - ((i + 1) *
sizeof(uint32_t));
355 memmove(keyPtr, keyPtr + 1, toMove);
357 seat->pressed_keys.size -=
sizeof(uint32_t);
362static void keyboard_handle_key(
void* data,
struct wl_keyboard* keyboard, uint32_t serial,
363 uint32_t time, uint32_t key, uint32_t state_w)
365 UwacSeat* input = (UwacSeat*)data;
368 UwacWindow* window = input->keyboard_focus;
369 UwacKeyEvent* keyEvent =
nullptr;
372 uint32_t num_syms = 0;
373 enum wl_keyboard_key_state state = state_w;
374 const xkb_keysym_t* syms =
nullptr;
375 xkb_keysym_t sym = 0;
376 struct itimerspec its;
378 if (state_w == WL_KEYBOARD_KEY_STATE_PRESSED)
379 update_key_pressed(input, key);
381 update_key_released(input, key);
383 input->display->serial = serial;
385 if (!window || !input->xkb.state)
396 num_syms = xkb_state_key_get_syms(input->xkb.state, code, &syms);
398 sym = XKB_KEY_NoSymbol;
402 if (state == WL_KEYBOARD_KEY_STATE_RELEASED && key == input->repeat_key)
404 its.it_interval.tv_sec = 0;
405 its.it_interval.tv_nsec = 0;
406 its.it_value.tv_sec = 0;
407 its.it_value.tv_nsec = 0;
408 (void)timerfd_settime(input->repeat_timer_fd, 0, &its,
nullptr);
410 else if (state == WL_KEYBOARD_KEY_STATE_PRESSED &&
411 xkb_keymap_key_repeats(input->xkb.keymap, code))
413 input->repeat_sym = sym;
414 input->repeat_key = key;
415 input->repeat_time = time;
416 its.it_interval.tv_sec = input->repeat_rate_sec;
417 its.it_interval.tv_nsec = input->repeat_rate_nsec;
418 its.it_value.tv_sec = input->repeat_delay_sec;
419 its.it_value.tv_nsec = input->repeat_delay_nsec;
420 (void)timerfd_settime(input->repeat_timer_fd, 0, &its,
nullptr);
423 keyEvent = (UwacKeyEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_KEY);
427 keyEvent->window = window;
429 keyEvent->raw_key = key;
430 keyEvent->pressed = (state == WL_KEYBOARD_KEY_STATE_PRESSED);
431 keyEvent->repeated =
false;
434static void keyboard_handle_modifiers(
void* data,
struct wl_keyboard* keyboard, uint32_t serial,
435 uint32_t mods_depressed, uint32_t mods_latched,
436 uint32_t mods_locked, uint32_t group)
438 UwacSeat* input = data;
441 UwacKeyboardModifiersEvent*
event =
nullptr;
442 xkb_mod_mask_t mask = 0;
445 if (!input->xkb.keymap)
448 xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
451 enum xkb_state_component components =
452 XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | XKB_STATE_MODS_LOCKED;
454 mask = xkb_state_serialize_mods(input->xkb.state, components);
455 input->modifiers = 0;
456 if (mask & input->xkb.control_mask)
457 input->modifiers |= UWAC_MOD_CONTROL_MASK;
458 if (mask & input->xkb.alt_mask)
459 input->modifiers |= UWAC_MOD_ALT_MASK;
460 if (mask & input->xkb.shift_mask)
461 input->modifiers |= UWAC_MOD_SHIFT_MASK;
462 if (mask & input->xkb.caps_mask)
463 input->modifiers |= UWAC_MOD_CAPS_MASK;
464 if (mask & input->xkb.num_mask)
465 input->modifiers |= UWAC_MOD_NUM_MASK;
467 event = (UwacKeyboardModifiersEvent*)UwacDisplayNewEvent(input->display,
468 UWAC_EVENT_KEYBOARD_MODIFIERS);
472 event->modifiers = input->modifiers;
475static void set_repeat_info(UwacSeat* input, int32_t rate, int32_t delay)
479 input->repeat_rate_sec = input->repeat_rate_nsec = 0;
480 input->repeat_delay_sec = input->repeat_delay_nsec = 0;
488 input->repeat_rate_sec = 1;
490 input->repeat_rate_nsec = 1000000000 / rate;
492 input->repeat_delay_sec = delay / 1000;
493 delay -= (input->repeat_delay_sec * 1000);
494 input->repeat_delay_nsec = delay * 1000 * 1000;
497static void keyboard_handle_repeat_info(
void* data,
struct wl_keyboard* keyboard, int32_t rate,
500 UwacSeat* input = data;
503 set_repeat_info(input, rate, delay);
506static const struct wl_keyboard_listener keyboard_listener = {
507 keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave,
508 keyboard_handle_key, keyboard_handle_modifiers, keyboard_handle_repeat_info
511static bool touch_send_start_frame(UwacSeat* seat)
515 UwacTouchFrameBegin* ev =
516 (UwacTouchFrameBegin*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_BEGIN);
520 seat->touch_frame_started =
true;
524static void touch_handle_down(
void* data,
struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
525 struct wl_surface* surface, int32_t
id, wl_fixed_t x_w,
528 UwacSeat* seat = data;
529 UwacTouchDown* tdata =
nullptr;
532 assert(seat->display);
534 seat->display->serial = serial;
535 if (!seat->touch_frame_started && !touch_send_start_frame(seat))
538 tdata = (UwacTouchDown*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_DOWN);
545 double sx = wl_fixed_to_double(x_w);
546 double sy = wl_fixed_to_double(y_w);
548 tdata->x = (wl_fixed_t)lround(sx);
549 tdata->y = (wl_fixed_t)lround(sy);
552 struct widget *widget;
553 float sx = wl_fixed_to_double(x);
554 float sy = wl_fixed_to_double(y);
557 input->touch_focus = wl_surface_get_user_data(surface);
558 if (!input->touch_focus) {
559 DBG(
"Failed to find to touch focus for surface %p\n", (
void*) surface);
563 if (surface != input->touch_focus->main_surface->surface) {
564 DBG(
"Ignoring input event from subsurface %p\n", (
void*) surface);
565 input->touch_focus =
nullptr;
570 widget = input->grab;
572 widget = window_find_widget(input->touch_focus,
573 wl_fixed_to_double(x),
574 wl_fixed_to_double(y));
576 struct touch_point *tp = xmalloc(
sizeof *tp);
582 wl_list_insert(&input->touch_point_list, &tp->link);
584 if (widget->touch_down_handler)
585 (*widget->touch_down_handler)(widget, input,
594static void touch_handle_up(
void* data,
struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
597 UwacSeat* seat = data;
598 UwacTouchUp* tdata =
nullptr;
602 if (!seat->touch_frame_started && !touch_send_start_frame(seat))
605 tdata = (UwacTouchUp*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_UP);
613 struct touch_point *tp, *tmp;
615 if (!input->touch_focus) {
616 DBG(
"No touch focus found for touch up event!\n");
620 wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
624 if (tp->widget->touch_up_handler)
625 (*tp->widget->touch_up_handler)(tp->widget, input, serial,
627 tp->widget->user_data);
629 wl_list_remove(&tp->link);
637static void touch_handle_motion(
void* data,
struct wl_touch* wl_touch, uint32_t time, int32_t
id,
638 wl_fixed_t x_w, wl_fixed_t y_w)
640 UwacSeat* seat = data;
643 UwacTouchMotion* tdata =
nullptr;
645 if (!seat->touch_frame_started && !touch_send_start_frame(seat))
648 tdata = (UwacTouchMotion*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_MOTION);
655 double sx = wl_fixed_to_double(x_w);
656 double sy = wl_fixed_to_double(y_w);
658 tdata->x = (wl_fixed_t)lround(sx);
659 tdata->y = (wl_fixed_t)lround(sy);
662 struct touch_point *tp;
663 float sx = wl_fixed_to_double(x);
664 float sy = wl_fixed_to_double(y);
666 DBG(
"touch_handle_motion: %i %i\n",
id, wl_list_length(&seat->touch_point_list));
668 if (!seat->touch_focus) {
669 DBG(
"No touch focus found for touch motion event!\n");
673 wl_list_for_each(tp, &seat->touch_point_list, link) {
679 if (tp->widget->touch_motion_handler)
680 (*tp->widget->touch_motion_handler)(tp->widget, seat, time,
682 tp->widget->user_data);
688static void touch_handle_frame(
void* data,
struct wl_touch* wl_touch)
690 UwacSeat* seat = data;
693 UwacTouchFrameEnd* ev =
694 (UwacTouchFrameEnd*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_END);
699 seat->touch_frame_started =
false;
702static void touch_handle_cancel(
void* data,
struct wl_touch* wl_touch)
704 UwacSeat* seat = data;
707 UwacTouchCancel* ev =
708 (UwacTouchCancel*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_CANCEL);
713 seat->touch_frame_started =
false;
716 struct touch_point *tp, *tmp;
718 DBG(
"touch_handle_cancel\n");
720 if (!input->touch_focus) {
721 DBG(
"No touch focus found for touch cancel event!\n");
725 wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
726 if (tp->widget->touch_cancel_handler)
727 (*tp->widget->touch_cancel_handler)(tp->widget, input,
728 tp->widget->user_data);
730 wl_list_remove(&tp->link);
736static void touch_handle_shape(
void* data,
struct wl_touch* wl_touch, int32_t
id, wl_fixed_t major,
739 UwacSeat* seat = data;
745static void touch_handle_orientation(
void* data,
struct wl_touch* wl_touch, int32_t
id,
746 wl_fixed_t orientation)
748 UwacSeat* seat = data;
754static const struct wl_touch_listener touch_listener = {
755 touch_handle_down, touch_handle_up, touch_handle_motion, touch_handle_frame,
756 touch_handle_cancel, touch_handle_shape, touch_handle_orientation
759static void pointer_handle_enter(
void* data,
struct wl_pointer* pointer, uint32_t serial,
760 struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w)
762 UwacSeat* input = data;
763 UwacWindow* window =
nullptr;
764 UwacPointerEnterLeaveEvent*
event =
nullptr;
768 double sx = wl_fixed_to_double(sx_w);
769 double sy = wl_fixed_to_double(sy_w);
777 input->display->serial = serial;
778 input->display->pointer_focus_serial = serial;
779 window = wl_surface_get_user_data(surface);
781 window->pointer_enter_serial = serial;
782 input->pointer_focus = window;
787 (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_ENTER);
792 event->window = window;
793 event->x = (uint32_t)lround(sx);
794 event->y = (uint32_t)lround(sy);
797 set_cursor_image(input, serial);
800static void pointer_handle_leave(
void* data,
struct wl_pointer* pointer, uint32_t serial,
801 struct wl_surface* surface)
803 UwacPointerEnterLeaveEvent*
event =
nullptr;
804 UwacWindow* window =
nullptr;
805 UwacSeat* input = data;
808 input->display->serial = serial;
811 (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
815 window = wl_surface_get_user_data(surface);
818 event->window = window;
821static void pointer_handle_motion(
void* data,
struct wl_pointer* pointer, uint32_t time,
822 wl_fixed_t sx_w, wl_fixed_t sy_w)
824 UwacPointerMotionEvent* motion_event =
nullptr;
825 UwacSeat* input = data;
828 UwacWindow* window = input->pointer_focus;
829 if (!window || !window->display)
832 int scale = window->display->actual_scale;
833 int sx_i = wl_fixed_to_int(sx_w) * scale;
834 int sy_i = wl_fixed_to_int(sy_w) * scale;
835 double sx_d = wl_fixed_to_double(sx_w) * scale;
836 double sy_d = wl_fixed_to_double(sy_w) * scale;
838 if ((sx_i < 0) || (sy_i < 0))
845 (UwacPointerMotionEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_MOTION);
849 motion_event->seat = input;
850 motion_event->window = window;
851 motion_event->x = sx_i;
852 motion_event->y = sy_i;
855static void pointer_handle_button(
void* data,
struct wl_pointer* pointer, uint32_t serial,
856 uint32_t time, uint32_t button, uint32_t state_w)
858 UwacPointerButtonEvent*
event =
nullptr;
859 UwacSeat* seat = data;
862 UwacWindow* window = seat->pointer_focus;
864 seat->display->serial = serial;
866 event = (UwacPointerButtonEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_BUTTONS);
871 event->window = window;
872 event->x = (uint32_t)lround(seat->sx);
873 event->y = (uint32_t)lround(seat->sy);
874 event->button = button;
875 event->state = (
enum wl_pointer_button_state)state_w;
878static void pointer_handle_axis(
void* data,
struct wl_pointer* pointer, uint32_t time,
879 uint32_t axis, wl_fixed_t value)
881 UwacPointerAxisEvent*
event =
nullptr;
882 UwacSeat* seat = data;
885 UwacWindow* window = seat->pointer_focus;
890 event = (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS);
895 event->window = window;
896 event->x = (uint32_t)lround(seat->sx);
897 event->y = (uint32_t)lround(seat->sy);
899 event->value = value;
902static void pointer_frame(
void* data,
struct wl_pointer* wl_pointer)
904 UwacPointerFrameEvent*
event =
nullptr;
905 UwacSeat* seat = data;
908 UwacWindow* window = seat->pointer_focus;
913 event = (UwacPointerFrameEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_FRAME);
918 event->window = window;
921static void pointer_axis_source(
void* data,
struct wl_pointer* wl_pointer, uint32_t axis_source)
923 UwacPointerSourceEvent*
event =
nullptr;
924 UwacSeat* seat = data;
927 UwacWindow* window = seat->pointer_focus;
932 event = (UwacPointerSourceEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_SOURCE);
937 event->window = window;
938 event->axis_source = axis_source;
941static void pointer_axis_stop(
void* data,
struct wl_pointer* wl_pointer, uint32_t time,
944 UwacSeat* seat = data;
948static void pointer_axis_discrete(
void* data,
struct wl_pointer* wl_pointer, uint32_t axis,
952 UwacPointerAxisEvent*
event =
nullptr;
953 UwacSeat* seat = data;
956 UwacWindow* window = seat->pointer_focus;
962 (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
967 event->window = window;
968 event->x = (uint32_t)lround(seat->sx);
969 event->y = (uint32_t)lround(seat->sy);
971 event->value = discrete;
974static void pointer_axis_value120(
void* data,
struct wl_pointer* wl_pointer, uint32_t axis,
978 UwacPointerAxisEvent*
event =
nullptr;
979 UwacSeat* seat = data;
982 UwacWindow* window = seat->pointer_focus;
988 (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
993 event->window = window;
994 event->x = (uint32_t)lround(seat->sx);
995 event->y = (uint32_t)lround(seat->sy);
997 event->value = value120 / 120;
1000static const struct wl_pointer_listener pointer_listener = {
1001 pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button,
1002 pointer_handle_axis, pointer_frame, pointer_axis_source, pointer_axis_stop,
1003 pointer_axis_discrete, pointer_axis_value120
1006static void seat_handle_capabilities(
void* data,
struct wl_seat* seat, uint32_t caps)
1008 UwacSeat* input = data;
1011 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer)
1013 input->pointer = wl_seat_get_pointer(seat);
1014 wl_pointer_set_user_data(input->pointer, input);
1015 wl_pointer_add_listener(input->pointer, &pointer_listener, input);
1017 input->cursor_theme = wl_cursor_theme_load(
nullptr, 32, input->display->shm);
1018 if (!input->cursor_theme)
1020 assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1021 "unable to get wayland cursor theme\n"));
1025 input->default_cursor = wl_cursor_theme_get_cursor(input->cursor_theme,
"left_ptr");
1026 if (!input->default_cursor)
1028 assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1029 "unable to get wayland cursor left_ptr\n"));
1033 else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer)
1035#ifdef WL_POINTER_RELEASE_SINCE_VERSION
1036 if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1037 wl_pointer_release(input->pointer);
1040 wl_pointer_destroy(input->pointer);
1041 if (input->cursor_theme)
1042 wl_cursor_theme_destroy(input->cursor_theme);
1044 input->default_cursor =
nullptr;
1045 input->cursor_theme =
nullptr;
1046 input->pointer =
nullptr;
1049 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard)
1051 input->keyboard = wl_seat_get_keyboard(seat);
1052 wl_keyboard_set_user_data(input->keyboard, input);
1053 wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input);
1055 else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard)
1057#ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1058 if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1059 wl_keyboard_release(input->keyboard);
1062 wl_keyboard_destroy(input->keyboard);
1063 input->keyboard =
nullptr;
1066 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch)
1068 input->touch = wl_seat_get_touch(seat);
1069 wl_touch_set_user_data(input->touch, input);
1070 wl_touch_add_listener(input->touch, &touch_listener, input);
1072 else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch)
1074#ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1075 if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1076 wl_touch_release(input->touch);
1079 wl_touch_destroy(input->touch);
1080 input->touch =
nullptr;
1084static void seat_handle_name(
void* data,
struct wl_seat* seat,
const char* name)
1086 UwacSeat* input = data;
1092 input->name = strdup(name);
1094 assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1095 "unable to strdup seat's name\n"));
1098static const struct wl_seat_listener seat_listener = { seat_handle_capabilities, seat_handle_name };
1100UwacSeat* UwacSeatNew(UwacDisplay* d, uint32_t
id, uint32_t version)
1102 UwacSeat* ret = xzalloc(
sizeof(UwacSeat));
1108 ret->seat_version = version;
1110 wl_array_init(&ret->pressed_keys);
1111 ret->xkb_context = xkb_context_new(0);
1112 if (!ret->xkb_context)
1114 (void)fprintf(stderr,
"%s: unable to allocate a xkb_context\n", __func__);
1118 ret->seat = wl_registry_bind(d->registry,
id, &wl_seat_interface, version);
1119 wl_seat_add_listener(ret->seat, &seat_listener, ret);
1120 wl_seat_set_user_data(ret->seat, ret);
1122 ret->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
1123 if (ret->repeat_timer_fd < 0)
1125 (void)fprintf(stderr,
"%s: error creating repeat timer\n", __func__);
1128 ret->repeat_task.run = keyboard_repeat_func;
1129 if (UwacDisplayWatchFd(d, ret->repeat_timer_fd, EPOLLIN, &ret->repeat_task) < 0)
1131 (void)fprintf(stderr,
"%s: error polling repeat timer\n", __func__);
1135 wl_list_insert(d->seats.prev, &ret->link);
1139 UwacSeatDestroy(ret);
1143void UwacSeatDestroy(UwacSeat* s)
1148 UwacSeatInhibitShortcuts(s,
false);
1151#ifdef WL_SEAT_RELEASE_SINCE_VERSION
1152 if (s->seat_version >= WL_SEAT_RELEASE_SINCE_VERSION)
1153 wl_seat_release(s->seat);
1156 wl_seat_destroy(s->seat);
1161 wl_array_release(&s->pressed_keys);
1163 xkb_state_unref(s->xkb.state);
1164 xkb_context_unref(s->xkb_context);
1168#ifdef WL_POINTER_RELEASE_SINCE_VERSION
1169 if (s->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1170 wl_pointer_release(s->pointer);
1173 wl_pointer_destroy(s->pointer);
1178#ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1179 if (s->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1180 wl_touch_release(s->touch);
1183 wl_touch_destroy(s->touch);
1188#ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1189 if (s->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1190 wl_keyboard_release(s->keyboard);
1193 wl_keyboard_destroy(s->keyboard);
1197 wl_data_device_destroy(s->data_device);
1200 wl_data_source_destroy(s->data_source);
1202 if (s->pointer_surface)
1203 wl_surface_destroy(s->pointer_surface);
1205 free(s->pointer_image);
1206 free(s->pointer_data);
1208 wl_list_remove(&s->link);
1212const char* UwacSeatGetName(
const UwacSeat* seat)
1218UwacSeatId UwacSeatGetId(
const UwacSeat* seat)
1221 return seat->seat_id;
1224UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* s,
bool inhibit)
1227 return UWAC_ERROR_CLOSED;
1229 if (s->keyboard_inhibitor)
1231 zwp_keyboard_shortcuts_inhibitor_v1_destroy(s->keyboard_inhibitor);
1232 s->keyboard_inhibitor =
nullptr;
1234 if (inhibit && s->display && s->display->keyboard_inhibit_manager)
1235 s->keyboard_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(
1236 s->display->keyboard_inhibit_manager, s->keyboard_focus->surface, s->seat);
1238 if (inhibit && !s->keyboard_inhibitor)
1239 return UWAC_ERROR_INTERNAL;
1240 return UWAC_SUCCESS;
1243UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat,
const void* data,
size_t length,
size_t width,
1244 size_t height,
size_t hot_x,
size_t hot_y)
1247 return UWAC_ERROR_CLOSED;
1249 free(seat->pointer_image);
1250 seat->pointer_image =
nullptr;
1252 free(seat->pointer_data);
1253 seat->pointer_data =
nullptr;
1254 seat->pointer_size = 0;
1257 if ((data !=
nullptr) && (length != 0))
1259 seat->pointer_image = xzalloc(
sizeof(
struct wl_cursor_image));
1260 if (!seat->pointer_image)
1261 return UWAC_ERROR_NOMEMORY;
1262 seat->pointer_image->width = width;
1263 seat->pointer_image->height = height;
1264 seat->pointer_image->hotspot_x = hot_x;
1265 seat->pointer_image->hotspot_y = hot_y;
1267 free(seat->pointer_data);
1268 seat->pointer_data = xmalloc(length);
1269 memcpy(seat->pointer_data, data, length);
1270 seat->pointer_size = length;
1272 seat->pointer_type = 2;
1275 else if (length != 0)
1277 seat->pointer_type = 0;
1282 seat->pointer_type = 1;
1284 if (seat && !seat->default_cursor)
1285 return UWAC_SUCCESS;
1286 return set_cursor_image(seat, seat->display->pointer_focus_serial);