⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_win32.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
    return strcoll(fname, szName) == 0;
}

/*
 * Replace all slashes by backslashes.
 * This used to be the other way around, but MS-DOS sometimes has problems
 * with slashes (e.g. in a command name).  We can't have mixed slashes and
 * backslashes, because comparing file names will not work correctly.  The
 * commands that use a file name should try to avoid the need to type a
 * backslash twice.
 */
    void
slash_adjust(p)
    char_u  *p;
{
    while (*p)
    {
	if (*p == '/')
	    *p = '\\';
	++p;
    }
}


/*
 * get file permissions for `name'
 * -1 : error
 * else FILE_ATTRIBUTE_* defined in winnt.h
 */
    long
mch_getperm(
    char_u *name)
{
    return (long)GetFileAttributes((char *)name);
}


/*
 * set file permission for `name' to `perm'
 */
    int
mch_setperm(
    char_u *name,
    long perm)
{
    perm |= FILE_ATTRIBUTE_ARCHIVE;	/* file has changed, set archive bit */
    return SetFileAttributes((char *)name, perm) ? OK : FAIL;
}


/*
 * Set hidden flag for "name".
 */
    void
mch_hide(char_u *name)
{
    int	perm;

    perm = GetFileAttributes((char *)name);
    if (perm >= 0)
    {
	perm |= FILE_ATTRIBUTE_HIDDEN;
	SetFileAttributes((char *)name, perm);
    }
}

/*
 * return TRUE if "name" is a directory
 * return FALSE if "name" is not a directory or upon error
 */
    int
mch_isdir(char_u *name)
{
    int f = mch_getperm(name);

    if (f == -1)
	return FALSE;		    /* file does not exist at all */

    return (f & FILE_ATTRIBUTE_DIRECTORY) != 0;
}


#ifdef USE_GUI_WIN32
    void
mch_settmode(int tmode)
{
    /* nothing to do */
}

    int
mch_get_winsize()
{
    /* never used */
    return OK;
}

    void
mch_set_winsize()
{
    /* never used */
}
#else

/*
 * handler for ctrl-break, ctrl-c interrupts, and fatal events.
 */
    static BOOL WINAPI
handler_routine(
    DWORD dwCtrlType)
{
    switch (dwCtrlType)
    {
    case CTRL_C_EVENT:
	g_fCtrlCPressed = TRUE;
	return TRUE;

    case CTRL_BREAK_EVENT:
	g_fCBrkPressed	= TRUE;
	return TRUE;

    /* fatal events: shut down gracefully */
    case CTRL_CLOSE_EVENT:
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
	windgoto((int)Rows - 1, 0);
	sprintf((char *)IObuff, "Vim: Caught %s event\n",
		(dwCtrlType == CTRL_CLOSE_EVENT ? "close"
		 : dwCtrlType == CTRL_LOGOFF_EVENT ? "logoff" : "shutdown"));

#ifdef DEBUG
	OutputDebugString(IObuff);
#endif

	preserve_exit();	/* output IObuff, preserve files and exit */

	return TRUE;		/* not reached */

    default:
	return FALSE;
    }
}


/*
 * set the tty in (raw) ? "raw" : "cooked" mode
 */
    void
mch_settmode(
    int tmode)
{
    DWORD cmodein;
    DWORD cmodeout;

    GetConsoleMode(g_hConIn,  &cmodein);
    GetConsoleMode(g_hCurOut, &cmodeout);

    if (tmode == TMODE_RAW)
    {
	cmodein &= ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
		     ENABLE_ECHO_INPUT);
	cmodein |= (
#ifdef USE_MOUSE
	    (g_fMouseActive ? ENABLE_MOUSE_INPUT : 0) |
#endif
	    ENABLE_WINDOW_INPUT);

	SetConsoleMode(g_hConIn, cmodein);

	cmodeout &= ~(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
	SetConsoleMode(g_hCurOut, cmodeout);
	SetConsoleCtrlHandler(handler_routine, TRUE);
    }
    else /* cooked */
    {
	cmodein =  g_cmodein;
	cmodeout = g_cmodeout;
	SetConsoleMode(g_hConIn,  g_cmodein);
	SetConsoleMode(g_hCurOut, g_cmodeout);

	SetConsoleCtrlHandler(handler_routine, FALSE);
    }

#ifdef MCH_WRITE_DUMP
    if (fdDump)
    {
	fprintf(fdDump, "mch_settmode(%s, CurOut = %s, in = %x, out = %x)\n",
		tmode == TMODE_RAW ? "raw" :
				    tmode == TMODE_COOK ? "cooked" : "normal",
		(g_hCurOut == g_hSavOut ? "Sav" : "Con"),
		cmodein, cmodeout);
	fflush(fdDump);
    }
#endif
}


