From: Rémi Bernon rbernon@codeweavers.com
--- include/immdev.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/include/immdev.h b/include/immdev.h index 92f2a47c167..4141e9350c0 100644 --- a/include/immdev.h +++ b/include/immdev.h @@ -134,6 +134,13 @@ DWORD WINAPI ImmGetIMCCSize(HIMCC); #define IMMGWL_IMC 0 #define IMMGWL_PRIVATE (sizeof(LONG_PTR))
+#define INIT_STATUSWNDPOS 0x00000001 +#define INIT_CONVERSION 0x00000002 +#define INIT_SENTENCE 0x00000004 +#define INIT_LOGFONT 0x00000008 +#define INIT_COMPFORM 0x00000010 +#define INIT_SOFTKBDPOS 0x00000020 + /* IME Property bits */ #define IME_PROP_END_UNLOAD 0x0001 #define IME_PROP_KBD_CHAR_FIRST 0x0002
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index bbfae7e65d1..c3c68d1e91b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -168,6 +168,14 @@ static void check_candidate_form_( int line, CANDIDATEFORM *form, const CANDIDAT check_member_rect_( __FILE__, line, *form, *expect, rcArea ); }
+#define check_composition_form( a, b ) check_composition_form_( __LINE__, a, b ) +static void check_composition_form_( int line, COMPOSITIONFORM *form, const COMPOSITIONFORM *expect ) +{ + check_member_( __FILE__, line, *form, *expect, "%#lx", dwStyle ); + check_member_point_( __FILE__, line, *form, *expect, ptCurrentPos ); + check_member_rect_( __FILE__, line, *form, *expect, rcArea ); +} + #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE, enabled_ ## func = FALSE
@@ -6007,6 +6015,110 @@ cleanup: SET_ENABLE( ImeSetCompositionString, FALSE ); }
+static void test_ImmSetCompositionWindow(void) +{ + struct ime_call set_composition_window_0_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONWINDOW}, + .todo = TRUE + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_TEST_WIN, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETCOMPOSITIONWINDOW}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_IME_UI, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETCOMPOSITIONWINDOW}, + }, + {0}, + }; + struct ime_call set_composition_window_1_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONWINDOW}, + .todo = TRUE + }, + {.todo = TRUE}, + }; + COMPOSITIONFORM comp_form, expect_form = + { + .dwStyle = 0xfeedcafe, + .ptCurrentPos = {.x = 123, .y = 456}, + .rcArea = {.left = 1, .top = 2, .right = 3, .bottom = 4}, + }; + INPUTCONTEXT *ctx; + HIMC himc; + HKL hkl; + + ime_info.fdwProperty = IME_PROP_END_UNLOAD | IME_PROP_UNICODE; + + if (!(hkl = wineime_hkl)) return; + + hwnd = CreateWindowW( test_class.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 100, 100, NULL, NULL, NULL, NULL ); + ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + + ok_ret( 1, ImmActivateLayout( hkl ) ); + ok_ret( 1, ImmLoadIME( hkl ) ); + himc = ImmCreateContext(); + ok_ne( NULL, himc, HIMC, "%p" ); + ctx = ImmLockIMC( himc ); + ok_ne( NULL, ctx, INPUTCONTEXT *, "%p" ); + process_messages(); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; + + set_composition_window_0_seq[0].himc = himc; + set_composition_window_1_seq[0].himc = himc; + + ctx->cfCompForm = expect_form; + ctx->fdwInit = ~INIT_COMPFORM; + memset( &comp_form, 0xcd, sizeof(comp_form) ); + todo_wine ok_ret( 0, ImmGetCompositionWindow( himc, &comp_form ) ); + todo_wine ok_eq( 0xcdcdcdcd, comp_form.dwStyle, UINT, "%#x" ); + ctx->fdwInit = INIT_COMPFORM; + ok_ret( 1, ImmGetCompositionWindow( himc, &comp_form ) ); + check_composition_form( &comp_form, &expect_form ); + ok_seq( empty_sequence ); + + ctx->hWnd = hwnd; + ctx->fdwInit = 0; + memset( &comp_form, 0xcd, sizeof(comp_form) ); + ok_ret( 1, ImmSetCompositionWindow( himc, &comp_form ) ); + ok_seq( set_composition_window_0_seq ); + todo_wine ok_eq( INIT_COMPFORM, ctx->fdwInit, UINT, "%u" ); + check_composition_form( &ctx->cfCompForm, &comp_form ); + + ok_ret( 1, ImmSetCompositionWindow( himc, &expect_form ) ); + ok_seq( set_composition_window_0_seq ); + check_composition_form( &ctx->cfCompForm, &expect_form ); + + ctx->cfCompForm = expect_form; + ok_ret( 1, ImmGetCompositionWindow( himc, &comp_form ) ); + check_composition_form( &comp_form, &expect_form ); + ok_seq( empty_sequence ); + + ctx->hWnd = 0; + memset( &comp_form, 0xcd, sizeof(comp_form) ); + ok_ret( 1, ImmSetCompositionWindow( himc, &comp_form ) ); + ok_seq( set_composition_window_1_seq ); + check_composition_form( &ctx->cfCompForm, &comp_form ); + + ok_ret( 1, ImmUnlockIMC( himc ) ); + ok_ret( 1, ImmDestroyContext( himc ) ); + + ok_ret( 1, ImmActivateLayout( default_hkl ) ); + ok_ret( 1, DestroyWindow( hwnd ) ); + process_messages(); + + ok_ret( 1, ImmFreeLayout( hkl ) ); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; +} + START_TEST(imm32) { default_hkl = GetKeyboardLayout( 0 ); @@ -6063,6 +6175,7 @@ START_TEST(imm32)
test_ImmGetCompositionString( TRUE ); test_ImmGetCompositionString( FALSE ); + test_ImmSetCompositionWindow();
if (wineime_hkl) ime_cleanup( wineime_hkl, TRUE );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 99 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index c3c68d1e91b..60ecf7b050b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6119,6 +6119,104 @@ static void test_ImmSetCompositionWindow(void) ime_call_count = 0; }
+static void test_ImmSetStatusWindowPos(void) +{ + struct ime_call set_status_window_pos_0_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETSTATUSWINDOWPOS}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_TEST_WIN, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETSTATUSWINDOWPOS}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_IME_UI, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETSTATUSWINDOWPOS}, + }, + {0}, + }; + struct ime_call set_status_window_pos_1_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETSTATUSWINDOWPOS}, + }, + {.todo = TRUE}, + }; + INPUTCONTEXT *ctx; + POINT pos; + HIMC himc; + HKL hkl; + + ime_info.fdwProperty = IME_PROP_END_UNLOAD | IME_PROP_UNICODE; + + if (!(hkl = wineime_hkl)) return; + + hwnd = CreateWindowW( test_class.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 100, 100, NULL, NULL, NULL, NULL ); + ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + + ok_ret( 1, ImmActivateLayout( hkl ) ); + ok_ret( 1, ImmLoadIME( hkl ) ); + himc = ImmCreateContext(); + ok_ne( NULL, himc, HIMC, "%p" ); + ctx = ImmLockIMC( himc ); + ok_ne( NULL, ctx, INPUTCONTEXT *, "%p" ); + process_messages(); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; + + set_status_window_pos_0_seq[0].himc = himc; + set_status_window_pos_1_seq[0].himc = himc; + + memset( &pos, 0xcd, sizeof(pos) ); + ctx->ptStatusWndPos.x = 0xdeadbeef; + ctx->ptStatusWndPos.y = 0xfeedcafe; + ctx->fdwInit = ~INIT_STATUSWNDPOS; + todo_wine ok_ret( 0, ImmGetStatusWindowPos( himc, &pos ) ); + todo_wine ok_eq( 0xcdcdcdcd, pos.x, UINT, "%u" ); + todo_wine ok_eq( 0xcdcdcdcd, pos.y, UINT, "%u" ); + ctx->fdwInit = INIT_STATUSWNDPOS; + ok_ret( 1, ImmGetStatusWindowPos( himc, &pos ) ); + ok_eq( 0xdeadbeef, pos.x, UINT, "%u" ); + ok_eq( 0xfeedcafe, pos.y, UINT, "%u" ); + ok_seq( empty_sequence ); + + pos.x = 123; + pos.y = 456; + ctx->hWnd = hwnd; + ctx->fdwInit = 0; + ok_ret( 1, ImmSetStatusWindowPos( himc, &pos ) ); + ok_seq( set_status_window_pos_0_seq ); + todo_wine ok_eq( INIT_STATUSWNDPOS, ctx->fdwInit, UINT, "%u" ); + + ok_ret( 1, ImmSetStatusWindowPos( himc, &pos ) ); + ok_seq( set_status_window_pos_0_seq ); + ok_ret( 1, ImmGetStatusWindowPos( himc, &pos ) ); + ok_eq( 123, pos.x, UINT, "%u" ); + ok_eq( 123, ctx->ptStatusWndPos.x, UINT, "%u" ); + ok_eq( 456, pos.y, UINT, "%u" ); + ok_eq( 456, ctx->ptStatusWndPos.y, UINT, "%u" ); + ok_seq( empty_sequence ); + + ctx->hWnd = 0; + ok_ret( 1, ImmSetStatusWindowPos( himc, &pos ) ); + ok_seq( set_status_window_pos_1_seq ); + + ok_ret( 1, ImmUnlockIMC( himc ) ); + ok_ret( 1, ImmDestroyContext( himc ) ); + + ok_ret( 1, ImmActivateLayout( default_hkl ) ); + ok_ret( 1, DestroyWindow( hwnd ) ); + process_messages(); + + ok_ret( 1, ImmFreeLayout( hkl ) ); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; +} + START_TEST(imm32) { default_hkl = GetKeyboardLayout( 0 ); @@ -6176,6 +6274,7 @@ START_TEST(imm32) test_ImmGetCompositionString( TRUE ); test_ImmGetCompositionString( FALSE ); test_ImmSetCompositionWindow(); + test_ImmSetStatusWindowPos();
if (wineime_hkl) ime_cleanup( wineime_hkl, TRUE );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 205 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 60ecf7b050b..8202d1f7c1f 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -97,6 +97,12 @@ extern BOOL WINAPI ImmActivateLayout(HKL); #define check_member_wstr( val, exp, member ) \ check_member_wstr_( __FILE__, __LINE__, val, exp, member )
+#define check_member_str_( file, line, val, exp, member ) \ + ok_(file, line)( !strcmp( (val).member, (exp).member ), "got " #member " %s\n", \ + debugstr_a((val).member) ) +#define check_member_str( val, exp, member ) \ + check_member_str_( __FILE__, __LINE__, val, exp, member ) + #define check_member_point_( file, line, val, exp, member ) \ ok_(file, line)( !memcmp( &(val).member, &(exp).member, sizeof(POINT) ), \ "got " #member " %s\n", wine_dbgstr_point( &(val).member ) ) @@ -176,6 +182,44 @@ static void check_composition_form_( int line, COMPOSITIONFORM *form, const COMP check_member_rect_( __FILE__, line, *form, *expect, rcArea ); }
+#define check_logfont_w( a, b ) check_logfont_w_( __LINE__, a, b, FALSE ) +static void check_logfont_w_( int line, LOGFONTW *font, const LOGFONTW *expect, BOOL todo ) +{ + check_member_( __FILE__, line, *font, *expect, "%lu", lfHeight ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfWidth ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfEscapement ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfOrientation ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfWeight ); + check_member_( __FILE__, line, *font, *expect, "%u", lfItalic ); + check_member_( __FILE__, line, *font, *expect, "%u", lfUnderline ); + check_member_( __FILE__, line, *font, *expect, "%u", lfStrikeOut ); + check_member_( __FILE__, line, *font, *expect, "%u", lfCharSet ); + check_member_( __FILE__, line, *font, *expect, "%u", lfOutPrecision ); + check_member_( __FILE__, line, *font, *expect, "%u", lfClipPrecision ); + check_member_( __FILE__, line, *font, *expect, "%u", lfQuality ); + check_member_( __FILE__, line, *font, *expect, "%u", lfPitchAndFamily ); + todo_wine_if(todo) check_member_wstr_( __FILE__, line, *font, *expect, lfFaceName ); +} + +#define check_logfont_a( a, b ) check_logfont_a_( __LINE__, a, b, FALSE ) +static void check_logfont_a_( int line, LOGFONTA *font, const LOGFONTA *expect, BOOL todo ) +{ + check_member_( __FILE__, line, *font, *expect, "%lu", lfHeight ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfWidth ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfEscapement ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfOrientation ); + check_member_( __FILE__, line, *font, *expect, "%lu", lfWeight ); + check_member_( __FILE__, line, *font, *expect, "%u", lfItalic ); + check_member_( __FILE__, line, *font, *expect, "%u", lfUnderline ); + check_member_( __FILE__, line, *font, *expect, "%u", lfStrikeOut ); + check_member_( __FILE__, line, *font, *expect, "%u", lfCharSet ); + check_member_( __FILE__, line, *font, *expect, "%u", lfOutPrecision ); + check_member_( __FILE__, line, *font, *expect, "%u", lfClipPrecision ); + check_member_( __FILE__, line, *font, *expect, "%u", lfQuality ); + check_member_( __FILE__, line, *font, *expect, "%u", lfPitchAndFamily ); + todo_wine_if(todo) check_member_str_( __FILE__, line, *font, *expect, lfFaceName ); +} + #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE, enabled_ ## func = FALSE
@@ -1009,6 +1053,7 @@ static DWORD WINAPI test_cross_thread_himc_thread( void *arg ) COMPOSITIONFORM composition = {0}; INPUTCONTEXT *contexts[2]; HIMC himc[2], tmp_himc; + LOGFONTW fontW = {0}; HWND hwnd, tmp_hwnd; POINT pos = {0}; MSG msg; @@ -1041,6 +1086,8 @@ static DWORD WINAPI test_cross_thread_himc_thread( void *arg ) ok_ret( 1, ImmSetCandidateWindow( himc[1], &candidate ) ); ok_ret( 1, ImmSetStatusWindowPos( himc[0], &pos ) ); ok_ret( 1, ImmSetStatusWindowPos( himc[1], &pos ) ); + ok_ret( 1, ImmSetCompositionFontW( himc[0], &fontW ) ); + ok_ret( 1, ImmSetCompositionFontW( himc[1], &fontW ) );
params->hwnd = hwnd; params->himc[0] = himc[0]; @@ -6217,6 +6264,162 @@ static void test_ImmSetStatusWindowPos(void) ime_call_count = 0; }
+static void test_ImmSetCompositionFont( BOOL unicode ) +{ + struct ime_call set_composition_font_0_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONFONT}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_TEST_WIN, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETCOMPOSITIONFONT}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_IME_UI, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETCOMPOSITIONFONT}, + }, + {0}, + }; + struct ime_call set_composition_font_1_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONFONT}, + }, + {.todo = TRUE}, + }; + LOGFONTW fontW, expect_fontW = + { + .lfHeight = 1, + .lfWidth = 2, + .lfEscapement = 3, + .lfOrientation = 4, + .lfWeight = 5, + .lfItalic = 6, + .lfUnderline = 7, + .lfStrikeOut = 8, + .lfCharSet = 8, + .lfOutPrecision = 10, + .lfClipPrecision = 11, + .lfQuality = 12, + .lfPitchAndFamily = 13, + .lfFaceName = L"FontFace", + }; + LOGFONTA fontA, expect_fontA = + { + .lfHeight = 1, + .lfWidth = 2, + .lfEscapement = 3, + .lfOrientation = 4, + .lfWeight = 5, + .lfItalic = 6, + .lfUnderline = 7, + .lfStrikeOut = 8, + .lfCharSet = 8, + .lfOutPrecision = 10, + .lfClipPrecision = 11, + .lfQuality = 12, + .lfPitchAndFamily = 13, + .lfFaceName = "FontFace", + }; + INPUTCONTEXT *ctx; + HIMC himc; + HKL hkl; + + winetest_push_context( unicode ? "unicode" : "ansi" ); + + /* IME_PROP_END_UNLOAD for the IME to unload / reload. */ + ime_info.fdwProperty = IME_PROP_END_UNLOAD; + if (unicode) ime_info.fdwProperty |= IME_PROP_UNICODE; + + if (!(hkl = wineime_hkl)) goto cleanup; + + hwnd = CreateWindowW( test_class.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 100, 100, NULL, NULL, NULL, NULL ); + ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + + ok_ret( 1, ImmActivateLayout( hkl ) ); + ok_ret( 1, ImmLoadIME( hkl ) ); + himc = ImmCreateContext(); + ok_ne( NULL, himc, HIMC, "%p" ); + ctx = ImmLockIMC( himc ); + ok_ne( NULL, ctx, INPUTCONTEXT *, "%p" ); + process_messages(); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; + + set_composition_font_0_seq[0].himc = himc; + set_composition_font_1_seq[0].himc = himc; + + memset( &fontW, 0xcd, sizeof(fontW) ); + memset( &fontA, 0xcd, sizeof(fontA) ); + + if (unicode) ctx->lfFont.W = expect_fontW; + else ctx->lfFont.A = expect_fontA; + ctx->fdwInit = ~INIT_LOGFONT; + todo_wine ok_ret( 0, ImmGetCompositionFontW( himc, &fontW ) ); + todo_wine ok_ret( 0, ImmGetCompositionFontA( himc, &fontA ) ); + ctx->fdwInit = INIT_LOGFONT; + ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); + check_logfont_w_( __LINE__, &fontW, &expect_fontW, !unicode ); + ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); + check_logfont_a_( __LINE__, &fontA, &expect_fontA, !unicode ); + + ctx->hWnd = hwnd; + ctx->fdwInit = 0; + memset( &ctx->lfFont, 0xcd, sizeof(ctx->lfFont) ); + ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) ); + todo_wine ok_eq( INIT_LOGFONT, ctx->fdwInit, UINT, "%u" ); + ok_seq( set_composition_font_0_seq ); + ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) ); + ok_seq( set_composition_font_0_seq ); + if (unicode) check_logfont_w( &ctx->lfFont.W, &expect_fontW ); + else check_logfont_a_( __LINE__, &ctx->lfFont.A, &expect_fontA, TRUE ); + + ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); + check_logfont_w( &fontW, &expect_fontW ); + ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); + check_logfont_a( &fontA, &expect_fontA ); + + ctx->hWnd = hwnd; + ctx->fdwInit = 0; + memset( &ctx->lfFont, 0xcd, sizeof(ctx->lfFont) ); + ok_ret( 1, ImmSetCompositionFontA( himc, &expect_fontA ) ); + todo_wine ok_eq( INIT_LOGFONT, ctx->fdwInit, UINT, "%u" ); + ok_seq( set_composition_font_0_seq ); + ok_ret( 1, ImmSetCompositionFontA( himc, &expect_fontA ) ); + ok_seq( set_composition_font_0_seq ); + if (unicode) check_logfont_w( &ctx->lfFont.W, &expect_fontW ); + else check_logfont_a_( __LINE__, &ctx->lfFont.A, &expect_fontA, TRUE ); + + ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); + check_logfont_w( &fontW, &expect_fontW ); + ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); + check_logfont_a( &fontA, &expect_fontA ); + + ctx->hWnd = 0; + ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) ); + ok_seq( set_composition_font_1_seq ); + ok_ret( 1, ImmSetCompositionFontA( himc, &expect_fontA ) ); + ok_seq( set_composition_font_1_seq ); + + ok_ret( 1, ImmUnlockIMC( himc ) ); + ok_ret( 1, ImmDestroyContext( himc ) ); + + ok_ret( 1, ImmActivateLayout( default_hkl ) ); + ok_ret( 1, DestroyWindow( hwnd ) ); + process_messages(); + + ok_ret( 1, ImmFreeLayout( hkl ) ); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; + +cleanup: + winetest_pop_context(); +} + START_TEST(imm32) { default_hkl = GetKeyboardLayout( 0 ); @@ -6275,6 +6478,8 @@ START_TEST(imm32) test_ImmGetCompositionString( FALSE ); test_ImmSetCompositionWindow(); test_ImmSetStatusWindowPos(); + test_ImmSetCompositionFont( TRUE ); + test_ImmSetCompositionFont( FALSE );
if (wineime_hkl) ime_cleanup( wineime_hkl, TRUE );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 8202d1f7c1f..ccdc6b8f801 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6420,6 +6420,106 @@ cleanup: winetest_pop_context(); }
+static void test_ImmSetCandidateWindow(void) +{ + struct ime_call set_candidate_window_0_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCANDIDATEPOS}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_TEST_WIN, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETCANDIDATEPOS, .lparam = 4}, + }, + { + .hkl = expect_ime, .himc = default_himc, + .func = MSG_IME_UI, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETCANDIDATEPOS, .lparam = 4}, + }, + {0}, + }; + struct ime_call set_candidate_window_1_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, + .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCANDIDATEPOS}, + }, + {.todo = TRUE}, + }; + CANDIDATEFORM cand_form, expect_form = + { + .dwIndex = 2, .dwStyle = 0xfeedcafe, + .ptCurrentPos = {.x = 123, .y = 456}, + .rcArea = {.left = 1, .top = 2, .right = 3, .bottom = 4}, + }; + INPUTCONTEXT *ctx; + HIMC himc; + HKL hkl; + + ime_info.fdwProperty = IME_PROP_END_UNLOAD | IME_PROP_UNICODE; + + if (!(hkl = wineime_hkl)) return; + + hwnd = CreateWindowW( test_class.lpszClassName, NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 100, 100, NULL, NULL, NULL, NULL ); + ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() ); + + ok_ret( 1, ImmActivateLayout( hkl ) ); + ok_ret( 1, ImmLoadIME( hkl ) ); + himc = ImmCreateContext(); + ok_ne( NULL, himc, HIMC, "%p" ); + ctx = ImmLockIMC( himc ); + ok_ne( NULL, ctx, INPUTCONTEXT *, "%p" ); + process_messages(); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; + + set_candidate_window_0_seq[0].himc = himc; + set_candidate_window_1_seq[0].himc = himc; + + ctx->cfCandForm[1] = expect_form; + ctx->cfCandForm[2] = expect_form; + ctx->fdwInit = 0; + memset( &cand_form, 0xcd, sizeof(cand_form) ); + ok_ret( 0, ImmGetCandidateWindow( himc, 0, &cand_form ) ); + ok_eq( 0xcdcdcdcd, cand_form.dwStyle, UINT, "%#x" ); + todo_wine ok_ret( 1, ImmGetCandidateWindow( himc, 1, &cand_form ) ); + todo_wine check_candidate_form( &cand_form, &expect_form ); + ok_ret( 1, ImmGetCandidateWindow( himc, 2, &cand_form ) ); + check_candidate_form( &cand_form, &expect_form ); + ok_seq( empty_sequence ); + + ctx->hWnd = hwnd; + memset( &cand_form, 0xcd, sizeof(cand_form) ); + cand_form.dwIndex = 2; + ok_ret( 1, ImmSetCandidateWindow( himc, &cand_form ) ); + ok_seq( set_candidate_window_0_seq ); + check_candidate_form( &ctx->cfCandForm[2], &cand_form ); + ok_eq( 0, ctx->fdwInit, UINT, "%u" ); + + ok_ret( 1, ImmSetCandidateWindow( himc, &expect_form ) ); + ok_seq( set_candidate_window_0_seq ); + check_candidate_form( &ctx->cfCandForm[2], &expect_form ); + + ctx->hWnd = 0; + memset( &cand_form, 0xcd, sizeof(cand_form) ); + cand_form.dwIndex = 2; + ok_ret( 1, ImmSetCandidateWindow( himc, &cand_form ) ); + ok_seq( set_candidate_window_1_seq ); + check_candidate_form( &ctx->cfCandForm[2], &cand_form ); + + ok_ret( 1, ImmUnlockIMC( himc ) ); + ok_ret( 1, ImmDestroyContext( himc ) ); + + ok_ret( 1, ImmActivateLayout( default_hkl ) ); + ok_ret( 1, DestroyWindow( hwnd ) ); + process_messages(); + + ok_ret( 1, ImmFreeLayout( hkl ) ); + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; +} + START_TEST(imm32) { default_hkl = GetKeyboardLayout( 0 ); @@ -6480,6 +6580,7 @@ START_TEST(imm32) test_ImmSetStatusWindowPos(); test_ImmSetCompositionFont( TRUE ); test_ImmSetCompositionFont( FALSE ); + test_ImmSetCandidateWindow();
if (wineime_hkl) ime_cleanup( wineime_hkl, TRUE );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 39 ++++++++++++++++++++------------------- dlls/imm32/tests/imm32.c | 6 ++---- 2 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index d29684f34a2..16c36c0173d 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -119,6 +119,14 @@ static struct list ime_list = LIST_INIT( ime_list );
static const WCHAR layouts_formatW[] = L"System\CurrentControlSet\Control\Keyboard Layouts\%08lx";
+static const char *debugstr_composition( const COMPOSITIONFORM *composition ) +{ + if (!composition) return "(null)"; + return wine_dbg_sprintf( "style %#lx, pos %s, area %s", composition->dwStyle, + wine_dbgstr_point( &composition->ptCurrentPos ), + wine_dbgstr_rect( &composition->rcArea ) ); +} + static BOOL ime_is_unicode( const struct ime *ime ) { return !!(ime->info.fdwProperty & IME_PROP_UNICODE); @@ -2595,28 +2603,19 @@ BOOL WINAPI ImmSetCompositionStringW( /*********************************************************************** * ImmSetCompositionWindow (IMM32.@) */ -BOOL WINAPI ImmSetCompositionWindow( - HIMC hIMC, LPCOMPOSITIONFORM lpCompForm) +BOOL WINAPI ImmSetCompositionWindow( HIMC himc, COMPOSITIONFORM *composition ) { BOOL reshow = FALSE; - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx; HWND ui_hwnd;
- TRACE("(%p, %p)\n", hIMC, lpCompForm); - if (lpCompForm) - TRACE("\t%lx, %s, %s\n", lpCompForm->dwStyle, - wine_dbgstr_point(&lpCompForm->ptCurrentPos), - wine_dbgstr_rect(&lpCompForm->rcArea)); + TRACE( "himc %p, composition %s\n", himc, debugstr_composition( composition ) );
- if (!data) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - - if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE;
- data->IMC.cfCompForm = *lpCompForm; + ctx->cfCompForm = *composition; + ctx->fdwInit |= INIT_COMPFORM;
if ((ui_hwnd = get_ime_ui_window()) && IsWindowVisible( ui_hwnd )) { @@ -2624,11 +2623,13 @@ BOOL WINAPI ImmSetCompositionWindow( ShowWindow( ui_hwnd, SW_HIDE ); }
- /* FIXME: this is a partial stub */ - if (ui_hwnd && reshow) ShowWindow( ui_hwnd, SW_SHOWNOACTIVATE );
- imc_notify_ime( data, IMN_SETCOMPOSITIONWINDOW, 0 ); + ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONWINDOW ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONWINDOW, 0 ); + + ImmUnlockIMC( himc ); + return TRUE; }
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index ccdc6b8f801..45efd946d4e 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6069,7 +6069,6 @@ static void test_ImmSetCompositionWindow(void) { .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONWINDOW}, - .todo = TRUE }, { .hkl = expect_ime, .himc = default_himc, @@ -6086,9 +6085,8 @@ static void test_ImmSetCompositionWindow(void) { .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONWINDOW}, - .todo = TRUE }, - {.todo = TRUE}, + {0}, }; COMPOSITIONFORM comp_form, expect_form = { @@ -6136,7 +6134,7 @@ static void test_ImmSetCompositionWindow(void) memset( &comp_form, 0xcd, sizeof(comp_form) ); ok_ret( 1, ImmSetCompositionWindow( himc, &comp_form ) ); ok_seq( set_composition_window_0_seq ); - todo_wine ok_eq( INIT_COMPFORM, ctx->fdwInit, UINT, "%u" ); + ok_eq( INIT_COMPFORM, ctx->fdwInit, UINT, "%u" ); check_composition_form( &ctx->cfCompForm, &comp_form );
ok_ret( 1, ImmSetCompositionWindow( himc, &expect_form ) );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 15 ++++++++------- dlls/imm32/tests/imm32.c | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 16c36c0173d..31a63ecbc80 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1740,17 +1740,18 @@ LONG WINAPI ImmGetCompositionStringW( /*********************************************************************** * ImmGetCompositionWindow (IMM32.@) */ -BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm) +BOOL WINAPI ImmGetCompositionWindow( HIMC himc, COMPOSITIONFORM *composition ) { - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx; + BOOL ret;
- TRACE("(%p, %p)\n", hIMC, lpCompForm); + TRACE( "himc %p, composition %p\n", himc, composition );
- if (!data) - return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if ((ret = !!(ctx->fdwInit & INIT_COMPFORM))) *composition = ctx->cfCompForm; + ImmUnlockIMC( himc );
- *lpCompForm = data->IMC.cfCompForm; - return TRUE; + return ret; }
/*********************************************************************** diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 45efd946d4e..3aa50ea3582 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6122,8 +6122,8 @@ static void test_ImmSetCompositionWindow(void) ctx->cfCompForm = expect_form; ctx->fdwInit = ~INIT_COMPFORM; memset( &comp_form, 0xcd, sizeof(comp_form) ); - todo_wine ok_ret( 0, ImmGetCompositionWindow( himc, &comp_form ) ); - todo_wine ok_eq( 0xcdcdcdcd, comp_form.dwStyle, UINT, "%#x" ); + ok_ret( 0, ImmGetCompositionWindow( himc, &comp_form ) ); + ok_eq( 0xcdcdcdcd, comp_form.dwStyle, UINT, "%#x" ); ctx->fdwInit = INIT_COMPFORM; ok_ret( 1, ImmGetCompositionWindow( himc, &comp_form ) ); check_composition_form( &comp_form, &expect_form );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 23 +++++++++++++---------- dlls/imm32/tests/imm32.c | 4 ++-- 2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 31a63ecbc80..b88ca86c15c 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -2698,25 +2698,28 @@ BOOL WINAPI ImmSetOpenStatus( HIMC himc, BOOL status ) /*********************************************************************** * ImmSetStatusWindowPos (IMM32.@) */ -BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) +BOOL WINAPI ImmSetStatusWindowPos( HIMC himc, POINT *pos ) { - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx;
- TRACE("(%p, %p)\n", hIMC, lpptPos); + TRACE( "himc %p, pos %s\n", himc, wine_dbgstr_point( pos ) );
- if (!data || !lpptPos) + if (!pos) { - SetLastError(ERROR_INVALID_HANDLE); + SetLastError( ERROR_INVALID_HANDLE ); return FALSE; }
- if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE;
- TRACE("\t%s\n", wine_dbgstr_point(lpptPos)); + ctx->ptStatusWndPos = *pos; + ctx->fdwInit |= INIT_STATUSWNDPOS;
- data->IMC.ptStatusWndPos = *lpptPos; - ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS); - imc_notify_ime( data, IMN_SETSTATUSWINDOWPOS, 0 ); + ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETSTATUSWINDOWPOS, 0 ); + + ImmUnlockIMC( himc );
return TRUE; } diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 3aa50ea3582..cc09d5d969d 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6188,7 +6188,7 @@ static void test_ImmSetStatusWindowPos(void) .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETSTATUSWINDOWPOS}, }, - {.todo = TRUE}, + {0}, }; INPUTCONTEXT *ctx; POINT pos; @@ -6235,7 +6235,7 @@ static void test_ImmSetStatusWindowPos(void) ctx->fdwInit = 0; ok_ret( 1, ImmSetStatusWindowPos( himc, &pos ) ); ok_seq( set_status_window_pos_0_seq ); - todo_wine ok_eq( INIT_STATUSWNDPOS, ctx->fdwInit, UINT, "%u" ); + ok_eq( INIT_STATUSWNDPOS, ctx->fdwInit, UINT, "%u" );
ok_ret( 1, ImmSetStatusWindowPos( himc, &pos ) ); ok_seq( set_status_window_pos_0_seq );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 16 ++++++++-------- dlls/imm32/tests/imm32.c | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index b88ca86c15c..8ff3a99324a 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -2092,18 +2092,18 @@ UINT WINAPI ImmGetRegisterWordStyleW( HKL hkl, UINT count, STYLEBUFW *styleW ) /*********************************************************************** * ImmGetStatusWindowPos (IMM32.@) */ -BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) +BOOL WINAPI ImmGetStatusWindowPos( HIMC himc, POINT *pos ) { - struct imc *data = get_imc_data( hIMC ); - - TRACE("(%p, %p)\n", hIMC, lpptPos); + INPUTCONTEXT *ctx; + BOOL ret;
- if (!data || !lpptPos) - return FALSE; + TRACE( "himc %p, pos %p\n", himc, pos );
- *lpptPos = data->IMC.ptStatusWndPos; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if ((ret = !!(ctx->fdwInit & INIT_STATUSWNDPOS))) *pos = ctx->ptStatusWndPos; + ImmUnlockIMC( himc );
- return TRUE; + return ret; }
/*********************************************************************** diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index cc09d5d969d..0dda2217979 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6220,9 +6220,9 @@ static void test_ImmSetStatusWindowPos(void) ctx->ptStatusWndPos.x = 0xdeadbeef; ctx->ptStatusWndPos.y = 0xfeedcafe; ctx->fdwInit = ~INIT_STATUSWNDPOS; - todo_wine ok_ret( 0, ImmGetStatusWindowPos( himc, &pos ) ); - todo_wine ok_eq( 0xcdcdcdcd, pos.x, UINT, "%u" ); - todo_wine ok_eq( 0xcdcdcdcd, pos.y, UINT, "%u" ); + ok_ret( 0, ImmGetStatusWindowPos( himc, &pos ) ); + ok_eq( 0xcdcdcdcd, pos.x, UINT, "%u" ); + ok_eq( 0xcdcdcdcd, pos.y, UINT, "%u" ); ctx->fdwInit = INIT_STATUSWNDPOS; ok_ret( 1, ImmGetStatusWindowPos( himc, &pos ) ); ok_eq( 0xdeadbeef, pos.x, UINT, "%u" );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 78 +++++++++++++++++++++++++++------------- dlls/imm32/tests/imm32.c | 18 +++++----- 2 files changed, 63 insertions(+), 33 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 8ff3a99324a..d261725bc08 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -132,6 +132,12 @@ static BOOL ime_is_unicode( const struct ime *ime ) return !!(ime->info.fdwProperty & IME_PROP_UNICODE); }
+static BOOL input_context_is_unicode( INPUTCONTEXT *ctx ) +{ + struct imc *imc = CONTAINING_RECORD( ctx, struct imc, IMC ); + return !imc->ime || ime_is_unicode( imc->ime ); +} + static BOOL IMM_DestroyContext(HIMC hIMC); static struct imc *get_imc_data( HIMC hIMC );
@@ -2438,49 +2444,73 @@ BOOL WINAPI ImmSetCandidateWindow( /*********************************************************************** * ImmSetCompositionFontA (IMM32.@) */ -BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) +BOOL WINAPI ImmSetCompositionFontA( HIMC himc, LOGFONTA *fontA ) { - struct imc *data = get_imc_data( hIMC ); - TRACE("(%p, %p)\n", hIMC, lplf); + INPUTCONTEXT *ctx; + BOOL ret = TRUE;
- if (!data || !lplf) + TRACE( "hwnd %p, fontA %p\n", himc, fontA ); + + if (!fontA) return FALSE; + + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + + if (input_context_is_unicode( ctx )) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; + LOGFONTW fontW; + memcpy( &fontW, fontA, offsetof(LOGFONTW, lfFaceName) ); + MultiByteToWideChar( CP_ACP, 0, fontA->lfFaceName, -1, fontW.lfFaceName, LF_FACESIZE ); + ret = ImmSetCompositionFontW( himc, &fontW ); } + else + { + ctx->lfFont.A = *fontA; + ctx->fdwInit |= INIT_LOGFONT;
- if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0 ); + }
- memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA)); - MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName, - LF_FACESIZE); - ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT); - imc_notify_ime( data, IMN_SETCOMPOSITIONFONT, 0 ); + ImmUnlockIMC( himc );
- return TRUE; + return ret; }
/*********************************************************************** * ImmSetCompositionFontW (IMM32.@) */ -BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) +BOOL WINAPI ImmSetCompositionFontW( HIMC himc, LOGFONTW *fontW ) { - struct imc *data = get_imc_data( hIMC ); - TRACE("(%p, %p)\n", hIMC, lplf); + INPUTCONTEXT *ctx; + BOOL ret = TRUE;
- if (!data || !lplf) + TRACE( "hwnd %p, fontW %p\n", himc, fontW ); + + if (!fontW) return FALSE; + + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + + if (!input_context_is_unicode( ctx )) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; + LOGFONTA fontA; + memcpy( &fontA, fontW, offsetof(LOGFONTA, lfFaceName) ); + WideCharToMultiByte( CP_ACP, 0, fontW->lfFaceName, -1, fontA.lfFaceName, LF_FACESIZE, NULL, NULL ); + ret = ImmSetCompositionFontA( himc, &fontA ); } + else + { + ctx->lfFont.W = *fontW; + ctx->fdwInit |= INIT_LOGFONT;
- if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0 ); + }
- data->IMC.lfFont.W = *lplf; - ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT); - imc_notify_ime( data, IMN_SETCOMPOSITIONFONT, 0 ); + ImmUnlockIMC( himc );
- return TRUE; + return ret; }
/*********************************************************************** diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 0dda2217979..2e59f04e108 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6286,7 +6286,7 @@ static void test_ImmSetCompositionFont( BOOL unicode ) .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCOMPOSITIONFONT}, }, - {.todo = TRUE}, + {0}, }; LOGFONTW fontW, expect_fontW = { @@ -6369,33 +6369,33 @@ static void test_ImmSetCompositionFont( BOOL unicode ) ctx->fdwInit = 0; memset( &ctx->lfFont, 0xcd, sizeof(ctx->lfFont) ); ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) ); - todo_wine ok_eq( INIT_LOGFONT, ctx->fdwInit, UINT, "%u" ); + ok_eq( INIT_LOGFONT, ctx->fdwInit, UINT, "%u" ); ok_seq( set_composition_font_0_seq ); ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) ); ok_seq( set_composition_font_0_seq ); if (unicode) check_logfont_w( &ctx->lfFont.W, &expect_fontW ); - else check_logfont_a_( __LINE__, &ctx->lfFont.A, &expect_fontA, TRUE ); + else check_logfont_a( &ctx->lfFont.A, &expect_fontA );
ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); - check_logfont_w( &fontW, &expect_fontW ); + check_logfont_w_( __LINE__, &fontW, &expect_fontW, !unicode ); ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); - check_logfont_a( &fontA, &expect_fontA ); + check_logfont_a_( __LINE__, &fontA, &expect_fontA, !unicode );
ctx->hWnd = hwnd; ctx->fdwInit = 0; memset( &ctx->lfFont, 0xcd, sizeof(ctx->lfFont) ); ok_ret( 1, ImmSetCompositionFontA( himc, &expect_fontA ) ); - todo_wine ok_eq( INIT_LOGFONT, ctx->fdwInit, UINT, "%u" ); + ok_eq( INIT_LOGFONT, ctx->fdwInit, UINT, "%u" ); ok_seq( set_composition_font_0_seq ); ok_ret( 1, ImmSetCompositionFontA( himc, &expect_fontA ) ); ok_seq( set_composition_font_0_seq ); if (unicode) check_logfont_w( &ctx->lfFont.W, &expect_fontW ); - else check_logfont_a_( __LINE__, &ctx->lfFont.A, &expect_fontA, TRUE ); + else check_logfont_a( &ctx->lfFont.A, &expect_fontA );
ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); - check_logfont_w( &fontW, &expect_fontW ); + check_logfont_w_( __LINE__, &fontW, &expect_fontW, !unicode ); ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); - check_logfont_a( &fontA, &expect_fontA ); + check_logfont_a_( __LINE__, &fontA, &expect_fontA, !unicode );
ctx->hWnd = 0; ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 51 ++++++++++++++++++++++++++-------------- dlls/imm32/tests/imm32.c | 28 +++++++++++----------- 2 files changed, 47 insertions(+), 32 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index d261725bc08..68196bf0149 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1413,38 +1413,53 @@ BOOL WINAPI ImmGetCandidateWindow( /*********************************************************************** * ImmGetCompositionFontA (IMM32.@) */ -BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) +BOOL WINAPI ImmGetCompositionFontA( HIMC himc, LOGFONTA *fontA ) { - LOGFONTW lfW; - BOOL rc; + INPUTCONTEXT *ctx; + LOGFONTW fontW; + BOOL ret = TRUE;
- TRACE("(%p, %p):\n", hIMC, lplf); + TRACE( "himc %p, fontA %p\n", himc, fontA );
- rc = ImmGetCompositionFontW(hIMC,&lfW); - if (!rc || !lplf) - return FALSE; + if (!fontA) return FALSE;
- memcpy(lplf,&lfW,sizeof(LOGFONTA)); - WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName, - LF_FACESIZE, NULL, NULL); - return TRUE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if (!(ctx->fdwInit & INIT_LOGFONT)) ret = FALSE; + else if (!input_context_is_unicode( ctx )) *fontA = ctx->lfFont.A; + else if ((ret = ImmGetCompositionFontW( himc, &fontW ))) + { + memcpy( fontA, &fontW, offsetof(LOGFONTA, lfFaceName) ); + WideCharToMultiByte( CP_ACP, 0, fontW.lfFaceName, -1, fontA->lfFaceName, LF_FACESIZE, NULL, NULL ); + } + ImmUnlockIMC( himc ); + + return ret; }
/*********************************************************************** * ImmGetCompositionFontW (IMM32.@) */ -BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) +BOOL WINAPI ImmGetCompositionFontW( HIMC himc, LOGFONTW *fontW ) { - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx; + LOGFONTA fontA; + BOOL ret = TRUE;
- TRACE("(%p, %p):\n", hIMC, lplf); + TRACE( "himc %p, fontW %p\n", himc, fontW );
- if (!data || !lplf) - return FALSE; + if (!fontW) return FALSE;
- *lplf = data->IMC.lfFont.W; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if (!(ctx->fdwInit & INIT_LOGFONT)) ret = FALSE; + else if (input_context_is_unicode( ctx )) *fontW = ctx->lfFont.W; + else if ((ret = ImmGetCompositionFontA( himc, &fontA ))) + { + memcpy( fontW, &fontA, offsetof(LOGFONTW, lfFaceName) ); + MultiByteToWideChar( CP_ACP, 0, fontA.lfFaceName, -1, fontW->lfFaceName, LF_FACESIZE ); + } + ImmUnlockIMC( himc );
- return TRUE; + return ret; }
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 2e59f04e108..3b8b4755080 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -182,8 +182,8 @@ static void check_composition_form_( int line, COMPOSITIONFORM *form, const COMP check_member_rect_( __FILE__, line, *form, *expect, rcArea ); }
-#define check_logfont_w( a, b ) check_logfont_w_( __LINE__, a, b, FALSE ) -static void check_logfont_w_( int line, LOGFONTW *font, const LOGFONTW *expect, BOOL todo ) +#define check_logfont_w( a, b ) check_logfont_w_( __LINE__, a, b ) +static void check_logfont_w_( int line, LOGFONTW *font, const LOGFONTW *expect ) { check_member_( __FILE__, line, *font, *expect, "%lu", lfHeight ); check_member_( __FILE__, line, *font, *expect, "%lu", lfWidth ); @@ -198,11 +198,11 @@ static void check_logfont_w_( int line, LOGFONTW *font, const LOGFONTW *expect, check_member_( __FILE__, line, *font, *expect, "%u", lfClipPrecision ); check_member_( __FILE__, line, *font, *expect, "%u", lfQuality ); check_member_( __FILE__, line, *font, *expect, "%u", lfPitchAndFamily ); - todo_wine_if(todo) check_member_wstr_( __FILE__, line, *font, *expect, lfFaceName ); + check_member_wstr_( __FILE__, line, *font, *expect, lfFaceName ); }
-#define check_logfont_a( a, b ) check_logfont_a_( __LINE__, a, b, FALSE ) -static void check_logfont_a_( int line, LOGFONTA *font, const LOGFONTA *expect, BOOL todo ) +#define check_logfont_a( a, b ) check_logfont_a_( __LINE__, a, b ) +static void check_logfont_a_( int line, LOGFONTA *font, const LOGFONTA *expect ) { check_member_( __FILE__, line, *font, *expect, "%lu", lfHeight ); check_member_( __FILE__, line, *font, *expect, "%lu", lfWidth ); @@ -217,7 +217,7 @@ static void check_logfont_a_( int line, LOGFONTA *font, const LOGFONTA *expect, check_member_( __FILE__, line, *font, *expect, "%u", lfClipPrecision ); check_member_( __FILE__, line, *font, *expect, "%u", lfQuality ); check_member_( __FILE__, line, *font, *expect, "%u", lfPitchAndFamily ); - todo_wine_if(todo) check_member_str_( __FILE__, line, *font, *expect, lfFaceName ); + check_member_str_( __FILE__, line, *font, *expect, lfFaceName ); }
#define DEFINE_EXPECT(func) \ @@ -6357,13 +6357,13 @@ static void test_ImmSetCompositionFont( BOOL unicode ) if (unicode) ctx->lfFont.W = expect_fontW; else ctx->lfFont.A = expect_fontA; ctx->fdwInit = ~INIT_LOGFONT; - todo_wine ok_ret( 0, ImmGetCompositionFontW( himc, &fontW ) ); - todo_wine ok_ret( 0, ImmGetCompositionFontA( himc, &fontA ) ); + ok_ret( 0, ImmGetCompositionFontW( himc, &fontW ) ); + ok_ret( 0, ImmGetCompositionFontA( himc, &fontA ) ); ctx->fdwInit = INIT_LOGFONT; ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); - check_logfont_w_( __LINE__, &fontW, &expect_fontW, !unicode ); + check_logfont_w( &fontW, &expect_fontW ); ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); - check_logfont_a_( __LINE__, &fontA, &expect_fontA, !unicode ); + check_logfont_a( &fontA, &expect_fontA );
ctx->hWnd = hwnd; ctx->fdwInit = 0; @@ -6377,9 +6377,9 @@ static void test_ImmSetCompositionFont( BOOL unicode ) else check_logfont_a( &ctx->lfFont.A, &expect_fontA );
ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); - check_logfont_w_( __LINE__, &fontW, &expect_fontW, !unicode ); + check_logfont_w( &fontW, &expect_fontW ); ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); - check_logfont_a_( __LINE__, &fontA, &expect_fontA, !unicode ); + check_logfont_a( &fontA, &expect_fontA );
ctx->hWnd = hwnd; ctx->fdwInit = 0; @@ -6393,9 +6393,9 @@ static void test_ImmSetCompositionFont( BOOL unicode ) else check_logfont_a( &ctx->lfFont.A, &expect_fontA );
ok_ret( 1, ImmGetCompositionFontW( himc, &fontW ) ); - check_logfont_w_( __LINE__, &fontW, &expect_fontW, !unicode ); + check_logfont_w( &fontW, &expect_fontW ); ok_ret( 1, ImmGetCompositionFontA( himc, &fontA ) ); - check_logfont_a_( __LINE__, &fontA, &expect_fontA, !unicode ); + check_logfont_a( &fontA, &expect_fontA );
ctx->hWnd = 0; ok_ret( 1, ImmSetCompositionFontW( himc, &expect_fontW ) );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 42 ++++++++++++++++++---------------------- dlls/imm32/tests/imm32.c | 2 +- 2 files changed, 20 insertions(+), 24 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 68196bf0149..aa63be82e4b 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -127,6 +127,14 @@ static const char *debugstr_composition( const COMPOSITIONFORM *composition ) wine_dbgstr_rect( &composition->rcArea ) ); }
+static const char *debugstr_candidate( const CANDIDATEFORM *candidate ) +{ + if (!candidate) return "(null)"; + return wine_dbg_sprintf( "idx %#lx, style %#lx, pos %s, area %s", candidate->dwIndex, + candidate->dwStyle, wine_dbgstr_point( &candidate->ptCurrentPos ), + wine_dbgstr_rect( &candidate->rcArea ) ); +} + static BOOL ime_is_unicode( const struct ime *ime ) { return !!(ime->info.fdwProperty & IME_PROP_UNICODE); @@ -827,13 +835,6 @@ static void imc_send_message( struct imc *imc, TRANSMSG *message ) SendMessageW( target, message->message, message->wParam, message->lParam ); }
-static LRESULT imc_notify_ime( struct imc *imc, WPARAM notify, LPARAM lparam ) -{ - HWND target; - if (!(target = imc->IMC.hWnd) && !(target = GetFocus())) return 0; - return SendMessageW( target, WM_IME_NOTIFY, notify, lparam ); -} - /*********************************************************************** * ImmSetActiveContext (IMM32.@) */ @@ -2429,29 +2430,24 @@ LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam) /*********************************************************************** * ImmSetCandidateWindow (IMM32.@) */ -BOOL WINAPI ImmSetCandidateWindow( - HIMC hIMC, LPCANDIDATEFORM lpCandidate) +BOOL WINAPI ImmSetCandidateWindow( HIMC himc, CANDIDATEFORM *candidate ) { - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx;
- TRACE("(%p, %p)\n", hIMC, lpCandidate); + TRACE( "hwnd %p, candidate %s\n", himc, debugstr_candidate( candidate ) );
- if (!data || !lpCandidate) - return FALSE; + if (!candidate) return FALSE; + if (candidate->dwIndex >= ARRAY_SIZE(ctx->cfCandForm)) return FALSE;
- if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE;
- TRACE("\t%lx, %lx, %s, %s\n", - lpCandidate->dwIndex, lpCandidate->dwStyle, - wine_dbgstr_point(&lpCandidate->ptCurrentPos), - wine_dbgstr_rect(&lpCandidate->rcArea)); + ctx->cfCandForm[candidate->dwIndex] = *candidate;
- if (lpCandidate->dwIndex >= ARRAY_SIZE(data->IMC.cfCandForm)) - return FALSE; + ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETCANDIDATEPOS, 1 << candidate->dwIndex );
- data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate; - ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS); - imc_notify_ime( data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex ); + ImmUnlockIMC( himc );
return TRUE; } diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 3b8b4755080..cf6c521e52f 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -6442,7 +6442,7 @@ static void test_ImmSetCandidateWindow(void) .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETCANDIDATEPOS}, }, - {.todo = TRUE}, + {0}, }; CANDIDATEFORM cand_form, expect_form = {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 24 ++++++++++-------------- dlls/imm32/tests/imm32.c | 14 +++++++------- 2 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index aa63be82e4b..62b95eba77a 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1390,25 +1390,21 @@ done: /*********************************************************************** * ImmGetCandidateWindow (IMM32.@) */ -BOOL WINAPI ImmGetCandidateWindow( - HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate) +BOOL WINAPI ImmGetCandidateWindow( HIMC himc, DWORD index, CANDIDATEFORM *candidate ) { - struct imc *data = get_imc_data( hIMC ); - - TRACE("%p, %ld, %p\n", hIMC, dwIndex, lpCandidate); - - if (!data || !lpCandidate) - return FALSE; + INPUTCONTEXT *ctx; + BOOL ret = TRUE;
- if (dwIndex >= ARRAY_SIZE(data->IMC.cfCandForm)) - return FALSE; + TRACE( "himc %p, index %lu, candidate %p\n", himc, index, candidate );
- if (data->IMC.cfCandForm[dwIndex].dwIndex != dwIndex) - return FALSE; + if (!candidate) return FALSE;
- *lpCandidate = data->IMC.cfCandForm[dwIndex]; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if (ctx->cfCandForm[index].dwIndex == -1) ret = FALSE; + else *candidate = ctx->cfCandForm[index]; + ImmUnlockIMC( himc );
- return TRUE; + return ret; }
/*********************************************************************** diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index cf6c521e52f..a623cabef7b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -5653,21 +5653,21 @@ static void test_ImmGetCandidateWindow(void) ok_eq( 0xcdcdcdcd, cand_form.dwIndex, UINT, "%u" ); ok_ret( 0, ImmGetCandidateWindow( default_himc, 3, &cand_form ) ); ok_eq( 0xcdcdcdcd, cand_form.dwIndex, UINT, "%u" ); - todo_wine ok_ret( 1, ImmGetCandidateWindow( default_himc, 4, &cand_form ) ); + ok_ret( 1, ImmGetCandidateWindow( default_himc, 4, &cand_form ) ); ok_seq( empty_sequence );
ok_ret( 0, ImmGetCandidateWindow( himc, 0, &cand_form ) ); ok_seq( empty_sequence );
- todo_wine ok_seq( empty_sequence ); + ok_seq( empty_sequence ); ok( !!ctx, "ImmLockIMC failed, error %lu\n", GetLastError() ); ctx->cfCandForm[0] = expect_form;
- todo_wine ok_ret( 1, ImmGetCandidateWindow( himc, 0, &cand_form ) ); - todo_wine check_candidate_form( &cand_form, &expect_form ); + ok_ret( 1, ImmGetCandidateWindow( himc, 0, &cand_form ) ); + check_candidate_form( &cand_form, &expect_form ); ok_seq( empty_sequence );
- todo_wine ok_seq( empty_sequence ); + ok_seq( empty_sequence ); ok( !!ctx, "ImmLockIMC failed, error %lu\n", GetLastError() ); ctx->cfCandForm[0].dwIndex = -1;
@@ -6481,8 +6481,8 @@ static void test_ImmSetCandidateWindow(void) memset( &cand_form, 0xcd, sizeof(cand_form) ); ok_ret( 0, ImmGetCandidateWindow( himc, 0, &cand_form ) ); ok_eq( 0xcdcdcdcd, cand_form.dwStyle, UINT, "%#x" ); - todo_wine ok_ret( 1, ImmGetCandidateWindow( himc, 1, &cand_form ) ); - todo_wine check_candidate_form( &cand_form, &expect_form ); + ok_ret( 1, ImmGetCandidateWindow( himc, 1, &cand_form ) ); + check_candidate_form( &cand_form, &expect_form ); ok_ret( 1, ImmGetCandidateWindow( himc, 2, &cand_form ) ); check_candidate_form( &cand_form, &expect_form ); ok_seq( empty_sequence );