Skip to content

Commit

Permalink
Added support for Dynamic PSN / RT from file. Use Dynamic PSN at your…
Browse files Browse the repository at this point in the history
… own risk !
  • Loading branch information
mickflemm committed Aug 15, 2017
1 parent d62ff90 commit 63d07ec
Show file tree
Hide file tree
Showing 11 changed files with 743 additions and 24 deletions.
3 changes: 2 additions & 1 deletion Makefile.am
Expand Up @@ -5,7 +5,7 @@ jmpxrds_SOURCES = filters.c oscilator.c resampler.c rds_encoder.c \
jmpxrds_LDADD = $(LIBM) $(LIBRT) $(LIBSAMPLERATE) $(LIBFFTW3) $(LIBJACK)
jmpxrds_CFLAGS = $(CFLAGS)

rds_tool_SOURCES = utils.c rds_config.c rds_tool.c
rds_tool_SOURCES = utils.c rds_config.c rds_dynpsrt.c rds_tool.c
rds_tool_LDADD = $(LIBRT)
rds_tool_CFLAGS = $(CFLAGS)

Expand All @@ -17,6 +17,7 @@ if GUI
bin_PROGRAMS += jmpxrds_gui

jmpxrds_gui_SOURCES = utils.c rds_config.c
jmpxrds_gui_SOURCES += @srcdir@/gui/jmrg_file_chooser.c @srcdir@/rds_dynpsrt.c
jmpxrds_gui_SOURCES += @srcdir@/gui/jmrg_radio_button.c @srcdir@/gui/jmrg_switch.c
jmpxrds_gui_SOURCES += @srcdir@/gui/jmrg_level_bar.c @srcdir@/gui/jmrg_vscale.c
jmpxrds_gui_SOURCES += @srcdir@/gui/jmrg_mpx_plotter.c @srcdir@/gui/jmrg_mpx_plotter_gl.c
Expand Down
8 changes: 8 additions & 0 deletions gui/jmpxrds_gui.h
Expand Up @@ -50,6 +50,13 @@ struct value_map {

/* Autocomplete entry match index */
int acentry_match_idx;

/* Dynamic PSN / RT infos */
struct rds_dynps_state dps;
struct rds_dynrt_state drt;

/* Switch for disabling Dynamic PSN / RT */
GtkWidget *sw;
};


Expand All @@ -61,6 +68,7 @@ GtkWidget* jmrg_level_bar_init(const char*, float*);
GtkWidget* jmrg_radio_button_init(const char*, int *, int, GtkRadioButton*);
/* Widgets on RDSEnc panel */
GtkWidget* jmrg_set_button_init(const char*, struct value_map*);
GtkWidget* jmrg_file_chooser_init(struct value_map*);
GtkWidget* jmrg_checkbox_init(struct rds_encoder_state*, const char*,
int, int, int);
GtkWidget* jmrg_display_field_init(struct rds_encoder_state*, const char*, int);
Expand Down
59 changes: 42 additions & 17 deletions gui/jmrg_display_field.c
Expand Up @@ -31,12 +31,22 @@ jmrg_display_field_poll(gpointer data)
gtk_label_set_text(GTK_LABEL(vmap->target), pi);
return TRUE;
case RDS_FIELD_PS:
if(!st->ps_set)
return TRUE;
text = rds_get_ps(st);
if(gtk_widget_get_sensitive(vmap->target2) == FALSE)
gtk_widget_set_sensitive(vmap->target2, TRUE);
break;
case RDS_FIELD_RT:
if(!st->rt_set)
return TRUE;
text = rds_get_rt(st);
if(gtk_widget_get_sensitive(vmap->target2) == FALSE)
gtk_widget_set_sensitive(vmap->target2, TRUE);
break;
case RDS_FIELD_PTYN:
if(!st->ptyn_set)
return TRUE;
text = rds_get_ptyn(st);
if(!text) {
tmp = rds_get_pty(st);
Expand All @@ -49,7 +59,9 @@ jmrg_display_field_poll(gpointer data)
return FALSE;
}

gtk_label_set_text(GTK_LABEL(vmap->target), text);
if(text)
gtk_label_set_text(GTK_LABEL(vmap->target), text);

return TRUE;
}

