mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
Implement NtUserUnloadKeyboardLayout()
svn path=/trunk/; revision=26233
This commit is contained in:
parent
36af38d7dd
commit
9e8d69fa5d
|
@ -1923,10 +1923,10 @@ NTAPI
|
|||
NtUserUnhookWinEvent(
|
||||
DWORD Unknown0);
|
||||
|
||||
DWORD
|
||||
BOOL
|
||||
NTAPI
|
||||
NtUserUnloadKeyboardLayout(
|
||||
DWORD Unknown0);
|
||||
HKL hKl);
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
|
|
|
@ -15,8 +15,9 @@ typedef struct _KBL
|
|||
DWORD klid; // Low word - language id. High word - device id.
|
||||
} KBL, *PKBL;
|
||||
|
||||
#define KBL_UNLOADED 0x20000000
|
||||
#define KBL_RESET 0x40000000
|
||||
#define KBL_UNLOAD 1
|
||||
#define KBL_PRELOAD 2
|
||||
#define KBL_RESET 4
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
InitInputImpl(VOID);
|
||||
|
|
|
@ -156,7 +156,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID,
|
|||
RtlFreeUnicodeString(&LayoutFile);
|
||||
|
||||
*phModule = EngLoadImage(FullLayoutPath.Buffer);
|
||||
|
||||
|
||||
if(*phModule)
|
||||
{
|
||||
DPRINT("Loaded %wZ\n", &FullLayoutPath);
|
||||
|
@ -262,6 +262,8 @@ BOOL UserInitDefaultKeyboardLayout()
|
|||
}
|
||||
}
|
||||
|
||||
KBLList->Flags |= KBL_PRELOAD;
|
||||
|
||||
InitializeListHead(&KBLList->List);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -318,17 +320,56 @@ static PKBL UserHklToKbl(HKL hKl)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PKBL co_UserActivateKbl(PW32THREAD Thread, PKBL pKbl)
|
||||
BOOL UserUnloadKbl(PKBL pKbl)
|
||||
{
|
||||
/* According to msdn, UnloadKeyboardLayout can fail
|
||||
if the keyboard layout identifier was preloaded. */
|
||||
|
||||
if(pKbl->Flags & KBL_PRELOAD)
|
||||
{
|
||||
DPRINT1("Attempted to unload preloaded keyboard layout.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(pKbl->RefCount > 0)
|
||||
{
|
||||
/* Layout is used by other threads.
|
||||
Mark it as unloaded and don't do anything else. */
|
||||
pKbl->Flags |= KBL_UNLOAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Unload the layout
|
||||
EngUnloadImage(pKbl->hModule);
|
||||
RemoveEntryList(&pKbl->List);
|
||||
ExFreePool(pKbl);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PKBL co_UserActivateKbl(PW32THREAD w32Thread, PKBL pKbl, UINT Flags)
|
||||
{
|
||||
PKBL Prev;
|
||||
|
||||
Prev = Thread->KeyboardLayout;
|
||||
Prev = w32Thread->KeyboardLayout;
|
||||
Prev->RefCount--;
|
||||
Thread->KeyboardLayout = pKbl;
|
||||
w32Thread->KeyboardLayout = pKbl;
|
||||
pKbl->RefCount++;
|
||||
|
||||
if(Flags & KLF_SETFORPROCESS)
|
||||
{
|
||||
//FIXME
|
||||
|
||||
}
|
||||
|
||||
if(Prev->Flags & KBL_UNLOAD && Prev->RefCount == 0)
|
||||
{
|
||||
UserUnloadKbl(Prev);
|
||||
}
|
||||
|
||||
// Send WM_INPUTLANGCHANGE to thread's focus window
|
||||
co_IntSendMessage(Thread->MessageQueue->FocusWindow,
|
||||
co_IntSendMessage(w32Thread->MessageQueue->FocusWindow,
|
||||
WM_INPUTLANGCHANGE,
|
||||
0, // FIXME: put charset here (what is this?)
|
||||
(LPARAM)pKbl->hkl); //klid
|
||||
|
@ -394,10 +435,13 @@ NtUserGetKeyboardLayoutList(
|
|||
|
||||
while(Ret < nItems)
|
||||
{
|
||||
pHklBuff[Ret] = pKbl->hkl;
|
||||
Ret++;
|
||||
pKbl = (PKBL) pKbl->List.Flink;
|
||||
if(pKbl == KBLList) break;
|
||||
if(!(pKbl->Flags & KBL_UNLOAD))
|
||||
{
|
||||
pHklBuff[Ret] = pKbl->hkl;
|
||||
Ret++;
|
||||
pKbl = (PKBL) pKbl->List.Flink;
|
||||
if(pKbl == KBLList) break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -457,18 +501,21 @@ NtUserLoadKeyboardLayoutEx(
|
|||
|
||||
UserEnterExclusive();
|
||||
|
||||
//Let's see if layout was already loaded.
|
||||
Cur = KBLList;
|
||||
do
|
||||
{
|
||||
if(Cur->klid == dwKLID)
|
||||
{
|
||||
pKbl = Cur;
|
||||
pKbl->Flags &= ~KBL_UNLOAD;
|
||||
break;
|
||||
}
|
||||
|
||||
Cur = (PKBL) Cur->List.Flink;
|
||||
} while(Cur != KBLList);
|
||||
|
||||
//It wasn't, so load it.
|
||||
if(!pKbl)
|
||||
{
|
||||
pKbl = UserLoadDllAndCreateKbl(dwKLID);
|
||||
|
@ -485,14 +532,14 @@ NtUserLoadKeyboardLayoutEx(
|
|||
|
||||
if(Flags & KLF_ACTIVATE)
|
||||
{
|
||||
co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl);
|
||||
co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl, Flags);
|
||||
}
|
||||
|
||||
Ret = pKbl->hkl;
|
||||
|
||||
//FIXME: Respect Flags!
|
||||
// KLF_NOTELLSHELL KLF_SETFORPROCESS
|
||||
// KLF_REPLACELANG KLF_SUBSTITUTE_OK
|
||||
//FIXME: KLF_NOTELLSHELL
|
||||
// KLF_REPLACELANG
|
||||
// KLF_SUBSTITUTE_OK
|
||||
|
||||
the_end:
|
||||
UserLeave();
|
||||
|
@ -530,7 +577,6 @@ NtUserActivateKeyboardLayout(
|
|||
else pKbl = UserHklToKbl(hKl);
|
||||
|
||||
//FIXME: KLF_RESET, KLF_SHIFTLOCK
|
||||
//FIXME: KLF_SETFORPROCESS
|
||||
|
||||
if(pKbl)
|
||||
{
|
||||
|
@ -543,15 +589,41 @@ NtUserActivateKeyboardLayout(
|
|||
}
|
||||
else
|
||||
{
|
||||
pKbl = co_UserActivateKbl(pWThread, pKbl);
|
||||
pKbl = co_UserActivateKbl(pWThread, pKbl, Flags);
|
||||
Ret = pKbl->hkl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);
|
||||
}
|
||||
|
||||
the_end:
|
||||
UserLeave();
|
||||
return Ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
NtUserUnloadKeyboardLayout(
|
||||
HKL hKl)
|
||||
{
|
||||
PKBL pKbl;
|
||||
BOOL Ret = FALSE;
|
||||
|
||||
UserEnterExclusive();
|
||||
|
||||
if((pKbl = UserHklToKbl(hKl)))
|
||||
{
|
||||
Ret = UserUnloadKbl(pKbl);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);
|
||||
}
|
||||
|
||||
UserLeave();
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -616,16 +616,6 @@ NtUserTrackMouseEvent(
|
|||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserUnloadKeyboardLayout(
|
||||
DWORD Unknown0)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
|
|
Loading…
Reference in a new issue