refactor(capture): screen capture in subprocess

- Move screen capture to child process
- Isolate GDI/BitBlt crashes from agent
- Use -capture flag for internal helper mode
- Add protocol for frame request/response
- Make monitor enumeration thread-safe
This commit is contained in:
2026-09-01 23:25:38 +03:00
parent cc2b1d049b
commit a3c78820ed
14 changed files with 432 additions and 12 deletions
+21 -9
View File
@@ -7,6 +7,7 @@ import (
"image/jpeg"
"image/png"
"runtime"
"sync"
"syscall"
"unsafe"
@@ -157,19 +158,30 @@ func attachInputDesktop() error {
return nil
}
var (
enumMu sync.Mutex
enumBuf []rect
enumCB = syscall.NewCallback(enumMonitor)
)
func enumMonitor(_ uintptr, _ uintptr, monitorRect uintptr, _ uintptr) uintptr {
if monitorRect != 0 {
enumBuf = append(enumBuf, *(*rect)(unsafe.Pointer(monitorRect)))
}
return 1
}
func enumerateMonitors() ([]rect, error) {
var monitors []rect
callback := syscall.NewCallback(func(_ uintptr, _ uintptr, monitorRect uintptr, _ uintptr) uintptr {
if monitorRect != 0 {
monitors = append(monitors, *(*rect)(unsafe.Pointer(monitorRect)))
}
return 1
})
ok, _, err := procEnumDisplayMonitors.Call(0, 0, callback, 0)
enumMu.Lock()
defer enumMu.Unlock()
enumBuf = enumBuf[:0]
ok, _, err := procEnumDisplayMonitors.Call(0, 0, enumCB, 0)
if ok == 0 {
return nil, err
}
return monitors, nil
out := make([]rect, len(enumBuf))
copy(out, enumBuf)
return out, nil
}
func captureRect(r rect) (*image.RGBA, error) {