Example #1
0
/*	let user pick one station
 *	@param piano handle
 *	@return pointer to selected station or NULL
 */
PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt,
		BarStationSorting_t order, FILE *curFd) {
	PianoStation_t **sortedStations = NULL, *retStation = NULL;
	size_t stationCount, i;
	int input;

	/* sort and print stations */
	sortedStations = BarSortedStations (ph->stations, &stationCount, order);
	for (i = 0; i < stationCount; i++) {
		const PianoStation_t *currStation = sortedStations[i];
		BarUiMsg (MSG_LIST, "%2i) %c%c%c %s\n", i,
				currStation->useQuickMix ? 'q' : ' ',
				currStation->isQuickMix ? 'Q' : ' ',
				!currStation->isCreator ? 'S' : ' ',
				currStation->name);
	}

	BarUiMsg (MSG_QUESTION, prompt);
	/* FIXME: using a _signed_ int is ugly */
	if (BarReadlineInt (&input, curFd) == 0) {
		free (sortedStations);
		return NULL;
	}
	if (input < stationCount) {
		retStation = sortedStations[input];
	}
	free (sortedStations);
	return retStation;
}
Example #2
0
/*	let user pick one station
 *	@param app handle
 *	@param prompt string
 *	@param called if input was not a number
 *	@return pointer to selected station or NULL
 */
PianoStation_t *BarUiSelectStation (BarApp_t *app, PianoStation_t *stations,
		const char *prompt, BarUiSelectStationCallback_t callback) {
	PianoStation_t **sortedStations = NULL, *retStation = NULL;
	size_t stationCount, i;
	char buf[100];

	if (stations == NULL) {
		BarUiMsg (&app->settings, MSG_ERR, "No station available.\n");
		return NULL;
	}

	memset (buf, 0, sizeof (buf));

	/* sort and print stations */
	sortedStations = BarSortedStations (stations, &stationCount,
			app->settings.sortOrder);

	do {
		for (i = 0; i < stationCount; i++) {
			const PianoStation_t *currStation = sortedStations[i];
			/* filter stations */
			if (BarStrCaseStr (currStation->name, buf) != NULL) {
				BarUiMsg (&app->settings, MSG_LIST, "%2i) %c%c%c %s\n", i,
						currStation->useQuickMix ? 'q' : ' ',
						currStation->isQuickMix ? 'Q' : ' ',
						!currStation->isCreator ? 'S' : ' ',
						currStation->name);
			}
		}

		BarUiMsg (&app->settings, MSG_QUESTION, prompt);
		if (BarReadlineStr (buf, sizeof (buf), &app->input,
				BAR_RL_DEFAULT) == 0) {
			free (sortedStations);
			return NULL;
		}

		if (isnumeric (buf)) {
			unsigned long selected = strtoul (buf, NULL, 0);
			if (selected < stationCount) {
				retStation = sortedStations[selected];
			}
		}

		/* hand over buffer to external function if it was not a station number */
		if (retStation == NULL && callback != NULL) {
			callback (app, buf);
		}
	} while (retStation == NULL);

	free (sortedStations);
	return retStation;
}
Example #3
0
/*	Excute external event handler
 *	@param settings containing the cmdline
 *	@param event type
 *	@param current station
 *	@param current song
 *	@param piano error-code (PIANO_RET_OK if not applicable)
 *	@param waitress error-code (WAITRESS_RET_OK if not applicable)
 */
