/** * Copyright (c) 2019 The xterm.js authors. All rights reserved. * @license MIT * * Script to test different mouse modes in terminal emulators. * Tests for protocols DECSET 9, 1000, 1002, 1003 with different * report encodings (default, UTF8, SGR, URXVT, SGR-pixels). * * VT200 Highlight mode (DECSET 1001) is not implemented. * * The test basically applies the report data to the cursor, thus * a mouse report should move the cursor to the cell under the mouse. * Furthermore the reports are printed in the left lower corner as * raw data and their meaning. * * A failing test might show: * - wrong coords: the cursor will jump to some other place * - wrong buttons: see meaning output and check whether it makes sense * - faulty reports: inspect the raw data and compare with other emulators * - missing events: compare with spec / other emulators */ let activeProtocol = 0; let activeEnc = 0; const stdin = process.openStdin(); process.stdin.setRawMode(true); // close handler - reset terminal on exit stdin.addListener('data', function(data) { if (data[0] === 0x03) { process.stdin.setRawMode(false); process.stdout.write('\x1bc'); process.exit(); } if (data[0] === 0x01) { switchActiveProtocol(); printMenu(); } if (data[0] === 0x02) { switchActiveEnc(); printMenu(); } console.log('\x1b[100;H\x1b[2A\x1b[2KReport:', data, [data.toString('binary')]); // filter mouse reports if (data[0] === 0x1b && data[1] === '['.charCodeAt(0)) { applyReportData(data); } }); // button definitions const buttons = { '': -1, left: 0, middle: 1, right: 2, released: 3, wheelUp: 4, wheelDown: 5, wheelLeft: 6, wheelRight: 7, aux1: 8, aux2: 9, aux3: 10, aux4: 11, aux5: 12, aux6: 13, aux7: 14, aux8: 15 }; const reverseButtons = {}; for (const el in buttons) { reverseButtons[buttons[el]] = el; } // extract button data from buttonCode function evalButtonCode(code) { // more than 15 buttons are not supported if (code > 255) { return {button: 'invalid', action: 'invalid', modifier: {}}; } const modifier = {shift: !!(code & 4), meta: !!(code & 8), control: !!(code & 16)}; const move = code & 32; let button = code & 3; if (code & 128) { button |= 8; } if (code & 64) { button |= 4 } let action = 'press'; let buttonS = reverseButtons[button]; if (button === 3) { buttonS = ''; action = 'release'; } if (move) { action = 'move'; } else if (4 <= button && button <= 7) { buttonS = 'wheel'; action = button === 4 ? 'up' : button === 5 ? 'down' : button === 6 ? 'left' : 'right'; } return {button: buttonS, action, modifier}; } // protocols const PROTOCOLS = { '9 (X10: press only)': '\x1b[?9h', '1000 (VT200: press, release, wheel)': '\x1b[?1000h', // '1001 (VT200 highlight)': '\x1b[?1001h', // handle of backreport - not implemented '1002 (press, release, move on pressed, wheel)': '\x1b[?1002h', '1003 (press, relase, move, wheel)': '\x1b[?1003h' } // encodings: ENCODING_NAME => [sequence, parse_report] const ENC = { 'DEFAULT' : [ '', // format: CSI M