/*
* PROJECT: ReactOS Win32k subsystem
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/win32k/ntuser/kbdlayout.c
+ * FILE: win32ss/user/ntuser/kbdlayout.c
* PURPOSE: Keyboard layout management
* COPYRIGHT: Copyright 2007 Saveliy Tretiakov
* Copyright 2008 Colin Finck
#include <win32k.h>
-#include <winnls.h>
+// Was included only because of CP_ACP and required the
+// definition of SYSTEMTIME in ndk\rtltypes.h
+//#include <winnls.h>
+#define CP_ACP 0
DBG_DEFAULT_CHANNEL(UserKbdLayout);
PKL gspklBaseLayout = NULL;
PKBDFILE gpkfList = NULL;
+DWORD gSystemFS = 0;
+UINT gSystemCPCharSet = 0;
typedef PVOID (*PFN_KBDLAYERDESCRIPTOR)(VOID);
}
/* Read filename of layout DLL */
- cbSize = sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR);
+ cbSize = (ULONG)(sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR));
Status = RegQueryValue(hKey,
L"Layout File",
REG_SZ,
* Loads keyboard layout and creates KL object
*/
static PKL
-UserLoadKbdLayout(PUNICODE_STRING pwszKLID, HKL hKL)
+UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
{
LCID lCid;
CHARSETINFO cs;
}
pKl->hkl = hKL;
- pKl->spkf = UserLoadKbdFile(pwszKLID);
+ pKl->spkf = UserLoadKbdFile(pustrKLID);
/* Dereference keyboard layout */
UserDereferenceObject(pKl);
/* If we failed, remove KL object */
if (!pKl->spkf)
{
- ERR("UserLoadKbdFile(%wZ) failed!\n", pwszKLID);
+ ERR("UserLoadKbdFile(%wZ) failed!\n", pustrKLID);
UserDeleteObject(pKl->head.h, TYPE_KBDLAYOUT);
return NULL;
}
// Up to Language Identifiers..
- RtlUnicodeStringToInteger(pwszKLID, (ULONG)16, (PULONG)&lCid);
- TRACE("Language Identifiers %wZ LCID 0x%x\n", pwszKLID, lCid);
+ if (!NT_SUCCESS(RtlUnicodeStringToInteger(pustrKLID, 16, (PULONG)&lCid)))
+ {
+ ERR("RtlUnicodeStringToInteger failed for '%wZ'\n", pustrKLID);
+ UserDeleteObject(pKl->head.h, TYPE_KBDLAYOUT);
+ return NULL;
+ }
+
+ TRACE("Language Identifiers %wZ LCID 0x%x\n", pustrKLID, lCid);
if (co_IntGetCharsetInfo(lCid, &cs))
{
pKl->iBaseCharset = cs.ciCharset;
pKl->dwFontSigs = cs.fs.fsCsb[0];
pKl->CodePage = (USHORT)cs.ciACP;
- TRACE("Charset %u Font Sig %lu CodePage %u\n", pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
+ TRACE("Charset %u Font Sig %lu CodePage %u\n",
+ pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
}
else
{
pKl->CodePage = CP_ACP;
}
+ // Set initial system character set and font signature.
+ if (gSystemFS == 0)
+ {
+ gSystemCPCharSet = pKl->iBaseCharset;
+ gSystemFS = pKl->dwFontSigs;
+ }
+
return pKl;
}
co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
{
PKL pklPrev;
+ PWND pWnd;
pklPrev = pti->KeyboardLayout;
if (pklPrev)
// FIXME
}
+ if (!(pWnd = pti->MessageQueue->spwndFocus))
+ {
+ pWnd = pti->MessageQueue->spwndActive;
+ }
+
// Send WM_INPUTLANGCHANGE to thread's focus window
- co_IntSendMessage(pti->MessageQueue->spwndFocus ? UserHMGetHandle(pti->MessageQueue->spwndFocus) : 0,
+ co_IntSendMessage( pWnd ? UserHMGetHandle(pWnd) : 0,
WM_INPUTLANGCHANGE,
(WPARAM)pKl->iBaseCharset, // FIXME: How to set it?
(LPARAM)pKl->hkl); // hkl
UserGetKeyboardLayout(
DWORD dwThreadId)
{
- NTSTATUS Status;
- PETHREAD pThread;
PTHREADINFO pti;
+ PLIST_ENTRY ListEntry;
PKL pKl;
- HKL hKl;
+
+ pti = PsGetCurrentThreadWin32Thread();
if (!dwThreadId)
{
- pti = PsGetCurrentThreadWin32Thread();
pKl = pti->KeyboardLayout;
return pKl ? pKl->hkl : NULL;
}
- Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)dwThreadId, &pThread);
- if (!NT_SUCCESS(Status))
+ ListEntry = pti->rpdesk->PtiList.Flink;
+
+ //
+ // Search the Desktop Thread list for related Desktop active Threads.
+ //
+ while(ListEntry != &pti->rpdesk->PtiList)
{
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
+ pti = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
+
+ if (PsGetThreadId(pti->pEThread) == UlongToHandle(dwThreadId))
+ {
+ pKl = pti->KeyboardLayout;
+ return pKl ? pKl->hkl : NULL;
+ }
+
+ ListEntry = ListEntry->Flink;
}
- pti = PsGetThreadWin32Thread(pThread);
- pKl = pti->KeyboardLayout;
- hKl = pKl ? pKl->hkl : NULL;;
- ObDereferenceObject(pThread);
- return hKl;
+ return NULL;
}
/*
if (Flags & ~(KLF_ACTIVATE|KLF_NOTELLSHELL|KLF_REORDER|KLF_REPLACELANG|
KLF_SUBSTITUTE_OK|KLF_SETFORPROCESS|KLF_UNLOADPREVIOUS|
- KLF_RESET|KLF_SETFORPROCESS|KLF_SHIFTLOCK))
+ KLF_RESET|KLF_SHIFTLOCK))
{
ERR("Invalid flags: %x\n", Flags);
EngSetLastError(ERROR_INVALID_FLAGS);
UserEnterExclusive();
/* If hklUnload is specified, unload it and load new layput as default */
- if (hklUnload && hklUnload != (HKL)hkl)
+ if (hklUnload && (hklUnload != UlongToHandle(hkl)))
{
pKl = UserHklToKbl(hklUnload);
if (pKl)
}
/* Let's see if layout was already loaded. */
- pKl = UserHklToKbl((HKL)hkl);
+ pKl = UserHklToKbl(UlongToHandle(hkl));
if (!pKl)
{
/* It wasn't, so load it. */
- pKl = UserLoadKbdLayout(&ustrSafeKLID, (HKL)hkl);
+ pKl = UserLoadKbdLayout(&ustrSafeKLID, UlongToHandle(hkl));
if (!pKl)
goto cleanup;
co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
/* Return hkl on success */
- hklRet = (HKL)hkl;
+ hklRet = UlongToHandle(hkl);
/* FIXME: KLF_REPLACELANG
KLF_REORDER */
{
/* Get previous keyboard layout starting with current */
if (pti->KeyboardLayout)
- pKl = pti->KeyboardLayout->pklNext;
+ pKl = pti->KeyboardLayout->pklPrev;
}
else
pKl = UserHklToKbl(hKl);