https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92393a75176f0f49f33b90333ebc78afeaf49ba0

commit 92393a75176f0f49f33b90333ebc78afeaf49ba0
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Jul 11 09:48:15 2021 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Jul 11 09:48:15 2021 +0900

    [IMM32] Add some candidate handlings (#3799)
    
    - Implement ImmGetCandidateListA and ImmGetCandidateListW, by using newly 
added ImmGetCandidateListAW function.
    - Implement ImmLockClientImc and ImmUnlockClientImc functions.
    - Modify imm32.spec.
    - Remove #ifdef's.
    CORE-11700
---
 dll/win32/imm32/imm.c             | 563 +++++++++++++++++++++++---------------
 dll/win32/imm32/imm32.spec        |   4 +-
 media/doc/WINESYNC.txt            |   2 +-
 sdk/include/reactos/imm32_undoc.h |  20 +-
 win32ss/include/ntuser.h          |   7 +-
 win32ss/user/ntuser/misc.c        |   3 +
 win32ss/user/ntuser/ntstubs.c     |   6 +-
 7 files changed, 373 insertions(+), 232 deletions(-)

diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index e26e6872f3c..e7ad9746680 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -22,28 +22,25 @@
 #include <stdarg.h>
 #include <stdio.h>
 
-#ifdef __REACTOS__
 #define WIN32_NO_STATUS
-#endif
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imm.h"
-#include "ddk/imm.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "wine/list.h"
-#ifdef __REACTOS__
+#include <windef.h>
+#include <winbase.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include <winerror.h>
+#include <wine/debug.h>
+#include <imm.h>
+#include <ddk/imm.h>
+#include <winnls.h>
+#include <winreg.h>
+#include <wine/list.h>
 #include <stdlib.h>
 #include <ndk/umtypes.h>
 #include <ndk/pstypes.h>
+#include <ndk/rtlfuncs.h>
 #include "../../../win32ss/include/ntuser.h"
 #include <imm32_undoc.h>
 #include <strsafe.h>
-#endif
 
 WINE_DEFAULT_DEBUG_CHANNEL(imm);
 
@@ -853,19 +850,7 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
  */
 BOOL WINAPI ImmDisableIME(DWORD idThread)
 {
-#ifdef __REACTOS__
     return NtUserDisableThreadIme(idThread);
-#else
-    if (idThread == (DWORD)-1)
-        disable_ime = TRUE;
-    else {
-        IMMThreadData *thread_data = IMM_GetThreadData(NULL, idThread);
-        if (!thread_data) return FALSE;
-        thread_data->disableIME = TRUE;
-        LeaveCriticalSection(&threaddata_cs);
-    }
-    return TRUE;
-#endif
 }
 
 /***********************************************************************
@@ -1017,45 +1002,323 @@ LRESULT WINAPI ImmEscapeW(
         return 0;
 }
 
-/***********************************************************************
- *             ImmGetCandidateListA (IMM32.@)
- */
-DWORD WINAPI ImmGetCandidateListA(
-  HIMC hIMC, DWORD dwIndex,
-  LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+#define ROUNDUP4(n) (((n) + 3) & ~3)  /* DWORD alignment */
+
+HANDLE g_hImm32Heap = NULL;
+
+LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes)
+{
+    if (!g_hImm32Heap)
+    {
+        g_hImm32Heap = GetProcessHeap(); // FIXME: Use TEB
+        if (g_hImm32Heap == NULL)
+            return NULL;
+    }
+    return HeapAlloc(g_hImm32Heap, dwFlags, dwBytes);
+}
+
+static DWORD_PTR APIENTRY
+Imm32GetThreadState(DWORD Routine)
+{
+    return NtUserGetThreadState(Routine);
+}
+
+static DWORD APIENTRY
+Imm32UpdateInputContext(HIMC hIMC, DWORD Unknown1, PCLIENTIMC pClientImc)
+{
+    return NtUserUpdateInputContext(hIMC, Unknown1, pClientImc);
+}
+
+static PCLIENTIMC APIENTRY Imm32GetClientImcCache(void)
+{
+    // FIXME: Do something properly here
+    return NULL;
+}
+
+PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
+{
+    PCLIENTIMC pClientImc;
+
+    TRACE("ImmLockClientImc(%p)\n", hImc);
+
+    if (hImc == NULL)
+        return NULL;
+
+    pClientImc = Imm32GetClientImcCache();
+    if (!pClientImc)
+    {
+        pClientImc = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
+        if (!pClientImc)
+            return NULL;
+
+        RtlInitializeCriticalSection(&pClientImc->cs);
+        pClientImc->unknown = Imm32GetThreadState(THREADSTATE_UNKNOWN13);
+
+        if (!Imm32UpdateInputContext(hImc, 0, pClientImc))
+        {
+            HeapFree(g_hImm32Heap, 0, pClientImc);
+            return NULL;
+        }
+
+        pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
+    }
+    else
+    {
+        if (pClientImc->dwFlags & CLIENTIMC_DISABLED)
+            return NULL;
+    }
+
+    InterlockedIncrement(&pClientImc->cLockObj);
+    return pClientImc;
+}
+
+VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
+{
+    LONG cLocks;
+    HIMC hImc;
+
+    TRACE("ImmUnlockClientImc(%p)\n", pClientImc);
+
+    cLocks = InterlockedDecrement(&pClientImc->cLockObj);
+    if (cLocks != 0 || (pClientImc->dwFlags & CLIENTIMC_DISABLED))
+        return;
+
+    hImc = pClientImc->hImc;
+    if (hImc)
+        LocalFree(hImc);
+
+    RtlDeleteCriticalSection(&pClientImc->cs);
+    HeapFree(g_hImm32Heap, 0, pClientImc);
+}
+
+static DWORD APIENTRY
+CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, 
DWORD dwBufLen,
+                        UINT uCodePage)
+{
+    BOOL bUsedDefault;
+    DWORD dwSize, dwIndex, cbGot, cbLeft;
+    const BYTE *pbWide;
+    LPBYTE pbAnsi;
+    LPDWORD pibOffsets;
+
+    /* calculate total ansi size */
+    if (pWideCL->dwCount > 0)
+    {
+        dwSize = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * 
sizeof(DWORD));
+        for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex)
+        {
+            pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex];
+            cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1, 
NULL, 0,
+                                        NULL, &bUsedDefault);
+            dwSize += cbGot;
+        }
+    }
+    else
+    {
+        dwSize = sizeof(CANDIDATELIST);
+    }
+
+    dwSize = ROUNDUP4(dwSize);
+    if (dwBufLen == 0)
+        return dwSize;
+    if (dwBufLen < dwSize)
+        return 0;
+
+    /* store to ansi */
+    pAnsiCL->dwSize = dwBufLen;
+    pAnsiCL->dwStyle = pWideCL->dwStyle;
+    pAnsiCL->dwCount = pWideCL->dwCount;
+    pAnsiCL->dwSelection = pWideCL->dwSelection;
+    pAnsiCL->dwPageStart = pWideCL->dwPageStart;
+    pAnsiCL->dwPageSize = pWideCL->dwPageSize;
+
+    pibOffsets = pAnsiCL->dwOffset;
+    if (pWideCL->dwCount > 0)
+    {
+        pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * 
sizeof(DWORD));
+        cbLeft = dwBufLen - pibOffsets[0];
+
+        for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex)
+        {
+            pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex];
+            pbAnsi = (LPBYTE)pAnsiCL + pibOffsets[dwIndex];
+
+            /* convert to ansi */
+            cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1,
+                                        (LPSTR)pbAnsi, cbLeft, NULL, 
&bUsedDefault);
+            cbLeft -= cbGot;
+
+            if (dwIndex < pWideCL->dwCount - 1)
+                pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot;
+        }
+    }
+    else
+    {
+        pibOffsets[0] = sizeof(CANDIDATELIST);
+    }
+
+    return dwBufLen;
+}
+
+static DWORD APIENTRY
+CandidateListAnsiToWide(const CANDIDATELIST *pAnsiCL, LPCANDIDATELIST pWideCL, 
DWORD dwBufLen,
+                        UINT uCodePage)
+{
+    DWORD dwSize, dwIndex, cchGot, cbGot, cbLeft;
+    const BYTE *pbAnsi;
+    LPBYTE pbWide;
+    LPDWORD pibOffsets;
+
+    /* calculate total wide size */
+    if (pAnsiCL->dwCount > 0)
+    {
+        dwSize = sizeof(CANDIDATELIST) + ((pAnsiCL->dwCount - 1) * 
sizeof(DWORD));
+        for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex)
+        {
+            pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex];
+            cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, 
(LPCSTR)pbAnsi, -1, NULL, 0);
+            dwSize += cchGot * sizeof(WCHAR);
+        }
+    }
+    else
+    {
+        dwSize = sizeof(CANDIDATELIST);
+    }
+
+    dwSize = ROUNDUP4(dwSize);
+    if (dwBufLen == 0)
+        return dwSize;
+    if (dwBufLen < dwSize)
+        return 0;
+
+    /* store to wide */
+    pWideCL->dwSize = dwBufLen;
+    pWideCL->dwStyle = pAnsiCL->dwStyle;
+    pWideCL->dwCount = pAnsiCL->dwCount;
+    pWideCL->dwSelection = pAnsiCL->dwSelection;
+    pWideCL->dwPageStart = pAnsiCL->dwPageStart;
+    pWideCL->dwPageSize = pAnsiCL->dwPageSize;
+
+    pibOffsets = pWideCL->dwOffset;
+    if (pAnsiCL->dwCount > 0)
+    {
+        pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * 
sizeof(DWORD));
+        cbLeft = dwBufLen - pibOffsets[0];
+
+        for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex)
+        {
+            pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex];
+            pbWide = (LPBYTE)pWideCL + pibOffsets[dwIndex];
+
+            /* convert to wide */
+            cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, 
(LPCSTR)pbAnsi, -1,
+                                         (LPWSTR)pbWide, cbLeft / 
sizeof(WCHAR));
+            cbGot = cchGot * sizeof(WCHAR);
+            cbLeft -= cbGot;
+
+            if (dwIndex + 1 < pAnsiCL->dwCount)
+                pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot;
+        }
+    }
+    else
+    {
+        pibOffsets[0] = sizeof(CANDIDATELIST);
+    }
+
+    return dwBufLen;
+}
+
+static DWORD APIENTRY
+ImmGetCandidateListAW(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, 
DWORD dwBufLen,
+                      BOOL bAnsi)
 {
-    InputContextData *data = get_imc_data(hIMC);
-    LPCANDIDATEINFO candinfo;
-    LPCANDIDATELIST candlist;
     DWORD ret = 0;
+    LPINPUTCONTEXT pIC;
+    PCLIENTIMC pClientImc;
+    LPCANDIDATEINFO pCI;
+    LPCANDIDATELIST pCL;
+    DWORD dwSize;
 
-    TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
+    pClientImc = ImmLockClientImc(hIMC);
+    if (!pClientImc)
+        return 0;
 
-    if (!data || !data->IMC.hCandInfo)
-       return 0;
+    pIC = ImmLockIMC(hIMC);
+    if (pIC == NULL)
+    {
+        ImmUnlockClientImc(pClientImc);
+        return 0;
+    }
 
-    candinfo = ImmLockIMCC(data->IMC.hCandInfo);
-    if (dwIndex >= candinfo->dwCount || dwIndex >= 
ARRAY_SIZE(candinfo->dwOffset))
-        goto done;
+    pCI = ImmLockIMCC(pIC->hCandInfo);
+    if (pCI == NULL)
+    {
+        ImmUnlockIMC(hIMC);
+        ImmUnlockClientImc(pClientImc);
+        return 0;
+    }
 
-    candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + 
candinfo->dwOffset[dwIndex]);
-    if ( !candlist->dwSize || !candlist->dwCount )
-        goto done;
+    if (pCI->dwSize < sizeof(CANDIDATEINFO) || pCI->dwCount <= dwIndex)
+        goto Quit;
 
