|
|
|
@ -1762,37 +1762,6 @@ input_set_focus_widget(struct input *input, struct widget *focus, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
pointer_handle_motion(void *data, struct wl_pointer *pointer, |
|
|
|
|
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct window *window = input->pointer_focus; |
|
|
|
|
struct widget *widget; |
|
|
|
|
int cursor = CURSOR_LEFT_PTR; |
|
|
|
|
float sx = wl_fixed_to_double(sx_w); |
|
|
|
|
float sy = wl_fixed_to_double(sy_w); |
|
|
|
|
|
|
|
|
|
input->sx = sx; |
|
|
|
|
input->sy = sy; |
|
|
|
|
|
|
|
|
|
if (!(input->grab && input->grab_button)) { |
|
|
|
|
widget = widget_find_widget(window->widget, sx, sy); |
|
|
|
|
input_set_focus_widget(input, widget, sx, sy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (input->grab) |
|
|
|
|
widget = input->grab; |
|
|
|
|
else |
|
|
|
|
widget = input->focus_widget; |
|
|
|
|
if (widget && widget->motion_handler) |
|
|
|
|
cursor = widget->motion_handler(input->focus_widget, |
|
|
|
|
input, time, sx, sy, |
|
|
|
|
widget->user_data); |
|
|
|
|
|
|
|
|
|
input_set_pointer_image(input, cursor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
input_grab(struct input *input, struct widget *widget, uint32_t button) |
|
|
|
|
{ |
|
|
|
@ -1813,147 +1782,6 @@ input_ungrab(struct input *input) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, |
|
|
|
|
uint32_t time, uint32_t button, uint32_t state_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct widget *widget; |
|
|
|
|
enum wl_pointer_button_state state = state_w; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
if (input->focus_widget && input->grab == NULL && |
|
|
|
|
state == WL_POINTER_BUTTON_STATE_PRESSED) |
|
|
|
|
input_grab(input, input->focus_widget, button); |
|
|
|
|
|
|
|
|
|
widget = input->grab; |
|
|
|
|
if (widget && widget->button_handler) |
|
|
|
|
(*widget->button_handler)(widget, |
|
|
|
|
input, time, |
|
|
|
|
button, state, |
|
|
|
|
input->grab->user_data); |
|
|
|
|
|
|
|
|
|
if (input->grab && input->grab_button == button && |
|
|
|
|
state == WL_POINTER_BUTTON_STATE_RELEASED) |
|
|
|
|
input_ungrab(input); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
pointer_handle_axis(void *data, struct wl_pointer *pointer, |
|
|
|
|
uint32_t time, uint32_t axis, wl_fixed_t value) |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_key(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, uint32_t time, uint32_t key, |
|
|
|
|
uint32_t state_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct window *window = input->keyboard_focus; |
|
|
|
|
uint32_t code, num_syms; |
|
|
|
|
enum wl_keyboard_key_state state = state_w; |
|
|
|
|
const xkb_keysym_t *syms; |
|
|
|
|
xkb_keysym_t sym; |
|
|
|
|
xkb_mod_mask_t mask; |
|
|
|
|
struct itimerspec its; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
code = key + 8; |
|
|
|
|
if (!window || window->keyboard_device != input || !input->xkb.state) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
num_syms = xkb_key_get_syms(input->xkb.state, code, &syms); |
|
|
|
|
|
|
|
|
|
mask = xkb_state_serialize_mods(input->xkb.state, |
|
|
|
|
XKB_STATE_DEPRESSED | |
|
|
|
|
XKB_STATE_LATCHED); |
|
|
|
|
input->modifiers = 0; |
|
|
|
|
if (mask & input->xkb.control_mask) |
|
|
|
|
input->modifiers |= MOD_CONTROL_MASK; |
|
|
|
|
if (mask & input->xkb.alt_mask) |
|
|
|
|
input->modifiers |= MOD_ALT_MASK; |
|
|
|
|
if (mask & input->xkb.shift_mask) |
|
|
|
|
input->modifiers |= MOD_SHIFT_MASK; |
|
|
|
|
|
|
|
|
|
sym = XKB_KEY_NoSymbol; |
|
|
|
|
if (num_syms == 1) |
|
|
|
|
sym = syms[0]; |
|
|
|
|
|
|
|
|
|
if (sym == XKB_KEY_F5 && input->modifiers == MOD_ALT_MASK) { |
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) |
|
|
|
|
window_set_maximized(window, |
|
|
|
|
window->type != TYPE_MAXIMIZED); |
|
|
|
|
} else if (sym == XKB_KEY_F11 && |
|
|
|
|
window->fullscreen_handler && |
|
|
|
|
state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
|
|
|
window->fullscreen_handler(window, window->user_data); |
|
|
|
|
} else if (sym == XKB_KEY_F4 && |
|
|
|
|
input->modifiers == MOD_ALT_MASK && |
|
|
|
|
state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
|
|
|
if (window->close_handler) |
|
|
|
|
window->close_handler(window->parent, |
|
|
|
|
window->user_data); |
|
|
|
|
else |
|
|
|
|
display_exit(window->display); |
|
|
|
|
} else if (window->key_handler) { |
|
|
|
|
(*window->key_handler)(window, input, time, key, |
|
|
|
|
sym, state, window->user_data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_RELEASED && |
|
|
|
|
key == input->repeat_key) { |
|
|
|
|
its.it_interval.tv_sec = 0; |
|
|
|
|
its.it_interval.tv_nsec = 0; |
|
|
|
|
its.it_value.tv_sec = 0; |
|
|
|
|
its.it_value.tv_nsec = 0; |
|
|
|
|
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL); |
|
|
|
|
} else if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
|
|
|
input->repeat_sym = sym; |
|
|
|
|
input->repeat_key = key; |
|
|
|
|
input->repeat_time = time; |
|
|
|
|
its.it_interval.tv_sec = 0; |
|
|
|
|
its.it_interval.tv_nsec = 25 * 1000 * 1000; |
|
|
|
|
its.it_value.tv_sec = 0; |
|
|
|
|
its.it_value.tv_nsec = 400 * 1000 * 1000; |
|
|
|
|
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_repeat_func(struct task *task, uint32_t events) |
|
|
|
|
{ |
|
|
|
|
struct input *input = |
|
|
|
|
container_of(task, struct input, repeat_task); |
|
|
|
|
struct window *window = input->keyboard_focus; |
|
|
|
|
uint64_t exp; |
|
|
|
|
|
|
|
|
|
if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp) |
|
|
|
|
/* If we change the timer between the fd becoming
|
|
|
|
|
* readable and getting here, there'll be nothing to |
|
|
|
|
* read and we get EAGAIN. */ |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (window && window->key_handler) { |
|
|
|
|
(*window->key_handler)(window, input, input->repeat_time, |
|
|
|
|
input->repeat_key, input->repeat_sym, |
|
|
|
|
WL_KEYBOARD_KEY_STATE_PRESSED, |
|
|
|
|
window->user_data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, uint32_t mods_depressed, |
|
|
|
|
uint32_t mods_latched, uint32_t mods_locked, |
|
|
|
|
uint32_t group) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
|
|
|
|
|
xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, |
|
|
|
|
mods_locked, 0, 0, group); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
input_remove_pointer_focus(struct input *input) |
|
|
|
|
{ |
|
|
|
@ -2013,6 +1841,76 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer, |
|
|
|
|
input_remove_pointer_focus(input); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
pointer_handle_motion(void *data, struct wl_pointer *pointer, |
|
|
|
|
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct window *window = input->pointer_focus; |
|
|
|
|
struct widget *widget; |
|
|
|
|
int cursor = CURSOR_LEFT_PTR; |
|
|
|
|
float sx = wl_fixed_to_double(sx_w); |
|
|
|
|
float sy = wl_fixed_to_double(sy_w); |
|
|
|
|
|
|
|
|
|
input->sx = sx; |
|
|
|
|
input->sy = sy; |
|
|
|
|
|
|
|
|
|
if (!(input->grab && input->grab_button)) { |
|
|
|
|
widget = widget_find_widget(window->widget, sx, sy); |
|
|
|
|
input_set_focus_widget(input, widget, sx, sy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (input->grab) |
|
|
|
|
widget = input->grab; |
|
|
|
|
else |
|
|
|
|
widget = input->focus_widget; |
|
|
|
|
if (widget && widget->motion_handler) |
|
|
|
|
cursor = widget->motion_handler(input->focus_widget, |
|
|
|
|
input, time, sx, sy, |
|
|
|
|
widget->user_data); |
|
|
|
|
|
|
|
|
|
input_set_pointer_image(input, cursor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, |
|
|
|
|
uint32_t time, uint32_t button, uint32_t state_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct widget *widget; |
|
|
|
|
enum wl_pointer_button_state state = state_w; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
if (input->focus_widget && input->grab == NULL && |
|
|
|
|
state == WL_POINTER_BUTTON_STATE_PRESSED) |
|
|
|
|
input_grab(input, input->focus_widget, button); |
|
|
|
|
|
|
|
|
|
widget = input->grab; |
|
|
|
|
if (widget && widget->button_handler) |
|
|
|
|
(*widget->button_handler)(widget, |
|
|
|
|
input, time, |
|
|
|
|
button, state, |
|
|
|
|
input->grab->user_data); |
|
|
|
|
|
|
|
|
|
if (input->grab && input->grab_button == button && |
|
|
|
|
state == WL_POINTER_BUTTON_STATE_RELEASED) |
|
|
|
|
input_ungrab(input); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
pointer_handle_axis(void *data, struct wl_pointer *pointer, |
|
|
|
|
uint32_t time, uint32_t axis, wl_fixed_t value) |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const struct wl_pointer_listener pointer_listener = { |
|
|
|
|
pointer_handle_enter, |
|
|
|
|
pointer_handle_leave, |
|
|
|
|
pointer_handle_motion, |
|
|
|
|
pointer_handle_button, |
|
|
|
|
pointer_handle_axis, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
input_remove_keyboard_focus(struct input *input) |
|
|
|
|
{ |
|
|
|
@ -2037,32 +1935,25 @@ input_remove_keyboard_focus(struct input *input) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, struct wl_surface *surface, |
|
|
|
|
struct wl_array *keys) |
|
|
|
|
keyboard_repeat_func(struct task *task, uint32_t events) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct window *window; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
input->keyboard_focus = wl_surface_get_user_data(surface); |
|
|
|
|
|
|
|
|
|
window = input->keyboard_focus; |
|
|
|
|
window->keyboard_device = input; |
|
|
|
|
if (window->keyboard_focus_handler) |
|
|
|
|
(*window->keyboard_focus_handler)(window, |
|
|
|
|
window->keyboard_device, |
|
|
|
|
window->user_data); |
|
|
|
|
} |
|
|
|
|
struct input *input = |
|
|
|
|
container_of(task, struct input, repeat_task); |
|
|
|
|
struct window *window = input->keyboard_focus; |
|
|
|
|
uint64_t exp; |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, struct wl_surface *surface) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp) |
|
|
|
|
/* If we change the timer between the fd becoming
|
|
|
|
|
* readable and getting here, there'll be nothing to |
|
|
|
|
* read and we get EAGAIN. */ |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
input_remove_keyboard_focus(input); |
|
|
|
|
if (window && window->key_handler) { |
|
|
|
|
(*window->key_handler)(window, input, input->repeat_time, |
|
|
|
|
input->repeat_key, input->repeat_sym, |
|
|
|
|
WL_KEYBOARD_KEY_STATE_PRESSED, |
|
|
|
|
window->user_data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -2116,13 +2007,122 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const struct wl_pointer_listener pointer_listener = { |
|
|
|
|
pointer_handle_enter, |
|
|
|
|
pointer_handle_leave, |
|
|
|
|
pointer_handle_motion, |
|
|
|
|
pointer_handle_button, |
|
|
|
|
pointer_handle_axis, |
|
|
|
|
}; |
|
|
|
|
static void |
|
|
|
|
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, struct wl_surface *surface, |
|
|
|
|
struct wl_array *keys) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct window *window; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
input->keyboard_focus = wl_surface_get_user_data(surface); |
|
|
|
|
|
|
|
|
|
window = input->keyboard_focus; |
|
|
|
|
window->keyboard_device = input; |
|
|
|
|
if (window->keyboard_focus_handler) |
|
|
|
|
(*window->keyboard_focus_handler)(window, |
|
|
|
|
window->keyboard_device, |
|
|
|
|
window->user_data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, struct wl_surface *surface) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
input_remove_keyboard_focus(input); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_key(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, uint32_t time, uint32_t key, |
|
|
|
|
uint32_t state_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct window *window = input->keyboard_focus; |
|
|
|
|
uint32_t code, num_syms; |
|
|
|
|
enum wl_keyboard_key_state state = state_w; |
|
|
|
|
const xkb_keysym_t *syms; |
|
|
|
|
xkb_keysym_t sym; |
|
|
|
|
xkb_mod_mask_t mask; |
|
|
|
|
struct itimerspec its; |
|
|
|
|
|
|
|
|
|
input->display->serial = serial; |
|
|
|
|
code = key + 8; |
|
|
|
|
if (!window || window->keyboard_device != input || !input->xkb.state) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
num_syms = xkb_key_get_syms(input->xkb.state, code, &syms); |
|
|
|
|
|
|
|
|
|
mask = xkb_state_serialize_mods(input->xkb.state, |
|
|
|
|
XKB_STATE_DEPRESSED | |
|
|
|
|
XKB_STATE_LATCHED); |
|
|
|
|
input->modifiers = 0; |
|
|
|
|
if (mask & input->xkb.control_mask) |
|
|
|
|
input->modifiers |= MOD_CONTROL_MASK; |
|
|
|
|
if (mask & input->xkb.alt_mask) |
|
|
|
|
input->modifiers |= MOD_ALT_MASK; |
|
|
|
|
if (mask & input->xkb.shift_mask) |
|
|
|
|
input->modifiers |= MOD_SHIFT_MASK; |
|
|
|
|
|
|
|
|
|
sym = XKB_KEY_NoSymbol; |
|
|
|
|
if (num_syms == 1) |
|
|
|
|
sym = syms[0]; |
|
|
|
|
|
|
|
|
|
if (sym == XKB_KEY_F5 && input->modifiers == MOD_ALT_MASK) { |
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) |
|
|
|
|
window_set_maximized(window, |
|
|
|
|
window->type != TYPE_MAXIMIZED); |
|
|
|
|
} else if (sym == XKB_KEY_F11 && |
|
|
|
|
window->fullscreen_handler && |
|
|
|
|
state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
|
|
|
window->fullscreen_handler(window, window->user_data); |
|
|
|
|
} else if (sym == XKB_KEY_F4 && |
|
|
|
|
input->modifiers == MOD_ALT_MASK && |
|
|
|
|
state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
|
|
|
if (window->close_handler) |
|
|
|
|
window->close_handler(window->parent, |
|
|
|
|
window->user_data); |
|
|
|
|
else |
|
|
|
|
display_exit(window->display); |
|
|
|
|
} else if (window->key_handler) { |
|
|
|
|
(*window->key_handler)(window, input, time, key, |
|
|
|
|
sym, state, window->user_data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (state == WL_KEYBOARD_KEY_STATE_RELEASED && |
|
|
|
|
key == input->repeat_key) { |
|
|
|
|
its.it_interval.tv_sec = 0; |
|
|
|
|
its.it_interval.tv_nsec = 0; |
|
|
|
|
its.it_value.tv_sec = 0; |
|
|
|
|
its.it_value.tv_nsec = 0; |
|
|
|
|
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL); |
|
|
|
|
} else if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
|
|
|
|
input->repeat_sym = sym; |
|
|
|
|
input->repeat_key = key; |
|
|
|
|
input->repeat_time = time; |
|
|
|
|
its.it_interval.tv_sec = 0; |
|
|
|
|
its.it_interval.tv_nsec = 25 * 1000 * 1000; |
|
|
|
|
its.it_value.tv_sec = 0; |
|
|
|
|
its.it_value.tv_nsec = 400 * 1000 * 1000; |
|
|
|
|
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, |
|
|
|
|
uint32_t serial, uint32_t mods_depressed, |
|
|
|
|
uint32_t mods_latched, uint32_t mods_locked, |
|
|
|
|
uint32_t group) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
|
|
|
|
|
xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, |
|
|
|
|
mods_locked, 0, 0, group); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const struct wl_keyboard_listener keyboard_listener = { |
|
|
|
|
keyboard_handle_keymap, |
|
|
|
|