cursor_windows.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package terminal
  2. import (
  3. "os"
  4. "syscall"
  5. "unsafe"
  6. )
  7. func CursorUp(n int) {
  8. cursorMove(0, n)
  9. }
  10. func CursorDown(n int) {
  11. cursorMove(0, -1*n)
  12. }
  13. func CursorForward(n int) {
  14. cursorMove(n, 0)
  15. }
  16. func CursorBack(n int) {
  17. cursorMove(-1*n, 0)
  18. }
  19. func cursorMove(x int, y int) {
  20. handle := syscall.Handle(os.Stdout.Fd())
  21. var csbi consoleScreenBufferInfo
  22. procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
  23. var cursor Coord
  24. cursor.X = csbi.cursorPosition.X + Short(x)
  25. cursor.Y = csbi.cursorPosition.Y + Short(y)
  26. procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor))))
  27. }
  28. func CursorNextLine(n int) {
  29. CursorUp(n)
  30. CursorHorizontalAbsolute(0)
  31. }
  32. func CursorPreviousLine(n int) {
  33. CursorDown(n)
  34. CursorHorizontalAbsolute(0)
  35. }
  36. func CursorHorizontalAbsolute(x int) {
  37. handle := syscall.Handle(os.Stdout.Fd())
  38. var csbi consoleScreenBufferInfo
  39. procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
  40. var cursor Coord
  41. cursor.X = Short(x)
  42. cursor.Y = csbi.cursorPosition.Y
  43. if csbi.size.X < cursor.X {
  44. cursor.X = csbi.size.X
  45. }
  46. procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor))))
  47. }
  48. func CursorShow() {
  49. handle := syscall.Handle(os.Stdout.Fd())
  50. var cci consoleCursorInfo
  51. procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci)))
  52. cci.visible = 1
  53. procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci)))
  54. }
  55. func CursorHide() {
  56. handle := syscall.Handle(os.Stdout.Fd())
  57. var cci consoleCursorInfo
  58. procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci)))
  59. cci.visible = 0
  60. procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci)))
  61. }
  62. func CursorLocation() (Coord, error) {
  63. handle := syscall.Handle(os.Stdout.Fd())
  64. var csbi consoleScreenBufferInfo
  65. procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
  66. return csbi.cursorPosition, nil
  67. }
  68. func Size() (Coord, error) {
  69. handle := syscall.Handle(os.Stdout.Fd())
  70. var csbi consoleScreenBufferInfo
  71. procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
  72. return csbi.size, nil
  73. }