[IMM32] Improve ImmSimulateHotKey (#3858)

- Improve ImmSimulateHotKey function.
- Modify IMEDPI structure.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2021-07-31 15:56:11 +09:00 committed by GitHub
parent 89cb8a38b3
commit d7f13aa696
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 249 additions and 4 deletions

View file

@ -48,6 +48,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
#define IMM_INIT_MAGIC 0x19650412
#define IMM_INVALID_CANDFORM ULONG_MAX
#define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
#define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
#define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)
#define REGKEY_KEYBOARD_LAYOUTS \
L"System\\CurrentControlSet\\Control\\Keyboard Layouts"
#define REGKEY_IMM \
@ -1205,6 +1209,234 @@ static DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD dwThreadId, HIMC **pphLis
#undef MAX_RETRY
}
static BOOL APIENTRY Imm32ImeNonImeToggle(HIMC hIMC, HKL hKL, HWND hWnd, LANGID LangID)
{
LPINPUTCONTEXT pIC;
BOOL fOpen;
if (hWnd != NULL)
return FALSE;
if (!IS_IME_HKL(hKL) || LOWORD(hKL) != LangID)
{
FIXME("We have to do something here\n");
return TRUE;
}
pIC = ImmLockIMC(hIMC);
if (pIC == NULL)
return TRUE;
fOpen = pIC->fOpen;
ImmUnlockIMC(hIMC);
if (!fOpen)
{
ImmSetOpenStatus(hIMC, TRUE);
return TRUE;
}
FIXME("We have to do something here\n");
return TRUE;
}
static BOOL APIENTRY Imm32CShapeToggle(HIMC hIMC, HKL hKL, HWND hWnd)
{
LPINPUTCONTEXT pIC;
BOOL fOpen;
DWORD dwConversion, dwSentence;
if (hWnd == NULL || !IS_IME_HKL(hKL))
return FALSE;
pIC = ImmLockIMC(hIMC);
if (pIC == NULL)
return TRUE;
fOpen = pIC->fOpen;
if (fOpen)
{
dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE);
dwSentence = pIC->fdwSentence;
}
ImmUnlockIMC(hIMC);
if (fOpen)
ImmSetConversionStatus(hIMC, dwConversion, dwSentence);
else
ImmSetOpenStatus(hIMC, TRUE);
return TRUE;
}
static BOOL APIENTRY Imm32CSymbolToggle(HIMC hIMC, HKL hKL, HWND hWnd)
{
LPINPUTCONTEXT pIC;
BOOL fOpen;
DWORD dwConversion, dwSentence;
if (hWnd == NULL || !IS_IME_HKL(hKL))
return FALSE;
pIC = ImmLockIMC(hIMC);
if (pIC == NULL)
return TRUE;
fOpen = pIC->fOpen;
if (fOpen)
{
dwConversion = (pIC->fdwConversion ^ IME_CMODE_SYMBOL);
dwSentence = pIC->fdwSentence;
}
ImmUnlockIMC(hIMC);
if (fOpen)
ImmSetConversionStatus(hIMC, dwConversion, dwSentence);
else
ImmSetOpenStatus(hIMC, TRUE);
return TRUE;
}
static BOOL APIENTRY Imm32JCloseOpen(HIMC hIMC, HKL hKL, HWND hWnd)
{
BOOL fOpen;
if (ImmIsIME(hKL) && LOWORD(hKL) == LANGID_JAPANESE)
{
fOpen = ImmGetOpenStatus(hIMC);
ImmSetOpenStatus(hIMC, !fOpen);
return TRUE;
}
FIXME("We have to do something here\n");
return TRUE;
}
static BOOL APIENTRY Imm32KShapeToggle(HIMC hIMC)
{
LPINPUTCONTEXT pIC;
DWORD dwConversion, dwSentence;
pIC = ImmLockIMC(hIMC);
if (pIC == NULL)
return FALSE;
dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE);
dwSentence = pIC->fdwSentence;
ImmSetConversionStatus(hIMC, dwConversion, dwSentence);
if (pIC->fdwConversion & (IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE))
ImmSetOpenStatus(hIMC, TRUE);
else
ImmSetOpenStatus(hIMC, FALSE);
ImmUnlockIMC(hIMC);
return TRUE;
}
static BOOL APIENTRY Imm32KHanjaConvert(HIMC hIMC)
{
LPINPUTCONTEXT pIC;
DWORD dwConversion, dwSentence;
pIC = ImmLockIMC(hIMC);
if (!pIC)
return FALSE;
dwConversion = (pIC->fdwConversion ^ IME_CMODE_HANJACONVERT);
dwSentence = pIC->fdwSentence;
ImmUnlockIMC(hIMC);
ImmSetConversionStatus(hIMC, dwConversion, dwSentence);
return TRUE;
}
static BOOL APIENTRY Imm32KEnglish(HIMC hIMC)
{
LPINPUTCONTEXT pIC;
DWORD dwConversion, dwSentence;
BOOL fOpen;
pIC = ImmLockIMC(hIMC);
if (pIC == NULL)
return FALSE;
dwConversion = (pIC->fdwConversion ^ IME_CMODE_NATIVE);
dwSentence = pIC->fdwSentence;
ImmSetConversionStatus(hIMC, dwConversion, dwSentence);
fOpen = ((pIC->fdwConversion & (IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE)) != 0);
ImmSetOpenStatus(hIMC, fOpen);
ImmUnlockIMC(hIMC);
return TRUE;
}
static BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID)
{
DWORD dwImeThreadId, dwThreadId;
PIMEDPI pImeDpi;
BOOL ret;
if (hIMC)
{
dwImeThreadId = Imm32QueryInputContext(hIMC, 1);
dwThreadId = GetCurrentThreadId();
if (dwImeThreadId != dwThreadId)
return FALSE;
}
switch (dwHotKeyID)
{
case IME_CHOTKEY_IME_NONIME_TOGGLE:
return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_SIMPLIFIED);
case IME_CHOTKEY_SHAPE_TOGGLE:
return Imm32CShapeToggle(hIMC, hKL, hWnd);
case IME_CHOTKEY_SYMBOL_TOGGLE:
return Imm32CSymbolToggle(hIMC, hKL, hWnd);
case IME_JHOTKEY_CLOSE_OPEN:
return Imm32JCloseOpen(hIMC, hKL, hWnd);
case IME_KHOTKEY_SHAPE_TOGGLE:
return Imm32KShapeToggle(hIMC);
case IME_KHOTKEY_HANJACONVERT:
return Imm32KHanjaConvert(hIMC);
case IME_KHOTKEY_ENGLISH:
return Imm32KEnglish(hIMC);
case IME_THOTKEY_IME_NONIME_TOGGLE:
return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_TRADITIONAL);
case IME_THOTKEY_SHAPE_TOGGLE:
return Imm32CShapeToggle(hIMC, hKL, hWnd);
case IME_THOTKEY_SYMBOL_TOGGLE:
return Imm32CSymbolToggle(hIMC, hKL, hWnd);
default:
break;
}
if (dwHotKeyID < IME_HOTKEY_PRIVATE_FIRST || IME_HOTKEY_PRIVATE_LAST < dwHotKeyID)
return FALSE;
pImeDpi = ImmLockImeDpi(hKL);
if (pImeDpi == NULL)
return FALSE;
ret = (BOOL)pImeDpi->ImeEscape(hIMC, IME_ESC_PRIVATE_HOTKEY, &dwHotKeyID);
ImmUnlockImeDpi(pImeDpi);
return ret;
}
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
{
PCLIENTIMC pClientImc;
@ -3288,9 +3520,19 @@ BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
*/
BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
{
FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
HIMC hIMC;
DWORD dwThreadId;
HKL hKL;
BOOL ret;
TRACE("ImmSimulateHotKey(%p, 0x%lX)\n", hWnd, dwHotKeyID);
hIMC = ImmGetContext(hWnd);
dwThreadId = GetWindowThreadProcessId(hWnd, NULL);
hKL = GetKeyboardLayout(dwThreadId);
ret = Imm32ProcessHotKey(hWnd, hIMC, hKL, dwHotKeyID);
ImmReleaseContext(hWnd, hIMC);
return ret;
}
/***********************************************************************

View file

@ -1213,6 +1213,7 @@ typedef struct _IMEWND
} IMEWND, *PIMEWND;
typedef BOOL (WINAPI *FN_ImeDestroy)(UINT uReserved);
typedef LRESULT (WINAPI *FN_ImeEscape)(HIMC hIMC, UINT uEscape, LPVOID lpData);
typedef BOOL (WINAPI *FN_NotifyIME)(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue);
typedef struct IMEDPI /* unconfirmed */
@ -1227,7 +1228,8 @@ typedef struct IMEDPI /* unconfirmed */
DWORD dwFlags;
DWORD dwUnknown3[7];
FN_ImeDestroy ImeDestroy;
DWORD dwUnknown4[5];
FN_ImeEscape ImeEscape;
DWORD dwUnknown4[4];
FN_NotifyIME NotifyIME;
/* ... */
} IMEDPI, *PIMEDPI;
@ -1239,6 +1241,7 @@ C_ASSERT(offsetof(IMEDPI, hKL) == 0x8);
C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c);
C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50);
C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70);
C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74);
C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88);
#endif