Exemplo n.º 1
0
Arquivo: input.c Projeto: mikekap/wine
/**********************************************************************
 *		VkKeyScanA (USER32.@)
 *
 * VkKeyScan translates an ANSI character to a virtual-key and shift code
 * for the current keyboard.
 * high-order byte yields :
 *	0	Unshifted
 *	1	Shift
 *	2	Ctrl
 *	3-5	Shift-key combinations that are not used for characters
 *	6	Ctrl-Alt
 *	7	Ctrl-Alt-Shift
 *	I.e. :	Shift = 1, Ctrl = 2, Alt = 4.
 * FIXME : works ok except for dead chars :
 * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
 */
SHORT WINAPI VkKeyScanA(CHAR cChar)
{
    WCHAR wChar;

    if (IsDBCSLeadByte(cChar)) return -1;

    MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1);
    return VkKeyScanW(wChar);
}
Exemplo n.º 2
0
/*
 * @implemented
 */
DWORD WINAPI
OemKeyScan(WORD wOemChar)
{
    WCHAR p;
    SHORT Vk;
    UINT Scan;

    MultiByteToWideChar(CP_OEMCP, 0, (PCSTR)&wOemChar, 1, &p, 1);
    Vk = VkKeyScanW(p);
    Scan = MapVirtualKeyW((Vk & 0x00ff), 0);
    if (!Scan) return -1;
    /*
       Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
       scan code and high word has the shift state.
     */
    return ((Vk & 0xff00) << 8) | Scan;
}
Exemplo n.º 3
0
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
                         PGUI_CONSOLE_DATA GuiData)
{
    /*
     * This function supposes that the system clipboard was opened.
     */

    PCONSRV_CONSOLE Console = Buffer->Header.Console;

    HANDLE hData;
    LPWSTR str;
    WCHAR CurChar = 0;

    USHORT VkKey; // MAKEWORD(low = vkey_code, high = shift_state);
    INPUT_RECORD er;

    hData = GetClipboardData(CF_UNICODETEXT);
    if (hData == NULL) return;

    str = GlobalLock(hData);
    if (str == NULL) return;

    DPRINT("Got data <%S> from clipboard\n", str);

    er.EventType = KEY_EVENT;
    er.Event.KeyEvent.wRepeatCount = 1;
    while (*str)
    {
        /* \r or \n characters. Go to the line only if we get "\r\n" sequence. */
        if (CurChar == L'\r' && *str == L'\n')
        {
            str++;
            continue;
        }
        CurChar = *str++;

        /* Get the key code (+ shift state) corresponding to the character */
        VkKey = VkKeyScanW(CurChar);
        if (VkKey == 0xFFFF)
        {
            DPRINT1("FIXME: TODO: VkKeyScanW failed - Should simulate the key!\n");
            /*
             * We don't really need the scan/key code because we actually only
             * use the UnicodeChar for output purposes. It may pose few problems
             * later on but it's not of big importance. One trick would be to
             * convert the character to OEM / multibyte and use MapVirtualKey
             * on each byte (simulating an Alt-0xxx OEM keyboard press).
             */
        }

        /* Pressing some control keys */

        /* Pressing the character key, with the control keys maintained pressed */
        er.Event.KeyEvent.bKeyDown = TRUE;
        er.Event.KeyEvent.wVirtualKeyCode = LOBYTE(VkKey);
        er.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyW(LOBYTE(VkKey), MAPVK_VK_TO_VSC);
        er.Event.KeyEvent.uChar.UnicodeChar = CurChar;
        er.Event.KeyEvent.dwControlKeyState = 0;
        if (HIBYTE(VkKey) & 1)
            er.Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
        if (HIBYTE(VkKey) & 2)
            er.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; // RIGHT_CTRL_PRESSED;
        if (HIBYTE(VkKey) & 4)
            er.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; // RIGHT_ALT_PRESSED;

        ConioProcessInputEvent(Console, &er);

        /* Up all the character and control keys */
        er.Event.KeyEvent.bKeyDown = FALSE;
        ConioProcessInputEvent(Console, &er);
    }

    GlobalUnlock(hData);
}
Exemplo n.º 4
0
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
                         PGUI_CONSOLE_DATA GuiData)
{
    /*
     * This function supposes that the system clipboard was opened.
     */

    PCONSRV_CONSOLE Console = Buffer->Header.Console;

    HANDLE hData;
    LPWSTR str;
    WCHAR CurChar = 0;

    USHORT VkKey; // MAKEWORD(low = vkey_code, high = shift_state);
    INPUT_RECORD er;

    hData = GetClipboardData(CF_UNICODETEXT);
    if (hData == NULL) return;

    str = GlobalLock(hData);
    if (str == NULL) return;

    DPRINT("Got data <%S> from clipboard\n", str);

    er.EventType = KEY_EVENT;
    er.Event.KeyEvent.wRepeatCount = 1;
    while (*str)
    {
        /* \r or \n characters. Go to the line only if we get "\r\n" sequence. */
        if (CurChar == L'\r' && *str == L'\n')
        {
            str++;
            continue;
        }
        CurChar = *str++;

        /* Get the key code (+ shift state) corresponding to the character */
        VkKey = VkKeyScanW(CurChar);
        if (VkKey == 0xFFFF)
        {
            DPRINT1("VkKeyScanW failed - Should simulate the key...\n");
            continue;
        }

        /* Pressing some control keys */

        /* Pressing the character key, with the control keys maintained pressed */
        er.Event.KeyEvent.bKeyDown = TRUE;
        er.Event.KeyEvent.wVirtualKeyCode = LOBYTE(VkKey);
        er.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyW(LOBYTE(VkKey), MAPVK_VK_TO_CHAR);
        er.Event.KeyEvent.uChar.UnicodeChar = CurChar;
        er.Event.KeyEvent.dwControlKeyState = 0;
        if (HIBYTE(VkKey) & 1)
            er.Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
        if (HIBYTE(VkKey) & 2)
            er.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; // RIGHT_CTRL_PRESSED;
        if (HIBYTE(VkKey) & 4)
            er.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; // RIGHT_ALT_PRESSED;

        ConioProcessInputEvent(Console, &er);

        /* Up all the character and control keys */
        er.Event.KeyEvent.bKeyDown = FALSE;
        ConioProcessInputEvent(Console, &er);
    }

    GlobalUnlock(hData);
}
Exemplo n.º 5
0
//-------------------------------------------------
void PushBuffer(HWND wndFocused)
{
	SHORT scanCode;
	WPARAM lParam;

	PostMessage(wndFocused,WM_KEYUP,VK_PAUSE,
		(LPARAM(VK_PAUSE_SCAN)<<16)+LPARAM(IsReleased)+1);
	if (pShMem->keyMode == UNICODE_CHARSET && pShMem->codeTable.encoding == UNICODE_UCS2) {
		if (!pShMem->options.useUnicodeClipboard && pShMem->unicodePlatform && 
			IsWindowUnicode(wndFocused)) {
			for (int i=0; i<VnKbd.keysPushed; i++) {
				scanCode = VkKeyScanW(VnKbd.uniPush[i]);
				lParam = (scanCode << 16) + 1;
				PostMessageW(wndFocused, (pShMem->options.useIME)? WM_IME_CHAR : WM_CHAR,
							VnKbd.uniPush[i], lParam);
			}
		}
		else {
			OpenClipboard(pShMem->hMainDlg);

			EmptyClipboard();

			VnKbd.uniPush[VnKbd.keysPushed] = 0; // null-terminated
			VnKbd.ansiPush[VnKbd.keysPushed] = 0;
			VnKbd.keysPushed++;

			HGLOBAL hBuf = GlobalAlloc(GMEM_MOVEABLE, sizeof(WORD) * VnKbd.keysPushed);
			HGLOBAL hBufAnsi = GlobalAlloc(GMEM_MOVEABLE, VnKbd.keysPushed);

			LPVOID pBuf = GlobalLock(hBuf);
			LPVOID pBufAnsi = GlobalLock(hBufAnsi);

			memcpy(pBuf, VnKbd.uniPush, sizeof(WORD) * VnKbd.keysPushed);
			memcpy(pBufAnsi, VnKbd.ansiPush, VnKbd.keysPushed);
			GlobalUnlock(hBuf);
			GlobalUnlock(hBufAnsi);

			SetClipboardData(CF_UNICODETEXT, hBuf);
			SetClipboardData(CF_TEXT, hBufAnsi);

			CloseClipboard();
			sendPasteCmd();
			ClipboardIsEmpty = 0;
		}
	}
	else if (pShMem->keyMode == DECOMPOSED_UNICODE_CHARSET) {
		if (pShMem->unicodePlatform && IsWindowUnicode(wndFocused)) {
			for (int i=0; i<VnKbd.keysPushed; i++) {
				scanCode = VkKeyScanW(VnKbd.uniPush[i]);
				lParam = (scanCode << 16) + 1;
				PostMessageW(wndFocused, (pShMem->options.useIME)? WM_IME_CHAR : WM_CHAR,
							VnKbd.uniPush[i],lParam);
			}
		}
		else {
			if (ViKeyboardLayout != NULL) {
				ActivateKeyboardLayout(ViKeyboardLayout, 0);
				LayoutChangeForced = 1;
			}

			int count = WideCharToMultiByte(1258, 0, VnKbd.uniPush, VnKbd.keysPushed, 
				                           (char *)VnKbd.ansiPush, VnKbd.keysPushed, 0, 0);
			for (int i=0; i<count; i++) {
				scanCode = VkKeyScan(VnKbd.ansiPush[i]);
				lParam = (scanCode << 16) + 1;
				PostMessage(wndFocused, (pShMem->options.useIME)? WM_IME_CHAR : WM_CHAR,
							VnKbd.ansiPush[i], lParam);
			}
		}
	}
	else {
		if (pShMem->keyMode == WINCP1258_CHARSET && ViKeyboardLayout!=NULL) {
			ActivateKeyboardLayout(ViKeyboardLayout, 0);
			LayoutChangeForced = 1;
		}

		for (int i=0; i<VnKbd.keysPushed; i++) {
			scanCode = VkKeyScan(VnKbd.ansiPush[i]);
			lParam = (scanCode << 16) + 1;
//			PostMessage(wndFocused, WM_IME_CHAR, VnKbd.ansiPush[i], lParam);
			PostMessage(wndFocused, (pShMem->options.useIME)? WM_IME_CHAR : WM_CHAR,
						VnKbd.ansiPush[i], lParam);
		}
	}
	return;
}
Exemplo n.º 6
-1
void KeyMap::PCtoX(BYTE virtKey, DWORD keyData, ClientConnection* clientCon)
{
    bool down = ((keyData & 0x80000000) == 0);
    bool extended = ((keyData & 0x1000000) != 0);
    bool repeated = ((keyData & 0xc0000000) == 0x40000000);
    UINT extVkey = virtKey + (extended ? 256 : 0);

	// exclude winkey when not scroll-lock
	if (virtKey==91 || virtKey==92) return;

   vnclog.Print(8, _T("\nPCtoX: %svirtKey 0x%02x%s%s, keyData 0x%08x\n"),
              (extended ? _T("extended ") : _T("")), virtKey,
              (repeated ? _T(" repeated") : _T("")),
              (down ? _T(" down") : _T(" up")), keyData);

    // If this is a key release then just send the associated sent KeySym when
    //   this key was pressed
    if (!down) {
     vnclog.Print(8, _T("Release the associated KeySym when this VirtKey was pressed\n"));

      if (downUnicode[extVkey]) {
         vnclog.Print(8, _T("  0x%04x (%c): "), downUnicode[extVkey], downUnicode[extVkey]);
          downUnicode[extVkey] = NULL;
      } else {
         vnclog.Print(8, _T("  Control character: "));
      }

      releaseKey(clientCon, extVkey);
     vnclog.Print(8, _T("\n"));
	 GetKeyboardState(KBKeysState);
    if (!((KBKeysState[VK_MENU] & 0x80) && (KBKeysState[VK_CONTROL] & 0x80)))
	{
	 if (storedDeadChar && reset) {
 	 reset=false;
	 keybd_event(VK_SPACE, 0, 0, 0);
	 keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0);
	 }
	}
      return;
    }

    // We try to look it up in our key table
    // Look up the desired code in the keyMap table try to find the exact match according to
    //   the extended flag, then try the opposite of the extended flag
    CARD32 foundXCode = XK_VoidSymbol;
    bool exactMatched = false;
   vnclog.Print(8, _T("Looking in key table "));

    for (UINT i = 0; i < (sizeof(keyMap) / sizeof(vncKeyMapping_t)); i++) {
        if (keyMap[i].WinCode == virtKey) {
            foundXCode = keyMap[i].XCode;
            if (extended == keyMap[i].extVK) {
                exactMatched = true;
                break;
            }
        }
    }

    if (foundXCode != XK_VoidSymbol) {
       vnclog.Print(8, _T("-> keyMap gives (from %s extended flag) KeySym %u (0x%08x)\n"),
                  (exactMatched ? _T("matched") : _T("opposite")),
                  foundXCode, foundXCode);
        pressKey(clientCon, extVkey, foundXCode);
       vnclog.Print(8, _T("\n"));
        return;
    } else {
       vnclog.Print(8, _T("-> not in special keyMap\n"));
    }

    // Under CE, we're not so concerned about this bit because we handle a WM_CHAR message later
