Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e28fc117
Commit
e28fc117
authored
Feb 25, 2015
by
Aric Stewart
Committed by
Alexandre Julliard
Feb 26, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
imm32: Move thread data from TLSEntry to an internal list.
parent
9491044e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
132 additions
and
36 deletions
+132
-36
imm.c
dlls/imm32/imm.c
+132
-36
No files found.
dlls/imm32/imm.c
View file @
e28fc117
...
...
@@ -89,12 +89,14 @@ typedef struct _tagTRANSMSG {
}
TRANSMSG
,
*
LPTRANSMSG
;
typedef
struct
_tagIMMThreadData
{
struct
list
entry
;
DWORD
threadID
;
HIMC
defaultContext
;
HWND
hwndDefault
;
}
IMMThreadData
;
static
DWORD
tlsIndex
=
0
;
static
struct
list
ImmHklList
=
LIST_INIT
(
ImmHklList
);
static
struct
list
ImmThreadDataList
=
LIST_INIT
(
ImmThreadDataList
);
static
const
WCHAR
szwWineIMCProperty
[]
=
{
'W'
,
'i'
,
'n'
,
'e'
,
'I'
,
'm'
,
'm'
,
'H'
,
'I'
,
'M'
,
'C'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
0
};
...
...
@@ -104,6 +106,15 @@ static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\\','C','u','r','r'
static
const
WCHAR
szwIME
[]
=
{
'I'
,
'M'
,
'E'
,
0
};
static
CRITICAL_SECTION
threaddata_cs
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
{
0
,
0
,
&
threaddata_cs
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": threaddata_cs"
)
}
};
static
CRITICAL_SECTION
threaddata_cs
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
...
...
@@ -211,29 +222,47 @@ static DWORD convert_candidatelist_AtoW(
return
ret
;
}
static
IMMThreadData
*
IMM_GetThreadData
(
vo
id
)
static
IMMThreadData
*
IMM_GetThreadData
(
DWORD
id
)
{
IMMThreadData
*
data
=
TlsGetValue
(
tlsIndex
);
if
(
!
data
)
IMMThreadData
*
data
;
if
(
!
id
)
id
=
GetCurrentThreadId
();
EnterCriticalSection
(
&
threaddata_cs
);
LIST_FOR_EACH_ENTRY
(
data
,
&
ImmThreadDataList
,
IMMThreadData
,
entry
)
{
data
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
IMMThreadData
));
TlsSetValue
(
tlsIndex
,
data
);
TRACE
(
"Thread Data Created
\n
"
);
if
(
data
->
threadID
==
id
)
return
data
;
}
data
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
IMMThreadData
));
data
->
threadID
=
id
;
list_add_head
(
&
ImmThreadDataList
,
&
data
->
entry
);
TRACE
(
"Thread Data Created (%x)
\n
"
,
id
);
return
data
;
}
static
void
IMM_FreeThreadData
(
void
)
{
IMMThreadData
*
data
=
TlsGetValue
(
tlsIndex
);
if
(
data
)
IMMThreadData
*
data
;
EnterCriticalSection
(
&
threaddata_cs
);
LIST_FOR_EACH_ENTRY
(
data
,
&
ImmThreadDataList
,
IMMThreadData
,
entry
)
{
IMM_DestroyContext
(
data
->
defaultContext
);
DestroyWindow
(
data
->
hwndDefault
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
TRACE
(
"Thread Data Destroyed
\n
"
);
if
(
data
->
threadID
==
GetCurrentThreadId
())
{
list_remove
(
&
data
->
entry
);
LeaveCriticalSection
(
&
threaddata_cs
);
IMM_DestroyContext
(
data
->
defaultContext
);
DestroyWindow
(
data
->
hwndDefault
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
TRACE
(
"Thread Data Destroyed
\n
"
);
return
;
}
}
LeaveCriticalSection
(
&
threaddata_cs
);
}
static
HMODULE
load_graphics_driver
(
void
)
...
...
@@ -368,12 +397,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
switch
(
fdwReason
)
{
case
DLL_PROCESS_ATTACH
:
tlsIndex
=
TlsAlloc
();
if
(
tlsIndex
==
TLS_OUT_OF_INDEXES
)
return
FALSE
;
if
(
!
User32InitializeImmEntryTable
(
IMM_INIT_MAGIC
))
{
TlsFree
(
tlsIndex
);
return
FALSE
;
}
break
;
...
...
@@ -386,7 +411,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
if
(
lpReserved
)
break
;
IMM_FreeThreadData
();
IMM_FreeAllImmHkl
();
TlsFree
(
tlsIndex
);
break
;
}
return
TRUE
;
...
...
@@ -442,6 +466,34 @@ static InputContextData* get_imc_data(HIMC hIMC)
return
data
;
}
static
IMMThreadData
*
IMM_GetInitializedThreadData
(
void
)
{
IMMThreadData
*
thread_data
=
IMM_GetThreadData
(
0
);
if
(
!
thread_data
)
return
NULL
;
if
(
!
thread_data
->
defaultContext
)
{
HIMC
defaultContext
;
LeaveCriticalSection
(
&
threaddata_cs
);
defaultContext
=
ImmCreateContext
();
thread_data
=
IMM_GetThreadData
(
0
);
if
(
!
thread_data
)
{
IMM_DestroyContext
(
defaultContext
);
return
NULL
;
}
if
(
thread_data
->
defaultContext
)
/* someone beat us */
IMM_DestroyContext
(
defaultContext
);
else
thread_data
->
defaultContext
=
defaultContext
;
}
return
thread_data
;
}
/***********************************************************************
* ImmAssociateContext (IMM32.@)
*/
...
...
@@ -449,31 +501,33 @@ 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
);
if
(
hIMC
&&
!
data
)
return
NULL
;
if
(
!
IMM_GetThreadData
()
->
defaultContext
)
IMM_GetThreadData
()
->
defaultContext
=
ImmCreateContext
();
/*
* If already associated just return
*/
if
(
hIMC
&&
data
->
IMC
.
hWnd
==
hWnd
)
return
hIMC
;
thread_data
=
IMM_GetInitializedThreadData
();
if
(
!
thread_data
)
return
NULL
;
if
(
hWnd
)
{
old
=
RemovePropW
(
hWnd
,
szwWineIMCProperty
);
if
(
old
==
NULL
)
old
=
IMM_GetThreadData
()
->
defaultContext
;
old
=
thread_data
->
defaultContext
;
else
if
(
old
==
(
HIMC
)
-
1
)
old
=
NULL
;
if
(
hIMC
!=
IMM_GetThreadData
()
->
defaultContext
)
if
(
hIMC
!=
thread_data
->
defaultContext
)
{
if
(
hIMC
==
NULL
)
/* Meaning disable imm for that window*/
SetPropW
(
hWnd
,
szwWineIMCProperty
,(
HANDLE
)
-
1
);
...
...
@@ -488,6 +542,7 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
old_data
->
IMC
.
hWnd
=
NULL
;
}
}
LeaveCriticalSection
(
&
threaddata_cs
);
if
(
!
hIMC
)
return
old
;
...
...
@@ -529,12 +584,20 @@ 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
);
if
(
!
IMM_GetThreadData
()
->
defaultContext
)
IMM_GetThreadData
()
->
defaultContext
=
ImmCreateContext
();
thread_data
=
IMM_GetInitializedThreadData
();
if
(
!
thread_data
)
return
FALSE
;
if
(
!
hWnd
)
return
FALSE
;
defaultContext
=
thread_data
->
defaultContext
;
LeaveCriticalSection
(
&
threaddata_cs
);
if
(
!
hWnd
)
return
FALSE
;
switch
(
dwFlags
)
{
...
...
@@ -542,7 +605,7 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
ImmAssociateContext
(
hWnd
,
hIMC
);
return
TRUE
;
case
IACE_DEFAULT
:
ImmAssociateContext
(
hWnd
,
IMM_GetThreadData
()
->
defaultContext
);
ImmAssociateContext
(
hWnd
,
defaultContext
);
return
TRUE
;
case
IACE_IGNORENOCONTEXT
:
if
(
GetPropW
(
hWnd
,
szwWineIMCProperty
))
...
...
@@ -717,7 +780,11 @@ static BOOL IMM_DestroyContext(HIMC hIMC)
*/
BOOL
WINAPI
ImmDestroyContext
(
HIMC
hIMC
)
{
if
(
hIMC
!=
IMM_GetThreadData
()
->
defaultContext
)
IMMThreadData
*
thread_data
=
IMM_GetThreadData
(
0
);
HIMC
defaultContext
=
thread_data
->
defaultContext
;
LeaveCriticalSection
(
&
threaddata_cs
);
if
(
hIMC
!=
defaultContext
)
return
IMM_DestroyContext
(
hIMC
);
else
return
FALSE
;
...
...
@@ -1383,6 +1450,7 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
HIMC
WINAPI
ImmGetContext
(
HWND
hWnd
)
{
HIMC
rc
;
IMMThreadData
*
thread_data
;
TRACE
(
"%p
\n
"
,
hWnd
);
...
...
@@ -1391,20 +1459,24 @@ HIMC WINAPI ImmGetContext(HWND hWnd)
SetLastError
(
ERROR_INVALID_WINDOW_HANDLE
);
return
NULL
;
}
if
(
!
IMM_GetThreadData
()
->
defaultContext
)
IMM_GetThreadData
()
->
defaultContext
=
ImmCreateContext
();
thread_data
=
IMM_GetInitializedThreadData
();
if
(
!
thread_data
)
return
NULL
;
rc
=
GetPropW
(
hWnd
,
szwWineIMCProperty
);
if
(
rc
==
(
HIMC
)
-
1
)
rc
=
NULL
;
else
if
(
rc
==
NULL
)
rc
=
IMM_GetThreadData
()
->
defaultContext
;
rc
=
thread_data
->
defaultContext
;
if
(
rc
)
{
InputContextData
*
data
=
rc
;
data
->
IMC
.
hWnd
=
hWnd
;
}
LeaveCriticalSection
(
&
threaddata_cs
);
TRACE
(
"returning %p
\n
"
,
rc
);
return
rc
;
...
...
@@ -1512,11 +1584,35 @@ BOOL WINAPI ImmGetConversionStatus(
*/
HWND
WINAPI
ImmGetDefaultIMEWnd
(
HWND
hWnd
)
{
if
(
IMM_GetThreadData
()
->
hwndDefault
==
NULL
)
IMM_GetThreadData
()
->
hwndDefault
=
CreateWindowExW
(
WS_EX_TOOLWINDOW
,
HWND
ret
,
new
=
NULL
;
IMMThreadData
*
thread_data
=
IMM_GetThreadData
(
0
);
if
(
!
thread_data
)
return
NULL
;
if
(
thread_data
->
hwndDefault
==
NULL
)
{
/* 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
);
TRACE
(
"Default is %p
\n
"
,
IMM_GetThreadData
()
->
hwndDefault
);
return
IMM_GetThreadData
()
->
hwndDefault
;
thread_data
=
IMM_GetThreadData
(
0
);
if
(
!
thread_data
)
return
NULL
;
/* See if anyone beat us */
if
(
thread_data
->
hwndDefault
==
NULL
)
{
thread_data
->
hwndDefault
=
new
;
new
=
NULL
;
}
}
ret
=
thread_data
->
hwndDefault
;
LeaveCriticalSection
(
&
threaddata_cs
);
TRACE
(
"Default is %p
\n
"
,
ret
);
/* Clean up an unused new window outside of the critical section */
if
(
new
!=
NULL
)
{
DestroyWindow
(
new
);
}
return
ret
;
}
/***********************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment