terminal_windows.odin 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #+private
  2. package terminal
  3. import "base:runtime"
  4. import "core:os"
  5. import "core:sys/windows"
  6. _is_terminal :: proc "contextless" (handle: os.Handle) -> bool {
  7. is_tty := windows.GetFileType(windows.HANDLE(handle)) == windows.FILE_TYPE_CHAR
  8. return is_tty
  9. }
  10. old_modes: [2]struct{
  11. handle: windows.DWORD,
  12. mode: windows.DWORD,
  13. } = {
  14. {windows.STD_OUTPUT_HANDLE, 0},
  15. {windows.STD_ERROR_HANDLE, 0},
  16. }
  17. @(init)
  18. _init_terminal :: proc "contextless" () {
  19. vtp_enabled: bool
  20. for &v in old_modes {
  21. handle := windows.GetStdHandle(v.handle)
  22. if handle == windows.INVALID_HANDLE || handle == nil {
  23. return
  24. }
  25. if windows.GetConsoleMode(handle, &v.mode) {
  26. windows.SetConsoleMode(handle, v.mode | windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
  27. new_mode: windows.DWORD
  28. windows.GetConsoleMode(handle, &new_mode)
  29. if new_mode & (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0 {
  30. vtp_enabled = true
  31. }
  32. }
  33. }
  34. if vtp_enabled {
  35. // This color depth is available on Windows 10 since build 10586.
  36. color_depth = .Four_Bit
  37. } else {
  38. context = runtime.default_context()
  39. // The user may be on a non-default terminal emulator.
  40. color_depth = get_environment_color()
  41. }
  42. }
  43. @(fini)
  44. _fini_terminal :: proc "contextless" () {
  45. for v in old_modes {
  46. handle := windows.GetStdHandle(v.handle)
  47. if handle == windows.INVALID_HANDLE || handle == nil {
  48. return
  49. }
  50. windows.SetConsoleMode(handle, v.mode)
  51. }
  52. }