Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial MPRIS support #5255

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions app/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ if usb_support
]
endif

mpris_support = get_option('mpris') and host_machine.system() == 'linux'
if mpris_support
src += [ 'src/mpris.c' ]
endif

cc = meson.get_compiler('c')

dependencies = [
Expand All @@ -123,6 +128,11 @@ if usb_support
dependencies += dependency('libusb-1.0')
endif

if mpris_support
dependencies += dependency('glib-2.0')
dependencies += dependency('gio-2.0')
endif

if host_machine.system() == 'windows'
dependencies += cc.find_library('mingw32')
dependencies += cc.find_library('ws2_32')
Expand Down Expand Up @@ -174,6 +184,9 @@ conf.set('HAVE_V4L2', v4l2_support)
# enable HID over AOA support (linux only)
conf.set('HAVE_USB', usb_support)

# enable DBus MPRIS support (linux only)
conf.set('HAVE_MPRIS', mpris_support)

configure_file(configuration: conf, output: 'config.h')

src_dir = include_directories('src')
Expand Down
10 changes: 10 additions & 0 deletions app/src/control_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ enum sc_control_msg_type {
SC_CONTROL_MSG_TYPE_UHID_INPUT,
SC_CONTROL_MSG_TYPE_UHID_DESTROY,
SC_CONTROL_MSG_TYPE_OPEN_HARD_KEYBOARD_SETTINGS,
SC_CONTROL_MSG_TYPE_MEDIA_STATE,
SC_CONTROL_MSG_TYPE_MEDIA_SEEK,
};

enum sc_screen_power_mode {
Expand Down Expand Up @@ -110,6 +112,14 @@ struct sc_control_msg {
struct {
uint16_t id;
} uhid_destroy;
struct {
uint16_t player_id;
uint64_t position;
} media_seek;
struct {
uint16_t player_id;
uint8_t state;
} media_state;
};
};

Expand Down
64 changes: 48 additions & 16 deletions app/src/device_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
#include "util/binary.h"
#include "util/log.h"

static int read_message(uint8_t **target, const uint8_t *src, const uint16_t size) {
uint8_t *data = malloc(size + 1);
if (!data) {
LOG_OOM();
return -1;
}
if (size) {
data[size] = '\0';
memcpy(data, src, size);
}
*target = data;
Comment on lines +17 to +20

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this leave target pointing at uninitialized memory if size == 0? Below, the null terminator write was done unconditionally. Putting this here would result in:

Suggested change
data[size] = '\0';
memcpy(data, src, size);
}
*target = data;
memcpy(data, src, size);
}
data[size] = '\0';
*target = data;

return 0;
}

ssize_t
sc_device_msg_deserialize(const uint8_t *buf, size_t len,
struct sc_device_msg *msg) {
Expand All @@ -25,17 +39,10 @@ sc_device_msg_deserialize(const uint8_t *buf, size_t len,
if (clipboard_len > len - 5) {
return 0; // no complete message
}
char *text = malloc(clipboard_len + 1);
if (!text) {
LOG_OOM();
if (read_message((uint8_t **)&msg->clipboard.text, &buf[5], clipboard_len) == -1) {
return -1;
}
if (clipboard_len) {
memcpy(text, &buf[5], clipboard_len);
}
text[clipboard_len] = '\0';

msg->clipboard.text = text;
return 5 + clipboard_len;
}
case DEVICE_MSG_TYPE_ACK_CLIPBOARD: {
Expand All @@ -56,21 +63,43 @@ sc_device_msg_deserialize(const uint8_t *buf, size_t len,
if (size < len - 5) {
return 0; // not available
}
uint8_t *data = malloc(size);
if (!data) {
LOG_OOM();

msg->uhid_output.id = id;
msg->uhid_output.size = size;
if (read_message(&msg->uhid_output.data, &buf[5], size) == -1) {
return -1;
}
if (size) {
memcpy(data, &buf[5], size);

return 5 + size;
case DEVICE_MSG_TYPE_MEDIA_UPDATE: {
if (len < 5) {
// at least id + size
return 0; // not available
}
uint16_t id = sc_read16be(&buf[1]);
size_t size = sc_read16be(&buf[3]);
if (size < len - 5) {
return 0; // not available
}

msg->uhid_output.id = id;
msg->uhid_output.size = size;
msg->uhid_output.data = data;
msg->media_update.id = id;
msg->media_update.size = size;
if (read_message(&msg->media_update.data, &buf[5], size) == -1) {
return -1;
}

return 5 + size;
}
case DEVICE_MSG_TYPE_MEDIA_REMOVE: {
if (len < 3) {
// at least id
return 0; // not available
}
uint16_t id = sc_read16be(&buf[1]);
msg->media_remove.id = id;
return 3;
}
}
Comment on lines +101 to +102

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional that these closing brackets don't match their indentation level? The first one closes the case of DEVICE_MSG_TYPE_MEDIA_REMOVE (henceforth m) while the second one closes the case of DEVICE_MSG_TYPE_UHID_OUTPUT (henceforth o).

(I'm not even sure if the case of m works since it's inside the block opened by o, but I don't know C well enough to say for sure. Maybe cases inside a switch can be in nested blocks and blocks aren't hard scopes.)

default:
LOGW("Unknown device message type: %d", (int) msg->type);
return -1; // error, we cannot recover
Expand All @@ -86,6 +115,9 @@ sc_device_msg_destroy(struct sc_device_msg *msg) {
case DEVICE_MSG_TYPE_UHID_OUTPUT:
free(msg->uhid_output.data);
break;
case DEVICE_MSG_TYPE_MEDIA_UPDATE:
free(msg->media_update.data);
break;
default:
// nothing to do
break;
Expand Down
10 changes: 10 additions & 0 deletions app/src/device_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ enum sc_device_msg_type {
DEVICE_MSG_TYPE_CLIPBOARD,
DEVICE_MSG_TYPE_ACK_CLIPBOARD,
DEVICE_MSG_TYPE_UHID_OUTPUT,
DEVICE_MSG_TYPE_MEDIA_UPDATE,
DEVICE_MSG_TYPE_MEDIA_REMOVE,
};

struct sc_device_msg {
Expand All @@ -31,6 +33,14 @@ struct sc_device_msg {
uint16_t size;
uint8_t *data; // owned, to be freed by free()
} uhid_output;
struct {
uint16_t id;
uint16_t size;
uint8_t *data; // owned, to be freed by free()
} media_update;
struct {
uint16_t id;
} media_remove;
};
};

Expand Down
1 change: 1 addition & 0 deletions app/src/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum {
SC_EVENT_TIME_LIMIT_REACHED,
SC_EVENT_CONTROLLER_ERROR,
SC_EVENT_AOA_OPEN_ERROR,
SC_EVENT_RAISE_WINDOW,
};

bool
Expand Down
Loading