|
|
|
@ -274,6 +274,11 @@ struct widget { |
|
|
|
|
widget_leave_handler_t leave_handler; |
|
|
|
|
widget_motion_handler_t motion_handler; |
|
|
|
|
widget_button_handler_t button_handler; |
|
|
|
|
widget_touch_down_handler_t touch_down_handler; |
|
|
|
|
widget_touch_up_handler_t touch_up_handler; |
|
|
|
|
widget_touch_motion_handler_t touch_motion_handler; |
|
|
|
|
widget_touch_frame_handler_t touch_frame_handler; |
|
|
|
|
widget_touch_cancel_handler_t touch_cancel_handler; |
|
|
|
|
widget_axis_handler_t axis_handler; |
|
|
|
|
void *user_data; |
|
|
|
|
int opaque; |
|
|
|
@ -281,13 +286,22 @@ struct widget { |
|
|
|
|
int default_cursor; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct touch_point { |
|
|
|
|
int32_t id; |
|
|
|
|
struct widget *widget; |
|
|
|
|
struct wl_list link; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct input { |
|
|
|
|
struct display *display; |
|
|
|
|
struct wl_seat *seat; |
|
|
|
|
struct wl_pointer *pointer; |
|
|
|
|
struct wl_keyboard *keyboard; |
|
|
|
|
struct wl_touch *touch; |
|
|
|
|
struct wl_list touch_point_list; |
|
|
|
|
struct window *pointer_focus; |
|
|
|
|
struct window *keyboard_focus; |
|
|
|
|
struct window *touch_focus; |
|
|
|
|
int current_cursor; |
|
|
|
|
uint32_t cursor_anim_start; |
|
|
|
|
struct wl_callback *cursor_frame_cb; |
|
|
|
@ -1889,6 +1903,41 @@ widget_set_button_handler(struct widget *widget, |
|
|
|
|
widget->button_handler = handler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
widget_set_touch_up_handler(struct widget *widget, |
|
|
|
|
widget_touch_up_handler_t handler) |
|
|
|
|
{ |
|
|
|
|
widget->touch_up_handler = handler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
widget_set_touch_down_handler(struct widget *widget, |
|
|
|
|
widget_touch_down_handler_t handler) |
|
|
|
|
{ |
|
|
|
|
widget->touch_down_handler = handler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
widget_set_touch_motion_handler(struct widget *widget, |
|
|
|
|
widget_touch_motion_handler_t handler) |
|
|
|
|
{ |
|
|
|
|
widget->touch_motion_handler = handler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
widget_set_touch_frame_handler(struct widget *widget, |
|
|
|
|
widget_touch_frame_handler_t handler) |
|
|
|
|
{ |
|
|
|
|
widget->touch_frame_handler = handler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
widget_set_touch_cancel_handler(struct widget *widget, |
|
|
|
|
widget_touch_cancel_handler_t handler) |
|
|
|
|
{ |
|
|
|
|
widget->touch_cancel_handler = handler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
widget_set_axis_handler(struct widget *widget, |
|
|
|
|
widget_axis_handler_t handler) |
|
|
|
@ -2303,6 +2352,35 @@ frame_button_button_handler(struct widget *widget, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
frame_button_touch_down_handler(struct widget *widget, uint32_t serial, |
|
|
|
|
uint32_t time, int32_t id, |
|
|
|
|
float x, float y, void *data) |
|
|
|
|
{ |
|
|
|
|
struct frame_button *frame_button = data; |
|
|
|
|
struct window *window = widget->window; |
|
|
|
|
|
|
|
|
|
switch (frame_button->type) { |
|
|
|
|
case FRAME_BUTTON_CLOSE: |
|
|
|
|
if (window->close_handler) |
|
|
|
|
window->close_handler(window->parent, |
|
|
|
|
window->user_data); |
|
|
|
|
else |
|
|
|
|
display_exit(window->display); |
|
|
|
|
break; |
|
|
|
|
case FRAME_BUTTON_MINIMIZE: |
|
|
|
|
fprintf(stderr,"Minimize stub\n"); |
|
|
|
|
break; |
|
|
|
|
case FRAME_BUTTON_MAXIMIZE: |
|
|
|
|
window_set_maximized(window, window->type != TYPE_MAXIMIZED); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
/* Unknown operation */ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
frame_button_motion_handler(struct widget *widget, |
|
|
|
|
struct input *input, uint32_t time, |
|
|
|
@ -2402,6 +2480,7 @@ frame_button_create(struct frame *frame, void *data, enum frame_button_action ty |
|
|
|
|
widget_set_redraw_handler(frame_button->widget, frame_button_redraw_handler); |
|
|
|
|
widget_set_enter_handler(frame_button->widget, frame_button_enter_handler); |
|
|
|
|
widget_set_leave_handler(frame_button->widget, frame_button_leave_handler); |
|
|
|
|
widget_set_touch_down_handler(frame_button->widget, frame_button_touch_down_handler); |
|
|
|
|
widget_set_button_handler(frame_button->widget, frame_button_button_handler); |
|
|
|
|
widget_set_motion_handler(frame_button->widget, frame_button_motion_handler); |
|
|
|
|
return frame_button->widget; |
|
|
|
@ -3115,6 +3194,153 @@ static const struct wl_keyboard_listener keyboard_listener = { |
|
|
|
|
keyboard_handle_modifiers, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
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 x_w, wl_fixed_t y_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct widget *widget; |
|
|
|
|
float sx = wl_fixed_to_double(x_w); |
|
|
|
|
float sy = wl_fixed_to_double(y_w); |
|
|
|
|
|
|
|
|
|
DBG("touch_handle_down: %i %i\n", id, wl_list_length(&input->touch_point_list)); |
|
|
|
|
|
|
|
|
|
input->touch_focus = wl_surface_get_user_data(surface); |
|
|
|
|
if (!input->touch_focus) { |
|
|
|
|
DBG("Failed to find to touch focus for surface %p\n", surface); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
widget = window_find_widget(input->touch_focus, |
|
|
|
|
wl_fixed_to_double(x_w), |
|
|
|
|
wl_fixed_to_double(y_w)); |
|
|
|
|
if (widget) { |
|
|
|
|
struct touch_point *tp = xmalloc(sizeof *tp); |
|
|
|
|
if (tp) { |
|
|
|
|
tp->id = id; |
|
|
|
|
tp->widget = widget; |
|
|
|
|
wl_list_insert(&input->touch_point_list, &tp->link); |
|
|
|
|
|
|
|
|
|
if (widget->touch_down_handler) |
|
|
|
|
(*widget->touch_down_handler)(widget, serial, |
|
|
|
|
time, id, |
|
|
|
|
sx, sy, |
|
|
|
|
widget->user_data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
touch_handle_up(void *data, struct wl_touch *wl_touch, |
|
|
|
|
uint32_t serial, uint32_t time, int32_t id) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct touch_point *tp, *tmp; |
|
|
|
|
|
|
|
|
|
DBG("touch_handle_up: %i %i\n", id, wl_list_length(&input->touch_point_list)); |
|
|
|
|
|
|
|
|
|
if (!input->touch_focus) { |
|
|
|
|
DBG("No touch focus found for touch up event!\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) { |
|
|
|
|
if (tp->id != id) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (tp->widget->touch_up_handler) |
|
|
|
|
(*tp->widget->touch_up_handler)(tp->widget, serial, |
|
|
|
|
time, id, |
|
|
|
|
tp->widget->user_data); |
|
|
|
|
|
|
|
|
|
wl_list_remove(&tp->link); |
|
|
|
|
free(tp); |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
touch_handle_motion(void *data, struct wl_touch *wl_touch, |
|
|
|
|
uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct touch_point *tp; |
|
|
|
|
float sx = wl_fixed_to_double(x_w); |
|
|
|
|
float sy = wl_fixed_to_double(y_w); |
|
|
|
|
|
|
|
|
|
DBG("touch_handle_motion: %i %i\n", id, wl_list_length(&input->touch_point_list)); |
|
|
|
|
|
|
|
|
|
if (!input->touch_focus) { |
|
|
|
|
DBG("No touch focus found for touch motion event!\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wl_list_for_each(tp, &input->touch_point_list, link) { |
|
|
|
|
if (tp->id != id) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (tp->widget->touch_motion_handler) |
|
|
|
|
(*tp->widget->touch_motion_handler)(tp->widget, time, |
|
|
|
|
id, sx, sy, |
|
|
|
|
tp->widget->user_data); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
touch_handle_frame(void *data, struct wl_touch *wl_touch) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct touch_point *tp, *tmp; |
|
|
|
|
|
|
|
|
|
DBG("touch_handle_frame\n"); |
|
|
|
|
|
|
|
|
|
if (!input->touch_focus) { |
|
|
|
|
DBG("No touch focus found for touch frame event!\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) { |
|
|
|
|
if (tp->widget->touch_frame_handler) |
|
|
|
|
(*tp->widget->touch_frame_handler)(tp->widget, tp->widget->user_data); |
|
|
|
|
|
|
|
|
|
wl_list_remove(&tp->link); |
|
|
|
|
free(tp); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
touch_handle_cancel(void *data, struct wl_touch *wl_touch) |
|
|
|
|
{ |
|
|
|
|
struct input *input = data; |
|
|
|
|
struct touch_point *tp, *tmp; |
|
|
|
|
|
|
|
|
|
DBG("touch_handle_cancel\n"); |
|
|
|
|
|
|
|
|
|
if (!input->touch_focus) { |
|
|
|
|
DBG("No touch focus found for touch cancel event!\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) { |
|
|
|
|
if (tp->widget->touch_cancel_handler) |
|
|
|
|
(*tp->widget->touch_cancel_handler)(tp->widget, tp->widget->user_data); |
|
|
|
|
|
|
|
|
|
wl_list_remove(&tp->link); |
|
|
|
|
free(tp); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const struct wl_touch_listener touch_listener = { |
|
|
|
|
touch_handle_down, |
|
|
|
|
touch_handle_up, |
|
|
|
|
touch_handle_motion, |
|
|
|
|
touch_handle_frame, |
|
|
|
|
touch_handle_cancel, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
seat_handle_capabilities(void *data, struct wl_seat *seat, |
|
|
|
|
enum wl_seat_capability caps) |
|
|
|
@ -3140,6 +3366,15 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, |
|
|
|
|
wl_keyboard_destroy(input->keyboard); |
|
|
|
|
input->keyboard = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) { |
|
|
|
|
input->touch = wl_seat_get_touch(seat); |
|
|
|
|
wl_touch_set_user_data(input->touch, input); |
|
|
|
|
wl_touch_add_listener(input->touch, &touch_listener, input); |
|
|
|
|
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) { |
|
|
|
|
wl_touch_destroy(input->touch); |
|
|
|
|
input->touch = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const struct wl_seat_listener seat_listener = { |
|
|
|
@ -4693,6 +4928,7 @@ display_add_input(struct display *d, uint32_t id) |
|
|
|
|
input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1); |
|
|
|
|
input->pointer_focus = NULL; |
|
|
|
|
input->keyboard_focus = NULL; |
|
|
|
|
wl_list_init(&input->touch_point_list); |
|
|
|
|
wl_list_insert(d->input_list.prev, &input->link); |
|
|
|
|
|
|
|
|
|
wl_seat_add_listener(input->seat, &seat_listener, input); |
|
|
|
|