void BarUiStartEventCmd (const BarSettings_t *settings, const char *type,
		const PianoStation_t *curStation, const PianoSong_t *curSong,
		const struct audioPlayer *player, PianoStation_t *stations,
                PianoReturn_t pRet, WaitressReturn_t wRet) {
	pid_t chld;
	int pipeFd[2];

	if (settings->eventCmd == NULL) {
		/* nothing to do... */
		return;
	}

	if (pipe (pipeFd) == -1) {
		BarUiMsg (settings, MSG_ERR, "Cannot create eventcmd pipe. (%s)\n", strerror (errno));
		return;
	}

	chld = fork ();
	if (chld == 0) {
		/* child */
		close (pipeFd[1]);
		dup2 (pipeFd[0], fileno (stdin));
		execl (settings->eventCmd, settings->eventCmd, type, (char *) NULL);
		BarUiMsg (settings, MSG_ERR, "Cannot start eventcmd. (%s)\n", strerror (errno));
		close (pipeFd[0]);
		exit (1);
	} else if (chld == -1) {
		BarUiMsg (settings, MSG_ERR, "Cannot fork eventcmd. (%s)\n", strerror (errno));
	} else {
		/* parent */
		int status;
		PianoStation_t *songStation = NULL;
		FILE *pipeWriteFd;

		close (pipeFd[0]);

		pipeWriteFd = fdopen (pipeFd[1], "w");

		if (curSong != NULL && stations != NULL && curStation->isQuickMix) {
			songStation = PianoFindStationById (stations, curSong->stationId);
		}

		fprintf (pipeWriteFd,
				"artist=%s\n"
				"title=%s\n"
				"album=%s\n"
				"coverArt=%s\n"
				"stationName=%s\n"
				"songStationName=%s\n"
				"pRet=%i\n"
				"pRetStr=%s\n"
				"wRet=%i\n"
				"wRetStr=%s\n"
				"songDuration=%lu\n"
				"songPlayed=%lu\n"
				"rating=%i\n"
				"detailUrl=%s\n",
				curSong == NULL ? "" : curSong->artist,
				curSong == NULL ? "" : curSong->title,
				curSong == NULL ? "" : curSong->album,
				curSong == NULL ? "" : curSong->coverArt,
				curStation == NULL ? "" : curStation->name,
				songStation == NULL ? "" : songStation->name,
				pRet,
				PianoErrorToStr (pRet),
				wRet,
				WaitressErrorToStr (wRet),
				player->songDuration,
				player->songPlayed,
				curSong == NULL ? PIANO_RATE_NONE : curSong->rating,
				curSong == NULL ? "" : curSong->detailUrl
				);

		if (stations != NULL) {
			/* send station list */
			PianoStation_t **sortedStations = NULL;
			size_t stationCount;
			sortedStations = BarSortedStations (stations, &stationCount,
					settings->sortOrder);
			assert (sortedStations != NULL);

			fprintf (pipeWriteFd, "stationCount=%zd\n", stationCount);

			for (size_t i = 0; i < stationCount; i++) {
				const PianoStation_t *currStation = sortedStations[i];
				fprintf (pipeWriteFd, "station%zd=%s\n", i,
						currStation->name);
			}
			free (sortedStations);
		} else {
			const char * const msg = "stationCount=0\n";
			fwrite (msg, sizeof (*msg), strlen (msg), pipeWriteFd);
		}
	
		/* closes pipeFd[1] as well */
		fclose (pipeWriteFd);
		/* wait to get rid of the zombie */
		waitpid (chld, &status, 0);
	}
}
Example #4
0
File: ui.c Project: biorisk/panpigo
/*	Excute external event handler
 *	@param settings containing the cmdline
 *	@param event type
 *	@param current station
 *	@param current song
 *	@param piano error-code (PIANO_RET_OK if not applicable)
 *	@param waitress error-code (WAITRESS_RET_OK if not applicable)
 */
