⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apollo-client.c

📁 可以播放MP3,wma等文件格式的播放器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -