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/ntus... ============================================================================== --- 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/inc... ============================================================================== --- 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/ntu... ============================================================================== --- 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/ntu... ============================================================================== --- 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