patch 8.1.0940: MS-Windows console resizing not handled properly

Problem:    MS-Windows console resizing not handled properly.
Solution:   Handle resizing the console better. (Nobuhiro Takasaki,
            closes #3968, closes #3611)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index ccca2f9..8cdb046 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -9853,6 +9853,9 @@
     if (need_maketitle)
 	maketitle();
 #endif
+#if defined(WIN3264) && !defined(FEAT_GUI_W32)
+    resize_console_buf();
+#endif
     RedrawingDisabled = r;
     p_lz = p;
 
diff --git a/src/normal.c b/src/normal.c
index 624e347..ca0d8ff 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -5401,6 +5401,9 @@
 # endif
 #endif
 	redraw_later(CLEAR);
+#if defined(WIN3264) && !defined(FEAT_GUI_W32)
+	resize_console_buf();
+#endif
     }
 }
 
diff --git a/src/os_win32.c b/src/os_win32.c
index 97fc2a4..a392d13 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1492,6 +1492,8 @@
     ui_focus_change((int)g_fJustGotFocus);
 }
 
+static void ResizeConBuf(HANDLE hConsole, COORD coordScreen);
+
 /*
  * Wait until console input from keyboard or mouse is available,
  * or the time is up.
@@ -1657,11 +1659,18 @@
 		handle_focus_event(ir);
 	    else if (ir.EventType == WINDOW_BUFFER_SIZE_EVENT)
 	    {
-		/* Only call shell_resized() when the size actually change to
-		 * avoid the screen is cleard. */
-		if (ir.Event.WindowBufferSizeEvent.dwSize.X != Columns
-			|| ir.Event.WindowBufferSizeEvent.dwSize.Y != Rows)
+		COORD dwSize = ir.Event.WindowBufferSizeEvent.dwSize;
+
+		// Only call shell_resized() when the size actually change to
+		// avoid the screen is cleard.
+		if (dwSize.X != Columns || dwSize.Y != Rows)
+		{
+		    CONSOLE_SCREEN_BUFFER_INFO csbi;
+		    GetConsoleScreenBufferInfo(g_hConOut, &csbi);
+		    dwSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+		    ResizeConBuf(g_hConOut, dwSize);
 		    shell_resized();
+		}
 	    }
 #ifdef FEAT_MOUSE
 	    else if (ir.EventType == MOUSE_EVENT
@@ -6327,7 +6336,7 @@
 	     * character was written, otherwise we get stuck. */
 	    if (WriteConsoleOutputCharacterW(g_hConOut, unicodebuf, length,
 			coord, &cchwritten) == 0
-		    || cchwritten == 0)
+		    || cchwritten == 0 || cchwritten == (DWORD)-1)
 		cchwritten = 1;
 	}
 	else
@@ -6361,7 +6370,7 @@
 	     * character was written, otherwise we get stuck. */
 	    if (WriteConsoleOutputCharacter(g_hConOut, (LPCSTR)pchBuf, cbToWrite,
 			coord, &written) == 0
-		    || written == 0)
+		    || written == 0 || written == (DWORD)-1)
 		written = 1;
 	}
 	else
@@ -7707,7 +7716,7 @@
 
 }
 
-#ifndef FEAT_GUI_W32
+#if !defined(FEAT_GUI_W32) || defined(PROTO)
 
     static void
 vtp_init(void)
@@ -7931,3 +7940,28 @@
 {
     return conpty_stable;
 }
+
+#if !defined(FEAT_GUI_W32) || defined(PROTO)
+    void
+resize_console_buf(void)
+{
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+    COORD coord;
+    SMALL_RECT newsize;
+
+    if (GetConsoleScreenBufferInfo(g_hConOut, &csbi))
+    {
+	coord.X = SRWIDTH(csbi.srWindow);
+	coord.Y = SRHEIGHT(csbi.srWindow);
+	SetConsoleScreenBufferSize(g_hConOut, coord);
+
+	newsize.Left = 0;
+	newsize.Top = 0;
+	newsize.Right = coord.X - 1;
+	newsize.Bottom = coord.Y - 1;
+	SetConsoleWindowInfo(g_hConOut, TRUE, &newsize);
+
+	SetConsoleScreenBufferSize(g_hConOut, coord);
+    }
+}
+#endif
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index 6157e01..ca5bad6 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -75,4 +75,5 @@
 int has_vtp_working(void);
 int has_conpty_working(void);
 int is_conpty_stable(void);
+void resize_console_buf(void);
 /* vim: set ft=c : */
diff --git a/src/version.c b/src/version.c
index 06500bd..e042578 100644
--- a/src/version.c
+++ b/src/version.c
@@ -780,6 +780,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    940,
+/**/
     939,
 /**/
     938,