Ejemplo n.º 1
0
Entry *pl_browser_get_selected_entry(PlaylistBrowser *pb)
{
	Entry *sel = gmu_core_playlist_get_first();
	int    i = 0;
	while (sel != NULL && i != pl_browser_get_selection(pb)) {
		sel = playlist_get_next(sel);
		i++;
	}
	return sel;
}
Ejemplo n.º 2
0
int
streamPlaylist(shout_t *shout, const char *fileName)
{
	const char	*song;
	char		 lastSong[PATH_MAX];

	if (playlist == NULL) {
		if (pezConfig->fileNameIsProgram) {
			if ((playlist = playlist_program(fileName)) == NULL)
				return (0);
		} else {
			if ((playlist = playlist_read(fileName)) == NULL)
				return (0);
			if (vFlag && playlist_get_num_items(playlist) == 0)
				printf("%s: Warning: Playlist '%s' is empty\n",
				       __progname, fileName);
		}
	} else {
		/*
		 * XXX: This preserves traditional behavior, however,
		 *      rereading the playlist after each walkthrough seems a
		 *      bit more logical.
		 */
		playlist_rewind(playlist);
	}

	if (!pezConfig->fileNameIsProgram && pezConfig->shuffle)
		playlist_shuffle(playlist);

	while ((song = playlist_get_next(playlist)) != NULL) {
		strlcpy(lastSong, song, sizeof(lastSong));
		if (!streamFile(shout, song))
			return (0);
		if (quit)
			break;
		if (rereadPlaylist) {
			rereadPlaylist = rereadPlaylist_notify = 0;
			if (pezConfig->fileNameIsProgram)
				continue;
			printf("%s: Rereading playlist\n", __progname);
			if (!playlist_reread(&playlist))
				return (0);
			if (pezConfig->shuffle)
				playlist_shuffle(playlist);
			else {
				playlist_goto_entry(playlist, lastSong);
				playlist_skip_next(playlist);
			}
			continue;
		}
	}

	return (1);
}
Ejemplo n.º 3
0
int pl_browser_are_selection_and_current_entry_equal(PlaylistBrowser *pb)
{
	int    i = 0, result = 0;
	Entry *entry;

	if (gmu_core_playlist_get_length() > 0) {
		entry = gmu_core_playlist_get_first();
		while (entry != NULL && i != pl_browser_get_selection(pb)) {
			entry = playlist_get_next(entry);
			i++;
		}
		if (entry == gmu_core_playlist_get_current())
			result = 1;
	}
	return result;
}
Ejemplo n.º 4
0
void pl_brower_move_selection_down(PlaylistBrowser *pb)
{
	if (pb->selection < gmu_core_playlist_get_length() - 1) {
		pb->selection++;
	} else {
		pb->selection = 0;
		pb->offset = 0;
		pb->first_visible_entry = gmu_core_playlist_get_first();
	}
	if (pb->selection > pb->offset + skin_textarea_get_number_of_lines((Skin *)pb->skin) - 1) {
		pb->offset++;
		if (pb->first_visible_entry != NULL)
			pb->first_visible_entry = playlist_get_next(pb->first_visible_entry);
		else
			pb->first_visible_entry = gmu_core_playlist_get_first();
	}
}
Ejemplo n.º 5
0
int pl_browser_playlist_remove_selection(PlaylistBrowser *pb)
{
	int    i = 0, result = 0;
	Entry *entry;

	if (gmu_core_playlist_get_length() > 0) {
		entry = gmu_core_playlist_get_first();
		while (entry != NULL && i != pl_browser_get_selection(pb)) {
			entry = playlist_get_next(entry);
			i++;
		}
		printf("Removing entry %s...\n", gmu_core_playlist_get_entry_name(entry));
		if (pb->first_visible_entry == entry)
			pb->first_visible_entry = (entry->next ? entry->next : entry->prev);
		result = gmu_core_playlist_entry_delete(entry);
		if (pb->selection > gmu_core_playlist_get_length() - 1)
			pb->selection = (gmu_core_playlist_get_length() - 1 >= 0 ? 
			                 gmu_core_playlist_get_length() - 1 : 0);
	}
	return result;
}
Ejemplo n.º 6
0
int pl_browser_set_selection(PlaylistBrowser *pb, int pos)
{
	int res = 0, i, new_first_visible_entry = 0;
	Entry *entry = gmu_core_playlist_get_first();

	if (pos < gmu_core_playlist_get_length() && pos >= 0) {
		pb->selection = pos;
		if (pb->selection < pb->offset) {
			pb->offset = pb->selection;
			new_first_visible_entry = 1;
		} else if (pb->selection > pb->offset + skin_textarea_get_number_of_lines((Skin *)pb->skin) - 1) {
			pb->offset = pb->selection;
			new_first_visible_entry = 1;
		}
		if (new_first_visible_entry) {
			for (i = 0; i < pos; i++)
				entry = playlist_get_next(entry);
			pb->first_visible_entry = entry;
		}  
		res = 1;
	}
	return res;
}
Ejemplo n.º 7
0
int
main(int argc, char *argv[])
{
	int		 c;
	char		*configFile = NULL;
	char		*host = NULL;
	unsigned short	 port = 0;
	char		*mount = NULL;
	shout_t 	*shout;
	extern char	*optarg;
	extern int	 optind;
#ifdef HAVE_SIGNALS
	struct sigaction act;
	unsigned int	 i;
#endif

#ifdef XALLOC_DEBUG
	xalloc_initialize_debug(2, NULL);
#else
	xalloc_initialize();
#endif /* XALLOC_DEBUG */
	playlist_init();
	shout_init();

	__progname = getProgname(argv[0]);
	pezConfig = getEZConfig();

	mFlag = 0;
	nFlag = 0;
	qFlag = 0;
	vFlag = 0;

	while ((c = local_getopt(argc, argv, "c:hmnqsVv")) != -1) {
		switch (c) {
		case 'c':
			if (configFile != NULL) {
				printf("Error: multiple -c arguments given\n");
				usage();
				return (ez_shutdown(2));
			}
			configFile = xstrdup(optarg);
			break;
		case 'h':
			usage();
			usageHelp();
			return (ez_shutdown(0));
		case 'm':
			mFlag = 1;
			break;
		case 'n':
			nFlag = 1;
			break;
		case 'q':
			qFlag = 1;
			break;
		case 's':
			sFlag = 1;
			break;
		case 'V':
			printf("%s\n", PACKAGE_STRING);
			return (ez_shutdown(0));
		case 'v':
			vFlag++;
			break;
		case '?':
			usage();
			return (ez_shutdown(2));
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;

	if (sFlag) {
		playlist_t	*pl;
		const char	*entry;

		switch (argc) {
		case 0:
			pl = playlist_read(NULL);
			if (pl == NULL)
				return (ez_shutdown(1));
			break;
		case 1:
			pl = playlist_read(argv[0]);
			if (pl == NULL)
				return (ez_shutdown(1));
			break;
		default:
			printf("Error: Too many arguments.\n");
			return (ez_shutdown(2));
		}

		playlist_shuffle(pl);
		while ((entry = playlist_get_next(pl)) != NULL)
			printf("%s\n", entry);

		playlist_free(&pl);

		return (ez_shutdown(0));
	}

	if (configFile == NULL) {
		printf("You must supply a config file with the -c argument.\n");
		usage();
		return (ez_shutdown(2));
	} else {
		/*
		 * Attempt to open configFile here for a more meaningful error
		 * message. Where possible, do it with stat() and check for
		 * safe config file permissions.
		 */
#ifdef HAVE_STAT
		struct stat	  st;

		if (stat(configFile, &st) == -1) {
			printf("%s: %s\n", configFile, strerror(errno));
			usage();
			return (ez_shutdown(2));
		}
		if (vFlag && (st.st_mode & (S_IRGRP | S_IROTH)))
			printf("%s: Warning: %s is group and/or world readable\n",
			       __progname, configFile);
		if (st.st_mode & (S_IWGRP | S_IWOTH)) {
			printf("%s: Error: %s is group and/or world writeable\n",
			       __progname, configFile);
			return (ez_shutdown(2));
		}
#else
		FILE		 *tmp;

		if ((tmp = fopen(configFile, "r")) == NULL) {
			printf("%s: %s\n", configFile, strerror(errno));
			usage();
			return (ez_shutdown(2));
		}
		fclose(tmp);
#endif /* HAVE_STAT */
	}

	if (!parseConfig(configFile))
		return (ez_shutdown(2));

	if (pezConfig->URL == NULL) {
		printf("%s: Error: Missing <url>\n", configFile);
		return (ez_shutdown(2));
	}
	if (!urlParse(pezConfig->URL, &host, &port, &mount)) {
		printf("Must be of the form ``http://server:port/mountpoint''\n");
		return (ez_shutdown(2));
	}
	if (strlen(host) == 0) {
		printf("%s: Error: Invalid <url>: Missing server:\n", configFile);
		printf("Must be of the form ``http://server:port/mountpoint''\n");
		return (ez_shutdown(2));
	}
	if (strlen(mount) == 0) {
		printf("%s: Error: Invalid <url>: Missing mountpoint:\n", configFile);
		printf("Must be of the form ``http://server:port/mountpoint''\n");
		return (ez_shutdown(2));
	}
	if (pezConfig->password == NULL) {
		printf("%s: Error: Missing <sourcepassword>\n", configFile);
		return (ez_shutdown(2));
	}
	if (pezConfig->fileName == NULL) {
		printf("%s: Error: Missing <filename>\n", configFile);
		return (ez_shutdown(2));
	}
	if (pezConfig->format == NULL) {
		printf("%s: Warning: Missing <format>:\n", configFile);
		printf("Specify a stream format of either MP3, VORBIS or THEORA\n");
	}

	xfree(configFile);

	if ((shout = stream_setup(host, port, mount)) == NULL)
		return (ez_shutdown(1));

	if (pezConfig->metadataProgram != NULL)
		metadataFromProgram = 1;
	else
		metadataFromProgram = 0;

#ifdef HAVE_SIGNALS
	memset(&act, 0, sizeof(act));
	act.sa_handler = sig_handler;
# ifdef SA_RESTART
	act.sa_flags = SA_RESTART;
# endif
	for (i = 0; i < sizeof(ezstream_signals) / sizeof(int); i++) {
		if (sigaction(ezstream_signals[i], &act, NULL) == -1) {
			printf("%s: sigaction(): %s\n",
			       __progname, strerror(errno));
			return (ez_shutdown(1));
		}
	}
	/*
	 * Ignore SIGPIPE, which has been seen to give a long-running ezstream
	 * process trouble. EOF and/or EPIPE are also easier to handle.
	 */
	act.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &act, NULL) == -1) {
		printf("%s: sigaction(): %s\n",
		       __progname, strerror(errno));
		return (ez_shutdown(1));
	}
#endif /* HAVE_SIGNALS */

	if (shout_open(shout) == SHOUTERR_SUCCESS) {
		int	ret;

		printf("%s: Connected to http://%s:%hu%s\n", __progname,
		       host, port, mount);

		if (pezConfig->fileNameIsProgram ||
		    strrcasecmp(pezConfig->fileName, ".m3u") == 0 ||
		    strrcasecmp(pezConfig->fileName, ".txt") == 0)
			playlistMode = 1;
		else
			playlistMode = 0;

		if (vFlag && pezConfig->fileNameIsProgram)
			printf("%s: Using program '%s' to get filenames for streaming\n",
			       __progname, pezConfig->fileName);

		do {
			if (playlistMode) {
				ret = streamPlaylist(shout,
						     pezConfig->fileName);
			} else {
				ret = streamFile(shout, pezConfig->fileName);
			}
			if (quit)
				break;
			if (pezConfig->streamOnce)
				break;
		} while (ret);

		shout_close(shout);
	} else
		printf("%s: Connection to http://%s:%hu%s failed: %s\n", __progname,
		       host, port, mount, shout_get_error(shout));

	if (quit)
		printf("\r%s: SIGINT or SIGTERM received\n", __progname);

	if (vFlag)
		printf("%s: Exiting ...\n", __progname);

	xfree(host);
	xfree(mount);
	playlist_free(&playlist);

	return (ez_shutdown(0));
}
Ejemplo n.º 8
0
void pl_browser_draw(PlaylistBrowser *pb, SDL_Surface *sdl_target)
{
	int    i = 0;
	char   buf[64];
	Entry *pl_entry;
	int    number_of_visible_lines = skin_textarea_get_number_of_lines((Skin *)pb->skin);
	int    len = (skin_textarea_get_characters_per_line((Skin *)pb->skin) > 63 ? 
	              63 : skin_textarea_get_characters_per_line((Skin *)pb->skin));
	int    selected_entry_drawn = 0;

	snprintf(buf, 63, "Playlist (%d %s)", gmu_core_playlist_get_length(),
	         gmu_core_playlist_get_length() != 1 ? "entries" : "entry");
	skin_draw_header_text((Skin *)pb->skin, buf, sdl_target);

	if (pb->first_visible_entry == NULL || pb->offset == 0) {
		pb->first_visible_entry = gmu_core_playlist_get_first();
	}

	pb->longest_line_so_far = 0;
	pl_entry = pb->first_visible_entry;
	for (i = pb->offset; 
	     i < pb->offset + number_of_visible_lines && 
	     i < gmu_core_playlist_get_length() && pl_entry != NULL;
	     i++) {
		char  c = (playlist_get_played(pl_entry) ? 'o' : ' ');
		char *entry_name = gmu_core_playlist_get_entry_name(pl_entry);
		char *format = "%c%3d";
		int   l = gmu_core_playlist_get_length();
		int   line_length = strlen(entry_name);
		LCD  *font, *font_inverted;

		if (line_length > pb->longest_line_so_far)
			pb->longest_line_so_far = line_length;

		if (l > 999 && l <= 9999) format = "%c%4d";
		if (l > 9999) format = "%c%5d";

		if (playlist_entry_get_queue_pos(pl_entry) == 0)
			snprintf(buf, len, format, (pl_entry == gmu_core_playlist_get_current() ? '*' : c), i + 1);
		else
			snprintf(buf, len, "%cQ:%d", (pl_entry == gmu_core_playlist_get_current() ? '*' : c),
			         playlist_entry_get_queue_pos(pl_entry));

		if (i == pb->offset + number_of_visible_lines - 1 && !selected_entry_drawn)
			pb->selection = i;

		font =          (LCD *)(i == pb->selection ? &pb->skin->font2 : &pb->skin->font1);
		font_inverted = (LCD *)(i == pb->selection ? &pb->skin->font1 : &pb->skin->font2);

		if (i == pb->selection) selected_entry_drawn = 1;
		lcd_draw_string(font, buf, sdl_target, gmu_widget_get_pos_x((GmuWidget *)&pb->skin->lv, 1),
						gmu_widget_get_pos_y((GmuWidget *)&pb->skin->lv, 1) + 1
						+ (i-pb->offset) * (pb->skin->font2_char_height + 1));
		lcd_draw_string_with_highlight(font, font_inverted, entry_name, pb->horiz_offset, sdl_target, 
									   gmu_widget_get_pos_x((GmuWidget *)&pb->skin->lv, 1)
									   + pb->skin->font1_char_width * 7,
									   gmu_widget_get_pos_y((GmuWidget *)&pb->skin->lv, 1) + 1
									   + (i-pb->offset)*(pb->skin->font2_char_height+1),
									   skin_textarea_get_characters_per_line((Skin *)pb->skin)-6, RENDER_ARROW);
		pl_entry = playlist_get_next(pl_entry);
	}
}