예제 #1
0
파일: console.cpp 프로젝트: janturon/hedy
int getkey() {
  DWORD cnt;
  INPUT_RECORD ir;
  HANDLE conin = GetStdHandle(STD_INPUT_HANDLE);
  if(PeekConsoleInputW(conin,&ir,1,&cnt)) {
    do ReadConsoleInputW(conin,&ir,1,&cnt); while(ir.EventType!=KEY_EVENT);
  }
  FlushConsoleInputBuffer(conin);
  do ReadConsoleInputW(conin,&ir,1,&cnt); while(ir.EventType!=KEY_EVENT);
  FlushConsoleInputBuffer(conin);
  KEY_EVENT_RECORD ke = ir.Event.KeyEvent;
  int result = ke.uChar.UnicodeChar;
  if(result==0) return 1000000+ke.wVirtualKeyCode;
}
예제 #2
0
파일: editline.c 프로젝트: bilboed/wine
static BOOL WCEL_Get(WCEL_Context* ctx, INPUT_RECORD* ir)
{
    if (ReadConsoleInputW(ctx->hConIn, ir, 1, NULL)) return TRUE;
    ERR("hmm bad situation\n");
    ctx->error = 1;
    return FALSE;
}
예제 #3
0
파일: console.c 프로젝트: geek-li/flinux
static int console_get_poll_status(struct file *f)
{
	/* Writing is always ready */
	struct console_file *console_file = (struct console_file *) f;
	if (console->input_buffer_head != console->input_buffer_tail)
		return LINUX_POLLIN | LINUX_POLLOUT;

	console_lock();
	INPUT_RECORD ir;
	DWORD num_read;
	while (PeekConsoleInputW(console->in, &ir, 1, &num_read) && num_read > 0)
	{
		/* Test if the event will be discarded */
		if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown)
		{
			console_unlock();
			return LINUX_POLLIN | LINUX_POLLOUT;
		}
		/* Discard the event */
		ReadConsoleInputW(console->in, &ir, 1, &num_read);
	}
	/* We don't find any readable events */
	console_unlock();
	return LINUX_POLLOUT;
}
예제 #4
0
파일: w32inevt.c 프로젝트: exedre/emacs
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));
}
예제 #5
0
파일: input.cpp 프로젝트: firstblade/avbot
	// async_wait 调用到这里
	void operator()(boost::system::error_code ec)
	{
		DWORD r =0;
		INPUT_RECORD ir;
		ReadConsoleInputW(console_handle.native_handle(), &ir, 1, &r);
		if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown && ir.Event.KeyEvent.uChar.UnicodeChar)
		{
			WCHAR c = ir.Event.KeyEvent.uChar.UnicodeChar;
			if (c == L'\b')
			{
				// 退格键啊,应该删了
//				WriteConsoleOutputW();
				if (!readbuf.empty())
				{
					WCHAR lc = readbuf.back();
					
					readbuf.pop_back();
					
					if (lc >= 256)
					{
						WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\b \b \b", 5, &r, 0);
					}
					else
					{
						WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\b \b", 3, &r, 0);
					}
				}
			}
			else
			{
				readbuf.push_back(c);
			}

			if (iswprint(c))
			{
				WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), &c, 1, &r, 0);
			}
			// 判定 是不是读取到了 "\n"
			// 是的话就可以调用 handler 了
			if (c == L'\r')
			{
				// 读取到行尾啦!回调吧
				std::string thisline = wide_to_utf8(std::wstring(readbuf.data(), readbuf.size()));
				readbuf.clear();
				WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, &r, 0);
				SetConsoleMode(console_handle.native_handle(), m_savedmode);
				m_handler(thisline);
				return;
			}
		}

		// 重复读取
		console_handle.async_wait(*this);
	}
