diff options
-rw-r--r-- | backend/wayland/wl_seat.c | 9 | ||||
-rw-r--r-- | include/rootston/config.h | 2 | ||||
-rw-r--r-- | include/wlr/types/wlr_cursor.h | 2 | ||||
-rw-r--r-- | include/wlr/types/wlr_output.h | 4 | ||||
-rw-r--r-- | include/wlr/types/wlr_seat.h | 9 | ||||
-rw-r--r-- | include/wlr/types/wlr_xcursor_manager.h | 6 | ||||
-rw-r--r-- | rootston/config.c | 2 | ||||
-rw-r--r-- | rootston/seat.c | 7 | ||||
-rw-r--r-- | types/wlr_cursor.c | 6 | ||||
-rw-r--r-- | types/wlr_data_device.c | 146 | ||||
-rw-r--r-- | types/wlr_output.c | 6 | ||||
-rw-r--r-- | types/wlr_seat.c | 280 | ||||
-rw-r--r-- | types/wlr_xcursor_manager.c | 4 |
13 files changed, 262 insertions, 221 deletions
diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 9fcc48dd..0d4ebc8d 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -59,14 +59,15 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, &box.width, &box.height); box.x = wl_fixed_to_int(surface_x); box.y = wl_fixed_to_int(surface_y); - struct wlr_box transformed; + struct wlr_box transformed; wlr_box_transform(&box, wlr_output->transform, &transformed); - box.x /= wlr_output->scale; - box.y /= wlr_output->scale; + transformed.x /= wlr_output->scale; + transformed.y /= wlr_output->scale; struct wlr_box layout_box; - wlr_wl_output_layout_get_box(wlr_wl_pointer->current_output->backend, &layout_box); + wlr_wl_output_layout_get_box(wlr_wl_pointer->current_output->backend, + &layout_box); struct wlr_event_pointer_motion_absolute wlr_event; wlr_event.device = dev; diff --git a/include/rootston/config.h b/include/rootston/config.h index 1d54314e..d453a82c 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -9,7 +9,7 @@ struct roots_output_config { char *name; enum wl_output_transform transform; int x, y; - int scale; + float scale; struct wl_list link; struct { int width, height; diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index c73a4c8d..e072ca05 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -68,7 +68,7 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, */ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y, uint32_t scale); + int32_t hotspot_y, float scale); /** * Set the cursor surface. The surface can be committed to update the cursor diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 39aad718..037fa515 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -45,7 +45,7 @@ struct wlr_output { char make[48]; char model[16]; char serial[16]; - uint32_t scale; + float scale; int32_t width, height; int32_t phys_width, phys_height; // mm enum wl_output_subpixel subpixel; @@ -92,7 +92,7 @@ bool wlr_output_set_custom_mode(struct wlr_output *output, int32_t width, void wlr_output_set_transform(struct wlr_output *output, enum wl_output_transform transform); void wlr_output_set_position(struct wlr_output *output, int32_t lx, int32_t ly); -void wlr_output_set_scale(struct wlr_output *output, uint32_t scale); +void wlr_output_set_scale(struct wlr_output *output, float scale); void wlr_output_destroy(struct wlr_output *output); void wlr_output_effective_resolution(struct wlr_output *output, int *width, int *height); diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 00fd8da1..dea9a9d0 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -16,10 +16,11 @@ struct wlr_seat_client { struct wl_client *client; struct wlr_seat *seat; - struct wl_resource *pointer; - struct wl_resource *keyboard; - struct wl_resource *touch; - struct wl_resource *data_device; + // lists of wl_resource + struct wl_list pointers; + struct wl_list keyboards; + struct wl_list touches; + struct wl_list data_devices; struct { struct wl_signal destroy; diff --git a/include/wlr/types/wlr_xcursor_manager.h b/include/wlr/types/wlr_xcursor_manager.h index c78a6e8d..2a2c9035 100644 --- a/include/wlr/types/wlr_xcursor_manager.h +++ b/include/wlr/types/wlr_xcursor_manager.h @@ -9,7 +9,7 @@ * A scaled XCursor theme. */ struct wlr_xcursor_manager_theme { - uint32_t scale; + float scale; struct wlr_xcursor_theme *theme; struct wl_list link; }; @@ -38,10 +38,10 @@ struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name, void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager); int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, - uint32_t scale); + float scale); struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( - struct wlr_xcursor_manager *manager, const char *name, uint32_t scale); + struct wlr_xcursor_manager *manager, const char *name, float scale); /** * Set a `wlr_cursor` image. The manager uses all currently loaded scaled diff --git a/rootston/config.c b/rootston/config.c index db77506f..ed91d4fd 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -270,7 +270,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(name, "y") == 0) { oc->y = strtol(value, NULL, 10); } else if (strcmp(name, "scale") == 0) { - oc->scale = strtol(value, NULL, 10); + oc->scale = strtof(value, NULL); assert(oc->scale >= 1); } else if (strcmp(name, "rotate") == 0) { if (strcmp(value, "normal") == 0) { diff --git a/rootston/seat.c b/rootston/seat.c index 8a581157..ce0f1374 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -459,11 +459,10 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { struct roots_output *output; wl_list_for_each(output, &seat->input->server->desktop->outputs, link) { - if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager, - output->wlr_output->scale)) { + float scale = output->wlr_output->scale; + if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager, scale)) { wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' " - "with scale %d", output->wlr_output->name, - output->wlr_output->scale); + "with scale %f", output->wlr_output->name, scale); } } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index ec66f7c7..a432c219 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -299,11 +299,11 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y, uint32_t scale) { + int32_t hotspot_y, float scale) { struct wlr_cursor_output_cursor *output_cursor; wl_list_for_each(output_cursor, &cur->state->output_cursors, link) { - if (scale != 0 && - output_cursor->output_cursor->output->scale != scale) { + float output_scale = output_cursor->output_cursor->output->scale; + if (scale > 0 && output_scale != scale) { continue; } diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index b27009dc..c0399160 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -231,28 +231,35 @@ static void handle_offer_source_destroyed(struct wl_listener *listener, static struct wlr_data_offer *wlr_data_source_send_offer( struct wlr_data_source *source, - struct wl_resource *target) { + struct wlr_seat_client *target) { + if (wl_list_empty(&target->data_devices)) { + return NULL; + } + struct wlr_data_offer *offer = calloc(1, sizeof(struct wlr_data_offer)); if (offer == NULL) { return NULL; } - offer->resource = - wl_resource_create(wl_resource_get_client(target), - &wl_data_offer_interface, - wl_resource_get_version(target), 0); + uint32_t version = wl_resource_get_version( + wl_resource_from_link(target->data_devices.next)); + offer->resource = wl_resource_create(target->client, + &wl_data_offer_interface, version, 0); if (offer->resource == NULL) { free(offer); return NULL; } - wl_resource_set_implementation(offer->resource, &data_offer_impl, offer, data_offer_resource_destroy); offer->source_destroy.notify = handle_offer_source_destroyed; wl_signal_add(&source->events.destroy, &offer->source_destroy); - wl_data_device_send_data_offer(target, offer->resource); + struct wl_resource *target_resource; + wl_resource_for_each(target_resource, &target->data_devices) { + wl_data_device_send_data_offer(target_resource, offer->resource); + } + char **p; wl_array_for_each(p, &source->mime_types) { wl_data_offer_send_offer(offer->resource, *p); @@ -265,20 +272,27 @@ static struct wlr_data_offer *wlr_data_source_send_offer( return offer; } - void wlr_seat_client_send_selection(struct wlr_seat_client *seat_client) { - if (!seat_client->data_device) { + if (wl_list_empty(&seat_client->data_devices)) { return; } if (seat_client->seat->selection_source) { - struct wlr_data_offer *offer = - wlr_data_source_send_offer(seat_client->seat->selection_source, - seat_client->data_device); - wl_data_device_send_selection(seat_client->data_device, - offer->resource); + struct wlr_data_offer *offer = wlr_data_source_send_offer( + seat_client->seat->selection_source, seat_client); + if (offer == NULL) { + return; + } + + struct wl_resource *resource; + wl_resource_for_each(resource, &seat_client->data_devices) { + wl_data_device_send_selection(resource, offer->resource); + } } else { - wl_data_device_send_selection(seat_client->data_device, NULL); + struct wl_resource *resource; + wl_resource_for_each(resource, &seat_client->data_devices) { + wl_data_device_send_selection(resource, NULL); + } } } @@ -286,12 +300,13 @@ static void seat_client_selection_data_source_destroy( struct wl_listener *listener, void *data) { struct wlr_seat *seat = wl_container_of(listener, seat, selection_data_source_destroy); + struct wlr_seat_client *seat_client = seat->keyboard_state.focused_client; - if (seat->keyboard_state.focused_client && - seat->keyboard_state.focused_surface && - seat->keyboard_state.focused_client->data_device) { - wl_data_device_send_selection( - seat->keyboard_state.focused_client->data_device, NULL); + if (seat_client && seat->keyboard_state.focused_surface) { + struct wl_resource *resource; + wl_resource_for_each(resource, &seat_client->data_devices) { + wl_data_device_send_selection(resource, NULL); + } } seat->selection_source = NULL; @@ -367,9 +382,14 @@ static void wlr_drag_set_focus(struct wlr_drag *drag, return; } - if (drag->focus_client && drag->focus_client->data_device) { + if (drag->focus_client) { wl_list_remove(&drag->seat_client_destroy.link); - wl_data_device_send_leave(drag->focus_client->data_device); + + struct wl_resource *resource; + wl_resource_for_each(resource, &drag->focus_client->data_devices) { + wl_data_device_send_leave(resource); + } + drag->focus_client = NULL; drag->focus = NULL; } @@ -395,15 +415,15 @@ static void wlr_drag_set_focus(struct wlr_drag *drag, wlr_seat_client_for_wl_client(drag->seat_client->seat, wl_resource_get_client(surface->resource)); - if (!focus_client || !focus_client->data_device) { + if (!focus_client || wl_list_empty(&focus_client->data_devices)) { return; } struct wl_resource *offer_resource = NULL; if (drag->source) { drag->source->accepted = false; - struct wlr_data_offer *offer = - wlr_data_source_send_offer(drag->source, focus_client->data_device); + struct wlr_data_offer *offer = wlr_data_source_send_offer(drag->source, + focus_client); if (offer == NULL) { return; } @@ -421,10 +441,11 @@ static void wlr_drag_set_focus(struct wlr_drag *drag, uint32_t serial = wl_display_next_serial(drag->seat_client->seat->display); - - wl_data_device_send_enter(focus_client->data_device, serial, - surface->resource, wl_fixed_from_double(sx), - wl_fixed_from_double(sy), offer_resource); + struct wl_resource *resource; + wl_resource_for_each(resource, &focus_client->data_devices) { + wl_data_device_send_enter(resource, serial, surface->resource, + wl_fixed_from_double(sx), wl_fixed_from_double(sy), offer_resource); + } drag->focus = surface; drag->focus_client = focus_client; @@ -467,9 +488,12 @@ static void pointer_drag_enter(struct wlr_seat_pointer_grab *grab, static void pointer_drag_motion(struct wlr_seat_pointer_grab *grab, uint32_t time, double sx, double sy) { struct wlr_drag *drag = grab->data; - if (drag->focus && drag->focus_client && drag->focus_client->data_device) { - wl_data_device_send_motion(drag->focus_client->data_device, time, - wl_fixed_from_double(sx), wl_fixed_from_double(sy)); + if (drag->focus != NULL&& drag->focus_client != NULL) { + struct wl_resource *resource; + wl_resource_for_each(resource, &drag->focus_client->data_devices) { + wl_data_device_send_motion(resource, time, wl_fixed_from_double(sx), + wl_fixed_from_double(sy)); + } } } @@ -480,14 +504,16 @@ static uint32_t pointer_drag_button(struct wlr_seat_pointer_grab *grab, if (drag->source && grab->seat->pointer_state.grab_button == button && state == WL_POINTER_BUTTON_STATE_RELEASED) { - if (drag->focus_client && drag->focus_client->data_device && - drag->source->current_dnd_action && + if (drag->focus_client && drag->source->current_dnd_action && drag->source->accepted) { - wl_data_device_send_drop(drag->focus_client->data_device); + struct wl_resource *resource; + wl_resource_for_each(resource, &drag->focus_client->data_devices) { + wl_data_device_send_drop(resource); + } if (wl_resource_get_version(drag->source->resource) >= WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) { wl_data_source_send_dnd_drop_performed( - drag->source->resource); + drag->source->resource); } drag->source->offer->in_ask = @@ -538,8 +564,11 @@ static void touch_drag_up(struct wlr_seat_touch_grab *grab, uint32_t time, return; } - if (drag->focus_client && drag->focus_client->data_device) { - wl_data_device_send_drop(drag->focus_client->data_device); + if (drag->focus_client) { + struct wl_resource *resource; + wl_resource_for_each(resource, &drag->focus_client->data_devices) { + wl_data_device_send_drop(resource); + } } wlr_drag_end(drag); @@ -548,9 +577,13 @@ static void touch_drag_up(struct wlr_seat_touch_grab *grab, uint32_t time, static void touch_drag_motion(struct wlr_seat_touch_grab *grab, uint32_t time, struct wlr_touch_point *point) { struct wlr_drag *drag = grab->data; - if (drag->focus && drag->focus_client && drag->focus_client->data_device) { - wl_data_device_send_motion(drag->focus_client->data_device, time, - wl_fixed_from_double(point->sx), wl_fixed_from_double(point->sy)); + if (drag->focus && drag->focus_client) { + struct wl_resource *resource; + wl_resource_for_each(resource, &drag->focus_client->data_devices) { + wl_data_device_send_motion(resource, time, + wl_fixed_from_double(point->sx), + wl_fixed_from_double(point->sy)); + } } } @@ -687,19 +720,18 @@ static bool seat_client_start_drag(struct wlr_seat_client *client, drag->seat = client->seat; - drag->is_pointer_grab = client->pointer != NULL && + drag->is_pointer_grab = !wl_list_empty(&client->pointers) && client->seat->pointer_state.button_count == 1 && client->seat->pointer_state.grab_serial == serial && client->seat->pointer_state.focused_surface && client->seat->pointer_state.focused_surface == origin; - bool is_touch_grab = client->touch && + bool is_touch_grab = !wl_list_empty(&client->touches) && wlr_seat_touch_num_points(client->seat) == 1 && client->seat->touch_state.grab_serial == serial; // set in the iteration struct wlr_touch_point *point = NULL; - if (is_touch_grab) { wl_list_for_each(point, &client->seat->touch_state.touch_points, link) { is_touch_grab = point->surface && point->surface == origin; @@ -717,7 +749,6 @@ static bool seat_client_start_drag(struct wlr_seat_client *client, struct wlr_drag_icon *icon = wlr_drag_icon_create(icon_surface, client, drag->is_pointer_grab, touch_id); - if (!icon) { free(drag); return false; @@ -800,31 +831,26 @@ static const struct wl_data_device_interface data_device_impl = { .release = data_device_release, }; +static void data_device_destroy(struct wl_resource *resource) { + wl_list_remove(wl_resource_get_link(resource)); +} + void data_device_manager_get_data_device(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource) { struct wlr_seat_client *seat_client = wl_resource_get_user_data(seat_resource); - struct wl_resource *resource = - wl_resource_create(client, - &wl_data_device_interface, - wl_resource_get_version(manager_resource), id); + struct wl_resource *resource = wl_resource_create(client, + &wl_data_device_interface, wl_resource_get_version(manager_resource), + id); if (resource == NULL) { wl_resource_post_no_memory(manager_resource); return; } - - if (seat_client->data_device != NULL) { - // XXX this is probably a protocol violation, but it simplfies our code - // and it's stupid to create several data devices for the same seat. - wl_resource_destroy(seat_client->data_device); - } - - seat_client->data_device = resource; - - wl_resource_set_implementation(resource, &data_device_impl, - seat_client, NULL); + wl_resource_set_implementation(resource, &data_device_impl, seat_client, + &data_device_destroy); + wl_list_insert(&seat_client->data_devices, wl_resource_get_link(resource)); } static void data_source_resource_destroy(struct wl_resource *resource) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 450d513a..de1d29df 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -43,7 +43,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { } } if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) { - wl_output_send_scale(resource, output->scale); + wl_output_send_scale(resource, (uint32_t)ceil(output->scale)); } if (version >= WL_OUTPUT_DONE_SINCE_VERSION) { wl_output_send_done(resource); @@ -240,7 +240,7 @@ void wlr_output_set_position(struct wlr_output *output, int32_t lx, } } -void wlr_output_set_scale(struct wlr_output *output, uint32_t scale) { +void wlr_output_set_scale(struct wlr_output *output, float scale) { if (output->scale == scale) { return; } @@ -522,7 +522,7 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, } } - wlr_log(L_INFO, "Falling back to software cursor"); + wlr_log(L_DEBUG, "Falling back to software cursor"); cursor->output->needs_swap = true; cursor->enabled = pixels != NULL; diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 84a7045d..2a931241 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -55,14 +55,11 @@ static void wl_pointer_set_cursor(struct wl_client *client, static const struct wl_pointer_interface wl_pointer_impl = { .set_cursor = wl_pointer_set_cursor, - .release = resource_destroy + .release = resource_destroy, }; static void wl_pointer_destroy(struct wl_resource *resource) { - struct wlr_seat_client *client = wl_resource_get_user_data(resource); - if (client->pointer) { - client->pointer = NULL; - } + wl_list_remove(wl_resource_get_link(resource)); } static void wl_seat_get_pointer(struct wl_client *client, @@ -72,55 +69,55 @@ static void wl_seat_get_pointer(struct wl_client *client, if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) { return; } - if (seat_client->pointer) { - // TODO: this is probably a protocol violation but it simplifies our - // code and it'd be stupid for clients to create several pointers for - // the same seat - wl_resource_destroy(seat_client->pointer); - } - seat_client->pointer = wl_resource_create(client, &wl_pointer_interface, - wl_resource_get_version(seat_resource), id); - if (seat_client->pointer == NULL) { + + struct wl_resource *resource = wl_resource_create(client, + &wl_pointer_interface, wl_resource_get_version(seat_resource), id); + if (resource == NULL) { wl_resource_post_no_memory(seat_resource); return; } - wl_resource_set_implementation(seat_client->pointer, &wl_pointer_impl, - seat_client, &wl_pointer_destroy); + wl_resource_set_implementation(resource, &wl_pointer_impl, seat_client, + &wl_pointer_destroy); + wl_list_insert(&seat_client->pointers, wl_resource_get_link(resource)); } static const struct wl_keyboard_interface wl_keyboard_impl = { - .release = resource_destroy + .release = resource_destroy, }; static void wl_keyboard_destroy(struct wl_resource *resource) { - struct wlr_seat_client *client = wl_resource_get_user_data(resource); - if (client->keyboard) { - client->keyboard = NULL; - } + wl_list_remove(wl_resource_get_link(resource)); } static void seat_client_send_keymap(struct wlr_seat_client *client, struct wlr_keyboard *keyboard) { - if (!keyboard || !client->keyboard) { + if (!keyboard) { return; } + // TODO: We should probably lift all of the keys set by the other // keyboard - wl_keyboard_send_keymap(client->keyboard, - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keyboard->keymap_fd, - keyboard->keymap_size); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->keyboards) { + wl_keyboard_send_keymap(resource, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keyboard->keymap_fd, + keyboard->keymap_size); + } } static void seat_client_send_repeat_info(struct wlr_seat_client *client, struct wlr_keyboard *keyboard) { - if (!keyboard || !client->keyboard) { + if (!keyboard) { return; } - if (wl_resource_get_version(client->keyboard) >= - WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { - wl_keyboard_send_repeat_info(client->keyboard, - keyboard->repeat_info.rate, keyboard->repeat_info.delay); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->keyboards) { + if (wl_resource_get_version(resource) >= + WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { + wl_keyboard_send_repeat_info(resource, + keyboard->repeat_info.rate, keyboard->repeat_info.delay); + } } } @@ -131,20 +128,16 @@ static void wl_seat_get_keyboard(struct wl_client *client, if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) { return; } - if (seat_client->keyboard) { - // TODO: this is probably a protocol violation but it simplifies our - // code and it'd be stupid for clients to create several keyboards for - // the same seat - wl_resource_destroy(seat_client->keyboard); - } - seat_client->keyboard = wl_resource_create(client, &wl_keyboard_interface, - wl_resource_get_version(seat_resource), id); - if (seat_client->keyboard == NULL) { + + struct wl_resource *resource = wl_resource_create(client, + &wl_keyboard_interface, wl_resource_get_version(seat_resource), id); + if (resource == NULL) { wl_resource_post_no_memory(seat_resource); return; } - wl_resource_set_implementation(seat_client->keyboard, &wl_keyboard_impl, - seat_client, &wl_keyboard_destroy); + wl_resource_set_implementation(resource, &wl_keyboard_impl, seat_client, + &wl_keyboard_destroy); + wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource)); struct wlr_keyboard *keyboard = seat_client->seat->keyboard_state.keyboard; seat_client_send_keymap(seat_client, keyboard); @@ -155,14 +148,11 @@ static void wl_seat_get_keyboard(struct wl_client *client, } static const struct wl_touch_interface wl_touch_impl = { - .release = resource_destroy + .release = resource_destroy, }; static void wl_touch_destroy(struct wl_resource *resource) { - struct wlr_seat_client *client = wl_resource_get_user_data(resource); - if (client->touch) { - client->touch = NULL; - } + wl_list_remove(wl_resource_get_link(resource)); } static void wl_seat_get_touch(struct wl_client *client, @@ -172,24 +162,20 @@ static void wl_seat_get_touch(struct wl_client *client, if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_TOUCH)) { return; } - if (seat_client->touch) { - // TODO: this is probably a protocol violation but it simplifies our - // code and it'd be stupid for clients to create several pointers for - // the same seat - wl_resource_destroy(seat_client->touch); - } - seat_client->touch = wl_resource_create(client, &wl_touch_interface, - wl_resource_get_version(seat_resource), id); - if (seat_client->touch == NULL) { + + struct wl_resource *resource = wl_resource_create(client, + &wl_touch_interface, wl_resource_get_version(seat_resource), id); + if (resource == NULL) { wl_resource_post_no_memory(seat_resource); return; } - wl_resource_set_implementation(seat_client->touch, &wl_touch_impl, - seat_client, &wl_touch_destroy); + wl_resource_set_implementation(resource, &wl_touch_impl, seat_client, + &wl_touch_destroy); + wl_list_insert(&seat_client->touches, wl_resource_get_link(resource)); } -static void wlr_seat_client_resource_destroy(struct wl_resource *resource) { - struct wlr_seat_client *client = wl_resource_get_user_data(resource); +static void wlr_seat_client_resource_destroy(struct wl_resource *seat_resource) { + struct wlr_seat_client *client = wl_resource_get_user_data(seat_resource); wl_signal_emit(&client->events.destroy, client); if (client == client->seat->pointer_state.focused_client) { @@ -199,18 +185,20 @@ static void wlr_seat_client_resource_destroy(struct wl_resource *resource) { client->seat->keyboard_state.focused_client = NULL; } - if (client->pointer) { - wl_resource_destroy(client->pointer); + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &client->pointers) { + wl_resource_destroy(resource); } - if (client->keyboard) { - wl_resource_destroy(client->keyboard); + wl_resource_for_each_safe(resource, tmp, &client->keyboards) { + wl_resource_destroy(resource); } - if (client->touch) { - wl_resource_destroy(client->touch); + wl_resource_for_each_safe(resource, tmp, &client->touches) { + wl_resource_destroy(resource); } - if (client->data_device) { - wl_resource_destroy(client->data_device); + wl_resource_for_each_safe(resource, tmp, &client->data_devices) { + wl_resource_destroy(resource); } + wl_list_remove(&client->link); free(client); } @@ -219,7 +207,7 @@ struct wl_seat_interface wl_seat_impl = { .get_pointer = wl_seat_get_pointer, .get_keyboard = wl_seat_get_keyboard, .get_touch = wl_seat_get_touch, - .release = resource_destroy + .release = resource_destroy, }; static void wl_seat_bind(struct wl_client *client, void *_wlr_seat, @@ -242,6 +230,10 @@ static void wl_seat_bind(struct wl_client *client, void *_wlr_seat, } seat_client->client = client; seat_client->seat = wlr_seat; + wl_list_init(&seat_client->pointers); + wl_list_init(&seat_client->keyboards); + wl_list_init(&seat_client->touches); + wl_list_init(&seat_client->data_devices); wl_resource_set_implementation(seat_client->wl_resource, &wl_seat_impl, seat_client, wlr_seat_client_resource_destroy); wl_list_insert(&wlr_seat->clients, &seat_client->link); @@ -253,7 +245,7 @@ static void wl_seat_bind(struct wl_client *client, void *_wlr_seat, } static void default_pointer_enter(struct wlr_seat_pointer_grab *grab, - struct wlr_surface *surface, double sx, double sy) { + struct wlr_surface *surface, double sx, double sy) { wlr_seat_pointer_enter(grab->seat, surface, sx, sy); } @@ -514,11 +506,6 @@ static void pointer_resource_destroy_notify(struct wl_listener *listener, wlr_seat_pointer_clear_focus(state->seat); } -static bool wlr_seat_pointer_has_focus_resource(struct wlr_seat *wlr_seat) { - return wlr_seat->pointer_state.focused_client && - wlr_seat->pointer_state.focused_client->pointer; -} - void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, struct wlr_surface *surface, double sx, double sy) { assert(wlr_seat); @@ -529,7 +516,6 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, } struct wlr_seat_client *client = NULL; - if (surface) { struct wl_client *wl_client = wl_resource_get_client(surface->resource); client = wlr_seat_client_for_wl_client(wlr_seat, wl_client); @@ -541,19 +527,24 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, wlr_seat->pointer_state.focused_surface; // leave the previously entered surface - if (focused_client && focused_client->pointer && focused_surface) { + if (focused_client != NULL && focused_surface != NULL) { uint32_t serial = wl_display_next_serial(wlr_seat->display); - wl_pointer_send_leave(focused_client->pointer, serial, - focused_surface->resource); - pointer_send_frame(focused_client->pointer); + struct wl_resource *resource; + wl_resource_for_each(resource, &focused_client->pointers) { + wl_pointer_send_leave(resource, serial, focused_surface->resource); + pointer_send_frame(resource); + } } // enter the current surface - if (client && client->pointer) { + if (client != NULL && surface != NULL) { uint32_t serial = wl_display_next_serial(wlr_seat->display); - wl_pointer_send_enter(client->pointer, serial, surface->resource, - wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - pointer_send_frame(client->pointer); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + wl_pointer_send_enter(resource, serial, surface->resource, + wl_fixed_from_double(sx), wl_fixed_from_double(sy)); + pointer_send_frame(resource); + } } // reinitialize the focus destroy events @@ -561,7 +552,7 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, wl_list_init(&wlr_seat->pointer_state.surface_destroy.link); wl_list_remove(&wlr_seat->pointer_state.resource_destroy.link); wl_list_init(&wlr_seat->pointer_state.resource_destroy.link); - if (surface) { + if (surface != NULL) { wl_signal_add(&surface->events.destroy, &wlr_seat->pointer_state.surface_destroy); wl_resource_add_destroy_listener(surface->resource, @@ -584,46 +575,53 @@ void wlr_seat_pointer_clear_focus(struct wlr_seat *wlr_seat) { void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, double sx, double sy) { - if (!wlr_seat_pointer_has_focus_resource(wlr_seat)) { + struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client; + if (client == NULL) { return; } - wl_pointer_send_motion(wlr_seat->pointer_state.focused_client->pointer, - time, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - pointer_send_frame(wlr_seat->pointer_state.focused_client->pointer); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + wl_pointer_send_motion(resource, time, wl_fixed_from_double(sx), + wl_fixed_from_double(sy)); + pointer_send_frame(resource); + } } uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time, uint32_t button, uint32_t state) { - if (!wlr_seat_pointer_has_focus_resource(wlr_seat)) { + struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client; + if (client == NULL) { return 0; } uint32_t serial = wl_display_next_serial(wlr_seat->display); - wl_pointer_send_button(wlr_seat->pointer_state.focused_client->pointer, - serial, time, button, state); - pointer_send_frame(wlr_seat->pointer_state.focused_client->pointer); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + wl_pointer_send_button(resource, serial, time, button, state); + pointer_send_frame(resource); + } return serial; } void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time, enum wlr_axis_orientation orientation, double value) { - if (!wlr_seat_pointer_has_focus_resource(wlr_seat)) { + struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client; + if (client == NULL) { return; } - struct wl_resource *pointer = - wlr_seat->pointer_state.focused_client->pointer; - - if (value) { - wl_pointer_send_axis(pointer, time, orientation, - wl_fixed_from_double(value)); - } else if (wl_resource_get_version(pointer) >= - WL_POINTER_AXIS_STOP_SINCE_VERSION) { - wl_pointer_send_axis_stop(pointer, time, orientation); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + if (value) { + wl_pointer_send_axis(resource, time, orientation, + wl_fixed_from_double(value)); + } else if (wl_resource_get_version(resource) >= + WL_POINTER_AXIS_STOP_SINCE_VERSION) { + wl_pointer_send_axis_stop(resource, time, orientation); + } + pointer_send_frame(resource); } - - pointer_send_frame(pointer); } void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat, @@ -697,13 +695,15 @@ bool wlr_seat_pointer_has_grab(struct wlr_seat *seat) { void wlr_seat_keyboard_send_key(struct wlr_seat *wlr_seat, uint32_t time, uint32_t key, uint32_t state) { struct wlr_seat_client *client = wlr_seat->keyboard_state.focused_client; - if (!client || !client->keyboard) { + if (!client) { return; } uint32_t serial = wl_display_next_serial(wlr_seat->display); - wl_keyboard_send_key(client->keyboard, serial, - time, key, state); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->keyboards) { + wl_keyboard_send_key(resource, serial, time, key, state); + } } static void handle_keyboard_keymap(struct wl_listener *listener, void *data) { @@ -811,19 +811,22 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener, void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat) { struct wlr_seat_client *client = seat->keyboard_state.focused_client; - if (!client || !client->keyboard) { + if (client == NULL) { return; } struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; - if (!keyboard) { + if (keyboard == NULL) { return; } uint32_t serial = wl_display_next_serial(seat->display); - wl_keyboard_send_modifiers(client->keyboard, serial, - keyboard->modifiers.depressed, keyboard->modifiers.latched, - keyboard->modifiers.locked, keyboard->modifiers.group); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->keyboards) { + wl_keyboard_send_modifiers(resource, serial, + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); + } } void wlr_seat_keyboard_enter(struct wlr_seat *seat, @@ -846,29 +849,31 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat, seat->keyboard_state.focused_surface; // leave the previously entered surface - if (focused_client && focused_client->keyboard && focused_surface) { + if (focused_client != NULL && focused_surface != NULL) { uint32_t serial = wl_display_next_serial(seat->display); - wl_keyboard_send_leave(focused_client->keyboard, serial, - focused_surface->resource); + struct wl_resource *resource; + wl_resource_for_each(resource, &focused_client->keyboards) { + wl_keyboard_send_leave(resource, serial, focused_surface->resource); + } } // enter the current surface - if (client && client->keyboard && seat->keyboard_state.keyboard) { + if (client != NULL && seat->keyboard_state.keyboard != NULL) { struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; struct wl_array keys; wl_array_init(&keys); - size_t n = 0; for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { if (keyboard->keycodes[i] != 0) { - wl_array_add(&keys, sizeof(uint32_t)); - ((uint32_t *)keys.data)[n] = keyboard->keycodes[i]; - n++; + uint32_t *p = wl_array_add(&keys, sizeof(uint32_t)); + *p = keyboard->keycodes[i]; } } uint32_t serial = wl_display_next_serial(seat->display); - wl_keyboard_send_enter(client->keyboard, serial, - surface->resource, &keys); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->keyboards) { + wl_keyboard_send_enter(resource, serial, surface->resource, &keys); + } wl_array_release(&keys); wlr_seat_client_send_selection(client); @@ -893,7 +898,7 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat, seat->keyboard_state.focused_client = client; seat->keyboard_state.focused_surface = surface; - if (client && client->keyboard && seat->keyboard_state.keyboard) { + if (client != NULL && seat->keyboard_state.keyboard != NULL) { // tell new client about any modifier change last, // as it targets seat->keyboard_state.focused_client wlr_seat_keyboard_send_modifiers(seat); @@ -986,7 +991,7 @@ static struct wlr_touch_point *touch_point_create( struct wl_client *wl_client = wl_resource_get_client(surface->resource); struct wlr_seat_client *client = wlr_seat_client_for_wl_client(seat, wl_client); - if (!client || !client->touch) { + if (client == NULL || wl_list_empty(&client->touches)) { // touch points are not valid without a connected client with touch return NULL; } @@ -1101,7 +1106,7 @@ static void touch_point_set_focus(struct wlr_touch_point *point, wlr_seat_client_for_wl_client(point->client->seat, wl_resource_get_client(surface->resource)); - if (client && client->touch) { + if (client && !wl_list_empty(&client->touches)) { wl_signal_add(&surface->events.destroy, &point->focus_surface_destroy); point->focus_surface_destroy.notify = handle_point_focus_destroy; point->focus_surface = surface; @@ -1151,9 +1156,12 @@ uint32_t wlr_seat_touch_send_down(struct wlr_seat *seat, } uint32_t serial = wl_display_next_serial(seat->display); - wl_touch_send_down(point->client->touch, serial, time, surface->resource, - touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - wl_touch_send_frame(point->client->touch); + struct wl_resource *resource; + wl_resource_for_each(resource, &point->client->touches) { + wl_touch_send_down(resource, serial, time, surface->resource, + touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); + wl_touch_send_frame(resource); + } return serial; } @@ -1166,8 +1174,11 @@ void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time, int32_t touch_ } uint32_t serial = wl_display_next_serial(seat->display); - wl_touch_send_up(point->client->touch, serial, time, touch_id); - wl_touch_send_frame(point->client->touch); + struct wl_resource *resource; + wl_resource_for_each(resource, &point->client->touches) { + wl_touch_send_up(resource, serial, time, touch_id); + wl_touch_send_frame(resource); + } } void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t touch_id, @@ -1178,9 +1189,12 @@ void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t to return; } - wl_touch_send_motion(point->client->touch, time, touch_id, - wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - wl_touch_send_frame(point->client->touch); + struct wl_resource *resource; + wl_resource_for_each(resource, &point->client->touches) { + wl_touch_send_motion(resource, time, touch_id, wl_fixed_from_double(sx), + wl_fixed_from_double(sy)); + wl_touch_send_frame(resource); + } } int wlr_seat_touch_num_points(struct wlr_seat *seat) { diff --git a/types/wlr_xcursor_manager.c b/types/wlr_xcursor_manager.c index f32a96bc..d81b639d 100644 --- a/types/wlr_xcursor_manager.c +++ b/types/wlr_xcursor_manager.c @@ -33,7 +33,7 @@ void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager) { } int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, - uint32_t scale) { + float scale) { struct wlr_xcursor_manager_theme *theme; wl_list_for_each(theme, &manager->scaled_themes, link) { if (theme->scale == scale) { @@ -56,7 +56,7 @@ int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, } struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( - struct wlr_xcursor_manager *manager, const char *name, uint32_t scale) { + struct wlr_xcursor_manager *manager, const char *name, float scale) { struct wlr_xcursor_manager_theme *theme; wl_list_for_each(theme, &manager->scaled_themes, link) { if (theme->scale == scale) { |