2 * This file is part of the PulseView project.
4 * Copyright (C) 2012-2013 Joel Holdsworth <joel@airwebreathe.org.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <boost/foreach.hpp>
23 #include <libsigrok/libsigrok.h>
27 #include "pv/devicemanager.h"
28 #include "pv/device/device.h"
31 /* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */
32 #define __STDC_FORMAT_MACROS
34 #include <libsigrok/libsigrok.h>
37 using boost::shared_ptr
;
41 extern sr_context
*sr_ctx
;
46 Connect::Connect(QWidget
*parent
, pv::DeviceManager
&device_manager
) :
48 _device_manager(device_manager
),
53 _serial_device(&_form
),
54 _scan_button(tr("Scan for Devices"), this),
56 _button_box(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel
,
59 setWindowTitle(tr("Connect to Device"));
61 connect(&_button_box
, SIGNAL(accepted()), this, SLOT(accept()));
62 connect(&_button_box
, SIGNAL(rejected()), this, SLOT(reject()));
65 connect(&_drivers
, SIGNAL(activated(int)),
66 this, SLOT(device_selected(int)));
68 _form
.setLayout(&_form_layout
);
69 _form_layout
.addRow(tr("Driver"), &_drivers
);
71 _form_layout
.addRow(tr("Serial Port"), &_serial_device
);
75 connect(&_scan_button
, SIGNAL(pressed()),
76 this, SLOT(scan_pressed()));
79 _layout
.addWidget(&_form
);
80 _layout
.addWidget(&_scan_button
);
81 _layout
.addWidget(&_device_list
);
82 _layout
.addWidget(&_button_box
);
85 shared_ptr
<device::Device
> Connect::get_selected_device() const
87 const QListWidgetItem
*const item
= _device_list
.currentItem();
89 return shared_ptr
<device::Device
>();
91 const sr_dev_inst
*const sdi
= (sr_dev_inst
*)item
->data(
92 Qt::UserRole
).value
<void*>();
95 std::map
<const sr_dev_inst
*, boost::shared_ptr
<pv::device::Device
> >::
96 const_iterator iter
= _device_map
.find(sdi
);
97 assert(iter
!= _device_map
.end());
99 return (*iter
).second
;
102 void Connect::populate_drivers()
105 const int32_t *hwopts
;
106 struct sr_dev_driver
**drivers
= sr_driver_list();
109 for (int i
= 0; drivers
[i
]; ++i
) {
111 * We currently only support devices that can deliver
112 * samples at a fixed samplerate i.e. oscilloscopes and
114 * @todo Add support for non-monotonic devices i.e. DMMs
117 bool supported_device
= false;
118 if ((sr_config_list(drivers
[i
], NULL
, NULL
,
119 SR_CONF_DEVICE_OPTIONS
, &gvar_opts
) == SR_OK
)) {
120 hwopts
= (const int32_t *)g_variant_get_fixed_array(gvar_opts
,
121 &num_opts
, sizeof(int32_t));
122 for (unsigned int j
= 0; j
< num_opts
; j
++)
123 if (hwopts
[j
] == SR_CONF_SAMPLERATE
) {
124 supported_device
= true;
129 if (supported_device
)
130 _drivers
.addItem(QString("%1 (%2)").arg(
131 drivers
[i
]->longname
).arg(drivers
[i
]->name
),
132 qVariantFromValue((void*)drivers
[i
]));
136 void Connect::unset_connection()
138 _device_list
.clear();
140 _serial_device
.hide();
141 _form_layout
.labelForField(&_serial_device
)->hide();
142 _button_box
.button(QDialogButtonBox::Ok
)->setDisabled(true);
145 void Connect::set_serial_connection()
147 _serial_device
.show();
148 _form_layout
.labelForField(&_serial_device
)->show();
151 void Connect::scan_pressed()
153 _device_list
.clear();
156 const int index
= _drivers
.currentIndex();
160 sr_dev_driver
*const driver
= (sr_dev_driver
*)_drivers
.itemData(
161 index
).value
<void*>();
163 GSList
*drvopts
= NULL
;
165 if (_serial_device
.isVisible()) {
166 sr_config
*const src
= (sr_config
*)g_try_malloc(sizeof(sr_config
));
167 src
->key
= SR_CONF_CONN
;
168 const QByteArray byteArray
= _serial_device
.text().toUtf8();
169 src
->data
= g_variant_new_string((const gchar
*)byteArray
.constData());
170 drvopts
= g_slist_append(drvopts
, src
);
173 const list
< shared_ptr
<device::Device
> > devices
=
174 _device_manager
.driver_scan(driver
, drvopts
);
176 g_slist_free_full(drvopts
, (GDestroyNotify
)free_drvopts
);
178 BOOST_FOREACH(shared_ptr
<device::Device
> dev_inst
, devices
)
181 const sr_dev_inst
*const sdi
= dev_inst
->dev_inst();
184 const string title
= dev_inst
->format_device_title();
185 QString text
= QString::fromUtf8(title
.c_str());
188 text
+= QString(" with %1 channels").arg(
189 g_slist_length(sdi
->channels
));
192 QListWidgetItem
*const item
= new QListWidgetItem(text
,
194 item
->setData(Qt::UserRole
, qVariantFromValue((void*)sdi
));
195 _device_list
.addItem(item
);
196 _device_map
[sdi
] = dev_inst
;
199 _device_list
.setCurrentRow(0);
200 _button_box
.button(QDialogButtonBox::Ok
)->setDisabled(_device_list
.count() == 0);
203 void Connect::device_selected(int index
)
206 const int32_t *hwopts
;
208 sr_dev_driver
*const driver
= (sr_dev_driver
*)_drivers
.itemData(
209 index
).value
<void*>();
213 if ((sr_config_list(driver
, NULL
, NULL
,
214 SR_CONF_SCAN_OPTIONS
, &gvar_list
) == SR_OK
)) {
215 hwopts
= (const int32_t *)g_variant_get_fixed_array(gvar_list
,
216 &num_opts
, sizeof(int32_t));
218 for (unsigned int i
= 0; i
< num_opts
; i
++) {
220 case SR_CONF_SERIALCOMM
:
221 set_serial_connection();
230 g_variant_unref(gvar_list
);
234 void Connect::free_drvopts(struct sr_config
*src
)
236 g_variant_unref(src
->data
);
240 } // namespace dialogs