[PATCH 8/9] [Kernel32]: modify editline logic so that it also work with bare consoles
Eric Pouech
eric.pouech at orange.fr
Mon Aug 30 15:19:31 CDT 2010
A+
---
dlls/kernel32/console.c | 5 ++-
dlls/kernel32/console_private.h | 2 +
dlls/kernel32/editline.c | 63 ++++++++++++++++++++++++++++++++++-----
3 files changed, 59 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index a0246fc..f6bbbe3 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -1528,11 +1528,12 @@ BOOL WINAPI ReadConsoleW(HANDLE hConsoleInput, LPVOID lpBuffer,
DWORD charsread;
LPWSTR xbuf = lpBuffer;
DWORD mode;
+ BOOL is_bare;
TRACE("(%p,%p,%d,%p,%p)\n",
hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved);
- if (!GetConsoleMode(hConsoleInput, &mode))
+ if (!get_console_mode(hConsoleInput, &mode, &is_bare))
return FALSE;
if (mode & ENABLE_LINE_INPUT)
@@ -1540,7 +1541,7 @@ BOOL WINAPI ReadConsoleW(HANDLE hConsoleInput, LPVOID lpBuffer,
if (!S_EditString || S_EditString[S_EditStrPos] == 0)
{
HeapFree(GetProcessHeap(), 0, S_EditString);
- if (!(S_EditString = CONSOLE_Readline(hConsoleInput)))
+ if (!(S_EditString = CONSOLE_Readline(hConsoleInput, !is_bare)))
return FALSE;
S_EditStrPos = 0;
}
diff --git a/dlls/kernel32/console_private.h b/dlls/kernel32/console_private.h
index f8d5958..06a8bd6 100644
--- a/dlls/kernel32/console_private.h
+++ b/dlls/kernel32/console_private.h
@@ -31,6 +31,6 @@ extern void CONSOLE_FillLineUniform(HANDLE hConsoleOutput, int i, int j, int
extern BOOL CONSOLE_GetEditionMode(HANDLE, int*);
/* editline.c */
-extern WCHAR* CONSOLE_Readline(HANDLE);
+extern WCHAR* CONSOLE_Readline(HANDLE, BOOL);
#endif /* __WINE_CONSOLE_PRIVATE_H */
diff --git a/dlls/kernel32/editline.c b/dlls/kernel32/editline.c
index ab70916..b79c5cb 100644
--- a/dlls/kernel32/editline.c
+++ b/dlls/kernel32/editline.c
@@ -53,6 +53,10 @@ typedef struct WCEL_Context {
WCHAR* line; /* the line being edited */
size_t alloc; /* number of WCHAR in line */
unsigned len; /* number of chars in line */
+ unsigned last_rub; /* number of chars to rub to get to start
+ (for consoles that can't change cursor pos) */
+ unsigned last_max; /* max number of chars written
+ (for consoles that can't change cursor pos) */
unsigned ofs; /* offset for cursor in current line */
WCHAR* yanked; /* yanked line */
unsigned mark; /* marked point (emacs mode only) */
@@ -61,7 +65,8 @@ typedef struct WCEL_Context {
HANDLE hConOut;
unsigned done : 1, /* to 1 when we're done with 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 */
+ can_pos_cursor : 1; /* to 1 when console can (re)position cursor */
unsigned histSize;
unsigned histPos;
WCHAR* histCurr;
@@ -123,10 +128,33 @@ static inline COORD WCEL_GetCoord(WCEL_Context* ctx, int ofs)
static inline void WCEL_Update(WCEL_Context* ctx, int beg, int len)
{
- WriteConsoleOutputCharacterW(ctx->hConOut, &ctx->line[beg], len,
- WCEL_GetCoord(ctx, beg), NULL);
- FillConsoleOutputAttribute(ctx->hConOut, ctx->csbi.wAttributes, len,
- WCEL_GetCoord(ctx, beg), NULL);
+ if (ctx->can_pos_cursor)
+ {
+ WriteConsoleOutputCharacterW(ctx->hConOut, &ctx->line[beg], len,
+ WCEL_GetCoord(ctx, beg), NULL);
+ FillConsoleOutputAttribute(ctx->hConOut, ctx->csbi.wAttributes, len,
+ WCEL_GetCoord(ctx, beg), NULL);
+ }
+ else
+ {
+ char ch;
+ unsigned i;
+ DWORD dw;
+
+ /* erase previous chars */
+ ch = '\b';
+ for (i = beg; i < ctx->last_rub; i++)
+ WriteFile(ctx->hConOut, &ch, 1, &dw, NULL);
+ beg = min(beg, ctx->last_rub);
+
+ /* write new chars */
+ WriteConsoleW(ctx->hConOut, &ctx->line[beg], ctx->len - beg, &dw, NULL);
+ /* clean rest of line (if any) */
+ ch = ' ';
+ for (i = ctx->len; i < ctx->last_max; i++)
+ WriteFile(ctx->hConOut, &ch, 1, &dw, NULL);
+ ctx->last_rub = max(ctx->last_max, ctx->len);
+ }
}
/* ====================================================================
@@ -765,7 +793,7 @@ static const KeyMap Win32KeyMap[] =
*
* ====================================================================*/
-WCHAR* CONSOLE_Readline(HANDLE hConsoleIn)
+WCHAR* CONSOLE_Readline(HANDLE hConsoleIn, BOOL can_pos_cursor)
{
WCEL_Context ctx;
INPUT_RECORD ir;
@@ -788,6 +816,7 @@ WCHAR* CONSOLE_Readline(HANDLE hConsoleIn)
!GetConsoleScreenBufferInfo(ctx.hConOut, &ctx.csbi))
return NULL;
ctx.can_wrap = (GetConsoleMode(ctx.hConOut, &ks) && (ks & ENABLE_WRAP_AT_EOL_OUTPUT)) ? 1 : 0;
+ ctx.can_pos_cursor = can_pos_cursor;
if (!WCEL_Grow(&ctx, 1))
{
@@ -842,8 +871,26 @@ WCHAR* CONSOLE_Readline(HANDLE hConsoleIn)
else TRACE("Dropped event\n");
/* EPP WCEL_Dump(&ctx, "after func"); */
- if (ctx.ofs != ofs)
- SetConsoleCursorPosition(ctx.hConOut, WCEL_GetCoord(&ctx, ctx.ofs));
+ if (ctx.can_pos_cursor)
+ {
+ if (ctx.ofs != ofs)
+ SetConsoleCursorPosition(ctx.hConOut, WCEL_GetCoord(&ctx, ctx.ofs));
+ }
+ else if (!ctx.done && !ctx.error)
+ {
+ char ch;
+ unsigned i;
+ DWORD dw;
+
+ /* erase previous chars */
+ ch = '\b';
+ for (i = 0; i < ctx.last_rub; i++)
+ WriteFile(ctx.hConOut, &ch, 1, &dw, NULL);
+
+ /* write chars up to cursor */
+ WriteConsoleW(ctx.hConOut, ctx.line, ctx.ofs, &dw, NULL);
+ if ((ctx.last_rub = ctx.ofs) > ctx.last_max) ctx.last_max = ctx.ofs;
+ }
}
if (ctx.error)
{
More information about the wine-patches
mailing list