pointer: Set cursor on pointer enter

qemu-extended-key-event
Andri Yngvason 2020-07-14 20:44:18 +00:00
parent 91c7a76ef3
commit a1d455b0c5
3 changed files with 69 additions and 2 deletions

View File

@ -18,6 +18,8 @@
#include <wayland-client.h> #include <wayland-client.h>
struct wl_cursor_theme;
enum pointer_button_mask { enum pointer_button_mask {
POINTER_BUTTON_LEFT = 1 << 0, POINTER_BUTTON_LEFT = 1 << 0,
POINTER_BUTTON_MIDDLE = 1 << 1, POINTER_BUTTON_MIDDLE = 1 << 1,
@ -29,8 +31,12 @@ struct pointer {
struct wl_pointer* wl_pointer; struct wl_pointer* wl_pointer;
struct wl_list link; struct wl_list link;
uint32_t serial;
enum pointer_button_mask pressed; enum pointer_button_mask pressed;
wl_fixed_t x, y; wl_fixed_t x, y;
struct wl_cursor_theme* cursor_theme;
struct wl_surface* cursor_surface;
}; };
struct pointer_collection { struct pointer_collection {

View File

@ -30,6 +30,7 @@ librt = cc.find_library('rt', required: false)
xkbcommon = dependency('xkbcommon') xkbcommon = dependency('xkbcommon')
pixman = dependency('pixman-1') pixman = dependency('pixman-1')
wayland_client = dependency('wayland-client') wayland_client = dependency('wayland-client')
wayland_cursor = dependency('wayland-cursor')
libvncclient = dependency('libvncclient') libvncclient = dependency('libvncclient')
aml_project = subproject('aml', required: false) aml_project = subproject('aml', required: false)
@ -60,6 +61,7 @@ dependencies = [
pixman, pixman,
aml, aml,
wayland_client, wayland_client,
wayland_cursor,
libvncclient, libvncclient,
client_protos, client_protos,
] ]

View File

@ -19,10 +19,30 @@
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <wayland-cursor.h>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#include "pointer.h" #include "pointer.h"
extern struct wl_shm* wl_shm;
extern struct wl_compositor* wl_compositor;
static struct wl_cursor_theme* pointer_load_cursor_theme(void)
{
const char* xcursor_theme = getenv("XCURSOR_THEME");
const char* xcursor_size_str = getenv("XCURSOR_SIZE");
unsigned long xcursor_size = 24;
if (xcursor_size_str) {
char* end;
unsigned long size = strtoul(xcursor_size_str, &end, 10);
if (!*end && *xcursor_size_str)
xcursor_size = size;
}
return wl_cursor_theme_load(xcursor_theme, xcursor_size, wl_shm);
}
struct pointer* pointer_new(struct wl_pointer* wl_pointer) struct pointer* pointer_new(struct wl_pointer* wl_pointer)
{ {
struct pointer* self = calloc(1, sizeof(*self)); struct pointer* self = calloc(1, sizeof(*self));
@ -30,6 +50,8 @@ struct pointer* pointer_new(struct wl_pointer* wl_pointer)
return NULL; return NULL;
self->wl_pointer = wl_pointer; self->wl_pointer = wl_pointer;
self->cursor_theme = pointer_load_cursor_theme();
self->cursor_surface = wl_compositor_create_surface(wl_compositor);
return self; return self;
} }
@ -37,6 +59,8 @@ struct pointer* pointer_new(struct wl_pointer* wl_pointer)
void pointer_destroy(struct pointer* self) void pointer_destroy(struct pointer* self)
{ {
wl_pointer_destroy(self->wl_pointer); wl_pointer_destroy(self->wl_pointer);
wl_cursor_theme_destroy(self->cursor_theme);
wl_surface_destroy(self->cursor_surface);
free(self); free(self);
} }
@ -75,17 +99,50 @@ struct pointer* pointer_collection_find_wl_pointer(
return NULL; return NULL;
} }
static void pointer_update_cursor(struct pointer* self)
{
struct wl_cursor* cursor = wl_cursor_theme_get_cursor(
self->cursor_theme, "left_ptr");
assert(cursor && cursor->image_count > 0);
struct wl_cursor_image* image = cursor->images[0];
// TODO Set buffer scale
wl_surface_attach(self->cursor_surface,
wl_cursor_image_get_buffer(image), 0, 0);
wl_pointer_set_cursor(self->wl_pointer, self->serial,
self->cursor_surface, image->hotspot_x,
image->hotspot_y);
wl_surface_damage_buffer(self->cursor_surface, 0, 0, image->width,
image->height);
wl_surface_commit(self->cursor_surface);
}
static void pointer_enter(void* data, struct wl_pointer* wl_pointer, static void pointer_enter(void* data, struct wl_pointer* wl_pointer,
uint32_t serial, struct wl_surface* surface, wl_fixed_t x, uint32_t serial, struct wl_surface* surface, wl_fixed_t x,
wl_fixed_t y) wl_fixed_t y)
{ {
// TODO struct pointer_collection* self = data;
struct pointer* pointer =
pointer_collection_find_wl_pointer(self, wl_pointer);
assert(pointer);
pointer->serial = serial;
pointer_update_cursor(pointer);
} }
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, static void pointer_leave(void* data, struct wl_pointer* wl_pointer,
uint32_t serial, struct wl_surface* surface) uint32_t serial, struct wl_surface* surface)
{ {
// TODO struct pointer_collection* self = data;
struct pointer* pointer =
pointer_collection_find_wl_pointer(self, wl_pointer);
assert(pointer);
pointer->serial = serial;
// Do nothing?
} }
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, static void pointer_motion(void* data, struct wl_pointer* wl_pointer,
@ -122,6 +179,8 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer,
pointer_collection_find_wl_pointer(self, wl_pointer); pointer_collection_find_wl_pointer(self, wl_pointer);
assert(pointer); assert(pointer);
pointer->serial = serial;
switch (button) { switch (button) {
case BTN_LEFT: case BTN_LEFT:
pointer_set_button_state(pointer, POINTER_BUTTON_LEFT, state); pointer_set_button_state(pointer, POINTER_BUTTON_LEFT, state);