-    if ( !is_himc_ime_unicode(data) )
+    /* get required size */
+    pCL = (LPCANDIDATELIST)((LPBYTE)pCI + pCI->dwOffset[dwIndex]);
+    if (bAnsi)
     {
-        ret = candlist->dwSize;
-        if ( lpCandList && dwBufLen >= ret )
-            memcpy(lpCandList, candlist, ret);
+        if (pClientImc->dwFlags & CLIENTIMC_WIDE)
+            dwSize = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP);
+        else
+            dwSize = pCL->dwSize;
     }
     else
-        ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
+    {
+        if (pClientImc->dwFlags & CLIENTIMC_WIDE)
+            dwSize = pCL->dwSize;
+        else
+            dwSize = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP);
+    }
 
-done:
-    ImmUnlockIMCC(data->IMC.hCandInfo);
+    if (dwBufLen != 0 && dwSize != 0)
+    {
+        if (lpCandList == NULL || dwBufLen < dwSize)
+            goto Quit;
+
+        /* store */
+        if (bAnsi)
+        {
+            if (pClientImc->dwFlags & CLIENTIMC_WIDE)
+                CandidateListAnsiToWide(pCL, lpCandList, dwSize, CP_ACP);
+            else
+                RtlCopyMemory(lpCandList, pCL, dwSize);
+        }
+        else
+        {
+            if (pClientImc->dwFlags & CLIENTIMC_WIDE)
+                RtlCopyMemory(lpCandList, pCL, dwSize);
+            else
+                CandidateListWideToAnsi(pCL, lpCandList, dwSize, CP_ACP);
+        }
+    }
+
+    ret = dwSize;
+
+Quit:
+    ImmUnlockIMCC(pIC->hCandInfo);
+    ImmUnlockIMC(hIMC);
+    ImmUnlockClientImc(pClientImc);
     return ret;
 }
 
