From: Aric Stewart <aric@codeweavers.com>
Subject: (Retry)[2/5] imm32: do not let ImmDestroyContext destroy any default contexts
Message-Id: <53D95617.2080806@codeweavers.com>
Date: Wed, 30 Jul 2014 15:31:19 -0500


optimization suggested by Nikolay Sivov
---
 dlls/imm32/imm.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index 7bd283e..19a1470 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -74,6 +74,7 @@ typedef struct tagInputContextData
 
         ImmHkl          *immKbd;
         UINT            lastVK;
+        BOOL            threadDefault;
         DWORD           magic;
 } InputContextData;
 
@@ -128,6 +129,7 @@ static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
 #define is_kbd_ime_unicode(p)  (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
 
 static BOOL IMM_DestroyContext(HIMC hIMC);
+static InputContextData* get_imc_data(HIMC hIMC);
 
 static inline WCHAR *strdupAtoW( const char *str )
 {
@@ -253,6 +255,16 @@ static IMMThreadData* IMM_GetThreadData(DWORD id)
     return data;
 }
 
+static BOOL IMM_IsDefaultContext(HIMC imc)
+{
+    InputContextData *data = get_imc_data(imc);
+
+    if (!data)
+        return FALSE;
+
+    return data->threadDefault;
+}
+
 static void IMM_FreeThreadData(DWORD id)
 {
     BOOL found = FALSE;
@@ -511,6 +523,8 @@ static IMMThreadData* IMM_GetInitializedThreadData(void)
         HIMC defaultContext;
         LeaveCriticalSection(&threaddata_cs);
         defaultContext = ImmCreateContext();
+        if (defaultContext)
+            ((InputContextData*)defaultContext)->threadDefault = TRUE;
         thread_data = IMM_GetThreadData(0);
         if (!thread_data)
         {
@@ -813,11 +827,7 @@ static BOOL IMM_DestroyContext(HIMC hIMC)
  */
 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
 {
-    IMMThreadData* thread_data = IMM_GetThreadData(0);
-    HIMC defaultContext = thread_data->defaultContext;
-    LeaveCriticalSection(&threaddata_cs);
-
-    if (hIMC != defaultContext)
+    if (!IMM_IsDefaultContext(hIMC))
         return IMM_DestroyContext(hIMC);
     else
         return FALSE;