aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llwindow
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:59 -0500
committerJacek Antonelli2008-08-15 23:44:59 -0500
commita408bac29378072fbf36864164149458c978cfcc (patch)
tree67feccf1a5d3816611ba48d6762f86f0f7f4b1f6 /linden/indra/llwindow
parentSecond Life viewer sources 1.17.0.12 (diff)
downloadmeta-impy-a408bac29378072fbf36864164149458c978cfcc.zip
meta-impy-a408bac29378072fbf36864164149458c978cfcc.tar.gz
meta-impy-a408bac29378072fbf36864164149458c978cfcc.tar.bz2
meta-impy-a408bac29378072fbf36864164149458c978cfcc.tar.xz
Second Life viewer sources 1.17.1.0
Diffstat (limited to 'linden/indra/llwindow')
-rw-r--r--linden/indra/llwindow/llwindow.cpp50
-rw-r--r--linden/indra/llwindow/llwindow.h13
-rw-r--r--linden/indra/llwindow/llwindowmacosx.cpp75
-rw-r--r--linden/indra/llwindow/llwindowmacosx.h8
-rw-r--r--linden/indra/llwindow/llwindowsdl.cpp7
-rw-r--r--linden/indra/llwindow/llwindowwin32.cpp172
-rw-r--r--linden/indra/llwindow/llwindowwin32.h11
7 files changed, 325 insertions, 11 deletions
diff --git a/linden/indra/llwindow/llwindow.cpp b/linden/indra/llwindow/llwindow.cpp
index cad1dc4..faa5e61 100644
--- a/linden/indra/llwindow/llwindow.cpp
+++ b/linden/indra/llwindow/llwindow.cpp
@@ -241,7 +241,8 @@ LLWindow::LLWindow(BOOL fullscreen, U32 flags)
241 mIsMouseClipping(FALSE), 241 mIsMouseClipping(FALSE),
242 mSwapMethod(SWAP_METHOD_UNDEFINED), 242 mSwapMethod(SWAP_METHOD_UNDEFINED),
243 mHideCursorPermanent(FALSE), 243 mHideCursorPermanent(FALSE),
244 mFlags(flags) 244 mFlags(flags),
245 mHighSurrogate(0)
245{ 246{
246 for (U32 i = 0; i < 6; i++) 247 for (U32 i = 0; i < 6; i++)
247 { 248 {
@@ -296,6 +297,53 @@ void LLWindow::setCallbacks(LLWindowCallbacks *callbacks)
296 } 297 }
297} 298}
298 299
300#define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
301#define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400)
302#define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
303
304void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask)
305{
306 // Note that we could discard unpaired surrogates, but I'm
307 // following the Unicode Consortium's recommendation here;
308 // that is, to preserve those unpaired surrogates in UTF-32
309 // values. _To_preserve_ means to pass to the callback in our
310 // context.
311
312 if (mHighSurrogate == 0)
313 {
314 if (UTF16_IS_HIGH_SURROGATE(utf16))
315 {
316 mHighSurrogate = utf16;
317 }
318 else
319 {
320 mCallbacks->handleUnicodeChar(utf16, mask);
321 }
322 }
323 else
324 {
325 if (UTF16_IS_LOW_SURROGATE(utf16))
326 {
327 /* A legal surrogate pair. */
328 mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate, utf16), mask);
329 mHighSurrogate = 0;
330 }
331 else if (UTF16_IS_HIGH_SURROGATE(utf16))
332 {
333 /* Two consecutive high surrogates. */
334 mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
335 mHighSurrogate = utf16;
336 }
337 else
338 {
339 /* A non-low-surrogate preceeded by a high surrogate. */
340 mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
341 mHighSurrogate = 0;
342 mCallbacks->handleUnicodeChar(utf16, mask);
343 }
344 }
345}
346
299// 347//
300// LLSplashScreen 348// LLSplashScreen
301// 349//
diff --git a/linden/indra/llwindow/llwindow.h b/linden/indra/llwindow/llwindow.h
index 2bb49e9..1016bce 100644
--- a/linden/indra/llwindow/llwindow.h
+++ b/linden/indra/llwindow/llwindow.h
@@ -218,6 +218,10 @@ public:
218// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac) 218// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac)
219 virtual void *getPlatformWindow() = 0; 219 virtual void *getPlatformWindow() = 0;
220 220
221 // control platform's Language Text Input mechanisms.
222 virtual void allowLanguageTextInput( BOOL b ) {};
223 virtual void setLanguageTextInput( LLCoordWindow pos ) {};
224
221protected: 225protected:
222 LLWindow(BOOL fullscreen, U32 flags); 226 LLWindow(BOOL fullscreen, U32 flags);
223 virtual ~LLWindow() {} 227 virtual ~LLWindow() {}
@@ -246,6 +250,15 @@ protected:
246 U32 mFlags; 250 U32 mFlags;
247 F32 mJoyAxis[6]; 251 F32 mJoyAxis[6];
248 U8 mJoyButtonState[16]; 252 U8 mJoyButtonState[16];
253 U16 mHighSurrogate;
254
255 // Handle a UTF-16 encoding unit received from keyboard.
256 // Converting the series of UTF-16 encoding units to UTF-32 data,
257 // this method passes the resulting UTF-32 data to mCallback's
258 // handleUnicodeChar. The mask should be that to be passed to the
259 // callback. This method uses mHighSurrogate as a dedicated work
260 // variable.
261 void handleUnicodeUTF16(U16 utf16, MASK mask);
249 262
250 friend class LLWindowManager; 263 friend class LLWindowManager;
251}; 264};
diff --git a/linden/indra/llwindow/llwindowmacosx.cpp b/linden/indra/llwindow/llwindowmacosx.cpp
index 0c5d6ed..021d7a4 100644
--- a/linden/indra/llwindow/llwindowmacosx.cpp
+++ b/linden/indra/llwindow/llwindowmacosx.cpp
@@ -239,6 +239,10 @@ LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width,
239 mNeedsResize = FALSE; 239 mNeedsResize = FALSE;
240 mOverrideAspectRatio = 0.f; 240 mOverrideAspectRatio = 0.f;
241 mMinimized = FALSE; 241 mMinimized = FALSE;
242 mTSMDocument = NULL; // Just in case.
243 mLanguageTextInputAllowed = FALSE;
244 mTSMScriptCode = 0;
245 mTSMLangCode = 0;
242 246
243 // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state. 247 // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state.
244 // Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state. 248 // Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state.
@@ -479,6 +483,29 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
479 483
480 } 484 }
481 485
486 {
487 // Create and initialize our TSM document for language text input.
488 // If an error occured, we can do nothing better than simply ignore it.
489 // mTSMDocument will be kept NULL in case.
490 if (mTSMDocument)
491 {
492 DeactivateTSMDocument(mTSMDocument);
493 DeleteTSMDocument(mTSMDocument);
494 mTSMDocument = NULL;
495 }
496 static InterfaceTypeList types = { kUnicodeDocument };
497 OSErr err = NewTSMDocument(1, types, &mTSMDocument, 0);
498 if (err != noErr)
499 {
500 llwarns << "createContext: couldn't create a TSMDocument (" << err << ")" << llendl;
501 }
502 if (mTSMDocument)
503 {
504 UseInputWindow(mTSMDocument, TRUE);
505 ActivateTSMDocument(mTSMDocument);
506 }
507 }
508
482 if(mContext == NULL) 509 if(mContext == NULL)
483 { 510 {
484 AGLRendererInfo rendererInfo = NULL; 511 AGLRendererInfo rendererInfo = NULL;
@@ -924,6 +951,15 @@ void LLWindowMacOSX::destroyContext()
924 mWindowHandlerRef = NULL; 951 mWindowHandlerRef = NULL;
925 } 952 }
926 953
954 // Cleanup any TSM document we created.
955 if(mTSMDocument != NULL)
956 {
957 llinfos << "destroyContext: deleting TSM document" << llendl;
958 DeactivateTSMDocument(mTSMDocument);
959 DeleteTSMDocument(mTSMDocument);
960 mTSMDocument = NULL;
961 }
962
927 // Close the window 963 // Close the window
928 if(mWindow != NULL) 964 if(mWindow != NULL)
929 { 965 {
@@ -1529,7 +1565,7 @@ void LLWindowMacOSX::flashIcon(F32 seconds)
1529 OSErr err; 1565 OSErr err;
1530 1566
1531 mBounceTime = seconds; 1567 mBounceTime = seconds;
1532 memset(&mBounceRec, sizeof(mBounceRec), 0); 1568 memset(&mBounceRec, 0, sizeof(mBounceRec));
1533 mBounceRec.qType = nmType; 1569 mBounceRec.qType = nmType;
1534 mBounceRec.nmMark = 1; 1570 mBounceRec.nmMark = 1;
1535 err = NMInstall(&mBounceRec); 1571 err = NMInstall(&mBounceRec);
@@ -2241,6 +2277,10 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
2241 switch(evtKind) 2277 switch(evtKind)
2242 { 2278 {
2243 case kEventWindowActivated: 2279 case kEventWindowActivated:
2280 if (mTSMDocument)
2281 {
2282 ActivateTSMDocument(mTSMDocument);
2283 }
2244 mCallbacks->handleFocus(this); 2284 mCallbacks->handleFocus(this);
2245 break; 2285 break;
2246 case kEventWindowDeactivated: 2286 case kEventWindowDeactivated:
@@ -2952,4 +2992,37 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
2952 return int_value; // otherwise return the long value 2992 return int_value; // otherwise return the long value
2953} 2993}
2954 2994
2995void LLWindowMacOSX::allowLanguageTextInput(BOOL b)
2996{
2997 ScriptLanguageRecord script_language;
2998
2999 if (b == mLanguageTextInputAllowed)
3000 {
3001 return;
3002 }
3003 mLanguageTextInputAllowed = b;
3004
3005 if (b)
3006 {
3007 if (mTSMScriptCode != smRoman)
3008 {
3009 script_language.fScript = mTSMScriptCode;
3010 script_language.fLanguage = mTSMLangCode;
3011 SetTextServiceLanguage(&script_language);
3012 }
3013 }
3014 else
3015 {
3016 GetTextServiceLanguage(&script_language);
3017 mTSMScriptCode = script_language.fScript;
3018 mTSMLangCode = script_language.fLanguage;
3019 if (mTSMScriptCode != smRoman)
3020 {
3021 script_language.fScript = smRoman;
3022 script_language.fLanguage = langEnglish;
3023 SetTextServiceLanguage(&script_language);
3024 }
3025 }
3026}
3027
2955#endif // LL_DARWIN 3028#endif // LL_DARWIN
diff --git a/linden/indra/llwindow/llwindowmacosx.h b/linden/indra/llwindow/llwindowmacosx.h
index 63d846e..01b9303 100644
--- a/linden/indra/llwindow/llwindowmacosx.h
+++ b/linden/indra/llwindow/llwindowmacosx.h
@@ -108,6 +108,8 @@ public:
108 /*virtual*/ void *getPlatformWindow(); 108 /*virtual*/ void *getPlatformWindow();
109 /*virtual*/ void bringToFront() {}; 109 /*virtual*/ void bringToFront() {};
110 110
111 /*virtual*/ void allowLanguageTextInput(BOOL b);
112
111protected: 113protected:
112 LLWindowMacOSX( 114 LLWindowMacOSX(
113 char *title, char *name, int x, int y, int width, int height, U32 flags, 115 char *title, char *name, int x, int y, int width, int height, U32 flags,
@@ -183,6 +185,12 @@ protected:
183 NMRec mBounceRec; 185 NMRec mBounceRec;
184 LLTimer mBounceTimer; 186 LLTimer mBounceTimer;
185 187
188 // Imput method management through Text Service Manager.
189 TSMDocumentID mTSMDocument;
190 BOOL mLanguageTextInputAllowed;
191 ScriptCode mTSMScriptCode;
192 LangCode mTSMLangCode;
193
186 friend class LLWindowManager; 194 friend class LLWindowManager;
187}; 195};
188 196
diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp
index a1cdeb3..94111e7 100644
--- a/linden/indra/llwindow/llwindowsdl.cpp
+++ b/linden/indra/llwindow/llwindowsdl.cpp
@@ -42,7 +42,9 @@
42#include "indra_constants.h" 42#include "indra_constants.h"
43 43
44#if LL_GTK 44#if LL_GTK
45extern "C" {
45# include "gtk/gtk.h" 46# include "gtk/gtk.h"
47}
46#endif // LL_GTK 48#endif // LL_GTK
47 49
48#if LL_LINUX 50#if LL_LINUX
@@ -1984,7 +1986,10 @@ void LLWindowSDL::gatherInput()
1984 SDLReallyCaptureInput(TRUE); 1986 SDLReallyCaptureInput(TRUE);
1985 1987
1986 if (event.key.keysym.unicode) 1988 if (event.key.keysym.unicode)
1987 mCallbacks->handleUnicodeChar(event.key.keysym.unicode, gKeyboard->currentMask(FALSE)); 1989 {
1990 handleUnicodeUTF16(event.key.keysym.unicode,
1991 gKeyboard->currentMask(FALSE));
1992 }
1988 break; 1993 break;
1989 1994
1990 case SDL_KEYUP: 1995 case SDL_KEYUP:
diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp
index 2cd1353..0b3cdd4 100644
--- a/linden/indra/llwindow/llwindowwin32.cpp
+++ b/linden/indra/llwindow/llwindowwin32.cpp
@@ -37,6 +37,7 @@
37#include <mapi.h> 37#include <mapi.h>
38#include <process.h> // for _spawn 38#include <process.h> // for _spawn
39#include <shellapi.h> 39#include <shellapi.h>
40#include <Imm.h>
40 41
41// Require DirectInput version 8 42// Require DirectInput version 8
42#define DIRECTINPUT_VERSION 0x0800 43#define DIRECTINPUT_VERSION 0x0800
@@ -84,6 +85,98 @@ void show_window_creation_error(const char* title)
84//static 85//static
85BOOL LLWindowWin32::sIsClassRegistered = FALSE; 86BOOL LLWindowWin32::sIsClassRegistered = FALSE;
86 87
88BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; /* XXX */
89BOOL LLWindowWin32::sWinIMEOpened = FALSE;
90HKL LLWindowWin32::sWinInputLocale;
91DWORD LLWindowWin32::sWinIMEConversionMode;
92DWORD LLWindowWin32::sWinIMESentenceMode;
93
94// The following class LLWinImm delegates Windows IMM APIs.
95// We need this because some language versions of Windows,
96// e.g., US version of Windows XP, doesn't install IMM32.DLL
97// as a default, and we can't link against imm32.lib statically.
98// I believe DLL loading of this type is best suited to do
99// in a static initialization of a class. What I'm not sure is
100// whether it follows the Linden Conding Standard...
101// See http://wiki.secondlife.com/wiki/Coding_standards#Static_Members
102
103class LLWinImm
104{
105public:
106 static bool isAvailable() { return sTheInstance.mHImmDll != NULL; }
107
108public:
109 // Wrappers for IMM API.
110 static BOOL isIME(HKL hkl) { return sTheInstance.mImmIsIME(hkl); }
111 static HIMC getContext(HWND hwnd) { return sTheInstance.mImmGetContext(hwnd); }
112 static BOOL releaseContext(HWND hwnd, HIMC himc) { return sTheInstance.mImmReleaseContext(hwnd, himc); }
113 static BOOL getOpenStatus(HIMC himc) { return sTheInstance.mImmGetOpenStatus(himc); }
114 static BOOL setOpenStatus(HIMC himc, BOOL status) { return sTheInstance.mImmSetOpenStatus(himc, status); }
115 static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) { return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); }
116 static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) { return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); }
117
118private:
119 LLWinImm();
120 ~LLWinImm();
121
122private:
123 // Pointers to IMM API.
124 BOOL (WINAPI *mImmIsIME)(HKL);
125 HIMC (WINAPI *mImmGetContext)(HWND);
126 BOOL (WINAPI *mImmReleaseContext)(HWND, HIMC);
127 BOOL (WINAPI *mImmGetOpenStatus)(HIMC);
128 BOOL (WINAPI *mImmSetOpenStatus)(HIMC, BOOL);
129 BOOL (WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
130 BOOL (WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD);
131
132private:
133 HMODULE mHImmDll;
134 static LLWinImm sTheInstance;
135};
136
137LLWinImm LLWinImm::sTheInstance;
138
139LLWinImm::LLWinImm()
140{
141 mHImmDll = LoadLibraryA("Imm32");
142 if (mHImmDll != NULL)
143 {
144 mImmIsIME = (BOOL (WINAPI *)(HKL)) GetProcAddress(mHImmDll, "ImmIsIME");
145 mImmGetContext = (HIMC (WINAPI *)(HWND)) GetProcAddress(mHImmDll, "ImmGetContext");
146 mImmReleaseContext = (BOOL (WINAPI *)(HWND, HIMC)) GetProcAddress(mHImmDll, "ImmReleaseContext");
147 mImmGetOpenStatus = (BOOL (WINAPI *)(HIMC)) GetProcAddress(mHImmDll, "ImmGetOpenStatus");
148 mImmSetOpenStatus = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(mHImmDll, "ImmSetOpenStatus");
149 mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus");
150 mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmSetConversionStatus");
151 if (mImmIsIME == NULL ||
152 mImmGetContext == NULL ||
153 mImmReleaseContext == NULL ||
154 mImmGetOpenStatus == NULL ||
155 mImmSetOpenStatus == NULL ||
156 mImmGetConversionStatus == NULL ||
157 mImmSetConversionStatus == NULL)
158 {
159 // If any of the above API entires are not found, we can't use IMM API.
160 // So, turn off the IMM support. We should log some warning message in
161 // the case, since it is very unusual; these APIs are available from
162 // the beginning, and all versions of IMM32.DLL should have them all.
163 // Unfortunately, this code may be executed before initialization of
164 // the logging channel (llwarns), and we can't do it here... Yes, this
165 // is one of disadvantages to use static constraction to DLL loading.
166 FreeLibrary(mHImmDll);
167 mHImmDll = NULL;
168 }
169 }
170}
171
172LLWinImm::~LLWinImm()
173{
174 if (mHImmDll != NULL)
175 {
176 FreeLibrary(mHImmDll);
177 mHImmDll = NULL;
178 }
179}
87 180
88 181
89LPDIRECTINPUT8 g_pDI = NULL; 182LPDIRECTINPUT8 g_pDI = NULL;
@@ -111,6 +204,10 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
111 // Initialize the keyboard 204 // Initialize the keyboard
112 gKeyboard = new LLKeyboardWin32(); 205 gKeyboard = new LLKeyboardWin32();
113 206
207 // Initialize (boot strap) the Language text input management,
208 // based on the system's (user's) default settings.
209 allowLanguageTextInput(FALSE);
210
114 GLuint pixel_format; 211 GLuint pixel_format;
115 WNDCLASS wc; 212 WNDCLASS wc;
116 DWORD dw_ex_style; 213 DWORD dw_ex_style;
@@ -347,7 +444,6 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width,
347 444
348 if (!mWindowHandle) 445 if (!mWindowHandle)
349 { 446 {
350 DestroyWindow(mWindowHandle);
351 OSMessageBox("Window creation error", "Error", OSMB_OK); 447 OSMessageBox("Window creation error", "Error", OSMB_OK);
352 return; 448 return;
353 } 449 }
@@ -1926,6 +2022,15 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
1926 case WM_CHAR: 2022 case WM_CHAR:
1927 // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need 2023 // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
1928 // to figure out how that works. - Doug 2024 // to figure out how that works. - Doug
2025 //
2026 // ... Well, I don't think so.
2027 // How it works is explained in Win32 API document, but WM_UNICHAR didn't work
2028 // as specified at least on Windows XP SP1 Japanese version. I have never used
2029 // it since then, and I'm not sure whether it has been fixed now, but I don't think
2030 // it is worth trying. The good old WM_CHAR works just fine even for supplementary
2031 // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
2032 // by ourselves. It is not that tough. -- Alissa Sabre @ SL
2033 //
1929 // llinfos << "WM_CHAR: " << w_param << llendl; 2034 // llinfos << "WM_CHAR: " << w_param << llendl;
1930 if (gDebugWindowProc) 2035 if (gDebugWindowProc)
1931 { 2036 {
@@ -1933,11 +2038,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
1933 << " key " << S32(w_param) 2038 << " key " << S32(w_param)
1934 << llendl; 2039 << llendl;
1935 } 2040 }
1936 if (window_imp->mCallbacks->handleUnicodeChar(w_param, gKeyboard->currentMask(FALSE))) 2041 // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
1937 { 2042 // we *did* processed the event, so I believe we should not pass it to DefWindowProc...
1938 return 0; 2043 window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE));
1939 } 2044 return 0;
1940 break;
1941 2045
1942 case WM_LBUTTONDOWN: 2046 case WM_LBUTTONDOWN:
1943 { 2047 {
@@ -2971,7 +3075,7 @@ void spawn_web_browser(const char* escaped_url )
2971 char reg_path_str[256]; /* Flawfinder: ignore */ 3075 char reg_path_str[256]; /* Flawfinder: ignore */
2972 snprintf(reg_path_str, sizeof(reg_path_str), "%s\\shell\\open\\command", gURLProtocolWhitelistHandler[i]); /* Flawfinder: ignore */ 3076 snprintf(reg_path_str, sizeof(reg_path_str), "%s\\shell\\open\\command", gURLProtocolWhitelistHandler[i]); /* Flawfinder: ignore */
2973 WCHAR reg_path_wstr[256]; 3077 WCHAR reg_path_wstr[256];
2974 mbstowcs(reg_path_wstr, reg_path_str, 1024); 3078 mbstowcs(reg_path_wstr, reg_path_str, sizeof(reg_path_wstr)/sizeof(reg_path_wstr[0]));
2975 3079
2976 HKEY key; 3080 HKEY key;
2977 WCHAR browser_open_wstr[1024]; 3081 WCHAR browser_open_wstr[1024];
@@ -3102,6 +3206,58 @@ void LLWindowWin32::bringToFront()
3102void LLWindowWin32::focusClient() 3206void LLWindowWin32::focusClient()
3103{ 3207{
3104 SetFocus ( mWindowHandle ); 3208 SetFocus ( mWindowHandle );
3105}; 3209}
3210
3211void LLWindowWin32::allowLanguageTextInput(BOOL b)
3212{
3213 if (b == sLanguageTextInputAllowed || !LLWinImm::isAvailable())
3214 {
3215 /* Not actually allowing/disallowing. Do nothing. */
3216 return;
3217 }
3218 sLanguageTextInputAllowed = b;
3219
3220 if (b)
3221 {
3222 /* Allowing: Restore the previous IME status,
3223 so that the user has a feeling that the previous
3224 text input continues naturally. Be careful, however,
3225 the IME status is meaningful only during the user keeps
3226 using same Input Locale (aka Keyboard Layout). */
3227 if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
3228 {
3229 HIMC himc = LLWinImm::getContext(mWindowHandle);
3230 LLWinImm::setOpenStatus(himc, TRUE);
3231 LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
3232 LLWinImm::releaseContext(mWindowHandle, himc);
3233 }
3234 }
3235 else
3236 {
3237 /* Disallowing: Turn off the IME so that succeeding
3238 key events bypass IME and come to us directly.
3239 However, do it after saving the current IME
3240 status. We need to restore the status when
3241 allowing language text input again. */
3242 sWinInputLocale = GetKeyboardLayout(0);
3243 sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
3244 if (sWinIMEOpened)
3245 {
3246 HIMC himc = LLWinImm::getContext(mWindowHandle);
3247 sWinIMEOpened = LLWinImm::getOpenStatus(himc);
3248 if (sWinIMEOpened)
3249 {
3250 LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
3251
3252 /* We need both ImmSetConversionStatus and ImmSetOpenStatus here
3253 to surely disable IME's keyboard hooking, because Some IME reacts
3254 only on the former and some other on the latter... */
3255 LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
3256 LLWinImm::setOpenStatus(himc, FALSE);
3257 }
3258 LLWinImm::releaseContext(mWindowHandle, himc);
3259 }
3260 }
3261}
3106 3262
3107#endif // LL_WINDOWS 3263#endif // LL_WINDOWS
diff --git a/linden/indra/llwindow/llwindowwin32.h b/linden/indra/llwindow/llwindowwin32.h
index 691c648..0f0cf7c 100644
--- a/linden/indra/llwindow/llwindowwin32.h
+++ b/linden/indra/llwindow/llwindowwin32.h
@@ -106,6 +106,8 @@ public:
106 /*virtual*/ void bringToFront(); 106 /*virtual*/ void bringToFront();
107 /*virtual*/ void focusClient(); 107 /*virtual*/ void focusClient();
108 108
109 /*virtual*/ void allowLanguageTextInput(BOOL b);
110
109protected: 111protected:
110 LLWindowWin32( 112 LLWindowWin32(
111 char *title, char *name, int x, int y, int width, int height, U32 flags, 113 char *title, char *name, int x, int y, int width, int height, U32 flags,
@@ -174,6 +176,15 @@ protected:
174 BOOL mMousePositionModified; 176 BOOL mMousePositionModified;
175 BOOL mInputProcessingPaused; 177 BOOL mInputProcessingPaused;
176 178
179 // The following five variables are for Language Text Input control.
180 // They are all static, since one context is shared by all LLWindowWin32
181 // instances.
182 static BOOL sLanguageTextInputAllowed;
183 static BOOL sWinIMEOpened;
184 static HKL sWinInputLocale;
185 static DWORD sWinIMEConversionMode;
186 static DWORD sWinIMESentenceMode;
187
177 friend class LLWindowManager; 188 friend class LLWindowManager;
178}; 189};
179 190