diff options
author | Jacek Antonelli | 2008-08-15 23:45:11 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:11 -0500 |
commit | 215f423cbe18fe9ca14a26caef918d303bad28ff (patch) | |
tree | 0743442b286216cc8e19aa487c26f4e9345ffd64 /linden/indra/llwindow/llwindowwin32.cpp | |
parent | Second Life viewer sources 1.18.3.5-RC (diff) | |
download | meta-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.cpp | 197 |
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 |
86 | BOOL LLWindowWin32::sIsClassRegistered = FALSE; | 89 | BOOL LLWindowWin32::sIsClassRegistered = FALSE; |
87 | 90 | ||
88 | BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; /* XXX */ | 91 | BOOL LLWindowWin32::sLanguageTextInputAllowed = TRUE; |
89 | BOOL LLWindowWin32::sWinIMEOpened = FALSE; | 92 | HKL LLWindowWin32::sWinInputLocale = 0; |
90 | HKL LLWindowWin32::sWinInputLocale; | 93 | DWORD LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE; |
91 | DWORD LLWindowWin32::sWinIMEConversionMode; | 94 | DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC; |
92 | DWORD 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 | ||
108 | public: | 110 | public: |
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 | ||
118 | private: | 122 | private: |
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 | ||
132 | private: | 138 | private: |
133 | HMODULE mHImmDll; | 139 | HMODULE mHImmDll; |
@@ -136,8 +142,13 @@ private: | |||
136 | 142 | ||
137 | LLWinImm LLWinImm::sTheInstance; | 143 | LLWinImm LLWinImm::sTheInstance; |
138 | 144 | ||
139 | LLWinImm::LLWinImm() | 145 | LLWinImm::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 | ||
201 | BOOL LLWinImm::isIME(HKL hkl) | ||
202 | { | ||
203 | if ( sTheInstance.mImmIsIME ) | ||
204 | return sTheInstance.mImmIsIME(hkl); | ||
205 | return FALSE; | ||
206 | } | ||
207 | |||
208 | // static | ||
209 | HIMC LLWinImm::getContext(HWND hwnd) | ||
210 | { | ||
211 | if ( sTheInstance.mImmGetContext ) | ||
212 | return sTheInstance.mImmGetContext(hwnd); | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | //static | ||
217 | BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc) | ||
218 | { | ||
219 | if ( sTheInstance.mImmIsIME ) | ||
220 | return sTheInstance.mImmReleaseContext(hwnd, himc); | ||
221 | return FALSE; | ||
222 | } | ||
223 | |||
224 | // static | ||
225 | BOOL LLWinImm::getOpenStatus(HIMC himc) | ||
226 | { | ||
227 | if ( sTheInstance.mImmGetOpenStatus ) | ||
228 | return sTheInstance.mImmGetOpenStatus(himc); | ||
229 | return FALSE; | ||
230 | } | ||
231 | |||
232 | // static | ||
233 | BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) | ||
234 | { | ||
235 | if ( sTheInstance.mImmSetOpenStatus ) | ||
236 | return sTheInstance.mImmSetOpenStatus(himc, status); | ||
237 | return FALSE; | ||
238 | } | ||
239 | |||
240 | // static | ||
241 | BOOL 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 | ||
249 | BOOL 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 | ||
257 | BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) | ||
258 | { | ||
259 | if ( sTheInstance.mImmGetCompostitionWindow ) | ||
260 | return sTheInstance.mImmGetCompostitionWindow(himc, form); | ||
261 | return FALSE; | ||
262 | } | ||
263 | |||
264 | // static | ||
265 | BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) | ||
266 | { | ||
267 | if ( sTheInstance.mImmSetCompostitionWindow ) | ||
268 | return sTheInstance.mImmSetCompostitionWindow(himc, form); | ||
269 | return FALSE; | ||
270 | } | ||
271 | |||
272 | |||
273 | // ---------------------------------------------------------------------------------------- | ||
172 | LLWinImm::~LLWinImm() | 274 | LLWinImm::~LLWinImm() |
173 | { | 275 | { |
174 | if (mHImmDll != NULL) | 276 | if (mHImmDll != NULL) |
@@ -3222,53 +3324,74 @@ void LLWindowWin32::focusClient() | |||
3222 | 3324 | ||
3223 | void LLWindowWin32::allowLanguageTextInput(BOOL b) | 3325 | void 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. | ||
3373 | void 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 | ||