Merge pull request #5221 from akallabeth/wayland_mouse_cursor
Added wayland mouse cursor
This commit is contained in:
commit
72ad4af356
@ -27,6 +27,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
wlfreerdp.h
|
||||
wlf_disp.c
|
||||
wlf_disp.h
|
||||
wlf_pointer.c
|
||||
wlf_pointer.h
|
||||
wlf_input.c
|
||||
wlf_input.h
|
||||
wlf_cliprdr.c
|
||||
|
136
client/Wayland/wlf_pointer.c
Normal file
136
client/Wayland/wlf_pointer.c
Normal file
@ -0,0 +1,136 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Wayland Mouse Pointer
|
||||
*
|
||||
* Copyright 2019 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2019 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "wlf_pointer.h"
|
||||
#include "wlfreerdp.h"
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("wayland.pointer")
|
||||
|
||||
struct wlf_pointer
|
||||
{
|
||||
rdpPointer pointer;
|
||||
size_t size;
|
||||
void* data;
|
||||
};
|
||||
typedef struct wlf_pointer wlfPointer;
|
||||
|
||||
static BOOL wlf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
wlfPointer* ptr = (wlfPointer*)pointer;
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
|
||||
ptr->size = pointer->width * pointer->height * 4;
|
||||
ptr->data = _aligned_malloc(ptr->size, 16);
|
||||
if (!ptr->data)
|
||||
return FALSE;
|
||||
|
||||
if (!freerdp_image_copy_from_pointer_data(
|
||||
ptr->data, PIXEL_FORMAT_RGBA32,
|
||||
0, 0, 0, pointer->width, pointer->height,
|
||||
pointer->xorMaskData, pointer->lengthXorMask,
|
||||
pointer->andMaskData, pointer->lengthAndMask,
|
||||
pointer->xorBpp, &context->gdi->palette))
|
||||
{
|
||||
_aligned_free(ptr->data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wlf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
wlfPointer* ptr = (wlfPointer*)pointer;
|
||||
WINPR_UNUSED(context);
|
||||
if (ptr)
|
||||
_aligned_free(ptr->data);
|
||||
}
|
||||
|
||||
static BOOL wlf_Pointer_Set(rdpContext* context,
|
||||
const rdpPointer* pointer)
|
||||
{
|
||||
wlfContext* wlf = (wlfContext*)context;
|
||||
wlfPointer* ptr = (wlfPointer*)pointer;
|
||||
|
||||
if (!wlf || !wlf->seat)
|
||||
return FALSE;
|
||||
|
||||
// TODO: Scale according to SmartSizing
|
||||
if (UwacSeatSetMouseCursor(wlf->seat, ptr->data, ptr->size, pointer->width, pointer->height, pointer->xPos, pointer->yPos) != UWAC_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL wlf_Pointer_SetNull(rdpContext* context)
|
||||
{
|
||||
wlfContext* wlf = (wlfContext*)context;
|
||||
if (!wlf || !wlf->seat)
|
||||
return FALSE;
|
||||
|
||||
if (UwacSeatSetMouseCursor(wlf->seat, NULL, 0, 0, 0, 0, 0) != UWAC_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL wlf_Pointer_SetDefault(rdpContext* context)
|
||||
{
|
||||
wlfContext* wlf = (wlfContext*)context;
|
||||
if (!wlf || !wlf->seat)
|
||||
return FALSE;
|
||||
|
||||
if (UwacSeatSetMouseCursor(wlf->seat, NULL, 1, 0, 0, 0, 0) != UWAC_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL wlf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
|
||||
{
|
||||
// TODO
|
||||
WLog_WARN(TAG, "%s not implemented", __FUNCTION__);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL wlf_register_pointer(rdpGraphics* graphics)
|
||||
{
|
||||
rdpPointer* pointer = NULL;
|
||||
|
||||
if (!(pointer = (rdpPointer*) calloc(1, sizeof(rdpPointer))))
|
||||
return FALSE;
|
||||
|
||||
pointer->size = sizeof(wlfPointer);
|
||||
pointer->New = wlf_Pointer_New;
|
||||
pointer->Free = wlf_Pointer_Free;
|
||||
pointer->Set = wlf_Pointer_Set;
|
||||
pointer->SetNull = wlf_Pointer_SetNull;
|
||||
pointer->SetDefault = wlf_Pointer_SetDefault;
|
||||
pointer->SetPosition = wlf_Pointer_SetPosition;
|
||||
graphics_register_pointer(graphics, pointer);
|
||||
free(pointer);
|
||||
return TRUE;
|
||||
}
|
28
client/Wayland/wlf_pointer.h
Normal file
28
client/Wayland/wlf_pointer.h
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Wayland Mouse Pointer
|
||||
*
|
||||
* Copyright 2019 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2019 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CLIENT_WAYLAND_POINTER_H
|
||||
#define FREERDP_CLIENT_WAYLAND_POINTER_H
|
||||
|
||||
#include <freerdp/graphics.h>
|
||||
|
||||
BOOL wlf_register_pointer(rdpGraphics* graphics);
|
||||
|
||||
#endif /* FREERDP_CLIENT_WAYLAND_POINTER_H */
|
@ -39,6 +39,7 @@
|
||||
#include "wlf_cliprdr.h"
|
||||
#include "wlf_disp.h"
|
||||
#include "wlf_channels.h"
|
||||
#include "wlf_pointer.h"
|
||||
|
||||
static BOOL wl_begin_paint(rdpContext* context)
|
||||
{
|
||||
@ -222,6 +223,9 @@ static BOOL wl_post_connect(freerdp* instance)
|
||||
if (!gdi || (gdi->width < 0) || (gdi->height < 0))
|
||||
return FALSE;
|
||||
|
||||
if (!wlf_register_pointer(instance->context->graphics))
|
||||
return FALSE;
|
||||
|
||||
w = (UINT32)gdi->width;
|
||||
h = (UINT32)gdi->height;
|
||||
context = (wlfContext*) instance->context;
|
||||
@ -286,6 +290,14 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
|
||||
/*printf("UWAC event type %d\n", event.type);*/
|
||||
switch (event.type)
|
||||
{
|
||||
case UWAC_EVENT_NEW_SEAT:
|
||||
context->seat = event.seat_new.seat;
|
||||
break;
|
||||
|
||||
case UWAC_EVENT_REMOVED_SEAT:
|
||||
context->seat = NULL;
|
||||
break;
|
||||
|
||||
case UWAC_EVENT_FRAME_DONE:
|
||||
break;
|
||||
|
||||
|
@ -41,6 +41,7 @@ struct wlf_context
|
||||
UwacDisplay* display;
|
||||
HANDLE displayHandle;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
|
||||
BOOL fullscreen;
|
||||
|
||||
|
@ -30,6 +30,7 @@ include(FindPkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(WAYLAND_SCANNER_PC wayland-scanner)
|
||||
pkg_check_modules(WAYLAND_CLIENT_PC wayland-client)
|
||||
pkg_check_modules(WAYLAND_CURSOR_PC wayland-cursor)
|
||||
pkg_check_modules(XKBCOMMON_PC xkbcommon)
|
||||
endif()
|
||||
|
||||
@ -41,11 +42,20 @@ find_path(WAYLAND_INCLUDE_DIR wayland-client.h
|
||||
HINTS ${WAYLAND_CLIENT_PC_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(WAYLAND_LIBS
|
||||
find_library(WAYLAND_CLIENT_LIB
|
||||
NAMES "wayland-client"
|
||||
HINTS "${WAYLAND_CLIENT_PC_LIBRARY_DIRS}"
|
||||
)
|
||||
|
||||
find_library(WAYLAND_CURSOR_LIB
|
||||
NAMES "wayland-cursor"
|
||||
HINTS "${WAYLAND_CURSOR_PC_LIBRARY_DIRS}"
|
||||
)
|
||||
|
||||
if (WAYLAND_CLIENT_LIB AND WAYLAND_CURSOR_LIB)
|
||||
list(APPEND WAYLAND_LIBS ${WAYLAND_CLIENT_LIB} ${WAYLAND_CURSOR_LIB})
|
||||
endif (WAYLAND_CLIENT_LIB AND WAYLAND_CURSOR_LIB)
|
||||
|
||||
find_path(XKBCOMMON_INCLUDE_DIR xkbcommon/xkbcommon.h
|
||||
HINTS ${XKBCOMMON_PC_INCLUDE_DIRS}
|
||||
)
|
||||
|
@ -97,6 +97,7 @@ enum
|
||||
UWAC_EVENT_CLIPBOARD_AVAILABLE,
|
||||
UWAC_EVENT_CLIPBOARD_SELECT,
|
||||
UWAC_EVENT_CLIPBOARD_OFFER,
|
||||
UWAC_EVENT_OUTPUT_GEOMETRY,
|
||||
};
|
||||
|
||||
/** @brief window states */
|
||||
@ -243,11 +244,27 @@ struct uwac_clipboard_event
|
||||
};
|
||||
typedef struct uwac_clipboard_event UwacClipboardEvent;
|
||||
|
||||
struct uwac_output_geometry_event
|
||||
{
|
||||
int type;
|
||||
UwacOutput* output;
|
||||
int x;
|
||||
int y;
|
||||
int physical_width;
|
||||
int physical_height;
|
||||
int subpixel;
|
||||
const char *make;
|
||||
const char *model;
|
||||
int transform;
|
||||
};
|
||||
typedef struct uwac_output_geometry_event UwacOutputGeometryEvent;
|
||||
|
||||
/** @brief */
|
||||
union uwac_event
|
||||
{
|
||||
int type;
|
||||
UwacOutputNewEvent output_new;
|
||||
UwacOutputGeometryEvent output_geometry;
|
||||
UwacSeatNewEvent seat_new;
|
||||
UwacSeatRemovedEvent seat_removed;
|
||||
UwacPointerEnterLeaveEvent mouse_enter_leave;
|
||||
@ -564,6 +581,25 @@ UWAC_API void* UwacClipboardDataGet(UwacSeat* seat, const char* mime, size_t* si
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* seat, bool inhibit);
|
||||
|
||||
/**
|
||||
* @brief UwacSeatSetMouseCursor Sets the specified image as the new mouse cursor.
|
||||
* Special values: If data == NULL && lenght == 0
|
||||
* the cursor is hidden, if data == NULL && length != 0
|
||||
* the default system cursor is used.
|
||||
*
|
||||
* @param seat The UwacSeat to apply the cursor image to
|
||||
* @param data A pointer to the image data
|
||||
* @param length The size of the image data
|
||||
* @param width The image width in pixel
|
||||
* @param height The image height in pixel
|
||||
* @param hot_x The hotspot horizontal offset in pixel
|
||||
* @param hot_y The hotspot vertical offset in pixel
|
||||
*
|
||||
* @return UWAC_SUCCESS if successful, an appropriate error otherwise.
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat, const void* data, size_t length,
|
||||
size_t width, size_t height, size_t hot_x, size_t hot_y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include "uwac-os.h"
|
||||
#include "wayland-cursor.h"
|
||||
|
||||
#define TARGET_COMPOSITOR_INTERFACE 3
|
||||
#define TARGET_SHM_INTERFACE 1
|
||||
@ -151,6 +152,14 @@ static void UwacSeatRegisterDDM(UwacSeat *seat)
|
||||
seat->data_device = wl_data_device_manager_get_data_device(d->data_device_manager, seat->seat);
|
||||
}
|
||||
|
||||
static void UwacRegisterCursor(UwacSeat* seat)
|
||||
{
|
||||
if (!seat || !seat->display || !seat->display->compositor)
|
||||
return;
|
||||
|
||||
seat->pointer_surface = wl_compositor_create_surface(seat->display->compositor);
|
||||
}
|
||||
|
||||
static void registry_handle_global(void* data, struct wl_registry* registry, uint32_t id,
|
||||
const char* interface, uint32_t version)
|
||||
{
|
||||
@ -171,6 +180,18 @@ static void registry_handle_global(void* data, struct wl_registry* registry, uin
|
||||
{
|
||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, min(TARGET_SHM_INTERFACE, version));
|
||||
wl_shm_add_listener(d->shm, &shm_listener, d);
|
||||
|
||||
d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
|
||||
if (!d->cursor_theme) {
|
||||
assert(uwacErrorHandler(d, UWAC_ERROR_NOMEMORY, "unable to get wayland cursor theme\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
d->default_cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
|
||||
if (!d->default_cursor) {
|
||||
assert(uwacErrorHandler(d, UWAC_ERROR_NOMEMORY, "unable to get wayland cursor left_ptr\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (strcmp(interface, "wl_output") == 0)
|
||||
{
|
||||
@ -203,6 +224,7 @@ static void registry_handle_global(void* data, struct wl_registry* registry, uin
|
||||
|
||||
UwacSeatRegisterDDM(seat);
|
||||
UwacSeatRegisterClipboard(seat);
|
||||
UwacRegisterCursor(seat);
|
||||
ev = (UwacSeatNewEvent*)UwacDisplayNewEvent(d, UWAC_EVENT_NEW_SEAT);
|
||||
|
||||
if (!ev)
|
||||
@ -224,6 +246,7 @@ static void registry_handle_global(void* data, struct wl_registry* registry, uin
|
||||
{
|
||||
UwacSeatRegisterDDM(seat);
|
||||
UwacSeatRegisterClipboard(seat);
|
||||
UwacRegisterCursor(seat);
|
||||
}
|
||||
}
|
||||
else if (strcmp(interface, "wl_shell") == 0)
|
||||
@ -573,6 +596,9 @@ UwacReturnCode UwacCloseDisplay(UwacDisplay** pdisplay)
|
||||
if (display->shell)
|
||||
wl_shell_destroy(display->shell);
|
||||
|
||||
if (display->cursor_theme)
|
||||
wl_cursor_theme_destroy(display->cursor_theme);
|
||||
|
||||
if (display->shm)
|
||||
wl_shm_destroy(display->shm);
|
||||
|
||||
|
@ -32,6 +32,111 @@
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include "uwac-os.h"
|
||||
#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)
|
||||
{
|
||||
struct wl_buffer* buffer = NULL;
|
||||
struct wl_cursor* cursor;
|
||||
struct wl_cursor_image* image;
|
||||
struct wl_surface* surface = NULL;
|
||||
int32_t x = 0, y = 0;
|
||||
|
||||
if (!seat || !seat->display || !seat->display->default_cursor || !seat->display->default_cursor->images)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
switch(seat->pointer_type) {
|
||||
case 2: /* Custom poiner */
|
||||
image = seat->pointer_image;
|
||||
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;
|
||||
case 1: /* NULL pointer */
|
||||
break;
|
||||
default: /* Default system pointer */
|
||||
cursor = seat->display->default_cursor;
|
||||
if (!cursor)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
image = cursor->images[0];
|
||||
if (!image)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
x = image->hotspot_x;
|
||||
y = image->hotspot_y;
|
||||
buffer = wl_cursor_image_get_buffer(image);
|
||||
if (!buffer)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
surface = seat->pointer_surface;
|
||||
break;
|
||||
}
|
||||
|
||||
if (surface) {
|
||||
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;
|
||||
}
|
||||
|
||||
static void keyboard_repeat_func(UwacTask *task, uint32_t events)
|
||||
{
|
||||
@ -588,6 +693,10 @@ static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_
|
||||
event->window = window;
|
||||
event->x = sx;
|
||||
event->y = sy;
|
||||
|
||||
|
||||
/* Apply cursor theme */
|
||||
set_cursor_image(input, serial);
|
||||
}
|
||||
|
||||
static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
@ -871,6 +980,12 @@ void UwacSeatDestroy(UwacSeat *s) {
|
||||
if (s->data_source)
|
||||
wl_data_source_destroy(s->data_source);
|
||||
|
||||
if (s->pointer_surface)
|
||||
wl_surface_destroy(s->pointer_surface);
|
||||
|
||||
free(s->pointer_image);
|
||||
free(s->pointer_data);
|
||||
|
||||
wl_list_remove(&s->link);
|
||||
free(s);
|
||||
}
|
||||
@ -898,3 +1013,46 @@ UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* s, bool inhibit)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
return UWAC_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
free(seat->pointer_image);
|
||||
seat->pointer_image = 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 = calloc(1, sizeof(struct wl_cursor_image));
|
||||
if (!seat->pointer_image)
|
||||
return UWAC_ERROR_NOMEMORY;
|
||||
seat->pointer_image->width = width;
|
||||
seat->pointer_image->height = height;
|
||||
seat->pointer_image->hotspot_x = hot_x;
|
||||
seat->pointer_image->hotspot_y = hot_y;
|
||||
|
||||
free(seat->pointer_data);
|
||||
seat->pointer_data = malloc(length);
|
||||
memcpy(seat->pointer_data, data, length);
|
||||
seat->pointer_size = length;
|
||||
|
||||
seat->pointer_type = 2;
|
||||
}
|
||||
/* We want to use the system cursor */
|
||||
else if (length != 0) {
|
||||
seat->pointer_type = 0;
|
||||
}
|
||||
/* Hide the cursor */
|
||||
else {
|
||||
seat->pointer_type = 1;
|
||||
}
|
||||
return set_cursor_image(seat, seat->display->serial);
|
||||
}
|
||||
|
@ -212,11 +212,11 @@ static int create_tmpfile_cloexec(char* tmpname)
|
||||
int uwac_create_anonymous_file(off_t size)
|
||||
{
|
||||
static const char template[] = "/weston-shared-XXXXXX";
|
||||
const char* path;
|
||||
size_t length;
|
||||
char* name;
|
||||
const char* path;
|
||||
int fd;
|
||||
int ret;
|
||||
size_t length;
|
||||
path = getenv("XDG_RUNTIME_DIR");
|
||||
|
||||
if (!path)
|
||||
@ -225,6 +225,10 @@ int uwac_create_anonymous_file(off_t size)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(path, O_TMPFILE | O_RDWR | O_EXCL, 0600);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
length = strlen(path) + sizeof(template);
|
||||
name = malloc(length);
|
||||
|
||||
@ -234,6 +238,7 @@ int uwac_create_anonymous_file(off_t size)
|
||||
snprintf(name, length, "%s%s", path, template);
|
||||
fd = create_tmpfile_cloexec(name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
@ -52,6 +52,17 @@ static void output_handle_geometry(void *data, struct wl_output *wl_output, int
|
||||
if (!output->model) {
|
||||
assert(uwacErrorHandler(output->display, UWAC_ERROR_NOMEMORY, "%s: unable to strdup model\n", __FUNCTION__));
|
||||
}
|
||||
|
||||
UwacEvent* event = UwacDisplayNewEvent(output->display, UWAC_EVENT_OUTPUT_GEOMETRY);
|
||||
event->output_geometry.output = output;
|
||||
event->output_geometry.x = x;
|
||||
event->output_geometry.y = y;
|
||||
event->output_geometry.physical_width = physical_width;
|
||||
event->output_geometry.physical_height = physical_height;
|
||||
event->output_geometry.subpixel = subpixel;
|
||||
event->output_geometry.make = output->make;
|
||||
event->output_geometry.model = output->model;
|
||||
event->output_geometry.transform = transform;
|
||||
}
|
||||
|
||||
static void output_handle_done(void *data, struct wl_output *wl_output)
|
||||
|
@ -121,7 +121,7 @@ struct uwac_display {
|
||||
uint32_t serial;
|
||||
|
||||
struct wl_cursor_theme *cursor_theme;
|
||||
struct wl_cursor **cursors;
|
||||
struct wl_cursor *default_cursor;
|
||||
|
||||
struct wl_list windows;
|
||||
|
||||
@ -158,6 +158,11 @@ struct uwac_seat {
|
||||
struct wl_data_device* data_device;
|
||||
struct wl_data_source* data_source;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_surface *pointer_surface;
|
||||
struct wl_cursor_image *pointer_image;
|
||||
void *pointer_data;
|
||||
size_t pointer_size;
|
||||
int pointer_type;
|
||||
struct wl_keyboard *keyboard;
|
||||
struct wl_touch *touch;
|
||||
struct wl_data_offer* offer;
|
||||
|
Loading…
Reference in New Issue
Block a user