+/***********************************************************************
+ *             ImmGetCandidateListA (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListA(
+  HIMC hIMC, DWORD dwIndex,
+  LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+{
+    return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, TRUE);
+}
+
 /***********************************************************************
  *             ImmGetCandidateListCountA (IMM32.@)
  */
@@ -1127,36 +1390,7 @@ DWORD WINAPI ImmGetCandidateListW(
   HIMC hIMC, DWORD dwIndex,
   LPCANDIDATELIST lpCandList, DWORD dwBufLen)
 {
-    InputContextData *data = get_imc_data(hIMC);
-    LPCANDIDATEINFO candinfo;
-    LPCANDIDATELIST candlist;
-    DWORD ret = 0;
-
-    TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
-
-    if (!data || !data->IMC.hCandInfo)
-       return 0;
-
-    candinfo = ImmLockIMCC(data->IMC.hCandInfo);
-    if (dwIndex >= candinfo->dwCount || dwIndex >= 
ARRAY_SIZE(candinfo->dwOffset))
-        goto done;
-
-    candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + 
candinfo->dwOffset[dwIndex]);
-    if ( !candlist->dwSize || !candlist->dwCount )
-        goto done;
-
-    if ( is_himc_ime_unicode(data) )
-    {
-        ret = candlist->dwSize;
-        if ( lpCandList && dwBufLen >= ret )
-            memcpy(lpCandList, candlist, ret);
-    }
-    else
-        ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
-
-done:
-    ImmUnlockIMCC(data->IMC.hCandInfo);
-    return ret;
+    return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, FALSE);
 }
 
 /***********************************************************************
@@ -1641,7 +1875,6 @@ DWORD WINAPI ImmGetConversionListW(
 BOOL WINAPI ImmGetConversionStatus(
   HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
 {
-#ifdef __REACTOS__
     LPINPUTCONTEXT pIC;
 
     TRACE("ImmGetConversionStatus(%p %p %p)\n", hIMC, lpfdwConversion, 
lpfdwSentence);
@@ -1657,21 +1890,6 @@ BOOL WINAPI ImmGetConversionStatus(
 
     ImmUnlockIMC(hIMC);
     return TRUE;
-#else
-    InputContextData *data = get_imc_data(hIMC);
-
-    TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
-
-    if (!data)
-        return FALSE;
-
-    if (lpfdwConversion)
-        *lpfdwConversion = data->IMC.fdwConversion;
-    if (lpfdwSentence)
-        *lpfdwSentence = data->IMC.fdwSentence;
-
-    return TRUE;
-#endif
 }
 
 static BOOL needs_ime_window(HWND hwnd)
@@ -1786,13 +2004,12 @@ HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
 UINT WINAPI ImmGetDescriptionA(
   HKL hKL, LPSTR lpszDescription, UINT uBufLen)
 {
-#ifdef __REACTOS__
     IMEINFOEX info;
     size_t cch;
 
     TRACE("ImmGetDescriptionA(%p,%p,%d)\n", hKL, lpszDescription, uBufLen);
 
-    if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || 
!IS_IME_KBDLAYOUT(hKL))
+    if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || 
!IS_IME_HKL(hKL))
         return 0;
 
     StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), 
&cch);
@@ -1801,36 +2018,6 @@ UINT WINAPI ImmGetDescriptionA(
     if (uBufLen)
         lpszDescription[cch] = 0;
     return cch;
-#else
-  WCHAR *buf;
-  DWORD len;
-
-  TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
-
-  /* find out how many characters in the unicode buffer */
-  len = ImmGetDescriptionW( hKL, NULL, 0 );
-  if (!len)
-    return 0;
-
-  /* allocate a buffer of that size */
-  buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
-  if( !buf )
-  return 0;
-
-  /* fetch the unicode buffer */
-  len = ImmGetDescriptionW( hKL, buf, len + 1 );
-
-  /* convert it back to ASCII */
-  len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
-                             lpszDescription, uBufLen, NULL, NULL );
-
-  HeapFree( GetProcessHeap(), 0, buf );
-
-  if (len == 0)
-    return 0;
-
-  return len - 1;
-#endif
 }
 
 /***********************************************************************
@@ -1838,13 +2025,12 @@ UINT WINAPI ImmGetDescriptionA(
  */
 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
 {
-#ifdef __REACTOS__
     IMEINFOEX info;
     size_t cch;
 
     TRACE("ImmGetDescriptionW(%p, %p, %d)\n", hKL, lpszDescription, uBufLen);
 
-    if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || 
!IS_IME_KBDLAYOUT(hKL))
+    if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || 
!IS_IME_HKL(hKL))
         return 0;
 
     if (uBufLen != 0)
