neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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 }