clang-format the project
This commit is contained in:
11
.clang-format
Normal file
11
.clang-format
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
BasedOnStyle: google
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
IndentWidth: 4
|
||||||
|
PointerBindsToType: false
|
||||||
|
ColumnLimit: 100
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
IndentCaseLabels: false
|
@@ -1,5 +1,4 @@
|
|||||||
/* vim:ts=2:sw=2:expandtab
|
/*
|
||||||
*
|
|
||||||
* This file is part of playerctl.
|
* This file is part of playerctl.
|
||||||
*
|
*
|
||||||
* playerctl is free software: you can redistribute it and/or modify it under
|
* playerctl is free software: you can redistribute it and/or modify it under
|
||||||
@@ -18,12 +17,12 @@
|
|||||||
* Copyright © 2014 - 2016, Tony Crisci and contributors.
|
* Copyright © 2014 - 2016, Tony Crisci and contributors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "playerctl.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "playerctl.h"
|
||||||
|
|
||||||
#define LENGTH(array) (sizeof array / sizeof array[0])
|
#define LENGTH(array) (sizeof array / sizeof array[0])
|
||||||
|
|
||||||
@@ -40,425 +39,429 @@ static gboolean print_version_and_exit;
|
|||||||
/* The commands passed on the command line, filled in via G_OPTION_REMAINING. */
|
/* The commands passed on the command line, filled in via G_OPTION_REMAINING. */
|
||||||
static gchar **command = NULL;
|
static gchar **command = NULL;
|
||||||
|
|
||||||
static GString *list_player_names_on_bus(GError **err, GBusType busType)
|
static GString *list_player_names_on_bus(GError **err, GBusType busType) {
|
||||||
{
|
GError *tmp_error = NULL;
|
||||||
GError *tmp_error = NULL;
|
|
||||||
|
|
||||||
GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync(
|
GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync(
|
||||||
busType,
|
busType, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.DBus",
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
"/org/freedesktop/DBus", "org.freedesktop.DBus", NULL, &tmp_error);
|
||||||
NULL,
|
|
||||||
"org.freedesktop.DBus",
|
|
||||||
"/org/freedesktop/DBus",
|
|
||||||
"org.freedesktop.DBus",
|
|
||||||
NULL,
|
|
||||||
&tmp_error);
|
|
||||||
|
|
||||||
if (tmp_error != NULL) {
|
if (tmp_error != NULL) {
|
||||||
g_propagate_error(err, tmp_error);
|
g_propagate_error(err, tmp_error);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
GVariant *reply = g_dbus_proxy_call_sync(proxy,
|
|
||||||
"ListNames",
|
|
||||||
NULL,
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
|
||||||
-1,
|
|
||||||
NULL,
|
|
||||||
&tmp_error);
|
|
||||||
|
|
||||||
if (tmp_error != NULL) {
|
|
||||||
g_propagate_error(err, tmp_error);
|
|
||||||
g_object_unref(proxy);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GString *names_str = g_string_new("");
|
|
||||||
GVariant *reply_child = g_variant_get_child_value(reply, 0);
|
|
||||||
gsize reply_count;
|
|
||||||
const gchar **names = g_variant_get_strv(reply_child, &reply_count);
|
|
||||||
|
|
||||||
size_t offset = strlen ("org.mpris.MediaPlayer2.");
|
|
||||||
for (int i = 0; i < reply_count; i += 1) {
|
|
||||||
if (g_str_has_prefix(names[i], "org.mpris.MediaPlayer2.")) {
|
|
||||||
g_string_append_printf(names_str, "%s\n", names[i] + offset);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref(proxy);
|
GVariant *reply = g_dbus_proxy_call_sync(
|
||||||
g_variant_unref(reply);
|
proxy, "ListNames", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &tmp_error);
|
||||||
g_variant_unref(reply_child);
|
|
||||||
g_free(names);
|
|
||||||
|
|
||||||
return names_str;
|
if (tmp_error != NULL) {
|
||||||
|
g_propagate_error(err, tmp_error);
|
||||||
|
g_object_unref(proxy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GString *names_str = g_string_new("");
|
||||||
|
GVariant *reply_child = g_variant_get_child_value(reply, 0);
|
||||||
|
gsize reply_count;
|
||||||
|
const gchar **names = g_variant_get_strv(reply_child, &reply_count);
|
||||||
|
|
||||||
|
size_t offset = strlen("org.mpris.MediaPlayer2.");
|
||||||
|
for (int i = 0; i < reply_count; i += 1) {
|
||||||
|
if (g_str_has_prefix(names[i], "org.mpris.MediaPlayer2.")) {
|
||||||
|
g_string_append_printf(names_str, "%s\n", names[i] + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(proxy);
|
||||||
|
g_variant_unref(reply);
|
||||||
|
g_variant_unref(reply_child);
|
||||||
|
g_free(names);
|
||||||
|
|
||||||
|
return names_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *list_player_names(GError **err) {
|
static gchar *list_player_names(GError **err) {
|
||||||
GString *sessionPlayers = list_player_names_on_bus(err, G_BUS_TYPE_SESSION);
|
GString *sessionPlayers = list_player_names_on_bus(err, G_BUS_TYPE_SESSION);
|
||||||
GString *systemPlayers = list_player_names_on_bus(err, G_BUS_TYPE_SYSTEM);
|
GString *systemPlayers = list_player_names_on_bus(err, G_BUS_TYPE_SYSTEM);
|
||||||
|
|
||||||
if (!sessionPlayers && !systemPlayers)
|
if (!sessionPlayers && !systemPlayers)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!sessionPlayers)
|
if (!sessionPlayers)
|
||||||
return g_string_free(systemPlayers, FALSE);
|
return g_string_free(systemPlayers, FALSE);
|
||||||
if (!systemPlayers)
|
if (!systemPlayers)
|
||||||
|
return g_string_free(sessionPlayers, FALSE);
|
||||||
|
|
||||||
|
g_string_append(sessionPlayers, systemPlayers->str);
|
||||||
|
g_string_free(systemPlayers, TRUE);
|
||||||
return g_string_free(sessionPlayers, FALSE);
|
return g_string_free(sessionPlayers, FALSE);
|
||||||
|
|
||||||
g_string_append(sessionPlayers, systemPlayers->str);
|
|
||||||
g_string_free(systemPlayers, TRUE);
|
|
||||||
return g_string_free(sessionPlayers, FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PLAYER_COMMAND_FUNC(COMMAND) \
|
||||||
|
GError *tmp_error = NULL; \
|
||||||
|
\
|
||||||
|
playerctl_player_##COMMAND(player, &tmp_error); \
|
||||||
|
if (tmp_error) { \
|
||||||
|
g_propagate_error(error, tmp_error); \
|
||||||
|
return FALSE; \
|
||||||
|
} \
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
#define PLAYER_COMMAND_FUNC(COMMAND) \
|
static gboolean play(PlayerctlPlayer *player, gchar **arguments,
|
||||||
GError *tmp_error = NULL; \
|
GError **error) {
|
||||||
\
|
PLAYER_COMMAND_FUNC(play);
|
||||||
playerctl_player_##COMMAND(player, &tmp_error); \
|
|
||||||
if (tmp_error) { \
|
|
||||||
g_propagate_error(error, tmp_error); \
|
|
||||||
return FALSE; \
|
|
||||||
} \
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
static gboolean play (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
|
||||||
{
|
|
||||||
PLAYER_COMMAND_FUNC(play);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pause is defined in unistd.h */
|
/* Pause is defined in unistd.h */
|
||||||
static gboolean paus (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean paus(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
PLAYER_COMMAND_FUNC(pause);
|
PLAYER_COMMAND_FUNC(pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean play_pause (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean play_pause(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
PLAYER_COMMAND_FUNC(play_pause);
|
PLAYER_COMMAND_FUNC(play_pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean stop (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean stop(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
PLAYER_COMMAND_FUNC(stop);
|
PLAYER_COMMAND_FUNC(stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean next (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean next(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
PLAYER_COMMAND_FUNC(next);
|
PLAYER_COMMAND_FUNC(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean previous (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean previous(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
PLAYER_COMMAND_FUNC(previous);
|
PLAYER_COMMAND_FUNC(previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef PLAYER_COMMAND_FUNC
|
#undef PLAYER_COMMAND_FUNC
|
||||||
|
|
||||||
static gboolean open (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean open(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
const gchar *uri = *arguments;
|
const gchar *uri = *arguments;
|
||||||
GError *tmp_error = NULL;
|
GError *tmp_error = NULL;
|
||||||
if (uri) {
|
if (uri) {
|
||||||
playerctl_player_open(player, g_file_get_uri(g_file_new_for_commandline_arg(uri)), &tmp_error);
|
playerctl_player_open(player,
|
||||||
if (tmp_error != NULL) {
|
g_file_get_uri(g_file_new_for_commandline_arg(uri)),
|
||||||
g_propagate_error(error, tmp_error);
|
&tmp_error);
|
||||||
return FALSE;
|
if (tmp_error != NULL) {
|
||||||
|
g_propagate_error(error, tmp_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return TRUE;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean position (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
static gboolean position(PlayerctlPlayer *player, gchar **arguments,
|
||||||
{
|
GError **error) {
|
||||||
const gchar *position = *arguments;
|
const gchar *position = *arguments;
|
||||||
gint64 offset;
|
gint64 offset;
|
||||||
GError *tmp_error = NULL;
|
GError *tmp_error = NULL;
|
||||||
|
|
||||||
if (position) {
|
if (position) {
|
||||||
char *endptr = NULL;
|
char *endptr = NULL;
|
||||||
offset = 1000000.0 * strtod(position, &endptr);
|
offset = 1000000.0 * strtod(position, &endptr);
|
||||||
|
|
||||||
if (position == endptr) {
|
if (position == endptr) {
|
||||||
g_set_error(error, playerctl_cli_error_quark (), 1, "Could not parse position as a number: %s\n", position);
|
g_set_error(error, playerctl_cli_error_quark(), 1,
|
||||||
return FALSE;
|
"Could not parse position as a number: %s\n", position);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t last = strlen(position) - 1;
|
||||||
|
if (position[last] == '+' || position[last] == '-') {
|
||||||
|
if (position[last] == '-') {
|
||||||
|
offset *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerctl_player_seek(player, offset, &tmp_error);
|
||||||
|
if (tmp_error != NULL) {
|
||||||
|
g_propagate_error(error, tmp_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
playerctl_player_set_position(player, offset, &tmp_error);
|
||||||
|
if (tmp_error != NULL) {
|
||||||
|
g_propagate_error(error, tmp_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_object_get(player, "position", &offset, NULL);
|
||||||
|
printf("%f\n", (double)offset / 1000000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t last = strlen(position) - 1;
|
return TRUE;
|
||||||
if (position[last] == '+' || position[last] == '-') {
|
}
|
||||||
if (position[last] == '-') {
|
|
||||||
offset *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
playerctl_player_seek(player, offset, &tmp_error);
|
static gboolean set_or_get_volume(PlayerctlPlayer *player, gchar **arguments,
|
||||||
if (tmp_error != NULL) {
|
GError **error) {
|
||||||
|
const gchar *volume = *arguments;
|
||||||
|
gdouble level;
|
||||||
|
|
||||||
|
if (volume) {
|
||||||
|
char *endptr = NULL;
|
||||||
|
size_t last = strlen(volume) - 1;
|
||||||
|
|
||||||
|
if (volume[last] == '+' || volume[last] == '-') {
|
||||||
|
gdouble adjustment = strtod(volume, &endptr);
|
||||||
|
|
||||||
|
if (volume == endptr) {
|
||||||
|
g_set_error(error, playerctl_cli_error_quark(), 1,
|
||||||
|
"Could not parse volume as a number: %s\n", volume);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume[last] == '-') {
|
||||||
|
adjustment *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get(player, "volume", &level, NULL);
|
||||||
|
level += adjustment;
|
||||||
|
} else {
|
||||||
|
level = strtod(volume, &endptr);
|
||||||
|
if (volume == endptr) {
|
||||||
|
g_set_error(error, playerctl_cli_error_quark(), 1,
|
||||||
|
"Could not parse volume as a number: %s\n", volume);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_object_set(player, "volume", level, NULL);
|
||||||
|
} else {
|
||||||
|
g_object_get(player, "volume", &level, NULL);
|
||||||
|
g_print("%f\n", level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean status(PlayerctlPlayer *player, gchar **arguments,
|
||||||
|
GError **error) {
|
||||||
|
gchar *state = NULL;
|
||||||
|
|
||||||
|
g_object_get(player, "status", &state, NULL);
|
||||||
|
printf("%s\n", state ? state : "Not available");
|
||||||
|
g_free(state);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean get_metadata(PlayerctlPlayer *player, gchar **arguments,
|
||||||
|
GError **error) {
|
||||||
|
const gchar *type = *arguments;
|
||||||
|
GError *tmp_error = NULL;
|
||||||
|
gchar *data;
|
||||||
|
|
||||||
|
if (g_strcmp0(type, "artist") == 0)
|
||||||
|
data = playerctl_player_get_artist(player, &tmp_error);
|
||||||
|
else if (g_strcmp0(type, "title") == 0)
|
||||||
|
data = playerctl_player_get_title(player, &tmp_error);
|
||||||
|
else if (g_strcmp0(type, "album") == 0)
|
||||||
|
data = playerctl_player_get_album(player, &tmp_error);
|
||||||
|
else
|
||||||
|
data = playerctl_player_print_metadata_prop(player, type, &tmp_error);
|
||||||
|
|
||||||
|
if (tmp_error) {
|
||||||
g_propagate_error(error, tmp_error);
|
g_propagate_error(error, tmp_error);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
playerctl_player_set_position(player, offset, &tmp_error);
|
|
||||||
if (tmp_error != NULL) {
|
|
||||||
g_propagate_error(error, tmp_error);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
g_object_get(player, "position", &offset, NULL);
|
|
||||||
printf("%f\n", (double)offset / 1000000.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
printf("%s", data);
|
||||||
}
|
g_free(data);
|
||||||
|
|
||||||
static gboolean set_or_get_volume (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
return TRUE;
|
||||||
{
|
|
||||||
const gchar *volume = *arguments;
|
|
||||||
gdouble level;
|
|
||||||
|
|
||||||
if (volume) {
|
|
||||||
char *endptr = NULL;
|
|
||||||
size_t last = strlen(volume) - 1;
|
|
||||||
|
|
||||||
if(volume[last] == '+' || volume[last] == '-') {
|
|
||||||
gdouble adjustment = strtod(volume, &endptr);
|
|
||||||
|
|
||||||
if (volume == endptr) {
|
|
||||||
g_set_error(error, playerctl_cli_error_quark (), 1, "Could not parse volume as a number: %s\n", volume);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(volume[last] == '-') {
|
|
||||||
adjustment *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_get(player, "volume", &level, NULL);
|
|
||||||
level += adjustment;
|
|
||||||
} else {
|
|
||||||
level = strtod(volume, &endptr);
|
|
||||||
if (volume == endptr) {
|
|
||||||
g_set_error(error, playerctl_cli_error_quark (), 1, "Could not parse volume as a number: %s\n", volume);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
g_object_set(player, "volume", level, NULL);
|
|
||||||
} else {
|
|
||||||
g_object_get(player, "volume", &level, NULL);
|
|
||||||
g_print("%f\n", level);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean status (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
|
||||||
{
|
|
||||||
gchar *state = NULL;
|
|
||||||
|
|
||||||
g_object_get(player, "status", &state, NULL);
|
|
||||||
printf("%s\n", state ? state : "Not available");
|
|
||||||
g_free(state);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean get_metadata (PlayerctlPlayer *player, gchar **arguments, GError **error)
|
|
||||||
{
|
|
||||||
const gchar *type = *arguments;
|
|
||||||
GError *tmp_error = NULL;
|
|
||||||
gchar *data;
|
|
||||||
|
|
||||||
if (g_strcmp0(type, "artist") == 0)
|
|
||||||
data = playerctl_player_get_artist(player, &tmp_error);
|
|
||||||
else if (g_strcmp0(type, "title") == 0)
|
|
||||||
data = playerctl_player_get_title(player, &tmp_error);
|
|
||||||
else if (g_strcmp0(type, "album") == 0)
|
|
||||||
data = playerctl_player_get_album(player, &tmp_error);
|
|
||||||
else
|
|
||||||
data = playerctl_player_print_metadata_prop(player, type, &tmp_error);
|
|
||||||
|
|
||||||
if (tmp_error) {
|
|
||||||
g_propagate_error(error, tmp_error);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s", data);
|
|
||||||
g_free(data);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PlayerCommand {
|
struct PlayerCommand {
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
gboolean (*func) (PlayerctlPlayer *player, gchar **arguments, GError **error);
|
gboolean (*func)(PlayerctlPlayer *player, gchar **arguments, GError **error);
|
||||||
} commands[] = {
|
} commands[] = {
|
||||||
{ "open", &open },
|
{"open", &open},
|
||||||
{ "play", &play },
|
{"play", &play},
|
||||||
{ "pause", &paus },
|
{"pause", &paus},
|
||||||
{ "play-pause", &play_pause },
|
{"play-pause", &play_pause},
|
||||||
{ "stop", &stop },
|
{"stop", &stop},
|
||||||
{ "next", &next },
|
{"next", &next},
|
||||||
{ "previous", &previous },
|
{"previous", &previous},
|
||||||
{ "position", &position },
|
{"position", &position},
|
||||||
{ "volume", &set_or_get_volume },
|
{"volume", &set_or_get_volume},
|
||||||
{ "status", &status },
|
{"status", &status},
|
||||||
{ "metadata", &get_metadata },
|
{"metadata", &get_metadata},
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean handle_player_command (PlayerctlPlayer *player, gchar **command, GError **error)
|
static gboolean handle_player_command(PlayerctlPlayer *player, gchar **command,
|
||||||
{
|
GError **error) {
|
||||||
for (int i = 0; i < LENGTH(commands); i++) {
|
for (int i = 0; i < LENGTH(commands); i++) {
|
||||||
if (g_strcmp0(commands[i].name, command[0]) == 0) {
|
if (g_strcmp0(commands[i].name, command[0]) == 0) {
|
||||||
// Do not pass the command's name to the function that processes it.
|
// Do not pass the command's name to the function that processes it.
|
||||||
return commands[i].func(player, command + 1, error);
|
return commands[i].func(player, command + 1, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
g_set_error(error, playerctl_cli_error_quark(), 1,
|
||||||
g_set_error(error, playerctl_cli_error_quark (), 1, "Command not recognized: %s", command[0]);
|
"Command not recognized: %s", command[0]);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GOptionEntry entries[] = {
|
static const GOptionEntry entries[] = {
|
||||||
{ "player", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &player_name_list,
|
{"player", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &player_name_list,
|
||||||
"A comma separated list of names of players to control (default: the first available player)", "NAME" },
|
"A comma separated list of names of players to control (default: the "
|
||||||
{ "all-players", 'a', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &select_all_players,
|
"first available player)",
|
||||||
"Select all available players to be controlled", NULL },
|
"NAME"},
|
||||||
{ "list-all", 'l', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &list_all_players_and_exit,
|
{"all-players", 'a', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
|
||||||
"List the names of running players that can be controlled and exit", NULL },
|
&select_all_players, "Select all available players to be controlled",
|
||||||
{ "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &print_version_and_exit,
|
NULL},
|
||||||
"Print version information and exit", NULL },
|
{"list-all", 'l', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
|
||||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &command, NULL, "COMMAND" },
|
&list_all_players_and_exit,
|
||||||
{ NULL }
|
"List the names of running players that can be controlled and exit", NULL},
|
||||||
};
|
{"version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
|
||||||
|
&print_version_and_exit, "Print version information and exit", NULL},
|
||||||
|
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &command, NULL,
|
||||||
|
"COMMAND"},
|
||||||
|
{NULL}};
|
||||||
|
|
||||||
static gboolean parse_setup_options (int argc, char *argv[], GError **error)
|
static gboolean parse_setup_options(int argc, char *argv[], GError **error) {
|
||||||
{
|
static const gchar *description =
|
||||||
static const gchar *description = "Available Commands:"
|
"Available Commands:"
|
||||||
"\n open [URI] Command for the player to open given URI."
|
"\n open [URI] Command for the player to open given URI."
|
||||||
"\n URI can be either file path or remote URL with mandatory scheme, like http://..."
|
"\n URI can be either file path or remote URL "
|
||||||
"\n play Command the player to play"
|
"with mandatory scheme, like http://..."
|
||||||
"\n pause Command the player to pause"
|
"\n play Command the player to play"
|
||||||
"\n play-pause Command the player to toggle between play/pause"
|
"\n pause Command the player to pause"
|
||||||
"\n stop Command the player to stop"
|
"\n play-pause Command the player to toggle between "
|
||||||
"\n next Command the player to skip to the next track"
|
"play/pause"
|
||||||
"\n previous Command the player to skip to the previous track"
|
"\n stop Command the player to stop"
|
||||||
"\n position [OFFSET][+/-] Command the player to go to the position or seek forward/backward OFFSET in seconds"
|
"\n next Command the player to skip to the next track"
|
||||||
"\n volume [LEVEL][+/-] Print or set the volume to LEVEL from 0.0 to 1.0"
|
"\n previous Command the player to skip to the previous "
|
||||||
"\n status Get the play status of the player"
|
"track"
|
||||||
"\n metadata [KEY] Print metadata information for the current track. If KEY is passed,"
|
"\n position [OFFSET][+/-] Command the player to go to the position or "
|
||||||
"\n print only that value. KEY may be one of artist, title or album";
|
"seek forward/backward OFFSET in seconds"
|
||||||
static const gchar *summary = " Only for players supporting the MPRIS D-Bus specification";
|
"\n volume [LEVEL][+/-] Print or set the volume to LEVEL from 0.0 "
|
||||||
GOptionContext *context = NULL;
|
"to 1.0"
|
||||||
gboolean success;
|
"\n status Get the play status of the player"
|
||||||
|
"\n metadata [KEY] Print metadata information for the current "
|
||||||
|
"track. If KEY is passed,"
|
||||||
|
"\n print only that value. KEY may be one of "
|
||||||
|
"artist, title or album";
|
||||||
|
static const gchar *summary =
|
||||||
|
" Only for players supporting the MPRIS D-Bus specification";
|
||||||
|
GOptionContext *context = NULL;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
context = g_option_context_new("- Controller for MPRIS players");
|
context = g_option_context_new("- Controller for MPRIS players");
|
||||||
g_option_context_add_main_entries(context, entries, NULL);
|
g_option_context_add_main_entries(context, entries, NULL);
|
||||||
g_option_context_set_description(context, description);
|
g_option_context_set_description(context, description);
|
||||||
g_option_context_set_summary(context, summary);
|
g_option_context_set_summary(context, summary);
|
||||||
|
|
||||||
success = g_option_context_parse(context, &argc, &argv, error);
|
success = g_option_context_parse(context, &argc, &argv, error);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
g_option_context_free(context);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == NULL && !print_version_and_exit &&
|
||||||
|
!list_all_players_and_exit) {
|
||||||
|
gchar *help = g_option_context_get_help(context, TRUE, NULL);
|
||||||
|
g_set_error(error, playerctl_cli_error_quark(), 1,
|
||||||
|
"No command entered\n\n%s", help);
|
||||||
|
g_option_context_free(context);
|
||||||
|
g_free(help);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
g_option_context_free(context);
|
g_option_context_free(context);
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
if (command == NULL && !print_version_and_exit && !list_all_players_and_exit) {
|
|
||||||
gchar *help = g_option_context_get_help(context, TRUE, NULL);
|
|
||||||
g_set_error (error, playerctl_cli_error_quark(), 1, "No command entered\n\n%s", help);
|
|
||||||
g_option_context_free(context);
|
|
||||||
g_free(help);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_option_context_free(context);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
PlayerctlPlayer *player;
|
||||||
PlayerctlPlayer *player;
|
GError *error = NULL;
|
||||||
GError *error = NULL;
|
int exit_status = 0;
|
||||||
int exit_status = 0;
|
|
||||||
|
|
||||||
// seems to be required to print unicode (see #8)
|
// seems to be required to print unicode (see #8)
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
if (!parse_setup_options(argc, argv, &error)) {
|
if (!parse_setup_options(argc, argv, &error)) {
|
||||||
g_printerr("%s\n", error->message);
|
g_printerr("%s\n", error->message);
|
||||||
exit_status = 0;
|
exit_status = 0;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
|
||||||
|
|
||||||
if (print_version_and_exit) {
|
|
||||||
g_print("v%s\n", PLAYERCTL_VERSION_S);
|
|
||||||
exit_status = 0;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list_all_players_and_exit) {
|
|
||||||
gchar *player_names = list_player_names(&error);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
g_printerr("%s\n", error->message);
|
|
||||||
exit_status = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player_names[0] == '\0')
|
if (print_version_and_exit) {
|
||||||
g_printerr("No players were found");
|
g_print("v%s\n", PLAYERCTL_VERSION_S);
|
||||||
else
|
exit_status = 0;
|
||||||
g_print("%s", player_names);
|
goto end;
|
||||||
g_free(player_names);
|
|
||||||
|
|
||||||
exit_status = 0;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
gchar *player_names = player_name_list;
|
|
||||||
if (select_all_players) {
|
|
||||||
player_names = list_player_names(&error);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
g_printerr("%s\n", error->message);
|
|
||||||
exit_status = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const gchar *delim = ",\n";
|
|
||||||
const gboolean multiple_names = player_names != NULL;
|
|
||||||
gchar *player_name = multiple_names ? strtok(player_names, delim) : NULL;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
player = playerctl_player_new(player_name, &error);
|
|
||||||
|
|
||||||
if (error != NULL) {
|
|
||||||
g_printerr("Connection to player failed: %s\n", error->message);
|
|
||||||
exit_status = 1;
|
|
||||||
goto loopend;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handle_player_command(player, command, &error)) {
|
if (list_all_players_and_exit) {
|
||||||
g_printerr("Could not execute command: %s\n", error->message);
|
gchar *player_names = list_player_names(&error);
|
||||||
exit_status = 1;
|
|
||||||
|
if (error) {
|
||||||
|
g_printerr("%s\n", error->message);
|
||||||
|
exit_status = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player_names[0] == '\0')
|
||||||
|
g_printerr("No players were found");
|
||||||
|
else
|
||||||
|
g_print("%s", player_names);
|
||||||
|
g_free(player_names);
|
||||||
|
|
||||||
|
exit_status = 0;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
loopend:
|
gchar *player_names = player_name_list;
|
||||||
if (player != NULL) {
|
if (select_all_players) {
|
||||||
g_object_unref(player);
|
player_names = list_player_names(&error);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
g_printerr("%s\n", error->message);
|
||||||
|
exit_status = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_clear_error(&error);
|
|
||||||
error = NULL;
|
|
||||||
|
|
||||||
if (!multiple_names)
|
const gchar *delim = ",\n";
|
||||||
return exit_status;
|
const gboolean multiple_names = player_names != NULL;
|
||||||
|
gchar *player_name = multiple_names ? strtok(player_names, delim) : NULL;
|
||||||
|
|
||||||
player_name = strtok(NULL, delim);
|
for (;;) {
|
||||||
if (!player_name)
|
player = playerctl_player_new(player_name, &error);
|
||||||
return exit_status;
|
|
||||||
}
|
if (error != NULL) {
|
||||||
|
g_printerr("Connection to player failed: %s\n", error->message);
|
||||||
|
exit_status = 1;
|
||||||
|
goto loopend;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handle_player_command(player, command, &error)) {
|
||||||
|
g_printerr("Could not execute command: %s\n", error->message);
|
||||||
|
exit_status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
loopend:
|
||||||
|
if (player != NULL) {
|
||||||
|
g_object_unref(player);
|
||||||
|
}
|
||||||
|
g_clear_error(&error);
|
||||||
|
error = NULL;
|
||||||
|
|
||||||
|
if (!multiple_names)
|
||||||
|
return exit_status;
|
||||||
|
|
||||||
|
player_name = strtok(NULL, delim);
|
||||||
|
if (!player_name)
|
||||||
|
return exit_status;
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
g_clear_error(&error);
|
g_clear_error(&error);
|
||||||
|
|
||||||
return exit_status;
|
return exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
|||||||
/* vim:ts=2:sw=2:expandtab
|
/*
|
||||||
*
|
|
||||||
* This file is part of playerctl.
|
* This file is part of playerctl.
|
||||||
*
|
*
|
||||||
* playerctl is free software: you can redistribute it and/or modify it under
|
* playerctl is free software: you can redistribute it and/or modify it under
|
||||||
@@ -31,51 +30,60 @@
|
|||||||
* SECTION: playerctl-player
|
* SECTION: playerctl-player
|
||||||
* @short_description: A class to control an MPRIS player
|
* @short_description: A class to control an MPRIS player
|
||||||
*/
|
*/
|
||||||
#define PLAYERCTL_TYPE_PLAYER (playerctl_player_get_type ())
|
#define PLAYERCTL_TYPE_PLAYER (playerctl_player_get_type())
|
||||||
#define PLAYERCTL_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLAYERCTL_TYPE_PLAYER, PlayerctlPlayer))
|
#define PLAYERCTL_PLAYER(obj) \
|
||||||
#define PLAYERCTL_IS_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PLAYERCTL_TYPE_PLAYER))
|
(G_TYPE_CHECK_INSTANCE_CAST((obj), PLAYERCTL_TYPE_PLAYER, PlayerctlPlayer))
|
||||||
#define PLAYERCTL_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PLAYERCTL_TYPE_PLAYER, PlayerctlPlayerClass))
|
#define PLAYERCTL_IS_PLAYER(obj) \
|
||||||
#define PLAYERCTL_IS_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PLAYERCTL_TYPE_PLAYER))
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj), PLAYERCTL_TYPE_PLAYER))
|
||||||
#define PLAYERCTL_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PLAYERCTL_TYPE_PLAYER, PlayerctlPlayerClass))
|
#define PLAYERCTL_PLAYER_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass), PLAYERCTL_TYPE_PLAYER, \
|
||||||
|
PlayerctlPlayerClass))
|
||||||
|
#define PLAYERCTL_IS_PLAYER_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass), PLAYERCTL_TYPE_PLAYER))
|
||||||
|
#define PLAYERCTL_PLAYER_GET_CLASS(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS((obj), PLAYERCTL_TYPE_PLAYER, \
|
||||||
|
PlayerctlPlayerClass))
|
||||||
|
|
||||||
typedef struct _PlayerctlPlayer PlayerctlPlayer;
|
typedef struct _PlayerctlPlayer PlayerctlPlayer;
|
||||||
typedef struct _PlayerctlPlayerClass PlayerctlPlayerClass;
|
typedef struct _PlayerctlPlayerClass PlayerctlPlayerClass;
|
||||||
typedef struct _PlayerctlPlayerPrivate PlayerctlPlayerPrivate;
|
typedef struct _PlayerctlPlayerPrivate PlayerctlPlayerPrivate;
|
||||||
|
|
||||||
struct _PlayerctlPlayer
|
struct _PlayerctlPlayer {
|
||||||
{
|
/* Parent instance structure */
|
||||||
/* Parent instance structure */
|
GObject parent_instance;
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
/* Private members */
|
/* Private members */
|
||||||
PlayerctlPlayerPrivate *priv;
|
PlayerctlPlayerPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _PlayerctlPlayerClass
|
struct _PlayerctlPlayerClass {
|
||||||
{
|
/* Parent class structure */
|
||||||
/* Parent class structure */
|
GObjectClass parent_class;
|
||||||
GObjectClass parent_class;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType playerctl_player_get_type (void);
|
GType playerctl_player_get_type(void);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_new (const gchar *name, GError **err);
|
PlayerctlPlayer *playerctl_player_new(const gchar *name, GError **err);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Method definitions.
|
* Method definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_on(PlayerctlPlayer *self, const gchar *event, GClosure *callback, GError **err);
|
PlayerctlPlayer *playerctl_player_on(PlayerctlPlayer *self, const gchar *event,
|
||||||
|
GClosure *callback, GError **err);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_open(PlayerctlPlayer *self, gchar *uri, GError **err);
|
PlayerctlPlayer *playerctl_player_open(PlayerctlPlayer *self, gchar *uri,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_play_pause(PlayerctlPlayer *self, GError **err);
|
PlayerctlPlayer *playerctl_player_play_pause(PlayerctlPlayer *self,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_play(PlayerctlPlayer *self, GError **err);
|
PlayerctlPlayer *playerctl_player_play(PlayerctlPlayer *self, GError **err);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_stop(PlayerctlPlayer *self, GError **err);
|
PlayerctlPlayer *playerctl_player_stop(PlayerctlPlayer *self, GError **err);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_seek(PlayerctlPlayer *self, gint64 offset, GError **err);
|
PlayerctlPlayer *playerctl_player_seek(PlayerctlPlayer *self, gint64 offset,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_pause(PlayerctlPlayer *self, GError **err);
|
PlayerctlPlayer *playerctl_player_pause(PlayerctlPlayer *self, GError **err);
|
||||||
|
|
||||||
@@ -83,7 +91,9 @@ PlayerctlPlayer *playerctl_player_next(PlayerctlPlayer *self, GError **err);
|
|||||||
|
|
||||||
PlayerctlPlayer *playerctl_player_previous(PlayerctlPlayer *self, GError **err);
|
PlayerctlPlayer *playerctl_player_previous(PlayerctlPlayer *self, GError **err);
|
||||||
|
|
||||||
gchar *playerctl_player_print_metadata_prop(PlayerctlPlayer *self, const gchar *property, GError **err);
|
gchar *playerctl_player_print_metadata_prop(PlayerctlPlayer *self,
|
||||||
|
const gchar *property,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
gchar *playerctl_player_get_artist(PlayerctlPlayer *self, GError **err);
|
gchar *playerctl_player_get_artist(PlayerctlPlayer *self, GError **err);
|
||||||
|
|
||||||
@@ -91,6 +101,7 @@ gchar *playerctl_player_get_title(PlayerctlPlayer *self, GError **err);
|
|||||||
|
|
||||||
gchar *playerctl_player_get_album(PlayerctlPlayer *self, GError **err);
|
gchar *playerctl_player_get_album(PlayerctlPlayer *self, GError **err);
|
||||||
|
|
||||||
void playerctl_player_set_position(PlayerctlPlayer *self, gint64 position, GError **err);
|
void playerctl_player_set_position(PlayerctlPlayer *self, gint64 position,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
#endif /* __PLAYERCTL_PLAYER_H__ */
|
#endif /* __PLAYERCTL_PLAYER_H__ */
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
/* vim:ts=2:sw=2:expandtab
|
/*
|
||||||
*
|
|
||||||
* This file is part of playerctl.
|
* This file is part of playerctl.
|
||||||
*
|
*
|
||||||
* playerctl is free software: you can redistribute it and/or modify it under
|
* playerctl is free software: you can redistribute it and/or modify it under
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
/* vim:ts=2:sw=2:expandtab
|
/*
|
||||||
*
|
|
||||||
* This file is part of playerctl.
|
* This file is part of playerctl.
|
||||||
*
|
*
|
||||||
* playerctl is free software: you can redistribute it and/or modify it under
|
* playerctl is free software: you can redistribute it and/or modify it under
|
||||||
@@ -23,8 +22,8 @@
|
|||||||
|
|
||||||
#define __PLAYERCTL_INSIDE__
|
#define __PLAYERCTL_INSIDE__
|
||||||
|
|
||||||
#include <playerctl/playerctl-version.h>
|
|
||||||
#include <playerctl/playerctl-player.h>
|
#include <playerctl/playerctl-player.h>
|
||||||
|
#include <playerctl/playerctl-version.h>
|
||||||
|
|
||||||
#undef __PLAYERCTL_INSIDE__
|
#undef __PLAYERCTL_INSIDE__
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user