diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 6cbb0535..cfaaae21 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -558,39 +558,17 @@ 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; - } + struct wlr_box hotspot_box = { + .width = plane->surf.width, + .height = plane->surf.height, + .x = hotspot_x, + .y = hotspot_y, + }; + struct wlr_box transformed_hotspot_box; + wlr_output_transform_apply_to_box(output->transform, + &hotspot_box, &transformed_hotspot_box); + plane->cursor_hotspot_x = transformed_hotspot_box.x; + plane->cursor_hotspot_y = transformed_hotspot_box.y; if (!update_pixels) { // Only update the cursor hotspot diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 0d8e5b1f..deed215e 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -42,21 +42,30 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { struct wlr_input_device *dev = data; assert(dev && dev->pointer); - struct wlr_wl_pointer *wlr_wl_pointer = (struct wlr_wl_pointer *)dev->pointer; + struct wlr_wl_pointer *wlr_wl_pointer = + (struct wlr_wl_pointer *)dev->pointer; if (!wlr_wl_pointer->current_output) { wlr_log(L_ERROR, "pointer motion event without current output"); return; } - int width, height; + + struct wlr_box box; wl_egl_window_get_attached_size(wlr_wl_pointer->current_output->egl_window, - &width, &height); + &box.width, &box.height); + box.x = wl_fixed_to_int(surface_x); + box.y = wl_fixed_to_int(surface_y); + struct wlr_box transformed; + wlr_output_transform_apply_to_box( + wlr_wl_pointer->current_output->wlr_output.transform, &box, + &transformed); + struct wlr_event_pointer_motion_absolute wlr_event; wlr_event.device = dev; wlr_event.time_msec = time; - wlr_event.width_mm = width; - wlr_event.height_mm = height; - wlr_event.x_mm = wl_fixed_to_double(surface_x); - wlr_event.y_mm = wl_fixed_to_double(surface_y); + wlr_event.width_mm = transformed.width; + wlr_event.height_mm = transformed.height; + wlr_event.x_mm = transformed.x; + wlr_event.y_mm = transformed.y; wl_signal_emit(&dev->pointer->events.motion_absolute, &wlr_event); } diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index d365e8f5..1f6c60eb 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -2,6 +2,7 @@ #define WLR_INTERFACES_WLR_OUTPUT_H #include +#include #include #include @@ -31,4 +32,7 @@ struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output, struct wl_display *display); void wlr_output_destroy_global(struct wlr_output *wlr_output); +void wlr_output_transform_apply_to_box(enum wl_output_transform transform, + struct wlr_box *box, struct wlr_box *dest); + #endif diff --git a/types/wlr_output.c b/types/wlr_output.c index 44d24ae3..15b2f402 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -500,3 +500,57 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) { wl_list_remove(&cursor->link); free(cursor); } + +void wlr_output_transform_apply_to_box(enum wl_output_transform transform, + struct wlr_box *box, struct wlr_box *dest) { + switch (transform) { + case WL_OUTPUT_TRANSFORM_NORMAL: + case WL_OUTPUT_TRANSFORM_180: + case WL_OUTPUT_TRANSFORM_FLIPPED: + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + dest->width = box->width; + dest->height = box->height; + break; + case WL_OUTPUT_TRANSFORM_90: + case WL_OUTPUT_TRANSFORM_270: + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + dest->width = box->height; + dest->height = box->width; + break; + } + + switch (transform) { + case WL_OUTPUT_TRANSFORM_NORMAL: + dest->x = box->x; + dest->y = box->y; + break; + case WL_OUTPUT_TRANSFORM_90: + dest->x = box->y; + dest->y = box->width - box->x; + break; + case WL_OUTPUT_TRANSFORM_180: + dest->x = box->width - box->x; + dest->y = box->height - box->y; + break; + case WL_OUTPUT_TRANSFORM_270: + dest->x = box->height - box->y; + dest->y = box->x; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED: + dest->x = box->width - box->x; + dest->y = box->y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + dest->x = box->y; + dest->y = box->x; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + dest->x = box->x; + dest->y = box->height - box->y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + dest->x = box->height - box->y; + dest->y = box->width - box->x; + } +}