+ GSList *devlist = NULL;
+ sr_session_dev_list(&devlist);
+
+ if (!devlist || !devlist->data ||
+ sr_session_start() != SR_OK) {
+ error_handler(tr("Failed to start session."));
+ return;
+ }
+
+ sr_dev_inst *const sdi = (sr_dev_inst*)devlist->data;
+ g_slist_free(devlist);
+
+ update_signals(sdi);
+ read_sample_rate(sdi);
+
+ _sampling_thread = boost::thread(
+ &SigSession::load_session_thread_proc, this,
+ error_handler);
+
+ } else {
+ sr_input *in = NULL;
+
+ if (!(in = load_input_file_format(name.c_str(),
+ error_handler)))
+ return;
+
+ update_signals(in->sdi);
+ read_sample_rate(in->sdi);
+
+ _sampling_thread = boost::thread(
+ &SigSession::load_input_thread_proc, this,
+ name, in, error_handler);
+ }
+}
+
+SigSession::capture_state SigSession::get_capture_state() const
+{
+ lock_guard<mutex> lock(_sampling_mutex);
+ return _capture_state;
+}
+
+void SigSession::start_capture(uint64_t record_length,
+ function<void (const QString)> error_handler)
+{
+ stop_capture();
+
+ // Check that a device instance has been selected.
+ if (!_sdi) {
+ qDebug() << "No device selected";
+ return;
+ }
+
+ // Check that at least one probe is enabled
+ const GSList *l;
+ for (l = _sdi->probes; l; l = l->next) {
+ sr_probe *const probe = (sr_probe*)l->data;
+ assert(probe);
+ if (probe->enabled)
+ break;
+ }
+
+ if (!l) {
+ error_handler(tr("No probes enabled."));
+ return;
+ }
+
+ // Begin the session
+ _sampling_thread = boost::thread(
+ &SigSession::sample_thread_proc, this, _sdi,
+ record_length, error_handler);
+}
+
+void SigSession::stop_capture()
+{
+ if (get_capture_state() == Stopped)
+ return;
+
+ sr_session_stop();
+
+ // Check that sampling stopped
+ _sampling_thread.join();
+}
+
+vector< shared_ptr<view::Signal> > SigSession::get_signals() const
+{
+ lock_guard<mutex> lock(_signals_mutex);
+ return _signals;
+}
+
+boost::shared_ptr<data::Logic> SigSession::get_data()
+{
+ return _logic_data;
+}
+
+bool SigSession::add_decoder(srd_decoder *const dec,
+ std::map<const srd_probe*,
+ boost::shared_ptr<view::LogicSignal> > probes,
+ GHashTable *options)
+{
+ try
+ {
+ lock_guard<mutex> lock(_signals_mutex);
+
+ shared_ptr<data::Decoder> decoder(
+ new data::Decoder(dec, probes, options));
+ shared_ptr<view::DecodeSignal> d(
+ new view::DecodeSignal(*this, decoder,
+ _decode_traces.size()));
+ _decode_traces.push_back(d);
+ }
+ catch(std::runtime_error e)
+ {
+ return false;
+ }
+
+ signals_changed();
+
+ return true;
+}
+
+vector< shared_ptr<view::DecodeSignal> > SigSession::get_decode_signals() const
+{
+ lock_guard<mutex> lock(_signals_mutex);
+ return _decode_traces;
+}
+
+void SigSession::remove_decode_signal(view::DecodeSignal *signal)
+{
+ for (vector< shared_ptr<view::DecodeSignal> >::iterator i =
+ _decode_traces.begin();
+ i != _decode_traces.end();
+ i++)
+ if ((*i).get() == signal)
+ {
+ _decode_traces.erase(i);
+ signals_changed();
+ return;
+ }
+}
+
+void SigSession::set_capture_state(capture_state state)
+{
+ lock_guard<mutex> lock(_sampling_mutex);
+ const bool changed = _capture_state != state;
+ _capture_state = state;
+ if(changed)
+ capture_state_changed(state);
+}
+
+/**
+ * Attempts to autodetect the format. Failing that
+ * @param filename The filename of the input file.
+ * @return A pointer to the 'struct sr_input_format' that should be used,
+ * or NULL if no input format was selected or auto-detected.
+ */
+sr_input_format* SigSession::determine_input_file_format(
+ const string &filename)
+{
+ int i;
+
+ /* If there are no input formats, return NULL right away. */
+ sr_input_format *const *const inputs = sr_input_list();
+ if (!inputs) {
+ g_critical("No supported input formats available.");
+ return NULL;
+ }
+
+ /* Otherwise, try to find an input module that can handle this file. */
+ for (i = 0; inputs[i]; i++) {
+ if (inputs[i]->format_match(filename.c_str()))
+ break;