From 9ddb8260775f09ccfe266f42e092db26ebdbd6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 4 Jan 2012 21:30:29 -0500 Subject: [PATCH] Use new grab api --- src/compositor.c | 183 ++++++++++++++++++++++------------------------ src/compositor.h | 10 ++- src/data-device.c | 52 +++++-------- src/shell.c | 72 ++++++++++-------- 4 files changed, 153 insertions(+), 164 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 262798723..8e24f8f27 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -307,6 +307,14 @@ weston_surface_configure(struct weston_surface *surface, pixman_region32_init(&surface->opaque); } +static void +weston_surface_transform(struct weston_surface *surface, + int32_t x, int32_t y, int32_t *sx, int32_t *sy) +{ + *sx = x - surface->x; + *sy = y - surface->y; +} + WL_EXPORT uint32_t weston_compositor_get_time(void) { @@ -317,29 +325,43 @@ weston_compositor_get_time(void) return tv.tv_sec * 1000 + tv.tv_usec / 1000; } +WL_EXPORT void +weston_device_repick(struct wl_input_device *device, uint32_t time) +{ + struct weston_input_device *wd = (struct weston_input_device *) device; + const struct wl_grab_interface *interface; + struct weston_surface *surface, *focus; + + surface = weston_compositor_pick_surface(wd->compositor, + device->x, device->y, + &device->current_x, + &device->current_y); + + if (&surface->surface != device->current) { + interface = device->grab->interface; + interface->focus(device->grab, time, &surface->surface, + device->current_x, device->current_y); + device->current = &surface->surface; + } + + focus = (struct weston_surface *) device->grab->focus; + if (focus) + weston_surface_transform(focus, device->x, device->y, + &device->grab->x, &device->grab->y); +} + WL_EXPORT void weston_compositor_repick(struct weston_compositor *compositor) { struct weston_input_device *device; - struct weston_surface *surface; - int32_t sx, sy; uint32_t time; if (!compositor->focus) return; time = weston_compositor_get_time(); - wl_list_for_each(device, &compositor->input_device_list, link) { - if (device->input_device.grab) - continue; - surface = pick_surface(&device->input_device, &sx, &sy); - wl_input_device_set_pointer_focus(&device->input_device, - &surface->surface, - time, - device->input_device.x, - device->input_device.y, - sx, sy); - } + wl_list_for_each(device, &compositor->input_device_list, link) + weston_device_repick(&device->input_device, time); } static void @@ -1071,15 +1093,7 @@ const static struct wl_compositor_interface compositor_interface = { compositor_create_surface, }; -static void -weston_surface_transform(struct weston_surface *surface, - int32_t x, int32_t y, int32_t *sx, int32_t *sy) -{ - *sx = x - surface->x; - *sy = y - surface->y; -} - -static struct weston_surface * +WL_EXPORT struct weston_surface * weston_compositor_pick_surface(struct weston_compositor *compositor, int32_t x, int32_t y, int32_t *sx, int32_t *sy) { @@ -1097,56 +1111,56 @@ weston_compositor_pick_surface(struct weston_compositor *compositor, return NULL; } -WL_EXPORT struct weston_surface * -pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy) +static void +default_grab_focus(struct wl_grab *grab, uint32_t time, + struct wl_surface *surface, int32_t x, int32_t y) { - struct weston_input_device *wd = (struct weston_input_device *) device; + struct wl_input_device *device = grab->input_device; - return weston_compositor_pick_surface(wd->compositor, - device->x, device->y, sx, sy); + if (device->button_count > 0) + return; + + wl_input_device_set_pointer_focus(device, surface, time, + device->x, device->y, x, y); } - static void -implicit_grab_motion(struct wl_grab *grab, - uint32_t time, int32_t x, int32_t y) +default_grab_motion(struct wl_grab *grab, + uint32_t time, int32_t x, int32_t y) { - struct weston_input_device *device = - (struct weston_input_device *) grab->input_device; - struct weston_surface *es = - (struct weston_surface *) device->input_device.pointer_focus; - int32_t sx, sy; + struct wl_input_device *device = grab->input_device; struct wl_resource *resource; resource = grab->input_device->pointer_focus_resource; - if (resource) { - weston_surface_transform(es, x, y, &sx, &sy); + if (resource) wl_resource_post_event(resource, WL_INPUT_DEVICE_MOTION, - time, x, y, sx, sy); - } + time, device->x, device->y, x, y); } static void -implicit_grab_button(struct wl_grab *grab, - uint32_t time, int32_t button, int32_t state) +default_grab_button(struct wl_grab *grab, + uint32_t time, int32_t button, int32_t state) { + struct wl_input_device *device = grab->input_device; struct wl_resource *resource; - resource = grab->input_device->pointer_focus_resource; + if (device->button_count == 0 && state == 0) + wl_input_device_set_pointer_focus(device, + device->current, time, + device->x, device->y, + device->current_x, + device->current_y); + + resource = device->pointer_focus_resource; if (resource) wl_resource_post_event(resource, WL_INPUT_DEVICE_BUTTON, time, button, state); } -static void -implicit_grab_end(struct wl_grab *grab, uint32_t time) -{ -} - -static const struct wl_grab_interface implicit_grab_interface = { - implicit_grab_motion, - implicit_grab_button, - implicit_grab_end +static const struct wl_grab_interface default_grab_interface = { + default_grab_focus, + default_grab_motion, + default_grab_button }; WL_EXPORT void @@ -1199,12 +1213,10 @@ idle_handler(void *data) WL_EXPORT void notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) { - struct weston_surface *es; struct weston_output *output; const struct wl_grab_interface *interface; struct weston_input_device *wd = (struct weston_input_device *) device; struct weston_compositor *ec = wd->compositor; - int32_t sx, sy; int x_valid = 0, y_valid = 0; int min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN; @@ -1245,19 +1257,10 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) device->x = x; device->y = y; - if (device->grab) { - interface = device->grab->interface; - interface->motion(device->grab, time, x, y); - } else { - es = pick_surface(device, &sx, &sy); - wl_input_device_set_pointer_focus(device, - &es->surface, - time, x, y, sx, sy); - if (device->pointer_focus_resource) - wl_resource_post_event(device->pointer_focus_resource, - WL_INPUT_DEVICE_MOTION, - time, x, y, sx, sy); - } + weston_device_repick(device, time); + interface = device->grab->interface; + interface->motion(device->grab, time, + device->grab->x, device->grab->y); if (wd->sprite) { weston_surface_damage_below(wd->sprite); @@ -1285,34 +1288,25 @@ notify_button(struct wl_input_device *device, { struct weston_input_device *wd = (struct weston_input_device *) device; struct weston_compositor *compositor = wd->compositor; - struct weston_surface *surface = - (struct weston_surface *) device->pointer_focus; - int32_t sx, sy; - if (state) + if (state) { weston_compositor_idle_inhibit(compositor); - else + if (device->button_count == 0) { + device->grab_button = button; + device->grab_time = time; + device->grab_x = device->x; + device->grab_y = device->y; + } + device->button_count++; + } else { weston_compositor_idle_release(compositor); + device->button_count--; + } weston_compositor_run_binding(compositor, wd, time, 0, button, state); - if (state && surface && device->grab == NULL) { - wl_input_device_start_grab(device, - &device->implicit_grab, - button, time); - } + device->grab->interface->button(device->grab, time, button, state); - if (device->grab) - device->grab->interface->button(device->grab, time, - button, state); - - if (!state && device->grab && device->grab_button == button) { - wl_input_device_end_grab(device, time); - surface = pick_surface(device, &sx, &sy); - wl_input_device_set_pointer_focus(device, &surface->surface, - time, device->x, device->y, - sx, sy); - } } static void @@ -1387,22 +1381,15 @@ notify_pointer_focus(struct wl_input_device *device, { struct weston_input_device *wd = (struct weston_input_device *) device; struct weston_compositor *compositor = wd->compositor; - struct weston_surface *es; - int32_t sx, sy; if (output) { device->x = x; device->y = y; - es = pick_surface(device, &sx, &sy); - wl_input_device_set_pointer_focus(device, - &es->surface, - time, x, y, sx, sy); - compositor->focus = 1; + weston_compositor_repick(compositor); } else { - wl_input_device_set_pointer_focus(device, NULL, - time, 0, 0, 0, 0); compositor->focus = 0; + weston_compositor_repick(compositor); } } @@ -1678,7 +1665,9 @@ weston_input_device_init(struct weston_input_device *device, device->modifier_state = 0; device->num_tp = 0; - device->input_device.implicit_grab.interface = &implicit_grab_interface; + device->input_device.default_grab.interface = &default_grab_interface; + device->input_device.default_grab.input_device = &device->input_device; + device->input_device.grab = &device->input_device.default_grab; wl_list_insert(ec->input_device_list.prev, &device->link); diff --git a/src/compositor.h b/src/compositor.h index f6c87da2c..bf21feefb 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -115,10 +115,10 @@ struct weston_input_device { struct wl_surface *drag_focus; struct wl_resource *drag_focus_resource; struct wl_listener drag_focus_listener; + struct wl_grab drag_grab; struct weston_data_source *selection_data_source; struct wl_listener selection_data_source_listener; - struct wl_grab grab; struct wl_list selection_listener_list; uint32_t num_tp; @@ -297,6 +297,8 @@ void weston_input_device_set_selection(struct weston_input_device *device, struct weston_data_source *source, uint32_t time); +void +weston_device_repick(struct wl_input_device *device, uint32_t time); void weston_spring_init(struct weston_spring *spring, @@ -339,6 +341,9 @@ void weston_output_finish_frame(struct weston_output *output, int msecs); void weston_output_damage(struct weston_output *output); +struct weston_surface * +weston_compositor_pick_surface(struct weston_compositor *compositor, + int32_t x, int32_t y, int32_t *sx, int32_t *sy); void weston_compositor_repick(struct weston_compositor *compositor); void @@ -397,9 +402,6 @@ weston_surface_damage_rectangle(struct weston_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height); -struct weston_surface * -pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy); - uint32_t weston_compositor_get_time(void); diff --git a/src/data-device.c b/src/data-device.c index 500c6b09a..049dcb05c 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -179,15 +179,13 @@ destroy_drag_focus(struct wl_listener *listener, } static void -drag_set_focus(struct weston_input_device *device, - struct wl_surface *surface, uint32_t time, - int32_t x, int32_t y) +drag_grab_focus(struct wl_grab *grab, uint32_t time, + struct wl_surface *surface, int32_t x, int32_t y) { + struct weston_input_device *device = + container_of(grab, struct weston_input_device, drag_grab); struct wl_resource *resource, *offer; - if (device->drag_focus == surface) - return; - if (device->drag_focus_resource) { wl_resource_post_event(device->drag_focus_resource, WL_DATA_DEVICE_LEAVE); @@ -212,6 +210,7 @@ drag_set_focus(struct weston_input_device *device, wl_list_insert(resource->destroy_listener_list.prev, &device->drag_focus_listener.link); device->drag_focus_resource = resource; + grab->focus = surface; } } @@ -220,13 +219,9 @@ drag_grab_motion(struct wl_grab *grab, uint32_t time, int32_t x, int32_t y) { struct weston_input_device *device = - container_of(grab, struct weston_input_device, grab); - struct weston_surface *es; + container_of(grab, struct weston_input_device, drag_grab); - es = pick_surface(&device->input_device, &x, &y); - drag_set_focus(device, &es->surface, time, x, y); - - if (es && device->drag_focus_resource) + if (device->drag_focus_resource) wl_resource_post_event(device->drag_focus_resource, WL_DATA_DEVICE_MOTION, time, x, y); } @@ -234,27 +229,25 @@ drag_grab_motion(struct wl_grab *grab, static void drag_grab_button(struct wl_grab *grab, uint32_t time, int32_t button, int32_t state) -{ -} - -static void -drag_grab_end(struct wl_grab *grab, uint32_t time) { struct weston_input_device *device = - container_of(grab, struct weston_input_device, grab); + container_of(grab, struct weston_input_device, drag_grab); - if (device->drag_focus_resource) + if (device->drag_focus_resource && + device->input_device.grab_button == button && state == 0) wl_resource_post_event(device->drag_focus_resource, WL_DATA_DEVICE_DROP); - drag_set_focus(device, NULL, time, 0, 0); - device->drag_data_source = NULL; + if (device->input_device.button_count == 0 && state == 0) { + wl_input_device_end_grab(&device->input_device, time); + device->drag_data_source = NULL; + } } static const struct wl_grab_interface drag_grab_interface = { + drag_grab_focus, drag_grab_motion, drag_grab_button, - drag_grab_end }; static void @@ -263,26 +256,17 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface_resource, uint32_t time) { struct weston_input_device *device = resource->data; - struct weston_surface *surface = surface_resource->data; - struct weston_surface *target; - int32_t sx, sy; /* FIXME: Check that client has implicit grab on the surface * that matches the given time. */ /* FIXME: Check that the data source type array isn't empty. */ - if (wl_input_device_update_grab(&device->input_device, &device->grab, - &surface->surface, time) < 0) - return; - - device->grab.interface = &drag_grab_interface; + device->drag_grab.interface = &drag_grab_interface; device->drag_data_source = source_resource->data; - target = pick_surface(&device->input_device, &sx, &sy); - wl_input_device_set_pointer_focus(&device->input_device, - NULL, time, 0, 0, 0, 0); - drag_set_focus(device, &target->surface, time, sx, sy); + wl_input_device_start_grab(&device->input_device, + &device->drag_grab, time); } static void diff --git a/src/shell.c b/src/shell.c index a39adb391..b27067dcc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -125,38 +125,48 @@ shell_configuration(struct wl_shell *shell) return ret; } +static void +noop_grab_focus(struct wl_grab *grab, uint32_t time, + struct wl_surface *surface, int32_t x, int32_t y) +{ + grab->focus = NULL; +} + static void move_grab_motion(struct wl_grab *grab, - uint32_t time, int32_t x, int32_t y) + uint32_t time, int32_t x, int32_t y) { struct weston_move_grab *move = (struct weston_move_grab *) grab; + struct wl_input_device *device = grab->input_device; struct weston_surface *es = move->surface; - weston_surface_configure(es, x + move->dx, y + move->dy, - es->width, es->height); + weston_surface_configure(es, + device->x + move->dx, + device->y + move->dy, + es->width, es->height); } static void move_grab_button(struct wl_grab *grab, uint32_t time, int32_t button, int32_t state) { -} + struct wl_input_device *device = grab->input_device; -static void -move_grab_end(struct wl_grab *grab, uint32_t time) -{ - free(grab); + if (device->button_count == 0 && state == 0) { + wl_input_device_end_grab(device, time); + free(grab); + } } static const struct wl_grab_interface move_grab_interface = { + noop_grab_focus, move_grab_motion, move_grab_button, - move_grab_end }; static int weston_surface_move(struct weston_surface *es, - struct weston_input_device *wd, uint32_t time) + struct weston_input_device *wd, uint32_t time) { struct weston_move_grab *move; @@ -169,11 +179,7 @@ weston_surface_move(struct weston_surface *es, move->dy = es->y - wd->input_device.grab_y; move->surface = es; - if (wl_input_device_update_grab(&wd->input_device, - &move->grab, &es->surface, time) < 0) { - free(move); - return 0; - } + wl_input_device_start_grab(&wd->input_device, &move->grab, time); wl_input_device_set_pointer_focus(&wd->input_device, NULL, time, 0, 0, 0, 0); @@ -188,6 +194,11 @@ shell_surface_move(struct wl_client *client, struct wl_resource *resource, struct weston_input_device *wd = input_resource->data; struct shell_surface *shsurf = resource->data; + if (wd->input_device.button_count == 0 || + wd->input_device.grab_time != time || + wd->input_device.pointer_focus != &shsurf->surface->surface) + return; + if (weston_surface_move(shsurf->surface, wd, time) < 0) wl_resource_post_no_memory(resource); } @@ -208,17 +219,17 @@ resize_grab_motion(struct wl_grab *grab, int32_t width, height; if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) { - width = device->grab_x - x + resize->width; + width = device->grab_x - device->x + resize->width; } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) { - width = x - device->grab_x + resize->width; + width = device->x - device->grab_x + resize->width; } else { width = resize->width; } if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) { - height = device->grab_y - y + resize->height; + height = device->grab_y - device->y + resize->height; } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) { - height = y - device->grab_y + resize->height; + height = device->y - device->grab_y + resize->height; } else { height = resize->height; } @@ -232,18 +243,18 @@ static void resize_grab_button(struct wl_grab *grab, uint32_t time, int32_t button, int32_t state) { -} + struct wl_input_device *device = grab->input_device; -static void -resize_grab_end(struct wl_grab *grab, uint32_t time) -{ - free(grab); + if (device->button_count == 0 && state == 0) { + wl_input_device_end_grab(device, time); + free(grab); + } } static const struct wl_grab_interface resize_grab_interface = { + noop_grab_focus, resize_grab_motion, resize_grab_button, - resize_grab_end }; static int @@ -272,9 +283,7 @@ weston_surface_resize(struct shell_surface *shsurf, (edges & 3) == 3 || (edges & 12) == 12) goto err_out; - if (wl_input_device_update_grab(&wd->input_device, - &resize->grab, &es->surface, time) < 0) - goto err_out; + wl_input_device_start_grab(&wd->input_device, &resize->grab, time); wl_input_device_set_pointer_focus(&wd->input_device, NULL, time, 0, 0, 0, 0); @@ -296,6 +305,11 @@ shell_surface_resize(struct wl_client *client, struct wl_resource *resource, /* FIXME: Reject if fullscreen */ + if (wd->input_device.button_count == 0 || + wd->input_device.grab_time != time || + wd->input_device.pointer_focus != &shsurf->surface->surface) + return; + if (weston_surface_resize(shsurf, wd, time, edges) < 0) wl_resource_post_no_memory(resource); } @@ -865,7 +879,7 @@ click_to_activate_binding(struct wl_input_device *device, struct weston_surface *focus; focus = (struct weston_surface *) device->pointer_focus; - if (state && focus && device->grab == NULL) + if (state && focus && device->grab == &device->default_grab) activate(compositor->shell, focus, wd, time); }