os_win_console.c (4043B)
1 #include <string.h> 2 3 #include "nvim/globals.h" 4 #include "nvim/memory.h" 5 #include "nvim/os/fs.h" 6 #include "nvim/os/input.h" 7 #include "nvim/os/os.h" 8 #include "nvim/os/os_win_console.h" 9 10 #include "os/os_win_console.c.generated.h" 11 12 static char origTitle[256] = { 0 }; 13 static HWND hWnd = NULL; 14 static HICON hOrigIconSmall = NULL; 15 static HICON hOrigIcon = NULL; 16 17 int os_open_conin_fd(void) 18 { 19 const HANDLE conin_handle = CreateFile("CONIN$", 20 GENERIC_READ | GENERIC_WRITE, 21 FILE_SHARE_READ | FILE_SHARE_WRITE, 22 (LPSECURITY_ATTRIBUTES)NULL, 23 OPEN_EXISTING, 0, (HANDLE)NULL); 24 assert(conin_handle != INVALID_HANDLE_VALUE); 25 int conin_fd = _open_osfhandle((intptr_t)conin_handle, _O_RDONLY); 26 assert(conin_fd != -1); 27 return conin_fd; 28 } 29 30 void os_clear_hwnd(void) 31 { 32 hWnd = NULL; 33 } 34 35 void os_replace_stdin_to_conin(void) 36 { 37 close(STDIN_FILENO); 38 const int conin_fd = os_open_conin_fd(); 39 assert(conin_fd == STDIN_FILENO); 40 } 41 42 void os_replace_stdout_and_stderr_to_conout(void) 43 { 44 const HANDLE conout_handle = 45 CreateFile("CONOUT$", 46 GENERIC_READ | GENERIC_WRITE, 47 FILE_SHARE_READ | FILE_SHARE_WRITE, 48 (LPSECURITY_ATTRIBUTES)NULL, 49 OPEN_EXISTING, 0, (HANDLE)NULL); 50 assert(conout_handle != INVALID_HANDLE_VALUE); 51 close(STDOUT_FILENO); 52 const int conout_fd = _open_osfhandle((intptr_t)conout_handle, 0); 53 assert(conout_fd == STDOUT_FILENO); 54 close(STDERR_FILENO); 55 const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0); 56 assert(conerr_fd == STDERR_FILENO); 57 } 58 59 /// Resets Windows console icon if we got an original one on startup. 60 void os_icon_reset(void) 61 { 62 if (hWnd == NULL) { 63 return; 64 } 65 66 if (hOrigIconSmall) { 67 SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hOrigIconSmall); 68 } 69 if (hOrigIcon) { 70 SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hOrigIcon); 71 } 72 } 73 74 /// Sets Nvim logo as Windows console icon. 75 /// 76 /// Saves the original icon so it can be restored at exit. 77 void os_icon_init(void) 78 { 79 if ((hWnd = GetConsoleWindow()) == NULL) { 80 return; 81 } 82 83 char *vimruntime = os_getenv("VIMRUNTIME"); 84 if (vimruntime != NULL) { 85 snprintf(NameBuff, MAXPATHL, "%s/neovim.ico", vimruntime); 86 if (!os_path_exists(NameBuff)) { 87 WLOG("neovim.ico not found: %s", NameBuff); 88 } else { 89 HICON hVimIcon = LoadImage(NULL, NameBuff, IMAGE_ICON, 64, 64, 90 LR_LOADFROMFILE | LR_LOADMAP3DCOLORS); 91 hOrigIconSmall = (HICON)SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hVimIcon); 92 hOrigIcon = (HICON)SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hVimIcon); 93 } 94 xfree(vimruntime); 95 } 96 } 97 98 /// Saves the original Windows console title. 99 void os_title_save(void) 100 { 101 GetConsoleTitle(origTitle, sizeof(origTitle)); 102 } 103 104 /// Resets the original Windows console title. 105 void os_title_reset(void) 106 { 107 SetConsoleTitle(origTitle); 108 } 109 110 #if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) 111 # define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 112 #endif 113 /// Guesses the terminal-type. Calls SetConsoleMode() and uv_set_vterm_state() 114 /// if appropriate. 115 /// 116 /// @param[in,out] term Name of the guessed terminal, statically-allocated 117 /// @param out_fd stdout file descriptor 118 void os_tty_guess_term(const char **term, int out_fd) 119 { 120 bool conemu_ansi = strequal(os_getenv_noalloc("ConEmuANSI"), "ON"); 121 bool vtp = false; 122 123 HANDLE handle = (HANDLE)_get_osfhandle(out_fd); 124 DWORD dwMode; 125 if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { 126 dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; 127 if (SetConsoleMode(handle, dwMode)) { 128 vtp = true; 129 } 130 } 131 132 if (*term == NULL) { 133 if (vtp) { 134 *term = "vtpcon"; 135 } else if (conemu_ansi) { 136 *term = "conemu"; 137 } else { 138 *term = "win32con"; 139 } 140 } 141 142 if (conemu_ansi) { 143 uv_tty_set_vterm_state(UV_TTY_SUPPORTED); 144 } 145 }