Commit 9b4c09d8 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winex11: Post internal WM_IME_NOTIFY wparam on composition updates.

parent ecd8c931
......@@ -41,6 +41,7 @@ static const char *debugstr_imn( WPARAM wparam )
case IMN_GUIDELINE: return "IMN_GUIDELINE";
case IMN_SETSTATUSWINDOWPOS: return "IMN_SETSTATUSWINDOWPOS";
case IMN_WINE_SET_OPEN_STATUS: return "IMN_WINE_SET_OPEN_STATUS";
case IMN_WINE_SET_COMP_STRING: return "IMN_WINE_SET_COMP_STRING";
default: return wine_dbg_sprintf( "%#Ix", wparam );
}
}
......@@ -338,6 +339,28 @@ static void ime_ui_start_composition( HIMC himc, HWND hwnd )
ImmUnlockIMC( himc );
}
static UINT ime_set_comp_string( HIMC himc, LPARAM lparam )
{
union
{
struct
{
UINT uMsgCount;
TRANSMSG TransMsg[10];
};
TRANSMSGLIST list;
} buffer = {.uMsgCount = ARRAY_SIZE(buffer.TransMsg)};
UINT count;
TRACE( "himc %p\n", himc );
count = ImeToAsciiEx( VK_PROCESSKEY, lparam, NULL, &buffer.list, 0, himc );
if (count >= buffer.uMsgCount)
WARN( "ImeToAsciiEx returned %#x messages\n", count );
return count;
}
static LRESULT ime_ui_notify( HIMC himc, HWND hwnd, WPARAM wparam, LPARAM lparam )
{
TRACE( "himc %p, hwnd %p, wparam %s, lparam %#Ix\n", hwnd, himc, debugstr_imn(wparam), lparam );
......@@ -346,6 +369,8 @@ static LRESULT ime_ui_notify( HIMC himc, HWND hwnd, WPARAM wparam, LPARAM lparam
{
case IMN_WINE_SET_OPEN_STATUS:
return ImmSetOpenStatus( himc, lparam );
case IMN_WINE_SET_COMP_STRING:
return ime_set_comp_string( himc, lparam );
default:
FIXME( "himc %p, hwnd %p, wparam %s, lparam %#Ix stub!\n", hwnd, himc, debugstr_imn(wparam), lparam );
return 0;
......
......@@ -398,6 +398,7 @@ 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,
......
......@@ -1347,7 +1347,7 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
if (status == XLookupChars)
{
X11DRV_XIMLookupChars( Str, ascii_chars );
xim_set_result_string( hwnd, Str, ascii_chars );
if (buf != Str)
free( Str );
return TRUE;
......
......@@ -208,6 +208,8 @@ extern INT X11DRV_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size ) DECLSPE
extern UINT X11DRV_MapVirtualKeyEx( UINT code, UINT map_type, HKL hkl ) DECLSPEC_HIDDEN;
extern INT X11DRV_ToUnicodeEx( UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
LPWSTR bufW, int bufW_size, UINT flags, HKL hkl ) DECLSPEC_HIDDEN;
extern UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state,
COMPOSITIONSTRING *compstr, HIMC himc ) DECLSPEC_HIDDEN;
extern SHORT X11DRV_VkKeyScanEx( WCHAR wChar, HKL hkl ) DECLSPEC_HIDDEN;
extern void X11DRV_NotifyIMEStatus( HWND hwnd, UINT status ) DECLSPEC_HIDDEN;
extern void X11DRV_DestroyCursorIcon( HCURSOR handle ) DECLSPEC_HIDDEN;
......@@ -824,7 +826,7 @@ extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN;
extern BOOL xim_init( const WCHAR *input_style ) DECLSPEC_HIDDEN;
extern void xim_thread_attach( struct x11drv_thread_data *data ) DECLSPEC_HIDDEN;
extern BOOL xim_in_compose_mode(void) DECLSPEC_HIDDEN;
extern void X11DRV_XIMLookupChars( const char *str, UINT count ) DECLSPEC_HIDDEN;
extern void xim_set_result_string( HWND hwnd, const char *str, UINT count ) DECLSPEC_HIDDEN;
extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
extern void xim_set_focus( HWND hwnd, BOOL focus ) DECLSPEC_HIDDEN;
......
......@@ -27,6 +27,8 @@
#include <stdlib.h>
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
......@@ -42,6 +44,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(xim);
#define XICProc XIMProc
#endif
struct ime_update
{
struct list entry;
DWORD id;
};
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;
......@@ -72,6 +83,21 @@ BOOL xim_in_compose_mode(void)
return !!ime_comp_buf;
}
static void post_ime_update( HWND hwnd )
{
UINT id;
struct ime_update *update;
if (!(update = malloc( sizeof(struct ime_update) ))) return;
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 );
}
static void xim_update_comp_string( UINT offset, UINT old_len, const WCHAR *text, UINT new_len )
{
UINT len = ime_comp_buf ? wcslen( ime_comp_buf ) : 0;
......@@ -96,18 +122,20 @@ static void xim_update_comp_string( UINT offset, UINT old_len, const WCHAR *text
x11drv_client_func( client_func_ime_set_composition_string, ime_comp_buf, len * sizeof(WCHAR) );
}
void X11DRV_XIMLookupChars( const char *str, UINT count )
void xim_set_result_string( HWND hwnd, const char *str, UINT count )
{
WCHAR *output;
DWORD len;
TRACE("%p %u\n", str, count);
TRACE( "hwnd %p, string %s\n", hwnd, debugstr_an(str, count) );
if (!(output = malloc( (count + 1) * sizeof(WCHAR) ))) return;
len = ntdll_umbstowcs( str, count, output, count );
output[len] = 0;
post_ime_update( hwnd );
x11drv_client_func( client_func_ime_set_result, output, len * sizeof(WCHAR) );
free( output );
}
......@@ -142,6 +170,8 @@ static int xic_preedit_start( XIC xic, XPointer user, XPointer arg )
if ((ime_comp_buf = realloc( ime_comp_buf, sizeof(WCHAR) ))) *ime_comp_buf = 0;
else ERR( "Failed to allocate preedit buffer\n" );
post_ime_update( hwnd );
return -1;
}
......@@ -155,6 +185,8 @@ static int xic_preedit_done( XIC xic, XPointer user, XPointer arg )
ime_comp_buf = NULL;
x11drv_client_call( client_ime_set_composition_status, FALSE );
post_ime_update( hwnd );
return 0;
}
......@@ -193,6 +225,7 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg )
if (text && str != text->string.multi_byte) free( str );
x11drv_client_call( client_ime_set_cursor_pos, params->caret );
post_ime_update( hwnd );
return 0;
}
......@@ -239,6 +272,8 @@ static int xic_preedit_caret( XIC xic, XPointer user, XPointer arg )
x11drv_client_call( client_ime_set_cursor_pos, pos );
params->position = xim_caret_pos = pos;
post_ime_update( hwnd );
return 0;
}
......@@ -474,10 +509,46 @@ 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 (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.@)
*/
UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc )
{
struct ime_update *update;
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 )))
list_remove( &update->entry );
pthread_mutex_unlock( &ime_mutex );
free( update );
return 0;
}
......@@ -494,6 +494,7 @@ enum wine_internal_message
/* internal WM_IME_NOTIFY wparams, not compatible with Windows */
#define IMN_WINE_SET_OPEN_STATUS 0x000f
#define IMN_WINE_SET_COMP_STRING 0x0010
/* builtin IME driver calls */
enum wine_ime_call
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment