implement touch up and touch down
This commit is contained in:
parent
c914697676
commit
5e06d61e42
|
@ -58,12 +58,20 @@ struct touch_point {
|
||||||
double x, y;
|
double x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void warp_to_touch(struct sample_state *sample) {
|
static void warp_to_touch(struct sample_state *sample, struct wlr_input_device *dev) {
|
||||||
wlr_log(L_DEBUG, "TODO: warp to touch");
|
if (sample->touch_points->length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double x = 0, y = 0;
|
||||||
for (size_t i = 0; i < sample->touch_points->length; ++i) {
|
for (size_t i = 0; i < sample->touch_points->length; ++i) {
|
||||||
struct touch_point *point = sample->touch_points->items[i];
|
struct touch_point *point = sample->touch_points->items[i];
|
||||||
wlr_log(L_DEBUG, "have point x=%f,y=%f", point->x, point->y);
|
x += point->x;
|
||||||
|
y += point->y;
|
||||||
}
|
}
|
||||||
|
x /= sample->touch_points->length;
|
||||||
|
y /= sample->touch_points->length;
|
||||||
|
wlr_cursor_warp_absolute(sample->cursor, dev, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_output_frame(struct output_state *output, struct timespec *ts) {
|
static void handle_output_frame(struct output_state *output, struct timespec *ts) {
|
||||||
|
@ -248,7 +256,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warp_to_touch(sample);
|
warp_to_touch(sample, event->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_touch_down(struct wl_listener *listener, void *data) {
|
static void handle_touch_down(struct wl_listener *listener, void *data) {
|
||||||
|
@ -262,7 +270,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
|
||||||
free(point);
|
free(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
warp_to_touch(sample);
|
warp_to_touch(sample, event->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
||||||
|
@ -277,7 +285,7 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warp_to_touch(sample);
|
warp_to_touch(sample, event->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
@ -46,6 +46,9 @@ void wlr_cursor_set_xcursor(struct wlr_cursor *cur, struct wlr_xcursor *xcur);
|
||||||
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
double x, double y);
|
double x, double y);
|
||||||
|
|
||||||
|
void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
|
||||||
|
struct wlr_input_device *dev, double x_mm, double y_mm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the cursor in the direction of the given x and y coordinates.
|
* Move the cursor in the direction of the given x and y coordinates.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,4 +15,6 @@ bool wlr_geometry_intersection(struct wlr_geometry *geo_a,
|
||||||
|
|
||||||
bool wlr_geometry_contains_point(struct wlr_geometry *geo, int x, int y);
|
bool wlr_geometry_contains_point(struct wlr_geometry *geo, int x, int y);
|
||||||
|
|
||||||
|
bool wlr_geometry_empty(struct wlr_geometry *geo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,14 +4,20 @@
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct wlr_output_layout_state;
|
||||||
|
|
||||||
struct wlr_output_layout {
|
struct wlr_output_layout {
|
||||||
struct wl_list outputs;
|
struct wl_list outputs;
|
||||||
|
struct wlr_output_layout_state *state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wlr_output_layout_output_state;
|
||||||
|
|
||||||
struct wlr_output_layout_output {
|
struct wlr_output_layout_output {
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
int x, y;
|
int x, y;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
struct wlr_output_layout_output_state *state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_output_layout *wlr_output_layout_init();
|
struct wlr_output_layout *wlr_output_layout_init();
|
||||||
|
@ -55,4 +61,11 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout,
|
||||||
struct wlr_output *reference, double x, double y, double *dest_x,
|
struct wlr_output *reference, double x, double y, double *dest_x,
|
||||||
double *dest_y);
|
double *dest_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the geometry of the layout for the given reference output. If `reference`
|
||||||
|
* is NULL, the geometry will be for the extents of the entire layout.
|
||||||
|
*/
|
||||||
|
struct wlr_geometry *wlr_output_layout_get_geometry(
|
||||||
|
struct wlr_output_layout *layout, struct wlr_output *reference);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
@ -95,6 +96,29 @@ static struct wlr_cursor_device *get_cursor_device(struct wlr_cursor *cur,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wlr_cursor_warp_unchecked(struct wlr_cursor *cur, double x, double y) {
|
||||||
|
int hotspot_x = 0;
|
||||||
|
int hotspot_y = 0;
|
||||||
|
|
||||||
|
if (cur->state->xcursor && cur->state->xcursor->image_count > 0) {
|
||||||
|
struct wlr_xcursor_image *image = cur->state->xcursor->images[0];
|
||||||
|
hotspot_x = image->hotspot_x;
|
||||||
|
hotspot_y = image->hotspot_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct wlr_output_layout_output *l_output;
|
||||||
|
wl_list_for_each(l_output, &cur->state->layout->outputs, link) {
|
||||||
|
double output_x = x;
|
||||||
|
double output_y = y;
|
||||||
|
|
||||||
|
wlr_output_layout_output_coords(cur->state->layout,
|
||||||
|
l_output->output, &output_x, &output_y);
|
||||||
|
wlr_output_move_cursor(l_output->output, output_x - hotspot_x,
|
||||||
|
output_y - hotspot_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
double x, double y) {
|
double x, double y) {
|
||||||
assert(cur->state->layout);
|
assert(cur->state->layout);
|
||||||
|
@ -120,30 +144,61 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hotspot_x = 0;
|
wlr_cursor_warp_unchecked(cur, x, y);
|
||||||
int hotspot_y = 0;
|
|
||||||
|
|
||||||
if (cur->state->xcursor && cur->state->xcursor->image_count > 0) {
|
|
||||||
struct wlr_xcursor_image *image = cur->state->xcursor->images[0];
|
|
||||||
hotspot_x = image->hotspot_x;
|
|
||||||
hotspot_y = image->hotspot_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct wlr_output_layout_output *l_output;
|
|
||||||
wl_list_for_each(l_output, &cur->state->layout->outputs, link) {
|
|
||||||
double output_x = x;
|
|
||||||
double output_y = y;
|
|
||||||
|
|
||||||
wlr_output_layout_output_coords(cur->state->layout,
|
|
||||||
l_output->output, &output_x, &output_y);
|
|
||||||
wlr_output_move_cursor(l_output->output, output_x - hotspot_x,
|
|
||||||
output_y - hotspot_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
|
||||||
|
struct wlr_input_device *dev, double x_mm, double y_mm) {
|
||||||
|
// convert from absolute to global coordinates
|
||||||
|
assert(cur->state->layout);
|
||||||
|
struct wlr_output *mapped_output = NULL;
|
||||||
|
struct wlr_cursor_device *c_device = get_cursor_device(cur, dev);
|
||||||
|
|
||||||
|
if (c_device && c_device->mapped_output) {
|
||||||
|
mapped_output = c_device->mapped_output;
|
||||||
|
} else {
|
||||||
|
mapped_output = cur->state->mapped_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_geometry *constraints = calloc(1, sizeof(struct wlr_geometry));
|
||||||
|
// XXX how do we express infinite regions?
|
||||||
|
constraints->x = INT_MIN / 2;
|
||||||
|
constraints->y = INT_MIN / 2;
|
||||||
|
constraints->width = INT_MAX;
|
||||||
|
constraints->height = INT_MAX;
|
||||||
|
|
||||||
|
if (cur->state->mapped_geometry) {
|
||||||
|
wlr_geometry_intersection(cur->state->mapped_geometry, constraints,
|
||||||
|
&constraints);
|
||||||
|
}
|
||||||
|
if (c_device->mapped_geometry) {
|
||||||
|
wlr_geometry_intersection(c_device->mapped_geometry, constraints,
|
||||||
|
&constraints);
|
||||||
|
}
|
||||||
|
struct wlr_geometry *geo;
|
||||||
|
if (mapped_output) {
|
||||||
|
geo = wlr_output_layout_get_geometry(cur->state->layout, mapped_output);
|
||||||
|
wlr_geometry_intersection(geo, constraints, &constraints);
|
||||||
|
}
|
||||||
|
geo = wlr_output_layout_get_geometry(cur->state->layout, NULL);
|
||||||
|
wlr_geometry_intersection(geo, constraints, &constraints);
|
||||||
|
|
||||||
|
if (wlr_geometry_empty(constraints)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
double x = constraints->width * x_mm + constraints->x;
|
||||||
|
double y = constraints->height * y_mm + constraints->y;
|
||||||
|
|
||||||
|
wlr_cursor_warp_unchecked(cur, x, y);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (constraints) {
|
||||||
|
free(constraints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
double delta_x, double delta_y) {
|
double delta_x, double delta_y) {
|
||||||
assert(cur->state->layout);
|
assert(cur->state->layout);
|
||||||
|
@ -195,10 +250,9 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_cursor_warp(cur, dev, x, y)) {
|
wlr_cursor_warp_unchecked(cur, x, y);
|
||||||
cur->x = x;
|
cur->x = x;
|
||||||
cur->y = y;
|
cur->y = y;
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (constraints) {
|
if (constraints) {
|
||||||
|
|
|
@ -45,8 +45,8 @@ void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y,
|
||||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool wlr_geometry_empty(struct wlr_geometry *geo) {
|
bool wlr_geometry_empty(struct wlr_geometry *geo) {
|
||||||
return geo == NULL || geo->width < 0 || geo->height < 0;
|
return geo == NULL || geo->width <= 0 || geo->height <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_geometry_intersection(struct wlr_geometry *geo_a,
|
bool wlr_geometry_intersection(struct wlr_geometry *geo_a,
|
||||||
|
@ -55,20 +55,12 @@ bool wlr_geometry_intersection(struct wlr_geometry *geo_a,
|
||||||
bool a_empty = wlr_geometry_empty(geo_a);
|
bool a_empty = wlr_geometry_empty(geo_a);
|
||||||
bool b_empty = wlr_geometry_empty(geo_b);
|
bool b_empty = wlr_geometry_empty(geo_b);
|
||||||
|
|
||||||
if (a_empty && b_empty) {
|
if (a_empty || b_empty) {
|
||||||
|
dest->x = 0;
|
||||||
|
dest->y = 0;
|
||||||
|
dest->width = -100;
|
||||||
|
dest->height = -100;
|
||||||
return false;
|
return false;
|
||||||
} else if (a_empty) {
|
|
||||||
dest->x = geo_b->x;
|
|
||||||
dest->y = geo_b->y;
|
|
||||||
dest->height = geo_b->height;
|
|
||||||
dest->width = geo_b->width;
|
|
||||||
return true;
|
|
||||||
} else if (b_empty) {
|
|
||||||
dest->x = geo_a->x;
|
|
||||||
dest->y = geo_a->y;
|
|
||||||
dest->height = geo_a->height;
|
|
||||||
dest->width = geo_a->width;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int x1 = max(geo_a->x, geo_b->x);
|
int x1 = max(geo_a->x, geo_b->x);
|
||||||
|
|
|
@ -1,16 +1,35 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
|
#include <wlr/types/wlr_geometry.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
struct wlr_output_layout_state {
|
||||||
|
struct wlr_geometry *_geo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_output_layout_output_state {
|
||||||
|
struct wlr_geometry *_geo;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_output_layout *wlr_output_layout_init() {
|
struct wlr_output_layout *wlr_output_layout_init() {
|
||||||
struct wlr_output_layout *layout = calloc(1, sizeof(struct wlr_output_layout));
|
struct wlr_output_layout *layout = calloc(1, sizeof(struct wlr_output_layout));
|
||||||
|
layout->state = calloc(1, sizeof(struct wlr_output_layout_state));
|
||||||
|
layout->state->_geo = calloc(1, sizeof(struct wlr_geometry));
|
||||||
wl_list_init(&layout->outputs);
|
wl_list_init(&layout->outputs);
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wlr_output_layout_output_destroy(
|
||||||
|
struct wlr_output_layout_output *l_output) {
|
||||||
|
wl_list_remove(&l_output->link);
|
||||||
|
free(l_output->state->_geo);
|
||||||
|
free(l_output->state);
|
||||||
|
free(l_output);
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_output_layout_destroy(struct wlr_output_layout *layout) {
|
void wlr_output_layout_destroy(struct wlr_output_layout *layout) {
|
||||||
if (!layout) {
|
if (!layout) {
|
||||||
return;
|
return;
|
||||||
|
@ -18,20 +37,24 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) {
|
||||||
|
|
||||||
struct wlr_output_layout_output *_output, *temp = NULL;
|
struct wlr_output_layout_output *_output, *temp = NULL;
|
||||||
wl_list_for_each_safe(_output, temp, &layout->outputs, link) {
|
wl_list_for_each_safe(_output, temp, &layout->outputs, link) {
|
||||||
wl_list_remove(&_output->link);
|
wlr_output_layout_output_destroy(_output);
|
||||||
free(_output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(layout->state->_geo);
|
||||||
|
free(layout->state);
|
||||||
free(layout);
|
free(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_output_layout_add(struct wlr_output_layout *layout,
|
void wlr_output_layout_add(struct wlr_output_layout *layout,
|
||||||
struct wlr_output *output, int x, int y) {
|
struct wlr_output *output, int x, int y) {
|
||||||
struct wlr_output_layout_output *layout_output = calloc(1, sizeof(struct wlr_output_layout_output));
|
struct wlr_output_layout_output *l_output;
|
||||||
layout_output->output = output;
|
l_output= calloc(1, sizeof(struct wlr_output_layout_output));
|
||||||
layout_output->x = x;
|
l_output->state = calloc(1, sizeof(struct wlr_output_layout_output_state));
|
||||||
layout_output->y = y;
|
l_output->state->_geo = calloc(1, sizeof(struct wlr_geometry));
|
||||||
wl_list_insert(&layout->outputs, &layout_output->link);
|
l_output->output = output;
|
||||||
|
l_output->x = x;
|
||||||
|
l_output->y = y;
|
||||||
|
wl_list_insert(&layout->outputs, &l_output->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_layout_output *wlr_output_layout_get(
|
struct wlr_output_layout_output *wlr_output_layout_get(
|
||||||
|
@ -104,11 +127,10 @@ void wlr_output_layout_move(struct wlr_output_layout *layout,
|
||||||
|
|
||||||
void wlr_output_layout_remove(struct wlr_output_layout *layout,
|
void wlr_output_layout_remove(struct wlr_output_layout *layout,
|
||||||
struct wlr_output *output) {
|
struct wlr_output *output) {
|
||||||
struct wlr_output_layout_output *layout_output =
|
struct wlr_output_layout_output *l_output;
|
||||||
wlr_output_layout_get(layout, output);
|
l_output= wlr_output_layout_get(layout, output);
|
||||||
if (layout_output) {
|
if (l_output) {
|
||||||
wl_list_remove(&layout_output->link);
|
wlr_output_layout_output_destroy(l_output);
|
||||||
free(layout_output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,3 +201,46 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout,
|
||||||
*dest_x = min_x;
|
*dest_x = min_x;
|
||||||
*dest_y = min_y;
|
*dest_y = min_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_geometry *wlr_output_layout_get_geometry(
|
||||||
|
struct wlr_output_layout *layout, struct wlr_output *reference) {
|
||||||
|
struct wlr_output_layout_output *l_output;
|
||||||
|
if (reference) {
|
||||||
|
// output extents
|
||||||
|
l_output= wlr_output_layout_get(layout, reference);
|
||||||
|
l_output->state->_geo->x = l_output->x;
|
||||||
|
l_output->state->_geo->y = l_output->y;
|
||||||
|
wlr_output_effective_resolution(reference,
|
||||||
|
&l_output->state->_geo->width, &l_output->state->_geo->height);
|
||||||
|
return l_output->state->_geo;
|
||||||
|
} else {
|
||||||
|
// layout extents
|
||||||
|
int min_x = INT_MAX, min_y = INT_MAX;
|
||||||
|
int max_x = INT_MIN, max_y = INT_MIN;
|
||||||
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
||||||
|
int width, height;
|
||||||
|
wlr_output_effective_resolution(l_output->output, &width, &height);
|
||||||
|
if (l_output->x < min_x) {
|
||||||
|
min_x = l_output->x;
|
||||||
|
}
|
||||||
|
if (l_output->y < min_y) {
|
||||||
|
min_y = l_output->y;
|
||||||
|
}
|
||||||
|
if (l_output->x + width > max_x) {
|
||||||
|
max_x = l_output->x + width;
|
||||||
|
}
|
||||||
|
if (l_output->y + height > max_y) {
|
||||||
|
max_y = l_output->y + height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->state->_geo->x = min_x;
|
||||||
|
layout->state->_geo->y = min_y;
|
||||||
|
layout->state->_geo->width = max_x - min_x;
|
||||||
|
layout->state->_geo->height = max_y - min_y;
|
||||||
|
|
||||||
|
return layout->state->_geo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not reached
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue