Clean up serial handling

This commit is contained in:
Markus Ongyerth 2018-05-17 14:23:17 +02:00
parent 88a4b908d1
commit 25c2808153
6 changed files with 84 additions and 79 deletions

View File

@ -49,10 +49,6 @@ struct wlr_tablet_pad_client_v2 {
struct wl_resource *resource; struct wl_resource *resource;
struct wlr_tablet_v2_tablet_pad *pad; struct wlr_tablet_v2_tablet_pad *pad;
uint32_t enter_serial;
uint32_t mode_serial;
uint32_t leave_serial;
size_t button_count; size_t button_count;
size_t group_count; size_t group_count;
@ -73,8 +69,6 @@ struct wlr_tablet_tool_client_v2 {
struct wlr_tablet_v2_tablet_tool *tool; struct wlr_tablet_v2_tablet_tool *tool;
struct wlr_tablet_seat_client_v2 *seat; struct wlr_tablet_seat_client_v2 *seat;
uint32_t proximity_serial;
struct wl_event_source *frame_source; struct wl_event_source *frame_source;
}; };

View File

@ -47,11 +47,12 @@ struct wlr_tablet_v2_tablet_tool {
struct wl_listener surface_destroy; struct wl_listener surface_destroy;
struct wl_listener client_destroy; struct wl_listener client_destroy;
uint32_t down_serial; uint32_t proximity_serial;
bool is_down; bool is_down;
uint32_t button_serial; uint32_t down_serial;
size_t num_buttons; size_t num_buttons;
uint32_t pressed_buttons[WLR_TABLEt_V2_TOOL_BUTTONS_CAP]; uint32_t pressed_buttons[WLR_TABLEt_V2_TOOL_BUTTONS_CAP];
uint32_t pressed_serials[WLR_TABLEt_V2_TOOL_BUTTONS_CAP];
struct { struct {
struct wl_signal set_cursor; // struct wlr_tablet_v2_event_cursor struct wl_signal set_cursor; // struct wlr_tablet_v2_event_cursor
@ -93,42 +94,42 @@ struct wlr_tablet_v2_event_feedback {
}; };
struct wlr_tablet_v2_tablet *wlr_tablet_create( struct wlr_tablet_v2_tablet *wlr_tablet_create(
struct wlr_tablet_manager_v2 *manager, struct wlr_tablet_manager_v2 *manager,
struct wlr_seat *wlr_seat, struct wlr_seat *wlr_seat,
struct wlr_input_device *wlr_device); struct wlr_input_device *wlr_device);
struct wlr_tablet_v2_tablet_pad *wlr_tablet_pad_create( struct wlr_tablet_v2_tablet_pad *wlr_tablet_pad_create(
struct wlr_tablet_manager_v2 *manager, struct wlr_tablet_manager_v2 *manager,
struct wlr_seat *wlr_seat, struct wlr_seat *wlr_seat,
struct wlr_input_device *wlr_device); struct wlr_input_device *wlr_device);
struct wlr_tablet_v2_tablet_tool *wlr_tablet_tool_create( struct wlr_tablet_v2_tablet_tool *wlr_tablet_tool_create(
struct wlr_tablet_manager_v2 *manager, struct wlr_tablet_manager_v2 *manager,
struct wlr_seat *wlr_seat, struct wlr_seat *wlr_seat,
struct wlr_tablet_tool_tool *wlr_tool); struct wlr_tablet_tool_tool *wlr_tool);
struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display); struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display);
void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager); void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager);
uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in( void wlr_send_tablet_v2_tablet_tool_proximity_in(
struct wlr_tablet_v2_tablet_tool *tool, struct wlr_tablet_v2_tablet_tool *tool,
struct wlr_tablet_v2_tablet *tablet, struct wlr_tablet_v2_tablet *tablet,
struct wlr_surface *surface); struct wlr_surface *surface);
uint32_t wlr_send_tablet_v2_tablet_tool_down(struct wlr_tablet_v2_tablet_tool *tool); void wlr_send_tablet_v2_tablet_tool_down(struct wlr_tablet_v2_tablet_tool *tool);
void wlr_send_tablet_v2_tablet_tool_up(struct wlr_tablet_v2_tablet_tool *tool); void wlr_send_tablet_v2_tablet_tool_up(struct wlr_tablet_v2_tablet_tool *tool);
void wlr_send_tablet_v2_tablet_tool_motion( void wlr_send_tablet_v2_tablet_tool_motion(
struct wlr_tablet_v2_tablet_tool *tool, double x, double y); struct wlr_tablet_v2_tablet_tool *tool, double x, double y);
void wlr_send_tablet_v2_tablet_tool_pressure( void wlr_send_tablet_v2_tablet_tool_pressure(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t pressure); struct wlr_tablet_v2_tablet_tool *tool, uint32_t pressure);
void wlr_send_tablet_v2_tablet_tool_distance( void wlr_send_tablet_v2_tablet_tool_distance(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t distance); struct wlr_tablet_v2_tablet_tool *tool, uint32_t distance);
void wlr_send_tablet_v2_tablet_tool_tilt( void wlr_send_tablet_v2_tablet_tool_tilt(
struct wlr_tablet_v2_tablet_tool *tool, double x, double y); struct wlr_tablet_v2_tablet_tool *tool, double x, double y);
void wlr_send_tablet_v2_tablet_tool_rotation( void wlr_send_tablet_v2_tablet_tool_rotation(
struct wlr_tablet_v2_tablet_tool *tool, double degrees); struct wlr_tablet_v2_tablet_tool *tool, double degrees);
@ -142,30 +143,30 @@ void wlr_send_tablet_v2_tablet_tool_wheel(
void wlr_send_tablet_v2_tablet_tool_proximity_out( void wlr_send_tablet_v2_tablet_tool_proximity_out(
struct wlr_tablet_v2_tablet_tool *tool); struct wlr_tablet_v2_tablet_tool *tool);
uint32_t wlr_send_tablet_v2_tablet_tool_button( void wlr_send_tablet_v2_tablet_tool_button(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t button, struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
enum zwp_tablet_pad_v2_button_state state); enum zwp_tablet_pad_v2_button_state state);
uint32_t wlr_send_tablet_v2_tablet_pad_enter( uint32_t wlr_send_tablet_v2_tablet_pad_enter(
struct wlr_tablet_v2_tablet_pad *pad, struct wlr_tablet_v2_tablet_pad *pad,
struct wlr_tablet_v2_tablet *tablet, struct wlr_tablet_v2_tablet *tablet,
struct wlr_surface *surface); struct wlr_surface *surface);
void wlr_send_tablet_v2_tablet_pad_button( void wlr_send_tablet_v2_tablet_pad_button(
struct wlr_tablet_v2_tablet_pad *pad, size_t button, struct wlr_tablet_v2_tablet_pad *pad, size_t button,
uint32_t time, enum zwp_tablet_pad_v2_button_state state); uint32_t time, enum zwp_tablet_pad_v2_button_state state);
void wlr_send_tablet_v2_tablet_pad_strip( struct wlr_tablet_v2_tablet_pad *pad, void wlr_send_tablet_v2_tablet_pad_strip( struct wlr_tablet_v2_tablet_pad *pad,
uint32_t strip, double position, bool finger, uint32_t time); uint32_t strip, double position, bool finger, uint32_t time);
void wlr_send_tablet_v2_tablet_pad_ring(struct wlr_tablet_v2_tablet_pad *pad, void wlr_send_tablet_v2_tablet_pad_ring(struct wlr_tablet_v2_tablet_pad *pad,
uint32_t ring, double position, bool finger, uint32_t time); uint32_t ring, double position, bool finger, uint32_t time);
uint32_t wlr_send_tablet_v2_tablet_pad_leave(struct wlr_tablet_v2_tablet_pad *pad, uint32_t wlr_send_tablet_v2_tablet_pad_leave(struct wlr_tablet_v2_tablet_pad *pad,
struct wlr_surface *surface); struct wlr_surface *surface);
uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad, uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad,
size_t group, uint32_t mode, uint32_t time); size_t group, uint32_t mode, uint32_t time);
bool wlr_surface_accepts_tablet_v2(struct wlr_tablet_v2_tablet *tablet, bool wlr_surface_accepts_tablet_v2(struct wlr_tablet_v2_tablet *tablet,
struct wlr_surface *surface); struct wlr_surface *surface);
#endif /* WLR_TYPES_WLR_TABLET_V2_H */ #endif /* WLR_TYPES_WLR_TABLET_V2_H */

View File

@ -77,8 +77,6 @@ struct wlr_tablet_seat_v2 *get_or_create_tablet_seat(
return create_tablet_seat(manager, wlr_seat); return create_tablet_seat(manager, wlr_seat);
} }
static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource(struct wl_resource *resource);
static void tablet_seat_destroy(struct wl_client *client, static void tablet_seat_destroy(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
wl_resource_destroy(resource); wl_resource_destroy(resource);
@ -136,6 +134,8 @@ static void tablet_manager_destroy(struct wl_client *client,
wl_resource_destroy(resource); wl_resource_destroy(resource);
} }
static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource(struct wl_resource *resource);
static void get_tablet_seat(struct wl_client *wl_client, struct wl_resource *resource, static void get_tablet_seat(struct wl_client *wl_client, struct wl_resource *resource,
uint32_t id, struct wl_resource *seat_resource) uint32_t id, struct wl_resource *seat_resource)
{ {

View File

@ -323,7 +323,6 @@ static void handle_wlr_tablet_pad_destroy(struct wl_listener *listener, void *da
struct wlr_tablet_pad_client_v2 *pos; struct wlr_tablet_pad_client_v2 *pos;
struct wlr_tablet_pad_client_v2 *tmp; struct wlr_tablet_pad_client_v2 *tmp;
wl_list_for_each_safe(pos, tmp, &pad->clients, pad_link) { wl_list_for_each_safe(pos, tmp, &pad->clients, pad_link) {
// XXX: Add a timer/flag to destroy if client is slow?
zwp_tablet_pad_v2_send_removed(pos->resource); zwp_tablet_pad_v2_send_removed(pos->resource);
for (size_t i = 0; i < pos->group_count; ++i) { for (size_t i = 0; i < pos->group_count; ++i) {
@ -441,7 +440,7 @@ uint32_t wlr_send_tablet_v2_tablet_pad_enter(
/* Pre-increment keeps 0 clean. wraparound would be after 2^32 /* Pre-increment keeps 0 clean. wraparound would be after 2^32
* proximity_in. Someone wants to do the math how long that would take? * proximity_in. Someone wants to do the math how long that would take?
*/ */
uint32_t serial = ++pad_client->enter_serial; uint32_t serial = wl_display_next_serial(wl_client_get_display(client));
zwp_tablet_pad_v2_send_enter(pad_client->resource, serial, zwp_tablet_pad_v2_send_enter(pad_client->resource, serial,
tablet_client->resource, surface->resource); tablet_client->resource, surface->resource);
@ -512,15 +511,12 @@ void wlr_send_tablet_v2_tablet_pad_ring(struct wlr_tablet_v2_tablet_pad *pad,
uint32_t wlr_send_tablet_v2_tablet_pad_leave(struct wlr_tablet_v2_tablet_pad *pad, uint32_t wlr_send_tablet_v2_tablet_pad_leave(struct wlr_tablet_v2_tablet_pad *pad,
struct wlr_surface *surface) { struct wlr_surface *surface) {
if (!pad->current_client || struct wl_client *client = wl_resource_get_client(surface->resource);
wl_resource_get_client(surface->resource) != pad->current_client->client) { if (!pad->current_client || client != pad->current_client->client) {
return 0; return 0;
} }
/* Pre-increment keeps 0 clean. wraparound would be after 2^32 uint32_t serial = wl_display_next_serial(wl_client_get_display(client));
* proximity_in. Someone wants to do the math how long that would take?
*/
uint32_t serial = ++pad->current_client->leave_serial;
zwp_tablet_pad_v2_send_leave(pad->current_client->resource, serial, surface->resource); zwp_tablet_pad_v2_send_leave(pad->current_client->resource, serial, surface->resource);
return serial; return serial;
@ -540,10 +536,8 @@ uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad
pad->groups[group] = mode; pad->groups[group] = mode;
/* Pre-increment keeps 0 clean. wraparound would be after 2^32 struct wl_client *client = wl_resource_get_client(pad->current_client->resource);
* proximity_in. Someone wants to do the math how long that would take? uint32_t serial = wl_display_next_serial(wl_client_get_display(client));
*/
uint32_t serial = ++pad->current_client->mode_serial;
zwp_tablet_pad_group_v2_send_mode_switch( zwp_tablet_pad_group_v2_send_mode_switch(
pad->current_client->groups[group], time, serial, mode); pad->current_client->groups[group], time, serial, mode);

View File

@ -40,7 +40,6 @@ static void handle_wlr_tablet_destroy(struct wl_listener *listener, void *data)
struct wlr_tablet_client_v2 *pos; struct wlr_tablet_client_v2 *pos;
struct wlr_tablet_client_v2 *tmp; struct wlr_tablet_client_v2 *tmp;
wl_list_for_each_safe(pos, tmp, &tablet->clients, tablet_link) { wl_list_for_each_safe(pos, tmp, &tablet->clients, tablet_link) {
// XXX: Add a timer/flag to destroy if client is slow?
zwp_tablet_v2_send_removed(pos->resource); zwp_tablet_v2_send_removed(pos->resource);
} }

View File

@ -178,7 +178,6 @@ static void handle_wlr_tablet_tool_destroy(struct wl_listener *listener, void *d
struct wlr_tablet_tool_client_v2 *pos; struct wlr_tablet_tool_client_v2 *pos;
struct wlr_tablet_tool_client_v2 *tmp; struct wlr_tablet_tool_client_v2 *tmp;
wl_list_for_each_safe(pos, tmp, &tool->clients, tool_link) { wl_list_for_each_safe(pos, tmp, &tool->clients, tool_link) {
// XXX: Add a timer/flag to destroy if client is slow?
zwp_tablet_tool_v2_send_removed(pos->resource); zwp_tablet_tool_v2_send_removed(pos->resource);
pos->tool = NULL; pos->tool = NULL;
} }
@ -251,7 +250,7 @@ static size_t push_zeroes_to_end(uint32_t arr[], size_t n) {
return ret; return ret;
} }
static void tablet_tool_button_update(struct wlr_tablet_v2_tablet_tool *tool, static ssize_t tablet_tool_button_update(struct wlr_tablet_v2_tablet_tool *tool,
uint32_t button, enum zwp_tablet_pad_v2_button_state state) { uint32_t button, enum zwp_tablet_pad_v2_button_state state) {
bool found = false; bool found = false;
size_t i = 0; size_t i = 0;
@ -264,20 +263,31 @@ static void tablet_tool_button_update(struct wlr_tablet_v2_tablet_tool *tool,
if (button == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED && !found && if (button == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED && !found &&
tool->num_buttons < WLR_TABLEt_V2_TOOL_BUTTONS_CAP) { tool->num_buttons < WLR_TABLEt_V2_TOOL_BUTTONS_CAP) {
tool->pressed_buttons[tool->num_buttons++] = button; i = tool->num_buttons++;
tool->pressed_buttons[i] = button;
} }
if (button == ZWP_TABLET_PAD_V2_BUTTON_STATE_RELEASED && found) { if (button == ZWP_TABLET_PAD_V2_BUTTON_STATE_RELEASED && found) {
tool->pressed_buttons[i] = 0; tool->pressed_buttons[i] = 0;
tool->pressed_serials[i] = 0;
tool->num_buttons = push_zeroes_to_end(tool->pressed_buttons, WLR_TABLEt_V2_TOOL_BUTTONS_CAP); tool->num_buttons = push_zeroes_to_end(tool->pressed_buttons, WLR_TABLEt_V2_TOOL_BUTTONS_CAP);
tool->num_buttons = push_zeroes_to_end(tool->pressed_serials, WLR_TABLEt_V2_TOOL_BUTTONS_CAP);
i = -1;
} }
assert(tool->num_buttons <= WLR_TABLEt_V2_TOOL_BUTTONS_CAP); assert(tool->num_buttons <= WLR_TABLEt_V2_TOOL_BUTTONS_CAP);
return i;
}
static inline int64_t timespec_to_msec(const struct timespec *a) {
return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
} }
static void send_tool_frame(void *data) { static void send_tool_frame(void *data) {
struct wlr_tablet_tool_client_v2 *tool = data; struct wlr_tablet_tool_client_v2 *tool = data;
zwp_tablet_tool_v2_send_frame(tool->resource, 0); struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
zwp_tablet_tool_v2_send_frame(tool->resource, timespec_to_msec(&now));
tool->frame_source = NULL; tool->frame_source = NULL;
} }
@ -290,14 +300,14 @@ static void queue_tool_frame(struct wlr_tablet_tool_client_v2 *tool) {
} }
} }
uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in( void wlr_send_tablet_v2_tablet_tool_proximity_in(
struct wlr_tablet_v2_tablet_tool *tool, struct wlr_tablet_v2_tablet_tool *tool,
struct wlr_tablet_v2_tablet *tablet, struct wlr_tablet_v2_tablet *tablet,
struct wlr_surface *surface) { struct wlr_surface *surface) {
struct wl_client *client = wl_resource_get_client(surface->resource); struct wl_client *client = wl_resource_get_client(surface->resource);
if (tool->focused_surface == surface) { if (tool->focused_surface == surface) {
return 0; return;
} }
struct wlr_tablet_client_v2 *tablet_tmp; struct wlr_tablet_client_v2 *tablet_tmp;
@ -313,7 +323,7 @@ uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in(
// the client didn't bind tablet_v2 at all, or not for the relevant // the client didn't bind tablet_v2 at all, or not for the relevant
// seat // seat
if (!tablet_client) { if (!tablet_client) {
return 0; return;
} }
struct wlr_tablet_tool_client_v2 *tool_tmp = NULL; struct wlr_tablet_tool_client_v2 *tool_tmp = NULL;
@ -329,22 +339,28 @@ uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in(
// the client didn't bind tablet_v2 at all, or not for the relevant // the client didn't bind tablet_v2 at all, or not for the relevant
// seat // seat
if (!tool_client) { if (!tool_client) {
return 0; return;
} }
tool->current_client = tool_client; tool->current_client = tool_client;
/* Pre-increment keeps 0 clean. wraparound would be after 2^32 uint32_t serial = wl_display_next_serial(wl_client_get_display(client));
* proximity_in. Someone wants to do the math how long that would take? tool->focused_surface = surface;
*/ tool->proximity_serial = serial;
uint32_t serial = ++tool_client->proximity_serial;
zwp_tablet_tool_v2_send_proximity_in(tool_client->resource, serial, zwp_tablet_tool_v2_send_proximity_in(tool_client->resource, serial,
tablet_client->resource, surface->resource); tablet_client->resource, surface->resource);
queue_tool_frame(tool_client); /* Send all the pressed buttons */
for (size_t i = 0; i < tool->num_buttons; ++i) {
wlr_send_tablet_v2_tablet_tool_button(tool,
tool->pressed_buttons[i],
ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED);
}
if (tool->is_down) {
wlr_send_tablet_v2_tablet_tool_down(tool);
}
tool->focused_surface = surface; queue_tool_frame(tool_client);
return serial;
} }
void wlr_send_tablet_v2_tablet_tool_motion( void wlr_send_tablet_v2_tablet_tool_motion(
@ -363,7 +379,6 @@ void wlr_send_tablet_v2_tablet_tool_proximity_out(
struct wlr_tablet_v2_tablet_tool *tool) { struct wlr_tablet_v2_tablet_tool *tool) {
if (tool->current_client) { if (tool->current_client) {
zwp_tablet_tool_v2_send_proximity_out(tool->current_client->resource); zwp_tablet_tool_v2_send_proximity_out(tool->current_client->resource);
// XXX: Get the time for the frame
if (tool->current_client->frame_source) { if (tool->current_client->frame_source) {
wl_event_source_remove(tool->current_client->frame_source); wl_event_source_remove(tool->current_client->frame_source);
send_tool_frame(tool->current_client); send_tool_frame(tool->current_client);
@ -428,22 +443,23 @@ void wlr_send_tablet_v2_tablet_tool_slider(
queue_tool_frame(tool->current_client); queue_tool_frame(tool->current_client);
} }
uint32_t wlr_send_tablet_v2_tablet_tool_button( void wlr_send_tablet_v2_tablet_tool_button(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t button, struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
enum zwp_tablet_pad_v2_button_state state) { enum zwp_tablet_pad_v2_button_state state) {
tablet_tool_button_update(tool, button, state); ssize_t index = tablet_tool_button_update(tool, button, state);
if (tool->current_client) { if (tool->current_client) {
uint32_t serial = ++tool->button_serial; struct wl_client *client =
wl_resource_get_client(tool->current_client->resource);
uint32_t serial = wl_display_next_serial(wl_client_get_display(client));
if (index >= 0) {
tool->pressed_serials[index] = serial;
}
zwp_tablet_tool_v2_send_button(tool->current_client->resource, zwp_tablet_tool_v2_send_button(tool->current_client->resource,
serial, button, state); serial, button, state);
queue_tool_frame(tool->current_client); queue_tool_frame(tool->current_client);
return serial;
} }
return 0;
} }
void wlr_send_tablet_v2_tablet_tool_wheel( void wlr_send_tablet_v2_tablet_tool_wheel(
@ -456,23 +472,23 @@ void wlr_send_tablet_v2_tablet_tool_wheel(
} }
} }
uint32_t wlr_send_tablet_v2_tablet_tool_down(struct wlr_tablet_v2_tablet_tool *tool) { void wlr_send_tablet_v2_tablet_tool_down(struct wlr_tablet_v2_tablet_tool *tool) {
if (tool->is_down) { if (tool->is_down) {
return 0; return;
} }
tool->is_down = true; tool->is_down = true;
if (tool->current_client) { if (tool->current_client) {
uint32_t serial = ++tool->down_serial; struct wl_client *client =
wl_resource_get_client(tool->current_client->resource);
uint32_t serial = wl_display_next_serial(wl_client_get_display(client));
zwp_tablet_tool_v2_send_down(tool->current_client->resource, zwp_tablet_tool_v2_send_down(tool->current_client->resource,
serial); serial);
queue_tool_frame(tool->current_client); queue_tool_frame(tool->current_client);
return serial; tool->down_serial = serial;
} }
return 0;
} }
void wlr_send_tablet_v2_tablet_tool_up(struct wlr_tablet_v2_tablet_tool *tool) { void wlr_send_tablet_v2_tablet_tool_up(struct wlr_tablet_v2_tablet_tool *tool) {
@ -480,6 +496,7 @@ void wlr_send_tablet_v2_tablet_tool_up(struct wlr_tablet_v2_tablet_tool *tool) {
return; return;
} }
tool->is_down = false; tool->is_down = false;
tool->down_serial = 0;
if (tool->current_client) { if (tool->current_client) {
zwp_tablet_tool_v2_send_up(tool->current_client->resource); zwp_tablet_tool_v2_send_up(tool->current_client->resource);