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
}
|