diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index 71c9e7a7e..cff5e2d59 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -204,6 +204,8 @@
+
+
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters
index eefef7c86..77a05a3d6 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj.filters
+++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters
@@ -139,6 +139,8 @@
inc
+
+
diff --git a/contrib/win32/win32compat/ansiprsr.c b/contrib/win32/win32compat/ansiprsr.c
index f2e99bc66..e5344e8c1 100644
--- a/contrib/win32/win32compat/ansiprsr.c
+++ b/contrib/win32/win32compat/ansiprsr.c
@@ -48,14 +48,12 @@ extern int ScreenX;
extern int ScreenY;
extern int ScrollTop;
extern int ScrollBottom;
-extern BOOL bAnsiParsing;
bool gbVTAppMode = false;
/* private message for port printing to */
unsigned char VT_ST[] = { 0x1b, '/', '\0' };
static int AutoWrap = 1;
BOOL bAtEOLN = FALSE;
-static int term_mode = TERM_ANSI;
/*
* ParseANSI globals - these need to be here, because sometimes blocks are sent
@@ -142,12 +140,24 @@ BufConvertToG2(char * pszBuffer, int length)
void
GoToNextLine()
{
- if (ConGetCursorY() >= (ConWindowSizeY() - 1)) {
- ConScrollDown(ScrollTop, ScrollBottom);
- ConMoveCursorPosition(-ConGetCursorX(), 0);
- }
- else
- ConMoveCursorPosition(-ConGetCursorX(), 1);
+ int currentX = 0;
+ int currentY = 0;
+
+ ConGetCursorPosition(¤tX, ¤tY);
+
+ /* If the cursor is the last line of the visible window */
+ if (is_cursor_at_lastline_of_visible_window()) {
+ if (currentY >= ConGetBufferHeight()) {
+ /* handle the max window buffer size */
+ ConScrollDown(0, currentY);
+ ConMoveCursorPosition(-currentX, 0);
+ } else {
+ /* max window buffer is not breached */
+ ConMoveVisibleWindow(1);
+ ConMoveCursorPosition(-currentX, 1);
+ }
+ } else /* If the cursor is NOT the last line of the visible window */
+ ConMoveCursorPosition(-currentX, 1);
bAtEOLN = FALSE;
}
@@ -155,8 +165,8 @@ GoToNextLine()
unsigned char*
ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char **respbuf, size_t *resplen)
{
- int CurrentX;
- int CurrentY;
+ int currentX;
+ int currentY;
int bufLen, cmpLen, i;
if (!fcompletion) {
@@ -164,8 +174,7 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char
unsigned char * pszCurrent = pszBuffer + 1;
unsigned char * pszNewCurrent = pszCurrent;
- if (term_mode == TERM_ANSI && bAnsiParsing)
- pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen);
+ pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen);
/* Pointer didn't move inside Parse function */
if (pszCurrent == pszNewCurrent) {
@@ -200,8 +209,8 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char
case 8:
pszBuffer++;
if (!bAtEOLN) {
- CurrentX = ConGetCursorX();
- if (CurrentX == 0) {
+ currentX = ConGetCursorX();
+ if (currentX == 0) {
ConMoveCursorPosition(ScreenX - 1, -1);
ConWriteString(" ", 1);
} else {
@@ -263,10 +272,8 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char
if (*pszCurrent == 27) {
pszNewCurrent += ConWriteString((char *)pszCurrent, 1);
return pszBuffer + 1;
- } else {
- if (term_mode == TERM_ANSI)
- pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen);
- }
+ } else
+ pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen);
if (pszNewCurrent > pszCurrent)
pszBuffer = pszNewCurrent;
@@ -278,12 +285,12 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char
if (bAtEOLN) GoToNextLine();
unsigned char* pszCurrent = pszBuffer;
- CurrentX = ConGetCursorX();
+ currentX = ConGetCursorX();
int nCharCount = 0;
while ((pszCurrent < pszBufferEnd) && (*pszCurrent != (unsigned char)27)
&& (*pszCurrent > (unsigned char)15) && (*pszCurrent != (unsigned char)255)
- && (CurrentX++ < ScreenX)) {
+ && (currentX++ < ScreenX)) {
if (*pszCurrent > 127) {
unsigned char nLead = *pszCurrent;
nCharCount++;
@@ -305,7 +312,7 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char
pszBuffer += ConWriteString((char *)pszBuffer, (int)(pszCurrent - pszBuffer));
- if ((CurrentX >= ScreenX) && AutoWrap && !(VTMode & MODE_CURSORAPP))
+ if ((currentX >= ScreenX) && AutoWrap && !(VTMode & MODE_CURSORAPP))
bAtEOLN = TRUE;
}
break;
@@ -561,10 +568,10 @@ ParseANSI(unsigned char * pszBuffer, unsigned char * pszBufferEnd, unsigned char
if (iParam[0]) {
int i;
for (i = 0; i < iParam[0]; i++)
- ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConWindowSizeY() - 2);
+ ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConVisibleWindowHeight() - 2);
} else {
- if (ConGetCursorY() <= ScrollTop + ConWindowSizeY() - 2)
- ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConWindowSizeY() - 2);
+ if (ConGetCursorY() <= ScrollTop + ConVisibleWindowHeight() - 2)
+ ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConVisibleWindowHeight() - 2);
}
fcompletion = 1;
bAtEOLN = FALSE;
@@ -600,7 +607,7 @@ ParseANSI(unsigned char * pszBuffer, unsigned char * pszBufferEnd, unsigned char
for (i = 0; i < iParam[0]; i++)
ConScrollUp(ConGetCursorY(), ScrollTop - ConGetCursorY());
} else {
- if (ConGetCursorY() <= ScrollTop + ConWindowSizeY() - 2)
+ if (ConGetCursorY() <= ScrollTop + ConVisibleWindowHeight() - 2)
ConScrollUp(ConGetCursorY(), ScrollTop - ConGetCursorY());
}
fcompletion = 1;
diff --git a/contrib/win32/win32compat/console.c b/contrib/win32/win32compat/console.c
index eb6b717d7..7ec2eeb43 100644
--- a/contrib/win32/win32compat/console.c
+++ b/contrib/win32/win32compat/console.c
@@ -52,13 +52,14 @@ int ScrollTop;
int ScrollBottom;
int LastCursorX;
int LastCursorY;
-BOOL bAnsiParsing = FALSE;
+BOOL isAnsiParsingRequired = FALSE;
char *pSavedScreen = NULL;
static COORD ZeroCoord = { 0,0 };
COORD SavedScreenSize = { 0,0 };
COORD SavedScreenCursor = { 0, 0 };
SMALL_RECT SavedViewRect = { 0,0,0,0 };
CONSOLE_SCREEN_BUFFER_INFOEX SavedWindowState;
+BOOL isConHostParserEnabled = TRUE;
typedef struct _SCREEN_RECORD {
PCHAR_INFO pScreenBuf;
@@ -69,10 +70,11 @@ typedef struct _SCREEN_RECORD {
PSCREEN_RECORD pSavedScreenRec = NULL;
int in_raw_mode = 0;
+char *consoleTitle = "Microsoft openSSH client";
-/* Used to Initialize the Console for output */
+/* Used to enter the raw mode */
int
-ConInit(DWORD OutputHandle, BOOL fSmartInit)
+ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
{
OSVERSIONINFO os;
DWORD dwAttributes = 0;
@@ -87,16 +89,18 @@ ConInit(DWORD OutputHandle, BOOL fSmartInit)
hOutputConsole = GetStdHandle(OutputHandle);
if (hOutputConsole == INVALID_HANDLE_VALUE) {
dwRet = GetLastError();
- printf("GetStdHandle on OutputHandle failed with %d\n", dwRet);
+ error("GetStdHandle on OutputHandle failed with %d\n", dwRet);
return dwRet;
}
if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &dwSavedAttributes)) {
dwRet = GetLastError();
- printf("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
+ error("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
return dwRet;
}
+ SetConsoleTitle(consoleTitle);
+
dwAttributes = dwSavedAttributes;
dwAttributes &= ~(ENABLE_LINE_INPUT |
ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
@@ -104,53 +108,69 @@ ConInit(DWORD OutputHandle, BOOL fSmartInit)
if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwAttributes)) { /* Windows NT */
dwRet = GetLastError();
- printf("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
+ error("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
return dwRet;
}
if (!GetConsoleMode(hOutputConsole, &dwAttributes)) {
dwRet = GetLastError();
- printf("GetConsoleMode on hOutputConsole failed with %d\n", dwRet);
+ error("GetConsoleMode on hOutputConsole failed with %d\n", dwRet);
return dwRet;
+
}
dwAttributes |= (DWORD)ENABLE_VIRTUAL_TERMINAL_PROCESSING;
- if (!SetConsoleMode(hOutputConsole, dwAttributes)) /* Windows NT */
- bAnsiParsing = TRUE;
+ if (NULL != getenv("SSH_TERM_CONHOST_PARSER"))
+ isConHostParserEnabled = atoi(getenv("SSH_TERM_CONHOST_PARSER"));
+
+ /* We use our custom ANSI parser when
+ * a) User sets the environment variable "SSH_TERM_CONHOST_PARSER" to 0
+ * b) or when the console doesn't have the inbuilt capability to parse the ANSI/Xterm raw buffer.
+ */
+ if (FALSE == isConHostParserEnabled || !SetConsoleMode(hOutputConsole, dwAttributes)) /* Windows NT */
+ isAnsiParsingRequired = TRUE;
+
+ GetConsoleScreenBufferInfo(hOutputConsole, &csbi);
+
+ /* if we are passing rawbuffer to console then we need to move the cursor to top
+ * so that the clearscreen will not erase any lines.
+ */
+ if (TRUE == isAnsiParsingRequired) {
+ SavedViewRect = csbi.srWindow;
+ debug("console doesn't support the ansi parsing");
+ } else {
+ ConMoveCurosorTop(csbi);
+ debug("console supports the ansi parsing");
+ }
ConSetScreenX();
ConSetScreenY();
ScrollTop = 0;
- ScrollBottom = ConWindowSizeY();
-
- if (GetConsoleScreenBufferInfo(hOutputConsole, &csbi))
- SavedViewRect = csbi.srWindow;
-
+ ScrollBottom = ConVisibleWindowHeight();
+
in_raw_mode = 1;
+
return 0;
}
/* Used to Uninitialize the Console */
int
-ConUnInit(void)
+ConExitRawMode()
{
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
in_raw_mode = 0;
- if (hOutputConsole == NULL)
+ if (hOutputConsole == NULL || !GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
return 0;
-
- if (!GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
- return 0;
-
+
SetConsoleMode(hOutputConsole, dwSavedAttributes);
return 0;
}
-/* Used to Uninitialize the Console */
+/* Used to exit the raw mode */
int
-ConUnInitWithRestore(void)
+ConUnInitWithRestore()
{
DWORD dwWritten;
COORD Coord;
@@ -446,9 +466,9 @@ ConScreenSizeY()
return (consoleInfo.srWindow.Bottom - consoleInfo.srWindow.Top + 1);
}
-/* returns visible size of screen window */
+/* returns width of visible window */
int
-ConWindowSizeX()
+ConVisibleWindowWidth()
{
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
@@ -458,9 +478,9 @@ ConWindowSizeX()
return (consoleInfo.srWindow.Right - consoleInfo.srWindow.Left + 1);
}
-/* returns visible size of screen window */
+/* returns height of visible window */
int
-ConWindowSizeY()
+ConVisibleWindowHeight()
{
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
@@ -837,7 +857,7 @@ ConDisplayCursor(BOOL bVisible)
}
void
-ConClearScreen(void)
+ConClearScreen()
{
DWORD dwWritten;
COORD Coord;
@@ -850,7 +870,7 @@ ConClearScreen(void)
Coord.X = 0;
Coord.Y = 0;
- DWORD dwNumChar = (consoleInfo.srWindow.Bottom + 1) * (consoleInfo.srWindow.Right + 1);
+ DWORD dwNumChar = (consoleInfo.dwSize.Y) * (consoleInfo.dwSize.X);
FillConsoleOutputCharacter(hOutputConsole, ' ', dwNumChar, Coord, &dwWritten);
FillConsoleOutputAttribute(hOutputConsole, consoleInfo.wAttributes, dwNumChar, Coord, &dwWritten);
srcWindow = consoleInfo.srWindow;
@@ -1055,11 +1075,25 @@ ConScrollUp(int topline, int botline)
);
}
+void
+ConMoveVisibleWindow(int offset)
+{
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ SMALL_RECT visibleWindowRect;
+
+ if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) {
+ memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect));
+ visibleWindowRect.Top += offset;
+ visibleWindowRect.Bottom += offset;
+
+ SetConsoleWindowInfo(hOutputConsole, TRUE, &visibleWindowRect);
+ }
+}
+
void
ConScrollDown(int topline, int botline)
{
- SMALL_RECT ScrollRect;
- SMALL_RECT ClipRect;
+ SMALL_RECT ScrollRect;
COORD destination;
CHAR_INFO Fill;
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
@@ -1078,11 +1112,6 @@ ConScrollDown(int topline, int botline)
ScrollRect.Left = 0;
ScrollRect.Right = ConScreenSizeX() - 1;
- ClipRect.Top = ScrollRect.Top;
- ClipRect.Bottom = ScrollRect.Bottom;
- ClipRect.Left = ScrollRect.Left;
- ClipRect.Right = ScrollRect.Right;
-
destination.X = 0;
destination.Y = ScrollRect.Top - 1;
@@ -1152,6 +1181,17 @@ ConChangeCursor(CONSOLE_CURSOR_INFO *pCursorInfo)
return SetConsoleCursorInfo(hOutputConsole, pCursorInfo);
}
+void
+ConGetCursorPosition(int *x, int *y)
+{
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+
+ if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) {
+ *x = consoleInfo.dwCursorPosition.X;
+ *y = consoleInfo.dwCursorPosition.Y;
+ }
+}
+
int
ConGetCursorX()
{
@@ -1163,6 +1203,21 @@ ConGetCursorX()
return consoleInfo.dwCursorPosition.X;
}
+int
+is_cursor_at_lastline_of_visible_window()
+{
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ int return_val = 0;
+
+ if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) {
+ int cursor_linenum_in_visible_window = consoleInfo.dwCursorPosition.Y - consoleInfo.srWindow.Top;
+ if (cursor_linenum_in_visible_window >= ConVisibleWindowHeight() - 1)
+ return_val = 1;
+ }
+
+ return return_val;
+}
+
int
ConGetCursorY()
{
@@ -1175,14 +1230,14 @@ ConGetCursorY()
}
int
-ConGetCursorInBufferY()
+ConGetBufferHeight()
{
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
if (!GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
return 0;
- return (consoleInfo.dwCursorPosition.Y);
+ return (consoleInfo.dwSize.Y - 1);
}
void
@@ -1390,28 +1445,53 @@ ConDeleteScreenHandle(SCREEN_HANDLE hScreen)
/* Restores Previous Saved screen info and buffer */
BOOL
-ConRestoreScreen(void)
+ConRestoreScreen()
{
return ConRestoreScreenHandle(pSavedScreenRec);
}
/* Saves current screen info and buffer */
-BOOL
-ConSaveScreen(void)
+void
+ConSaveScreen()
{
- pSavedScreenRec = (PSCREEN_RECORD)ConSaveScreenHandle(pSavedScreenRec);
- return TRUE;
+ pSavedScreenRec = (PSCREEN_RECORD)ConSaveScreenHandle(pSavedScreenRec);
}
void
-ConSaveViewRect(void)
+ConSaveViewRect()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
- if (!GetConsoleScreenBufferInfo(hOutputConsole, &csbi))
- return;
+ if (GetConsoleScreenBufferInfo(hOutputConsole, &csbi))
+ SavedViewRect = csbi.srWindow;
+}
- SavedViewRect = csbi.srWindow;
+void
+ConRestoreViewRect()
+{
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ HWND hwnd = FindWindow(NULL, consoleTitle);
+
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(WINDOWPLACEMENT);
+ GetWindowPlacement(hwnd, &wp);
+
+ if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo) &&
+ ((consoleInfo.srWindow.Top != SavedViewRect.Top ||
+ consoleInfo.srWindow.Bottom != SavedViewRect.Bottom))) {
+ if ((SavedViewRect.Right - SavedViewRect.Left > consoleInfo.dwSize.X) ||
+ (wp.showCmd == SW_SHOWMAXIMIZED)) {
+ COORD coordScreen;
+ coordScreen.X = SavedViewRect.Right - SavedViewRect.Left;
+ coordScreen.Y = consoleInfo.dwSize.Y;
+ SetConsoleScreenBufferSize(hOutputConsole, coordScreen);
+
+ ShowWindow(hwnd, SW_SHOWMAXIMIZED);
+ } else
+ ShowWindow(hwnd, SW_RESTORE);
+
+ SetConsoleWindowInfo(hOutputConsole, TRUE, &SavedViewRect);
+ }
}
BOOL
@@ -1460,7 +1540,7 @@ GetConsoleInputHandle()
}
void
-ConSaveWindowsState(void)
+ConSaveWindowsState()
{
CONSOLE_SCREEN_BUFFER_INFOEX csbiex;
csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
@@ -1470,3 +1550,12 @@ ConSaveWindowsState(void)
SavedWindowState = csbiex;
}
+
+void
+ConMoveCurosorTop(CONSOLE_SCREEN_BUFFER_INFO csbi)
+{
+ int offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top;
+ ConMoveVisibleWindow(offset);
+
+ ConSaveViewRect();
+}
diff --git a/contrib/win32/win32compat/console.h b/contrib/win32/win32compat/console.h
index f06143e26..c98386d3a 100644
--- a/contrib/win32/win32compat/console.h
+++ b/contrib/win32/win32compat/console.h
@@ -42,38 +42,38 @@
#define __PRAGMA_CONSOLE_h
#define ANSI_ATTR_RESET 0
-#define ANSI_BRIGHT 1
-#define ANSI_DIM 2
+#define ANSI_BRIGHT 1
+#define ANSI_DIM 2
#define ANSI_UNDERSCORE 4
-#define ANSI_BLINK 5
+#define ANSI_BLINK 5
#define ANSI_REVERSE 7
-#define ANSI_HIDDEN 8
-#define ANSI_NOUNDERSCORE 24
+#define ANSI_HIDDEN 8
+#define ANSI_NOUNDERSCORE 24
#define ANSI_NOREVERSE 27
-#define ANSI_FOREGROUND_BLACK 30
+#define ANSI_FOREGROUND_BLACK 30
#define ANSI_FOREGROUND_RED 31
-#define ANSI_FOREGROUND_GREEN 32
-#define ANSI_FOREGROUND_YELLOW 33
-#define ANSI_FOREGROUND_BLUE 34
-#define ANSI_FOREGROUND_MAGENTA 35
-#define ANSI_FOREGROUND_CYAN 36
-#define ANSI_FOREGROUND_WHITE 37
-#define ANSI_DEFAULT_FOREGROUND 39
-#define ANSI_BACKGROUND_BLACK 40
+#define ANSI_FOREGROUND_GREEN 32
+#define ANSI_FOREGROUND_YELLOW 33
+#define ANSI_FOREGROUND_BLUE 34
+#define ANSI_FOREGROUND_MAGENTA 35
+#define ANSI_FOREGROUND_CYAN 36
+#define ANSI_FOREGROUND_WHITE 37
+#define ANSI_DEFAULT_FOREGROUND 39
+#define ANSI_BACKGROUND_BLACK 40
#define ANSI_BACKGROUND_RED 41
-#define ANSI_BACKGROUND_GREEN 42
-#define ANSI_BACKGROUND_YELLOW 43
-#define ANSI_BACKGROUND_BLUE 44
-#define ANSI_BACKGROUND_MAGENTA 45
-#define ANSI_BACKGROUND_CYAN 46
-#define ANSI_BACKGROUND_WHITE 47
-#define ANSI_DEFAULT_BACKGROUND 49
-#define ANSI_BACKGROUND_BRIGHT 128
+#define ANSI_BACKGROUND_GREEN 42
+#define ANSI_BACKGROUND_YELLOW 43
+#define ANSI_BACKGROUND_BLUE 44
+#define ANSI_BACKGROUND_MAGENTA 45
+#define ANSI_BACKGROUND_CYAN 46
+#define ANSI_BACKGROUND_WHITE 47
+#define ANSI_DEFAULT_BACKGROUND 49
+#define ANSI_BACKGROUND_BRIGHT 128
-#define TAB_LENGTH 4
-#define TAB_CHAR '\t'
-#define TAB_SPACE " "
+#define TAB_LENGTH 4
+#define TAB_CHAR '\t'
+#define TAB_SPACE " "
#define true TRUE
#define false FALSE
@@ -81,30 +81,30 @@
typedef void * SCREEN_HANDLE;
-int ConInit( DWORD OutputHandle, BOOL fSmartInit);
-int ConUnInitWithRestore( void );
-int ConUnInit( void );
+int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
+int ConUnInitWithRestore();
+int ConExitRawMode();
BOOL ConIsRedirected(HANDLE hInput);
HANDLE GetConsoleOutputHandle();
HANDLE GetConsoleInputHandle();
-BOOL ConSetScreenRect( int xSize, int ySize );
-BOOL ConSetScreenSize( int X, int Y );
-BOOL ConRestoreScreen( void );
-BOOL ConSaveScreen( void );
-void ConSetAttribute( int *iParam, int iParamCount );
-int ConScreenSizeX();
-int ConSetScreenX();
+BOOL ConSetScreenRect(int xSize, int ySize);
+BOOL ConSetScreenSize(int X, int Y);
+BOOL ConRestoreScreen();
+void ConSaveScreen();
+void ConSetAttribute(int *iParam, int iParamCount);
+int ConScreenSizeX();
+int ConSetScreenX();
int ConScreenSizeY();
-int ConWindowSizeX();
-int ConWindowSizeY();
+int ConVisibleWindowWidth();
+int ConVisibleWindowHeight();
int ConSetScreenY();
void ConFillToEndOfLine();
int ConWriteString(char* pszString, int cbString);
-BOOL ConWriteChar( CHAR ch );
-int ConWriteConsole( char *pData, int NumChars );
+BOOL ConWriteChar(CHAR ch);
+int ConWriteConsole(char *pData, int NumChars);
PCHAR ConDisplayData(char* pData, int NumLines);
PCHAR ConWriteLine(char* pData);
-int Con_printf( const char *Format, ... );
+int Con_printf(const char *Format, ...);
void ConClearScrollRegion();
void ConClearScreen();
void ConClearEOScreen();
@@ -115,25 +115,27 @@ void ConClearNFromCursorRight(int n);
void ConClearNFromCursorLeft(int n);
void ConScrollUpEntireBuffer();
void ConScrollDownEntireBuffer();
-void ConScrollUp(int topline,int botline);
-void ConScrollDown(int topline,int botline);
+void ConScrollUp(int topline,int botline);
+void ConScrollDown(int topline,int botline);
void ConClearBOLine();
-BOOL ConChangeCursor( CONSOLE_CURSOR_INFO *pCursorInfo );
+BOOL ConChangeCursor(CONSOLE_CURSOR_INFO *pCursorInfo);
void ConSetCursorPosition(int x, int y);
int ConGetCursorX();
int ConGetCursorY();
-int ConGetCursorInBufferY(void);
-BOOL ConDisplayCursor( BOOL bVisible );
+int ConGetBufferHeight();
+BOOL ConDisplayCursor(BOOL bVisible);
void ConMoveCursorPosition(int x, int y);
void ConGetRelativeCursorPosition(int *x, int *y);
-BOOL ConRestoreScreenHandle( SCREEN_HANDLE hScreen );
-BOOL ConRestoreScreenColors( void );
-SCREEN_HANDLE ConSaveScreenHandle( SCREEN_HANDLE);
-void ConDeleteScreenHandle( SCREEN_HANDLE hScreen );
-void ConSaveViewRect( void );
-void ConRestoreViewRect( void );
+BOOL ConRestoreScreenHandle(SCREEN_HANDLE hScreen);
+BOOL ConRestoreScreenColors();
+SCREEN_HANDLE ConSaveScreenHandle(SCREEN_HANDLE);
+void ConDeleteScreenHandle(SCREEN_HANDLE hScreen);
+void ConSaveViewRect();
+void ConRestoreViewRect();
void ConDeleteChars(int n);
-void ConSaveWindowsState(void);
-
-
+void ConSaveWindowsState();
+void ConMoveVisibleWindow(int offset);
+int is_cursor_at_lastline_of_visible_window();
+void ConGetCursorPosition(int *x, int *y);
+void ConMoveCurosorTop(CONSOLE_SCREEN_BUFFER_INFO csbi);
#endif
diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c
index e74dd7160..08d907960 100644
--- a/contrib/win32/win32compat/misc.c
+++ b/contrib/win32/win32compat/misc.c
@@ -388,10 +388,12 @@ w32_ioctl(int d, int request, ...)
errno = EINVAL;
return -1;
}
- wsize->ws_col = c_info.dwSize.X - 5;
- wsize->ws_row = c_info.dwSize.Y;
+
+ wsize->ws_col = c_info.srWindow.Right - c_info.srWindow.Left + 1;
+ wsize->ws_row = c_info.srWindow.Bottom - c_info.srWindow.Top + 1;
wsize->ws_xpixel = 640;
wsize->ws_ypixel = 480;
+
return 0;
}
default:
diff --git a/contrib/win32/win32compat/misc_internal.h b/contrib/win32/win32compat/misc_internal.h
index d17278ade..6150de03a 100644
--- a/contrib/win32/win32compat/misc_internal.h
+++ b/contrib/win32/win32compat/misc_internal.h
@@ -1,3 +1,4 @@
+#pragma once
#define PATH_MAX MAX_PATH
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
@@ -9,4 +10,4 @@ void w32posix_done();
char* w32_programdir();
void convertToBackslash(char *str);
-void convertToForwardslash(char *str);
\ No newline at end of file
+void convertToForwardslash(char *str);
diff --git a/contrib/win32/win32compat/shell-host.c b/contrib/win32/win32compat/shell-host.c
index 7b1fd95d3..a6e5b4615 100644
--- a/contrib/win32/win32compat/shell-host.c
+++ b/contrib/win32/win32compat/shell-host.c
@@ -121,6 +121,9 @@ struct key_translation keys[] = {
{ "\x1b[24~", VK_F12, 0 }
};
+static SHORT lastX = 0;
+static SHORT lastY = 0;
+
consoleEvent* head = NULL;
consoleEvent* tail = NULL;
@@ -182,6 +185,17 @@ STARTUPINFO inputSi;
goto cleanup; \
} while(0)
+int
+ConSRWidth()
+{
+ CONSOLE_SCREEN_BUFFER_INFOEX consoleBufferInfo;
+ ZeroMemory(&consoleBufferInfo, sizeof(consoleBufferInfo));
+ consoleBufferInfo.cbSize = sizeof(consoleBufferInfo);
+
+ GetConsoleScreenBufferInfoEx(child_out, &consoleBufferInfo);
+ return consoleBufferInfo.srWindow.Right;
+}
+
/*
* This function will handle the console keystrokes.
*/
@@ -426,7 +440,7 @@ SendBuffer(HANDLE hInput, CHAR_INFO *buffer, DWORD bufferSize)
}
void
-CalculateAndSetCursor(HANDLE hInput, UINT aboveTopLine, UINT viewPortHeight, UINT x, UINT y)
+CalculateAndSetCursor(HANDLE hInput, UINT x, UINT y)
{
SendSetCursor(pipe_out, x + 1, y + 1);
@@ -548,14 +562,13 @@ ProcessEvent(void *p)
case EVENT_CONSOLE_CARET:
{
COORD co;
+ co.X = LOWORD(idChild);
+ co.Y = HIWORD(idChild);
- if (idObject == CONSOLE_CARET_SELECTION) {
- co.X = HIWORD(idChild);
- co.Y = LOWORD(idChild);
- } else {
- co.X = HIWORD(idChild);
- co.Y = LOWORD(idChild);
- }
+ lastX = co.X;
+ lastY = co.Y;
+
+ SendSetCursor(pipe_out, lastX + 1, lastY + 1);
break;
}
@@ -568,6 +581,8 @@ ProcessEvent(void *p)
readRect.Bottom = HIWORD(idChild);
readRect.Right = LOWORD(idChild);
+ readRect.Right = max(readRect.Right, ConSRWidth());
+
/* Detect a "cls" (Windows) */
if (!bStartup &&
(readRect.Top == consoleInfo.srWindow.Top || readRect.Top == nextConsoleInfo.srWindow.Top)) {
@@ -632,7 +647,7 @@ ProcessEvent(void *p)
SendLF(pipe_out);
/* Set cursor location based on the reported location from the message */
- CalculateAndSetCursor(pipe_out, ViewPortY, viewPortHeight, readRect.Left, readRect.Top);
+ CalculateAndSetCursor(pipe_out, readRect.Left, readRect.Top);
/* Send the entire block */
SendBuffer(pipe_out, pBuffer, bufferSize);
@@ -649,12 +664,37 @@ ProcessEvent(void *p)
wAttributes = HIWORD(idChild);
wX = LOWORD(idObject);
wY = HIWORD(idObject);
-
+
+ SMALL_RECT readRect;
+ readRect.Top = wY;
+ readRect.Bottom = wY;
+ readRect.Left = wX;
+ readRect.Right = ConSRWidth();
+
/* Set cursor location based on the reported location from the message */
- CalculateAndSetCursor(pipe_out, ViewPortY, viewPortHeight, wX, wY);
+ CalculateAndSetCursor(pipe_out, wX, wY);
+
+ COORD coordBufSize;
+ coordBufSize.Y = readRect.Bottom - readRect.Top + 1;
+ coordBufSize.X = readRect.Right - readRect.Left + 1;
+ /* The top left destination cell of the temporary buffer is row 0, col 0 */
+ COORD coordBufCoord;
+ coordBufCoord.X = 0;
+ coordBufCoord.Y = 0;
+ int pBufferSize = coordBufSize.X * coordBufSize.Y;
/* Send the one character. Note that a CR doesn't end up here */
- SendCharacter(pipe_out, wAttributes, chUpdate);
+ CHAR_INFO *pBuffer = (PCHAR_INFO)malloc(sizeof(CHAR_INFO) * pBufferSize);
+
+ /* Copy the block from the screen buffer to the temp. buffer */
+ if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) {
+ DWORD dwError = GetLastError();
+ free(pBuffer);
+ return dwError;
+ }
+
+ SendBuffer(pipe_out, pBuffer, pBufferSize);
+ free(pBuffer);
break;
}
@@ -699,18 +739,24 @@ ProcessEvent(void *p)
}
}
- ZeroMemory(&consoleInfo, sizeof(consoleInfo));
- consoleInfo.cbSize = sizeof(consoleInfo);
- GetConsoleScreenBufferInfoEx(child_out, &consoleInfo);
-
return ERROR_SUCCESS;
}
DWORD WINAPI
ProcessEventQueue(LPVOID p)
{
- static SHORT lastX = 0;
- static SHORT lastY = 0;
+ if (child_in != INVALID_HANDLE_VALUE && child_in != NULL &&
+ child_out != INVALID_HANDLE_VALUE && child_out != NULL) {
+ DWORD dwInputMode;
+ DWORD dwOutputMode;
+
+ if (GetConsoleMode(child_in, &dwInputMode) && GetConsoleMode(child_out, &dwOutputMode))
+ if (((dwOutputMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == ENABLE_VIRTUAL_TERMINAL_PROCESSING) &&
+ ((dwInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT))
+ bAnsi = TRUE;
+ else
+ bAnsi = FALSE;
+ }
while (1) {
while (head) {
@@ -738,14 +784,6 @@ ProcessEventQueue(LPVOID p)
DWORD dwInputMode;
DWORD dwOutputMode;
- if (GetConsoleMode(child_in, &dwInputMode) && GetConsoleMode(child_out, &dwOutputMode)) {
- if (((dwOutputMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == ENABLE_VIRTUAL_TERMINAL_PROCESSING) &&
- ((dwInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT))
- bAnsi = TRUE;
- else
- bAnsi = FALSE;
- }
-
ZeroMemory(&consoleInfo, sizeof(consoleInfo));
consoleInfo.cbSize = sizeof(consoleInfo);
@@ -953,7 +991,7 @@ start_with_pty(wchar_t *command)
/*
* Windows PTY sends cursor positions in absolute coordinates starting from <0,0>
* We send a clear screen upfront to simplify client
- */
+ */
SendClearScreen(pipe_out);
ZeroMemory(&inputSi, sizeof(STARTUPINFO));
GetStartupInfo(&inputSi);
@@ -963,7 +1001,7 @@ start_with_pty(wchar_t *command)
hostThreadId = GetCurrentThreadId();
hostProcessId = GetCurrentProcessId();
InitializeCriticalSection(&criticalSection);
- hEventHook = __SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_LAYOUT, NULL,
+ hEventHook = __SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_END_APPLICATION, NULL,
ConsoleEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
memset(&si, 0, sizeof(STARTUPINFO));
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
diff --git a/contrib/win32/win32compat/ssh-agent/agent.h b/contrib/win32/win32compat/ssh-agent/agent.h
index 36686ffea..e919cfc4a 100644
--- a/contrib/win32/win32compat/ssh-agent/agent.h
+++ b/contrib/win32/win32compat/ssh-agent/agent.h
@@ -37,7 +37,7 @@ struct agent_connection {
};
void agent_connection_on_io(struct agent_connection*, DWORD, OVERLAPPED*);
-void agent_connection_on_error(struct agent_connection* , DWORD );
+void agent_connection_on_error(struct agent_connection* , DWORD);
void agent_connection_disconnect(struct agent_connection*);
void agent_start(BOOL, BOOL, HANDLE);
diff --git a/contrib/win32/win32compat/termio.c b/contrib/win32/win32compat/termio.c
index 967b20e97..d637aded0 100644
--- a/contrib/win32/win32compat/termio.c
+++ b/contrib/win32/win32compat/termio.c
@@ -39,6 +39,7 @@
#include "w32fd.h"
#include "tncon.h"
#include "inc\utf.h"
+#include "tnnet.h"
#define TERM_IO_BUF_SIZE 2048
@@ -136,6 +137,7 @@ WriteAPCProc(_In_ ULONG_PTR dwParam)
pio->write_overlapped.hEvent = 0;
}
+
/* Write worker thread */
static DWORD WINAPI
WriteThread(_In_ LPVOID lpParameter)
@@ -145,27 +147,27 @@ WriteThread(_In_ LPVOID lpParameter)
size_t resplen = 0;
DWORD dwSavedAttributes = ENABLE_PROCESSED_INPUT;
debug3("TermWrite thread, io:%p", pio);
-
- if (in_raw_mode == 0) {
- /* convert stream to utf16 and dump on console */
- pio->write_details.buf[write_status.to_transfer] = '\0';
+
+ pio->write_details.buf[write_status.to_transfer] = '\0';
+
+ if (0 == in_raw_mode) {
wchar_t* t = utf8_to_utf16(pio->write_details.buf);
WriteConsoleW(WINHANDLE(pio), t, wcslen(t), 0, 0);
- free(t);
- write_status.transferred = write_status.to_transfer;
+ free(t);
} else {
- /* console mode */
- telProcessNetwork(pio->write_details.buf, write_status.to_transfer, &respbuf, &resplen);
+ processBuffer(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer, &respbuf, &resplen);
/* TODO - respbuf is not null in some cases, this needs to be returned back via read stream */
- write_status.transferred = write_status.to_transfer;
}
+ write_status.transferred = write_status.to_transfer;
+
if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) {
debug("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
pio->write_details.pending = FALSE;
pio->write_details.error = GetLastError();
DebugBreak();
}
+
return 0;
}
diff --git a/contrib/win32/win32compat/tncon.c b/contrib/win32/win32compat/tncon.c
index 6d6d81e31..503816ec7 100644
--- a/contrib/win32/win32compat/tncon.c
+++ b/contrib/win32/win32compat/tncon.c
@@ -1,37 +1,37 @@
/*
- * Author: Ray Hayes
- * ANSI TTY Reader - Maps Windows console input events to ANSI stream
- *
- * Author: Balu
- * Misc fixes and code cleanup
- *
- * Copyright (c) 2017 Microsoft Corp.
- * All rights reserved
- *
- * This file is responsible for console reading calls for building an emulator
- * over Windows Console.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+* Author: Ray Hayes
+* ANSI TTY Reader - Maps Windows console input events to ANSI stream
+*
+* Author: Balu
+* Misc fixes and code cleanup
+*
+* Copyright (c) 2017 Microsoft Corp.
+* All rights reserved
+*
+* This file is responsible for console reading calls for building an emulator
+* over Windows Console.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
#include
#include
#include
@@ -75,10 +75,10 @@ TelParams* pParams = &Parameters;
void queue_terminal_window_change_event();
/*
- * For our case, in NetWriteString2(), we do not use socket, but write the out going data to
- * a global buffer setup by ReadConsoleForTermEmul().
- */
-int
+* For our case, in NetWriteString2(), we do not use socket, but write the out going data to
+* a global buffer setup by ReadConsoleForTermEmul().
+*/
+int
NetWriteString2(SOCKET sock, char* source, size_t len, int options)
{
while (len > 0) {
@@ -91,7 +91,7 @@ NetWriteString2(SOCKET sock, char* source, size_t len, int options)
return glob_outlen;
}
-BOOL
+BOOL
DataAvailable(HANDLE h)
{
DWORD dwRet = WaitForSingleObject(h, INFINITE);
@@ -102,7 +102,7 @@ DataAvailable(HANDLE h)
return FALSE;
}
-int
+int
ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
{
HANDLE hHandle[] = { hInput, NULL };
@@ -130,7 +130,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
break;
case FOCUS_EVENT:
- /* FALLTHROUGH */
+ /* FALLTHROUGH */
case MENU_EVENT:
break;
@@ -210,41 +210,41 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
case VK_F1:
if (dwControlKeyState == 0)
NetWriteString2(pParams->Socket, (char *)PF1_KEY, strlen(PF1_KEY), 0);
-
+
else if (dwControlKeyState == SHIFT_PRESSED)
NetWriteString2(pParams->Socket, (char *)SHIFT_PF1_KEY, strlen(SHIFT_PF1_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED)
NetWriteString2(pParams->Socket, (char *)CTRL_PF1_KEY, strlen(CTRL_PF1_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED)
NetWriteString2(pParams->Socket, (char *)ALT_PF1_KEY, strlen(ALT_PF1_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
(dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF1_KEY, strlen(SHIFT_ALT_CTRL_PF1_KEY), 0);
-
+
else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) &&
((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF1_KEY, strlen(ALT_CTRL_PF1_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
(dwControlKeyState & LEFT_ALT_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_PF1_KEY, strlen(SHIFT_ALT_PF1_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_CTRL_PF1_KEY, strlen(SHIFT_CTRL_PF1_KEY), 0);
-
+
break;
case VK_F2:
if (dwControlKeyState == 0)
NetWriteString2(pParams->Socket, (char *)PF2_KEY, strlen(PF2_KEY), 0);
-
+
else if (dwControlKeyState == SHIFT_PRESSED)
NetWriteString2(pParams->Socket, (char *)SHIFT_PF2_KEY, strlen(SHIFT_PF2_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED)
NetWriteString2(pParams->Socket, (char *)CTRL_PF2_KEY, strlen(CTRL_PF2_KEY), 0);
@@ -255,15 +255,15 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
(dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF2_KEY, strlen(SHIFT_ALT_CTRL_PF2_KEY), 0);
-
+
else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) &&
((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF2_KEY, strlen(ALT_CTRL_PF2_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
(dwControlKeyState & LEFT_ALT_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_PF2_KEY, strlen(SHIFT_ALT_PF2_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_CTRL_PF2_KEY, strlen(SHIFT_CTRL_PF2_KEY), 0);
@@ -271,13 +271,13 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
case VK_F3:
if (dwControlKeyState == 0)
NetWriteString2(pParams->Socket, (char *)PF3_KEY, strlen(PF3_KEY), 0);
-
+
else if (dwControlKeyState == SHIFT_PRESSED)
NetWriteString2(pParams->Socket, (char *)SHIFT_PF3_KEY, strlen(SHIFT_PF3_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED)
NetWriteString2(pParams->Socket, (char *)CTRL_PF3_KEY, strlen(CTRL_PF3_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED)
NetWriteString2(pParams->Socket, (char *)ALT_PF3_KEY, strlen(ALT_PF3_KEY), 0);
@@ -301,29 +301,29 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
case VK_F4:
if (dwControlKeyState == 0)
NetWriteString2(pParams->Socket, (char *)PF4_KEY, strlen(PF4_KEY), 0);
-
+
else if (dwControlKeyState == SHIFT_PRESSED)
NetWriteString2(pParams->Socket, (char *)SHIFT_PF4_KEY, strlen(SHIFT_PF4_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED)
NetWriteString2(pParams->Socket, (char *)CTRL_PF4_KEY, strlen(CTRL_PF4_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED)
NetWriteString2(pParams->Socket, (char *)ALT_PF4_KEY, strlen(ALT_PF4_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
(dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF4_KEY, strlen(SHIFT_ALT_CTRL_PF4_KEY), 0);
-
+
else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) &&
((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF4_KEY, strlen(ALT_CTRL_PF4_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
(dwControlKeyState & LEFT_ALT_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_PF4_KEY, strlen(SHIFT_ALT_PF4_KEY), 0);
-
+
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_CTRL_PF4_KEY, strlen(SHIFT_CTRL_PF4_KEY), 0);
@@ -331,10 +331,10 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
case VK_F5:
if (dwControlKeyState == 0)
NetWriteString2(pParams->Socket, (char *)PF5_KEY, strlen(PF5_KEY), 0);
-
+
else if (dwControlKeyState == SHIFT_PRESSED)
NetWriteString2(pParams->Socket, (char *)SHIFT_PF5_KEY, strlen(SHIFT_PF5_KEY), 0);
-
+
else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED)
NetWriteString2(pParams->Socket, (char *)CTRL_PF5_KEY, strlen(CTRL_PF5_KEY), 0);
@@ -345,7 +345,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
(dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF5_KEY, strlen(SHIFT_ALT_CTRL_PF5_KEY), 0);
-
+
else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) &&
((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF5_KEY, strlen(ALT_CTRL_PF5_KEY), 0);
@@ -492,7 +492,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
NetWriteString2(pParams->Socket, (char *)ALT_PF10_KEY, strlen(ALT_PF10_KEY), 0);
else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
- (dwControlKeyState & LEFT_ALT_PRESSED)) &&((dwControlKeyState & LEFT_CTRL_PRESSED) ||
+ (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF10_KEY, strlen(SHIFT_ALT_CTRL_PF10_KEY), 0);
@@ -521,7 +521,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED)
NetWriteString2(pParams->Socket, (char *)ALT_PF11_KEY, strlen(ALT_PF11_KEY), 0);
- else if ((dwControlKeyState & SHIFT_PRESSED) &&((dwControlKeyState & RIGHT_ALT_PRESSED) ||
+ else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) ||
(dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) ||
(dwControlKeyState & RIGHT_CTRL_PRESSED)))
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF11_KEY, strlen(SHIFT_ALT_CTRL_PF11_KEY), 0);
diff --git a/contrib/win32/win32compat/tnnet.c b/contrib/win32/win32compat/tnnet.c
index 9763010e0..310546e60 100644
--- a/contrib/win32/win32compat/tnnet.c
+++ b/contrib/win32/win32compat/tnnet.c
@@ -35,17 +35,20 @@
#include
#include
#include "ansiprsr.h"
+#include "inc\utf.h"
#define dwBuffer 4096
+extern BOOL isAnsiParsingRequired;
+
/*
* Server will always be returning a sequence of ANSI control characters which the client
* protocol can either passthru directly to the console or transform based on an output terminal
* type. We're not using termcap so we're only supporting the ANSI (vt100) sequences that
* are hardcoded in the server and will be transformed to Windows Console commands.
*/
-size_t
-telProcessNetwork(char *buf, size_t len, unsigned char **respbuf, size_t *resplen)
+void
+processBuffer(HANDLE handle, char *buf, size_t len, unsigned char **respbuf, size_t *resplen)
{
unsigned char szBuffer[dwBuffer + 8];
unsigned char* pszNewHead = NULL;
@@ -53,7 +56,17 @@ telProcessNetwork(char *buf, size_t len, unsigned char **respbuf, size_t *resple
unsigned char* pszTail = NULL;
if (len == 0)
- return len;
+ return;
+
+ if (false == isAnsiParsingRequired) {
+ /* Console has the capability to parse so pass the raw buffer to console directly */
+ ConRestoreViewRect(); /* Restore the visible window, otherwise WriteConsoleW() gets messy */
+ wchar_t* t = utf8_to_utf16(buf);
+ WriteConsoleW(handle, t, wcslen(t), 0, 0);
+ free(t);
+ ConSaveViewRect();
+ return;
+ }
/* Transform a single carriage return into a single linefeed before continuing */
if ((len == 1) && (buf[0] == 13))
@@ -74,6 +87,4 @@ telProcessNetwork(char *buf, size_t len, unsigned char **respbuf, size_t *resple
pszNewHead = ParseBuffer(pszHead, pszTail, respbuf, resplen);
} while ((pszNewHead != pszHead) && (pszNewHead < pszTail) && (resplen == NULL || (resplen != NULL && *resplen == 0)));
- len = 0;
- return len;
}
diff --git a/contrib/win32/win32compat/tnnet.h b/contrib/win32/win32compat/tnnet.h
index d2fb54b67..c3f5c312d 100644
--- a/contrib/win32/win32compat/tnnet.h
+++ b/contrib/win32/win32compat/tnnet.h
@@ -35,8 +35,6 @@
#ifndef __TNNET_H
#define __TNNET_H
+void processBuffer(HANDLE handle, char *buf, size_t len, unsigned char **respbuf, size_t *resplen);
- size_t telProcessNetwork (char *buf, size_t len, unsigned char **respbuf, size_t *resplen);
-
-#endif
-
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/sshtty.c b/sshtty.c
index aca8899cd..5825c85e7 100644
--- a/sshtty.c
+++ b/sshtty.c
@@ -52,8 +52,8 @@ static int _in_raw_mode = 0;
* TTY raw mode routines for Windows
*/
-int ConInit(DWORD OutputHandle, BOOL fSmartInit);
-int ConUnInit(void);
+int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
+int ConExitRawMode(void);
struct termios term_settings;
@@ -70,12 +70,12 @@ struct termios *
void
leave_raw_mode(int quiet) {
- ConUnInit();
+ ConExitRawMode();
}
void
enter_raw_mode(int quiet) {
- ConInit(STD_OUTPUT_HANDLE, TRUE);
+ ConEnterRawMode(STD_OUTPUT_HANDLE, TRUE);
}
#else /* !WINDOWS */
struct termios *