From 1f434c1ef11fa55bab1718ea4e3ca8d115c0dfb1 Mon Sep 17 00:00:00 2001
From: Florrie <towerofnix@gmail.com>
Date: Sat, 8 Dec 2018 02:37:15 -0400
Subject: Mouse support

Not exactly the most elegant implementation, but it definitely works and
isn't really difficult to code around!
---
 util/ansi.js     |  4 ++++
 util/telchars.js | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

(limited to 'util')

diff --git a/util/ansi.js b/util/ansi.js
index f976c12..6d26f5d 100644
--- a/util/ansi.js
+++ b/util/ansi.js
@@ -104,6 +104,10 @@ const ansi = {
     return `${ESC}[27m`
   },
 
+  startTrackingMouse() {
+    return `${ESC}[?9h`
+  },
+
   requestCursorPosition() {
     // Requests the position of the cursor.
     // Expect a stdin-result '\ESC[l;cR', where l is the line number (1-based),
diff --git a/util/telchars.js b/util/telchars.js
index dcb840f..b099f65 100644
--- a/util/telchars.js
+++ b/util/telchars.js
@@ -31,6 +31,42 @@ const telchars = {
   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 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'
+    }
+
+    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'),
-- 
cgit 1.3.0-6-gf8a5