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
5f313c0f
Commit
5f313c0f
authored
Jan 12, 2024
by
Rémi Bernon
Committed by
Alexandre Julliard
Jan 17, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
win32u: Move ImeToAsciiEx implementation from winex11.
Using a new WINE_IME_POST_UPDATE NtUserMessageCall call for the drivers.
parent
59820f0e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
149 additions
and
151 deletions
+149
-151
driver.c
dlls/win32u/driver.c
+1
-1
imm.c
dlls/win32u/imm.c
+143
-1
init.c
dlls/winex11.drv/init.c
+0
-1
x11drv.h
dlls/winex11.drv/x11drv.h
+0
-2
xim.c
dlls/winex11.drv/xim.c
+3
-146
user.c
dlls/wow64win/user.c
+1
-0
ntuser.h
include/ntuser.h
+1
-0
No files found.
dlls/win32u/driver.c
View file @
5f313c0f
...
...
@@ -731,7 +731,7 @@ static UINT nulldrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const BY
static
UINT
nulldrv_ImeToAsciiEx
(
UINT
vkey
,
UINT
vsc
,
const
BYTE
*
state
,
COMPOSITIONSTRING
*
compstr
,
HIMC
himc
)
{
return
0
;
return
STATUS_NOT_IMPLEMENTED
;
}
static
void
nulldrv_NotifyIMEStatus
(
HWND
hwnd
,
UINT
status
)
...
...
dlls/win32u/imm.c
View file @
5f313c0f
...
...
@@ -34,6 +34,15 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
imm
);
struct
ime_update
{
struct
list
entry
;
DWORD
id
;
DWORD
cursor_pos
;
WCHAR
*
comp_str
;
WCHAR
*
result_str
;
WCHAR
buffer
[];
};
struct
imc
{
...
...
@@ -53,6 +62,7 @@ struct imm_thread_data
static
struct
list
thread_data_list
=
LIST_INIT
(
thread_data_list
);
static
pthread_mutex_t
imm_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
struct
list
ime_updates
=
LIST_INIT
(
ime_updates
);
static
BOOL
disable_ime
;
static
struct
imc
*
get_imc_ptr
(
HIMC
handle
)
...
...
@@ -421,15 +431,147 @@ NTSTATUS WINAPI NtUserBuildHimcList( UINT thread_id, UINT count, HIMC *buffer, U
return
STATUS_SUCCESS
;
}
static
void
post_ime_update
(
HWND
hwnd
,
UINT
cursor_pos
,
WCHAR
*
comp_str
,
WCHAR
*
result_str
)
{
static
UINT
ime_update_count
;
UINT
id
,
comp_len
,
result_len
;
struct
ime_update
*
update
;
TRACE
(
"hwnd %p, cursor_pos %u, comp_str %s, result_str %s
\n
"
,
hwnd
,
cursor_pos
,
debugstr_w
(
comp_str
),
debugstr_w
(
result_str
)
);
comp_len
=
comp_str
?
wcslen
(
comp_str
)
+
1
:
0
;
result_len
=
result_str
?
wcslen
(
result_str
)
+
1
:
0
;
if
(
!
(
update
=
malloc
(
offsetof
(
struct
ime_update
,
buffer
[
comp_len
+
result_len
])
)))
return
;
update
->
cursor_pos
=
cursor_pos
;
update
->
comp_str
=
comp_str
?
memcpy
(
update
->
buffer
,
comp_str
,
comp_len
*
sizeof
(
WCHAR
)
)
:
NULL
;
update
->
result_str
=
result_str
?
memcpy
(
update
->
buffer
+
comp_len
,
result_str
,
result_len
*
sizeof
(
WCHAR
)
)
:
NULL
;
pthread_mutex_lock
(
&
imm_mutex
);
id
=
update
->
id
=
++
ime_update_count
;
list_add_tail
(
&
ime_updates
,
&
update
->
entry
);
pthread_mutex_unlock
(
&
imm_mutex
);
NtUserPostMessage
(
hwnd
,
WM_IME_NOTIFY
,
IMN_WINE_SET_COMP_STRING
,
id
);
}
static
struct
ime_update
*
find_ime_update
(
UINT
id
)
{
struct
ime_update
*
update
;
LIST_FOR_EACH_ENTRY
(
update
,
&
ime_updates
,
struct
ime_update
,
entry
)
if
(
update
->
id
==
id
)
return
update
;
return
NULL
;
}
UINT
ime_to_tascii_ex
(
UINT
vkey
,
UINT
lparam
,
const
BYTE
*
state
,
COMPOSITIONSTRING
*
compstr
,
HIMC
himc
)
{
UINT
needed
=
sizeof
(
COMPOSITIONSTRING
),
comp_len
,
result_len
;
struct
ime_update
*
update
;
void
*
dst
;
TRACE
(
"vkey %#x, lparam %#x, state %p, compstr %p, himc %p
\n
"
,
vkey
,
lparam
,
state
,
compstr
,
himc
);
pthread_mutex_lock
(
&
imm_mutex
);
if
(
!
(
update
=
find_ime_update
(
lparam
)))
{
pthread_mutex_unlock
(
&
imm_mutex
);
return
STATUS_NOT_FOUND
;
}
if
(
!
update
->
comp_str
)
comp_len
=
0
;
else
{
comp_len
=
wcslen
(
update
->
comp_str
);
needed
+=
comp_len
*
sizeof
(
WCHAR
);
/* GCS_COMPSTR */
needed
+=
comp_len
;
/* GCS_COMPATTR */
needed
+=
2
*
sizeof
(
DWORD
);
/* GCS_COMPCLAUSE */
}
if
(
!
update
->
result_str
)
result_len
=
0
;
else
{
result_len
=
wcslen
(
update
->
result_str
);
needed
+=
result_len
*
sizeof
(
WCHAR
);
/* GCS_RESULTSTR */
needed
+=
2
*
sizeof
(
DWORD
);
/* GCS_RESULTCLAUSE */
}
if
(
compstr
->
dwSize
<
needed
)
{
compstr
->
dwSize
=
needed
;
pthread_mutex_unlock
(
&
imm_mutex
);
return
STATUS_BUFFER_TOO_SMALL
;
}
list_remove
(
&
update
->
entry
);
pthread_mutex_unlock
(
&
imm_mutex
);
memset
(
compstr
,
0
,
sizeof
(
*
compstr
)
);
compstr
->
dwSize
=
sizeof
(
*
compstr
);
if
(
update
->
comp_str
)
{
compstr
->
dwCursorPos
=
update
->
cursor_pos
;
compstr
->
dwCompStrLen
=
comp_len
;
compstr
->
dwCompStrOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwCompStrOffset
;
memcpy
(
dst
,
update
->
comp_str
,
compstr
->
dwCompStrLen
*
sizeof
(
WCHAR
)
);
compstr
->
dwSize
+=
compstr
->
dwCompStrLen
*
sizeof
(
WCHAR
);
compstr
->
dwCompClauseLen
=
2
*
sizeof
(
DWORD
);
compstr
->
dwCompClauseOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwCompClauseOffset
;
*
((
DWORD
*
)
dst
+
0
)
=
0
;
*
((
DWORD
*
)
dst
+
1
)
=
compstr
->
dwCompStrLen
;
compstr
->
dwSize
+=
compstr
->
dwCompClauseLen
;
compstr
->
dwCompAttrLen
=
compstr
->
dwCompStrLen
;
compstr
->
dwCompAttrOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwCompAttrOffset
;
memset
(
dst
,
ATTR_INPUT
,
compstr
->
dwCompAttrLen
);
compstr
->
dwSize
+=
compstr
->
dwCompAttrLen
;
}
if
(
update
->
result_str
)
{
compstr
->
dwResultStrLen
=
result_len
;
compstr
->
dwResultStrOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwResultStrOffset
;
memcpy
(
dst
,
update
->
result_str
,
compstr
->
dwResultStrLen
*
sizeof
(
WCHAR
)
);
compstr
->
dwSize
+=
compstr
->
dwResultStrLen
*
sizeof
(
WCHAR
);
compstr
->
dwResultClauseLen
=
2
*
sizeof
(
DWORD
);
compstr
->
dwResultClauseOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwResultClauseOffset
;
*
((
DWORD
*
)
dst
+
0
)
=
0
;
*
((
DWORD
*
)
dst
+
1
)
=
compstr
->
dwResultStrLen
;
compstr
->
dwSize
+=
compstr
->
dwResultClauseLen
;
}
free
(
update
);
return
0
;
}
LRESULT
ime_driver_call
(
HWND
hwnd
,
enum
wine_ime_call
call
,
WPARAM
wparam
,
LPARAM
lparam
,
struct
ime_driver_call_params
*
params
)
{
LRESULT
res
;
switch
(
call
)
{
case
WINE_IME_PROCESS_KEY
:
return
user_driver
->
pImeProcessKey
(
params
->
himc
,
wparam
,
lparam
,
params
->
state
);
case
WINE_IME_TO_ASCII_EX
:
return
user_driver
->
pImeToAsciiEx
(
wparam
,
lparam
,
params
->
state
,
params
->
compstr
,
params
->
himc
);
res
=
user_driver
->
pImeToAsciiEx
(
wparam
,
lparam
,
params
->
state
,
params
->
compstr
,
params
->
himc
);
if
((
NTSTATUS
)
res
!=
STATUS_NOT_IMPLEMENTED
)
return
res
;
return
ime_to_tascii_ex
(
wparam
,
lparam
,
params
->
state
,
params
->
compstr
,
params
->
himc
);
case
WINE_IME_POST_UPDATE
:
post_ime_update
(
hwnd
,
wparam
,
(
WCHAR
*
)
lparam
,
(
WCHAR
*
)
params
);
return
0
;
default:
ERR
(
"Unknown IME driver call %#x
\n
"
,
call
);
return
0
;
...
...
dlls/winex11.drv/init.c
View file @
5f313c0f
...
...
@@ -397,7 +397,6 @@ static const struct user_driver_funcs x11drv_funcs =
.
pMapVirtualKeyEx
=
X11DRV_MapVirtualKeyEx
,
.
pToUnicodeEx
=
X11DRV_ToUnicodeEx
,
.
pVkKeyScanEx
=
X11DRV_VkKeyScanEx
,
.
pImeToAsciiEx
=
X11DRV_ImeToAsciiEx
,
.
pNotifyIMEStatus
=
X11DRV_NotifyIMEStatus
,
.
pDestroyCursorIcon
=
X11DRV_DestroyCursorIcon
,
.
pSetCursor
=
X11DRV_SetCursor
,
...
...
dlls/winex11.drv/x11drv.h
View file @
5f313c0f
...
...
@@ -208,8 +208,6 @@ extern INT X11DRV_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size );
extern
UINT
X11DRV_MapVirtualKeyEx
(
UINT
code
,
UINT
map_type
,
HKL
hkl
);
extern
INT
X11DRV_ToUnicodeEx
(
UINT
virtKey
,
UINT
scanCode
,
const
BYTE
*
lpKeyState
,
LPWSTR
bufW
,
int
bufW_size
,
UINT
flags
,
HKL
hkl
);
extern
UINT
X11DRV_ImeToAsciiEx
(
UINT
vkey
,
UINT
vsc
,
const
BYTE
*
state
,
COMPOSITIONSTRING
*
compstr
,
HIMC
himc
);
extern
SHORT
X11DRV_VkKeyScanEx
(
WCHAR
wChar
,
HKL
hkl
);
extern
void
X11DRV_NotifyIMEStatus
(
HWND
hwnd
,
UINT
status
);
extern
void
X11DRV_DestroyCursorIcon
(
HCURSOR
handle
);
...
...
dlls/winex11.drv/xim.c
View file @
5f313c0f
...
...
@@ -44,19 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(xim);
#define XICProc XIMProc
#endif
struct
ime_update
{
struct
list
entry
;
DWORD
id
;
DWORD
cursor_pos
;
WCHAR
*
comp_str
;
WCHAR
*
result_str
;
WCHAR
buffer
[];
};
static
pthread_mutex_t
ime_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
struct
list
ime_updates
=
LIST_INIT
(
ime_updates
);
static
DWORD
ime_update_count
;
static
WCHAR
*
ime_comp_buf
;
static
XIMStyle
input_style
=
0
;
...
...
@@ -89,23 +76,8 @@ BOOL xim_in_compose_mode(void)
static
void
post_ime_update
(
HWND
hwnd
,
UINT
cursor_pos
,
WCHAR
*
comp_str
,
WCHAR
*
result_str
)
{
UINT
id
,
comp_len
,
result_len
;
struct
ime_update
*
update
;
comp_len
=
comp_str
?
wcslen
(
comp_str
)
+
1
:
0
;
result_len
=
result_str
?
wcslen
(
result_str
)
+
1
:
0
;
if
(
!
(
update
=
malloc
(
offsetof
(
struct
ime_update
,
buffer
[
comp_len
+
result_len
])
)))
return
;
update
->
cursor_pos
=
cursor_pos
;
update
->
comp_str
=
comp_str
?
memcpy
(
update
->
buffer
,
comp_str
,
comp_len
*
sizeof
(
WCHAR
)
)
:
NULL
;
update
->
result_str
=
result_str
?
memcpy
(
update
->
buffer
+
comp_len
,
result_str
,
result_len
*
sizeof
(
WCHAR
)
)
:
NULL
;
pthread_mutex_lock
(
&
ime_mutex
);
id
=
update
->
id
=
++
ime_update_count
;
list_add_tail
(
&
ime_updates
,
&
update
->
entry
);
pthread_mutex_unlock
(
&
ime_mutex
);
NtUserPostMessage
(
hwnd
,
WM_IME_NOTIFY
,
IMN_WINE_SET_COMP_STRING
,
id
);
NtUserMessageCall
(
hwnd
,
WINE_IME_POST_UPDATE
,
cursor_pos
,
(
LPARAM
)
comp_str
,
result_str
,
NtUserImeDriverCall
,
FALSE
);
}
static
void
xim_update_comp_string
(
UINT
offset
,
UINT
old_len
,
const
WCHAR
*
text
,
UINT
new_len
)
...
...
@@ -511,123 +483,8 @@ XIC X11DRV_get_ic( HWND hwnd )
void
xim_set_focus
(
HWND
hwnd
,
BOOL
focus
)
{
struct
list
updates
=
LIST_INIT
(
updates
);
struct
ime_update
*
update
,
*
next
;
XIC
xic
;
if
(
!
(
xic
=
X11DRV_get_ic
(
hwnd
)))
return
;
if
((
xic
=
X11DRV_get_ic
(
hwnd
)))
return
;
if
(
focus
)
XSetICFocus
(
xic
);
else
XUnsetICFocus
(
xic
);
pthread_mutex_lock
(
&
ime_mutex
);
list_move_tail
(
&
updates
,
&
ime_updates
);
pthread_mutex_unlock
(
&
ime_mutex
);
LIST_FOR_EACH_ENTRY_SAFE
(
update
,
next
,
&
updates
,
struct
ime_update
,
entry
)
free
(
update
);
}
static
struct
ime_update
*
find_ime_update
(
UINT
id
)
{
struct
ime_update
*
update
;
LIST_FOR_EACH_ENTRY
(
update
,
&
ime_updates
,
struct
ime_update
,
entry
)
if
(
update
->
id
==
id
)
return
update
;
return
NULL
;
}
/***********************************************************************
* ImeToAsciiEx (X11DRV.@)
*
* As XIM filters key events upfront, we don't use ImeProcessKey and ImeToAsciiEx is instead called
* back from the IME UI window procedure when WM_IME_NOTIFY / IMN_WINE_SET_COMP_STRING messages are
* sent to it, to retrieve composition string updates and generate WM_IME messages.
*/
UINT
X11DRV_ImeToAsciiEx
(
UINT
vkey
,
UINT
lparam
,
const
BYTE
*
state
,
COMPOSITIONSTRING
*
compstr
,
HIMC
himc
)
{
UINT
needed
=
sizeof
(
COMPOSITIONSTRING
),
comp_len
,
result_len
;
struct
ime_update
*
update
;
void
*
dst
;
TRACE
(
"vkey %#x, lparam %#x, state %p, compstr %p, himc %p
\n
"
,
vkey
,
lparam
,
state
,
compstr
,
himc
);
pthread_mutex_lock
(
&
ime_mutex
);
if
(
!
(
update
=
find_ime_update
(
lparam
)))
{
pthread_mutex_unlock
(
&
ime_mutex
);
return
STATUS_NOT_FOUND
;
}
if
(
!
update
->
comp_str
)
comp_len
=
0
;
else
{
comp_len
=
wcslen
(
update
->
comp_str
);
needed
+=
comp_len
*
sizeof
(
WCHAR
);
/* GCS_COMPSTR */
needed
+=
comp_len
;
/* GCS_COMPATTR */
needed
+=
2
*
sizeof
(
DWORD
);
/* GCS_COMPCLAUSE */
}
if
(
!
update
->
result_str
)
result_len
=
0
;
else
{
result_len
=
wcslen
(
update
->
result_str
);
needed
+=
result_len
*
sizeof
(
WCHAR
);
/* GCS_RESULTSTR */
needed
+=
2
*
sizeof
(
DWORD
);
/* GCS_RESULTCLAUSE */
}
if
(
compstr
->
dwSize
<
needed
)
{
compstr
->
dwSize
=
needed
;
pthread_mutex_unlock
(
&
ime_mutex
);
return
STATUS_BUFFER_TOO_SMALL
;
}
list_remove
(
&
update
->
entry
);
pthread_mutex_unlock
(
&
ime_mutex
);
memset
(
compstr
,
0
,
sizeof
(
*
compstr
)
);
compstr
->
dwSize
=
sizeof
(
*
compstr
);
if
(
update
->
comp_str
)
{
compstr
->
dwCursorPos
=
update
->
cursor_pos
;
compstr
->
dwCompStrLen
=
comp_len
;
compstr
->
dwCompStrOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwCompStrOffset
;
memcpy
(
dst
,
update
->
comp_str
,
compstr
->
dwCompStrLen
*
sizeof
(
WCHAR
)
);
compstr
->
dwSize
+=
compstr
->
dwCompStrLen
*
sizeof
(
WCHAR
);
compstr
->
dwCompClauseLen
=
2
*
sizeof
(
DWORD
);
compstr
->
dwCompClauseOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwCompClauseOffset
;
*
((
DWORD
*
)
dst
+
0
)
=
0
;
*
((
DWORD
*
)
dst
+
1
)
=
compstr
->
dwCompStrLen
;
compstr
->
dwSize
+=
compstr
->
dwCompClauseLen
;
compstr
->
dwCompAttrLen
=
compstr
->
dwCompStrLen
;
compstr
->
dwCompAttrOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwCompAttrOffset
;
memset
(
dst
,
ATTR_INPUT
,
compstr
->
dwCompAttrLen
);
compstr
->
dwSize
+=
compstr
->
dwCompAttrLen
;
}
if
(
update
->
result_str
)
{
compstr
->
dwResultStrLen
=
result_len
;
compstr
->
dwResultStrOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwResultStrOffset
;
memcpy
(
dst
,
update
->
result_str
,
compstr
->
dwResultStrLen
*
sizeof
(
WCHAR
)
);
compstr
->
dwSize
+=
compstr
->
dwResultStrLen
*
sizeof
(
WCHAR
);
compstr
->
dwResultClauseLen
=
2
*
sizeof
(
DWORD
);
compstr
->
dwResultClauseOffset
=
compstr
->
dwSize
;
dst
=
(
BYTE
*
)
compstr
+
compstr
->
dwResultClauseOffset
;
*
((
DWORD
*
)
dst
+
0
)
=
0
;
*
((
DWORD
*
)
dst
+
1
)
=
compstr
->
dwResultStrLen
;
compstr
->
dwSize
+=
compstr
->
dwResultClauseLen
;
}
free
(
update
);
return
0
;
}
dlls/wow64win/user.c
View file @
5f313c0f
...
...
@@ -3597,6 +3597,7 @@ NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args )
ULONG
compstr
;
}
*
params32
=
result_info
;
struct
ime_driver_call_params
params
;
if
(
msg
==
WINE_IME_POST_UPDATE
)
ERR
(
"Unexpected WINE_IME_POST_UPDATE message
\n
"
);
params
.
himc
=
UlongToPtr
(
params32
->
himc
);
params
.
state
=
UlongToPtr
(
params32
->
state
);
params
.
compstr
=
UlongToPtr
(
params32
->
compstr
);
...
...
include/ntuser.h
View file @
5f313c0f
...
...
@@ -511,6 +511,7 @@ enum wine_ime_call
{
WINE_IME_PROCESS_KEY
,
WINE_IME_TO_ASCII_EX
,
WINE_IME_POST_UPDATE
,
/* for the user drivers */
};
/* NtUserImeDriverCall params */
...
...
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