예제 #6
0
파일: tty.c 프로젝트: hghazal/node
void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
    uv_req_t* req) {
  /* Shortcut for handle->last_input_record.Event.KeyEvent. */
#define KEV handle->last_input_record.Event.KeyEvent

  DWORD records_left, records_read;
  uv_buf_t buf;
  off_t buf_used;

  assert(handle->type == UV_TTY);
  handle->flags &= ~UV_HANDLE_READ_PENDING;

  if (!(handle->flags & UV_HANDLE_READING) ||
      !(handle->flags & UV_HANDLE_TTY_RAW)) {
    goto out;
  }

  if (!REQ_SUCCESS(req)) {
    /* An error occurred while waiting for the event. */
    if ((handle->flags & UV_HANDLE_READING)) {
      handle->flags &= ~UV_HANDLE_READING;
      loop->last_error = GET_REQ_UV_ERROR(req);
      handle->read_cb((uv_stream_t*)handle, -1, uv_null_buf_);
    }
    goto out;
  }

  /* Fetch the number of events  */
  if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) {
    handle->flags &= ~UV_HANDLE_READING;
    uv_set_sys_error(loop, GetLastError());
    handle->read_cb((uv_stream_t*)handle, -1, uv_null_buf_);
    goto out;
  }

  /* Windows sends a lot of events that we're not interested in, so buf */
  /* will be allocated on demand, when there's actually something to emit. */
  buf = uv_null_buf_;
  buf_used = 0;

  while ((records_left > 0 || handle->last_key_len > 0) &&
         (handle->flags & UV_HANDLE_READING)) {
    if (handle->last_key_len == 0) {
      /* Read the next input record */
      if (!ReadConsoleInputW(handle->handle,
                             &handle->last_input_record,
                             1,
                             &records_read)) {
        uv_set_sys_error(loop, GetLastError());
        handle->flags &= ~UV_HANDLE_READING;
        handle->read_cb((uv_stream_t*) handle, -1, buf);
        goto out;
      }
      records_left--;

      /* Ignore events that are not keyboard events */
      if (handle->last_input_record.EventType != KEY_EVENT) {
        continue;
      }

      /* Ignore keyup events, unless the left alt key was held and a valid */
      /* unicode character was emitted. */
      if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
          KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
        continue;
      }

      /* Ignore keypresses to numpad number keys if the left alt is held */
      /* because the user is composing a character, or windows simulating */
      /* this. */
      if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) &&
          !(KEV.dwControlKeyState & ENHANCED_KEY) &&
          (KEV.wVirtualKeyCode == VK_INSERT ||
          KEV.wVirtualKeyCode == VK_END ||
          KEV.wVirtualKeyCode == VK_DOWN ||
          KEV.wVirtualKeyCode == VK_NEXT ||
          KEV.wVirtualKeyCode == VK_LEFT ||
          KEV.wVirtualKeyCode == VK_CLEAR ||
          KEV.wVirtualKeyCode == VK_RIGHT ||
          KEV.wVirtualKeyCode == VK_HOME ||
          KEV.wVirtualKeyCode == VK_UP ||
          KEV.wVirtualKeyCode == VK_PRIOR ||
          KEV.wVirtualKeyCode == VK_NUMPAD0 ||
          KEV.wVirtualKeyCode == VK_NUMPAD1 ||
          KEV.wVirtualKeyCode == VK_NUMPAD2 ||
          KEV.wVirtualKeyCode == VK_NUMPAD3 ||
          KEV.wVirtualKeyCode == VK_NUMPAD4 ||
          KEV.wVirtualKeyCode == VK_NUMPAD5 ||
          KEV.wVirtualKeyCode == VK_NUMPAD6 ||
          KEV.wVirtualKeyCode == VK_NUMPAD7 ||
          KEV.wVirtualKeyCode == VK_NUMPAD8 ||
          KEV.wVirtualKeyCode == VK_NUMPAD9)) {
        continue;
      }

      if (KEV.uChar.UnicodeChar != 0) {
        int prefix_len, char_len;

        /* Character key pressed */
        if (KEV.uChar.UnicodeChar >= 0xD800 &&
            KEV.uChar.UnicodeChar < 0xDC00) {
          /* UTF-16 high surrogate */
          handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
          continue;
        }

        /* Prefix with \u033 if alt was held, but alt was not used as part */
        /* a compose sequence. */
        if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
            && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
            RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
          handle->last_key[0] = '\033';
          prefix_len = 1;
        } else {
          prefix_len = 0;
        }

        if (KEV.uChar.UnicodeChar >= 0xDC00 &&
            KEV.uChar.UnicodeChar < 0xE000) {
          /* UTF-16 surrogate pair */
          WCHAR utf16_buffer[2] = { handle->last_utf16_high_surrogate,
                                    KEV.uChar.UnicodeChar};
          char_len = WideCharToMultiByte(CP_UTF8,
                                         0,
                                         utf16_buffer,
                                         2,
                                         &handle->last_key[prefix_len],
                                         sizeof handle->last_key,
                                         NULL,
                                         NULL);
        } else {
          /* Single UTF-16 character */
          char_len = WideCharToMultiByte(CP_UTF8,
                                         0,
                                         &KEV.uChar.UnicodeChar,
                                         1,
                                         &handle->last_key[prefix_len],
                                         sizeof handle->last_key,
                                         NULL,
                                         NULL);
        }

        /* Whatever happened, the last character wasn't a high surrogate. */
        handle->last_utf16_high_surrogate = 0;

        /* If the utf16 character(s) couldn't be converted something must */
        /* be wrong. */
        if (!char_len) {
          uv_set_sys_error(loop, GetLastError());
          handle->flags &= ~UV_HANDLE_READING;
          handle->read_cb((uv_stream_t*) handle, -1, buf);
          goto out;
        }

        handle->last_key_len = (unsigned char) (prefix_len + char_len);
        handle->last_key_offset = 0;
        continue;

      } else {
        /* Function key pressed */
        const char* vt100;
        size_t prefix_len, vt100_len;

        vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode,
                                  !!(KEV.dwControlKeyState & SHIFT_PRESSED),
                                  !!(KEV.dwControlKeyState & (
                                    LEFT_CTRL_PRESSED |
                                    RIGHT_CTRL_PRESSED)),
                                  &vt100_len);

        /* If we were unable to map to a vt100 sequence, just ignore. */
        if (!vt100) {
          continue;
        }

        /* Prefix with \x033 when the alt key was held. */
        if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
          handle->last_key[0] = '\033';
          prefix_len = 1;
        } else {
          prefix_len = 0;
        }

        /* Copy the vt100 sequence to the handle buffer. */
        assert(prefix_len + vt100_len < sizeof handle->last_key);
        memcpy(&handle->last_key[prefix_len], vt100, vt100_len);

        handle->last_key_len = (unsigned char) (prefix_len + vt100_len);
        handle->last_key_offset = 0;
        continue;
      }
    } else {
      /* Copy any bytes left from the last keypress to the user buffer. */
      if (handle->last_key_offset < handle->last_key_len) {
        /* Allocate a buffer if needed */
        if (buf_used == 0) {
          buf = handle->alloc_cb((uv_handle_t*) handle, 1024);
        }

        buf.base[buf_used++] = handle->last_key[handle->last_key_offset++];

        /* If the buffer is full, emit it */
        if (buf_used == buf.len) {
          handle->read_cb((uv_stream_t*) handle, buf_used, buf);
          buf = uv_null_buf_;
          buf_used = 0;
        }

        continue;
      }

      /* Apply dwRepeat from the last input record. */
      if (--KEV.wRepeatCount > 0) {
        handle->last_key_offset = 0;
        continue;
      }

      handle->last_key_len = 0;
      continue;
    }
  }

  /* Send the buffer back to the user */
  if (buf_used > 0) {
    handle->read_cb((uv_stream_t*) handle, buf_used, buf);
  }

 out:
  /* Wait for more input events. */
  if ((handle->flags & UV_HANDLE_READING) &&
      !(handle->flags & UV_HANDLE_READ_PENDING)) {
    uv_tty_queue_read(loop, handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);

#undef KEV
}
예제 #7
0
String ReadLine()
{
    String ret;
    
    #ifdef _WIN32
    HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
    HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
    if (input == INVALID_HANDLE_VALUE || output == INVALID_HANDLE_VALUE)
        return ret;

    // Use char-based input
    SetConsoleMode(input, ENABLE_PROCESSED_INPUT);

    INPUT_RECORD record;
    DWORD events = 0;
    DWORD readEvents = 0;

    if (!GetNumberOfConsoleInputEvents(input, &events))
        return ret;

    while (events--)
    {
        ReadConsoleInputW(input, &record, 1, &readEvents);
        if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
        {
            unsigned c = record.Event.KeyEvent.uChar.UnicodeChar;
            if (c)
            {
                if (c == '\b')
                {
                    PrintUnicode("\b \b");
                    size_t length = currentLine.LengthUTF8();
                    if (length)
                        currentLine = currentLine.SubstringUTF8(0, length - 1);
                }
                else if (c == '\r')
                {
                    PrintUnicode("\n");
                    ret = currentLine;
                    currentLine.Clear();
                    return ret;
                }
                else
                {
                    // We have disabled echo, so echo manually
                    wchar_t out = (wchar_t)c;
                    DWORD charsWritten;
                    WriteConsoleW(output, &out, 1, &charsWritten, 0);
                    currentLine.AppendUTF8(c);
                }
            }
        }
    }
    #else
    int flags = fcntl(STDIN_FILENO, F_GETFL);
    fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
    for (;;)
    {
        int ch = fgetc(stdin);
        if (ch >= 0 && ch != '\n')
            ret += (char)ch;
        else
            break;
    }
    #endif

    return ret;
}
예제 #8
0
파일: mswin.c 프로젝트: icostin/acx1
/* acx1_read_event **********************************************************/
ACX1_API unsigned int ACX1_CALL acx1_read_event (acx1_event_t * event_p)
{
    INPUT_RECORD ir;
    DWORD n;
    uint16_t ch;
    uint32_t m;

    for (;;)
    {
        if (!ReadConsoleInputW(hin, &ir, 1, &n))
        {
            LE("read console input failed!\n");
            return ACX1_TERM_IO_FAILED;
        }
        if (ir.EventType == WINDOW_BUFFER_SIZE_EVENT)
        {
            event_p->type = ACX1_RESIZE;
            event_p->size.w = ir.Event.WindowBufferSizeEvent.dwSize.X;
            event_p->size.h = ir.Event.WindowBufferSizeEvent.dwSize.Y;
            LI("screen resized to %ux%u\n", event_p->size.w, event_p->size.h);
            return 0;
        }
        if (ir.EventType == KEY_EVENT)
        {
            if (!ir.Event.KeyEvent.bKeyDown) continue;
            m = 0;
            if (ir.Event.KeyEvent.dwControlKeyState &
                    (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
                m |= ACX1_ALT;
            if (ir.Event.KeyEvent.dwControlKeyState &
                    (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
                m |= ACX1_CTRL;
            if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
                m |= ACX1_SHIFT;
            event_p->type = ACX1_KEY;
            ch = ir.Event.KeyEvent.uChar.UnicodeChar;
            if (ch >= 0x20)
                event_p->km = (m & ~ACX1_SHIFT) | ir.Event.KeyEvent.uChar.UnicodeChar;
            else //if (ch > 0)
            {

                if (ch == 0x08 || ch == 0x09 || ch == 0x0D) m = ch;
                else
                {
                    // event_p->km = ACX1_CTRL | 0x40 | ch;
                    switch (ch = ir.Event.KeyEvent.wVirtualKeyCode)
                    {
                    case VK_BACK:
                        m |= ACX1_BACKSPACE;
                        break;
                    case VK_TAB:
                        m |= ACX1_TAB;
                        break;
                    case VK_RETURN:
                        m |= ACX1_ENTER;
                        break;
                    case VK_ESCAPE:
                        m |= ACX1_ESC;
                        break;
                    case VK_SPACE:
                        m |= ACX1_SPACE;
                        break;
                    case VK_PRIOR:
                        m |= ACX1_PAGE_UP;
                        break;
                    case VK_NEXT:
                        m |= ACX1_PAGE_DOWN;
                        break;
                    case VK_END:
                        m |= ACX1_END;
                        break;
                    case VK_HOME:
                        m |= ACX1_HOME;
                        break;
                    case VK_LEFT:
                        m |= ACX1_LEFT;
                        break;
                    case VK_UP:
                        m |= ACX1_UP;
                        break;
                    case VK_RIGHT:
                        m |= ACX1_RIGHT;
                        break;
                    case VK_DOWN:
                        m |= ACX1_DOWN;
                        break;
                    case VK_INSERT:
                        m |= ACX1_INS;
                        break;
                    case VK_DELETE:
                        m |= ACX1_DEL;
                        break;
                    case VK_F1:
                        m |= ACX1_F1;
                        break;
                    case VK_F2:
                        m |= ACX1_F2;
                        break;
                    case VK_F3:
                        m |= ACX1_F3;
                        break;
                    case VK_F4:
                        m |= ACX1_F4;
                        break;
                    case VK_F5:
                        m |= ACX1_F5;
                        break;
                    case VK_F6:
                        m |= ACX1_F6;
                        break;
                    case VK_F7:
                        m |= ACX1_F7;
                        break;
                    case VK_F8:
                        m |= ACX1_F8;
                        break;
                    case VK_F9:
                        m |= ACX1_F9;
                        break;
                    case VK_F10:
                        m |= ACX1_F10;
                        break;
                    case VK_F11:
                        m |= ACX1_F11;
                        break;
                    case VK_F12:
                        m |= ACX1_F12;
                        break;
                    default:
                        if ((ch >= '0' && ch <= '9') ||
                                (ch >= 'A' && ch <= 'Z')) m |= ch;
                        else continue;
                    }
                }

                event_p->km = m;
            }
            // else { event_p->km = '?'; }
            LI("got key: 0x%X\n", event_p->km);
            return 0;
        }
    }
}
예제 #9
0
/*
    Taken from msvcrt.dll's getextendedkeycode()

                          ELSE SHFT CTRL ALTS
    00000000`723d36e0  1c 000d 000d 000a a600
    00000000`723d36ea  35 002f 003f 9500 a400
    00000000`723d36f4  47 47e0 47e0 77e0 9700
    00000000`723d36fe  48 48e0 48e0 8de0 9800
    00000000`723d3708  49 49e0 49e0 86e0 9900
    00000000`723d3712  4b 4be0 4be0 73e0 9b00
    00000000`723d371c  4d 4de0 4de0 74e0 9d00
    00000000`723d3726  4f 4fe0 4fe0 75e0 9f00
    00000000`723d3730  50 50e0 50e0 91e0 a000
    00000000`723d373a  51 51e0 51e0 76e0 a100
    00000000`723d3744  52 52e0 52e0 92e0 a200
    00000000`723d374e  53 53e0 53e0 93e0 a300

    home 01 00 00 00 01 00 24 00 47 00 00 00 00 00 00 00
    end  01 00 00 00 01 00 23 00 4f 00 00 00 00 00 00 00
    pgup 01 00 00 00 01 00 21 00 49 00 00 00 00 00 00 00
    pgdn 01 00 00 00 01 00 22 00 51 00 00 00 00 00 00 00
*/
static int getc_internal(int* alt)
{
    static int       carry        = 0; // Multithreading? What's that?
    static const int CTRL_PRESSED = LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED;

    int key_char;
    int key_vk;
    int key_sc;
    int key_flags;
    HANDLE handle;
    DWORD mode;

    // Clear all flags so the console doesn't do anything special. This prevents
    // key presses such as Ctrl-C and Ctrl-S from being swallowed.
    handle = GetStdHandle(STD_INPUT_HANDLE);
    GetConsoleMode(handle, &mode);

loop:
    key_char = 0;
    key_vk = 0;
    key_sc = 0;
    key_flags = 0;
    *alt = 0;

    // Read a key or use what was carried across from a previous call.
    if (carry)
    {
        key_flags = ENHANCED_KEY;
        key_char = carry;
        carry = 0;
    }
    else
    {
        HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        DWORD i;
        INPUT_RECORD record;
        const KEY_EVENT_RECORD* key;
        int altgr_sub;

        GetConsoleScreenBufferInfo(handle_stdout, &csbi);

        // Check for a new buffer size for simulated SIGWINCH signals.
        i = (csbi.dwSize.X << 16) | csbi.dwSize.Y;
        if (!g_knownBufferSize || g_knownBufferSize != i)
        {
            simulate_sigwinch(csbi.dwCursorPosition);
            g_knownBufferSize = i;
            goto loop;
        }

        // Fresh read from the console.
        SetConsoleMode(handle, 0);
        ReadConsoleInputW(handle, &record, 1, &i);
        if (record.EventType != KEY_EVENT)
        {
            goto loop;
        }

        key = &record.Event.KeyEvent;
        key_char = key->uChar.UnicodeChar;
        key_vk = key->wVirtualKeyCode;
        key_sc = key->wVirtualScanCode;
        key_flags = key->dwControlKeyState;

#if defined(DEBUG_GETC) && defined(_DEBUG)
        {
            static int id = 0;
            int i;
            printf("\n%03d: %s ", id++, key->bKeyDown ? "+" : "-");
            for (i = 2; i < sizeof(*key) / sizeof(short); ++i)
            {
                printf("%04x ", ((unsigned short*)key)[i]);
            }
        }
#endif

        if (key->bKeyDown == FALSE)
        {
            // Some times conhost can send through ALT codes, with the resulting
            // Unicode code point in the Alt key-up event.
            if (key_vk == VK_MENU && key_char)
            {
                goto end;
            }

            goto loop;
        }

        // Windows supports an AltGr substitute which we check for here. As it
        // collides with Readline mappings Clink's support can be disabled.
        altgr_sub = !!(key_flags & LEFT_ALT_PRESSED);
        altgr_sub &= !!(key_flags & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED));
        altgr_sub &= !!key_char;
        altgr_sub &= get_clink_setting_int("use_altgr_substitute");

        if (!altgr_sub)
        {
            *alt = !!(key_flags & LEFT_ALT_PRESSED);
        }
    }

    // No Unicode character? Then some post-processing is required to make the
    // output compatible with whatever standard Linux terminals adhere to and
    // that which Readline expects.
    if (key_char == 0)
    {
        int i;

        // The numpad keys such as PgUp, End, etc. don't come through with the
        // ENHANCED_KEY flag set so we'll infer it here.
        static const int enhanced_vks[] = {
            VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME, VK_END,
            VK_INSERT, VK_DELETE, VK_PRIOR, VK_NEXT,
        };

        for (i = 0; i < sizeof_array(enhanced_vks); ++i)
        {
            if (key_vk == enhanced_vks[i])
            {
                key_flags |= ENHANCED_KEY;
                break;
            }
        }

        // Differentiate enhanced keys depending on modifier key state. MSVC's
        // runtime does something similar. Slightly non-standard.
        if (key_flags & ENHANCED_KEY)
        {
            static const int mod_map[][4] =
            {
                //Nrml  Shft  Ctrl  CtSh
                { 0x47, 0x61, 0x77, 0x21 }, // Gaw! home
                { 0x48, 0x62, 0x54, 0x22 }, // HbT" up
                { 0x49, 0x63, 0x55, 0x23 }, // IcU# pgup
                { 0x4b, 0x64, 0x73, 0x24 }, // Kds$ left
                { 0x4d, 0x65, 0x74, 0x25 }, // Met% right
                { 0x4f, 0x66, 0x75, 0x26 }, // Ofu& end
                { 0x50, 0x67, 0x56, 0x27 }, // PgV' down
                { 0x51, 0x68, 0x76, 0x28 }, // Qhv( pgdn
                { 0x52, 0x69, 0x57, 0x29 }, // RiW) insert
                { 0x53, 0x6a, 0x58, 0x2a }, // SjX* delete
            };

            for (i = 0; i < sizeof_array(mod_map); ++i)
            {
                int j = 0;
                if (mod_map[i][j] != key_sc)
                {
                    continue;
                }

                j += !!(key_flags & SHIFT_PRESSED);
                j += !!(key_flags & CTRL_PRESSED) << 1;
                carry = mod_map[i][j];
                break;
            }

            // Blacklist.
            if (!carry)
            {
                goto loop;
            }

            key_vk = 0xe0;
        }
        else if (!(key_flags & CTRL_PRESSED))
        {
            goto loop;
        }

        // This builds Ctrl-<key> map to match that as described by Readline's
        // source for the emacs/vi keymaps.
        #define CONTAINS(l, r) (unsigned)(key_vk - l) <= (r - l)
        else if (CONTAINS('A', 'Z'))    key_vk -= 'A' - 1;
        else if (CONTAINS(0xdb, 0xdd))  key_vk -= 0xdb - 0x1b;
        else if (key_vk == 0x32)        key_vk = 0;
        else if (key_vk == 0x36)        key_vk = 0x1e;
        else if (key_vk == 0xbd)        key_vk = 0x1f;
        else                            goto loop;
        #undef CONTAINS

        key_char = key_vk;
    }
    else if (!(key_flags & ENHANCED_KEY) && key_char > 0x7f)
    {
        key_char |= 0x8000000;
    }

end:
#if defined(DEBUG_GETC) && defined(_DEBUG)
    printf("\n%08x '%c'", key_char, key_char);
#endif

    SetConsoleMode(handle, mode);
    return key_char;
}
예제 #10
0
/*--------------------------------------------------------------------------*/
static unsigned char TerminalGetchar(void)
{
    INPUT_RECORD irBuffer;
    DWORD n = 0;
    unsigned char ch = 0;
    do
    {
        /* http://bugzilla.scilab.org/show_bug.cgi?id=1052 */
        if ( ismenu() == 1 )
        {
            return 0;
        }

        WaitForSingleObject(Win32InputStream, INFINITE);
        PeekConsoleInput (Win32InputStream, &irBuffer, 1, &n);

        switch (irBuffer.EventType)
        {
            case KEY_EVENT:
            {
                if (irBuffer.Event.KeyEvent.bKeyDown)
                {
                    if (irBuffer.Event.KeyEvent.dwControlKeyState)
                    {
                        if (isCTRLPressed(irBuffer.Event.KeyEvent.dwControlKeyState))
                        {
                            char c = actionControlKey();
                            if (c)
                            {
                                ReadConsoleInputW (Win32InputStream, &irBuffer, 1, &n);
                                return c;
                            }
                            else
                            {
                                if (irBuffer.Event.KeyEvent.uChar.AsciiChar != '\0')
                                {
                                    ReadConsoleInputW (Win32InputStream, &irBuffer, 1, &n);
                                    c = irBuffer.Event.KeyEvent.uChar.AsciiChar;
                                    if ( (c > 0) && !iscntrl(c) )
                                    {
                                        return c;
                                    }
                                }
                                else
                                {
                                    ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
                                }
                            }
                            break;
                        }

                        if (isALTPressed(irBuffer.Event.KeyEvent.dwControlKeyState))
                        {
                            if (irBuffer.Event.KeyEvent.uChar.AsciiChar != '\0')
                            {
                                ReadConsole (Win32InputStream, &ch, 1, &n, NULL);
                                return ch;
                            }
                            else
                            {
                                DWORD stateKey = 0;
                                WORD vk = 0;

                                ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);

                                stateKey = irBuffer.Event.KeyEvent.dwControlKeyState;
                                vk = irBuffer.Event.KeyEvent.wVirtualKeyCode;

                                switch (vk)
                                {
                                    case VK_F4:
                                        ALTF4_Command();
                                        break;

                                    default:
                                        break;
                                }
                            }
                            break;
                        }
                    }

                    if (irBuffer.Event.KeyEvent.uChar.AsciiChar != '\0')
                    {
                        ReadConsole (Win32InputStream, &ch, 1, &n, NULL);

                        switch (ch)
                        {
                            case VK_TAB:
                                TermCompletion();
                                break;
                            case VK_BACK:
                                deletePreviousChar();
                                break;
                            default:
                            {
                                if ( !iscntrl(ch) || (ch == CR_1) || (ch == CR_2) )
                                {
                                    return ch;
                                }
                            }
                            break;
                        }
                    }
                    else
                    {
                        WORD vk = 0;
                        ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
                        vk = irBuffer.Event.KeyEvent.wVirtualKeyCode;

                        switch (vk)
                        {
                            case VK_F1:
                            case VK_HELP:
                                F1_Command();
                                break;
                            case VK_F2:
                                F2_Command();
                                break;
                            case VK_LEFT:
                                moveBackSingleChar();
                                break;
                            case VK_RIGHT:
                                moveForwardSingleChar();
                                break;
                            case VK_UP:
                                moveBackHistory();
                                break;
                            case VK_DOWN:
                                moveForwardHistory();
                                break;
                            case VK_DELETE:
                                deleteCurrentChar();
                                break;
                            case VK_HOME:
                                moveBeginningLine();
                                break;
                            case VK_END:
                                moveEndLine();
                                break;
                            default:
                                break;
                        }
                    }
                }
                else
                {
                    ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
                }
            }
            break;
            case MOUSE_EVENT:
            {
                /* Read mouse Input but not used */
                ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
            }
            break;
            case WINDOW_BUFFER_SIZE_EVENT:
            {
                /* Read resize event Input */
                setColumnsSize(irBuffer.Event.WindowBufferSizeEvent.dwSize.X);
                setLinesSize(irBuffer.Event.WindowBufferSizeEvent.dwSize.Y);

                ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
            }
            break;
            case MENU_EVENT:
            {
                ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
            }
            break;
            case FOCUS_EVENT:
            {
                ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
            }
            break;
            default:
            {
                /* Read Input but not used */
                ReadConsoleInput (Win32InputStream, &irBuffer, 1, &n);
            }
            break;
        }
    }
    while (TRUE);
}
예제 #11
0
int
ConsoleReadCh()
{
    const int max_input = 8;
    static char console_input[8];
    static int first_input_char = 0;
    static int last_input_char = 0;
    INPUT_RECORD rec;
    DWORD recRead;
    HANDLE h;

    if (first_input_char != last_input_char) {
	int c = console_input[first_input_char];
	first_input_char++;
	first_input_char %= max_input;
	return c;
    }

    h = GetStdHandle(STD_INPUT_HANDLE);
    if (h == NULL)
	return NUL;

    ReadConsoleInputW(h, &rec, 1, &recRead);
    /* FIXME: We should handle rec.Event.KeyEvent.wRepeatCount > 1, too. */
    if (recRead == 1 && rec.EventType == KEY_EVENT && rec.Event.KeyEvent.bKeyDown &&
       (rec.Event.KeyEvent.wVirtualKeyCode < VK_SHIFT ||
	rec.Event.KeyEvent.wVirtualKeyCode > VK_MENU)) {
	    if (rec.Event.KeyEvent.uChar.UnicodeChar) {
		if ((rec.Event.KeyEvent.dwControlKeyState == SHIFT_PRESSED) && (rec.Event.KeyEvent.wVirtualKeyCode == VK_TAB)) {
		    return 034; /* remap Shift-Tab */
		} else {
		    int i, count;
		    char mbchar[8];
		    count = WideCharToMultiByte(WinGetCodepage(encoding), 0,
				&rec.Event.KeyEvent.uChar.UnicodeChar, 1,
				mbchar, sizeof(mbchar),
				NULL, NULL);
		    for (i = 1; i < count; i++) {
			console_input[last_input_char] = mbchar[i];
			last_input_char++;
			last_input_char %= max_input;
		    }
		    return mbchar[0];
		}
	    } else {
		switch (rec.Event.KeyEvent.wVirtualKeyCode) {
		case VK_UP: return 020;
		case VK_DOWN: return 016;
		case VK_LEFT: return 002;
		case VK_RIGHT: return 006;
		case VK_HOME: return 001;
		case VK_END: return 005;
		case VK_DELETE: return 0117;
		}
	    }
    }

    /* Error reading event or, key up or, one of the following event records:
	MOUSE_EVENT_RECORD, WINDOW_BUFFER_SIZE_RECORD, MENU_EVENT_RECORD, FOCUS_EVENT_RECORD */
    return NUL;
}
예제 #12
0
inline void Console::handle_input (HANDLE in, ConsoleScreenBuffer & buffer) {

    DWORD num;
    INPUT_RECORD ir;
    if (!ReadConsoleInputW(
                in,
                &ir,
                1,
                &num
            )) Raise();

    //	Nothing was read
    if (num==0) return;

    //	If a resize event was read,
    //	handle and return
    if (ir.EventType==WINDOW_BUFFER_SIZE_EVENT) {

        buffer.Resize();

        return;

    }

    //	We're only concerned with key
    //	press events besides resize
    //	events
    if (!(
                (ir.EventType==KEY_EVENT) &&
                (ir.Event.KeyEvent.bKeyDown)
            )) return;

    //	Loop for the number of times
    //	this key press was repeated
    for (WORD i=0; i<ir.Event.KeyEvent.wRepeatCount; ++i) {

        //	Switch depending on the key
        //	pressed
        switch (ir.Event.KeyEvent.wVirtualKeyCode) {

        case VK_RETURN: {

            //	Enter was pressed

            //	Get line from the screen
            String line(buffer.Return());
            //	Dispatch callback (if applicable)
            if (callback) callback(std::move(line));

        }
        break;

        case VK_HOME:

            //	Home was pressed

            //	Fire appropriate event
            //	depending on whether CTRL
            //	is pressed or not
            if (ctrl_pressed(ir)) buffer.CtrlHome();
            else buffer.Home();

            break;

        case VK_END:

            //	End was pressed

            //	Fire appropriate event
            //	depending on whether
            //	CTRL is pressed or not
            if (ctrl_pressed(ir)) buffer.CtrlEnd();
            else buffer.End();

            break;

        case VK_RIGHT:

            //	Right was pressed

            buffer.Right();

            break;

        case VK_LEFT:

            //	Left was pressed

            buffer.Left();

            break;

        case VK_DELETE:

            //	Delete was pressed

            buffer.Delete();

            break;

        case VK_BACK:

            //	Backspace was pressed

            buffer.Backspace();

            break;

        case VK_PRIOR:

            //	Page Up was pressed

            buffer.PageUp();

            break;

        case VK_NEXT:

            //	Page Down was pressed

            buffer.PageDown();

            break;

        default:

            if (ir.Event.KeyEvent.uChar.UnicodeChar!=0) buffer.Add(
                    static_cast<CodePoint>(
                        ir.Event.KeyEvent.uChar.UnicodeChar
                    )
                );

            break;

        }

    }

}
예제 #13
0
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_readInput(JNIEnv *env, jclass target, jobject char_buffer, jobject result) {
    init_input(env, result);
    INPUT_RECORD events[1];
    DWORD nread;
    while(TRUE) {
        if (!ReadConsoleInputW(console_buffer, events, 1, &nread)) {
            mark_failed_with_errno(env, "could not read from console", result);
            return;
        }
        if (events[0].EventType != KEY_EVENT) {
            continue;
        }
        KEY_EVENT_RECORD keyEvent = events[0].Event.KeyEvent;
        if (!keyEvent.bKeyDown) {
            if (keyEvent.wVirtualKeyCode == 0x43 && keyEvent.uChar.UnicodeChar == 3) {
                // key down event for ctrl-c doesn't seem to be delivered, but key up event does
                return;
            }
            continue;
        }

        if ((keyEvent.dwControlKeyState & (LEFT_ALT_PRESSED|LEFT_CTRL_PRESSED|RIGHT_ALT_PRESSED|RIGHT_CTRL_PRESSED|SHIFT_PRESSED)) == 0) {
            if (keyEvent.wVirtualKeyCode == VK_RETURN) {
                control_key(env, 0, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_UP) {
                control_key(env, 1, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_DOWN) {
                control_key(env, 2, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_LEFT) {
                control_key(env, 3, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_RIGHT) {
                control_key(env, 4, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_HOME) {
                control_key(env, 5, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_END) {
                control_key(env, 6, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_BACK) {
                control_key(env, 7, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_DELETE) {
                control_key(env, 8, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_PRIOR) { // page up
                control_key(env, 10, char_buffer, result);
                return;
            } else if (keyEvent.wVirtualKeyCode == VK_NEXT) { // page down
                control_key(env, 11, char_buffer, result);
                return;
            }
        }
        if (keyEvent.wVirtualKeyCode == 0x44 && keyEvent.uChar.UnicodeChar == 4) {
            // ctrl-d
            return;
        }
        if (keyEvent.uChar.UnicodeChar == 0) {
            // Some other control key
            continue;
        }
        if (keyEvent.uChar.UnicodeChar == '\t' && (keyEvent.dwControlKeyState & (SHIFT_PRESSED)) == 0) {
            // shift-tab
            control_key(env, 9, char_buffer, result);
        } else {
            character(env, (jchar)keyEvent.uChar.UnicodeChar, char_buffer, result);
        }
        return;
    }
}
예제 #14
0
파일: getline.c 프로젝트: radfordneal/pqR
static int
gl_getc(void)
/* get a character without echoing it to screen */
{
    int             c;
    static char buf[9] = "";
    static int bufavail = 0;
    static int bufpos = 0;

    if (bufavail > 0) {
	bufavail--;
	return buf[bufpos++];
    }
    bufpos = 0;

/* guido masarotto (3/12/98)
 * get Ansi char code from a Win32 console
 */
    DWORD a;
    INPUT_RECORD r;
    DWORD st;
    WORD vk;
    CONSOLE_SCREEN_BUFFER_INFO csb;
    int bbb = 0, nAlt=0, n;

    c = 0; 
    while (!c) {
      /* 
	   Following two lines seem to be needed under Win2k 
	   to reshow the cursor 
      */
      GetConsoleScreenBufferInfo(Win32OutputStream, &csb);
      SetConsoleCursorPosition(Win32OutputStream, csb.dwCursorPosition);
      ReadConsoleInputW(Win32InputStream, &r, 1, &a);
      if (!(r.EventType == KEY_EVENT)) break;
      st = r.Event.KeyEvent.dwControlKeyState;
      vk = r.Event.KeyEvent.wVirtualKeyCode;
      if (r.Event.KeyEvent.bKeyDown) {
        AltIsDown = (st & LEFT_ALT_PRESSED);
	if (vk == VK_MENU && AltIsDown) { /* VK_MENU is
							   Alt or AltGr */
	  nAlt = 0;
	  bbb  = 0;
	} 
	else if (st & ENHANCED_KEY) { 
	  switch(vk) {
	  case VK_LEFT: c=2 ;break;
	  case VK_RIGHT: c=6;break;
	  case VK_HOME:  c='\001';break;
	  case VK_END: c='\005';break;
	  case VK_UP:  c=16;break;
	  case VK_DOWN: c=14;break;		
	  case VK_DELETE:  c='\004';break;
	  }
	} 
	else if (AltIsDown) { /* Interpret Alt+xxx entries */
	  switch (vk) {
	  case VK_INSERT: n = 0; break;
	  case VK_END: n = 1; break;
	  case VK_DOWN: n = 2; break;
	  case VK_NEXT: n = 3;break;
	  case VK_LEFT: n = 4; break;
	  case VK_CLEAR:  n = 5; break;
	  case VK_RIGHT: n = 6; break;
	  case VK_HOME: n = 7; break;
	  case VK_UP: n = 8; break;
	  case VK_PRIOR: n = 9; break;	 
	  default: n = -1;
	  }
	  if (n >= 0) bbb = 10 * bbb + n;
	  nAlt += 1;
	  if (nAlt==3) { 
	    c = (bbb < 256) && (bbb > 0) ? bbb : 0;
	    bbb = 0;
	    nAlt = 0;
	  } 
	} 
	else {
	  /* Originally uChar.AsciiChar was used here and for MBCS characters
	     GetConsoleInput returned as many events as bytes in the character.
	     As of Windows 8 this reportedly no longer works, GetConsoleInput
	     would only generate one event with the first byte in AsciiChar.
	     The bug still exists in Windows 10, and thus we now call
	     GetConsoleInputW to get uchar.UnicodeChar. Ideally (at least for
	     Windows) all of getline code would be refactored to work with wide
	     characters, but for now we just convert the character back to bytes
	     in current native locale to recover the old behavior of gl_getc. */
	  wchar_t wc = r.Event.KeyEvent.uChar.UnicodeChar;
	  mbstate_t mb_st;
	  mbs_init(&mb_st);
	  if (wc != L'\0') {
	    size_t cres = wcrtomb(buf, wc, &mb_st);
	    if (cres != (size_t)-1) {
	      bufavail = (int) cres - 1;
	      bufpos = 1;
	      c = buf[0];
	    }
	  }
	}
      }
      else if (vk == VK_MENU && AltIsDown) { 
           /* Alt key up event: could be AltGr, but let's hope users 
	      only press one of them at a time. */
	AltIsDown = 0;
	c = (bbb < 256) && (bbb > 0) ? bbb : 0;
	bbb = 0;
	nAlt = 0;
      }
      if ((c < -127) || (c > 255)) c = 0; 
      if (c < 0) c = 256 + c;    
    }
    return c;
}