diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index 8acb8248..2e86428c 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -365,6 +365,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) gClient->SetQuitIntro(true); } // Fall through to other events + case WM_CHAR: case WM_KEYUP : case WM_LBUTTONUP : case WM_RBUTTONUP : diff --git a/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp b/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp index 1bd0c886..50bff0d3 100644 --- a/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp +++ b/Sources/Plasma/FeatureLib/pfConsole/pfConsole.cpp @@ -828,9 +828,9 @@ void pfConsole::IHandleKey( plKeyEventMsg *msg ) { fWorkingCursor = 0; } - else + else if (msg->GetKeyChar() != nil) { - key = plKeyboardDevice::KeyEventToChar( msg ); + key = msg->GetKeyChar(); // do they want to go into help mode? if( !fPythonMode && key == L'?' && fWorkingCursor == 0 ) { diff --git a/Sources/Plasma/FeatureLib/pfConsole/pfConsole.h b/Sources/Plasma/FeatureLib/pfConsole/pfConsole.h index 98275967..239c55fe 100644 --- a/Sources/Plasma/FeatureLib/pfConsole/pfConsole.h +++ b/Sources/Plasma/FeatureLib/pfConsole/pfConsole.h @@ -95,7 +95,6 @@ class pfConsole : public hsKeyedObject pfConsoleEngine *fEngine; void IHandleKey( plKeyEventMsg *msg ); - char IKeyEventToChar( plKeyEventMsg *msg ); static UInt32 fConsoleTextColor; static pfConsole *fTheConsole; diff --git a/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp b/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp index 210c6ec4..cde1e260 100644 --- a/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp +++ b/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp @@ -60,10 +60,7 @@ pfGUIEditBoxMod::pfGUIEditBoxMod() fFirstHalfExitKeyPushed = false; fSpecialCaptureKeyEventMode = false; fBuffer = 0; - fLastDeadKey = 0; SetBufferSize( 128 ); - - SetupDeadKeyConverter(); } pfGUIEditBoxMod::~pfGUIEditBoxMod() @@ -71,61 +68,6 @@ pfGUIEditBoxMod::~pfGUIEditBoxMod() delete [] fBuffer; } -void pfGUIEditBoxMod::SetupDeadKeyConverter() -{ - int i,j; - for (i=0; i<255; i++) - for (j=0; j<255; j++) - fDeadKeyConverter[i][j] = 0L; - - // we are adding 100 to the indexes because some of these chars have a negative index for some reason - fDeadKeyConverter['^'+100]['a'] = L'â'; - fDeadKeyConverter['^'+100]['e'] = L'ê'; - fDeadKeyConverter['^'+100]['i'] = L'î'; - fDeadKeyConverter['^'+100]['o'] = L'ô'; - fDeadKeyConverter['^'+100]['u'] = L'û'; - fDeadKeyConverter['^'+100]['A'] = L'Â'; - fDeadKeyConverter['^'+100]['E'] = L'Ê'; - fDeadKeyConverter['^'+100]['I'] = L'Î'; - fDeadKeyConverter['^'+100]['O'] = L'Ô'; - fDeadKeyConverter['^'+100]['U'] = L'Û'; - - fDeadKeyConverter['¨'+100]['a'] = L'ä'; - fDeadKeyConverter['¨'+100]['e'] = L'ë'; - fDeadKeyConverter['¨'+100]['i'] = L'ï'; - fDeadKeyConverter['¨'+100]['o'] = L'ö'; - fDeadKeyConverter['¨'+100]['u'] = L'ü'; - fDeadKeyConverter['¨'+100]['A'] = L'Ä'; - fDeadKeyConverter['¨'+100]['E'] = L'Ë'; - fDeadKeyConverter['¨'+100]['I'] = L'Ï'; - fDeadKeyConverter['¨'+100]['O'] = L'Ö'; - fDeadKeyConverter['¨'+100]['U'] = L'Ü'; - - fDeadKeyConverter['´'+100]['a'] = L'á'; - fDeadKeyConverter['´'+100]['e'] = L'é'; - fDeadKeyConverter['´'+100]['i'] = L'í'; - fDeadKeyConverter['´'+100]['o'] = L'ó'; - fDeadKeyConverter['´'+100]['u'] = L'ú'; - fDeadKeyConverter['´'+100]['y'] = L'ý'; - fDeadKeyConverter['´'+100]['A'] = L'Á'; - fDeadKeyConverter['´'+100]['E'] = L'É'; - fDeadKeyConverter['´'+100]['I'] = L'Í'; - fDeadKeyConverter['´'+100]['O'] = L'Ó'; - fDeadKeyConverter['´'+100]['U'] = L'Ú'; - fDeadKeyConverter['´'+100]['Y'] = L'Ý'; - - fDeadKeyConverter['`'+100]['a'] = L'à'; - fDeadKeyConverter['`'+100]['e'] = L'è'; - fDeadKeyConverter['`'+100]['i'] = L'ì'; - fDeadKeyConverter['`'+100]['o'] = L'ò'; - fDeadKeyConverter['`'+100]['u'] = L'ù'; - fDeadKeyConverter['`'+100]['A'] = L'À'; - fDeadKeyConverter['`'+100]['E'] = L'È'; - fDeadKeyConverter['`'+100]['I'] = L'Ì'; - fDeadKeyConverter['`'+100]['O'] = L'Ò'; - fDeadKeyConverter['`'+100]['U'] = L'Ù'; -} - //// IEval /////////////////////////////////////////////////////////////////// hsBool pfGUIEditBoxMod::IEval( double secs, hsScalar del, UInt32 dirty ) @@ -288,62 +230,8 @@ hsBool pfGUIEditBoxMod::HandleKeyPress( wchar_t key, UInt8 modifiers ) fIgnoreNextKey = false; return true; } - - if (plKeyboardDevice::KeyIsDeadKey()) - { - if (fLastDeadKey != 0) - { - wchar_t temp = key; // we have two dead keys in a row, print out the old one and store the new one - key = fLastDeadKey; - fLastDeadKey = temp; - } - else - { - fLastDeadKey = key; // store the dead key and don't print it until we get the next char - return true; - } - } int i = wcslen( fBuffer ); - if (fLastDeadKey != 0) // we have a dead key that needs to be added in - { - wchar_t translatedKey = fDeadKeyConverter[(char)fLastDeadKey+100][(char)key]; - if (translatedKey == 0) // no translation possible? - { - // so we need to print the dead key, followed by the typed key - // unless key is a space, then we just type the dead key - if (key == L' ') - { - if (iIHandleKeyEvt( pfGameGUIMgr::kKeyRepeat, pKeyMsg->GetKeyCode(), fModifiers ); - handled |= fGUIManager->IHandleKeyPress( plKeyboardDevice::KeyEventToChar( pKeyMsg ), fModifiers ); + if (pKeyMsg->GetKeyChar()) + handled |= fGUIManager->IHandleKeyPress( pKeyMsg->GetKeyChar(), fModifiers ); } else handled = fGUIManager->IHandleKeyEvt( pfGameGUIMgr::kKeyUp, pKeyMsg->GetKeyCode(), fModifiers ); @@ -765,7 +766,7 @@ hsBool pfGameUIInputInterface::InterpretInputEvent( plInputEventMsg *pMsg ) // also trigger on key-down and we don't want to be taking screen shots when // the user re-binds the screenshot command. // HACK HACK HACK - if ((!handled) && (pKeyMsg->GetKeyDown())) + if ((!handled) && (pKeyMsg->GetKeyDown()) && !pKeyMsg->GetKeyChar()) { const plKeyBinding* keymap = plInputInterfaceMgr::GetInstance()->FindBindingByConsoleCmd("Game.KITakePicture"); if (keymap) diff --git a/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp b/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp index 41c89652..c1a2f548 100644 --- a/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp @@ -889,18 +889,6 @@ void plPythonFileMod::RemoveTarget(plSceneObject* so) void plPythonFileMod::HandleDiscardedKey( plKeyEventMsg *msg ) { - // So OnDefaultKeyCaught takes two parameters: the key character pressed and a boolean saying up or down - wchar_t keyChar = plKeyboardDevice::KeyEventToChar( msg ); - - // if the caps lock is down then reverse upper and lowercase - if ( msg->GetCapsLockKeyDown() ) - { - if ( std::islower(keyChar,std::locale()) ) - keyChar = std::toupper(keyChar,std::locale()); - else - keyChar = std::tolower(keyChar,std::locale()); - } - if (!fPyFunctionInstances[kfunc_OnDefaultKeyCaught]) return; @@ -909,7 +897,7 @@ void plPythonFileMod::HandleDiscardedKey( plKeyEventMsg *msg ) PyObject* retVal = PyObject_CallMethod( fPyFunctionInstances[ kfunc_OnDefaultKeyCaught ], fFunctionNames[ kfunc_OnDefaultKeyCaught ], "ciiiii", - keyChar, + msg->GetKeyChar(), (int)msg->GetKeyDown(), (int)msg->GetRepeat(), (int)msg->GetShiftKeyDown(), diff --git a/Sources/Plasma/NucleusLib/pnInputCore/plOSMsg.h b/Sources/Plasma/NucleusLib/pnInputCore/plOSMsg.h index aceed278..e483bf4d 100644 --- a/Sources/Plasma/NucleusLib/pnInputCore/plOSMsg.h +++ b/Sources/Plasma/NucleusLib/pnInputCore/plOSMsg.h @@ -52,6 +52,7 @@ enum plOSMsg SYSKEYUP = WM_SYSKEYUP, M_BUTTONDN = WM_MBUTTONDOWN, M_BUTTONUP = WM_MBUTTONUP, + CHAR_MSG = WM_CHAR, }; diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp index 6f467b35..05df204d 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp @@ -52,7 +52,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com plKeyboardDevice* plKeyboardDevice::fInstance = nil; bool plKeyboardDevice::fKeyboardState[256]; hsBool plKeyboardDevice::fIgnoreCapsLock = false; -hsBool plKeyboardDevice::fKeyIsDeadKey = false; plKeyboardDevice::plKeyboardDevice() : fShiftKeyDown(false), @@ -148,7 +147,7 @@ void plKeyboardDevice::Shutdown() { } -void plKeyboardDevice::HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDown, hsBool bKeyRepeat) +void plKeyboardDevice::HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDown, hsBool bKeyRepeat, wchar_t c) { // update the internal keyboard state unsigned int keyCode = (unsigned int)key; @@ -177,6 +176,7 @@ void plKeyboardDevice::HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDo // send a key event... plKeyEventMsg* pMsg = TRACKED_NEW plKeyEventMsg; + pMsg->SetKeyChar( c ); pMsg->SetKeyCode( key ); pMsg->SetKeyDown( bKeyDown ); pMsg->SetShiftKeyDown( fShiftKeyDown ); @@ -199,50 +199,6 @@ void plKeyboardDevice::HandleWindowActivate(bool bActive, HWND hWnd) } -//// KeyEventToChar ////////////////////////////////////////////////////////// -// Translate a Plasma key event to an actual char -wchar_t plKeyboardDevice::KeyEventToChar( plKeyEventMsg *msg ) -{ - unsigned int code = msg->GetKeyCode(); - wchar_t c = 0; - unsigned char kbState[256]; - wchar_t buffer[256]; - unsigned int scanCode; - int retVal; - - buffer[0] = 0; - - // let windows translate everything for us! - scanCode = MapVirtualKeyW(code, 0); - GetKeyboardState(kbState); - if (fIgnoreCapsLock) - kbState[KEY_CAPSLOCK] = 0; // clear the caps lock key - retVal = ToUnicode(code, scanCode, kbState, (wchar_t*)buffer, 256, 0); - if (retVal == -1) - { - // It's a stored dead key. - c = 0; - fKeyIsDeadKey = true; - } - else if (retVal == 0) - // Invalid crap - c = 0; - else if (retVal == 1) - { - // Exactly one good character - fKeyIsDeadKey = false; - c = buffer[0]; - } - else if (retVal >= 2) - { - fKeyIsDeadKey = !fKeyIsDeadKey; - if (!fKeyIsDeadKey) - c = buffer[0]; - } - - return c; -} - // // diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h index 6fffe7bc..03039d91 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h @@ -57,7 +57,7 @@ public: UInt32 GetFlags() { return fFlags; } void SetFlags(UInt32 f) { fFlags = f; } - virtual void HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDown, hsBool bKeyRepeat) {;} + virtual void HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDown, hsBool bKeyRepeat, wchar_t c = nil) {;} virtual void HandleMouseEvent(plOSMsg message, plMouseState state) {;} virtual void HandleWindowActivate(bool bActive, HWND hWnd) {;} virtual hsBool MsgReceive(plMessage* msg) {return false;} @@ -79,7 +79,6 @@ class plKeyboardDevice : public plInputDevice static bool fKeyboardState[256]; // virtual key code is the index, bool is whether it is down or not static hsBool fIgnoreCapsLock; // set if we want it to ignore this key when translating characters (i.e. for chatting) - static hsBool fKeyIsDeadKey; // the key we just got was a dead key, store the value if you're a text input object static plKeyboardDevice* fInstance; void InitKeyboardMaps(); @@ -100,19 +99,15 @@ public: void SetControlMode(int i) { fControlMode = i; } const char* GetInputName() { return "keyboard"; } - void HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDown, hsBool bKeyRepeat); + void HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDown, hsBool bKeyRepeat, wchar_t c = nil); virtual void HandleWindowActivate(bool bActive, HWND hWnd); virtual hsBool IsCapsLockKeyOn(); virtual void Shutdown(); static hsBool IgnoreCapsLock() { return fIgnoreCapsLock; } static void IgnoreCapsLock(hsBool ignore) { fIgnoreCapsLock = ignore; } - - static hsBool KeyIsDeadKey() { return fKeyIsDeadKey; } static plKeyboardDevice* GetInstance() { return fInstance; } - - static wchar_t KeyEventToChar( plKeyEventMsg *msg ); }; class plPlate; diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputInterface.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputInterface.cpp index 55c64e63..92c6a89c 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputInterface.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputInterface.cpp @@ -132,6 +132,8 @@ hsBool plInputInterface::ProcessKeyBindings( plInputEventMsg *msg ) plKeyEventMsg *keyMsg = plKeyEventMsg::ConvertNoRef( msg ); if( keyMsg == nil ) return false; + if ( keyMsg->GetKeyChar()) + return false; /// We might have controls that are currently enabled that are triggered in part by diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp index 707fd3cb..20c4ef6e 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp @@ -273,6 +273,21 @@ void plInputManager::HandleWin32ControlEvent(UINT message, WPARAM Wparam, LPARAM fInputDevices[i]->HandleKeyEvent( KEYUP, UntranslateKey((plKeyDef)Wparam, bExtended), false, false ); } break; + case CHAR_MSG: + { + // These are handled by KEYUP/KEYDOWN and should not be sent + // We don't like garbage getting in string fields + if (Wparam == KEY_BACKSPACE || Wparam == 0x0A || Wparam == KEY_ESCAPE || + Wparam == KEY_TAB || Wparam == 0x0D) + break; + + bExtended = Lparam >> 24 & 1; + hsBool bRepeat = ((Lparam >> 29) & 0xf) != 0; + bool down = !(Lparam >> 31); + for (int i=0; iHandleKeyEvent( CHAR_MSG, (plKeyDef)-1, down, bRepeat, (wchar_t)Wparam ); + } + break; case MOUSEWHEEL: { plMouseEventMsg* pMsg = TRACKED_NEW plMouseEventMsg; diff --git a/Sources/Plasma/PubUtilLib/plMessage/plInputEventMsg.h b/Sources/Plasma/PubUtilLib/plMessage/plInputEventMsg.h index c2731c14..69e8584e 100644 --- a/Sources/Plasma/PubUtilLib/plMessage/plInputEventMsg.h +++ b/Sources/Plasma/PubUtilLib/plMessage/plInputEventMsg.h @@ -109,6 +109,7 @@ public: class plKeyEventMsg : public plInputEventMsg { protected: + wchar_t fKeyChar; plKeyDef fKeyCode; hsBool fKeyDown; hsBool fCapsLockKeyDown; @@ -128,6 +129,7 @@ public: CLASSNAME_REGISTER( plKeyEventMsg ); GETINTERFACE_ANY( plKeyEventMsg, plInputEventMsg ); + void SetKeyChar(wchar_t key) { fKeyChar = key; } void SetKeyCode(plKeyDef w) { fKeyCode = w; } void SetKeyDown(hsBool b) { fKeyDown = b; } void SetShiftKeyDown(hsBool b) { fShiftKeyDown = b; } @@ -135,6 +137,7 @@ public: void SetCapsLockKeyDown(hsBool b) { fCapsLockKeyDown = b; } void SetRepeat(hsBool b) { fRepeat = b; } + wchar_t GetKeyChar() { return fKeyChar; } plKeyDef GetKeyCode() { return fKeyCode; } hsBool GetKeyDown() { return fKeyDown; } hsBool GetShiftKeyDown() { return fShiftKeyDown; }