quitando basura del index
[VSoRC/.git] / node_modules / node-pty / deps / winpty / src / agent / Terminal.cc
diff --git a/node_modules/node-pty/deps/winpty/src/agent/Terminal.cc b/node_modules/node-pty/deps/winpty/src/agent/Terminal.cc
deleted file mode 100644 (file)
index afa0a36..0000000
+++ /dev/null
@@ -1,535 +0,0 @@
-// Copyright (c) 2011-2015 Ryan Prichard
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-
-#include "Terminal.h"
-
-#include <windows.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <string>
-
-#include "NamedPipe.h"
-#include "UnicodeEncoding.h"
-#include "../shared/DebugClient.h"
-#include "../shared/WinptyAssert.h"
-#include "../shared/winpty_snprintf.h"
-
-#define CSI "\x1b["
-
-// Work around the old MinGW, which lacks COMMON_LVB_LEADING_BYTE and
-// COMMON_LVB_TRAILING_BYTE.
-const int WINPTY_COMMON_LVB_LEADING_BYTE  = 0x100;
-const int WINPTY_COMMON_LVB_TRAILING_BYTE = 0x200;
-const int WINPTY_COMMON_LVB_REVERSE_VIDEO = 0x4000;
-const int WINPTY_COMMON_LVB_UNDERSCORE    = 0x8000;
-
-const int COLOR_ATTRIBUTE_MASK =
-        FOREGROUND_BLUE |
-        FOREGROUND_GREEN |
-        FOREGROUND_RED |
-        FOREGROUND_INTENSITY |
-        BACKGROUND_BLUE |
-        BACKGROUND_GREEN |
-        BACKGROUND_RED |
-        BACKGROUND_INTENSITY |
-        WINPTY_COMMON_LVB_REVERSE_VIDEO |
-        WINPTY_COMMON_LVB_UNDERSCORE;
-
-const int FLAG_RED    = 1;
-const int FLAG_GREEN  = 2;
-const int FLAG_BLUE   = 4;
-const int FLAG_BRIGHT = 8;
-
-const int BLACK  = 0;
-const int DKGRAY = BLACK | FLAG_BRIGHT;
-const int LTGRAY = FLAG_RED | FLAG_GREEN | FLAG_BLUE;
-const int WHITE  = LTGRAY | FLAG_BRIGHT;
-
-// SGR parameters (Select Graphic Rendition)
-const int SGR_FORE = 30;
-const int SGR_FORE_HI = 90;
-const int SGR_BACK = 40;
-const int SGR_BACK_HI = 100;
-
-namespace {
-
-static void outUInt(std::string &out, unsigned int n)
-{
-    char buf[32];
-    char *pbuf = &buf[32];
-    *(--pbuf) = '\0';
-    do {
-        *(--pbuf) = '0' + n % 10;
-        n /= 10;
-    } while (n != 0);
-    out.append(pbuf);
-}
-
-static void outputSetColorSgrParams(std::string &out, bool isFore, int color)
-{
-    out.push_back(';');
-    const int sgrBase = isFore ? SGR_FORE : SGR_BACK;
-    if (color & FLAG_BRIGHT) {
-        // Some terminals don't support the 9X/10X "intensive" color parameters
-        // (e.g. the Eclipse TM terminal as of this writing).  Those terminals
-        // will quietly ignore a 9X/10X code, and the other terminals will
-        // ignore a 3X/4X code if it's followed by a 9X/10X code.  Therefore,
-        // output a 3X/4X code as a fallback, then override it.
-        const int colorBase = color & ~FLAG_BRIGHT;
-        outUInt(out, sgrBase + colorBase);
-        out.push_back(';');
-        outUInt(out, sgrBase + (SGR_FORE_HI - SGR_FORE) + colorBase);
-    } else {
-        outUInt(out, sgrBase + color);
-    }
-}
-
-static void outputSetColor(std::string &out, int color)
-{
-    int fore = 0;
-    int back = 0;
-    if (color & FOREGROUND_RED)       fore |= FLAG_RED;
-    if (color & FOREGROUND_GREEN)     fore |= FLAG_GREEN;
-    if (color & FOREGROUND_BLUE)      fore |= FLAG_BLUE;
-    if (color & FOREGROUND_INTENSITY) fore |= FLAG_BRIGHT;
-    if (color & BACKGROUND_RED)       back |= FLAG_RED;
-    if (color & BACKGROUND_GREEN)     back |= FLAG_GREEN;
-    if (color & BACKGROUND_BLUE)      back |= FLAG_BLUE;
-    if (color & BACKGROUND_INTENSITY) back |= FLAG_BRIGHT;
-
-    if (color & WINPTY_COMMON_LVB_REVERSE_VIDEO) {
-        // n.b.: The COMMON_LVB_REVERSE_VIDEO flag also swaps
-        // FOREGROUND_INTENSITY and BACKGROUND_INTENSITY.  Tested on
-        // Windows 10 v14393.
-        std::swap(fore, back);
-    }
-
-    // Translate the fore/back colors into terminal escape codes using
-    // a heuristic that works OK with common white-on-black or
-    // black-on-white color schemes.  We don't know which color scheme
-    // the terminal is using.  It is ugly to force white-on-black text
-    // on a black-on-white terminal, and it's even ugly to force the
-    // matching scheme.  It's probably relevant that the default
-    // fore/back terminal colors frequently do not match any of the 16
-    // palette colors.
-
-    // Typical default terminal color schemes (according to palette,
-    // when possible):
-    //  - mintty:               LtGray-on-Black(A)
-    //  - putty:                LtGray-on-Black(A)
-    //  - xterm:                LtGray-on-Black(A)
-    //  - Konsole:              LtGray-on-Black(A)
-    //  - JediTerm/JetBrains:   Black-on-White(B)
-    //  - rxvt:                 Black-on-White(B)
-
-    // If the background is the default color (black), then it will
-    // map to Black(A) or White(B).  If we translate White to White,
-    // then a Black background and a White background in the console
-    // are both White with (B).  Therefore, we should translate White
-    // using SGR 7 (Invert).  The typical finished mapping table for
-    // background grayscale colors is:
-    //
-    //  (A) White => LtGray(fore)
-    //  (A) Black => Black(back)
-    //  (A) LtGray => LtGray
-    //  (A) DkGray => DkGray
-    //
-    //  (B) White => Black(fore)
-    //  (B) Black => White(back)
-    //  (B) LtGray => LtGray
-    //  (B) DkGray => DkGray
-    //
-
-    out.append(CSI "0");
-    if (back == BLACK) {
-        if (fore == LTGRAY) {
-            // The "default" foreground color.  Use the terminal's
-            // default colors.
-        } else if (fore == WHITE) {
-            // Sending the literal color white would behave poorly if
-            // the terminal were black-on-white.  Sending Bold is not
-            // guaranteed to alter the color, but it will make the text
-            // visually distinct, so do that instead.
-            out.append(";1");
-        } else if (fore == DKGRAY) {
-            // Set the foreground color to DkGray(90) with a fallback
-            // of LtGray(37) for terminals that don't handle the 9X SGR
-            // parameters (e.g. Eclipse's TM Terminal as of this
-            // writing).
-            out.append(";37;90");
-        } else {
-            outputSetColorSgrParams(out, true, fore);
-        }
-    } else if (back == WHITE) {
-        // Set the background color using Invert on the default
-        // foreground color, and set the foreground color by setting a
-        // background color.
-
-        // Use the terminal's inverted colors.
-        out.append(";7");
-        if (fore == LTGRAY || fore == BLACK) {
-            // We're likely mapping Console White to terminal LtGray or
-            // Black.  If they are the Console foreground color, then
-            // don't set a terminal foreground color to avoid creating
-            // invisible text.
-        } else {
-            outputSetColorSgrParams(out, false, fore);
-        }
-    } else {
-        // Set the foreground and background to match exactly that in
-        // the Windows console.
-        outputSetColorSgrParams(out, true, fore);
-        outputSetColorSgrParams(out, false, back);
-    }
-    if (fore == back) {
-        // The foreground and background colors are exactly equal, so
-        // attempt to hide the text using the Conceal SGR parameter,
-        // which some terminals support.
-        out.append(";8");
-    }
-    if (color & WINPTY_COMMON_LVB_UNDERSCORE) {
-        out.append(";4");
-    }
-    out.push_back('m');
-}
-
-static inline unsigned int fixSpecialCharacters(unsigned int ch)
-{
-    if (ch <= 0x1b) {
-        switch (ch) {
-            // The Windows Console has a popup window (e.g. that appears with
-            // F7) that is sometimes bordered with box-drawing characters.
-            // With the Japanese and Korean system locales (CP932 and CP949),
-            // the UnicodeChar values for the box-drawing characters are 1
-            // through 6.  Detect this and map the values to the correct
-            // Unicode values.
-            //
-            // N.B. In the English locale, the UnicodeChar values are correct,
-            // and they identify single-line characters rather than
-            // double-line.  In the Chinese Simplified and Traditional locales,
-            // the popups use ASCII characters instead.
-            case 1: return 0x2554; // BOX DRAWINGS DOUBLE DOWN AND RIGHT
-            case 2: return 0x2557; // BOX DRAWINGS DOUBLE DOWN AND LEFT
-            case 3: return 0x255A; // BOX DRAWINGS DOUBLE UP AND RIGHT
-            case 4: return 0x255D; // BOX DRAWINGS DOUBLE UP AND LEFT
-            case 5: return 0x2551; // BOX DRAWINGS DOUBLE VERTICAL
-            case 6: return 0x2550; // BOX DRAWINGS DOUBLE HORIZONTAL
-
-            // Convert an escape character to some other character.  This
-            // conversion only applies to console cells containing an escape
-            // character.  In newer versions of Windows 10 (e.g. 10.0.10586),
-            // the non-legacy console recognizes escape sequences in
-            // WriteConsole and interprets them without writing them to the
-            // cells of the screen buffer.  In that case, the conversion here
-            // does not apply.
-            case 0x1b: return '?';
-        }
-    }
-    return ch;
-}
-
-static inline bool isFullWidthCharacter(const CHAR_INFO *data, int width)
-{
-    if (width < 2) {
-        return false;
-    }
-    return
-        (data[0].Attributes & WINPTY_COMMON_LVB_LEADING_BYTE) &&
-        (data[1].Attributes & WINPTY_COMMON_LVB_TRAILING_BYTE) &&
-        data[0].Char.UnicodeChar == data[1].Char.UnicodeChar;
-}
-
-// Scan to find a single Unicode Scalar Value.  Full-width characters occupy
-// two console cells, and this code also tries to handle UTF-16 surrogate
-// pairs.
-//
-// Windows expands at least some wide characters outside the Basic
-// Multilingual Plane into four cells, such as U+20000:
-//   1. 0xD840, attr=0x107
-//   2. 0xD840, attr=0x207
-//   3. 0xDC00, attr=0x107
-//   4. 0xDC00, attr=0x207
-// Even in the Traditional Chinese locale on Windows 10, this text is rendered
-// as two boxes, but if those boxes are copied-and-pasted, the character is
-// copied correctly.
-static inline void scanUnicodeScalarValue(
-    const CHAR_INFO *data, int width,
-    int &outCellCount, unsigned int &outCharValue)
-{
-    ASSERT(width >= 1);
-
-    const int w1 = isFullWidthCharacter(data, width) ? 2 : 1;
-    const wchar_t c1 = data[0].Char.UnicodeChar;
-
-    if ((c1 & 0xF800) == 0xD800) {
-        // The first cell is either a leading or trailing surrogate pair.
-        if ((c1 & 0xFC00) != 0xD800 ||
-                width <= w1 ||
-                ((data[w1].Char.UnicodeChar & 0xFC00) != 0xDC00)) {
-            // Invalid surrogate pair
-            outCellCount = w1;
-            outCharValue = '?';
-        } else {
-            // Valid surrogate pair
-            outCellCount = w1 + (isFullWidthCharacter(&data[w1], width - w1) ? 2 : 1);
-            outCharValue = decodeSurrogatePair(c1, data[w1].Char.UnicodeChar);
-        }
-    } else {
-        outCellCount = w1;
-        outCharValue = c1;
-    }
-}
-
-} // anonymous namespace
-
-void Terminal::reset(SendClearFlag sendClearFirst, int64_t newLine)
-{
-    if (sendClearFirst == SendClear && !m_plainMode) {
-        // 0m   ==> reset SGR parameters
-        // 1;1H ==> move cursor to top-left position
-        // 2J   ==> clear the entire screen
-        m_output.write(CSI "0m" CSI "1;1H" CSI "2J");
-    }
-    m_remoteLine = newLine;
-    m_remoteColumn = 0;
-    m_lineData.clear();
-    m_cursorHidden = false;
-    m_remoteColor = -1;
-}
-
-void Terminal::sendLine(int64_t line, const CHAR_INFO *lineData, int width,
-                        int cursorColumn)
-{
-    ASSERT(width >= 1);
-
-    moveTerminalToLine(line);
-
-    // If possible, see if we can append to what we've already output for this
-    // line.
-    if (m_lineDataValid) {
-        ASSERT(m_lineData.size() == static_cast<size_t>(m_remoteColumn));
-        if (m_remoteColumn > 0) {
-            // In normal mode, if m_lineData.size() equals `width`, then we
-            // will have trouble outputing the "erase rest of line" command,
-            // which must be output before reaching the end of the line.  In
-            // plain mode, we don't output that command, so we're OK with a
-            // full line.
-            bool okWidth = false;
-            if (m_plainMode) {
-                okWidth = static_cast<size_t>(width) >= m_lineData.size();
-            } else {
-                okWidth = static_cast<size_t>(width) > m_lineData.size();
-            }
-            if (!okWidth ||
-                    memcmp(m_lineData.data(), lineData,
-                           sizeof(CHAR_INFO) * m_lineData.size()) != 0) {
-                m_lineDataValid = false;
-            }
-        }
-    }
-    if (!m_lineDataValid) {
-        // We can't reuse, so we must reset this line.
-        hideTerminalCursor();
-        if (m_plainMode) {
-            // We can't backtrack, so repeat this line.
-            m_output.write("\r\n");
-        } else {
-            m_output.write("\r");
-        }
-        m_lineDataValid = true;
-        m_lineData.clear();
-        m_remoteColumn = 0;
-    }
-
-    std::string &termLine = m_termLineWorkingBuffer;
-    termLine.clear();
-    size_t trimmedLineLength = 0;
-    int trimmedCellCount = m_lineData.size();
-    bool alreadyErasedLine = false;
-
-    int cellCount = 1;
-    for (int i = m_lineData.size(); i < width; i += cellCount) {
-        if (m_outputColor) {
-            int color = lineData[i].Attributes & COLOR_ATTRIBUTE_MASK;
-            if (color != m_remoteColor) {
-                outputSetColor(termLine, color);
-                trimmedLineLength = termLine.size();
-                m_remoteColor = color;
-
-                // All the cells just up to this color change will be output.
-                trimmedCellCount = i;
-            }
-        }
-        unsigned int ch;
-        scanUnicodeScalarValue(&lineData[i], width - i, cellCount, ch);
-        if (ch == ' ') {
-            // Tentatively add this space character.  We'll only output it if
-            // we see something interesting after it.
-            termLine.push_back(' ');
-        } else {
-            if (i + cellCount == width) {
-                // We'd like to erase the line after outputting all non-blank
-                // characters, but this doesn't work if the last cell in the
-                // line is non-blank.  At the point, the cursor is positioned
-                // just past the end of the line, but in many terminals,
-                // issuing a CSI 0K at that point also erases the last cell in
-                // the line.  Work around this behavior by issuing the erase
-                // one character early in that case.
-                if (!m_plainMode) {
-                    termLine.append(CSI "0K"); // Erase from cursor to EOL
-                }
-                alreadyErasedLine = true;
-            }
-            ch = fixSpecialCharacters(ch);
-            char enc[4];
-            int enclen = encodeUtf8(enc, ch);
-            if (enclen == 0) {
-                enc[0] = '?';
-                enclen = 1;
-            }
-            termLine.append(enc, enclen);
-            trimmedLineLength = termLine.size();
-
-            // All the cells up to and including this cell will be output.
-            trimmedCellCount = i + cellCount;
-        }
-    }
-
-    if (cursorColumn != -1 && trimmedCellCount > cursorColumn) {
-        // The line content would run past the cursor, so hide it before we
-        // output.
-        hideTerminalCursor();
-    }
-
-    m_output.write(termLine.data(), trimmedLineLength);
-    if (!alreadyErasedLine && !m_plainMode) {
-        m_output.write(CSI "0K"); // Erase from cursor to EOL
-    }
-
-    ASSERT(trimmedCellCount <= width);
-    m_lineData.insert(m_lineData.end(),
-                      &lineData[m_lineData.size()],
-                      &lineData[trimmedCellCount]);
-    m_remoteColumn = trimmedCellCount;
-}
-
-void Terminal::showTerminalCursor(int column, int64_t line)
-{
-    moveTerminalToLine(line);
-    if (!m_plainMode) {
-        if (m_remoteColumn != column) {
-            char buffer[32];
-            winpty_snprintf(buffer, CSI "%dG", column + 1);
-            m_output.write(buffer);
-            m_lineDataValid = (column == 0);
-            m_lineData.clear();
-            m_remoteColumn = column;
-        }
-        if (m_cursorHidden) {
-            m_output.write(CSI "?25h");
-            m_cursorHidden = false;
-        }
-    }
-}
-
-void Terminal::hideTerminalCursor()
-{
-    if (!m_plainMode) {
-        if (m_cursorHidden) {
-            return;
-        }
-        m_output.write(CSI "?25l");
-        m_cursorHidden = true;
-    }
-}
-
-void Terminal::moveTerminalToLine(int64_t line)
-{
-    if (line == m_remoteLine) {
-        return;
-    }
-
-    // Do not use CPL or CNL.  Konsole 2.5.4 does not support Cursor Previous
-    // Line (CPL) -- there are "Undecodable sequence" errors.  gnome-terminal
-    // 2.32.0 does handle it.  Cursor Next Line (CNL) does nothing if the
-    // cursor is on the last line already.
-
-    hideTerminalCursor();
-
-    if (line < m_remoteLine) {
-        if (m_plainMode) {
-            // We can't backtrack, so instead repeat the lines again.
-            m_output.write("\r\n");
-            m_remoteLine = line;
-        } else {
-            // Backtrack and overwrite previous lines.
-            // CUrsor Up (CUU)
-            char buffer[32];
-            winpty_snprintf(buffer, "\r" CSI "%uA",
-                static_cast<unsigned int>(m_remoteLine - line));
-            m_output.write(buffer);
-            m_remoteLine = line;
-        }
-    } else if (line > m_remoteLine) {
-        while (line > m_remoteLine) {
-            m_output.write("\r\n");
-            m_remoteLine++;
-        }
-    }
-
-    m_lineDataValid = true;
-    m_lineData.clear();
-    m_remoteColumn = 0;
-}
-
-void Terminal::enableMouseMode(bool enabled)
-{
-    if (m_mouseModeEnabled == enabled || m_plainMode) {
-        return;
-    }
-    m_mouseModeEnabled = enabled;
-    if (enabled) {
-        // Start by disabling UTF-8 coordinate mode (1005), just in case we
-        // have a terminal that does not support 1006/1015 modes, and 1005
-        // happens to be enabled.  The UTF-8 coordinates can't be unambiguously
-        // decoded.
-        //
-        // Enable basic mouse support first (1000), then try to switch to
-        // button-move mode (1002), then try full mouse-move mode (1003).
-        // Terminals that don't support a mode will be stuck at the highest
-        // mode they do support.
-        //
-        // Enable encoding mode 1015 first, then try to switch to 1006.  On
-        // some terminals, both modes will be enabled, but 1006 will have
-        // priority.  On other terminals, 1006 wins because it's listed last.
-        //
-        // See misc/MouseInputNotes.txt for details.
-        m_output.write(
-            CSI "?1005l"
-            CSI "?1000h" CSI "?1002h" CSI "?1003h" CSI "?1015h" CSI "?1006h");
-    } else {
-        // Resetting both encoding modes (1006 and 1015) is necessary, but
-        // apparently we only need to use reset on one of the 100[023] modes.
-        // Doing both doesn't hurt.
-        m_output.write(
-            CSI "?1006l" CSI "?1015l" CSI "?1003l" CSI "?1002l" CSI "?1000l");
-    }
-}