commit eb13cd60ae70d0644ffb07df9a7b7b3c65a8c57e
parent ec054438dfbb34bc52ea089e49838f42505ccf2b
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Tue, 5 Dec 2023 16:59:50 +0800
winrt: add auto-generated COM definitions
This includes the definitions we need, and is better than hand writing them.
Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Diffstat:
6 files changed, 424 insertions(+), 0 deletions(-)
diff --git a/internal/kernel32/kernel32.go b/internal/kernel32/kernel32.go
@@ -0,0 +1,78 @@
+//go:build windows
+
+package kernel32
+
+import (
+ "sync/atomic"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+type (
+ heapHandle = uintptr
+ win32Error uint32
+ heapFlags uint32
+)
+
+const (
+ heapNone heapFlags = 0
+ heapZeroMemory heapFlags = 8 // The allocated memory will be initialized to zero.
+)
+
+var (
+ libKernel32 = windows.NewLazySystemDLL("kernel32.dll")
+
+ pHeapFree uintptr
+ pHeapAlloc uintptr
+ pGetProcessHeap uintptr
+
+ hHeap heapHandle
+)
+
+func init() {
+ hHeap, _ = getProcessHeap()
+}
+
+// Malloc allocates the given amount of bytes in the heap
+func Malloc(size uintptr) unsafe.Pointer {
+ return heapAlloc(hHeap, heapZeroMemory, size)
+}
+
+// Free releases the given unsafe pointer from the heap
+func Free(inst unsafe.Pointer) {
+ _, _ = heapFree(hHeap, heapNone, inst)
+}
+
+// https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc
+func heapAlloc(hHeap heapHandle, dwFlags heapFlags, dwBytes uintptr) unsafe.Pointer {
+ addr := getProcAddr(&pHeapAlloc, libKernel32, "HeapAlloc")
+ allocatedPtr, _, _ := syscall.SyscallN(addr, hHeap, uintptr(dwFlags), dwBytes)
+ // Since this pointer is allocated in the heap by Windows, it will never be
+ // GCd by Go, so this is a safe operation.
+ // But linter thinks it is not (probably because we are not using CGO) and fails.
+ return unsafe.Pointer(allocatedPtr) //nolint:gosec,govet
+}
+
+// https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapfree
+func heapFree(hHeap heapHandle, dwFlags heapFlags, lpMem unsafe.Pointer) (bool, win32Error) {
+ addr := getProcAddr(&pHeapFree, libKernel32, "HeapFree")
+ ret, _, err := syscall.SyscallN(addr, hHeap, uintptr(dwFlags), uintptr(lpMem))
+ return ret == 0, win32Error(err)
+}
+
+func getProcessHeap() (heapHandle, win32Error) {
+ addr := getProcAddr(&pGetProcessHeap, libKernel32, "GetProcessHeap")
+ ret, _, err := syscall.SyscallN(addr)
+ return ret, win32Error(err)
+}
+
+func getProcAddr(pAddr *uintptr, lib *windows.LazyDLL, procName string) uintptr {
+ addr := atomic.LoadUintptr(pAddr)
+ if addr == 0 {
+ addr = lib.NewProc(procName).Addr()
+ atomic.StoreUintptr(pAddr, addr)
+ }
+ return addr
+}
diff --git a/internal/winrt/data/xml/dom/xmldocument.go b/internal/winrt/data/xml/dom/xmldocument.go
@@ -0,0 +1,73 @@
+// Code generated by winrt-go-gen. DO NOT EDIT.
+
+//go:build windows
+
+//nolint:all
+package dom
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/go-ole/go-ole"
+)
+
+const SignatureXmlDocument string = "rc(Windows.Data.Xml.Dom.XmlDocument;{f7f3a506-1e87-42d6-bcfb-b8c809fa5494})"
+
+type XmlDocument struct {
+ ole.IUnknown
+}
+
+func NewXmlDocument() (*XmlDocument, error) {
+ inspectable, err := ole.RoActivateInstance("Windows.Data.Xml.Dom.XmlDocument")
+ if err != nil {
+ return nil, err
+ }
+ return (*XmlDocument)(unsafe.Pointer(inspectable)), nil
+}
+
+func (impl *XmlDocument) LoadXml(xml string) error {
+ itf := impl.MustQueryInterface(ole.NewGUID(GUIDiXmlDocumentIO))
+ defer itf.Release()
+ v := (*iXmlDocumentIO)(unsafe.Pointer(itf))
+ return v.LoadXml(xml)
+}
+
+const (
+ GUIDiXmlDocumentIO string = "6cd0e74e-ee65-4489-9ebf-ca43e87ba637"
+ SignatureiXmlDocumentIO string = "{6cd0e74e-ee65-4489-9ebf-ca43e87ba637}"
+)
+
+type iXmlDocumentIO struct {
+ ole.IInspectable
+}
+
+type iXmlDocumentIOVtbl struct {
+ ole.IInspectableVtbl
+
+ LoadXml uintptr
+ LoadXmlWithSettings uintptr
+ SaveToFileAsync uintptr
+}
+
+func (v *iXmlDocumentIO) VTable() *iXmlDocumentIOVtbl {
+ return (*iXmlDocumentIOVtbl)(unsafe.Pointer(v.RawVTable))
+}
+
+func (v *iXmlDocumentIO) LoadXml(xml string) error {
+ xmlHStr, err := ole.NewHString(xml)
+ if err != nil {
+ return err
+ }
+ hr, _, _ := syscall.SyscallN(
+ v.VTable().LoadXml,
+ uintptr(unsafe.Pointer(v)), // this
+ uintptr(xmlHStr), // in string
+ )
+
+ if hr != 0 {
+ return ole.NewError(hr)
+ }
+
+ return nil
+}
diff --git a/internal/winrt/ui/notifications/toastnotification.go b/internal/winrt/ui/notifications/toastnotification.go
@@ -0,0 +1,88 @@
+// Code generated by winrt-go-gen. DO NOT EDIT.
+
+//go:build windows
+
+//nolint:all
+package notifications
+
+import (
+ "syscall"
+ "unsafe"
+
+ "git.sr.ht/~jackmordaunt/go-toast/internal/winrt/data/xml/dom"
+ "github.com/go-ole/go-ole"
+)
+
+const SignatureToastNotification string = "rc(Windows.UI.Notifications.ToastNotification;{997e2675-059e-4e60-8b06-1760917c8b80})"
+
+func CreateToastNotification(content *dom.XmlDocument) (*ToastNotification, error) {
+ inspectable, err := ole.RoGetActivationFactory("Windows.UI.Notifications.ToastNotification", ole.NewGUID(GUIDiToastNotificationFactory))
+ if err != nil {
+ return nil, err
+ }
+ v := (*iToastNotificationFactory)(unsafe.Pointer(inspectable))
+
+ var out *ToastNotification
+ hr, _, _ := syscall.SyscallN(
+ v.VTable().CreateToastNotification,
+ 0, // this is a static func, so there's no this
+ uintptr(unsafe.Pointer(content)), // in dom.XmlDocument
+ uintptr(unsafe.Pointer(&out)), // out ToastNotification
+ )
+
+ if hr != 0 {
+ return nil, ole.NewError(hr)
+ }
+
+ return out, nil
+}
+
+type ToastNotification struct {
+ ole.IUnknown
+}
+
+const (
+ GUIDiToastNotification string = "997e2675-059e-4e60-8b06-1760917c8b80"
+ SignatureiToastNotification string = "{997e2675-059e-4e60-8b06-1760917c8b80}"
+)
+
+type iToastNotification struct {
+ ole.IInspectable
+}
+
+type iToastNotificationVtbl struct {
+ ole.IInspectableVtbl
+
+ GetContent uintptr
+ SetExpirationTime uintptr
+ GetExpirationTime uintptr
+ AddDismissed uintptr
+ RemoveDismissed uintptr
+ AddActivated uintptr
+ RemoveActivated uintptr
+ AddFailed uintptr
+ RemoveFailed uintptr
+}
+
+func (v *iToastNotification) VTable() *iToastNotificationVtbl {
+ return (*iToastNotificationVtbl)(unsafe.Pointer(v.RawVTable))
+}
+
+const (
+ GUIDiToastNotificationFactory string = "04124b20-82c6-4229-b109-fd9ed4662b53"
+ SignatureiToastNotificationFactory string = "{04124b20-82c6-4229-b109-fd9ed4662b53}"
+)
+
+type iToastNotificationFactory struct {
+ ole.IInspectable
+}
+
+type iToastNotificationFactoryVtbl struct {
+ ole.IInspectableVtbl
+
+ CreateToastNotification uintptr
+}
+
+func (v *iToastNotificationFactory) VTable() *iToastNotificationFactoryVtbl {
+ return (*iToastNotificationFactoryVtbl)(unsafe.Pointer(v.RawVTable))
+}
diff --git a/internal/winrt/ui/notifications/toastnotificationmanager.go b/internal/winrt/ui/notifications/toastnotificationmanager.go
@@ -0,0 +1,53 @@
+// Code generated by winrt-go-gen. DO NOT EDIT.
+
+//go:build windows
+
+//nolint:all
+package notifications
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/go-ole/go-ole"
+)
+
+const (
+ GUIDiToastNotificationManagerStatics5 string = "d6f5f569-d40d-407c-8989-88cab42cfd14"
+ SignatureiToastNotificationManagerStatics5 string = "{d6f5f569-d40d-407c-8989-88cab42cfd14}"
+)
+
+type iToastNotificationManagerStatics5 struct {
+ ole.IInspectable
+}
+
+type iToastNotificationManagerStatics5Vtbl struct {
+ ole.IInspectableVtbl
+
+ GetDefault uintptr
+}
+
+func (v *iToastNotificationManagerStatics5) VTable() *iToastNotificationManagerStatics5Vtbl {
+ return (*iToastNotificationManagerStatics5Vtbl)(unsafe.Pointer(v.RawVTable))
+}
+
+func GetDefault() (*ToastNotificationManagerForUser, error) {
+ inspectable, err := ole.RoGetActivationFactory("Windows.UI.Notifications.ToastNotificationManager", ole.NewGUID(GUIDiToastNotificationManagerStatics5))
+ if err != nil {
+ return nil, err
+ }
+ v := (*iToastNotificationManagerStatics5)(unsafe.Pointer(inspectable))
+
+ var out *ToastNotificationManagerForUser
+ hr, _, _ := syscall.SyscallN(
+ v.VTable().GetDefault,
+ 0, // this is a static func, so there's no this
+ uintptr(unsafe.Pointer(&out)), // out ToastNotificationManagerForUser
+ )
+
+ if hr != 0 {
+ return nil, ole.NewError(hr)
+ }
+
+ return out, nil
+}
diff --git a/internal/winrt/ui/notifications/toastnotificationmanagerforuser.go b/internal/winrt/ui/notifications/toastnotificationmanagerforuser.go
@@ -0,0 +1,68 @@
+// Code generated by winrt-go-gen. DO NOT EDIT.
+
+//go:build windows
+
+//nolint:all
+package notifications
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/go-ole/go-ole"
+)
+
+const SignatureToastNotificationManagerForUser string = "rc(Windows.UI.Notifications.ToastNotificationManagerForUser;{79ab57f6-43fe-487b-8a7f-99567200ae94})"
+
+type ToastNotificationManagerForUser struct {
+ ole.IUnknown
+}
+
+func (impl *ToastNotificationManagerForUser) CreateToastNotifierWithId(applicationId string) (*ToastNotifier, error) {
+ itf := impl.MustQueryInterface(ole.NewGUID(GUIDiToastNotificationManagerForUser))
+ defer itf.Release()
+ v := (*iToastNotificationManagerForUser)(unsafe.Pointer(itf))
+ return v.CreateToastNotifierWithId(applicationId)
+}
+
+const (
+ GUIDiToastNotificationManagerForUser string = "79ab57f6-43fe-487b-8a7f-99567200ae94"
+ SignatureiToastNotificationManagerForUser string = "{79ab57f6-43fe-487b-8a7f-99567200ae94}"
+)
+
+type iToastNotificationManagerForUser struct {
+ ole.IInspectable
+}
+
+type iToastNotificationManagerForUserVtbl struct {
+ ole.IInspectableVtbl
+
+ CreateToastNotifier uintptr
+ CreateToastNotifierWithId uintptr
+ GetHistory uintptr
+ GetUser uintptr
+}
+
+func (v *iToastNotificationManagerForUser) VTable() *iToastNotificationManagerForUserVtbl {
+ return (*iToastNotificationManagerForUserVtbl)(unsafe.Pointer(v.RawVTable))
+}
+
+func (v *iToastNotificationManagerForUser) CreateToastNotifierWithId(applicationId string) (*ToastNotifier, error) {
+ var out *ToastNotifier
+ applicationIdHStr, err := ole.NewHString(applicationId)
+ if err != nil {
+ return nil, err
+ }
+ hr, _, _ := syscall.SyscallN(
+ v.VTable().CreateToastNotifierWithId,
+ uintptr(unsafe.Pointer(v)), // this
+ uintptr(applicationIdHStr), // in string
+ uintptr(unsafe.Pointer(&out)), // out ToastNotifier
+ )
+
+ if hr != 0 {
+ return nil, ole.NewError(hr)
+ }
+
+ return out, nil
+}
diff --git a/internal/winrt/ui/notifications/toastnotifier.go b/internal/winrt/ui/notifications/toastnotifier.go
@@ -0,0 +1,64 @@
+// Code generated by winrt-go-gen. DO NOT EDIT.
+
+//go:build windows
+
+//nolint:all
+package notifications
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/go-ole/go-ole"
+)
+
+const SignatureToastNotifier string = "rc(Windows.UI.Notifications.ToastNotifier;{75927b93-03f3-41ec-91d3-6e5bac1b38e7})"
+
+type ToastNotifier struct {
+ ole.IUnknown
+}
+
+func (impl *ToastNotifier) Show(notification *ToastNotification) error {
+ itf := impl.MustQueryInterface(ole.NewGUID(GUIDiToastNotifier))
+ defer itf.Release()
+ v := (*iToastNotifier)(unsafe.Pointer(itf))
+ return v.Show(notification)
+}
+
+const (
+ GUIDiToastNotifier string = "75927b93-03f3-41ec-91d3-6e5bac1b38e7"
+ SignatureiToastNotifier string = "{75927b93-03f3-41ec-91d3-6e5bac1b38e7}"
+)
+
+type iToastNotifier struct {
+ ole.IInspectable
+}
+
+type iToastNotifierVtbl struct {
+ ole.IInspectableVtbl
+
+ Show uintptr
+ Hide uintptr
+ GetSetting uintptr
+ AddToSchedule uintptr
+ RemoveFromSchedule uintptr
+ GetScheduledToastNotifications uintptr
+}
+
+func (v *iToastNotifier) VTable() *iToastNotifierVtbl {
+ return (*iToastNotifierVtbl)(unsafe.Pointer(v.RawVTable))
+}
+
+func (v *iToastNotifier) Show(notification *ToastNotification) error {
+ hr, _, _ := syscall.SyscallN(
+ v.VTable().Show,
+ uintptr(unsafe.Pointer(v)), // this
+ uintptr(unsafe.Pointer(notification)), // in ToastNotification
+ )
+
+ if hr != 0 {
+ return ole.NewError(hr)
+ }
+
+ return nil
+}