📄 xmmsctrl.c
字号:
/* XMMS - Cross-platform multimedia player * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies * Copyright (C) 1999-2003 Haavard Kvaalen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#if defined(HAVE_CONFIG_H)#include "config.h"#endif#include <glib.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <sys/un.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include "xmmsctrl.h"#include "../xmms/controlsocket.h"#ifdef HAVE_UNISTD_H#include <unistd.h>#endifstatic int read_all(int fd, void *buf, size_t count){ size_t left = count; int r; do { r = read(fd, buf, left); if (r < 0) return -1; left -= r; buf = (char *)buf + r; } while (left > 0 && r > 0); return count - left;}static gpointer remote_read_packet(gint fd, ServerPktHeader * pkt_hdr){ gpointer data = NULL; if (read_all(fd, pkt_hdr, sizeof (ServerPktHeader)) == sizeof (ServerPktHeader)) { if (pkt_hdr->data_length) { data = g_malloc0(pkt_hdr->data_length); if (read_all(fd, data, pkt_hdr->data_length) < 0) { g_free(data); data = NULL; } } } return data;}static void remote_read_ack(gint fd){ gpointer data; ServerPktHeader pkt_hdr; data = remote_read_packet(fd, &pkt_hdr); if (data) g_free(data);}static int write_all(int fd, const void *buf, size_t count){ size_t left = count; /* FIXME: This can take forever */ do { int written = write(fd, buf, left); if (written < 0) { g_warning("remote_send_packet(): " "Failed to send data to xmms: %s", strerror(errno)); return -1; } left -= written; buf = (char *)buf + written; } while (left > 0); return count;}static void remote_send_packet(gint fd, guint32 command, gpointer data, guint32 data_length){ ClientPktHeader pkt_hdr; pkt_hdr.version = XMMS_PROTOCOL_VERSION; pkt_hdr.command = command; pkt_hdr.data_length = data_length; if (write_all(fd, &pkt_hdr, sizeof (ClientPktHeader)) < 0) return; if (data_length && data) write_all(fd, data, data_length);}static void remote_send_guint32(gint session, guint32 cmd, guint32 val){ gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return; remote_send_packet(fd, cmd, &val, sizeof (guint32)); remote_read_ack(fd); close(fd);}static void remote_send_boolean(gint session, guint32 cmd, gboolean val){ gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return; remote_send_packet(fd, cmd, &val, sizeof (gboolean)); remote_read_ack(fd); close(fd);}static void remote_send_gfloat(gint session, guint32 cmd, gfloat value){ gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return; remote_send_packet(fd, cmd, &value, sizeof (gfloat)); remote_read_ack(fd); close(fd);}static void remote_send_string(gint session, guint32 cmd, gchar * string){ gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return; remote_send_packet(fd, cmd, string, string ? strlen(string) + 1 : 0); remote_read_ack(fd); close(fd);}static gboolean remote_cmd(gint session, guint32 cmd){ gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return FALSE; remote_send_packet(fd, cmd, NULL, 0); remote_read_ack(fd); close(fd); return TRUE;}static gboolean remote_get_gboolean(gint session, gint cmd){ ServerPktHeader pkt_hdr; gboolean ret = FALSE; gpointer data; gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return ret; remote_send_packet(fd, cmd, NULL, 0); data = remote_read_packet(fd, &pkt_hdr); if (data) { ret = *((gboolean *) data); g_free(data); } remote_read_ack(fd); close(fd); return ret;}static guint32 remote_get_gint(gint session, gint cmd){ ServerPktHeader pkt_hdr; gpointer data; gint fd, ret = 0; if ((fd = xmms_connect_to_session(session)) == -1) return ret; remote_send_packet(fd, cmd, NULL, 0); data = remote_read_packet(fd, &pkt_hdr); if (data) { ret = *((gint *) data); g_free(data); } remote_read_ack(fd); close(fd); return ret;}static gfloat remote_get_gfloat(gint session, gint cmd){ ServerPktHeader pkt_hdr; gpointer data; gint fd; gfloat ret = 0.0; if ((fd = xmms_connect_to_session(session)) == -1) return ret; remote_send_packet(fd, cmd, NULL, 0); data = remote_read_packet(fd, &pkt_hdr); if (data) { ret = *((gfloat *) data); g_free(data); } remote_read_ack(fd); close(fd); return ret;}gchar *remote_get_string(gint session, gint cmd){ ServerPktHeader pkt_hdr; gpointer data; gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return NULL; remote_send_packet(fd, cmd, NULL, 0); data = remote_read_packet(fd, &pkt_hdr); remote_read_ack(fd); close(fd); return data;}gchar *remote_get_string_pos(gint session, gint cmd, guint32 pos){ ServerPktHeader pkt_hdr; gpointer data; gint fd; if ((fd = xmms_connect_to_session(session)) == -1) return NULL; remote_send_packet(fd, cmd, &pos, sizeof (guint32)); data = remote_read_packet(fd, &pkt_hdr); remote_read_ack(fd); close(fd); return data;}gint xmms_connect_to_session(gint session){ gint fd; uid_t stored_uid, euid; struct sockaddr_un saddr; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { saddr.sun_family = AF_UNIX; stored_uid = getuid(); euid = geteuid(); setuid(euid); g_snprintf(saddr.sun_path, 108, "%s/xmms_%s.%d", g_get_tmp_dir(), g_get_user_name(), session); setreuid(stored_uid, euid); if (connect(fd, (struct sockaddr *) &saddr, sizeof (saddr)) != -1) return fd; } close(fd); return -1;}void xmms_remote_playlist(gint session, gchar ** list, gint num, gboolean enqueue){ gint fd, i; gchar *data, *ptr; gint data_length; guint32 len; g_return_if_fail(list != NULL); g_return_if_fail(num > 0); if (!enqueue) xmms_remote_playlist_clear(session); if ((fd = xmms_connect_to_session(session)) == -1) return; for (i = 0, data_length = 0; i < num; i++) data_length += (((strlen(list[i]) + 1) + 3) / 4) * 4 + 4; if (data_length) { data_length += 4; data = g_malloc(data_length); for (i = 0, ptr = data; i < num; i++) { len = strlen(list[i]) + 1; *((guint32 *) ptr) = len; ptr += 4; memcpy(ptr, list[i], len); ptr += ((len + 3) / 4) * 4; } *((guint32 *) ptr) = 0; remote_send_packet(fd, CMD_PLAYLIST_ADD, data, data_length); remote_read_ack(fd); close(fd); g_free(data); } if (!enqueue) xmms_remote_play(session);}gint xmms_remote_get_version(gint session){ return remote_get_gint(session, CMD_GET_VERSION);}void xmms_remote_play_files(gint session, GList * list){ g_return_if_fail(list != NULL); xmms_remote_playlist_clear(session); xmms_remote_add_files(session, list); xmms_remote_play(session);}void xmms_remote_playlist_add(gint session, GList * list){ gchar **str_list; GList *node; gint i, num; g_return_if_fail(list != NULL); num = g_list_length(list); str_list = g_malloc0(num * sizeof (gchar *)); for (i = 0, node = list; i < num && node; i++, node = g_list_next(node)) str_list[i] = node->data; xmms_remote_playlist(session, str_list, num, TRUE); g_free(str_list);}void xmms_remote_playlist_delete(gint session, gint pos){ remote_send_guint32(session,CMD_PLAYLIST_DELETE, pos);}void xmms_remote_play(gint session){ remote_cmd(session, CMD_PLAY);}void xmms_remote_pause(gint session){ remote_cmd(session, CMD_PAUSE);}void xmms_remote_stop(gint session){ remote_cmd(session, CMD_STOP);}void xmms_remote_play_pause(gint session){ remote_cmd(session, CMD_PLAY_PAUSE);}gboolean xmms_remote_is_playing(gint session){ return remote_get_gboolean(session, CMD_IS_PLAYING);}gboolean xmms_remote_is_paused(gint session){ return remote_get_gboolean(session, CMD_IS_PAUSED);}gint xmms_remote_get_playlist_pos(gint session){ return remote_get_gint(session, CMD_GET_PLAYLIST_POS);}void xmms_remote_set_playlist_pos(gint session, gint pos){ remote_send_guint32(session, CMD_SET_PLAYLIST_POS, pos);}gint xmms_remote_get_playlist_length(gint session){ return remote_get_gint(session, CMD_GET_PLAYLIST_LENGTH);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -