]> sigrok.org Git - pulseview.git/commitdiff
Use libsigrok C++ bindings (patch version 7).
authorMartin Ling <redacted>
Wed, 15 Oct 2014 00:04:55 +0000 (01:04 +0100)
committerMartin Ling <redacted>
Wed, 15 Oct 2014 00:04:55 +0000 (01:04 +0100)
51 files changed:
CMakeLists.txt
main.cpp
pv/data/decode/decoder.cpp
pv/data/logicsnapshot.cpp
pv/data/logicsnapshot.h
pv/data/snapshot.h
pv/device/device.cpp [deleted file]
pv/device/device.h [deleted file]
pv/device/devinst.cpp [deleted file]
pv/device/devinst.h [deleted file]
pv/device/file.cpp [deleted file]
pv/device/file.h [deleted file]
pv/device/sessionfile.cpp [deleted file]
pv/device/sessionfile.h [deleted file]
pv/devicemanager.cpp
pv/devicemanager.h
pv/dialogs/about.cpp
pv/dialogs/about.h
pv/dialogs/connect.cpp
pv/dialogs/connect.h
pv/mainwindow.cpp
pv/mainwindow.h
pv/popups/channels.cpp
pv/popups/channels.h
pv/popups/deviceoptions.cpp
pv/popups/deviceoptions.h
pv/prop/binding/binding.cpp
pv/prop/binding/binding.h
pv/prop/binding/decoderoptions.cpp
pv/prop/binding/decoderoptions.h
pv/prop/binding/deviceoptions.cpp
pv/prop/binding/deviceoptions.h
pv/prop/bool.cpp
pv/prop/double.cpp
pv/prop/enum.cpp
pv/prop/enum.h
pv/prop/int.cpp
pv/prop/int.h
pv/prop/property.h
pv/prop/string.cpp
pv/sigsession.cpp
pv/sigsession.h
pv/storesession.cpp
pv/toolbars/samplingbar.cpp
pv/toolbars/samplingbar.h
pv/view/analogsignal.cpp
pv/view/analogsignal.h
pv/view/logicsignal.cpp
pv/view/logicsignal.h
pv/view/signal.cpp
pv/view/signal.h

index f334f9118c024018179cd8fb433d2525790cce39..31926adf5d5703ff4c476f635d0278389a5a2af1 100644 (file)
@@ -58,7 +58,7 @@ endif()
 #= Dependencies
 #-------------------------------------------------------------------------------
 
-list(APPEND PKGDEPS libsigrok>=0.3.0)
+list(APPEND PKGDEPS libsigrokxx>=0.3.0)
 
 if(ENABLE_DECODE)
        list(APPEND PKGDEPS libsigrokdecode>=0.3.0)
@@ -140,10 +140,6 @@ set(pulseview_SOURCES
        pv/data/logicsnapshot.cpp
        pv/data/signaldata.cpp
        pv/data/snapshot.cpp
-       pv/device/device.cpp
-       pv/device/file.cpp
-       pv/device/devinst.cpp
-       pv/device/sessionfile.cpp
        pv/dialogs/about.cpp
        pv/dialogs/connect.cpp
        pv/dialogs/storeprogress.cpp
@@ -186,7 +182,6 @@ set(pulseview_HEADERS
        pv/mainwindow.h
        pv/sigsession.h
        pv/storesession.h
-       pv/device/devinst.h
        pv/dialogs/about.h
        pv/dialogs/connect.h
        pv/dialogs/storeprogress.h
@@ -198,6 +193,7 @@ set(pulseview_HEADERS
        pv/prop/int.h
        pv/prop/property.h
        pv/prop/string.h
+       pv/prop/binding/deviceoptions.h
        pv/toolbars/samplingbar.h
        pv/view/cursor.h
        pv/view/cursorheader.h
index 5c3e5b25818ffc70d1ac28a347e9b33cb91bda47..c0ac04b475d49b9ac2330856ceded776ab34e292 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -23,7 +23,7 @@
 #endif
 
 #include <stdint.h>
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
 #include <getopt.h>
 
@@ -65,7 +65,7 @@ void usage()
 int main(int argc, char *argv[])
 {
        int ret = 0;
-       struct sr_context *sr_ctx = NULL;
+       std::shared_ptr<sigrok::Context> context;
        const char *open_file = NULL;
 
        Application a(argc, argv);
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
                case 'l':
                {
                        const int loglevel = atoi(optarg);
-                       sr_log_loglevel_set(loglevel);
+                       context->set_log_level(sigrok::LogLevel::get(loglevel));
 
 #ifdef ENABLE_DECODE
                        srd_log_loglevel_set(loglevel);
@@ -121,10 +121,7 @@ int main(int argc, char *argv[])
                open_file = argv[argc - 1];
 
        // Initialise libsigrok
-       if (sr_init(&sr_ctx) != SR_OK) {
-               qDebug() << "ERROR: libsigrok init failed.";
-               return 1;
-       }
+       context = sigrok::Context::create();
 
        do {
 
@@ -141,7 +138,7 @@ int main(int argc, char *argv[])
 
                try {
                        // Create the device manager, initialise the drivers
-                       pv::DeviceManager device_manager(sr_ctx);
+                       pv::DeviceManager device_manager(context);
 
                        // Initialise the main window
                        pv::MainWindow w(device_manager, open_file);
@@ -177,9 +174,5 @@ int main(int argc, char *argv[])
 
        } while (0);
 
-       // Destroy libsigrok
-       if (sr_ctx)
-               sr_exit(sr_ctx);
-
        return ret;
 }
index 14097cfdc03453431a66d22f81f8d1ae87a40692..56ebc7e598299f4faae507a0aea943d9401b77f1 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <cassert>
 
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 #include <libsigrokdecode/libsigrokdecode.h>
 
 #include "decoder.h"
@@ -139,7 +139,7 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_si
        {
                shared_ptr<view::LogicSignal> signal((*i).second);
                GVariant *const gvar = g_variant_new_int32(
-                       signal->channel()->index);
+                       signal->channel()->index());
                g_variant_ref_sink(gvar);
                g_hash_table_insert(channels, (*i).first->id, gvar);
        }
index 825d2f1f51f6ea59d93883ec3178e68a11675e54..a00a22ede0cd33ee5aa3b43042f51b59c37d8376 100644 (file)
 #include "config.h"
 #include "logicsnapshot.h"
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::lock_guard;
 using std::recursive_mutex;
 using std::max;
 using std::min;
 using std::pair;
+using std::shared_ptr;
+
+using sigrok::Logic;
 
 namespace pv {
 namespace data {
@@ -42,9 +47,9 @@ const int LogicSnapshot::MipMapScaleFactor = 1 << MipMapScalePower;
 const float LogicSnapshot::LogMipMapScaleFactor = logf(MipMapScaleFactor);
 const uint64_t LogicSnapshot::MipMapDataUnit = 64*1024;        // bytes
 
-LogicSnapshot::LogicSnapshot(const sr_datafeed_logic &logic,
+LogicSnapshot::LogicSnapshot(shared_ptr<Logic> logic,
                              const uint64_t expected_num_samples) :
-       Snapshot(logic.unitsize),
+       Snapshot(logic->unit_size()),
        _last_append_sample(0)
 {
        set_capacity(expected_num_samples);
@@ -135,15 +140,15 @@ void LogicSnapshot::pack_sample(uint8_t *ptr, uint64_t value)
 #endif
 }
 
-void LogicSnapshot::append_payload(
-       const sr_datafeed_logic &logic)
+void LogicSnapshot::append_payload(shared_ptr<Logic> logic)
 {
-       assert(_unit_size == logic.unitsize);
-       assert((logic.length % _unit_size) == 0);
+       assert(_unit_size == logic->unit_size());
+       assert((logic->data_length() % _unit_size) == 0);
 
        lock_guard<recursive_mutex> lock(_mutex);
 
-       append_data(logic.data, logic.length / _unit_size);
+       append_data(logic->data_pointer(),
+               logic->data_length() / _unit_size);
 
        // Generate the first mip-map from the data
        append_payload_to_mipmap();
index bcb644da58da7073831883920f4294535eae8a2d..a215f92801307879b91402ffadffc9f3e668cc2a 100644 (file)
 #include <utility>
 #include <vector>
 
+namespace sigrok {
+       class Logic;
+}
+
 namespace LogicSnapshotTest {
 struct Pow2;
 struct Basic;
@@ -58,12 +62,12 @@ public:
        typedef std::pair<int64_t, bool> EdgePair;
 
 public:
-       LogicSnapshot(const sr_datafeed_logic &logic,
+       LogicSnapshot(std::shared_ptr<sigrok::Logic> logic,
                      uint64_t expected_num_samples = 0);
 
        virtual ~LogicSnapshot();
 
-       void append_payload(const sr_datafeed_logic &logic);
+       void append_payload(std::shared_ptr<sigrok::Logic> logic);
 
        void get_samples(uint8_t *const data,
                int64_t start_sample, int64_t end_sample) const;
index fcb420c773e27a37359dcff4f2678b625764e73c..48879991fbbcc7d4af1d197ea68accba72512699 100644 (file)
@@ -21,8 +21,6 @@
 #ifndef PULSEVIEW_PV_DATA_SNAPSHOT_H
 #define PULSEVIEW_PV_DATA_SNAPSHOT_H
 
-#include <libsigrok/libsigrok.h>
-
 #include <thread>
 #include <mutex>
 #include <vector>
diff --git a/pv/device/device.cpp b/pv/device/device.cpp
deleted file mode 100644 (file)
index 546ce39..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <cassert>
-#include <sstream>
-
-#include <libsigrok/libsigrok.h>
-
-#include "device.h"
-
-using std::list;
-using std::make_pair;
-using std::map;
-using std::ostringstream;
-using std::string;
-
-namespace pv {
-namespace device {
-
-Device::Device(sr_dev_inst *sdi) :
-       _sdi(sdi)
-{
-       assert(_sdi);
-}
-
-sr_dev_inst* Device::dev_inst() const
-{
-       return _sdi;
-}
-
-void Device::use(SigSession *owner) throw(QString)
-{
-       DevInst::use(owner);
-
-       sr_session_new(&SigSession::_sr_session);
-
-       assert(_sdi);
-       sr_dev_open(_sdi);
-       if (sr_session_dev_add(SigSession::_sr_session, _sdi) != SR_OK)
-               throw QString(tr("Failed to use device."));
-}
-
-void Device::release()
-{
-       if (_owner) {
-               DevInst::release();
-               sr_session_destroy(SigSession::_sr_session);
-       }
-
-       sr_dev_close(_sdi);
-}
-
-std::string Device::format_device_title() const
-{
-       ostringstream s;
-
-       assert(_sdi);
-
-       if (_sdi->vendor && _sdi->vendor[0])
-               s << _sdi->vendor << " ";
-
-       if (_sdi->model && _sdi->model[0])
-               s << _sdi->model << " ";
-
-       if (_sdi->version && _sdi->version[0])
-               s << _sdi->version << " ";
-
-       // Show connection string only if no serial number is present.
-       if (_sdi->serial_num && _sdi->serial_num[0])
-               s << "(" << _sdi->serial_num << ") ";
-       else if (_sdi->connection_id && _sdi->connection_id[0])
-               s << "[" << _sdi->connection_id << "] ";
-
-       // Remove trailing space.
-       s.seekp(-1, std::ios_base::end);
-       s << std::ends;
-
-       return s.str();
-}
-
-map<string, string> Device::get_device_info() const
-{
-       map<string, string> result;
-
-       assert(_sdi);
-
-       if (_sdi->vendor && _sdi->vendor[0])
-               result.insert(make_pair("vendor", _sdi->vendor));
-
-       if (_sdi->model && _sdi->model[0])
-               result.insert(make_pair("model", _sdi->model));
-
-       if (_sdi->version && _sdi->version[0])
-               result.insert(make_pair("version", _sdi->version));
-
-       if (_sdi->serial_num && _sdi->serial_num[0])
-               result.insert(make_pair("serial_num", _sdi->serial_num));
-
-       if (_sdi->connection_id && _sdi->connection_id[0])
-               result.insert(make_pair("connection_id", _sdi->connection_id));
-
-       return result;
-}
-
-} // device
-} // pv
diff --git a/pv/device/device.h b/pv/device/device.h
deleted file mode 100644 (file)
index 0a908a7..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_DEVICE_DEVICE_H
-#define PULSEVIEW_PV_DEVICE_DEVICE_H
-
-#include <map>
-#include <string>
-
-#include "devinst.h"
-
-namespace pv {
-namespace device {
-
-class Device : public DevInst
-{
-public:
-       Device(sr_dev_inst *dev_inst);
-
-       sr_dev_inst* dev_inst() const;
-
-       void use(SigSession *owner) throw(QString);
-
-       void release();
-
-       std::string format_device_title() const;
-
-       std::map<std::string, std::string> get_device_info() const;
-
-private:
-       sr_dev_inst *const _sdi;
-};
-
-} // device
-} // pv
-
-#endif // PULSVIEW_PV_DEVICE_DEVICE_H
diff --git a/pv/device/devinst.cpp b/pv/device/devinst.cpp
deleted file mode 100644 (file)
index 0301063..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <cassert>
-
-#include <QDebug>
-
-#include <libsigrok/libsigrok.h>
-
-#include "devinst.h"
-
-#include <pv/sigsession.h>
-
-namespace pv {
-namespace device {
-
-DevInst::DevInst() :
-       _owner(NULL)
-{
-}
-
-void DevInst::use(SigSession *owner) throw(QString)
-{
-       assert(owner);
-       assert(!_owner);
-       _owner = owner;
-}
-
-void DevInst::release()
-{
-       if (_owner) {
-               _owner->release_device(this);
-               _owner = NULL;
-       }
-}
-
-SigSession* DevInst::owner() const
-{
-       return _owner;
-}
-
-GVariant* DevInst::get_config(const sr_channel_group *group, int key)
-{
-       GVariant *data = NULL;
-       assert(_owner);
-       sr_dev_inst *const sdi = dev_inst();
-       assert(sdi);
-       if (sr_config_get(sdi->driver, sdi, group, key, &data) != SR_OK)
-               return NULL;
-       return data;
-}
-
-bool DevInst::set_config(const sr_channel_group *group, int key, GVariant *data)
-{
-       assert(_owner);
-       sr_dev_inst *const sdi = dev_inst();
-       assert(sdi);
-       if(sr_config_set(sdi, group, key, data) == SR_OK) {
-               config_changed();
-               return true;
-       }
-       return false;
-}
-
-GVariant* DevInst::list_config(const sr_channel_group *group, int key)
-{
-       GVariant *data = NULL;
-       assert(_owner);
-       sr_dev_inst *const sdi = dev_inst();
-       assert(sdi);
-       if (sr_config_list(sdi->driver, sdi, group, key, &data) != SR_OK)
-               return NULL;
-       return data;
-}
-
-void DevInst::enable_channel(const sr_channel *channel, bool enable)
-{
-       assert(_owner);
-       sr_dev_inst *const sdi = dev_inst();
-       assert(sdi);
-       for (const GSList *p = sdi->channels; p; p = p->next)
-               if (channel == p->data) {
-                       const_cast<sr_channel*>(channel)->enabled = enable;
-                       config_changed();
-                       return;
-               }
-
-       // Channel was not found in the device
-       assert(0);
-}
-
-uint64_t DevInst::get_sample_limit()
-{
-       uint64_t sample_limit;
-       GVariant* gvar = get_config(NULL, SR_CONF_LIMIT_SAMPLES);
-       if (gvar != NULL) {
-               sample_limit = g_variant_get_uint64(gvar);
-               g_variant_unref(gvar);
-       } else {
-               sample_limit = 0U;
-       }
-       return sample_limit;
-}
-
-bool DevInst::is_trigger_enabled() const
-{
-       return false;
-}
-
-void DevInst::start()
-{
-       if (sr_session_start(SigSession::_sr_session) != SR_OK)
-               throw tr("Failed to start session.");
-}
-
-void DevInst::run()
-{
-       sr_session_run(SigSession::_sr_session);
-}
-
-} // device
-} // pv
diff --git a/pv/device/devinst.h b/pv/device/devinst.h
deleted file mode 100644 (file)
index 1e0850c..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_DEVICE_DEVINST_H
-#define PULSEVIEW_PV_DEVICE_DEVINST_H
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <QObject>
-
-#include <glib.h>
-
-#include <stdint.h>
-
-struct sr_dev_inst;
-struct sr_channel;
-struct sr_channel_group;
-
-#include <pv/sigsession.h>
-
-namespace pv {
-
-namespace device {
-
-class DevInst : public QObject
-{
-       Q_OBJECT
-
-protected:
-       DevInst();
-
-public:
-       virtual sr_dev_inst* dev_inst() const = 0;
-
-       virtual void use(SigSession *owner) throw(QString);
-
-       virtual void release();
-
-       SigSession* owner() const;
-
-       virtual std::string format_device_title() const = 0;
-
-       virtual std::map<std::string, std::string> get_device_info() const = 0;
-
-       GVariant* get_config(const sr_channel_group *group, int key);
-
-       bool set_config(const sr_channel_group *group, int key, GVariant *data);
-
-       GVariant* list_config(const sr_channel_group *group, int key);
-
-       void enable_channel(const sr_channel *channel, bool enable = true);
-
-       /**
-        * @brief Gets the sample limit from the driver.
-        *
-        * @return The returned sample limit from the driver, or 0 if the
-        *      sample limit could not be read.
-        */
-       uint64_t get_sample_limit();
-
-       virtual bool is_trigger_enabled() const;
-
-public:
-       virtual void start();
-
-       virtual void run();
-
-Q_SIGNALS:
-       void config_changed();
-
-protected:
-       SigSession *_owner;
-};
-
-} // device
-} // pv
-
-#endif // PULSEVIEW_PV_DEVICE_DEVINST_H
diff --git a/pv/device/file.cpp b/pv/device/file.cpp
deleted file mode 100644 (file)
index 368276a..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "file.h"
-#include "sessionfile.h"
-
-#include <boost/filesystem.hpp>
-
-#include <libsigrok/libsigrok.h>
-
-using std::make_pair;
-using std::map;
-using std::string;
-
-namespace pv {
-namespace device {
-
-File::File(const std::string path) :
-       _path(path)
-{
-}
-
-std::string File::format_device_title() const
-{
-       return boost::filesystem::path(_path).filename().string();
-}
-
-map<string, string> File::get_device_info() const
-{
-       map<string, string> result;
-
-       result.insert(make_pair("vendor", "sigrok"));
-       result.insert(make_pair("model", "file"));
-       result.insert(make_pair("connection_id",
-                       boost::filesystem::path(_path).filename().string()));
-
-       return result;
-}
-
-File* File::create(const string &name)
-{
-       struct sr_session *temp_session;
-       if (sr_session_load(name.c_str(), &temp_session) == SR_OK) {
-               GSList *devlist = NULL;
-               sr_session_dev_list(temp_session, &devlist);
-               sr_session_destroy(temp_session);
-
-               if (devlist) {
-                       sr_dev_inst *const sdi = (sr_dev_inst*)devlist->data;
-                       g_slist_free(devlist);
-                       if (sdi) {
-                               sr_dev_close(sdi);
-                               sr_dev_clear(sdi->driver);
-                               return new SessionFile(name);
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-} // device
-} // pv
diff --git a/pv/device/file.h b/pv/device/file.h
deleted file mode 100644 (file)
index c6c21ca..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_DEVICE_FILE_H
-#define PULSEVIEW_PV_DEVICE_FILE_H
-
-#include <string>
-
-#include "devinst.h"
-
-namespace pv {
-namespace device {
-
-class File : public DevInst
-{
-protected:
-       File(const std::string path);
-
-public:
-       static File* create(const std::string &name);
-
-public:
-       std::string format_device_title() const;
-
-       std::map<std::string, std::string> get_device_info() const;
-
-protected:
-       const std::string _path;
-};
-
-} // device
-} // pv
-
-#endif // PULSEVIEW_PV_DEVICE_FILE_H
diff --git a/pv/device/sessionfile.cpp b/pv/device/sessionfile.cpp
deleted file mode 100644 (file)
index a2810d4..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <cassert>
-
-#include "sessionfile.h"
-
-#include <libsigrok/libsigrok.h>
-
-namespace pv {
-namespace device {
-
-SessionFile::SessionFile(const std::string &path) :
-       File(path),
-       _sdi(NULL)
-{
-}
-
-sr_dev_inst* SessionFile::dev_inst() const
-{
-       return _sdi;
-}
-
-void SessionFile::use(SigSession *owner) throw(QString)
-{
-       assert(!_sdi);
-
-       if (sr_session_load(_path.c_str(), &SigSession::_sr_session) != SR_OK)
-               throw tr("Failed to open file.\n");
-
-       GSList *devlist = NULL;
-       sr_session_dev_list(SigSession::_sr_session, &devlist);
-
-       if (!devlist || !devlist->data) {
-               if (devlist)
-                       g_slist_free(devlist);
-               throw tr("Failed to start session.");
-       }
-
-       _sdi = (sr_dev_inst*)devlist->data;
-       g_slist_free(devlist);
-
-       File::use(owner);
-}
-
-void SessionFile::release()
-{
-       if (!_owner)
-               return;
-
-       assert(_sdi);
-       File::release();
-       sr_dev_close(_sdi);
-       sr_dev_clear(_sdi->driver);
-       sr_session_destroy(SigSession::_sr_session);
-       _sdi = NULL;
-}
-
-} // device
-} // pv
diff --git a/pv/device/sessionfile.h b/pv/device/sessionfile.h
deleted file mode 100644 (file)
index c0ed958..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_DEVICE_SESSIONFILE_H
-#define PULSEVIEW_PV_DEVICE_SESSIONFILE_H
-
-#include "file.h"
-
-namespace pv {
-namespace device {
-
-class SessionFile : public File
-{
-public:
-       SessionFile(const std::string &path);
-
-       sr_dev_inst* dev_inst() const;
-
-       virtual void use(SigSession *owner) throw(QString);
-
-       virtual void release();
-
-private:
-       sr_dev_inst *_sdi;
-};
-
-} // device
-} // pv
-
-#endif // PULSEVIEW_PV_DEVICE_SESSIONFILE_H
index 13b44e969cc2720e0d17f86c9ab4871030221f06..c06fd79f3b77891a8605a57c386bb68f806004cc 100644 (file)
  */
 
 #include "devicemanager.h"
-#include "device/device.h"
 #include "sigsession.h"
 
 #include <cassert>
 #include <stdexcept>
+#include <sstream>
 #include <string>
+#include <vector>
 
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
+#include <boost/filesystem.hpp>
+
+using std::dynamic_pointer_cast;
 using std::list;
 using std::map;
+using std::ostringstream;
+using std::remove_if;
 using std::runtime_error;
 using std::shared_ptr;
 using std::string;
+using std::vector;
+
+using Glib::VariantBase;
+
+using sigrok::ConfigKey;
+using sigrok::Context;
+using sigrok::Driver;
+using sigrok::Device;
+using sigrok::HardwareDevice;
+using sigrok::SessionDevice;
 
 namespace pv {
 
-DeviceManager::DeviceManager(struct sr_context *sr_ctx) :
-       _sr_ctx(sr_ctx)
+DeviceManager::DeviceManager(shared_ptr<Context> context) :
+       _context(context)
 {
-       init_drivers();
-       scan_all_drivers();
+       for (auto entry : context->drivers())
+               driver_scan(entry.second, map<const ConfigKey *, VariantBase>());
 }
 
 DeviceManager::~DeviceManager()
 {
-       release_devices();
 }
 
-const list< shared_ptr<pv::device::Device> >& DeviceManager::devices() const
+shared_ptr<Context> DeviceManager::context()
+{
+       return _context;
+}
+
+const list< shared_ptr<HardwareDevice> >& DeviceManager::devices() const
 {
        return _devices;
 }
 
-list< shared_ptr<device::Device> > DeviceManager::driver_scan(
-       struct sr_dev_driver *const driver, GSList *const drvopts)
+list< shared_ptr<HardwareDevice> > DeviceManager::driver_scan(
+       shared_ptr<Driver> driver, map<const ConfigKey *, VariantBase> drvopts)
 {
-       list< shared_ptr<device::Device> > driver_devices;
+       list< shared_ptr<HardwareDevice> > driver_devices;
 
        assert(driver);
 
        // Remove any device instances from this driver from the device
        // list. They will not be valid after the scan.
-       auto i = _devices.begin();
-       while (i != _devices.end()) {
-               if ((*i)->dev_inst()->driver == driver)
-                       i = _devices.erase(i);
-               else
-                       i++;
-       }
-
-       // Release this driver and all it's attached devices
-       release_driver(driver);
+       remove_if(_devices.begin(), _devices.end(),
+               [&](shared_ptr<HardwareDevice> device) {
+                       return device->driver() == driver; });
 
        // Do the scan
-       GSList *const devices = sr_driver_scan(driver, drvopts);
-       for (GSList *l = devices; l; l = l->next)
-               driver_devices.push_back(shared_ptr<device::Device>(
-                       new device::Device((sr_dev_inst*)l->data)));
-       g_slist_free(devices);
+       auto devices = driver->scan(drvopts);
+       driver_devices.insert(driver_devices.end(), devices.begin(), devices.end());
        driver_devices.sort(compare_devices);
 
        // Add the scanned devices to the main list
@@ -89,17 +99,38 @@ list< shared_ptr<device::Device> > DeviceManager::driver_scan(
        return driver_devices;
 }
 
-const shared_ptr<device::Device> DeviceManager::find_device_from_info(
+const map<string, string> DeviceManager::get_device_info(
+       shared_ptr<Device> device)
+{
+       map<string, string> result;
+
+       assert(device);
+
+       if (device->vendor().length() > 0)
+               result["vendor"] = device->vendor();
+       if (device->model().length() > 0)
+               result["model"] = device->model();
+       if (device->version().length() > 0)
+               result["version"] = device->version();
+       if (device->serial_number().length() > 0)
+               result["serial_num"] = device->serial_number();
+       if (device->connection_id().length() > 0)
+               result["connection_id"] = device->connection_id();
+
+       return result;
+}
+
+const shared_ptr<HardwareDevice> DeviceManager::find_device_from_info(
        const map<string, string> search_info)
 {
-       shared_ptr<device::Device> last_resort_dev;
+       shared_ptr<HardwareDevice> last_resort_dev;
        map<string, string> dev_info;
 
        last_resort_dev = NULL;
 
-       for (shared_ptr<device::Device> dev : _devices) {
+       for (shared_ptr<HardwareDevice> dev : _devices) {
                assert(dev);
-               dev_info = dev->get_device_info();
+               dev_info = get_device_info(dev);
 
                // If present, vendor and model always have to match.
                if (dev_info.count("vendor") > 0 && search_info.count("vendor") > 0)
@@ -140,59 +171,43 @@ const shared_ptr<device::Device> DeviceManager::find_device_from_info(
        return last_resort_dev;
 }
 
-void DeviceManager::init_drivers()
+string DeviceManager::device_description(shared_ptr<Device> device)
 {
-       // Initialise all libsigrok drivers
-       sr_dev_driver **const drivers = sr_driver_list();
-       for (sr_dev_driver **driver = drivers; *driver; driver++) {
-               if (sr_driver_init(_sr_ctx, *driver) != SR_OK) {
-                       throw runtime_error(
-                               string("Failed to initialize driver ") +
-                               string((*driver)->name));
-               }
-       }
-}
+       auto session_device = dynamic_pointer_cast<SessionDevice>(device);
 
-void DeviceManager::release_devices()
-{
-       // Release all the used devices
-       for (shared_ptr<device::Device> dev : _devices) {
-               assert(dev);
-               dev->release();
-       }
+       if (session_device)
+               return boost::filesystem::path(
+                       session_device->parent()->filename()).filename().string();
 
-       // Clear all the drivers
-       sr_dev_driver **const drivers = sr_driver_list();
-       for (sr_dev_driver **driver = drivers; *driver; driver++)
-               sr_dev_clear(*driver);
-}
+       ostringstream s;
 
-void DeviceManager::scan_all_drivers()
-{
-       // Scan all drivers for all devices.
-       struct sr_dev_driver **const drivers = sr_driver_list();
-       for (struct sr_dev_driver **driver = drivers; *driver; driver++)
-               driver_scan(*driver);
-}
+       vector<string> parts = {device->vendor(), device->model(),
+               device->version(), device->serial_number()};
 
-void DeviceManager::release_driver(struct sr_dev_driver *const driver)
-{
-       for (shared_ptr<device::Device> dev : _devices) {
-               assert(dev);
-               if(dev->dev_inst()->driver == driver)
-                       dev->release();
+       for (size_t i = 0; i < parts.size(); i++)
+       {
+               if (parts[i].length() > 0)
+               {
+                       if (i != 0)
+                               s << " ";
+                       s << parts[i];
+               }
        }
 
-       // Clear all the old device instances from this driver
-       sr_dev_clear(driver);
+       if (device->serial_number().length() == 0 &&
+                       device->connection_id().length() > 0)
+               s << " " << device->connection_id();
+
+       return s.str();
 }
 
-bool DeviceManager::compare_devices(shared_ptr<device::Device> a,
-       shared_ptr<device::Device> b)
+bool DeviceManager::compare_devices(shared_ptr<HardwareDevice> a,
+       shared_ptr<HardwareDevice> b)
 {
        assert(a);
        assert(b);
-       return a->format_device_title().compare(b->format_device_title()) < 0;
+
+       return device_description(a).compare(device_description(b)) < 0;
 }
 
 } // namespace pv
index 0a8f2e0dca7d24fedb53cf7b734d321320ff180a..0a47a35a004659b09da56ce7545135159a448939 100644 (file)
 #ifndef PULSEVIEW_PV_DEVICEMANAGER_H
 #define PULSEVIEW_PV_DEVICEMANAGER_H
 
-#include <glib.h>
-
 #include <list>
 #include <map>
 #include <memory>
 #include <string>
 
-struct sr_context;
-struct sr_dev_driver;
+namespace Glib {
+       class VariantBase;
+}
+
+namespace sigrok {
+       class ConfigKey;
+       class Context;
+       class Driver;
+       class Device;
+       class HardwareDevice;
+}
 
 namespace pv {
 
 class SigSession;
 
-namespace device {
-class Device;
-}
-
 class DeviceManager
 {
 public:
-       DeviceManager(struct sr_context *sr_ctx);
+       DeviceManager(std::shared_ptr<sigrok::Context> context);
 
        ~DeviceManager();
 
-       const std::list< std::shared_ptr<pv::device::Device> >&
-               devices() const;
-
-       std::list< std::shared_ptr<pv::device::Device> > driver_scan(
-               struct sr_dev_driver *const driver,
-               GSList *const drvopts = NULL);
-
-       const std::shared_ptr<device::Device> find_device_from_info(
-               const std::map<std::string, std::string> search_info);
+       std::shared_ptr<sigrok::Context> context();
 
-private:
-       void init_drivers();
+       const std::list< std::shared_ptr<sigrok::HardwareDevice> >&
+               devices() const;
 
-       void release_devices();
+       std::list< std::shared_ptr<sigrok::HardwareDevice> > driver_scan(
+               std::shared_ptr<sigrok::Driver> driver,
+               std::map<const sigrok::ConfigKey *, Glib::VariantBase> drvopts);
 
-       void scan_all_drivers();
+       const std::map<std::string, std::string> get_device_info(
+               const std::shared_ptr<sigrok::Device> device);
 
-       void release_driver(struct sr_dev_driver *const driver);
+       const std::shared_ptr<sigrok::HardwareDevice> find_device_from_info(
+               const std::map<std::string, std::string> search_info);
 
-       static bool compare_devices(std::shared_ptr<device::Device> a,
-               std::shared_ptr<device::Device> b);
+       static std::string device_description(std::shared_ptr<sigrok::Device> device);
 
 private:
-       struct sr_context *const _sr_ctx;
-       std::list< std::shared_ptr<pv::device::Device> > _devices;
+       static bool compare_devices(std::shared_ptr<sigrok::HardwareDevice> a,
+               std::shared_ptr<sigrok::HardwareDevice> b);
+
+protected:
+       std::shared_ptr<sigrok::Context> _context;
+       std::list< std::shared_ptr<sigrok::HardwareDevice> > _devices;
 };
 
 } // namespace pv
index f8394f2ae6f3784bdd72ef84089ac26e3dcd3711..05daff8a2698c99b11c1e88c7dcb61292a9a5775 100644 (file)
 #include "about.h"
 #include <ui_about.h>
 
-/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */
-#define __STDC_FORMAT_MACROS
-#include <glib.h>
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
+using std::shared_ptr;
+using sigrok::Context;
 
 namespace pv {
 namespace dialogs {
 
-About::About(QWidget *parent) :
+About::About(shared_ptr<Context> context, QWidget *parent) :
        QDialog(parent),
        ui(new Ui::About)
 {
-       struct sr_dev_driver **drivers;
-
 #ifdef ENABLE_DECODE
        struct srd_decoder *dec;
 #endif
@@ -64,11 +61,19 @@ About::About(QWidget *parent) :
        s.append("<tr><td colspan=\"2\"><b>" +
                tr("Supported hardware drivers:") +
                "</b></td></tr>");
-       drivers = sr_driver_list();
-       for (int i = 0; drivers[i]; ++i) {
+       for (auto entry : context->drivers()) {
+               s.append(QString("<tr><td><i>%1</i></td><td>%2</td></tr>")
+                        .arg(QString::fromUtf8(entry.first.c_str()))
+                        .arg(QString::fromUtf8(entry.second->long_name().c_str())));
+       }
+
+       s.append("<tr><td colspan=\"2\"><b>" +
+               tr("Supported input formats:") +
+               "</b></td></tr>");
+       for (auto entry : context->input_formats()) {
                s.append(QString("<tr><td><i>%1</i></td><td>%2</td></tr>")
-                        .arg(QString::fromUtf8(drivers[i]->name))
-                        .arg(QString::fromUtf8(drivers[i]->longname)));
+                        .arg(QString::fromUtf8(entry.first.c_str()))
+                        .arg(QString::fromUtf8(entry.second->description().c_str())));
        }
 
 #ifdef ENABLE_DECODE
index cc153addc78ef043e9773d416aed06141f496d76..6656f9c0fc7f2ca94c29082443b9ebbc052a32f2 100644 (file)
 
 class QTextDocument;
 
+namespace sigrok {
+       class Context;
+}
+
 namespace Ui {
 class About;
 }
@@ -39,7 +43,7 @@ class About : public QDialog
        Q_OBJECT
 
 public:
-       explicit About(QWidget *parent = 0);
+       explicit About(std::shared_ptr<sigrok::Context> context, QWidget *parent = 0);
        ~About();
 
 private:
index 1156d6f5c87b2e79993f6cea7426e8411adc51e4..19dfde8d1a3f227065e39cd1499b2300212f3d8a 100644 (file)
 
 #include <cassert>
 
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
 #include "connect.h"
 
 #include "pv/devicemanager.h"
-#include "pv/device/device.h"
-
-extern "C" {
-/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */
-#define __STDC_FORMAT_MACROS
-#include <glib.h>
-#include <libsigrok/libsigrok.h>
-}
 
 using std::list;
+using std::map;
 using std::shared_ptr;
 using std::string;
 
-extern sr_context *sr_ctx;
+using Glib::ustring;
+using Glib::Variant;
+using Glib::VariantBase;
+
+using sigrok::ConfigKey;
+using sigrok::Driver;
+using sigrok::Error;
+using sigrok::HardwareDevice;
 
 namespace pv {
 namespace dialogs {
@@ -82,30 +82,20 @@ Connect::Connect(QWidget *parent, pv::DeviceManager &device_manager) :
        _layout.addWidget(&_button_box);
 }
 
-shared_ptr<device::Device> Connect::get_selected_device() const
+shared_ptr<HardwareDevice> Connect::get_selected_device() const
 {
        const QListWidgetItem *const item = _device_list.currentItem();
        if (!item)
-               return shared_ptr<device::Device>();
-
-       const sr_dev_inst *const sdi = (sr_dev_inst*)item->data(
-               Qt::UserRole).value<void*>();
-       assert(sdi);
-
-       const auto iter = _device_map.find(sdi);
-       assert(iter != _device_map.end());
+               return shared_ptr<HardwareDevice>();
 
-       return (*iter).second;
+       return item->data(Qt::UserRole).value<shared_ptr<HardwareDevice>>();
 }
 
 void Connect::populate_drivers()
 {
-       gsize num_opts = 0;
-       const int32_t *hwopts;
-       struct sr_dev_driver **drivers = sr_driver_list();
-       GVariant *gvar_opts;
-
-       for (int i = 0; drivers[i]; ++i) {
+       for (auto entry : _device_manager.context()->drivers()) {
+               auto name = entry.first;
+               auto driver = entry.second;
                /**
                 * We currently only support devices that can deliver
                 * samples at a fixed samplerate i.e. oscilloscopes and
@@ -113,29 +103,19 @@ void Connect::populate_drivers()
                 * @todo Add support for non-monotonic devices i.e. DMMs
                 * and sensors.
                 */
-               bool supported_device = false;
-               if ((sr_config_list(drivers[i], NULL, NULL,
-                               SR_CONF_DEVICE_OPTIONS, &gvar_opts) == SR_OK)) {
-                       hwopts = (const int32_t *)g_variant_get_fixed_array(gvar_opts,
-                                       &num_opts, sizeof(int32_t));
-                       for (unsigned int j = 0; j < num_opts; j++)
-                               if ((hwopts[j] & SR_CONF_MASK) == SR_CONF_SAMPLERATE) {
-                                       supported_device = true;
-                                       break;
-                               }
-               }
+               bool supported_device = driver->config_check(
+                       ConfigKey::SAMPLERATE, ConfigKey::DEVICE_OPTIONS);
 
                if (supported_device)
                        _drivers.addItem(QString("%1 (%2)").arg(
-                               drivers[i]->longname).arg(drivers[i]->name),
-                               qVariantFromValue((void*)drivers[i]));
+                               driver->long_name().c_str()).arg(name.c_str()),
+                               qVariantFromValue(driver));
        }
 }
 
 void Connect::unset_connection()
 {
        _device_list.clear();
-       _device_map.clear();
        _serial_device.hide();
        _form_layout.labelForField(&_serial_device)->hide();
        _button_box.button(QDialogButtonBox::Ok)->setDisabled(true);
@@ -150,49 +130,37 @@ void Connect::set_serial_connection()
 void Connect::scan_pressed()
 {
        _device_list.clear();
-       _device_map.clear();
 
        const int index = _drivers.currentIndex();
        if (index == -1)
                return;
 
-       sr_dev_driver *const driver = (sr_dev_driver*)_drivers.itemData(
-               index).value<void*>();
+       shared_ptr<Driver> driver =
+               _drivers.itemData(index).value<shared_ptr<Driver>>();
 
-       GSList *drvopts = NULL;
+       assert(driver);
 
-       if (_serial_device.isVisible()) {
-               sr_config *const src = (sr_config*)g_try_malloc(sizeof(sr_config));
-               src->key = SR_CONF_CONN;
-               const QByteArray byteArray = _serial_device.text().toUtf8();
-               src->data = g_variant_new_string((const gchar*)byteArray.constData());
-               drvopts = g_slist_append(drvopts, src);
-       }
+       map<const ConfigKey *, VariantBase> drvopts;
 
-       const list< shared_ptr<device::Device> > devices =
-               _device_manager.driver_scan(driver, drvopts);
+       if (_serial_device.isVisible())
+               drvopts[ConfigKey::CONN] = Variant<ustring>::create(
+                       _serial_device.text().toUtf8().constData());
 
-       g_slist_free_full(drvopts, (GDestroyNotify)free_drvopts);
+       list< shared_ptr<HardwareDevice> > devices =
+               _device_manager.driver_scan(driver, drvopts);
 
-       for (shared_ptr<device::Device> dev_inst : devices)
+       for (shared_ptr<HardwareDevice> device : devices)
        {
-               assert(dev_inst);
-               const sr_dev_inst *const sdi = dev_inst->dev_inst();
-               assert(sdi);
+               assert(device);
 
-               const string title = dev_inst->format_device_title();
-               QString text = QString::fromUtf8(title.c_str());
-
-               if (sdi->channels) {
-                       text += QString(" with %1 channels").arg(
-                               g_slist_length(sdi->channels));
-               }
+               QString text = QString::fromStdString(
+                       _device_manager.device_description(device));
+               text += QString(" with %1 channels").arg(device->channels().size());
 
                QListWidgetItem *const item = new QListWidgetItem(text,
                        &_device_list);
-               item->setData(Qt::UserRole, qVariantFromValue((void*)sdi));
+               item->setData(Qt::UserRole, qVariantFromValue(device));
                _device_list.addItem(item);
-               _device_map[sdi] = dev_inst;
        }
 
        _device_list.setCurrentRow(0);
@@ -201,39 +169,13 @@ void Connect::scan_pressed()
 
 void Connect::device_selected(int index)
 {
-       gsize num_opts = 0;
-       const int32_t *hwopts;
-       GVariant *gvar_list;
-       sr_dev_driver *const driver = (sr_dev_driver*)_drivers.itemData(
-               index).value<void*>();
+       shared_ptr<Driver> driver =
+               _drivers.itemData(index).value<shared_ptr<Driver>>();
 
        unset_connection();
 
-       if ((sr_config_list(driver, NULL, NULL,
-                               SR_CONF_SCAN_OPTIONS, &gvar_list) == SR_OK)) {
-               hwopts = (const int32_t *)g_variant_get_fixed_array(gvar_list,
-                               &num_opts, sizeof(int32_t));
-
-               for (unsigned int i = 0; i < num_opts; i++) {
-                       switch(hwopts[i]) {
-                       case SR_CONF_SERIALCOMM:
-                               set_serial_connection();
-                               break;
-
-                       default:
-                               continue;
-                       }
-
-                       break;
-               }
-               g_variant_unref(gvar_list);
-       }
-}
-
-void Connect::free_drvopts(struct sr_config *src)
-{
-       g_variant_unref(src->data);
-       g_free(src);
+       if (driver->config_check(ConfigKey::SERIALCOMM, ConfigKey::SCAN_OPTIONS))
+                       set_serial_connection();
 }
 
 } // namespace dialogs
index e1a2c30d6c68422fbc37858c2be491702860e42d..fbac9e3ecf23f51f8c71267b269a2011a43f9e91 100644 (file)
 #include <QPushButton>
 #include <QVBoxLayout>
 
-struct sr_config;
-struct sr_dev_inst;
+namespace sigrok {
+       class Driver;
+       class HardwareDevice;
+}
+
+Q_DECLARE_METATYPE(std::shared_ptr<sigrok::Driver>);
+Q_DECLARE_METATYPE(std::shared_ptr<sigrok::HardwareDevice>);
 
 namespace pv {
 
 class DeviceManager;
 
-namespace device {
-class Device;
-}
-
 namespace dialogs {
 
 class Connect : public QDialog
@@ -52,7 +53,7 @@ class Connect : public QDialog
 public:
        Connect(QWidget *parent, pv::DeviceManager &device_manager);
 
-       std::shared_ptr<device::Device> get_selected_device() const;
+       std::shared_ptr<sigrok::HardwareDevice> get_selected_device() const;
 
 private:
        void populate_drivers();
@@ -66,9 +67,6 @@ private Q_SLOTS:
 
        void scan_pressed();
 
-private:
-       static void free_drvopts(sr_config *src);
-
 private:
        pv::DeviceManager &_device_manager;
 
@@ -83,8 +81,6 @@ private:
 
        QPushButton _scan_button;
        QListWidget _device_list;
-       std::map<const sr_dev_inst*, std::shared_ptr<pv::device::Device> >
-               _device_map;
 
        QDialogButtonBox _button_box;
 };
index d4c5f1f79ed27111c17bcbe9bee6a97902d4a7e8..598976eb77298b83d4aa9b123259722c82964e85 100644 (file)
@@ -43,7 +43,6 @@
 #include "mainwindow.h"
 
 #include "devicemanager.h"
-#include "device/device.h"
 #include "dialogs/about.h"
 #include "dialogs/connect.h"
 #include "dialogs/storeprogress.h"
 #include "widgets/decodermenu.h"
 #endif
 
-/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */
-#define __STDC_FORMAT_MACROS
 #include <inttypes.h>
 #include <stdint.h>
 #include <stdarg.h>
 #include <glib.h>
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
 using std::list;
 using std::map;
 using std::shared_ptr;
 using std::string;
 
+using sigrok::Device;
+using sigrok::Error;
+using sigrok::HardwareDevice;
+
 namespace pv {
 
 namespace view {
@@ -290,7 +291,8 @@ void MainWindow::save_ui_settings()
                key_list.push_back("serial_num");
                key_list.push_back("connection_id");
 
-               dev_info = _session.get_device()->get_device_info();
+               dev_info = _device_manager.get_device_info(
+                       _session.get_device());
 
                for (string key : key_list) {
 
@@ -309,7 +311,7 @@ void MainWindow::restore_ui_settings()
 {
        QSettings settings;
 
-       shared_ptr<pv::device::DevInst> device;
+       shared_ptr<HardwareDevice> device;
 
        map<string, string> dev_info;
        list<string> key_list;
@@ -365,8 +367,8 @@ void MainWindow::update_device_list()
 {
        assert(_sampling_bar);
 
-       shared_ptr<pv::device::DevInst> selected_device = _session.get_device();
-       list< shared_ptr<device::DevInst> > devices;
+       shared_ptr<Device> selected_device = _session.get_device();
+       list< shared_ptr<Device> > devices;
 
        if (_device_manager.devices().size() == 0)
                return;
@@ -379,7 +381,12 @@ void MainWindow::update_device_list()
                devices.push_back(selected_device);
        assert(selected_device);
 
-       _sampling_bar->set_device_list(devices, selected_device);
+       map<shared_ptr<Device>, string> device_names;
+
+       for (auto device : devices)
+               device_names[device] = _device_manager.device_description(device);
+
+       _sampling_bar->set_device_list(device_names, selected_device);
 }
 
 void MainWindow::closeEvent(QCloseEvent *event)
@@ -396,8 +403,8 @@ void MainWindow::load_file(QString file_name)
 
        try {
                _session.set_file(file_name.toStdString());
-       } catch(QString e) {
-               show_session_error(tr("Failed to load ") + file_name, e);
+       } catch(Error e) {
+               show_session_error(tr("Failed to load ") + file_name, e.what());
                _session.set_default_device();
                update_device_list();
                return;
@@ -516,7 +523,7 @@ void MainWindow::on_actionViewShowCursors_triggered()
 
 void MainWindow::on_actionAbout_triggered()
 {
-       dialogs::About dlg(this);
+       dialogs::About dlg(_device_manager.context(), this);
        dlg.exec();
 }
 
index 1b2135df1f8d47d53ee75a9fd9b1dff1dc49e935..b9fc3e0e3dc77b8c488b5269ac568a3fd9d21e12 100644 (file)
@@ -36,10 +36,6 @@ namespace pv {
 
 class DeviceManager;
 
-namespace device {
-class DevInst;
-}
-
 namespace toolbars {
 class ContextBar;
 class SamplingBar;
index 1e4bc5789dca0188291bb8639572059dec6df779..5a854453c3eebf1d78e27c5b7a205b45fe4e8656 100644 (file)
 
 #include "channels.h"
 
-#include <pv/device/devinst.h>
 #include <pv/prop/binding/deviceoptions.h>
 #include <pv/sigsession.h>
 #include <pv/view/signal.h>
 
+#include <libsigrok/libsigrok.hpp>
+
 using namespace Qt;
 
 using std::map;
@@ -39,6 +40,10 @@ using std::set;
 using std::shared_ptr;
 using std::vector;
 
+using sigrok::Channel;
+using sigrok::ChannelGroup;
+using sigrok::Device;
+
 using pv::view::Signal;
 
 namespace pv {
@@ -55,33 +60,25 @@ Channels::Channels(SigSession &session, QWidget *parent) :
        // Create the layout
        setLayout(&_layout);
 
-       shared_ptr<device::DevInst> dev_inst = _session.get_device();
-       assert(dev_inst);
-       const sr_dev_inst *const sdi = dev_inst->dev_inst();
-       assert(sdi);
+       shared_ptr<sigrok::Device> device = _session.get_device();
+       assert(device);
 
        // Collect a set of signals
-       map<const sr_channel*, shared_ptr<Signal> > signal_map;
+       map<shared_ptr<Channel>, shared_ptr<Signal> > signal_map;
        const vector< shared_ptr<Signal> > sigs = _session.get_signals();
 
        for (const shared_ptr<Signal> &sig : sigs)
                signal_map[sig->channel()] = sig;
 
        // Populate channel groups
-       for (const GSList *g = sdi->channel_groups; g; g = g->next)
+       for (auto entry : device->channel_groups())
        {
-               const sr_channel_group *const group =
-                       (const sr_channel_group*)g->data;
-               assert(group);
-
-               // Make a set of signals and remove these signals from the
+               shared_ptr<ChannelGroup> group = entry.second;
+               // Make a set of signals, and removed this signals from the
                // signal map.
                vector< shared_ptr<Signal> > group_sigs;
-               for (const GSList *p = group->channels; p; p = p->next)
+               for (auto channel : group->channels())
                {
-                       const sr_channel *const channel = (const sr_channel*)p->data;
-                       assert(channel);
-
                        const auto iter = signal_map.find(channel);
 
                        if (iter == signal_map.end())
@@ -96,12 +93,9 @@ Channels::Channels(SigSession &session, QWidget *parent) :
 
        // Make a vector of the remaining channels
        vector< shared_ptr<Signal> > global_sigs;
-       for (const GSList *p = sdi->channels; p; p = p->next)
+       for (auto channel : device->channels())
        {
-               const sr_channel *const channel = (const sr_channel*)p->data;
-               assert(channel);
-
-               const map<const sr_channel*, shared_ptr<Signal> >::
+               const map<shared_ptr<Channel>, shared_ptr<Signal> >::
                        const_iterator iter = signal_map.find(channel);
                if (iter != signal_map.end())
                        global_sigs.push_back((*iter).second);
@@ -148,7 +142,7 @@ void Channels::set_all_channels(bool set)
        _updating_channels = false;
 }
 
-void Channels::populate_group(const sr_channel_group *group,
+void Channels::populate_group(shared_ptr<ChannelGroup> group,
        const vector< shared_ptr<pv::view::Signal> > sigs)
 {
        using pv::prop::binding::DeviceOptions;
@@ -158,14 +152,13 @@ void Channels::populate_group(const sr_channel_group *group,
        // popup.
        shared_ptr<DeviceOptions> binding;
        if (group)
-               binding = shared_ptr<DeviceOptions>(new DeviceOptions(
-                       _session.get_device(), group));
+               binding = shared_ptr<DeviceOptions>(new DeviceOptions(group));
 
        // Create a title if the group is going to have any content
        if ((!sigs.empty() || (binding && !binding->properties().empty())) &&
-               group && group->name)
+               group)
                _layout.addRow(new QLabel(
-                       QString("<h3>%1</h3>").arg(group->name)));
+                       QString("<h3>%1</h3>").arg(group->name().c_str())));
 
        // Create the channel group grid
        QGridLayout *const channel_grid =
index 3cd9eef95b939525a4041ecff82c3bbf2d7d265c..97475a57579f6f293df49d312f19c975199bf78b 100644 (file)
 
 #include <pv/widgets/popup.h>
 
-struct sr_channel_group;
-
 class QCheckBox;
 class QGridLayout;
 
+namespace sigrok {
+       class ChannelGroup;
+}
+
 namespace pv {
 
 class SigSession;
@@ -63,7 +65,7 @@ public:
 private:
        void set_all_channels(bool set);
 
-       void populate_group(const sr_channel_group *group,
+       void populate_group(std::shared_ptr<sigrok::ChannelGroup> group,
                const std::vector< std::shared_ptr<pv::view::Signal> > sigs);
 
        QGridLayout* create_channel_group_grid(
index eaa036c2e237c4a38b20460709e3ef0c2664e447..3d069f799e1f40f9a6066148804c9e73f687109c 100644 (file)
 
 #include <pv/prop/property.h>
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::shared_ptr;
 
+using sigrok::Device;
+
 namespace pv {
 namespace popups {
 
-DeviceOptions::DeviceOptions(shared_ptr<device::DevInst> dev_inst,
-       QWidget *parent) :
+DeviceOptions::DeviceOptions(shared_ptr<Device> device, QWidget *parent) :
        Popup(parent),
-       _dev_inst(dev_inst),
+       _device(device),
        _layout(this),
-       _binding(dev_inst)
+       _binding(device)
 {
        setLayout(&_layout);
 
index deedf587854c5af7570643c1892af4d93a65bf80..6d260a4d6bb2ef5430db4dcb18f606d9942c39b3 100644 (file)
 #include <pv/prop/binding/deviceoptions.h>
 #include <pv/widgets/popup.h>
 
+namespace sigrok {
+       class Device;
+}
+
 namespace pv {
 namespace popups {
 
@@ -35,13 +39,13 @@ class DeviceOptions : public pv::widgets::Popup
        Q_OBJECT
 
 public:
-       DeviceOptions(std::shared_ptr<device::DevInst> dev_inst,
+       DeviceOptions(std::shared_ptr<sigrok::Device> device,
                QWidget *parent);
 
        pv::prop::binding::DeviceOptions& binding();
 
 private:
-       std::shared_ptr<device::DevInst> _dev_inst;
+       std::shared_ptr<sigrok::Device> _device;
 
        QVBoxLayout _layout;
 
index 6432d2935f71deb62120ed75babbfab1507a63ca..86318139673a72bb71d6f89010361519c7284a5c 100644 (file)
@@ -73,18 +73,18 @@ QWidget* Binding::get_property_form(QWidget *parent,
        return form;
 }
 
-QString Binding::print_gvariant(GVariant *const gvar)
+QString Binding::print_gvariant(Glib::VariantBase gvar)
 {
        QString s;
 
-       if (g_variant_is_of_type(gvar, G_VARIANT_TYPE("s")))
-               s = QString::fromUtf8(g_variant_get_string(gvar, NULL));
+       if (!gvar.gobj())
+               s = QString::fromStdString("(null)");
+       else if (gvar.is_of_type(Glib::VariantType("s")))
+               s = QString::fromStdString(
+                       Glib::VariantBase::cast_dynamic<Glib::Variant<std::string>>(
+                               gvar).get());
        else
-       {
-               gchar *const text = g_variant_print(gvar, FALSE);
-               s = QString::fromUtf8(text);
-               g_free(text);
-       }
+               s = QString::fromStdString(gvar.print());
 
        return s;
 }
index cce8ebf8a15cfe86d174aa5641fa9d514880bcea..9d52731d778556835239af38acffa7c8a17ed3ca 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef PULSEVIEW_PV_PROP_BINDING_BINDING_H
 #define PULSEVIEW_PV_PROP_BINDING_BINDING_H
 
-#include <glib.h>
+#include <glibmm-2.4/glibmm.h>
 
 #include <vector>
 #include <memory>
@@ -51,7 +51,7 @@ public:
        QWidget* get_property_form(QWidget *parent,
                bool auto_commit = false) const;
 
-       static QString print_gvariant(GVariant *const gvar);
+       static QString print_gvariant(Glib::VariantBase gvar);
 
 protected:
        std::vector< std::shared_ptr<Property> > _properties;
index c5278c75fbb82583ba7082e4d4dc04ef4bf502f6..a01d722f431f2a47feb2e258f73f48e25baa4ee2 100644 (file)
@@ -63,7 +63,7 @@ DecoderOptions::DecoderOptions(
 
                const Property::Getter get = [&, opt]() {
                        return getter(opt->id); };
-               const Property::Setter set = [&, opt](GVariant *value) {
+               const Property::Setter set = [&, opt](Glib::VariantBase value) {
                        setter(opt->id, value); };
 
                shared_ptr<Property> prop;
@@ -90,17 +90,16 @@ shared_ptr<Property> DecoderOptions::bind_enum(
        const QString &name, const srd_decoder_option *option,
        Property::Getter getter, Property::Setter setter)
 {
-       vector< pair<GVariant*, QString> > values;
+       vector< pair<Glib::VariantBase, QString> > values;
        for (GSList *l = option->values; l; l = l->next) {
-               GVariant *const var = (GVariant*)l->data;
-               assert(var);
+               Glib::VariantBase var = Glib::VariantBase((GVariant*)l->data, true);
                values.push_back(make_pair(var, print_gvariant(var)));
        }
 
        return shared_ptr<Property>(new Enum(name, values, getter, setter));
 }
 
-GVariant* DecoderOptions::getter(const char *id)
+Glib::VariantBase DecoderOptions::getter(const char *id)
 {
        GVariant *val = NULL;
 
@@ -129,15 +128,15 @@ GVariant* DecoderOptions::getter(const char *id)
        }
 
        if (val)
-               g_variant_ref(val);
-
-       return val;
+               return Glib::VariantBase(val, true);
+       else
+               return Glib::VariantBase();
 }
 
-void DecoderOptions::setter(const char *id, GVariant *value)
+void DecoderOptions::setter(const char *id, Glib::VariantBase value)
 {
        assert(_decoder);
-       _decoder->set_option(id, value);
+       _decoder->set_option(id, value.gobj());
 
        assert(_decoder_stack);
        _decoder_stack->begin_decode();
index a0b8dc4d3880b04495edcb2e8d6726cd17ba095b..a95bc33f3748b854220febdfd1ccdf10bbc60c59 100644 (file)
@@ -50,9 +50,9 @@ private:
                const srd_decoder_option *option,
                Property::Getter getter, Property::Setter setter);
 
-       GVariant* getter(const char *id);
+       Glib::VariantBase getter(const char *id);
 
-       void setter(const char *id, GVariant *value);
+       void setter(const char *id, Glib::VariantBase value);
 
 private:
        std::shared_ptr<pv::data::DecoderStack> _decoder_stack;
index c8da5a05f47b392d7d7577dfaf41da3b785d2239..0023eb2ea748bb608441e1835548d58deff0947a 100644 (file)
 
 #include "deviceoptions.h"
 
-#include <pv/device/devinst.h>
 #include <pv/prop/bool.h>
 #include <pv/prop/double.h>
 #include <pv/prop/enum.h>
 #include <pv/prop/int.h>
 
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
 using boost::optional;
 using std::function;
@@ -40,44 +39,50 @@ using std::shared_ptr;
 using std::string;
 using std::vector;
 
+using sigrok::Capability;
+using sigrok::Configurable;
+using sigrok::ConfigKey;
+using sigrok::Error;
+
 namespace pv {
 namespace prop {
 namespace binding {
 
-DeviceOptions::DeviceOptions(shared_ptr<pv::device::DevInst> dev_inst,
-       const sr_channel_group *group) :
-       _dev_inst(dev_inst),
-       _group(group)
+DeviceOptions::DeviceOptions(shared_ptr<sigrok::Configurable> configurable) :
+       _configurable(configurable)
 {
-       assert(dev_inst);
-
-       GVariant *gvar_opts;
-       gsize num_opts;
+       assert(configurable);
 
-       if (!(gvar_opts = dev_inst->list_config(group, SR_CONF_DEVICE_OPTIONS)))
-               /* Driver supports no device instance options. */
-               return;
+       for (auto entry : configurable->config_keys(ConfigKey::DEVICE_OPTIONS)) {
+               auto key = entry.first;
+               auto capabilities = entry.second;
 
-       const int *const options = (const int32_t *)g_variant_get_fixed_array(
-               gvar_opts, &num_opts, sizeof(int32_t));
-       for (unsigned int i = 0; i < num_opts; i++) {
-               const struct sr_config_info *const info =
-                       sr_config_info_get(options[i] & SR_CONF_MASK);
+               Glib::VariantContainerBase gvar_list;
 
-               if (!info)
+               if (!capabilities.count(Capability::GET) ||
+                       !capabilities.count(Capability::SET))
                        continue;
 
-               const int key = info->key;
-               GVariant *const gvar_list = dev_inst->list_config(group, key);
+               if (capabilities.count(Capability::LIST))
+                       gvar_list = configurable->config_list(key);
 
-               const QString name = QString::fromUtf8(info->name);
+               string name_str;
+               try {
+                       name_str = key->description();
+               } catch (Error e) {
+                       name_str = key->name();
+               }
+
+               const QString name = QString::fromStdString(name_str);
 
                const Property::Getter get = [&, key]() {
-                       return _dev_inst->get_config(_group, key); };
-               const Property::Setter set = [&, key](GVariant *value) {
-                       _dev_inst->set_config(_group, key, value); };
+                       return _configurable->config_get(key); };
+               const Property::Setter set = [&, key](Glib::VariantBase value) {
+                       _configurable->config_set(key, value);
+                       config_changed();
+               };
 
-               switch(key)
+               switch (key->id())
                {
                case SR_CONF_SAMPLERATE:
                        // Sample rate values are not bound because they are shown
@@ -96,7 +101,7 @@ DeviceOptions::DeviceOptions(shared_ptr<pv::device::DevInst> dev_inst,
                case SR_CONF_FILTER:
                case SR_CONF_COUPLING:
                case SR_CONF_CLOCK_EDGE:
-                       bind_enum(name, key, gvar_list, get, set);
+                       bind_enum(name, gvar_list, get, set);
                        break;
 
                case SR_CONF_EXTERNAL_CLOCK:
@@ -105,51 +110,42 @@ DeviceOptions::DeviceOptions(shared_ptr<pv::device::DevInst> dev_inst,
                        break;
 
                case SR_CONF_TIMEBASE:
-                       bind_enum(name, key, gvar_list,
-                               get, set, print_timebase);
+                       bind_enum(name, gvar_list, get, set, print_timebase);
                        break;
 
                case SR_CONF_VDIV:
-                       bind_enum(name, key, gvar_list, get, set, print_vdiv);
+                       bind_enum(name, gvar_list, get, set, print_vdiv);
                        break;
 
                case SR_CONF_VOLTAGE_THRESHOLD:
-                       bind_enum(name, key, gvar_list,
-                               get, set, print_voltage_threshold);
+                       bind_enum(name, gvar_list, get, set, print_voltage_threshold);
                        break;
-               }
 
-               if (gvar_list)
-                       g_variant_unref(gvar_list);
+               default:
+                       break;
+               }
        }
-       g_variant_unref(gvar_opts);
 }
 
 void DeviceOptions::bind_bool(const QString &name,
        Property::Getter getter, Property::Setter setter)
 {
-       assert(_dev_inst);
+       assert(_configurable);
        _properties.push_back(shared_ptr<Property>(new Bool(
                name, getter, setter)));
 }
 
-void DeviceOptions::bind_enum(const QString &name, int key,
-       GVariant *const gvar_list, Property::Getter getter,
-       Property::Setter setter, function<QString (GVariant*)> printer)
+void DeviceOptions::bind_enum(const QString &name,
+       Glib::VariantContainerBase gvar_list, Property::Getter getter,
+       Property::Setter setter, function<QString (Glib::VariantBase)> printer)
 {
-       GVariant *gvar;
-       GVariantIter iter;
-       vector< pair<GVariant*, QString> > values;
-
-       assert(_dev_inst);
-       if (!gvar_list) {
-               qDebug() << "Config key " << key << " was listed, but no "
-                       "options were given";
-               return;
-       }
+       Glib::VariantBase gvar;
+       vector< pair<Glib::VariantBase, QString> > values;
+
+       assert(_configurable);
 
-       g_variant_iter_init (&iter, gvar_list);
-       while ((gvar = g_variant_iter_next_value (&iter)))
+       Glib::VariantIter iter(gvar_list);
+       while ((iter.next_value(gvar)))
                values.push_back(make_pair(gvar, printer(gvar)));
 
        _properties.push_back(shared_ptr<Property>(new Enum(name, values,
@@ -160,30 +156,30 @@ void DeviceOptions::bind_int(const QString &name, QString suffix,
        optional< std::pair<int64_t, int64_t> > range,
        Property::Getter getter, Property::Setter setter)
 {
-       assert(_dev_inst);
+       assert(_configurable);
 
        _properties.push_back(shared_ptr<Property>(new Int(name, suffix, range,
                getter, setter)));
 }
 
-QString DeviceOptions::print_timebase(GVariant *const gvar)
+QString DeviceOptions::print_timebase(Glib::VariantBase gvar)
 {
        uint64_t p, q;
-       g_variant_get(gvar, "(tt)", &p, &q);
+       g_variant_get(gvar.gobj(), "(tt)", &p, &q);
        return QString::fromUtf8(sr_period_string(p * q));
 }
 
-QString DeviceOptions::print_vdiv(GVariant *const gvar)
+QString DeviceOptions::print_vdiv(Glib::VariantBase gvar)
 {
        uint64_t p, q;
-       g_variant_get(gvar, "(tt)", &p, &q);
+       g_variant_get(gvar.gobj(), "(tt)", &p, &q);
        return QString::fromUtf8(sr_voltage_string(p, q));
 }
 
-QString DeviceOptions::print_voltage_threshold(GVariant *const gvar)
+QString DeviceOptions::print_voltage_threshold(Glib::VariantBase gvar)
 {
        gdouble lo, hi;
-       g_variant_get(gvar, "(dd)", &lo, &hi);
+       g_variant_get(gvar.gobj(), "(dd)", &lo, &hi);
        return QString("L<%1V H>%2V").arg(lo, 0, 'f', 1).arg(hi, 0, 'f', 1);
 }
 
index a1efd06a3fbc0bed6e42aec944f3315d1b7e3c49..a7fffa30ed47e937c2e135bf382eee03ae02999c 100644 (file)
 
 #include <boost/optional.hpp>
 
+#include <QObject>
 #include <QString>
 
-#include <glib.h>
-
 #include "binding.h"
 
 #include <pv/prop/property.h>
 
-struct sr_dev_inst;
-struct sr_channel_group;
+namespace sigrok {
+       class Configurable;
+}
 
 namespace pv {
 
-namespace device {
-class DevInst;
-}
-
 namespace prop {
 namespace binding {
 
-class DeviceOptions : public Binding
+class DeviceOptions : public QObject, public Binding
 {
+       Q_OBJECT
+
 public:
-       DeviceOptions(std::shared_ptr<pv::device::DevInst> dev_inst,
-               const sr_channel_group *group = NULL);
+       DeviceOptions(std::shared_ptr<sigrok::Configurable> configurable);
+
+Q_SIGNALS:
+       void config_changed();
 
 private:
        void bind_bool(const QString &name,
                Property::Getter getter, Property::Setter setter);
-       void bind_enum(const QString &name, int key,
-               GVariant *const gvar_list,
+       void bind_enum(const QString &name, Glib::VariantContainerBase gvar_list,
                Property::Getter getter, Property::Setter setter,
-               std::function<QString (GVariant*)> printer = print_gvariant);
+               std::function<QString (Glib::VariantBase)> printer = print_gvariant);
        void bind_int(const QString &name, QString suffix,
                boost::optional< std::pair<int64_t, int64_t> > range,
                Property::Getter getter, Property::Setter setter);
 
-       static QString print_timebase(GVariant *const gvar);
-       static QString print_vdiv(GVariant *const gvar);
-       static QString print_voltage_threshold(GVariant *const gvar);
+       static QString print_timebase(Glib::VariantBase gvar);
+       static QString print_vdiv(Glib::VariantBase gvar);
+       static QString print_voltage_threshold(Glib::VariantBase gvar);
 
 protected:
-       std::shared_ptr<device::DevInst> _dev_inst;
-       const sr_channel_group *const _group;
+       std::shared_ptr<sigrok::Configurable> _configurable;
 };
 
 } // binding
index e0e052fc6b2b377c3d580192beda10793d331884..699656f75d3ab60adbd81006d0c4c692886161db 100644 (file)
@@ -42,14 +42,18 @@ QWidget* Bool::get_widget(QWidget *parent, bool auto_commit)
        if (_check_box)
                return _check_box;
 
-       GVariant *const value = _getter ? _getter() : NULL;
-       if (!value)
+       if (!_getter)
                return NULL;
 
+       Glib::VariantBase variant = _getter();
+       if (!variant.gobj())
+               return NULL;
+
+       bool value = Glib::VariantBase::cast_dynamic<Glib::Variant<bool>>(
+               variant).get();
+
        _check_box = new QCheckBox(name(), parent);
-       _check_box->setCheckState(g_variant_get_boolean(value) ?
-               Qt::Checked : Qt::Unchecked);
-       g_variant_unref(value);
+       _check_box->setCheckState(value ? Qt::Checked : Qt::Unchecked);
 
        if (auto_commit)
                connect(_check_box, SIGNAL(stateChanged(int)),
@@ -70,7 +74,7 @@ void Bool::commit()
        if (!_check_box)
                return;
 
-       _setter(g_variant_new_boolean(
+       _setter(Glib::Variant<bool>::create(
                _check_box->checkState() == Qt::Checked));
 }
 
index 93b45d327362f93b12595a4249e154bcdac0bb14..54540bc68ded41c0575c3202726ac383665b5814 100644 (file)
@@ -55,10 +55,16 @@ QWidget* Double::get_widget(QWidget *parent, bool auto_commit)
        if (_spin_box)
                return _spin_box;
 
-       GVariant *const value = _getter ? _getter() : NULL;
-       if (!value)
+       if (!_getter)
                return NULL;
 
+       Glib::VariantBase variant = _getter();
+       if (!variant.gobj())
+               return NULL;
+
+       double value = Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(
+               variant).get();
+
        _spin_box = new QDoubleSpinBox(parent);
        _spin_box->setDecimals(_decimals);
        _spin_box->setSuffix(_suffix);
@@ -67,8 +73,7 @@ QWidget* Double::get_widget(QWidget *parent, bool auto_commit)
        if (_step)
                _spin_box->setSingleStep(*_step);
 
-       _spin_box->setValue(g_variant_get_double(value));
-       g_variant_unref(value);
+       _spin_box->setValue(value);
 
        if (auto_commit)
                connect(_spin_box, SIGNAL(valueChanged(double)),
@@ -84,7 +89,7 @@ void Double::commit()
        if (!_spin_box)
                return;
 
-       _setter(g_variant_new_double(_spin_box->value()));
+       _setter(Glib::Variant<double>::create(_spin_box->value()));
 }
 
 void Double::on_value_changed(double)
index 6439a725c7adbdca16d90865c622da719fe9ef3b..03524344048d5ca27e4a06b3a7f72f3f17e18fd6 100644 (file)
@@ -31,22 +31,16 @@ namespace pv {
 namespace prop {
 
 Enum::Enum(QString name,
-       vector<pair<GVariant*, QString> > values,
+       vector<pair<Glib::VariantBase, QString> > values,
        Getter getter, Setter setter) :
        Property(name, getter, setter),
        _values(values),
        _selector(NULL)
 {
-       for (vector< pair<GVariant*, QString> >::const_iterator i =
-               _values.begin(); i != _values.end(); i++)
-               g_variant_ref((*i).first);
 }
 
 Enum::~Enum()
 {
-       for (vector< pair<GVariant*, QString> >::const_iterator i =
-               _values.begin(); i != _values.end(); i++)
-               g_variant_unref((*i).first);
 }
 
 QWidget* Enum::get_widget(QWidget *parent, bool auto_commit)
@@ -54,20 +48,21 @@ QWidget* Enum::get_widget(QWidget *parent, bool auto_commit)
        if (_selector)
                return _selector;
 
-       GVariant *const value = _getter ? _getter() : NULL;
-       if (!value)
+       if (!_getter)
+               return NULL;
+
+       Glib::VariantBase variant = _getter();
+       if (!variant.gobj())
                return NULL;
 
        _selector = new QComboBox(parent);
        for (unsigned int i = 0; i < _values.size(); i++) {
-               const pair<GVariant*, QString> &v = _values[i];
-               _selector->addItem(v.second, qVariantFromValue((void*)v.first));
-               if (value && g_variant_equal(v.first, value))
+               const pair<Glib::VariantBase, QString> &v = _values[i];
+               _selector->addItem(v.second, qVariantFromValue(v.first));
+               if (v.first.equal(variant))
                        _selector->setCurrentIndex(i);
        }
 
-       g_variant_unref(value);
-
        if (auto_commit)
                connect(_selector, SIGNAL(currentIndexChanged(int)),
                        this, SLOT(on_current_item_changed(int)));
@@ -86,7 +81,7 @@ void Enum::commit()
        if (index < 0)
                return;
 
-       _setter((GVariant*)_selector->itemData(index).value<void*>());
+       _setter(_selector->itemData(index).value<Glib::VariantBase>());
 }
 
 void Enum::on_current_item_changed(int)
index eff6647afd40974314b8a1218d9182ce98024909..6ff785a3ba430562fffbfacb47d97b5990a0ed04 100644 (file)
 
 #include "property.h"
 
+#include <QMetaType>
+
+Q_DECLARE_METATYPE(Glib::VariantBase);
+
 class QComboBox;
 
 namespace pv {
@@ -36,7 +40,7 @@ class Enum : public Property
        Q_OBJECT;
 
 public:
-       Enum(QString name, std::vector<std::pair<GVariant*, QString> > values,
+       Enum(QString name, std::vector<std::pair<Glib::VariantBase, QString> > values,
                Getter getter, Setter setter);
 
        virtual ~Enum();
@@ -49,7 +53,7 @@ private Q_SLOTS:
        void on_current_item_changed(int);
 
 private:
-       const std::vector< std::pair<GVariant*, QString> > _values;
+       const std::vector< std::pair<Glib::VariantBase, QString> > _values;
 
        QComboBox *_selector;
 };
index 8124f9b0c9a2abc88772f99cac0961b9e72fb20a..45113ac73e6e8954aeb6b05f5b4a2ffce5ca6f23 100644 (file)
@@ -41,15 +41,12 @@ Int::Int(QString name,
        Property(name, getter, setter),
        _suffix(suffix),
        _range(range),
-       _value(NULL),
        _spin_box(NULL)
 {
 }
 
 Int::~Int()
 {
-       if (_value)
-               g_variant_unref(_value);
 }
 
 QWidget* Int::get_widget(QWidget *parent, bool auto_commit)
@@ -59,52 +56,54 @@ QWidget* Int::get_widget(QWidget *parent, bool auto_commit)
        if (_spin_box)
                return _spin_box;
 
-       if (_value)
-               g_variant_unref(_value);
+       if (!_getter)
+               return NULL;
+
+       _value = _getter();
 
-       _value = _getter ? _getter() : NULL;
-       if (!_value)
+       GVariant *value = _value.gobj();
+       if (!value)
                return NULL;
 
        _spin_box = new QSpinBox(parent);
        _spin_box->setSuffix(_suffix);
 
-       const GVariantType *const type = g_variant_get_type(_value);
+       const GVariantType *const type = g_variant_get_type(value);
        assert(type);
 
        if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
        {
-               int_val = g_variant_get_byte(_value);
+               int_val = g_variant_get_byte(value);
                range_min = 0, range_max = UINT8_MAX;
        }
        else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
        {
-               int_val = g_variant_get_int16(_value);
+               int_val = g_variant_get_int16(value);
                range_min = INT16_MIN, range_max = INT16_MAX;
        }
        else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
        {
-               int_val = g_variant_get_uint16(_value);
+               int_val = g_variant_get_uint16(value);
                range_min = 0, range_max = UINT16_MAX;
        }
        else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
        {
-               int_val = g_variant_get_int32(_value);
+               int_val = g_variant_get_int32(value);
                range_min = INT32_MIN, range_max = INT32_MAX;
        }
        else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
        {
-               int_val = g_variant_get_uint32(_value);
+               int_val = g_variant_get_uint32(value);
                range_min = 0, range_max = UINT32_MAX;
        }
        else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
        {
-               int_val = g_variant_get_int64(_value);
+               int_val = g_variant_get_int64(value);
                range_min = INT64_MIN, range_max = INT64_MAX;
        }
        else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
        {
-               int_val = g_variant_get_uint64(_value);
+               int_val = g_variant_get_uint64(value);
                range_min = 0, range_max = UINT64_MAX;
        }
        else
@@ -142,10 +141,8 @@ void Int::commit()
        if (!_spin_box)
                return;
 
-       assert(_value);
-
        GVariant *new_value = NULL;
-       const GVariantType *const type = g_variant_get_type(_value);
+       const GVariantType *const type = g_variant_get_type(_value.gobj());
        assert(type);
 
        if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
@@ -170,11 +167,9 @@ void Int::commit()
 
        assert(new_value);
 
-       g_variant_unref(_value);
-       g_variant_ref(new_value);
-       _value = new_value;
+       _value = Glib::VariantBase(new_value);
 
-       _setter(new_value);
+       _setter(_value);
 }
 
 void Int::on_value_changed(int)
index 1a3180a1a9ab324950a1beafc08bdabb48e59159..1de99d6765cc6394164989303c8ebf3330156d5a 100644 (file)
@@ -54,7 +54,7 @@ private:
        const QString _suffix;
        const boost::optional< std::pair<int64_t, int64_t> > _range;
 
-       GVariant *_value;
+       Glib::VariantBase _value;
        QSpinBox *_spin_box;
 };
 
index b3aa1a690b00c3e29e74140317169bc5b2ac195e..0d1b53160ca2381997ce5aa621b6b8dcd47a30d3 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef PULSEVIEW_PV_PROP_PROPERTY_H
 #define PULSEVIEW_PV_PROP_PROPERTY_H
 
-#include <glib.h>
+#include <glibmm-2.4/glibmm.h>
 
 #include <functional>
 #include <QString>
@@ -37,8 +37,8 @@ class Property : public QObject
        Q_OBJECT;
 
 public:
-       typedef std::function<GVariant* ()> Getter;
-       typedef std::function<void (GVariant*)> Setter;
+       typedef std::function<Glib::VariantBase ()> Getter;
+       typedef std::function<void (Glib::VariantBase)> Setter;
 
 protected:
        Property(QString name, Getter getter, Setter setter);
index 7fcc656958b9fed74d6f91c89f29e2ebe58d429e..511fe6c4352de19356c36604b5d1479e8ab46319 100644 (file)
 
 #include "string.h"
 
+using std::string;
+
+using Glib::ustring;
+
 namespace pv {
 namespace prop {
 
@@ -41,14 +45,18 @@ QWidget* String::get_widget(QWidget *parent, bool auto_commit)
        if (_line_edit)
                return _line_edit;
 
-       GVariant *const value = _getter ? _getter() : NULL;
-       if (!value)
+       if (!_getter)
                return NULL;
 
+       Glib::VariantBase variant = _getter();
+       if (!variant.gobj())
+               return NULL;
+
+       string value = Glib::VariantBase::cast_dynamic<Glib::Variant<ustring>>(
+               variant).get();
+
        _line_edit = new QLineEdit(parent);
-       _line_edit->setText(QString::fromUtf8(
-               g_variant_get_string(value, NULL)));
-       g_variant_unref(value);
+       _line_edit->setText(QString::fromStdString(value));
 
        if (auto_commit)
                connect(_line_edit, SIGNAL(textEdited(const QString&)),
@@ -65,7 +73,7 @@ void String::commit()
                return;
 
        QByteArray ba = _line_edit->text().toLocal8Bit();
-       _setter(g_variant_new_string(ba.data()));
+       _setter(Glib::Variant<ustring>::create(ba.data()));
 }
 
 void String::on_text_edited(const QString&)
index 90854c7dbaf2b9d2cc26f6fc3d82e4b26bf44c61..2e49422fb9a60746246c1d858e66234940674426 100644 (file)
@@ -25,8 +25,6 @@
 #include "sigsession.h"
 
 #include "devicemanager.h"
-#include "device/device.h"
-#include "device/file.h"
 
 #include "data/analog.h"
 #include "data/analogsnapshot.h"
@@ -47,6 +45,8 @@
 
 #include <QDebug>
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::dynamic_pointer_cast;
 using std::function;
 using std::lock_guard;
@@ -58,81 +58,106 @@ using std::shared_ptr;
 using std::string;
 using std::vector;
 
-namespace pv {
+using sigrok::Analog;
+using sigrok::Channel;
+using sigrok::ChannelType;
+using sigrok::ConfigKey;
+using sigrok::DatafeedCallbackFunction;
+using sigrok::Device;
+using sigrok::Error;
+using sigrok::HardwareDevice;
+using sigrok::Header;
+using sigrok::Logic;
+using sigrok::Meta;
+using sigrok::Packet;
+using sigrok::PacketPayload;
+using sigrok::Session;
+using sigrok::SessionDevice;
+
+using Glib::VariantBase;
+using Glib::Variant;
 
-// TODO: This should not be necessary
-SigSession* SigSession::_session = NULL;
+namespace pv {
 
 // TODO: This should not be necessary
-struct sr_session *SigSession::_sr_session = NULL;
+shared_ptr<Session> SigSession::_sr_session = nullptr;
 
 SigSession::SigSession(DeviceManager &device_manager) :
        _device_manager(device_manager),
        _capture_state(Stopped)
 {
        // TODO: This should not be necessary
-       _session = this;
+       _sr_session = device_manager.context()->create_session();
 
        set_default_device();
 }
 
 SigSession::~SigSession()
 {
-       using pv::device::Device;
-
        // Stop and join to the thread
        stop_capture();
-
-       if (_dev_inst)
-               _dev_inst->release();
-
-       // TODO: This should not be necessary
-       _session = NULL;
 }
 
-shared_ptr<device::DevInst> SigSession::get_device() const
+shared_ptr<Device> SigSession::get_device() const
 {
-       return _dev_inst;
+       return _device;
 }
 
-void SigSession::set_device(
-       shared_ptr<device::DevInst> dev_inst) throw(QString)
+void SigSession::set_device(shared_ptr<Device> device)
 {
-       using pv::device::Device;
-
-       if (!dev_inst)
-               return;
-
        // Ensure we are not capturing before setting the device
        stop_capture();
 
-       if (_dev_inst) {
-               sr_session_datafeed_callback_remove_all(_sr_session);
-               _dev_inst->release();
+       // Are we setting a session device?
+       auto session_device = dynamic_pointer_cast<SessionDevice>(device);
+       // Did we have a session device selected previously?
+       auto prev_session_device = dynamic_pointer_cast<SessionDevice>(_device);
+
+       if (_device) {
+               _sr_session->remove_datafeed_callbacks();
+               if (!prev_session_device) {
+                       _device->close();
+                       _sr_session->remove_devices();
+               }
        }
 
-       _dev_inst = dev_inst;
+       if (session_device)
+               _sr_session = session_device->parent();
+
+       _device = device;
        _decode_traces.clear();
 
-       if (dev_inst) {
-               dev_inst->use(this);
-               sr_session_datafeed_callback_add(_sr_session, data_feed_in_proc, NULL);
-               update_signals(dev_inst);
+       if (device) {
+               if (!session_device)
+               {
+                       _sr_session = _device_manager.context()->create_session();
+                       device->open();
+                       _sr_session->add_device(device);
+               }
+               _sr_session->add_datafeed_callback([=]
+                       (shared_ptr<Device> device, shared_ptr<Packet> packet) {
+                               data_feed_in(device, packet);
+                       });
+               update_signals(device);
        }
 }
 
-void SigSession::set_file(const string &name) throw(QString)
+void SigSession::set_file(const string &name)
 {
-       // Deselect the old device, because file type detection in File::create
-       // destroys the old session inside libsigrok.
-       set_device(shared_ptr<device::DevInst>());
-       set_device(shared_ptr<device::DevInst>(device::File::create(name)));
+       _sr_session = _device_manager.context()->load_session(name);
+       _device = _sr_session->devices()[0];
+       _decode_traces.clear();
+       _sr_session->add_datafeed_callback([=]
+               (shared_ptr<Device> device, shared_ptr<Packet> packet) {
+                       data_feed_in(device, packet);
+               });
+       update_signals(_device);
 }
 
 void SigSession::set_default_device()
 {
-       shared_ptr<pv::device::DevInst> default_device;
-       const list< shared_ptr<device::Device> > &devices =
+       shared_ptr<HardwareDevice> default_device;
+       const list< shared_ptr<HardwareDevice> > &devices =
                _device_manager.devices();
 
        if (!devices.empty()) {
@@ -140,24 +165,14 @@ void SigSession::set_default_device()
                default_device = devices.front();
 
                // Try and find the demo device and select that by default
-               for (shared_ptr<pv::device::Device> dev : devices)
-                       if (strcmp(dev->dev_inst()->driver->name,
-                               "demo") == 0) {
+               for (shared_ptr<HardwareDevice> dev : devices)
+                       if (dev->driver()->name().compare("demo") == 0) {
                                default_device = dev;
                                break;
                        }
-       }
-
-       set_device(default_device);
-}
-
-void SigSession::release_device(device::DevInst *dev_inst)
-{
-       (void)dev_inst;
-       assert(_dev_inst.get() == dev_inst);
 
-       assert(_capture_state == Stopped);
-       _dev_inst = shared_ptr<device::DevInst>();
+               set_device(default_device);
+       }
 }
 
 SigSession::capture_state SigSession::get_capture_state() const
@@ -171,37 +186,31 @@ void SigSession::start_capture(function<void (const QString)> error_handler)
        stop_capture();
 
        // Check that a device instance has been selected.
-       if (!_dev_inst) {
+       if (!_device) {
                qDebug() << "No device selected";
                return;
        }
 
-       assert(_dev_inst->dev_inst());
-
        // Check that at least one channel is enabled
-       const GSList *l;
-       for (l = _dev_inst->dev_inst()->channels; l; l = l->next) {
-               sr_channel *const channel = (sr_channel*)l->data;
-               assert(channel);
-               if (channel->enabled)
-                       break;
-       }
+       auto channels = _device->channels();
+       bool enabled = std::any_of(channels.begin(), channels.end(),
+               [](shared_ptr<Channel> channel) { return channel->enabled(); });
 
-       if (!l) {
+       if (!enabled) {
                error_handler(tr("No channels enabled."));
                return;
        }
 
        // Begin the session
        _sampling_thread = std::thread(
-               &SigSession::sample_thread_proc, this, _dev_inst,
+               &SigSession::sample_thread_proc, this, _device,
                        error_handler);
 }
 
 void SigSession::stop_capture()
 {
        if (get_capture_state() != Stopped)
-               sr_session_stop(_sr_session);
+               _sr_session->stop();
 
        // Check that sampling stopped
        if (_sampling_thread.joinable())
@@ -310,32 +319,20 @@ void SigSession::set_capture_state(capture_state state)
                capture_state_changed(state);
 }
 
-void SigSession::update_signals(shared_ptr<device::DevInst> dev_inst)
+void SigSession::update_signals(shared_ptr<Device> device)
 {
-       assert(dev_inst);
+       assert(device);
        assert(_capture_state == Stopped);
 
-       unsigned int logic_channel_count = 0;
-
        // Clear the decode traces
        _decode_traces.clear();
 
        // Detect what data types we will receive
-       if(dev_inst) {
-               assert(dev_inst->dev_inst());
-               for (const GSList *l = dev_inst->dev_inst()->channels;
-                       l; l = l->next) {
-                       const sr_channel *const channel = (const sr_channel *)l->data;
-                       if (!channel->enabled)
-                               continue;
-
-                       switch(channel->type) {
-                       case SR_CHANNEL_LOGIC:
-                               logic_channel_count++;
-                               break;
-                       }
-               }
-       }
+       auto channels = device->channels();
+       unsigned int logic_channel_count = std::count_if(
+               channels.begin(), channels.end(),
+               [] (shared_ptr<Channel> channel) {
+                       return channel->type() == ChannelType::LOGIC; });
 
        // Create data containers for the logic data snapshots
        {
@@ -355,21 +352,13 @@ void SigSession::update_signals(shared_ptr<device::DevInst> dev_inst)
 
                _signals.clear();
 
-               if(!dev_inst)
-                       break;
-
-               assert(dev_inst->dev_inst());
-               for (const GSList *l = dev_inst->dev_inst()->channels;
-                       l; l = l->next) {
+               for (auto channel : device->channels()) {
                        shared_ptr<view::Signal> signal;
-                       sr_channel *const channel = (sr_channel *)l->data;
-                       assert(channel);
 
-                       switch(channel->type) {
+                       switch(channel->type()->id()) {
                        case SR_CHANNEL_LOGIC:
                                signal = shared_ptr<view::Signal>(
-                                       new view::LogicSignal(dev_inst,
-                                               channel, _logic_data));
+                                       new view::LogicSignal(device, channel, _logic_data));
                                break;
 
                        case SR_CHANNEL_ANALOG:
@@ -377,8 +366,7 @@ void SigSession::update_signals(shared_ptr<device::DevInst> dev_inst)
                                shared_ptr<data::Analog> data(
                                        new data::Analog());
                                signal = shared_ptr<view::Signal>(
-                                       new view::AnalogSignal(dev_inst,
-                                               channel, data));
+                                       new view::AnalogSignal(channel, data));
                                break;
                        }
 
@@ -397,7 +385,7 @@ void SigSession::update_signals(shared_ptr<device::DevInst> dev_inst)
 }
 
 shared_ptr<view::Signal> SigSession::signal_from_channel(
-       const sr_channel *channel) const
+       shared_ptr<Channel> channel) const
 {
        lock_guard<mutex> lock(_signals_mutex);
        for (shared_ptr<view::Signal> sig : _signals) {
@@ -408,24 +396,10 @@ shared_ptr<view::Signal> SigSession::signal_from_channel(
        return shared_ptr<view::Signal>();
 }
 
-void SigSession::read_sample_rate(const sr_dev_inst *const sdi)
+void SigSession::read_sample_rate(shared_ptr<Device> device)
 {
-       GVariant *gvar;
-       uint64_t sample_rate = 0;
-
-       // Read out the sample rate
-       if(sdi->driver)
-       {
-               const int ret = sr_config_get(sdi->driver, sdi, NULL,
-                       SR_CONF_SAMPLERATE, &gvar);
-               if (ret != SR_OK) {
-                       qDebug("Failed to get samplerate\n");
-                       return;
-               }
-
-               sample_rate = g_variant_get_uint64(gvar);
-               g_variant_unref(gvar);
-       }
+       uint64_t sample_rate = VariantBase::cast_dynamic<Variant<guint64>>(
+               device->config_get(ConfigKey::SAMPLERATE)).get();
 
        // Set the sample rate of all data
        const set< shared_ptr<data::SignalData> > data_set = get_data();
@@ -435,26 +409,25 @@ void SigSession::read_sample_rate(const sr_dev_inst *const sdi)
        }
 }
 
-void SigSession::sample_thread_proc(shared_ptr<device::DevInst> dev_inst,
+void SigSession::sample_thread_proc(shared_ptr<Device> device,
        function<void (const QString)> error_handler)
 {
-       assert(dev_inst);
-       assert(dev_inst->dev_inst());
+       assert(device);
        assert(error_handler);
 
-       read_sample_rate(dev_inst->dev_inst());
+       read_sample_rate(device);
 
        try {
-               dev_inst->start();
-       } catch(const QString e) {
-               error_handler(e);
+               _sr_session->start();
+       } catch(Error e) {
+               error_handler(e.what());
                return;
        }
 
-       set_capture_state(sr_session_trigger_get(_sr_session) ?
+       set_capture_state(_sr_session->trigger() ?
                AwaitingTrigger : Running);
 
-       dev_inst->run();
+       _sr_session->run();
        set_capture_state(Stopped);
 
        // Confirm that SR_DF_END was received
@@ -465,22 +438,20 @@ void SigSession::sample_thread_proc(shared_ptr<device::DevInst> dev_inst,
        }
 }
 
-void SigSession::feed_in_header(const sr_dev_inst *sdi)
+void SigSession::feed_in_header(shared_ptr<Device> device)
 {
-       read_sample_rate(sdi);
+       read_sample_rate(device);
 }
 
-void SigSession::feed_in_meta(const sr_dev_inst *sdi,
-       const sr_datafeed_meta &meta)
+void SigSession::feed_in_meta(shared_ptr<Device> device,
+       shared_ptr<Meta> meta)
 {
-       (void)sdi;
+       (void)device;
 
-       for (const GSList *l = meta.config; l; l = l->next) {
-               const sr_config *const src = (const sr_config*)l->data;
-               switch (src->key) {
+       for (auto entry : meta->config()) {
+               switch (entry.first->id()) {
                case SR_CONF_SAMPLERATE:
                        /// @todo handle samplerate changes
-                       /// samplerate = (uint64_t *)src->value;
                        break;
                default:
                        // Unknown metadata is not an error.
@@ -497,7 +468,7 @@ void SigSession::feed_in_frame_begin()
                frame_began();
 }
 
-void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
+void SigSession::feed_in_logic(shared_ptr<Logic> logic)
 {
        lock_guard<mutex> lock(_data_mutex);
 
@@ -512,9 +483,18 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
                // This could be the first packet after a trigger
                set_capture_state(Running);
 
+               // Get sample limit.
+               uint64_t sample_limit;
+               try {
+                       sample_limit = VariantBase::cast_dynamic<Variant<guint64>>(
+                               _device->config_get(ConfigKey::LIMIT_SAMPLES)).get();
+               } catch (Error) {
+                       sample_limit = 0;
+               }
+
                // Create a new data snapshot
                _cur_logic_snapshot = shared_ptr<data::LogicSnapshot>(
-                       new data::LogicSnapshot(logic, _dev_inst->get_sample_limit()));
+                       new data::LogicSnapshot(logic, sample_limit));
                _logic_data->push_snapshot(_cur_logic_snapshot);
 
                // @todo Putting this here means that only listeners querying
@@ -532,24 +512,22 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
        data_received();
 }
 
-void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
+void SigSession::feed_in_analog(shared_ptr<Analog> analog)
 {
        lock_guard<mutex> lock(_data_mutex);
 
-       const unsigned int channel_count = g_slist_length(analog.channels);
-       const size_t sample_count = analog.num_samples / channel_count;
-       const float *data = analog.data;
+       const vector<shared_ptr<Channel>> channels = analog->channels();
+       const unsigned int channel_count = channels.size();
+       const size_t sample_count = analog->num_samples() / channel_count;
+       const float *data = analog->data_pointer();
        bool sweep_beginning = false;
 
-       for (GSList *p = analog.channels; p; p = p->next)
+       for (auto channel : channels)
        {
                shared_ptr<data::AnalogSnapshot> snapshot;
 
-               sr_channel *const channel = (sr_channel*)p->data;
-               assert(channel);
-
                // Try to get the snapshot of the channel
-               const map< const sr_channel*, shared_ptr<data::AnalogSnapshot> >::
+               const map< shared_ptr<Channel>, shared_ptr<data::AnalogSnapshot> >::
                        iterator iter = _cur_analog_snapshots.find(channel);
                if (iter != _cur_analog_snapshots.end())
                        snapshot = (*iter).second;
@@ -560,9 +538,18 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
                        // in the sweep containing this snapshot.
                        sweep_beginning = true;
 
+                       // Get sample limit.
+                       uint64_t sample_limit;
+                       try {
+                               sample_limit = VariantBase::cast_dynamic<Variant<guint64>>(
+                                       _device->config_get(ConfigKey::LIMIT_SAMPLES)).get();
+                       } catch (Error) {
+                               sample_limit = 0;
+                       }
+
                        // Create a snapshot, keep it in the maps of channels
                        snapshot = shared_ptr<data::AnalogSnapshot>(
-                               new data::AnalogSnapshot(_dev_inst->get_sample_limit()));
+                               new data::AnalogSnapshot(sample_limit));
                        _cur_analog_snapshots[channel] = snapshot;
 
                        // Find the annalog data associated with the channel
@@ -593,21 +580,18 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
        data_received();
 }
 
-void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
-       const struct sr_datafeed_packet *packet)
+void SigSession::data_feed_in(shared_ptr<Device> device, shared_ptr<Packet> packet)
 {
-       assert(sdi);
+       assert(device);
        assert(packet);
 
-       switch (packet->type) {
+       switch (packet->type()->id()) {
        case SR_DF_HEADER:
-               feed_in_header(sdi);
+               feed_in_header(device);
                break;
 
        case SR_DF_META:
-               assert(packet->payload);
-               feed_in_meta(sdi,
-                       *(const sr_datafeed_meta*)packet->payload);
+               feed_in_meta(device, dynamic_pointer_cast<Meta>(packet->payload()));
                break;
 
        case SR_DF_FRAME_BEGIN:
@@ -615,13 +599,11 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
                break;
 
        case SR_DF_LOGIC:
-               assert(packet->payload);
-               feed_in_logic(*(const sr_datafeed_logic*)packet->payload);
+               feed_in_logic(dynamic_pointer_cast<Logic>(packet->payload()));
                break;
 
        case SR_DF_ANALOG:
-               assert(packet->payload);
-               feed_in_analog(*(const sr_datafeed_analog*)packet->payload);
+               feed_in_analog(dynamic_pointer_cast<Analog>(packet->payload()));
                break;
 
        case SR_DF_END:
@@ -639,12 +621,4 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
        }
 }
 
-void SigSession::data_feed_in_proc(const struct sr_dev_inst *sdi,
-       const struct sr_datafeed_packet *packet, void *cb_data)
-{
-       (void) cb_data;
-       assert(_session);
-       _session->data_feed_in(sdi, packet);
-}
-
 } // namespace pv
index 9359176c784ac5ebbd633741e4d4eb9782dde19b..a624d1d216aaf6e0e280cfde4bf514a61ee118c4 100644 (file)
 #include <QObject>
 #include <QString>
 
-#include <libsigrok/libsigrok.h>
-
 struct srd_decoder;
 struct srd_channel;
 
+namespace sigrok {
+       class Analog;
+       class Channel;
+       class Device;
+       class Logic;
+       class Meta;
+       class Packet;
+       class Session;
+}
+
 namespace pv {
 
 class DeviceManager;
@@ -49,10 +57,6 @@ class LogicSnapshot;
 class SignalData;
 }
 
-namespace device {
-class DevInst;
-}
-
 namespace view {
 class DecodeTrace;
 class LogicSignal;
@@ -75,21 +79,17 @@ public:
 
        ~SigSession();
 
-       std::shared_ptr<device::DevInst> get_device() const;
+       std::shared_ptr<sigrok::Device> get_device() const;
 
        /**
         * Sets device instance that will be used in the next capture session.
         */
-       void set_device(std::shared_ptr<device::DevInst> dev_inst)
-               throw(QString);
+       void set_device(std::shared_ptr<sigrok::Device> device);
 
-       void set_file(const std::string &name)
-               throw(QString);
+       void set_file(const std::string &name);
 
        void set_default_device();
 
-       void release_device(device::DevInst *dev_inst);
-
        capture_state get_capture_state() const;
 
        void start_capture(std::function<void (const QString)> error_handler);
@@ -113,33 +113,30 @@ public:
 private:
        void set_capture_state(capture_state state);
 
-       void update_signals(std::shared_ptr<device::DevInst> dev_inst);
+       void update_signals(std::shared_ptr<sigrok::Device> device);
 
        std::shared_ptr<view::Signal> signal_from_channel(
-               const sr_channel *channel) const;
+               std::shared_ptr<sigrok::Channel> channel) const;
 
-       void read_sample_rate(const sr_dev_inst *const sdi);
+       void read_sample_rate(std::shared_ptr<sigrok::Device>);
 
 private:
-       void sample_thread_proc(std::shared_ptr<device::DevInst> dev_inst,
+       void sample_thread_proc(std::shared_ptr<sigrok::Device> device,
                std::function<void (const QString)> error_handler);
 
-       void feed_in_header(const sr_dev_inst *sdi);
+       void feed_in_header(std::shared_ptr<sigrok::Device> device);
 
-       void feed_in_meta(const sr_dev_inst *sdi,
-               const sr_datafeed_meta &meta);
+       void feed_in_meta(std::shared_ptr<sigrok::Device> device,
+               std::shared_ptr<sigrok::Meta> meta);
 
        void feed_in_frame_begin();
 
-       void feed_in_logic(const sr_datafeed_logic &logic);
-
-       void feed_in_analog(const sr_datafeed_analog &analog);
+       void feed_in_logic(std::shared_ptr<sigrok::Logic> logic);
 
-       void data_feed_in(const struct sr_dev_inst *sdi,
-               const struct sr_datafeed_packet *packet);
+       void feed_in_analog(std::shared_ptr<sigrok::Analog> analog);
 
-       static void data_feed_in_proc(const struct sr_dev_inst *sdi,
-               const struct sr_datafeed_packet *packet, void *cb_data);
+       void data_feed_in(std::shared_ptr<sigrok::Device> device,
+               std::shared_ptr<sigrok::Packet> packet);
 
 private:
        DeviceManager &_device_manager;
@@ -147,7 +144,7 @@ private:
        /**
         * The device instance that will be used in the next capture session.
         */
-       std::shared_ptr<device::DevInst> _dev_inst;
+       std::shared_ptr<sigrok::Device> _device;
 
        std::vector< std::shared_ptr<view::DecodeTrace> > _decode_traces;
 
@@ -160,7 +157,7 @@ private:
        mutable std::mutex _data_mutex;
        std::shared_ptr<data::Logic> _logic_data;
        std::shared_ptr<data::LogicSnapshot> _cur_logic_snapshot;
-       std::map< const sr_channel*, std::shared_ptr<data::AnalogSnapshot> >
+       std::map< std::shared_ptr<sigrok::Channel>, std::shared_ptr<data::AnalogSnapshot> >
                _cur_analog_snapshots;
 
        std::thread _sampling_thread;
@@ -176,21 +173,13 @@ Q_SIGNALS:
 
        void frame_ended();
 
-private:
-       // TODO: This should not be necessary. Multiple concurrent
-       // sessions should should be supported and it should be
-       // possible to associate a pointer with a sr_session.
-       static SigSession *_session;
-
 public:
-       // TODO: Even more of a hack. The libsigrok API now allows for
-       // multiple sessions. However sr_session_* calls are scattered
-       // around the PV architecture and a single SigSession object is
-       // being used across multiple sequential sessions, which are
-       // created and destroyed in other classes in pv::device. This
-       // is a mess. For now just keep a single sr_session pointer here
-       // which we can use for all those scattered calls.
-       static struct sr_session *_sr_session;
+       // Hack. The libsigrok API now allows for multiple sessions. However,
+       // sigrok::Session calls are scattered around the PV architecture and a
+       // single SigSession object is being used across multiple sequential
+       // sessions. This is a mess. For now just keep a single sigrok::Session
+       // pointer here which we can use for all those scattered calls.
+       static std::shared_ptr<sigrok::Session> _sr_session;
 };
 
 } // namespace pv
index 9ad494e2be3e34a2fced82ea34a961f354358483..d5355cba3bbe03c71aeb2bf27a2bc654f72479bb 100644 (file)
@@ -27,6 +27,8 @@
 #include <pv/data/logicsnapshot.h>
 #include <pv/view/signal.h>
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::deque;
 using std::dynamic_pointer_cast;
 using std::lock_guard;
@@ -40,6 +42,8 @@ using std::string;
 using std::thread;
 using std::vector;
 
+using sigrok::Error;
+
 namespace pv {
 
 const size_t StoreSession::BlockSize = 1024 * 1024;
@@ -120,8 +124,9 @@ bool StoreSession::start()
        channels[sigs.size()] = NULL;
 
        // Begin storing
-       if (sr_session_save_init(SigSession::_sr_session, _file_name.c_str(),
-               data->samplerate(), channels) != SR_OK) {
+       try {
+               SigSession::_sr_session->begin_save(_file_name);
+       } catch (Error error) {
                _error = tr("Error while saving.");
                return false;
        }
@@ -179,9 +184,11 @@ void StoreSession::store_proc(shared_ptr<data::LogicSnapshot> snapshot)
                        start_sample + samples_per_block, sample_count);
                snapshot->get_samples(data, start_sample, end_sample);
 
-               if(sr_session_append(SigSession::_sr_session, _file_name.c_str(), data,
-                       unit_size, end_sample - start_sample) != SR_OK)
-               {
+               size_t length = end_sample - start_sample;
+
+               try {
+                       SigSession::_sr_session->append(data, length, unit_size);
+               } catch (Error error) {
                        _error = tr("Error while saving.");
                        break;
                }
index c34373776ca572ca101465a2fc73bfff2ab2cf80..2350a45f8f76269f6457f67e3cf46d4652f25242 100644 (file)
 #include "samplingbar.h"
 
 #include <pv/devicemanager.h>
-#include <pv/device/devinst.h>
 #include <pv/popups/deviceoptions.h>
 #include <pv/popups/channels.h>
 #include <pv/util.h>
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::map;
+using std::vector;
 using std::max;
 using std::min;
 using std::shared_ptr;
 using std::string;
 
+using sigrok::Capability;
+using sigrok::ConfigKey;
+using sigrok::Device;
+using sigrok::Error;
+
 namespace pv {
 namespace toolbars {
 
@@ -102,8 +109,8 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
 }
 
 void SamplingBar::set_device_list(
-       const std::list< shared_ptr<pv::device::DevInst> > &devices,
-       shared_ptr<pv::device::DevInst> selected)
+       const std::map< shared_ptr<Device>, string > &device_names,
+       shared_ptr<Device> selected)
 {
        int selected_index = -1;
 
@@ -112,20 +119,18 @@ void SamplingBar::set_device_list(
        _updating_device_selector = true;
 
        _device_selector.clear();
-       _device_selector_map.clear();
 
-       for (shared_ptr<pv::device::DevInst> dev_inst : devices) {
-               assert(dev_inst);
-               const string title = dev_inst->format_device_title();
-               const sr_dev_inst *sdi = dev_inst->dev_inst();
-               assert(sdi);
+       for (auto entry : device_names) {
+               auto device = entry.first;
+               auto description = entry.second;
 
-               if (selected == dev_inst)
+               assert(device);
+
+               if (selected == device)
                        selected_index = _device_selector.count();
 
-               _device_selector_map[sdi] = dev_inst;
-               _device_selector.addItem(title.c_str(),
-                       qVariantFromValue((void*)sdi));
+               _device_selector.addItem(description.c_str(),
+                       qVariantFromValue(device));
        }
 
        // The selected device should have been in the list
@@ -137,22 +142,13 @@ void SamplingBar::set_device_list(
        _updating_device_selector = false;
 }
 
-shared_ptr<pv::device::DevInst> SamplingBar::get_selected_device() const
+shared_ptr<Device> SamplingBar::get_selected_device() const
 {
        const int index = _device_selector.currentIndex();
        if (index < 0)
-               return shared_ptr<pv::device::DevInst>();
-
-       const sr_dev_inst *const sdi =
-               (const sr_dev_inst*)_device_selector.itemData(
-                       index).value<void*>();
-       assert(sdi);
+               return shared_ptr<Device>();
 
-       const auto iter = _device_selector_map.find(sdi);
-       if (iter == _device_selector_map.end())
-               return shared_ptr<pv::device::DevInst>();
-
-       return shared_ptr<pv::device::DevInst>((*iter).second);
+       return _device_selector.itemData(index).value<shared_ptr<Device>>();
 }
 
 void SamplingBar::set_capture_state(pv::SigSession::capture_state state)
@@ -165,28 +161,30 @@ void SamplingBar::set_capture_state(pv::SigSession::capture_state state)
 
 void SamplingBar::update_sample_rate_selector()
 {
-       GVariant *gvar_dict, *gvar_list;
+       Glib::VariantContainerBase gvar_dict;
+       GVariant *gvar_list;
        const uint64_t *elements = NULL;
        gsize num_elements;
 
        if (_updating_sample_rate)
                return;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       const shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
        assert(!_updating_sample_rate);
        _updating_sample_rate = true;
 
-       if (!(gvar_dict = dev_inst->list_config(NULL, SR_CONF_SAMPLERATE)))
-       {
+       try {
+               gvar_dict = device->config_list(ConfigKey::SAMPLERATE);
+       } catch (Error error) {
                _sample_rate.show_none();
                _updating_sample_rate = false;
                return;
        }
 
-       if ((gvar_list = g_variant_lookup_value(gvar_dict,
+       if ((gvar_list = g_variant_lookup_value(gvar_dict.gobj(),
                        "samplerate-steps", G_VARIANT_TYPE("at"))))
        {
                elements = (const uint64_t *)g_variant_get_fixed_array(
@@ -214,7 +212,7 @@ void SamplingBar::update_sample_rate_selector()
                        _sample_rate.show_min_max_step(min, max, step);
                }
        }
-       else if ((gvar_list = g_variant_lookup_value(gvar_dict,
+       else if ((gvar_list = g_variant_lookup_value(gvar_dict.gobj(),
                        "samplerates", G_VARIANT_TYPE("at"))))
        {
                elements = (const uint64_t *)g_variant_get_fixed_array(
@@ -224,44 +222,39 @@ void SamplingBar::update_sample_rate_selector()
        }
        _updating_sample_rate = false;
 
-       g_variant_unref(gvar_dict);
        update_sample_rate_selector_value();
 }
 
 void SamplingBar::update_sample_rate_selector_value()
 {
-       GVariant *gvar;
-       uint64_t samplerate;
-
        if (_updating_sample_rate)
                return;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       const shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
-       if (!(gvar = dev_inst->get_config(NULL, SR_CONF_SAMPLERATE))) {
+       try {
+               auto gvar = device->config_get(ConfigKey::SAMPLERATE);
+               uint64_t samplerate =
+                       Glib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();
+               assert(!_updating_sample_rate);
+               _updating_sample_rate = true;
+               _sample_rate.set_value(samplerate);
+               _updating_sample_rate = false;
+       } catch (Error error) {
                qDebug() << "WARNING: Failed to get value of sample rate";
                return;
        }
-       samplerate = g_variant_get_uint64(gvar);
-       g_variant_unref(gvar);
-
-       assert(!_updating_sample_rate);
-       _updating_sample_rate = true;
-       _sample_rate.set_value(samplerate);
-       _updating_sample_rate = false;
 }
 
 void SamplingBar::update_sample_count_selector()
 {
-       GVariant *gvar;
-
        if (_updating_sample_count)
                return;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       const shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
        assert(!_updating_sample_count);
@@ -276,12 +269,11 @@ void SamplingBar::update_sample_count_selector()
                if (sample_count == 0)
                        sample_count = DefaultSampleCount;
 
-               if ((gvar = dev_inst->list_config(NULL, SR_CONF_LIMIT_SAMPLES)))
-               {
-                       g_variant_get(gvar, "(tt)",
+               try {
+                       auto gvar = device->config_list(ConfigKey::LIMIT_SAMPLES);
+                       g_variant_get(gvar.gobj(), "(tt)",
                                &min_sample_count, &max_sample_count);
-                       g_variant_unref(gvar);
-               }
+               } catch (Error error) {}
 
                min_sample_count = min(max(min_sample_count, MinSampleCount),
                        max_sample_count);
@@ -289,16 +281,14 @@ void SamplingBar::update_sample_count_selector()
                _sample_count.show_125_list(
                        min_sample_count, max_sample_count);
 
-               if ((gvar = dev_inst->get_config(NULL, SR_CONF_LIMIT_SAMPLES)))
-               {
-                       sample_count = g_variant_get_uint64(gvar);
+               try {
+                       auto gvar = device->config_get(ConfigKey::LIMIT_SAMPLES);
+                       sample_count = g_variant_get_uint64(gvar.gobj());
                        if (sample_count == 0)
                                sample_count = DefaultSampleCount;
                        sample_count = min(max(sample_count, MinSampleCount),
                                max_sample_count);
-
-                       g_variant_unref(gvar);
-               }
+               } catch (Error error) {}
 
                _sample_count.set_value(sample_count);
        }
@@ -310,16 +300,14 @@ void SamplingBar::update_sample_count_selector()
 
 void SamplingBar::update_device_config_widgets()
 {
-       GVariant *gvar;
-
        using namespace pv::popups;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       const shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
        // Update the configure popup
-       DeviceOptions *const opts = new DeviceOptions(dev_inst, this);
+       DeviceOptions *const opts = new DeviceOptions(device, this);
        _configure_button_action->setVisible(
                !opts->binding().properties().empty());
        _configure_button.set_popup(opts);
@@ -331,31 +319,33 @@ void SamplingBar::update_device_config_widgets()
        // Update supported options.
        _sample_count_supported = false;
 
-       if ((gvar = dev_inst->list_config(NULL, SR_CONF_DEVICE_OPTIONS)))
-       {
-               gsize num_opts;
-               const int *const options =
-                       (const int32_t *)g_variant_get_fixed_array(
-                               gvar, &num_opts, sizeof(int32_t));
-               for (unsigned int i = 0; i < num_opts; i++)
+       try {
+               for (auto entry : device->config_keys(ConfigKey::DEVICE_OPTIONS))
                {
-                       switch (options[i] & SR_CONF_MASK) {
+                       auto key = entry.first;
+                       auto capabilities = entry.second;
+                       switch (key->id()) {
                        case SR_CONF_LIMIT_SAMPLES:
-                               if (options[i] & SR_CONF_SET)
+                               if (capabilities.count(Capability::SET))
                                        _sample_count_supported = true;
                                break;
                        case SR_CONF_LIMIT_FRAMES:
-                               if (options[i] & SR_CONF_SET)
-                                       dev_inst->set_config(NULL, SR_CONF_LIMIT_FRAMES,
-                                               g_variant_new_uint64(1));
+                               if (capabilities.count(Capability::SET))
+                               {
+                                       device->config_set(ConfigKey::LIMIT_FRAMES,
+                                               Glib::Variant<uint64_t>::create(1));
+                                       on_config_changed();
+                               }
+                               break;
+                       default:
                                break;
                        }
                }
-       }
+       } catch (Error error) {}
 
        // Add notification of reconfigure events
        disconnect(this, SLOT(on_config_changed()));
-       connect(dev_inst.get(), SIGNAL(config_changed()),
+       connect(&opts->binding(), SIGNAL(config_changed()),
                this, SLOT(on_config_changed()));
 
        // Update sweep timing widgets.
@@ -370,8 +360,8 @@ void SamplingBar::commit_sample_count()
        if (_updating_sample_count)
                return;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       const shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
        sample_count = _sample_count.value();
@@ -379,11 +369,16 @@ void SamplingBar::commit_sample_count()
        // Set the sample count
        assert(!_updating_sample_count);
        _updating_sample_count = true;
-       if (_sample_count_supported &&
-               !dev_inst->set_config(NULL, SR_CONF_LIMIT_SAMPLES,
-               g_variant_new_uint64(sample_count))) {
-               qDebug() << "Failed to configure sample count.";
-               return;
+       if (_sample_count_supported)
+       {
+               try {
+                       device->config_set(ConfigKey::LIMIT_SAMPLES,
+                               Glib::Variant<uint64_t>::create(sample_count));
+                       on_config_changed();
+               } catch (Error error) {
+                       qDebug() << "Failed to configure sample count.";
+                       return;
+               }
        }
        _updating_sample_count = false;
 }
@@ -395,8 +390,8 @@ void SamplingBar::commit_sample_rate()
        if (_updating_sample_rate)
                return;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       const shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
        sample_rate = _sample_rate.value();
@@ -406,8 +401,11 @@ void SamplingBar::commit_sample_rate()
        // Set the samplerate
        assert(!_updating_sample_rate);
        _updating_sample_rate = true;
-       if (!dev_inst->set_config(NULL, SR_CONF_SAMPLERATE,
-               g_variant_new_uint64(sample_rate))) {
+       try {
+               device->config_set(ConfigKey::SAMPLERATE,
+                       Glib::Variant<uint64_t>::create(sample_rate));
+               on_config_changed();
+       } catch (Error error) {
                qDebug() << "Failed to configure samplerate.";
                return;
        }
@@ -419,11 +417,11 @@ void SamplingBar::on_device_selected()
        if (_updating_device_selector)
                return;
 
-       const shared_ptr<device::DevInst> dev_inst = get_selected_device();
-       if (!dev_inst)
+       shared_ptr<Device> device = get_selected_device();
+       if (!device)
                return;
 
-       _session.set_device(dev_inst);
+       _session.set_device(device);
 
        update_device_config_widgets();
 }
index b2e7def25f7c4d1a2f112b4c3838f24bae7e7328..7c0ec9af2d75a2d29577e7d5126f1b2c78c717ee 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <stdint.h>
 
-#include <list>
 #include <map>
 #include <memory>
 
 #include <pv/widgets/popuptoolbutton.h>
 #include <pv/widgets/sweeptimingwidget.h>
 
+namespace sigrok {
+       class Device;
+}
+
+Q_DECLARE_METATYPE(std::shared_ptr<sigrok::Device>)
+
 class QAction;
 
 namespace pv {
 
 class SigSession;
 
-namespace device {
-class DevInst;
-}
-
 namespace toolbars {
 
 class SamplingBar : public QToolBar
@@ -61,11 +62,11 @@ public:
        SamplingBar(SigSession &session, QWidget *parent);
 
        void set_device_list(
-               const std::list< std::shared_ptr<pv::device::DevInst> >
-                       &devices,
-               std::shared_ptr<pv::device::DevInst> selected);
+               const std::map< std::shared_ptr<sigrok::Device>, std::string >
+                       &device_names,
+               std::shared_ptr<sigrok::Device> selected);
 
-       std::shared_ptr<pv::device::DevInst> get_selected_device() const;
+       std::shared_ptr<sigrok::Device> get_selected_device() const;
 
        void set_capture_state(pv::SigSession::capture_state state);
 
@@ -95,8 +96,6 @@ private:
        SigSession &_session;
 
        QComboBox _device_selector;
-       std::map<const sr_dev_inst*, std::weak_ptr<device::DevInst> >
-               _device_selector_map;
        bool _updating_device_selector;
 
        pv::widgets::PopupToolButton _configure_button;
index e3f51aabc6d787b00f10955432a1c53e73d5a179..7b49bbd2b7d454606d2ac5d51e482a331ca1b01c 100644 (file)
 #include "pv/data/analogsnapshot.h"
 #include "pv/view/view.h"
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::max;
 using std::min;
 using std::shared_ptr;
 using std::deque;
 
+using sigrok::Channel;
+
 namespace pv {
 namespace view {
 
@@ -45,13 +49,13 @@ const QColor AnalogSignal::SignalColours[4] = {
 
 const float AnalogSignal::EnvelopeThreshold = 256.0f;
 
-AnalogSignal::AnalogSignal(shared_ptr<pv::device::DevInst> dev_inst,
-       const sr_channel *const channel, shared_ptr<data::Analog> data) :
-       Signal(dev_inst, channel),
+AnalogSignal::AnalogSignal(shared_ptr<Channel> channel,
+       shared_ptr<data::Analog> data) :
+       Signal(channel),
        _data(data),
        _scale(1.0f)
 {
-       _colour = SignalColours[channel->index % countof(SignalColours)];
+       _colour = SignalColours[_channel->index() % countof(SignalColours)];
 }
 
 AnalogSignal::~AnalogSignal()
@@ -75,7 +79,7 @@ void AnalogSignal::set_scale(float scale)
 
 void AnalogSignal::paint_back(QPainter &p, int left, int right)
 {
-       if (_channel->enabled)
+       if (_channel->enabled())
                paint_axis(p, get_y(), left, right);
 }
 
@@ -92,7 +96,7 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right)
 
        const double offset = _view->offset();
 
-       if (!_channel->enabled)
+       if (!_channel->enabled())
                return;
 
        const deque< shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
index 934203366dca78b93591402b57fc49d56b996c8e..4070a8aa199ecb29834559e912df27a9ad683fb6 100644 (file)
@@ -42,8 +42,7 @@ private:
        static const float EnvelopeThreshold;
 
 public:
-       AnalogSignal(std::shared_ptr<pv::device::DevInst> dev_inst,
-               const sr_channel *const channel,
+       AnalogSignal(std::shared_ptr<sigrok::Channel> channel,
                std::shared_ptr<pv::data::Analog> data);
 
        virtual ~AnalogSignal();
index 27635f902f1fe80e47595e95a829fd3ad49957b7..54d257819ade28b05be7ac0646f01e96390a579e 100644 (file)
 #include "view.h"
 
 #include <pv/sigsession.h>
-#include <pv/device/devinst.h>
 #include <pv/data/logic.h>
 #include <pv/data/logicsnapshot.h>
 #include <pv/view/view.h>
 
+#include <libsigrok/libsigrok.hpp>
+
 using std::deque;
 using std::max;
 using std::min;
@@ -42,6 +43,13 @@ using std::pair;
 using std::shared_ptr;
 using std::vector;
 
+using sigrok::Channel;
+using sigrok::ConfigKey;
+using sigrok::Device;
+using sigrok::Error;
+using sigrok::Trigger;
+using sigrok::TriggerMatchType;
+
 namespace pv {
 namespace view {
 
@@ -64,9 +72,11 @@ const QColor LogicSignal::SignalColours[10] = {
        QColor(0xEE, 0xEE, 0xEC),       // White
 };
 
-LogicSignal::LogicSignal(shared_ptr<pv::device::DevInst> dev_inst,
-       const sr_channel *const channel, shared_ptr<data::Logic> data) :
-       Signal(dev_inst, channel),
+LogicSignal::LogicSignal(shared_ptr<Device> device,
+               shared_ptr<Channel> channel,
+               shared_ptr<data::Logic> data) :
+       Signal(channel),
+       _device(device),
        _data(data),
        _trigger_none(NULL),
        _trigger_rising(NULL),
@@ -75,26 +85,18 @@ LogicSignal::LogicSignal(shared_ptr<pv::device::DevInst> dev_inst,
        _trigger_low(NULL),
        _trigger_change(NULL)
 {
-       struct sr_trigger *trigger;
-       struct sr_trigger_stage *stage;
-       struct sr_trigger_match *match;
-       const GSList *l, *m;
+       shared_ptr<Trigger> trigger;
 
-       _colour = SignalColours[channel->index % countof(SignalColours)];
+       _colour = SignalColours[channel->index() % countof(SignalColours)];
 
        /* Populate this channel's trigger setting with whatever we
         * find in the current session trigger, if anything. */
-       _trigger_match = 0;
-       if ((trigger = sr_session_trigger_get(SigSession::_sr_session))) {
-               for (l = trigger->stages; l && !_trigger_match; l = l->next) {
-                       stage = (struct sr_trigger_stage *)l->data;
-                       for (m = stage->matches; m && !_trigger_match; m = m->next) {
-                               match = (struct sr_trigger_match *)m->data;
-                               if (match->channel == _channel)
-                                       _trigger_match = match->match;
-                       }
-               }
-       }
+       _trigger_match = nullptr;
+       if ((trigger = SigSession::_sr_session->trigger()))
+               for (auto stage : trigger->stages())
+                       for (auto match : stage->matches())
+                               if (match->channel() == _channel)
+                                       _trigger_match = match->type();
 }
 
 LogicSignal::~LogicSignal()
@@ -113,7 +115,7 @@ shared_ptr<pv::data::Logic> LogicSignal::logic_data() const
 
 void LogicSignal::paint_back(QPainter &p, int left, int right)
 {
-       if (_channel->enabled)
+       if (_channel->enabled())
                paint_axis(p, get_y(), left, right);
 }
 
@@ -137,7 +139,7 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right)
        
        const double offset = _view->offset();
 
-       if (!_channel->enabled)
+       if (!_channel->enabled())
                return;
 
        const float high_offset = y - View::SignalHeight + 0.5f;
@@ -167,7 +169,7 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right)
        snapshot->get_subsampled_edges(edges,
                min(max((int64_t)floor(start), (int64_t)0), last_sample),
                min(max((int64_t)ceil(end), (int64_t)0), last_sample),
-               samples_per_pixel / Oversampling, _channel->index);
+               samples_per_pixel / Oversampling, _channel->index());
        assert(edges.size() >= 2);
 
        // Paint the edges
@@ -251,12 +253,12 @@ void LogicSignal::init_trigger_actions(QWidget *parent)
        connect(_trigger_change, SIGNAL(triggered()), this, SLOT(on_trigger()));
 }
 
-QAction* LogicSignal::match_action(int match)
+QAction* LogicSignal::match_action(const TriggerMatchType *type)
 {
        QAction *action;
 
        action = _trigger_none;
-       switch (match) {
+       switch (type->id()) {
        case SR_TRIGGER_ZERO:
                action = _trigger_low;
                break;
@@ -272,56 +274,56 @@ QAction* LogicSignal::match_action(int match)
        case SR_TRIGGER_EDGE:
                action = _trigger_change;
                break;
+       default:
+               assert(0);
        }
 
        return action;
 }
 
-int LogicSignal::action_match(QAction *action)
+const TriggerMatchType *LogicSignal::action_match(QAction *action)
 {
-       int match;
-
        if (action == _trigger_low)
-               match = SR_TRIGGER_ZERO;
+               return TriggerMatchType::ZERO;
        else if (action == _trigger_high)
-               match = SR_TRIGGER_ONE;
+               return TriggerMatchType::ONE;
        else if (action == _trigger_rising)
-               match = SR_TRIGGER_RISING;
+               return TriggerMatchType::RISING;
        else if (action == _trigger_falling)
-               match = SR_TRIGGER_FALLING;
+               return TriggerMatchType::FALLING;
        else if (action == _trigger_change)
-               match = SR_TRIGGER_EDGE;
+               return TriggerMatchType::EDGE;
        else
-               match = 0;
-
-       return match;
+               return nullptr;
 }
 
 void LogicSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
 {
-       GVariant *gvar;
-       gsize num_opts;
-       const int32_t *trig_matches;
-       unsigned int i;
+       Glib::VariantContainerBase gvar;
+       vector<int32_t> trig_types;
        bool is_checked;
 
        Signal::populate_popup_form(parent, form);
 
-       if (!(gvar = _dev_inst->list_config(NULL, SR_CONF_TRIGGER_MATCH)))
+       try {
+               gvar = _device->config_list(ConfigKey::TRIGGER_MATCH);
+       } catch (Error e) {
                return;
+       }
 
        _trigger_bar = new QToolBar(parent);
        init_trigger_actions(_trigger_bar);
        _trigger_bar->addAction(_trigger_none);
-       trig_matches = (const int32_t *)g_variant_get_fixed_array(gvar,
-                       &num_opts, sizeof(int32_t));
-       for (i = 0; i < num_opts; i++) {
-               _trigger_bar->addAction(match_action(trig_matches[i]));
-               is_checked = _trigger_match == trig_matches[i];
-               match_action(trig_matches[i])->setChecked(is_checked);
+       trig_types =
+               Glib::VariantBase::cast_dynamic<Glib::Variant<vector<int32_t>>>(
+                       gvar).get();
+       for (auto type_id : trig_types) {
+               auto type = TriggerMatchType::get(type_id);
+               _trigger_bar->addAction(match_action(type));
+               is_checked = _trigger_match == type;
+               match_action(type)->setChecked(is_checked);
        }
        form->addRow(tr("Trigger"), _trigger_bar);
-       g_variant_unref(gvar);
 
 }
 
index 0f6714cf0ce11661c58e0c264d6973e5350b6753..11b1d2bdd6a18933e26804f2203ce80836979cfd 100644 (file)
 
 class QToolBar;
 
+namespace sigrok {
+       class Device;
+       class TriggerMatchType;
+}
+
 namespace pv {
 
 namespace data {
@@ -49,8 +54,8 @@ private:
        static const QColor SignalColours[10];
 
 public:
-       LogicSignal(std::shared_ptr<pv::device::DevInst> dev_inst,
-               const sr_channel *const channel,
+       LogicSignal(std::shared_ptr<sigrok::Device> device,
+               std::shared_ptr<sigrok::Channel> channel,
                std::shared_ptr<pv::data::Logic> data);
 
        virtual ~LogicSignal();
@@ -83,17 +88,18 @@ private:
 
        void init_trigger_actions(QWidget *parent);
 
-       QAction* match_action(int match);
-       int action_match(QAction *action);
+       QAction* match_action(const sigrok::TriggerMatchType *match);
+       const sigrok::TriggerMatchType *action_match(QAction *action);
        void populate_popup_form(QWidget *parent, QFormLayout *form);
 
 private Q_SLOTS:
        void on_trigger();
 
 private:
+       std::shared_ptr<sigrok::Device> _device;
        std::shared_ptr<pv::data::Logic> _data;
 
-       int _trigger_match;
+       const sigrok::TriggerMatchType *_trigger_match;
        QToolBar *_trigger_bar;
        QAction *_trigger_none;
        QAction *_trigger_rising;
index 7df31767ea5492659dcc8e1e33ef5b0a17c9cb4c..16ebc74d24a890f70f8ca3f5bf0d8b1335506f5b 100644 (file)
 #include <QLineEdit>
 #include <QMenu>
 
-#include <libsigrok/libsigrok.h>
+#include <libsigrok/libsigrok.hpp>
 
 #include "signal.h"
 #include "view.h"
 
-#include <pv/device/devinst.h>
-
 using std::shared_ptr;
 
+using sigrok::Channel;
+
 namespace pv {
 namespace view {
 
@@ -58,10 +58,8 @@ const char *const ChannelNames[] = {
        "SCL"
 };
 
-Signal::Signal(shared_ptr<pv::device::DevInst> dev_inst,
-       const sr_channel *const channel) :
-       Trace(channel->name),
-       _dev_inst(dev_inst),
+Signal::Signal(shared_ptr<Channel> channel) :
+       Trace(channel->name().c_str()),
        _channel(channel),
        _name_widget(NULL),
        _updating_name_widget(false)
@@ -79,16 +77,16 @@ void Signal::set_name(QString name)
 
 bool Signal::enabled() const
 {
-       return _channel->enabled;
+       return _channel->enabled();
 }
 
 void Signal::enable(bool enable)
 {
-       _dev_inst->enable_channel(_channel, enable);
+       _channel->set_enabled(enable);
        visibility_changed();
 }
 
-const sr_channel* Signal::channel() const
+shared_ptr<Channel> Signal::channel() const
 {
        return _channel;
 }
index cce9f4694e237da6fd7abd8a99b8f2c3f566fc68..7028b29e9fb31cdc182b5396ba2e7fa7f9ba75b8 100644 (file)
@@ -30,7 +30,9 @@
 
 #include "trace.h"
 
-struct sr_channel;
+namespace sigrok {
+       class Channel;
+}
 
 namespace pv {
 
@@ -38,10 +40,6 @@ namespace data {
 class SignalData;
 }
 
-namespace device {
-class DevInst;
-}
-
 namespace view {
 
 class Signal : public Trace
@@ -49,8 +47,7 @@ class Signal : public Trace
        Q_OBJECT
 
 protected:
-       Signal(std::shared_ptr<pv::device::DevInst> dev_inst,
-               const sr_channel *const channel);
+       Signal(std::shared_ptr<sigrok::Channel> channel);
 
 public:
        /**
@@ -67,7 +64,7 @@ public:
 
        void enable(bool enable = true);
 
-       const sr_channel* channel() const;
+       std::shared_ptr<sigrok::Channel> channel() const;
 
        virtual void populate_popup_form(QWidget *parent, QFormLayout *form);
 
@@ -79,8 +76,7 @@ private Q_SLOTS:
        void on_disable();
 
 protected:
-       std::shared_ptr<pv::device::DevInst> _dev_inst;
-       const sr_channel *const _channel;
+       std::shared_ptr<sigrok::Channel> _channel;
 
        QComboBox *_name_widget;
        bool _updating_name_widget;