Example #1
0
static inline BOOL
w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize,
			DWORD *waiting)
{
  return (w32_console_unicode_input
	  ? ReadConsoleInputW (h, rec, recsize, waiting)
	  : ReadConsoleInputA (h, rec, recsize, waiting));
}
Example #2
0
char Consola::getch(void) {
	INPUT_RECORD irInputRecord;
	DWORD dwEventsRead;
	CHAR cChar;

	while(ReadConsoleInputA(hStdin, &irInputRecord, 1, &dwEventsRead)) /* Read key press */
		if (irInputRecord.EventType == KEY_EVENT
			&& irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_SHIFT
			&& irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_MENU
			&& irInputRecord.Event.KeyEvent.wVirtualKeyCode != VK_CONTROL)
		{

		cChar = irInputRecord.Event.KeyEvent.uChar.AsciiChar;
		ReadConsoleInputA (hStdin, &irInputRecord , 1, &dwEventsRead); /* Read key release */

		if (irInputRecord.Event.KeyEvent.wVirtualKeyCode == VK_LEFT) return ESQUERDA;
		if (irInputRecord.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT) return DIREITA;
		if (irInputRecord.Event.KeyEvent.wVirtualKeyCode == VK_UP) return CIMA;
		if (irInputRecord.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) return BAIXO;

		return cChar;
    }
  return EOF;
}
Example #3
0
static void DOSVM_ProcessConsole(void)
{
  INPUT_RECORD msg;
  DWORD res;
  BYTE scan, ascii;

  if (ReadConsoleInputA(GetStdHandle(STD_INPUT_HANDLE),&msg,1,&res)) {
    switch (msg.EventType) {
    case KEY_EVENT:
      scan = msg.Event.KeyEvent.wVirtualScanCode;
      ascii = msg.Event.KeyEvent.uChar.AsciiChar;
      TRACE("scan %02x, ascii %02x\n", scan, ascii);

      /* set the "break" (release) flag if key released */
      if (!msg.Event.KeyEvent.bKeyDown) scan |= 0x80;

      /* check whether extended bit is set,
       * and if so, queue the extension prefix */
      if (msg.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY) {
        DOSVM_Int09SendScan(0xE0,0);
      }
      DOSVM_Int09SendScan(scan, ascii);
      break;
    case MOUSE_EVENT:
      DOSVM_Int33Console(&msg.Event.MouseEvent);
      break;
    case WINDOW_BUFFER_SIZE_EVENT:
      FIXME("unhandled WINDOW_BUFFER_SIZE_EVENT.\n");
      break;
    case MENU_EVENT:
      FIXME("unhandled MENU_EVENT.\n");
      break;
    case FOCUS_EVENT:
      FIXME("unhandled FOCUS_EVENT.\n");
      break;
    default:
      FIXME("unknown console event: %d\n", msg.EventType);
    }
  }
}
Example #4
0
void Console::readInput() // Check for input and stuff.
{
    DWORD num_events, num_events_read;
    GetNumberOfConsoleInputEvents(in, &num_events);
    if (num_events) {
        INPUT_RECORD *events = new INPUT_RECORD[num_events];
        ReadConsoleInputA(in, events, num_events, &num_events_read);

        for (DWORD i = 0; i < num_events_read; ++i) {
            INPUT_RECORD &i_event = events[i];
            switch (i_event.EventType) {
            case KEY_EVENT:
                keys[i_event.Event.KeyEvent.wVirtualKeyCode] = i_event.Event.KeyEvent.bKeyDown;
                break;
            default:
                continue;
                break;
            }

        }
        delete[] events;
    }
}
Example #5
0
/* Note that this should parse some special keys into their emacs ctrl-key combos
 * Return of -1 signifies unrecognized code
 */
