zenilib: zenilib/jni/external/sdl/src/video/windows/SDL_windowskeyboard.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_windowskeyboard.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 #if SDL_VIDEO_DRIVER_WINDOWS
24
25 #include "SDL_windowsvideo.h"
26
27 #include "../../events/SDL_keyboard_c.h"
28 #include "../../events/scancodes_windows.h"
29
30 #include <imm.h>
31 #include <oleauto.h>
32
33 #ifndef SDL_DISABLE_WINDOWS_IME
34 static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
35 static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
36 static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
37 static void IME_Quit(SDL_VideoData *videodata);
38 #endif /* !SDL_DISABLE_WINDOWS_IME */
39
40 #ifndef MAPVK_VK_TO_VSC
41 #define MAPVK_VK_TO_VSC 0
42 #endif
43 #ifndef MAPVK_VSC_TO_VK
44 #define MAPVK_VSC_TO_VK 1
45 #endif
46 #ifndef MAPVK_VK_TO_CHAR
47 #define MAPVK_VK_TO_CHAR 2
48 #endif
49
50 /* Alphabetic scancodes for PC keyboards */
51 void
52 WIN_InitKeyboard(_THIS)
53 {
54 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
55
56 data->ime_com_initialized = SDL_FALSE;
57 data->ime_threadmgr = 0;
58 data->ime_initialized = SDL_FALSE;
59 data->ime_enabled = SDL_FALSE;
60 data->ime_available = SDL_FALSE;
61 data->ime_hwnd_main = 0;
62 data->ime_hwnd_current = 0;
63 data->ime_himc = 0;
64 data->ime_composition[0] = 0;
65 data->ime_readingstring[0] = 0;
66 data->ime_cursor = 0;
67
68 data->ime_candlist = SDL_FALSE;
69 SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates));
70 data->ime_candcount = 0;
71 data->ime_candref = 0;
72 data->ime_candsel = 0;
73 data->ime_candpgsize = 0;
74 data->ime_candlistindexbase = 0;
75 data->ime_candvertical = SDL_TRUE;
76
77 data->ime_dirty = SDL_FALSE;
78 SDL_memset(&data->ime_rect, 0, sizeof(data->ime_rect));
79 SDL_memset(&data->ime_candlistrect, 0, sizeof(data->ime_candlistrect));
80 data->ime_winwidth = 0;
81 data->ime_winheight = 0;
82
83 data->ime_hkl = 0;
84 data->ime_himm32 = 0;
85 data->GetReadingString = 0;
86 data->ShowReadingWindow = 0;
87 data->ImmLockIMC = 0;
88 data->ImmUnlockIMC = 0;
89 data->ImmLockIMCC = 0;
90 data->ImmUnlockIMCC = 0;
91 data->ime_uiless = SDL_FALSE;
92 data->ime_threadmgrex = 0;
93 data->ime_uielemsinkcookie = TF_INVALID_COOKIE;
94 data->ime_alpnsinkcookie = TF_INVALID_COOKIE;
95 data->ime_openmodesinkcookie = TF_INVALID_COOKIE;
96 data->ime_convmodesinkcookie = TF_INVALID_COOKIE;
97 data->ime_uielemsink = 0;
98 data->ime_ippasink = 0;
99
100 WIN_UpdateKeymap();
101
102 SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
103 SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows");
104 SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows");
105 }
106
107 void
108 WIN_UpdateKeymap()
109 {
110 int i;
111 SDL_Scancode scancode;
112 SDL_Keycode keymap[SDL_NUM_SCANCODES];
113
114 SDL_GetDefaultKeymap(keymap);
115
116 for (i = 0; i < SDL_arraysize(windows_scancode_table); i++) {
117 int vk;
118 /* Make sure this scancode is a valid character scancode */
119 scancode = windows_scancode_table[i];
120 if (scancode == SDL_SCANCODE_UNKNOWN ) {
121 continue;
122 }
123
124 /* If this key is one of the non-mappable keys, ignore it */
125 /* Don't allow the number keys right above the qwerty row to translate or the top left key (grave/backquote) */
126 /* Not mapping numbers fixes the French layout, giving numeric keycodes for the number keys, which is the expected behavior */
127 if ((keymap[scancode] & SDLK_SCANCODE_MASK) ||
128 scancode == SDL_SCANCODE_GRAVE ||
129 (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0) ) {
130 continue;
131 }
132
133 vk = MapVirtualKey(i, MAPVK_VSC_TO_VK);
134 if ( vk ) {
135 int ch = (MapVirtualKey( vk, MAPVK_VK_TO_CHAR ) & 0x7FFF);
136 if ( ch ) {
137 if ( ch >= 'A' && ch <= 'Z' ) {
138 keymap[scancode] = SDLK_a + ( ch - 'A' );
139 } else {
140 keymap[scancode] = ch;
141 }
142 }
143 }
144 }
145
146 SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
147 }
148
149 void
150 WIN_QuitKeyboard(_THIS)
151 {
152 #ifndef SDL_DISABLE_WINDOWS_IME
153 IME_Quit((SDL_VideoData *)_this->driverdata);
154 #endif
155 }
156
157 void
158 WIN_StartTextInput(_THIS)
159 {
160 #ifndef SDL_DISABLE_WINDOWS_IME
161 SDL_Window *window = SDL_GetKeyboardFocus();
162 if (window) {
163 HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
164 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
165 SDL_GetWindowSize(window, &videodata->ime_winwidth, &videodata->ime_winheight);
166 IME_Init(videodata, hwnd);
167 IME_Enable(videodata, hwnd);
168 }
169 #endif /* !SDL_DISABLE_WINDOWS_IME */
170 }
171
172 void
173 WIN_StopTextInput(_THIS)
174 {
175 #ifndef SDL_DISABLE_WINDOWS_IME
176 SDL_Window *window = SDL_GetKeyboardFocus();
177 if (window) {
178 HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
179 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
180 IME_Init(videodata, hwnd);
181 IME_Disable(videodata, hwnd);
182 }
183 #endif /* !SDL_DISABLE_WINDOWS_IME */
184 }
185
186 void
187 WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
188 {
189 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
190
191 if (!rect) {
192 SDL_InvalidParamError("rect");
193 return;
194 }
195
196 videodata->ime_rect = *rect;
197 }
198
199 #ifdef SDL_DISABLE_WINDOWS_IME
200
201
202 SDL_bool
203 IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
204 {
205 return SDL_FALSE;
206 }
207
208 void IME_Present(SDL_VideoData *videodata)
209 {
210 }
211
212 #else
213
214 #ifdef __GNUC__
215 #undef DEFINE_GUID
216 #define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
217 DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C);
218 DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
219 DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31);
220 DEFINE_GUID(IID_ITfSource, 0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7);
221 DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
222 DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
223 DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
224 DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E);
225 DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50);
226 DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C);
227 #endif
228
229 #define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
230 #define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
231
232 #define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
233 #define IMEID_VER(id) ((id) & 0xffff0000)
234 #define IMEID_LANG(id) ((id) & 0x0000ffff)
235
236 #define CHT_HKL_DAYI ((HKL)0xE0060404)
237 #define CHT_HKL_NEW_PHONETIC ((HKL)0xE0080404)
238 #define CHT_HKL_NEW_CHANG_JIE ((HKL)0xE0090404)
239 #define CHT_HKL_NEW_QUICK ((HKL)0xE00A0404)
240 #define CHT_HKL_HK_CANTONESE ((HKL)0xE00B0404)
241 #define CHT_IMEFILENAME1 "TINTLGNT.IME"
242 #define CHT_IMEFILENAME2 "CINTLGNT.IME"
243 #define CHT_IMEFILENAME3 "MSTCIPHA.IME"
244 #define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2))
245 #define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3))
246 #define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4))
247 #define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0))
248 #define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1))
249 #define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2))
250 #define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0))
251 #define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0))
252
253 #define CHS_HKL ((HKL)0xE00E0804)
254 #define CHS_IMEFILENAME1 "PINTLGNT.IME"
255 #define CHS_IMEFILENAME2 "MSSCIPYA.IME"
256 #define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1))
257 #define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2))
258 #define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3))
259
260 #define LANG() LOWORD((videodata->ime_hkl))
261 #define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
262 #define SUBLANG() SUBLANGID(LANG())
263
264 static void IME_UpdateInputLocale(SDL_VideoData *videodata);
265 static void IME_ClearComposition(SDL_VideoData *videodata);
266 static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
267 static void IME_SetupAPI(SDL_VideoData *videodata);
268 static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
269 static void IME_SendEditingEvent(SDL_VideoData *videodata);
270 static void IME_DestroyTextures(SDL_VideoData *videodata);
271
272 #define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2)
273 #define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID)))
274
275 static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata);
276 static void UILess_ReleaseSinks(SDL_VideoData *videodata);
277 static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
278 static void UILess_DisableUIUpdates(SDL_VideoData *videodata);
279
280 static void
281 IME_Init(SDL_VideoData *videodata, HWND hwnd)
282 {
283 if (videodata->ime_initialized)
284 return;
285
286 videodata->ime_hwnd_main = hwnd;
287 if (SUCCEEDED(WIN_CoInitialize())) {
288 videodata->ime_com_initialized = SDL_TRUE;
289 CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr);
290 }
291 videodata->ime_initialized = SDL_TRUE;
292 videodata->ime_himm32 = SDL_LoadObject("imm32.dll");
293 if (!videodata->ime_himm32) {
294 videodata->ime_available = SDL_FALSE;
295 return;
296 }
297 videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMC");
298 videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMC");
299 videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMCC");
300 videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMCC");
301
302 IME_SetWindow(videodata, hwnd);
303 videodata->ime_himc = ImmGetContext(hwnd);
304 ImmReleaseContext(hwnd, videodata->ime_himc);
305 if (!videodata->ime_himc) {
306 videodata->ime_available = SDL_FALSE;
307 IME_Disable(videodata, hwnd);
308 return;
309 }
310 videodata->ime_available = SDL_TRUE;
311 IME_UpdateInputLocale(videodata);
312 IME_SetupAPI(videodata);
313 videodata->ime_uiless = UILess_SetupSinks(videodata);
314 IME_UpdateInputLocale(videodata);
315 IME_Disable(videodata, hwnd);
316 }
317
318 static void
319 IME_Enable(SDL_VideoData *videodata, HWND hwnd)
320 {
321 if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
322 return;
323
324 if (!videodata->ime_available) {
325 IME_Disable(videodata, hwnd);
326 return;
327 }
328 if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
329 ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc);
330
331 videodata->ime_enabled = SDL_TRUE;
332 IME_UpdateInputLocale(videodata);
333 UILess_EnableUIUpdates(videodata);
334 }
335
336 static void
337 IME_Disable(SDL_VideoData *videodata, HWND hwnd)
338 {
339 if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
340 return;
341
342 IME_ClearComposition(videodata);
343 if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
344 ImmAssociateContext(videodata->ime_hwnd_current, (HIMC)0);
345
346 videodata->ime_enabled = SDL_FALSE;
347 UILess_DisableUIUpdates(videodata);
348 }
349
350 static void
351 IME_Quit(SDL_VideoData *videodata)
352 {
353 if (!videodata->ime_initialized)
354 return;
355
356 UILess_ReleaseSinks(videodata);
357 if (videodata->ime_hwnd_main)
358 ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc);
359
360 videodata->ime_hwnd_main = 0;
361 videodata->ime_himc = 0;
362 if (videodata->ime_himm32) {
363 SDL_UnloadObject(videodata->ime_himm32);
364 videodata->ime_himm32 = 0;
365 }
366 if (videodata->ime_threadmgr) {
367 videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr);
368 videodata->ime_threadmgr = 0;
369 }
370 if (videodata->ime_com_initialized) {
371 WIN_CoUninitialize();
372 videodata->ime_com_initialized = SDL_FALSE;
373 }
374 IME_DestroyTextures(videodata);
375 videodata->ime_initialized = SDL_FALSE;
376 }
377
378 static void
379 IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd)
380 {
381 DWORD id = 0;
382 HIMC himc = 0;
383 WCHAR buffer[16];
384 WCHAR *s = buffer;
385 DWORD len = 0;
386 INT err = 0;
387 BOOL vertical = FALSE;
388 UINT maxuilen = 0;
389 static OSVERSIONINFOA osversion = {0};
390 if (videodata->ime_uiless)
391 return;
392
393 videodata->ime_readingstring[0] = 0;
394 if (!osversion.dwOSVersionInfoSize) {
395 osversion.dwOSVersionInfoSize = sizeof(osversion);
396 GetVersionExA(&osversion);
397 }
398 id = IME_GetId(videodata, 0);
399 if (!id)
400 return;
401
402 himc = ImmGetContext(hwnd);
403 if (!himc)
404 return;
405
406 if (videodata->GetReadingString) {
407 len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
408 if (len) {
409 if (len > SDL_arraysize(buffer))
410 len = SDL_arraysize(buffer);
411
412 len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
413 }
414 SDL_wcslcpy(videodata->ime_readingstring, s, len);
415 }
416 else {
417 LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
418 LPBYTE p = 0;
419 s = 0;
420 switch (id)
421 {
422 case IMEID_CHT_VER42:
423 case IMEID_CHT_VER43:
424 case IMEID_CHT_VER44:
425 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
426 if (!p)
427 break;
428
429 len = *(DWORD *)(p + 7*4 + 32*4);
430 s = (WCHAR *)(p + 56);
431 break;
432 case IMEID_CHT_VER51:
433 case IMEID_CHT_VER52:
434 case IMEID_CHS_VER53:
435 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
436 if (!p)
437 break;
438
439 p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
440 if (!p)
441 break;
442
443 len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
444 s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
445 break;
446 case IMEID_CHS_VER41:
447 {
448 int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
449 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
450 if (!p)
451 break;
452
453 len = *(DWORD *)(p + 7*4 + 16*2*4);
454 s = (WCHAR *)(p + 6*4 + 16*2*1);
455 }
456 break;
457 case IMEID_CHS_VER42:
458 if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT)
459 break;
460
461 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
462 if (!p)
463 break;
464
465 len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
466 s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
467 break;
468 }
469 if (s) {
470 size_t size = SDL_min((size_t)(len + 1), SDL_arraysize(videodata->ime_readingstring));
471 SDL_wcslcpy(videodata->ime_readingstring, s, size);
472 }
473
474 videodata->ImmUnlockIMCC(lpimc->hPrivate);
475 videodata->ImmUnlockIMC(himc);
476 }
477 ImmReleaseContext(hwnd, himc);
478 IME_SendEditingEvent(videodata);
479 }
480
481 static void
482 IME_InputLangChanged(SDL_VideoData *videodata)
483 {
484 UINT lang = PRIMLANG();
485 IME_UpdateInputLocale(videodata);
486 if (!videodata->ime_uiless)
487 videodata->ime_candlistindexbase = (videodata->ime_hkl == CHT_HKL_DAYI) ? 0 : 1;
488
489 IME_SetupAPI(videodata);
490 if (lang != PRIMLANG()) {
491 IME_ClearComposition(videodata);
492 }
493 }
494
495 static DWORD
496 IME_GetId(SDL_VideoData *videodata, UINT uIndex)
497 {
498 static HKL hklprev = 0;
499 static DWORD dwRet[2] = {0};
500 DWORD dwVerSize = 0;
501 DWORD dwVerHandle = 0;
502 LPVOID lpVerBuffer = 0;
503 LPVOID lpVerData = 0;
504 UINT cbVerData = 0;
505 char szTemp[256];
506 HKL hkl = 0;
507 DWORD dwLang = 0;
508 if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0]))
509 return 0;
510
511 hkl = videodata->ime_hkl;
512 if (hklprev == hkl)
513 return dwRet[uIndex];
514
515 hklprev = hkl;
516 dwLang = ((DWORD_PTR)hkl & 0xffff);
517 if (videodata->ime_uiless && LANG() == LANG_CHT) {
518 dwRet[0] = IMEID_CHT_VER_VISTA;
519 dwRet[1] = 0;
520 return dwRet[0];
521 }
522 if (hkl != CHT_HKL_NEW_PHONETIC
523 && hkl != CHT_HKL_NEW_CHANG_JIE
524 && hkl != CHT_HKL_NEW_QUICK
525 && hkl != CHT_HKL_HK_CANTONESE
526 && hkl != CHS_HKL) {
527 dwRet[0] = dwRet[1] = 0;
528 return dwRet[uIndex];
529 }
530 if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) {
531 dwRet[0] = dwRet[1] = 0;
532 return dwRet[uIndex];
533 }
534 if (!videodata->GetReadingString) {
535 #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
536 if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
537 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
538 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
539 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
540 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) {
541 dwRet[0] = dwRet[1] = 0;
542 return dwRet[uIndex];
543 }
544 #undef LCID_INVARIANT
545 dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
546 if (dwVerSize) {
547 lpVerBuffer = SDL_malloc(dwVerSize);
548 if (lpVerBuffer) {
549 if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) {
550 if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) {
551 #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData)
552 DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
553 dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
554 if ((videodata->GetReadingString) ||
555 ((dwLang == LANG_CHT) && (
556 dwVer == MAKEIMEVERSION(4, 2) ||
557 dwVer == MAKEIMEVERSION(4, 3) ||
558 dwVer == MAKEIMEVERSION(4, 4) ||
559 dwVer == MAKEIMEVERSION(5, 0) ||
560 dwVer == MAKEIMEVERSION(5, 1) ||
561 dwVer == MAKEIMEVERSION(5, 2) ||
562 dwVer == MAKEIMEVERSION(6, 0)))
563 ||
564 ((dwLang == LANG_CHS) && (
565 dwVer == MAKEIMEVERSION(4, 1) ||
566 dwVer == MAKEIMEVERSION(4, 2) ||
567 dwVer == MAKEIMEVERSION(5, 3)))) {
568 dwRet[0] = dwVer | dwLang;
569 dwRet[1] = pVerFixedInfo->dwFileVersionLS;
570 SDL_free(lpVerBuffer);
571 return dwRet[0];
572 }
573 #undef pVerFixedInfo
574 }
575 }
576 }
577 SDL_free(lpVerBuffer);
578 }
579 }
580 dwRet[0] = dwRet[1] = 0;
581 return dwRet[uIndex];
582 }
583
584 static void
585 IME_SetupAPI(SDL_VideoData *videodata)
586 {
587 char ime_file[MAX_PATH + 1];
588 void* hime = 0;
589 HKL hkl = 0;
590 videodata->GetReadingString = 0;
591 videodata->ShowReadingWindow = 0;
592 if (videodata->ime_uiless)
593 return;
594
595 hkl = videodata->ime_hkl;
596 if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0)
597 return;
598
599 hime = SDL_LoadObject(ime_file);
600 if (!hime)
601 return;
602
603 videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
604 SDL_LoadFunction(hime, "GetReadingString");
605 videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
606 SDL_LoadFunction(hime, "ShowReadingWindow");
607
608 if (videodata->ShowReadingWindow) {
609 HIMC himc = ImmGetContext(videodata->ime_hwnd_current);
610 if (himc) {
611 videodata->ShowReadingWindow(himc, FALSE);
612 ImmReleaseContext(videodata->ime_hwnd_current, himc);
613 }
614 }
615 }
616
617 static void
618 IME_SetWindow(SDL_VideoData* videodata, HWND hwnd)
619 {
620 videodata->ime_hwnd_current = hwnd;
621 if (videodata->ime_threadmgr) {
622 struct ITfDocumentMgr *document_mgr = 0;
623 if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) {
624 if (document_mgr)
625 document_mgr->lpVtbl->Release(document_mgr);
626 }
627 }
628 }
629
630 static void
631 IME_UpdateInputLocale(SDL_VideoData *videodata)
632 {
633 static HKL hklprev = 0;
634 videodata->ime_hkl = GetKeyboardLayout(0);
635 if (hklprev == videodata->ime_hkl)
636 return;
637
638 hklprev = videodata->ime_hkl;
639 switch (PRIMLANG()) {
640 case LANG_CHINESE:
641 videodata->ime_candvertical = SDL_TRUE;
642 if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED)
643 videodata->ime_candvertical = SDL_FALSE;
644
645 break;
646 case LANG_JAPANESE:
647 videodata->ime_candvertical = SDL_TRUE;
648 break;
649 case LANG_KOREAN:
650 videodata->ime_candvertical = SDL_FALSE;
651 break;
652 }
653 }
654
655 static void
656 IME_ClearComposition(SDL_VideoData *videodata)
657 {
658 HIMC himc = 0;
659 if (!videodata->ime_initialized)
660 return;
661
662 himc = ImmGetContext(videodata->ime_hwnd_current);
663 if (!himc)
664 return;
665
666 ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
667 if (videodata->ime_uiless)
668 ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR));
669
670 ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
671 ImmReleaseContext(videodata->ime_hwnd_current, himc);
672 SDL_SendEditingText("", 0, 0);
673 }
674
675 static void
676 IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
677 {
678 LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition) - sizeof(videodata->ime_composition[0]));
679 if (length < 0)
680 length = 0;
681
682 length /= sizeof(videodata->ime_composition[0]);
683 videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
684 if (videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) && videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
685 int i;
686 for (i = videodata->ime_cursor + 1; i < length; ++i)
687 videodata->ime_composition[i - 1] = videodata->ime_composition[i];
688
689 --length;
690 }
691 videodata->ime_composition[length] = 0;
692 }
693
694 static void
695 IME_SendInputEvent(SDL_VideoData *videodata)
696 {
697 char *s = 0;
698 s = WIN_StringToUTF8(videodata->ime_composition);
699 SDL_SendKeyboardText(s);
700 SDL_free(s);
701
702 videodata->ime_composition[0] = 0;
703 videodata->ime_readingstring[0] = 0;
704 videodata->ime_cursor = 0;
705 }
706
707 static void
708 IME_SendEditingEvent(SDL_VideoData *videodata)
709 {
710 char *s = 0;
711 WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
712 const size_t size = SDL_arraysize(buffer);
713 buffer[0] = 0;
714 if (videodata->ime_readingstring[0]) {
715 size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
716 SDL_wcslcpy(buffer, videodata->ime_composition, len + 1);
717 SDL_wcslcat(buffer, videodata->ime_readingstring, size);
718 SDL_wcslcat(buffer, &videodata->ime_composition[len], size);
719 }
720 else {
721 SDL_wcslcpy(buffer, videodata->ime_composition, size);
722 }
723 s = WIN_StringToUTF8(buffer);
724 SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0);
725 SDL_free(s);
726 }
727
728 static void
729 IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate)
730 {
731 LPWSTR dst = videodata->ime_candidates[i];
732 *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10));
733 if (videodata->ime_candvertical)
734 *dst++ = TEXT(' ');
735
736 while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i])))
737 *dst++ = *candidate++;
738
739 *dst = (WCHAR)'\0';
740 }
741
742 static void
743 IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata)
744 {
745 LPCANDIDATELIST cand_list = 0;
746 DWORD size = ImmGetCandidateListW(himc, 0, 0, 0);
747 if (size) {
748 cand_list = (LPCANDIDATELIST)SDL_malloc(size);
749 if (cand_list) {
750 size = ImmGetCandidateListW(himc, 0, cand_list, size);
751 if (size) {
752 int i = 0;
753 int j = 0;
754 int page_start = 0;
755 videodata->ime_candsel = cand_list->dwSelection;
756 videodata->ime_candcount = cand_list->dwCount;
757
758 if (LANG() == LANG_CHS && IME_GetId(videodata, 0)) {
759 const UINT maxcandchar = 18;
760 UINT i = 0;
761 UINT cchars = 0;
762
763 for (; i < videodata->ime_candcount; ++i) {
764 UINT len = SDL_wcslen((LPWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i])) + 1;
765 if (len + cchars > maxcandchar) {
766 if (i > cand_list->dwSelection)
767 break;
768
769 page_start = i;
770 cchars = len;
771 }
772 else {
773 cchars += len;
774 }
775 }
776 videodata->ime_candpgsize = i - page_start;
777 }
778 else {
779 videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST);
780 page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize;
781 }
782 SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
783 for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) {
784 LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i]);
785 IME_AddCandidate(videodata, j, candidate);
786 }
787 if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0)))
788 videodata->ime_candsel = -1;
789
790 }
791 SDL_free(cand_list);
792 }
793 }
794 }
795
796 static void
797 IME_ShowCandidateList(SDL_VideoData *videodata)
798 {
799 videodata->ime_dirty = SDL_TRUE;
800 videodata->ime_candlist = SDL_TRUE;
801 IME_DestroyTextures(videodata);
802 IME_SendEditingEvent(videodata);
803 }
804
805 static void
806 IME_HideCandidateList(SDL_VideoData *videodata)
807 {
808 videodata->ime_dirty = SDL_FALSE;
809 videodata->ime_candlist = SDL_FALSE;
810 IME_DestroyTextures(videodata);
811 IME_SendEditingEvent(videodata);
812 }
813
814 SDL_bool
815 IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
816 {
817 SDL_bool trap = SDL_FALSE;
818 HIMC himc = 0;
819 if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled)
820 return SDL_FALSE;
821
822 switch (msg) {
823 case WM_INPUTLANGCHANGE:
824 IME_InputLangChanged(videodata);
825 break;
826 case WM_IME_SETCONTEXT:
827 *lParam = 0;
828 break;
829 case WM_IME_STARTCOMPOSITION:
830 trap = SDL_TRUE;
831 break;
832 case WM_IME_COMPOSITION:
833 trap = SDL_TRUE;
834 himc = ImmGetContext(hwnd);
835 if (*lParam & GCS_RESULTSTR) {
836 IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
837 IME_SendInputEvent(videodata);
838 }
839 if (*lParam & GCS_COMPSTR) {
840 if (!videodata->ime_uiless)
841 videodata->ime_readingstring[0] = 0;
842
843 IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
844 IME_SendEditingEvent(videodata);
845 }
846 ImmReleaseContext(hwnd, himc);
847 break;
848 case WM_IME_ENDCOMPOSITION:
849 videodata->ime_composition[0] = 0;
850 videodata->ime_readingstring[0] = 0;
851 videodata->ime_cursor = 0;
852 SDL_SendEditingText("", 0, 0);
853 break;
854 case WM_IME_NOTIFY:
855 switch (wParam) {
856 case IMN_SETCONVERSIONMODE:
857 case IMN_SETOPENSTATUS:
858 IME_UpdateInputLocale(videodata);
859 break;
860 case IMN_OPENCANDIDATE:
861 case IMN_CHANGECANDIDATE:
862 if (videodata->ime_uiless)
863 break;
864
865 trap = SDL_TRUE;
866 IME_ShowCandidateList(videodata);
867 himc = ImmGetContext(hwnd);
868 if (!himc)
869 break;
870
871 IME_GetCandidateList(himc, videodata);
872 ImmReleaseContext(hwnd, himc);
873 break;
874 case IMN_CLOSECANDIDATE:
875 trap = SDL_TRUE;
876 IME_HideCandidateList(videodata);
877 break;
878 case IMN_PRIVATE:
879 {
880 DWORD dwId = IME_GetId(videodata, 0);
881 IME_GetReadingString(videodata, hwnd);
882 switch (dwId)
883 {
884 case IMEID_CHT_VER42:
885 case IMEID_CHT_VER43:
886 case IMEID_CHT_VER44:
887 case IMEID_CHS_VER41:
888 case IMEID_CHS_VER42:
889 if (*lParam == 1 || *lParam == 2)
890 trap = SDL_TRUE;
891
892 break;
893 case IMEID_CHT_VER50:
894 case IMEID_CHT_VER51:
895 case IMEID_CHT_VER52:
896 case IMEID_CHT_VER60:
897 case IMEID_CHS_VER53:
898 if (*lParam == 16
899 || *lParam == 17
900 || *lParam == 26
901 || *lParam == 27
902 || *lParam == 28)
903 trap = SDL_TRUE;
904 break;
905 }
906 }
907 break;
908 default:
909 trap = SDL_TRUE;
910 break;
911 }
912 break;
913 }
914 return trap;
915 }
916
917 static void
918 IME_CloseCandidateList(SDL_VideoData *videodata)
919 {
920 IME_HideCandidateList(videodata);
921 videodata->ime_candcount = 0;
922 SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
923 }
924
925 static void
926 UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist)
927 {
928 UINT selection = 0;
929 UINT count = 0;
930 UINT page = 0;
931 UINT pgcount = 0;
932 DWORD pgstart = 0;
933 DWORD pgsize = 0;
934 UINT i, j;
935 pcandlist->lpVtbl->GetSelection(pcandlist, &selection);
936 pcandlist->lpVtbl->GetCount(pcandlist, &count);
937 pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page);
938
939 videodata->ime_candsel = selection;
940 videodata->ime_candcount = count;
941 IME_ShowCandidateList(videodata);
942
943 pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount);
944 if (pgcount > 0) {
945 UINT *idxlist = SDL_malloc(sizeof(UINT) * pgcount);
946 if (idxlist) {
947 pcandlist->lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount);
948 pgstart = idxlist[page];
949 if (page < pgcount - 1)
950 pgsize = SDL_min(count, idxlist[page + 1]) - pgstart;
951 else
952 pgsize = count - pgstart;
953
954 SDL_free(idxlist);
955 }
956 }
957 videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST);
958 videodata->ime_candsel = videodata->ime_candsel - pgstart;
959
960 SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
961 for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) {
962 BSTR bstr;
963 if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) {
964 if (bstr) {
965 IME_AddCandidate(videodata, j, bstr);
966 SysFreeString(bstr);
967 }
968 }
969 }
970 if (PRIMLANG() == LANG_KOREAN)
971 videodata->ime_candsel = -1;
972 }
973
974 STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink)
975 {
976 return ++sink->refcount;
977 }
978
979 STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink)
980 {
981 --sink->refcount;
982 if (sink->refcount == 0) {
983 SDL_free(sink);
984 return 0;
985 }
986 return sink->refcount;
987 }
988
989 STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
990 {
991 if (!ppv)
992 return E_INVALIDARG;
993
994 *ppv = 0;
995 if (SDL_IsEqualIID(riid, &IID_IUnknown))
996 *ppv = (IUnknown *)sink;
997 else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink))
998 *ppv = (ITfUIElementSink *)sink;
999
1000 if (*ppv) {
1001 TSFSink_AddRef(sink);
1002 return S_OK;
1003 }
1004 return E_NOINTERFACE;
1005 }
1006
1007 ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId)
1008 {
1009 ITfUIElementMgr *puiem = 0;
1010 ITfUIElement *pelem = 0;
1011 ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex;
1012
1013 if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) {
1014 puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
1015 puiem->lpVtbl->Release(puiem);
1016 }
1017 return pelem;
1018 }
1019
1020 STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
1021 {
1022 ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
1023 ITfReadingInformationUIElement *preading = 0;
1024 ITfCandidateListUIElement *pcandlist = 0;
1025 SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1026 if (!element)
1027 return E_INVALIDARG;
1028
1029 *pbShow = FALSE;
1030 if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
1031 BSTR bstr;
1032 if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
1033 SysFreeString(bstr);
1034 }
1035 preading->lpVtbl->Release(preading);
1036 }
1037 else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
1038 videodata->ime_candref++;
1039 UILess_GetCandidateList(videodata, pcandlist);
1040 pcandlist->lpVtbl->Release(pcandlist);
1041 }
1042 return S_OK;
1043 }
1044
1045 STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId)
1046 {
1047 ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
1048 ITfReadingInformationUIElement *preading = 0;
1049 ITfCandidateListUIElement *pcandlist = 0;
1050 SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1051 if (!element)
1052 return E_INVALIDARG;
1053
1054 if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
1055 BSTR bstr;
1056 if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
1057 WCHAR *s = (WCHAR *)bstr;
1058 SDL_wcslcpy(videodata->ime_readingstring, s, SDL_arraysize(videodata->ime_readingstring));
1059 IME_SendEditingEvent(videodata);
1060 SysFreeString(bstr);
1061 }
1062 preading->lpVtbl->Release(preading);
1063 }
1064 else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
1065 UILess_GetCandidateList(videodata, pcandlist);
1066 pcandlist->lpVtbl->Release(pcandlist);
1067 }
1068 return S_OK;
1069 }
1070
1071 STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId)
1072 {
1073 ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
1074 ITfReadingInformationUIElement *preading = 0;
1075 ITfCandidateListUIElement *pcandlist = 0;
1076 SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1077 if (!element)
1078 return E_INVALIDARG;
1079
1080 if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
1081 videodata->ime_readingstring[0] = 0;
1082 IME_SendEditingEvent(videodata);
1083 preading->lpVtbl->Release(preading);
1084 }
1085 if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
1086 videodata->ime_candref--;
1087 if (videodata->ime_candref == 0)
1088 IME_CloseCandidateList(videodata);
1089
1090 pcandlist->lpVtbl->Release(pcandlist);
1091 }
1092 return S_OK;
1093 }
1094
1095 STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
1096 {
1097 if (!ppv)
1098 return E_INVALIDARG;
1099
1100 *ppv = 0;
1101 if (SDL_IsEqualIID(riid, &IID_IUnknown))
1102 *ppv = (IUnknown *)sink;
1103 else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
1104 *ppv = (ITfInputProcessorProfileActivationSink *)sink;
1105
1106 if (*ppv) {
1107 TSFSink_AddRef(sink);
1108 return S_OK;
1109 }
1110 return E_NOINTERFACE;
1111 }
1112
1113 STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
1114 {
1115 static const GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } };
1116 SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1117 videodata->ime_candlistindexbase = SDL_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1;
1118 if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE))
1119 IME_InputLangChanged((SDL_VideoData *)sink->data);
1120
1121 IME_HideCandidateList(videodata);
1122 return S_OK;
1123 }
1124
1125 static void *vtUIElementSink[] = {
1126 (void *)(UIElementSink_QueryInterface),
1127 (void *)(TSFSink_AddRef),
1128 (void *)(TSFSink_Release),
1129 (void *)(UIElementSink_BeginUIElement),
1130 (void *)(UIElementSink_UpdateUIElement),
1131 (void *)(UIElementSink_EndUIElement)
1132 };
1133
1134 static void *vtIPPASink[] = {
1135 (void *)(IPPASink_QueryInterface),
1136 (void *)(TSFSink_AddRef),
1137 (void *)(TSFSink_Release),
1138 (void *)(IPPASink_OnActivated)
1139 };
1140
1141 static void
1142 UILess_EnableUIUpdates(SDL_VideoData *videodata)
1143 {
1144 ITfSource *source = 0;
1145 if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE)
1146 return;
1147
1148 if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
1149 source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie);
1150 source->lpVtbl->Release(source);
1151 }
1152 }
1153
1154 static void
1155 UILess_DisableUIUpdates(SDL_VideoData *videodata)
1156 {
1157 ITfSource *source = 0;
1158 if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE)
1159 return;
1160
1161 if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
1162 source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
1163 videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE;
1164 source->lpVtbl->Release(source);
1165 }
1166 }
1167
1168 static SDL_bool
1169 UILess_SetupSinks(SDL_VideoData *videodata)
1170 {
1171 TfClientId clientid = 0;
1172 SDL_bool result = SDL_FALSE;
1173 ITfSource *source = 0;
1174 if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex)))
1175 return SDL_FALSE;
1176
1177 if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY)))
1178 return SDL_FALSE;
1179
1180 videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink));
1181 videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink));
1182
1183 videodata->ime_uielemsink->lpVtbl = vtUIElementSink;
1184 videodata->ime_uielemsink->refcount = 1;
1185 videodata->ime_uielemsink->data = videodata;
1186
1187 videodata->ime_ippasink->lpVtbl = vtIPPASink;
1188 videodata->ime_ippasink->refcount = 1;
1189 videodata->ime_ippasink->data = videodata;
1190
1191 if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
1192 if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) {
1193 if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) {
1194 result = SDL_TRUE;
1195 }
1196 }
1197 source->lpVtbl->Release(source);
1198 }
1199 return result;
1200 }
1201
1202 #define SAFE_RELEASE(p) \
1203 { \
1204 if (p) { \
1205 (p)->lpVtbl->Release((p)); \
1206 (p) = 0; \
1207 } \
1208 }
1209
1210 static void
1211 UILess_ReleaseSinks(SDL_VideoData *videodata)
1212 {
1213 ITfSource *source = 0;
1214 if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
1215 source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
1216 source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie);
1217 SAFE_RELEASE(source);
1218 videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex);
1219 SAFE_RELEASE(videodata->ime_threadmgrex);
1220 TSFSink_Release(videodata->ime_uielemsink);
1221 videodata->ime_uielemsink = 0;
1222 TSFSink_Release(videodata->ime_ippasink);
1223 videodata->ime_ippasink = 0;
1224 }
1225 }
1226
1227 static void *
1228 StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height)
1229 {
1230 BITMAPINFO info;
1231 BITMAPINFOHEADER *infoHeader = &info.bmiHeader;
1232 BYTE *bits = NULL;
1233 if (hhbm) {
1234 SDL_zero(info);
1235 infoHeader->biSize = sizeof(BITMAPINFOHEADER);
1236 infoHeader->biWidth = width;
1237 infoHeader->biHeight = -1 * SDL_abs(height);
1238 infoHeader->biPlanes = 1;
1239 infoHeader->biBitCount = 32;
1240 infoHeader->biCompression = BI_RGB;
1241 *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (void **)&bits, 0, 0);
1242 if (*hhbm)
1243 SelectObject(hdc, *hhbm);
1244 }
1245 return bits;
1246 }
1247
1248 static void
1249 StopDrawToBitmap(HDC hdc, HBITMAP *hhbm)
1250 {
1251 if (hhbm && *hhbm) {
1252 DeleteObject(*hhbm);
1253 *hhbm = NULL;
1254 }
1255 }
1256
1257 /* This draws only within the specified area and fills the entire region. */
1258 static void
1259 DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize)
1260 {
1261 /* The case of no pen (PenSize = 0) is automatically taken care of. */
1262 const int penadjust = (int)SDL_floor(pensize / 2.0f - 0.5f);
1263 left += pensize / 2;
1264 top += pensize / 2;
1265 right -= penadjust;
1266 bottom -= penadjust;
1267 Rectangle(hdc, left, top, right, bottom);
1268 }
1269
1270 static void
1271 IME_DestroyTextures(SDL_VideoData *videodata)
1272 {
1273 }
1274
1275 #define SDL_swap(a,b) { \
1276 int c = (a); \
1277 (a) = (b); \
1278 (b) = c; \
1279 }
1280
1281 static void
1282 IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size)
1283 {
1284 int left, top, right, bottom;
1285 SDL_bool ok = SDL_FALSE;
1286 int winw = videodata->ime_winwidth;
1287 int winh = videodata->ime_winheight;
1288
1289 /* Bottom */
1290 left = videodata->ime_rect.x;
1291 top = videodata->ime_rect.y + videodata->ime_rect.h;
1292 right = left + size.cx;
1293 bottom = top + size.cy;
1294 if (right >= winw) {
1295 left -= right - winw;
1296 right = winw;
1297 }
1298 if (bottom < winh)
1299 ok = SDL_TRUE;
1300
1301 /* Top */
1302 if (!ok) {
1303 left = videodata->ime_rect.x;
1304 top = videodata->ime_rect.y - size.cy;
1305 right = left + size.cx;
1306 bottom = videodata->ime_rect.y;
1307 if (right >= winw) {
1308 left -= right - winw;
1309 right = winw;
1310 }
1311 if (top >= 0)
1312 ok = SDL_TRUE;
1313 }
1314
1315 /* Right */
1316 if (!ok) {
1317 left = videodata->ime_rect.x + size.cx;
1318 top = 0;
1319 right = left + size.cx;
1320 bottom = size.cy;
1321 if (right < winw)
1322 ok = SDL_TRUE;
1323 }
1324
1325 /* Left */
1326 if (!ok) {
1327 left = videodata->ime_rect.x - size.cx;
1328 top = 0;
1329 right = videodata->ime_rect.x;
1330 bottom = size.cy;
1331 if (right >= 0)
1332 ok = SDL_TRUE;
1333 }
1334
1335 /* Window too small, show at (0,0) */
1336 if (!ok) {
1337 left = 0;
1338 top = 0;
1339 right = size.cx;
1340 bottom = size.cy;
1341 }
1342
1343 videodata->ime_candlistrect.x = left;
1344 videodata->ime_candlistrect.y = top;
1345 videodata->ime_candlistrect.w = right - left;
1346 videodata->ime_candlistrect.h = bottom - top;
1347 }
1348
1349 static void
1350 IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc)
1351 {
1352 int i, j;
1353 SIZE size = {0};
1354 SIZE candsizes[MAX_CANDLIST];
1355 SIZE maxcandsize = {0};
1356 HBITMAP hbm = NULL;
1357 const int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize);
1358 SDL_bool vertical = videodata->ime_candvertical;
1359
1360 const int listborder = 1;
1361 const int listpadding = 0;
1362 const int listbordercolor = RGB(0xB4, 0xC7, 0xAA);
1363 const int listfillcolor = RGB(255, 255, 255);
1364
1365 const int candborder = 1;
1366 const int candpadding = 0;
1367 const int candmargin = 1;
1368 const COLORREF candbordercolor = RGB(255, 255, 255);
1369 const COLORREF candfillcolor = RGB(255, 255, 255);
1370 const COLORREF candtextcolor = RGB(0, 0, 0);
1371 const COLORREF selbordercolor = RGB(0x84, 0xAC, 0xDD);
1372 const COLORREF selfillcolor = RGB(0xD2, 0xE6, 0xFF);
1373 const COLORREF seltextcolor = RGB(0, 0, 0);
1374 const int horzcandspacing = 5;
1375
1376 HPEN listpen = listborder != 0 ? CreatePen(PS_SOLID, listborder, listbordercolor) : (HPEN)GetStockObject(NULL_PEN);
1377 HBRUSH listbrush = CreateSolidBrush(listfillcolor);
1378 HPEN candpen = candborder != 0 ? CreatePen(PS_SOLID, candborder, candbordercolor) : (HPEN)GetStockObject(NULL_PEN);
1379 HBRUSH candbrush = CreateSolidBrush(candfillcolor);
1380 HPEN selpen = candborder != 0 ? CreatePen(PS_DOT, candborder, selbordercolor) : (HPEN)GetStockObject(NULL_PEN);
1381 HBRUSH selbrush = CreateSolidBrush(selfillcolor);
1382 HFONT font = CreateFont((int)(1 + videodata->ime_rect.h * 0.75f), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("Microsoft Sans Serif"));
1383
1384 SetBkMode(hdc, TRANSPARENT);
1385 SelectObject(hdc, font);
1386
1387 for (i = 0; i < candcount; ++i) {
1388 const WCHAR *s = videodata->ime_candidates[i];
1389 if (!*s)
1390 break;
1391
1392 GetTextExtentPoint32W(hdc, s, SDL_wcslen(s), &candsizes[i]);
1393 maxcandsize.cx = SDL_max(maxcandsize.cx, candsizes[i].cx);
1394 maxcandsize.cy = SDL_max(maxcandsize.cy, candsizes[i].cy);
1395
1396 }
1397 if (vertical) {
1398 size.cx =
1399 (listborder * 2) +
1400 (listpadding * 2) +
1401 (candmargin * 2) +
1402 (candborder * 2) +
1403 (candpadding * 2) +
1404 (maxcandsize.cx)
1405 ;
1406 size.cy =
1407 (listborder * 2) +
1408 (listpadding * 2) +
1409 ((candcount + 1) * candmargin) +
1410 (candcount * candborder * 2) +
1411 (candcount * candpadding * 2) +
1412 (candcount * maxcandsize.cy)
1413 ;
1414 }
1415 else {
1416 size.cx =
1417 (listborder * 2) +
1418 (listpadding * 2) +
1419 ((candcount + 1) * candmargin) +
1420 (candcount * candborder * 2) +
1421 (candcount * candpadding * 2) +
1422 ((candcount - 1) * horzcandspacing);
1423 ;
1424
1425 for (i = 0; i < candcount; ++i)
1426 size.cx += candsizes[i].cx;
1427
1428 size.cy =
1429 (listborder * 2) +
1430 (listpadding * 2) +
1431 (candmargin * 2) +
1432 (candborder * 2) +
1433 (candpadding * 2) +
1434 (maxcandsize.cy)
1435 ;
1436 }
1437
1438 StartDrawToBitmap(hdc, &hbm, size.cx, size.cy);
1439
1440 SelectObject(hdc, listpen);
1441 SelectObject(hdc, listbrush);
1442 DrawRect(hdc, 0, 0, size.cx, size.cy, listborder);
1443
1444 SelectObject(hdc, candpen);
1445 SelectObject(hdc, candbrush);
1446 SetTextColor(hdc, candtextcolor);
1447 SetBkMode(hdc, TRANSPARENT);
1448
1449 for (i = 0; i < candcount; ++i) {
1450 const WCHAR *s = videodata->ime_candidates[i];
1451 int left, top, right, bottom;
1452 if (!*s)
1453 break;
1454
1455 if (vertical) {
1456 left = listborder + listpadding + candmargin;
1457 top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy);
1458 right = size.cx - listborder - listpadding - candmargin;
1459 bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2);
1460 }
1461 else {
1462 left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing);
1463
1464 for (j = 0; j < i; ++j)
1465 left += candsizes[j].cx;
1466
1467 top = listborder + listpadding + candmargin;
1468 right = left + candsizes[i].cx + (candpadding * 2) + (candborder * 2);
1469 bottom = size.cy - listborder - listpadding - candmargin;
1470 }
1471
1472 if (i == videodata->ime_candsel) {
1473 SelectObject(hdc, selpen);
1474 SelectObject(hdc, selbrush);
1475 SetTextColor(hdc, seltextcolor);
1476 }
1477 else {
1478 SelectObject(hdc, candpen);
1479 SelectObject(hdc, candbrush);
1480 SetTextColor(hdc, candtextcolor);
1481 }
1482
1483 DrawRect(hdc, left, top, right, bottom, candborder);
1484 ExtTextOutW(hdc, left + candborder + candpadding, top + candborder + candpadding, 0, NULL, s, SDL_wcslen(s), NULL);
1485 }
1486 StopDrawToBitmap(hdc, &hbm);
1487
1488 DeleteObject(listpen);
1489 DeleteObject(listbrush);
1490 DeleteObject(candpen);
1491 DeleteObject(candbrush);
1492 DeleteObject(selpen);
1493 DeleteObject(selbrush);
1494 DeleteObject(font);
1495
1496 IME_PositionCandidateList(videodata, size);
1497 }
1498
1499 static void
1500 IME_Render(SDL_VideoData *videodata)
1501 {
1502 HDC hdc = CreateCompatibleDC(NULL);
1503
1504 if (videodata->ime_candlist)
1505 IME_RenderCandidateList(videodata, hdc);
1506
1507 DeleteDC(hdc);
1508
1509 videodata->ime_dirty = SDL_FALSE;
1510 }
1511
1512 void IME_Present(SDL_VideoData *videodata)
1513 {
1514 if (videodata->ime_dirty)
1515 IME_Render(videodata);
1516
1517 /* FIXME: Need to show the IME bitmap */
1518 }
1519
1520 #endif /* SDL_DISABLE_WINDOWS_IME */
1521
1522 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
1523
1524 /* vi: set ts=4 sw=4 expandtab: */
TSFSink::data
void * data
Definition: SDL_windowsvideo.h:85
sink
GLsizei GLenum GLboolean sink
Definition: glew.h:4448
SDL_GetDefaultKeymap
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
Definition: SDL_keyboard.c:579
BI_RGB
#define BI_RGB
Definition: SDL_bmp.c:43
RGB
Definition: edid.h:20
LPINPUTCONTEXT2
struct tagINPUTCONTEXT2 * LPINPUTCONTEXT2
MAX_CANDLIST
#define MAX_CANDLIST
Definition: SDL_windowsvideo.h:38
bottom
GLint GLint bottom
Definition: glew.h:7291
s
GLdouble s
Definition: glew.h:1376
ITfUIElement
Definition: SDL_msctf.h:188
INT
typedef INT(WINAPI *PFNWGLGETGPUINFOAMDPROC)(UINT id
SDL_VideoData::ime_uielemsink
TSFSink * ime_uielemsink
Definition: SDL_windowsvideo.h:169
left
GLint left
Definition: glew.h:7291
NULL
#define NULL
Definition: ftobjs.h:61
f
GLclampf f
Definition: glew.h:3390
ITfThreadMgrEx
Definition: SDL_msctf.h:76
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
TSFSink
Definition: SDL_windowsvideo.h:81
ITfDocumentMgr
Definition: SDL_msctf.h:94
SDL_TRUE
Definition: SDL_stdinc.h:119
SDL_VideoData::ime_candcount
DWORD ime_candcount
Definition: SDL_windowsvideo.h:141
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:314
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
TSFSink::lpVtbl
void ** lpVtbl
Definition: SDL_windowsvideo.h:83
j
int32_t j
Definition: e_log.c:102
SDL_VideoData::ime_winheight
int ime_winheight
Definition: SDL_windowsvideo.h:152
height
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
SDL_VideoData::ime_hwnd_main
HWND ime_hwnd_main
Definition: SDL_windowsvideo.h:131
SDLK_SCANCODE_MASK
#define SDLK_SCANCODE_MASK
Definition: SDL_keycode.h:44
tagINPUTCONTEXT2
Definition: SDL_windowsvideo.h:89
ITfUIElementSink
Definition: SDL_msctf.h:109
SDL_GetWindowSize
DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window *window, int *w, int *h)
Get the size of a window&#39;s client area.
Definition: SDL_video.c:1638
TF_INVALID_COOKIE
#define TF_INVALID_COOKIE
Definition: SDL_msctf.h:6
len
GLenum GLsizei len
Definition: glew.h:7035
ITfInputProcessorProfileActivationSink
Definition: SDL_msctf.h:202
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
bits
#define bits
Definition: infblock.c:15
UINT
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
if
if(!yyg->yy_init)
Definition: glslang_lex.cpp:1037
SDL_FALSE
Definition: SDL_stdinc.h:118
SDL_VideoData::ime_openmodesinkcookie
DWORD ime_openmodesinkcookie
Definition: SDL_windowsvideo.h:167
SDL_VideoData::ime_alpnsinkcookie
DWORD ime_alpnsinkcookie
Definition: SDL_windowsvideo.h:166
SDL_Keycode
Sint32 SDL_Keycode
The SDL virtual key representation.
Definition: SDL_keycode.h:42
SDLK_a
Definition: SDL_keycode.h:97
SDL_SCANCODE_GRAVE
Definition: SDL_scancode.h:130
SDL_abs
DECLSPEC int SDLCALL SDL_abs(int x)
Definition: SDL_stdlib.c:169
SDL_config.h
TSFSink::refcount
int refcount
Definition: SDL_windowsvideo.h:84
HDC
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(VOID)
SDL_WindowData
Definition: SDL_androidwindow.h:33
TfClientId
DWORD TfClientId
Definition: SDL_msctf.h:30
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
SDL_VideoData::ime_candlist
SDL_bool ime_candlist
Definition: SDL_windowsvideo.h:139
SDL_VideoData::ime_uielemsinkcookie
DWORD ime_uielemsinkcookie
Definition: SDL_windowsvideo.h:165
SDL_SetKeymap
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
Definition: SDL_keyboard.c:585
buffer
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
SDL_VideoData::ime_rect
SDL_Rect ime_rect
Definition: SDL_windowsvideo.h:149
WIN_StartTextInput
void WIN_StartTextInput(_THIS)
SDL_VideoData::ime_candsel
DWORD ime_candsel
Definition: SDL_windowsvideo.h:143
result
GLuint64EXT * result
Definition: glew.h:12708
dst
GLenum GLenum dst
Definition: glew.h:2396
int
int
Definition: SDL_systhread.c:37
length
GLsizei GLsizei * length
Definition: gl2ext.h:792
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
width
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
WIN_CoInitialize
HRESULT WIN_CoInitialize(void)
SDL_SCANCODE_0
Definition: SDL_scancode.h:90
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_SendKeyboardText
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:784
ITfCandidateListUIElement
Definition: SDL_msctf.h:150
ITfUIElementMgr::lpVtbl
struct ITfUIElementMgrVtbl * lpVtbl
Definition: SDL_msctf.h:128
SDL_VideoData::ime_initialized
SDL_bool ime_initialized
Definition: SDL_windowsvideo.h:128
count
GLint GLsizei count
Definition: gl2ext.h:1011
SDL_LoadObject
DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile)
p
GLfloat GLfloat p
Definition: glew.h:14938
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:245
ITfUIElementMgr
Definition: SDL_msctf.h:126
TF_IPSINK_FLAG_ACTIVE
#define TF_IPSINK_FLAG_ACTIVE
Definition: SDL_msctf.h:7
SDL_VideoData::osversion
SInt32 osversion
Definition: SDL_cocoavideo.h:48
SDL_memset
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: SDL_opengl.h:10449
SDL_VideoData::ime_winwidth
int ime_winwidth
Definition: SDL_windowsvideo.h:151
WIN_StopTextInput
void WIN_StopTextInput(_THIS)
SDL_wcslcat
DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
Definition: SDL_string.c:433
SDL_UnloadObject
DECLSPEC void SDLCALL SDL_UnloadObject(void *handle)
WIN_StringToUTF8
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:41
DEFINE_GUID
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71)
dwFlags
DWORD dwFlags
Definition: SDL_dxjoystick_c.h:93
SDL_malloc
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
SDL_VideoData::ime_candpgsize
UINT ime_candpgsize
Definition: SDL_windowsvideo.h:144
ITfThreadMgrEx::lpVtbl
struct ITfThreadMgrExVtbl * lpVtbl
Definition: SDL_msctf.h:78
SDL_VideoData::ime_candref
DWORD ime_candref
Definition: SDL_windowsvideo.h:142
WIN_InitKeyboard
void WIN_InitKeyboard(_THIS)
SDL_Rect::x
int x
Definition: SDL_rect.h:65
SDL_VideoData::ime_ippasink
TSFSink * ime_ippasink
Definition: SDL_windowsvideo.h:170
WIN_QuitKeyboard
void WIN_QuitKeyboard(_THIS)
SDL_floor
DECLSPEC double SDLCALL SDL_floor(double x)
Definition: SDL_stdlib.c:100
top
GLfloat GLfloat GLfloat top
Definition: glew.h:13816
SDL_SetScancodeName
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
Definition: SDL_keyboard.c:597
SDL_VideoData::ime_enabled
SDL_bool ime_enabled
Definition: SDL_windowsvideo.h:129
FALSE
#define FALSE
Definition: ftobjs.h:57
SDL_VideoData::ime_hkl
HKL ime_hkl
Definition: SDL_windowsvideo.h:154
SDL_Rect::w
int w
Definition: SDL_rect.h:66
SDL_VideoData::ime_convmodesinkcookie
DWORD ime_convmodesinkcookie
Definition: SDL_windowsvideo.h:168
SDL_wcslen
DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr)
Definition: SDL_string.c:403
SDL_VideoData::ime_available
SDL_bool ime_available
Definition: SDL_windowsvideo.h:130
SDL_VideoData::ime_com_initialized
SDL_bool ime_com_initialized
Definition: SDL_windowsvideo.h:126
ITfUIElement::lpVtbl
struct ITfUIElementVtbl * lpVtbl
Definition: SDL_msctf.h:190
LPVOID
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
SDL_VideoData::ime_readingstring
WCHAR ime_readingstring[16]
Definition: SDL_windowsvideo.h:136
SDL_VideoData::ime_dirty
SDL_bool ime_dirty
Definition: SDL_windowsvideo.h:148
ITfSource
Definition: SDL_msctf.h:216
ITfSource::lpVtbl
struct ITfSourceVtbl * lpVtbl
Definition: SDL_msctf.h:218
WIN_CoUninitialize
void WIN_CoUninitialize(void)
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
SDL_SCANCODE_UNKNOWN
Definition: SDL_scancode.h:45
WIN_UpdateKeymap
void WIN_UpdateKeymap(void)
tagINPUTCONTEXT2::hPrivate
HIMCC hPrivate
Definition: SDL_windowsvideo.h:105
WIN_SetTextInputRect
void WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
offset
GLintptr offset
Definition: glew.h:1668
SDL_VideoData::ime_uiless
SDL_bool ime_uiless
Definition: SDL_windowsvideo.h:163
ITfCandidateListUIElement::lpVtbl
struct ITfCandidateListUIElementVtbl * lpVtbl
Definition: SDL_msctf.h:152
windows_scancode_table
static const SDL_Scancode windows_scancode_table[]
Definition: scancodes_windows.h:27
ITfReadingInformationUIElement
Definition: SDL_msctf.h:172
SDL_Rect::h
int h
Definition: SDL_rect.h:66
SDL_Window
Definition: SDL_sysvideo.h:71
SDL_SCANCODE_LGUI
Definition: SDL_scancode.h:331
DWORD
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
ITfReadingInformationUIElement::lpVtbl
struct ITfReadingInformationUIElementVtbl * lpVtbl
Definition: SDL_msctf.h:174
SDL_NUM_SCANCODES
Definition: SDL_scancode.h:395
SDL_VideoData::ime_candvertical
SDL_bool ime_candvertical
Definition: SDL_windowsvideo.h:146
SDL_SCANCODE_1
Definition: SDL_scancode.h:81
SDL_SCANCODE_RGUI
Definition: SDL_scancode.h:335
SDL_VideoData::ime_himm32
void * ime_himm32
Definition: SDL_windowsvideo.h:155
SDL_SCANCODE_APPLICATION
Definition: SDL_scancode.h:210
ITfThreadMgr::lpVtbl
struct ITfThreadMgrVtbl * lpVtbl
Definition: SDL_msctf.h:53
SDL_VideoData
Definition: SDL_androidvideo.h:35
SDL_VideoData::ime_composition
WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE]
Definition: SDL_windowsvideo.h:135
SDL_VideoData::ime_candlistindexbase
int ime_candlistindexbase
Definition: SDL_windowsvideo.h:145
SDL_VideoData::ime_candlistrect
SDL_Rect ime_candlistrect
Definition: SDL_windowsvideo.h:150
SDL_GetKeyboardFocus
DECLSPEC SDL_Window *SDLCALL SDL_GetKeyboardFocus(void)
Get the window which currently has keyboard focus.
Definition: SDL_keyboard.c:603
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
SDL_VideoData::ime_hwnd_current
HWND ime_hwnd_current
Definition: SDL_windowsvideo.h:132
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:99
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:244
i
int i
Definition: pngrutil.c:1377
right
GLfloat right
Definition: glew.h:13816
TF_TMAE_UIELEMENTENABLEDONLY
#define TF_TMAE_UIELEMENTENABLEDONLY
Definition: SDL_msctf.h:8
SDL_VideoData::ime_cursor
int ime_cursor
Definition: SDL_windowsvideo.h:137
SDL_LoadFunction
DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, const char *name)
SDL_windowsvideo.h
source
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
SDL_VideoData::ime_himc
HIMC ime_himc
Definition: SDL_windowsvideo.h:133
SDL_Rect::y
int y
Definition: SDL_rect.h:65
SDL_Scancode
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43
SDL_SendEditingText
int SDL_SendEditingText(const char *text, int start, int length)
Definition: SDL_keyboard.c:807
SDL_VideoData::ime_candidates
WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH]
Definition: SDL_windowsvideo.h:140
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
IME_HandleMessage
SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata)
SDL_TEXTEDITINGEVENT_TEXT_SIZE
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE
Definition: SDL_events.h:188
SDL_VideoData::ime_threadmgrex
struct ITfThreadMgrEx * ime_threadmgrex
Definition: SDL_windowsvideo.h:164
SDL_wcslcpy
DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
Definition: SDL_string.c:417
SDL_VideoData::ime_threadmgr
struct ITfThreadMgr * ime_threadmgr
Definition: SDL_windowsvideo.h:127
BOOL
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC
ITfDocumentMgr::lpVtbl
struct ITfDocumentMgrVtbl * lpVtbl
Definition: SDL_msctf.h:96
size
GLsizei size
Definition: gl2ext.h:1467