diff options
Diffstat (limited to 'src/modules/rtv/rtv.c')
| -rw-r--r-- | src/modules/rtv/rtv.c | 159 | 
1 files changed, 101 insertions, 58 deletions
| diff --git a/src/modules/rtv/rtv.c b/src/modules/rtv/rtv.c index b49ac37..217368c 100644 --- a/src/modules/rtv/rtv.c +++ b/src/modules/rtv/rtv.c @@ -20,6 +20,7 @@  #define RTV_DURATION_SECS		15  #define RTV_CAPTION_DURATION_SECS	5  #define RTV_CONTEXT_DURATION_SECS	60 +#define RTV_DEFAULT_SNOW_MODULE		"snow"  typedef struct rtv_channel_t {  	const til_module_t	*module; @@ -38,12 +39,26 @@ typedef struct rtv_context_t {  	rtv_channel_t		*channel, *last_channel;  	txt_t			*caption; +	unsigned		duration; +	unsigned		context_duration; +	unsigned		snow_duration; +	unsigned		caption_duration; +  	rtv_channel_t		snow_channel;  	size_t			n_channels;  	rtv_channel_t		channels[];  } rtv_context_t; +typedef struct rtv_setup_t { +	unsigned	duration; +	unsigned	context_duration; +	unsigned	snow_duration; +	unsigned	caption_duration; +	char 		*snow_module; +	char		*channels[]; +} rtv_setup_t; +  static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks);  static void * rtv_create_context(unsigned ticks, unsigned num_cpus, void *setup);  static void rtv_destroy_context(void *context); @@ -51,12 +66,14 @@ static void rtv_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, ti  static void rtv_finish_frame(void *context, unsigned ticks, til_fb_fragment_t *fragment);  static int rtv_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, void **res_setup); -static unsigned rtv_duration = RTV_DURATION_SECS; -static unsigned rtv_context_duration = RTV_CONTEXT_DURATION_SECS; -static unsigned rtv_snow_duration = RTV_SNOW_DURATION_SECS; -static unsigned rtv_caption_duration = RTV_CAPTION_DURATION_SECS; -static char	**rtv_channels; -static char 	*rtv_snow_module; +static rtv_setup_t rtv_default_setup = { +	.duration = RTV_DURATION_SECS, +	.context_duration = RTV_CONTEXT_DURATION_SECS, +	.snow_duration = RTV_SNOW_DURATION_SECS, +	.caption_duration = RTV_CAPTION_DURATION_SECS, +	.snow_module = RTV_DEFAULT_SNOW_MODULE, +	.channels = { NULL }, /* NULL == "all" */ +};  til_module_t	rtv_module = { @@ -143,7 +160,7 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks)  	 */  	if (ctxt->channel) {  		ctxt->channel->cumulative_time += now - ctxt->channel->last_on_time; -		if (ctxt->channel->cumulative_time >= rtv_context_duration) { +		if (ctxt->channel->cumulative_time >= ctxt->context_duration) {  			ctxt->channel->cumulative_time = 0;  			ctxt->channel->module_ctxt = til_module_destroy_context(ctxt->channel->module, ctxt->channel->module_ctxt); @@ -159,7 +176,7 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks)  		ctxt->last_channel = ctxt->channel;  		ctxt->channel = &ctxt->snow_channel;  		ctxt->caption = NULL; -		ctxt->next_switch = now + rtv_snow_duration; +		ctxt->next_switch = now + ctxt->snow_duration;  	} else {  		size_t	i; @@ -195,8 +212,8 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks)  			ctxt->channel->settings = settings ? settings : strdup("");  		} -		ctxt->next_switch = now + rtv_duration; -		ctxt->next_hide_caption = now + rtv_caption_duration; +		ctxt->next_switch = now + ctxt->duration; +		ctxt->next_hide_caption = now + ctxt->caption_duration;  	}  	if (!ctxt->channel->module_ctxt) @@ -206,16 +223,19 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks)  } -static int rtv_should_skip_module(const rtv_context_t *ctxt, const til_module_t *module) +static int rtv_should_skip_module(const rtv_setup_t *setup, const til_module_t *module)  {  	if (module == &rtv_module || -	    module == ctxt->snow_channel.module) +	    (setup->snow_module && !strcmp(module->name, setup->snow_module)))  		return 1; -	if (!rtv_channels) +	/* An empty channels list is a special case for representing "all", an +	 * empty channels setting returns -EINVAL during _setup(). +	 */ +	if (!setup->channels[0])  		return 0; -	for (char **channel = rtv_channels; *channel; channel++) { +	for (char * const *channel = setup->channels; *channel; channel++) {  		if (!strcmp(module->name, *channel))  			return 0;  	} @@ -228,28 +248,39 @@ static void * rtv_create_context(unsigned ticks, unsigned num_cpus, void *setup)  {  	rtv_context_t		*ctxt;  	const til_module_t	**modules; -	size_t			n_modules; +	size_t			n_modules, n_channels = 0;  	static til_module_t	none_module = {}; +	if (!setup) +		setup = &rtv_default_setup; +  	til_get_modules(&modules, &n_modules); -	ctxt = calloc(1, sizeof(rtv_context_t) + n_modules * sizeof(rtv_channel_t)); +	/* how many modules are in the setup? */ +	for (size_t i = 0; i < n_modules; i++) { +		if (!rtv_should_skip_module(setup, modules[i])) +			n_channels++; +	} + +	ctxt = calloc(1, sizeof(rtv_context_t) + n_channels * sizeof(rtv_channel_t));  	if (!ctxt)  		return NULL;  	ctxt->n_cpus = num_cpus; +	ctxt->duration = ((rtv_setup_t *)setup)->duration; +	ctxt->context_duration = ((rtv_setup_t *)setup)->context_duration; +	ctxt->snow_duration = ((rtv_setup_t *)setup)->snow_duration; +	ctxt->caption_duration = ((rtv_setup_t *)setup)->caption_duration;  	ctxt->snow_channel.module = &none_module; -	if (rtv_snow_module) { -		ctxt->snow_channel.module = til_lookup_module(rtv_snow_module); +	if (((rtv_setup_t *)setup)->snow_module) { +		ctxt->snow_channel.module = til_lookup_module(((rtv_setup_t *)setup)->snow_module);  		(void) til_module_create_context(ctxt->snow_channel.module, ticks, NULL, &ctxt->snow_channel.module_ctxt);  	}  	for (size_t i = 0; i < n_modules; i++) { -		if (rtv_should_skip_module(ctxt, modules[i])) -			continue; - -		ctxt->channels[ctxt->n_channels++].module = modules[i]; +		if (!rtv_should_skip_module(setup, modules[i])) +			ctxt->channels[ctxt->n_channels++].module = modules[i];  	}  	setup_next_channel(ctxt, ticks); @@ -400,52 +431,64 @@ static int rtv_setup(const til_settings_t *settings, til_setting_t **res_setting  	if (r)  		return r; -	/* turn channels colon-separated list into a null-terminated array of strings */ -	if (strcmp(channels, "all")) { -		const til_module_t	**modules; -		size_t			n_modules; -		char			*tokchannels, *channel; -		int			n = 2; - -		til_get_modules(&modules, &n_modules); +	if (res_setup) { +		rtv_setup_t	*setup; -		tokchannels = strdup(channels); -		if (!tokchannels) +		setup = calloc(1, sizeof(*setup) + sizeof(setup->channels[0])); +		if (!setup)  			return -ENOMEM; -		channel = strtok(tokchannels, ":"); -		do { -			char	**new; -			size_t	i; +		/* turn channels colon-separated list into a null-terminated array of strings */ +		if (strcmp(channels, "all")) { +			const til_module_t	**modules; +			size_t			n_modules; +			char			*tokchannels, *channel; +			int			n = 2; -			for (i = 0; i < n_modules; i++) { -				if (!strcmp(channel, modules[i]->name)) -					break; -			} - -			if (i >= n_modules) -				return -EINVAL; +			til_get_modules(&modules, &n_modules); -			new = realloc(rtv_channels, n * sizeof(*rtv_channels)); -			if (!new) +			tokchannels = strdup(channels); +			if (!tokchannels)  				return -ENOMEM; -			new[n - 2] = channel; -			new[n - 1] = NULL; -			n++; +			channel = strtok(tokchannels, ":"); +			do { +				rtv_setup_t	*new; +				size_t		i; -			rtv_channels = new; -		} while (channel = strtok(NULL, ":")); -	} +				for (i = 0; i < n_modules; i++) { +					if (!strcmp(channel, modules[i]->name)) +						break; +				} + +				if (i >= n_modules) +					return -EINVAL; + +				new = realloc(setup, sizeof(*setup) + n * sizeof(setup->channels[0])); +				if (!new) { +					free(setup); +					return -ENOMEM; +				} -	if (strcmp(snow_module, "none")) -		rtv_snow_module = strdup(snow_module); +				new->channels[n - 2] = channel; +				new->channels[n - 1] = NULL; +				n++; -	/* TODO FIXME: parse errors */ -	sscanf(duration, "%u", &rtv_duration); -	sscanf(context_duration, "%u", &rtv_context_duration); -	sscanf(caption_duration, "%u", &rtv_caption_duration); -	sscanf(snow_duration, "%u", &rtv_snow_duration); +				setup = new; +			} while (channel = strtok(NULL, ":")); +		} + +		if (strcmp(snow_module, "none")) +			setup->snow_module = strdup(snow_module); + +		/* TODO FIXME: parse errors */ +		sscanf(duration, "%u", &setup->duration); +		sscanf(context_duration, "%u", &setup->context_duration); +		sscanf(caption_duration, "%u", &setup->caption_duration); +		sscanf(snow_duration, "%u", &setup->snow_duration); + +		*res_setup = setup; +	}  	return 0;  } | 
