/* Processes WM_UNICHAR messages The nVirtKey already contains utf-32 char, so we do not need to do any iconv translation */ bool ev_Win32Keyboard::onUniChar(AV_View * pView, HWND /*hWnd*/, UINT /*iMsg*/, WPARAM nVirtKey, LPARAM /*keyData*/) { // as WM_UNICHAR is not proceeded by WM_KEYDOWN message, we need to reset this flag here. m_bWasAnAbiCommand = false; EV_EditModifierState ems = _getModifierState(); EV_EditMethod * pEM; EV_EditEventMapperResult result = m_pEEM->Keystroke(EV_EKP_PRESS|ems|nVirtKey,&pEM); switch (result) { case EV_EEMR_BOGUS_START: //UT_DEBUGMSG((" Unbound StartChar: %c\n",b)); break; case EV_EEMR_BOGUS_CONT: //UT_DEBUGMSG((" Unbound ContChar: %c\n",b)); break; case EV_EEMR_COMPLETE: UT_ASSERT(pEM); invokeKeyboardMethod(pView,pEM,(UT_UCS4Char*)&nVirtKey,1); break; case EV_EEMR_INCOMPLETE: //MSG(keyData,((" Non-Terminal-Char: %c\n",b))); break; default: UT_ASSERT(UT_SHOULD_NOT_HAPPEN); break; } return true; }
void ev_Win32Keyboard::_emitChar(AV_View * pView, HWND /*hWnd*/, UINT iMsg, WPARAM nVirtKey, LPARAM /*keyData*/, UT_uint32 b, EV_EditModifierState ems) { // do the dirty work of pumping this character thru the state machine. UT_UCSChar charData[2]; size_t ret; if( m_iconv != UT_ICONV_INVALID ) { // convert to 8bit string and null terminate size_t len_in, len_out; const char *In = (const char *)&b; char *Out = (char *)&charData; // 2 bytes for Unicode and MBCS // 4 bytes for UNICHAR msg if(iMsg == WM_UNICHAR) len_in = 4; else if(m_bIsUnicodeInput || (nVirtKey & 0xff00)) len_in = 2; else len_in = 1; len_out = sizeof(charData); if ((ret = UT_iconv( m_iconv, &In, &len_in, &Out, &len_out )) == -1) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); } if (Out == (char *)charData) { // m_iconv is waiting for a combination keystroke. Flush the buffer if ((ret = UT_iconv( m_iconv, NULL, &len_in, &Out, &len_out )) == -1) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); } } } else { charData[0] = b; charData[1] = 0; } EV_EditMethod * pEM; EV_EditEventMapperResult result = m_pEEM->Keystroke(EV_EKP_PRESS|ems|charData[0],&pEM); switch (result) { case EV_EEMR_BOGUS_START: //UT_DEBUGMSG((" Unbound StartChar: %c\n",b)); break; case EV_EEMR_BOGUS_CONT: //UT_DEBUGMSG((" Unbound ContChar: %c\n",b)); break; case EV_EEMR_COMPLETE: UT_ASSERT(pEM); invokeKeyboardMethod(pView,pEM,charData,1); break; case EV_EEMR_INCOMPLETE: //MSG(keyData,((" Non-Terminal-Char: %c\n",b))); break; default: UT_ASSERT(UT_SHOULD_NOT_HAPPEN); break; } return; }
bool ev_UnixKeyboard::keyPressEvent(AV_View* pView, GdkEventKey* e) { EV_EditBits state = 0; EV_EditEventMapperResult result; EV_EditMethod * pEM; UT_uint32 charData = e->keyval; if (e->state & GDK_SHIFT_MASK) state |= EV_EMS_SHIFT; if (e->state & GDK_CONTROL_MASK) { state |= EV_EMS_CONTROL; // Gdk does us the favour of working out a translated keyvalue for us, // but with the Ctrl keys, we do not want that -- see bug 9545 Display * display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(e->window)); KeySym sym = XKeycodeToKeysym(display, e->hardware_keycode, e->state & GDK_SHIFT_MASK ? 1 : 0); xxx_UT_DEBUGMSG(("ev_UnixKeyboard::keyPressEvent: keyval %d, hardware_keycode %d\n" " sym: 0x%x\n", e->keyval, e->hardware_keycode, sym)); charData = sym; } if (e->state & (s_alt_mask)) state |= EV_EMS_ALT; if (s_isVirtualKeyCode(charData)) { EV_EditBits nvk = s_mapVirtualKeyCodeToNVK(charData); switch (nvk) { case EV_NVK__IGNORE__: return false; default: result = m_pEEM->Keystroke(static_cast<UT_uint32>(EV_EKP_PRESS|state|nvk),&pEM); switch (result) { case EV_EEMR_BOGUS_START: // If it is a bogus key and we don't have a sequence in // progress, we should let the system handle it // (this lets things like ALT-F4 work). return false; case EV_EEMR_BOGUS_CONT: // If it is a bogus key but in the middle of a sequence, // we should silently eat it (this is to prevent things // like Control-X ALT-F4 from killing us -- if they want // to kill us, fine, but they shouldn't be in the middle // of a sequence). return true; case EV_EEMR_COMPLETE: UT_ASSERT(pEM); invokeKeyboardMethod(pView,pEM,0,0); // no char data to offer return true; case EV_EEMR_INCOMPLETE: return true; default: UT_ASSERT(0); return true; } } } else { // TODO: is this necessary? charData = gdk_keyval_to_unicode (charData); UT_UTF8String utf8 (static_cast<const UT_UCS4Char *>(&charData), 1); return charDataEvent (pView, state, utf8.utf8_str(), utf8.byteLength()); } return false; }
/* 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; }
bool ev_UnixKeyboard::charDataEvent(AV_View* pView, EV_EditBits state, const char * text, size_t len) { EV_EditEventMapperResult result; EV_EditMethod * pEM; /* do some sanity checking, since: - delete_surrounding commits a 0 length string in some IMs - some IMs state a length of 1, while the text being "" (for example the Amharic IM for keystrokes that have no secondary character (eg. shift-R) */ if (!text || *text == '\0' || !len) return true; UT_UCS4String ucs (text, len); UT_uint32 charData = static_cast<UT_uint32>(ucs[0]); xxx_UT_DEBUGMSG(("DOM: charData: %d | length: %d | string: '%s'\n", charData, len, text)); if (charData == 32) charData = 'a'; // HACK!!! for space bar not working. investigate more.... if(charData>0xff || charData == 0) result = m_pEEM->Keystroke(EV_EKP_PRESS|state|'a',&pEM); else result = m_pEEM->Keystroke(EV_EKP_PRESS|state|charData,&pEM); switch (result) { case EV_EEMR_BOGUS_START: // If it is a bogus key and we don't have a sequence in // progress, we should let the system handle it // (this lets things like ALT-F4 work). return false; case EV_EEMR_BOGUS_CONT: // If it is a bogus key but in the middle of a sequence, // we should silently eat it (this is to prevent things // like Control-X ALT-F4 from killing us -- if they want // to kill us, fine, but they shouldn't be in the middle // of a sequence). return true; case EV_EEMR_COMPLETE: { UT_ASSERT(pEM); invokeKeyboardMethod(pView,pEM, ucs.ucs4_str(), static_cast<UT_uint32>(ucs.size())); return true; } case EV_EEMR_INCOMPLETE: return true; default: UT_ASSERT(0); return true; } return false; }