https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b9ef348ab08b446594a25…
commit b9ef348ab08b446594a25c7070273bc265021dbc
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Mar 12 13:39:41 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Mar 12 13:39:41 2023 +0900
[NTUSER][USER32] KLF_SETFORPROCESS for ActivateKeyboardLayout (#5126)
Supporting KLF_SETFORPROCESS flag in ActivateKeyboardLayout function.
Implement KLF_SETFORPROCESS for co_UserActivateKeyboardLayout.
Use KLF_SETFORPROCESS flag in WM_INPUTLANGCHANGEREQUEST handling.
Add co_IntSetKeyboardLayoutForProcess helper function.
---
win32ss/user/ntuser/kbdlayout.c | 56 ++++++++++++++++++++++++++++++------
win32ss/user/user32/windows/defwnd.c | 2 +-
2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/win32ss/user/ntuser/kbdlayout.c b/win32ss/user/ntuser/kbdlayout.c
index 9a5c43d60a4..2f9ea599ab7 100644
--- a/win32ss/user/ntuser/kbdlayout.c
+++ b/win32ss/user/ntuser/kbdlayout.c
@@ -630,7 +630,6 @@ co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
return pklPrev;
}
-// Win: xxxImmActivateLayout
VOID APIENTRY
IntImmActivateLayout(
_Inout_ PTHREADINFO pti,
@@ -656,7 +655,40 @@ IntImmActivateLayout(
pti->pClientInfo->hKL = pKL->hkl;
}
-/* Win: xxxInternalActivateKeyboardLayout */
+static VOID co_IntSetKeyboardLayoutForProcess(PPROCESSINFO ppi, PKL pKL)
+{
+ PTHREADINFO ptiNode, ptiNext;
+ PCLIENTINFO pClientInfo;
+ BOOL bImmMode = IS_IMM_MODE();
+
+ for (ptiNode = ppi->ptiList; ptiNode; ptiNode = ptiNext)
+ {
+ IntReferenceThreadInfo(ptiNode);
+ ptiNext = ptiNode->ptiSibling;
+
+ /* Skip this thread if its keyboard layout is already the correct one, or if
it's dying */
+ if (ptiNode->KeyboardLayout == pKL || (ptiNode->TIF_flags &
TIF_INCLEANUP))
+ {
+ IntDereferenceThreadInfo(ptiNode);
+ continue;
+ }
+
+ if (bImmMode)
+ {
+ IntImmActivateLayout(ptiNode, pKL);
+ }
+ else
+ {
+ UserAssignmentLock((PVOID*)&ptiNode->KeyboardLayout, pKL);
+ pClientInfo = ptiNode->pClientInfo;
+ pClientInfo->CodePage = pKL->CodePage;
+ pClientInfo->hKL = pKL->hkl;
+ }
+
+ IntDereferenceThreadInfo(ptiNode);
+ }
+}
+
HKL APIENTRY
co_UserActivateKeyboardLayout(
_Inout_ PKL pKL,
@@ -669,7 +701,11 @@ co_UserActivateKeyboardLayout(
PWND pTargetWnd, pImeWnd;
HWND hTargetWnd, hImeWnd;
USER_REFERENCE_ENTRY Ref1, Ref2;
- PCLIENTINFO ClientInfo = pti->pClientInfo;
+ PCLIENTINFO ClientInfo;
+ BOOL bSetForProcess = !!(uFlags & KLF_SETFORPROCESS);
+
+ IntReferenceThreadInfo(pti);
+ ClientInfo = pti->pClientInfo;
if (pti->KeyboardLayout)
{
@@ -683,8 +719,11 @@ co_UserActivateKeyboardLayout(
FIXME("KLF_RESET\n");
}
- if (!(uFlags & KLF_SETFORPROCESS) && pKL == pti->KeyboardLayout)
+ if (!bSetForProcess && pKL == pti->KeyboardLayout)
+ {
+ IntDereferenceThreadInfo(pti);
return hOldKL;
+ }
pKL->wchDiacritic = 0;
@@ -697,9 +736,9 @@ co_UserActivateKeyboardLayout(
ClientInfo->CodePage = pKL->CodePage;
ClientInfo->hKL = pKL->hkl;
}
- else if (uFlags & KLF_SETFORPROCESS)
+ else if (bSetForProcess)
{
- FIXME("KLF_SETFORPROCESS\n");
+ co_IntSetKeyboardLayoutForProcess(pti->ppi, pKL);
}
else
{
@@ -748,9 +787,8 @@ co_UserActivateKeyboardLayout(
if (pImeWnd)
{
UserRefObjectCo(pImeWnd, &Ref2);
- BOOL bProcess = !!(pti->TIF_flags & KLF_SETFORPROCESS);
hImeWnd = UserHMGetHandle(pImeWnd);
- co_IntSendMessage(hImeWnd, WM_IME_SYSTEM, IMS_SENDNOTIFICATION,
bProcess);
+ co_IntSendMessage(hImeWnd, WM_IME_SYSTEM, IMS_SENDNOTIFICATION,
bSetForProcess);
UserDerefObjectCo(pImeWnd);
}
}
@@ -758,6 +796,8 @@ co_UserActivateKeyboardLayout(
if (pOldKL)
UserDerefObjectCo(pOldKL);
+
+ IntDereferenceThreadInfo(pti);
return hOldKL;
}
diff --git a/win32ss/user/user32/windows/defwnd.c b/win32ss/user/user32/windows/defwnd.c
index 0a976bf50ee..cbb421209dc 100644
--- a/win32ss/user/user32/windows/defwnd.c
+++ b/win32ss/user/user32/windows/defwnd.c
@@ -561,7 +561,7 @@ User32DefWindowProc(HWND hWnd,
else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
else NewHkl = (HKL) lParam;
- NtUserActivateKeyboardLayout(NewHkl, 0);
+ NtUserActivateKeyboardLayout(NewHkl, KLF_SETFORPROCESS);
return TRUE;
}