2019-05-30 06:25:37 +08:00
|
|
|
#include "receiver.h"
|
|
|
|
|
2019-11-28 04:11:40 +08:00
|
|
|
#include <assert.h>
|
2019-05-30 06:25:37 +08:00
|
|
|
#include <SDL2/SDL_clipboard.h>
|
|
|
|
|
2019-05-31 20:55:11 +08:00
|
|
|
#include "device_msg.h"
|
2019-11-24 18:53:00 +08:00
|
|
|
#include "util/lock.h"
|
|
|
|
#include "util/log.h"
|
2019-05-30 06:25:37 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
receiver_init(struct receiver *receiver, socket_t control_socket) {
|
|
|
|
if (!(receiver->mutex = SDL_CreateMutex())) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
receiver->control_socket = control_socket;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
receiver_destroy(struct receiver *receiver) {
|
|
|
|
SDL_DestroyMutex(receiver->mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-11-26 16:08:12 +08:00
|
|
|
process_msg(struct device_msg *msg) {
|
2019-05-31 20:55:11 +08:00
|
|
|
switch (msg->type) {
|
2020-07-17 06:00:42 +08:00
|
|
|
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");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-31 21:43:25 +08:00
|
|
|
LOGI("Device clipboard copied");
|
2019-05-31 20:55:11 +08:00
|
|
|
SDL_SetClipboardText(msg->clipboard.text);
|
2019-05-30 06:25:37 +08:00
|
|
|
break;
|
2020-07-17 06:00:42 +08:00
|
|
|
}
|
2019-05-30 06:25:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
2019-11-26 16:08:12 +08:00
|
|
|
process_msgs(const unsigned char *buf, size_t len) {
|
2019-05-30 06:25:37 +08:00
|
|
|
size_t head = 0;
|
|
|
|
for (;;) {
|
2019-05-31 20:55:11 +08:00
|
|
|
struct device_msg msg;
|
|
|
|
ssize_t r = device_msg_deserialize(&buf[head], len - head, &msg);
|
2019-05-30 06:25:37 +08:00
|
|
|
if (r == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (r == 0) {
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
|
2019-11-26 16:08:12 +08:00
|
|
|
process_msg(&msg);
|
2019-05-31 20:55:11 +08:00
|
|
|
device_msg_destroy(&msg);
|
2019-05-30 06:25:37 +08:00
|
|
|
|
|
|
|
head += r;
|
2019-11-28 04:11:40 +08:00
|
|
|
assert(head <= len);
|
2019-05-30 06:25:37 +08:00
|
|
|
if (head == len) {
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
run_receiver(void *data) {
|
|
|
|
struct receiver *receiver = data;
|
|
|
|
|
2020-06-05 05:50:08 +08:00
|
|
|
static unsigned char buf[DEVICE_MSG_MAX_SIZE];
|
2019-05-30 06:25:37 +08:00
|
|
|
size_t head = 0;
|
|
|
|
|
|
|
|
for (;;) {
|
2020-06-05 03:26:38 +08:00
|
|
|
assert(head < DEVICE_MSG_MAX_SIZE);
|
2020-06-05 04:44:43 +08:00
|
|
|
ssize_t r = net_recv(receiver->control_socket, buf + head,
|
2020-06-05 03:26:38 +08:00
|
|
|
DEVICE_MSG_MAX_SIZE - head);
|
2019-05-30 06:25:37 +08:00
|
|
|
if (r <= 0) {
|
|
|
|
LOGD("Receiver stopped");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-06-05 04:44:43 +08:00
|
|
|
head += r;
|
|
|
|
ssize_t consumed = process_msgs(buf, head);
|
2019-05-30 06:25:37 +08:00
|
|
|
if (consumed == -1) {
|
|
|
|
// an error occurred
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (consumed) {
|
2020-06-05 04:44:43 +08:00
|
|
|
head -= consumed;
|
2019-05-30 06:25:37 +08:00
|
|
|
// shift the remaining data in the buffer
|
2020-06-05 04:44:43 +08:00
|
|
|
memmove(buf, &buf[consumed], head);
|
2019-05-30 06:25:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
receiver_start(struct receiver *receiver) {
|
|
|
|
LOGD("Starting receiver thread");
|
|
|
|
|
|
|
|
receiver->thread = SDL_CreateThread(run_receiver, "receiver", receiver);
|
|
|
|
if (!receiver->thread) {
|
|
|
|
LOGC("Could not start receiver thread");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
receiver_join(struct receiver *receiver) {
|
|
|
|
SDL_WaitThread(receiver->thread, NULL);
|
|
|
|
}
|