From 455ca1adb08a87c01a7b044171c909176d8895cf Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Wed, 25 Feb 2015 11:45:22 -0600 Subject: [PATCH] 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 db5939ced3d..2b3804e6337 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 d43464870ce..34e82c68c5a 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)