void BarUiStartEventCmd (const BarSettings_t *settings, const char *type,
		const PianoStation_t *curStation, const PianoSong_t *curSong,
		const struct audioPlayer *player, PianoStation_t *stations,
                PianoReturn_t pRet, WaitressReturn_t wRet) {

	int status;
	PianoStation_t *songStation = NULL;

	if (curSong != NULL && stations != NULL && curStation->isQuickMix) {
		songStation = PianoFindStationById (stations, curSong->stationId);
	}

	printf ("current\tartist=%s\n"
			"current\ttitle=%s\n"
			"current\talbum=%s\n"
			"current\tcoverArt=%s\n"
			"current\tstationName=%s\n"
			"songStationName=%s\n"
			"pRet=%i\n"
			"pRetStr=%s\n"
			"wRet=%i\n"
			"wRetStr=%s\n"
			"songDuration=%lu\n"
			"songPlayed=%lu\n"
			"rating=%i\n"
			"detailUrl=%s\n",
			curSong == NULL ? "" : curSong->artist,
			curSong == NULL ? "" : curSong->title,
			curSong == NULL ? "" : curSong->album,
			curSong == NULL ? "" : curSong->coverArt,
			curStation == NULL ? "" : curStation->name,
			songStation == NULL ? "" : songStation->name,
			pRet,
			PianoErrorToStr (pRet),
			wRet,
			WaitressErrorToStr (wRet),
			player->songDuration,
			player->songPlayed,
			curSong == NULL ? PIANO_RATE_NONE : curSong->rating,
			curSong == NULL ? "" : curSong->detailUrl
			);

	if (stations != NULL) {
		/* send station list */
		PianoStation_t **sortedStations = NULL;
		size_t stationCount;
		sortedStations = BarSortedStations (stations, &stationCount,
				settings->sortOrder);
		assert (sortedStations != NULL);

		printf ("station\tstationCount=%zd\n", stationCount);

		for (size_t i = 0; i < stationCount; i++) {
			const PianoStation_t *currStation = sortedStations[i];
			printf ("station\tstation%zd=%s\n", i,
					currStation->name);
		}

		free (sortedStations);
	}
}
Example #5
0
/*	let user pick one station
 *	@param app handle
 *	@param stations that should be listed
 *	@param prompt string
 *	@param called if input was not a number
 *	@param auto-select if only one station remains after filtering
 *	@return pointer to selected station or NULL
 */
PianoStation_t *BarUiSelectStation (BarApp_t *app, PianoStation_t *stations,
		const char *prompt, BarUiSelectStationCallback_t callback,
		bool autoselect) {
	PianoStation_t **sortedStations = NULL, *retStation = NULL;
	size_t stationCount, i, lastDisplayed, displayCount;
	char buf[100];

	if (stations == NULL) {
		BarUiMsg (&app->settings, MSG_ERR, "No station available.\n");
		return NULL;
	}

	memset (buf, 0, sizeof (buf));

	/* sort and print stations */
	sortedStations = BarSortedStations (stations, &stationCount,
			app->settings.sortOrder);

	do {
		displayCount = 0;
		for (i = 0; i < stationCount; i++) {
			const PianoStation_t *currStation = sortedStations[i];
			/* filter stations */
			if (BarStrCaseStr (currStation->name, buf) != NULL) {
				BarUiMsg (&app->settings, MSG_LIST, "%2zi) %c%c%c %s\n", i,
						currStation->useQuickMix ? 'q' : ' ',
						currStation->isQuickMix ? 'Q' : ' ',
						!currStation->isCreator ? 'S' : ' ',
						currStation->name);
				++displayCount;
				lastDisplayed = i;
			}
		}

		BarUiMsg (&app->settings, MSG_QUESTION, "%s", prompt);
		if (autoselect && displayCount == 1 && stationCount != 1) {
			/* auto-select last remaining station */
			BarUiMsg (&app->settings, MSG_NONE, "%zi\n", lastDisplayed);
			retStation = sortedStations[lastDisplayed];
		} else {
			if (BarReadlineStr (buf, sizeof (buf), app->rl,
					BAR_RL_DEFAULT) == 0) {
				break;
			}

			if (isnumeric (buf)) {
				unsigned long selected = strtoul (buf, NULL, 0);
				if (selected < stationCount) {
					retStation = sortedStations[selected];
				}
			}

			/* hand over buffer to external function if it was not a station number */
			if (retStation == NULL && callback != NULL) {
				callback (app, buf);
			}
		}
	} while (retStation == NULL);

	free (sortedStations);
	return retStation;
}