From bd817f6f422991c2653493436c7845e75ea9d855 Mon Sep 17 00:00:00 2001 From: rider Date: Fri, 6 Nov 2015 14:12:30 -0800 Subject: MAINT-5754: Basic keyboard functionality on the Mac. Still incomplete --- indra/llwindow/llopenglview-objc.mm | 45 ++++++++++++++++++++++++---- indra/llwindow/llwindowmacosx-objc.h | 23 ++++++++++++-- indra/llwindow/llwindowmacosx.cpp | 38 ++++++++++++----------- indra/media_plugins/cef/media_plugin_cef.cpp | 41 ++++++++++++++++++------- indra/newview/llappviewer.cpp | 2 +- indra/newview/llviewermedia.cpp | 3 +- indra/newview/llviewerwindow.cpp | 2 +- 7 files changed, 116 insertions(+), 38 deletions(-) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index deb8cb90d8..7bb20240d2 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -42,6 +42,7 @@ return screen; } + - (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint { float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x)); @@ -57,6 +58,24 @@ @end +void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData) +{ + if ([theEvent characters].length) + { + eventData->mCharacter = (wchar_t)[[theEvent characters] characterAtIndex:0]; + } + else + { + eventData->mCharacter = [theEvent keyCode]; + } + eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN; + eventData->mKeyCode = [theEvent keyCode]; + eventData->mKeyModifiers = [theEvent modifierFlags]; + eventData->mScanCode = [theEvent keyCode ]; + eventData->mKeyboardType = 0; +} + + attributedStringInfo getSegments(NSAttributedString *str) { attributedStringInfo segments; @@ -402,11 +421,20 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) keyUp:(NSEvent *)theEvent { - callKeyUp([theEvent keyCode], [theEvent modifierFlags]); + NativeKeyEventData eventData; + + extractKeyDataFromEvent( theEvent, &eventData ); + eventData.mKeyEvent = NativeKeyEventData::KEYUP; + callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]); } - (void) keyDown:(NSEvent *)theEvent { + NativeKeyEventData eventData; + + extractKeyDataFromEvent( theEvent, &eventData ); + eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; + uint keycode = [theEvent keyCode]; // We must not depend on flagsChange event to detect modifier flags changed, // must depend on the modifire flags in the event parameter. @@ -414,7 +442,7 @@ attributedStringInfo getSegments(NSAttributedString *str) // e.g. OS Window for upload something or Input Window... // mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit) mModifiers = [theEvent modifierFlags]; - bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers); + bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers); unichar ch; if (acceptsText && !mMarkedTextAllowed && @@ -435,12 +463,17 @@ attributedStringInfo getSegments(NSAttributedString *str) // Since SL assumes we receive those, we fake it here. if (mModifiers & NSCommandKeyMask && !mHasMarkedText) { - callKeyUp([theEvent keyCode], mModifiers); + eventData.mKeyEvent = NativeKeyEventData::KEYUP; + callKeyUp(&eventData, [theEvent keyCode], mModifiers); } } - (void)flagsChanged:(NSEvent *)theEvent { + NativeKeyEventData eventData; + + extractKeyDataFromEvent( theEvent, &eventData ); + mModifiers = [theEvent modifierFlags]; callModifier([theEvent modifierFlags]); @@ -462,11 +495,13 @@ attributedStringInfo getSegments(NSAttributedString *str) if (mModifiers & mask) { - callKeyDown([theEvent keyCode], 0); + eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; + callKeyDown(&eventData, [theEvent keyCode], 0); } else { - callKeyUp([theEvent keyCode], 0); + eventData.mKeyEvent = NativeKeyEventData::KEYUP; + callKeyUp(&eventData, [theEvent keyCode], 0); } } diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index e6e8f27f53..2455d6aeb9 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -46,6 +46,25 @@ typedef void *CursorRef; typedef void *NSWindowRef; typedef void *GLViewRef; + +struct NativeKeyEventData { + enum EventType { + KEYUNKNOWN, + KEYUP, + KEYDOWN, + KEYCHAR + }; + + EventType mKeyEvent; + uint32_t mKeyCode; + uint32_t mScanCode; + uint32_t mKeyModifiers; + uint32_t mKeyboardType; + wchar_t mCharacter; +}; + +typedef const NativeKeyEventData * NSKeyEventRef; + // These are defined in llappviewermacosx.cpp. bool initViewer(); void handleQuit(); @@ -102,8 +121,8 @@ void setupInputWindow(NSWindowRef window, GLViewRef view); // These are all implemented in llwindowmacosx.cpp. // This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict) -bool callKeyUp(unsigned short key, unsigned int mask); -bool callKeyDown(unsigned short key, unsigned int mask); +bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask); +bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask); void callResetKeys(); bool callUnicodeCallback(wchar_t character, unsigned int mask); void callRightMouseDown(float *pos, unsigned int mask); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 15e054fb5d..2a104c1877 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -47,6 +47,10 @@ extern BOOL gDebugWindowProc; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; +namespace +{ + NSKeyEventRef mRawKeyEvent = NULL; +} // // LLWindowMacOSX // @@ -194,14 +198,20 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, // These functions are used as wrappers for our internal event handling callbacks. // It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow. -bool callKeyUp(unsigned short key, unsigned int mask) +bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask) { - return gKeyboard->handleKeyUp(key, mask); + mRawKeyEvent = event; + bool retVal = gKeyboard->handleKeyUp(key, mask); + mRawKeyEvent = NULL; + return retVal; } -bool callKeyDown(unsigned short key, unsigned int mask) +bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask) { - return gKeyboard->handleKeyDown(key, mask); + mRawKeyEvent = event; + bool retVal = gKeyboard->handleKeyDown(key, mask); + mRawKeyEvent = NULL; + return retVal; } void callResetKeys() @@ -1713,23 +1723,15 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) LLSD LLWindowMacOSX::getNativeKeyData() { LLSD result = LLSD::emptyMap(); -#if 0 +#if 1 if(mRawKeyEvent) { - char char_code = 0; - UInt32 key_code = 0; - UInt32 modifiers = 0; - UInt32 keyboard_type = 0; - - GetEventParameter (mRawKeyEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &char_code); - GetEventParameter (mRawKeyEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code); - GetEventParameter (mRawKeyEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); - GetEventParameter (mRawKeyEvent, kEventParamKeyboardType, typeUInt32, NULL, sizeof(UInt32), NULL, &keyboard_type); - result["char_code"] = (S32)char_code; - result["key_code"] = (S32)key_code; - result["modifiers"] = (S32)modifiers; - result["keyboard_type"] = (S32)keyboard_type; + result["char_code"] = (S32)(mRawKeyEvent)->mCharacter; + result["scan_code"] = (S32)(mRawKeyEvent)->mScanCode; + result["key_code"] = (S32)(mRawKeyEvent->mKeyCode); + result["modifiers"] = (S32)(mRawKeyEvent->mKeyModifiers); + result["keyboard_type"] = (S32)(mRawKeyEvent->mKeyboardType); #if 0 // This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc) diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index bb2270181e..d653aaace9 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -551,6 +551,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) #if LL_DARWIN std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + +#if 0 if (event == "down") { //mLLCEFLib->keyPress(key, true); @@ -562,7 +565,21 @@ void MediaPluginCEF::receiveMessage(const char* message_string) //mLLCEFLib->keyPress(key, false); mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); } - +#else + // Treat unknown events as key-up for safety. + LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP; + if (event == "down") + { + key_event = LLCEFLib::KE_KEY_DOWN; + } + else if (event == "repeat") + { + key_event = LLCEFLib::KE_KEY_REPEAT; + } + + keyEvent(key_event, key, LLCEFLib::KM_MODIFIER_NONE, native_key_data); + +#endif #elif LL_WINDOWS std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); @@ -708,12 +725,20 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: #if LL_DARWIN std::string utf8_text; + uint32_t native_char_code = native_key_data["char_code"].asInteger(); + uint32_t native_scan_code = native_key_data["scan_code"].asInteger(); + uint32_t native_virtual_key = native_key_data["key_code"].asInteger(); + uint32_t native_modifiers = native_key_data["modifiers"].asInteger(); + + + if (key < 128) { - utf8_text = (char)key; + utf8_text = (char)native_virtual_key; } - + switch ((KEY)key) + { case KEY_BACKSPACE: utf8_text = (char)8; break; case KEY_TAB: utf8_text = (char)9; break; @@ -725,16 +750,12 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: break; } - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); - - mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), native_modifiers, native_scan_code, native_virtual_key, native_modifiers); #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); #endif }; @@ -743,7 +764,7 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar { #if LL_DARWIN //mLLCEFLib->keyPress(utf8str[0], true); - mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); + //mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9e80e26e3f..03a8756ac8 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2786,7 +2786,7 @@ bool LLAppViewer::initConfiguration() // gWindowTitle = LLTrans::getString("APP_NAME"); #if LL_DEBUG - gWindowTitle += std::string(" [DEBUG]") + gWindowTitle += std::string(" [DEBUG]"); #endif if (!gArgs.empty()) { diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 0824a7def7..626938f7b5 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1450,7 +1450,8 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url) std::string cookie_name = ""; std::string cookie_value = ""; std::string cookie_path = ""; - if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path)) + if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path) && + media_instance->getMediaPlugin()) { media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6be63ef889..86a90a2c24 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2559,7 +2559,7 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) // We have keyboard focus, and it's not an accelerator if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown()) { - return keyboard_focus->handleKey(key, mask, FALSE); + return keyboard_focus->handleKeyUp(key, mask, FALSE); } else if (key < 0x80) { -- cgit v1.2.3