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
|
// Useful telnet key detection.
const compareBufStr = (buf, str) => {
return buf.equals(Buffer.from(str.split('').map(c => c.charCodeAt(0))))
}
const telchars = {
isSpace: buf => buf[0] === 0x20,
isEnter: buf => buf[0] === 0x0d,
isTab: buf => buf[0] === 0x09,
isBackTab: buf => buf[0] === 0x1b && buf[2] === 0x5A,
isBackspace: buf => buf[0] === 0x7F,
// isEscape is hard because it's just send as ESC (the ANSI escape code),
// so we need to make sure that the escape code is all on its own
// (i.e. the length is 1)
isEscape: buf => buf[0] === 0x1b && buf.length === 1,
// Use this for when you'd like to detect the user confirming or issuing a
// command, like the X button on your PlayStation controller, or the mouse
// when you click on a button.
isSelect: buf => telchars.isSpace(buf) || telchars.isEnter(buf),
// Use this for when you'd like to detect the user cancelling an action,
// like the O button on your PlayStation controller, or the Escape key on
// your keyboard.
isCancel: buf => telchars.isEscape(buf),
isUp: buf => buf[0] === 0x1b && buf[2] === 0x41,
isDown: buf => buf[0] === 0x1b && buf[2] === 0x42,
isRight: buf => buf[0] === 0x1b && buf[2] === 0x43,
isLeft: buf => buf[0] === 0x1b && buf[2] === 0x44,
// Mouse constants!
mapMouseActionNum: num => {
let button = null
if (num & 64) {
if (num & 1) button = 'scroll-down'
else button = 'scroll-up'
} else {
const drag = num & 32
const bits = num & 3
if (bits === 0) button = 'left'
else if (bits === 1) button = 'middle'
else if (bits === 2) button = 'right'
else if (bits === 3) button = 'release'
if (drag) {
button = 'drag-' + button
}
}
const shift = !!(num & 4)
const ctrl = !!(num & 16)
return {button, shift, ctrl}
},
isMouse: buf => buf[0] === 0x1b && buf[2] === 0x4d,
parseMouse: buf => {
if (!telchars.isMouse(buf)) {
return null
}
const actionNum = buf[3] - 32
const col = buf[4] - 32
const line = buf[5] - 32
const { button, shift, ctrl } = telchars.mapMouseActionNum(actionNum)
return {button, shift, ctrl, col, line, actionNum}
},
isShiftUp: buf => compareBufStr(buf, '\x1b[1;2A'),
isShiftDown: buf => compareBufStr(buf, '\x1b[1;2B'),
isShiftRight: buf => compareBufStr(buf, '\x1b[1;2C'),
isShiftLeft: buf => compareBufStr(buf, '\x1b[1;2D'),
isControlUp: buf => compareBufStr(buf, '\x1b[1;5A'),
isControlDown: buf => compareBufStr(buf, '\x1b[1;5B'),
isControlRight: buf => compareBufStr(buf, '\x1b[1;5C'),
isControlLeft: buf => compareBufStr(buf, '\x1b[1;5D'),
isPageUp: buf => compareBufStr(buf, '\x1b[5~'),
isPageDown: buf => compareBufStr(buf, '\x1b[6~'),
isCaselessLetter: (buf, letter) => compareBufStr(buf, letter.toLowerCase()) || compareBufStr(buf, letter.toUpperCase()),
isCharacter: (buf, char) => compareBufStr(buf, char),
}
module.exports = telchars
|