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 +++++++++++++++--------------- 3 files changed, 81 insertions(+), 25 deletions(-) (limited to 'indra/llwindow') 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) -- cgit v1.2.3