home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
text
/
vim
/
src
/
winnt.c
< prev
Wrap
C/C++ Source or Header
|
1995-02-27
|
31KB
|
1,198 lines
/* vi:ts=4:sw=4
*
* VIM - Vi IMproved
*
*/
/*
* winnt.c
*
* Windows NT system-dependent routines.
* A reasonable approximation of the amiga dependent code.
* Portions lifted from SDK samples, from the MSDOS dependent code,
* and from NetHack 3.1.3.
*
* rogerk@wonderware.com
*/
#include <io.h>
#include "vim.h"
#include "globals.h"
#include "param.h"
#include "proto.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <windows.h>
#include <wincon.h>
static int WaitForChar __ARGS((int));
static int cbrk_handler __ARGS(());
/* Win32 Console handles for input and output */
HANDLE hConIn;
HANDLE hConOut;
/* Win32 Screen buffer,coordinate,console I/O information */
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD ntcoord;
INPUT_RECORD ir;
/* The attribute of the screen when the editor was started */
WORD DefaultAttribute;
typedef struct filelist {
char **file;
int nfiles;
int maxfiles;
} FileList;
static void addfile __ARGS((FileList *, char *, int));
static int pstrcmp(); /* __ARGS((char **, char **)); BCC does not
* like this */
static void strlowcpy __ARGS((char *, char *));
static int expandpath __ARGS((FileList *, char *, int, int, int));
static int cbrk_pressed = FALSE; /* set by ctrl-break interrupt */
static int ctrlc_pressed = FALSE; /* set when ctrl-C or ctrl-break
* detected */
void vim_delay()
{
delay(500);
}
/*
* this version of remove is not scared by a readonly (backup) file
*/
int vim_remove(name)
char *name;
{
setperm(name, _S_IWRITE); /* default permissions */
return unlink(name);
}
/*
* mch_write(): write the output buffer to the screen
*/
void mch_write(s, len)
char *s;
int len;
{
char *p;
int row,
col;
s[len] = '\0';
if (term_console) /* translate ESC | sequences into bios calls */
while (len--) {
/* optimization: use one single WriteConsole for runs of text,
rather than calling putch() multiple times. It ain't curses,
but it helps. */
DWORD prefix = strcspn(s, "\n\r\a\033");
if (prefix) {
DWORD nwritten;
if (WriteConsole(hConOut, s, prefix, &nwritten, 0)) {
len -= (nwritten - 1);
s += nwritten;
}
continue;
}
if (s[0] == '\n') {
if (ntcoord.Y == (Rows - 1)) {
gotoxy(1, ntcoord.Y + 1);
scroll();
} else {
gotoxy(1, ntcoord.Y + 2);
}
s++;
continue;
} else if (s[0] == '\r') {
gotoxy(1, ntcoord.Y + 1);
s++;
continue;
} else if (s[0] == '\a') {
vbell();
s++;
continue;
} else if (s[0] == ESC && len > 1 && s[1] == '|') {
switch (s[2]) {
case 'v':
cursor_visible(0);
goto got3;
case 'V':
cursor_visible(1);
goto got3;
case 'J':
clrscr();
goto got3;
case 'K':
clreol();
goto got3;
case 'L':
insline(1);
goto got3;
case 'M':
delline(1);
got3: s += 3;
len -= 2;
continue;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
p = s + 2;
row = getdigits(&p); /* no check for length! */
if (p > s + len)
break;
if (*p == ';') {
++p;
col = getdigits(&p); /* no check for length! */
if (p > s + len)
break;
if (*p == 'H') {
gotoxy(col, row);
len -= p - s;
s = p + 1;
continue;
}
} else if (*p == 'm') {
if (row == 0)
normvideo();
else
textattr(row);
len -= p - s;
s = p + 1;
continue;
} else if (*p == 'L') {
insline(row);
len -= p - s;
s = p + 1;
continue;
} else if (*p == 'M') {
delline(row);
len -= p - s;
s = p + 1;
continue;
}
}
}
putch(*s++);
}
else
write(1, s, (unsigned) len);
}
/*
* Keyboard translation tables.
* (Adopted from the MSDOS port)
*/
#define KEYPADLO 0x47
#define KEYPADHI 0x53
#define PADKEYS (KEYPADHI - KEYPADLO + 1)
#define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
/*
* Wait until console input is available
*/
static int WaitForChar(msec)
int msec;
{
int count;
int ch;
int scan;
int shiftstate;
int altseq;
int retval = 0;
if (WaitForSingleObject(hConIn, msec) == WAIT_OBJECT_0) {
count = 0;
PeekConsoleInput(hConIn, &ir, 1, &count);
if (count > 0) {
ch = ir.Event.KeyEvent.uChar.AsciiChar;
scan = ir.Event.KeyEvent.wVirtualScanCode;
shiftstate = ir.Event.KeyEvent.dwControlKeyState;
if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) &&
(ch || (iskeypad(scan)))) {
retval = 1; /* Found what we sought */
}
} else { /* There are no events in console event queue */
retval = 0;
}
}
return retval;
}
static int pending = 0;
int tgetch()
{
int valid = 0;
int metaflags = 0;
int count;
unsigned short int scan;
unsigned char ch;
unsigned long shiftstate;
const struct pad *kpad;
char keymess[100];
if (pending)
{
ch = pending;
pending = 0;
}
else
{
valid = 0;
while (!valid) {
ReadConsoleInput(hConIn, &ir, 1, &count);
if (ir.EventType == WINDOW_BUFFER_SIZE_EVENT) {
set_winsize(Rows, Columns, FALSE);
}
else
{
if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
{
ch = ir.Event.KeyEvent.uChar.AsciiChar;
scan = ir.Event.KeyEvent.wVirtualScanCode;
if (ch || (iskeypad(scan)))
valid = 1;
}
}
}
if (!ch)
{
pending = scan;
ch = 0;
}
}
return ch;
}
int kbhit()
{
int done = 0; /* true = "stop searching" */
int retval; /* true = "we had a match" */
int count;
unsigned short int scan;
unsigned char ch;
unsigned long shiftstate;
if (pending)
return 1;
done = 0;
retval = 0;
while (!done) {
count = 0;
PeekConsoleInput(hConIn, &ir, 1, &count);
if (count > 0) {
ch = ir.Event.KeyEvent.uChar.AsciiChar;
scan = ir.Event.KeyEvent.wVirtualScanCode;
shiftstate = ir.Event.KeyEvent.dwControlKeyState;
if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) &&
(ch || (iskeypad(scan)) )) {
done = 1; /* Stop looking */
retval = 1; /* Found what we sought */
} else /* Discard it, its an insignificant event */
ReadConsoleInput(hConIn, &ir, 1, &count);
} else { /* There are no events in console event queue */
done = 1; /* Stop looking */
retval = 0;
}
}
return retval;
}
/*
* GetChars(): low level input funcion.
* Get a characters from the keyboard.
* If time == 0 do not wait for characters.
* If time == n wait a short time for characters.
* If time == -1 wait forever for characters.
*/
int GetChars(buf, maxlen, time)
char *buf;
int maxlen;
int time;
{
int len = 0;
int c;
if (time >= 0) {
if (time == 0) /* don't know if time == 0 is allowed */
time = 1;
if (WaitForChar(time) == 0) /* no character available */
return 0;
} else { /* time == -1 */
/* If there is no character available within 2 seconds (default)
* write the autoscript file to disk */
if (WaitForChar((int) p_ut) == 0)
updatescript(0);
}
/*
* Try to read as many characters as there are.
* Works for the controlling tty only.
*/
--maxlen; /* may get two chars at once */
/* we will get at least one key. Get more if they are available After a
* ctrl-break we have to read a 0 (!) from the buffer. bioskey(1) will
* return 0 if no key is available and when a ctrl-break was typed. When
* ctrl-break is hit, this does not always implies a key hit. */
cbrk_pressed = FALSE;
while ((len == 0 || kbhit()) && len < maxlen) {
switch (c = tgetch()) {
case 0:
*buf++ = K_NUL;
break;
case 3:
cbrk_pressed = TRUE;
/* FALLTHROUGH */
default:
*buf++ = c;
}
len++;
}
return len;
}
/*
* We have no job control, fake it by starting a new shell.
*/
void mch_suspend()
{
outstr("new shell started\n");
call_shell(NULL, 0, TRUE);
}
extern int _fmode;
char OrigTitle[256];
/*
*/
void mch_windinit()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
_fmode = O_BINARY; /* we do our own CR-LF translation */
flushbuf();
/* Obtain handles for the standard Console I/O devices */
hConIn = CreateFile("CONIN$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
hConOut = CreateFile("CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
GetConsoleTitle(OrigTitle, sizeof(OrigTitle));
/* get current attributes and fill out CHAR_INFO structure for fill char */
GetConsoleScreenBufferInfo(hConOut, &csbi);
DefaultAttribute = csbi.wAttributes;
mch_get_winsize();
}
void check_win(argc, argv)
int argc;
char **argv;
{
if (!isatty(0) || !isatty(1)) {
fprintf(stderr, "VIM: no controlling terminal\n");
exit(2);
}
/* In some cases with DOS 6.0 on a NEC notebook there is a 12 seconds
* delay when starting up that can be avoided by the next two lines.
* Don't ask me why! This could be fixed by removing setver.sys from
* config.sys. Forget it. gotoxy(1,1); cputs(" "); */
}
/*
* fname_case(): Set the case of the filename, if it already exists.
* msdos filesystem is far to primitive for that. do nothing.
*/
void fname_case(name)
char *name;
{
}
/*
* mch_settitle(): set titlebar of our window
* Can the icon also be set?
*/
void mch_settitle(title, icon)
char *title;
char *icon;
{
if (title != NULL)
SetConsoleTitle(title);
}
/*
* Restore the window/icon title.
* which is one of:
* 1 Just restore title
* 2 Just restore icon (which we don't have)
* 3 Restore title and icon (which we don't have)
*/
void
mch_restore_title(which)
int which;
{
mch_settitle((which & 1) ? OrigTitle : NULL, NULL);
}
/*
* Get name of current directory into buffer 'buf' of length 'len' bytes.
* Return non-zero for success.
*/
int vim_dirname(buf, len)
char *buf;
int len;
{
return (_getcwd(buf, len) != NULL);
}
/*
* get absolute filename into buffer 'buf' of length 'len' bytes
*/
int FullName(fname, buf, len)
char *fname,
*buf;
int len;
{
if (fname == NULL) /* always fail */
return FAIL;
if (_fullpath(buf, fname, len) == NULL) {
strncpy(buf, fname, len); /* failed, use the relative path name */
return FAIL;
}
return OK;
}
/*
* return TRUE is fname is an absolute path name
*/
int
isFullName(fname)
char_u *fname;
{
return (STRCHR(fname, ':') != NULL);
}
/*
* get file permissions for 'name'
* -1 : error
* else FA_attributes defined in dos.h
*/
long getperm(name)
char *name;
{
int r;
struct stat sb;
r = _stat(name, &sb); /* get file mode */
if (r)
return r;
else
return sb.st_mode;
}
/*
* set file permission for 'name' to 'perm'
*/
int setperm(name, perm)
char *name;
long perm;
{
return _chmod(name, (int) perm);
}
/*
* check if "name" is a directory
*/
int isdir(name)
char *name;
{
int f;
f = getperm(name);
if (f == -1)
return -1; /* file does not exist at all */
if ((f & _S_IFDIR) == 0)
return FAIL; /* not a directory */
return OK;
}
/*
* Careful: mch_windexit() may be called before mch_windinit()!
*/
void mch_windexit(r)
int r;
{
settmode(0);
stoptermcap();
flushbuf();
ml_close_all(); /* remove all memfiles */
mch_restore_title(3);
exit(r);
}
/*
* function for ctrl-break interrupt
*/
BOOL WINAPI handler_routine(DWORD dwCtrlType)
{
cbrk_pressed = TRUE;
ctrlc_pressed = TRUE;
}
/*
* set the tty in (raw) ? "raw" : "cooked" mode
*
*/
void mch_settmode(raw)
int raw;
{
long cmodein;
long cmodeout;
long mask;
GetConsoleMode(hConIn, &cmodein);
GetConsoleMode(hConOut, &cmodeout);
if (raw) {
if (term_console)
outstr(T_TP); /* set colors */
cmodein &= ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
ENABLE_ECHO_INPUT);
cmodein |= ENABLE_WINDOW_INPUT;
SetConsoleMode(hConIn, cmodein);
cmodeout &= ~(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
SetConsoleMode(hConOut, cmodeout);
SetConsoleCtrlHandler(handler_routine, TRUE);
} else {
if (term_console)
normvideo(); /* restore screen colors */
cmodein |= (ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
ENABLE_ECHO_INPUT);
cmodein &= ~(ENABLE_WINDOW_INPUT);
SetConsoleMode(hConIn, cmodein);
cmodeout |= (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
SetConsoleMode(hConOut, cmodeout);
SetConsoleCtrlHandler(handler_routine, FALSE);
}
}
int mch_get_winsize()
{
int i;
/*
* Use the console mode API
*/
if (GetConsoleScreenBufferInfo(hConOut, &csbi)) {
Rows = csbi.dwSize.Y;
Columns = csbi.dwSize.X;
DefaultAttribute = csbi.wAttributes;
} else {
Rows = 25;
Columns = 80;
}
if (Columns < 5 || Columns > MAX_COLUMNS ||
Rows < 2 || Rows > MAX_COLUMNS) {
/* these values are overwritten by termcap size or default */
Columns = 80;
Rows = 25;
return OK;
}
/* Rows_max = Rows; /* remember physical max height */
check_winsize();
/*script_winsize();*/
return OK;
}
/*********************************************************************
* FUNCTION: perr(PCHAR szFileName, int line, PCHAR szApiName, *
* DWORD dwError) *
* *
* PURPOSE: report API errors. Allocate a new console buffer, display *
* error number and error text, restore previous console *
* buffer *
* *
* INPUT: current source file name, current line number, name of the *
* API that failed, and the error number *
* *
* RETURNS: none *
*********************************************************************/
/* maximum size of the buffer to be returned from FormatMessage */
#define MAX_MSG_BUF_SIZE 512
void perr(PCHAR szFileName, int line, PCHAR szApiName, DWORD dwError)
{
CHAR szTemp[1024];
DWORD cMsgLen;
CHAR *msgBuf; /* buffer for message text from system */
int iButtonPressed; /* receives button pressed in the
* error box */
/* format our error message */
sprintf(szTemp, "%s: Error %d from %s on line %d:\n", szFileName,
dwError, szApiName, line);
/* get the text description for that error number from the system */
cMsgLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL, dwError,
MAKELANGID(0, SUBLANG_ENGLISH_US), (LPTSTR) & msgBuf, MAX_MSG_BUF_SIZE,
NULL);
if (!cMsgLen)
sprintf(szTemp + strlen(szTemp), "Unable to obtain error message text! \n"
"%s: Error %d from %s on line %d", __FILE__,
GetLastError(), "FormatMessage", __LINE__);
else
strcat(szTemp, msgBuf);
strcat(szTemp, "\n\nContinue execution?");
MessageBeep(MB_ICONEXCLAMATION);
iButtonPressed = MessageBox(NULL, szTemp, "Console API Error",
MB_ICONEXCLAMATION | MB_YESNO | MB_SETFOREGROUND);
/* free the message buffer returned to us by the system */
if (cMsgLen)
LocalFree((HLOCAL) msgBuf);
if (iButtonPressed == IDNO)
exit(1);
return;
}
#define PERR(bSuccess, api) {if (!(bSuccess)) perr(__FILE__, __LINE__, \
api, GetLastError());}
void resizeConBufAndWindow(HANDLE hConsole, SHORT xSize, SHORT ySize)
{
CONSOLE_SCREEN_BUFFER_INFO csbi; /* hold current console buffer info */
BOOL bSuccess;
SMALL_RECT srWindowRect; /* hold the new console size */
COORD coordScreen;
bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
PERR(bSuccess, "GetConsoleScreenBufferInfo");
/* get the largest size we can size the console window to */
coordScreen = GetLargestConsoleWindowSize(hConsole);
PERR(coordScreen.X | coordScreen.Y, "GetLargestConsoleWindowSize");
/* define the new console window size and scroll position */
srWindowRect.Right = (SHORT) (min(xSize, coordScreen.X) - 1);
srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1);
srWindowRect.Left = srWindowRect.Top = (SHORT) 0;
/* define the new console buffer size */
coordScreen.X = xSize;
coordScreen.Y = ySize;
/* if the current buffer is larger than what we want, resize the */
/* console window first, then the buffer */
if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize) {
bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect);
PERR(bSuccess, "SetConsoleWindowInfo");
bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen);
PERR(bSuccess, "SetConsoleScreenBufferSize");
}
/* if the current buffer is smaller than what we want, resize the */
/* buffer first, then the console window */
if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize) {
bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen);
PERR(bSuccess, "SetConsoleScreenBufferSize");
bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect);
PERR(bSuccess, "SetConsoleWindowInfo");
}
/* if the current buffer *is* the size we want, don't do anything! */
return;
}
void mch_set_winsize()
{
resizeConBufAndWindow(hConOut, Columns, Rows);
}
int call_shell(cmd, filter, cooked)
char *cmd;
int filter; /* if != 0: called by dofilter() */
int cooked;
{
int x;
char newcmd[200];
flushbuf();
if (cooked)
settmode(0); /* set to cooked mode */
if (cmd == NULL)
x = system(p_sh);
else { /* we use "command" to start the shell, slow
* but easy */
sprintf(newcmd, "%s /c %s", p_sh, cmd);
x = system(newcmd);
}
outchar('\n');
if (cooked)
settmode(1); /* set to raw mode */
#ifdef WEBB_COMPLETE
if (x && !expand_interactively)
#else
if (x)
#endif
{
smsg("%d returned", x);
outchar('\n');
}
resettitle();
return x;
}
#define FL_CHUNK 32
static void addfile(fl, f, isdir)
FileList *fl;
char *f;
int isdir;
{
char *p;
if (!fl->file) {
fl->file = (char **) alloc(sizeof(char *) * FL_CHUNK);
if (!fl->file)
return;
fl->nfiles = 0;
fl->maxfiles = FL_CHUNK;
}
if (fl->nfiles >= fl->maxfiles) {
char **t;
int i;
t = (char **) lalloc(sizeof(char *) * (fl->maxfiles + FL_CHUNK), TRUE);
if (!t)
return;
for (i = fl->nfiles - 1; i >= 0; i--)
t[i] = fl->file[i];
free(fl->file);
fl->file = t;
fl->maxfiles += FL_CHUNK;
}
p = alloc((unsigned) (strlen(f) + 1 + isdir));
if (p) {
strcpy(p, f);
if (isdir)
strcat(p, "/");
}
fl->file[fl->nfiles++] = p;
}
static int pstrcmp(a, b)
char **a,
**b;
{
return (strcmp(*a, *b));
}
int has_wildcard(s)
char *s;
{
if (s)
for (; *s; ++s)
if (*s == '?' || *s == '*')
return 1;
return 0;
}
static void strlowcpy(d, s)
char *d,
*s;
{
while (*s)
*d++ = tolower(*s++);
*d = '\0';
}
static int expandpath(fl, path, fonly, donly, notf)
FileList *fl;
char *path;
int fonly,
donly,
notf;
{
char buf[MAX_PATH];
char *p,
*s,
*e;
int lastn,
c = 1,
r;
WIN32_FIND_DATA fb;
HANDLE hFind;
lastn = fl->nfiles;
/*
* Find the first part in the path name that contains a wildcard.
* Copy it into buf, including the preceding characters.
*/
p = buf;
s = NULL;
e = NULL;
while (*path) {
if (*path == '\\' || *path == ':' || *path == '/') {
if (e)
break;
else
s = p;
}
if (*path == '*' || *path == '?')
e = p;
*p++ = *path++;
}
e = p;
if (s)
s++;
else
s = buf;
/* now we have one wildcard component between s and e */
*e = '\0';
r = 0;
/* If we are expanding wildcards we try both files and directories */
if ((hFind = FindFirstFile(buf, &fb)) == INVALID_HANDLE_VALUE) {
/* not found */
strcpy(e, path);
if (notf)
addfile(fl, buf, FALSE);
return 1; /* unexpanded or empty */
}
while (c) {
strlowcpy(s, fb.cFileName);
if (*s != '.' || (s[1] != '\0' && (s[1] != '.' || s[2] != '\0'))) {
strcat(buf, path);
if (!has_wildcard(path))
addfile(fl, buf, (isdir(buf) > 0));
else
r |= expandpath(fl, buf, fonly, donly, notf);
}
c = FindNextFile(hFind, &fb);
}
qsort(fl->file + lastn, fl->nfiles - lastn, sizeof(char *), pstrcmp);
FindClose(hFind);
return r;
}
/*
* MSDOS rebuilt of Scott Ballantynes ExpandWildCard for amiga/arp.
* jw
*/
int ExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
int num_pat;
char **pat;
int *num_file;
char ***file;
int files_only,
list_notfound;
{
int i,
r = 0;
FileList f;
f.file = NULL;
f.nfiles = 0;
for (i = 0; i < num_pat; i++) {
if (!has_wildcard(pat[i]))
addfile(&f, pat[i], files_only ? FALSE : (isdir(pat[i]) > 0));
else
r |= expandpath(&f, pat[i], files_only, 0, list_notfound);
}
if (r == 0) {
*num_file = f.nfiles;
*file = f.file;
} else {
*num_file = 0;
*file = NULL;
}
return (r ? FAIL : OK);
}
void FreeWild(num, file)
int num;
char **file;
{
if (file == NULL || num <= 0)
return;
while (num--)
free(file[num]);
free(file);
}
/*
* The normal chdir() does not change the default drive.
* This one does.
*/
#undef chdir
int vim_chdir(path)
char *path;
{
if (path[0] == NUL) /* just checking... */
return FAIL;
if (path[1] == ':') { /* has a drive name */
if (_chdrive(toupper(path[0]) - 'A' + 1))
return -1; /* invalid drive name */
path += 2;
}
if (*path == NUL) /* drive name only */
return OK;
return _chdir(path); /* let the normal chdir() do the rest */
}
clrscr()
{
int count;
ntcoord.X = 0;
ntcoord.Y = 0;
FillConsoleOutputCharacter(hConOut, ' ', Columns * Rows,
ntcoord, &count);
FillConsoleOutputAttribute(hConOut, DefaultAttribute, Rows * Columns,
ntcoord, &count);
}
clreol()
{
int count;
FillConsoleOutputCharacter(hConOut, ' ',
Columns - ntcoord.X,
ntcoord, &count);
FillConsoleOutputAttribute(hConOut, DefaultAttribute,
Columns - ntcoord.X,
ntcoord, &count);
}
insline(int count)
{
SMALL_RECT source,
clip;
COORD dest;
CHAR_INFO fill;
dest.X = 0;
dest.Y = ntcoord.Y + count;
source.Left = 0;
source.Top = ntcoord.Y;
source.Right = Columns;
source.Bottom = Rows - 1;
fill.Char.AsciiChar = ' ';
fill.Attributes = DefaultAttribute;
ScrollConsoleScreenBuffer(hConOut, &source, (PSMALL_RECT) 0, dest,
&fill);
}
delline(int count)
{
SMALL_RECT source,
clip;
COORD dest;
CHAR_INFO fill;
dest.X = 0;
dest.Y = ntcoord.Y;
source.Left = 0;
source.Top = ntcoord.Y + count;
source.Right = Columns;
source.Bottom = Rows - 1;
/* get current attributes and fill out CHAR_INFO structure for fill char */
fill.Char.AsciiChar = ' ';
fill.Attributes = DefaultAttribute;
ScrollConsoleScreenBuffer(hConOut, &source, (PSMALL_RECT) 0, dest,
&fill);
}
scroll()
{
SMALL_RECT source,
clip;
COORD dest;
CHAR_INFO fill;
dest.X = 0;
dest.Y = 0;
source.Left = 0;
source.Top = 1;
source.Right = Columns;
source.Bottom = Rows - 1;
/* get current attributes and fill out CHAR_INFO structure for fill char */
fill.Char.AsciiChar = ' ';
fill.Attributes = DefaultAttribute;
ScrollConsoleScreenBuffer(hConOut, &source, (PSMALL_RECT) 0, dest,
&fill);
}
gotoxy(x, y)
register int x,
y;
{
ntcoord.X = x - 1;
ntcoord.Y = y - 1;
SetConsoleCursorPosition(hConOut, ntcoord);
}
normvideo()
{
int count;
WORD attr = DefaultAttribute;
SetConsoleTextAttribute(hConOut, attr);
}
textattr(int attr)
{
int count;
WORD attrw = attr;
SetConsoleTextAttribute(hConOut, attr);
}
putch(char c)
{
int count;
WriteConsole(hConOut, &c, 1, &count, 0);
ntcoord.X += count;
}
delay(x)
{
Sleep(x);
}
sleep(x)
{
Sleep(x * 1000);
}
vbell()
{
COORD origin = {0, 0};
WORD flash = ~DefaultAttribute & 0xff;
WORD off = DefaultAttribute;
int count;
LPWORD oldattrs = alloc(Rows * Columns * sizeof(WORD));
ReadConsoleOutputAttribute(hConOut, oldattrs, Rows * Columns, origin,
&count);
FillConsoleOutputAttribute(hConOut, flash, Rows * Columns, origin,
&count);
WriteConsoleOutputAttribute(hConOut, oldattrs, Rows * Columns, origin,
&count);
free(oldattrs);
}
cursor_visible(int visible)
{
CONSOLE_CURSOR_INFO cci;
cci.bVisible = visible ? TRUE : FALSE;
cci.dwSize = 100; /* 100 percent cursor */
SetConsoleCursorInfo(hConOut, &cci);
}
void set_window(void)
{
}
/*
* check for an "interrupt signal": CTRL-break or CTRL-C
*/
void breakcheck()
{
if (ctrlc_pressed) {
ctrlc_pressed = FALSE;
got_int = TRUE;
}
}
long
mch_avail_mem(special)
int special;
{
return 0x7fffffff; /* virual memory eh */
}
/*
* return non-zero if a character is available
*/
int
mch_char_avail()
{
return WaitForChar(0);
}
/*
* set screen mode, always fails.
*/
int
mch_screenmode(arg)
char_u *arg;
{
EMSG("Screen mode setting not supported");
return FAIL;
}