fixed saved peripherals for a new project

This commit is contained in:
2024-12-29 21:22:53 +01:00
parent b69097e2a4
commit 556f24991e
12 changed files with 264 additions and 169 deletions

View File

@@ -49,41 +49,35 @@ func NewHardwareManager() *HardwareManager {
// Start starts to find new peripheral events
func (h *HardwareManager) Start(ctx context.Context) error {
// Configure wndProc callback
cb := windows.NewCallback(h.wndProc)
log.Trace().Str("file", "hardware").Msg("wndProc callback set")
inst := win.GetModuleHandle(nil)
log.Trace().Str("file", "hardware").Msg("got windows API instance")
cn, err := syscall.UTF16PtrFromString("DMXConnect peripheral watcher")
// Register window class
className, err := syscall.UTF16PtrFromString("DMXConnectPeripheralWatcher")
if err != nil {
log.Err(err).Str("file", "hardware").Msg("failed to convert window class name to UTF16")
return fmt.Errorf("failed to convert window class name to UTF16: %w", err)
}
wc := win.WNDCLASSEX{
CbSize: uint32(unsafe.Sizeof(win.WNDCLASSEX{})),
HInstance: inst,
LpfnWndProc: cb,
LpszClassName: cn,
LpszClassName: className,
}
log.Trace().Str("file", "hardware").Msg("windows API class created")
wc.CbSize = uint32(unsafe.Sizeof(wc))
if win.RegisterClassEx(&wc) == 0 {
log.Err(syscall.GetLastError()).Str("file", "hardware").Msg("failed to register window class")
return fmt.Errorf("failed to register window class: %w", syscall.GetLastError())
}
log.Trace().Str("file", "hardware").Msg("window class registered")
wName, err := syscall.UTF16PtrFromString("usbevent.exe")
// Create hidden window
windowName, err := syscall.UTF16PtrFromString("usbevent.exe")
if err != nil {
log.Err(err).Str("file", "hardware").Msg("failed to convert window class name to UTF16")
return fmt.Errorf("failed to convert window name to UTF16: %w", err)
}
wdw := win.CreateWindowEx(
hwnd := win.CreateWindowEx(
0,
wc.LpszClassName,
wName,
win.WS_MINIMIZE|win.WS_OVERLAPPEDWINDOW,
windowName,
win.WS_OVERLAPPEDWINDOW,
win.CW_USEDEFAULT,
win.CW_USEDEFAULT,
100,
@@ -91,34 +85,18 @@ func (h *HardwareManager) Start(ctx context.Context) error {
0,
0,
wc.HInstance,
nil)
if wdw == 0 {
log.Err(syscall.GetLastError()).Str("file", "hardware").Msg("failed to create window")
nil,
)
if hwnd == 0 {
return fmt.Errorf("failed to create window: %w", syscall.GetLastError())
}
log.Trace().Str("file", "hardware").Msg("window created successfully")
_ = win.ShowWindow(wdw, win.SW_HIDE)
win.UpdateWindow(wdw)
log.Trace().Str("file", "hardware").Msg("window shown and updated")
// Hide and update window
win.ShowWindow(hwnd, win.SW_HIDE)
win.UpdateWindow(hwnd)
// To continuously get the devices events from Windows
go func() {
defer log.Debug().Str("file", "hardware").Msg("peripheral watcher goroutine exited")
for {
select {
case <-ctx.Done():
return
default:
var msg win.MSG
got := win.GetMessage(&msg, win.HWND(windows.HWND(wdw)), 0, 0)
if got == 0 {
win.TranslateMessage(&msg)
win.DispatchMessage(&msg)
}
}
}
}()
// Start message loop in a goroutine
go messageLoop(ctx, hwnd)
// To handle the peripheral changed
go func() {
@@ -139,6 +117,31 @@ func (h *HardwareManager) Start(ctx context.Context) error {
return nil
}
func messageLoop(ctx context.Context, hwnd win.HWND) {
defer log.Debug().Str("file", "hardware").Msg("Peripheral watcher goroutine exited")
for {
select {
case <-ctx.Done():
win.PostQuitMessage(0) // Gracefully terminate message loop
return
default:
var msg win.MSG
result := win.GetMessage(&msg, hwnd, 0, 0)
if result > 0 {
win.TranslateMessage(&msg)
win.DispatchMessage(&msg)
} else if result == 0 {
log.Warn().Str("file", "hardware").Msg("WM_QUIT message received")
return
} else {
log.Error().Str("file", "hardware").Msg("GetMessage returned an error")
return
}
}
}
}
// GetDriver returns a register driver
func (h *HardwareManager) GetDriver(driverName string) (PeripheralDriver, error) {
driver, exists := h.drivers[driverName]
@@ -190,6 +193,7 @@ func (h *HardwareManager) Scan(ctx context.Context) error {
}
func (h *HardwareManager) wndProc(hwnd windows.HWND, msg uint32, wParam, lParam uintptr) uintptr {
log.Trace().Str("file", "hardware").Msg("wndProc triggered")
switch msg {
case win.WM_DEVICECHANGE:
// Trigger the devices scan when the last DEVICE_CHANGE event is received