From 4213f8d6b75f66a1b2c993ee3d8ca143c7ea0dc9 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Thu, 13 Jun 2024 16:31:18 +0800 Subject: [PATCH] Capture the power event in windows --- DSView/pv/sigsession.cpp | 1 + DSView/pv/winnativewidget.cpp | 95 +++++++++++++++++++++++++++++------ libsigrok4DSL/lib_main.c | 23 ++++++++- libsigrok4DSL/libsigrok.h | 2 + 4 files changed, 106 insertions(+), 15 deletions(-) diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index c82a6d24..63931863 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -2592,6 +2592,7 @@ namespace pv if (_is_working && _device_agent.is_hardware()){ stop_capture(); } + ds_close_all_device(); } else{ ds_reload_device_list(); diff --git a/DSView/pv/winnativewidget.cpp b/DSView/pv/winnativewidget.cpp index 02e3c332..9b523669 100644 --- a/DSView/pv/winnativewidget.cpp +++ b/DSView/pv/winnativewidget.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "log.h" #include "mainframe.h" @@ -50,11 +51,71 @@ #define WINDOW_STATUS_NORMAL 2 #define WINDOW_STATUS_MIN 3 +typedef HPOWERNOTIFY(WINAPI* PFN_REGISTER_SUSPEND_RESUME_NOTIFICATION)(HANDLE, DWORD); +typedef BOOL(WINAPI* PFN_UNREGISTER_SUSPEND_RESUME_NOTIFICATION)(HPOWERNOTIFY); + namespace pv { namespace { bool g_enable_ncclient = true; + HPOWERNOTIFY g_hPowerNotification = NULL; + HMODULE g_hUser32 = NULL; + PFN_REGISTER_SUSPEND_RESUME_NOTIFICATION fnRegisterSuspendResumeNotification = NULL; + PFN_UNREGISTER_SUSPEND_RESUME_NOTIFICATION fnUnregisterSuspendResumeNotification = NULL; +} + +static bool InitCapturePowerEvent(HWND hWnd) +{ + g_hUser32 = LoadLibrary(L"user32.dll"); + if (g_hUser32 == NULL) { + dsv_info("ERROR: Failed to load user32.dll"); + return false; + } + + fnRegisterSuspendResumeNotification = (PFN_REGISTER_SUSPEND_RESUME_NOTIFICATION)GetProcAddress(g_hUser32, + "RegisterSuspendResumeNotification"); + + if (fnRegisterSuspendResumeNotification == NULL){ + dsv_info("ERROR: failed to get RegisterSuspendResumeNotification address"); + FreeLibrary(g_hUser32); + g_hUser32 = NULL; + return false; + } + + fnUnregisterSuspendResumeNotification = (PFN_UNREGISTER_SUSPEND_RESUME_NOTIFICATION)GetProcAddress(g_hUser32, + "UnregisterSuspendResumeNotification"); + + if (fnUnregisterSuspendResumeNotification == NULL){ + dsv_info("ERROR: failed to get UnregisterSuspendResumeNotification address"); + FreeLibrary(g_hUser32); + g_hUser32 = NULL; + return false; + } + + g_hPowerNotification = fnRegisterSuspendResumeNotification(hWnd, DEVICE_NOTIFY_WINDOW_HANDLE); + + if (g_hPowerNotification == NULL){ + dsv_info("ERROR: failed to call RegisterSuspendResumeNotification()."); + FreeLibrary(g_hUser32); + g_hUser32 = NULL; + return false; + } + + return true; +} + +static void UninitCapturePowerEvent() +{ + if (g_hPowerNotification != NULL){ + fnUnregisterSuspendResumeNotification(g_hPowerNotification); + g_hPowerNotification = NULL; + } + + if (g_hUser32 != NULL){ + FreeLibrary(g_hUser32); + g_hUser32 = NULL; + } } //-----------------------------WinNativeWidget @@ -118,6 +179,8 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, _shadow->createWinId(); _shadow->SetCallback(this); } + + InitCapturePowerEvent(_hWnd); } WinNativeWidget::~WinNativeWidget() @@ -139,6 +202,8 @@ void WinNativeWidget::SetChildWidget(MainFrame *w) else if (_shadow != NULL){ _shadow->hideShadow(); _shadow->close(); //Set null, the applictoin will exit. + + UninitCapturePowerEvent(); } } @@ -164,7 +229,7 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam } switch (message) - { + { case WM_SYSCOMMAND: { if (wParam == SC_KEYMENU) @@ -375,25 +440,27 @@ 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()); + pv::MainFrame *frame = dynamic_cast(self->_childWidget); + pv::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; + case PBT_APMSUSPEND:{ + dsv_info("WM_POWERBROADCAST: windows enters sleep."); + mainWnd->OnWindowsPowerEvent(true); + break; + } + case PBT_APMRESUMEAUTOMATIC:{ + dsv_info("WM_POWERBROADCAST: windows be awaked."); + mainWnd->OnWindowsPowerEvent(false); + break; + } } } + break; } } diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index 743829f0..332c1f54 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -1369,7 +1369,6 @@ static void process_attach_event(int isEvent) 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. } } @@ -1747,3 +1746,25 @@ SR_API int ds_reload_device_list() return SR_OK; } + +SR_API int ds_close_all_device() +{ + sr_info("Close all device."); + + GSList *l; + struct sr_dev_inst *dev; + + pthread_mutex_lock(&lib_ctx.mutext); + + for (l = lib_ctx.device_list; l; l = l->next) + { + dev = l->data; + if (dev->dev_type == DEV_TYPE_USB){ + close_device_instance(dev); + } + } + + pthread_mutex_unlock(&lib_ctx.mutext); + + return SR_OK; +} diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 175305fa..4487aea2 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -1480,6 +1480,8 @@ SR_API int ds_get_last_error(); SR_API int ds_reload_device_list(); +SR_API int ds_close_all_device(); + /*---config -----------------------------------------------*/ SR_API int ds_get_actived_device_config(const struct sr_channel *ch, const struct sr_channel_group *cg,