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