summaryrefslogtreecommitdiff
path: root/src/modules/rtv
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/rtv')
-rw-r--r--src/modules/rtv/rtv.c159
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;
}
© All Rights Reserved