event_windows.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package power
  2. // modify from https://github.com/golang/go/blob/b634f6fdcbebee23b7da709a243f3db217b64776/src/runtime/os_windows.go#L257
  3. import (
  4. "runtime"
  5. "unsafe"
  6. "golang.org/x/sys/windows"
  7. )
  8. var (
  9. libPowrProf = windows.NewLazySystemDLL("powrprof.dll")
  10. powerRegisterSuspendResumeNotification = libPowrProf.NewProc("PowerRegisterSuspendResumeNotification")
  11. powerUnregisterSuspendResumeNotification = libPowrProf.NewProc("PowerUnregisterSuspendResumeNotification")
  12. )
  13. func NewEventListener(cb func(Type)) (func(), error) {
  14. if err := powerRegisterSuspendResumeNotification.Find(); err != nil {
  15. return nil, err // Running on Windows 7, where we don't need it anyway.
  16. }
  17. if err := powerUnregisterSuspendResumeNotification.Find(); err != nil {
  18. return nil, err // Running on Windows 7, where we don't need it anyway.
  19. }
  20. // Defines the type of event
  21. const (
  22. PBT_APMSUSPEND uint32 = 4
  23. PBT_APMRESUMESUSPEND uint32 = 7
  24. PBT_APMRESUMEAUTOMATIC uint32 = 18
  25. )
  26. const (
  27. _DEVICE_NOTIFY_CALLBACK = 2
  28. )
  29. type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
  30. callback uintptr
  31. context uintptr
  32. }
  33. var fn interface{} = func(context uintptr, changeType uint32, setting uintptr) uintptr {
  34. switch changeType {
  35. case PBT_APMSUSPEND:
  36. cb(SUSPEND)
  37. case PBT_APMRESUMESUSPEND:
  38. cb(RESUME)
  39. case PBT_APMRESUMEAUTOMATIC:
  40. cb(RESUMEAUTOMATIC)
  41. }
  42. return 0
  43. }
  44. params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
  45. callback: windows.NewCallback(fn),
  46. }
  47. handle := uintptr(0)
  48. _, _, err := powerRegisterSuspendResumeNotification.Call(
  49. _DEVICE_NOTIFY_CALLBACK,
  50. uintptr(unsafe.Pointer(&params)),
  51. uintptr(unsafe.Pointer(&handle)),
  52. )
  53. if err != nil {
  54. return nil, err
  55. }
  56. return func() {
  57. _, _, _ = powerUnregisterSuspendResumeNotification.Call(
  58. uintptr(unsafe.Pointer(&handle)),
  59. )
  60. runtime.KeepAlive(params)
  61. runtime.KeepAlive(handle)
  62. }, nil
  63. }