From 2c780d67b8a22d75a2da4b2af21fd35f0c6f5236 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 17 May 2009 22:29:06 -0700 Subject: [PATCH 1/1] Handle disappearing serial devices Put up a dialog when the serial open fails, and shut down monitoring when the serial device disappears while running. Signed-off-by: Keith Packard --- aoview/aoview.glade | 31 ++++++++++++++++++++++++- aoview/aoview.h | 6 +++-- aoview/aoview_dev_dialog.c | 23 ++++++++++++++++++- aoview/aoview_log.c | 3 ++- aoview/aoview_monitor.c | 47 ++++++++++++++++++++++---------------- aoview/aoview_serial.c | 9 ++++---- 6 files changed, 90 insertions(+), 29 deletions(-) diff --git a/aoview/aoview.glade b/aoview/aoview.glade index bf74da7b..92580472 100644 --- a/aoview/aoview.glade +++ b/aoview/aoview.glade @@ -372,9 +372,10 @@ 5 - popup + Failed to create log normal True + aoview error close Cannot create log file @@ -397,4 +398,32 @@ + + 5 + Failed to open device + normal + True + aoview + error + close + Cannot open device + + + True + vertical + 2 + + + True + end + + + False + end + 0 + + + + + diff --git a/aoview/aoview.h b/aoview/aoview.h index f584045f..78244912 100644 --- a/aoview/aoview.h +++ b/aoview/aoview.h @@ -73,7 +73,7 @@ struct aostate { void aoview_monitor_disconnect(void); -void +gboolean aoview_monitor_connect(char *tty); struct aoview_serial * @@ -82,9 +82,11 @@ aoview_serial_open(const char *tty); void aoview_serial_close(struct aoview_serial *serial); +typedef void (*aoview_serial_callback)(gpointer user_data, struct aoview_serial *serial, gint revents); + void aoview_serial_set_callback(struct aoview_serial *serial, - GSourceFunc func, + aoview_serial_callback func, gpointer data, GDestroyNotify notify); diff --git a/aoview/aoview_dev_dialog.c b/aoview/aoview_dev_dialog.c index 00947404..530187c1 100644 --- a/aoview/aoview_dev_dialog.c +++ b/aoview/aoview_dev_dialog.c @@ -45,6 +45,23 @@ aoview_dev_dialog_map(GtkWidget *widget, gpointer data) gtk_tree_view_columns_autosize(dev_list); } +static GtkMessageDialog *dev_open_fail_dialog; + +static void +aoview_dev_open_failed(char *name) +{ + char *utf8_file; + utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL); + if (!utf8_file) + utf8_file = name; + gtk_message_dialog_format_secondary_text(dev_open_fail_dialog, + "\"%s\"", utf8_file); + if (utf8_file != name) + g_free(utf8_file); + gtk_dialog_run(GTK_DIALOG(dev_open_fail_dialog)); + gtk_widget_hide(GTK_WIDGET(dev_open_fail_dialog)); +} + static void aoview_dev_selected(GtkTreeModel *model, GtkTreePath *path, @@ -55,7 +72,8 @@ aoview_dev_selected(GtkTreeModel *model, gtk_tree_model_get(model, iter, 2, &string, -1); - aoview_monitor_connect(string); + if (!aoview_monitor_connect(string)) + aoview_dev_open_failed(string); } static GtkWidget *dialog; @@ -123,4 +141,7 @@ aoview_dev_dialog_init(GladeXML *xml) g_signal_connect(G_OBJECT(ao_disconnect), "activate", G_CALLBACK(aoview_dev_disconnect), ao_disconnect); + + dev_open_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "dev_open_fail_dialog")); + assert(dev_open_fail_dialog); } diff --git a/aoview/aoview_log.c b/aoview/aoview_log.c index a9300f61..0afdb64e 100644 --- a/aoview/aoview_log.c +++ b/aoview/aoview_log.c @@ -92,7 +92,8 @@ aoview_log_open_failed(char *name) "\"%s\"", utf8_file); if (utf8_file != name) g_free(utf8_file); - gtk_widget_show(GTK_WIDGET(log_fail_dialog)); + gtk_dialog_run(GTK_DIALOG(log_fail_dialog)); + gtk_widget_hide(GTK_WIDGET(log_fail_dialog)); aoview_log_failed = 1; } diff --git a/aoview/aoview_monitor.c b/aoview/aoview_monitor.c index 5c2daaa5..3b3245e2 100644 --- a/aoview/aoview_monitor.c +++ b/aoview/aoview_monitor.c @@ -116,38 +116,45 @@ aoview_monitor_parse(char *line) aoview_state_notify(&state); } -static gboolean -aoview_monitor_callback(void *user_data) +static void +aoview_monitor_callback(gpointer user_data, + struct aoview_serial *serial, + gint revents) { int c; - if (!monitor_serial) - return FALSE; - - for (;;) { - c = aoview_serial_getc(monitor_serial); - if (c == -1) - break; - if (c == '\r') - continue; - if (c == '\n') { - monitor_line[monitor_pos] = '\0'; - if (monitor_pos) - aoview_monitor_parse(monitor_line); - monitor_pos = 0; - } else if (monitor_pos < MONITOR_LEN) - monitor_line[monitor_pos++] = c; + if (revents & (G_IO_HUP|G_IO_ERR)) { + aoview_monitor_disconnect(); + return; + } + if (revents & G_IO_IN) { + for (;;) { + c = aoview_serial_getc(serial); + if (c == -1) + break; + if (c == '\r') + continue; + if (c == '\n') { + monitor_line[monitor_pos] = '\0'; + if (monitor_pos) + aoview_monitor_parse(monitor_line); + monitor_pos = 0; + } else if (monitor_pos < MONITOR_LEN) + monitor_line[monitor_pos++] = c; + } } - return TRUE; } -void +gboolean aoview_monitor_connect(char *tty) { aoview_monitor_disconnect(); monitor_serial = aoview_serial_open(tty); + if (!monitor_serial) + return FALSE; aoview_serial_set_callback(monitor_serial, aoview_monitor_callback, monitor_serial, NULL); + return TRUE; } diff --git a/aoview/aoview_serial.c b/aoview/aoview_serial.c index 5cb286f8..1721a286 100644 --- a/aoview/aoview_serial.c +++ b/aoview/aoview_serial.c @@ -191,6 +191,7 @@ serial_dispatch(GSource *source, gpointer user_data) { struct aoview_serial *serial = (struct aoview_serial *) source; + aoview_serial_callback func = (aoview_serial_callback) callback; gint revents = serial->poll_fd.revents; if (revents & G_IO_IN) @@ -199,8 +200,8 @@ serial_dispatch(GSource *source, if (revents & G_IO_OUT) aoview_buf_flush(&serial->out_buf, serial->fd); - if (callback && (revents & G_IO_IN)) - (*callback)(user_data); + if (func) + (*func)(user_data, serial, revents); return TRUE; } @@ -262,9 +263,9 @@ aoview_serial_close(struct aoview_serial *serial) void aoview_serial_set_callback(struct aoview_serial *serial, - GSourceFunc func, + aoview_serial_callback func, gpointer data, GDestroyNotify notify) { - g_source_set_callback(&serial->source, func, data, notify); + g_source_set_callback(&serial->source, (GSourceFunc) func, data, notify); } -- 2.30.2