mirror of
https://github.com/reactos/reactos.git
synced 2024-07-20 19:36:38 +00:00
Implement NtUserUnloadKeyboardLayout()
svn path=/trunk/; revision=26233
This commit is contained in:
parent
36af38d7dd
commit
9e8d69fa5d
|
@ -1923,10 +1923,10 @@ NTAPI
|
||||||
NtUserUnhookWinEvent(
|
NtUserUnhookWinEvent(
|
||||||
DWORD Unknown0);
|
DWORD Unknown0);
|
||||||
|
|
||||||
DWORD
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserUnloadKeyboardLayout(
|
NtUserUnloadKeyboardLayout(
|
||||||
DWORD Unknown0);
|
HKL hKl);
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -15,8 +15,9 @@ typedef struct _KBL
|
||||||
DWORD klid; // Low word - language id. High word - device id.
|
DWORD klid; // Low word - language id. High word - device id.
|
||||||
} KBL, *PKBL;
|
} KBL, *PKBL;
|
||||||
|
|
||||||
#define KBL_UNLOADED 0x20000000
|
#define KBL_UNLOAD 1
|
||||||
#define KBL_RESET 0x40000000
|
#define KBL_PRELOAD 2
|
||||||
|
#define KBL_RESET 4
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
InitInputImpl(VOID);
|
InitInputImpl(VOID);
|
||||||
|
|
|
@ -262,6 +262,8 @@ BOOL UserInitDefaultKeyboardLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KBLList->Flags |= KBL_PRELOAD;
|
||||||
|
|
||||||
InitializeListHead(&KBLList->List);
|
InitializeListHead(&KBLList->List);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -318,17 +320,56 @@ static PKBL UserHklToKbl(HKL hKl)
|
||||||
return NULL;
|
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;
|
PKBL Prev;
|
||||||
|
|
||||||
Prev = Thread->KeyboardLayout;
|
Prev = w32Thread->KeyboardLayout;
|
||||||
Prev->RefCount--;
|
Prev->RefCount--;
|
||||||
Thread->KeyboardLayout = pKbl;
|
w32Thread->KeyboardLayout = pKbl;
|
||||||
pKbl->RefCount++;
|
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
|
// Send WM_INPUTLANGCHANGE to thread's focus window
|
||||||
co_IntSendMessage(Thread->MessageQueue->FocusWindow,
|
co_IntSendMessage(w32Thread->MessageQueue->FocusWindow,
|
||||||
WM_INPUTLANGCHANGE,
|
WM_INPUTLANGCHANGE,
|
||||||
0, // FIXME: put charset here (what is this?)
|
0, // FIXME: put charset here (what is this?)
|
||||||
(LPARAM)pKbl->hkl); //klid
|
(LPARAM)pKbl->hkl); //klid
|
||||||
|
@ -394,10 +435,13 @@ NtUserGetKeyboardLayoutList(
|
||||||
|
|
||||||
while(Ret < nItems)
|
while(Ret < nItems)
|
||||||
{
|
{
|
||||||
pHklBuff[Ret] = pKbl->hkl;
|
if(!(pKbl->Flags & KBL_UNLOAD))
|
||||||
Ret++;
|
{
|
||||||
pKbl = (PKBL) pKbl->List.Flink;
|
pHklBuff[Ret] = pKbl->hkl;
|
||||||
if(pKbl == KBLList) break;
|
Ret++;
|
||||||
|
pKbl = (PKBL) pKbl->List.Flink;
|
||||||
|
if(pKbl == KBLList) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -457,18 +501,21 @@ NtUserLoadKeyboardLayoutEx(
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
//Let's see if layout was already loaded.
|
||||||
Cur = KBLList;
|
Cur = KBLList;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if(Cur->klid == dwKLID)
|
if(Cur->klid == dwKLID)
|
||||||
{
|
{
|
||||||
pKbl = Cur;
|
pKbl = Cur;
|
||||||
|
pKbl->Flags &= ~KBL_UNLOAD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cur = (PKBL) Cur->List.Flink;
|
Cur = (PKBL) Cur->List.Flink;
|
||||||
} while(Cur != KBLList);
|
} while(Cur != KBLList);
|
||||||
|
|
||||||
|
//It wasn't, so load it.
|
||||||
if(!pKbl)
|
if(!pKbl)
|
||||||
{
|
{
|
||||||
pKbl = UserLoadDllAndCreateKbl(dwKLID);
|
pKbl = UserLoadDllAndCreateKbl(dwKLID);
|
||||||
|
@ -485,14 +532,14 @@ NtUserLoadKeyboardLayoutEx(
|
||||||
|
|
||||||
if(Flags & KLF_ACTIVATE)
|
if(Flags & KLF_ACTIVATE)
|
||||||
{
|
{
|
||||||
co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl);
|
co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ret = pKbl->hkl;
|
Ret = pKbl->hkl;
|
||||||
|
|
||||||
//FIXME: Respect Flags!
|
//FIXME: KLF_NOTELLSHELL
|
||||||
// KLF_NOTELLSHELL KLF_SETFORPROCESS
|
// KLF_REPLACELANG
|
||||||
// KLF_REPLACELANG KLF_SUBSTITUTE_OK
|
// KLF_SUBSTITUTE_OK
|
||||||
|
|
||||||
the_end:
|
the_end:
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
@ -530,7 +577,6 @@ NtUserActivateKeyboardLayout(
|
||||||
else pKbl = UserHklToKbl(hKl);
|
else pKbl = UserHklToKbl(hKl);
|
||||||
|
|
||||||
//FIXME: KLF_RESET, KLF_SHIFTLOCK
|
//FIXME: KLF_RESET, KLF_SHIFTLOCK
|
||||||
//FIXME: KLF_SETFORPROCESS
|
|
||||||
|
|
||||||
if(pKbl)
|
if(pKbl)
|
||||||
{
|
{
|
||||||
|
@ -543,15 +589,41 @@ NtUserActivateKeyboardLayout(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pKbl = co_UserActivateKbl(pWThread, pKbl);
|
pKbl = co_UserActivateKbl(pWThread, pKbl, Flags);
|
||||||
Ret = pKbl->hkl;
|
Ret = pKbl->hkl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);
|
||||||
|
}
|
||||||
|
|
||||||
the_end:
|
the_end:
|
||||||
UserLeave();
|
UserLeave();
|
||||||
return Ret;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -616,16 +616,6 @@ NtUserTrackMouseEvent(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
|
||||||
STDCALL
|
|
||||||
NtUserUnloadKeyboardLayout(
|
|
||||||
DWORD Unknown0)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
|
|
Loading…
Reference in a new issue