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 = NULL;
47 struct wl_shm_pool* pool = NULL;
51 const int fd = uwac_create_anonymous_file(WINPR_ASSERTING_INT_CAST(off_t, size));
56 void* data = mmap(NULL, 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] = { 0 };
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 = NULL;
101 struct wl_cursor* cursor = NULL;
102 struct wl_cursor_image* image = NULL;
103 struct wl_surface* surface = NULL;
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 = NULL;
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 = NULL;
194 struct xkb_state* state = NULL;
195 char* map_str = NULL;
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(NULL, 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 = 1 << xkb_keymap_mod_get_index(input->xkb.keymap,
"Control");
245 input->xkb.alt_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap,
"Mod1");
246 input->xkb.shift_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap,
"Shift");
247 input->xkb.caps_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap,
"Lock");
248 input->xkb.num_mask = 1 << 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 = { 0 };
282 uint32_t* pressedKey = NULL;
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, NULL);
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 = NULL;
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 = NULL;
372 uint32_t num_syms = 0;
373 enum wl_keyboard_key_state state = state_w;
374 const xkb_keysym_t* syms = NULL;
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, NULL);
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, NULL);
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 = NULL;
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);
449 mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_DEPRESSED |
450 XKB_STATE_MODS_LATCHED |
451 XKB_STATE_MODS_LOCKED);
452 input->modifiers = 0;
453 if (mask & input->xkb.control_mask)
454 input->modifiers |= UWAC_MOD_CONTROL_MASK;
455 if (mask & input->xkb.alt_mask)
456 input->modifiers |= UWAC_MOD_ALT_MASK;
457 if (mask & input->xkb.shift_mask)
458 input->modifiers |= UWAC_MOD_SHIFT_MASK;
459 if (mask & input->xkb.caps_mask)
460 input->modifiers |= UWAC_MOD_CAPS_MASK;
461 if (mask & input->xkb.num_mask)
462 input->modifiers |= UWAC_MOD_NUM_MASK;
464 event = (UwacKeyboardModifiersEvent*)UwacDisplayNewEvent(input->display,
465 UWAC_EVENT_KEYBOARD_MODIFIERS);
469 event->modifiers = input->modifiers;
472static void set_repeat_info(UwacSeat* input, int32_t rate, int32_t delay)
476 input->repeat_rate_sec = input->repeat_rate_nsec = 0;
477 input->repeat_delay_sec = input->repeat_delay_nsec = 0;
485 input->repeat_rate_sec = 1;
487 input->repeat_rate_nsec = 1000000000 / rate;
489 input->repeat_delay_sec = delay / 1000;
490 delay -= (input->repeat_delay_sec * 1000);
491 input->repeat_delay_nsec = delay * 1000 * 1000;
494static void keyboard_handle_repeat_info(
void* data,
struct wl_keyboard* keyboard, int32_t rate,
497 UwacSeat* input = data;
500 set_repeat_info(input, rate, delay);
503static const struct wl_keyboard_listener keyboard_listener = {
504 keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave,
505 keyboard_handle_key, keyboard_handle_modifiers, keyboard_handle_repeat_info
508static bool touch_send_start_frame(UwacSeat* seat)
512 UwacTouchFrameBegin* ev =
513 (UwacTouchFrameBegin*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_BEGIN);
517 seat->touch_frame_started =
true;
521static void touch_handle_down(
void* data,
struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
522 struct wl_surface* surface, int32_t
id, wl_fixed_t x_w,
525 UwacSeat* seat = data;
526 UwacTouchDown* tdata = NULL;
529 assert(seat->display);
531 seat->display->serial = serial;
532 if (!seat->touch_frame_started && !touch_send_start_frame(seat))
535 tdata = (UwacTouchDown*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_DOWN);
542 double sx = wl_fixed_to_double(x_w);
543 double sy = wl_fixed_to_double(y_w);
545 tdata->x = (wl_fixed_t)lround(sx);
546 tdata->y = (wl_fixed_t)lround(sy);
549 struct widget *widget;
550 float sx = wl_fixed_to_double(x);
551 float sy = wl_fixed_to_double(y);
554 input->touch_focus = wl_surface_get_user_data(surface);
555 if (!input->touch_focus) {
556 DBG(
"Failed to find to touch focus for surface %p\n", (
void*) surface);
560 if (surface != input->touch_focus->main_surface->surface) {
561 DBG(
"Ignoring input event from subsurface %p\n", (
void*) surface);
562 input->touch_focus = NULL;
567 widget = input->grab;
569 widget = window_find_widget(input->touch_focus,
570 wl_fixed_to_double(x),
571 wl_fixed_to_double(y));
573 struct touch_point *tp = xmalloc(
sizeof *tp);
579 wl_list_insert(&input->touch_point_list, &tp->link);
581 if (widget->touch_down_handler)
582 (*widget->touch_down_handler)(widget, input,
591static void touch_handle_up(
void* data,
struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
594 UwacSeat* seat = data;
595 UwacTouchUp* tdata = NULL;
599 if (!seat->touch_frame_started && !touch_send_start_frame(seat))
602 tdata = (UwacTouchUp*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_UP);
610 struct touch_point *tp, *tmp;
612 if (!input->touch_focus) {
613 DBG(
"No touch focus found for touch up event!\n");
617 wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
621 if (tp->widget->touch_up_handler)
622 (*tp->widget->touch_up_handler)(tp->widget, input, serial,
624 tp->widget->user_data);
626 wl_list_remove(&tp->link);
634static void touch_handle_motion(
void* data,
struct wl_touch* wl_touch, uint32_t time, int32_t
id,
635 wl_fixed_t x_w, wl_fixed_t y_w)
637 UwacSeat* seat = data;
640 UwacTouchMotion* tdata = NULL;
642 if (!seat->touch_frame_started && !touch_send_start_frame(seat))
645 tdata = (UwacTouchMotion*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_MOTION);
652 double sx = wl_fixed_to_double(x_w);
653 double sy = wl_fixed_to_double(y_w);
655 tdata->x = (wl_fixed_t)lround(sx);
656 tdata->y = (wl_fixed_t)lround(sy);
659 struct touch_point *tp;
660 float sx = wl_fixed_to_double(x);
661 float sy = wl_fixed_to_double(y);
663 DBG(
"touch_handle_motion: %i %i\n",
id, wl_list_length(&seat->touch_point_list));
665 if (!seat->touch_focus) {
666 DBG(
"No touch focus found for touch motion event!\n");
670 wl_list_for_each(tp, &seat->touch_point_list, link) {
676 if (tp->widget->touch_motion_handler)
677 (*tp->widget->touch_motion_handler)(tp->widget, seat, time,
679 tp->widget->user_data);
685static void touch_handle_frame(
void* data,
struct wl_touch* wl_touch)
687 UwacSeat* seat = data;
690 UwacTouchFrameEnd* ev =
691 (UwacTouchFrameEnd*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_END);
696 seat->touch_frame_started =
false;
699static void touch_handle_cancel(
void* data,
struct wl_touch* wl_touch)
701 UwacSeat* seat = data;
704 UwacTouchCancel* ev =
705 (UwacTouchCancel*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_CANCEL);
710 seat->touch_frame_started =
false;
713 struct touch_point *tp, *tmp;
715 DBG(
"touch_handle_cancel\n");
717 if (!input->touch_focus) {
718 DBG(
"No touch focus found for touch cancel event!\n");
722 wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
723 if (tp->widget->touch_cancel_handler)
724 (*tp->widget->touch_cancel_handler)(tp->widget, input,
725 tp->widget->user_data);
727 wl_list_remove(&tp->link);
733static void touch_handle_shape(
void* data,
struct wl_touch* wl_touch, int32_t
id, wl_fixed_t major,
736 UwacSeat* seat = data;
742static void touch_handle_orientation(
void* data,
struct wl_touch* wl_touch, int32_t
id,
743 wl_fixed_t orientation)
745 UwacSeat* seat = data;
751static const struct wl_touch_listener touch_listener = {
752 touch_handle_down, touch_handle_up, touch_handle_motion, touch_handle_frame,
753 touch_handle_cancel, touch_handle_shape, touch_handle_orientation
756static void pointer_handle_enter(
void* data,
struct wl_pointer* pointer, uint32_t serial,
757 struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w)
759 UwacSeat* input = data;
760 UwacWindow* window = NULL;
761 UwacPointerEnterLeaveEvent*
event = NULL;
765 double sx = wl_fixed_to_double(sx_w);
766 double sy = wl_fixed_to_double(sy_w);
774 input->display->serial = serial;
775 input->display->pointer_focus_serial = serial;
776 window = wl_surface_get_user_data(surface);
778 window->pointer_enter_serial = serial;
779 input->pointer_focus = window;
784 (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_ENTER);
789 event->window = window;
790 event->x = (uint32_t)lround(sx);
791 event->y = (uint32_t)lround(sy);
794 set_cursor_image(input, serial);
797static void pointer_handle_leave(
void* data,
struct wl_pointer* pointer, uint32_t serial,
798 struct wl_surface* surface)
800 UwacPointerEnterLeaveEvent*
event = NULL;
801 UwacWindow* window = NULL;
802 UwacSeat* input = data;
805 input->display->serial = serial;
808 (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
812 window = wl_surface_get_user_data(surface);
815 event->window = window;
818static void pointer_handle_motion(
void* data,
struct wl_pointer* pointer, uint32_t time,
819 wl_fixed_t sx_w, wl_fixed_t sy_w)
821 UwacPointerMotionEvent* motion_event = NULL;
822 UwacSeat* input = data;
825 UwacWindow* window = input->pointer_focus;
826 if (!window || !window->display)
829 int scale = window->display->actual_scale;
830 int sx_i = wl_fixed_to_int(sx_w) * scale;
831 int sy_i = wl_fixed_to_int(sy_w) * scale;
832 double sx_d = wl_fixed_to_double(sx_w) * scale;
833 double sy_d = wl_fixed_to_double(sy_w) * scale;
835 if ((sx_i < 0) || (sy_i < 0))
842 (UwacPointerMotionEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_MOTION);
846 motion_event->seat = input;
847 motion_event->window = window;
848 motion_event->x = sx_i;
849 motion_event->y = sy_i;
852static void pointer_handle_button(
void* data,
struct wl_pointer* pointer, uint32_t serial,
853 uint32_t time, uint32_t button, uint32_t state_w)
855 UwacPointerButtonEvent*
event = NULL;
856 UwacSeat* seat = data;
859 UwacWindow* window = seat->pointer_focus;
861 seat->display->serial = serial;
863 event = (UwacPointerButtonEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_BUTTONS);
868 event->window = window;
869 event->x = (uint32_t)lround(seat->sx);
870 event->y = (uint32_t)lround(seat->sy);
871 event->button = button;
872 event->state = (
enum wl_pointer_button_state)state_w;
875static void pointer_handle_axis(
void* data,
struct wl_pointer* pointer, uint32_t time,
876 uint32_t axis, wl_fixed_t value)
878 UwacPointerAxisEvent*
event = NULL;
879 UwacSeat* seat = data;
882 UwacWindow* window = seat->pointer_focus;
887 event = (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS);
892 event->window = window;
893 event->x = (uint32_t)lround(seat->sx);
894 event->y = (uint32_t)lround(seat->sy);
896 event->value = value;
899static void pointer_frame(
void* data,
struct wl_pointer* wl_pointer)
901 UwacPointerFrameEvent*
event = NULL;
902 UwacSeat* seat = data;
905 UwacWindow* window = seat->pointer_focus;
910 event = (UwacPointerFrameEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_FRAME);
915 event->window = window;
918static void pointer_axis_source(
void* data,
struct wl_pointer* wl_pointer, uint32_t axis_source)
920 UwacPointerSourceEvent*
event = NULL;
921 UwacSeat* seat = data;
924 UwacWindow* window = seat->pointer_focus;
929 event = (UwacPointerSourceEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_SOURCE);
934 event->window = window;
935 event->axis_source = axis_source;
938static void pointer_axis_stop(
void* data,
struct wl_pointer* wl_pointer, uint32_t time,
941 UwacSeat* seat = data;
945static void pointer_axis_discrete(
void* data,
struct wl_pointer* wl_pointer, uint32_t axis,
949 UwacPointerAxisEvent*
event = NULL;
950 UwacSeat* seat = data;
953 UwacWindow* window = seat->pointer_focus;
959 (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
964 event->window = window;
965 event->x = (uint32_t)lround(seat->sx);
966 event->y = (uint32_t)lround(seat->sy);
968 event->value = discrete;
971static void pointer_axis_value120(
void* data,
struct wl_pointer* wl_pointer, uint32_t axis,
975 UwacPointerAxisEvent*
event = NULL;
976 UwacSeat* seat = data;
979 UwacWindow* window = seat->pointer_focus;
985 (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
990 event->window = window;
991 event->x = (uint32_t)lround(seat->sx);
992 event->y = (uint32_t)lround(seat->sy);
994 event->value = value120 / 120;
997static const struct wl_pointer_listener pointer_listener = {
998 pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button,
999 pointer_handle_axis, pointer_frame, pointer_axis_source, pointer_axis_stop,
1000 pointer_axis_discrete, pointer_axis_value120
1003static void seat_handle_capabilities(
void* data,
struct wl_seat* seat, uint32_t caps)
1005 UwacSeat* input = data;
1008 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer)
1010 input->pointer = wl_seat_get_pointer(seat);
1011 wl_pointer_set_user_data(input->pointer, input);
1012 wl_pointer_add_listener(input->pointer, &pointer_listener, input);
1014 input->cursor_theme = wl_cursor_theme_load(NULL, 32, input->display->shm);
1015 if (!input->cursor_theme)
1017 assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1018 "unable to get wayland cursor theme\n"));
1022 input->default_cursor = wl_cursor_theme_get_cursor(input->cursor_theme,
"left_ptr");
1023 if (!input->default_cursor)
1025 assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1026 "unable to get wayland cursor left_ptr\n"));
1030 else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer)
1032#ifdef WL_POINTER_RELEASE_SINCE_VERSION
1033 if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1034 wl_pointer_release(input->pointer);
1037 wl_pointer_destroy(input->pointer);
1038 if (input->cursor_theme)
1039 wl_cursor_theme_destroy(input->cursor_theme);
1041 input->default_cursor = NULL;
1042 input->cursor_theme = NULL;
1043 input->pointer = NULL;
1046 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard)
1048 input->keyboard = wl_seat_get_keyboard(seat);
1049 wl_keyboard_set_user_data(input->keyboard, input);
1050 wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input);
1052 else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard)
1054#ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1055 if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1056 wl_keyboard_release(input->keyboard);
1059 wl_keyboard_destroy(input->keyboard);
1060 input->keyboard = NULL;
1063 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch)
1065 input->touch = wl_seat_get_touch(seat);
1066 wl_touch_set_user_data(input->touch, input);
1067 wl_touch_add_listener(input->touch, &touch_listener, input);
1069 else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch)
1071#ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1072 if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1073 wl_touch_release(input->touch);
1076 wl_touch_destroy(input->touch);
1077 input->touch = NULL;
1081static void seat_handle_name(
void* data,
struct wl_seat* seat,
const char* name)
1083 UwacSeat* input = data;
1089 input->name = strdup(name);
1091 assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1092 "unable to strdup seat's name\n"));
1095static const struct wl_seat_listener seat_listener = { seat_handle_capabilities, seat_handle_name };
1097UwacSeat* UwacSeatNew(UwacDisplay* d, uint32_t
id, uint32_t version)
1099 UwacSeat* ret = xzalloc(
sizeof(UwacSeat));
1105 ret->seat_version = version;
1107 wl_array_init(&ret->pressed_keys);
1108 ret->xkb_context = xkb_context_new(0);
1109 if (!ret->xkb_context)
1111 (void)fprintf(stderr,
"%s: unable to allocate a xkb_context\n", __func__);
1115 ret->seat = wl_registry_bind(d->registry,
id, &wl_seat_interface, version);
1116 wl_seat_add_listener(ret->seat, &seat_listener, ret);
1117 wl_seat_set_user_data(ret->seat, ret);
1119 ret->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
1120 if (ret->repeat_timer_fd < 0)
1122 (void)fprintf(stderr,
"%s: error creating repeat timer\n", __func__);
1125 ret->repeat_task.run = keyboard_repeat_func;
1126 if (UwacDisplayWatchFd(d, ret->repeat_timer_fd, EPOLLIN, &ret->repeat_task) < 0)
1128 (void)fprintf(stderr,
"%s: error polling repeat timer\n", __func__);
1132 wl_list_insert(d->seats.prev, &ret->link);
1136 UwacSeatDestroy(ret);
1140void UwacSeatDestroy(UwacSeat* s)
1145 UwacSeatInhibitShortcuts(s,
false);
1148#ifdef WL_SEAT_RELEASE_SINCE_VERSION
1149 if (s->seat_version >= WL_SEAT_RELEASE_SINCE_VERSION)
1150 wl_seat_release(s->seat);
1153 wl_seat_destroy(s->seat);
1158 wl_array_release(&s->pressed_keys);
1160 xkb_state_unref(s->xkb.state);
1161 xkb_context_unref(s->xkb_context);
1165#ifdef WL_POINTER_RELEASE_SINCE_VERSION
1166 if (s->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1167 wl_pointer_release(s->pointer);
1170 wl_pointer_destroy(s->pointer);
1175#ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1176 if (s->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1177 wl_touch_release(s->touch);
1180 wl_touch_destroy(s->touch);
1185#ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1186 if (s->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1187 wl_keyboard_release(s->keyboard);
1190 wl_keyboard_destroy(s->keyboard);
1194 wl_data_device_destroy(s->data_device);
1197 wl_data_source_destroy(s->data_source);
1199 if (s->pointer_surface)
1200 wl_surface_destroy(s->pointer_surface);
1202 free(s->pointer_image);
1203 free(s->pointer_data);
1205 wl_list_remove(&s->link);
1209const char* UwacSeatGetName(
const UwacSeat* seat)
1215UwacSeatId UwacSeatGetId(
const UwacSeat* seat)
1218 return seat->seat_id;
1221UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* s,
bool inhibit)
1224 return UWAC_ERROR_CLOSED;
1226 if (s->keyboard_inhibitor)
1228 zwp_keyboard_shortcuts_inhibitor_v1_destroy(s->keyboard_inhibitor);
1229 s->keyboard_inhibitor = NULL;
1231 if (inhibit && s->display && s->display->keyboard_inhibit_manager)
1232 s->keyboard_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(
1233 s->display->keyboard_inhibit_manager, s->keyboard_focus->surface, s->seat);
1235 if (inhibit && !s->keyboard_inhibitor)
1236 return UWAC_ERROR_INTERNAL;
1237 return UWAC_SUCCESS;
1240UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat,
const void* data,
size_t length,
size_t width,
1241 size_t height,
size_t hot_x,
size_t hot_y)
1244 return UWAC_ERROR_CLOSED;
1246 free(seat->pointer_image);
1247 seat->pointer_image = NULL;
1249 free(seat->pointer_data);
1250 seat->pointer_data = NULL;
1251 seat->pointer_size = 0;
1254 if ((data != NULL) && (length != 0))
1256 seat->pointer_image = xzalloc(
sizeof(
struct wl_cursor_image));
1257 if (!seat->pointer_image)
1258 return UWAC_ERROR_NOMEMORY;
1259 seat->pointer_image->width = width;
1260 seat->pointer_image->height = height;
1261 seat->pointer_image->hotspot_x = hot_x;
1262 seat->pointer_image->hotspot_y = hot_y;
1264 free(seat->pointer_data);
1265 seat->pointer_data = xmalloc(length);
1266 memcpy(seat->pointer_data, data, length);
1267 seat->pointer_size = length;
1269 seat->pointer_type = 2;
1272 else if (length != 0)
1274 seat->pointer_type = 0;
1279 seat->pointer_type = 1;
1281 if (seat && !seat->default_cursor)
1282 return UWAC_SUCCESS;
1283 return set_cursor_image(seat, seat->display->pointer_focus_serial);