/*
 * Get the size of the current window in `Rows' and `Columns'
 * Return OK when size could be determined, FAIL otherwise.
 */
    int
mch_get_winsize()
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;

    if (GetConsoleScreenBufferInfo(g_hCurOut, &csbi))
    {
	Rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
	Columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    }
    else
    {
	Rows = 25;
	Columns = 80;
    }

    if (Columns < MIN_COLUMNS || Rows < MIN_LINES)
    {
	/* these values are overwritten by termcap size or default */
	Rows = 25;
	Columns = 80;
    }

    check_winsize();
    set_scroll_region(0, 0, Columns - 1, Rows - 1);

    return OK;
}


/*
 * Set a console window to `xSize' * `ySize'
 */
    static void
ResizeConBufAndWindow(
    HANDLE hConsole,
    int xSize,
    int ySize)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;	/* hold current console buffer info */
    SMALL_RECT	    srWindowRect;	/* hold the new console size */
    COORD	    coordScreen;
    int		    did_start_termcap = FALSE;

#ifdef MCH_WRITE_DUMP
    if (fdDump)
    {
	fprintf(fdDump, "ResizeConBufAndWindow(%d, %d)\n", xSize, ySize);
	fflush(fdDump);
    }
#endif

    /*
     * The resizing MUST be done while in our own console buffer, otherwise it
     * will never be possible to restore the old one, and we will crash on
     * exit in Windows 95.
     */
    if (g_hCurOut != g_hConOut)
    {
	termcap_mode_start();
	did_start_termcap = TRUE;
    }

    /* get the largest size we can size the console window to */
    coordScreen = GetLargestConsoleWindowSize(hConsole);

    /* define the new console window size and scroll position */
    srWindowRect.Left = srWindowRect.Top = (SHORT) 0;
    srWindowRect.Right =  (SHORT) (min(xSize, coordScreen.X) - 1);
    srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1);

    if (GetConsoleScreenBufferInfo(g_hCurOut, &csbi))
    {
	int sx, sy;

	sx = csbi.srWindow.Right - csbi.srWindow.Left + 1;
	sy = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
	if (sy < ySize || sx < xSize)
	{
	    /*
	     * Increasing number of lines/columns, do buffer first.
	     * Use the maximal size in x and y direction.
	     */
	    if (sy < ySize)
		coordScreen.Y = ySize;
	    else
		coordScreen.Y = sy;
	    if (sx < xSize)
		coordScreen.X = xSize;
	    else
		coordScreen.X = sx;
	    SetConsoleScreenBufferSize(hConsole, coordScreen);
	}
    }

    if (!SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect))
    {
#ifdef MCH_WRITE_DUMP
	if (fdDump)
	{
	    fprintf(fdDump, "SetConsoleWindowInfo failed: %lx\n",
		    GetLastError());
	    fflush(fdDump);
	}
#endif
    }

    /* define the new console buffer size */
    coordScreen.X = xSize;
    coordScreen.Y = ySize;

    if (!SetConsoleScreenBufferSize(hConsole, coordScreen))
    {
#ifdef MCH_WRITE_DUMP
	if (fdDump)
	{
	    fprintf(fdDump, "SetConsoleScreenBufferSize failed: %lx\n",
		    GetLastError());
	    fflush(fdDump);
	}
#endif
    }

    if (did_start_termcap)
	termcap_mode_end();
}


/*
 * Set the console window to `Rows' * `Columns'
 */
    void
mch_set_winsize()
{
    COORD coordScreen;

    /* Don't change window size while still starting up */
    if (suppress_winsize)
    {
	suppress_winsize = 2;
	return;
    }

    coordScreen = GetLargestConsoleWindowSize(g_hCurOut);

    /* Clamp Rows and Columns to reasonable values */
    if (Rows > coordScreen.Y)
	Rows = coordScreen.Y;
    if (Columns > coordScreen.X)
	Columns = coordScreen.X;

    ResizeConBufAndWindow(g_hCurOut, Columns, Rows);
    set_scroll_region(0, 0, Columns - 1, Rows - 1);
}

/*
 * Called when started up, to set the winsize that was delayed.
 */
    void
mch_set_winsize_now()
{
    if (suppress_winsize == 2)
    {
	suppress_winsize = 0;
	mch_set_winsize();
	check_winsize();	    /* in case 'columns' changed */
    }
    suppress_winsize = 0;
}
#endif /* USE_GUI_WIN32 */


