Skip to content

Commit

Permalink
chore: add power event code for windows
Browse files Browse the repository at this point in the history
  • Loading branch information
wwqgtxx committed Feb 16, 2024
1 parent 93b48a9 commit 985b884
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
22 changes: 22 additions & 0 deletions component/power/event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package power

type Type uint8

const (
SUSPEND Type = iota
RESUME
RESUMEAUTOMATIC // Because the user is not present, most applications should do nothing.
)

func (t Type) String() string {
switch t {
case SUSPEND:
return "SUSPEND"
case RESUME:
return "RESUME"
case RESUMEAUTOMATIC:
return "RESUMEAUTOMATIC"
default:
return ""
}
}
9 changes: 9 additions & 0 deletions component/power/event_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !windows

package power

import "errors"

func NewEventListener(cb func(Type)) (func(), error) {
return nil, errors.New("not support on this platform")
}
74 changes: 74 additions & 0 deletions component/power/event_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package power

// modify from https://github.com/golang/go/blob/b634f6fdcbebee23b7da709a243f3db217b64776/src/runtime/os_windows.go#L257

import (
"runtime"
"unsafe"

"golang.org/x/sys/windows"
)

var (
libPowrProf = windows.NewLazySystemDLL("powrprof.dll")
powerRegisterSuspendResumeNotification = libPowrProf.NewProc("PowerRegisterSuspendResumeNotification")
powerUnregisterSuspendResumeNotification = libPowrProf.NewProc("PowerUnregisterSuspendResumeNotification")
)

func NewEventListener(cb func(Type)) (func(), error) {
if err := powerRegisterSuspendResumeNotification.Find(); err != nil {
return nil, err // Running on Windows 7, where we don't need it anyway.
}
if err := powerUnregisterSuspendResumeNotification.Find(); err != nil {
return nil, err // Running on Windows 7, where we don't need it anyway.
}

// Defines the type of event
const (
PBT_APMSUSPEND uint32 = 4
PBT_APMRESUMESUSPEND uint32 = 7
PBT_APMRESUMEAUTOMATIC uint32 = 18
)

const (
_DEVICE_NOTIFY_CALLBACK = 2
)
type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
callback uintptr
context uintptr
}

var fn interface{} = func(context uintptr, changeType uint32, setting uintptr) uintptr {
switch changeType {
case PBT_APMSUSPEND:
cb(SUSPEND)
case PBT_APMRESUMESUSPEND:
cb(RESUME)
case PBT_APMRESUMEAUTOMATIC:
cb(RESUMEAUTOMATIC)
}
return 0
}

params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
callback: windows.NewCallback(fn),
}
handle := uintptr(0)

_, _, err := powerRegisterSuspendResumeNotification.Call(
_DEVICE_NOTIFY_CALLBACK,
uintptr(unsafe.Pointer(&params)),
uintptr(unsafe.Pointer(&handle)),
)
if err != nil {
return nil, err
}

return func() {
_, _, _ = powerUnregisterSuspendResumeNotification.Call(
uintptr(unsafe.Pointer(&handle)),
)
runtime.KeepAlive(params)
runtime.KeepAlive(handle)
}, nil
}

0 comments on commit 985b884

Please sign in to comment.