aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llwindow/llwindowwin32.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:11 -0500
committerJacek Antonelli2008-08-15 23:45:11 -0500
commit215f423cbe18fe9ca14a26caef918d303bad28ff (patch)
tree0743442b286216cc8e19aa487c26f4e9345ffd64 /linden/indra/llwindow/llwindowwin32.cpp
parentSecond Life viewer sources 1.18.3.5-RC (diff)
downloadmeta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.zip
meta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.tar.gz
meta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.tar.bz2
meta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.tar.xz
Second Life viewer sources 1.18.4.0-RC
Diffstat (limited to 'linden/indra/llwindow/llwindowwin32.cpp')
-rw-r--r--linden/indra/llwindow/llwindowwin32.cpp197
1 files changed, 160 insertions, 37 deletions
diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp
index 3a41d01..bb99d4c 100644
--- a/linden/indra/llwindow/llwindowwin32.cpp
+++ b/linden/indra/llwindow/llwindowwin32.cpp
@@ -2,6 +2,8 @@
2 * @file llwindowwin32.cpp 2 * @file llwindowwin32.cpp
3 * @brief Platform-dependent implementation of llwindow 3 * @brief Platform-dependent implementation of llwindow
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 7 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 8 *
7 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
@@ -24,6 +26,7 @@
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE. 28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
27 */ 30 */
28 31
29#include "linden_common.h" 32#include "linden_common.h"
@@ -85,11 +88,10 @@ void show_window_creation_error(const char* title)
85//static 88//static
86BOOL LLWindowWin32::sIsClassRegistered = FALSE; 89BOOL LLWindowWin32::sIsClassRegistered = FALSE;
87 90
88BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; /* XXX */ 91BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE;
89BOOL LLWindowWin32::sWinIMEOpened = FALSE; 92HKL LLWindowWin32::sWinInputLocale = 0;
90HKL LLWindowWin32::sWinInputLocale; 93DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE;
91DWORD LLWindowWin32::sWinIMEConversionMode; 94DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC;
92DWORD LLWindowWin32::sWinIMESentenceMode;
93 95
94// The following class LLWinImm delegates Windows IMM APIs. 96// The following class LLWinImm delegates Windows IMM APIs.
95// We need this because some language versions of Windows, 97// We need this because some language versions of Windows,
@@ -107,13 +109,15 @@ public:
107 109
108public: 110public:
109 // Wrappers for IMM API. 111 // Wrappers for IMM API.
110 static BOOL isIME(HKL hkl) { return sTheInstance.mImmIsIME(hkl); } 112 static BOOL isIME(HKL hkl);
111 static HIMC getContext(HWND hwnd) { return sTheInstance.mImmGetContext(hwnd); } 113 static HIMC getContext(HWND hwnd);
112 static BOOL releaseContext(HWND hwnd, HIMC himc) { return sTheInstance.mImmReleaseContext(hwnd, himc); } 114 static BOOL releaseContext(HWND hwnd, HIMC himc);
113 static BOOL getOpenStatus(HIMC himc) { return sTheInstance.mImmGetOpenStatus(himc); } 115 static BOOL getOpenStatus(HIMC himc);
114 static BOOL setOpenStatus(HIMC himc, BOOL status) { return sTheInstance.mImmSetOpenStatus(himc, status); } 116 static BOOL setOpenStatus(HIMC himc, BOOL status);
115 static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) { return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); } 117 static BOOL getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence);
116 static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) { return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); } 118 static BOOL setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence);
119 static BOOL getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);
120 static BOOL setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);
117 121
118private: 122private:
119 LLWinImm(); 123 LLWinImm();
@@ -128,6 +132,8 @@ private:
128 BOOL (WINAPI *mImmSetOpenStatus)(HIMC, BOOL); 132 BOOL (WINAPI *mImmSetOpenStatus)(HIMC, BOOL);
129 BOOL (WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD); 133 BOOL (WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
130 BOOL (WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD); 134 BOOL (WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD);
135 BOOL (WINAPI *mImmGetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
136 BOOL (WINAPI *mImmSetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
131 137
132private: 138private:
133 HMODULE mHImmDll; 139 HMODULE mHImmDll;
@@ -136,8 +142,13 @@ private:
136 142
137LLWinImm LLWinImm::sTheInstance; 143LLWinImm LLWinImm::sTheInstance;
138 144
139LLWinImm::LLWinImm() 145LLWinImm::LLWinImm() : mHImmDll(NULL)
140{ 146{
147 // Check system metrics
148 if ( !GetSystemMetrics( SM_DBCSENABLED ) )
149 return;
150
151
141 mHImmDll = LoadLibraryA("Imm32"); 152 mHImmDll = LoadLibraryA("Imm32");
142 if (mHImmDll != NULL) 153 if (mHImmDll != NULL)
143 { 154 {
@@ -148,13 +159,18 @@ LLWinImm::LLWinImm()
148 mImmSetOpenStatus = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(mHImmDll, "ImmSetOpenStatus"); 159 mImmSetOpenStatus = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(mHImmDll, "ImmSetOpenStatus");
149 mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus"); 160 mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus");
150 mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmSetConversionStatus"); 161 mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmSetConversionStatus");
162 mImmGetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmGetCompositionWindow");
163 mImmSetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmSetCompositionWindow");
164
151 if (mImmIsIME == NULL || 165 if (mImmIsIME == NULL ||
152 mImmGetContext == NULL || 166 mImmGetContext == NULL ||
153 mImmReleaseContext == NULL || 167 mImmReleaseContext == NULL ||
154 mImmGetOpenStatus == NULL || 168 mImmGetOpenStatus == NULL ||
155 mImmSetOpenStatus == NULL || 169 mImmSetOpenStatus == NULL ||
156 mImmGetConversionStatus == NULL || 170 mImmGetConversionStatus == NULL ||
157 mImmSetConversionStatus == NULL) 171 mImmSetConversionStatus == NULL ||
172 mImmGetCompostitionWindow == NULL ||
173 mImmSetCompostitionWindow == NULL)
158 { 174 {
159 // If any of the above API entires are not found, we can't use IMM API. 175 // 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 176 // So, turn off the IMM support. We should log some warning message in
@@ -165,10 +181,96 @@ LLWinImm::LLWinImm()
165 // is one of disadvantages to use static constraction to DLL loading. 181 // is one of disadvantages to use static constraction to DLL loading.
166 FreeLibrary(mHImmDll); 182 FreeLibrary(mHImmDll);
167 mHImmDll = NULL; 183 mHImmDll = NULL;
184
185 // If we unload the library, make sure all the function pointers are cleared
186 mImmIsIME = NULL;
187 mImmGetContext = NULL;
188 mImmReleaseContext = NULL;
189 mImmGetOpenStatus = NULL;
190 mImmSetOpenStatus = NULL;
191 mImmGetConversionStatus = NULL;
192 mImmSetConversionStatus = NULL;
193 mImmGetCompostitionWindow = NULL;
194 mImmSetCompostitionWindow = NULL;
168 } 195 }
169 } 196 }
170} 197}
171 198
199
200// static
201BOOL LLWinImm::isIME(HKL hkl)
202{
203 if ( sTheInstance.mImmIsIME )
204 return sTheInstance.mImmIsIME(hkl);
205 return FALSE;
206}
207
208// static
209HIMC LLWinImm::getContext(HWND hwnd)
210{
211 if ( sTheInstance.mImmGetContext )
212 return sTheInstance.mImmGetContext(hwnd);
213 return 0;
214}
215
216//static
217BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc)
218{
219 if ( sTheInstance.mImmIsIME )
220 return sTheInstance.mImmReleaseContext(hwnd, himc);
221 return FALSE;
222}
223
224// static
225BOOL LLWinImm::getOpenStatus(HIMC himc)
226{
227 if ( sTheInstance.mImmGetOpenStatus )
228 return sTheInstance.mImmGetOpenStatus(himc);
229 return FALSE;
230}
231
232// static
233BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
234{
235 if ( sTheInstance.mImmSetOpenStatus )
236 return sTheInstance.mImmSetOpenStatus(himc, status);
237 return FALSE;
238}
239
240// static
241BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence)
242{
243 if ( sTheInstance.mImmGetConversionStatus )
244 return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence);
245 return FALSE;
246}
247
248// static
249BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence)
250{
251 if ( sTheInstance.mImmSetConversionStatus )
252 return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence);
253 return FALSE;
254}
255
256// static
257BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
258{
259 if ( sTheInstance.mImmGetCompostitionWindow )
260 return sTheInstance.mImmGetCompostitionWindow(himc, form);
261 return FALSE;
262}
263
264// static
265BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
266{
267 if ( sTheInstance.mImmSetCompostitionWindow )
268 return sTheInstance.mImmSetCompostitionWindow(himc, form);
269 return FALSE;
270}
271
272
273// ----------------------------------------------------------------------------------------
172LLWinImm::~LLWinImm() 274LLWinImm::~LLWinImm()
173{ 275{
174 if (mHImmDll != NULL) 276 if (mHImmDll != NULL)
@@ -3222,53 +3324,74 @@ void LLWindowWin32::focusClient()
3222 3324
3223void LLWindowWin32::allowLanguageTextInput(BOOL b) 3325void LLWindowWin32::allowLanguageTextInput(BOOL b)
3224{ 3326{
3225 if (b == sLanguageTextInputAllowed || !LLWinImm::isAvailable()) 3327 if ( !LLWinImm::isAvailable() )
3226 { 3328 {
3227 /* Not actually allowing/disallowing. Do nothing. */
3228 return; 3329 return;
3229 } 3330 }
3230 sLanguageTextInputAllowed = b; 3331 sLanguageTextInputAllowed = b;
3231 3332
3232 if (b) 3333 if (b)
3233 { 3334 {
3234 /* Allowing: Restore the previous IME status, 3335 // Allowing: Restore the previous IME status, so that the user has a feeling that the previous
3235 so that the user has a feeling that the previous 3336 // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
3236 text input continues naturally. Be careful, however, 3337 // using same Input Locale (aka Keyboard Layout).
3237 the IME status is meaningful only during the user keeps 3338 HIMC himc = LLWinImm::getContext(mWindowHandle);
3238 using same Input Locale (aka Keyboard Layout). */ 3339 LLWinImm::setOpenStatus(himc, TRUE);
3239 if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) 3340 if (GetKeyboardLayout(0) == sWinInputLocale && sWinIMEConversionMode != IME_CMODE_RESERVED)
3240 { 3341 {
3241 HIMC himc = LLWinImm::getContext(mWindowHandle);
3242 LLWinImm::setOpenStatus(himc, TRUE);
3243 LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode); 3342 LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
3244 LLWinImm::releaseContext(mWindowHandle, himc); 3343 sWinIMEConversionMode = IME_CMODE_RESERVED; // Set saved state so we won't do this repeatedly
3245 } 3344 }
3345 LLWinImm::releaseContext(mWindowHandle, himc);
3246 } 3346 }
3247 else 3347 else
3248 { 3348 {
3249 /* Disallowing: Turn off the IME so that succeeding 3349 // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
3250 key events bypass IME and come to us directly. 3350 // However, do it after saving the current IME status. We need to restore the status when
3251 However, do it after saving the current IME 3351 // allowing language text input again.
3252 status. We need to restore the status when
3253 allowing language text input again. */
3254 sWinInputLocale = GetKeyboardLayout(0); 3352 sWinInputLocale = GetKeyboardLayout(0);
3255 sWinIMEOpened = LLWinImm::isIME(sWinInputLocale); 3353 if ( LLWinImm::isIME(sWinInputLocale) )
3256 if (sWinIMEOpened)
3257 { 3354 {
3258 HIMC himc = LLWinImm::getContext(mWindowHandle); 3355 HIMC himc = LLWinImm::getContext(mWindowHandle);
3259 sWinIMEOpened = LLWinImm::getOpenStatus(himc); 3356 if ( LLWinImm::getOpenStatus(himc) )
3260 if (sWinIMEOpened)
3261 { 3357 {
3262 LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); 3358 LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
3263 3359
3264 /* We need both ImmSetConversionStatus and ImmSetOpenStatus here 3360 // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
3265 to surely disable IME's keyboard hooking, because Some IME reacts 3361 // keyboard hooking, because Some IME reacts only on the former and some other on the latter...
3266 only on the former and some other on the latter... */
3267 LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); 3362 LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
3268 LLWinImm::setOpenStatus(himc, FALSE); 3363 LLWinImm::setOpenStatus(himc, FALSE);
3269 } 3364 }
3270 LLWinImm::releaseContext(mWindowHandle, himc); 3365 LLWinImm::releaseContext(mWindowHandle, himc);
3366 }
3367 }
3368
3369}
3370
3371
3372// Put the IME window at the right place (near current text input). Point coordinates should be the top of the current text line.
3373void LLWindowWin32::setLanguageTextInput( const LLCoordGL & position )
3374{
3375 if (sLanguageTextInputAllowed && LLWinImm::isAvailable())
3376 {
3377 HIMC himc = LLWinImm::getContext(mWindowHandle);
3378
3379 LLCoordWindow win_pos;
3380 convertCoords( position, &win_pos );
3381
3382 if ( win_pos.mX >= 0 && win_pos.mY >= 0 )
3383 {
3384 COMPOSITIONFORM ime_form;
3385 memset( &ime_form, 0, sizeof(ime_form) );
3386 ime_form.dwStyle = CFS_POINT;
3387 ime_form.ptCurrentPos.x = win_pos.mX;
3388 ime_form.ptCurrentPos.y = win_pos.mY;
3389
3390 LLWinImm::setCompositionWindow( himc, &ime_form );
3271 } 3391 }
3392
3393 LLWinImm::releaseContext(mWindowHandle, himc);
3394
3272 } 3395 }
3273} 3396}
3274 3397