/*
 * We have no job control, so fake it by starting a new shell.
 */
    void
mch_suspend()
{
    suspend_shell();
}

#if defined(USE_GUI_WIN32) || defined(PROTO)

#ifdef OLD_CONSOLE_STUFF
/*
 * Functions to open and close a console window.
 * The open function sets the size of the window to 25x80, to avoid problems
 * with Windows 95.  In the long term should make sure that the "close" icon
 * cannot crash vim (it doesn't do so at the moment!).
 * The close function waits for the user to press a key before closing the
 * window.
 */

    static BOOL
ConsoleCtrlHandler(DWORD what)
{
    return TRUE;
}

    static void
mch_open_console(void)
{
    COORD	size;
    SMALL_RECT	window_size;
    HANDLE	console_handle;

    AllocConsole();

    /* On windows 95, we must use a 25x80 console size, to avoid trouble with
     * some DOS commands */
    if (g_PlatformId != VER_PLATFORM_WIN32_NT)
    {
	console_handle = GetStdHandle(STD_OUTPUT_HANDLE);

	size.X = 80;
	size.Y = 25;
	window_size.Left = 0;
	window_size.Top = 0;
	window_size.Right = 79;
	window_size.Bottom = 24;

	/* First set the window size, then also resize the screen buffer, to
	 * avoid a scrollbar */
	SetConsoleWindowInfo(console_handle, TRUE, &window_size);
	SetConsoleScreenBufferSize(console_handle, size);
    }

    SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleCtrlHandler, TRUE);
}

    static void
mch_close_console(int wait_key, DWORD ret)
{
    if (wait_key)
    {
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
	DWORD number;
	static char message[] = "\nPress any key to close this window...";
	static char err_buf[80];
	char buffer[1];

	if (ret)
	{
	    sprintf(err_buf, "\n%ld returned.", ret);
	    WriteConsole(hStderr, err_buf, strlen(err_buf), &number, NULL);
	}
	/* Write a message to the user */
	WriteConsole(hStderr, message, sizeof(message)-1, &number, NULL);

	/* Clear the console input buffer, and set the input to "raw" mode */
	FlushConsoleInputBuffer(hStdin);
	SetConsoleMode(hStdin, 0);

	/* Wait for a keypress */
	ReadConsole(hStdin, buffer, 1, &number, NULL);
    }

    /* Close the console window */
    FreeConsole();
}
#endif

#ifdef mch_errmsg
# undef mch_errmsg
# undef mch_display_error
#endif

/*
 * Record an error message for later display.
 */
    void
mch_errmsg(char *str)
{
    int		len = STRLEN(str) + 1;

    if (error_ga.ga_growsize == 0)
    {
	error_ga.ga_growsize = 80;
	error_ga.ga_itemsize = 1;
    }
    if (ga_grow(&error_ga, len) == OK)
    {
	mch_memmove((char_u *)error_ga.ga_data + error_ga.ga_len,
							  (char_u *)str, len);
	--len;			/* don't count the NUL at the end */
	error_ga.ga_len += len;
	error_ga.ga_room -= len;
    }
}

/*
 * Display the saved error message(s).
 */
    void
mch_display_error()
{
    char *p;

    if (error_ga.ga_data != NULL)
    {
	/* avoid putting up a message box with blanks only */
	for (p = (char *)error_ga.ga_data; *p; ++p)
	    if (!isspace(*p))
	    {
		MessageBox(0, p, "Vim", MB_TASKMODAL|MB_SETFOREGROUND);
		break;
	    }
	ga_clear(&error_ga);
    }
}

/*
 * Specialised version of system() for Win32 GUI mode.
 * This version proceeds as follows:
 *    1. Create a console window for use by the subprocess
 *    2. Run the subprocess (it gets the allocated console by default)
 *    3. Wait for the subprocess to terminate and get its exit code
 *    4. Prompt the user to press a key to close the console window
 */
static BOOL fUseConsole = TRUE;

    static int
mch_system(char *cmd, int options)
{
    STARTUPINFO		si;
    PROCESS_INFORMATION pi;
    DWORD		ret = 0;

    si.cb = sizeof(si);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
    si.dwFlags = STARTF_USESHOWWINDOW;
    /*
     * It's nicer to run a filter command in a minimized window, but in
     * Windows 95 this makes the command MUCH slower.
     */
    if ((options & SHELL_DOOUT) && !mch_windows95())
	si.wShowWindow = SW_SHOWMINIMIZED;
    else
	si.wShowWindow = SW_SHOWNORMAL;
    si.cbReserved2 = 0;
    si.lpReserved2 = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -