weston-info: Add support for tablet-unstable-v2

This now prints each tablet seat with at least one tablet/pad/tool
attached.
For each tablet seat, each tablet, pad and tool is printed with as much
detail about the device as the protocol provides.
Seat info is stored to be referenced, because the protocol requires to
request a tablet_seat for each wl_seat and it's not guaranteed that the
tablet_v2_manager is available when seats are advertised.

Signed-off-by: Markus Ongyerth <wl@ongy.net>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
dev
Markus Ongyerth 7 years ago committed by Pekka Paalanen
parent e0dc5d47cb
commit ccdc81d609
  1. 14
      Makefile.am
  2. 845
      clients/weston-info.c

@ -825,11 +825,13 @@ weston_simple_im_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
weston_info_SOURCES = \ weston_info_SOURCES = \
clients/weston-info.c \ clients/weston-info.c \
shared/helpers.h shared/helpers.h
nodist_weston_info_SOURCES = \ nodist_weston_info_SOURCES = \
protocol/presentation-time-protocol.c \ protocol/presentation-time-protocol.c \
protocol/presentation-time-client-protocol.h \ protocol/presentation-time-client-protocol.h \
protocol/linux-dmabuf-unstable-v1-protocol.c \ protocol/linux-dmabuf-unstable-v1-protocol.c \
protocol/linux-dmabuf-unstable-v1-client-protocol.h protocol/linux-dmabuf-unstable-v1-client-protocol.h \
protocol/tablet-unstable-v2-protocol.c \
protocol/tablet-unstable-v2-client-protocol.h
weston_info_LDADD = $(WESTON_INFO_LIBS) libshared.la weston_info_LDADD = $(WESTON_INFO_LIBS) libshared.la
weston_info_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) weston_info_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
@ -889,6 +891,8 @@ BUILT_SOURCES += \
protocol/ivi-application-client-protocol.h \ protocol/ivi-application-client-protocol.h \
protocol/linux-dmabuf-unstable-v1-protocol.c \ protocol/linux-dmabuf-unstable-v1-protocol.c \
protocol/linux-dmabuf-unstable-v1-client-protocol.h \ protocol/linux-dmabuf-unstable-v1-client-protocol.h \
protocol/tablet-unstable-v2-protocol.c \
protocol/tablet-unstable-v2-client-protocol.h \
protocol/input-timestamps-unstable-v1-protocol.c \ protocol/input-timestamps-unstable-v1-protocol.c \
protocol/input-timestamps-unstable-v1-client-protocol.h protocol/input-timestamps-unstable-v1-client-protocol.h

