diff options
-rw-r--r-- | display-gtk.h | 4 | ||||
-rw-r--r-- | gtk-gui.c | 48 | ||||
-rw-r--r-- | linux.c | 59 | ||||
-rw-r--r-- | macos.c | 52 | ||||
-rw-r--r-- | windows.c | 66 |
5 files changed, 202 insertions, 27 deletions
diff --git a/display-gtk.h b/display-gtk.h index 7b2ce5f2e..f4961b301 100644 --- a/display-gtk.h +++ b/display-gtk.h @@ -45,12 +45,14 @@ extern const void *subsurface_get_conf(char *name, pref_type_t type); extern void subsurface_flush_conf(void); extern void subsurface_close_conf(void); -extern const char *subsurface_USB_name(void); +extern int subsurface_fill_device_list(GtkListStore *store); extern const char *subsurface_icon_name(void); extern void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar, GtkWidget *vbox, GtkUIManager *ui_manager); extern void quit(GtkWidget *w, gpointer data); +extern int is_default_dive_computer_device(const char *name); + extern visible_cols_t visible_cols; extern const char *divelist_font; @@ -49,7 +49,7 @@ static int is_default_dive_computer(const char *vendor, const char *product) default_dive_computer_product && !strcmp(product, default_dive_computer_product); } -static int is_default_dive_computer_device(const char *name) +int is_default_dive_computer_device(const char *name) { return default_dive_computer_device && !strcmp(name, default_dive_computer_device); } @@ -1360,29 +1360,31 @@ static GtkComboBox *dive_computer_selector(GtkWidget *vbox) return GTK_COMBO_BOX(combo_box); } -const char *subsurface_device_name() +static GtkComboBox *dc_device_selector(GtkWidget *vbox) { - if (!default_dive_computer_device || !*default_dive_computer_device) - return subsurface_USB_name(); - else - return default_dive_computer_device; -} - -static GtkEntry *dive_computer_device(GtkWidget *vbox) -{ - GtkWidget *hbox, *entry, *frame; + GtkWidget *hbox, *combo_box, *frame; + GtkListStore *model; + GtkCellRenderer *renderer; + int default_index; hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); - frame = gtk_frame_new(_("Device name")); + model = gtk_list_store_new(1, G_TYPE_STRING); + default_index = subsurface_fill_device_list(model); + + frame = gtk_frame_new(_("Device or mount point")); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3); - entry = gtk_entry_new(); - gtk_container_add(GTK_CONTAINER(frame), entry); - gtk_entry_set_text(GTK_ENTRY(entry), subsurface_device_name()); + combo_box = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(model), 0); + gtk_container_add(GTK_CONTAINER(frame), combo_box); - return GTK_ENTRY(entry); + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, TRUE); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), default_index); + + return GTK_COMBO_BOX(combo_box); } static void do_import_file(gpointer data, gpointer user_data) @@ -1498,9 +1500,8 @@ void download_dialog(GtkWidget *w, gpointer data) { int result; GtkWidget *dialog, *button, *hbox, *vbox, *label, *info = NULL; - GtkComboBox *computer; + GtkComboBox *computer, *device; GtkTreeIter iter; - GtkEntry *device; device_data_t devicedata = { .devname = NULL, }; @@ -1516,7 +1517,7 @@ void download_dialog(GtkWidget *w, gpointer data) label = gtk_label_new(_(" Please select dive computer and device. ")); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 3); computer = dive_computer_selector(vbox); - device = dive_computer_device(vbox); + device = dc_device_selector(vbox); hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 3); devicedata.progress.bar = gtk_progress_bar_new(); @@ -1552,7 +1553,14 @@ repeat: devicedata.descriptor = descriptor; devicedata.vendor = vendor; devicedata.product = product; - devicedata.devname = gtk_entry_get_text(device); + + if (!gtk_combo_box_get_active_iter(device, &iter)) + break; + + model = gtk_combo_box_get_model(device); + gtk_tree_model_get(model, &iter, + 0, &devicedata.devname, + -1); set_default_dive_computer(vendor, product); set_default_dive_computer_device(devicedata.devname); info = import_dive_computer(&devicedata, GTK_DIALOG(dialog)); @@ -56,9 +56,64 @@ void subsurface_close_conf(void) /* this is a no-op */ } -const char *subsurface_USB_name() +int subsurface_fill_device_list(GtkListStore *store) { - return "/dev/ttyUSB0"; + int i = 0; + int index = -1; + GtkTreeIter iter; + GDir *dev; + const char *name; + char *buffer; + gsize length; + + dev = g_dir_open("/dev", 0, NULL); + while (dev && (name = g_dir_read_name(dev)) != NULL) { + if (strstr(name, "USB")) { + int len = strlen(name) + 6; + char *devicename = malloc(len); + snprintf(devicename, len, "/dev/%s", name); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, devicename, -1); + if (is_default_dive_computer_device(devicename)) + index = i; + i++; + } + } + if (dev) + g_dir_close(dev); + if (g_file_get_contents("/proc/mounts", &buffer, &length, NULL) && + length > 0) { + char *ptr = strstr(buffer, "UEMISSDA"); + if (ptr) { + char *end = ptr, *start = ptr; + while (start > buffer && *start != ' ') + start--; + if (*start == ' ') + start++; + while (*end != ' ' && *end != '\0') + end++; + *end = '\0'; + name = strdup(start); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, name, -1); + if (is_default_dive_computer_device(name)) + index = i; + i++; + free((void *)name); + } + g_free(buffer); + } + if (i == 0) { + /* if we can't find anything, use the default */ + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, "/dev/ttyUSB0", -1); + if (is_default_dive_computer_device("/dev/ttyUSB0")) + index = i; + } + return index; } const char *subsurface_icon_name() @@ -72,9 +72,57 @@ void subsurface_close_conf(void) /* Nothing */ } -const char *subsurface_USB_name() +Int subsurface_fill_device_list(GtkListStore *store) { - return "/dev/tty.SLAB_USBtoUART"; + int i = 0; + int index = -1; + GtkTreeIter iter; + GDir *dev; + const char *name; + char *buffer; + gsize length; + + dev = g_dir_open("/dev", 0, NULL); + while (dev && (name = g_dir_read_name(dev)) != NULL) { + if (strstr(name, "usbserial")) { + int len = strlen(name) + 6; + char *devicename = malloc(len); + snprintf(devicename, len, "/dev/%s", name); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, devicename, -1); + if (is_default_dive_computer_device(devicename)) + index = i; + i++; + } + } + if (dev) + g_dir_close(dev); + dev = g_dir_open("/Volumes", 0, NULL); + while (dev && (name = g_dir_read_name(dev)) != NULL) { + if (strstr(name, "UEMISSDA")) { + int len = strlen(name) + 10; + char *devicename = malloc(len); + snprintf(devicename, len, "/Volumes/%s", name); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, devicename, -1); + if (is_default_dive_computer_device(devicename)) + index = i; + i++; + } + } + if (dev) + g_dir_close(dev); + if (i == 0) { + /* if we can't find anything, use the default */ + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, "/dev/tty.SLAB_USBtoUART", -1); + if (is_default_dive_computer_device("/dev/tty.SLAB_USBtoUART")) + index = i; + } + return index; } const char *subsurface_icon_name() @@ -119,9 +119,71 @@ void subsurface_close_conf(void) RegCloseKey(hkey); } -const char *subsurface_USB_name() +int subsurface_fill_device_list(GtkListStore *store) { - return "COM3"; + const int bufdef = 512; + const char *dlabels[] = {"UEMISSDA", NULL}; + const char *devdef = "COM1"; + GtkTreeIter iter; + int index = -1, nentries = 0, ret, i; + char bufname[bufdef], bufval[bufdef], *p; + DWORD nvalues, bufval_len, bufname_len; + HKEY key; + + /* add serial ports */ + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", + 0, KEY_READ, &key); + if (ret == ERROR_SUCCESS) { + ret = RegQueryInfoKeyA(key, NULL, NULL, NULL, NULL, NULL, NULL, &nvalues, + NULL, NULL, NULL, NULL); + if (ret == ERROR_SUCCESS) + for (i = 0; i < nvalues; i++) { + memset(bufval, 0, bufdef); + memset(bufname, 0, bufdef); + bufname_len = bufdef; + bufval_len = bufdef; + ret = RegEnumValueA(key, i, bufname, &bufname_len, NULL, NULL, bufval, + &bufval_len); + if (ret == ERROR_SUCCESS) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, bufval, -1); + if (is_default_dive_computer_device(bufval)) + index = nentries; + nentries++; + } + } + } + /* add drive letters that match labels */ + memset(bufname, 0, bufdef); + bufname_len = bufdef; + if (GetLogicalDriveStringsA(bufname_len, bufname)) { + p = bufname; + while (*p) { + memset(bufval, 0, bufdef); + if (GetVolumeInformationA(p, bufval, bufdef, NULL, NULL, NULL, NULL, 0)) { + for (i = 0; dlabels[i] != NULL; i++) + if (!strcmp(bufval, dlabels[i])) { + char name[80]; + snprintf(name, sizeof(name), "%s (%s)", p, dlabels[i]); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, name, -1); + if (is_default_dive_computer_device(p)) + index = nentries; + nentries++; + } + } + p = &p[strlen(p) + 1]; + } + } + /* if we can't find anything, use the default */ + if (!nentries) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, devdef, -1); + if (is_default_dive_computer_device(devdef)) + index = 0; + } + return index; } const char *subsurface_icon_name() |