Aric Stewart : imm: Default context and hwnd are per thread so store that data in a thread local storage .
Alexandre Julliard
julliard at winehq.org
Mon Apr 7 14:46:53 CDT 2008
Module: wine
Branch: master
Commit: b72dcd114d1c622b3046506563cc91fc38d40835
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b72dcd114d1c622b3046506563cc91fc38d40835
Author: Aric Stewart <aric at codeweavers.com>
Date: Mon Apr 7 10:17:32 2008 -0500
imm: Default context and hwnd are per thread so store that data in a thread local storage.
---
dlls/imm32/imm.c | 79 +++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 57 insertions(+), 22 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index 4d82398..beda98f 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -86,10 +86,13 @@ typedef struct _tagTRANSMSG {
LPARAM lParam;
} TRANSMSG, *LPTRANSMSG;
-static InputContextData *root_context = NULL;
-static HWND hwndDefault = NULL;
-static HANDLE hImeInst;
+typedef struct _tagIMMThreadData {
+ HIMC defaultContext;
+ HWND hwndDefault;
+} IMMThreadData;
+static HANDLE hImeInst;
+static DWORD tlsIndex = 0;
static struct list ImmHklList = LIST_INIT(ImmHklList);
/* MSIME messages */
@@ -130,6 +133,29 @@ static inline CHAR *strdupWtoA( const WCHAR *str )
return ret;
}
+static IMMThreadData* IMM_GetThreadData(void)
+{
+ return (IMMThreadData*)TlsGetValue(tlsIndex);
+}
+
+static void IMM_InitThreadData(void)
+{
+ IMMThreadData* data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(IMMThreadData));
+ TlsSetValue(tlsIndex,data);
+
+ TRACE("Thread Data Created\n");
+}
+
+static void IMM_FreeThreadData(void)
+{
+ IMMThreadData* data = TlsGetValue(tlsIndex);
+ ImmDestroyContext(data->defaultContext);
+ DestroyWindow(data->hwndDefault);
+ HeapFree(GetProcessHeap(),0,data);
+ TRACE("Thread Data Destroyed\n");
+}
+
static HMODULE LoadDefaultWineIME(void)
{
char buffer[MAX_PATH], libname[32], *name, *next;
@@ -265,12 +291,21 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hInstDLL);
hImeInst = hInstDLL;
IMM_RegisterMessages();
+ tlsIndex = TlsAlloc();
+ IMM_InitThreadData();
+ break;
+ case DLL_THREAD_ATTACH:
+ IMM_InitThreadData();
+ break;
+ case DLL_THREAD_DETACH:
+ IMM_FreeThreadData();
break;
case DLL_PROCESS_DETACH:
+ IMM_FreeThreadData();
IMM_FreeAllImmHkl();
+ TlsFree(tlsIndex);
break;
}
return TRUE;
@@ -321,8 +356,8 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
TRACE("(%p, %p):\n", hWnd, hIMC);
- if (!root_context)
- root_context = ImmCreateContext();
+ if (!IMM_GetThreadData()->defaultContext)
+ IMM_GetThreadData()->defaultContext = ImmCreateContext();
/*
* If already associated just return
@@ -335,11 +370,11 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
if (old == NULL)
- old = (HIMC)root_context;
+ old = IMM_GetThreadData()->defaultContext;
else if (old == (HIMC)-1)
old = NULL;
- if (hIMC != (HIMC)root_context)
+ if (hIMC != IMM_GetThreadData()->defaultContext)
{
if (hIMC == NULL) /* Meaning disable imm for that window*/
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
@@ -499,8 +534,8 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
data->immKbd->uSelected --;
data->immKbd->pImeSelect(hIMC, FALSE);
- if (hwndDefault == data->imeWnd)
- hwndDefault = NULL;
+ if (IMM_GetThreadData()->hwndDefault == data->imeWnd)
+ IMM_GetThreadData()->hwndDefault = NULL;
DestroyWindow(data->imeWnd);
ImmDestroyIMCC(data->IMC.hCompStr);
@@ -913,14 +948,14 @@ HIMC WINAPI ImmGetContext(HWND hWnd)
HIMC rc = NULL;
TRACE("%p\n", hWnd);
- if (!root_context)
- root_context = ImmCreateContext();
+ if (!IMM_GetThreadData()->defaultContext)
+ IMM_GetThreadData()->defaultContext = ImmCreateContext();
rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
if (rc == (HIMC)-1)
rc = NULL;
else if (rc == NULL)
- rc = (HIMC)root_context;
+ rc = IMM_GetThreadData()->defaultContext;
if (rc)
{
@@ -981,8 +1016,8 @@ BOOL WINAPI ImmGetConversionStatus(
*/
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
{
- TRACE("Default is %x\n",(unsigned)hwndDefault);
- return hwndDefault;
+ TRACE("Default is %x\n",(unsigned)IMM_GetThreadData()->hwndDefault);
+ return IMM_GetThreadData()->hwndDefault;
}
/***********************************************************************
@@ -1288,11 +1323,11 @@ BOOL WINAPI ImmIsUIMessageA(
(msg == WM_MSIME_DOCUMENTFEED))
{
- if (!hwndDefault)
+ if (!IMM_GetThreadData()->hwndDefault)
ImmGetDefaultIMEWnd(NULL);
if (hWndIME == NULL)
- PostMessageA(hwndDefault, msg, wParam, lParam);
+ PostMessageA(IMM_GetThreadData()->hwndDefault, msg, wParam, lParam);
rc = TRUE;
}
@@ -1306,7 +1341,7 @@ BOOL WINAPI ImmIsUIMessageW(
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL rc = FALSE;
- TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME, msg, wParam, lParam);
+ TRACE("(%p, %d, %ld, %ld):\n", hWndIME, msg, wParam, lParam);
if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
(msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
(msg == WM_MSIME_SERVICE) ||
@@ -1506,16 +1541,16 @@ BOOL WINAPI ImmSetCompositionWindow(
data->IMC.cfCompForm = *lpCompForm;
- if (IsWindowVisible(hwndDefault))
+ if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
{
reshow = TRUE;
- ShowWindow(hwndDefault,SW_HIDE);
+ ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
}
/* FIXME: this is a partial stub */
if (reshow)
- ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+ ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
return TRUE;
@@ -1558,7 +1593,7 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
data->immKbd->imeClassName,
NULL, WS_POPUP, 0, 0, 1, 1, 0, 0, hImeInst, 0);
SetWindowLongW(data->imeWnd, IMMGWL_IMC, (LONG)data);
- hwndDefault = data->imeWnd;
+ IMM_GetThreadData()->hwndDefault = data->imeWnd;
}
data->IMC.fOpen = fOpen;
More information about the wine-cvs
mailing list