@ -41,6 +41,7 @@
#include "shared/zalloc.h" #include "shared/zalloc.h"
#include "presentation-time-client-protocol.h" #include "presentation-time-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h" #include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "tablet-unstable-v2-client-protocol.h"
typedef void (*print_info_t)(void *info); typedef void (*print_info_t)(void *info);
typedef void (*destroy_info_t)(void *info); typedef void (*destroy_info_t)(void *info);
@ -113,6 +114,7 @@ struct linux_dmabuf_info {
struct seat_info { struct seat_info {
struct global_info global; struct global_info global;
struct wl_list global_link;
struct wl_seat *seat; struct wl_seat *seat;
struct weston_info *info; struct weston_info *info;
@ -123,6 +125,75 @@ struct seat_info {
int32_t repeat_delay; int32_t repeat_delay;
}; };
struct tablet_v2_path {
struct wl_list link;
char *path;
};
struct tablet_tool_info {
struct wl_list link;
struct zwp_tablet_tool_v2 *tool;
uint64_t hardware_serial;
uint64_t hardware_id_wacom;
enum zwp_tablet_tool_v2_type type;
bool has_tilt;
bool has_pressure;
bool has_distance;
bool has_rotation;
bool has_slider;
bool has_wheel;
};
struct tablet_pad_group_info {
struct wl_list link;
struct zwp_tablet_pad_group_v2 *group;
uint32_t modes;
size_t button_count;
int *buttons;
size_t strips;
size_t rings;
};
struct tablet_pad_info {
struct wl_list link;
struct zwp_tablet_pad_v2 *pad;
uint32_t buttons;
struct wl_list paths;
struct wl_list groups;
};
struct tablet_info {
struct wl_list link;
struct zwp_tablet_v2 *tablet;
char *name;
uint32_t vid, pid;
struct wl_list paths;
};
struct tablet_seat_info {
struct wl_list link;
struct zwp_tablet_seat_v2 *seat;
struct seat_info *seat_info;
struct wl_list tablets;
struct wl_list tools;
struct wl_list pads;
};
struct tablet_v2_info {
struct global_info global;
struct zwp_tablet_manager_v2 *manager;
struct weston_info *info;
struct wl_list seats;
};
struct presentation_info { struct presentation_info {
struct global_info global; struct global_info global;
struct wp_presentation *presentation; struct wp_presentation *presentation;
@ -136,6 +207,10 @@ struct weston_info {
struct wl_list infos; struct wl_list infos;
bool roundtrip_needed; bool roundtrip_needed;
/* required for tablet-unstable-v2 */
struct wl_list seats;
struct tablet_v2_info *tablet_info;
}; };
static void static void
@ -455,6 +530,767 @@ destroy_seat_info(void *data)
if (seat->name != NULL) if (seat->name != NULL)
free(seat->name); free(seat->name);
wl_list_remove(&seat->global_link);
}
static const char *
tablet_tool_type_to_str(enum zwp_tablet_tool_v2_type type)
{
switch (type) {
case ZWP_TABLET_TOOL_V2_TYPE_PEN:
return "pen";
case ZWP_TABLET_TOOL_V2_TYPE_ERASER:
return "eraser";
case ZWP_TABLET_TOOL_V2_TYPE_BRUSH:
return "brush";
case ZWP_TABLET_TOOL_V2_TYPE_PENCIL:
return "pencil";
case ZWP_TABLET_TOOL_V2_TYPE_AIRBRUSH:
return "airbrush";
case ZWP_TABLET_TOOL_V2_TYPE_FINGER:
return "finger";
case ZWP_TABLET_TOOL_V2_TYPE_MOUSE:
return "mouse";
case ZWP_TABLET_TOOL_V2_TYPE_LENS:
return "lens";
}
return "Unknown type";
}
static void
print_tablet_tool_info(const struct tablet_tool_info *info)
{
printf("\t\ttablet_tool: %s\n", tablet_tool_type_to_str(info->type));
if (info->hardware_serial) {
printf("\t\t\thardware serial: %lx\n", info->hardware_serial);
}
if (info->hardware_id_wacom) {
printf("\t\t\thardware wacom: %lx\n", info->hardware_id_wacom);
}
printf("\t\t\tcapabilities:");
if (info->has_tilt) {
printf(" tilt");
}
if (info->has_pressure) {
printf(" pressure");
}
if (info->has_distance) {
printf(" distance");
}
if (info->has_rotation) {
printf(" rotation");
}
if (info->has_slider) {
printf(" slider");
}
if (info->has_wheel) {
printf(" wheel");
}
printf("\n");
}
static void
destroy_tablet_tool_info(struct tablet_tool_info *info)
{
wl_list_remove(&info->link);
zwp_tablet_tool_v2_destroy(info->tool);
free(info);
}
static void
print_tablet_pad_group_info(const struct tablet_pad_group_info *info)
{
size_t i;
printf("\t\t\tgroup:\n");
printf("\t\t\t\tmodes: %u\n", info->modes);
printf("\t\t\t\tstrips: %zu\n", info->strips);
printf("\t\t\t\trings: %zu\n", info->rings);
printf("\t\t\t\tbuttons:");
for (i = 0; i < info->button_count; ++i) {
printf(" %d", info->buttons[i]);
}
printf("\n");
}
static void
destroy_tablet_pad_group_info(struct tablet_pad_group_info *info)
{
wl_list_remove(&info->link);
zwp_tablet_pad_group_v2_destroy(info->group);
if (info->buttons) {
free(info->buttons);
}
free(info);
}
static void
print_tablet_pad_info(const struct tablet_pad_info *info)
{
const struct tablet_v2_path *path;
const struct tablet_pad_group_info *group;
printf("\t\tpad:\n");
printf("\t\t\tbuttons: %u\n", info->buttons);
wl_list_for_each(path, &info->paths, link) {
printf("\t\t\tpath: %s\n", path->path);
}
wl_list_for_each(group, &info->groups, link) {
print_tablet_pad_group_info(group);
}
}
static void
destroy_tablet_pad_info(struct tablet_pad_info *info)
{
struct tablet_v2_path *path;
struct tablet_v2_path *tmp_path;
struct tablet_pad_group_info *group;
struct tablet_pad_group_info *tmp_group;
wl_list_remove(&info->link);
zwp_tablet_pad_v2_destroy(info->pad);
wl_list_for_each_safe(path, tmp_path, &info->paths, link) {
wl_list_remove(&path->link);
free(path->path);
free(path);
}
wl_list_for_each_safe(group, tmp_group, &info->groups, link) {
destroy_tablet_pad_group_info(group);
}
free(info);
}
static void
print_tablet_info(const struct tablet_info *info)
{
const struct tablet_v2_path *path;
printf("\t\ttablet: %s\n", info->name);
printf("\t\t\tvendor: %u\n", info->vid);
printf("\t\t\tproduct: %u\n", info->pid);
wl_list_for_each(path, &info->paths, link) {
printf("\t\t\tpath: %s\n", path->path);
}
}
static void
destroy_tablet_info(struct tablet_info *info)
{
struct tablet_v2_path *path;
struct tablet_v2_path *tmp;
wl_list_remove(&info->link);
zwp_tablet_v2_destroy(info->tablet);
if (info->name) {
free(info->name);
}
wl_list_for_each_safe(path, tmp, &info->paths, link) {
wl_list_remove(&path->link);
free(path->path);
free(path);
}
free(info);
}
static void
print_tablet_seat_info(const struct tablet_seat_info *info)
{
const struct tablet_info *tablet;
const struct tablet_pad_info *pad;
const struct tablet_tool_info *tool;
printf("\ttablet_seat: %s\n", info->seat_info->name);
wl_list_for_each(tablet, &info->tablets, link) {
print_tablet_info(tablet);
}
wl_list_for_each(pad, &info->pads, link) {
print_tablet_pad_info(pad);
}
wl_list_for_each(tool, &info->tools, link) {
print_tablet_tool_info(tool);
}
}
static void
destroy_tablet_seat_info(struct tablet_seat_info *info)
{
struct tablet_info *tablet;
struct tablet_info *tmp_tablet;
struct tablet_pad_info *pad;
struct tablet_pad_info *tmp_pad;
struct tablet_tool_info *tool;
struct tablet_tool_info *tmp_tool;
wl_list_remove(&info->link);
zwp_tablet_seat_v2_destroy(info->seat);
wl_list_for_each_safe(tablet, tmp_tablet, &info->tablets, link) {
destroy_tablet_info(tablet);
}
wl_list_for_each_safe(pad, tmp_pad, &info->pads, link) {
destroy_tablet_pad_info(pad);
}
wl_list_for_each_safe(tool, tmp_tool, &info->tools, link) {
destroy_tablet_tool_info(tool);
}
free(info);
}
static void
print_tablet_v2_info(void *data)
{
struct tablet_v2_info *info = data;
struct tablet_seat_info *seat;
print_global_info(data);
wl_list_for_each(seat, &info->seats, link) {
/* Skip tablet_seats without a tablet, they are irrelevant */
if (wl_list_empty(&seat->pads) &&
wl_list_empty(&seat->tablets) &&
wl_list_empty(&seat->tools)) {
continue;
}
print_tablet_seat_info(seat);
}
}
static void
destroy_tablet_v2_info(void *data)
{
struct tablet_v2_info *info = data;
struct tablet_seat_info *seat;
struct tablet_seat_info *tmp;
zwp_tablet_manager_v2_destroy(info->manager);
wl_list_for_each_safe(seat, tmp, &info->seats, link) {
destroy_tablet_seat_info(seat);
}
}
static void
handle_tablet_v2_tablet_tool_done(void *data, struct zwp_tablet_tool_v2 *tool)
{
/* don't bother waiting for this; there's no good reason a
* compositor will wait more than one roundtrip before sending
* these initial events. */
}
static void
handle_tablet_v2_tablet_tool_removed(void *data, struct zwp_tablet_tool_v2 *tool)
{
/* don't bother waiting for this; we never make any request either way. */
}
static void
handle_tablet_v2_tablet_tool_type(void *data, struct zwp_tablet_tool_v2 *tool,
uint32_t tool_type)
{
struct tablet_tool_info *info = data;
info->type = tool_type;
}
static void
handle_tablet_v2_tablet_tool_hardware_serial(void *data,
struct zwp_tablet_tool_v2 *tool,
uint32_t serial_hi,
uint32_t serial_lo)
{
struct tablet_tool_info *info = data;
info->hardware_serial = ((uint64_t) serial_hi) << 32 |
(uint64_t) serial_lo;
}
static void
handle_tablet_v2_tablet_tool_hardware_id_wacom(void *data,
struct zwp_tablet_tool_v2 *tool,
uint32_t id_hi, uint32_t id_lo)
{
struct tablet_tool_info *info = data;
info->hardware_id_wacom = ((uint64_t) id_hi) << 32 | (uint64_t) id_lo;
}
static void
handle_tablet_v2_tablet_tool_capability(void *data,
struct zwp_tablet_tool_v2 *tool,
uint32_t capability)
{
struct tablet_tool_info *info = data;
enum zwp_tablet_tool_v2_capability cap = capability;
switch(cap) {
case ZWP_TABLET_TOOL_V2_CAPABILITY_TILT:
info->has_tilt = true;
break;
case ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE:
info->has_pressure = true;
break;
case ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE:
info->has_distance = true;
break;
case ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION:
info->has_rotation = true;
break;
case ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER:
info->has_slider = true;
break;
case ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL:
info->has_wheel = true;
break;
}
}
static void
handle_tablet_v2_tablet_tool_proximity_in(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
uint32_t serial, struct zwp_tablet_v2 *tablet,
struct wl_surface *surface)
{
}
static void
handle_tablet_v2_tablet_tool_proximity_out(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2)
{
}
static void
handle_tablet_v2_tablet_tool_down(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
uint32_t serial)
{
}
static void
handle_tablet_v2_tablet_tool_up(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2)
{
}
static void
handle_tablet_v2_tablet_tool_motion(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
wl_fixed_t x,
wl_fixed_t y)
{
}
static void
handle_tablet_v2_tablet_tool_pressure(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
uint32_t pressure)
{
}
static void
handle_tablet_v2_tablet_tool_distance(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
uint32_t distance)
{
}
static void
handle_tablet_v2_tablet_tool_tilt(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
wl_fixed_t tilt_x,
wl_fixed_t tilt_y)
{
}
static void
handle_tablet_v2_tablet_tool_rotation(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
wl_fixed_t degrees)
{
}
static void
handle_tablet_v2_tablet_tool_slider(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
int32_t position)
{
}
static void
handle_tablet_v2_tablet_tool_wheel(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
wl_fixed_t degrees,
int32_t clicks)
{
}
static void
handle_tablet_v2_tablet_tool_button(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
uint32_t serial,
uint32_t button,
uint32_t state)
{
}
static void
handle_tablet_v2_tablet_tool_frame(void *data,
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2,
uint32_t time)
{
}
static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
.removed = handle_tablet_v2_tablet_tool_removed,
.done = handle_tablet_v2_tablet_tool_done,
.type = handle_tablet_v2_tablet_tool_type,
.hardware_serial = handle_tablet_v2_tablet_tool_hardware_serial,
.hardware_id_wacom = handle_tablet_v2_tablet_tool_hardware_id_wacom,
.capability = handle_tablet_v2_tablet_tool_capability,
.proximity_in = handle_tablet_v2_tablet_tool_proximity_in,
.proximity_out = handle_tablet_v2_tablet_tool_proximity_out,
.down = handle_tablet_v2_tablet_tool_down,
.up = handle_tablet_v2_tablet_tool_up,
.motion = handle_tablet_v2_tablet_tool_motion,
.pressure = handle_tablet_v2_tablet_tool_pressure,
.distance = handle_tablet_v2_tablet_tool_distance,
.tilt = handle_tablet_v2_tablet_tool_tilt,
.rotation = handle_tablet_v2_tablet_tool_rotation,
.slider = handle_tablet_v2_tablet_tool_slider,
.wheel = handle_tablet_v2_tablet_tool_wheel,
.button = handle_tablet_v2_tablet_tool_button,
.frame = handle_tablet_v2_tablet_tool_frame,
};
static void add_tablet_v2_tablet_tool_info(void *data,
struct zwp_tablet_seat_v2 *tablet_seat_v2,
struct zwp_tablet_tool_v2 *tool)
{
struct tablet_seat_info *tablet_seat = data;
struct tablet_tool_info *tool_info = xzalloc(sizeof *tool_info);
tool_info->tool = tool;
wl_list_insert(&tablet_seat->tools, &tool_info->link);
zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, tool_info);
}
static void
handle_tablet_v2_tablet_pad_group_mode_switch(void *data,
struct zwp_tablet_pad_group_v2 *zwp_tablet_pad_group_v2,
uint32_t time, uint32_t serial, uint32_t mode)
{
/* This shouldn't ever happen */
}
static void
handle_tablet_v2_tablet_pad_group_done(void *data,
struct zwp_tablet_pad_group_v2 *group)
{
/* don't bother waiting for this; there's no good reason a
* compositor will wait more than one roundtrip before sending
* these initial events. */
}
static void
handle_tablet_v2_tablet_pad_group_modes(void *data,
struct zwp_tablet_pad_group_v2 *group,
uint32_t modes)
{
struct tablet_pad_group_info *info = data;
info->modes = modes;
}
static void
handle_tablet_v2_tablet_pad_group_buttons(void *data,
struct zwp_tablet_pad_group_v2 *group,
struct wl_array *buttons)
{
struct tablet_pad_group_info *info = data;
info->button_count = buttons->size / sizeof(int);
info->buttons = xzalloc(buttons->size);
memcpy(info->buttons, buttons->data, buttons->size);
}
static void
handle_tablet_v2_tablet_pad_group_ring(void *data,
struct zwp_tablet_pad_group_v2 *group,
struct zwp_tablet_pad_ring_v2 *ring)
{
struct tablet_pad_group_info *info = data;
++info->rings;
zwp_tablet_pad_ring_v2_destroy(ring);
}
static void
handle_tablet_v2_tablet_pad_group_strip(void *data,
struct zwp_tablet_pad_group_v2 *group,
struct zwp_tablet_pad_strip_v2 *strip)
{
struct tablet_pad_group_info *info = data;
++info->strips;
zwp_tablet_pad_strip_v2_destroy(strip);
}
static const struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = {
.buttons = handle_tablet_v2_tablet_pad_group_buttons,
.modes = handle_tablet_v2_tablet_pad_group_modes,
.ring = handle_tablet_v2_tablet_pad_group_ring,
.strip = handle_tablet_v2_tablet_pad_group_strip,
.done = handle_tablet_v2_tablet_pad_group_done,
.mode_switch = handle_tablet_v2_tablet_pad_group_mode_switch,
};
static void
handle_tablet_v2_tablet_pad_group(void *data,
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
struct zwp_tablet_pad_group_v2 *pad_group)
{
struct tablet_pad_info *pad_info = data;
struct tablet_pad_group_info *group = xzalloc(sizeof *group);
wl_list_insert(&pad_info->groups, &group->link);
group->group = pad_group;
zwp_tablet_pad_group_v2_add_listener(pad_group,
&tablet_pad_group_listener, group);
}
static void
handle_tablet_v2_tablet_pad_path(void *data, struct zwp_tablet_pad_v2 *pad,
const char *path)
{
struct tablet_pad_info *pad_info = data;
struct tablet_v2_path *path_elem = xzalloc(sizeof *path_elem);
path_elem->path = xstrdup(path);
wl_list_insert(&pad_info->paths, &path_elem->link);
}
static void
handle_tablet_v2_tablet_pad_buttons(void *data, struct zwp_tablet_pad_v2 *pad,
uint32_t buttons)
{
struct tablet_pad_info *pad_info = data;
pad_info->buttons = buttons;
}
static void
handle_tablet_v2_tablet_pad_done(void *data, struct zwp_tablet_pad_v2 *pad)
{
/* don't bother waiting for this; there's no good reason a
* compositor will wait more than one roundtrip before sending
* these initial events. */
}
static void
handle_tablet_v2_tablet_pad_removed(void *data, struct zwp_tablet_pad_v2 *pad)
{
/* don't bother waiting for this; We never make any request that's not
* allowed to be issued either way. */
}
static void
handle_tablet_v2_tablet_pad_button(void *data, struct zwp_tablet_pad_v2 *pad,
uint32_t time, uint32_t button, uint32_t state)
{
/* we don't have a surface, so this can't ever happen */
}
static void
handle_tablet_v2_tablet_pad_enter(void *data, struct zwp_tablet_pad_v2 *pad,
uint32_t serial,
struct zwp_tablet_v2 *tablet,
struct wl_surface *surface)
{
/* we don't have a surface, so this can't ever happen */
}
static void
handle_tablet_v2_tablet_pad_leave(void *data, struct zwp_tablet_pad_v2 *pad,
uint32_t serial, struct wl_surface *surface)
{
/* we don't have a surface, so this can't ever happen */
}
static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
.group = handle_tablet_v2_tablet_pad_group,
.path = handle_tablet_v2_tablet_pad_path,
.buttons = handle_tablet_v2_tablet_pad_buttons,
.done = handle_tablet_v2_tablet_pad_done,
.removed = handle_tablet_v2_tablet_pad_removed,
.button = handle_tablet_v2_tablet_pad_button,
.enter = handle_tablet_v2_tablet_pad_enter,
.leave = handle_tablet_v2_tablet_pad_leave,
};
static void add_tablet_v2_tablet_pad_info(void *data,
struct zwp_tablet_seat_v2 *tablet_seat_v2,
struct zwp_tablet_pad_v2 *pad)
{
struct tablet_seat_info *tablet_seat = data;
struct tablet_pad_info *pad_info = xzalloc(sizeof *pad_info);
wl_list_init(&pad_info->paths);
wl_list_init(&pad_info->groups);
pad_info->pad = pad;
wl_list_insert(&tablet_seat->pads, &pad_info->link);
zwp_tablet_pad_v2_add_listener(pad, &tablet_pad_listener, pad_info);
}
static void
handle_tablet_v2_tablet_name(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
const char *name)
{
struct tablet_info *tablet_info = data;
tablet_info->name = xstrdup(name);
}
static void
handle_tablet_v2_tablet_path(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
const char *path)
{
struct tablet_info *tablet_info = data;
struct tablet_v2_path *path_elem = xzalloc(sizeof *path_elem);
path_elem->path = xstrdup(path);
wl_list_insert(&tablet_info->paths, &path_elem->link);
}
static void
handle_tablet_v2_tablet_id(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
uint32_t vid, uint32_t pid)
{
struct tablet_info *tablet_info = data;
tablet_info->vid = vid;
tablet_info->pid = pid;
}
static void
handle_tablet_v2_tablet_done(void *data, struct zwp_tablet_v2 *zwp_tablet_v2)
{
/* don't bother waiting for this; there's no good reason a
* compositor will wait more than one roundtrip before sending
* these initial events. */
}
static void
handle_tablet_v2_tablet_removed(void *data, struct zwp_tablet_v2 *zwp_tablet_v2)
{
/* don't bother waiting for this; We never make any request that's not
* allowed to be issued either way. */
}
static const struct zwp_tablet_v2_listener tablet_listener = {
.name = handle_tablet_v2_tablet_name,
.id = handle_tablet_v2_tablet_id,
.path = handle_tablet_v2_tablet_path,
.done = handle_tablet_v2_tablet_done,
.removed = handle_tablet_v2_tablet_removed
};
static void
add_tablet_v2_tablet_info(void *data, struct zwp_tablet_seat_v2 *tablet_seat_v2,
struct zwp_tablet_v2 *tablet)
{
struct tablet_seat_info *tablet_seat = data;
struct tablet_info *tablet_info = xzalloc(sizeof *tablet_info);
wl_list_init(&tablet_info->paths);
tablet_info->tablet = tablet;
wl_list_insert(&tablet_seat->tablets, &tablet_info->link);
zwp_tablet_v2_add_listener(tablet, &tablet_listener, tablet_info);
}
static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
.tablet_added = add_tablet_v2_tablet_info,
.pad_added = add_tablet_v2_tablet_pad_info,
.tool_added = add_tablet_v2_tablet_tool_info,
};
static void
add_tablet_seat_info(struct tablet_v2_info *tablet_info, struct seat_info *seat)
{
struct tablet_seat_info *tablet_seat = xzalloc(sizeof *tablet_seat);
wl_list_insert(&tablet_info->seats, &tablet_seat->link);
tablet_seat->seat = zwp_tablet_manager_v2_get_tablet_seat(
tablet_info->manager, seat->seat);
zwp_tablet_seat_v2_add_listener(tablet_seat->seat,
&tablet_seat_listener, tablet_seat);
wl_list_init(&tablet_seat->pads);
wl_list_init(&tablet_seat->tablets);
wl_list_init(&tablet_seat->tools);
tablet_seat->seat_info = seat;
tablet_info->info->roundtrip_needed = true;
}
static void
add_tablet_v2_info(struct weston_info *info, uint32_t id, uint32_t version)
{
struct seat_info *seat;
struct tablet_v2_info *tablet = xzalloc(sizeof *tablet);
wl_list_init(&tablet->seats);
tablet->info = info;
init_global_info(info, &tablet->global, id,
zwp_tablet_manager_v2_interface.name, version);
tablet->global.print = print_tablet_v2_info;
tablet->global.destroy = destroy_tablet_v2_info;
tablet->manager = wl_registry_bind(info->registry,
id, &zwp_tablet_manager_v2_interface, 1);
wl_list_for_each(seat, &info->seats, global_link) {
add_tablet_seat_info(tablet, seat);
}
info->tablet_info = tablet;
} }
static void static void
@ -477,6 +1313,11 @@ add_seat_info(struct weston_info *info, uint32_t id, uint32_t version)
seat->repeat_rate = seat->repeat_delay = -1; seat->repeat_rate = seat->repeat_delay = -1;
info->roundtrip_needed = true; info->roundtrip_needed = true;
wl_list_insert(&info->seats, &seat->global_link);
if (info->tablet_info) {
add_tablet_seat_info(info->tablet_info, seat);
}
} }
static void static void
@ -784,6 +1625,8 @@ global_handler(void *data, struct wl_registry *registry, uint32_t id,
add_output_info(info, id, version); add_output_info(info, id, version);
else if (!strcmp(interface, wp_presentation_interface.name)) else if (!strcmp(interface, wp_presentation_interface.name))
add_presentation_info(info, id, version); add_presentation_info(info, id, version);
else if (!strcmp(interface, zwp_tablet_manager_v2_interface.name))
add_tablet_v2_info(info, id, version);
else else
add_global_info(info, id, interface, version); add_global_info(info, id, interface, version);
} }
@ -837,7 +1680,9 @@ main(int argc, char **argv)
return -1; return -1;
} }
info.tablet_info = NULL;
wl_list_init(&info.infos); wl_list_init(&info.infos);
wl_list_init(&info.seats);
info.registry = wl_display_get_registry(info.display); info.registry = wl_display_get_registry(info.display);
wl_registry_add_listener(info.registry, &registry_listener, &info); wl_registry_add_listener(info.registry, &registry_listener, &info);

Loading…
Cancel
Save