Merge commit '852f2a6343518919e5ca8d3c1bbcab9f493e3cd8'

This commit is contained in:
2024-01-17 17:02:59 +01:00
1244 changed files with 50102 additions and 28146 deletions

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -35,7 +35,7 @@ int Wayland_SetClipboardData(SDL_VideoDevice *_this)
SDL_WaylandDataDevice *data_device = NULL;
int status = 0;
if (video_data->input != NULL && video_data->input->data_device != NULL) {
if (video_data->input && video_data->input->data_device) {
data_device = video_data->input->data_device;
if (_this->clipboard_callback && _this->clipboard_mime_types) {
@@ -60,7 +60,7 @@ void *Wayland_GetClipboardData(SDL_VideoDevice *_this, const char *mime_type, si
SDL_WaylandDataDevice *data_device = NULL;
void *buffer = NULL;
if (video_data->input != NULL && video_data->input->data_device != NULL) {
if (video_data->input && video_data->input->data_device) {
data_device = video_data->input->data_device;
if (data_device->selection_source) {
buffer = SDL_GetInternalClipboardData(_this, mime_type, length);
@@ -78,9 +78,9 @@ SDL_bool Wayland_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type)
SDL_WaylandDataDevice *data_device = NULL;
SDL_bool result = SDL_FALSE;
if (video_data->input != NULL && video_data->input->data_device != NULL) {
if (video_data->input && video_data->input->data_device) {
data_device = video_data->input->data_device;
if (data_device->selection_source != NULL) {
if (data_device->selection_source) {
result = SDL_HasInternalClipboardData(_this, mime_type);
} else {
result = Wayland_data_offer_has_mime(data_device->selection_offer, mime_type);
@@ -107,9 +107,9 @@ int Wayland_SetPrimarySelectionText(SDL_VideoDevice *_this, const char *text)
{
SDL_VideoData *video_data = _this->driverdata;
SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL;
int status = 0;
int status = -1;
if (video_data->input != NULL && video_data->input->primary_selection_device != NULL) {
if (video_data->input && video_data->input->primary_selection_device) {
primary_selection_device = video_data->input->primary_selection_device;
if (text[0] != '\0') {
SDL_WaylandPrimarySelectionSource *source = Wayland_primary_selection_source_create(_this);
@@ -137,16 +137,16 @@ char *Wayland_GetPrimarySelectionText(SDL_VideoDevice *_this)
char *text = NULL;
size_t length = 0;
if (video_data->input != NULL && video_data->input->primary_selection_device != NULL) {
if (video_data->input && video_data->input->primary_selection_device) {
primary_selection_device = video_data->input->primary_selection_device;
if (primary_selection_device->selection_source != NULL) {
if (primary_selection_device->selection_source) {
text = Wayland_primary_selection_source_get_data(primary_selection_device->selection_source, TEXT_MIME, &length);
} else if (Wayland_primary_selection_offer_has_mime(primary_selection_device->selection_offer, TEXT_MIME)) {
text = Wayland_primary_selection_offer_receive(primary_selection_device->selection_offer, TEXT_MIME, &length);
}
}
if (text == NULL) {
if (!text) {
text = SDL_strdup("");
}
@@ -159,9 +159,9 @@ SDL_bool Wayland_HasPrimarySelectionText(SDL_VideoDevice *_this)
SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL;
SDL_bool result = SDL_FALSE;
if (video_data->input != NULL && video_data->input->primary_selection_device != NULL) {
if (video_data->input && video_data->input->primary_selection_device) {
primary_selection_device = video_data->input->primary_selection_device;
if (primary_selection_device->selection_source != NULL) {
if (primary_selection_device->selection_source) {
result = SDL_TRUE;
} else {
result = Wayland_primary_selection_offer_has_mime(primary_selection_device->selection_offer, TEXT_MIME);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -112,14 +112,14 @@ static ssize_t read_pipe(int fd, void **buffer, size_t *total_length)
new_buffer_length = *total_length + sizeof(Uint32);
if (*buffer == NULL) {
if (!*buffer) {
output_buffer = SDL_malloc(new_buffer_length);
} else {
output_buffer = SDL_realloc(*buffer, new_buffer_length);
}
if (output_buffer == NULL) {
bytes_read = SDL_OutOfMemory();
if (!output_buffer) {
bytes_read = -1;
} else {
SDL_memcpy((Uint8 *)output_buffer + pos, temp, bytes_read);
SDL_memset((Uint8 *)output_buffer + (new_buffer_length - sizeof(Uint32)), 0, sizeof(Uint32));
@@ -155,35 +155,35 @@ static int mime_data_list_add(struct wl_list *list,
SDL_MimeDataList *mime_data = NULL;
void *internal_buffer = NULL;
if (buffer != NULL) {
if (buffer) {
internal_buffer = SDL_malloc(length);
if (internal_buffer == NULL) {
return SDL_OutOfMemory();
if (!internal_buffer) {
return -1;
}
SDL_memcpy(internal_buffer, buffer, length);
}
mime_data = mime_data_list_find(list, mime_type);
if (mime_data == NULL) {
if (!mime_data) {
mime_data = SDL_calloc(1, sizeof(*mime_data));
if (mime_data == NULL) {
status = SDL_OutOfMemory();
if (!mime_data) {
status = -1;
} else {
WAYLAND_wl_list_insert(list, &(mime_data->link));
mime_type_length = SDL_strlen(mime_type) + 1;
mime_data->mime_type = SDL_malloc(mime_type_length);
if (mime_data->mime_type == NULL) {
status = SDL_OutOfMemory();
if (!mime_data->mime_type) {
status = -1;
} else {
SDL_memcpy(mime_data->mime_type, mime_type, mime_type_length);
}
}
}
if (mime_data != NULL && buffer != NULL && length > 0) {
if (mime_data->data != NULL) {
if (mime_data && buffer && length > 0) {
if (mime_data->data) {
SDL_free(mime_data->data);
}
mime_data->data = internal_buffer;
@@ -202,10 +202,10 @@ static void mime_data_list_free(struct wl_list *list)
wl_list_for_each_safe(mime_data, next, list, link)
{
if (mime_data->data != NULL) {
if (mime_data->data) {
SDL_free(mime_data->data);
}
if (mime_data->mime_type != NULL) {
if (mime_data->mime_type) {
SDL_free(mime_data->mime_type);
}
SDL_free(mime_data);
@@ -216,7 +216,7 @@ static size_t Wayland_send_data(const void *data, size_t length, int fd)
{
size_t result = 0;
if (length > 0 && data != NULL) {
if (length > 0 && data) {
while (write_pipe(fd, data, length, &result) > 0) {
/* Just keep spinning */
}
@@ -276,11 +276,9 @@ void Wayland_primary_selection_source_set_callback(SDL_WaylandPrimarySelectionSo
static void *Wayland_clone_data_buffer(const void *buffer, size_t *len)
{
void *clone = NULL;
if (*len > 0 && buffer != NULL) {
if (*len > 0 && buffer) {
clone = SDL_malloc((*len)+sizeof(Uint32));
if (clone == NULL) {
SDL_OutOfMemory();
} else {
if (clone) {
SDL_memcpy(clone, buffer, *len);
SDL_memset((Uint8 *)clone + *len, 0, sizeof(Uint32));
}
@@ -295,9 +293,9 @@ void *Wayland_data_source_get_data(SDL_WaylandDataSource *source,
const void *internal_buffer;
*length = 0;
if (source == NULL) {
if (!source) {
SDL_SetError("Invalid data source");
} else if (source->callback != NULL) {
} else if (source->callback) {
internal_buffer = source->callback(source->userdata.data, mime_type, length);
buffer = Wayland_clone_data_buffer(internal_buffer, length);
}
@@ -312,7 +310,7 @@ void *Wayland_primary_selection_source_get_data(SDL_WaylandPrimarySelectionSourc
const void *internal_buffer;
*length = 0;
if (source == NULL) {
if (!source) {
SDL_SetError("Invalid primary selection source");
} else if (source->callback) {
internal_buffer = source->callback(source->userdata.data, mime_type, length);
@@ -324,7 +322,7 @@ void *Wayland_primary_selection_source_get_data(SDL_WaylandPrimarySelectionSourc
void Wayland_data_source_destroy(SDL_WaylandDataSource *source)
{
if (source != NULL) {
if (source) {
SDL_WaylandDataDevice *data_device = (SDL_WaylandDataDevice *)source->data_device;
if (data_device && (data_device->selection_source == source)) {
data_device->selection_source = NULL;
@@ -341,7 +339,7 @@ void Wayland_data_source_destroy(SDL_WaylandDataSource *source)
void Wayland_primary_selection_source_destroy(SDL_WaylandPrimarySelectionSource *source)
{
if (source != NULL) {
if (source) {
SDL_WaylandPrimarySelectionDevice *primary_selection_device = (SDL_WaylandPrimarySelectionDevice *)source->primary_selection_device;
if (primary_selection_device && (primary_selection_device->selection_source == source)) {
primary_selection_device->selection_source = NULL;
@@ -363,12 +361,12 @@ void *Wayland_data_offer_receive(SDL_WaylandDataOffer *offer,
void *buffer = NULL;
*length = 0;
if (offer == NULL) {
if (!offer) {
SDL_SetError("Invalid data offer");
return NULL;
}
data_device = offer->data_device;
if (data_device == NULL) {
if (!data_device) {
SDL_SetError("Data device not initialized");
} else if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) {
SDL_SetError("Could not read pipe");
@@ -396,12 +394,12 @@ void *Wayland_primary_selection_offer_receive(SDL_WaylandPrimarySelectionOffer *
void *buffer = NULL;
*length = 0;
if (offer == NULL) {
if (!offer) {
SDL_SetError("Invalid data offer");
return NULL;
}
primary_selection_device = offer->primary_selection_device;
if (primary_selection_device == NULL) {
if (!primary_selection_device) {
SDL_SetError("Primary selection device not initialized");
} else if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) {
SDL_SetError("Could not read pipe");
@@ -437,7 +435,7 @@ SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer,
{
SDL_bool found = SDL_FALSE;
if (offer != NULL) {
if (offer) {
found = mime_data_list_find(&offer->mimes, mime_type) != NULL;
}
return found;
@@ -448,7 +446,7 @@ SDL_bool Wayland_primary_selection_offer_has_mime(SDL_WaylandPrimarySelectionOff
{
SDL_bool found = SDL_FALSE;
if (offer != NULL) {
if (offer) {
found = mime_data_list_find(&offer->mimes, mime_type) != NULL;
}
return found;
@@ -456,7 +454,7 @@ SDL_bool Wayland_primary_selection_offer_has_mime(SDL_WaylandPrimarySelectionOff
void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
{
if (offer != NULL) {
if (offer) {
wl_data_offer_destroy(offer->offer);
mime_data_list_free(&offer->mimes);
SDL_free(offer);
@@ -465,7 +463,7 @@ void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
void Wayland_primary_selection_offer_destroy(SDL_WaylandPrimarySelectionOffer *offer)
{
if (offer != NULL) {
if (offer) {
zwp_primary_selection_offer_v1_destroy(offer->offer);
mime_data_list_free(&offer->mimes);
SDL_free(offer);
@@ -476,9 +474,9 @@ int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *data_device)
{
int status = 0;
if (data_device == NULL || data_device->data_device == NULL) {
if (!data_device || !data_device->data_device) {
status = SDL_SetError("Invalid Data Device");
} else if (data_device->selection_source != NULL) {
} else if (data_device->selection_source) {
wl_data_device_set_selection(data_device->data_device, NULL, 0);
Wayland_data_source_destroy(data_device->selection_source);
data_device->selection_source = NULL;
@@ -490,9 +488,9 @@ int Wayland_primary_selection_device_clear_selection(SDL_WaylandPrimarySelection
{
int status = 0;
if (primary_selection_device == NULL || primary_selection_device->primary_selection_device == NULL) {
if (!primary_selection_device || !primary_selection_device->primary_selection_device) {
status = SDL_SetError("Invalid Primary Selection Device");
} else if (primary_selection_device->selection_source != NULL) {
} else if (primary_selection_device->selection_source) {
zwp_primary_selection_device_v1_set_selection(primary_selection_device->primary_selection_device,
NULL, 0);
Wayland_primary_selection_source_destroy(primary_selection_device->selection_source);
@@ -508,9 +506,9 @@ int Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device,
{
int status = 0;
if (data_device == NULL) {
if (!data_device) {
status = SDL_SetError("Invalid Data Device");
} else if (source == NULL) {
} else if (!source) {
status = SDL_SetError("Invalid source");
} else {
size_t index = 0;
@@ -532,7 +530,7 @@ int Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device,
source->source,
data_device->selection_serial);
}
if (data_device->selection_source != NULL) {
if (data_device->selection_source) {
Wayland_data_source_destroy(data_device->selection_source);
}
data_device->selection_source = source;
@@ -550,9 +548,9 @@ int Wayland_primary_selection_device_set_selection(SDL_WaylandPrimarySelectionDe
{
int status = 0;
if (primary_selection_device == NULL) {
if (!primary_selection_device) {
status = SDL_SetError("Invalid Primary Selection Device");
} else if (source == NULL) {
} else if (!source) {
status = SDL_SetError("Invalid source");
} else {
size_t index = 0;
@@ -573,7 +571,7 @@ int Wayland_primary_selection_device_set_selection(SDL_WaylandPrimarySelectionDe
source->source,
primary_selection_device->selection_serial);
}
if (primary_selection_device->selection_source != NULL) {
if (primary_selection_device->selection_source) {
Wayland_primary_selection_source_destroy(primary_selection_device->selection_source);
}
primary_selection_device->selection_source = source;
@@ -588,11 +586,11 @@ int Wayland_data_device_set_serial(SDL_WaylandDataDevice *data_device,
uint32_t serial)
{
int status = -1;
if (data_device != NULL) {
if (data_device) {
status = 0;
/* If there was no serial and there is a pending selection set it now. */
if (data_device->selection_serial == 0 && data_device->selection_source != NULL) {
if (data_device->selection_serial == 0 && data_device->selection_source) {
wl_data_device_set_selection(data_device->data_device,
data_device->selection_source->source,
data_device->selection_serial);
@@ -608,11 +606,11 @@ int Wayland_primary_selection_device_set_serial(SDL_WaylandPrimarySelectionDevic
uint32_t serial)
{
int status = -1;
if (primary_selection_device != NULL) {
if (primary_selection_device) {
status = 0;
/* If there was no serial and there is a pending selection set it now. */
if (primary_selection_device->selection_serial == 0 && primary_selection_device->selection_source != NULL) {
if (primary_selection_device->selection_serial == 0 && primary_selection_device->selection_source) {
zwp_primary_selection_device_v1_set_selection(primary_selection_device->primary_selection_device,
primary_selection_device->selection_source->source,
primary_selection_device->selection_serial);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -56,23 +56,23 @@ static void *WAYLAND_GetSym(const char *fnname, int *pHasModule, SDL_bool requir
void *fn = NULL;
waylanddynlib *dynlib;
for (dynlib = waylandlibs; dynlib->libname; dynlib++) {
if (dynlib->lib != NULL) {
if (dynlib->lib) {
fn = SDL_LoadFunction(dynlib->lib, fnname);
if (fn != NULL) {
if (fn) {
break;
}
}
}
#if DEBUG_DYNAMIC_WAYLAND
if (fn != NULL) {
if (fn) {
SDL_Log("WAYLAND: Found '%s' in %s (%p)\n", fnname, dynlib->libname, fn);
} else {
SDL_Log("WAYLAND: Symbol '%s' NOT FOUND!\n", fnname);
}
#endif
if (fn == NULL && required) {
if (!fn && required) {
*pHasModule = 0; /* kill this module. */
}
@@ -112,7 +112,7 @@ void SDL_WAYLAND_UnloadSymbols(void)
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) {
if (waylandlibs[i].lib != NULL) {
if (waylandlibs[i].lib) {
SDL_UnloadObject(waylandlibs[i].lib);
waylandlibs[i].lib = NULL;
}
@@ -133,7 +133,7 @@ int SDL_WAYLAND_LoadSymbols(void)
int i;
int *thismod = NULL;
for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) {
if (waylandlibs[i].libname != NULL) {
if (waylandlibs[i].libname) {
waylandlibs[i].lib = SDL_LoadObject(waylandlibs[i].libname);
}
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -25,6 +25,7 @@
#define SDL_waylandevents_h_
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_pen_c.h"
#include "SDL_waylandvideo.h"
#include "SDL_waylandwindow.h"
@@ -55,31 +56,38 @@ struct SDL_WaylandTabletInput
struct SDL_WaylandTabletObjectListNode *tools;
struct SDL_WaylandTabletObjectListNode *pads;
Uint32 id;
Uint32 num_pens; /* next pen ID is num_pens+1 */
struct SDL_WaylandCurrentPen
{
SDL_Pen *builder; /* pen that is being defined or receiving updates, if any */
SDL_bool builder_guid_complete; /* have complete/precise GUID information */
SDL_PenStatusInfo update_status; /* collects pen update information before sending event */
Uint16 buttons_pressed; /* Mask of newly pressed buttons, plus SDL_PEN_DOWN_MASK for PEN_DOWN */
Uint16 buttons_released; /* Mask of newly pressed buttons, plus SDL_PEN_DOWN_MASK for PEN_UP */
Uint32 serial; /* Most recent serial event number observed, or 0 */
SDL_WindowData *update_window; /* NULL while no event is in progress, otherwise the affected window */
} current_pen;
SDL_WindowData *tool_focus;
uint32_t tool_prox_serial;
/* Last motion location */
/* Last motion end location (kept separate from sx_w, sy_w for the mouse pointer) */
wl_fixed_t sx_w;
wl_fixed_t sy_w;
SDL_bool is_down;
SDL_bool btn_stylus;
SDL_bool btn_stylus2;
SDL_bool btn_stylus3;
};
typedef struct
{
int32_t repeat_rate; /* Repeat rate in range of [1, 1000] character(s) per second */
int32_t repeat_delay_ms; /* Time to first repeat event in milliseconds */
int32_t repeat_rate; /* Repeat rate in range of [1, 1000] character(s) per second */
int32_t repeat_delay_ms; /* Time to first repeat event in milliseconds */
SDL_bool is_initialized;
SDL_bool is_key_down;
uint32_t key;
Uint64 wl_press_time_ns; /* Key press time as reported by the Wayland API */
Uint64 sdl_press_time_ns; /* Key press time expressed in SDL ticks */
Uint64 next_repeat_ns; /* Next repeat event in nanoseconds */
Uint64 wl_press_time_ns; /* Key press time as reported by the Wayland API */
Uint64 sdl_press_time_ns; /* Key press time expressed in SDL ticks */
Uint64 next_repeat_ns; /* Next repeat event in nanoseconds */
uint32_t scancode;
char text[8];
} SDL_WaylandKeyboardRepeat;
@@ -169,6 +177,12 @@ struct SDL_WaylandInput
SDL_Keymod locked_modifiers;
};
struct SDL_WaylandTool
{
SDL_PenID penid;
struct SDL_WaylandTabletInput *tablet;
};
extern Uint64 Wayland_GetTouchTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms);
extern void Wayland_PumpEvents(SDL_VideoDevice *_this);
@@ -182,18 +196,12 @@ extern void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32
extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version);
extern void Wayland_display_destroy_input(SDL_VideoData *d);
extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id);
extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d);
extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input);
extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input);
extern int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window);
extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window);
extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id);
extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d);
extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input);
extern int Wayland_input_ungrab_keyboard(SDL_Window *window);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -32,7 +32,7 @@ int Wayland_InitKeyboard(SDL_VideoDevice *_this)
{
#ifdef SDL_USE_IME
SDL_VideoData *driverdata = _this->driverdata;
if (driverdata->text_input_manager == NULL) {
if (!driverdata->text_input_manager) {
SDL_IME_Init();
}
#endif
@@ -45,7 +45,7 @@ void Wayland_QuitKeyboard(SDL_VideoDevice *_this)
{
#ifdef SDL_USE_IME
SDL_VideoData *driverdata = _this->driverdata;
if (driverdata->text_input_manager == NULL) {
if (!driverdata->text_input_manager) {
SDL_IME_Quit();
}
#endif
@@ -57,7 +57,7 @@ void Wayland_StartTextInput(SDL_VideoDevice *_this)
if (driverdata->text_input_manager) {
struct SDL_WaylandInput *input = driverdata->input;
if (input != NULL && input->text_input) {
if (input && input->text_input) {
const SDL_Rect *rect = &input->text_input->cursor_rect;
/* Don't re-enable if we're already enabled. */
@@ -98,7 +98,7 @@ void Wayland_StopTextInput(SDL_VideoDevice *_this)
if (driverdata->text_input_manager) {
struct SDL_WaylandInput *input = driverdata->input;
if (input != NULL && input->text_input) {
if (input && input->text_input) {
zwp_text_input_v3_disable(input->text_input->text_input);
zwp_text_input_v3_commit(input->text_input->text_input);
input->text_input->is_enabled = SDL_FALSE;
@@ -117,7 +117,7 @@ int Wayland_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect)
SDL_VideoData *driverdata = _this->driverdata;
if (driverdata->text_input_manager) {
struct SDL_WaylandInput *input = driverdata->input;
if (input != NULL && input->text_input) {
if (input && input->text_input) {
if (!SDL_RectsEqual(rect, &input->text_input->cursor_rect)) {
SDL_copyp(&input->text_input->cursor_rect, rect);
zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input,

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -36,7 +36,8 @@
#define MAX_BUTTONS 8 /* Maximum number of buttons supported */
static int run_zenity(const char **args, int fd_pipe[2]) {
static int run_zenity(const char **args, int fd_pipe[2])
{
int status;
pid_t pid1;
@@ -47,6 +48,7 @@ static int run_zenity(const char **args, int fd_pipe[2]) {
if (dup2(fd_pipe[1], STDOUT_FILENO) == -1) {
_exit(128);
}
close(fd_pipe[1]);
/* const casting argv is fine:
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html -> rational
@@ -56,7 +58,6 @@ static int run_zenity(const char **args, int fd_pipe[2]) {
} else if (pid1 < 0) { /* fork() failed */
return SDL_SetError("fork() failed: %s", strerror(errno));
} else { /* parent process */
close(fd_pipe[1]); /* no writing to the pipe */
if (waitpid(pid1, &status, 0) != pid1) {
return SDL_SetError("Waiting on zenity failed: %s", strerror(errno));
}
@@ -73,7 +74,8 @@ static int run_zenity(const char **args, int fd_pipe[2]) {
}
}
static int get_zenity_version(int *major, int *minor) {
static int get_zenity_version(int *major, int *minor)
{
int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */
const char *argv[] = { "zenity", "--version", NULL };
@@ -87,8 +89,9 @@ static int get_zenity_version(int *major, int *minor) {
char *version_ptr = NULL, *end_ptr = NULL;
int tmp;
close(fd_pipe[1]);
outputfp = fdopen(fd_pipe[0], "r");
if (outputfp == NULL) {
if (!outputfp) {
close(fd_pipe[0]);
return SDL_SetError("failed to open pipe for reading: %s", strerror(errno));
}
@@ -96,6 +99,10 @@ static int get_zenity_version(int *major, int *minor) {
version_ptr = fgets(version_str, ZENITY_VERSION_LEN, outputfp);
(void)fclose(outputfp); /* will close underlying fd */
if (!version_ptr) {
return SDL_SetError("failed to read zenity version string");
}
/* we expect the version string is in the form of MAJOR.MINOR.MICRO
* as described in meson.build. We'll ignore everything after that.
*/
@@ -105,12 +112,16 @@ static int get_zenity_version(int *major, int *minor) {
}
*major = tmp;
version_ptr = end_ptr + 1; /* skip the dot */
tmp = (int) SDL_strtol(version_ptr, &end_ptr, 10);
if (tmp == 0 && end_ptr == version_ptr) {
return SDL_SetError("failed to get zenity minor version number");
if (*end_ptr == '.') {
version_ptr = end_ptr + 1; /* skip the dot */
tmp = (int) SDL_strtol(version_ptr, &end_ptr, 10);
if (tmp == 0 && end_ptr == version_ptr) {
return SDL_SetError("failed to get zenity minor version number");
}
*minor = tmp;
} else {
*minor = 0;
}
*minor = tmp;
return 0; /* success */
}
@@ -120,7 +131,8 @@ static int get_zenity_version(int *major, int *minor) {
return -1; /* run_zenity should've called SDL_SetError() */
}
int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) {
int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */
int zenity_major = 0, zenity_minor = 0, output_len = 0;
int argc = 5, i;
@@ -128,6 +140,14 @@ int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *button
"zenity", "--question", "--switch", "--no-wrap", "--no-markup"
};
/* Are we trying to connect to or are currently in a Wayland session? */
if (!SDL_getenv("WAYLAND_DISPLAY")) {
const char *session = SDL_getenv("XDG_SESSION_TYPE");
if (session && SDL_strcasecmp(session, "wayland") != 0) {
return SDL_SetError("Not on a wayland display");
}
}
if (messageboxdata->numbuttons > MAX_BUTTONS) {
return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS);
}
@@ -193,7 +213,7 @@ int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *button
char *output = NULL;
char *tmp = NULL;
if (buttonid == NULL) {
if (!buttonid) {
/* if we don't need buttonid, we can return immediately */
close(fd_pipe[0]);
return 0; /* success */
@@ -201,14 +221,14 @@ int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *button
*buttonid = -1;
output = SDL_malloc(output_len + 1);
if (output == NULL) {
if (!output) {
close(fd_pipe[0]);
return SDL_OutOfMemory();
return -1;
}
output[0] = '\0';
outputfp = fdopen(fd_pipe[0], "r");
if (outputfp == NULL) {
if (!outputfp) {
SDL_free(output);
close(fd_pipe[0]);
return SDL_SetError("Couldn't open pipe for reading: %s", strerror(errno));
@@ -216,20 +236,20 @@ int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *button
tmp = fgets(output, output_len + 1, outputfp);
(void)fclose(outputfp);
if ((tmp == NULL) || (*tmp == '\0') || (*tmp == '\n')) {
if ((!tmp) || (*tmp == '\0') || (*tmp == '\n')) {
SDL_free(output);
return 0; /* User simply closed the dialog */
}
/* It likes to add a newline... */
tmp = SDL_strrchr(output, '\n');
if (tmp != NULL) {
if (tmp) {
*tmp = '\0';
}
/* Check which button got pressed */
for (i = 0; i < messageboxdata->numbuttons; i += 1) {
if (messageboxdata->buttons[i].text != NULL) {
if (messageboxdata->buttons[i].text) {
if (SDL_strcmp(output, messageboxdata->buttons[i].text) == 0) {
*buttonid = messageboxdata->buttons[i].buttonid;
break;

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -41,6 +41,8 @@
#include "../../SDL_hints_c.h"
static SDL_Cursor *sys_cursors[SDL_HITTEST_RESIZE_LEFT + 1];
static int Wayland_SetRelativeMouseMode(SDL_bool enabled);
typedef struct
@@ -215,7 +217,7 @@ static void Wayland_DBusInitCursorProperties(SDL_VideoData *vdata)
SDL_DBusContext *dbus = SDL_DBus_GetContext();
SDL_bool add_filter = SDL_FALSE;
if (dbus == NULL) {
if (!dbus) {
return;
}
@@ -279,7 +281,7 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
}
/* First, find the appropriate theme based on the current scale... */
focus = SDL_GetMouse()->focus;
if (focus == NULL) {
if (!focus) {
/* Nothing to see here, bail. */
return SDL_FALSE;
}
@@ -294,15 +296,15 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
break;
}
}
if (theme == NULL) {
if (!theme) {
const char *xcursor_theme = dbus_cursor_theme;
vdata->cursor_themes = SDL_realloc(vdata->cursor_themes,
sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1));
if (vdata->cursor_themes == NULL) {
SDL_OutOfMemory();
SDL_WaylandCursorTheme *new_cursor_themes = SDL_realloc(vdata->cursor_themes,
sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1));
if (!new_cursor_themes) {
return SDL_FALSE;
}
vdata->cursor_themes = new_cursor_themes;
/* Fallback envvar if the DBus properties don't exist */
if (!xcursor_theme) {
@@ -314,43 +316,82 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
vdata->cursor_themes[vdata->num_cursor_themes++].theme = theme;
}
/* Next, find the cursor from the theme... */
/* Next, find the cursor from the theme. Names taken from: */
/* https://www.freedesktop.org/wiki/Specifications/cursor-spec/ */
switch (cdata->system_cursor) {
case SDL_SYSTEM_CURSOR_ARROW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "left_ptr");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "default");
break;
case SDL_SYSTEM_CURSOR_IBEAM:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "xterm");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "text");
break;
case SDL_SYSTEM_CURSOR_WAIT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "wait");
break;
case SDL_SYSTEM_CURSOR_CROSSHAIR:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "tcross");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "crosshair");
break;
case SDL_SYSTEM_CURSOR_WAITARROW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "progress");
break;
case SDL_SYSTEM_CURSOR_SIZENWSE:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "top_left_corner");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "nwse-resize");
if (!cursor) {
/* only a single arrow */
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "nw-resize");
}
break;
case SDL_SYSTEM_CURSOR_SIZENESW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "top_right_corner");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "nesw-resize");
if (!cursor) {
/* only a single arrow */
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "ne-resize");
}
break;
case SDL_SYSTEM_CURSOR_SIZEWE:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "sb_h_double_arrow");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "ew-resize");
if (!cursor) {
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "col-resize");
}
break;
case SDL_SYSTEM_CURSOR_SIZENS:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "sb_v_double_arrow");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "ns-resize");
if (!cursor) {
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "row-resize");
}
break;
case SDL_SYSTEM_CURSOR_SIZEALL:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "fleur");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "all-scroll");
break;
case SDL_SYSTEM_CURSOR_NO:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "pirate");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "not-allowed");
break;
case SDL_SYSTEM_CURSOR_HAND:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand2");
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "pointer");
break;
case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "nw-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_TOP:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "n-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "ne-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_RIGHT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "e-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "se-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "s-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "sw-resize");
break;
case SDL_SYSTEM_CURSOR_WINDOW_LEFT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "w-resize");
break;
default:
SDL_assert(0);
@@ -382,7 +423,7 @@ static int wayland_create_tmp_file(off_t size)
int fd;
xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
if (xdg_path == NULL) {
if (!xdg_path) {
return -1;
}
@@ -462,15 +503,12 @@ static int create_buffer_from_shm(Wayland_CursorData *d,
static SDL_Cursor *Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
SDL_Cursor *cursor;
cursor = SDL_calloc(1, sizeof(*cursor));
SDL_Cursor *cursor = SDL_calloc(1, sizeof(*cursor));
if (cursor) {
SDL_VideoDevice *vd = SDL_GetVideoDevice();
SDL_VideoData *wd = vd->driverdata;
Wayland_CursorData *data = SDL_calloc(1, sizeof(Wayland_CursorData));
if (data == NULL) {
SDL_OutOfMemory();
if (!data) {
SDL_free(cursor);
return NULL;
}
@@ -498,8 +536,6 @@ static SDL_Cursor *Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot
data->hot_y = hot_y;
data->w = surface->w;
data->h = surface->h;
} else {
SDL_OutOfMemory();
}
return cursor;
@@ -508,13 +544,10 @@ static SDL_Cursor *Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot
static SDL_Cursor *Wayland_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_VideoData *data = SDL_GetVideoDevice()->driverdata;
SDL_Cursor *cursor;
cursor = SDL_calloc(1, sizeof(*cursor));
SDL_Cursor *cursor = SDL_calloc(1, sizeof(*cursor));
if (cursor) {
Wayland_CursorData *cdata = SDL_calloc(1, sizeof(Wayland_CursorData));
if (cdata == NULL) {
SDL_OutOfMemory();
if (!cdata) {
SDL_free(cursor);
return NULL;
}
@@ -527,8 +560,6 @@ static SDL_Cursor *Wayland_CreateSystemCursor(SDL_SystemCursor id)
* is output-specific. See wayland_get_system_cursor for the rest!
*/
cdata->system_cursor = id;
} else {
SDL_OutOfMemory();
}
return cursor;
@@ -556,7 +587,7 @@ static void Wayland_FreeCursorData(Wayland_CursorData *d)
static void Wayland_FreeCursor(SDL_Cursor *cursor)
{
if (cursor == NULL) {
if (!cursor) {
return;
}
@@ -580,7 +611,7 @@ static int Wayland_ShowCursor(SDL_Cursor *cursor)
struct wl_pointer *pointer = d->pointer;
float scale = 1.0f;
if (pointer == NULL) {
if (!pointer) {
return -1;
}
@@ -588,7 +619,7 @@ static int Wayland_ShowCursor(SDL_Cursor *cursor)
Wayland_CursorData *data = cursor->driverdata;
/* TODO: High-DPI custom cursors? -flibit */
if (data->shm_data == NULL) {
if (!data->shm_data) {
if (!wayland_get_system_cursor(d, data, &scale)) {
return -1;
}
@@ -770,6 +801,23 @@ void Wayland_InitMouse(void)
input->relative_mode_override = SDL_FALSE;
input->cursor_visible = SDL_TRUE;
SDL_HitTestResult r = SDL_HITTEST_NORMAL;
while (r <= SDL_HITTEST_RESIZE_LEFT) {
switch (r) {
case SDL_HITTEST_NORMAL: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); break;
case SDL_HITTEST_DRAGGABLE: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); break;
case SDL_HITTEST_RESIZE_TOPLEFT: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT); break;
case SDL_HITTEST_RESIZE_TOP: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_TOP); break;
case SDL_HITTEST_RESIZE_TOPRIGHT: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT); break;
case SDL_HITTEST_RESIZE_RIGHT: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_RIGHT); break;
case SDL_HITTEST_RESIZE_BOTTOMRIGHT: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT); break;
case SDL_HITTEST_RESIZE_BOTTOM: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_BOTTOM); break;
case SDL_HITTEST_RESIZE_BOTTOMLEFT: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT); break;
case SDL_HITTEST_RESIZE_LEFT: sys_cursors[r] = Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_WINDOW_LEFT); break;
}
r++;
}
#ifdef SDL_USE_LIBDBUS
Wayland_DBusInitCursorProperties(d);
#endif
@@ -783,6 +831,7 @@ void Wayland_InitMouse(void)
void Wayland_FiniMouse(SDL_VideoData *data)
{
struct SDL_WaylandInput *input = data->input;
int i;
Wayland_FreeCursorThemes(data);
@@ -792,6 +841,20 @@ void Wayland_FiniMouse(SDL_VideoData *data)
SDL_DelHintCallback(SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP,
Wayland_EmulateMouseWarpChanged, input);
for (i = 0; i < SDL_arraysize(sys_cursors); i++) {
Wayland_FreeCursor(sys_cursors[i]);
sys_cursors[i] = NULL;
}
}
void Wayland_SetHitTestCursor(SDL_HitTestResult rc)
{
if (rc == SDL_HITTEST_NORMAL || rc == SDL_HITTEST_DRAGGABLE) {
SDL_SetCursor(NULL);
} else {
Wayland_ShowCursor(sys_cursors[rc]);
}
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -26,6 +26,7 @@
extern void Wayland_InitMouse(void);
extern void Wayland_FiniMouse(SDL_VideoData *data);
extern void Wayland_SetHitTestCursor(SDL_HitTestResult rc);
#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */
extern void Wayland_RecreateCursors(void);
#endif /* 0 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -219,12 +219,12 @@ SDL_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_
enum libdecor_window_state *))
SDL_WAYLAND_SYM(int, libdecor_dispatch, (struct libdecor *, int))
#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) || defined(SDL_HAVE_LIBDECOR_VER_0_1_2)
#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) || defined(SDL_HAVE_LIBDECOR_VER_0_2_0)
/* Only found in libdecor 0.1.1 or higher, so failure to load them is not fatal. */
SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_min_content_size, (struct libdecor_frame *,\
SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_min_content_size, (const struct libdecor_frame *,\
int *,\
int *))
SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_max_content_size, (struct libdecor_frame *,\
SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_max_content_size, (const struct libdecor_frame *,\
int *,\
int *))
#endif

View File

@@ -1,283 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* Contributed by Thomas Perl <thomas.perl@jollamobile.com> */
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
#include "SDL_waylandtouch.h"
#include "SDL_waylandevents_c.h"
#include "../../events/SDL_touch_c.h"
struct SDL_WaylandTouch
{
struct qt_touch_extension *touch_extension;
};
/**
* Qt TouchPointState
* adapted from qtbase/src/corelib/global/qnamespace.h
**/
enum QtWaylandTouchPointState
{
QtWaylandTouchPointPressed = 0x01,
QtWaylandTouchPointMoved = 0x02,
/*
Never sent by the server:
QtWaylandTouchPointStationary = 0x04,
*/
QtWaylandTouchPointReleased = 0x08,
};
static void touch_handle_touch(void *data,
struct qt_touch_extension *qt_touch_extension,
uint32_t time,
uint32_t id,
uint32_t state,
int32_t x,
int32_t y,
int32_t normalized_x,
int32_t normalized_y,
int32_t width,
int32_t height,
uint32_t pressure,
int32_t velocity_x,
int32_t velocity_y,
uint32_t flags,
struct wl_array *rawdata)
{
/**
* Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent
* (src/compositor/wayland_wrapper/qwltouch.cpp)
**/
SDL_VideoData *viddata = data;
float FIXED_TO_FLOAT = 1. / 10000.;
float xf = FIXED_TO_FLOAT * normalized_x;
float yf = FIXED_TO_FLOAT * normalized_y;
float PRESSURE_TO_FLOAT = 1. / 255.;
float pressuref = PRESSURE_TO_FLOAT * pressure;
uint32_t touchState = state & 0xFFFF;
/*
Other fields that are sent by the server (qwltouch.cpp),
but not used at the moment can be decoded in this way:
uint32_t sentPointCount = state >> 16;
uint32_t touchFlags = flags & 0xFFFF;
uint32_t capabilities = flags >> 16;
*/
SDL_Window *window = NULL;
SDL_TouchID deviceId = 1;
if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "qt_touch_extension") < 0) {
SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
}
/* FIXME: This should be the window the given wayland surface is associated
* with, but how do we get the wayland surface? */
window = SDL_GetMouseFocus();
if (window == NULL) {
window = SDL_GetKeyboardFocus();
}
switch (touchState) {
case QtWaylandTouchPointPressed:
case QtWaylandTouchPointReleased:
SDL_SendTouch(Wayland_GetTouchTimestamp(viddata->input, time), deviceId, (SDL_FingerID)id,
window, (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE, xf, yf, pressuref);
break;
case QtWaylandTouchPointMoved:
SDL_SendTouchMotion(Wayland_GetTouchTimestamp(viddata->input, time), deviceId, (SDL_FingerID)id,
window, xf, yf, pressuref);
break;
default:
/* Should not happen */
break;
}
}
static void touch_handle_configure(void *data,
struct qt_touch_extension *qt_touch_extension,
uint32_t flags)
{
}
/* wayland-qt-touch-extension.c BEGINS */
static const struct qt_touch_extension_listener touch_listener = {
touch_handle_touch,
touch_handle_configure,
};
static const struct wl_interface *qt_touch_extension_types[] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
static const struct wl_message qt_touch_extension_requests[] = {
{ "dummy", "", qt_touch_extension_types + 0 },
};
static const struct wl_message qt_touch_extension_events[] = {
{ "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 },
{ "configure", "u", qt_touch_extension_types + 0 },
};
const struct wl_interface qt_touch_extension_interface = {
"qt_touch_extension",
1,
1,
qt_touch_extension_requests,
2,
qt_touch_extension_events,
};
/* wayland-qt-touch-extension.c ENDS */
/* wayland-qt-windowmanager.c BEGINS */
static const struct wl_interface *qt_windowmanager_types[] = {
NULL,
NULL,
};
static const struct wl_message qt_windowmanager_requests[] = {
{ "open_url", "us", qt_windowmanager_types + 0 },
};
static const struct wl_message qt_windowmanager_events[] = {
{ "hints", "i", qt_windowmanager_types + 0 },
{ "quit", "", qt_windowmanager_types + 0 },
};
const struct wl_interface qt_windowmanager_interface = {
"qt_windowmanager",
1,
1,
qt_windowmanager_requests,
2,
qt_windowmanager_events,
};
/* wayland-qt-windowmanager.c ENDS */
/* wayland-qt-surface-extension.c BEGINS */
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
extern const struct wl_interface wl_surface_interface;
#endif
static const struct wl_interface *qt_surface_extension_types[] = {
NULL,
NULL,
&qt_extended_surface_interface,
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
/* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ?
* The value comes from auto generated code and does
* not appear to actually be used anywhere
*/
NULL,
#else
&wl_surface_interface,
#endif
};
static const struct wl_message qt_surface_extension_requests[] = {
{ "get_extended_surface", "no", qt_surface_extension_types + 2 },
};
const struct wl_interface qt_surface_extension_interface = {
"qt_surface_extension",
1,
1,
qt_surface_extension_requests,
0,
NULL,
};
static const struct wl_message qt_extended_surface_requests[] = {
{ "update_generic_property", "sa", qt_surface_extension_types + 0 },
{ "set_content_orientation", "i", qt_surface_extension_types + 0 },
{ "set_window_flags", "i", qt_surface_extension_types + 0 },
};
static const struct wl_message qt_extended_surface_events[] = {
{ "onscreen_visibility", "i", qt_surface_extension_types + 0 },
{ "set_generic_property", "sa", qt_surface_extension_types + 0 },
{ "close", "", qt_surface_extension_types + 0 },
};
const struct wl_interface qt_extended_surface_interface = {
"qt_extended_surface",
1,
3,
qt_extended_surface_requests,
3,
qt_extended_surface_events,
};
/* wayland-qt-surface-extension.c ENDS */
void Wayland_touch_create(SDL_VideoData *data, uint32_t id)
{
struct SDL_WaylandTouch *touch;
if (data->touch) {
Wayland_touch_destroy(data);
}
/* !!! FIXME: check for failure, call SDL_OutOfMemory() */
data->touch = SDL_malloc(sizeof(struct SDL_WaylandTouch));
touch = data->touch;
touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1);
qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data);
}
void Wayland_touch_destroy(SDL_VideoData *data)
{
if (data->touch) {
struct SDL_WaylandTouch *touch = data->touch;
if (touch->touch_extension) {
qt_touch_extension_destroy(touch->touch_extension);
}
SDL_free(data->touch);
data->touch = NULL;
}
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */

View File

@@ -1,334 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_waylandtouch_h_
#define SDL_waylandtouch_h_
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
#include "SDL_waylandvideo.h"
#include <stdint.h>
#include <stddef.h>
#include "wayland-util.h"
void Wayland_touch_create(SDL_VideoData *data, uint32_t id);
void Wayland_touch_destroy(SDL_VideoData *data);
struct qt_touch_extension;
/* Autogenerated QT headers */
/*
Support for Wayland with QmlCompositor as Server
================================================
The Wayland video driver has support for some additional features when
using QtWayland's "qmlcompositor" as Wayland server. This is needed for touch
input when running SDL applications under a qmlcompositor Wayland server.
The files following headers have been
generated from the Wayland XML Protocol Definition in QtWayland as follows:
Clone QtWayland from Git:
http://qt.gitorious.org/qt/qtwayland/
Generate headers and glue code:
for extension in touch-extension surface-extension windowmanager; do
wayland-scanner client-header < src/extensions/$extension.xml > wayland-qt-$extension.h
wayland-scanner code < src/extensions/$extension.xml > wayland-qt-$extension.c
done
*/
/* wayland-qt-surface-extension.h */
struct wl_client;
struct wl_resource;
struct qt_surface_extension;
struct qt_extended_surface;
extern const struct wl_interface qt_surface_extension_interface;
extern const struct wl_interface qt_extended_surface_interface;
#define QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE 0
static inline void qt_surface_extension_set_user_data(struct qt_surface_extension *qt_surface_extension, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *)qt_surface_extension, user_data);
}
static inline void *qt_surface_extension_get_user_data(struct qt_surface_extension *qt_surface_extension)
{
return wl_proxy_get_user_data((struct wl_proxy *)qt_surface_extension);
}
static inline void qt_surface_extension_destroy(struct qt_surface_extension *qt_surface_extension)
{
WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_surface_extension);
}
static inline struct qt_extended_surface *qt_surface_extension_get_extended_surface(struct qt_surface_extension *qt_surface_extension, struct wl_surface *surface)
{
struct wl_proxy *id;
id = wl_proxy_create((struct wl_proxy *)qt_surface_extension,
&qt_extended_surface_interface);
if (id == NULL)
return NULL;
WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_surface_extension,
QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE, id, surface);
return (struct qt_extended_surface *)id;
}
#ifndef QT_EXTENDED_SURFACE_ORIENTATION_ENUM
#define QT_EXTENDED_SURFACE_ORIENTATION_ENUM
enum qt_extended_surface_orientation
{
QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION = 0,
QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION = 1,
QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION = 2,
QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION = 4,
QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION = 8,
};
#endif /* QT_EXTENDED_SURFACE_ORIENTATION_ENUM */
#ifndef QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM
#define QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM
enum qt_extended_surface_windowflag
{
QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES = 1,
QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP = 2,
};
#endif /* QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM */
struct qt_extended_surface_listener
{
/**
* onscreen_visibility - (none)
* @visible: (none)
*/
void (*onscreen_visibility)(void *data,
struct qt_extended_surface *qt_extended_surface,
int32_t visible);
/**
* set_generic_property - (none)
* @name: (none)
* @value: (none)
*/
void (*set_generic_property)(void *data,
struct qt_extended_surface *qt_extended_surface,
const char *name,
struct wl_array *value);
/**
* close - (none)
*/
void (*close)(void *data,
struct qt_extended_surface *qt_extended_surface);
};
static inline int qt_extended_surface_add_listener(struct qt_extended_surface *qt_extended_surface,
const struct qt_extended_surface_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *)qt_extended_surface,
(void (**)(void))listener, data);
}
#define QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY 0
#define QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION 1
#define QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS 2
static inline void qt_extended_surface_set_user_data(struct qt_extended_surface *qt_extended_surface, void *user_data)
{
WAYLAND_wl_proxy_set_user_data((struct wl_proxy *)qt_extended_surface, user_data);
}
static inline void *qt_extended_surface_get_user_data(struct qt_extended_surface *qt_extended_surface)
{
return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *)qt_extended_surface);
}
static inline void qt_extended_surface_destroy(struct qt_extended_surface *qt_extended_surface)
{
WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_extended_surface);
}
static inline void qt_extended_surface_update_generic_property(struct qt_extended_surface *qt_extended_surface, const char *name, struct wl_array *value)
{
WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_extended_surface,
QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY, name, value);
}
static inline void qt_extended_surface_set_content_orientation(struct qt_extended_surface *qt_extended_surface, int32_t orientation)
{
WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_extended_surface,
QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION, orientation);
}
static inline void qt_extended_surface_set_window_flags(struct qt_extended_surface *qt_extended_surface, int32_t flags)
{
WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_extended_surface,
QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS, flags);
}
/* wayland-qt-touch-extension.h */
extern const struct wl_interface qt_touch_extension_interface;
#ifndef QT_TOUCH_EXTENSION_FLAGS_ENUM
#define QT_TOUCH_EXTENSION_FLAGS_ENUM
enum qt_touch_extension_flags
{
QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH = 0x1,
};
#endif /* QT_TOUCH_EXTENSION_FLAGS_ENUM */
struct qt_touch_extension_listener
{
/**
* touch - (none)
* @time: (none)
* @id: (none)
* @state: (none)
* @x: (none)
* @y: (none)
* @normalized_x: (none)
* @normalized_y: (none)
* @width: (none)
* @height: (none)
* @pressure: (none)
* @velocity_x: (none)
* @velocity_y: (none)
* @flags: (none)
* @rawdata: (none)
*/
void (*touch)(void *data,
struct qt_touch_extension *qt_touch_extension,
uint32_t time,
uint32_t id,
uint32_t state,
int32_t x,
int32_t y,
int32_t normalized_x,
int32_t normalized_y,
int32_t width,
int32_t height,
uint32_t pressure,
int32_t velocity_x,
int32_t velocity_y,
uint32_t flags,
struct wl_array *rawdata);
/**
* configure - (none)
* @flags: (none)
*/
void (*configure)(void *data,
struct qt_touch_extension *qt_touch_extension,
uint32_t flags);
};
static inline int qt_touch_extension_add_listener(struct qt_touch_extension *qt_touch_extension,
const struct qt_touch_extension_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *)qt_touch_extension,
(void (**)(void))listener, data);
}
#define QT_TOUCH_EXTENSION_DUMMY 0
static inline void qt_touch_extension_set_user_data(struct qt_touch_extension *qt_touch_extension, void *user_data)
{
WAYLAND_wl_proxy_set_user_data((struct wl_proxy *)qt_touch_extension, user_data);
}
static inline void *qt_touch_extension_get_user_data(struct qt_touch_extension *qt_touch_extension)
{
return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *)qt_touch_extension);
}
static inline void qt_touch_extension_destroy(struct qt_touch_extension *qt_touch_extension)
{
WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_touch_extension);
}
static inline void qt_touch_extension_dummy(struct qt_touch_extension *qt_touch_extension)
{
WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_touch_extension,
QT_TOUCH_EXTENSION_DUMMY);
}
/* wayland-qt-windowmanager.h */
extern const struct wl_interface qt_windowmanager_interface;
struct qt_windowmanager_listener
{
/**
* hints - (none)
* @show_is_fullscreen: (none)
*/
void (*hints)(void *data,
struct qt_windowmanager *qt_windowmanager,
int32_t show_is_fullscreen);
/**
* quit - (none)
*/
void (*quit)(void *data,
struct qt_windowmanager *qt_windowmanager);
};
static inline int qt_windowmanager_add_listener(struct qt_windowmanager *qt_windowmanager,
const struct qt_windowmanager_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *)qt_windowmanager,
(void (**)(void))listener, data);
}
#define QT_WINDOWMANAGER_OPEN_URL 0
static inline void qt_windowmanager_set_user_data(struct qt_windowmanager *qt_windowmanager, void *user_data)
{
WAYLAND_wl_proxy_set_user_data((struct wl_proxy *)qt_windowmanager, user_data);
}
static inline void *qt_windowmanager_get_user_data(struct qt_windowmanager *qt_windowmanager)
{
return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *)qt_windowmanager);
}
static inline void qt_windowmanager_destroy(struct qt_windowmanager *qt_windowmanager)
{
WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_windowmanager);
}
static inline void qt_windowmanager_open_url(struct qt_windowmanager *qt_windowmanager, uint32_t remaining, const char *url)
{
WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_windowmanager,
QT_WINDOWMANAGER_OPEN_URL, remaining, url);
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
#endif /* SDL_waylandtouch_h_ */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -32,7 +32,6 @@
#include "SDL_waylandopengles.h"
#include "SDL_waylandmouse.h"
#include "SDL_waylandkeyboard.h"
#include "SDL_waylandtouch.h"
#include "SDL_waylandclipboard.h"
#include "SDL_waylandvulkan.h"
@@ -55,6 +54,8 @@
#include "primary-selection-unstable-v1-client-protocol.h"
#include "fractional-scale-v1-client-protocol.h"
#include "input-timestamps-unstable-v1-client-protocol.h"
#include "relative-pointer-unstable-v1-client-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
#ifdef HAVE_LIBDECOR_H
#include <libdecor.h>
@@ -105,12 +106,45 @@ SDL_bool SDL_WAYLAND_own_output(struct wl_output *output)
return wl_proxy_get_tag((struct wl_proxy *)output) == &SDL_WAYLAND_output_tag;
}
/* External surfaces may have their own user data attached, the modification of which
* can cause problems with external toolkits. Instead, external windows are kept in
* their own list, and a search is conducted to find a matching surface.
*/
static struct wl_list external_window_list;
void Wayland_AddWindowDataToExternalList(SDL_WindowData *data)
{
WAYLAND_wl_list_insert(&external_window_list, &data->external_window_list_link);
}
void Wayland_RemoveWindowDataFromExternalList(SDL_WindowData *data)
{
WAYLAND_wl_list_remove(&data->external_window_list_link);
}
SDL_WindowData *Wayland_GetWindowDataForOwnedSurface(struct wl_surface *surface)
{
if (SDL_WAYLAND_own_surface(surface)) {
return (SDL_WindowData *)wl_surface_get_user_data(surface);
} else if (!WAYLAND_wl_list_empty(&external_window_list)) {
SDL_WindowData *p;
wl_list_for_each (p, &external_window_list, external_window_list_link) {
if (p->surface == surface) {
return p;
}
}
}
return NULL;
}
static void Wayland_DeleteDevice(SDL_VideoDevice *device)
{
SDL_VideoData *data = device->driverdata;
if (data->display) {
if (data->display && !data->display_externally_owned) {
WAYLAND_wl_display_flush(data->display);
WAYLAND_wl_display_disconnect(data->display);
SDL_ClearProperty(SDL_GetGlobalProperties(), SDL_PROPERTY_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER);
}
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
@@ -124,40 +158,57 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
{
SDL_VideoDevice *device;
SDL_VideoData *data;
struct wl_display *display;
struct wl_display *display = SDL_GetProperty(SDL_GetGlobalProperties(),
SDL_PROPERTY_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER, NULL);
SDL_bool display_is_external = !!display;
/* Are we trying to connect to or are currently in a Wayland session? */
if (!SDL_getenv("WAYLAND_DISPLAY")) {
const char *session = SDL_getenv("XDG_SESSION_TYPE");
if (session && SDL_strcasecmp(session, "wayland") != 0) {
return NULL;
}
}
if (!SDL_WAYLAND_LoadSymbols()) {
return NULL;
}
display = WAYLAND_wl_display_connect(NULL);
if (display == NULL) {
SDL_WAYLAND_UnloadSymbols();
return NULL;
if (!display) {
display = WAYLAND_wl_display_connect(NULL);
if (!display) {
SDL_WAYLAND_UnloadSymbols();
return NULL;
}
}
data = SDL_calloc(1, sizeof(*data));
if (data == NULL) {
if (!data) {
WAYLAND_wl_display_disconnect(display);
SDL_WAYLAND_UnloadSymbols();
SDL_OutOfMemory();
return NULL;
}
data->initializing = SDL_TRUE;
data->display = display;
data->display_externally_owned = display_is_external;
WAYLAND_wl_list_init(&data->output_list);
WAYLAND_wl_list_init(&external_window_list);
/* Initialize all variables that we clean on shutdown */
device = SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device == NULL) {
if (!device) {
SDL_free(data);
WAYLAND_wl_display_disconnect(display);
SDL_WAYLAND_UnloadSymbols();
SDL_OutOfMemory();
return NULL;
}
if (!display_is_external) {
SDL_SetProperty(SDL_GetGlobalProperties(),
SDL_PROPERTY_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER, display);
}
device->driverdata = data;
device->wakeup_lock = SDL_CreateMutex();
@@ -165,7 +216,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
device->VideoInit = Wayland_VideoInit;
device->VideoQuit = Wayland_VideoQuit;
device->GetDisplayBounds = Wayland_GetDisplayBounds;
device->GetWindowWMInfo = Wayland_GetWindowWMInfo;
device->SuspendScreenSaver = Wayland_SuspendScreenSaver;
device->PumpEvents = Wayland_PumpEvents;
@@ -210,6 +260,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
device->FlashWindow = Wayland_FlashWindow;
device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport;
device->ShowWindowSystemMenu = Wayland_ShowWindowSystemMenu;
device->SyncWindow = Wayland_SyncWindow;
#ifdef SDL_USE_LIBDBUS
if (SDL_SystemTheme_Init())
@@ -220,9 +271,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
device->SetClipboardData = Wayland_SetClipboardData;
device->GetClipboardData = Wayland_GetClipboardData;
device->HasClipboardData = Wayland_HasClipboardData;
device->SetPrimarySelectionText = Wayland_SetPrimarySelectionText;
device->GetPrimarySelectionText = Wayland_GetPrimarySelectionText;
device->HasPrimarySelectionText = Wayland_HasPrimarySelectionText;
device->StartTextInput = Wayland_StartTextInput;
device->StopTextInput = Wayland_StopTextInput;
device->SetTextInputRect = Wayland_SetTextInputRect;
@@ -236,9 +284,9 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
device->free = Wayland_DeleteDevice;
device->quirk_flags = VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED |
VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE |
VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT;
device->device_caps = VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED |
VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
return device;
}
@@ -409,7 +457,7 @@ static void display_handle_geometry(void *data,
driverdata->physical_height = physical_height;
/* The model is only used for the output name if wl_output or xdg-output haven't provided a description. */
if (driverdata->display == 0 && driverdata->placeholder.name == NULL) {
if (driverdata->display == 0 && !driverdata->placeholder.name) {
driverdata->placeholder.name = SDL_strdup(model);
}
@@ -568,7 +616,7 @@ static void display_handle_done(void *data,
SDL_SetDesktopDisplayMode(dpy, &desktop_mode);
/* Expose the unscaled, native resolution if the scale is 1.0 or viewports are available... */
if (driverdata->scale_factor == 1.0f || video->viewporter != NULL) {
if (driverdata->scale_factor == 1.0f || video->viewporter) {
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
} else {
/* ...otherwise expose the integer scaled variants of the desktop resolution down to 1. */
@@ -591,7 +639,7 @@ static void display_handle_done(void *data,
if (driverdata->display == 0) {
/* First time getting display info, create the VideoDisplay */
SDL_bool send_event = driverdata->videodata->initializing ? SDL_FALSE : SDL_TRUE;
SDL_bool send_event = !driverdata->videodata->initializing;
if (driverdata->physical_width >= driverdata->physical_height) {
driverdata->placeholder.natural_orientation = SDL_ORIENTATION_LANDSCAPE;
} else {
@@ -645,7 +693,7 @@ static int Wayland_add_display(SDL_VideoData *d, uint32_t id, uint32_t version)
SDL_DisplayData *data;
output = wl_registry_bind(d->registry, id, &wl_output_interface, version);
if (output == NULL) {
if (!output) {
return SDL_SetError("Failed to retrieve output.");
}
data = (SDL_DisplayData *)SDL_calloc(1, sizeof(*data));
@@ -704,23 +752,6 @@ static void Wayland_init_xdg_output(SDL_VideoData *d)
}
}
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
static void windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
int32_t show_is_fullscreen)
{
}
static void windowmanager_quit(void *data, struct qt_windowmanager *qt_windowmanager)
{
SDL_SendQuit();
}
static const struct qt_windowmanager_listener windowmanager_listener = {
windowmanager_hints,
windowmanager_quit,
};
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
static void handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial)
{
xdg_wm_base_pong(xdg, serial);
@@ -762,9 +793,9 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
} else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
Wayland_display_add_relative_pointer_manager(d, id);
d->relative_pointer_manager = wl_registry_bind(d->registry, id, &zwp_relative_pointer_manager_v1_interface, 1);
} else if (SDL_strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
Wayland_display_add_pointer_constraints(d, id);
d->pointer_constraints = wl_registry_bind(d->registry, id, &zwp_pointer_constraints_v1_interface, 1);
} else if (SDL_strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) {
d->key_inhibitor_manager = wl_registry_bind(d->registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
} else if (SDL_strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
@@ -797,17 +828,6 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
if (d->input) {
Wayland_RegisterTimestampListeners(d->input);
}
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
Wayland_touch_create(d, id);
} else if (SDL_strcmp(interface, "qt_surface_extension") == 0) {
d->surface_extension = wl_registry_bind(registry, id,
&qt_surface_extension_interface, 1);
} else if (SDL_strcmp(interface, "qt_windowmanager") == 0) {
d->windowmanager = wl_registry_bind(registry, id,
&qt_windowmanager_interface, 1);
qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d);
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
}
}
@@ -881,7 +901,7 @@ int Wayland_VideoInit(SDL_VideoDevice *_this)
}
data->registry = wl_display_get_registry(data->display);
if (data->registry == NULL) {
if (!data->registry) {
return SDL_SetError("Failed to get the Wayland registry");
}
@@ -902,6 +922,12 @@ int Wayland_VideoInit(SDL_VideoDevice *_this)
Wayland_InitKeyboard(_this);
if (data->primary_selection_device_manager) {
_this->SetPrimarySelectionText = Wayland_SetPrimarySelectionText;
_this->GetPrimarySelectionText = Wayland_GetPrimarySelectionText;
_this->HasPrimarySelectionText = Wayland_HasPrimarySelectionText;
}
data->initializing = SDL_FALSE;
return 0;
@@ -941,8 +967,16 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this)
}
Wayland_display_destroy_input(data);
Wayland_display_destroy_pointer_constraints(data);
Wayland_display_destroy_relative_pointer_manager(data);
if (data->pointer_constraints) {
zwp_pointer_constraints_v1_destroy(data->pointer_constraints);
data->pointer_constraints = NULL;
}
if (data->relative_pointer_manager) {
zwp_relative_pointer_manager_v1_destroy(data->relative_pointer_manager);
data->relative_pointer_manager = NULL;
}
if (data->activation_manager) {
xdg_activation_v1_destroy(data->activation_manager);
@@ -970,19 +1004,6 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this)
WAYLAND_xkb_context_unref(data->xkb_context);
data->xkb_context = NULL;
}
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
if (data->windowmanager) {
qt_windowmanager_destroy(data->windowmanager);
data->windowmanager = NULL;
}
if (data->surface_extension) {
qt_surface_extension_destroy(data->surface_extension);
data->surface_extension = NULL;
}
Wayland_touch_destroy(data);
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
if (data->tablet_manager) {
zwp_tablet_manager_v2_destroy((struct zwp_tablet_manager_v2 *)data->tablet_manager);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -35,12 +35,6 @@ struct xkb_context;
struct SDL_WaylandInput;
struct SDL_WaylandTabletManager;
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
struct SDL_WaylandTouch;
struct qt_surface_extension;
struct qt_windowmanager;
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
typedef struct
{
struct wl_cursor_theme *theme;
@@ -84,13 +78,8 @@ struct SDL_VideoData
struct SDL_WaylandTabletManager *tablet_manager;
struct wl_list output_list;
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
struct SDL_WaylandTouch *touch;
struct qt_surface_extension *surface_extension;
struct qt_windowmanager *windowmanager;
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
int relative_mouse_mode;
SDL_bool display_externally_owned;
};
struct SDL_DisplayData
@@ -119,6 +108,10 @@ extern void SDL_WAYLAND_register_output(struct wl_output *output);
extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface);
extern SDL_bool SDL_WAYLAND_own_output(struct wl_output *output);
extern SDL_WindowData *Wayland_GetWindowDataForOwnedSurface(struct wl_surface *surface);
void Wayland_AddWindowDataToExternalList(SDL_WindowData *data);
void Wayland_RemoveWindowDataFromExternalList(SDL_WindowData *data);
extern SDL_bool Wayland_LoadLibdecor(SDL_VideoData *data, SDL_bool ignore_xdg);
extern SDL_bool Wayland_VideoReconnect(SDL_VideoDevice *_this);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -28,16 +28,12 @@
#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_WAYLAND)
#include "../SDL_vulkan_internal.h"
#include "SDL_waylandvideo.h"
#include "SDL_waylandwindow.h"
#include "../SDL_vulkan_internal.h"
#include "SDL_waylandvulkan.h"
#include <SDL3/SDL_syswm.h>
#ifdef __OpenBSD__
#define DEFAULT_VULKAN "libvulkan.so"
#else
@@ -56,10 +52,10 @@ int Wayland_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
}
/* Load the Vulkan loader library */
if (path == NULL) {
if (!path) {
path = SDL_getenv("SDL_VULKAN_LIBRARY");
}
if (path == NULL) {
if (!path) {
path = DEFAULT_VULKAN;
}
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
@@ -84,7 +80,7 @@ int Wayland_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
(PFN_vkEnumerateInstanceExtensionProperties)
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
&extensionCount);
if (extensions == NULL) {
if (!extensions) {
goto fail;
}
for (i = 0; i < extensionCount; i++) {
@@ -118,25 +114,23 @@ void Wayland_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
SDL_bool Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
unsigned *count,
const char **names)
char const* const* Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForWayland[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
};
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
if (count) {
*count = SDL_arraysize(extensionsForWayland);
}
return SDL_Vulkan_GetInstanceExtensions_Helper(
count, names, SDL_arraysize(extensionsForWayland),
extensionsForWayland);
return extensionsForWayland;
}
SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
const struct VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface)
{
SDL_WindowData *windowData = window->driverdata;
@@ -165,8 +159,7 @@ SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
createInfo.flags = 0;
createInfo.display = windowData->waylandData->display;
createInfo.surface = windowData->surface;
result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
NULL, surface);
result = vkCreateWaylandSurfaceKHR(instance, &createInfo, allocator, surface);
if (result != VK_SUCCESS) {
SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -36,12 +36,12 @@
int Wayland_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
void Wayland_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
SDL_bool Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
unsigned *count,
const char **names);
char const* const* Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count);
SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
const struct VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -27,8 +27,6 @@
#include "../SDL_sysvideo.h"
#include "../../events/SDL_touch_c.h"
#include <SDL3/SDL_syswm.h>
#include "SDL_waylandvideo.h"
struct SDL_WaylandInput;
@@ -72,7 +70,8 @@ struct SDL_WindowData
WAYLAND_SURFACE_UNKNOWN = 0,
WAYLAND_SURFACE_XDG_TOPLEVEL,
WAYLAND_SURFACE_XDG_POPUP,
WAYLAND_SURFACE_LIBDECOR
WAYLAND_SURFACE_LIBDECOR,
WAYLAND_SURFACE_CUSTOM
} shell_surface_type;
enum
{
@@ -97,15 +96,8 @@ struct SDL_WindowData
struct wp_viewport *draw_viewport;
struct wp_fractional_scale_v1 *fractional_scale;
/* floating dimensions for restoring from maximized and fullscreen */
int floating_width, floating_height;
SDL_AtomicInt swap_interval_ready;
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
struct qt_extended_surface *extended_surface;
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
SDL_DisplayData **outputs;
int num_outputs;
@@ -115,24 +107,37 @@ struct SDL_WindowData
float windowed_scale_factor;
float pointer_scale_x;
float pointer_scale_y;
struct
{
int width, height;
} pending_size_event;
int last_configure_width, last_configure_height;
int requested_window_width, requested_window_height;
int drawable_width, drawable_height;
int wl_window_width, wl_window_height;
int system_min_required_width;
int system_min_required_height;
SDL_DisplayID last_displayID;
int fullscreen_deadline_count;
SDL_bool floating;
SDL_bool suspended;
SDL_bool active;
SDL_bool is_fullscreen;
SDL_bool in_fullscreen_transition;
SDL_bool drop_fullscreen_requests;
SDL_bool fullscreen_was_positioned;
SDL_bool show_hide_sync_required;
SDL_HitTestResult hit_test_result;
struct wl_list external_window_list_link;
};
extern void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
extern int Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
SDL_VideoDisplay *_display,
SDL_bool fullscreen);
extern void Wayland_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
@@ -143,7 +148,7 @@ extern void Wayland_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *wi
extern void Wayland_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
extern void Wayland_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
extern int Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
extern int Wayland_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window *window);
@@ -155,8 +160,8 @@ extern void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
extern void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int Wayland_SuspendScreenSaver(SDL_VideoDevice *_this);
extern int Wayland_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, SDL_SysWMinfo *info);
extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern int Wayland_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
extern int Wayland_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window);
#endif /* SDL_waylandwindow_h_ */