Expand All @@ -64,31 +76,32 @@ jmrg_display_field_init(struct rds_encoder_state *st, const char* label, int typ
GtkWidget *container = NULL;
GtkWidget *vbox = NULL;
GtkWidget *display = NULL;
GtkWidget *hbox = NULL;
GtkWidget *input_hbox = NULL;
GtkWidget *input = NULL;
GtkWidget *flag_check = NULL;
GtkWidget *set_button = NULL;
GtkWidget *file_chooser = NULL;
GtkStyleContext *context = NULL;
struct value_map *vmap = NULL;
int has_flag = 1;
int has_flag = 0;
int is_dynamic = 0;
int max_len = 1;

switch(type) {
case RDS_FIELD_PI:
max_len = 5;
has_flag = 0;
break;
case RDS_FIELD_PS:
max_len = RDS_PS_LENGTH;
has_flag = 0;
is_dynamic = 1;
break;
case RDS_FIELD_RT:
max_len = RDS_RT_LENGTH;
has_flag = 1;
is_dynamic = 1;
break;
case RDS_FIELD_PTYN:
max_len = RDS_PTYN_LENGTH;
has_flag = 0;
break;
default:
return NULL;
Expand All @@ -107,6 +120,7 @@ jmrg_display_field_init(struct rds_encoder_state *st, const char* label, int typ
else
gtk_frame_set_shadow_type(GTK_FRAME(container),
GTK_SHADOW_NONE);
gtk_widget_set_valign(container, GTK_ALIGN_START);


/* Use a box to have better control */
Expand All @@ -115,12 +129,11 @@ jmrg_display_field_init(struct rds_encoder_state *st, const char* label, int typ
goto cleanup;
gtk_container_add(GTK_CONTAINER(container), vbox);


/* Create the display as a label widget */
display = gtk_label_new(NULL);
if(!display)
goto cleanup;
gtk_box_pack_start(GTK_BOX(vbox), display, 1, 1, 6);
gtk_box_pack_start(GTK_BOX(vbox), display, 1, 0, 6);
gtk_label_set_max_width_chars(GTK_LABEL(display), max_len);

/* Register custom CSS */
Expand All @@ -130,26 +143,25 @@ jmrg_display_field_init(struct rds_encoder_state *st, const char* label, int typ

/* Create the input field with its set button and
* an optional checkbox (flag) for the RT field */
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
if(!hbox)
input_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
if(!input_hbox)
goto cleanup;
gtk_box_pack_end(GTK_BOX(vbox), hbox, 1, 1, 6);
gtk_box_pack_start(GTK_BOX(vbox), input_hbox, 1, 1, 6);

input = gtk_entry_new();
if(!input)
goto cleanup;
gtk_box_pack_start(GTK_BOX(hbox), input, 1, 1, 6);
gtk_box_pack_start(GTK_BOX(input_hbox), input, 1, 1, 6);
gtk_entry_set_max_width_chars(GTK_ENTRY(input), max_len);

if(has_flag) {
flag_check = jmrg_checkbox_init(st, "Flush remote buffer",
0, 0, 1);
if(!flag_check)
goto cleanup;
gtk_box_pack_start(GTK_BOX(hbox), flag_check, 0, 0, 2);
gtk_box_pack_start(GTK_BOX(input_hbox), flag_check, 0, 0, 2);
}


/* Initialize value_map */
vmap = malloc(sizeof(struct value_map));
if(!vmap)
Expand All @@ -166,9 +178,20 @@ jmrg_display_field_init(struct rds_encoder_state *st, const char* label, int typ
set_button = jmrg_set_button_init("Set", vmap);
if(!set_button)
goto cleanup;
gtk_box_pack_start(GTK_BOX(hbox), set_button, 0, 0, 6);
gtk_box_pack_start(GTK_BOX(input_hbox), set_button, 0, 0, 6);


/* If it's Dynamic PSN / RT, add the file chooser */
if(is_dynamic) {
file_chooser = jmrg_file_chooser_init(vmap);
if(!file_chooser)
goto cleanup;
gtk_box_pack_start(GTK_BOX(vbox), file_chooser, 1, 1, 6);
gtk_widget_set_halign(file_chooser, GTK_ALIGN_START);
gtk_widget_set_sensitive(file_chooser, FALSE);
vmap->target2 = file_chooser;
}

/* Register polling function and signal handlers */
vmap->esid = g_timeout_add(200, jmrg_display_field_poll, vmap);

Expand All @@ -179,10 +202,12 @@ jmrg_display_field_init(struct rds_encoder_state *st, const char* label, int typ
cleanup:
if(vmap)
free(vmap);
if(set_button)
gtk_widget_destroy(set_button);
if(input)
gtk_widget_destroy(input);
if(hbox)
gtk_widget_destroy(hbox);
if(input_hbox)
gtk_widget_destroy(input_hbox);
if(display)
gtk_widget_destroy(display);
if(vbox)
Expand Down
155 changes: 155 additions & 0 deletions gui/jmrg_file_chooser.c
@@ -0,0 +1,155 @@
#include <stdlib.h> /* For strtol() */
#include "jmpxrds_gui.h"
#include <linux/limits.h> /* For PATH_MAX */
#include <string.h> /* For strncmp() */

/*****************\
* SIGNAL HANDLERS *
\*****************/

static void
jmrg_file_chooser_done(GtkWidget *button, gpointer data)
{
struct value_map *vmap = (struct value_map*) data;
struct rds_encoder_state *st = vmap->st;
const char *filepath = NULL;
int ret = 0;

filepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(button));

switch(vmap->type) {
case RDS_FIELD_PS:
if((&vmap->dps)->active)
rds_dynps_destroy(&vmap->dps);
if(!filepath)
return;
ret = rds_dynps_init(&vmap->dps, vmap->st, filepath);
break;
case RDS_FIELD_RT:
if((&vmap->drt)->active)
rds_dynrt_destroy(&vmap->drt);
if(!filepath)
return;
ret = rds_dynrt_init(&vmap->drt, vmap->st, filepath);
break;
default:
return;
};


if(gtk_switch_get_state(GTK_SWITCH(vmap->sw)) == FALSE)
gtk_switch_set_state(GTK_SWITCH(vmap->sw), TRUE);

return;
}

static gboolean
jmrg_file_chooser_swtoggle(GtkSwitch *widget, gboolean state, gpointer data)
{
struct value_map *vmap = (struct value_map*) data;
GtkWidget *parent = gtk_widget_get_parent(GTK_WIDGET(widget));
GList *children = gtk_container_get_children(GTK_CONTAINER(parent));
GtkWidget *file_chooser = g_list_nth_data(children, 1);
int active = 0;

switch(vmap->type) {
case RDS_FIELD_PS:
active = (&vmap->dps)->active;
break;
case RDS_FIELD_RT:
active = (&vmap->drt)->active;
break;
default:
return FALSE;
};

if(state) {
if((&vmap->dps)->active)
return FALSE;

if(vmap->type == RDS_FIELD_PS && (&vmap->dps)->filepath)
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(file_chooser),
(&vmap->dps)->filepath);
else if(vmap->type == RDS_FIELD_RT && (&vmap->drt)->filepath)
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(file_chooser),
(&vmap->drt)->filepath);
else {
gtk_switch_set_state(widget, FALSE);
return FALSE;
}
} else {
if(!(&vmap->dps)->active)
return FALSE;
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(file_chooser));
}

g_signal_emit_by_name(G_OBJECT(file_chooser), "file-set");
return FALSE;
}

/*************\
* ENTRY POINT *
\*************/

GtkWidget*
jmrg_file_chooser_init(struct value_map *vmap)
{
GtkWidget *container = NULL;
GtkWidget *label = NULL;
GtkWidget *button = NULL;
GtkWidget *sw = NULL;
const char* label_text;
const char* chooser_title;

if(!vmap)
goto cleanup;

container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
if(!container)
goto cleanup;

switch(vmap->type) {
case RDS_FIELD_PS:
label_text = "Dynamic PSN from file";
chooser_title = "Dynamic PSN data file";
break;
case RDS_FIELD_RT:
label_text = "Dynamic RT from file";
chooser_title = "Dynamic RT data file";
break;
}

label = gtk_label_new(label_text);
if(!label)
goto cleanup;
gtk_box_pack_start(GTK_BOX(container), label, 0, 0, 6);

button = gtk_file_chooser_button_new(chooser_title,
GTK_FILE_CHOOSER_ACTION_OPEN);
if(!button)
goto cleanup;
gtk_box_pack_start(GTK_BOX(container), button, 0, 0, 6);

sw = gtk_switch_new();
if(!sw)
goto cleanup;
gtk_box_pack_end(GTK_BOX(container), sw, 0, 0, 8);

vmap->sw = sw;

g_signal_connect(sw, "state-set", G_CALLBACK(jmrg_file_chooser_swtoggle),
vmap);

g_signal_connect(button, "file-set",
G_CALLBACK(jmrg_file_chooser_done),
vmap);
return container;
cleanup:
if(button)
gtk_widget_destroy(button);
if(label)
gtk_widget_destroy(label);
if(container)
gtk_widget_destroy(container);
return NULL;
}
4 changes: 2 additions & 2 deletions rds_config.c
Expand Up @@ -195,8 +195,8 @@ rds_set_ps(struct rds_encoder_state *st, const char *ps)
return -1;

pslen = strnlen(ps, RDS_PS_LENGTH);
if (pslen > RDS_PS_LENGTH)
return -1;
if (!pslen || pslen > RDS_PS_LENGTH)
return -2;

memset(st->ps, 0, RDS_PS_LENGTH);

Expand Down

0 comments on commit 63d07ec

Please sign in to comment.