Skip to content

Commit

Permalink
Use runtime.Pinner to pin object
Browse files Browse the repository at this point in the history
  • Loading branch information
kbinani committed Jan 18, 2025
1 parent 4c885c4 commit d6fdf5e
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 43 deletions.
43 changes: 0 additions & 43 deletions windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,49 +95,6 @@ func Capture(x, y, width, height int) (*image.RGBA, error) {
return img, nil
}

func NumActiveDisplays() int {
// It appears that `count` may be relocated after calling enumDisplayMonitors.
// Therefore, using `uintptr(unsafe.Pointer(&count))` to obtain memory directly may lead to
// reading undefined values. To address this, we're using an approach that allocates memory
// directly on the native heap.
// Please refer to the discussions on https://github.com/kbinani/screenshot/pull/36 for details
var count int
hmem := win.GlobalAlloc(win.GMEM_MOVEABLE, unsafe.Sizeof(count))
defer win.GlobalFree(hmem)
ptr := win.GlobalLock(hmem)
defer win.GlobalUnlock(hmem)

*(*int)(ptr) = 0

enumDisplayMonitors(win.HDC(0), nil, syscall.NewCallback(countupMonitorCallback), uintptr(ptr))
count = *(*int)(ptr)

return count
}

func GetDisplayBounds(displayIndex int) image.Rectangle {
// It appears that `ctx` may be relocated after calling enumDisplayMonitors.
// Therefore, using `uintptr(unsafe.Pointer(&ctx))` to obtain memory directly may lead to
// reading undefined values. To address this, we're using an approach that allocates memory
// directly on the native heap.
// Please refer to the discussions on https://github.com/kbinani/screenshot/pull/36 for details
var ctx getMonitorBoundsContext
hmem := win.GlobalAlloc(win.GMEM_MOVEABLE, unsafe.Sizeof(ctx))
defer win.GlobalFree(hmem)
ptr := win.GlobalLock(hmem)
defer win.GlobalUnlock(hmem)

(*getMonitorBoundsContext)(ptr).Index = displayIndex
(*getMonitorBoundsContext)(ptr).Count = 0

enumDisplayMonitors(win.HDC(0), nil, syscall.NewCallback(getMonitorBoundsCallback), uintptr(ptr))
ctx = *(*getMonitorBoundsContext)(ptr)

return image.Rect(
int(ctx.Rect.Left), int(ctx.Rect.Top),
int(ctx.Rect.Right), int(ctx.Rect.Bottom))
}

func getDesktopWindow() win.HWND {
ret, _, _ := syscall.Syscall(funcGetDesktopWindow, 0, 0, 0, 0)
return win.HWND(ret)
Expand Down
37 changes: 37 additions & 0 deletions windows_ge1.21.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//go:build windows && go1.21

package screenshot

import (
"image"
"runtime"
"syscall"
"unsafe"

"github.com/lxn/win"
)

func NumActiveDisplays() int {
count := new(int)
pinner := new(runtime.Pinner)
pinner.Pin(count)
defer pinner.Unpin()
*count = 0
ptr := unsafe.Pointer(count)
enumDisplayMonitors(win.HDC(0), nil, syscall.NewCallback(countupMonitorCallback), uintptr(ptr))
return *count
}

func GetDisplayBounds(displayIndex int) image.Rectangle {
ctx := new(getMonitorBoundsContext)
pinner := new(runtime.Pinner)
pinner.Pin(ctx)
defer pinner.Unpin()
ctx.Index = displayIndex
ctx.Count = 0
ptr := unsafe.Pointer(ctx)
enumDisplayMonitors(win.HDC(0), nil, syscall.NewCallback(getMonitorBoundsCallback), uintptr(ptr))
return image.Rect(
int(ctx.Rect.Left), int(ctx.Rect.Top),
int(ctx.Rect.Right), int(ctx.Rect.Bottom))
}
30 changes: 30 additions & 0 deletions windows_lt1.21.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//go:build windows && !go1.21

package screenshot

import (
"image"
"syscall"
"unsafe"

"github.com/lxn/win"
)

func NumActiveDisplays() int {
var count int
count = 0
ptr := unsafe.Pointer(&count)
enumDisplayMonitors(win.HDC(0), nil, syscall.NewCallback(countupMonitorCallback), uintptr(ptr))
return count
}

func GetDisplayBounds(displayIndex int) image.Rectangle {
var ctx getMonitorBoundsContext
ctx.Index = displayIndex
ctx.Count = 0
ptr := unsafe.Pointer(&ctx)
enumDisplayMonitors(win.HDC(0), nil, syscall.NewCallback(getMonitorBoundsCallback), uintptr(ptr))
return image.Rect(
int(ctx.Rect.Left), int(ctx.Rect.Top),
int(ctx.Rect.Right), int(ctx.Rect.Bottom))
}

0 comments on commit d6fdf5e

Please sign in to comment.