Author: tretiakov
Date: Sun Apr 1 21:30:44 2007
New Revision: 26233
URL:
http://svn.reactos.org/svn/reactos?rev=26233&view=rev
Log:
Implement NtUserUnloadKeyboardLayout()
Modified:
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/input.h
trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c
trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Sun Apr 1 21:30:44 2007
@@ -1923,10 +1923,10 @@
NtUserUnhookWinEvent(
DWORD Unknown0);
-DWORD
+BOOL
NTAPI
NtUserUnloadKeyboardLayout(
- DWORD Unknown0);
+ HKL hKl);
BOOL
NTAPI
Modified: trunk/reactos/subsystems/win32/win32k/include/input.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/input.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/input.h Sun Apr 1 21:30:44 2007
@@ -15,8 +15,9 @@
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);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c Sun Apr 1 21:30:44 2007
@@ -156,7 +156,7 @@
RtlFreeUnicodeString(&LayoutFile);
*phModule = EngLoadImage(FullLayoutPath.Buffer);
-
+
if(*phModule)
{
DPRINT("Loaded %wZ\n", &FullLayoutPath);
@@ -262,6 +262,8 @@
}
}
+ KBLList->Flags |= KBL_PRELOAD;
+
InitializeListHead(&KBLList->List);
return TRUE;
}
@@ -318,17 +320,56 @@
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 @@
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 @@
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 @@
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 @@
else pKbl = UserHklToKbl(hKl);
//FIXME: KLF_RESET, KLF_SHIFTLOCK
- //FIXME: KLF_SETFORPROCESS
if(pKbl)
{
@@ -543,9 +589,13 @@
}
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:
@@ -553,5 +603,27 @@
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 */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c Sun Apr 1 21:30:44 2007
@@ -616,16 +616,6 @@
return 0;
}
-DWORD
-STDCALL
-NtUserUnloadKeyboardLayout(
- DWORD Unknown0)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
DWORD
STDCALL