github.com/kelleygo/clashcore@v1.0.2/component/power/event_windows.go (about)

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