@@ -1852,16 +2038,6 @@ UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR 
lpszDescription, UINT uBufLen)
 
     StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), 
&cch);
     return (UINT)cch;
-#else
-  static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
-
-  FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
-
-  if (!hKL) return 0;
-  if (!uBufLen) return lstrlenW( name );
-  lstrcpynW( lpszDescription, name, uBufLen );
-  return lstrlenW( lpszDescription );
-#endif
 }
 
 /***********************************************************************
@@ -1973,7 +2149,6 @@ UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR 
lpszFileName, UINT uBufLen)
  */
 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
 {
-#ifdef __REACTOS__
     BOOL ret;
     LPINPUTCONTEXT pIC;
 
@@ -1990,20 +2165,6 @@ BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
 
     ImmUnlockIMC(hIMC);
     return ret;
-#else
-  InputContextData *data = get_imc_data(hIMC);
-  static int i;
-
-    if (!data)
-        return FALSE;
-
-    TRACE("(%p): semi-stub\n", hIMC);
-
-    if (!i++)
-      FIXME("(%p): semi-stub\n", hIMC);
-
-  return data->IMC.fOpen;
-#endif
 }
 
 /***********************************************************************
@@ -2219,16 +2380,9 @@ HKL WINAPI ImmInstallIMEW(
  */
 BOOL WINAPI ImmIsIME(HKL hKL)
 {
-#ifdef __REACTOS__
     IMEINFOEX info;
     TRACE("ImmIsIME(%p)\n", hKL);
     return !!ImmGetImeInfoEx(&info, ImeInfoExImeWindow, &hKL);
-#else
-    ImmHkl *ptr;
-    TRACE("(%p):\n", hKL);
-    ptr = IMM_GetImmHkl(hKL);
-    return (ptr && ptr->hIME);
-#endif
 }
 
 /***********************************************************************
@@ -2759,14 +2913,8 @@ HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT 
hOwner, int x, int y)
  */
 BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
 {
-#ifdef __REACTOS__
     TRACE("(%p)\n", hSoftWnd);
     return DestroyWindow(hSoftWnd);
-#else
-    FIXME("(%p): stub\n", hSoftWnd);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
-#endif
 }
 
 /***********************************************************************
@@ -2774,14 +2922,9 @@ BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
  */
 BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
 {
-#ifdef __REACTOS__
     TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
     if (hSoftWnd)
         return ShowWindow(hSoftWnd, nCmdShow);
-#else
-    FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-#endif
     return FALSE;
 }
 
@@ -3013,12 +3156,19 @@ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
 */
 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
 {
-    InputContextData *data = get_imc_data(hIMC);
+    PCLIENTIMC pClientIMC;
+    HIMC hClientImc;
 
-    if (!data)
+    pClientIMC = ImmLockClientImc(hIMC);
+    if (pClientIMC == NULL)
         return FALSE;
-    if (data->dwLock)
-        data->dwLock--;
+
+    hClientImc = pClientIMC->hImc;
+    if (hClientImc)
+        LocalUnlock(hClientImc);
+
+    InterlockedDecrement(&pClientIMC->cLockObj);
+    ImmUnlockClientImc(pClientIMC);
     return TRUE;
 }
 
@@ -3027,10 +3177,21 @@ BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
 */
 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
 {
-    InputContextData *data = get_imc_data(hIMC);
-    if (!data)
+    DWORD ret;
+    HIMC hClientImc;
+    PCLIENTIMC pClientImc;
+
+    pClientImc = ImmLockClientImc(hIMC);
+    if (pClientImc == NULL)
         return 0;
-    return data->dwLock;
+
+    ret = 0;
+    hClientImc = pClientImc->hImc;
+    if (hClientImc)
+        ret = (LocalFlags(hClientImc) & LMEM_LOCKCOUNT);
+
+    ImmUnlockClientImc(pClientImc);
+    return ret;
 }
 
 /***********************************************************************
@@ -3038,13 +3199,9 @@ DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
 */
 HIMCC  WINAPI ImmCreateIMCC(DWORD size)
 {
-#ifdef __REACTOS__
     if (size < 4)
         size = 4;
     return LocalAlloc(LHND, size);
-#else
-    return GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, size);
-#endif
 }
 
 /***********************************************************************
@@ -3052,13 +3209,9 @@ HIMCC  WINAPI ImmCreateIMCC(DWORD size)
 */
 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
 {
-#ifdef __REACTOS__
     if (block)
         return LocalFree(block);
     return NULL;
-#else
-    return GlobalFree(block);
-#endif
 }
 
 /***********************************************************************
@@ -3066,13 +3219,9 @@ HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
 */
 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
 {
-#ifdef __REACTOS__
     if (imcc)
         return LocalLock(imcc);
     return NULL;
-#else
-    return GlobalLock(imcc);
-#endif
 }
 
 /***********************************************************************
@@ -3080,13 +3229,9 @@ LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
 */
 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
 {
-#ifdef __REACTOS__
     if (imcc)
         return LocalUnlock(imcc);
     return FALSE;
-#else
-    return GlobalUnlock(imcc);
-#endif
 }
 
 /***********************************************************************
@@ -3094,11 +3239,7 @@ BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
 */
 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
 {
-#ifdef __REACTOS__
     return LocalFlags(imcc) & LMEM_LOCKCOUNT;
-#else
-    return GlobalFlags(imcc) & GMEM_LOCKCOUNT;
-#endif
 }
 
 /***********************************************************************
@@ -3106,13 +3247,9 @@ DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
 */
 HIMCC  WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
 {
-#ifdef __REACTOS__
     if (!imcc)
         return NULL;
     return LocalReAlloc(imcc, size, LHND);
-#else
-    return GlobalReAlloc(imcc, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
-#endif
 }
 
 /***********************************************************************
@@ -3120,13 +3257,9 @@ HIMCC  WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
 */
 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
 {
-#ifdef __REACTOS__
     if (imcc)
         return LocalSize(imcc);
     return 0;
-#else
-    return GlobalSize(imcc);
-#endif
 }
 
 /***********************************************************************
@@ -3302,7 +3435,6 @@ BOOL WINAPI ImmEnumInputContext(DWORD idThread, 
IMCENUMPROC lpfn, LPARAM lParam)
  *              ImmGetHotKey(IMM32.@)
  */
 
-#ifdef __REACTOS__
 BOOL WINAPI
 ImmGetHotKey(IN DWORD dwHotKey,
              OUT LPUINT lpuModifiers,
@@ -3314,13 +3446,6 @@ ImmGetHotKey(IN DWORD dwHotKey,
         return NtUserGetImeHotKey(dwHotKey, lpuModifiers, lpuVKey, lphKL);
     return FALSE;
 }
-#else
-BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl)
-{
-    FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl);
-    return FALSE;
-}
-#endif
 
 /***********************************************************************
  *              ImmDisableLegacyIME(IMM32.@)
@@ -3331,7 +3456,6 @@ BOOL WINAPI ImmDisableLegacyIME(void)
     return TRUE;
 }
 
-#ifdef __REACTOS__
 /***********************************************************************
  *              ImmSetActiveContext(IMM32.@)
  */
@@ -3392,4 +3516,3 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx,
     }
     return NtUserGetImeInfoEx(pImeInfoEx, SearchType);
 }
-#endif
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec
index b9c0fe55516..b41e2ee2049 100644
--- a/dll/win32/imm32/imm32.spec
+++ b/dll/win32/imm32/imm32.spec
@@ -68,7 +68,7 @@
 @ stdcall ImmIsUIMessageW(long long long long)
 @ stdcall -stub ImmLoadIME(long)
 @ stdcall -stub ImmLoadLayout(long ptr)
-@ stub ImmLockClientImc
+@ stdcall ImmLockClientImc(ptr)
 @ stdcall ImmLockIMC(ptr)
 @ stdcall ImmLockIMCC(ptr)
 @ stdcall -stub ImmLockImeDpi(long)
@@ -102,7 +102,7 @@
 @ stdcall ImmSimulateHotKey(ptr long)
 @ stdcall -stub ImmSystemHandler(ptr long long)
 @ stdcall ImmTranslateMessage(ptr long long long)
-@ stub ImmUnlockClientImc
+@ stdcall ImmUnlockClientImc(ptr)
 @ stdcall ImmUnlockIMC(ptr)
 @ stdcall ImmUnlockIMCC(ptr)
 @ stdcall -stub ImmUnlockImeDpi(ptr)
diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt
index 1b78cfd0cfd..6d3e209eb8c 100644
--- a/media/doc/WINESYNC.txt
+++ b/media/doc/WINESYNC.txt
@@ -79,7 +79,7 @@ dll/win32/iccvid              # Synced to WineStaging-4.0
 dll/win32/ieframe             # Synced to WineStaging-4.18
 dll/win32/imaadp32.acm        # Synced to WineStaging-4.0
 dll/win32/imagehlp            # Synced to WineStaging-4.18
-dll/win32/imm32               # Synced to WineStaging-4.18
+dll/win32/imm32               # Forked at WineStaging-4.18
 dll/win32/inetcomm            # Synced to WineStaging-4.18
 dll/win32/inetmib1            # Synced to WineStaging-4.18
 dll/win32/initpki             # Synced to WineStaging-4.18
diff --git a/sdk/include/reactos/imm32_undoc.h 
b/sdk/include/reactos/imm32_undoc.h
index 32858af1068..8332d6bfde9 100644
--- a/sdk/include/reactos/imm32_undoc.h
+++ b/sdk/include/reactos/imm32_undoc.h
@@ -7,9 +7,23 @@
 
 #pragma once
 
-#define KBDLAYOUT_MASK 0xF000
-#define KBDLAYOUT_IME 0xE000
-#define IS_IME_KBDLAYOUT(hKL) ((HIWORD(hKL) & KBDLAYOUT_MASK) == KBDLAYOUT_IME)
+/* unconfirmed */
+typedef struct tagCLIENTIMC
+{
+    HIMC hImc;
+    LONG cLockObj;
+    DWORD dwFlags;
+    DWORD unknown;
+    RTL_CRITICAL_SECTION cs;
+    DWORD unknown2;
+    DWORD unknown3;
+    BOOL bUnknown4;
+} CLIENTIMC, *PCLIENTIMC;
+
+/* flags for CLIENTIMC */
+#define CLIENTIMC_WIDE (1 << 0)
+#define CLIENTIMC_DISABLED (1 << 6)
+#define CLIENTIMC_UNKNOWN2 (1 << 8)
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index ff34bd12a5a..54499388337 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -2464,7 +2464,8 @@ enum ThreadStateRoutines
     THREADSTATE_UPTIMELASTREAD,
     THREADSTATE_FOREGROUNDTHREAD,
     THREADSTATE_GETCURSOR,
