kernel32: Proper support for echo-input (enable/disable) when getting console input.

This commit is contained in:
Eric Pouech 2010-12-12 22:31:40 +01:00 committed by Alexandre Julliard
parent 4149643fbe
commit 8b4c2ce9c5
1 changed files with 41 additions and 29 deletions

View File

@ -66,6 +66,7 @@ typedef struct WCEL_Context {
unsigned done : 1, /* to 1 when we're done with editing */ unsigned done : 1, /* to 1 when we're done with editing */
error : 1, /* to 1 when an error occurred in the editing */ error : 1, /* to 1 when an error occurred in the editing */
can_wrap : 1, /* to 1 when multi-line edition can take place */ can_wrap : 1, /* to 1 when multi-line edition can take place */
shall_echo : 1, /* to 1 when characters should be echo:ed when keyed-in */
can_pos_cursor : 1; /* to 1 when console can (re)position cursor */ can_pos_cursor : 1; /* to 1 when console can (re)position cursor */
unsigned histSize; unsigned histSize;
unsigned histPos; unsigned histPos;
@ -128,6 +129,7 @@ static inline COORD WCEL_GetCoord(WCEL_Context* ctx, int ofs)
static inline void WCEL_Update(WCEL_Context* ctx, int beg, int len) static inline void WCEL_Update(WCEL_Context* ctx, int beg, int len)
{ {
if (!ctx->shall_echo) return;
if (ctx->can_pos_cursor) if (ctx->can_pos_cursor)
{ {
WriteConsoleOutputCharacterW(ctx->hConOut, &ctx->line[beg], len, WriteConsoleOutputCharacterW(ctx->hConOut, &ctx->line[beg], len,
@ -194,34 +196,38 @@ static BOOL WCEL_Grow(WCEL_Context* ctx, size_t len)
static void WCEL_DeleteString(WCEL_Context* ctx, int beg, int end) static void WCEL_DeleteString(WCEL_Context* ctx, int beg, int end)
{ {
unsigned str_len = end - beg; unsigned str_len = end - beg;
COORD cbeg = WCEL_GetCoord(ctx, ctx->len - str_len);
COORD cend = WCEL_GetCoord(ctx, ctx->len);
CHAR_INFO ci;
if (end < ctx->len) if (end < ctx->len)
memmove(&ctx->line[beg], &ctx->line[end], (ctx->len - end) * sizeof(WCHAR)); memmove(&ctx->line[beg], &ctx->line[end], (ctx->len - end) * sizeof(WCHAR));
/* we need to clean from ctx->len - str_len to ctx->len */ /* we need to clean from ctx->len - str_len to ctx->len */
ci.Char.UnicodeChar = ' '; if (ctx->shall_echo)
ci.Attributes = ctx->csbi.wAttributes; {
COORD cbeg = WCEL_GetCoord(ctx, ctx->len - str_len);
COORD cend = WCEL_GetCoord(ctx, ctx->len);
CHAR_INFO ci;
if (cbeg.Y == cend.Y) ci.Char.UnicodeChar = ' ';
{ ci.Attributes = ctx->csbi.wAttributes;
/* partial erase of sole line */
CONSOLE_FillLineUniform(ctx->hConOut, cbeg.X, cbeg.Y, if (cbeg.Y == cend.Y)
cend.X - cbeg.X, &ci); {
} /* partial erase of sole line */
else CONSOLE_FillLineUniform(ctx->hConOut, cbeg.X, cbeg.Y,
{ cend.X - cbeg.X, &ci);
int i; }
/* erase til eol on first line */ else
CONSOLE_FillLineUniform(ctx->hConOut, cbeg.X, cbeg.Y, {
ctx->csbi.dwSize.X - cbeg.X, &ci); int i;
/* completely erase all the others (full lines) */ /* erase til eol on first line */
for (i = cbeg.Y + 1; i < cend.Y; i++) CONSOLE_FillLineUniform(ctx->hConOut, cbeg.X, cbeg.Y,
CONSOLE_FillLineUniform(ctx->hConOut, 0, i, ctx->csbi.dwSize.X, &ci); ctx->csbi.dwSize.X - cbeg.X, &ci);
/* erase from beginning of line until last pos on last line */ /* completely erase all the others (full lines) */
CONSOLE_FillLineUniform(ctx->hConOut, 0, cend.Y, cend.X, &ci); for (i = cbeg.Y + 1; i < cend.Y; i++)
CONSOLE_FillLineUniform(ctx->hConOut, 0, i, ctx->csbi.dwSize.X, &ci);
/* erase from beginning of line until last pos on last line */
CONSOLE_FillLineUniform(ctx->hConOut, 0, cend.Y, cend.X, &ci);
}
} }
ctx->len -= str_len; ctx->len -= str_len;
WCEL_Update(ctx, 0, ctx->len); WCEL_Update(ctx, 0, ctx->len);
@ -378,7 +384,8 @@ static void WCEL_FindPrevInHist(WCEL_Context* ctx)
ctx->ofs = 0; ctx->ofs = 0;
WCEL_InsertString(ctx, data); WCEL_InsertString(ctx, data);
ctx->ofs = oldofs; ctx->ofs = oldofs;
SetConsoleCursorPosition(ctx->hConOut, WCEL_GetCoord(ctx, ctx->ofs)); if (ctx->shall_echo)
SetConsoleCursorPosition(ctx->hConOut, WCEL_GetCoord(ctx, ctx->ofs));
HeapFree(GetProcessHeap(), 0, data); HeapFree(GetProcessHeap(), 0, data);
return; return;
} }
@ -630,15 +637,18 @@ static void WCEL_MoveToLastHist(WCEL_Context* ctx)
static void WCEL_Redraw(WCEL_Context* ctx) static void WCEL_Redraw(WCEL_Context* ctx)
{ {
COORD c = WCEL_GetCoord(ctx, ctx->len); if (ctx->shall_echo)
CHAR_INFO ci; {
COORD c = WCEL_GetCoord(ctx, ctx->len);
CHAR_INFO ci;
WCEL_Update(ctx, 0, ctx->len); WCEL_Update(ctx, 0, ctx->len);
ci.Char.UnicodeChar = ' '; ci.Char.UnicodeChar = ' ';
ci.Attributes = ctx->csbi.wAttributes; ci.Attributes = ctx->csbi.wAttributes;
CONSOLE_FillLineUniform(ctx->hConOut, c.X, c.Y, ctx->csbi.dwSize.X - c.X, &ci); CONSOLE_FillLineUniform(ctx->hConOut, c.X, c.Y, ctx->csbi.dwSize.X - c.X, &ci);
}
} }
static void WCEL_RepeatCount(WCEL_Context* ctx) static void WCEL_RepeatCount(WCEL_Context* ctx)
@ -812,6 +822,7 @@ WCHAR* CONSOLE_Readline(HANDLE hConsoleIn, BOOL can_pos_cursor)
OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE || OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE ||
!GetConsoleScreenBufferInfo(ctx.hConOut, &ctx.csbi)) !GetConsoleScreenBufferInfo(ctx.hConOut, &ctx.csbi))
return NULL; return NULL;
ctx.shall_echo = (GetConsoleMode(hConsoleIn, &ks) && (ks & ENABLE_ECHO_INPUT)) ? 1 : 0;
ctx.can_wrap = (GetConsoleMode(ctx.hConOut, &ks) && (ks & ENABLE_WRAP_AT_EOL_OUTPUT)) ? 1 : 0; ctx.can_wrap = (GetConsoleMode(ctx.hConOut, &ks) && (ks & ENABLE_WRAP_AT_EOL_OUTPUT)) ? 1 : 0;
ctx.can_pos_cursor = can_pos_cursor; ctx.can_pos_cursor = can_pos_cursor;
@ -868,6 +879,7 @@ WCHAR* CONSOLE_Readline(HANDLE hConsoleIn, BOOL can_pos_cursor)
else TRACE("Dropped event\n"); else TRACE("Dropped event\n");
/* EPP WCEL_Dump(&ctx, "after func"); */ /* EPP WCEL_Dump(&ctx, "after func"); */
if (!ctx.shall_echo) continue;
if (ctx.can_pos_cursor) if (ctx.can_pos_cursor)
{ {
if (ctx.ofs != ofs) if (ctx.ofs != ofs)