mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Divecomputer download: try to offer only those devices that make sense
If the user selects a Uemis divecomputer, don't show serial devices. If the user selects a serial divecomputer, don't show the Uemis filesystem. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
6d42a99e7f
commit
047032ee46
7 changed files with 178 additions and 111 deletions
|
@ -29,7 +29,7 @@ const char *system_default_filename(void)
|
||||||
return strdup(system_default_filename.toUtf8().data());
|
return strdup(system_default_filename.toUtf8().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
int enumerate_devices (device_callback_t callback, void *userdata)
|
int enumerate_devices (device_callback_t callback, void *userdata, int dc_type)
|
||||||
{
|
{
|
||||||
/* FIXME: we need to enumerate in some other way on android */
|
/* FIXME: we need to enumerate in some other way on android */
|
||||||
/* qtserialport maybee? */
|
/* qtserialport maybee? */
|
||||||
|
|
|
@ -55,7 +55,12 @@ extern int is_default_dive_computer_device(const char *);
|
||||||
extern int is_default_dive_computer(const char *, const char *);
|
extern int is_default_dive_computer(const char *, const char *);
|
||||||
|
|
||||||
typedef void (*device_callback_t)(const char *name, void *userdata);
|
typedef void (*device_callback_t)(const char *name, void *userdata);
|
||||||
int enumerate_devices(device_callback_t callback, void *userdata);
|
|
||||||
|
#define DC_TYPE_SERIAL 1
|
||||||
|
#define DC_TYPE_UEMIS 2
|
||||||
|
#define DC_TYPE_OTHER 3
|
||||||
|
|
||||||
|
int enumerate_devices(device_callback_t callback, void *userdata, int dc_type);
|
||||||
|
|
||||||
extern const char *default_dive_computer_vendor;
|
extern const char *default_dive_computer_vendor;
|
||||||
extern const char *default_dive_computer_product;
|
extern const char *default_dive_computer_product;
|
||||||
|
|
104
linux.c
104
linux.c
|
@ -49,78 +49,80 @@ const char *system_default_filename(void)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int enumerate_devices(device_callback_t callback, void *userdata)
|
int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
DIR *dp = NULL;
|
DIR *dp = NULL;
|
||||||
struct dirent *ep = NULL;
|
struct dirent *ep = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
const char *dirname = "/dev";
|
|
||||||
const char *patterns[] = {
|
|
||||||
"ttyUSB*",
|
|
||||||
"ttyS*",
|
|
||||||
"ttyACM*",
|
|
||||||
"rfcomm*",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
char *fname;
|
char *fname;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
if (dc_type != DC_TYPE_UEMIS) {
|
||||||
|
const char *dirname = "/dev";
|
||||||
|
const char *patterns[] = {
|
||||||
|
"ttyUSB*",
|
||||||
|
"ttyS*",
|
||||||
|
"ttyACM*",
|
||||||
|
"rfcomm*",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
dp = opendir(dirname);
|
dp = opendir(dirname);
|
||||||
if (dp == NULL) {
|
if (dp == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ep = readdir(dp)) != NULL) {
|
while ((ep = readdir(dp)) != NULL) {
|
||||||
for (i = 0; patterns[i] != NULL; ++i) {
|
for (i = 0; patterns[i] != NULL; ++i) {
|
||||||
if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
|
if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
|
||||||
char filename[1024];
|
char filename[1024];
|
||||||
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
|
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
|
||||||
if (n >= sizeof(filename)) {
|
if (n >= sizeof(filename)) {
|
||||||
closedir(dp);
|
closedir(dp);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
callback(filename, userdata);
|
||||||
|
if (is_default_dive_computer_device(filename))
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
callback(filename, userdata);
|
|
||||||
if (is_default_dive_computer_device(filename))
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
closedir(dp);
|
||||||
}
|
}
|
||||||
closedir(dp);
|
if (dc_type != DC_TYPE_SERIAL) {
|
||||||
|
file = fopen("/proc/mounts", "r");
|
||||||
|
if (file == NULL)
|
||||||
|
return index;
|
||||||
|
|
||||||
file = fopen("/proc/mounts", "r");
|
while ((getline(&line, &len, file)) != -1) {
|
||||||
if (file == NULL)
|
char *ptr = strstr(line, "UEMISSDA");
|
||||||
return index;
|
if (ptr) {
|
||||||
|
char *end = ptr, *start = ptr;
|
||||||
|
while (start > line && *start != ' ')
|
||||||
|
start--;
|
||||||
|
if (*start == ' ')
|
||||||
|
start++;
|
||||||
|
while (*end != ' ' && *end != '\0')
|
||||||
|
end++;
|
||||||
|
|
||||||
while ((getline(&line, &len, file)) != -1) {
|
*end = '\0';
|
||||||
char *ptr = strstr(line, "UEMISSDA");
|
fname = strdup(start);
|
||||||
if (ptr) {
|
|
||||||
char *end = ptr, *start = ptr;
|
|
||||||
while (start > line && *start != ' ')
|
|
||||||
start--;
|
|
||||||
if (*start == ' ')
|
|
||||||
start++;
|
|
||||||
while (*end != ' ' && *end != '\0')
|
|
||||||
end++;
|
|
||||||
|
|
||||||
*end = '\0';
|
callback(fname, userdata);
|
||||||
fname = strdup(start);
|
|
||||||
|
|
||||||
callback(fname, userdata);
|
if (is_default_dive_computer_device(fname))
|
||||||
|
index = i;
|
||||||
if (is_default_dive_computer_device(fname))
|
i++;
|
||||||
index = i;
|
free((void *)fname);
|
||||||
i++;
|
}
|
||||||
free((void *)fname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(line);
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
macos.c
55
macos.c
|
@ -45,27 +45,52 @@ const char *system_default_filename(void)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int enumerate_devices(device_callback_t callback, void *userdata)
|
int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
DIR *dp = NULL;
|
DIR *dp = NULL;
|
||||||
struct dirent *ep = NULL;
|
struct dirent *ep = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
const char *dirname = "/dev";
|
if (dc_type != DC_TYPE_UEMIS) {
|
||||||
const char *patterns[] = {
|
const char *dirname = "/dev";
|
||||||
"tty.*",
|
const char *patterns[] = {
|
||||||
"usbserial",
|
"tty.*",
|
||||||
NULL
|
"usbserial",
|
||||||
};
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
dp = opendir(dirname);
|
dp = opendir(dirname);
|
||||||
if (dp == NULL) {
|
if (dp == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ep = readdir(dp)) != NULL) {
|
||||||
|
for (i = 0; patterns[i] != NULL; ++i) {
|
||||||
|
if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
|
||||||
|
char filename[1024];
|
||||||
|
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
|
||||||
|
if (n >= sizeof(filename)) {
|
||||||
|
closedir(dp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
callback(filename, userdata);
|
||||||
|
if (is_default_dive_computer_device(filename))
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dp);
|
||||||
}
|
}
|
||||||
|
if (dc_type != DC_TYPE_SERIAL) {
|
||||||
|
const char *dirname = "/Volumes";
|
||||||
|
dp = opendir(dirname);
|
||||||
|
if (dp == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
while ((ep = readdir(dp)) != NULL) {
|
while ((ep = readdir(dp)) != NULL) {
|
||||||
for (i = 0; patterns[i] != NULL; ++i) {
|
if (fnmatch("UEMISSDA", ep->d_name, 0) == 0) {
|
||||||
if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
|
|
||||||
char filename[1024];
|
char filename[1024];
|
||||||
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
|
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
|
||||||
if (n >= sizeof(filename)) {
|
if (n >= sizeof(filename)) {
|
||||||
|
@ -78,10 +103,8 @@ int enumerate_devices(device_callback_t callback, void *userdata)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
closedir(dp);
|
||||||
}
|
}
|
||||||
// TODO: list UEMIS mount point from /proc/mounts
|
|
||||||
|
|
||||||
closedir(dp);
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) :
|
||||||
|
|
||||||
progress_bar_text = "";
|
progress_bar_text = "";
|
||||||
|
|
||||||
fill_device_list();
|
fill_device_list(DC_TYPE_OTHER);
|
||||||
fill_computer_list();
|
fill_computer_list();
|
||||||
|
|
||||||
ui.chooseDumpFile->setEnabled(ui.dumpToFile->isChecked());
|
ui.chooseDumpFile->setEnabled(ui.dumpToFile->isChecked());
|
||||||
|
@ -104,7 +104,7 @@ void DownloadFromDCWidget::updateState(states state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (state == INITIAL) {
|
if (state == INITIAL) {
|
||||||
fill_device_list();
|
fill_device_list(DC_TYPE_OTHER);
|
||||||
ui.progressBar->hide();
|
ui.progressBar->hide();
|
||||||
markChildrenAsEnabled();
|
markChildrenAsEnabled();
|
||||||
timer->stop();
|
timer->stop();
|
||||||
|
@ -176,6 +176,7 @@ void DownloadFromDCWidget::updateState(states state)
|
||||||
|
|
||||||
void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor)
|
void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor)
|
||||||
{
|
{
|
||||||
|
int dcType = DC_TYPE_SERIAL;
|
||||||
QAbstractItemModel *currentModel = ui.product->model();
|
QAbstractItemModel *currentModel = ui.product->model();
|
||||||
if (!currentModel)
|
if (!currentModel)
|
||||||
return;
|
return;
|
||||||
|
@ -183,6 +184,10 @@ void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor)
|
||||||
productModel = new QStringListModel(productList[vendor]);
|
productModel = new QStringListModel(productList[vendor]);
|
||||||
ui.product->setModel(productModel);
|
ui.product->setModel(productModel);
|
||||||
|
|
||||||
|
if (vendor == QString("Uemis"))
|
||||||
|
dcType = DC_TYPE_UEMIS;
|
||||||
|
fill_device_list(dcType);
|
||||||
|
|
||||||
// Memleak - but deleting gives me a crash.
|
// Memleak - but deleting gives me a crash.
|
||||||
//currentModel->deleteLater();
|
//currentModel->deleteLater();
|
||||||
}
|
}
|
||||||
|
@ -429,11 +434,11 @@ static void fillDeviceList(const char *name, void *data)
|
||||||
comboBox->addItem(name);
|
comboBox->addItem(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadFromDCWidget::fill_device_list()
|
void DownloadFromDCWidget::fill_device_list(int dc_type)
|
||||||
{
|
{
|
||||||
int deviceIndex;
|
int deviceIndex;
|
||||||
ui.device->clear();
|
ui.device->clear();
|
||||||
deviceIndex = enumerate_devices(fillDeviceList, ui.device);
|
deviceIndex = enumerate_devices(fillDeviceList, ui.device, dc_type);
|
||||||
if (deviceIndex >= 0)
|
if (deviceIndex >= 0)
|
||||||
ui.device->setCurrentIndex(deviceIndex);
|
ui.device->setCurrentIndex(deviceIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ private:
|
||||||
QStringListModel *vendorModel;
|
QStringListModel *vendorModel;
|
||||||
QStringListModel *productModel;
|
QStringListModel *productModel;
|
||||||
void fill_computer_list();
|
void fill_computer_list();
|
||||||
void fill_device_list();
|
void fill_device_list(int dc_type);
|
||||||
QString logFile;
|
QString logFile;
|
||||||
QString dumpFile;
|
QString dumpFile;
|
||||||
QTimer *timer;
|
QTimer *timer;
|
||||||
|
|
106
windows.c
106
windows.c
|
@ -36,56 +36,88 @@ const char *system_default_filename(void)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int enumerate_devices(device_callback_t callback, void *userdata)
|
int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
|
||||||
{
|
{
|
||||||
// Open the registry key.
|
|
||||||
HKEY hKey;
|
|
||||||
int index = -1;
|
int index = -1;
|
||||||
LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey);
|
|
||||||
if (rc != ERROR_SUCCESS) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the number of values.
|
|
||||||
DWORD count = 0;
|
|
||||||
rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL);
|
|
||||||
if (rc != ERROR_SUCCESS) {
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
DWORD i;
|
DWORD i;
|
||||||
for (i = 0; i < count; ++i) {
|
if (dc_type != DC_TYPE_UEMIS) {
|
||||||
// Get the value name, data and type.
|
// Open the registry key.
|
||||||
char name[512], data[512];
|
HKEY hKey;
|
||||||
DWORD name_len = sizeof(name);
|
LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey);
|
||||||
DWORD data_len = sizeof(data);
|
if (rc != ERROR_SUCCESS) {
|
||||||
DWORD type = 0;
|
return -1;
|
||||||
rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len);
|
}
|
||||||
|
|
||||||
|
// Get the number of values.
|
||||||
|
DWORD count = 0;
|
||||||
|
rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL);
|
||||||
if (rc != ERROR_SUCCESS) {
|
if (rc != ERROR_SUCCESS) {
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
// Get the value name, data and type.
|
||||||
|
char name[512], data[512];
|
||||||
|
DWORD name_len = sizeof(name);
|
||||||
|
DWORD data_len = sizeof(data);
|
||||||
|
DWORD type = 0;
|
||||||
|
rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len);
|
||||||
|
if (rc != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore non-string values.
|
// Ignore non-string values.
|
||||||
if (type != REG_SZ)
|
if (type != REG_SZ)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Prevent a possible buffer overflow.
|
// Prevent a possible buffer overflow.
|
||||||
if (data_len >= sizeof(data)) {
|
if (data_len >= sizeof(data)) {
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null terminate the string.
|
||||||
|
data[data_len] = 0;
|
||||||
|
|
||||||
|
callback(data, userdata);
|
||||||
|
index++;
|
||||||
|
if (is_default_dive_computer_device(name))
|
||||||
|
index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Null terminate the string.
|
RegCloseKey(hKey);
|
||||||
data[data_len] = 0;
|
|
||||||
|
|
||||||
callback(data, userdata);
|
|
||||||
index++;
|
|
||||||
if (is_default_dive_computer_device(name))
|
|
||||||
index = i;
|
|
||||||
}
|
}
|
||||||
|
if (dc_type != DC_TYPE_SERIAL) {
|
||||||
|
int i;
|
||||||
|
const int bufdef = 512;
|
||||||
|
const char *dlabels[] = {"UEMISSDA", NULL};
|
||||||
|
char bufname[bufdef], bufval[bufdef], *p;
|
||||||
|
DWORD bufname_len;
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
/* 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 data[512];
|
||||||
|
snprintf(data, sizeof(data), "%s (%s)", p, dlabels[i]);
|
||||||
|
callback(data, userdata);
|
||||||
|
if (is_default_dive_computer_device(p))
|
||||||
|
index = i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = &p[strlen(p) + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue