1//go:build windows
2// +build windows
3
4package uv
5
6import (
7 "fmt"
8
9 "github.com/charmbracelet/x/term"
10 "golang.org/x/sys/windows"
11)
12
13func (t *Terminal) makeRaw() (err error) {
14 if t.inTty == nil || t.outTty == nil || !term.IsTerminal(t.inTty.Fd()) || !term.IsTerminal(t.outTty.Fd()) {
15 return ErrNotTerminal
16 }
17
18 // Save stdin state and enable VT input.
19 // We also need to enable VT input here.
20 t.inTtyState, err = term.MakeRaw(t.inTty.Fd())
21 if err != nil {
22 return fmt.Errorf("error making terminal raw: %w", err)
23 }
24
25 // Enable VT input
26 var imode uint32
27 if err := windows.GetConsoleMode(windows.Handle(t.inTty.Fd()), &imode); err != nil {
28 return fmt.Errorf("error getting console mode: %w", err)
29 }
30
31 if err := windows.SetConsoleMode(windows.Handle(t.inTty.Fd()), imode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {
32 return fmt.Errorf("error setting console mode: %w", err)
33 }
34
35 // Save output screen buffer state and enable VT processing.
36 t.outTtyState, err = term.GetState(t.outTty.Fd())
37 if err != nil {
38 return fmt.Errorf("error getting terminal state: %w", err)
39 }
40
41 var omode uint32
42 if err := windows.GetConsoleMode(windows.Handle(t.outTty.Fd()), &omode); err != nil {
43 return fmt.Errorf("error getting console mode: %w", err)
44 }
45
46 if err := windows.SetConsoleMode(windows.Handle(t.outTty.Fd()),
47 omode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|
48 windows.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
49 return fmt.Errorf("error setting console mode: %w", err)
50 }
51
52 return //nolint:nakedret
53}
54
55func (t *Terminal) getSize() (w, h int, err error) {
56 if t.outTty != nil {
57 return term.GetSize(t.outTty.Fd())
58 }
59 return 0, 0, ErrNotTerminal
60}
61
62func (t *Terminal) optimizeMovements() {
63 t.useBspace = true
64 t.useTabs = true
65}
66
67func (t *Terminal) setMouse(enable bool) (err error) {
68 inTty := t.inTty
69 if inTty == nil {
70 _, inTty, err = openTTY()
71 if err != nil {
72 return err
73 }
74 }
75 state, err := term.GetState(inTty.Fd())
76 if err != nil {
77 return err
78 }
79 if enable {
80 state.Mode |= windows.ENABLE_MOUSE_INPUT
81 } else {
82 state.Mode &^= windows.ENABLE_MOUSE_INPUT
83 }
84 return term.SetState(inTty.Fd(), state)
85}
86
87func (t *Terminal) enableWindowsMouse() (err error) {
88 return t.setMouse(true)
89}
90
91func (t *Terminal) disableWindowsMouse() (err error) {
92 return t.setMouse(false)
93}