diff options
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 12 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 4 | ||||
| -rw-r--r-- | indra/llwindow/llwindow.h | 4 | ||||
| -rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 69 | ||||
| -rw-r--r-- | indra/llwindow/llwindowmacosx.h | 5 | ||||
| -rw-r--r-- | indra/media_plugins/webkit/media_plugin_webkit.cpp | 117 | ||||
| -rw-r--r-- | indra/newview/llviewermedia.cpp | 12 | ||||
| -rw-r--r-- | indra/test_apps/llplugintest/llmediaplugintest.cpp | 4 | ||||
| -rw-r--r-- | install.xml | 4 | 
9 files changed, 152 insertions, 79 deletions
| diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 3d2eaed5c5..adc0b3467d 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -469,7 +469,7 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int  	sendMessage(message);  } -bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers) +bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data)  {  	bool result = true; @@ -526,6 +526,7 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie  		message.setValueS32("key", key_code);  		message.setValue("modifiers", translateModifiers(modifiers)); +		message.setValueLLSD("native_key_data", native_key_data);  		sendMessage(message);  	} @@ -544,12 +545,13 @@ void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)  	sendMessage(message);  } -bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers) +bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data)  {  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event");  	message.setValue("text", text);  	message.setValue("modifiers", translateModifiers(modifiers)); +	message.setValueLLSD("native_key_data", native_key_data);  	sendMessage(message); @@ -680,13 +682,13 @@ LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type)  	// so that we don't expose the llqtwebkit header in viewer code  	switch (target_type)  	{ -	case LinkTargetType::LTT_TARGET_NONE: +	case LLQtWebKit::LTT_TARGET_NONE:  		return LLPluginClassMedia::TARGET_NONE; -	case LinkTargetType::LTT_TARGET_BLANK: +	case LLQtWebKit::LTT_TARGET_BLANK:  		return LLPluginClassMedia::TARGET_BLANK; -	case LinkTargetType::LTT_TARGET_EXTERNAL: +	case LLQtWebKit::LTT_TARGET_EXTERNAL:  		return LLPluginClassMedia::TARGET_EXTERNAL;  	default: diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index ebb9099576..58e91fa0b4 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -114,12 +114,12 @@ public:  		KEY_EVENT_REPEAT  	}EKeyEventType; -	bool keyEvent(EKeyEventType type, int key_code, MASK modifiers); +	bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);  	void scrollEvent(int x, int y, MASK modifiers);  	// Text may be unicode (utf8 encoded) -	bool textInput(const std::string &text, MASK modifiers); +	bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);  	void loadURI(const std::string &uri); diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 127dbf45e0..55b221e716 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -37,6 +37,7 @@  #include "llcoord.h"  #include "llstring.h"  #include "llcursortypes.h" +#include "llsd.h"  class LLSplashScreen;  class LLPreeditor; @@ -162,6 +163,9 @@ public:  	virtual void spawnWebBrowser(const std::string& escaped_url) {};  	static std::vector<std::string> getDynamicFallbackFontList(); +	 +	// Provide native key event data +	virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); }  protected:  	LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index ed62faece6..84105ef126 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -260,6 +260,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,  	mTSMScriptCode = 0;  	mTSMLangCode = 0;  	mPreeditor = NULL; +	mRawKeyEvent = NULL;  	mFSAASamples = fsaa_samples;  	mForceRebuild = FALSE; @@ -2135,10 +2136,11 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  				{  					UInt32 modifiers = 0; +  					// First, process the raw event.  					{ -						EventRef rawEvent; - +						EventRef rawEvent = NULL; +						  						// Get the original event and extract the modifier keys, so we can ignore command-key events.  						if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr)  						{ @@ -2147,6 +2149,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  							// and call this function recursively to handle the raw key event.  							eventHandler (myHandler, rawEvent); +							 +							// save the raw event until we're done processing the unicode input as well. +							mRawKeyEvent = rawEvent;  						}  					} @@ -2200,6 +2205,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  						delete[] buffer;  					} +					mRawKeyEvent = NULL;  					result = err;  				}  				break; @@ -2274,6 +2280,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  			GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);  			GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); +			// save the raw event so getNativeKeyData can use it. +			mRawKeyEvent = event; +  			//			printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers);  			//			fflush(stdout); @@ -2369,6 +2378,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  				result = eventNotHandledErr;  				break;  			} +			 +			mRawKeyEvent = NULL;  		}  		break; @@ -3201,6 +3212,60 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url)  	}  } +LLSD LLWindowMacOSX::getNativeKeyData() +{ +	LLSD result = LLSD::emptyMap(); +	 +	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; +		 +#if 0 +		// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc) +		// cause llsd serialization to create XML that the llsd deserializer won't parse! +		std::string unicode; +		OSStatus err = noErr; +		EventParamType actualType = typeUTF8Text; +		UInt32 actualSize = 0; +		char *buffer = NULL; +		 +		err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL); +		if(err == noErr) +		{ +			// allocate a buffer and get the actual data. +			buffer = new char[actualSize]; +			err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, actualSize, &actualSize, buffer); +			if(err == noErr) +			{ +				unicode.assign(buffer, actualSize); +			} +			delete[] buffer; +		} +		 +		result["unicode"] = unicode; +#endif + +	} + + +	lldebugs << "native key data is: " << result << llendl; +	 +	return result; +} +  BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)  { diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index fbfa07fab4..7f27c64712 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -119,6 +119,10 @@ public:  	static std::vector<std::string> getDynamicFallbackFontList(); +	// Provide native key event data +	/*virtual*/ LLSD getNativeKeyData(); + +  protected:  	LLWindowMacOSX(LLWindowCallbacks* callbacks,  		const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, @@ -208,6 +212,7 @@ protected:  	friend class LLWindowManager;  	static WindowRef sMediaWindow; +	EventRef 	mRawKeyEvent;  }; diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 42d680ade6..54814e5e46 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -473,88 +473,77 @@ private:  	////////////////////////////////////////////////////////////////////////////////  	// -	void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers) +	void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())  	{ -		int llqt_key; -		  		// The incoming values for 'key' will be the ones from indra_constants.h -		// the outgoing values are the ones from llqtwebkit.h +		std::string utf8_text; +		 +		if(key < KEY_SPECIAL) +		{ +			// Low-ascii characters need to get passed through. +			utf8_text = (char)key; +		} +		// Any special-case handling we want to do for particular keys...  		switch((KEY)key)  		{ -			// This is the list that the llqtwebkit implementation actually maps into Qt keys. -//			case KEY_XXX:			llqt_key = LL_DOM_VK_CANCEL;			break; -//			case KEY_XXX:			llqt_key = LL_DOM_VK_HELP;			break; -			case KEY_BACKSPACE:		llqt_key = LL_DOM_VK_BACK_SPACE;		break; -			case KEY_TAB:			llqt_key = LL_DOM_VK_TAB;			break; -//			case KEY_XXX:			llqt_key = LL_DOM_VK_CLEAR;			break; -			case KEY_RETURN:		llqt_key = LL_DOM_VK_RETURN;			break; -			case KEY_PAD_RETURN:	llqt_key = LL_DOM_VK_ENTER;			break; -			case KEY_SHIFT:			llqt_key = LL_DOM_VK_SHIFT;			break; -			case KEY_CONTROL:		llqt_key = LL_DOM_VK_CONTROL;		break; -			case KEY_ALT:			llqt_key = LL_DOM_VK_ALT;			break; -//			case KEY_XXX:			llqt_key = LL_DOM_VK_PAUSE;			break; -			case KEY_CAPSLOCK:		llqt_key = LL_DOM_VK_CAPS_LOCK;		break; -			case KEY_ESCAPE:		llqt_key = LL_DOM_VK_ESCAPE;			break; -			case KEY_PAGE_UP:		llqt_key = LL_DOM_VK_PAGE_UP;		break; -			case KEY_PAGE_DOWN:		llqt_key = LL_DOM_VK_PAGE_DOWN;		break; -			case KEY_END:			llqt_key = LL_DOM_VK_END;			break; -			case KEY_HOME:			llqt_key = LL_DOM_VK_HOME;			break; -			case KEY_LEFT:			llqt_key = LL_DOM_VK_LEFT;			break; -			case KEY_UP:			llqt_key = LL_DOM_VK_UP;				break; -			case KEY_RIGHT:			llqt_key = LL_DOM_VK_RIGHT;			break; -			case KEY_DOWN:			llqt_key = LL_DOM_VK_DOWN;			break; -//			case KEY_XXX:			llqt_key = LL_DOM_VK_PRINTSCREEN;	break; -			case KEY_INSERT:		llqt_key = LL_DOM_VK_INSERT;			break; -			case KEY_DELETE:		llqt_key = LL_DOM_VK_DELETE;			break; -//			case KEY_XXX:			llqt_key = LL_DOM_VK_CONTEXT_MENU;	break; +			// ASCII codes for some standard keys +			case LLQtWebKit::KEY_BACKSPACE:		utf8_text = (char)8;		break; +			case LLQtWebKit::KEY_TAB:			utf8_text = (char)9;		break; +			case LLQtWebKit::KEY_RETURN:		utf8_text = (char)13;		break; +			case LLQtWebKit::KEY_PAD_RETURN:	utf8_text = (char)13;		break; +			case LLQtWebKit::KEY_ESCAPE:		utf8_text = (char)27;		break; -			default: -				if(key < KEY_SPECIAL) -				{ -					// Pass the incoming key through -- it should be regular ASCII, which should be correct for webkit. -					llqt_key = key; -				} -				else -				{ -					// Don't pass through untranslated special keys -- they'll be all wrong. -					llqt_key = 0; -				} +			default:    			break;  		} -//		std::cerr << "keypress, original code = 0x" << std::hex << key << ", converted code = 0x" << std::hex << llqt_key << std::dec << std::endl; +//		std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl; -		if(llqt_key != 0) +		uint32_t native_scan_code = 0; +		uint32_t native_virtual_key = 0; +		uint32_t native_modifiers = 0; +		 +		if(native_key_data.isMap())  		{ -			LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, key_event, llqt_key, modifiers); +			native_scan_code = (uint32_t)(native_key_data["key_code"].asInteger()); +			native_virtual_key = (uint32_t)(native_key_data["char_code"].asInteger()); +			native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());  		} +		 +		LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);  		checkEditState();  	};  	////////////////////////////////////////////////////////////////////////////////  	// -	void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers) -	{ -		LLWString wstr = utf8str_to_wstring(utf8str); +	void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +	{		 +		uint32_t key = LLQtWebKit::KEY_NONE; -		unsigned int i; -		for(i=0; i < wstr.size(); i++) +//		std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl; +		 +		if(utf8str.size() == 1)  		{ -//			std::cerr << "unicode input, code = 0x" << std::hex << (unsigned long)(wstr[i]) << std::dec << std::endl; -			 -			if(wstr[i] == 32) -			{ -				// For some reason, the webkit plugin really wants the space bar to come in through the key-event path, not the unicode path. -				LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, 32, modifiers); -				LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, 32, modifiers); -			} -			else -			{ -				LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i], modifiers); -			} +			// The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character. +			// In this case, use it as the key value. +			key = utf8str[0]; +		} + +		uint32_t native_scan_code = 0; +		uint32_t native_virtual_key = 0; +		uint32_t native_modifiers = 0; +		 +		if(native_key_data.isMap()) +		{ +			native_scan_code = (uint32_t)(native_key_data["key_code"].asInteger()); +			native_virtual_key = (uint32_t)(native_key_data["char_code"].asInteger()); +			native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());  		} +		 +		LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); +		LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);  		checkEditState();  	}; @@ -852,6 +841,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)  				std::string event = message_in.getValue("event");  				S32 key = message_in.getValueS32("key");  				std::string modifiers = message_in.getValue("modifiers"); +				LLSD native_key_data = message_in.getValueLLSD("native_key_data");  				// Treat unknown events as key-up for safety.  				LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP; @@ -864,14 +854,15 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)  					key_event = LLQtWebKit::KE_KEY_REPEAT;  				} -				keyEvent(key_event, key, decodeModifiers(modifiers)); +				keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);  			}  			else if(message_name == "text_event")  			{  				std::string text = message_in.getValue("text");  				std::string modifiers = message_in.getValue("modifiers"); +				LLSD native_key_data = message_in.getValueLLSD("native_key_data"); -				unicodeInput(text, decodeModifiers(modifiers)); +				unicodeInput(text, decodeModifiers(modifiers), native_key_data);  			}  			if(message_name == "edit_cut")  			{ diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 9ced0194a2..ff4f776c1e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -57,6 +57,7 @@  #include "llkeyboard.h"  #include "llmutelist.h"  //#include "llfirstuse.h" +#include "llwindow.h"  #include <boost/bind.hpp>	// for SkinFolder listener  #include <boost/signals2.hpp> @@ -1839,9 +1840,12 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)  		if(!result)  		{ -			result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask); +			 +			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); +			 +			result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data);  			// Since the viewer internal event dispatching doesn't give us key-up events, simulate one here. -			(void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask); +			(void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data);  		}  	} @@ -1859,7 +1863,9 @@ bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)  		if (uni_char >= 32 // discard 'control' characters  			&& uni_char != 127) // SDL thinks this is 'delete' - yuck.  		{ -			mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE)); +			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); +			 +			mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data);  		}  	} diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index d183aac208..0ff53f3e00 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -1169,8 +1169,8 @@ void LLMediaPluginTest::keyboard( int key )  		exit( 0 );  	}; -	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 ); -	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0 ); +	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD()); +	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD());  };  //////////////////////////////////////////////////////////////////////////////// diff --git a/install.xml b/install.xml index 797bde5756..34a7b0ad6c 100644 --- a/install.xml +++ b/install.xml @@ -948,9 +948,9 @@ anguage Infrstructure (CLI) international standard</string>            <key>darwin</key>            <map>              <key>md5sum</key> -            <string>d97d843704514ae1b5f153fab2931920</string> +            <string>02d3d8171fff0c673f900f1d1a53046a</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100120.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100119.tar.bz2</uri>            </map>            <key>linux</key>            <map> | 
