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
047d74c4
Commit
047d74c4
authored
Jul 09, 2022
by
Jacek Caban
Committed by
Alexandre Julliard
Jul 12, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
win32u: Move default IME window management from imm32.
parent
f4f589c4
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
228 additions
and
265 deletions
+228
-265
imm.c
dlls/imm32/imm.c
+1
-218
imm32.spec
dlls/imm32/imm32.spec
+2
-4
imm32.c
dlls/imm32/tests/imm32.c
+0
-2
misc.c
dlls/user32/misc.c
+0
-4
user_main.c
dlls/user32/user_main.c
+0
-19
user_private.h
dlls/user32/user_private.h
+0
-3
class.c
dlls/win32u/class.c
+12
-0
gdiobj.c
dlls/win32u/gdiobj.c
+1
-0
imm.c
dlls/win32u/imm.c
+176
-0
input.c
dlls/win32u/input.c
+9
-3
ntuser_private.h
dlls/win32u/ntuser_private.h
+2
-3
sysparams.c
dlls/win32u/sysparams.c
+1
-1
win32u.spec
dlls/win32u/win32u.spec
+1
-1
win32u_private.h
dlls/win32u/win32u_private.h
+5
-0
window.c
dlls/win32u/window.c
+5
-7
wrappers.c
dlls/win32u/wrappers.c
+6
-0
ntuser.h
include/ntuser.h
+7
-0
No files found.
dlls/imm32/imm.c
View file @
047d74c4
...
...
@@ -100,14 +100,6 @@ typedef struct _tagTRANSMSG {
LPARAM
lParam
;
}
TRANSMSG
,
*
LPTRANSMSG
;
typedef
struct
_tagIMMThreadData
{
struct
list
entry
;
DWORD
threadID
;
HWND
hwndDefault
;
BOOL
disableIME
;
DWORD
windowRefs
;
}
IMMThreadData
;
struct
coinit_spy
{
IInitializeSpy
IInitializeSpy_iface
;
...
...
@@ -123,20 +115,9 @@ struct coinit_spy
};
static
struct
list
ImmHklList
=
LIST_INIT
(
ImmHklList
);
static
struct
list
ImmThreadDataList
=
LIST_INIT
(
ImmThreadDataList
);
static
const
WCHAR
szImeRegFmt
[]
=
L"System
\\
CurrentControlSet
\\
Control
\\
Keyboard Layouts
\\
%08lx"
;
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
};
static
BOOL
disable_ime
;
static
inline
BOOL
is_himc_ime_unicode
(
const
InputContextData
*
data
)
{
return
!!
(
data
->
immKbd
->
imeInfo
.
fdwProperty
&
IME_PROP_UNICODE
);
...
...
@@ -412,38 +393,6 @@ static void imm_coinit_thread(void)
spy
->
apt_flags
|=
IMM_APT_CREATED
;
}
static
IMMThreadData
*
IMM_GetThreadData
(
HWND
hwnd
,
DWORD
thread
)
{
IMMThreadData
*
data
;
DWORD
process
;
if
(
hwnd
)
{
if
(
!
(
thread
=
GetWindowThreadProcessId
(
hwnd
,
&
process
)))
return
NULL
;
if
(
process
!=
GetCurrentProcessId
())
return
NULL
;
}
else
if
(
thread
)
{
HANDLE
h
=
OpenThread
(
THREAD_QUERY_INFORMATION
,
FALSE
,
thread
);
if
(
!
h
)
return
NULL
;
process
=
GetProcessIdOfThread
(
h
);
CloseHandle
(
h
);
if
(
process
!=
GetCurrentProcessId
())
return
NULL
;
}
else
thread
=
GetCurrentThreadId
();
EnterCriticalSection
(
&
threaddata_cs
);
LIST_FOR_EACH_ENTRY
(
data
,
&
ImmThreadDataList
,
IMMThreadData
,
entry
)
if
(
data
->
threadID
==
thread
)
return
data
;
data
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
data
));
data
->
threadID
=
thread
;
list_add_head
(
&
ImmThreadDataList
,
&
data
->
entry
);
TRACE
(
"Thread Data Created (%lx)
\n
"
,
thread
);
return
data
;
}
static
BOOL
IMM_IsDefaultContext
(
HIMC
imc
)
{
InputContextData
*
data
=
get_imc_data
(
imc
);
...
...
@@ -490,21 +439,6 @@ static BOOL free_input_context_data(HIMC hIMC)
static
void
IMM_FreeThreadData
(
void
)
{
struct
coinit_spy
*
spy
;
IMMThreadData
*
data
;
EnterCriticalSection
(
&
threaddata_cs
);
LIST_FOR_EACH_ENTRY
(
data
,
&
ImmThreadDataList
,
IMMThreadData
,
entry
)
{
if
(
data
->
threadID
==
GetCurrentThreadId
())
{
list_remove
(
&
data
->
entry
);
LeaveCriticalSection
(
&
threaddata_cs
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
TRACE
(
"Thread Data Destroyed
\n
"
);
return
;
}
}
LeaveCriticalSection
(
&
threaddata_cs
);
free_input_context_data
(
NtUserGetThreadInfo
()
->
default_imc
);
if
((
spy
=
get_thread_coinit_spy
()))
...
...
@@ -981,62 +915,6 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
return
FALSE
;
}
static
HWND
imm_detach_default_window
(
IMMThreadData
*
thread_data
)
{
HWND
to_destroy
;
to_destroy
=
thread_data
->
hwndDefault
;
thread_data
->
hwndDefault
=
NULL
;
thread_data
->
windowRefs
=
0
;
return
to_destroy
;
}
/***********************************************************************
* ImmDisableIME (IMM32.@)
*/
BOOL
WINAPI
ImmDisableIME
(
DWORD
idThread
)
{
IMMThreadData
*
thread_data
;
HWND
to_destroy
;
if
(
idThread
==
(
DWORD
)
-
1
)
{
disable_ime
=
TRUE
;
while
(
1
)
{
to_destroy
=
0
;
EnterCriticalSection
(
&
threaddata_cs
);
LIST_FOR_EACH_ENTRY
(
thread_data
,
&
ImmThreadDataList
,
IMMThreadData
,
entry
)
{
if
(
thread_data
->
hwndDefault
)
{
to_destroy
=
imm_detach_default_window
(
thread_data
);
break
;
}
}
LeaveCriticalSection
(
&
threaddata_cs
);
if
(
!
to_destroy
)
break
;
DestroyWindow
(
to_destroy
);
}
}
else
if
(
!
idThread
||
idThread
==
GetCurrentThreadId
())
{
thread_data
=
IMM_GetThreadData
(
NULL
,
idThread
);
if
(
!
thread_data
)
return
FALSE
;
thread_data
->
disableIME
=
TRUE
;
to_destroy
=
imm_detach_default_window
(
thread_data
);
LeaveCriticalSection
(
&
threaddata_cs
);
if
(
to_destroy
)
DestroyWindow
(
to_destroy
);
}
else
return
FALSE
;
return
TRUE
;
}
/***********************************************************************
* ImmEnumRegisterWordA (IMM32.@)
*/
...
...
@@ -1816,107 +1694,12 @@ BOOL WINAPI ImmGetConversionStatus(
return
TRUE
;
}
static
BOOL
needs_ime_window
(
HWND
hwnd
)
{
WCHAR
classW
[
8
];
if
(
GetClassNameW
(
hwnd
,
classW
,
ARRAY_SIZE
(
classW
))
&&
!
lstrcmpW
(
classW
,
L"IME"
))
return
FALSE
;
if
(
GetClassLongPtrW
(
hwnd
,
GCL_STYLE
)
&
CS_IME
)
return
FALSE
;
return
TRUE
;
}
/***********************************************************************
* __wine_register_window (IMM32.@)
*/
BOOL
WINAPI
__wine_register_window
(
HWND
hwnd
)
{
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
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=%lu, hwndDefault=%p
\n
"
,
thread_data
->
windowRefs
,
thread_data
->
hwndDefault
);
/* Create default IME window */
if
(
thread_data
->
windowRefs
==
1
)
{
/* Do not create the window inside of a critical section */
LeaveCriticalSection
(
&
threaddata_cs
);
new
=
CreateWindowExW
(
0
,
L"IME"
,
L"Default IME"
,
WS_POPUP
|
WS_DISABLED
|
WS_CLIPSIBLINGS
,
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 */
if
(
thread_data
->
hwndDefault
==
NULL
)
{
thread_data
->
hwndDefault
=
new
;
new
=
NULL
;
TRACE
(
"Default is %p
\n
"
,
thread_data
->
hwndDefault
);
}
}
LeaveCriticalSection
(
&
threaddata_cs
);
/* 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=%lu, hwndDefault=%p
\n
"
,
thread_data
->
windowRefs
,
thread_data
->
hwndDefault
);
/* Destroy default IME window */
if
(
thread_data
->
windowRefs
==
0
)
to_destroy
=
imm_detach_default_window
(
thread_data
);
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
;
return
NtUserGetDefaultImeWindow
(
hWnd
);
}
/***********************************************************************
...
...
dlls/imm32/imm32.spec
View file @
047d74c4
...
...
@@ -9,8 +9,8 @@
@ stdcall ImmDestroyContext(long)
@ stdcall ImmDestroyIMCC(long)
@ stdcall ImmDestroySoftKeyboard(long)
@ stdcall ImmDisableIME(long)
@ stdcall ImmDisableIme(long)
ImmDisableIME
@ stdcall ImmDisableIME(long)
NtUserDisableThreadIme
@ stdcall ImmDisableIme(long)
NtUserDisableThreadIme
@ stdcall ImmDisableLegacyIME()
@ stdcall ImmDisableTextFrameService(long)
@ stdcall ImmEnumInputContext(long ptr long)
...
...
@@ -115,5 +115,3 @@
################################################################
# Wine internal extensions
@ stdcall __wine_ime_wnd_proc(long long long long long)
@ stdcall __wine_register_window(long)
@ stdcall __wine_unregister_window(long)
dlls/imm32/tests/imm32.c
View file @
047d74c4
...
...
@@ -2426,11 +2426,9 @@ static void test_ImmDisableIME(void)
ok
(
IsWindow
(
def
),
"not a window
\n
"
);
def2
=
ImmGetDefaultIMEWnd
(
hwnd
);
todo_wine
ok
(
def2
==
def
,
"ImmGetDefaultIMEWnd(hwnd) returned %p
\n
"
,
def2
);
ok
(
IsWindow
(
def
),
"not a window
\n
"
);
msg_spy_pump_msg_queue
();
todo_wine
ok
(
!
IsWindow
(
def
),
"window is still valid
\n
"
);
def
=
ImmGetDefaultIMEWnd
(
hwnd
);
ok
(
!
def
,
"ImmGetDefaultIMEWnd(hwnd) returned %p
\n
"
,
def
);
...
...
dlls/user32/misc.c
View file @
047d74c4
...
...
@@ -39,8 +39,6 @@ BOOL WINAPI ImmSetActiveContext(HWND, HIMC, BOOL);
#define IMM_INIT_MAGIC 0x19650412
static
LRESULT
(
WINAPI
*
imm_ime_wnd_proc
)(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
,
BOOL
ansi
);
BOOL
(
WINAPI
*
imm_register_window
)(
HWND
)
=
NULL
;
void
(
WINAPI
*
imm_unregister_window
)(
HWND
)
=
NULL
;
/* USER signal proc flags and codes */
/* See UserSignalProc for comments */
...
...
@@ -328,8 +326,6 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
/* this part is not compatible with native imm32.dll */
imm_ime_wnd_proc
=
(
void
*
)
GetProcAddress
(
imm32
,
"__wine_ime_wnd_proc"
);
imm_register_window
=
(
void
*
)
GetProcAddress
(
imm32
,
"__wine_register_window"
);
imm_unregister_window
=
(
void
*
)
GetProcAddress
(
imm32
,
"__wine_unregister_window"
);
if
(
!
imm_ime_wnd_proc
)
FIXME
(
"native imm32.dll not supported
\n
"
);
return
TRUE
;
...
...
dlls/user32/user_main.c
View file @
047d74c4
...
...
@@ -119,22 +119,6 @@ static void dpiaware_init(void)
}
}
static
void
CDECL
notify_ime
(
HWND
hwnd
,
UINT
param
)
{
HWND
ime_default
=
ImmGetDefaultIMEWnd
(
hwnd
);
if
(
ime_default
)
SendMessageW
(
ime_default
,
WM_IME_INTERNAL
,
param
,
HandleToUlong
(
hwnd
)
);
}
static
BOOL
WINAPI
register_imm
(
HWND
hwnd
)
{
return
imm_register_window
(
hwnd
);
}
static
void
WINAPI
unregister_imm
(
HWND
hwnd
)
{
imm_unregister_window
(
hwnd
);
}
static
NTSTATUS
try_finally
(
NTSTATUS
(
CDECL
*
func
)(
void
*
),
void
*
arg
,
void
(
CALLBACK
*
finally_func
)(
BOOL
))
{
...
...
@@ -152,11 +136,8 @@ static const struct user_callbacks user_funcs =
ImmProcessKey
,
ImmTranslateMessage
,
NtWaitForMultipleObjects
,
notify_ime
,
post_dde_message
,
unpack_dde_message
,
register_imm
,
unregister_imm
,
try_finally
,
};
...
...
dlls/user32/user_private.h
View file @
047d74c4
...
...
@@ -47,9 +47,6 @@ struct wm_char_mapping_data
MSG
get_msg
;
};
extern
BOOL
(
WINAPI
*
imm_register_window
)(
HWND
)
DECLSPEC_HIDDEN
;
extern
void
(
WINAPI
*
imm_unregister_window
)(
HWND
)
DECLSPEC_HIDDEN
;
static
inline
struct
user_thread_info
*
get_user_thread_info
(
void
)
{
return
(
struct
user_thread_info
*
)
NtCurrentTeb
()
->
Win32ClientInfo
;
...
...
dlls/win32u/class.c
View file @
047d74c4
...
...
@@ -1007,6 +1007,18 @@ WORD get_class_word( HWND hwnd, INT offset )
return
retvalue
;
}
BOOL
needs_ime_window
(
HWND
hwnd
)
{
static
const
WCHAR
imeW
[]
=
{
'I'
,
'M'
,
'E'
,
0
};
CLASS
*
class
;
BOOL
ret
;
if
(
!
(
class
=
get_class_ptr
(
hwnd
,
FALSE
)))
return
FALSE
;
ret
=
!
(
class
->
style
&
CS_IME
)
&&
wcscmp
(
imeW
,
class
->
name
);
release_class_ptr
(
class
);
return
ret
;
}
static
void
register_builtins
(
void
)
{
void
*
ret_ptr
;
...
...
dlls/win32u/gdiobj.c
View file @
047d74c4
...
...
@@ -1157,6 +1157,7 @@ static struct unix_funcs unix_funcs =
NtUserDestroyCursor
,
NtUserDestroyMenu
,
NtUserDestroyWindow
,
NtUserDisableThreadIme
,
NtUserDispatchMessage
,
NtUserDragDetect
,
NtUserDrawCaptionTemp
,
...
...
dlls/win32u/imm.c
View file @
047d74c4
/*
* Input Context implementation
*
* Copyright 1998 Patrik Stridvall
* Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
* Copyright 2022 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
...
...
@@ -22,6 +24,7 @@
#pragma makedep unix
#endif
#include <pthread.h>
#include "win32u_private.h"
#include "ntuser_private.h"
#include "wine/debug.h"
...
...
@@ -36,6 +39,18 @@ struct imc
UINT_PTR
client_ptr
;
};
struct
imm_thread_data
{
struct
list
entry
;
DWORD
thread_id
;
HWND
default_hwnd
;
BOOL
disable_ime
;
UINT
window_cnt
;
};
static
struct
list
thread_data_list
=
LIST_INIT
(
thread_data_list
);
static
pthread_mutex_t
imm_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
BOOL
disable_ime
;
static
struct
imc
*
get_imc_ptr
(
HIMC
handle
)
{
...
...
@@ -215,3 +230,164 @@ HIMC get_window_input_context( HWND hwnd )
release_win_ptr
(
win
);
return
ret
;
}
static
HWND
detach_default_window
(
struct
imm_thread_data
*
thread_data
)
{
HWND
hwnd
=
thread_data
->
default_hwnd
;
thread_data
->
default_hwnd
=
NULL
;
thread_data
->
window_cnt
=
0
;
return
hwnd
;
}
static
struct
imm_thread_data
*
get_imm_thread_data
(
void
)
{
struct
user_thread_info
*
thread_info
=
get_user_thread_info
();
if
(
!
thread_info
->
imm_thread_data
)
{
struct
imm_thread_data
*
data
;
if
(
!
(
data
=
calloc
(
1
,
sizeof
(
*
data
))))
return
NULL
;
data
->
thread_id
=
GetCurrentThreadId
();
pthread_mutex_lock
(
&
imm_mutex
);
list_add_tail
(
&
thread_data_list
,
&
data
->
entry
);
pthread_mutex_unlock
(
&
imm_mutex
);
thread_info
->
imm_thread_data
=
data
;
}
return
thread_info
->
imm_thread_data
;
}
BOOL
register_imm_window
(
HWND
hwnd
)
{
struct
imm_thread_data
*
thread_data
;
TRACE
(
"(%p)
\n
"
,
hwnd
);
if
(
disable_ime
||
!
needs_ime_window
(
hwnd
))
return
FALSE
;
thread_data
=
get_imm_thread_data
();
if
(
!
thread_data
||
thread_data
->
disable_ime
)
return
FALSE
;
TRACE
(
"window_cnt=%u, default_hwnd=%p
\n
"
,
thread_data
->
window_cnt
+
1
,
thread_data
->
default_hwnd
);
/* Create default IME window */
if
(
!
thread_data
->
window_cnt
++
)
{
UNICODE_STRING
class_name
,
name
;
static
const
WCHAR
imeW
[]
=
{
'I'
,
'M'
,
'E'
,
0
};
static
const
WCHAR
default_imeW
[]
=
{
'D'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
' '
,
'I'
,
'M'
,
'E'
,
0
};
RtlInitUnicodeString
(
&
class_name
,
imeW
);
RtlInitUnicodeString
(
&
name
,
default_imeW
);
thread_data
->
default_hwnd
=
NtUserCreateWindowEx
(
0
,
&
class_name
,
&
class_name
,
&
name
,
WS_POPUP
|
WS_DISABLED
|
WS_CLIPSIBLINGS
,
0
,
0
,
1
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
FALSE
);
}
return
TRUE
;
}
void
unregister_imm_window
(
HWND
hwnd
)
{
struct
imm_thread_data
*
thread_data
=
get_user_thread_info
()
->
imm_thread_data
;
if
(
!
thread_data
)
return
;
if
(
thread_data
->
default_hwnd
==
hwnd
)
{
detach_default_window
(
thread_data
);
return
;
}
if
(
!
(
win_set_flags
(
hwnd
,
0
,
WIN_HAS_IME_WIN
)
&
WIN_HAS_IME_WIN
))
return
;
/* destroy default IME window */
TRACE
(
"unregister IME window for %p
\n
"
,
hwnd
);
if
(
!--
thread_data
->
window_cnt
)
{
HWND
destroy_hwnd
=
detach_default_window
(
thread_data
);
if
(
destroy_hwnd
)
NtUserDestroyWindow
(
destroy_hwnd
);
}
}
/***********************************************************************
* NtUserDisableThreadIme (win32u.@)
*/
BOOL
WINAPI
NtUserDisableThreadIme
(
DWORD
thread_id
)
{
struct
imm_thread_data
*
thread_data
;
if
(
thread_id
==
-
1
)
{
disable_ime
=
TRUE
;
pthread_mutex_lock
(
&
imm_mutex
);
LIST_FOR_EACH_ENTRY
(
thread_data
,
&
thread_data_list
,
struct
imm_thread_data
,
entry
)
{
if
(
thread_data
->
thread_id
==
GetCurrentThreadId
())
continue
;
if
(
!
thread_data
->
default_hwnd
)
continue
;
NtUserMessageCall
(
thread_data
->
default_hwnd
,
WM_WINE_DESTROYWINDOW
,
0
,
0
,
0
,
NtUserSendNotifyMessage
,
FALSE
);
}
pthread_mutex_unlock
(
&
imm_mutex
);
}
else
if
(
!
thread_id
||
thread_id
==
GetCurrentThreadId
())
{
if
(
!
(
thread_data
=
get_imm_thread_data
()))
return
FALSE
;
thread_data
->
disable_ime
=
TRUE
;
}
else
return
FALSE
;
if
((
thread_data
=
get_user_thread_info
()
->
imm_thread_data
))
{
HWND
destroy_hwnd
=
detach_default_window
(
thread_data
);
NtUserDestroyWindow
(
destroy_hwnd
);
}
return
TRUE
;
}
HWND
get_default_ime_window
(
HWND
hwnd
)
{
struct
imm_thread_data
*
thread_data
;
HWND
ret
=
0
;
if
(
hwnd
)
{
DWORD
thread_id
;
if
(
!
(
thread_id
=
get_window_thread
(
hwnd
,
NULL
)))
return
0
;
pthread_mutex_lock
(
&
imm_mutex
);
LIST_FOR_EACH_ENTRY
(
thread_data
,
&
thread_data_list
,
struct
imm_thread_data
,
entry
)
{
if
(
thread_data
->
thread_id
!=
thread_id
)
continue
;
ret
=
thread_data
->
default_hwnd
;
break
;
}
pthread_mutex_unlock
(
&
imm_mutex
);
}
else
if
((
thread_data
=
get_user_thread_info
()
->
imm_thread_data
))
{
ret
=
thread_data
->
default_hwnd
;
}
TRACE
(
"default for %p is %p
\n
"
,
hwnd
,
ret
);
return
ret
;
}
void
cleanup_imm_thread
(
void
)
{
struct
user_thread_info
*
thread_info
=
get_user_thread_info
();
if
(
thread_info
->
imm_thread_data
)
{
pthread_mutex_lock
(
&
imm_mutex
);
list_remove
(
&
thread_info
->
imm_thread_data
->
entry
);
pthread_mutex_unlock
(
&
imm_mutex
);
free
(
thread_info
->
imm_thread_data
);
thread_info
->
imm_thread_data
=
NULL
;
}
NtUserDestroyInputContext
(
thread_info
->
client_info
.
default_imc
);
}
dlls/win32u/input.c
View file @
047d74c4
...
...
@@ -1551,7 +1551,7 @@ HWND get_focus(void)
*/
static
HWND
set_focus_window
(
HWND
hwnd
)
{
HWND
previous
=
0
;
HWND
previous
=
0
,
ime_hwnd
;
BOOL
ret
;
SERVER_START_REQ
(
set_focus_window
)
...
...
@@ -1568,7 +1568,10 @@ static HWND set_focus_window( HWND hwnd )
{
send_message
(
previous
,
WM_KILLFOCUS
,
(
WPARAM
)
hwnd
,
0
);
if
(
user_callbacks
)
user_callbacks
->
notify_ime
(
previous
,
IME_INTERNAL_DEACTIVATE
);
ime_hwnd
=
get_default_ime_window
(
previous
);
if
(
ime_hwnd
)
send_message
(
ime_hwnd
,
WM_IME_INTERNAL
,
IME_INTERNAL_DEACTIVATE
,
HandleToUlong
(
previous
)
);
if
(
hwnd
!=
get_focus
())
return
previous
;
/* changed by the message */
}
...
...
@@ -1576,7 +1579,10 @@ static HWND set_focus_window( HWND hwnd )
{
user_driver
->
pSetFocus
(
hwnd
);
if
(
user_callbacks
)
user_callbacks
->
notify_ime
(
hwnd
,
IME_INTERNAL_ACTIVATE
);
ime_hwnd
=
get_default_ime_window
(
hwnd
);
if
(
ime_hwnd
)
send_message
(
ime_hwnd
,
WM_IME_INTERNAL
,
IME_INTERNAL_ACTIVATE
,
HandleToUlong
(
hwnd
)
);
if
(
previous
)
NtUserNotifyWinEvent
(
EVENT_OBJECT_FOCUS
,
hwnd
,
OBJID_CLIENT
,
0
);
...
...
dlls/win32u/ntuser_private.h
View file @
047d74c4
...
...
@@ -35,13 +35,10 @@ struct user_callbacks
BOOL
(
WINAPI
*
pImmProcessKey
)(
HWND
,
HKL
,
UINT
,
LPARAM
,
DWORD
);
BOOL
(
WINAPI
*
pImmTranslateMessage
)(
HWND
,
UINT
,
WPARAM
,
LPARAM
);
NTSTATUS
(
WINAPI
*
pNtWaitForMultipleObjects
)(
ULONG
,
const
HANDLE
*
,
BOOLEAN
,
BOOLEAN
,
const
LARGE_INTEGER
*
);
void
(
CDECL
*
notify_ime
)(
HWND
hwnd
,
UINT
param
);
BOOL
(
CDECL
*
post_dde_message
)(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
,
DWORD
dest_tid
,
DWORD
type
);
BOOL
(
CDECL
*
unpack_dde_message
)(
HWND
hwnd
,
UINT
message
,
WPARAM
*
wparam
,
LPARAM
*
lparam
,
void
**
buffer
,
size_t
size
);
BOOL
(
WINAPI
*
register_imm
)(
HWND
hwnd
);
void
(
WINAPI
*
unregister_imm
)(
HWND
hwnd
);
NTSTATUS
(
CDECL
*
try_finally
)(
NTSTATUS
(
CDECL
*
func
)(
void
*
),
void
*
arg
,
void
(
CALLBACK
*
finally_func
)(
BOOL
));
};
...
...
@@ -154,6 +151,7 @@ struct user_thread_info
struct
received_message_info
*
receive_info
;
/* Message being currently received */
struct
wm_char_mapping_data
*
wmchar_data
;
/* Data for WM_CHAR mappings */
struct
user_key_state_info
*
key_state
;
/* Cache of global key state */
struct
imm_thread_data
*
imm_thread_data
;
/* IMM thread data */
HKL
kbd_layout
;
/* Current keyboard layout */
DWORD
kbd_layout_id
;
/* Current keyboard layout ID */
struct
rawinput_thread_data
*
rawinput
;
/* RawInput thread local data / buffer */
...
...
@@ -273,6 +271,7 @@ WNDPROC get_winproc( WNDPROC proc, BOOL ansi ) DECLSPEC_HIDDEN;
void
get_winproc_params
(
struct
win_proc_params
*
params
)
DECLSPEC_HIDDEN
;
struct
dce
*
get_class_dce
(
struct
tagCLASS
*
class
)
DECLSPEC_HIDDEN
;
struct
dce
*
set_class_dce
(
struct
tagCLASS
*
class
,
struct
dce
*
dce
)
DECLSPEC_HIDDEN
;
BOOL
needs_ime_window
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
void
register_builtin_classes
(
void
)
DECLSPEC_HIDDEN
;
/* cursoricon.c */
...
...
dlls/win32u/sysparams.c
View file @
047d74c4
...
...
@@ -4818,7 +4818,7 @@ static void thread_detach(void)
free
(
thread_info
->
rawinput
);
destroy_thread_windows
();
NtUserDestroyInputContext
(
thread_info
->
client_info
.
default_imc
);
cleanup_imm_thread
(
);
NtClose
(
thread_info
->
server_queue
);
exiting_thread_id
=
0
;
...
...
dlls/win32u/win32u.spec
View file @
047d74c4
...
...
@@ -837,7 +837,7 @@
@ stdcall NtUserDestroyWindow(long)
@ stub NtUserDisableImmersiveOwner
@ stub NtUserDisableProcessWindowFiltering
@ st
ub NtUserDisableThreadIme
@ st
dcall NtUserDisableThreadIme(long)
@ stub NtUserDiscardPointerFrameMessages
@ stdcall NtUserDispatchMessage(ptr)
@ stub NtUserDisplayConfigGetDeviceInfo
...
...
dlls/win32u/win32u_private.h
View file @
047d74c4
...
...
@@ -214,6 +214,7 @@ struct unix_funcs
BOOL
(
WINAPI
*
pNtUserDestroyCursor
)(
HCURSOR
cursor
,
ULONG
arg
);
BOOL
(
WINAPI
*
pNtUserDestroyMenu
)(
HMENU
handle
);
BOOL
(
WINAPI
*
pNtUserDestroyWindow
)(
HWND
hwnd
);
BOOL
(
WINAPI
*
pNtUserDisableThreadIme
)(
DWORD
thread_id
);
LRESULT
(
WINAPI
*
pNtUserDispatchMessage
)(
const
MSG
*
msg
);
BOOL
(
WINAPI
*
pNtUserDragDetect
)(
HWND
hwnd
,
int
x
,
int
y
);
BOOL
(
WINAPI
*
pNtUserDrawCaptionTemp
)(
HWND
hwnd
,
HDC
hdc
,
const
RECT
*
rect
,
HFONT
font
,
...
...
@@ -393,8 +394,12 @@ extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL
extern
BOOL
unhook_windows_hook
(
INT
id
,
HOOKPROC
proc
)
DECLSPEC_HIDDEN
;
/* imm.c */
extern
void
cleanup_imm_thread
(
void
)
DECLSPEC_HIDDEN
;
extern
HWND
get_default_ime_window
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
HIMC
get_default_input_context
(
void
)
DECLSPEC_HIDDEN
;
extern
HIMC
get_window_input_context
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
BOOL
register_imm_window
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
void
unregister_imm_window
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
/* input.c */
extern
BOOL
destroy_caret
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/win32u/window.c
View file @
047d74c4
...
...
@@ -4680,12 +4680,7 @@ LRESULT destroy_window( 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
);
if
(
user_callbacks
)
user_callbacks
->
unregister_imm
(
hwnd
);
}
unregister_imm_window
(
hwnd
);
/* free child windows */
if
((
children
=
list_window_children
(
0
,
hwnd
,
NULL
,
0
)))
...
...
@@ -5262,7 +5257,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
/* create default IME window */
if
(
!
is_desktop_window
(
hwnd
)
&&
parent
!=
get_hwnd_message_parent
()
&&
user_callbacks
&&
user_callbacks
->
register_imm
(
hwnd
))
register_imm_window
(
hwnd
))
{
TRACE
(
"register IME window for %p
\n
"
,
hwnd
);
win_set_flags
(
hwnd
,
WIN_HAS_IME_WIN
,
0
);
...
...
@@ -5377,6 +5372,9 @@ ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code )
case
NtUserCallHwnd_DrawMenuBar
:
return
draw_menu_bar
(
hwnd
);
case
NtUserCallHwnd_GetDefaultImeWindow
:
return
HandleToUlong
(
get_default_ime_window
(
hwnd
));
case
NtUserCallHwnd_GetDpiForWindow
:
return
get_dpi_for_window
(
hwnd
);
...
...
dlls/win32u/wrappers.c
View file @
047d74c4
...
...
@@ -849,6 +849,12 @@ BOOL WINAPI NtUserDestroyWindow( HWND hwnd )
return
unix_funcs
->
pNtUserDestroyWindow
(
hwnd
);
}
BOOL
WINAPI
NtUserDisableThreadIme
(
DWORD
thread_id
)
{
if
(
!
unix_funcs
)
return
FALSE
;
return
unix_funcs
->
pNtUserDisableThreadIme
(
thread_id
);
}
LRESULT
WINAPI
NtUserDispatchMessage
(
const
MSG
*
msg
)
{
if
(
!
unix_funcs
)
return
0
;
...
...
include/ntuser.h
View file @
047d74c4
...
...
@@ -599,6 +599,7 @@ BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg );
BOOL
WINAPI
NtUserDestroyInputContext
(
HIMC
handle
);
BOOL
WINAPI
NtUserDestroyMenu
(
HMENU
menu
);
BOOL
WINAPI
NtUserDestroyWindow
(
HWND
hwnd
);
BOOL
WINAPI
NtUserDisableThreadIme
(
DWORD
thread_id
);
LRESULT
WINAPI
NtUserDispatchMessage
(
const
MSG
*
msg
);
BOOL
WINAPI
NtUserDragDetect
(
HWND
hwnd
,
int
x
,
int
y
);
BOOL
WINAPI
NtUserDrawCaptionTemp
(
HWND
hwnd
,
HDC
hdc
,
const
RECT
*
rect
,
HFONT
font
,
...
...
@@ -1055,6 +1056,7 @@ enum
{
NtUserCallHwnd_ArrangeIconicWindows
,
NtUserCallHwnd_DrawMenuBar
,
NtUserCallHwnd_GetDefaultImeWindow
,
NtUserCallHwnd_GetDpiForWindow
,
NtUserCallHwnd_GetParent
,
NtUserCallHwnd_GetWindowContextHelpId
,
...
...
@@ -1083,6 +1085,11 @@ static inline DWORD NtUserGetWindowContextHelpId( HWND hwnd )
return
NtUserCallHwnd
(
hwnd
,
NtUserCallHwnd_GetWindowContextHelpId
);
}
static
inline
HWND
NtUserGetDefaultImeWindow
(
HWND
hwnd
)
{
return
UlongToHandle
(
NtUserCallHwnd
(
hwnd
,
NtUserCallHwnd_GetDefaultImeWindow
));
}
static
inline
UINT
NtUserGetDpiForWindow
(
HWND
hwnd
)
{
return
NtUserCallHwnd
(
hwnd
,
NtUserCallHwnd_GetDpiForWindow
);
...
...
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