Alexandre Julliard : imm32: Add a helper function to get the default context.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Feb 26 09:17:00 CST 2015
Module: wine
Branch: master
Commit: 29ce21e25de5495520e13a9d797edbd7bfb0f1cf
URL: http://source.winehq.org/git/wine.git/?a=commit;h=29ce21e25de5495520e13a9d797edbd7bfb0f1cf
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Feb 26 22:50:44 2015 +0900
imm32: Add a helper function to get the default context.
---
dlls/imm32/imm.c | 84 ++++++++++++++++++++++++++------------------------------
1 file changed, 39 insertions(+), 45 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index 3f5ad31..07ab598 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -494,34 +494,45 @@ static InputContextData* get_imc_data(HIMC hIMC)
return data;
}
-static IMMThreadData* IMM_GetInitializedThreadData(HWND hWnd)
+static HIMC get_default_context( HWND hwnd )
{
- IMMThreadData* thread_data = IMM_GetThreadDataForWindow(hWnd);
+ HIMC ret;
+ IMMThreadData* thread_data = IMM_GetThreadDataForWindow( hwnd );
- if (!thread_data)
- return NULL;
+ if (!thread_data) return 0;
- if (!thread_data->defaultContext && thread_data->threadID == GetCurrentThreadId())
+ if (thread_data->defaultContext)
{
- HIMC defaultContext;
+ ret = thread_data->defaultContext;
LeaveCriticalSection(&threaddata_cs);
- defaultContext = ImmCreateContext();
- if (defaultContext)
- ((InputContextData*)defaultContext)->threadDefault = TRUE;
- thread_data = IMM_GetThreadDataForWindow(hWnd);
- if (!thread_data)
- {
- IMM_DestroyContext(defaultContext);
- return NULL;
- }
+ return ret;
+ }
- if (thread_data->defaultContext) /* someone beat us */
- IMM_DestroyContext(defaultContext);
- else
- thread_data->defaultContext = defaultContext;
+ /* can't create a default context in another thread */
+ if (thread_data->threadID != GetCurrentThreadId())
+ {
+ LeaveCriticalSection(&threaddata_cs);
+ return 0;
}
- return thread_data;
+ LeaveCriticalSection(&threaddata_cs);
+
+ ret = ImmCreateContext();
+ if (!ret) return 0;
+ ((InputContextData*)ret)->threadDefault = TRUE;
+
+ /* thread_data is in the current thread so we can assume it's still valid */
+ EnterCriticalSection(&threaddata_cs);
+
+ if (thread_data->defaultContext) /* someone beat us */
+ {
+ IMM_DestroyContext( ret );
+ ret = thread_data->defaultContext;
+ }
+ else thread_data->defaultContext = ret;
+
+ LeaveCriticalSection(&threaddata_cs);
+ return ret;
}
static BOOL IMM_IsCrossThreadAccess(HWND hWnd, HIMC hIMC)
@@ -547,7 +558,6 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
{
HIMC old = NULL;
InputContextData *data = get_imc_data(hIMC);
- IMMThreadData* thread_data = NULL;
TRACE("(%p, %p):\n", hWnd, hIMC);
@@ -563,20 +573,17 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
if (hIMC && IMM_IsCrossThreadAccess(hWnd, hIMC))
return NULL;
- thread_data = IMM_GetInitializedThreadData(hWnd);
- if (!thread_data)
- return NULL;
-
if (hWnd)
{
+ HIMC defaultContext = get_default_context( hWnd );
old = RemovePropW(hWnd,szwWineIMCProperty);
if (old == NULL)
- old = thread_data->defaultContext;
+ old = defaultContext;
else if (old == (HIMC)-1)
old = NULL;
- if (hIMC != thread_data->defaultContext)
+ if (hIMC != defaultContext)
{
if (hIMC == NULL) /* Meaning disable imm for that window*/
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
@@ -591,7 +598,6 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
old_data->IMC.hWnd = NULL;
}
}
- LeaveCriticalSection(&threaddata_cs);
if (!hIMC)
return old;
@@ -633,18 +639,8 @@ static BOOL CALLBACK _ImmAssociateContextExEnumProc(HWND hwnd, LPARAM lParam)
*/
BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
{
- IMMThreadData* thread_data = NULL;
- HIMC defaultContext = NULL;
-
TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags);
- thread_data = IMM_GetInitializedThreadData(hWnd);
- if (!thread_data)
- return FALSE;
-
- defaultContext = thread_data->defaultContext;
- LeaveCriticalSection(&threaddata_cs);
-
if (!hWnd)
return FALSE;
@@ -654,8 +650,12 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
ImmAssociateContext(hWnd,hIMC);
return TRUE;
case IACE_DEFAULT:
+ {
+ HIMC defaultContext = get_default_context( hWnd );
+ if (!defaultContext) return FALSE;
ImmAssociateContext(hWnd,defaultContext);
return TRUE;
+ }
case IACE_IGNORENOCONTEXT:
if (GetPropW(hWnd,szwWineIMCProperty))
ImmAssociateContext(hWnd,hIMC);
@@ -1496,7 +1496,6 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
HIMC WINAPI ImmGetContext(HWND hWnd)
{
HIMC rc;
- IMMThreadData* thread_data;
TRACE("%p\n", hWnd);
@@ -1506,22 +1505,17 @@ HIMC WINAPI ImmGetContext(HWND hWnd)
return NULL;
}
- thread_data = IMM_GetInitializedThreadData(hWnd);
- if (!thread_data)
- return NULL;
-
rc = GetPropW(hWnd,szwWineIMCProperty);
if (rc == (HIMC)-1)
rc = NULL;
else if (rc == NULL)
- rc = thread_data->defaultContext;
+ rc = get_default_context( hWnd );
if (rc)
{
InputContextData *data = rc;
data->IMC.hWnd = hWnd;
}
- LeaveCriticalSection(&threaddata_cs);
TRACE("returning %p\n", rc);
More information about the wine-cvs
mailing list