#include "wayland-cursor.h"
#include "wayland-client-protocol.h"
+static struct wl_buffer* create_pointer_buffer(UwacSeat* seat, const void* src, size_t size)
+{
+ struct wl_buffer* buffer = NULL;
+ UwacReturnCode ret = UWAC_SUCCESS;
+ int fd;
+ void* data;
+ struct wl_shm_pool* pool;
+
+ fd = uwac_create_anonymous_file(size);
+
+ if (fd < 0)
+ return buffer;
+
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if (data == MAP_FAILED)
+ {
+ ret = UWAC_ERROR_NOMEMORY;
+ goto error_mmap;
+ }
+ memcpy(data, src, size);
+
+ pool = wl_shm_create_pool(seat->display->shm, fd, size);
+
+ if (!pool)
+ {
+ munmap(data, size);
+ ret = UWAC_ERROR_NOMEMORY;
+ goto error_mmap;
+ }
+
+ buffer = wl_shm_pool_create_buffer(pool, 0,
+ seat->pointer_image->width,
+ seat->pointer_image->height,
+ seat->pointer_image->width * 4,
+ WL_SHM_FORMAT_ARGB8888);
+ wl_shm_pool_destroy(pool);
+
+error_mmap:
+ close(fd);
+ return buffer;
+}
+
static UwacReturnCode
set_cursor_image(UwacSeat* seat, uint32_t serial)
{
switch(seat->pointer_type) {
case 2: /* Custom poiner */
- if (!seat->pointer_buffer)
- return UWAC_SUCCESS;
image = seat->pointer_image;
- buffer = seat->pointer_buffer;
- seat->pointer_buffer = NULL;
+ buffer = create_pointer_buffer(seat, seat->pointer_data, seat->pointer_size);
+ if (!buffer)
+ return UWAC_ERROR_INTERNAL;
surface = seat->pointer_surface;
x = image->hotspot_x;
y = image->hotspot_y;
break;
}
- wl_pointer_set_cursor(seat->pointer,
- serial,
- surface,
- x, y);
-
if (surface) {
- wl_surface_attach(surface, buffer, 0, 0);
+ wl_surface_attach(surface, buffer, -x, -y);
wl_surface_damage(surface, 0, 0,
image->width, image->height);
wl_surface_commit(surface);
}
+ if (buffer) {
+ wl_buffer_destroy(buffer);
+ }
+
+ wl_pointer_set_cursor(seat->pointer,
+ serial,
+ surface,
+ x, y);
+
return UWAC_SUCCESS;
}
if (s->pointer_surface)
wl_surface_destroy(s->pointer_surface);
- if (s->pointer_buffer)
- wl_buffer_destroy(s->pointer_buffer);
-
free(s->pointer_image);
+ free(s->pointer_data);
wl_list_remove(&s->link);
free(s);
return UWAC_SUCCESS;
}
-UwacReturnCode create_pointer_buffer(UwacSeat* seat, const void* src, size_t size)
-{
- UwacReturnCode ret = UWAC_SUCCESS;
- UwacBuffer* newBuffers;
- int fd;
- void* data;
- struct wl_shm_pool* pool;
-
- if (!newBuffers)
- return UWAC_ERROR_NOMEMORY;
-
- fd = uwac_create_anonymous_file(size);
-
- if (fd < 0)
- {
- return UWAC_ERROR_INTERNAL;
- }
-
- data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-
- if (data == MAP_FAILED)
- {
- ret = UWAC_ERROR_NOMEMORY;
- goto error_mmap;
- }
- memcpy(data, src, size);
-
- pool = wl_shm_create_pool(seat->display->shm, fd, size * 2);
-
- if (!pool)
- {
- munmap(data, size);
- ret = UWAC_ERROR_NOMEMORY;
- goto error_mmap;
- }
-
- seat->pointer_buffer = wl_shm_pool_create_buffer(pool, size,
- seat->pointer_image->width,
- seat->pointer_image->height,
- seat->pointer_image->width * 4,
- WL_SHM_FORMAT_ARGB8888);
- wl_shm_pool_destroy(pool);
-
-error_mmap:
- close(fd);
- return ret;
-}
-
UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat, const void* data, size_t length,
size_t width, size_t height,
size_t hot_x, size_t hot_y)
if (!seat)
return UWAC_ERROR_CLOSED;
+ fprintf(stderr, "%s: %p\n", __func__, data);
+ fflush(stderr);
+
free(seat->pointer_image);
- if (seat->pointer_buffer)
- wl_buffer_destroy(seat->pointer_buffer);
seat->pointer_image = NULL;
- seat->pointer_buffer = NULL;
+
+ free(seat->pointer_data);
+ seat->pointer_data = NULL;
+ seat->pointer_size = 0;
/* There is a cursor provided */
if ((data != NULL) && (length != 0))
seat->pointer_image->hotspot_x = hot_x;
seat->pointer_image->hotspot_y = hot_y;
- create_pointer_buffer(seat, data, length);
+ free(seat->pointer_data);
+ seat->pointer_data = malloc(length);
+ memcpy(seat->pointer_data, data, length);
+ seat->pointer_size = length;
seat->pointer_type = 2;
}