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:
parent
de1ed2e73b
commit
30d61d89c1
|
@ -135,7 +135,9 @@ nodist_libweston_la_SOURCES = \
|
|||
protocol/viewporter-protocol.c \
|
||||
protocol/viewporter-server-protocol.h \
|
||||
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)
|
||||
|
||||
|
|
|
@ -4703,6 +4703,9 @@ weston_compositor_create(struct wl_display *display, void *user_data)
|
|||
ec, bind_presentation))
|
||||
goto fail;
|
||||
|
||||
if (weston_input_init(ec) != 0)
|
||||
goto fail;
|
||||
|
||||
wl_list_init(&ec->view_list);
|
||||
wl_list_init(&ec->plane_list);
|
||||
wl_list_init(&ec->layer_list);
|
||||
|
|
|
@ -355,6 +355,7 @@ struct weston_pointer_client {
|
|||
struct wl_list link;
|
||||
struct wl_client *client;
|
||||
struct wl_list pointer_resources;
|
||||
struct wl_list relative_pointer_resources;
|
||||
};
|
||||
|
||||
struct weston_pointer {
|
||||
|
@ -1694,6 +1695,9 @@ weston_output_mode_switch_to_native(struct weston_output *output);
|
|||
int
|
||||
noop_renderer_init(struct weston_compositor *ec);
|
||||
|
||||
int
|
||||
weston_input_init(struct weston_compositor *compositor);
|
||||
|
||||
int
|
||||
backend_init(struct weston_compositor *c,
|
||||
struct weston_backend_config *config_base);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "shared/helpers.h"
|
||||
#include "shared/os-compatibility.h"
|
||||
#include "compositor.h"
|
||||
#include "protocol/relative-pointer-unstable-v1-server-protocol.h"
|
||||
|
||||
static void
|
||||
empty_region(pixman_region32_t *region)
|
||||
|
@ -56,6 +57,7 @@ weston_pointer_client_create(struct wl_client *client)
|
|||
|
||||
pointer_client->client = client;
|
||||
wl_list_init(&pointer_client->pointer_resources);
|
||||
wl_list_init(&pointer_client->relative_pointer_resources);
|
||||
|
||||
return pointer_client;
|
||||
}
|
||||
|
@ -69,7 +71,8 @@ weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
|
|||
static bool
|
||||
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 *
|
||||
|
@ -139,6 +142,49 @@ static void unbind_resource(struct wl_resource *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
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
weston_pointer_send_relative_motion(pointer, time, event);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1158,23 +1245,6 @@ weston_pointer_move_to(struct weston_pointer *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
|
||||
weston_pointer_move(struct weston_pointer *pointer,
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
WL_EXPORT int
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue