diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 791d2549..a6c5021c 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -2221,6 +2221,11 @@ namespace pv QWidget* MainWindow::GetBodyView() { return _view; - } + } + + void MainWindow::OnWindowsPowerEvent(bool bEnterSleep) + { + _session->ProcessPowerEvent(bEnterSleep); + } } // namespace pv diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 0415c1b2..a43e0427 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -134,6 +134,8 @@ public: void switchLanguage(int language) override; bool able_to_close(); QWidget* GetBodyView(); + + void OnWindowsPowerEvent(bool bEnterSleep); private: void setup_ui(); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 02ef29af..c82a6d24 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -2586,4 +2586,16 @@ namespace pv on_load_config_end(); } + void SigSession::ProcessPowerEvent(bool bEnterSleep) + { + if (bEnterSleep){ + if (_is_working && _device_agent.is_hardware()){ + stop_capture(); + } + } + else{ + ds_reload_device_list(); + } + } + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 9a2344cf..bfbba655 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -453,6 +453,8 @@ public: void apply_samplerate(); + void ProcessPowerEvent(bool bEnterSleep); + private: void set_cur_samplelimits(uint64_t samplelimits); void set_cur_snap_samplerate(uint64_t samplerate); diff --git a/DSView/pv/winnativewidget.cpp b/DSView/pv/winnativewidget.cpp index 7b866301..02e3c332 100644 --- a/DSView/pv/winnativewidget.cpp +++ b/DSView/pv/winnativewidget.cpp @@ -40,6 +40,7 @@ #include "mainframe.h" #include "dsvdef.h" #include "appcontrol.h" +#include "mainwindow.h" #define FIXED_WIDTH(widget) (widget->minimumWidth() >= widget->maximumWidth()) #define FIXED_HEIGHT(widget) (widget->minimumHeight() >= widget->maximumHeight()) @@ -373,6 +374,28 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam } break; } + case WM_POWERBROADCAST: + { + if (self->_childWidget != NULL) + { + dsv::MainFrame *frame = dynamic_cast(self->_childWidget); + dsv::MainWindow *mainWnd = dynamic_cast(frame->GetMainWindow()); + switch (wParam) + { + case PBT_APMQUERYSUSPEND: + dsv_info("Windows enters sleep.") + mainWnd->OnWindowsPowerEvent(true); + break; + + case PBT_APMRESUMESUSPEND: + case PBT_APMRESUMECRITICAL: + dsv_info("Windows be awaked.") + mainWnd->OnWindowsPowerEvent(false); + break; + } + } + break; + } } return DefWindowProc(hWnd, message, wParam, lParam); diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index f09fa4e6..743829f0 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -68,6 +68,7 @@ struct sr_lib_context int transaction_id; int transaction_command; int last_error; + int is_reloading_list; }; static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event); @@ -104,6 +105,7 @@ static struct sr_lib_context lib_ctx = { .transaction_id = 0, .transaction_command = DEV_TRANS_NONE, .last_error = SR_OK, + .is_reloading_list = 0, }; /** @@ -1111,6 +1113,10 @@ SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev) struct sr_dev_inst *dev; int bFind = 0; + if (lib_ctx.is_reloading_list){ + return 0; + } + if (usb_dev == NULL) { sr_err("sr_usb_device_is_exists(), @usb_dev is null."); @@ -1320,8 +1326,12 @@ static void process_attach_event(int isEvent) struct sr_dev_driver **drivers; GSList *dev_list; GSList *l; + GSList *l_check; struct sr_dev_driver *dr; + struct sr_dev_inst *sdi; + struct sr_dev_inst *new_sdi; int num = 0; + int bFind; if (isEvent){ sr_info("Process device attach event."); @@ -1336,14 +1346,32 @@ static void process_attach_event(int isEvent) if (dr->driver_type == DRIVER_TYPE_HARDWARE) { dev_list = dr->scan(NULL); - if (dev_list != NULL) - { - pthread_mutex_lock(&lib_ctx.mutext); + if (dev_list != NULL){ + pthread_mutex_lock(&lib_ctx.mutext); + for (l = dev_list; l; l = l->next) { - lib_ctx.device_list = g_slist_append(lib_ctx.device_list, l->data); - num++; + bFind = 0; + new_sdi = l->data; + + for (l_check = lib_ctx.device_list; l_check; l_check = l_check->next) + { + sdi = l_check->data; + if (sdi->handle == new_sdi->handle){ + bFind = 1; + break; + } + } + + if (!bFind){ + lib_ctx.device_list = g_slist_append(lib_ctx.device_list, l->data); + num++; + } + else{ + sr_info("A device not appent to list, handle:%p", (void*)new_sdi->handle); + sr_dev_inst_free(new_sdi); //Not append to list, so free it. + } } pthread_mutex_unlock(&lib_ctx.mutext); g_slist_free(dev_list); @@ -1708,3 +1736,14 @@ SR_API int ds_get_last_error() { return lib_ctx.last_error; } + +SR_API int ds_reload_device_list() +{ + sr_info("Reload device list."); + + lib_ctx.is_reloading_list = 1; + process_attach_event(0); + lib_ctx.is_reloading_list = 0; + + return SR_OK; +} diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index e8f6b15d..175305fa 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -1478,6 +1478,8 @@ SR_API int ds_release_actived_device(); SR_API int ds_get_last_error(); +SR_API int ds_reload_device_list(); + /*---config -----------------------------------------------*/ SR_API int ds_get_actived_device_config(const struct sr_channel *ch, const struct sr_channel_group *cg,