#ifndef UNDER_CE
    GetKeyboardState(KBKeysState);

    ModifierKeyReleaser lctrl(clientCon, VK_CONTROL, 0);
    ModifierKeyReleaser lalt(clientCon, VK_MENU, 0);
    ModifierKeyReleaser ralt(clientCon, VK_MENU, 1);

    if ((KBKeysState[VK_MENU] & 0x80) && (KBKeysState[VK_CONTROL] & 0x80)) {
        // This is a Ctrl-Alt (AltGr) key on international keyboards (= LCtrl-RAlt)
        // Ex. Ctrl-Alt-Q gives '@' on German keyboards
       vnclog.Print(8, _T("Ctrl-Alt pressed:\n"));

        // We must release Control and Alt (AltGr) if they were both pressed, so the character
        //   is seen without them by the VNC server
        // We don't release the Right Control; this allows German users
        //   to use it for doing Ctrl-AltGr-x, e.g. Ctl-@, etc
        lctrl.release(downKeysym);
        lalt.release(downKeysym);
        ralt.release(downKeysym);
    } else {
        // This is not a Ctrl-Alt (AltGr) key
       vnclog.Print(8, _T("Ctrl-Alt not pressed, fake release any Ctrl key\n"));

        // There are no KeySym corresponding to control characters, e.g. Ctrl-F
        // The server has already known whether the Ctrl key is pressed from the previouse key event
        // So we are interested in the key that would be there if the Ctrl key were not pressed
        KBKeysState[VK_CONTROL] = KBKeysState[VK_LCONTROL] = KBKeysState[VK_RCONTROL] = 0;
    }

	int ret;
    if (storedDeadChar) {
        SHORT virtDeadKey;
        BYTE prevModifierState = 0;

       vnclog.Print(8, _T("[Storing base character modifier(s)]\n"));
        StoreModifier(&prevModifierState, KBKeysState);
        virtDeadKey = VkKeyScanW(storedDeadChar);

       vnclog.Print(8, _T("[A dead key was stored, restoring the dead key state:")
                     _T(" 0x%02x (%c) using virtDeadKey 0x%02x] "),
                  storedDeadChar, storedDeadChar, virtDeadKey);
        SetModifier(HIBYTE(virtDeadKey), KBKeysState);
       vnclog.Print(8, _T("\n"));
        ToUnicode((virtDeadKey & 0xff), 0, KBKeysState, ucsChar, (sizeof(ucsChar) / sizeof(WCHAR)), 0);

       vnclog.Print(8, _T("[Restoring base character modifier(s)] "));
        SetModifier(prevModifierState, KBKeysState);
       vnclog.Print(8, _T("\n"));

        storedDeadChar = 0;
		ret = ToUnicode(virtKey, 0, KBKeysState, ucsChar, (sizeof(ucsChar) / sizeof(WCHAR)), 0);
    }

    else ret = ToUnicode(virtKey, 0, KBKeysState, ucsChar, (sizeof(ucsChar) / sizeof(WCHAR)), 0);
	if (ucsChar[0]==8364)
	{
		//euro
//		return;
	}
    if (ret < 0 || ret==2) {
        //  It is a dead key
       vnclog.Print(8, _T("ToUnicode returns dead key: 0x%02x (%c) "), *ucsChar, *ucsChar);

        if (sendDeadKey) {
            // We try to look it up in our dead key table
            // Look up the desired code in the deadKeyMap table
            foundXCode = XK_VoidSymbol;

            for (UINT i = 0; i < (sizeof(deadKeyMap) / sizeof(vncDeadKeyMapping_t)); i++) {
                if (deadKeyMap[i].deadKeyChar == *ucsChar) {
                    foundXCode = deadKeyMap[i].XCode;
                    break;
                }
            }

            if (foundXCode != XK_VoidSymbol) {
               vnclog.Print(8, _T("-> deadKeyMap gives KeySym %u (0x%08x)\n"),
                          foundXCode, foundXCode);
                pressKey(clientCon, extVkey, foundXCode);
            } else {
               vnclog.Print(8, _T("-> not in deadKeyMap\n"));
            }
        } else {
            storedDeadChar = *ucsChar;
			reset=true;
           vnclog.Print(8, _T("-> Store the dead key state, wait for next key-stroke\n"));
        }

        FlushDeadKey(KBKeysState);
    } else if (ret > 0) {
       vnclog.Print(8, _T("ToUnicode returns %d character(s):\n"), ret);

        for (int i = 0; i < ret; i++) {
            CARD32 xChar = UCS2X(*(ucsChar+i));
            if (xChar != XK_VoidSymbol) {
                downUnicode[extVkey] = *(ucsChar+i);
                pressKey(clientCon, extVkey, xChar);

            }
        }
    } else {
       vnclog.Print(8, _T("No character is generated by this key event\n"));
    }
#endif

   vnclog.Print(8, _T("\n"));
};