diff --git a/plugins/fmcomms2_adv.c b/plugins/fmcomms2_adv.c index 4bc8134e..fc91ccd8 100644 --- a/plugins/fmcomms2_adv.c +++ b/plugins/fmcomms2_adv.c @@ -85,6 +85,14 @@ struct w_info { const char * const name; }; +/* Container for passing both the progress bar and fraction to + * set_calibration_progress_ui. + * Allocated by caller, freed by callee. */ +struct set_calibration_progress_params { + GtkProgressBar *pbar; + float fraction; +}; + static struct w_info attrs[] = { {SPINBUTTON, "adi,agc-adc-large-overload-exceed-counter"}, {SPINBUTTON, "adi,agc-adc-large-overload-inc-steps"}, @@ -814,17 +822,76 @@ static int get_cal_samples(long long cal_tone, long long cal_freq) return env_samples; } +static bool set_calibration_progress_ui(struct set_calibration_progress_params *params) { + if (gtk_widget_get_visible(GTK_WIDGET(params->pbar))) { + char ptext[64]; + + snprintf(ptext, sizeof(ptext), "Calibration Progress (%.2f %%)", params->fraction * 100); + gtk_progress_bar_set_text(params->pbar, ptext); + gtk_progress_bar_set_fraction(params->pbar, params->fraction); + } + + free(params); + + return false; +} + static void set_calibration_progress(GtkProgressBar *pbar, float fraction) { - if (gtk_widget_get_visible(GTK_WIDGET(pbar))) { - char ptext[64]; + struct set_calibration_progress_params *params = malloc(sizeof(struct set_calibration_progress_params)); + params->pbar = pbar; + params->fraction = fraction; + + gdk_threads_add_idle(G_SOURCE_FUNC(set_calibration_progress_ui), params); +} - gdk_threads_enter(); - snprintf(ptext, sizeof(ptext), "Calibration Progress (%.2f %%)", fraction * 100); - gtk_progress_bar_set_text(pbar, ptext); - gtk_progress_bar_set_fraction(pbar, fraction); - gdk_threads_leave(); +struct calibration_failed_ui_param { + gpointer button; + int ret; +}; + +/* UI actions after a failed calibration + Parameter struct is allocated by caller and freed by callee + Not thread safe by itself - should be queued using gdk_threads_add_idle(), not g_idle_add_full() */ +static gboolean calibration_failed_ui(gpointer p) { + struct calibration_failed_ui_param *param = (struct calibration_failed_ui_param *) p; + + reload_settings(); + + if (param->ret) { + create_blocking_popup(GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, + "FMCOMMS5", "Calibration failed"); + auto_calibrate = -1; + } else { + /* set completed flag for testing */ + auto_calibrate = 1; } + + osc_plot_destroy(plot_xcorr_4ch); + if (param->button) + gtk_widget_show(GTK_WIDGET(param->button)); + + free(p); + + return false; +} + +struct calibration_prepare_plot_param { + int samples; +}; + +/* Prepare xcorr_4ch plot + Parameter struct is allocated by caller and freed by callee + Not thread safe by itself - should be queued using gdk_threads_add_idle(), not g_idle_add_full() */ +static gboolean calibration_prepare_plot(gpointer p) { + struct calibration_prepare_plot_param *param = (struct calibration_prepare_plot_param *) p; + + osc_plot_set_sample_count(plot_xcorr_4ch, param->samples); + osc_plot_draw_start(plot_xcorr_4ch); + + free(p); + + return false; } static void calibrate (gpointer button) @@ -877,10 +944,9 @@ static void calibrate (gpointer button) DBG("cal_tone %lld cal_freq %lld samples %d", cal_tone, cal_freq, samples); - gdk_threads_enter(); - osc_plot_set_sample_count(plot_xcorr_4ch, samples); - osc_plot_draw_start(plot_xcorr_4ch); - gdk_threads_leave(); + struct calibration_prepare_plot_param *p = malloc(sizeof(struct calibration_prepare_plot_param)); + p->samples = samples; + gdk_threads_add_idle(calibration_prepare_plot, (gpointer) p); /* Turn off quadrature tracking while the sync is going on */ iio_channel_attr_write(in0, "quadrature_tracking_en", "0"); @@ -957,22 +1023,10 @@ static void calibrate (gpointer button) iio_channel_attr_write(in0_slave, "quadrature_tracking_en", "1"); } - gdk_threads_enter(); - reload_settings(); - - if (ret) { - create_blocking_popup(GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, - "FMCOMMS5", "Calibration failed"); - auto_calibrate = -1; - } else { - /* set completed flag for testing */ - auto_calibrate = 1; - } - - osc_plot_destroy(plot_xcorr_4ch); - if (button) - gtk_widget_show(GTK_WIDGET(button)); - gdk_threads_leave(); + struct calibration_failed_ui_param *p = malloc(sizeof(struct calibration_failed_ui_param)); + p->button = button; + p->ret = ret; + gdk_threads_add_idle(calibration_failed_ui, (gpointer) p); /* reset progress bar */ gtk_progress_bar_set_fraction(calib_progress, 0.0);