Large commit with initial reading string support, TSF UILess code, etc.
1.1 --- a/src/video/win32/SDL_win32keyboard.c Tue Aug 03 16:52:10 2010 -0400
1.2 +++ b/src/video/win32/SDL_win32keyboard.c Tue Aug 03 16:57:49 2010 -0400
1.3 @@ -26,8 +26,13 @@
1.4 #include "../../events/SDL_keyboard_c.h"
1.5 #include "../../events/scancodes_win32.h"
1.6
1.7 -#include <msctf.h>
1.8 #include <imm.h>
1.9 +#include <oleauto.h>
1.10 +
1.11 +static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
1.12 +static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
1.13 +static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
1.14 +static void IME_Quit(SDL_VideoData *videodata);
1.15
1.16 #ifndef MAPVK_VK_TO_VSC
1.17 #define MAPVK_VK_TO_VSC 0
1.18 @@ -49,11 +54,6 @@
1.19 82, 79, 80, 81, 75, 76, 77, 71, 72, 73
1.20 };
1.21
1.22 -void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
1.23 -void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
1.24 -void IME_Init(SDL_VideoData *videodata, HWND hwnd);
1.25 -void IME_Quit(SDL_VideoData *videodata);
1.26 -
1.27 void
1.28 WIN_InitKeyboard(_THIS)
1.29 {
1.30 @@ -90,13 +90,32 @@
1.31 data->key_layout = win32_scancode_table;
1.32
1.33 data->ime_com_initialized = SDL_FALSE;
1.34 - data->ime_thread_mgr = 0;
1.35 + data->ime_threadmgr = 0;
1.36 data->ime_initialized = SDL_FALSE;
1.37 data->ime_enabled = SDL_FALSE;
1.38 data->ime_available = SDL_FALSE;
1.39 data->ime_hwnd_main = 0;
1.40 data->ime_hwnd_current = 0;
1.41 data->ime_himc = 0;
1.42 + data->ime_composition[0] = 0;
1.43 + data->ime_readingstring[0] = 0;
1.44 + data->ime_cursor = 0;
1.45 + data->ime_hkl = 0;
1.46 + data->ime_himm32 = 0;
1.47 + data->GetReadingString = 0;
1.48 + data->ShowReadingWindow = 0;
1.49 + data->ImmLockIMC = 0;
1.50 + data->ImmUnlockIMC = 0;
1.51 + data->ImmLockIMCC = 0;
1.52 + data->ImmUnlockIMCC = 0;
1.53 + data->ime_uiless = SDL_FALSE;
1.54 + data->ime_threadmgrex = 0;
1.55 + data->ime_uielemsinkcookie = TF_INVALID_COOKIE;
1.56 + data->ime_alpnsinkcookie = TF_INVALID_COOKIE;
1.57 + data->ime_openmodesinkcookie = TF_INVALID_COOKIE;
1.58 + data->ime_convmodesinkcookie = TF_INVALID_COOKIE;
1.59 + data->ime_uielemsink = 0;
1.60 + data->ime_ippasink = 0;
1.61
1.62 WIN_UpdateKeymap();
1.63
1.64 @@ -144,8 +163,7 @@
1.65 WIN_StartTextInput(_THIS)
1.66 {
1.67 SDL_Window *window = SDL_GetKeyboardFocus();
1.68 - if (window)
1.69 - {
1.70 + if (window) {
1.71 HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
1.72 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
1.73 IME_Init(videodata, hwnd);
1.74 @@ -157,8 +175,7 @@
1.75 WIN_StopTextInput(_THIS)
1.76 {
1.77 SDL_Window *window = SDL_GetKeyboardFocus();
1.78 - if (window)
1.79 - {
1.80 + if (window) {
1.81 HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
1.82 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
1.83 IME_Init(videodata, hwnd);
1.84 @@ -172,19 +189,94 @@
1.85
1.86 }
1.87
1.88 -void
1.89 -IME_Disable(SDL_VideoData *videodata, HWND hwnd)
1.90 +#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
1.91 +#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
1.92 +
1.93 +#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
1.94 +#define IMEID_VER(id) ((id) & 0xffff0000)
1.95 +#define IMEID_LANG(id) ((id) & 0x0000ffff)
1.96 +
1.97 +#define CHT_HKL_DAYI ((HKL)0xE0060404)
1.98 +#define CHT_HKL_NEW_PHONETIC ((HKL)0xE0080404)
1.99 +#define CHT_HKL_NEW_CHANG_JIE ((HKL)0xE0090404)
1.100 +#define CHT_HKL_NEW_QUICK ((HKL)0xE00A0404)
1.101 +#define CHT_HKL_HK_CANTONESE ((HKL)0xE00B0404)
1.102 +#define CHT_IMEFILENAME1 "TINTLGNT.IME"
1.103 +#define CHT_IMEFILENAME2 "CINTLGNT.IME"
1.104 +#define CHT_IMEFILENAME3 "MSTCIPHA.IME"
1.105 +#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2))
1.106 +#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3))
1.107 +#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4))
1.108 +#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0))
1.109 +#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1))
1.110 +#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2))
1.111 +#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0))
1.112 +#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0))
1.113 +
1.114 +#define CHS_HKL ((HKL)0xE00E0804)
1.115 +#define CHS_IMEFILENAME1 "PINTLGNT.IME"
1.116 +#define CHS_IMEFILENAME2 "MSSCIPYA.IME"
1.117 +#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1))
1.118 +#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2))
1.119 +#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3))
1.120 +
1.121 +#define LANG() LOWORD((videodata->ime_hkl))
1.122 +#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
1.123 +#define SUBLANG() SUBLANGID(LANG())
1.124 +
1.125 +static void IME_UpdateInputLocale(SDL_VideoData *videodata);
1.126 +static void IME_ClearComposition(SDL_VideoData *videodata);
1.127 +static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
1.128 +static void IME_SetupAPI(SDL_VideoData *videodata);
1.129 +static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
1.130 +static void IME_SendEditingEvent(SDL_VideoData *videodata);
1.131 +#define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2)
1.132 +#define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID)))
1.133 +
1.134 +static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata);
1.135 +static void UILess_ReleaseSinks(SDL_VideoData *videodata);
1.136 +static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
1.137 +static void UILess_DisableUIUpdates(SDL_VideoData *videodata);
1.138 +
1.139 +static void
1.140 +IME_Init(SDL_VideoData *videodata, HWND hwnd)
1.141 {
1.142 - if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
1.143 + if (videodata->ime_initialized)
1.144 return;
1.145
1.146 - if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
1.147 - ImmAssociateContext(videodata->ime_hwnd_current, NULL);
1.148 + videodata->ime_hwnd_main = hwnd;
1.149 + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
1.150 + videodata->ime_com_initialized = SDL_TRUE;
1.151 + CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, &videodata->ime_threadmgr);
1.152 + }
1.153 + videodata->ime_initialized = SDL_TRUE;
1.154 + videodata->ime_himm32 = LoadLibraryA("imm32.dll");
1.155 + if (!videodata->ime_himm32) {
1.156 + videodata->ime_available = SDL_FALSE;
1.157 + return;
1.158 + }
1.159 + videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmLockIMC");
1.160 + videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMC");
1.161 + videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmLockIMCC");
1.162 + videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMCC");
1.163
1.164 - videodata->ime_enabled = SDL_FALSE;
1.165 + IME_SetWindow(videodata, hwnd);
1.166 + videodata->ime_himc = ImmGetContext(hwnd);
1.167 + ImmReleaseContext(hwnd, videodata->ime_himc);
1.168 + if (!videodata->ime_himc) {
1.169 + videodata->ime_available = SDL_FALSE;
1.170 + IME_Disable(videodata, hwnd);
1.171 + return;
1.172 + }
1.173 + videodata->ime_available = SDL_TRUE;
1.174 + IME_UpdateInputLocale(videodata);
1.175 + IME_SetupAPI(videodata);
1.176 + videodata->ime_uiless = UILess_SetupSinks(videodata);
1.177 + IME_UpdateInputLocale(videodata);
1.178 + IME_Disable(videodata, hwnd);
1.179 }
1.180
1.181 -void
1.182 +static void
1.183 IME_Enable(SDL_VideoData *videodata, HWND hwnd)
1.184 {
1.185 if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
1.186 @@ -198,54 +290,45 @@
1.187 ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc);
1.188
1.189 videodata->ime_enabled = SDL_TRUE;
1.190 + IME_UpdateInputLocale(videodata);
1.191 + UILess_EnableUIUpdates(videodata);
1.192 }
1.193
1.194 -void
1.195 -IME_Init(SDL_VideoData *videodata, HWND hwnd)
1.196 +static void
1.197 +IME_Disable(SDL_VideoData *videodata, HWND hwnd)
1.198 {
1.199 - if (videodata->ime_initialized)
1.200 + if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
1.201 return;
1.202
1.203 - videodata->ime_hwnd_main = hwnd;
1.204 - if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
1.205 - videodata->ime_com_initialized = SDL_TRUE;
1.206 - CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, &videodata->ime_thread_mgr);
1.207 - }
1.208 - videodata->ime_initialized = SDL_TRUE;
1.209 - videodata->ime_hwnd_current = videodata->ime_hwnd_main;
1.210 - if (videodata->ime_thread_mgr) {
1.211 - struct ITfDocumentMgr *document_mgr = 0;
1.212 - if (SUCCEEDED(videodata->ime_thread_mgr->lpVtbl->AssociateFocus(videodata->ime_thread_mgr, hwnd, NULL, &document_mgr))) {
1.213 - if (document_mgr)
1.214 - document_mgr->lpVtbl->Release(document_mgr);
1.215 - }
1.216 - }
1.217 - videodata->ime_himc = ImmGetContext(hwnd);
1.218 - ImmReleaseContext(hwnd, videodata->ime_himc);
1.219 - if (!videodata->ime_himc) {
1.220 - videodata->ime_available = SDL_FALSE;
1.221 - IME_Disable(videodata, hwnd);
1.222 - return;
1.223 - }
1.224 - videodata->ime_available = SDL_TRUE;
1.225 - IME_Disable(videodata, hwnd);
1.226 + IME_ClearComposition(videodata);
1.227 + if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
1.228 + ImmAssociateContext(videodata->ime_hwnd_current, NULL);
1.229 +
1.230 + videodata->ime_enabled = SDL_FALSE;
1.231 + UILess_DisableUIUpdates(videodata);
1.232 }
1.233
1.234 -void
1.235 +static void
1.236 IME_Quit(SDL_VideoData *videodata)
1.237 {
1.238 if (!videodata->ime_initialized)
1.239 return;
1.240
1.241 + UILess_ReleaseSinks(videodata);
1.242 if (videodata->ime_hwnd_main)
1.243 ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc);
1.244
1.245 videodata->ime_hwnd_main = 0;
1.246 videodata->ime_himc = 0;
1.247 - if (videodata->ime_thread_mgr)
1.248 + if (videodata->ime_himm32)
1.249 {
1.250 - videodata->ime_thread_mgr->lpVtbl->Release(videodata->ime_thread_mgr);
1.251 - videodata->ime_thread_mgr = 0;
1.252 + FreeLibrary(videodata->ime_himm32);
1.253 + videodata->ime_himm32 = 0;
1.254 + }
1.255 + if (videodata->ime_threadmgr)
1.256 + {
1.257 + videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr);
1.258 + videodata->ime_threadmgr = 0;
1.259 }
1.260 if (videodata->ime_com_initialized)
1.261 {
1.262 @@ -255,18 +338,384 @@
1.263 videodata->ime_initialized = SDL_FALSE;
1.264 }
1.265
1.266 +static void
1.267 +IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd)
1.268 +{
1.269 + DWORD id = 0;
1.270 + HIMC himc = 0;
1.271 + WCHAR buffer[16];
1.272 + WCHAR *s = buffer;
1.273 + DWORD len = 0;
1.274 + DWORD err = 0;
1.275 + BOOL vertical = FALSE;
1.276 + UINT maxuilen = 0;
1.277 + static OSVERSIONINFOA osversion = {0};
1.278 + if (videodata->ime_uiless)
1.279 + return;
1.280 +
1.281 + videodata->ime_readingstring[0] = 0;
1.282 + if (!osversion.dwOSVersionInfoSize)
1.283 + {
1.284 + osversion.dwOSVersionInfoSize = sizeof(osversion);
1.285 + GetVersionExA(&osversion);
1.286 + }
1.287 + id = IME_GetId(videodata, 0);
1.288 + if (!id)
1.289 + return;
1.290 +
1.291 + himc = ImmGetContext(hwnd);
1.292 + if (!himc)
1.293 + return;
1.294 +
1.295 + if (videodata->GetReadingString)
1.296 + {
1.297 + len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
1.298 + if (len)
1.299 + {
1.300 + if (len > SDL_arraysize(buffer))
1.301 + len = SDL_arraysize(buffer);
1.302 +
1.303 + len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
1.304 + }
1.305 + SDL_wcslcpy(videodata->ime_readingstring, s, len);
1.306 + }
1.307 + else
1.308 + {
1.309 + LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
1.310 + LPBYTE p = 0;
1.311 + s = 0;
1.312 + switch (id)
1.313 + {
1.314 + case IMEID_CHT_VER42:
1.315 + case IMEID_CHT_VER43:
1.316 + case IMEID_CHT_VER44:
1.317 + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
1.318 + if (!p)
1.319 + break;
1.320 +
1.321 + len = *(DWORD *)(p + 7*4 + 32*4);
1.322 + s = (WCHAR *)(p + 56);
1.323 + break;
1.324 + case IMEID_CHT_VER51:
1.325 + case IMEID_CHT_VER52:
1.326 + case IMEID_CHS_VER53:
1.327 + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
1.328 + if (!p)
1.329 + break;
1.330 +
1.331 + p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
1.332 + if (!p)
1.333 + break;
1.334 +
1.335 + len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
1.336 + s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
1.337 + break;
1.338 + case IMEID_CHS_VER41:
1.339 + {
1.340 + int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
1.341 + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
1.342 + if (!p)
1.343 + break;
1.344 +
1.345 + len = *(DWORD *)(p + 7*4 + 16*2*4);
1.346 + s = (WCHAR *)(p + 6*4 + 16*2*1);
1.347 + }
1.348 + break;
1.349 + case IMEID_CHS_VER42:
1.350 + if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT)
1.351 + break;
1.352 +
1.353 + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
1.354 + if (!p)
1.355 + break;
1.356 +
1.357 + len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
1.358 + s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
1.359 + break;
1.360 + }
1.361 + if (s)
1.362 + {
1.363 + SDL_wcslcpy(videodata->ime_readingstring, s, len + 1);
1.364 + }
1.365 + videodata->ImmUnlockIMCC(lpimc->hPrivate);
1.366 + videodata->ImmUnlockIMC(himc);
1.367 + }
1.368 + ImmReleaseContext(hwnd, himc);
1.369 + IME_SendEditingEvent(videodata);
1.370 +}
1.371 +
1.372 +static void
1.373 +IME_InputLangChanged(SDL_VideoData *videodata)
1.374 +{
1.375 + UINT uLang = PRIMLANG();
1.376 + HWND hwndime = 0;
1.377 + IME_UpdateInputLocale(videodata);
1.378 + IME_SetupAPI(videodata);
1.379 + if (uLang != PRIMLANG())
1.380 + {
1.381 + IME_ClearComposition(videodata);
1.382 + }
1.383 + hwndime = ImmGetDefaultIMEWnd(videodata->ime_hwnd_current);
1.384 + if (hwndime)
1.385 + {
1.386 + SendMessageA(hwndime, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
1.387 + SendMessageA(hwndime, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0);
1.388 + }
1.389 +}
1.390 +
1.391 +static DWORD
1.392 +IME_GetId(SDL_VideoData *videodata, UINT uIndex)
1.393 +{
1.394 + static HKL hklprev = 0;
1.395 + static DWORD dwRet[2] = {0};
1.396 + DWORD dwVerSize = 0;
1.397 + DWORD dwVerHandle = 0;
1.398 + LPVOID lpVerBuffer = 0;
1.399 + LPVOID lpVerData = 0;
1.400 + UINT cbVerData = 0;
1.401 + char szTemp[256];
1.402 + HKL hkl = 0;
1.403 + DWORD dwLang = 0;
1.404 + if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0]))
1.405 + return 0;
1.406 +
1.407 + hkl = videodata->ime_hkl;
1.408 + if (hklprev == hkl)
1.409 + return dwRet[uIndex];
1.410 +
1.411 + hklprev = hkl;
1.412 + dwLang = ((DWORD)hkl & 0xffff);
1.413 + if (videodata->ime_uiless && LANG() == LANG_CHT)
1.414 + {
1.415 + dwRet[0] = IMEID_CHT_VER_VISTA;
1.416 + dwRet[1] = 0;
1.417 + return dwRet[0];
1.418 + }
1.419 + if (hkl != CHT_HKL_NEW_PHONETIC
1.420 + && hkl != CHT_HKL_NEW_CHANG_JIE
1.421 + && hkl != CHT_HKL_NEW_QUICK
1.422 + && hkl != CHT_HKL_HK_CANTONESE
1.423 + && hkl != CHS_HKL)
1.424 + {
1.425 + dwRet[0] = dwRet[1] = 0;
1.426 + return dwRet[uIndex];
1.427 + }
1.428 + if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0)
1.429 + {
1.430 + dwRet[0] = dwRet[1] = 0;
1.431 + return dwRet[uIndex];
1.432 + }
1.433 + if (!videodata->GetReadingString)
1.434 + {
1.435 + #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
1.436 + if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
1.437 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
1.438 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
1.439 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
1.440 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2
1.441 + )
1.442 + {
1.443 + dwRet[0] = dwRet[1] = 0;
1.444 + return dwRet[uIndex];
1.445 + }
1.446 + #undef LCID_INVARIANT
1.447 + dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
1.448 + if (dwVerSize)
1.449 + {
1.450 + lpVerBuffer = SDL_malloc(dwVerSize);
1.451 + if (lpVerBuffer)
1.452 + {
1.453 + if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer))
1.454 + {
1.455 + if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData))
1.456 + {
1.457 + #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData)
1.458 + DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
1.459 + dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
1.460 + if (videodata->GetReadingString ||
1.461 + dwLang == LANG_CHT && (
1.462 + dwVer == MAKEIMEVERSION(4, 2) ||
1.463 + dwVer == MAKEIMEVERSION(4, 3) ||
1.464 + dwVer == MAKEIMEVERSION(4, 4) ||
1.465 + dwVer == MAKEIMEVERSION(5, 0) ||
1.466 + dwVer == MAKEIMEVERSION(5, 1) ||
1.467 + dwVer == MAKEIMEVERSION(5, 2) ||
1.468 + dwVer == MAKEIMEVERSION(6, 0))
1.469 + ||
1.470 + dwLang == LANG_CHS && (
1.471 + dwVer == MAKEIMEVERSION(4, 1) ||
1.472 + dwVer == MAKEIMEVERSION(4, 2) ||
1.473 + dwVer == MAKEIMEVERSION(5, 3))
1.474 + )
1.475 + {
1.476 + dwRet[0] = dwVer | dwLang;
1.477 + dwRet[1] = pVerFixedInfo->dwFileVersionLS;
1.478 + SDL_free(lpVerBuffer);
1.479 + return dwRet[0];
1.480 + }
1.481 + #undef pVerFixedInfo
1.482 + }
1.483 + }
1.484 + }
1.485 + SDL_free(lpVerBuffer);
1.486 + }
1.487 + }
1.488 + dwRet[0] = dwRet[1] = 0;
1.489 + return dwRet[uIndex];
1.490 +}
1.491 +
1.492 +static void
1.493 +IME_SetupAPI(SDL_VideoData *videodata)
1.494 +{
1.495 + char ime_file[MAX_PATH + 1];
1.496 + HMODULE hime = 0;
1.497 + HKL hkl = 0;
1.498 + videodata->GetReadingString = 0;
1.499 + videodata->ShowReadingWindow = 0;
1.500 + if (videodata->ime_uiless)
1.501 + return;
1.502 +
1.503 + hkl = videodata->ime_hkl;
1.504 + if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0)
1.505 + return;
1.506 +
1.507 + hime = LoadLibraryA(ime_file);
1.508 + if (!hime)
1.509 + return;
1.510 +
1.511 + videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
1.512 + GetProcAddress(hime, "GetReadingString");
1.513 + videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
1.514 + GetProcAddress(hime, "ShowReadingWindow");
1.515 +
1.516 + if (videodata->ShowReadingWindow)
1.517 + {
1.518 + HIMC himc = ImmGetContext(videodata->ime_hwnd_current);
1.519 + if (himc)
1.520 + {
1.521 + videodata->ShowReadingWindow(himc, FALSE);
1.522 + ImmReleaseContext(videodata->ime_hwnd_current, himc);
1.523 + }
1.524 + }
1.525 +}
1.526 +
1.527 +static void
1.528 +IME_SetWindow(SDL_VideoData* videodata, HWND hwnd)
1.529 +{
1.530 + videodata->ime_hwnd_current = hwnd;
1.531 + if (videodata->ime_threadmgr) {
1.532 + struct ITfDocumentMgr *document_mgr = 0;
1.533 + if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) {
1.534 + if (document_mgr)
1.535 + document_mgr->lpVtbl->Release(document_mgr);
1.536 + }
1.537 + }
1.538 +}
1.539 +
1.540 +static void
1.541 +IME_UpdateInputLocale(SDL_VideoData *videodata)
1.542 +{
1.543 + static HKL hklPrevious = 0;
1.544 + videodata->ime_hkl = GetKeyboardLayout(0);
1.545 + if (hklPrevious == videodata->ime_hkl)
1.546 + return;
1.547 +
1.548 + hklPrevious = videodata->ime_hkl;
1.549 +}
1.550 +
1.551 +static void
1.552 +IME_ClearComposition(SDL_VideoData *videodata)
1.553 +{
1.554 + HIMC himc = 0;
1.555 + if (!videodata->ime_initialized)
1.556 + return;
1.557 +
1.558 + himc = ImmGetContext(videodata->ime_hwnd_current);
1.559 + if (!himc)
1.560 + return;
1.561 +
1.562 + ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
1.563 + if (videodata->ime_uiless)
1.564 + ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR));
1.565 +
1.566 + ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
1.567 + ImmReleaseContext(videodata->ime_hwnd_current, himc);
1.568 + SDL_SendEditingText("", 0, 0);
1.569 +}
1.570 +
1.571 +static void
1.572 +IME_ClearEditing(SDL_VideoData *videodata)
1.573 +{
1.574 +
1.575 +}
1.576 +
1.577 +static void
1.578 +IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
1.579 +{
1.580 + LONG Length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition));
1.581 + if (Length < 0)
1.582 + Length = 0;
1.583 +
1.584 + Length /= sizeof(videodata->ime_composition[0]);
1.585 + videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
1.586 + if (videodata->ime_composition[videodata->ime_cursor] == 0x3000)
1.587 + {
1.588 + int i;
1.589 + for (i = videodata->ime_cursor + 1; i < Length; ++i)
1.590 + videodata->ime_composition[i - 1] = videodata->ime_composition[i];
1.591 +
1.592 + --Length;
1.593 + }
1.594 + videodata->ime_composition[Length] = 0;
1.595 +}
1.596 +
1.597 +static void
1.598 +IME_SendInputEvent(SDL_VideoData *videodata)
1.599 +{
1.600 + char *s = 0;
1.601 + s = WIN_StringToUTF8(videodata->ime_composition);
1.602 + SDL_SendKeyboardText(s);
1.603 + SDL_free(s);
1.604 +
1.605 + videodata->ime_composition[0] = 0;
1.606 + videodata->ime_readingstring[0] = 0;
1.607 + videodata->ime_cursor = 0;
1.608 +}
1.609 +
1.610 +static void
1.611 +IME_SendEditingEvent(SDL_VideoData *videodata)
1.612 +{
1.613 + char *s = 0;
1.614 + WCHAR wBuffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
1.615 + wBuffer[0] = 0;
1.616 + if (videodata->ime_readingstring[0])
1.617 + {
1.618 + size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
1.619 + SDL_wcslcpy(wBuffer, videodata->ime_composition, len + 1);
1.620 + SDL_wcslcat(wBuffer, videodata->ime_readingstring, sizeof(wBuffer));
1.621 + SDL_wcslcat(wBuffer, &videodata->ime_composition[len], sizeof(wBuffer) - len);
1.622 + }
1.623 + else
1.624 + {
1.625 + SDL_wcslcpy(wBuffer, videodata->ime_composition, sizeof(videodata->ime_composition));
1.626 + }
1.627 + s = WIN_StringToUTF8(wBuffer);
1.628 + SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0);
1.629 + SDL_free(s);
1.630 +}
1.631 +
1.632 SDL_bool
1.633 IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
1.634 {
1.635 SDL_bool trap = SDL_FALSE;
1.636 HIMC himc = 0;
1.637 - WCHAR Buffer[SDL_TEXTINPUTEVENT_TEXT_SIZE / 2];
1.638 if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled)
1.639 return SDL_FALSE;
1.640
1.641 switch (msg)
1.642 {
1.643 case WM_INPUTLANGCHANGE:
1.644 + //IME_InputLangChanged(videodata);
1.645 break;
1.646 case WM_IME_SETCONTEXT:
1.647 *lParam = 0;
1.648 @@ -279,37 +728,31 @@
1.649 himc = ImmGetContext(hwnd);
1.650 if (*lParam & GCS_RESULTSTR)
1.651 {
1.652 - LONG Length = 0;
1.653 - char *s = 0;
1.654 - Length = ImmGetCompositionStringW(himc, GCS_RESULTSTR, Buffer, sizeof(Buffer) * sizeof(Buffer[0]));
1.655 - Buffer[Length / sizeof(Buffer[0])] = 0;
1.656 - s = WIN_StringToUTF8(Buffer);
1.657 - SDL_SendKeyboardText(s);
1.658 - SDL_free(s);
1.659 + IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
1.660 + IME_SendInputEvent(videodata);
1.661 }
1.662 if (*lParam & GCS_COMPSTR)
1.663 {
1.664 - LONG Length = 0;
1.665 - DWORD Cursor = 0;
1.666 - char *s = 0;
1.667 - Length = ImmGetCompositionStringW(himc, GCS_COMPSTR, Buffer, sizeof(Buffer) * sizeof(Buffer[0]));
1.668 - Buffer[Length / sizeof(Buffer[0])] = 0;
1.669 - s = WIN_StringToUTF8(Buffer);
1.670 - Cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
1.671 - SDL_SendEditingText(s, Cursor, 0);
1.672 - SDL_free(s);
1.673 + if (!videodata->ime_uiless)
1.674 + videodata->ime_readingstring[0] = 0;
1.675 +
1.676 + IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
1.677 + IME_SendEditingEvent(videodata);
1.678 }
1.679 ImmReleaseContext(hwnd, himc);
1.680 break;
1.681 case WM_IME_ENDCOMPOSITION:
1.682 - SDL_SendKeyboardText("");
1.683 + videodata->ime_composition[0] = 0;
1.684 + videodata->ime_readingstring[0] = 0;
1.685 + videodata->ime_cursor = 0;
1.686 + SDL_SendEditingText("", 0, 0);
1.687 break;
1.688 case WM_IME_NOTIFY:
1.689 switch (wParam)
1.690 {
1.691 case IMN_SETCONVERSIONMODE:
1.692 - break;
1.693 case IMN_SETOPENSTATUS:
1.694 + IME_UpdateInputLocale(videodata);
1.695 break;
1.696 case IMN_OPENCANDIDATE:
1.697 case IMN_CHANGECANDIDATE:
1.698 @@ -319,6 +762,34 @@
1.699 trap = SDL_TRUE;
1.700 break;
1.701 case IMN_PRIVATE:
1.702 + {
1.703 + DWORD dwId = IME_GetId(videodata, 0);
1.704 + IME_GetReadingString(videodata, hwnd);
1.705 + switch (dwId)
1.706 + {
1.707 + case IMEID_CHT_VER42:
1.708 + case IMEID_CHT_VER43:
1.709 + case IMEID_CHT_VER44:
1.710 + case IMEID_CHS_VER41:
1.711 + case IMEID_CHS_VER42:
1.712 + if (*lParam == 1 || *lParam == 2)
1.713 + trap = SDL_TRUE;
1.714 +
1.715 + break;
1.716 + case IMEID_CHT_VER50:
1.717 + case IMEID_CHT_VER51:
1.718 + case IMEID_CHT_VER52:
1.719 + case IMEID_CHT_VER60:
1.720 + case IMEID_CHS_VER53:
1.721 + if (*lParam == 16
1.722 + || *lParam == 17
1.723 + || *lParam == 26
1.724 + || *lParam == 27
1.725 + || *lParam == 28)
1.726 + trap = SDL_TRUE;
1.727 + break;
1.728 + }
1.729 + }
1.730 break;
1.731 default:
1.732 trap = SDL_TRUE;
1.733 @@ -329,4 +800,265 @@
1.734 return trap;
1.735 }
1.736
1.737 +STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink)
1.738 +{
1.739 + return ++sink->refcount;
1.740 +}
1.741 +
1.742 +STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink)
1.743 +{
1.744 + --sink->refcount;
1.745 + if (sink->refcount == 0)
1.746 + {
1.747 + SDL_free(sink);
1.748 + return 0;
1.749 + }
1.750 + return sink->refcount;
1.751 +}
1.752 +
1.753 +STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
1.754 +{
1.755 + if (!ppv)
1.756 + return E_INVALIDARG;
1.757 +
1.758 + *ppv = 0;
1.759 + if (SDL_IsEqualIID(riid, &IID_IUnknown))
1.760 + *ppv = (IUnknown *)sink;
1.761 + else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink))
1.762 + *ppv = (ITfUIElementSink *)sink;
1.763 +
1.764 + if (*ppv)
1.765 + {
1.766 + TSFSink_AddRef(sink);
1.767 + return S_OK;
1.768 + }
1.769 + return E_NOINTERFACE;
1.770 +}
1.771 +
1.772 +ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId)
1.773 +{
1.774 + ITfUIElementMgr *puiem = 0;
1.775 + ITfUIElement *pelem = 0;
1.776 + ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex;
1.777 +
1.778 + if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem)))
1.779 + {
1.780 + puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
1.781 + puiem->lpVtbl->Release(puiem);
1.782 + }
1.783 + return pelem;
1.784 +}
1.785 +
1.786 +STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
1.787 +{
1.788 + ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
1.789 + ITfReadingInformationUIElement *preading = 0;
1.790 + ITfCandidateListUIElement *pcandidates = 0;
1.791 + SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1.792 + if (!pElement)
1.793 + return E_INVALIDARG;
1.794 +
1.795 + *pbShow = FALSE;
1.796 + if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading)))
1.797 + {
1.798 + BSTR bstr;
1.799 + if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr)
1.800 + {
1.801 + WCHAR *s = (WCHAR *)bstr;
1.802 + SysFreeString(bstr);
1.803 + }
1.804 + preading->lpVtbl->Release(preading);
1.805 + }
1.806 + else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates)))
1.807 + {
1.808 + pcandidates->lpVtbl->Release(pcandidates);
1.809 + }
1.810 + return S_OK;
1.811 +}
1.812 +
1.813 +STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId)
1.814 +{
1.815 + ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
1.816 + ITfReadingInformationUIElement *preading = 0;
1.817 + ITfCandidateListUIElement *pcandidates = 0;
1.818 + SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1.819 + if (!pElement)
1.820 + return E_INVALIDARG;
1.821 +
1.822 + if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading)))
1.823 + {
1.824 + BSTR bstr;
1.825 + if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr)
1.826 + {
1.827 + WCHAR *s = (WCHAR *)bstr;
1.828 + SDL_wcslcpy(videodata->ime_readingstring, s, sizeof(videodata->ime_readingstring));
1.829 + IME_SendEditingEvent(videodata);
1.830 + SysFreeString(bstr);
1.831 + }
1.832 + preading->lpVtbl->Release(preading);
1.833 + }
1.834 + else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates)))
1.835 + {
1.836 + pcandidates->lpVtbl->Release(pcandidates);
1.837 + }
1.838 + return S_OK;
1.839 +}
1.840 +
1.841 +STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId)
1.842 +{
1.843 + ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
1.844 + ITfReadingInformationUIElement *preading = 0;
1.845 + ITfCandidateListUIElement *pcandidates = 0;
1.846 + SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
1.847 + if (!pElement)
1.848 + return E_INVALIDARG;
1.849 +
1.850 + if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading)))
1.851 + {
1.852 + videodata->ime_readingstring[0] = 0;
1.853 + IME_SendEditingEvent(videodata);
1.854 + preading->lpVtbl->Release(preading);
1.855 + }
1.856 + else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates)))
1.857 + {
1.858 + pcandidates->lpVtbl->Release(pcandidates);
1.859 + }
1.860 + return S_OK;
1.861 +}
1.862 +
1.863 +STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
1.864 +{
1.865 + if (!ppv)
1.866 + return E_INVALIDARG;
1.867 +
1.868 + *ppv = 0;
1.869 + if (SDL_IsEqualIID(riid, &IID_IUnknown))
1.870 + *ppv = (IUnknown *)sink;
1.871 + else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
1.872 + *ppv = (ITfInputProcessorProfileActivationSink *)sink;
1.873 +
1.874 + if (*ppv)
1.875 + {
1.876 + TSFSink_AddRef(sink);
1.877 + return S_OK;
1.878 + }
1.879 + return E_NOINTERFACE;
1.880 +}
1.881 +
1.882 +STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
1.883 +{
1.884 + if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE))
1.885 + IME_InputLangChanged((SDL_VideoData *)sink->data);
1.886 +
1.887 + return S_OK;
1.888 +}
1.889 +
1.890 +static void *vtUIElementSink[] = {
1.891 + (void *)(UIElementSink_QueryInterface),
1.892 + (void *)(TSFSink_AddRef),
1.893 + (void *)(TSFSink_Release),
1.894 + (void *)(UIElementSink_BeginUIElement),
1.895 + (void *)(UIElementSink_UpdateUIElement),
1.896 + (void *)(UIElementSink_EndUIElement)
1.897 +};
1.898 +
1.899 +static void *vtIPPASink[] = {
1.900 + (void *)(IPPASink_QueryInterface),
1.901 + (void *)(TSFSink_AddRef),
1.902 + (void *)(TSFSink_Release),
1.903 + (void *)(IPPASink_OnActivated)
1.904 +};
1.905 +
1.906 +static void
1.907 +UILess_EnableUIUpdates(SDL_VideoData *videodata)
1.908 +{
1.909 + ITfSource *source = 0;
1.910 + if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE)
1.911 + return;
1.912 +
1.913 + if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source)))
1.914 + {
1.915 + source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie);
1.916 + source->lpVtbl->Release(source);
1.917 + }
1.918 +}
1.919 +
1.920 +static void
1.921 +UILess_DisableUIUpdates(SDL_VideoData *videodata)
1.922 +{
1.923 + ITfSource *source = 0;
1.924 + if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE)
1.925 + return;
1.926 +
1.927 + if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source)))
1.928 + {
1.929 + source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
1.930 + videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE;
1.931 + source->lpVtbl->Release(source);
1.932 + }
1.933 +}
1.934 +
1.935 +static SDL_bool
1.936 +UILess_SetupSinks(SDL_VideoData *videodata)
1.937 +{
1.938 + TfClientId clientid = 0;
1.939 + SDL_bool result = SDL_FALSE;
1.940 + ITfSource *source = 0;
1.941 + if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, &videodata->ime_threadmgrex)))
1.942 + return SDL_FALSE;
1.943 +
1.944 + if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY)))
1.945 + return SDL_FALSE;
1.946 +
1.947 + videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink));
1.948 + videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink));
1.949 +
1.950 + videodata->ime_uielemsink->lpVtbl = vtUIElementSink;
1.951 + videodata->ime_uielemsink->refcount = 1;
1.952 + videodata->ime_uielemsink->data = videodata;
1.953 +
1.954 + videodata->ime_ippasink->lpVtbl = vtIPPASink;
1.955 + videodata->ime_ippasink->refcount = 1;
1.956 + videodata->ime_ippasink->data = videodata;
1.957 +
1.958 + if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source)))
1.959 + {
1.960 + if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie)))
1.961 + {
1.962 + if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie)))
1.963 + {
1.964 + result = SDL_TRUE;
1.965 + }
1.966 + }
1.967 + source->lpVtbl->Release(source);
1.968 + }
1.969 + return result;
1.970 +}
1.971 +
1.972 +#define SAFE_RELEASE(p) \
1.973 +{ \
1.974 + if (p) { \
1.975 + (p)->lpVtbl->Release((p)); \
1.976 + (p) = 0; \
1.977 + } \
1.978 +}
1.979 +
1.980 +static void
1.981 +UILess_ReleaseSinks(SDL_VideoData *videodata)
1.982 +{
1.983 + ITfSource *Source = 0;
1.984 + if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, &Source)))
1.985 + {
1.986 + Source->lpVtbl->UnadviseSink(Source, videodata->ime_uielemsinkcookie);
1.987 + Source->lpVtbl->UnadviseSink(Source, videodata->ime_alpnsinkcookie);
1.988 + SAFE_RELEASE(Source);
1.989 + videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex);
1.990 + SAFE_RELEASE(videodata->ime_threadmgrex);
1.991 + TSFSink_Release(videodata->ime_uielemsink);
1.992 + videodata->ime_uielemsink = 0;
1.993 + TSFSink_Release(videodata->ime_ippasink);
1.994 + videodata->ime_ippasink = 0;
1.995 + }
1.996 +}
1.997 +
1.998 /* vi: set ts=4 sw=4 expandtab: */
2.1 --- a/src/video/win32/SDL_win32video.h Tue Aug 03 16:52:10 2010 -0400
2.2 +++ b/src/video/win32/SDL_win32video.h Tue Aug 03 16:57:49 2010 -0400
2.3 @@ -1,95 +1,150 @@
2.4 -/*
2.5 - SDL - Simple DirectMedia Layer
2.6 - Copyright (C) 1997-2010 Sam Lantinga
2.7 -
2.8 - This library is free software; you can redistribute it and/or
2.9 - modify it under the terms of the GNU Lesser General Public
2.10 - License as published by the Free Software Foundation; either
2.11 - version 2.1 of the License, or (at your option) any later version.
2.12 -
2.13 - This library is distributed in the hope that it will be useful,
2.14 - but WITHOUT ANY WARRANTY; without even the implied warranty of
2.15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2.16 - Lesser General Public License for more details.
2.17 -
2.18 - You should have received a copy of the GNU Lesser General Public
2.19 - License along with this library; if not, write to the Free Software
2.20 - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2.21 -
2.22 - Sam Lantinga
2.23 - slouken@libsdl.org
2.24 -*/
2.25 -#include "SDL_config.h"
2.26 -
2.27 -#ifndef _SDL_win32video_h
2.28 -#define _SDL_win32video_h
2.29 -
2.30 -#include "../SDL_sysvideo.h"
2.31 -
2.32 -#define WIN32_LEAN_AND_MEAN
2.33 -#define STRICT
2.34 -#define UNICODE
2.35 -#undef WINVER
2.36 -#define WINVER 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
2.37 -#include <windows.h>
2.38 -
2.39 -#if SDL_VIDEO_RENDER_D3D
2.40 -//#include <d3d9.h>
2.41 -#define D3D_DEBUG_INFO
2.42 -#include "d3d9.h"
2.43 -#endif
2.44 -
2.45 -#if SDL_VIDEO_RENDER_DDRAW
2.46 -/* WIN32_LEAN_AND_MEAN was defined, so we have to include this by hand */
2.47 -#include <objbase.h>
2.48 -#include "ddraw.h"
2.49 -#endif
2.50 -
2.51 -#include "SDL_win32clipboard.h"
2.52 -#include "SDL_win32events.h"
2.53 -#include "SDL_win32gamma.h"
2.54 -#include "SDL_win32keyboard.h"
2.55 -#include "SDL_win32modes.h"
2.56 -#include "SDL_win32mouse.h"
2.57 -#include "SDL_win32opengl.h"
2.58 -#include "SDL_win32window.h"
2.59 -
2.60 -#ifdef UNICODE
2.61 -#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR))
2.62 -#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2", "UTF-8", (char *)S, SDL_strlen(S)+1)
2.63 -#else
2.64 -#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1))
2.65 -#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1)
2.66 -#endif
2.67 -extern void WIN_SetError(const char *prefix);
2.68 -
2.69 -/* Private display data */
2.70 -
2.71 -typedef struct SDL_VideoData
2.72 -{
2.73 -#if SDL_VIDEO_RENDER_D3D
2.74 - HANDLE d3dDLL;
2.75 - IDirect3D9 *d3d;
2.76 -#endif
2.77 -#if SDL_VIDEO_RENDER_DDRAW
2.78 - HANDLE ddrawDLL;
2.79 - IDirectDraw *ddraw;
2.80 -#endif
2.81 -
2.82 - const SDL_scancode *key_layout;
2.83 - DWORD clipboard_count;
2.84 -
2.85 - SDL_bool ime_com_initialized;
2.86 - struct ITfThreadMgr *ime_thread_mgr;
2.87 - SDL_bool ime_initialized;
2.88 - SDL_bool ime_enabled;
2.89 - SDL_bool ime_available;
2.90 - HWND ime_hwnd_main;
2.91 - HWND ime_hwnd_current;
2.92 - HIMC ime_himc;
2.93 -
2.94 -} SDL_VideoData;
2.95 -
2.96 -#endif /* _SDL_win32video_h */
2.97 -
2.98 -/* vi: set ts=4 sw=4 expandtab: */
2.99 +/*
2.100 + SDL - Simple DirectMedia Layer
2.101 + Copyright (C) 1997-2010 Sam Lantinga
2.102 +
2.103 + This library is free software; you can redistribute it and/or
2.104 + modify it under the terms of the GNU Lesser General Public
2.105 + License as published by the Free Software Foundation; either
2.106 + version 2.1 of the License, or (at your option) any later version.
2.107 +
2.108 + This library is distributed in the hope that it will be useful,
2.109 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2.110 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2.111 + Lesser General Public License for more details.
2.112 +
2.113 + You should have received a copy of the GNU Lesser General Public
2.114 + License along with this library; if not, write to the Free Software
2.115 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2.116 +
2.117 + Sam Lantinga
2.118 + slouken@libsdl.org
2.119 +*/
2.120 +#include "SDL_config.h"
2.121 +
2.122 +#ifndef _SDL_win32video_h
2.123 +#define _SDL_win32video_h
2.124 +
2.125 +#include "../SDL_sysvideo.h"
2.126 +
2.127 +#define WIN32_LEAN_AND_MEAN
2.128 +#define STRICT
2.129 +#define UNICODE
2.130 +#undef WINVER
2.131 +#define WINVER 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
2.132 +#include <windows.h>
2.133 +
2.134 +#include <msctf.h>
2.135 +
2.136 +#if SDL_VIDEO_RENDER_D3D
2.137 +//#include <d3d9.h>
2.138 +#define D3D_DEBUG_INFO
2.139 +#include "d3d9.h"
2.140 +#endif
2.141 +
2.142 +#if SDL_VIDEO_RENDER_DDRAW
2.143 +/* WIN32_LEAN_AND_MEAN was defined, so we have to include this by hand */
2.144 +#include <objbase.h>
2.145 +#include "ddraw.h"
2.146 +#endif
2.147 +
2.148 +#include "SDL_win32clipboard.h"
2.149 +#include "SDL_win32events.h"
2.150 +#include "SDL_win32gamma.h"
2.151 +#include "SDL_win32keyboard.h"
2.152 +#include "SDL_win32modes.h"
2.153 +#include "SDL_win32mouse.h"
2.154 +#include "SDL_win32opengl.h"
2.155 +#include "SDL_win32window.h"
2.156 +#include "SDL_events.h"
2.157 +
2.158 +#ifdef UNICODE
2.159 +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR))
2.160 +#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2", "UTF-8", (char *)S, SDL_strlen(S)+1)
2.161 +#else
2.162 +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1))
2.163 +#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1)
2.164 +#endif
2.165 +extern void WIN_SetError(const char *prefix);
2.166 +
2.167 +typedef struct
2.168 +{
2.169 + void **lpVtbl;
2.170 + int refcount;
2.171 + void *data;
2.172 +} TSFSink;
2.173 +
2.174 +// Definition from Win98DDK version of IMM.H
2.175 +typedef struct tagINPUTCONTEXT2 {
2.176 + HWND hWnd;
2.177 + BOOL fOpen;
2.178 + POINT ptStatusWndPos;
2.179 + POINT ptSoftKbdPos;
2.180 + DWORD fdwConversion;
2.181 + DWORD fdwSentence;
2.182 + union {
2.183 + LOGFONTA A;
2.184 + LOGFONTW W;
2.185 + } lfFont;
2.186 + COMPOSITIONFORM cfCompForm;
2.187 + CANDIDATEFORM cfCandForm[4];
2.188 + HIMCC hCompStr;
2.189 + HIMCC hCandInfo;
2.190 + HIMCC hGuideLine;
2.191 + HIMCC hPrivate;
2.192 + DWORD dwNumMsgBuf;
2.193 + HIMCC hMsgBuf;
2.194 + DWORD fdwInit;
2.195 + DWORD dwReserve[3];
2.196 +} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2;
2.197 +
2.198 +/* Private display data */
2.199 +
2.200 +typedef struct SDL_VideoData
2.201 +{
2.202 +#if SDL_VIDEO_RENDER_D3D
2.203 + HANDLE d3dDLL;
2.204 + IDirect3D9 *d3d;
2.205 +#endif
2.206 +#if SDL_VIDEO_RENDER_DDRAW
2.207 + HANDLE ddrawDLL;
2.208 + IDirectDraw *ddraw;
2.209 +#endif
2.210 +
2.211 + const SDL_scancode *key_layout;
2.212 + DWORD clipboard_count;
2.213 +
2.214 + SDL_bool ime_com_initialized;
2.215 + struct ITfThreadMgr *ime_threadmgr;
2.216 + SDL_bool ime_initialized;
2.217 + SDL_bool ime_enabled;
2.218 + SDL_bool ime_available;
2.219 + HWND ime_hwnd_main;
2.220 + HWND ime_hwnd_current;
2.221 + HIMC ime_himc;
2.222 +
2.223 + WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
2.224 + WCHAR ime_readingstring[16];
2.225 + int ime_cursor;
2.226 +
2.227 + HKL ime_hkl;
2.228 + HMODULE ime_himm32;
2.229 + UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen);
2.230 + BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow);
2.231 + LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc);
2.232 + BOOL (WINAPI *ImmUnlockIMC)(HIMC himc);
2.233 + LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc);
2.234 + BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc);
2.235 +
2.236 + SDL_bool ime_uiless;
2.237 + struct ITfThreadMgrEx *ime_threadmgrex;
2.238 + DWORD ime_uielemsinkcookie;
2.239 + DWORD ime_alpnsinkcookie;
2.240 + DWORD ime_openmodesinkcookie;
2.241 + DWORD ime_convmodesinkcookie;
2.242 + TSFSink *ime_uielemsink;
2.243 + TSFSink *ime_ippasink;
2.244 +} SDL_VideoData;
2.245 +
2.246 +#endif /* _SDL_win32video_h */
2.247 +
2.248 +/* vi: set ts=4 sw=4 expandtab: */