Aric Stewart : imm32: Use thread data from target HWND.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Feb 26 09:17:00 CST 2015


Module: wine
Branch: master
Commit: 455ca1adb08a87c01a7b044171c909176d8895cf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=455ca1adb08a87c01a7b044171c909176d8895cf

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Feb 25 11:45:22 2015 -0600

imm32: Use thread data from target HWND.

---

 dlls/imm32/imm.c         | 39 +++++++++++++++++++++++++++++----------
 dlls/imm32/tests/imm32.c | 21 ++++++++++++++-------
 2 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index db5939c..2b3804e 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -246,6 +246,21 @@ static IMMThreadData* IMM_GetThreadData(DWORD id)
     return data;
 }
 
+static IMMThreadData* IMM_GetThreadDataForWindow(HWND hwnd)
+{
+    DWORD process;
+    DWORD thread = 0;
+
+    if (hwnd)
+    {
+        thread = GetWindowThreadProcessId(hwnd, &process);
+        if (process != GetCurrentProcessId())
+            return NULL;
+    }
+
+    return IMM_GetThreadData(thread);
+}
+
 static BOOL IMM_IsDefaultContext(HIMC imc)
 {
     InputContextData *data = get_imc_data(imc);
@@ -478,21 +493,21 @@ static InputContextData* get_imc_data(HIMC hIMC)
     return data;
 }
 
-static IMMThreadData* IMM_GetInitializedThreadData(void)
+static IMMThreadData* IMM_GetInitializedThreadData(HWND hWnd)
 {
-    IMMThreadData* thread_data = IMM_GetThreadData(0);
+    IMMThreadData* thread_data = IMM_GetThreadDataForWindow(hWnd);
 
     if (!thread_data)
         return NULL;
 
-    if (!thread_data->defaultContext)
+    if (!thread_data->defaultContext && thread_data->threadID == GetCurrentThreadId())
     {
         HIMC defaultContext;
         LeaveCriticalSection(&threaddata_cs);
         defaultContext = ImmCreateContext();
         if (defaultContext)
             ((InputContextData*)defaultContext)->threadDefault = TRUE;
-        thread_data = IMM_GetThreadData(0);
+        thread_data = IMM_GetThreadDataForWindow(hWnd);
         if (!thread_data)
         {
             IMM_DestroyContext(defaultContext);
@@ -528,7 +543,7 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
     if (hIMC && data->IMC.hWnd == hWnd)
         return hIMC;
 
-    thread_data = IMM_GetInitializedThreadData();
+    thread_data = IMM_GetInitializedThreadData(hWnd);
     if (!thread_data)
         return NULL;
 
@@ -603,7 +618,7 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
 
     TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags);
 
-    thread_data = IMM_GetInitializedThreadData();
+    thread_data = IMM_GetInitializedThreadData(hWnd);
     if (!thread_data)
         return FALSE;
 
@@ -1470,7 +1485,7 @@ HIMC WINAPI ImmGetContext(HWND hWnd)
         return NULL;
     }
 
-    thread_data = IMM_GetInitializedThreadData();
+    thread_data = IMM_GetInitializedThreadData(hWnd);
     if (!thread_data)
         return NULL;
 
@@ -1595,18 +1610,21 @@ BOOL WINAPI ImmGetConversionStatus(
 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
 {
     HWND ret, new = NULL;
-    IMMThreadData* thread_data = IMM_GetThreadData(0);
+    IMMThreadData* thread_data = IMM_GetThreadDataForWindow(hWnd);
     if (!thread_data)
         return NULL;
-    if (thread_data->hwndDefault == NULL)
+    if (thread_data->hwndDefault == NULL && thread_data->threadID == GetCurrentThreadId())
     {
         /* Do not create the window inside of a critical section */
         LeaveCriticalSection(&threaddata_cs);
         new = CreateWindowExW( WS_EX_TOOLWINDOW,
                     szwIME, NULL, WS_POPUP, 0, 0, 1, 1, 0, 0, 0, 0);
-        thread_data = IMM_GetThreadData(0);
+        thread_data = IMM_GetThreadDataForWindow(hWnd);
         if (!thread_data)
+        {
+            DestroyWindow(new);
             return NULL;
+        }
         /* See if anyone beat us */
         if (thread_data->hwndDefault == NULL)
         {
@@ -1622,6 +1640,7 @@ HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
     {
         DestroyWindow(new);
     }
+    TRACE("Default is %p\n",ret);
     return ret;
 }
 
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c
index d434648..34e82c6 100644
--- a/dlls/imm32/tests/imm32.c
+++ b/dlls/imm32/tests/imm32.c
@@ -425,15 +425,17 @@ static DWORD WINAPI ImmGetContextThreadFunc( LPVOID lpParam)
     HWND hwnd2;
     COMPOSITIONFORM cf;
     POINT pt;
+    MSG msg;
+
     igc_threadinfo *info= (igc_threadinfo*)lpParam;
     info->hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
                                  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                                  240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
 
     h1 = ImmGetContext(hwnd);
-    todo_wine ok(info->himc == h1, "hwnd context changed in new thread\n");
+    ok(info->himc == h1, "hwnd context changed in new thread\n");
     h2 = ImmGetContext(info->hwnd);
-    todo_wine ok(h2 != h1, "new hwnd in new thread should have different context\n");
+    ok(h2 != h1, "new hwnd in new thread should have different context\n");
     info->himc = h2;
     ImmReleaseContext(hwnd,h1);
 
@@ -452,7 +454,12 @@ static DWORD WINAPI ImmGetContextThreadFunc( LPVOID lpParam)
     ImmSetStatusWindowPos(h1, &pt);
 
     SetEvent(info->event);
-    Sleep(INFINITE);
+
+    while(GetMessageW(&msg, 0, 0, 0))
+    {
+        TranslateMessage(&msg);
+        DispatchMessageW(&msg);
+    }
     return 1;
 }
 
@@ -477,8 +484,8 @@ static void test_ImmThreads(void)
 
     otherHimc = ImmGetContext(threadinfo.hwnd);
 
-    todo_wine ok(himc != otherHimc, "Windows from other threads should have different himc\n");
-    todo_wine ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n");
+    ok(himc != otherHimc, "Windows from other threads should have different himc\n");
+    ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n");
 
     if (0) /* FIXME: Causes wine to hang */
     {
@@ -566,7 +573,7 @@ static void test_ImmThreads(void)
     ok (rc == 1, "ImmGetCandidateWindow should succeed\n");
 
     rc = ImmGetCandidateWindow(otherHimc, 0, &cdf);
-    todo_wine ok (rc == 0, "ImmGetCandidateWindow should fail\n");
+    ok (rc == 0, "ImmGetCandidateWindow should fail\n");
     rc = ImmSetCandidateWindow(otherHimc, &cdf);
     todo_wine ok (rc == 0, "ImmSetCandidateWindow should fail\n");
 
@@ -577,7 +584,7 @@ static void test_ImmThreads(void)
     TerminateThread(hThread, 1);
 
     himc = ImmGetContext(GetDesktopWindow());
-    todo_wine ok(himc == NULL, "Should not be able to get himc from other process window\n");
+    ok(himc == NULL, "Should not be able to get himc from other process window\n");
 }
 
 static void test_ImmIsUIMessage(void)




More information about the wine-cvs mailing list