comparison src/os_win32.c @ 20589:ecaceb5c5644 v8.2.0848

patch 8.2.0848: MS-Windows: the Windows terminal code has some flaws Commit: https://github.com/vim/vim/commit/06b7b58455f9c09be3d1c36d174ffbfdf4efcd79 Author: Bram Moolenaar <Bram@vim.org> Date: Sat May 30 17:49:25 2020 +0200 patch 8.2.0848: MS-Windows: the Windows terminal code has some flaws Problem: MS-Windows: the Windows terminal code has some flaws. Solution: Do not redraw the right edge of the screen. Remove the background color trick. Flush the screen output buffer often. (Nobuhiro Takasaki, #5546)
author Bram Moolenaar <Bram@vim.org>
date Sat, 30 May 2020 18:00:04 +0200
parents af8feeaf167a
children 89b0f161e6a6
comparison
equal deleted inserted replaced
20588:7d6b68ad708c 20589:ecaceb5c5644
193 193
194 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) 194 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
195 static int vtp_working = 0; 195 static int vtp_working = 0;
196 static void vtp_init(); 196 static void vtp_init();
197 static void vtp_exit(); 197 static void vtp_exit();
198 static int vtp_printf(char *format, ...);
199 static void vtp_sgr_bulk(int arg); 198 static void vtp_sgr_bulk(int arg);
200 static void vtp_sgr_bulks(int argc, int *argv); 199 static void vtp_sgr_bulks(int argc, int *argv);
200
201 static int wt_working = 0;
202 static void wt_init();
201 203
202 static guicolor_T save_console_bg_rgb; 204 static guicolor_T save_console_bg_rgb;
203 static guicolor_T save_console_fg_rgb; 205 static guicolor_T save_console_fg_rgb;
204 static guicolor_T store_console_bg_rgb; 206 static guicolor_T store_console_bg_rgb;
205 static guicolor_T store_console_fg_rgb; 207 static guicolor_T store_console_fg_rgb;
212 static int default_console_color_fg = 0xc0c0c0; // white 214 static int default_console_color_fg = 0xc0c0c0; // white
213 # endif 215 # endif
214 216
215 # ifdef FEAT_TERMGUICOLORS 217 # ifdef FEAT_TERMGUICOLORS
216 # define USE_VTP (vtp_working && is_term_win32() && (p_tgc || (!p_tgc && t_colors >= 256))) 218 # define USE_VTP (vtp_working && is_term_win32() && (p_tgc || (!p_tgc && t_colors >= 256)))
219 # define USE_WT (wt_working)
217 # else 220 # else
218 # define USE_VTP 0 221 # define USE_VTP 0
222 # define USE_WT 0
219 # endif 223 # endif
220 224
221 static void set_console_color_rgb(void); 225 static void set_console_color_rgb(void);
222 static void reset_console_color_rgb(void); 226 static void reset_console_color_rgb(void);
223 static void restore_console_color_rgb(void); 227 static void restore_console_color_rgb(void);
233 #endif 237 #endif
234 238
235 static char_u *exe_path = NULL; 239 static char_u *exe_path = NULL;
236 240
237 static BOOL win8_or_later = FALSE; 241 static BOOL win8_or_later = FALSE;
242
243 # if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__)
244 # define UChar UnicodeChar
245 # else
246 # define UChar uChar.UnicodeChar
247 # endif
238 248
239 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) 249 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
240 // Dynamic loading for portability 250 // Dynamic loading for portability
241 typedef struct _DYN_CONSOLE_SCREEN_BUFFER_INFOEX 251 typedef struct _DYN_CONSOLE_SCREEN_BUFFER_INFOEX
242 { 252 {
284 } 294 }
285 return ver; 295 return ver;
286 } 296 }
287 297
288 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) 298 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
299 static BOOL
300 is_ambiwidth_event(
301 INPUT_RECORD *ir)
302 {
303 return ir->EventType == KEY_EVENT
304 && ir->Event.KeyEvent.bKeyDown
305 && ir->Event.KeyEvent.wRepeatCount == 1
306 && ir->Event.KeyEvent.wVirtualKeyCode == 0x12
307 && ir->Event.KeyEvent.wVirtualScanCode == 0x38
308 && ir->Event.KeyEvent.UChar == 0
309 && ir->Event.KeyEvent.dwControlKeyState == 2;
310 }
311
312 static void
313 make_ambiwidth_event(
314 INPUT_RECORD *down,
315 INPUT_RECORD *up)
316 {
317 down->Event.KeyEvent.wVirtualKeyCode = 0;
318 down->Event.KeyEvent.wVirtualScanCode = 0;
319 down->Event.KeyEvent.UChar = up->Event.KeyEvent.UChar;
320 down->Event.KeyEvent.dwControlKeyState = 0;
321 }
322
289 /* 323 /*
290 * Version of ReadConsoleInput() that works with IME. 324 * Version of ReadConsoleInput() that works with IME.
291 * Works around problems on Windows 8. 325 * Works around problems on Windows 8.
292 */ 326 */
293 static BOOL 327 static BOOL
320 return ReadConsoleInputW(hInput, lpBuffer, 1, &dwEvents); 354 return ReadConsoleInputW(hInput, lpBuffer, 1, &dwEvents);
321 } 355 }
322 356
323 if (s_dwMax == 0) 357 if (s_dwMax == 0)
324 { 358 {
325 if (nLength == -1) 359 if (!USE_WT && nLength == -1)
326 return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents); 360 return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
327 if (!ReadConsoleInputW(hInput, s_irCache, IRSIZE, &dwEvents)) 361 GetNumberOfConsoleInputEvents(hInput, &dwEvents);
328 return FALSE; 362 if (dwEvents == 0 && nLength == -1)
363 return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
364 ReadConsoleInputW(hInput, s_irCache, IRSIZE, &dwEvents);
329 s_dwIndex = 0; 365 s_dwIndex = 0;
330 s_dwMax = dwEvents; 366 s_dwMax = dwEvents;
331 if (dwEvents == 0) 367 if (dwEvents == 0)
332 { 368 {
333 *lpEvents = 0; 369 *lpEvents = 0;
334 return TRUE; 370 return TRUE;
335 } 371 }
372
373 for (i = s_dwIndex; i < (int)s_dwMax - 1; ++i)
374 if (is_ambiwidth_event(&s_irCache[i]))
375 make_ambiwidth_event(&s_irCache[i], &s_irCache[i + 1]);
336 376
337 if (s_dwMax > 1) 377 if (s_dwMax > 1)
338 { 378 {
339 head = 0; 379 head = 0;
340 tail = s_dwMax - 1; 380 tail = s_dwMax - 1;
934 { VK_NUMPAD8,TRUE, '\372', '\373', '\374', '\375', }, 974 { VK_NUMPAD8,TRUE, '\372', '\373', '\374', '\375', },
935 // Sorry, out of number space! <negri> 975 // Sorry, out of number space! <negri>
936 { VK_NUMPAD9,TRUE, '\376', '\377', '|', '}', }, 976 { VK_NUMPAD9,TRUE, '\376', '\377', '|', '}', },
937 }; 977 };
938 978
939
940 # if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__)
941 # define UChar UnicodeChar
942 # else
943 # define UChar uChar.UnicodeChar
944 # endif
945 979
946 /* 980 /*
947 * The return code indicates key code size. 981 * The return code indicates key code size.
948 */ 982 */
949 static int 983 static int
2687 win_clip_init(); 2721 win_clip_init();
2688 # endif 2722 # endif
2689 2723
2690 vtp_flag_init(); 2724 vtp_flag_init();
2691 vtp_init(); 2725 vtp_init();
2726 wt_init();
2692 } 2727 }
2693 2728
2694 /* 2729 /*
2695 * non-GUI version of mch_exit(). 2730 * non-GUI version of mch_exit().
2696 * Shut down and exit with status `r' 2731 * Shut down and exit with status `r'
5779 { 5814 {
5780 coord.Y = i; 5815 coord.Y = i;
5781 clear_chars(coord, source.Right - source.Left + 1); 5816 clear_chars(coord, source.Right - source.Left + 1);
5782 } 5817 }
5783 } 5818 }
5819
5820 if (USE_WT)
5821 {
5822 COORD coord;
5823 int i;
5824
5825 coord.X = source.Left;
5826 for (i = source.Top; i < dest.Y; ++i)
5827 {
5828 coord.Y = i;
5829 clear_chars(coord, source.Right - source.Left + 1);
5830 }
5831 }
5784 } 5832 }
5785 5833
5786 5834
5787 /* 5835 /*
5788 * Delete `cLines' lines at the current cursor position 5836 * Delete `cLines' lines at the current cursor position
5830 COORD coord; 5878 COORD coord;
5831 int i; 5879 int i;
5832 5880
5833 coord.X = source.Left; 5881 coord.X = source.Left;
5834 for (i = nb; i < clip.Bottom; ++i) 5882 for (i = nb; i < clip.Bottom; ++i)
5883 {
5884 coord.Y = i;
5885 clear_chars(coord, source.Right - source.Left + 1);
5886 }
5887 }
5888
5889 if (USE_WT)
5890 {
5891 COORD coord;
5892 int i;
5893
5894 coord.X = source.Left;
5895 for (i = nb; i <= source.Bottom; ++i)
5835 { 5896 {
5836 coord.Y = i; 5897 coord.Y = i;
5837 clear_chars(coord, source.Right - source.Left + 1); 5898 clear_chars(coord, source.Right - source.Left + 1);
5838 } 5899 }
5839 } 5900 }
7585 vtp_exit(void) 7646 vtp_exit(void)
7586 { 7647 {
7587 restore_console_color_rgb(); 7648 restore_console_color_rgb();
7588 } 7649 }
7589 7650
7590 static int 7651 int
7591 vtp_printf( 7652 vtp_printf(
7592 char *format, 7653 char *format,
7593 ...) 7654 ...)
7594 { 7655 {
7595 char_u buf[100]; 7656 char_u buf[100];
7758 default: 7819 default:
7759 break; 7820 break;
7760 } 7821 }
7761 } 7822 }
7762 7823
7824 static void
7825 wt_init(void)
7826 {
7827 wt_working = (mch_getenv("WT_SESSION") != NULL);
7828 }
7829
7830 int
7831 use_wt(void)
7832 {
7833 return USE_WT;
7834 }
7835
7763 # ifdef FEAT_TERMGUICOLORS 7836 # ifdef FEAT_TERMGUICOLORS
7764 static int 7837 static int
7765 ctermtoxterm( 7838 ctermtoxterm(
7766 int cterm) 7839 int cterm)
7767 { 7840 {
7782 7855
7783 if (!USE_VTP) 7856 if (!USE_VTP)
7784 return; 7857 return;
7785 7858
7786 get_default_console_color(&ctermfg, &ctermbg, &fg, &bg); 7859 get_default_console_color(&ctermfg, &ctermbg, &fg, &bg);
7860
7861 if (USE_WT)
7862 {
7863 term_fg_rgb_color(fg);
7864 term_bg_rgb_color(bg);
7865 return;
7866 }
7787 7867
7788 fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg); 7868 fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg);
7789 bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg); 7869 bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg);
7790 7870
7791 csbi.cbSize = sizeof(csbi); 7871 csbi.cbSize = sizeof(csbi);
7856 reset_console_color_rgb(void) 7936 reset_console_color_rgb(void)
7857 { 7937 {
7858 # ifdef FEAT_TERMGUICOLORS 7938 # ifdef FEAT_TERMGUICOLORS
7859 DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi; 7939 DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
7860 7940
7941 if (USE_WT)
7942 return;
7943
7861 csbi.cbSize = sizeof(csbi); 7944 csbi.cbSize = sizeof(csbi);
7862 if (has_csbiex) 7945 if (has_csbiex)
7863 pGetConsoleScreenBufferInfoEx(g_hConOut, &csbi); 7946 pGetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
7864 7947
7865 csbi.cbSize = sizeof(csbi); 7948 csbi.cbSize = sizeof(csbi);