📄 apollo-client.c
字号:
/* apollo-client.c * * $Id: apollo-client.c,v 1.1.2.1 2002/06/27 14:52:34 amos Exp $ * * Apollo sound player: http://www.apolloplayer.org * Copyright(C) 2000-2002 Apollo Team. See CREDITS file. * * 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. * * The GNU General Public License is also available online at: * * http://www.gnu.org/copyleft/gpl.html *//*! \file apollo-client.c remote control client for apollo Apollo uses XMMSs remote control mechanism: this is the client part, a seperate program that sends commands to - and read information from - a running apollo using a simple binary protocol through a unix domain socket. The code was copied from xmmsctrl by Alexandre David <adavid@docs.uu.se>, available at http://www.docs.uu.se/~adavid/utils/, and xmms.*/ #include <stdio.h>#include <errno.h>#include <limits.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <pwd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define XMMS_PROTOCOL_VERSION 1#include "../glibtypes.c"#include "apollo-client.h" #ifdef __cplusplusextern "C" {#endif/******************************************************************************************************* functions from xmms ***************************************************************************************************************************************************/static gpointer remote_read_packet(gint fd, ServerPktHeader * pkt_hdr){ gpointer data = NULL; if (read(fd, pkt_hdr, sizeof (ServerPktHeader)) == sizeof (ServerPktHeader)) { if (pkt_hdr->data_length) { data = malloc(pkt_hdr->data_length); read(fd, data, pkt_hdr->data_length); } } return data;}static void remote_read_ack(gint fd){ gpointer data; ServerPktHeader pkt_hdr; data = remote_read_packet(fd, &pkt_hdr); if (data) free(data);}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; write(fd, &pkt_hdr, sizeof (ClientPktHeader)); if (data_length && data) write(fd, data, data_length);}static void remote_send_guint32(gint session, guint32 cmd, guint32 val){ gint fd; if ((fd = 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 = 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 = 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 = 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 = 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 = 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); 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 = 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); 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 = 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); 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 = 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 = 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 connect_to_session(gint session){ gint fd; uid_t stored_uid, euid; struct sockaddr_un saddr; static char *app_name_for_socket = "xmms"; struct passwd *pwd; char *user_name; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { saddr.sun_family = AF_UNIX; stored_uid = getuid(); euid = geteuid(); setuid(euid); pwd = getpwuid(getuid()); user_name = pwd ? pwd->pw_name : "wtf?"; /* failure should be logged */ sprintf(saddr.sun_path, "%s/%s_%s.%d", g_get_tmp_dir(), app_name_for_socket, user_name, session); setreuid(stored_uid, euid); if (connect(fd, (struct sockaddr *) &saddr, sizeof (saddr)) != -1) return fd; } close(fd); return -1;}void remote_playlist(gint session, gchar ** list, gint num, gboolean enqueue, gboolean playfirstp){ gint fd, i; gchar *data, *ptr; gint data_length; guint32 len; gchar **resolved_list; if (!enqueue) remote_playlist_clear(session); resolved_list = malloc(num*sizeof(gchar *)); for (i = 0; i < num; i++) { resolved_list[i] = malloc(PATH_MAX*sizeof(char)); if (realpath(list[i], resolved_list[i]) == NULL) { fprintf(stderr, "Resolve filename error: %s", strerror(errno)); exit(1); } } for (i = 0, data_length = 0; i < num; i++) { data_length += (((strlen(resolved_list[i]) + 1) + 3) / 4) * 4 + 4; } if (data_length) { data_length += 4; data = (gchar*) malloc(data_length); for (i = 0, ptr = data; i < num; i++) { len = strlen(resolved_list[i]) + 1; *((guint32 *) ptr) = len; ptr += 4; memcpy(ptr, resolved_list[i], len); ptr += ((len + 3) / 4) * 4; } *((guint32 *) ptr) = 0; if ((fd = connect_to_session(session)) == -1) return; remote_send_packet(fd, playfirstp ? CMD_PLAYFIRST_ADD : CMD_PLAYLIST_ADD, data, data_length); remote_read_ack(fd); close(fd); free(data); } if (!enqueue) remote_play(session);}void remote_play_files(gint session, GList * list){ remote_playlist_clear(session); remote_playlist_add(session, list); remote_play(session);}void remote_playlist_add(gint session, GList * list){ gchar **str_list; GList *node; gint i, num; num = g_list_length(list); str_list = (gchar**) malloc(num * sizeof (gchar *)); for (i = 0, node = list; i < num && node; i++, node = g_list_next(node)) { str_list[i] = node->data; } remote_playlist(session, str_list, num, TRUE, FALSE); free(str_list);}void remote_playlist_delete(gint session,gint pos){ remote_send_guint32(session,CMD_PLAYLIST_DELETE,pos);}void remote_play(gint session){ remote_cmd(session, CMD_PLAY);}void remote_pause(gint session){ remote_cmd(session, CMD_PAUSE);}void remote_stop(gint session){ remote_cmd(session, CMD_STOP);}gboolean remote_is_playing(gint session){ return remote_get_gboolean(session, CMD_IS_PLAYING);}gboolean remote_is_paused(gint session){ return remote_get_gboolean(session, CMD_IS_PAUSED);}gint remote_get_playlist_pos(gint session){ return remote_get_gint(session, CMD_GET_PLAYLIST_POS);}void remote_set_playlist_pos(gint session, gint pos){ remote_send_guint32(session, CMD_SET_PLAYLIST_POS, pos);}gint remote_get_playlist_length(gint session){ return remote_get_gint(session, CMD_GET_PLAYLIST_LENGTH);}void remote_playlist_clear(gint session){ remote_cmd(session, CMD_PLAYLIST_CLEAR);}gint remote_get_output_time(gint session){ return remote_get_gint(session, CMD_GET_OUTPUT_TIME);}void remote_jump_to_time(gint session, gint pos){ remote_send_guint32(session, CMD_JUMP_TO_TIME, pos);}void remote_get_volume(gint session, gint * vl, gint * vr){ ServerPktHeader pkt_hdr; gint fd; gpointer data; if ((fd = connect_to_session(session)) == -1) return; remote_send_packet(fd, CMD_GET_VOLUME, NULL, 0); data = remote_read_packet(fd, &pkt_hdr); if (data) { *vl = ((guint32 *) data)[0]; *vr = ((guint32 *) data)[1]; free(data); } remote_read_ack(fd); close(fd);}gint remote_get_main_volume(gint session){ gint vl, vr; remote_get_volume(session, &vl, &vr); return (vl > vr) ? vl : vr;}gint remote_get_balance(gint session){ return remote_get_gint(session, CMD_GET_BALANCE);}void remote_set_volume(gint session, gint vl, gint vr){ gint fd; guint32 v[2]; if (vl < 0) vl = 0; if (vl > 100) vl = 100; if (vr < 0) vr = 0; if (vr > 100) vr = 100; if ((fd = connect_to_session(session)) == -1) return; v[0] = vl; v[1] = vr; remote_send_packet(fd, CMD_SET_VOLUME, v, 2 * sizeof (guint32)); remote_read_ack(fd); close(fd);}void remote_set_main_volume(gint session, gint v){ gint b, vl, vr; b = remote_get_balance(session); if (b < 0) { vl = v; vr = (v * (100 - abs(b))) / 100; } else if (b > 0) { vl = (v * (100 - b)) / 100; vr = v; } else vl = vr = v; remote_set_volume(session, vl, vr);}void remote_set_balance(gint session, gint b){ gint v, vl, vr; if (b < -100) b = -100; if (b > 100) b = 100; v = remote_get_main_volume(session); if (b < 0) { vl = v; vr = (v * (100 - abs(b))) / 100; } else if (b > 0) { vl = (v * (100 - b)) / 100; vr = v; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -