mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-11-22 06:59:44 -05:00
implement cursor and device geometry mapping
This commit is contained in:
parent
d0cf8d0d01
commit
0a97b68278
10 changed files with 186 additions and 5 deletions
|
|
@ -16,6 +16,7 @@ lib_wlr_types = static_library('wlr_types', files(
|
|||
'wlr_xdg_shell_v6.c',
|
||||
'wlr_wl_shell.c',
|
||||
'wlr_compositor.c',
|
||||
'wlr_geometry.c',
|
||||
),
|
||||
include_directories: wlr_inc,
|
||||
dependencies: [wayland_server, pixman, wlr_protos])
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ struct wlr_cursor_device {
|
|||
struct wlr_input_device *device;
|
||||
struct wl_list link;
|
||||
struct wlr_output *mapped_output;
|
||||
struct wlr_geometry *mapped_geometry;
|
||||
|
||||
struct wl_listener motion;
|
||||
struct wl_listener motion_absolute;
|
||||
|
|
@ -24,6 +25,7 @@ struct wlr_cursor_state {
|
|||
struct wlr_output_layout *layout;
|
||||
struct wlr_xcursor *xcursor;
|
||||
struct wlr_output *mapped_output;
|
||||
struct wlr_geometry *mapped_geometry;
|
||||
};
|
||||
|
||||
struct wlr_cursor *wlr_cursor_init() {
|
||||
|
|
@ -145,6 +147,25 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
|||
double x = cur->x + delta_x;
|
||||
double y = cur->y + delta_y;
|
||||
|
||||
// cursor geometry constraints
|
||||
if (cur->state->mapped_geometry) {
|
||||
int closest_x, closest_y;
|
||||
wlr_geometry_closest_boundary(cur->state->mapped_geometry, x, y,
|
||||
&closest_x, &closest_y, NULL);
|
||||
x = closest_x;
|
||||
y = closest_y;
|
||||
}
|
||||
|
||||
// device constraints
|
||||
if (c_device->mapped_geometry) {
|
||||
int closest_x, closest_y;
|
||||
wlr_geometry_closest_boundary(c_device->mapped_geometry, x, y,
|
||||
&closest_x, &closest_y, NULL);
|
||||
x = closest_x;
|
||||
y = closest_y;
|
||||
}
|
||||
|
||||
// layout constraints
|
||||
struct wlr_output *output;
|
||||
output = wlr_output_layout_output_at(cur->state->layout, x, y);
|
||||
|
||||
|
|
@ -271,3 +292,17 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur,
|
|||
|
||||
c_device->mapped_output = output;
|
||||
}
|
||||
|
||||
void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_geometry *geo) {
|
||||
cur->state->mapped_geometry = geo;
|
||||
}
|
||||
|
||||
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
|
||||
struct wlr_input_device *dev, struct wlr_geometry *geo) {
|
||||
struct wlr_cursor_device *c_device = get_cursor_device(cur, dev);
|
||||
if (!c_device) {
|
||||
wlr_log(L_ERROR, "Cannot map device \"%s\" to geometry (not found in this cursor)", dev->name);
|
||||
return;
|
||||
}
|
||||
c_device->mapped_geometry = geo;
|
||||
}
|
||||
|
|
|
|||
36
types/wlr_geometry.c
Normal file
36
types/wlr_geometry.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <wlr/types/wlr_geometry.h>
|
||||
|
||||
static double get_distance(double x1, double y1, double x2, double y2) {
|
||||
double distance;
|
||||
distance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||
return distance;
|
||||
}
|
||||
|
||||
void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y,
|
||||
int *dest_x, int *dest_y, double *distance) {
|
||||
// find the closest x point
|
||||
if (x < geo->x) {
|
||||
*dest_x = geo->x;
|
||||
} else if (x > geo->x + geo->width) {
|
||||
*dest_x = geo->x + geo->width;
|
||||
} else {
|
||||
*dest_x = x;
|
||||
}
|
||||
|
||||
// find closest y point
|
||||
if (y < geo->y) {
|
||||
*dest_y = geo->y;
|
||||
} else if (y > geo->y + geo->height) {
|
||||
*dest_y = geo->y + geo->height;
|
||||
} else {
|
||||
*dest_y = y;
|
||||
}
|
||||
|
||||
// calculate distance
|
||||
if (distance) {
|
||||
*distance = get_distance(*dest_x, *dest_y, x, y);
|
||||
}
|
||||
}
|
||||
|
|
@ -149,6 +149,7 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout,
|
|||
wlr_output_effective_resolution(l_output->output, &width, &height);
|
||||
|
||||
// find the closest x point
|
||||
// TODO use wlr_geometry_closest_boundary
|
||||
if (x < l_output->x) {
|
||||
output_x = l_output->x;
|
||||
} else if (x > l_output->x + width) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue