140 lines
3.2 KiB
Go
140 lines
3.2 KiB
Go
|
// +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
|
||
|
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
|
||
|
hConsoleOutput,
|
||
|
uintptr(unsafe.Pointer(&csbi)))
|
||
|
if 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 = getConsoleScreenBufferInfo(hStdout).WAttributes
|
||
|
} // if
|
||
|
|
||
|
if fg != None {
|
||
|
attr = attr & ^foreground_mask | fg_colors[fg]
|
||
|
if fgBright {
|
||
|
attr |= foreground_intensity
|
||
|
} // if
|
||
|
} // if
|
||
|
|
||
|
if bg != None {
|
||
|
attr = attr & ^background_mask | bg_colors[bg]
|
||
|
if bgBright {
|
||
|
attr |= background_intensity
|
||
|
} // if
|
||
|
} // if
|
||
|
|
||
|
setConsoleTextAttribute(hStdout, attr)
|
||
|
}
|