diff --git a/app/src/receiver.c b/app/src/receiver.c index 3e572067..806c34b7 100644 --- a/app/src/receiver.c +++ b/app/src/receiver.c @@ -6,6 +6,7 @@ #include #include "device_msg.h" +#include "events.h" #include "util/log.h" #include "util/str.h" @@ -33,20 +34,38 @@ sc_receiver_destroy(struct sc_receiver *receiver) { sc_mutex_destroy(&receiver->mutex); } +static void +task_set_clipboard(void *userdata) { + char *text = userdata; + + char *current = SDL_GetClipboardText(); + bool same = current && !strcmp(current, text); + SDL_free(current); + if (same) { + LOGD("Computer clipboard unchanged"); + free(text); + return; + } + + LOGI("Device clipboard copied"); + SDL_SetClipboardText(text); + free(text); +} + static void process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) { switch (msg->type) { case DEVICE_MSG_TYPE_CLIPBOARD: { - char *current = SDL_GetClipboardText(); - bool same = current && !strcmp(current, msg->clipboard.text); - SDL_free(current); - if (same) { - LOGD("Computer clipboard unchanged"); + // Take ownership of the text (do not destroy the msg) + char *text = msg->clipboard.text; + + bool ok = sc_post_to_main_thread(task_set_clipboard, text); + if (!ok) { + LOGW("Could not post clipboard to main thread"); + free(text); return; } - LOGI("Device clipboard copied"); - SDL_SetClipboardText(msg->clipboard.text); break; } case DEVICE_MSG_TYPE_ACK_CLIPBOARD: @@ -64,6 +83,7 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) { } sc_acksync_ack(receiver->acksync, msg->ack_clipboard.sequence); + // No allocation to free in the msg break; case DEVICE_MSG_TYPE_UHID_OUTPUT: if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) { @@ -86,6 +106,7 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) { // Also check at runtime (do not trust the server) if (!receiver->uhid_devices) { LOGE("Received unexpected HID output message"); + sc_device_msg_destroy(msg); return; } @@ -99,6 +120,8 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) { } else { LOGW("No UHID receiver for id %" PRIu16, msg->uhid_output.id); } + + sc_device_msg_destroy(msg); break; } } @@ -117,7 +140,7 @@ process_msgs(struct sc_receiver *receiver, const uint8_t *buf, size_t len) { } process_msg(receiver, &msg); - sc_device_msg_destroy(&msg); + // the device msg must be destroyed by process_msg() head += r; assert(head <= len);