Implement the relative pointer protocol
A wp_relative_pointer object is an extension to the wl_pointer interface only used for emitting relative pointer events. It will only emit events when the parent pointer has focus. To get a relative pointer object, use the get_relative_pointer request of the global wp_relative_pointer_manager object. The relative pointer protocol is currently an unstable protocol, so unstable protocol naming conventions has been applied. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
+3
-1
@@ -135,7 +135,9 @@ nodist_libweston_la_SOURCES = \
|
|||||||
protocol/viewporter-protocol.c \
|
protocol/viewporter-protocol.c \
|
||||||
protocol/viewporter-server-protocol.h \
|
protocol/viewporter-server-protocol.h \
|
||||||
protocol/linux-dmabuf-unstable-v1-protocol.c \
|
protocol/linux-dmabuf-unstable-v1-protocol.c \
|
||||||
protocol/linux-dmabuf-unstable-v1-server-protocol.h
|
protocol/linux-dmabuf-unstable-v1-server-protocol.h \
|
||||||
|
protocol/relative-pointer-unstable-v1-protocol.c \
|
||||||
|
protocol/relative-pointer-unstable-v1-server-protocol.h
|
||||||
|
|
||||||
BUILT_SOURCES += $(nodist_libweston_la_SOURCES)
|
BUILT_SOURCES += $(nodist_libweston_la_SOURCES)
|
||||||
|
|
||||||
|
|||||||
@@ -4703,6 +4703,9 @@ weston_compositor_create(struct wl_display *display, void *user_data)
|
|||||||
ec, bind_presentation))
|
ec, bind_presentation))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (weston_input_init(ec) != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
wl_list_init(&ec->view_list);
|
wl_list_init(&ec->view_list);
|
||||||
wl_list_init(&ec->plane_list);
|
wl_list_init(&ec->plane_list);
|
||||||
wl_list_init(&ec->layer_list);
|
wl_list_init(&ec->layer_list);
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ struct weston_pointer_client {
|
|||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_client *client;
|
struct wl_client *client;
|
||||||
struct wl_list pointer_resources;
|
struct wl_list pointer_resources;
|
||||||
|
struct wl_list relative_pointer_resources;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_pointer {
|
struct weston_pointer {
|
||||||
@@ -1694,6 +1695,9 @@ weston_output_mode_switch_to_native(struct weston_output *output);
|
|||||||
int
|
int
|
||||||
noop_renderer_init(struct weston_compositor *ec);
|
noop_renderer_init(struct weston_compositor *ec);
|
||||||
|
|
||||||
|
int
|
||||||
|
weston_input_init(struct weston_compositor *compositor);
|
||||||
|
|
||||||
int
|
int
|
||||||
backend_init(struct weston_compositor *c,
|
backend_init(struct weston_compositor *c,
|
||||||
struct weston_backend_config *config_base);
|
struct weston_backend_config *config_base);
|
||||||
|
|||||||
+169
-18
@@ -37,6 +37,7 @@
|
|||||||
#include "shared/helpers.h"
|
#include "shared/helpers.h"
|
||||||
#include "shared/os-compatibility.h"
|
#include "shared/os-compatibility.h"
|
||||||
#include "compositor.h"
|
#include "compositor.h"
|
||||||
|
#include "protocol/relative-pointer-unstable-v1-server-protocol.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
empty_region(pixman_region32_t *region)
|
empty_region(pixman_region32_t *region)
|
||||||
@@ -56,6 +57,7 @@ weston_pointer_client_create(struct wl_client *client)
|
|||||||
|
|
||||||
pointer_client->client = client;
|
pointer_client->client = client;
|
||||||
wl_list_init(&pointer_client->pointer_resources);
|
wl_list_init(&pointer_client->pointer_resources);
|
||||||
|
wl_list_init(&pointer_client->relative_pointer_resources);
|
||||||
|
|
||||||
return pointer_client;
|
return pointer_client;
|
||||||
}
|
}
|
||||||
@@ -69,7 +71,8 @@ weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
|
|||||||
static bool
|
static bool
|
||||||
weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
|
weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
|
||||||
{
|
{
|
||||||
return wl_list_empty(&pointer_client->pointer_resources);
|
return (wl_list_empty(&pointer_client->pointer_resources) &&
|
||||||
|
wl_list_empty(&pointer_client->relative_pointer_resources));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct weston_pointer_client *
|
static struct weston_pointer_client *
|
||||||
@@ -139,6 +142,49 @@ static void unbind_resource(struct wl_resource *resource)
|
|||||||
wl_list_remove(wl_resource_get_link(resource));
|
wl_list_remove(wl_resource_get_link(resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
weston_pointer_motion_to_abs(struct weston_pointer *pointer,
|
||||||
|
struct weston_pointer_motion_event *event,
|
||||||
|
wl_fixed_t *x, wl_fixed_t *y)
|
||||||
|
{
|
||||||
|
if (event->mask & WESTON_POINTER_MOTION_ABS) {
|
||||||
|
*x = wl_fixed_from_double(event->x);
|
||||||
|
*y = wl_fixed_from_double(event->y);
|
||||||
|
} else if (event->mask & WESTON_POINTER_MOTION_REL) {
|
||||||
|
*x = pointer->x + wl_fixed_from_double(event->dx);
|
||||||
|
*y = pointer->y + wl_fixed_from_double(event->dy);
|
||||||
|
} else {
|
||||||
|
assert(!"invalid motion event");
|
||||||
|
*x = *y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
weston_pointer_motion_to_rel(struct weston_pointer *pointer,
|
||||||
|
struct weston_pointer_motion_event *event,
|
||||||
|
double *dx, double *dy,
|
||||||
|
double *dx_unaccel, double *dy_unaccel)
|
||||||
|
{
|
||||||
|
if (event->mask & WESTON_POINTER_MOTION_REL &&
|
||||||
|
event->mask & WESTON_POINTER_MOTION_REL_UNACCEL) {
|
||||||
|
*dx = event->dx;
|
||||||
|
*dy = event->dy;
|
||||||
|
*dx_unaccel = event->dx_unaccel;
|
||||||
|
*dy_unaccel = event->dy_unaccel;
|
||||||
|
return true;
|
||||||
|
} else if (event->mask & WESTON_POINTER_MOTION_REL) {
|
||||||
|
*dx_unaccel = *dx = event->dx;
|
||||||
|
*dy_unaccel = *dy = event->dy;
|
||||||
|
return true;
|
||||||
|
} else if (event->mask & WESTON_POINTER_MOTION_REL_UNACCEL) {
|
||||||
|
*dx_unaccel = *dx = event->dx_unaccel;
|
||||||
|
*dy_unaccel = *dy = event->dy_unaccel;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
weston_seat_repick(struct weston_seat *seat)
|
weston_seat_repick(struct weston_seat *seat)
|
||||||
{
|
{
|
||||||
@@ -254,6 +300,45 @@ default_grab_pointer_focus(struct weston_pointer_grab *grab)
|
|||||||
weston_pointer_set_focus(pointer, view, sx, sy);
|
weston_pointer_set_focus(pointer, view, sx, sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
weston_pointer_send_relative_motion(struct weston_pointer *pointer,
|
||||||
|
uint32_t time,
|
||||||
|
struct weston_pointer_motion_event *event)
|
||||||
|
{
|
||||||
|
uint64_t time_usec;
|
||||||
|
double dx, dy, dx_unaccel, dy_unaccel;
|
||||||
|
wl_fixed_t dxf, dyf, dxf_unaccel, dyf_unaccel;
|
||||||
|
struct wl_list *resource_list;
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
if (!pointer->focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!weston_pointer_motion_to_rel(pointer, event,
|
||||||
|
&dx, &dy,
|
||||||
|
&dx_unaccel, &dy_unaccel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
resource_list = &pointer->focus_client->relative_pointer_resources;
|
||||||
|
time_usec = event->time_usec;
|
||||||
|
if (time_usec == 0)
|
||||||
|
time_usec = time * 1000ULL;
|
||||||
|
|
||||||
|
dxf = wl_fixed_from_double(dx);
|
||||||
|
dyf = wl_fixed_from_double(dy);
|
||||||
|
dxf_unaccel = wl_fixed_from_double(dx_unaccel);
|
||||||
|
dyf_unaccel = wl_fixed_from_double(dy_unaccel);
|
||||||
|
|
||||||
|
wl_resource_for_each(resource, resource_list) {
|
||||||
|
zwp_relative_pointer_v1_send_relative_motion(
|
||||||
|
resource,
|
||||||
|
(uint32_t) (time_usec >> 32),
|
||||||
|
(uint32_t) time_usec,
|
||||||
|
dxf, dyf,
|
||||||
|
dxf_unaccel, dyf_unaccel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
|
default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
|
||||||
struct weston_pointer_motion_event *event)
|
struct weston_pointer_motion_event *event)
|
||||||
@@ -281,6 +366,8 @@ default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
|
|||||||
pointer->sx, pointer->sy);
|
pointer->sx, pointer->sy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
weston_pointer_send_relative_motion(pointer, time, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1158,23 +1245,6 @@ weston_pointer_move_to(struct weston_pointer *pointer,
|
|||||||
wl_signal_emit(&pointer->motion_signal, pointer);
|
wl_signal_emit(&pointer->motion_signal, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
|
||||||
weston_pointer_motion_to_abs(struct weston_pointer *pointer,
|
|
||||||
struct weston_pointer_motion_event *event,
|
|
||||||
wl_fixed_t *x, wl_fixed_t *y)
|
|
||||||
{
|
|
||||||
if (event->mask & WESTON_POINTER_MOTION_ABS) {
|
|
||||||
*x = wl_fixed_from_double(event->x);
|
|
||||||
*y = wl_fixed_from_double(event->y);
|
|
||||||
} else if (event->mask & WESTON_POINTER_MOTION_REL) {
|
|
||||||
*x = pointer->x + wl_fixed_from_double(event->dx);
|
|
||||||
*y = pointer->y + wl_fixed_from_double(event->dy);
|
|
||||||
} else {
|
|
||||||
assert(!"invalid motion event");
|
|
||||||
*x = *y = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
weston_pointer_move(struct weston_pointer *pointer,
|
weston_pointer_move(struct weston_pointer *pointer,
|
||||||
struct weston_pointer_motion_event *event)
|
struct weston_pointer_motion_event *event)
|
||||||
@@ -2292,6 +2362,76 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
|||||||
wl_seat_send_name(resource, seat->seat_name);
|
wl_seat_send_name(resource, seat->seat_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
relative_pointer_destroy(struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = {
|
||||||
|
relative_pointer_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
relative_pointer_manager_destroy(struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
relative_pointer_manager_get_relative_pointer(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t id,
|
||||||
|
struct wl_resource *pointer_resource)
|
||||||
|
{
|
||||||
|
struct weston_pointer *pointer =
|
||||||
|
wl_resource_get_user_data(pointer_resource);
|
||||||
|
struct weston_pointer_client *pointer_client;
|
||||||
|
struct wl_resource *cr;
|
||||||
|
|
||||||
|
cr = wl_resource_create(client, &zwp_relative_pointer_v1_interface,
|
||||||
|
wl_resource_get_version(resource), id);
|
||||||
|
if (cr == NULL) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
|
||||||
|
if (!pointer_client) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_insert(&pointer_client->relative_pointer_resources,
|
||||||
|
wl_resource_get_link(cr));
|
||||||
|
wl_resource_set_implementation(cr, &relative_pointer_interface,
|
||||||
|
pointer,
|
||||||
|
unbind_pointer_client_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = {
|
||||||
|
relative_pointer_manager_destroy,
|
||||||
|
relative_pointer_manager_get_relative_pointer,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
bind_relative_pointer_manager(struct wl_client *client, void *data,
|
||||||
|
uint32_t version, uint32_t id)
|
||||||
|
{
|
||||||
|
struct weston_compositor *compositor = data;
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
resource = wl_resource_create(client,
|
||||||
|
&zwp_relative_pointer_manager_v1_interface,
|
||||||
|
1, id);
|
||||||
|
|
||||||
|
wl_resource_set_implementation(resource, &relative_pointer_manager,
|
||||||
|
compositor,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_XKBCOMMON
|
#ifdef ENABLE_XKBCOMMON
|
||||||
WL_EXPORT int
|
WL_EXPORT int
|
||||||
weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
|
weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
|
||||||
@@ -2799,3 +2939,14 @@ weston_seat_set_keyboard_focus(struct weston_seat *seat,
|
|||||||
inc_activate_serial(compositor);
|
inc_activate_serial(compositor);
|
||||||
wl_signal_emit(&compositor->activate_signal, surface);
|
wl_signal_emit(&compositor->activate_signal, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
weston_input_init(struct weston_compositor *compositor)
|
||||||
|
{
|
||||||
|
if (!wl_global_create(compositor->wl_display,
|
||||||
|
&zwp_relative_pointer_manager_v1_interface, 1,
|
||||||
|
compositor, bind_relative_pointer_manager))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user