[client] clipboard/wayland: address style nits

This commit is contained in:
Tudor Brindus 2021-01-10 17:27:02 -05:00 committed by Geoffrey McRae
parent bf223158d0
commit 2aa2ec31ef
2 changed files with 150 additions and 150 deletions

View File

@ -26,27 +26,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <unistd.h> #include <unistd.h>
#include <wayland-client.h> #include <wayland-client.h>
struct transfer { struct WCBTransfer
{
void * data; void * data;
size_t size; size_t size;
const char ** mimetypes; const char ** mimetypes;
}; };
struct state struct WCBState
{ {
struct wl_display * display; struct wl_display * display;
struct wl_registry * registry; struct wl_registry * registry;
struct wl_data_device_manager * data_device_manager; struct wl_data_device_manager * dataDeviceManager;
struct wl_seat * seat; struct wl_seat * seat;
struct wl_data_device * data_device; struct wl_data_device * dataDevice;
enum LG_ClipboardData stashed_type; enum LG_ClipboardData stashedType;
char * stashed_mimetype; char * stashedMimetype;
uint8_t * stashed_contents; uint8_t * stashedContents;
ssize_t stashed_size; ssize_t stashedSize;
struct wl_keyboard * keyboard; struct wl_keyboard * keyboard;
uint32_t keyboard_enter_serial; uint32_t keyboardEnterSerial;
uint32_t capabilities; uint32_t capabilities;
LG_ClipboardReleaseFn releaseFn; LG_ClipboardReleaseFn releaseFn;
@ -56,9 +57,9 @@ struct state
LG_ClipboardData type; LG_ClipboardData type;
}; };
static struct state * this = NULL; static struct WCBState * this = NULL;
static const char * text_mimetypes[] = static const char * textMimetypes[] =
{ {
"text/plain", "text/plain",
"text/plain;charset=utf-8", "text/plain;charset=utf-8",
@ -68,13 +69,13 @@ static const char * text_mimetypes[] =
NULL, NULL,
}; };
static const char * png_mimetypes[] = static const char * pngMimetypes[] =
{ {
"image/png", "image/png",
NULL, NULL,
}; };
static const char * bmp_mimetypes[] = static const char * bmpMimetypes[] =
{ {
"image/bmp", "image/bmp",
"image/x-bmp", "image/x-bmp",
@ -83,39 +84,39 @@ static const char * bmp_mimetypes[] =
NULL, NULL,
}; };
static const char * tiff_mimetypes[] = static const char * tiffMimetypes[] =
{ {
"image/tiff", "image/tiff",
NULL, NULL,
}; };
static const char * jpeg_mimetypes[] = static const char * jpegMimetypes[] =
{ {
"image/jpeg", "image/jpeg",
NULL, NULL,
}; };
static const char ** cb_type_to_mimetypes(enum LG_ClipboardData type) static const char ** cbTypeToMimetypes(enum LG_ClipboardData type)
{ {
switch (type) switch (type)
{ {
case LG_CLIPBOARD_DATA_TEXT: case LG_CLIPBOARD_DATA_TEXT:
return text_mimetypes; return textMimetypes;
case LG_CLIPBOARD_DATA_PNG: case LG_CLIPBOARD_DATA_PNG:
return png_mimetypes; return pngMimetypes;
case LG_CLIPBOARD_DATA_BMP: case LG_CLIPBOARD_DATA_BMP:
return bmp_mimetypes; return bmpMimetypes;
case LG_CLIPBOARD_DATA_TIFF: case LG_CLIPBOARD_DATA_TIFF:
return tiff_mimetypes; return tiffMimetypes;
case LG_CLIPBOARD_DATA_JPEG: case LG_CLIPBOARD_DATA_JPEG:
return jpeg_mimetypes; return jpegMimetypes;
default: default:
DEBUG_ERROR("invalid clipboard type"); DEBUG_ERROR("invalid clipboard type");
abort(); abort();
} }
} }
static bool contains_mimetype(const char ** mimetypes, static bool containsMimetype(const char ** mimetypes,
const char * needle) const char * needle)
{ {
for (const char ** mimetype = mimetypes; *mimetype; mimetype++) for (const char ** mimetype = mimetypes; *mimetype; mimetype++)
@ -125,29 +126,29 @@ static bool contains_mimetype(const char ** mimetypes,
return false; return false;
} }
static bool mimetype_endswith(const char * mimetype, const char * what) static bool mimetypeEndswith(const char * mimetype, const char * what)
{ {
size_t mimetype_len = strlen(mimetype); size_t mimetypeLen = strlen(mimetype);
size_t what_len = strlen(what); size_t whatLen = strlen(what);
if (mimetype_len < what_len) if (mimetypeLen < whatLen)
return false; return false;
return !strcmp(mimetype + mimetype_len - what_len, what); return !strcmp(mimetype + mimetypeLen - whatLen, what);
} }
static bool is_text_mimetype(const char * mimetype) static bool isTextMimetype(const char * mimetype)
{ {
if (contains_mimetype(text_mimetypes, mimetype)) if (containsMimetype(textMimetypes, mimetype))
return true; return true;
char * text = "text/"; char * text = "text/";
if (!strncmp(mimetype, text, strlen(text))) if (!strncmp(mimetype, text, strlen(text)))
return true; return true;
if (mimetype_endswith(mimetype, "script") || if (mimetypeEndswith(mimetype, "script") ||
mimetype_endswith(mimetype, "xml") || mimetypeEndswith(mimetype, "xml") ||
mimetype_endswith(mimetype, "yaml")) mimetypeEndswith(mimetype, "yaml"))
return true; return true;
if (strstr(mimetype, "json")) if (strstr(mimetype, "json"))
@ -156,21 +157,21 @@ static bool is_text_mimetype(const char * mimetype)
return false; return false;
} }
static enum LG_ClipboardData mimetype_to_cb_type(const char * mimetype) static enum LG_ClipboardData mimetypeToCbType(const char * mimetype)
{ {
if (is_text_mimetype(mimetype)) if (isTextMimetype(mimetype))
return LG_CLIPBOARD_DATA_TEXT; return LG_CLIPBOARD_DATA_TEXT;
if (contains_mimetype(png_mimetypes, mimetype)) if (containsMimetype(pngMimetypes, mimetype))
return LG_CLIPBOARD_DATA_PNG; return LG_CLIPBOARD_DATA_PNG;
if (contains_mimetype(bmp_mimetypes, mimetype)) if (containsMimetype(bmpMimetypes, mimetype))
return LG_CLIPBOARD_DATA_BMP; return LG_CLIPBOARD_DATA_BMP;
if (contains_mimetype(tiff_mimetypes, mimetype)) if (containsMimetype(tiffMimetypes, mimetype))
return LG_CLIPBOARD_DATA_TIFF; return LG_CLIPBOARD_DATA_TIFF;
if (contains_mimetype(jpeg_mimetypes, mimetype)) if (containsMimetype(jpegMimetypes, mimetype))
return LG_CLIPBOARD_DATA_JPEG; return LG_CLIPBOARD_DATA_JPEG;
return LG_CLIPBOARD_DATA_NONE; return LG_CLIPBOARD_DATA_NONE;
@ -183,87 +184,84 @@ static const char * wayland_cb_getName()
// Keyboard-handling listeners. // Keyboard-handling listeners.
static void keyboard_keymap_handler( static void keyboardKeymapHandler(void * data, struct wl_keyboard * keyboard,
void * data, uint32_t format, int fd, uint32_t size)
struct wl_keyboard * keyboard, {
uint32_t format, close(fd);
int fd,
uint32_t size
) {
close(fd);
} }
static void keyboard_enter_handler(void * data, struct wl_keyboard * keyboard, static void keyboardEnterHandler(void * data, struct wl_keyboard * keyboard,
uint32_t serial, struct wl_surface * surface, struct wl_array * keys) uint32_t serial, struct wl_surface * surface, struct wl_array * keys)
{ {
this->keyboard_enter_serial = serial; this->keyboardEnterSerial = serial;
} }
static void keyboard_leave_handler(void * data, struct wl_keyboard * keyboard, static void keyboardLeaveHandler(void * data, struct wl_keyboard * keyboard,
uint32_t serial, struct wl_surface * surface) uint32_t serial, struct wl_surface * surface)
{ {
// Do nothing. // Do nothing.
} }
static void keyboard_key_handler(void * data, struct wl_keyboard * keyboard, static void keyboardKeyHandler(void * data, struct wl_keyboard * keyboard,
uint32_t serial, uint32_t time, uint32_t key, uint32_t state) uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
{ {
// Do nothing. // Do nothing.
} }
static void keyboard_modifiers_handler(void * data, static void keyboardModifiersHandler(void * data,
struct wl_keyboard * keyboard, uint32_t serial, uint32_t mods_depressed, struct wl_keyboard * keyboard, uint32_t serial, uint32_t modsDepressed,
uint32_t mods_latched, uint32_t mods_locked, uint32_t group) uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
{ {
// Do nothing. // Do nothing.
} }
static const struct wl_keyboard_listener keyboard_listener = { static const struct wl_keyboard_listener keyboardListener = {
.keymap = keyboard_keymap_handler, .keymap = keyboardKeymapHandler,
.enter = keyboard_enter_handler, .enter = keyboardEnterHandler,
.leave = keyboard_leave_handler, .leave = keyboardLeaveHandler,
.key = keyboard_key_handler, .key = keyboardKeyHandler,
.modifiers = keyboard_modifiers_handler, .modifiers = keyboardModifiersHandler,
}; };
// Seat-handling listeners. // Seat-handling listeners.
static void seat_capabilities_handler(void * data, struct wl_seat * seat, static void seatCapabilitiesHandler(void * data, struct wl_seat * seat,
uint32_t capabilities) uint32_t capabilities)
{ {
this->capabilities = capabilities; this->capabilities = capabilities;
bool has_keyboard = capabilities & WL_SEAT_CAPABILITY_KEYBOARD; bool hasKeyboard = capabilities & WL_SEAT_CAPABILITY_KEYBOARD;
if (!has_keyboard && this->keyboard) if (!hasKeyboard && this->keyboard)
{ {
wl_keyboard_destroy(this->keyboard); wl_keyboard_destroy(this->keyboard);
this->keyboard = NULL; this->keyboard = NULL;
} }
else if (has_keyboard && !this->keyboard) else if (hasKeyboard && !this->keyboard)
{ {
this->keyboard = wl_seat_get_keyboard(this->seat); this->keyboard = wl_seat_get_keyboard(this->seat);
wl_keyboard_add_listener(this->keyboard, &keyboard_listener, NULL); wl_keyboard_add_listener(this->keyboard, &keyboardListener, NULL);
} }
} }
static void seat_name_handler(void * data, struct wl_seat * seat, static void seatNameHandler(void * data, struct wl_seat * seat,
const char * name) const char * name)
{ {
// Do nothing. // Do nothing.
} }
static const struct wl_seat_listener seat_listener = { static const struct wl_seat_listener seatListener = {
.capabilities = seat_capabilities_handler, .capabilities = seatCapabilitiesHandler,
.name = seat_name_handler .name = seatNameHandler
}; };
// Registry-handling listeners. // Registry-handling listeners.
static void registry_global_handler(void * data, static void registryGlobalHandler(void * data,
struct wl_registry * wl_registry, uint32_t name, const char * interface, struct wl_registry * registry, uint32_t name, const char * interface,
uint32_t version) { uint32_t version)
{
if (!strcmp(interface, wl_data_device_manager_interface.name)) if (!strcmp(interface, wl_data_device_manager_interface.name))
this->data_device_manager = wl_registry_bind(this->registry, name, this->dataDeviceManager = wl_registry_bind(this->registry, name,
&wl_data_device_manager_interface, 3); &wl_data_device_manager_interface, 3);
else if (!strcmp(interface, wl_seat_interface.name) && !this->seat) else if (!strcmp(interface, wl_seat_interface.name) && !this->seat)
// TODO: multi-seat support. // TODO: multi-seat support.
@ -271,49 +269,50 @@ static void registry_global_handler(void * data,
&wl_seat_interface, 1); &wl_seat_interface, 1);
} }
static void registry_global_remove_handler(void * data, static void registryGlobalRemoveHandler(void * data,
struct wl_registry * wl_registry, uint32_t name) { struct wl_registry * registry, uint32_t name)
{
// Do nothing. // Do nothing.
} }
static const struct wl_registry_listener registry_listener = { static const struct wl_registry_listener registryListener = {
.global = registry_global_handler, .global = registryGlobalHandler,
.global_remove = registry_global_remove_handler, .global_remove = registryGlobalRemoveHandler,
}; };
// Destination client handlers. // Destination client handlers.
static void wl_data_handle_offer(void * data, struct wl_data_offer * offer, static void dataHandleOffer(void * data, struct wl_data_offer * offer,
const char * mimetype) const char * mimetype)
{ {
enum LG_ClipboardData type = mimetype_to_cb_type(mimetype); enum LG_ClipboardData type = mimetypeToCbType(mimetype);
// Oftentimes we'll get text/html alongside text/png, but would prefer to send // Oftentimes we'll get text/html alongside text/png, but would prefer to send
// image/png. In general, prefer images over text content. // image/png. In general, prefer images over text content.
if (type != LG_CLIPBOARD_DATA_NONE && if (type != LG_CLIPBOARD_DATA_NONE &&
(this->stashed_type == LG_CLIPBOARD_DATA_NONE || (this->stashedType == LG_CLIPBOARD_DATA_NONE ||
this->stashed_type == LG_CLIPBOARD_DATA_TEXT)) this->stashedType == LG_CLIPBOARD_DATA_TEXT))
{ {
this->stashed_type = type; this->stashedType = type;
if (this->stashed_mimetype) if (this->stashedMimetype)
free(this->stashed_mimetype); free(this->stashedMimetype);
this->stashed_mimetype = strdup(mimetype); this->stashedMimetype = strdup(mimetype);
} }
} }
static const struct wl_data_offer_listener data_offer_listener = { static const struct wl_data_offer_listener dataOfferListener = {
.offer = wl_data_handle_offer, .offer = dataHandleOffer,
}; };
static void wl_data_device_handle_data_offer(void * data, static void dataDeviceHandleDataOffer(void * data,
struct wl_data_device * data_device, struct wl_data_offer * offer) struct wl_data_device * dataDevice, struct wl_data_offer * offer)
{ {
wl_data_offer_add_listener(offer, &data_offer_listener, NULL); wl_data_offer_add_listener(offer, &dataOfferListener, NULL);
} }
static void wl_data_device_handle_selection(void * data, static void dataDeviceHandleSelection(void * data,
struct wl_data_device * data_device, struct wl_data_offer * offer) struct wl_data_device * dataDevice, struct wl_data_offer * offer)
{ {
if (this->stashed_type == LG_CLIPBOARD_DATA_NONE || !offer) if (this->stashedType == LG_CLIPBOARD_DATA_NONE || !offer)
return; return;
int fds[2]; int fds[2];
@ -323,24 +322,24 @@ static void wl_data_device_handle_selection(void * data,
abort(); abort();
} }
wl_data_offer_receive(offer, this->stashed_mimetype, fds[1]); wl_data_offer_receive(offer, this->stashedMimetype, fds[1]);
close(fds[1]); close(fds[1]);
free(this->stashed_mimetype); free(this->stashedMimetype);
this->stashed_mimetype = NULL; this->stashedMimetype = NULL;
wl_display_roundtrip(this->display); wl_display_roundtrip(this->display);
if (this->stashed_contents) if (this->stashedContents)
{ {
free(this->stashed_contents); free(this->stashedContents);
this->stashed_contents = NULL; this->stashedContents = NULL;
} }
size_t size = 4096, num_read = 0; size_t size = 4096, numRead = 0;
uint8_t * buf = (uint8_t *) malloc(size); uint8_t * buf = (uint8_t *) malloc(size);
while (true) while (true)
{ {
ssize_t result = read(fds[0], buf + num_read, size - num_read); ssize_t result = read(fds[0], buf + numRead, size - numRead);
if (result < 0) if (result < 0)
{ {
DEBUG_ERROR("Failed to read from clipboard: %s", strerror(errno)); DEBUG_ERROR("Failed to read from clipboard: %s", strerror(errno));
@ -349,12 +348,12 @@ static void wl_data_device_handle_selection(void * data,
if (result == 0) if (result == 0)
{ {
buf[num_read] = 0; buf[numRead] = 0;
break; break;
} }
num_read += result; numRead += result;
if (num_read >= size) if (numRead >= size)
{ {
size *= 2; size *= 2;
void * nbuf = realloc(buf, size); void * nbuf = realloc(buf, size);
@ -367,27 +366,27 @@ static void wl_data_device_handle_selection(void * data,
} }
} }
this->stashed_size = num_read; this->stashedSize = numRead;
this->stashed_contents = buf; this->stashedContents = buf;
close(fds[0]); close(fds[0]);
wl_data_offer_destroy(offer); wl_data_offer_destroy(offer);
this->notifyFn(this->stashed_type, 0); this->notifyFn(this->stashedType, 0);
} }
static const struct wl_data_device_listener dataDeviceListener = {
.data_offer = dataDeviceHandleDataOffer,
.selection = dataDeviceHandleSelection,
};
static void wayland_cb_request(LG_ClipboardData type) static void wayland_cb_request(LG_ClipboardData type)
{ {
// We only notified once, so it must be this. // We only notified once, so it must be this.
assert(type == this->stashed_type); assert(type == this->stashedType);
this->dataFn(this->stashed_type, this->stashed_contents, this->stashed_size); this->dataFn(this->stashedType, this->stashedContents, this->stashedSize);
} }
static const struct wl_data_device_listener data_device_listener = {
.data_offer = wl_data_device_handle_data_offer,
.selection = wl_data_device_handle_selection,
};
// End of Wayland handlers. // End of Wayland handlers.
static bool wayland_cb_init( static bool wayland_cb_init(
@ -397,30 +396,28 @@ static bool wayland_cb_init(
LG_ClipboardDataFn dataFn) LG_ClipboardDataFn dataFn)
{ {
if (wminfo->subsystem != SDL_SYSWM_WAYLAND) if (wminfo->subsystem != SDL_SYSWM_WAYLAND)
{
return false; return false;
}
this = (struct state *)malloc(sizeof(struct state)); this = (struct WCBState *)malloc(sizeof(struct WCBState));
memset(this, 0, sizeof(struct state)); memset(this, 0, sizeof(struct WCBState));
this->releaseFn = releaseFn; this->releaseFn = releaseFn;
this->notifyFn = notifyFn; this->notifyFn = notifyFn;
this->dataFn = dataFn; this->dataFn = dataFn;
this->display = wminfo->info.wl.display; this->display = wminfo->info.wl.display;
this->registry = wl_display_get_registry(this->display); this->registry = wl_display_get_registry(this->display);
this->stashed_type = LG_CLIPBOARD_DATA_NONE; this->stashedType = LG_CLIPBOARD_DATA_NONE;
// Wait for the initial set of globals to appear. // Wait for the initial set of globals to appear.
wl_registry_add_listener(this->registry, &registry_listener, NULL); wl_registry_add_listener(this->registry, &registryListener, NULL);
wl_display_roundtrip(this->display); wl_display_roundtrip(this->display);
this->data_device = wl_data_device_manager_get_data_device( this->dataDevice = wl_data_device_manager_get_data_device(
this->data_device_manager, this->seat); this->dataDeviceManager, this->seat);
wl_data_device_add_listener(this->data_device, &data_device_listener, NULL); wl_data_device_add_listener(this->dataDevice, &dataDeviceListener, NULL);
// Wait for the compositor to let us know of capabilities. // Wait for the compositor to let us know of capabilities.
wl_seat_add_listener(this->seat, &seat_listener, NULL); wl_seat_add_listener(this->seat, &seatListener, NULL);
wl_display_roundtrip(this->display); wl_display_roundtrip(this->display);
return true; return true;
} }
@ -435,10 +432,11 @@ static void wayland_cb_wmevent(SDL_SysWMmsg * msg)
{ {
} }
static void data_source_handle_send(void * data, struct wl_data_source * source, static void dataSourceHandleSend(void * data, struct wl_data_source * source,
const char * mimetype, int fd) { const char * mimetype, int fd)
struct transfer * transfer = (struct transfer *) data; {
if (contains_mimetype(transfer->mimetypes, mimetype)) struct WCBTransfer * transfer = (struct WCBTransfer *) data;
if (containsMimetype(transfer->mimetypes, mimetype))
{ {
// Consider making this do non-blocking sends to not stall the Wayland // Consider making this do non-blocking sends to not stall the Wayland
// event loop if it becomes a problem. This is "fine" in the sense that // event loop if it becomes a problem. This is "fine" in the sense that
@ -464,41 +462,44 @@ error:
close(fd); close(fd);
} }
static void data_source_handle_cancelled(void * data, static void dataSourceHandleCancelled(void * data,
struct wl_data_source * source) { struct wl_data_source * source)
struct transfer * transfer = (struct transfer *) data; {
struct WCBTransfer * transfer = (struct WCBTransfer *) data;
free(transfer->data); free(transfer->data);
free(transfer); free(transfer);
wl_data_source_destroy(source); wl_data_source_destroy(source);
} }
static const struct wl_data_source_listener data_source_listener = { static const struct wl_data_source_listener dataSourceListener = {
.send = data_source_handle_send, .send = dataSourceHandleSend,
.cancelled = data_source_handle_cancelled, .cancelled = dataSourceHandleCancelled,
}; };
static void wayland_cb_reply_fn(void * opaque, LG_ClipboardData type, uint8_t * data, uint32_t size) static void wayland_cb_reply_fn(void * opaque, LG_ClipboardData type,
uint8_t * data, uint32_t size)
{ {
struct transfer * transfer = malloc(sizeof(struct transfer)); struct WCBTransfer * transfer = malloc(sizeof(struct WCBTransfer));
void * data_copy = malloc(size); void * dataCopy = malloc(size);
memcpy(data_copy, data, size); memcpy(dataCopy, data, size);
*transfer = (struct transfer) { *transfer = (struct WCBTransfer) {
.data = data_copy, .data = dataCopy,
.size = size, .size = size,
.mimetypes = cb_type_to_mimetypes(type), .mimetypes = cbTypeToMimetypes(type),
}; };
struct wl_data_source * source = struct wl_data_source * source =
wl_data_device_manager_create_data_source(this->data_device_manager); wl_data_device_manager_create_data_source(this->dataDeviceManager);
wl_data_source_add_listener(source, &data_source_listener, transfer); wl_data_source_add_listener(source, &dataSourceListener, transfer);
for (const char ** mimetype = transfer->mimetypes; *mimetype; mimetype++) for (const char ** mimetype = transfer->mimetypes; *mimetype; mimetype++)
wl_data_source_offer(source, *mimetype); wl_data_source_offer(source, *mimetype);
wl_data_device_set_selection(this->data_device, source, wl_data_device_set_selection(this->dataDevice, source,
this->keyboard_enter_serial); this->keyboardEnterSerial);
} }
static void wayland_cb_notice(LG_ClipboardRequestFn requestFn, LG_ClipboardData type) static void wayland_cb_notice(LG_ClipboardRequestFn requestFn,
LG_ClipboardData type)
{ {
this->requestFn = requestFn; this->requestFn = requestFn;
this->type = type; this->type = type;
@ -506,7 +507,8 @@ static void wayland_cb_notice(LG_ClipboardRequestFn requestFn, LG_ClipboardData
if (!this->requestFn) if (!this->requestFn)
return; return;
// Won't have a keyboard enter serial if we don't have the keyboard capability. // Won't have a keyboard enter serial if we don't have the keyboard
// capability.
if (!this->keyboard) if (!this->keyboard)
return; return;
@ -526,5 +528,5 @@ const LG_Clipboard LGC_Wayland =
.wmevent = wayland_cb_wmevent, .wmevent = wayland_cb_wmevent,
.notice = wayland_cb_notice, .notice = wayland_cb_notice,
.release = wayland_cb_release, .release = wayland_cb_release,
.request = wayland_cb_request .request = wayland_cb_request,
}; };

View File

@ -70,9 +70,7 @@ static bool x11_cb_init(
{ {
// final sanity check // final sanity check
if (wminfo->subsystem != SDL_SYSWM_X11) if (wminfo->subsystem != SDL_SYSWM_X11)
{
return false; return false;
}
this = (struct state *)malloc(sizeof(struct state)); this = (struct state *)malloc(sizeof(struct state));
memset(this, 0, sizeof(struct state)); memset(this, 0, sizeof(struct state));