Exemplo n.º 1
0
static void WCEL_InsertString(WCEL_Context* ctx, const WCHAR* str)
{
    size_t	len = lstrlenW(str), updtlen;

    if (!len) return;
    if (ctx->insert)
    {
        if (!WCEL_Grow(ctx, len)) return;
        if (ctx->len > ctx->ofs)
            memmove(&ctx->line[ctx->ofs + len], &ctx->line[ctx->ofs], (ctx->len - ctx->ofs) * sizeof(WCHAR));
        ctx->len += len;
        updtlen = ctx->len - ctx->ofs;
    }
    else
    {
        if (ctx->ofs + len > ctx->len)
        {
            if (!WCEL_Grow(ctx, (ctx->ofs + len) - ctx->len)) return;
            ctx->len = ctx->ofs + len;
        }
        updtlen = len;
    }
    memcpy(&ctx->line[ctx->ofs], str, len * sizeof(WCHAR));
    ctx->line[ctx->len] = 0;
    WCEL_Update(ctx, ctx->ofs, updtlen);
    ctx->ofs += len;
}
Exemplo n.º 2
0
static void WCEL_Done(WCEL_Context* ctx)
{
    WCHAR       nl = '\n';
    if (!WCEL_Grow(ctx, 2)) return;
    ctx->line[ctx->len++] = '\r';
    ctx->line[ctx->len++] = '\n';
    ctx->line[ctx->len] = 0;
    WriteConsoleW(ctx->hConOut, &nl, 1, NULL, NULL);
    ctx->done = 1;
}
Exemplo n.º 3
0
static void WCEL_Done(WCEL_Context* ctx)
{
    WCHAR       nl = '\n';
    if (!WCEL_Grow(ctx, 2)) return;
    ctx->line[ctx->len++] = '\r';
    ctx->line[ctx->len++] = '\n';
    ctx->line[ctx->len] = 0;
    WriteConsoleW(ctx->hConOut, &nl, 1, NULL, NULL);
    if (ctx->insertkey)
        SetConsoleCursorInfo(ctx->hConOut, &ctx->cinfo);
    ctx->done = 1;
}
Exemplo n.º 4
0
static void    WCEL_FindPrevInHist(WCEL_Context* ctx)
{
    int startPos = ctx->histPos;
    WCHAR*	data;
    unsigned int    len, oldofs;

    if (ctx->histPos && ctx->histPos == ctx->histSize) {
        startPos--;
        ctx->histPos--;
    }

    do {
       data = WCEL_GetHistory(ctx, ctx->histPos);

       if (ctx->histPos) ctx->histPos--;
       else ctx->histPos = (ctx->histSize-1);

       len = lstrlenW(data) + 1;
       if ((len >= ctx->ofs) &&
           (memcmp(ctx->line, data, ctx->ofs * sizeof(WCHAR)) == 0)) {

           /* need to clean also the screen if new string is shorter than old one */
           WCEL_DeleteString(ctx, 0, ctx->len);

           if (WCEL_Grow(ctx, len))
           {
              oldofs = ctx->ofs;
              ctx->ofs = 0;
              WCEL_InsertString(ctx, data);
              ctx->ofs = oldofs;
              if (ctx->shall_echo)
                  SetConsoleCursorPosition(ctx->hConOut, WCEL_GetCoord(ctx, ctx->ofs));
              HeapFree(GetProcessHeap(), 0, data);
              return;
           }
       }
    } while (ctx->histPos != startPos);

    return;
}
Exemplo n.º 5
0
static void    WCEL_MoveToHist(WCEL_Context* ctx, int idx)
{
    WCHAR*	data = WCEL_GetHistory(ctx, idx);
    int		len = lstrlenW(data) + 1;

    /* save current line edition for recall when needed (FIXME seems broken to me) */
    if (ctx->histPos == ctx->histSize - 1)
    {
	HeapFree(GetProcessHeap(), 0, ctx->histCurr);
	ctx->histCurr = HeapAlloc(GetProcessHeap(), 0, (ctx->len + 1) * sizeof(WCHAR));
	memcpy(ctx->histCurr, ctx->line, (ctx->len + 1) * sizeof(WCHAR));
    }
    /* need to clean also the screen if new string is shorter than old one */
    WCEL_DeleteString(ctx, 0, ctx->len);
    ctx->ofs = 0;
    /* insert new string */
    if (WCEL_Grow(ctx, len))
    {
	WCEL_InsertString(ctx, data);
	HeapFree(GetProcessHeap(), 0, data);
	ctx->histPos = idx;
    }
}
Exemplo n.º 6
0
WCHAR* CONSOLE_Readline(HANDLE hConsoleIn)
{
    WCEL_Context	ctx;
    INPUT_RECORD	ir;
    const KeyMap*	km;
    const KeyEntry*	ke;
    unsigned		ofs;
    void		(*func)(struct WCEL_Context* ctx);
    DWORD               ks;
    int                 use_emacs;

    memset(&ctx, 0, sizeof(ctx));
    ctx.hConIn = hConsoleIn;
    WCEL_HistoryInit(&ctx);

    if (!CONSOLE_GetEditionMode(hConsoleIn, &use_emacs))
        use_emacs = 0;

    if ((ctx.hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL,
				    OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE ||
	!GetConsoleScreenBufferInfo(ctx.hConOut, &ctx.csbi))
	return NULL;
    ctx.can_wrap = (GetConsoleMode(ctx.hConOut, &ks) && (ks & ENABLE_WRAP_AT_EOL_OUTPUT)) ? 1 : 0;

    if (!WCEL_Grow(&ctx, 1))
    {
	CloseHandle(ctx.hConOut);
	return NULL;
    }
    ctx.line[0] = 0;

/* EPP     WCEL_Dump(&ctx, "init"); */

    while (!ctx.done && !ctx.error && WCEL_Get(&ctx, &ir))
    {
	if (ir.EventType != KEY_EVENT) continue;
	TRACE("key%s repeatCount=%u, keyCode=%02x scanCode=%02x char=%02x keyState=%08x\n",
	      ir.Event.KeyEvent.bKeyDown ? "Down" : "Up  ", ir.Event.KeyEvent.wRepeatCount,
	      ir.Event.KeyEvent.wVirtualKeyCode, ir.Event.KeyEvent.wVirtualScanCode,
	      ir.Event.KeyEvent.uChar.UnicodeChar, ir.Event.KeyEvent.dwControlKeyState);
	if (!ir.Event.KeyEvent.bKeyDown) continue;

/* EPP  	WCEL_Dump(&ctx, "before func"); */
	ofs = ctx.ofs;
        /* mask out some bits which don't interest us */
        ks = ir.Event.KeyEvent.dwControlKeyState & ~(NUMLOCK_ON|SCROLLLOCK_ON|CAPSLOCK_ON|ENHANCED_KEY);

	func = NULL;
	for (km = (use_emacs) ? EmacsKeyMap : Win32KeyMap; km->entries != NULL; km++)
	{
	    if (km->keyState != ks)
		continue;
	    if (km->chkChar)
	    {
		for (ke = &km->entries[0]; ke->func != 0; ke++)
		    if (ke->val == ir.Event.KeyEvent.uChar.UnicodeChar) break;
	    }
	    else
	    {
		for (ke = &km->entries[0]; ke->func != 0; ke++)
		    if (ke->val == ir.Event.KeyEvent.wVirtualKeyCode) break;

	    }
	    if (ke->func)
	    {
		func = ke->func;
		break;
	    }
	}

	if (func)
	    (func)(&ctx);
	else if (!(ir.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED))
	    WCEL_InsertChar(&ctx, ir.Event.KeyEvent.uChar.UnicodeChar);
	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.error)
    {
	HeapFree(GetProcessHeap(), 0, ctx.line);
	ctx.line = NULL;
    }
    WCEL_FreeYank(&ctx);
    if (ctx.line)
	CONSOLE_AppendHistory(ctx.line);

    CloseHandle(ctx.hConOut);
    HeapFree(GetProcessHeap(), 0, ctx.histCurr);
    return ctx.line;
}
Exemplo n.º 7
0
WCHAR* CONSOLE_Readline(HANDLE hConsoleIn, BOOL can_pos_cursor)
{
    WCEL_Context	ctx;
    INPUT_RECORD	ir;
    const KeyMap*	km;
    const KeyEntry*	ke;
    unsigned		ofs;
    void		(*func)(struct WCEL_Context* ctx);
    DWORD               mode, input_mode, ks;
    int                 use_emacs;

    memset(&ctx, 0, sizeof(ctx));
    ctx.hConIn = hConsoleIn;
    WCEL_HistoryInit(&ctx);

    if (!CONSOLE_GetEditionMode(hConsoleIn, &use_emacs))
        use_emacs = 0;

    if ((ctx.hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL,
				    OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE ||
	!GetConsoleScreenBufferInfo(ctx.hConOut, &ctx.csbi))
	return NULL;
    if (!GetConsoleMode(hConsoleIn, &mode)) mode = 0;
    input_mode = mode;
    ctx.shall_echo = (mode & ENABLE_ECHO_INPUT) ? 1 : 0;
    ctx.insert = (mode & (ENABLE_INSERT_MODE|ENABLE_EXTENDED_FLAGS)) == (ENABLE_INSERT_MODE|ENABLE_EXTENDED_FLAGS) ? 1 : 0;
    if (!GetConsoleMode(ctx.hConOut, &mode)) mode = 0;
    ctx.can_wrap = (mode & ENABLE_WRAP_AT_EOL_OUTPUT) ? 1 : 0;
    ctx.can_pos_cursor = can_pos_cursor;
    GetConsoleCursorInfo(ctx.hConOut, &ctx.cinfo);

    if (!WCEL_Grow(&ctx, 1))
    {
	CloseHandle(ctx.hConOut);
	return NULL;
    }
    ctx.line[0] = 0;

/* EPP     WCEL_Dump(&ctx, "init"); */

    while (!ctx.done && !ctx.error && WCEL_Get(&ctx, &ir))
    {
	if (ir.EventType != KEY_EVENT) continue;
	TRACE("key%s repeatCount=%u, keyCode=%02x scanCode=%02x char=%02x keyState=%08x\n",
	      ir.Event.KeyEvent.bKeyDown ? "Down" : "Up  ", ir.Event.KeyEvent.wRepeatCount,
	      ir.Event.KeyEvent.wVirtualKeyCode, ir.Event.KeyEvent.wVirtualScanCode,
	      ir.Event.KeyEvent.uChar.UnicodeChar, ir.Event.KeyEvent.dwControlKeyState);
	if (!ir.Event.KeyEvent.bKeyDown) continue;

/* EPP  	WCEL_Dump(&ctx, "before func"); */
	ofs = ctx.ofs;
        /* mask out some bits which don't interest us */
        ks = ir.Event.KeyEvent.dwControlKeyState & ~(NUMLOCK_ON|SCROLLLOCK_ON|CAPSLOCK_ON|ENHANCED_KEY);

	func = NULL;
	for (km = (use_emacs) ? EmacsKeyMap : Win32KeyMap; km->entries != NULL; km++)
	{
	    if (km->keyState != ks)
		continue;
	    if (km->chkChar)
	    {
		for (ke = &km->entries[0]; ke->func != 0; ke++)
		    if (ke->val == ir.Event.KeyEvent.uChar.UnicodeChar) break;
	    }
	    else
	    {
		for (ke = &km->entries[0]; ke->func != 0; ke++)
		    if (ke->val == ir.Event.KeyEvent.wVirtualKeyCode) break;

	    }
	    if (ke->func)
	    {
		func = ke->func;
		break;
	    }
	}

        GetConsoleMode(hConsoleIn, &mode);
        if (input_mode != mode)
        {
            input_mode = mode;
            ctx.insertkey = 0;
        }
        ctx.insert = (mode & (ENABLE_INSERT_MODE|ENABLE_EXTENDED_FLAGS)) ==
                     (ENABLE_INSERT_MODE|ENABLE_EXTENDED_FLAGS);
        if (ctx.insertkey)
            ctx.insert = !ctx.insert;

	if (func)
	    (func)(&ctx);
	else if (!(ir.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED))
	    WCEL_InsertChar(&ctx, ir.Event.KeyEvent.uChar.UnicodeChar);
	else TRACE("Dropped event\n");

/* EPP         WCEL_Dump(&ctx, "after func"); */
        if (!ctx.shall_echo) continue;
        if (ctx.can_pos_cursor)
        {
            if (ctx.ofs != ofs)
                SetConsoleCursorPosition(ctx.hConOut, WCEL_GetCoord(&ctx, ctx.ofs));
        }
        else if (!ctx.done && !ctx.error)
        {
            DWORD last;
            /* erase previous chars */
            WCEL_WriteNChars(&ctx, '\b', ctx.last_rub);

            /* write chars up to cursor */
            ctx.last_rub = WCEL_WriteConsole(&ctx, 0, ctx.ofs);
            /* write chars past cursor */
            last = ctx.last_rub + WCEL_WriteConsole(&ctx, ctx.ofs, ctx.len - ctx.ofs);
            if (last < ctx.last_max) /* ctx.line has been shortened, erase */
            {
                WCEL_WriteNChars(&ctx, ' ', ctx.last_max - last);
                WCEL_WriteNChars(&ctx, '\b', ctx.last_max - last);
                ctx.last_max = last;
            }
            else ctx.last_max = last;
            /* reposition at cursor */
            WCEL_WriteNChars(&ctx, '\b', last - ctx.last_rub);
        }
    }
    if (ctx.error)
    {
	HeapFree(GetProcessHeap(), 0, ctx.line);
	ctx.line = NULL;
    }
    WCEL_FreeYank(&ctx);
    if (ctx.line)
	CONSOLE_AppendHistory(ctx.line);

    CloseHandle(ctx.hConOut);
    HeapFree(GetProcessHeap(), 0, ctx.histCurr);
    return ctx.line;
}