-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmouse.go
116 lines (98 loc) · 2.71 KB
/
mouse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package vaxis
import (
"git.sr.ht/~rockorager/vaxis/ansi"
"git.sr.ht/~rockorager/vaxis/log"
)
// Mouse is a mouse event
type Mouse struct {
Button MouseButton
Row int
Col int
EventType EventType
Modifiers ModifierMask
XPixel int
YPixel int
}
// MouseButton represents a mouse button
type MouseButton int
const (
MouseLeftButton MouseButton = iota
MouseMiddleButton
MouseRightButton
MouseNoButton
MouseWheelUp MouseButton = 64
MouseWheelDown MouseButton = 65
MouseButton8 MouseButton = 128
MouseButton9 MouseButton = 129
MouseButton10 MouseButton = 130
MouseButton11 MouseButton = 131
)
// MouseShape is used with OSC 22 to change the shape of the mouse cursor
type MouseShape string
const (
MouseShapeDefault MouseShape = "default"
MouseShapeTextInput MouseShape = "text"
MouseShapeClickable MouseShape = "pointer"
MouseShapeHelp MouseShape = "help"
MouseShapeBusyBackground MouseShape = "progress"
MouseShapeBusy MouseShape = "wait"
MouseShapeResizeHorizontal MouseShape = "ew-resize"
MouseShapeResizeVertical MouseShape = "ns-resize"
// The thick plus sign cursor that's typically used in spread-sheet applications to select cells.
MouseShapeCell MouseShape = "cell"
)
const (
motion = 0b00100000
buttonBits = 0b11000011
mouseModShift = 0b00000100
mouseModAlt = 0b00001000
mouseModCtrl = 0b00010000
)
func pixelToCell(px, length, cells int) int {
if length > 0 {
return px * cells / length
}
return 0
}
func parseMouseEvent(seq ansi.CSI, ws Resize, enableSGRPixels bool) (Mouse, bool) {
mouse := Mouse{}
if len(seq.Intermediate) != 1 && seq.Intermediate[0] != '<' {
log.Error("[CSI] unknown sequence: %s", seq)
return mouse, false
}
if len(seq.Parameters) != 3 {
log.Error("[CSI] unknown sequence: %s", seq)
return mouse, false
}
switch seq.Final {
case 'M':
mouse.EventType = EventPress
case 'm':
mouse.EventType = EventRelease
}
// buttons are encoded with the high two and low two bits
button := seq.Parameters[0][0] & buttonBits
mouse.Button = MouseButton(button)
if seq.Parameters[0][0]&motion != 0 {
mouse.EventType = EventMotion
}
if seq.Parameters[0][0]&mouseModShift != 0 {
mouse.Modifiers |= ModShift
}
if seq.Parameters[0][0]&mouseModAlt != 0 {
mouse.Modifiers |= ModAlt
}
if seq.Parameters[0][0]&mouseModCtrl != 0 {
mouse.Modifiers |= ModCtrl
}
if enableSGRPixels {
mouse.XPixel = seq.Parameters[1][0]
mouse.YPixel = seq.Parameters[2][0]
mouse.Col = pixelToCell(mouse.XPixel, ws.XPixel, ws.Cols)
mouse.Row = pixelToCell(mouse.YPixel, ws.YPixel, ws.Rows)
} else {
mouse.Col = seq.Parameters[1][0] - 1
mouse.Row = seq.Parameters[2][0] - 1
}
return mouse, true
}