[NTUSER][IMM32] Implement NtUserGetImeInfoEx (#4271)

- Add UserGetImeInfoEx helper function.
- Implement NtUserGetImeInfoEx function by using UserGetImeInfoEx.
- Fix imm32.ImmGetImeInfoEx.
- Modify enum IMEINFOEXCLASS.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2022-01-12 12:06:24 +09:00 committed by GitHub
parent a47590c9cf
commit 36740ca981
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 36 deletions

View file

@ -574,8 +574,7 @@ HKL WINAPI ImmInstallIMEW(LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
} }
/* If the IME for the specified filename is valid, then unload it now */ /* If the IME for the specified filename is valid, then unload it now */
/* FIXME: ImmGetImeInfoEx is broken */ if (ImmGetImeInfoEx(&InfoEx, ImeInfoExImeFileName, pchFilePart) &&
if (ImmGetImeInfoEx(&InfoEx, 3, pchFilePart) &&
!UnloadKeyboardLayout(InfoEx.hkl)) !UnloadKeyboardLayout(InfoEx.hkl))
{ {
hNewKL = NULL; hNewKL = NULL;
@ -623,8 +622,7 @@ BOOL WINAPI ImmIsIME(HKL hKL)
{ {
IMEINFOEX info; IMEINFOEX info;
TRACE("(%p)\n", hKL); TRACE("(%p)\n", hKL);
/* FIXME: ImmGetImeInfoEx is broken */ return !!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayoutTFS, &hKL);
return !!ImmGetImeInfoEx(&info, 1, &hKL);
} }
/*********************************************************************** /***********************************************************************
@ -681,42 +679,41 @@ BOOL WINAPI ImmDisableLegacyIME(void)
BOOL WINAPI BOOL WINAPI
ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearchKey) ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearchKey)
{ {
BOOL bDisabled = FALSE;
HKL hKL; HKL hKL;
if (SearchType == ImeInfoExKeyboardLayout || SearchType == ImeInfoExKeyboardLayoutTFS)
/* FIXME: broken */
switch (SearchType)
{ {
case ImeInfoExKeyboardLayout:
break;
case ImeInfoExImeWindow:
bDisabled = CtfImmIsTextFrameServiceDisabled();
SearchType = ImeInfoExKeyboardLayout;
break;
case ImeInfoExImeFileName:
StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile),
pvSearchKey);
goto Quit;
}
hKL = *(HKL*)pvSearchKey; hKL = *(HKL*)pvSearchKey;
pImeInfoEx->hkl = hKL; pImeInfoEx->hkl = hKL;
if (SearchType == ImeInfoExKeyboardLayoutTFS)
{
if (!IS_IME_HKL(hKL)) if (!IS_IME_HKL(hKL))
{ {
if (Imm32IsCiceroMode()) if (!CtfImmIsTextFrameServiceDisabled() ||
!Imm32IsCiceroMode() || Imm32Is16BitMode())
{ {
if (Imm32Is16BitMode())
return FALSE; return FALSE;
if (!bDisabled)
goto Quit;
} }
}
SearchType = ImeInfoExKeyboardLayout;
}
else
{
if (!IS_IME_HKL(hKL))
return FALSE;
}
}
else if (SearchType == ImeInfoExImeFileName)
{
StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile),
pvSearchKey);
}
else
{
return FALSE; return FALSE;
} }
Quit:
return NtUserGetImeInfoEx(pImeInfoEx, SearchType); return NtUserGetImeInfoEx(pImeInfoEx, SearchType);
} }

View file

@ -1183,9 +1183,12 @@ typedef struct tagIMEINFOEX
}; };
} IMEINFOEX, *PIMEINFOEX; } IMEINFOEX, *PIMEINFOEX;
typedef enum IMEINFOEXCLASS /* unconfirmed: buggy */ typedef enum IMEINFOEXCLASS
{ {
ImeInfoExKeyboardLayout, ImeInfoExKeyboardLayout,
#if 1
ImeInfoExKeyboardLayoutTFS,
#endif
ImeInfoExImeWindow, ImeInfoExImeWindow,
ImeInfoExImeFileName ImeInfoExImeFileName
} IMEINFOEXCLASS; } IMEINFOEXCLASS;

View file

@ -157,16 +157,98 @@ NtUserGetAppImeLevel(HWND hWnd)
return 0; return 0;
} }
BOOL FASTCALL UserGetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pInfoEx, IMEINFOEXCLASS SearchType)
{
PKL pkl, pklHead;
if (!gspklBaseLayout)
return FALSE;
pkl = pklHead = gspklBaseLayout;
/* Find the matching entry from the list and get info */
if (SearchType == ImeInfoExKeyboardLayout)
{
do
{
if (pInfoEx->hkl == pkl->hkl) /* Matched */
{
if (!pkl->piiex)
break;
*pInfoEx = *pkl->piiex; /* Get */
return TRUE; /* Found */
}
pkl = pkl->pklNext;
} while (pkl != pklHead);
}
else if (SearchType == ImeInfoExImeFileName)
{
do
{
if (pkl->piiex &&
_wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0) /* Matched */
{
*pInfoEx = *pkl->piiex; /* Get */
return TRUE; /* Found */
}
pkl = pkl->pklNext;
} while (pkl != pklHead);
}
else
{
/* Do nothing */
}
return FALSE; /* Not found */
}
BOOL BOOL
APIENTRY APIENTRY
NtUserGetImeInfoEx( NtUserGetImeInfoEx(
PIMEINFOEX pImeInfoEx, PIMEINFOEX pImeInfoEx,
IMEINFOEXCLASS SearchType) IMEINFOEXCLASS SearchType)
{ {
STUB; IMEINFOEX ImeInfoEx;
return FALSE; BOOL ret = FALSE;
UserEnterShared();
if (!IS_IMM_MODE())
goto Quit;
_SEH2_TRY
{
ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
ImeInfoEx = *pImeInfoEx;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
goto Quit;
}
_SEH2_END;
ret = UserGetImeInfoEx(NULL, &ImeInfoEx, SearchType);
if (ret)
{
_SEH2_TRY
{
*pImeInfoEx = ImeInfoEx;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = FALSE;
}
_SEH2_END;
} }
Quit:
UserLeave();
return ret;
}
DWORD DWORD
APIENTRY APIENTRY