Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions image.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package main
import (
"image"
"os"
"syscall"
"unsafe"
)

const defaultRatio float64 = 7.0 / 3.0 // The terminal's default cursor width/height ratio
Expand All @@ -20,22 +18,6 @@ func load(filename string) (image.Image, error) {
return img, err
}

// canvasSize returns the terminal columns, rows, and cursor aspect ratio
func canvasSize() (int, int, float64) {
var size [4]uint16
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(os.Stdout.Fd()), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&size)), 0, 0, 0); err != 0 {
panic(err)
}
rows, cols, width, height := size[0], size[1], size[2], size[3]

var whratio = defaultRatio
if width > 0 && height > 0 {
whratio = float64(height/rows) / float64(width/cols)
}

return int(cols), int(rows), whratio
}

// scales calculates the image scale to fit within the terminal width/height
func scale(imgW, imgH, termW, termH int, whratio float64) float64 {
hr := float64(imgH) / (float64(termH) * whratio)
Expand Down
36 changes: 36 additions & 0 deletions size_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Builds for these work but not all the resultant binaries have been tested.
// +build darwin dragonfly freebsd linux netbsd openbsd

// Note that as of at least termbox-go@v1.1.1 the following GOOS
// do not build (for termbox):
// aix
// illumos
// plan9
// solaris
// For other reasons, pxl doesn't appear to build on GOOS:
// android
// ios

package main

import (
"os"
"syscall"
"unsafe"
)

// canvasSize returns the terminal columns, rows, and cursor aspect ratio
func canvasSize() (int, int, float64) {
var size [4]uint16
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(os.Stdout.Fd()), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&size)), 0, 0, 0); err != 0 {
panic(err)
}
rows, cols, width, height := size[0], size[1], size[2], size[3]

var whratio = defaultRatio
if width > 0 && height > 0 {
whratio = float64(height/rows) / float64(width/cols)
}

return int(cols), int(rows), whratio
}
79 changes: 79 additions & 0 deletions size_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package main

import (
"sync"
"syscall"
"unsafe"

"github.com/nsf/termbox-go"
)

// canvasSize returns the terminal columns, rows, and cursor aspect ratio
func canvasSize() (int, int, float64) {
cols, rows := termbox.Size()
var whratio = defaultRatio
if width, height, err := primarySize(); err == nil && width > 0 && height > 0 {
whratio = float64(height/rows) / float64(width/cols)
}
return cols, rows, whratio
}

// Extracted (and trimmed down) from
// https://gist.github.com/dchapes/b90e4e0bde7d2672647b0d479ed42dbe
// (That's also why there are several functions and a bit more
// boiler plate that required for this one user32.dll call).

const spiGetWorkArea = 0x0030

var winapi struct {
once sync.Once
systemParametersInfo uintptr
err error
}

func loadWinAPI() {
winapi.once.Do(func() {
libuser32, err := syscall.LoadLibrary("user32.dll")
if err != nil {
winapi.err = err
return
}
winapi.systemParametersInfo, winapi.err = syscall.GetProcAddress(libuser32, "SystemParametersInfoW")
})
}

func systemParametersInfo(uiAction, uiParam uint32, pvParam unsafe.Pointer, fWinIni uint32) error {
loadWinAPI()
if winapi.err != nil {
return winapi.err
}

r1, _, err := syscall.Syscall6(winapi.systemParametersInfo, 4,
uintptr(uiAction), uintptr(uiParam),
uintptr(pvParam), uintptr(fWinIni), 0, 0)
if r1 == 0 {
return err
}
return nil
}

// primarySize returns the size of the primary display monitor.
func primarySize() (width, height int, err error) {
var rect struct {
left uint32
top uint32
right uint32
bottom uint32
// extra size as a safety margin
_ uint32
_ uint32
_ uint32
_ uint32
}
err = systemParametersInfo(spiGetWorkArea, 0, unsafe.Pointer(&rect.left), 0)
if err != nil {
return 0, 0, err
}
return int(rect.right) - int(rect.left),
int(rect.bottom) - int(rect.top), nil
}