static char linenoiseReadChar(int fd){
#ifdef _WIN32
    INPUT_RECORD rec;
    DWORD count;
    do {
        ReadConsoleInputA(console_in, &rec, 1, &count);
    } while (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown);

    if (rec.Event.KeyEvent.uChar.AsciiChar == 0) {
        /* handle keys that aren't converted to ASCII */
        switch (rec.Event.KeyEvent.wVirtualKeyCode) {
            case VK_LEFT: return 2; /* ctrl-b */
            case VK_RIGHT: return 6; /* ctrl-f */
            case VK_UP: return 16; /* ctrl-p */
            case VK_DOWN: return 14; /* ctrl-n */
            case VK_DELETE: return 127; /* ascii DEL byte */
            case VK_HOME: return 1; /* ctrl-a */
            case VK_END: return 5; /* ctrl-e */
            default: return -1;
        }
    }
    return rec.Event.KeyEvent.uChar.AsciiChar;
#else
    char c;
    int nread;
    char seq[2], seq2[2];

    nread = read(fd,&c,1);
    if (nread <= 0) return 0;

#if defined(_DEBUG)
    if (c == 28) { /* ctrl-\ */
        /* special debug mode. prints all keys hit. ctrl-c to get out */
        printf("\x1b[1G\n"); /* go to first column of new line */
        while (true) {
            char keys[10];
            int ret = read(fd, keys, 10);
            int i;

            if (ret <= 0) {
                printf("\nret: %d\n", ret);
            }

            for (i=0; i < ret; i++)
                printf("%d ", (int)keys[i]);
            printf("\x1b[1G\n"); /* go to first column of new line */

            if (keys[0] == 3) /* ctrl-c. may cause signal instead */
                return -1;
        }
    }
#endif

    if (c == 27) { /* escape */
        if (read(fd,seq,2) == -1) return 0;
        if (seq[0] == 91){
            if (seq[1] == 68) { /* left arrow */
                return 2; /* ctrl-b */
            } else if (seq[1] == 67) { /* right arrow */
                return 6; /* ctrl-f */
            } else if (seq[1] == 65) { /* up arrow */
                return 16; /* ctrl-p */
            } else if (seq[1] == 66) { /* down arrow */
                return 14; /* ctrl-n */
            } else if (seq[1] > 48 && seq[1] < 57) {
                /* extended escape */
                if (read(fd,seq2,2) == -1) return 0;
                if (seq2[0] == 126) {
                    if (seq[1] == 49 || seq[1] == 55) { /* home (linux console and rxvt based) */
                        return 1; /* ctrl-a */
                    } else if (seq[1] == 52 || seq[1] == 56 ) { /* end (linux console and rxvt based) */
                        return 5; /* ctrl-e */
                    } else if (seq[1] == 51) { /* delete */
                        return 127; /* ascii DEL byte */
                    } else {
                        return -1;
                    }
                } else {
                    return -1;
                }
                if (seq[1] == 51 && seq2[0] == 126) { /* delete */
                    return 127; /* ascii DEL byte */
                } else {
                    return -1;
                }
            } else {
                return -1;
            }
        } else if (seq[0] == 79){
            if (seq[1] == 72) { /* home (xterm based) */
                return 1; /* ctrl-a */
            } else if (seq[1] == 70) { /* end (xterm based) */
                return 5; /* ctrl-e */
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    } else if (c == 127) {
        /* some consoles use 127 for backspace rather than delete.
         * we only use it for delete */
        return 8;
    }

    return c; /* normalish character */
#endif
}
Example #6
0
int ProcessInput(LPCTSTR asName)
{
	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	TCHAR szName[MAX_PATH] = _T("\\\\.\\pipe\\");
	_tcscat(szName, asName);
	DWORD nRead, nWrite;
	INPUT_RECORD r;
	BOOL b;

	char sInfo[300] = "";
	wsprintfA(sInfo, "Client started, PID=%u\nConnecting to server '", GetCurrentProcessId());
#ifdef _UNICODE
	WideCharToMultiByte(CP_OEMCP, 0, asName, -1, sInfo+lstrlenA(sInfo), 200, 0, 0);
#else
	lstrcat(sInfo, asName);
#endif
	lstrcatA(sInfo, "'");
	PrintOut(sInfo);

	DWORD nStart = GetTickCount();
	while ((GetTickCount() - nStart) < 30000)
	{
		if (WaitNamedPipe(szName, 500))
			break;
		printf(".");
		Sleep(2000);
	}

	HANDLE hPipe = CreateFile(szName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (!hPipe || hPipe == INVALID_HANDLE_VALUE)
	{
		nRead = GetLastError();
		printf("\n!!! OpenPipe failed, code=%u !!!\n", nRead);
		return nRead;
	}
	printf("\nConnected! Alt+X - exit, Alt+L - clear, Alt+F - fill\n");

	SetConsoleCtrlHandler((PHANDLER_ROUTINE)HandlerRoutine, true);

	while (!gbExit)
	{
		if (ReadConsoleInputA(hIn, &r, 1, &nRead) && nRead)
		{
			if (r.EventType == KEY_EVENT && r.Event.KeyEvent.bKeyDown)
			{
				switch (r.Event.KeyEvent.wVirtualKeyCode)
				{
				case VK_UP:
					SendAnsi(hPipe, hOut, "\x1B[A"); continue;
				case VK_DOWN:
					SendAnsi(hPipe, hOut, "\x1B[B"); continue;
				case VK_RIGHT:
					SendAnsi(hPipe, hOut, "\x1B[C"); continue;
				case VK_LEFT:
					SendAnsi(hPipe, hOut, "\x1B[D"); continue;
				case VK_HOME:
					if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[1;1H");
					else
						SendAnsi(hPipe, hOut, "\x1B[1G");
					continue;
				case VK_END:
					if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[9999;1H");
					else
					{
						CONSOLE_SCREEN_BUFFER_INFO csbi;
						if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
						{
							char chEsc[32]; wsprintfA(chEsc, "\x1B[%uG", csbi.dwSize.X);
							SendAnsi(hPipe, hOut, chEsc);
						}
					}
					continue;
				case VK_PRIOR: // PgUp
					if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[9999S");
					else
						SendAnsi(hPipe, hOut, "\x1B[S");
					continue;
				case VK_NEXT: // PgDn
					if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[9999T");
					else
						SendAnsi(hPipe, hOut, "\x1B[T");
					continue;
				case VK_DELETE:
					if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[M");
					else if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[P");
					else if (r.Event.KeyEvent.dwControlKeyState & (SHIFT_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[X");
					else
						PrintOut("\nCtrl+Del - delete line, Alt+Del - delete char, Shift+Del - clear char\n");
					continue;
				case VK_INSERT:
					if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[L");
					else if (r.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED))
						SendAnsi(hPipe, hOut, "\x1B[@");
					else
						PrintOut("\nCtrl+Ins - insert line, Alt+Ins - insert char\n");
					continue;
				}
				if (r.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
				{
					switch (r.Event.KeyEvent.wVirtualKeyCode)
					{
					case '1':
						SendFile(hPipe, hOut, _T("AnsiColors16.ans")); continue;
					case '2':
						SendFile(hPipe, hOut, _T("AnsiColors16t.ans")); continue;
					case '3':
						SendFile(hPipe, hOut, _T("AnsiColors256.ans")); continue;
					}
				}
				if (r.Event.KeyEvent.uChar.AsciiChar)
				{
					if (r.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
					{
						char szText[100];
						switch (r.Event.KeyEvent.uChar.AsciiChar)
						{
						case 'x': case 'X':
							printf("\nExit session\n");
							gbExit = true;
							break;
						case 'l': case 'L':
							SendAnsi(hPipe, hOut, "\x1B[2J"); SendAnsi(hPipe, hOut, "\x1B[1;1H");
							break;
						case 'f': case 'F':
							SendAnsi(NULL, hOut, "\r\nFilling server console width text...\r\n");
							SendAnsi(hPipe, NULL, "\x02");
							break;
						case '1':
							SendAnsi(NULL, hOut, "{Alt+1}");
							SendAnsi(hPipe, NULL, "\r\nRequest terminal primary DA: ");
							SendAnsi(hPipe, hOut, "\x1B[c");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						case '2':
							SendAnsi(NULL, hOut, "{Alt+2}");
							SendAnsi(hPipe, NULL, "\r\nRequest terminal secondary DA: ");
							SendAnsi(hPipe, hOut, "\x1B[>c");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						case '3':
							SendAnsi(NULL, hOut, "{Alt+3}");
							SendAnsi(hPipe, NULL, "\r\nRequest terminal status: ");
							SendAnsi(hPipe, hOut, "\x1B[5n");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						case '4':
							SendAnsi(NULL, hOut, "{Alt+4}");
							SendAnsi(hPipe, NULL, "\r\nRequest cursor pos [row;col]: ");
							SendAnsi(hPipe, hOut, "\x1B[6n");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						case '5':
							SendAnsi(NULL, hOut, "{Alt+5}");
							SendAnsi(hPipe, NULL, "\r\nRequest text area size [height;width]: ");
							SendAnsi(hPipe, hOut, "\x1B[18t");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						case '6':
							SendAnsi(NULL, hOut, "{Alt+6}");
							SendAnsi(hPipe, NULL, "\r\nRequest screen area size [height;width]: ");
							SendAnsi(hPipe, hOut, "\x1B[19t");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						case '7':
							SendAnsi(NULL, hOut, "{Alt+7}");
							SendAnsi(hPipe, NULL, "\r\nRequest terminal title: ");
							SendAnsi(hPipe, hOut, "\x1B[21t");
							SendAnsi(hPipe, NULL, "\x01");
							break;
						}
						continue;
					}
						

					if (r.Event.KeyEvent.uChar.AsciiChar == 27)
						WriteConsoleW(hOut, gszAnalogues+27, 1, &nWrite, NULL);
					else
						WriteConsoleA(hOut, &r.Event.KeyEvent.uChar.AsciiChar, 1, &nWrite, NULL);


					b = WriteFile(hPipe, &r.Event.KeyEvent.uChar.AsciiChar, 1, &nWrite, NULL);
					if (b && r.Event.KeyEvent.uChar.AsciiChar == '\r')
					{
						WriteConsoleA(hOut, "\n", 1, &nWrite, NULL);
						b = WriteFile(hPipe, "\n", 1, &nWrite, NULL);
					}

					if (!b)
					{
						nRead = GetLastError();
						printf("\n!!! WritePipe failed, code=%u !!!\n", nRead);
						return nRead;
					}
				}
			}
		}
	}

	return 0;
}
Example #7
0
int getkbm(void)
{
	HANDLE con;
	DWORD nevents = 0;
	INPUT_RECORD buf;
	init_ti();
	if (nkeybuf)
	{
		return keybuf[--nkeybuf];
	}
	if (keystate) keystate = 0;
	con = GetStdHandle(STD_INPUT_HANDLE);
	while (1)
	{
		ReadConsoleInputA(con, &buf, 1, &nevents);
		if (buf.EventType == KEY_EVENT && buf.Event.KeyEvent.bKeyDown)
		{
			_controlkeystate = buf.Event.KeyEvent.dwControlKeyState;
			if (buf.Event.KeyEvent.uChar.AsciiChar == 0)
				return KEY_SPECIAL + buf.Event.KeyEvent.wVirtualScanCode;
			return buf.Event.KeyEvent.uChar.AsciiChar & 0xFF;
		}
		else if (buf.EventType == WINDOW_BUFFER_SIZE_EVENT)
		{
			ti.screenwidth = buf.Event.WindowBufferSizeEvent.dwSize.X;
			ti.screenheight = buf.Event.WindowBufferSizeEvent.dwSize.Y;
			if (ti.winright>ti.screenwidth) ti.winright = ti.screenwidth;
			if (ti.winbottom>ti.screenheight) ti.winbottom = ti.screenheight;
			if (ti.winleft>ti.winright) ti.winleft = ti.winright;
			if (ti.wintop>ti.winbottom) ti.wintop = ti.winbottom;
			if (!in_window(ti.winleft + ti.curx - 1, ti.wintop + ti.cury - 1))
				gotoxy(1, 1);
			return WINDOW_RESIZE;
		}
		else if (buf.EventType == MOUSE_EVENT)
		{
			switch (buf.Event.MouseEvent.dwEventFlags)
			{
			case 0:
				if (buf.Event.MouseEvent.dwButtonState != 0)
				{
					_mousebuttons = buf.Event.MouseEvent.dwButtonState;
					_mousex = buf.Event.MouseEvent.dwMousePosition.X + 1;
					_mousey = buf.Event.MouseEvent.dwMousePosition.Y + 1;
					return MOUSE_CLICK;
				}
				break;
			case DOUBLE_CLICK:
				_mousebuttons = buf.Event.MouseEvent.dwButtonState;
				_mousex = buf.Event.MouseEvent.dwMousePosition.X + 1;
				_mousey = buf.Event.MouseEvent.dwMousePosition.Y + 1;
				return MOUSE_DBLCLICK;
			case MOUSE_WHEELED:
				_mousex = buf.Event.MouseEvent.dwMousePosition.X + 1;
				_mousey = buf.Event.MouseEvent.dwMousePosition.Y + 1;
				if ((int)buf.Event.MouseEvent.dwButtonState>0)
					return MOUSE_WHEELUP;
				return MOUSE_WHEELDOWN;
			default:
				break;
			}
		}
	}
}
Example #8
0
static size_t console_read(struct file *f, char *buf, size_t count)
{
	struct console_file *console_file = (struct console_file *)f;

	console_lock();
	console_retrieve_state();

	size_t bytes_read = 0;
	while (console->input_buffer_head != console->input_buffer_tail && count > 0)
	{
		count--;
		buf[bytes_read++] = console->input_buffer[console->input_buffer_tail];
		console->input_buffer_tail = (console->input_buffer_tail + 1) % MAX_INPUT;
	}
	if (console->termios.c_lflag & ICANON)
	{
		char line[MAX_CANON + 1]; /* One more for storing CR or LF */
		size_t len = 0;
		while (count > 0)
		{
			INPUT_RECORD ir;
			DWORD read;
			ReadConsoleInputA(console->in, &ir, 1, &read);
			if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown)
			{
				switch (ir.Event.KeyEvent.wVirtualKeyCode)
				{
				case VK_RETURN:
				{
					if (!(console->termios.c_iflag & IGNCR))
						line[len++] = console->termios.c_iflag & ICRNL ? '\n' : '\r';
					size_t r = min(count, len);
					memcpy(buf + bytes_read, line, r);
					bytes_read += r;
					count -= r;
					if (r < len)
					{
						/* Some bytes not fit, add to input buffer */
						console_add_input(line + r, len - r);
					}
					if (console->termios.c_lflag & ECHO)
						crnl();
					goto read_done;
				}

				case VK_BACK:
				{
					if (len > 0)
					{
						len--;
						if (console->termios.c_lflag & ECHO)
							backspace(TRUE);
					}
				}
				default:
				{
					char ch = ir.Event.KeyEvent.uChar.AsciiChar;
					if (ch >= 0x20)
					{
						if (len < MAX_CANON)
						{
							line[len++] = ch;
							if (console->termios.c_lflag & ECHO)
								write_normal(&ch, 1);
						}
					}
				}
				}
			}
		}
	}
	else /* Non canonical mode */
	{
		int vtime = console->termios.c_cc[VTIME];
		int vmin = console->termios.c_cc[VMIN];
		while (count > 0)
		{
			if (bytes_read > 0 && bytes_read >= vmin)
				break;
			/* If vmin > 0 and vtime == 0, it is a blocking read, otherwise we need to poll first */
			if (vtime > 0 || (vmin == 0 && vtime == 0))
			{
				if (WaitForSingleObject(console->in, vtime * 100) == WAIT_TIMEOUT)
					break;
			}
			INPUT_RECORD ir;
			DWORD read;
			ReadConsoleInputA(console->in, &ir, 1, &read);
			if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown)
			{
				switch (ir.Event.KeyEvent.wVirtualKeyCode)
				{
				case VK_UP:
					console_buffer_add_string(buf, &bytes_read, &count, console->cursor_key_mode ? "\x1BOA" : "\x1B[A", 3);
					break;

				case VK_DOWN:
					console_buffer_add_string(buf, &bytes_read, &count, console->cursor_key_mode ? "\x1BOB" : "\x1B[B", 3);
					break;

				case VK_RIGHT:
					console_buffer_add_string(buf, &bytes_read, &count, console->cursor_key_mode ? "\x1BOC" : "\x1B[C", 3);
					break;

				case VK_LEFT:
					console_buffer_add_string(buf, &bytes_read, &count, console->cursor_key_mode ? "\x1BOD" : "\x1B[D", 3);
					break;

				case VK_HOME:
					console_buffer_add_string(buf, &bytes_read, &count, console->cursor_key_mode ? "\x1BOH" : "\x1B[H", 3);
					break;

				case VK_END:
					console_buffer_add_string(buf, &bytes_read, &count, console->cursor_key_mode ? "\x1BOF" : "\x1B[F", 3);
					break;

				case VK_INSERT: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[2~", 4); break;
				case VK_DELETE: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[3~", 4); break;
				case VK_PRIOR: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[5~", 4); break;
				case VK_NEXT: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[6~", 4); break;

				case VK_F1: console_buffer_add_string(buf, &bytes_read, &count, "\x1BOP", 3); break;
				case VK_F2: console_buffer_add_string(buf, &bytes_read, &count, "\x1BOQ", 3); break;
				case VK_F3: console_buffer_add_string(buf, &bytes_read, &count, "\x1BOR", 3); break;
				case VK_F4: console_buffer_add_string(buf, &bytes_read, &count, "\x1BOS", 3); break;
				case VK_F5: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[15~", 5); break;
				case VK_F6: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[17~", 5); break;
				case VK_F7: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[18~", 5); break;
				case VK_F8: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[19~", 5); break;
				case VK_F9: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[20~", 5); break;
				case VK_F10: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[21~", 5); break;
				case VK_F11: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[23~", 5); break;
				case VK_F12: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[24~", 5); break;
				case VK_F13: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[25~", 5); break;
				case VK_F14: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[26~", 5); break;
				case VK_F15: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[28~", 5); break;
				case VK_F16: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[29~", 5); break;
				case VK_F17: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[31~", 5); break;
				case VK_F18: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[32~", 5); break;
				case VK_F19: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[33~", 5); break;
				case VK_F20: console_buffer_add_string(buf, &bytes_read, &count, "\x1B[34~", 5); break;

				default:
				{
					char ch = ir.Event.KeyEvent.uChar.AsciiChar;
					if (ch == '\r' && console->termios.c_iflag & IGNCR)
						break;
					if (ch == '\r' && console->termios.c_iflag & ICRNL)
						ch = '\n';
					else if (ch == '\n' && console->termios.c_iflag & ICRNL)
						ch = '\r';
					if (ch > 0)
					{
						count--;
						buf[bytes_read++] = ch;
						if (console->termios.c_lflag & ECHO)
							write_normal(&ch, 1);
					}
				}
				}
			}
			else
			{
				/* TODO: Other types of input */
			}
		}
	}
read_done:
	/* This will make the caret immediately visible */
	set_pos(console->x, console->y);
	console_unlock();
	return bytes_read;
}
Example #9
0
/*********************************************************************
 *		_getch ([email protected])
 */
int CDECL _getch(void)
{
  int retval = MSVCRT_EOF;

  LOCK_CONSOLE;
  if (__MSVCRT_console_buffer != MSVCRT_EOF)
  {
    retval = __MSVCRT_console_buffer;
    __MSVCRT_console_buffer = MSVCRT_EOF;
  }
  else
  {
    INPUT_RECORD ir;
    DWORD count;
    DWORD mode = 0;

    GetConsoleMode(MSVCRT_console_in, &mode);
    if(mode)
      SetConsoleMode(MSVCRT_console_in, 0);

    do {
      if (ReadConsoleInputA(MSVCRT_console_in, &ir, 1, &count))
      {
          unsigned int i;
        /* Only interested in ASCII chars */
        if (ir.EventType == KEY_EVENT &&
            ir.Event.KeyEvent.bKeyDown)
        {
            if (ir.Event.KeyEvent.uChar.AsciiChar)
            {
                retval = ir.Event.KeyEvent.uChar.AsciiChar;
                break;
            }
            for (i = 0; i < sizeof(enh_map) / sizeof(enh_map[0]); i++)
            {
                if (ir.Event.KeyEvent.wVirtualScanCode == enh_map[i].vk) break;
            }
            if (i < sizeof(enh_map) / sizeof(enh_map[0]))
            {
                unsigned idx;

                if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
                    idx = ALT_CHAR;
                else if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) )
                    idx = CTRL_CHAR;
                else if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
                    idx = SHIFT_CHAR;
                else
                    idx = NORMAL_CHAR;

                retval = enh_map[i].ch[idx][0];
                __MSVCRT_console_buffer = enh_map[i].ch[idx][1];
                break;
            }
            WARN("Unmapped char keyState=%x vk=%x\n",
                 ir.Event.KeyEvent.dwControlKeyState, ir.Event.KeyEvent.wVirtualScanCode);
        }
      }
      else
        break;
    } while(1);
    if (mode)
      SetConsoleMode(MSVCRT_console_in, mode);
  }
  UNLOCK_CONSOLE;
  return retval;
}
Example #10
0
// replacement get_s which is EL_BIND aware
static char *
el_get_s (char *buffer, int chars)
{
    //
    char *head = buffer;
    //
    for ( ;; Sleep( 10 ) )
    {
        //
        INPUT_RECORD _record;
        //
        DWORD _read = 0;
        if ( ReadConsoleInputA( GetStdHandle( STD_INPUT_HANDLE ), &_record, 1, &_read ) == FALSE )
            break;
        // if we didnt read a key
        if ( _read == 0 )
            continue;
        // only interested in key events
        if ( _record.EventType != KEY_EVENT )
            continue;
        // is the key down
        if (! _record.Event.KeyEvent.bKeyDown )
            continue;
        // read the ascii key character
        char _key = _record.Event.KeyEvent.uChar.AsciiChar;
        // non ascii conformant key press
        if ( _key == 0 )
        {
            // check the scan code
            // if VK_UP scroll back through history
            // if VK_DOWN scroll forward through history
            continue;
        }
        // try to execute any bind this key may have
        if ( runBind( _key ) )
            continue;
        // if we read a return key
        if ( _key == '\n' || _key == '\r' )
        {
            con_return( );
            break;
        }
        // key is backspace
        if ( _key == 0x8 )
        {
            // avoid deleting past beginning
            if ( head > buffer )
            {
                con_backspace( );
                head--;
            }
            continue;
        }

        // add this key to the input buffer
        if ( (head-buffer) < (chars-1) )
        {
            con_output( _key );
            *(head++) = _key;
        }
    }
    // insert end of line character
    *head = '\0';

    return buffer;
}
Example #11
0
static int linenoisePrompt(char*       buf,
                           size_t      buflen,
                           const char* prompt)
{
    size_t plen = strlen(prompt);
    size_t pos = 0;
    size_t len = 0;
    int history_index = 0;
#ifdef ALT_KEYS
    unsigned char last_down = 0;
#endif
    buf[0] = '\0';
    buflen--; /* Make sure there is always space for the nulterm */

    /* The latest history entry is always our current buffer, that
     * initially is just an empty string. */
    linenoiseHistoryAdd("");

    CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
    GetConsoleScreenBufferInfo(console_out, &inf);
    size_t cols = inf.dwSize.X;
    output(prompt, plen, 0, inf.dwCursorPosition.Y);
    inf.dwCursorPosition.X = (SHORT)plen;
    SetConsoleCursorPosition(console_out, inf.dwCursorPosition);

    for ( ; ; )
        {
            INPUT_RECORD rec;
            DWORD count;
            ReadConsoleInputA(console_in, &rec, 1, &count);
            if (rec.EventType != KEY_EVENT)
                continue;
#ifdef ALT_KEYS
            if (rec.Event.KeyEvent.bKeyDown)
                {
                    last_down = rec.Event.KeyEvent.uChar.AsciiChar;
                    continue;
                }
#else
            if (!rec.Event.KeyEvent.bKeyDown)
                {
                    continue;
                }
#endif
            switch (rec.Event.KeyEvent.wVirtualKeyCode)
                {
                case VK_RETURN:    /* enter */
                    history_len--;
                    free(history[history_len]);
                    return (int)len;
                case VK_BACK:   /* backspace */
#ifdef ALT_KEYS
                backspace:
#endif
                    if (pos > 0 && len > 0)
                        {
                            memmove(buf + pos - 1, buf + pos, len - pos);
                            pos--;
                            len--;
                            buf[len] = '\0';
                            refreshLine(prompt, buf, len, pos, cols);
                        }
                    break;
                case VK_LEFT:
#ifdef ALT_KEYS
                left_arrow:
#endif
                    /* left arrow */
                    if (pos > 0)
                        {
                            pos--;
                            refreshLine(prompt, buf, len, pos, cols);
                        }
                    break;
                case VK_RIGHT:
#ifdef ALT_KEYS
                right_arrow:
#endif
                    /* right arrow */
                    if (pos != len)
                        {
                            pos++;
                            refreshLine(prompt, buf, len, pos, cols);
                        }
                    break;
                case VK_UP:
                case VK_DOWN:
#ifdef ALT_KEYS
                up_down_arrow:
#endif
                    /* up and down arrow: history */
                    if (history_len > 1)
                        {
                            /* Update the current history entry before to
                             * overwrite it with tne next one. */
                            free(history[history_len - 1 - history_index]);
                            history[history_len - 1 - history_index] = _strdup(buf);
                            /* Show the new entry */
                            history_index += (rec.Event.KeyEvent.wVirtualKeyCode == VK_UP) ? 1 : -1;
                            if (history_index < 0)
                                {
                                    history_index = 0;
                                    break;
                                }
                            else if (history_index >= history_len)
                                {
                                    history_index = history_len - 1;
                                    break;
                                }
                            strncpy(buf, history[history_len - 1 - history_index], buflen);
                            buf[buflen] = '\0';
                            len = pos = strlen(buf);
                            refreshLine(prompt, buf, len, pos, cols);
                        }
                    break;
                case VK_DELETE:
                    /* delete */
                    if (len > 0 && pos < len)
                        {
                            memmove(buf + pos, buf + pos + 1, len - pos - 1);
                            len--;
                            buf[len] = '\0';
                            refreshLine(prompt, buf, len, pos, cols);
                        }
                    break;
                case VK_HOME: /* Ctrl+a, go to the start of the line */
#ifdef ALT_KEYS
                home:
#endif
                    pos = 0;
                    refreshLine(prompt, buf, len, pos, cols);
                    break;
                case VK_END: /* ctrl+e, go to the end of the line */
#ifdef ALT_KEYS
                end:
#endif
                    pos = len;
                    refreshLine(prompt, buf, len, pos, cols);
                    break;
                default:
#ifdef ALT_KEYS
                    /* Use alt instead of CTRL since windows eats CTRL+char combos */
                    if (rec.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
                        {
                            switch (last_down)
                                {
                                case 'a': /* ctrl-t */
                                    goto home;
                                case 'e': /* ctrl-t */
                                    goto end;
                                case 't': /* ctrl-t */
                                    if (pos > 0 && pos < len)
                                        {
                                            int aux = buf[pos - 1];
                                            buf[pos - 1] = buf[pos];
                                            buf[pos] = aux;
                                            if (pos != len - 1)
                                                pos++;
                                            refreshLine(prompt, buf, len, pos, cols);
                                        }
                                    break;
                                case 'h': /* ctrl-h */
                                    goto backspace;
                                case 'b': /* ctrl-b */
                                    goto left_arrow;
                                case 'f': /* ctrl-f */
                                    goto right_arrow;
                                case 'p': /* ctrl-p */
                                    rec.Event.KeyEvent.wVirtualKeyCode = VK_UP;
                                    goto up_down_arrow;
                                case 'n': /* ctrl-n */
                                    rec.Event.KeyEvent.wVirtualKeyCode = VK_DOWN;
                                    goto up_down_arrow;
                                case 'u': /* Ctrl+u, delete the whole line. */
                                    buf[0] = '\0';
                                    pos = len = 0;
                                    refreshLine(prompt, buf, len, pos, cols);
                                    break;
                                case 'k': /* Ctrl+k, delete from current to end of line. */
                                    buf[pos] = '\0';
                                    len = pos;
                                    refreshLine(prompt, buf, len, pos, cols);
                                    break;
                                }
                            continue;
                        }
#endif /* ALT_KEYS */
                    if (rec.Event.KeyEvent.uChar.AsciiChar < ' ' ||
                        rec.Event.KeyEvent.uChar.AsciiChar > '~')
                        continue;

                    if (len < buflen)
                        {
                            if (len != pos)
                                memmove(buf + pos + 1, buf + pos, len - pos);
                            buf[pos] = rec.Event.KeyEvent.uChar.AsciiChar;
                            len++;
                            pos++;
                            buf[len] = '\0';
                            refreshLine(prompt, buf, len, pos, cols);
                        }
                    break;
                }
        }
}