static char *license = \
" Copyright (C) 2003 John Kasunich\n\
<jmkasunich AT users DOT sourceforge DOT net>\n\
\n\
This program is free software; you can redistribute it and/or\n\
modify it under the terms of version 2 of the GNU General\n\
Public License as published by the Free Software Foundation.\n\
This library is distributed in the hope that it will be useful,\n\
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
GNU General Public License for more details.\n\
\n\
You should have received a copy of the GNU General Public\n\
License along with this library; if not, write to the Free Software\n\
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\
\n\
THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR\n\
ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE\n\
TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of\n\
harming persons must have provisions for completely removing power\n\
from all motors, etc, before persons enter any danger area. All\n\
machinery must be designed to comply with local and national safety\n\
codes, and the authors of this software can not, and do not, take\n\
any responsibility for such compliance.\n\
\n\
\n\
This code was written as part of the EMC HAL project. For more\n\
information, go to www.linuxcnc.org.\n\
";
#include "config.h"
#include <locale.h>
#include <libintl.h>
#define _(x) gettext(x)
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "rtapi.h"
#include "hal.h"
#include "../hal_priv.h"
#include <gtk/gtk.h>
#include "miscgtk.h"
#include "scope_usr.h"
scope_usr_control_t *ctrl_usr;
scope_shm_control_t *ctrl_shm;
static int comp_id;
static int shm_id;
static scope_usr_control_t ctrl_struct;
static void init_usr_control_struct(void *shmem);
static void define_scope_windows(void);
static void init_run_mode_window(void);
static void exit_from_hal(void);
static void main_window_closed(GtkWidget * widget, gpointer * gdata);
static void set_focus(GtkWindow * window, GtkWidget *widget, gpointer * gdata);
static void quit(int sig);
static int heartbeat(gpointer data);
static void rm_normal_button_clicked(GtkWidget * widget, gpointer * gdata);
static void rm_single_button_clicked(GtkWidget * widget, gpointer * gdata);
static void rm_roll_button_clicked(GtkWidget * widget, gpointer * gdata);
static void rm_stop_button_clicked(GtkWidget * widget, gpointer * gdata);
static void *shm_base;
int main(int argc, gchar * argv[])
{
int retval;
int num_samples = SCOPE_NUM_SAMPLES_DEFAULT;
char *ifilename = "autosave.halscope";
char *ofilename = "autosave.halscope";
bindtextdomain("linuxcnc", EMC2_PO_DIR);
setlocale(LC_MESSAGES,"");
setlocale(LC_CTYPE,"");
textdomain("linuxcnc");
gtk_init(&argc, &argv);
while(1) {
int c;
c = getopt(argc, argv, "hi:o:");
if(c == -1) break;
switch(c) {
case 'h':
rtapi_print_msg(RTAPI_MSG_ERR,
_("Usage:\n halscope [-h] [-i infile] [-o outfile]"
" [num_samples]\n"));
return -1;
break;
case 'i':
ifilename = optarg;
break;
case 'o':
ofilename = optarg;
break;
}
}
if(argc > optind) num_samples = atoi(argv[argc-1]);
if(num_samples <= 0)
num_samples = SCOPE_NUM_SAMPLES_DEFAULT;
comp_id = hal_init("halscope");
if (comp_id < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "SCOPE: ERROR: hal_init() failed\n");
return -1;
}
if (!halpr_find_funct_by_name("scope.sample")) {
char buf[1000];
sprintf(buf, EMC2_BIN_DIR "/halcmd loadrt scope_rt num_samples=%d",
num_samples);
if(system(buf) != 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "loadrt scope_rt failed\n");
hal_exit(comp_id);
exit(1);
}
}
shm_id = rtapi_shmem_new(SCOPE_SHM_KEY, comp_id, sizeof(scope_shm_control_t));
if (shm_id < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"SCOPE: ERROR: failed to get shared memory (key=0x%x, size=%lu)\n",
SCOPE_SHM_KEY,
(unsigned long)sizeof(scope_shm_control_t)
);
hal_exit(comp_id);
return -1;
}
retval = rtapi_shmem_getptr(shm_id, &shm_base);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"SCOPE: ERROR: failed to map shared memory\n");
rtapi_shmem_delete(shm_id, comp_id);
hal_exit(comp_id);
return -1;
}
hal_ready(comp_id);
atexit(exit_from_hal);
ctrl_usr = &ctrl_struct;
init_usr_control_struct(shm_base);
ctrl_shm->watchdog = 10;
define_scope_windows();
gtk_signal_connect(GTK_OBJECT(ctrl_usr->main_win), "destroy",
GTK_SIGNAL_FUNC(main_window_closed), NULL);
gtk_signal_connect(GTK_OBJECT(ctrl_usr->main_win), "focus-in-event",
GTK_SIGNAL_FUNC(set_focus), NULL);
init_horiz();
init_vert();
init_trig();
init_display();
init_run_mode_window();
signal(SIGINT, quit);
signal(SIGTERM, quit);
gtk_widget_show(ctrl_usr->main_win);
read_config_file(ifilename);
gtk_timeout_add(100, heartbeat, NULL);
gtk_main();
write_config_file(ofilename);
return (0);
}
static int heartbeat(gpointer data)
{
refresh_state_info();
if (ctrl_shm->watchdog < 10) {
ctrl_shm->watchdog++;
} else {
handle_watchdog_timeout();
}
if (ctrl_usr->pending_restart && ctrl_shm->state == IDLE) {
ctrl_usr->pending_restart = 0;
ctrl_usr->run_mode = ctrl_usr->old_run_mode;
if(ctrl_usr->run_mode != STOP) {
start_capture();
}
}
if (ctrl_usr->display_refresh_timer > 0) {
if (--ctrl_usr->display_refresh_timer == 0) {
refresh_display();
}
}
if (ctrl_shm->state == DONE) {
if(!gtk_window_is_active(GTK_WINDOW(ctrl_usr->main_win)))
gtk_window_set_urgency_hint(GTK_WINDOW(ctrl_usr->main_win), TRUE);
capture_complete();
} else if (ctrl_usr->run_mode == ROLL) capture_cont();
return 1;
}
void start_capture(void)
{
int n;
scope_chan_t *chan;
hal_pin_t *pin;
hal_sig_t *sig;
hal_param_t *param;
if (ctrl_shm->state != IDLE) {
return;
}
for (n = 0; n < 16; n++) {
chan = &(ctrl_usr->chan[n]);
if ( chan->data_source_type == 0 ) {
pin = SHMPTR(chan->data_source);
if ( pin->name[0] == '\0' ) {
chan->data_source_type = -1;
chan->data_len = 0;
break;
}
if (pin->signal == 0) {
ctrl_shm->data_offset[n] = SHMOFF(&(pin->dummysig));
} else {
sig = SHMPTR(pin->signal);
ctrl_shm->data_offset[n] = sig->data_ptr;
}
} else if ( chan->data_source_type == 1 ) {
sig = SHMPTR(chan->data_source);
if ( sig->name[0] == '\0' ) {
chan->data_source_type = -1;
chan->data_len = 0;
break;
}
ctrl_shm->data_offset[n] = sig->data_ptr;
} else if ( chan->data_source_type == 2 ) {
param = SHMPTR(chan->data_source);
if ( param->name[0] == '\0' ) {
chan->data_source_type = -1;
chan->data_len = 0;
break;
}
ctrl_shm->data_offset[n] = param->data_ptr;
} else {
chan->data_len = 0;
}
ctrl_shm->data_type[n] = chan->data_type;
if (ctrl_usr->vert.chan_enabled[n]) {
ctrl_shm->data_len[n] = chan->data_len;
} else {
ctrl_shm->data_len[n] = 0;
}
}
ctrl_shm->pre_trig = (ctrl_shm->rec_len-2) * ctrl_usr->trig.position;
ctrl_shm->state = INIT;
}
void capture_copy_data(void) {
int n, offs;
scope_data_t *src, *dst, *src_end;
int samp_len, samp_size;
offs = 0;
for (n = 0; n < 16; n++) {
if (ctrl_shm->data_len[n] > 0) {
ctrl_usr->vert.data_offset[n] = offs;
offs++;
} else {
ctrl_usr->vert.data_offset[n] = -1;
}
}
ctrl_usr->samples = ctrl_shm->samples;
samp_len = ctrl_shm->sample_len;
samp_size = samp_len * sizeof(scope_data_t);
dst = ctrl_usr->disp_buf;
memset(dst, 0, sizeof(scope_data_t) * ctrl_shm->buf_len);
src = ctrl_usr->buffer + ctrl_shm->start;
src_end = ctrl_usr->buffer + (ctrl_shm->rec_len * samp_len);
n = 0;
while (n < ctrl_usr->samples) {
memcpy(dst, src, samp_size);
n++;
dst += samp_len;
src += samp_len;
if (src >= src_end) {
src = ctrl_usr->buffer;
}
}
}
void capture_cont()
{
capture_copy_data();
refresh_display();
}
void capture_complete(void)
{
capture_copy_data();
ctrl_shm->state = IDLE;
switch (ctrl_usr->run_mode) {
case STOP:
break;
case NORMAL:
case ROLL:
start_capture();
break;
case SINGLE:
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctrl_usr->
rm_stop_button), TRUE);
break;
default:
break;
}
refresh_display();
}
static void init_usr_control_struct(void *shmem)
{
char *cp;
int n, skip;
cp = (char *) ctrl_usr;
for (n = 0; n < sizeof(scope_usr_control_t); n++) {
cp[n] = 0;
}
ctrl_shm = shmem;
skip = (sizeof(scope_shm_control_t) + 3) & ~3;
ctrl_usr->buffer = (scope_data_t *) (((char *) (shmem)) + skip);
if (ctrl_shm->shm_size == 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "Realtime component not loaded? ctrl_shm->size == 0");
hal_exit(comp_id);
exit(1);
}
for (n = 0; n < 16; n++) {
ctrl_usr->chan[n].data_source_type = -1;
}
}
static void menuitem_response(gchar *string) {
printf("%s\n", string);
}
static void about(int junk) {
gtk_show_about_dialog(GTK_WINDOW(ctrl_usr->main_win),
"copyright", "Copyright (C) 2003 John Kasunich",
"license", license,
"website", "http://www.linuxcnc.org/",
NULL);
}
static char *halscope_suffix(GtkFileSelection *fs) {
static char buf[256];
int len;
char *suffix;
strncpy(buf, gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)),
sizeof(buf)-10);
len = strlen(buf);
suffix = strstr(buf, ".halscope");
if(!suffix || suffix != buf + len - 9) strcat(buf, ".halscope");
return buf;
}
static void do_open_configuration(GtkWidget *w, GtkFileSelection *fs) {
int n;
for (n = 0; n < 16; n++) {
ctrl_usr->chan[n].data_source_type = -1;
ctrl_usr->chan[n].data_len = 0;
ctrl_usr->vert.data_offset[n] = -1;
}
read_config_file(halscope_suffix(fs));
channel_changed();
refresh_display();
}
static void open_configuration(int junk) {
GtkWidget *filew;
filew = gtk_file_selection_new(_("Open Configuration File:"));
gtk_signal_connect (GTK_OBJECT (filew), "destroy",
(GtkSignalFunc) gtk_widget_destroy, &filew);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
"clicked", (GtkSignalFunc) do_open_configuration, filew );
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
(filew)->ok_button),
"clicked", (GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (filew));
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
(filew)->cancel_button),
"clicked", (GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (filew));
gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(filew), FALSE);
gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION(filew) );
gtk_file_selection_complete(GTK_FILE_SELECTION(filew), "*.halscope");
gtk_dialog_run(GTK_DIALOG(filew));
}
static void do_save_configuration(GtkWidget *w, GtkFileSelection *fs) {
write_config_file(halscope_suffix(fs));
}
static void save_configuration(int junk) {
GtkWidget *filew;
filew = gtk_file_selection_new(_("Open Configuration File:"));
gtk_signal_connect (GTK_OBJECT (filew), "destroy",
(GtkSignalFunc) gtk_widget_destroy, &filew);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
"clicked", (GtkSignalFunc) do_save_configuration, filew );
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
(filew)->ok_button),
"clicked", (GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (filew));
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
(filew)->cancel_button),
"clicked", (GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (filew));
gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(filew), FALSE);
gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION(filew) );
gtk_dialog_run(GTK_DIALOG(filew));
}
static void define_menubar(GtkWidget *vboxtop) {
GtkWidget *file_rootmenu, *help_rootmenu;
GtkWidget *menubar, *filemenu,
*fileopenconfiguration, *filesaveconfiguration,
*fileopendatafile, *filesavedatafile,
*filequit, *sep1, *sep2;
GtkWidget *helpmenu, *helpabout;
GtkWidget *vbox;
filemenu = gtk_menu_new();
helpmenu = gtk_menu_new();
sep1 = gtk_separator_menu_item_new();
sep2 = gtk_separator_menu_item_new();
fileopenconfiguration = gtk_menu_item_new_with_mnemonic(_("_Open Configuration..."));
gtk_menu_append(GTK_MENU(filemenu), fileopenconfiguration);
gtk_signal_connect_object(GTK_OBJECT(fileopenconfiguration), "activate",
GTK_SIGNAL_FUNC(open_configuration), 0);
gtk_widget_show(fileopenconfiguration);
filesaveconfiguration = gtk_menu_item_new_with_mnemonic(_("_Save Configuration..."));
gtk_menu_append(GTK_MENU(filemenu), filesaveconfiguration);
gtk_signal_connect_object(GTK_OBJECT(filesaveconfiguration), "activate",
GTK_SIGNAL_FUNC(save_configuration), 0);
gtk_widget_show(filesaveconfiguration);
gtk_menu_append(GTK_MENU(filemenu), sep1);
gtk_widget_show(sep1);
fileopendatafile = gtk_menu_item_new_with_mnemonic(_("O_pen Data File..."));
gtk_menu_append(GTK_MENU(filemenu), fileopendatafile);
gtk_signal_connect_object(GTK_OBJECT(fileopendatafile), "activate",
GTK_SIGNAL_FUNC(menuitem_response), "file/open datafile");
gtk_widget_set_sensitive(GTK_WIDGET(fileopendatafile), FALSE); gtk_widget_show(fileopendatafile);
filesavedatafile = gtk_menu_item_new_with_mnemonic(_("S_ave Data File..."));
gtk_menu_append(GTK_MENU(filemenu), filesavedatafile);
gtk_signal_connect_object(GTK_OBJECT(filesavedatafile), "activate",
GTK_SIGNAL_FUNC(log_popup), 0);
gtk_widget_show(filesavedatafile);
gtk_menu_append(GTK_MENU(filemenu), sep2);
gtk_widget_show(sep2);
filequit = gtk_menu_item_new_with_mnemonic(_("_Quit"));
gtk_menu_append(GTK_MENU(filemenu), filequit);
gtk_signal_connect_object(GTK_OBJECT(filequit), "activate",
GTK_SIGNAL_FUNC(quit), 0);
gtk_widget_show(filequit);
helpabout = gtk_menu_item_new_with_mnemonic(_("_About Halscope"));
gtk_menu_append(GTK_MENU(helpmenu), helpabout);
gtk_signal_connect_object(GTK_OBJECT(helpabout), "activate",
GTK_SIGNAL_FUNC(about), 0);
gtk_widget_show(helpabout);
file_rootmenu = gtk_menu_item_new_with_mnemonic(_("_File"));
gtk_widget_show(file_rootmenu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_rootmenu),filemenu);
help_rootmenu = gtk_menu_item_new_with_mnemonic(_("_Help"));
gtk_widget_show(help_rootmenu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_rootmenu),helpmenu);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(vboxtop), vbox);
gtk_widget_show(vbox);
menubar = gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 2);
gtk_widget_show(menubar);
gtk_menu_bar_append(GTK_MENU_BAR(menubar), file_rootmenu);
gtk_menu_bar_append(GTK_MENU_BAR(menubar), help_rootmenu);
}
static void define_scope_windows(void)
{
GtkWidget *vbox, *hbox, *vboxtop, *vboxbottom, *vboxleft, *vboxright, *hboxright;
ctrl_usr->main_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize(GTK_WIDGET(ctrl_usr->main_win), 500, 350);
gtk_window_set_policy(GTK_WINDOW(ctrl_usr->main_win), FALSE, TRUE, FALSE);
gtk_window_set_title(GTK_WINDOW(ctrl_usr->main_win), _("HAL Oscilloscope"));
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
gtk_container_add(GTK_CONTAINER(ctrl_usr->main_win), vbox);
gtk_widget_show(vbox);
vboxtop = gtk_hbox_new_in_box(FALSE, 0, 0, vbox, FALSE, FALSE, 0);
vboxbottom = gtk_hbox_new_in_box(FALSE, 0, 0, vbox, TRUE, TRUE, 0);
hbox = gtk_hbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
gtk_container_add(GTK_CONTAINER(vboxbottom), hbox);
gtk_widget_show(hbox);
define_menubar(vboxtop);
vboxleft = gtk_vbox_new_in_box(FALSE, 0, 0, hbox, TRUE, TRUE, 0);
hboxright = gtk_hbox_new_in_box(TRUE, 0, 0, hbox, FALSE, FALSE, 0);
ctrl_usr->horiz_info_win =
gtk_vbox_framed_new_in_box(_("Horizontal"), FALSE, 0, 0, vboxleft, FALSE,
FALSE, 1);
ctrl_usr->waveform_win =
gtk_vbox_new_in_box(FALSE, 0, 0, vboxleft, TRUE, TRUE, 0);
ctrl_usr->chan_sel_win =
gtk_hbox_new_in_box(TRUE, 0, 0, vboxleft, FALSE, FALSE, 0);
ctrl_usr->chan_info_win =
gtk_hbox_framed_new_in_box(_("Selected Channel"), FALSE, 0, 0, vboxleft,
FALSE, FALSE, 0);
vboxleft = gtk_vbox_new_in_box(FALSE, 0, 0, hboxright, FALSE, FALSE, 0);
vboxright = gtk_vbox_new_in_box(FALSE, 0, 0, hboxright, FALSE, FALSE, 0);
ctrl_usr->run_mode_win =
gtk_vbox_framed_new_in_box(_("Run Mode"), TRUE, 0, 0, vboxleft, FALSE,
FALSE, 0);
ctrl_usr->trig_info_win =
gtk_vbox_framed_new_in_box(_("Trigger"), FALSE, 0, 0, vboxright, TRUE,
TRUE, 0);
ctrl_usr->trig_mode_win =
gtk_vbox_new_in_box(TRUE, 0, 0, ctrl_usr->trig_info_win, FALSE,
FALSE, 0);
ctrl_usr->vert_info_win =
gtk_vbox_framed_new_in_box(_("Vertical"), FALSE, 0, 0, vboxleft, TRUE,
TRUE, 0);
}
static void init_run_mode_window(void)
{
ctrl_usr->rm_stop_button = gtk_radio_button_new_with_label(NULL, _("Stop"));
ctrl_usr->rm_normal_button =
gtk_radio_button_new_with_label(gtk_radio_button_group
(GTK_RADIO_BUTTON(ctrl_usr->rm_stop_button)), _("Normal"));
ctrl_usr->rm_single_button =
gtk_radio_button_new_with_label(gtk_radio_button_group
(GTK_RADIO_BUTTON(ctrl_usr->rm_stop_button)), _("Single"));
ctrl_usr->rm_roll_button =
gtk_radio_button_new_with_label(gtk_radio_button_group
(GTK_RADIO_BUTTON(ctrl_usr->rm_stop_button)), _("Roll"));
gtk_box_pack_start(GTK_BOX(ctrl_usr->run_mode_win),
ctrl_usr->rm_normal_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(ctrl_usr->run_mode_win),
ctrl_usr->rm_single_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(ctrl_usr->run_mode_win),
ctrl_usr->rm_roll_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(ctrl_usr->run_mode_win),
ctrl_usr->rm_stop_button, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(ctrl_usr->rm_normal_button), "clicked",
GTK_SIGNAL_FUNC(rm_normal_button_clicked), NULL);
gtk_signal_connect(GTK_OBJECT(ctrl_usr->rm_single_button), "clicked",
GTK_SIGNAL_FUNC(rm_single_button_clicked), NULL);
gtk_signal_connect(GTK_OBJECT(ctrl_usr->rm_roll_button), "clicked",
GTK_SIGNAL_FUNC(rm_roll_button_clicked), NULL);
gtk_signal_connect(GTK_OBJECT(ctrl_usr->rm_stop_button), "clicked",
GTK_SIGNAL_FUNC(rm_stop_button_clicked), NULL);
gtk_widget_show(ctrl_usr->rm_normal_button);
gtk_widget_show(ctrl_usr->rm_single_button);
gtk_widget_show(ctrl_usr->rm_roll_button);
gtk_widget_show(ctrl_usr->rm_stop_button);
}
static void exit_from_hal(void)
{
rtapi_shmem_delete(shm_id, comp_id);
hal_exit(comp_id);
}
static void main_window_closed(GtkWidget * widget, gpointer * gdata)
{
quit(0);
}
static void set_focus(GtkWindow *window, GtkWidget *widget, gpointer *data) {
gtk_window_set_urgency_hint(window, FALSE);
}
static void quit(int sig)
{
gtk_main_quit();
}
int set_run_mode(int mode)
{
GtkWidget *button;
if ( mode == 0 ) {
button = ctrl_usr->rm_stop_button;
} else if ( mode == 1 ) {
button = ctrl_usr->rm_normal_button;
} else if ( mode == 2 ) {
button = ctrl_usr->rm_single_button;
#if 0#endif
} else {
return -1;
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), 1);
return 0;
}
static void rm_normal_button_clicked(GtkWidget * widget, gpointer * gdata)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) != TRUE) {
return;
}
ctrl_usr->run_mode = NORMAL;
if (ctrl_shm->state == IDLE) {
start_capture();
}
}
static void rm_single_button_clicked(GtkWidget * widget, gpointer * gdata)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) != TRUE) {
return;
}
ctrl_usr->run_mode = SINGLE;
if (ctrl_shm->state == IDLE) {
start_capture();
}
}
static void rm_roll_button_clicked(GtkWidget * widget, gpointer * gdata)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) != TRUE) {
return;
}
ctrl_usr->run_mode = ROLL;
if (ctrl_shm->state == IDLE) {
start_capture();
}
}
static void rm_stop_button_clicked(GtkWidget * widget, gpointer * gdata)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) != TRUE) {
return;
}
if (ctrl_shm->state != IDLE) {
ctrl_shm->state = RESET;
}
ctrl_usr->run_mode = STOP;
}
void prepare_scope_restart(void) {
if(ctrl_usr->pending_restart) return;
ctrl_shm->state = RESET;
ctrl_usr->old_run_mode = ctrl_usr->run_mode;
ctrl_usr->pending_restart = 1;
ctrl_usr->run_mode = STOP;
}