Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
911d269b
Commit
911d269b
authored
Aug 23, 2016
by
Akihiro Sagawa
Committed by
Alexandre Julliard
Aug 29, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Create and destroy the default IME window implicitly.
Signed-off-by:
Akihiro Sagawa
<
sagawa.aki@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
876d5de0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
110 additions
and
23 deletions
+110
-23
imm.c
dlls/imm32/imm.c
+81
-16
imm32.spec
dlls/imm32/imm32.spec
+2
-0
imm32.c
dlls/imm32/tests/imm32.c
+5
-7
misc.c
dlls/user32/misc.c
+4
-0
user_private.h
dlls/user32/user_private.h
+2
-0
win.c
dlls/user32/win.c
+15
-0
win.h
dlls/user32/win.h
+1
-0
No files found.
dlls/imm32/imm.c
View file @
911d269b
...
...
@@ -96,6 +96,7 @@ typedef struct _tagIMMThreadData {
HIMC
defaultContext
;
HWND
hwndDefault
;
BOOL
disableIME
;
DWORD
windowRefs
;
}
IMMThreadData
;
static
struct
list
ImmHklList
=
LIST_INIT
(
ImmHklList
);
...
...
@@ -1618,27 +1619,51 @@ BOOL WINAPI ImmGetConversionStatus(
return
TRUE
;
}
static
BOOL
needs_ime_window
(
HWND
hwnd
)
{
WCHAR
classW
[
8
];
if
(
GetClassNameW
(
hwnd
,
classW
,
sizeof
(
classW
)
/
sizeof
(
classW
[
0
]))
&&
!
strcmpW
(
classW
,
szwIME
))
return
FALSE
;
if
(
GetClassLongPtrW
(
hwnd
,
GCL_STYLE
)
&
CS_IME
)
return
FALSE
;
return
TRUE
;
}
/***********************************************************************
*
ImmGetDefaultIMEWnd
(IMM32.@)
*
__wine_register_window
(IMM32.@)
*/
HWND
WINAPI
ImmGetDefaultIMEWnd
(
HWND
hW
nd
)
BOOL
WINAPI
__wine_register_window
(
HWND
hw
nd
)
{
HWND
ret
,
new
=
NULL
;
IMMThreadData
*
thread_data
=
IMM_GetThreadData
(
hWnd
,
0
);
HWND
new
=
NULL
;
IMMThreadData
*
thread_data
;
TRACE
(
"(%p)
\n
"
,
hwnd
);
if
(
!
needs_ime_window
(
hwnd
))
return
FALSE
;
thread_data
=
IMM_GetThreadData
(
hwnd
,
0
);
if
(
!
thread_data
)
return
NULL
;
if
(
thread_data
->
hwndDefault
==
NULL
&&
thread_data
->
threadID
==
GetCurrentThreadId
())
return
FALSE
;
if
(
thread_data
->
disableIME
||
disable_ime
)
{
TRACE
(
"IME for this thread is disabled
\n
"
);
LeaveCriticalSection
(
&
threaddata_cs
);
return
FALSE
;
}
thread_data
->
windowRefs
++
;
TRACE
(
"windowRefs=%u, hwndDefault=%p
\n
"
,
thread_data
->
windowRefs
,
thread_data
->
hwndDefault
);
/* Create default IME window */
if
(
thread_data
->
windowRefs
==
1
)
{
if
(
thread_data
->
disableIME
||
disable_ime
)
{
TRACE
(
"IME for this thread is disabled
\n
"
);
LeaveCriticalSection
(
&
threaddata_cs
);
return
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
);
szwIME
,
NULL
,
WS_POPUP
,
0
,
0
,
1
,
1
,
0
,
0
,
0
,
0
);
/* thread_data is in the current thread so we can assume it's still valid */
EnterCriticalSection
(
&
threaddata_cs
);
/* See if anyone beat us */
...
...
@@ -1646,16 +1671,56 @@ HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
{
thread_data
->
hwndDefault
=
new
;
new
=
NULL
;
TRACE
(
"Default is %p
\n
"
,
thread_data
->
hwndDefault
);
}
}
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
TRUE
;
}
/***********************************************************************
* __wine_unregister_window (IMM32.@)
*/
void
WINAPI
__wine_unregister_window
(
HWND
hwnd
)
{
HWND
to_destroy
=
0
;
IMMThreadData
*
thread_data
;
TRACE
(
"(%p)
\n
"
,
hwnd
);
thread_data
=
IMM_GetThreadData
(
hwnd
,
0
);
if
(
!
thread_data
)
return
;
thread_data
->
windowRefs
--
;
TRACE
(
"windowRefs=%u, hwndDefault=%p
\n
"
,
thread_data
->
windowRefs
,
thread_data
->
hwndDefault
);
/* Destroy default IME window */
if
(
thread_data
->
windowRefs
==
0
&&
thread_data
->
hwndDefault
)
{
to_destroy
=
thread_data
->
hwndDefault
;
thread_data
->
hwndDefault
=
NULL
;
}
LeaveCriticalSection
(
&
threaddata_cs
);
if
(
to_destroy
)
DestroyWindow
(
to_destroy
);
}
/***********************************************************************
* ImmGetDefaultIMEWnd (IMM32.@)
*/
HWND
WINAPI
ImmGetDefaultIMEWnd
(
HWND
hWnd
)
{
HWND
ret
;
IMMThreadData
*
thread_data
=
IMM_GetThreadData
(
hWnd
,
0
);
if
(
!
thread_data
)
return
NULL
;
ret
=
thread_data
->
hwndDefault
;
LeaveCriticalSection
(
&
threaddata_cs
);
TRACE
(
"Default is %p
\n
"
,
ret
);
return
ret
;
}
...
...
dlls/imm32/imm32.spec
View file @
911d269b
...
...
@@ -114,3 +114,5 @@
################################################################
# Wine internal extensions
@ stdcall __wine_get_ui_window(ptr)
@ stdcall __wine_register_window(long)
@ stdcall __wine_unregister_window(long)
dlls/imm32/tests/imm32.c
View file @
911d269b
...
...
@@ -207,7 +207,6 @@ static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case
FIRST_WINDOW
:
case
SECOND_WINDOW
:
case
CREATE_CANCEL
:
todo_wine_if
(
test_phase
==
FIRST_WINDOW
||
test_phase
==
CREATE_CANCEL
)
ok
(
default_ime_wnd
!=
NULL
,
"expected IME window existence
\n
"
);
break
;
case
IME_DISABLED
:
...
...
@@ -223,7 +222,6 @@ static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case
FIRST_WINDOW
:
case
SECOND_WINDOW
:
case
CREATE_CANCEL
:
todo_wine_if
(
test_phase
==
FIRST_WINDOW
||
test_phase
==
CREATE_CANCEL
)
ok
(
default_ime_wnd
!=
NULL
,
"expected IME window existence
\n
"
);
break
;
case
IME_DISABLED
:
...
...
@@ -952,9 +950,9 @@ static DWORD WINAPI test_default_ime_window_cb(void *arg)
240
,
24
,
hwnd
,
NULL
,
GetModuleHandleW
(
NULL
),
NULL
);
}
ime_wnd
=
get_ime_window
();
todo_wine
ok
(
ime_wnd
!=
NULL
,
"Expected IME window existence
\n
"
);
ok
(
ime_wnd
!=
NULL
,
"Expected IME window existence
\n
"
);
default_ime_wnd
=
ImmGetDefaultIMEWnd
(
hwnd1
);
todo_wine
ok
(
ime_wnd
==
default_ime_wnd
,
"Expected %p, got %p
\n
"
,
ime_wnd
,
default_ime_wnd
);
ok
(
ime_wnd
==
default_ime_wnd
,
"Expected %p, got %p
\n
"
,
ime_wnd
,
default_ime_wnd
);
test_phase
=
SECOND_WINDOW
;
hwnd2
=
CreateWindowExA
(
WS_EX_CLIENTEDGE
,
wndcls
,
"Wine imm32.dll test"
,
...
...
@@ -962,7 +960,7 @@ static DWORD WINAPI test_default_ime_window_cb(void *arg)
CW_USEDEFAULT
,
CW_USEDEFAULT
,
240
,
120
,
NULL
,
NULL
,
GetModuleHandleW
(
NULL
),
NULL
);
DestroyWindow
(
hwnd2
);
todo_wine
ok
(
IsWindow
(
ime_wnd
)
||
ok
(
IsWindow
(
ime_wnd
)
||
broken
(
!
testcase
->
visible
/* Vista */
)
||
broken
(
!
testcase
->
top_level_window
/* Vista */
)
,
"Expected IME window existence
\n
"
);
...
...
@@ -1000,9 +998,9 @@ static DWORD WINAPI test_default_ime_window_cancel_cb(void *arg)
CW_USEDEFAULT
,
CW_USEDEFAULT
,
240
,
120
,
NULL
,
NULL
,
GetModuleHandleW
(
NULL
),
NULL
);
ime_wnd
=
get_ime_window
();
todo_wine
ok
(
ime_wnd
!=
NULL
,
"Expected IME window existence
\n
"
);
ok
(
ime_wnd
!=
NULL
,
"Expected IME window existence
\n
"
);
default_ime_wnd
=
ImmGetDefaultIMEWnd
(
hwnd2
);
todo_wine
ok
(
ime_wnd
==
default_ime_wnd
,
"Expected %p, got %p
\n
"
,
ime_wnd
,
default_ime_wnd
);
ok
(
ime_wnd
==
default_ime_wnd
,
"Expected %p, got %p
\n
"
,
ime_wnd
,
default_ime_wnd
);
DestroyWindow
(
hwnd2
);
ok
(
!
IsWindow
(
ime_wnd
),
"Expected no IME windows
\n
"
);
...
...
dlls/user32/misc.c
View file @
911d269b
...
...
@@ -41,6 +41,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
#define IMM_INIT_MAGIC 0x19650412
static
HWND
(
WINAPI
*
imm_get_ui_window
)(
HKL
);
BOOL
(
WINAPI
*
imm_register_window
)(
HWND
)
=
NULL
;
void
(
WINAPI
*
imm_unregister_window
)(
HWND
)
=
NULL
;
/* MSIME messages */
static
UINT
WM_MSIME_SERVICE
;
...
...
@@ -684,6 +686,8 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
/* this part is not compatible with native imm32.dll */
imm_get_ui_window
=
(
void
*
)
GetProcAddress
(
imm32
,
"__wine_get_ui_window"
);
imm_register_window
=
(
void
*
)
GetProcAddress
(
imm32
,
"__wine_register_window"
);
imm_unregister_window
=
(
void
*
)
GetProcAddress
(
imm32
,
"__wine_unregister_window"
);
if
(
!
imm_get_ui_window
)
FIXME
(
"native imm32.dll not supported
\n
"
);
return
TRUE
;
...
...
dlls/user32/user_private.h
View file @
911d269b
...
...
@@ -196,6 +196,8 @@ struct user_thread_info
C_ASSERT
(
sizeof
(
struct
user_thread_info
)
<=
sizeof
(((
TEB
*
)
0
)
->
Win32ClientInfo
)
);
extern
INT
global_key_state_counter
DECLSPEC_HIDDEN
;
extern
BOOL
(
WINAPI
*
imm_register_window
)(
HWND
)
DECLSPEC_HIDDEN
;
extern
void
(
WINAPI
*
imm_unregister_window
)(
HWND
)
DECLSPEC_HIDDEN
;
struct
user_key_state_info
{
...
...
dlls/user32/win.c
View file @
911d269b
...
...
@@ -958,6 +958,13 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
TRACE
(
"%p
\n
"
,
hwnd
);
/* destroy default IME window */
if
(
win_set_flags
(
hwnd
,
0
,
WIN_HAS_IME_WIN
)
&
WIN_HAS_IME_WIN
)
{
TRACE
(
"unregister IME window for %p
\n
"
,
hwnd
);
imm_unregister_window
(
hwnd
);
}
/* free child windows */
if
((
list
=
WIN_ListChildren
(
hwnd
)))
{
...
...
@@ -1604,6 +1611,14 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
goto
failed
;
}
/* create default IME window */
if
(
imm_register_window
&&
!
is_desktop_window
(
hwnd
)
&&
imm_register_window
(
hwnd
))
{
TRACE
(
"register IME window for %p
\n
"
,
hwnd
);
win_set_flags
(
hwnd
,
WIN_HAS_IME_WIN
,
0
);
}
/* send WM_NCCALCSIZE */
if
(
WIN_GetRectangles
(
hwnd
,
COORDS_PARENT
,
&
rect
,
NULL
))
...
...
dlls/user32/win.h
View file @
911d269b
...
...
@@ -77,6 +77,7 @@ typedef struct tagWND
#define WIN_ISUNICODE 0x0010
/* Window is Unicode */
#define WIN_NEEDS_SHOW_OWNEDPOPUP 0x0020
/* WM_SHOWWINDOW:SC_SHOW must be sent in the next ShowOwnedPopup call */
#define WIN_CHILDREN_MOVED 0x0040
/* children may have moved, ignore stored positions */
#define WIN_HAS_IME_WIN 0x0080
/* the window has been registered with imm32 */
/* Window functions */
extern
HWND
get_hwnd_message_parent
(
void
)
DECLSPEC_HIDDEN
;
...
...
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