21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_WINDOWS 27 #include "../../events/SDL_keyboard_c.h" 28 #include "../../events/scancodes_windows.h" 33 #ifndef SDL_DISABLE_WINDOWS_IME 40 #ifndef MAPVK_VK_TO_VSC 41 #define MAPVK_VK_TO_VSC 0 43 #ifndef MAPVK_VSC_TO_VK 44 #define MAPVK_VSC_TO_VK 1 46 #ifndef MAPVK_VK_TO_CHAR 47 #define MAPVK_VK_TO_CHAR 2 85 data->GetReadingString = 0;
86 data->ShowReadingWindow = 0;
88 data->ImmUnlockIMC = 0;
89 data->ImmLockIMCC = 0;
90 data->ImmUnlockIMCC = 0;
136 vk = MapVirtualKey(i, MAPVK_VSC_TO_VK);
138 int ch = (MapVirtualKey( vk, MAPVK_VK_TO_CHAR ) & 0x7FFF);
140 if ( ch >=
'A' && ch <=
'Z' ) {
141 keymap[scancode] =
SDLK_a + ( ch -
'A' );
143 keymap[scancode] = ch;
155 #ifndef SDL_DISABLE_WINDOWS_IME 168 BYTE keyboardState[256];
170 int keycode, scancode,
result,
i;
172 GetKeyboardState(keyboardState);
175 scancode = MapVirtualKey(keycode, MAPVK_VK_TO_VSC);
181 for (i = 0; i < 5; i++) {
182 result = ToUnicode(keycode, scancode, keyboardState, (LPWSTR)buffer, 16, 0);
193 #ifndef SDL_DISABLE_WINDOWS_IME 199 #ifndef SDL_DISABLE_WINDOWS_IME 205 IME_Init(videodata, hwnd);
206 IME_Enable(videodata, hwnd);
214 #ifndef SDL_DISABLE_WINDOWS_IME 220 #ifndef SDL_DISABLE_WINDOWS_IME 225 IME_Init(videodata, hwnd);
226 IME_Disable(videodata, hwnd);
248 cf.ptCurrentPos.x = videodata->
ime_rect.
x;
249 cf.ptCurrentPos.y = videodata->
ime_rect.
y;
250 cf.dwStyle = CFS_FORCE_POSITION;
251 ImmSetCompositionWindow(himc, &cf);
256 #ifdef SDL_DISABLE_WINDOWS_IME 272 #define USE_INIT_GUID 273 #elif defined(__GNUC__) 274 #define USE_INIT_GUID 278 #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}} 279 DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C);
280 DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
281 DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31);
282 DEFINE_GUID(IID_ITfSource, 0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7);
283 DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
284 DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
285 DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
286 DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E);
287 DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50);
288 DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C);
291 #define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) 292 #define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) 294 #define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) )) 295 #define IMEID_VER(id) ((id) & 0xffff0000) 296 #define IMEID_LANG(id) ((id) & 0x0000ffff) 298 #define CHT_HKL_DAYI ((HKL)(UINT_PTR)0xE0060404) 299 #define CHT_HKL_NEW_PHONETIC ((HKL)(UINT_PTR)0xE0080404) 300 #define CHT_HKL_NEW_CHANG_JIE ((HKL)(UINT_PTR)0xE0090404) 301 #define CHT_HKL_NEW_QUICK ((HKL)(UINT_PTR)0xE00A0404) 302 #define CHT_HKL_HK_CANTONESE ((HKL)(UINT_PTR)0xE00B0404) 303 #define CHT_IMEFILENAME1 "TINTLGNT.IME" 304 #define CHT_IMEFILENAME2 "CINTLGNT.IME" 305 #define CHT_IMEFILENAME3 "MSTCIPHA.IME" 306 #define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2)) 307 #define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3)) 308 #define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4)) 309 #define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0)) 310 #define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1)) 311 #define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2)) 312 #define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0)) 313 #define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0)) 315 #define CHS_HKL ((HKL)(UINT_PTR)0xE00E0804) 316 #define CHS_IMEFILENAME1 "PINTLGNT.IME" 317 #define CHS_IMEFILENAME2 "MSSCIPYA.IME" 318 #define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1)) 319 #define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2)) 320 #define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3)) 322 #define LANG() LOWORD((videodata->ime_hkl)) 323 #define PRIMLANG() ((WORD)PRIMARYLANGID(LANG())) 324 #define SUBLANG() SUBLANGID(LANG()) 328 static void IME_SetWindow(
SDL_VideoData* videodata, HWND hwnd);
330 static DWORD IME_GetId(
SDL_VideoData *videodata, UINT uIndex);
336 static void UILess_EnableUIUpdates(
SDL_VideoData *videodata);
337 static void UILess_DisableUIUpdates(
SDL_VideoData *videodata);
348 CoCreateInstance(&CLSID_TF_ThreadMgr,
NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->
ime_threadmgr);
362 IME_SetWindow(videodata, hwnd);
363 videodata->
ime_himc = ImmGetContext(hwnd);
364 ImmReleaseContext(hwnd, videodata->
ime_himc);
367 IME_Disable(videodata, hwnd);
371 IME_UpdateInputLocale(videodata);
372 IME_SetupAPI(videodata);
373 videodata->
ime_uiless = UILess_SetupSinks(videodata);
374 IME_UpdateInputLocale(videodata);
375 IME_Disable(videodata, hwnd);
385 IME_Disable(videodata, hwnd);
392 IME_UpdateInputLocale(videodata);
393 UILess_EnableUIUpdates(videodata);
402 IME_ClearComposition(videodata);
407 UILess_DisableUIUpdates(videodata);
416 UILess_ReleaseSinks(videodata);
434 IME_DestroyTextures(videodata);
447 BOOL vertical =
FALSE;
455 id = IME_GetId(videodata, 0);
459 himc = ImmGetContext(hwnd);
463 if (videodata->GetReadingString) {
464 len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
469 len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
474 LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
479 case IMEID_CHT_VER42:
480 case IMEID_CHT_VER43:
481 case IMEID_CHT_VER44:
482 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
486 len = *(DWORD *)(p + 7*4 + 32*4);
487 s = (WCHAR *)(p + 56);
489 case IMEID_CHT_VER51:
490 case IMEID_CHT_VER52:
491 case IMEID_CHS_VER53:
492 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
496 p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
500 len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
501 s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
503 case IMEID_CHS_VER41:
505 int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
506 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
510 len = *(DWORD *)(p + 7*4 + 16*2*4);
511 s = (WCHAR *)(p + 6*4 + 16*2*1);
514 case IMEID_CHS_VER42:
515 p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
519 len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
520 s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
528 videodata->ImmUnlockIMCC(lpimc->hPrivate);
529 videodata->ImmUnlockIMC(himc);
531 ImmReleaseContext(hwnd, himc);
532 IME_SendEditingEvent(videodata);
538 UINT lang = PRIMLANG();
539 IME_UpdateInputLocale(videodata);
543 IME_SetupAPI(videodata);
544 if (lang != PRIMLANG()) {
545 IME_ClearComposition(videodata);
552 static HKL hklprev = 0;
553 static DWORD dwRet[2] = {0};
555 DWORD dwVerHandle = 0;
556 LPVOID lpVerBuffer = 0;
557 LPVOID lpVerData = 0;
562 if (uIndex >=
sizeof(dwRet) /
sizeof(dwRet[0]))
567 return dwRet[uIndex];
570 dwLang = ((DWORD_PTR)hkl & 0xffff);
571 if (videodata->
ime_uiless && LANG() == LANG_CHT) {
572 dwRet[0] = IMEID_CHT_VER_VISTA;
576 if (hkl != CHT_HKL_NEW_PHONETIC
577 && hkl != CHT_HKL_NEW_CHANG_JIE
578 && hkl != CHT_HKL_NEW_QUICK
579 && hkl != CHT_HKL_HK_CANTONESE
581 dwRet[0] = dwRet[1] = 0;
582 return dwRet[uIndex];
584 if (ImmGetIMEFileNameA(hkl, szTemp,
sizeof(szTemp) - 1) <= 0) {
585 dwRet[0] = dwRet[1] = 0;
586 return dwRet[uIndex];
588 if (!videodata->GetReadingString) {
589 #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) 590 if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
591 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
592 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
593 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
594 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) {
595 dwRet[0] = dwRet[1] = 0;
596 return dwRet[uIndex];
598 #undef LCID_INVARIANT 599 dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
603 if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) {
604 if (VerQueryValueA(lpVerBuffer,
"\\", &lpVerData, &cbVerData)) {
605 #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData) 606 DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
607 dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
608 if ((videodata->GetReadingString) ||
609 ((dwLang == LANG_CHT) && (
610 dwVer == MAKEIMEVERSION(4, 2) ||
611 dwVer == MAKEIMEVERSION(4, 3) ||
612 dwVer == MAKEIMEVERSION(4, 4) ||
613 dwVer == MAKEIMEVERSION(5, 0) ||
614 dwVer == MAKEIMEVERSION(5, 1) ||
615 dwVer == MAKEIMEVERSION(5, 2) ||
616 dwVer == MAKEIMEVERSION(6, 0)))
618 ((dwLang == LANG_CHS) && (
619 dwVer == MAKEIMEVERSION(4, 1) ||
620 dwVer == MAKEIMEVERSION(4, 2) ||
621 dwVer == MAKEIMEVERSION(5, 3)))) {
622 dwRet[0] = dwVer | dwLang;
623 dwRet[1] = pVerFixedInfo->dwFileVersionLS;
634 dwRet[0] = dwRet[1] = 0;
635 return dwRet[uIndex];
641 char ime_file[MAX_PATH + 1];
644 videodata->GetReadingString = 0;
645 videodata->ShowReadingWindow = 0;
650 if (ImmGetIMEFileNameA(hkl, ime_file,
sizeof(ime_file) - 1) <= 0)
657 videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
659 videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
662 if (videodata->ShowReadingWindow) {
665 videodata->ShowReadingWindow(himc,
FALSE);
679 document_mgr->
lpVtbl->Release(document_mgr);
687 static HKL hklprev = 0;
688 videodata->
ime_hkl = GetKeyboardLayout(0);
689 if (hklprev == videodata->
ime_hkl)
693 switch (PRIMLANG()) {
696 if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED)
720 ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
722 ImmSetCompositionString(himc, SCS_SETSTR, TEXT(
""),
sizeof(TCHAR), TEXT(
""),
sizeof(TCHAR));
724 ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
730 IME_GetCompositionString(
SDL_VideoData *videodata, HIMC himc, DWORD
string)
737 videodata->
ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
740 for (i = videodata->
ime_cursor + 1; i < length; ++i)
783 IME_AddCandidate(
SDL_VideoData *videodata, UINT i, LPCWSTR candidate)
791 *dst++ = *candidate++;
799 LPCANDIDATELIST cand_list = 0;
800 DWORD size = ImmGetCandidateListW(himc, 0, 0, 0);
802 cand_list = (LPCANDIDATELIST)
SDL_malloc(size);
804 size = ImmGetCandidateListW(himc, 0, cand_list, size);
811 if (LANG() == LANG_CHS && IME_GetId(videodata, 0)) {
812 const UINT maxcandchar = 18;
816 size_t len =
SDL_wcslen((LPWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i])) + 1;
817 if (len + cchars > maxcandchar) {
818 if (i > cand_list->dwSelection)
838 for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (
int)videodata->
ime_candpgsize; i++, j++) {
839 LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[
i]);
840 IME_AddCandidate(videodata, j, candidate);
842 if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0)))
856 IME_DestroyTextures(videodata);
857 IME_SendEditingEvent(videodata);
865 IME_DestroyTextures(videodata);
866 IME_SendEditingEvent(videodata);
878 case WM_INPUTLANGCHANGE:
879 IME_InputLangChanged(videodata);
881 case WM_IME_SETCONTEXT:
884 case WM_IME_STARTCOMPOSITION:
887 case WM_IME_COMPOSITION:
889 himc = ImmGetContext(hwnd);
890 if (*lParam & GCS_RESULTSTR) {
891 IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
892 IME_SendInputEvent(videodata);
894 if (*lParam & GCS_COMPSTR) {
898 IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
899 IME_SendEditingEvent(videodata);
901 ImmReleaseContext(hwnd, himc);
903 case WM_IME_ENDCOMPOSITION:
911 case IMN_SETCONVERSIONMODE:
912 case IMN_SETOPENSTATUS:
913 IME_UpdateInputLocale(videodata);
915 case IMN_OPENCANDIDATE:
916 case IMN_CHANGECANDIDATE:
921 IME_ShowCandidateList(videodata);
922 himc = ImmGetContext(hwnd);
926 IME_GetCandidateList(himc, videodata);
927 ImmReleaseContext(hwnd, himc);
929 case IMN_CLOSECANDIDATE:
931 IME_HideCandidateList(videodata);
935 DWORD dwId = IME_GetId(videodata, 0);
936 IME_GetReadingString(videodata, hwnd);
939 case IMEID_CHT_VER42:
940 case IMEID_CHT_VER43:
941 case IMEID_CHT_VER44:
942 case IMEID_CHS_VER41:
943 case IMEID_CHS_VER42:
944 if (*lParam == 1 || *lParam == 2)
948 case IMEID_CHT_VER50:
949 case IMEID_CHT_VER51:
950 case IMEID_CHT_VER52:
951 case IMEID_CHT_VER60:
952 case IMEID_CHS_VER53:
975 IME_HideCandidateList(videodata);
990 pcandlist->
lpVtbl->GetSelection(pcandlist, &selection);
991 pcandlist->
lpVtbl->GetCount(pcandlist, &count);
992 pcandlist->
lpVtbl->GetCurrentPage(pcandlist, &page);
996 IME_ShowCandidateList(videodata);
998 pcandlist->
lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount);
1000 UINT *idxlist =
SDL_malloc(
sizeof(UINT) * pgcount);
1002 pcandlist->
lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount);
1003 pgstart = idxlist[page];
1004 if (page < pgcount - 1)
1005 pgsize =
SDL_min(count, idxlist[page + 1]) - pgstart;
1007 pgsize = count - pgstart;
1016 for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) {
1020 IME_AddCandidate(videodata, j, bstr);
1021 SysFreeString(bstr);
1025 if (PRIMLANG() == LANG_KOREAN)
1029 STDMETHODIMP_(ULONG) TSFSink_AddRef(
TSFSink *
sink)
1034 STDMETHODIMP_(ULONG) TSFSink_Release(
TSFSink *
sink)
1044 STDMETHODIMP UIElementSink_QueryInterface(
TSFSink *sink, REFIID riid, PVOID *ppv)
1051 *ppv = (IUnknown *)sink;
1056 TSFSink_AddRef(sink);
1068 if (
SUCCEEDED(threadmgrex->
lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) {
1069 puiem->
lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
1070 puiem->lpVtbl->Release(puiem);
1075 STDMETHODIMP UIElementSink_BeginUIElement(
TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
1085 if (
SUCCEEDED(element->
lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
1087 if (
SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
1088 SysFreeString(bstr);
1090 preading->lpVtbl->Release(preading);
1092 else if (
SUCCEEDED(element->
lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
1094 UILess_GetCandidateList(videodata, pcandlist);
1095 pcandlist->lpVtbl->Release(pcandlist);
1100 STDMETHODIMP UIElementSink_UpdateUIElement(
TSFSink *sink, DWORD dwUIElementId)
1109 if (
SUCCEEDED(element->
lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
1111 if (
SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
1112 WCHAR *s = (WCHAR *)bstr;
1114 IME_SendEditingEvent(videodata);
1115 SysFreeString(bstr);
1117 preading->lpVtbl->Release(preading);
1119 else if (
SUCCEEDED(element->
lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
1120 UILess_GetCandidateList(videodata, pcandlist);
1121 pcandlist->lpVtbl->Release(pcandlist);
1126 STDMETHODIMP UIElementSink_EndUIElement(
TSFSink *sink, DWORD dwUIElementId)
1135 if (
SUCCEEDED(element->
lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
1137 IME_SendEditingEvent(videodata);
1138 preading->lpVtbl->Release(preading);
1140 if (
SUCCEEDED(element->
lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
1143 IME_CloseCandidateList(videodata);
1145 pcandlist->lpVtbl->Release(pcandlist);
1150 STDMETHODIMP IPPASink_QueryInterface(
TSFSink *sink, REFIID riid, PVOID *ppv)
1157 *ppv = (IUnknown *)sink;
1158 else if (
WIN_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
1162 TSFSink_AddRef(sink);
1168 STDMETHODIMP IPPASink_OnActivated(
TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
1170 static const GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } };
1176 IME_HideCandidateList(videodata);
1180 static void *vtUIElementSink[] = {
1181 (
void *)(UIElementSink_QueryInterface),
1182 (
void *)(TSFSink_AddRef),
1183 (
void *)(TSFSink_Release),
1184 (
void *)(UIElementSink_BeginUIElement),
1185 (
void *)(UIElementSink_UpdateUIElement),
1186 (
void *)(UIElementSink_EndUIElement)
1189 static void *vtIPPASink[] = {
1190 (
void *)(IPPASink_QueryInterface),
1191 (
void *)(TSFSink_AddRef),
1192 (
void *)(TSFSink_Release),
1193 (
void *)(IPPASink_OnActivated)
1205 source->lpVtbl->Release(source);
1219 source->lpVtbl->Release(source);
1229 if (
FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr,
NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->
ime_threadmgrex)))
1252 source->lpVtbl->Release(source);
1257 #define SAFE_RELEASE(p) \ 1260 (p)->lpVtbl->Release((p)); \ 1272 SAFE_RELEASE(source);
1283 StartDrawToBitmap(HDC hdc, HBITMAP *hhbm,
int width,
int height)
1286 BITMAPINFOHEADER *infoHeader = &info.bmiHeader;
1290 infoHeader->biSize =
sizeof(BITMAPINFOHEADER);
1291 infoHeader->biWidth =
width;
1292 infoHeader->biHeight = -1 *
SDL_abs(height);
1293 infoHeader->biPlanes = 1;
1294 infoHeader->biBitCount = 32;
1295 infoHeader->biCompression =
BI_RGB;
1296 *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (
void **)&bits, 0, 0);
1298 SelectObject(hdc, *hhbm);
1304 StopDrawToBitmap(HDC hdc, HBITMAP *hhbm)
1306 if (hhbm && *hhbm) {
1307 DeleteObject(*hhbm);
1317 const int penadjust = (int)
SDL_floor(pensize / 2.0
f - 0.5
f);
1318 left += pensize / 2;
1321 bottom -= penadjust;
1322 Rectangle(hdc, left, top, right, bottom);
1330 #define SDL_swap(a,b) { \ 1337 IME_PositionCandidateList(
SDL_VideoData *videodata, SIZE size)
1347 right = left + size.cx;
1348 bottom = top + size.cy;
1349 if (right >= winw) {
1350 left -= right - winw;
1360 right = left + size.cx;
1362 if (right >= winw) {
1363 left -= right - winw;
1374 right = left + size.cx;
1410 SIZE maxcandsize = {0};
1415 const int listborder = 1;
1416 const int listpadding = 0;
1417 const int listbordercolor =
RGB(0xB4, 0xC7, 0xAA);
1418 const int listfillcolor =
RGB(255, 255, 255);
1420 const int candborder = 1;
1421 const int candpadding = 0;
1422 const int candmargin = 1;
1423 const COLORREF candbordercolor =
RGB(255, 255, 255);
1424 const COLORREF candfillcolor =
RGB(255, 255, 255);
1425 const COLORREF candtextcolor =
RGB(0, 0, 0);
1426 const COLORREF selbordercolor =
RGB(0x84, 0xAC, 0xDD);
1427 const COLORREF selfillcolor =
RGB(0xD2, 0xE6, 0xFF);
1428 const COLORREF seltextcolor =
RGB(0, 0, 0);
1429 const int horzcandspacing = 5;
1431 HPEN listpen = listborder != 0 ? CreatePen(PS_SOLID, listborder, listbordercolor) : (HPEN)GetStockObject(NULL_PEN);
1432 HBRUSH listbrush = CreateSolidBrush(listfillcolor);
1433 HPEN candpen = candborder != 0 ? CreatePen(PS_SOLID, candborder, candbordercolor) : (HPEN)GetStockObject(NULL_PEN);
1434 HBRUSH candbrush = CreateSolidBrush(candfillcolor);
1435 HPEN selpen = candborder != 0 ? CreatePen(PS_DOT, candborder, selbordercolor) : (HPEN)GetStockObject(NULL_PEN);
1436 HBRUSH selbrush = CreateSolidBrush(selfillcolor);
1437 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"));
1439 SetBkMode(hdc, TRANSPARENT);
1440 SelectObject(hdc, font);
1442 for (i = 0; i < candcount; ++
i) {
1447 GetTextExtentPoint32W(hdc, s, (
int)
SDL_wcslen(s), &candsizes[i]);
1448 maxcandsize.cx =
SDL_max(maxcandsize.cx, candsizes[i].cx);
1449 maxcandsize.cy =
SDL_max(maxcandsize.cy, candsizes[i].cy);
1464 ((candcount + 1) * candmargin) +
1465 (candcount * candborder * 2) +
1466 (candcount * candpadding * 2) +
1467 (candcount * maxcandsize.cy)
1474 ((candcount + 1) * candmargin) +
1475 (candcount * candborder * 2) +
1476 (candcount * candpadding * 2) +
1477 ((candcount - 1) * horzcandspacing);
1480 for (i = 0; i < candcount; ++
i)
1481 size.cx += candsizes[i].cx;
1493 StartDrawToBitmap(hdc, &hbm, size.cx, size.cy);
1495 SelectObject(hdc, listpen);
1496 SelectObject(hdc, listbrush);
1497 DrawRect(hdc, 0, 0, size.cx, size.cy, listborder);
1499 SelectObject(hdc, candpen);
1500 SelectObject(hdc, candbrush);
1501 SetTextColor(hdc, candtextcolor);
1502 SetBkMode(hdc, TRANSPARENT);
1504 for (i = 0; i < candcount; ++
i) {
1511 left = listborder + listpadding + candmargin;
1512 top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy);
1513 right = size.cx - listborder - listpadding - candmargin;
1514 bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2);
1517 left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing);
1519 for (j = 0; j <
i; ++
j)
1520 left += candsizes[j].cx;
1522 top = listborder + listpadding + candmargin;
1523 right = left + candsizes[
i].cx + (candpadding * 2) + (candborder * 2);
1524 bottom = size.cy - listborder - listpadding - candmargin;
1528 SelectObject(hdc, selpen);
1529 SelectObject(hdc, selbrush);
1530 SetTextColor(hdc, seltextcolor);
1533 SelectObject(hdc, candpen);
1534 SelectObject(hdc, candbrush);
1535 SetTextColor(hdc, candtextcolor);
1538 DrawRect(hdc, left, top, right, bottom, candborder);
1539 ExtTextOutW(hdc, left + candborder + candpadding, top + candborder + candpadding, 0,
NULL, s, (
int)
SDL_wcslen(s),
NULL);
1541 StopDrawToBitmap(hdc, &hbm);
1543 DeleteObject(listpen);
1544 DeleteObject(listbrush);
1545 DeleteObject(candpen);
1546 DeleteObject(candbrush);
1547 DeleteObject(selpen);
1548 DeleteObject(selbrush);
1551 IME_PositionCandidateList(videodata, size);
1557 HDC hdc = CreateCompatibleDC(
NULL);
1560 IME_RenderCandidateList(videodata, hdc);
1570 IME_Render(videodata);
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
GLsizei GLenum GLboolean sink
GLuint GLuint GLsizei count
const struct ITfThreadMgrExVtbl * lpVtbl
const struct ITfSourceVtbl * lpVtbl
void WIN_ResetDeadKeys(void)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
static void DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
#define SDLK_SCANCODE_MASK
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
const struct ITfThreadMgrVtbl * lpVtbl
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
#define TF_INVALID_COOKIE
#define SDL_GetKeyboardFocus
#define SDL_InvalidParamError(param)
BOOL WIN_IsEqualGUID(const GUID *a, const GUID *b)
DWORD ime_openmodesinkcookie
GLdouble GLdouble GLdouble GLdouble top
Sint32 SDL_Keycode
The SDL virtual key representation.
GLint GLint GLsizei width
const struct ITfDocumentMgrVtbl * lpVtbl
static SDL_VideoDevice * _this
DWORD ime_uielemsinkcookie
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
#define SDL_GetWindowSize
void WIN_StartTextInput(_THIS)
HRESULT WIN_CoInitialize(void)
int SDL_SendKeyboardText(const char *text)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
#define TF_IPSINK_FLAG_ACTIVE
void WIN_StopTextInput(_THIS)
const struct ITfCandidateListUIElementVtbl * lpVtbl
#define WIN_StringToUTF8(S)
GLsizei GLsizei GLchar * source
void WIN_InitKeyboard(_THIS)
void WIN_QuitKeyboard(_THIS)
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
const struct ITfUIElementVtbl * lpVtbl
DWORD ime_convmodesinkcookie
SDL_bool ime_com_initialized
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
WCHAR ime_readingstring[16]
void WIN_CoUninitialize(void)
void WIN_UpdateKeymap(void)
void WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
GLint GLint GLsizei GLsizei height
EGLSurface EGLNativeWindowType * window
static const SDL_Scancode windows_scancode_table[]
The type used to identify a window.
SDL_bool ime_candvertical
BOOL WIN_IsEqualIID(REFIID a, REFIID b)
WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE]
int ime_candlistindexbase
#define SDL_arraysize(array)
SDL_Rect ime_candlistrect
void * SDL_LoadFunction(void *handle, const char *name)
#define TF_TMAE_UIELEMENTENABLEDONLY
GLuint GLsizei GLsizei * length
SDL_Scancode
The SDL keyboard scancode representation.
int SDL_SendEditingText(const char *text, int start, int length)
WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH]
A rectangle, with the origin at the upper left.
SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata)
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE
struct ITfThreadMgrEx * ime_threadmgrex
struct ITfThreadMgr * ime_threadmgr