From c45f2eef0e0fb805d88b54b65db23bb8a49ebea6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Oct 2017 10:39:47 +0100 Subject: Fix rootston --- rootston/cursor.c | 23 ++++------------------- rootston/output.c | 30 +++++++++++++----------------- 2 files changed, 17 insertions(+), 36 deletions(-) (limited to 'rootston') diff --git a/rootston/cursor.c b/rootston/cursor.c index 3fa8afb6..7307b6b2 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -33,24 +33,8 @@ const struct roots_input_event *get_input_event(struct roots_input *input, static void cursor_set_xcursor_image(struct roots_input *input, struct wlr_xcursor_image *image) { - struct roots_output *output; - wl_list_for_each(output, &input->server->desktop->outputs, link) { - if (!wlr_output_set_cursor(output->wlr_output, image->buffer, - image->width, image->width, image->height, - image->hotspot_x, image->hotspot_y)) { - wlr_log(L_DEBUG, "Failed to set hardware cursor"); - return; - } - } -} - -static void cursor_set_surface(struct roots_input *input, - struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y) { - struct roots_output *output; - wl_list_for_each(output, &input->server->desktop->outputs, link) { - wlr_output_set_cursor_surface(output->wlr_output, surface, - hotspot_x, hotspot_y); - } + wlr_cursor_set_image(input->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); } void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, @@ -487,7 +471,8 @@ static void handle_request_set_cursor(struct wl_listener *listener, } wlr_log(L_DEBUG, "Setting client cursor"); - cursor_set_surface(input, event->surface, event->hotspot_x, event->hotspot_y); + wlr_cursor_set_surface(input->cursor, event->surface, event->hotspot_x, + event->hotspot_y); input->cursor_client = event->seat_client->client; } diff --git a/rootston/output.c b/rootston/output.c index 6bc28996..6ca302d8 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -186,20 +186,20 @@ static void set_mode(struct wlr_output *output, struct output_config *oc) { } void output_add_notify(struct wl_listener *listener, void *data) { + struct roots_desktop *desktop = wl_container_of(listener, desktop, + output_add); struct wlr_output *wlr_output = data; - struct roots_desktop *desktop = wl_container_of(listener, desktop, output_add); struct roots_input *input = desktop->server->input; struct roots_config *config = desktop->config; wlr_log(L_DEBUG, "Output '%s' added", wlr_output->name); - wlr_log(L_DEBUG, "%s %s %"PRId32"mm x %"PRId32"mm", - wlr_output->make, wlr_output->model, - wlr_output->phys_width, wlr_output->phys_height); - if (wl_list_length(&wlr_output->modes) > 0) { - struct wlr_output_mode *mode = NULL; - mode = wl_container_of((&wlr_output->modes)->prev, mode, link); - wlr_output_set_mode(wlr_output, mode); - } + wlr_log(L_DEBUG, "%s %s %"PRId32"mm x %"PRId32"mm", wlr_output->make, + wlr_output->model, wlr_output->phys_width, wlr_output->phys_height); + if (wl_list_length(&wlr_output->modes) > 0) { + struct wlr_output_mode *mode = NULL; + mode = wl_container_of((&wlr_output->modes)->prev, mode, link); + wlr_output_set_mode(wlr_output, mode); + } struct roots_output *output = calloc(1, sizeof(struct roots_output)); clock_gettime(CLOCK_MONOTONIC, &output->last_frame); @@ -223,16 +223,12 @@ void output_add_notify(struct wl_listener *listener, void *data) { cursor_load_config(config, input->cursor, input, desktop); - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; // TODO the cursor must be set depending on which surface it is displayed // over which should happen in the compositor. - if (!wlr_output_set_cursor(wlr_output, image->buffer, - image->width, image->width, image->height, - image->hotspot_x, image->hotspot_y)) { - wlr_log(L_DEBUG, "Failed to set hardware cursor"); - return; - } + struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(input->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); wlr_cursor_warp(input->cursor, NULL, input->cursor->x, input->cursor->y); } -- cgit v1.2.3 From 4230a577cc878607c2db1e6e5e7051b9e7653584 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Oct 2017 18:14:58 +0100 Subject: Remove wlr_cursor_set_xcursor for now --- examples/pointer.c | 4 +++- include/wlr/types/wlr_cursor.h | 2 -- rootston/input.c | 5 ++++- types/wlr_cursor.c | 5 ----- 4 files changed, 7 insertions(+), 9 deletions(-) (limited to 'rootston') diff --git a/examples/pointer.c b/examples/pointer.c index 26d50b95..77f5192f 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -321,7 +321,9 @@ int main(int argc, char *argv[]) { return 1; } - wlr_cursor_set_xcursor(state.cursor, state.xcursor); + struct wlr_xcursor_image *image = state.xcursor->images[0]; + wlr_cursor_set_image(state.cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); compositor_init(&compositor); if (!wlr_backend_start(compositor.backend)) { diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index be4f322f..1aac2b94 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -36,8 +36,6 @@ struct wlr_cursor *wlr_cursor_create(); void wlr_cursor_destroy(struct wlr_cursor *cur); -void wlr_cursor_set_xcursor(struct wlr_cursor *cur, struct wlr_xcursor *xcur); - /** * Warp the cursor to the given x and y in layout coordinates. If x and y are * out of the layout boundaries or constraints, no warp will happen. diff --git a/rootston/input.c b/rootston/input.c index a6792bdb..8109d2b6 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -118,7 +118,10 @@ struct roots_input *input_create(struct roots_server *server, input->cursor = wlr_cursor_create(); cursor_initialize(input); - wlr_cursor_set_xcursor(input->cursor, xcursor); + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(input->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); wlr_cursor_attach_output_layout(input->cursor, server->desktop->layout); wlr_cursor_map_to_region(input->cursor, config->cursor.mapped_box); diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 76e20e9e..ece3d842 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -46,7 +46,6 @@ struct wlr_cursor_state { struct wl_list devices; // wlr_cursor_device::link struct wl_list output_cursors; // wlr_cursor_output_cursor::link struct wlr_output_layout *layout; - struct wlr_xcursor *xcursor; struct wlr_output *mapped_output; struct wlr_box *mapped_box; @@ -123,10 +122,6 @@ void wlr_cursor_destroy(struct wlr_cursor *cur) { free(cur); } -void wlr_cursor_set_xcursor(struct wlr_cursor *cur, struct wlr_xcursor *xcur) { - cur->state->xcursor = xcur; -} - static struct wlr_cursor_device *get_cursor_device(struct wlr_cursor *cur, struct wlr_input_device *device) { struct wlr_cursor_device *c_device, *ret = NULL; -- cgit v1.2.3 From c3b09f73da0d1fc4815f4b085ca07e30d175f549 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Oct 2017 18:45:53 +0100 Subject: Fix cursor hotspot with rotated outputs on DRM backend --- backend/drm/drm.c | 38 +++++++++++++++++++++++++++++++ include/backend/drm/drm.h | 1 + rootston/xcursor.c | 2 +- types/wlr_output.c | 58 ++++------------------------------------------- 4 files changed, 44 insertions(+), 55 deletions(-) (limited to 'rootston') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 23b9a9fa..6cbb0535 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -558,6 +558,40 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, } } + switch (output->transform) { + case WL_OUTPUT_TRANSFORM_90: + plane->cursor_hotspot_x = hotspot_x; + plane->cursor_hotspot_y = -plane->surf.height + hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_180: + plane->cursor_hotspot_x = plane->surf.width - hotspot_x; + plane->cursor_hotspot_y = plane->surf.height - hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_270: + plane->cursor_hotspot_x = -plane->surf.height + hotspot_x; + plane->cursor_hotspot_y = hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED: + plane->cursor_hotspot_x = plane->surf.width - hotspot_x; + plane->cursor_hotspot_y = hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + plane->cursor_hotspot_x = hotspot_x; + plane->cursor_hotspot_y = -hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + plane->cursor_hotspot_x = hotspot_x; + plane->cursor_hotspot_y = plane->surf.height - hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + plane->cursor_hotspot_x = -plane->surf.height + hotspot_x; + plane->cursor_hotspot_y = plane->surf.width - hotspot_y; + break; + default: // WL_OUTPUT_TRANSFORM_NORMAL + plane->cursor_hotspot_x = hotspot_x; + plane->cursor_hotspot_y = hotspot_y; + } + if (!update_pixels) { // Only update the cursor hotspot return true; @@ -605,6 +639,10 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output, struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; + struct wlr_drm_plane *plane = conn->crtc->cursor; + x -= plane->cursor_hotspot_x; + y -= plane->cursor_hotspot_y; + int width, height, tmp; wlr_output_effective_resolution(output, &width, &height); diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index a6dd247c..e08965e5 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -34,6 +34,7 @@ struct wlr_drm_plane { struct wlr_texture *wlr_tex; struct gbm_bo *cursor_bo; bool cursor_enabled; + int32_t cursor_hotspot_x, cursor_hotspot_y; union wlr_drm_plane_props props; }; diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 43cbfc51..0d18e1f0 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -2,7 +2,7 @@ #include "rootston/input.h" struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); + return wlr_xcursor_theme_get_cursor(theme, "grabbing"); } struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 5862d0fa..3cdeecfe 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -237,44 +237,6 @@ void wlr_output_make_current(struct wlr_output *output) { output->impl->make_current(output); } -static void output_cursor_get_effective_hotspot( - struct wlr_output_cursor *cursor, int32_t *hotspot_x, - int32_t *hotspot_y) { - switch (cursor->output->transform) { - case WL_OUTPUT_TRANSFORM_90: - *hotspot_x = cursor->hotspot_x; - *hotspot_y = -cursor->height + cursor->hotspot_y; - break; - case WL_OUTPUT_TRANSFORM_180: - *hotspot_x = cursor->width - cursor->hotspot_x; - *hotspot_y = cursor->height - cursor->hotspot_y; - break; - case WL_OUTPUT_TRANSFORM_270: - *hotspot_x = -cursor->height + cursor->hotspot_x; - *hotspot_y = cursor->hotspot_y; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED: - *hotspot_x = cursor->width - cursor->hotspot_x; - *hotspot_y = cursor->hotspot_y; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - *hotspot_x = cursor->hotspot_x; - *hotspot_y = -cursor->hotspot_y; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - *hotspot_x = cursor->hotspot_x; - *hotspot_y = cursor->height - cursor->hotspot_y; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - *hotspot_x = -cursor->height + cursor->hotspot_x; - *hotspot_y = cursor->width - cursor->hotspot_y; - break; - default: // WL_OUTPUT_TRANSFORM_NORMAL - *hotspot_x = cursor->hotspot_x; - *hotspot_y = cursor->hotspot_y; - } -} - static void output_cursor_render(struct wlr_output_cursor *cursor) { struct wlr_texture *texture = cursor->texture; struct wlr_renderer *renderer = cursor->renderer; @@ -290,13 +252,10 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - int32_t hotspot_x, hotspot_y; - output_cursor_get_effective_hotspot(cursor, &hotspot_x, &hotspot_y); - float matrix[16]; wlr_texture_get_matrix(texture, &matrix, - &cursor->output->transform_matrix, cursor->x - hotspot_x, - cursor->y - hotspot_y); + &cursor->output->transform_matrix, cursor->x - cursor->hotspot_x, + cursor->y - cursor->hotspot_y); wlr_render_with_matrix(renderer, texture, &matrix); } } @@ -349,14 +308,8 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, if (cursor->output->hardware_cursor == NULL && cursor->output->impl->set_cursor) { - int32_t hotspot_eff_x, hotspot_eff_y; - output_cursor_get_effective_hotspot(cursor, &hotspot_eff_x, - &hotspot_eff_y); - - // TODO: also transform pixels with output->transform before calling - // set_cursor int ok = cursor->output->impl->set_cursor(cursor->output, pixels, - stride, width, height, hotspot_eff_x, hotspot_eff_y, true); + stride, width, height, hotspot_x, hotspot_y, true); if (ok) { cursor->output->hardware_cursor = cursor; return true; @@ -438,11 +391,8 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, cursor->output->impl->set_cursor) { // If the surface hasn't changed and it's an hardware cursor, only // update the hotspot - int32_t hotspot_eff_x, hotspot_eff_y; - output_cursor_get_effective_hotspot(cursor, &hotspot_eff_x, - &hotspot_eff_y); cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, - hotspot_eff_x, hotspot_eff_y, false); + hotspot_x, hotspot_y, false); } return; } -- cgit v1.2.3 From 044173d1dfbce7bdc3ae134a829f2bb0d88d208b Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Oct 2017 20:03:56 +0100 Subject: Add multi-pointer example --- examples/meson.build | 2 + examples/multi-pointer.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++ examples/pointer.c | 22 +++--- rootston/xcursor.c | 2 +- types/wlr_cursor.c | 45 ++++++++--- 5 files changed, 250 insertions(+), 23 deletions(-) create mode 100644 examples/multi-pointer.c (limited to 'rootston') diff --git a/examples/meson.build b/examples/meson.build index a29a3310..3402441b 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -8,6 +8,8 @@ executable('simple', 'simple.c', dependencies: wlroots, link_with: lib_shared) executable('pointer', 'pointer.c', dependencies: wlroots, link_with: lib_shared) executable('touch', 'touch.c', dependencies: wlroots, link_with: lib_shared) executable('tablet', 'tablet.c', dependencies: wlroots, link_with: lib_shared) +executable('multi-pointer', 'multi-pointer.c', dependencies: wlroots, + link_with: lib_shared) executable( 'rotation', diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c new file mode 100644 index 00000000..c3a02cc7 --- /dev/null +++ b/examples/multi-pointer.c @@ -0,0 +1,202 @@ +#define _POSIX_C_SOURCE 199309L +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shared.h" +#include "config.h" +#include "cat.h" + +struct sample_state; + +struct sample_cursor { + struct sample_state *state; + struct wlr_input_device *device; + struct wlr_cursor *cursor; + struct wl_list link; + + struct wl_listener cursor_motion; + struct wl_listener cursor_motion_absolute; + struct wl_listener cursor_button; + struct wl_listener cursor_axis; +}; + +struct sample_state { + struct compositor_state *compositor; + struct example_config *config; + struct wlr_xcursor *xcursor; + float default_color[4]; + float clear_color[4]; + struct wlr_output_layout *layout; + struct wl_list cursors; // sample_cursor::link +}; + +static void handle_output_frame(struct output_state *output, + struct timespec *ts) { + struct compositor_state *state = output->compositor; + struct sample_state *sample = state->data; + struct wlr_output *wlr_output = output->output; + + wlr_output_make_current(wlr_output); + + glClearColor(sample->clear_color[0], sample->clear_color[1], + sample->clear_color[2], sample->clear_color[3]); + glClear(GL_COLOR_BUFFER_BIT); + + wlr_output_swap_buffers(wlr_output); +} + +static void handle_output_add(struct output_state *ostate) { + struct sample_state *sample = ostate->compositor->data; + + struct output_config *o_config = + example_config_get_output(sample->config, ostate->output); + + if (o_config) { + wlr_output_transform(ostate->output, o_config->transform); + wlr_output_layout_add(sample->layout, ostate->output, o_config->x, + o_config->y); + } else { + wlr_output_layout_add_auto(sample->layout, ostate->output); + } + + struct sample_cursor *cursor; + wl_list_for_each(cursor, &sample->cursors, link) { + example_config_configure_cursor(sample->config, cursor->cursor, + sample->compositor); + + // TODO the cursor must be set depending on which surface it is + // displayed over which should happen in the compositor. + struct wlr_xcursor_image *image = sample->xcursor->images[0]; + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + wlr_cursor_warp(cursor->cursor, NULL, cursor->cursor->x, + cursor->cursor->y); + } +} + +static void handle_output_remove(struct output_state *ostate) { + struct sample_state *sample = ostate->compositor->data; + + wlr_output_layout_remove(sample->layout, ostate->output); + + struct sample_cursor *cursor; + wl_list_for_each(cursor, &sample->cursors, link) { + example_config_configure_cursor(sample->config, cursor->cursor, + sample->compositor); + } +} + +static void handle_cursor_motion(struct wl_listener *listener, void *data) { + struct sample_cursor *cursor = + wl_container_of(listener, cursor, cursor_motion); + struct wlr_event_pointer_motion *event = data; + wlr_cursor_move(cursor->cursor, event->device, event->delta_x, + event->delta_y); +} + +static void handle_cursor_motion_absolute(struct wl_listener *listener, + void *data) { + struct sample_cursor *cursor = + wl_container_of(listener, cursor, cursor_motion_absolute); + struct wlr_event_pointer_motion_absolute *event = data; + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); +} + +static void handle_input_add(struct compositor_state *state, + struct wlr_input_device *device) { + struct sample_state *sample = state->data; + + if (device->type != WLR_INPUT_DEVICE_POINTER) { + return; + } + + struct sample_cursor *cursor = calloc(1, sizeof(struct sample_cursor)); + cursor->state = sample; + + cursor->cursor = wlr_cursor_create(); + wlr_cursor_attach_output_layout(cursor->cursor, sample->layout); + wlr_cursor_map_to_region(cursor->cursor, sample->config->cursor.mapped_box); + + wl_signal_add(&cursor->cursor->events.motion, &cursor->cursor_motion); + cursor->cursor_motion.notify = handle_cursor_motion; + wl_signal_add(&cursor->cursor->events.motion_absolute, + &cursor->cursor_motion_absolute); + cursor->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + + wlr_cursor_attach_input_device(cursor->cursor, device); + example_config_configure_cursor(sample->config, cursor->cursor, + sample->compositor); + + struct wlr_xcursor_image *image = sample->xcursor->images[0]; + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + wl_list_insert(&sample->cursors, &cursor->link); +} + +int main(int argc, char *argv[]) { + struct sample_state state = { + .default_color = { 0.25f, 0.25f, 0.25f, 1 }, + .clear_color = { 0.25f, 0.25f, 0.25f, 1 }, + }; + + wl_list_init(&state.cursors); + + state.config = parse_args(argc, argv); + state.layout = wlr_output_layout_create(); + + struct compositor_state compositor = { 0 }; + compositor.data = &state; + compositor.output_add_cb = handle_output_add; + compositor.output_remove_cb = handle_output_remove; + compositor.output_frame_cb = handle_output_frame; + compositor.input_add_cb = handle_input_add; + + state.compositor = &compositor; + + struct wlr_xcursor_theme *theme = wlr_xcursor_theme_load("default", 16); + if (!theme) { + wlr_log(L_ERROR, "Failed to load cursor theme"); + return 1; + } + state.xcursor = wlr_xcursor_theme_get_cursor(theme, "left_ptr"); + if (!state.xcursor) { + wlr_log(L_ERROR, "Failed to load left_ptr cursor"); + return 1; + } + + compositor_init(&compositor); + if (!wlr_backend_start(compositor.backend)) { + wlr_log(L_ERROR, "Failed to start backend"); + wlr_backend_destroy(compositor.backend); + exit(1); + } + wl_display_run(compositor.display); + compositor_fini(&compositor); + + wlr_xcursor_theme_destroy(theme); + example_config_destroy(state.config); + wlr_output_layout_destroy(state.layout); +} diff --git a/examples/pointer.c b/examples/pointer.c index 77f5192f..83122421 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -60,7 +60,7 @@ struct touch_point { }; static void warp_to_touch(struct sample_state *sample, - struct wlr_input_device *dev) { + struct wlr_input_device *dev) { if (sample->touch_points->length == 0) { return; } @@ -77,7 +77,7 @@ static void warp_to_touch(struct sample_state *sample, } static void handle_output_frame(struct output_state *output, - struct timespec *ts) { + struct timespec *ts) { struct compositor_state *state = output->compositor; struct sample_state *sample = state->data; struct wlr_output *wlr_output = output->output; @@ -127,7 +127,7 @@ static void handle_output_remove(struct output_state *ostate) { } static void handle_input_add(struct compositor_state *state, - struct wlr_input_device *device) { + struct wlr_input_device *device) { struct sample_state *sample = state->data; if (device->type == WLR_INPUT_DEVICE_POINTER || @@ -141,16 +141,16 @@ static void handle_input_add(struct compositor_state *state, static void handle_cursor_motion(struct wl_listener *listener, void *data) { struct sample_state *sample = - wl_container_of(listener, sample, cursor_motion); + wl_container_of(listener, sample, cursor_motion); struct wlr_event_pointer_motion *event = data; wlr_cursor_move(sample->cursor, event->device, event->delta_x, - event->delta_y); + event->delta_y); } static void handle_cursor_motion_absolute(struct wl_listener *listener, - void *data) { + void *data) { struct sample_state *sample = - wl_container_of(listener, sample, cursor_motion_absolute); + wl_container_of(listener, sample, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; sample->cur_x = event->x_mm; @@ -162,7 +162,7 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, static void handle_cursor_button(struct wl_listener *listener, void *data) { struct sample_state *sample = - wl_container_of(listener, sample, cursor_button); + wl_container_of(listener, sample, cursor_button); struct wlr_event_pointer_button *event = data; float (*color)[4]; @@ -179,7 +179,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { static void handle_cursor_axis(struct wl_listener *listener, void *data) { struct sample_state *sample = - wl_container_of(listener, sample, cursor_axis); + wl_container_of(listener, sample, cursor_axis); struct wlr_event_pointer_axis *event = data; for (size_t i = 0; i < 3; ++i) { @@ -226,7 +226,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) { static void handle_touch_motion(struct wl_listener *listener, void *data) { struct sample_state *sample = - wl_container_of(listener, sample, touch_motion); + wl_container_of(listener, sample, touch_motion); struct wlr_event_touch_motion *event = data; for (size_t i = 0; i < sample->touch_points->length; ++i) { struct touch_point *point = sample->touch_points->items[i]; @@ -246,7 +246,7 @@ static void handle_touch_cancel(struct wl_listener *listener, void *data) { static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { struct sample_state *sample = - wl_container_of(listener, sample, tablet_tool_axis); + wl_container_of(listener, sample, tablet_tool_axis); struct wlr_event_tablet_tool_axis *event = data; if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 0d18e1f0..43cbfc51 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -2,7 +2,7 @@ #include "rootston/input.h" struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); + return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); } struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index ece3d842..ece7973c 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -98,11 +98,30 @@ struct wlr_cursor *wlr_cursor_create() { return cur; } +static void output_cursor_remove( + struct wlr_cursor_output_cursor *output_cursor) { + wl_list_remove(&output_cursor->link); + wlr_output_cursor_destroy(output_cursor->output_cursor); + wl_list_remove(&output_cursor->layout_output_destroy.link); + free(output_cursor); +} + static void wlr_cursor_detach_output_layout(struct wlr_cursor *cur) { if (!cur->state->layout) { return; } + struct wlr_output_layout_output *l_output; + wl_list_for_each(l_output, &cur->state->layout->outputs, link) { + struct wlr_cursor_output_cursor *output_cursor, *tmp; + wl_list_for_each_safe(output_cursor, tmp, &cur->state->output_cursors, + link) { + if (output_cursor->output_cursor->output == l_output->output) { + output_cursor_remove(output_cursor); + } + } + } + wl_list_remove(&cur->state->layout_destroy.link); wl_list_remove(&cur->state->layout_change.link); wl_list_remove(&cur->state->layout_add.link); @@ -477,7 +496,6 @@ static void wlr_cursor_device_destroy(struct wlr_cursor_device *c_device) { wl_list_remove(&c_device->link); wl_list_remove(&c_device->destroy.link); free(c_device); - } void wlr_cursor_detach_input_device(struct wlr_cursor *cur, @@ -501,18 +519,11 @@ static void handle_layout_output_destroy(struct wl_listener *listener, struct wlr_cursor_output_cursor *output_cursor = wl_container_of(listener, output_cursor, layout_output_destroy); //struct wlr_output_layout_output *l_output = data; - - wl_list_remove(&output_cursor->link); - wlr_output_cursor_destroy(output_cursor->output_cursor); - wl_list_remove(&output_cursor->layout_output_destroy.link); - free(output_cursor); + output_cursor_remove(output_cursor); } -static void handle_layout_add(struct wl_listener *listener, void *data) { - struct wlr_cursor_state *state = - wl_container_of(listener, state, layout_add); - struct wlr_output_layout_output *l_output = data; - +static void layout_add(struct wlr_cursor_state *state, + struct wlr_output_layout_output *l_output) { struct wlr_cursor_output_cursor *output_cursor = calloc(1, sizeof(struct wlr_cursor_output_cursor)); if (output_cursor == NULL) { @@ -535,6 +546,13 @@ static void handle_layout_add(struct wl_listener *listener, void *data) { wl_list_insert(&state->cursor->state->output_cursors, &output_cursor->link); } +static void handle_layout_add(struct wl_listener *listener, void *data) { + struct wlr_cursor_state *state = + wl_container_of(listener, state, layout_add); + struct wlr_output_layout_output *l_output = data; + layout_add(state, l_output); +} + static void handle_layout_change(struct wl_listener *listener, void *data) { struct wlr_cursor_state *state = wl_container_of(listener, state, layout_change); @@ -568,6 +586,11 @@ void wlr_cursor_attach_output_layout(struct wlr_cursor *cur, cur->state->layout_destroy.notify = handle_layout_destroy; cur->state->layout = l; + + struct wlr_output_layout_output *l_output; + wl_list_for_each(l_output, &l->outputs, link) { + layout_add(cur->state, l_output); + } } void wlr_cursor_map_to_output(struct wlr_cursor *cur, -- cgit v1.2.3 From ae9a46fc9bc81051ef732a178b47017d8c2e591f Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 31 Oct 2017 10:54:05 +0100 Subject: Remove outdated TODOs, use wlr_surface_has_buffer --- examples/multi-pointer.c | 2 -- examples/pointer.c | 2 -- rootston/output.c | 2 -- types/wlr_output.c | 8 +++++--- 4 files changed, 5 insertions(+), 9 deletions(-) (limited to 'rootston') diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index 3cfa3910..e1ac2734 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -84,8 +84,6 @@ static void handle_output_add(struct output_state *ostate) { example_config_configure_cursor(sample->config, cursor->cursor, sample->compositor); - // TODO the cursor must be set depending on which surface it is - // displayed over which should happen in the compositor. struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, image->width, image->height, image->hotspot_x, image->hotspot_y); diff --git a/examples/pointer.c b/examples/pointer.c index 83122421..8927314e 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -108,8 +108,6 @@ static void handle_output_add(struct output_state *ostate) { example_config_configure_cursor(sample->config, sample->cursor, sample->compositor); - // TODO the cursor must be set depending on which surface it is displayed - // over which should happen in the compositor. struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(sample->cursor, image->buffer, image->width, image->width, image->height, image->hotspot_x, image->hotspot_y); diff --git a/rootston/output.c b/rootston/output.c index 6ca302d8..9e1cd4d5 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -223,8 +223,6 @@ void output_add_notify(struct wl_listener *listener, void *data) { cursor_load_config(config, input->cursor, input, desktop); - // TODO the cursor must be set depending on which surface it is displayed - // over which should happen in the compositor. struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); struct wlr_xcursor_image *image = xcursor->images[0]; wlr_cursor_set_image(input->cursor, image->buffer, image->width, diff --git a/types/wlr_output.c b/types/wlr_output.c index 3cdeecfe..3804f2e3 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -241,13 +241,15 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { struct wlr_texture *texture = cursor->texture; struct wlr_renderer *renderer = cursor->renderer; if (cursor->surface != NULL) { + // Some clients commit a cursor surface with a NULL buffer to hide it. + if (!wlr_surface_has_buffer(cursor->surface)) { + return; + } texture = cursor->surface->texture; renderer = cursor->surface->renderer; } - // We check texture->valid because some clients set a cursor surface - // with a NULL buffer to hide it - if (renderer && texture && texture->valid) { + if (texture != NULL && renderer != NULL) { glViewport(0, 0, cursor->output->width, cursor->output->height); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -- cgit v1.2.3