-    THREADSTATE_GETMESSAGEEXTRAINFO
+    THREADSTATE_GETMESSAGEEXTRAINFO,
+    THREADSTATE_UNKNOWN13
 };
 
 DWORD_PTR
@@ -3445,9 +3446,9 @@ NtUserUnregisterUserApiHook(VOID);
 DWORD
 NTAPI
 NtUserUpdateInputContext(
-    DWORD Unknown0,
+    HIMC hIMC,
     DWORD Unknown1,
-    DWORD Unknown2);
+    LPVOID pClientImc);
 
 DWORD
 NTAPI
diff --git a/win32ss/user/ntuser/misc.c b/win32ss/user/ntuser/misc.c
index c0e332b369e..f8c0d3e1ec3 100644
--- a/win32ss/user/ntuser/misc.c
+++ b/win32ss/user/ntuser/misc.c
@@ -314,6 +314,9 @@ NtUserGetThreadState(
       case THREADSTATE_GETMESSAGEEXTRAINFO:
          ret = (DWORD_PTR)MsqGetMessageExtraInfo();
         break;
+      case THREADSTATE_UNKNOWN13:
+         ret = FALSE; /* FIXME: See imm32 */
+         break;
    }
 
    TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);
diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c
index 44cbb5af3b2..87d2c3ed11a 100644
--- a/win32ss/user/ntuser/ntstubs.c
+++ b/win32ss/user/ntuser/ntstubs.c
@@ -356,9 +356,9 @@ NtUserSetSysColors(
 DWORD
 APIENTRY
 NtUserUpdateInputContext(
-   DWORD Unknown0,
-   DWORD Unknown1,
-   DWORD Unknown2)
+    HIMC hIMC,
+    DWORD Unknown1,
+    LPVOID pClientImc)
 {
    STUB
 

Reply via email to