// +build windows
package ct
import (
"syscall"
"unsafe"
)
var fg_colors = []uint16{
0,
0,
foreground_red,
foreground_green,
foreground_red | foreground_green,
foreground_blue,
foreground_red | foreground_blue,
foreground_green | foreground_blue,
foreground_red | foreground_green | foreground_blue}
var bg_colors = []uint16{
0,
0,
background_red,
background_green,
background_red | background_green,
background_blue,
background_red | background_blue,
background_green | background_blue,
background_red | background_green | background_blue}
const (
foreground_blue = uint16(0x0001)
foreground_green = uint16(0x0002)
foreground_red = uint16(0x0004)
foreground_intensity = uint16(0x0008)
background_blue = uint16(0x0010)
background_green = uint16(0x0020)
background_red = uint16(0x0040)
background_intensity = uint16(0x0080)
foreground_mask = foreground_blue | foreground_green | foreground_red | foreground_intensity
background_mask = background_blue | background_green | background_red | background_intensity
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetStdHandle = kernel32.NewProc("GetStdHandle")
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
hStdout uintptr
initScreenInfo *console_screen_buffer_info
)
func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
ret, _, _ := procSetConsoleTextAttribute.Call(
hConsoleOutput,
uintptr(wAttributes))
return ret != 0
}
type coord struct {
X, Y int16
}
type small_rect struct {
Left, Top, Right, Bottom int16
}
type console_screen_buffer_info struct {
DwSize coord
DwCursorPosition coord
WAttributes uint16
SrWindow small_rect
DwMaximumWindowSize coord
}
func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *console_screen_buffer_info {
var csbi console_screen_buffer_info
if ret, _, _ := procGetConsoleScreenBufferInfo.Call(hConsoleOutput, uintptr(unsafe.Pointer(&csbi))); ret == 0 {
return nil
}
return &csbi
}
const (
std_output_handle = uint32(-11 & 0xFFFFFFFF)
)
func init() {
kernel32 := syscall.NewLazyDLL("kernel32.dll")
procGetStdHandle = kernel32.NewProc("GetStdHandle")
hStdout, _, _ = procGetStdHandle.Call(uintptr(std_output_handle))
initScreenInfo = getConsoleScreenBufferInfo(hStdout)
syscall.LoadDLL("")
}
func resetColor() {
if initScreenInfo == nil { // No console info - Ex: stdout redirection
return
}
setConsoleTextAttribute(hStdout, initScreenInfo.WAttributes)
}
func changeColor(fg Color, fgBright bool, bg Color, bgBright bool) {
attr := uint16(0)
if fg == None || bg == None {
cbufinfo := getConsoleScreenBufferInfo(hStdout)
if cbufinfo == nil { // No console info - Ex: stdout redirection
return
}
attr = cbufinfo.WAttributes
}
if fg != None {
attr = attr & ^foreground_mask | fg_colors[fg]
if fgBright {
attr |= foreground_intensity
}
}
if bg != None {
attr = attr & ^background_mask | bg_colors[bg]
if bgBright {
attr |= background_intensity
}
}
setConsoleTextAttribute(hStdout, attr)
}