[ros-diffs] [tretiakov] 26233: Implement NtUserUnloadKeyboardLayout()

tretiakov at svn.reactos.org tretiakov at svn.reactos.org
Sun Apr 1 19:30:45 CEST 2007


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/ntuser.h?rev=26233&r1=26232&r2=26233&view=diff
==============================================================================
--- 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/include/input.h?rev=26233&r1=26232&r2=26233&view=diff
==============================================================================
--- 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/ntuser/kbdlayout.c?rev=26233&r1=26232&r2=26233&view=diff
==============================================================================
--- 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/ntuser/ntstubs.c?rev=26233&r1=26232&r2=26233&view=diff
==============================================================================
--- 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




More information about the Ros-diffs mailing list