output_windows.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package liner
  2. import (
  3. "unsafe"
  4. )
  5. type coord struct {
  6. x, y int16
  7. }
  8. type smallRect struct {
  9. left, top, right, bottom int16
  10. }
  11. type consoleScreenBufferInfo struct {
  12. dwSize coord
  13. dwCursorPosition coord
  14. wAttributes int16
  15. srWindow smallRect
  16. dwMaximumWindowSize coord
  17. }
  18. func (s *State) cursorPos(x int) {
  19. var sbi consoleScreenBufferInfo
  20. procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
  21. procSetConsoleCursorPosition.Call(uintptr(s.hOut),
  22. uintptr(int(x)&0xFFFF|int(sbi.dwCursorPosition.y)<<16))
  23. }
  24. func (s *State) eraseLine() {
  25. var sbi consoleScreenBufferInfo
  26. procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
  27. var numWritten uint32
  28. procFillConsoleOutputCharacter.Call(uintptr(s.hOut), uintptr(' '),
  29. uintptr(sbi.dwSize.x-sbi.dwCursorPosition.x),
  30. uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|int(sbi.dwCursorPosition.y)<<16),
  31. uintptr(unsafe.Pointer(&numWritten)))
  32. }
  33. func (s *State) eraseScreen() {
  34. var sbi consoleScreenBufferInfo
  35. procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
  36. var numWritten uint32
  37. procFillConsoleOutputCharacter.Call(uintptr(s.hOut), uintptr(' '),
  38. uintptr(sbi.dwSize.x)*uintptr(sbi.dwSize.y),
  39. 0,
  40. uintptr(unsafe.Pointer(&numWritten)))
  41. procSetConsoleCursorPosition.Call(uintptr(s.hOut), 0)
  42. }
  43. func (s *State) moveUp(lines int) {
  44. var sbi consoleScreenBufferInfo
  45. procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
  46. procSetConsoleCursorPosition.Call(uintptr(s.hOut),
  47. uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|(int(sbi.dwCursorPosition.y)-lines)<<16))
  48. }
  49. func (s *State) moveDown(lines int) {
  50. var sbi consoleScreenBufferInfo
  51. procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
  52. procSetConsoleCursorPosition.Call(uintptr(s.hOut),
  53. uintptr(int(sbi.dwCursorPosition.x)&0xFFFF|(int(sbi.dwCursorPosition.y)+lines)<<16))
  54. }
  55. func (s *State) emitNewLine() {
  56. // windows doesn't need to omit a new line
  57. }
  58. func (s *State) getColumns() {
  59. var sbi consoleScreenBufferInfo
  60. procGetConsoleScreenBufferInfo.Call(uintptr(s.hOut), uintptr(unsafe.Pointer(&sbi)))
  61. s.columns = int(sbi.dwSize.x)
  62. if s.columns > 1 {
  63. // Windows 10 needs a spare column for the cursor
  64. s.columns--
  65. }
  66. }