go-wca/pkg/wca/IMMNotificationClient_windows.go
Yoshiyuki Koyanagi 53a62d71d2 Apply go fmt
2023-03-04 15:43:43 +09:00

178 lines
4 KiB
Go

//go:build windows
// +build windows
package wca
import (
"syscall"
"unsafe"
"github.com/go-ole/go-ole"
)
func mmncQueryInterface(this uintptr, riid *ole.GUID, ppInterface *uintptr) int64 {
*ppInterface = 0
if ole.IsEqualGUID(riid, ole.IID_IUnknown) ||
ole.IsEqualGUID(riid, IID_IMMNotificationClient) {
mmncAddRef(this)
*ppInterface = this
return ole.S_OK
}
return ole.E_NOINTERFACE
}
func mmncAddRef(this uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
mmnc.refCount += 1
return int64(mmnc.refCount)
}
func mmncRelease(this uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
mmnc.refCount -= 1
return int64(mmnc.refCount)
}
func mmncOnDefaultDeviceChanged(this uintptr, flow, role uint64, pwstrDeviceId uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
if mmnc.callback.OnDefaultDeviceChanged == nil {
return ole.S_OK
}
// device := syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(pwstrDeviceId)))
device := LPCWSTRToString(pwstrDeviceId, 1024)
err := mmnc.callback.OnDefaultDeviceChanged(EDataFlow(flow), ERole(role), device)
if err != nil {
return ole.E_FAIL
}
return ole.S_OK
}
func mmncOnDeviceAdded(this uintptr, pwstrDeviceId uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
if mmnc.callback.OnDeviceAdded == nil {
return ole.S_OK
}
// device := syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(pwstrDeviceId)))
device := LPCWSTRToString(pwstrDeviceId, 1024)
err := mmnc.callback.OnDeviceAdded(device)
if err != nil {
return ole.E_FAIL
}
return ole.S_OK
}
func mmncOnDeviceRemoved(this uintptr, pwstrDeviceId uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
if mmnc.callback.OnDeviceRemoved == nil {
return ole.S_OK
}
// device := syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(pwstrDeviceId)))
device := LPCWSTRToString(pwstrDeviceId, 1024)
err := mmnc.callback.OnDeviceRemoved(device)
if err != nil {
return ole.E_FAIL
}
return ole.S_OK
}
func mmncOnDeviceStateChanged(this uintptr, pwstrDeviceId uintptr, dwNewState uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
if mmnc.callback.OnDeviceStateChanged == nil {
return ole.S_OK
}
// device := syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(pwstrDeviceId)))
device := LPCWSTRToString(pwstrDeviceId, 1024)
err := mmnc.callback.OnDeviceStateChanged(device, 0)
if err != nil {
return ole.E_FAIL
}
return ole.S_OK
}
func mmncOnPropertyValueChanged(this uintptr, pwstrDeviceId uintptr, key uintptr) int64 {
mmnc := (*IMMNotificationClient)(unsafe.Pointer(this))
if mmnc.callback.OnPropertyValueChanged == nil {
return ole.S_OK
}
// device := syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(pwstrDeviceId)))
device := LPCWSTRToString(pwstrDeviceId, 1024)
err := mmnc.callback.OnPropertyValueChanged(device, 0)
if err != nil {
return ole.E_FAIL
}
return ole.S_OK
}
func LPCWSTRToString(lpcwstr uintptr, maxChars int) string {
if lpcwstr == 0 || maxChars == 0 {
return ""
}
us := []uint16{}
for i := 0; i < maxChars; i += 2 {
u := *(*uint16)(unsafe.Pointer(lpcwstr + uintptr(i)))
if u == 0 {
break
}
us = append(us, u)
}
return syscall.UTF16ToString(us)
}
func NewIMMNotificationClient(callback IMMNotificationClientCallback) *IMMNotificationClient {
vTable := &IMMNotificationClientVtbl{}
// IUnknown methods
vTable.QueryInterface = syscall.NewCallback(mmncQueryInterface)
vTable.AddRef = syscall.NewCallback(mmncAddRef)
vTable.Release = syscall.NewCallback(mmncRelease)
// IMMNotificationClient methods
vTable.OnDeviceStateChanged = syscall.NewCallback(mmncOnDeviceStateChanged)
vTable.OnDeviceAdded = syscall.NewCallback(mmncOnDeviceAdded)
vTable.OnDeviceRemoved = syscall.NewCallback(mmncOnDeviceRemoved)
vTable.OnDefaultDeviceChanged = syscall.NewCallback(mmncOnDefaultDeviceChanged)
vTable.OnPropertyValueChanged = syscall.NewCallback(mmncOnPropertyValueChanged)
mmnc := &IMMNotificationClient{}
mmnc.vTable = vTable
mmnc.callback = callback
return mmnc
}