winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
April 2023
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
1 participants
817 discussions
Start a n
N
ew thread
Piotr Caban : wineps: Handle EMR_POLYDRAW record in spool files.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 1a326f6c4e004d5d46fd79f9be7311aa868fba0d URL:
https://gitlab.winehq.org/wine/wine/-/commit/1a326f6c4e004d5d46fd79f9be7311…
Author: Piotr Caban <piotr(a)codeweavers.com> Date: Tue Apr 11 15:58:26 2023 +0200 wineps: Handle EMR_POLYDRAW record in spool files. --- dlls/wineps.drv/printproc.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 20a1ca11aef..79d02c9f170 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -624,6 +624,74 @@ static int plg_blt(PHYSDEV dev, const EMRPLGBLT *p) return TRUE; } +static int poly_draw(PHYSDEV dev, const POINT *points, const BYTE *types, DWORD count) +{ + POINT first, cur, pts[4]; + DWORD i, num_pts; + + /* check for valid point types */ + for (i = 0; i < count; i++) + { + switch (types[i]) + { + case PT_MOVETO: + case PT_LINETO | PT_CLOSEFIGURE: + case PT_LINETO: + break; + case PT_BEZIERTO: + if (i + 2 >= count) return FALSE; + if (types[i + 1] != PT_BEZIERTO) return FALSE; + if ((types[i + 2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO) return FALSE; + i += 2; + break; + default: + return FALSE; + } + } + + GetCurrentPositionEx(dev->hdc, &cur); + first = cur; + + for (i = 0; i < count; i++) + { + switch (types[i]) + { + case PT_MOVETO: + first = points[i]; + break; + case PT_LINETO: + case (PT_LINETO | PT_CLOSEFIGURE): + pts[0] = cur; + pts[1] = points[i]; + num_pts = 2; + if (!PSDRV_PolyPolyline(dev, pts, &num_pts, 1)) + return FALSE; + break; + case PT_BEZIERTO: + pts[0] = cur; + pts[1] = points[i]; + pts[2] = points[i + 1]; + pts[3] = points[i + 2]; + if (!PSDRV_PolyBezier(dev, pts, 4)) + return FALSE; + i += 2; + break; + } + + cur = points[i]; + if (types[i] & PT_CLOSEFIGURE) + { + pts[0] = cur; + pts[1] = first; + num_pts = 2; + if (!PSDRV_PolyPolyline(dev, pts, &num_pts, 1)) + return FALSE; + } + } + + return TRUE; +} + static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, const ENHMETARECORD *rec, int n, LPARAM arg) { @@ -850,6 +918,14 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, } return ret; } + case EMR_POLYDRAW: + { + const EMRPOLYDRAW *p = (const EMRPOLYDRAW *)rec; + const POINT *pts = (const POINT *)p->aptl; + + return poly_draw(&data->pdev->dev, pts, (BYTE *)(p->aptl + p->cptl), p->cptl) && + MoveToEx(data->pdev->dev.hdc, pts[p->cptl - 1].x, pts[p->cptl - 1].y, NULL); + } case EMR_PAINTRGN: { const EMRPAINTRGN *p = (const EMRPAINTRGN *)rec;
1
0
0
0
Piotr Caban : wineps: Handle EMR_DELETEOBJECT record in spool files.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 700f0c6b8c24bf60d8a786b241b86d78b8cd3f91 URL:
https://gitlab.winehq.org/wine/wine/-/commit/700f0c6b8c24bf60d8a786b241b86d…
Author: Piotr Caban <piotr(a)codeweavers.com> Date: Tue Apr 11 15:57:22 2023 +0200 wineps: Handle EMR_DELETEOBJECT record in spool files. --- dlls/wineps.drv/printproc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 399e8a8c212..20a1ca11aef 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -735,6 +735,13 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, return 1; } } + case EMR_DELETEOBJECT: + { + const EMRDELETEOBJECT *p = (const EMRDELETEOBJECT *)rec; + + memset(&data->patterns[p->ihObject], 0, sizeof(*data->patterns)); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + } case EMR_ANGLEARC: { const EMRANGLEARC *p = (const EMRANGLEARC *)rec;
1
0
0
0
Santino Mazza : mf/session: Handle error when a source fails to start.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: dd6b2f9ab5e65142882748f873a1c7c2ed10cb00 URL:
https://gitlab.winehq.org/wine/wine/-/commit/dd6b2f9ab5e65142882748f873a1c7…
Author: Santino Mazza <smazza(a)codeweavers.com> Date: Fri Apr 7 14:07:26 2023 -0300 mf/session: Handle error when a source fails to start. --- dlls/mf/session.c | 4 ++++ dlls/mf/tests/mf.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index bac4f23b9c6..7d6a65d3f55 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -920,7 +920,11 @@ static void session_start(struct media_session *session, const GUID *time_format LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) { if (FAILED(hr = IMFMediaSource_Start(source->source, source->pd, &GUID_NULL, start_position))) + { WARN("Failed to start media source %p, hr %#lx.\n", source->source, hr); + session_command_complete_with_event(session, MESessionStarted, hr, NULL); + return; + } } session->state = SESSION_STATE_STARTING_SOURCES; diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 610c2e3da35..e8d7252aa3f 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2514,7 +2514,7 @@ static void test_media_session_events(void) hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 1000, &propvar); - todo_wine ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); PropVariantClear(&propvar);
1
0
0
0
Santino Mazza : mf/session: Handle errors when subscribing to source's events.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 74b64eab2049c0c6de7dded39bf5ffcf8c921da2 URL:
https://gitlab.winehq.org/wine/wine/-/commit/74b64eab2049c0c6de7dded39bf5ff…
Author: Santino Mazza <smazza(a)codeweavers.com> Date: Thu Mar 9 11:50:30 2023 -0300 mf/session: Handle errors when subscribing to source's events. --- dlls/mf/session.c | 18 +++++++++++------- dlls/mf/tests/mf.c | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 85baf07d05a..bac4f23b9c6 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -866,13 +866,13 @@ static void session_command_complete_with_event(struct media_session *session, M session_command_complete(session); } -static void session_subscribe_sources(struct media_session *session) +static HRESULT session_subscribe_sources(struct media_session *session) { struct media_source *source; - HRESULT hr; + HRESULT hr = S_OK; if (session->presentation.flags & SESSION_FLAG_SOURCES_SUBSCRIBED) - return; + return hr; LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) { @@ -880,10 +880,12 @@ static void session_subscribe_sources(struct media_session *session) source->object))) { WARN("Failed to subscribe to source events, hr %#lx.\n", hr); + return hr; } } session->presentation.flags |= SESSION_FLAG_SOURCES_SUBSCRIBED; + return hr; } static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) @@ -909,7 +911,11 @@ static void session_start(struct media_session *session, const GUID *time_format session->presentation.start_position.vt = VT_EMPTY; PropVariantCopy(&session->presentation.start_position, start_position); - session_subscribe_sources(session); + if (FAILED(hr = session_subscribe_sources(session))) + { + session_command_complete_with_event(session, MESessionStarted, hr, NULL); + return; + } LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) { @@ -1308,10 +1314,8 @@ static void session_set_rate(struct media_session *session, BOOL thin, float rat if (SUCCEEDED(hr)) hr = IMFRateControl_GetRate(session->clock_rate_control, NULL, &clock_rate); - if (SUCCEEDED(hr) && (rate != clock_rate)) + if (SUCCEEDED(hr) && (rate != clock_rate) && SUCCEEDED(hr = session_subscribe_sources(session))) { - session_subscribe_sources(session); - LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) { if (SUCCEEDED(hr = MFGetService(source->object, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index f3269eb7873..610c2e3da35 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2465,13 +2465,13 @@ static void test_media_session_events(void) hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 1000, &propvar); - todo_wine ok(hr == 0x80001234, "Unexpected hr %#lx.\n", hr); + ok(hr == 0x80001234, "Unexpected hr %#lx.\n", hr); ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); PropVariantClear(&propvar); CHECK_CALLED(test_source_BeginGetEvent); - todo_wine { CHECK_NOT_CALLED(test_source_Start); } + CHECK_NOT_CALLED(test_source_Start); hr = IMFMediaSession_ClearTopologies(session); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1
0
0
0
Santino Mazza : mf/tests: Test media session error handling.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 2580799e7068ff405ee55032dcdd8dcb941d604a URL:
https://gitlab.winehq.org/wine/wine/-/commit/2580799e7068ff405ee55032dcdd8d…
Author: Santino Mazza <smazza(a)codeweavers.com> Date: Thu Mar 9 11:28:41 2023 -0300 mf/tests: Test media session error handling. Test error handling for mfsession_Start when a source fails at different stages. --- dlls/mf/tests/mf.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 4 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 59689652677..f3269eb7873 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -41,6 +41,39 @@ #include "initguid.h" #include "evr9.h" +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT2(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +#define CHECK_NOT_CALLED(func) \ + do { \ + ok(!called_ ## func, "unexpected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +#define CLEAR_CALLED(func) \ + expect_ ## func = called_ ## func = FALSE + extern GUID DMOVideoFormat_RGB32; HRESULT (WINAPI *pMFCreateSampleCopierMFT)(IMFTransform **copier); @@ -237,10 +270,15 @@ static void init_sink_node(IMFStreamSink *stream_sink, MF_CONNECT_METHOD method, } } +DEFINE_EXPECT(test_source_BeginGetEvent); +DEFINE_EXPECT(test_source_QueueEvent); +DEFINE_EXPECT(test_source_Start); + struct test_source { IMFMediaSource IMFMediaSource_iface; LONG refcount; + HRESULT begin_get_event_res; IMFPresentationDescriptor *pd; }; @@ -295,8 +333,9 @@ static HRESULT WINAPI test_source_GetEvent(IMFMediaSource *iface, DWORD flags, I static HRESULT WINAPI test_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state) { - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + struct test_source *source = impl_from_IMFMediaSource(iface); + CHECK_EXPECT(test_source_BeginGetEvent); + return source->begin_get_event_res; } static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event) @@ -308,7 +347,7 @@ static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncRes static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type, HRESULT hr, const PROPVARIANT *value) { - ok(0, "Unexpected call.\n"); + CHECK_EXPECT(test_source_QueueEvent); return E_NOTIMPL; } @@ -327,7 +366,7 @@ static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *i static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format, const PROPVARIANT *start_position) { - ok(0, "Unexpected call.\n"); + CHECK_EXPECT(test_source_Start); return E_NOTIMPL; } @@ -373,6 +412,7 @@ static IMFMediaSource *create_test_source(IMFPresentationDescriptor *pd) source = calloc(1, sizeof(*source)); source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl; source->refcount = 1; + source->begin_get_event_res = E_NOTIMPL; IMFPresentationDescriptor_AddRef((source->pd = pd)); return &source->IMFMediaSource_iface; @@ -1915,6 +1955,41 @@ static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCal return status; } +#define wait_media_event_until_blocking(a, b, c, d, e) wait_media_event_until_blocking_(__LINE__, a, b, c, d, e) +static HRESULT wait_media_event_until_blocking_(int line, IMFMediaSession *session, IMFAsyncCallback *callback, + MediaEventType expect_type, DWORD timeout, PROPVARIANT *value) +{ + struct test_callback *impl = impl_from_IMFAsyncCallback(callback); + MediaEventType type; + HRESULT hr, status; + DWORD ret; + GUID guid; + + do + { + hr = IMFMediaSession_BeginGetEvent(session, &impl->IMFAsyncCallback_iface, (IUnknown *)session); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ret = WaitForSingleObject(impl->event, timeout); + if (ret == WAIT_TIMEOUT) return WAIT_TIMEOUT; + hr = IMFMediaEvent_GetType(impl->media_event, &type); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } while (type != expect_type); + + ok_(__FILE__, line)(type == expect_type, "got type %lu\n", type); + + hr = IMFMediaEvent_GetExtendedType(impl->media_event, &guid); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(IsEqualGUID(&guid, &GUID_NULL), "got extended type %s\n", debugstr_guid(&guid)); + + hr = IMFMediaEvent_GetValue(impl->media_event, value); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaEvent_GetStatus(impl->media_event, &status); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + return status; +} + static IMFMediaSource *create_media_source(const WCHAR *name, const WCHAR *mime) { IMFSourceResolver *resolver; @@ -1986,6 +2061,7 @@ static void test_media_session_events(void) struct test_stream_sink stream_sink = test_stream_sink; struct test_media_sink media_sink = test_media_sink; struct test_handler handler = test_handler; + struct test_source *source_impl; IMFAsyncCallback *callback, *callback2; IMFMediaType *input_type, *output_type; IMFTopologyNode *src_node, *sink_node; @@ -2364,6 +2440,105 @@ static void test_media_session_events(void) /* sometimes briefly leaking */ IMFMediaSession_Release(session); + + /* test IMFMediaSession_Start with source returning an error in BeginGetEvent */ + source_impl = impl_from_IMFMediaSource(source); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_UNKNOWN, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + source_impl->begin_get_event_res = 0x80001234; + + SET_EXPECT(test_source_BeginGetEvent); + SET_EXPECT(test_source_QueueEvent); + SET_EXPECT(test_source_Start); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 1000, &propvar); + todo_wine ok(hr == 0x80001234, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + CHECK_CALLED(test_source_BeginGetEvent); + todo_wine { CHECK_NOT_CALLED(test_source_Start); } + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(media_sink.shutdown, "media sink didn't shutdown.\n"); + media_sink.shutdown = FALSE; + + source_impl->begin_get_event_res = E_NOTIMPL; + + CLEAR_CALLED(test_source_BeginGetEvent); + CLEAR_CALLED(test_source_QueueEvent); + CLEAR_CALLED(test_source_Start); + + /* sometimes briefly leaking */ + IMFMediaSession_Release(session); + + + /* test IMFMediaSession_Start when test source BeginGetEvent returns S_OK */ + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_UNKNOWN, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + source_impl = impl_from_IMFMediaSource(source); + source_impl->begin_get_event_res = S_OK; + + SET_EXPECT(test_source_BeginGetEvent); + SET_EXPECT(test_source_QueueEvent); + SET_EXPECT(test_source_Start); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 1000, &propvar); + todo_wine ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + CHECK_CALLED(test_source_BeginGetEvent); + CHECK_CALLED(test_source_Start); + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(media_sink.shutdown, "media sink didn't shutdown.\n"); + media_sink.shutdown = FALSE; + + source_impl->begin_get_event_res = E_NOTIMPL; + + CLEAR_CALLED(test_source_BeginGetEvent); + CLEAR_CALLED(test_source_QueueEvent); + CLEAR_CALLED(test_source_Start); + + /* sometimes briefly leaking */ + IMFMediaSession_Release(session); + IMFAsyncCallback_Release(callback); if (handler.current_type)
1
0
0
0
Rémi Bernon : imm32: Use INPUTCONTEXT directly in ImmSetConversionStatus.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 1cd71e92be6ed57621ea545fcfbd46da7cfe7b58 URL:
https://gitlab.winehq.org/wine/wine/-/commit/1cd71e92be6ed57621ea545fcfbd46…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Apr 6 01:01:37 2023 +0200 imm32: Use INPUTCONTEXT directly in ImmSetConversionStatus. --- dlls/imm32/imm.c | 41 +++++++++++++++++++---------------------- dlls/imm32/tests/imm32.c | 1 - 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index b2dc58a95ab..d29684f34a2 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -2635,37 +2635,34 @@ BOOL WINAPI ImmSetCompositionWindow( /*********************************************************************** * ImmSetConversionStatus (IMM32.@) */ -BOOL WINAPI ImmSetConversionStatus( - HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence) +BOOL WINAPI ImmSetConversionStatus( HIMC himc, DWORD conversion, DWORD sentence ) { - DWORD oldConversion, oldSentence; - struct imc *data = get_imc_data( hIMC ); - - TRACE("%p %ld %ld\n", hIMC, fdwConversion, fdwSentence); + DWORD old_conversion, old_sentence; + INPUTCONTEXT *ctx; - if (!data) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + TRACE( "himc %p, conversion %#lx, sentence %#lx\n", himc, conversion, sentence ); - if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; - if ( fdwConversion != data->IMC.fdwConversion ) + if (conversion != ctx->fdwConversion) { - oldConversion = data->IMC.fdwConversion; - data->IMC.fdwConversion = fdwConversion; - ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldConversion, IMC_SETCONVERSIONMODE); - imc_notify_ime( data, IMN_SETCONVERSIONMODE, 0 ); + old_conversion = ctx->fdwConversion; + ctx->fdwConversion = conversion; + ImmNotifyIME( himc, NI_CONTEXTUPDATED, old_conversion, IMC_SETCONVERSIONMODE ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETCONVERSIONMODE, 0 ); } - if ( fdwSentence != data->IMC.fdwSentence ) + + if (sentence != ctx->fdwSentence) { - oldSentence = data->IMC.fdwSentence; - data->IMC.fdwSentence = fdwSentence; - ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldSentence, IMC_SETSENTENCEMODE); - imc_notify_ime( data, IMN_SETSENTENCEMODE, 0 ); + old_sentence = ctx->fdwSentence; + ctx->fdwSentence = sentence; + ImmNotifyIME( himc, NI_CONTEXTUPDATED, old_sentence, IMC_SETSENTENCEMODE ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETSENTENCEMODE, 0 ); } + ImmUnlockIMC( himc ); + return TRUE; } diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 8c6d441181b..bbfae7e65d1 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -4219,7 +4219,6 @@ static void test_ImmSetConversionStatus(void) .hkl = expect_ime, .himc = default_himc, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0xdeadbeef, .value = IMC_SETCONVERSIONMODE}, }, - {.todo = TRUE}, /* spurious calls */ {0}, }; const struct ime_call set_conversion_status_2_seq[] =
1
0
0
0
Rémi Bernon : imm32: Use INPUTCONTEXT directly in ImmGetConversionStatus.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 67ddc3146cb847e3161567a870230bba13d9c3f5 URL:
https://gitlab.winehq.org/wine/wine/-/commit/67ddc3146cb847e3161567a870230b…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Fri Apr 7 21:43:27 2023 +0200 imm32: Use INPUTCONTEXT directly in ImmGetConversionStatus. --- dlls/imm32/imm.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index c99feb65a45..b2dc58a95ab 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1844,20 +1844,16 @@ DWORD WINAPI ImmGetConversionListW( HKL hkl, HIMC himc, const WCHAR *srcW, CANDI /*********************************************************************** * ImmGetConversionStatus (IMM32.@) */ -BOOL WINAPI ImmGetConversionStatus( - HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence) +BOOL WINAPI ImmGetConversionStatus( HIMC himc, DWORD *conversion, DWORD *sentence ) { - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx; - TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence); + TRACE( "himc %p, conversion %p, sentence %p\n", himc, conversion, sentence ); - if (!data) - return FALSE; - - if (lpfdwConversion) - *lpfdwConversion = data->IMC.fdwConversion; - if (lpfdwSentence) - *lpfdwSentence = data->IMC.fdwSentence; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if (conversion) *conversion = ctx->fdwConversion; + if (sentence) *sentence = ctx->fdwSentence; + ImmUnlockIMC( himc ); return TRUE; }
1
0
0
0
Rémi Bernon : imm32: Compare open status values in ImmSetOpenStatus.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 26d2d2c438d9e5f66212b22dc2d29b7881e9ad09 URL:
https://gitlab.winehq.org/wine/wine/-/commit/26d2d2c438d9e5f66212b22dc2d29b…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Apr 6 00:54:42 2023 +0200 imm32: Compare open status values in ImmSetOpenStatus. --- dlls/imm32/imm.c | 2 +- dlls/imm32/tests/imm32.c | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 81444ad420c..c99feb65a45 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -2688,7 +2688,7 @@ BOOL WINAPI ImmSetOpenStatus( HIMC himc, BOOL status ) if ((ui_hwnd = get_ime_ui_window())) SetWindowLongPtrW( ui_hwnd, IMMGWL_IMC, (LONG_PTR)himc ); - if (!status != !ctx->fOpen) + if (status != ctx->fOpen) { ctx->fOpen = status; ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS ); diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 88b167c701d..8c6d441181b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -4399,7 +4399,6 @@ static void test_ImmSetOpenStatus(void) { .hkl = expect_ime, .himc = default_himc, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETOPENSTATUS}, - .todo = TRUE, }, {0}, }; @@ -4408,17 +4407,14 @@ static void test_ImmSetOpenStatus(void) { .hkl = expect_ime, .himc = default_himc, .func = IME_NOTIFY, .notify = {.action = NI_CONTEXTUPDATED, .index = 0, .value = IMC_SETOPENSTATUS}, - .todo = TRUE, }, { .hkl = expect_ime, .himc = default_himc, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETOPENSTATUS}, - .todo = TRUE, }, { .hkl = expect_ime, .himc = default_himc, .func = MSG_IME_UI, .message = {.msg = WM_IME_NOTIFY, .wparam = IMN_SETOPENSTATUS}, - .todo = TRUE, }, {0}, }; @@ -4483,8 +4479,8 @@ static void test_ImmSetOpenStatus(void) ok_seq( set_open_status_1_seq ); status = ImmGetOpenStatus( default_himc ); - todo_wine ok_eq( 0xfeedcafe, status, UINT, "%#x" ); - todo_wine ok_eq( 0xfeedcafe, ctx->fOpen, UINT, "%#x" ); + ok_eq( 0xfeedcafe, status, UINT, "%#x" ); + ok_eq( 0xfeedcafe, ctx->fOpen, UINT, "%#x" ); ctx->hWnd = hwnd; ok_seq( empty_sequence ); @@ -4492,15 +4488,15 @@ static void test_ImmSetOpenStatus(void) ok_seq( set_open_status_2_seq ); status = ImmGetOpenStatus( default_himc ); - todo_wine ok_eq( ~0, status, UINT, "%#x" ); - todo_wine ok_eq( ~0, ctx->fOpen, UINT, "%#x" ); + ok_eq( ~0, status, UINT, "%#x" ); + ok_eq( ~0, ctx->fOpen, UINT, "%#x" ); ok_ret( 1, ImmSetOpenStatus( default_himc, ~0 ) ); ok_seq( empty_sequence ); status = ImmGetOpenStatus( default_himc ); - todo_wine ok_eq( ~0, status, UINT, "%#x" ); - todo_wine ok_eq( ~0, ctx->fOpen, UINT, "%#x" ); + ok_eq( ~0, status, UINT, "%#x" ); + ok_eq( ~0, ctx->fOpen, UINT, "%#x" ); /* status is cached between IME activations */
1
0
0
0
Rémi Bernon : imm32: Cache INPUTCONTEXT values for every IME.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 6e51928ae5fbd7a7d199e2d12f25b3206e8cd94b URL:
https://gitlab.winehq.org/wine/wine/-/commit/6e51928ae5fbd7a7d199e2d12f25b3…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Fri Apr 7 19:47:26 2023 +0200 imm32: Cache INPUTCONTEXT values for every IME. --- dlls/imm32/imm.c | 89 +++++++++++++++++++++++++++++++++++++++++++----- dlls/imm32/tests/imm32.c | 18 +++------- 2 files changed, 84 insertions(+), 23 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index a17869a1c94..81444ad420c 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -39,6 +39,13 @@ UINT WM_MSIME_RECONVERT; UINT WM_MSIME_QUERYPOSITION; UINT WM_MSIME_DOCUMENTFEED; +struct imc_entry +{ + HIMC himc; + INPUTCONTEXT context; + struct list entry; +}; + struct ime { LONG refcount; /* guarded by ime_cs */ @@ -49,6 +56,7 @@ struct ime IMEINFO info; WCHAR ui_class[17]; + struct list input_contexts; BOOL (WINAPI *pImeInquire)(IMEINFO *, void *, DWORD); BOOL (WINAPI *pImeConfigure)(HKL, HWND, DWORD, void *); @@ -435,16 +443,21 @@ static struct ime *find_ime_from_hkl( HKL hkl ) BOOL WINAPI ImmFreeLayout( HKL hkl ) { + struct imc_entry *imc_entry, *imc_next; struct ime *ime; TRACE( "hkl %p\n", hkl ); EnterCriticalSection( &ime_cs ); - if ((ime = find_ime_from_hkl( hkl )) && ime->refcount) ime = NULL; - if (ime) + if ((ime = find_ime_from_hkl( hkl ))) { list_remove( &ime->entry ); if (!ime->pImeDestroy( 0 )) WARN( "ImeDestroy failed\n" ); + LIST_FOR_EACH_ENTRY_SAFE( imc_entry, imc_next, &ime->input_contexts, struct imc_entry, entry ) + { + ImmDestroyIMCC( imc_entry->context.hPrivate ); + free( imc_entry ); + } } LeaveCriticalSection( &ime_cs ); if (!ime) return TRUE; @@ -514,6 +527,7 @@ BOOL WINAPI ImmLoadIME( HKL hkl ) if (ime_is_unicode( ime )) lstrcpynW( ime->ui_class, buffer, ARRAY_SIZE(ime->ui_class) ); else MultiByteToWideChar( CP_ACP, 0, (char *)buffer, -1, ime->ui_class, ARRAY_SIZE(ime->ui_class) ); + list_init( &ime->input_contexts ); list_add_tail( &ime_list, &ime->entry ); LeaveCriticalSection( &ime_cs ); @@ -562,13 +576,63 @@ static void ime_release( struct ime *ime ) LeaveCriticalSection( &ime_cs ); } +static void ime_save_input_context( struct ime *ime, HIMC himc, INPUTCONTEXT *ctx ) +{ + static INPUTCONTEXT default_input_context = + { + .cfCandForm = {{.dwIndex = -1}, {.dwIndex = -1}, {.dwIndex = -1}, {.dwIndex = -1}} + }; + const INPUTCONTEXT old = *ctx; + struct imc_entry *entry; + + *ctx = default_input_context; + ctx->hWnd = old.hWnd; + ctx->hMsgBuf = old.hMsgBuf; + ctx->hCompStr = old.hCompStr; + ctx->hCandInfo = old.hCandInfo; + ctx->hGuideLine = old.hGuideLine; + if (!(ctx->hPrivate = ImmCreateIMCC( ime->info.dwPrivateDataSize ))) + WARN( "Failed to allocate IME private data\n" ); + + if (!(entry = malloc( sizeof(*entry) ))) return; + entry->himc = himc; + entry->context = *ctx; + + EnterCriticalSection( &ime_cs ); + + /* reference the IME the first time the input context cache is used + * in the same way Windows does it, so it doesn't get destroyed and + * INPUTCONTEXT cache lost when keyboard layout is changed + */ + if (list_empty( &ime->input_contexts )) ime->refcount++; + + list_add_tail( &ime->input_contexts, &entry->entry ); + LeaveCriticalSection( &ime_cs ); +} + +static INPUTCONTEXT *ime_find_input_context( struct ime *ime, HIMC himc ) +{ + struct imc_entry *entry; + + EnterCriticalSection( &ime_cs ); + LIST_FOR_EACH_ENTRY( entry, &ime->input_contexts, struct imc_entry, entry ) + if (entry->himc == himc) break; + LeaveCriticalSection( &ime_cs ); + + if (&entry->entry == &ime->input_contexts) return NULL; + return &entry->context; +} + static void imc_release_ime( struct imc *imc, struct ime *ime ) { + INPUTCONTEXT *ctx; + if (imc->ui_hwnd) DestroyWindow( imc->ui_hwnd ); imc->ui_hwnd = NULL; ime->pImeSelect( imc->handle, FALSE ); + + if ((ctx = ime_find_input_context( ime, imc->handle ))) *ctx = imc->IMC; ime_release( ime ); - ImmDestroyIMCC( imc->IMC.hPrivate ); } static struct ime *imc_select_ime( struct imc *imc ) @@ -587,10 +651,11 @@ static struct ime *imc_select_ime( struct imc *imc ) WARN( "Failed to acquire IME for HKL %p\n", hkl ); else { - if (!(imc->IMC.hPrivate = ImmCreateIMCC( imc->ime->info.dwPrivateDataSize ))) - WARN( "Failed to allocate IME private data for IMC %p\n", imc ); - imc->IMC.fdwConversion = imc->ime->info.fdwConversionCaps; - imc->IMC.fdwSentence = imc->ime->info.fdwSentenceCaps; + INPUTCONTEXT *ctx; + + if ((ctx = ime_find_input_context( imc->ime, imc->handle ))) imc->IMC = *ctx; + else ime_save_input_context( imc->ime, imc->handle, &imc->IMC ); + imc->ime->pImeSelect( imc->handle, TRUE ); } @@ -690,14 +755,20 @@ static void IMM_FreeThreadData(void) static void IMM_FreeAllImmHkl(void) { - struct ime *ime, *next; + struct ime *ime, *ime_next; - LIST_FOR_EACH_ENTRY_SAFE( ime, next, &ime_list, struct ime, entry ) + LIST_FOR_EACH_ENTRY_SAFE( ime, ime_next, &ime_list, struct ime, entry ) { + struct imc_entry *imc_entry, *imc_next; list_remove( &ime->entry ); ime->pImeDestroy( 1 ); FreeLibrary( ime->module ); + LIST_FOR_EACH_ENTRY_SAFE( imc_entry, imc_next, &ime->input_contexts, struct imc_entry, entry ) + { + ImmDestroyIMCC( imc_entry->context.hPrivate ); + free( imc_entry ); + } free( ime ); } diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 827a1326e3e..88b167c701d 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -4351,8 +4351,8 @@ static void test_ImmSetConversionStatus(void) todo_wine ok_eq( 0x200, ctx->fdwConversion, UINT, "%#x" ); ok_eq( old_sentence, ctx->fdwSentence, UINT, "%#x" ); ok_ret( 1, ImmActivateLayout( hkl ) ); - todo_wine ok_eq( ~0, ctx->fdwConversion, UINT, "%#x" ); - todo_wine ok_eq( ~0, ctx->fdwSentence, UINT, "%#x" ); + ok_eq( ~0, ctx->fdwConversion, UINT, "%#x" ); + ok_eq( ~0, ctx->fdwSentence, UINT, "%#x" ); ok_ret( 1, ImmActivateLayout( default_hkl ) ); todo_wine ok_eq( 0x200, ctx->fdwConversion, UINT, "%#x" ); ok_eq( old_sentence, ctx->fdwSentence, UINT, "%#x" ); @@ -4506,8 +4506,8 @@ static void test_ImmSetOpenStatus(void) ok_ret( 1, ImmActivateLayout( default_hkl ) ); status = ImmGetOpenStatus( default_himc ); - todo_wine ok_eq( old_status, status, UINT, "%#x" ); - todo_wine ok_eq( old_status, ctx->fOpen, UINT, "%#x" ); + ok_eq( old_status, status, UINT, "%#x" ); + ok_eq( old_status, ctx->fOpen, UINT, "%#x" ); ok_ret( 1, ImmActivateLayout( hkl ) ); status = ImmGetOpenStatus( default_himc ); todo_wine ok_eq( 1, status, UINT, "%#x" ); @@ -4752,10 +4752,8 @@ static void test_ImmActivateLayout(void) ok_ret( 1, ImmActivateLayout( hkl ) ); ok_seq( empty_sequence ); - todo_ImeDestroy = TRUE; /* Wine doesn't leak the IME */ ok_ret( 1, ImmActivateLayout( default_hkl ) ); ok_seq( deactivate_seq ); - todo_ImeDestroy = FALSE; ok_eq( default_hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); @@ -4786,9 +4784,7 @@ static void test_ImmActivateLayout(void) CHECK_CALLED( ImeInquire ); activate_with_window_seq[1].himc = himc; ok_seq( activate_with_window_seq ); - todo_ImeInquire = TRUE; ok_ret( 1, ImmLoadIME( hkl ) ); - todo_ImeInquire = FALSE; ok_eq( hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); @@ -4797,9 +4793,7 @@ static void test_ImmActivateLayout(void) memset( ime_calls, 0, sizeof(ime_calls) ); ime_call_count = 0; - todo_ImeDestroy = TRUE; /* Wine doesn't leak the IME */ ok_eq( hkl, ActivateKeyboardLayout( default_hkl, 0 ), HKL, "%p" ); - todo_ImeDestroy = FALSE; deactivate_with_window_seq[1].himc = himc; deactivate_with_window_seq[5].himc = himc; ok_seq( deactivate_with_window_seq ); @@ -4810,9 +4804,7 @@ static void test_ImmActivateLayout(void) ok_seq( empty_sequence ); - todo_ImeInquire = TRUE; ok_eq( default_hkl, ActivateKeyboardLayout( hkl, 0 ), HKL, "%p" ); - todo_ImeInquire = FALSE; ok_eq( hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); ok_ret( 1, EnumThreadWindows( GetCurrentThreadId(), enum_thread_ime_windows, (LPARAM)&ime_windows ) ); @@ -4820,9 +4812,7 @@ static void test_ImmActivateLayout(void) ok( !!ime_windows.ime_ui_hwnd, "missing IME UI window\n" ); ok_ret( (UINT_PTR)ime_windows.ime_hwnd, (UINT_PTR)GetParent( ime_windows.ime_ui_hwnd ) ); - todo_ImeDestroy = TRUE; /* Wine doesn't leak the IME */ ok_eq( hkl, ActivateKeyboardLayout( default_hkl, 0 ), HKL, "%p" ); - todo_ImeDestroy = FALSE; ok_eq( default_hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); process_messages();
1
0
0
0
Rémi Bernon : imm32: Use INPUTCONTEXT directly in ImmSetOpenStatus.
by Alexandre Julliard
11 Apr '23
11 Apr '23
Module: wine Branch: master Commit: 374db20a5d011ad909a61d6857ead7a6261231ec URL:
https://gitlab.winehq.org/wine/wine/-/commit/374db20a5d011ad909a61d6857ead7…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Mon Apr 3 17:39:21 2023 +0200 imm32: Use INPUTCONTEXT directly in ImmSetOpenStatus. --- dlls/imm32/imm.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 753213b623f..a17869a1c94 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -2605,30 +2605,27 @@ BOOL WINAPI ImmSetConversionStatus( /*********************************************************************** * ImmSetOpenStatus (IMM32.@) */ -BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen) +BOOL WINAPI ImmSetOpenStatus( HIMC himc, BOOL status ) { - struct imc *data = get_imc_data( hIMC ); + INPUTCONTEXT *ctx; HWND ui_hwnd; - TRACE("%p %d\n", hIMC, fOpen); - - if (!data) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + TRACE( "himc %p, status %u\n", himc, status ); - if (NtUserQueryInputContext( hIMC, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (NtUserQueryInputContext( himc, NtUserInputContextThreadId ) != GetCurrentThreadId()) return FALSE; + if (!(ctx = ImmLockIMC( himc ))) return FALSE; - if ((ui_hwnd = get_ime_ui_window())) SetWindowLongPtrW( ui_hwnd, IMMGWL_IMC, (LONG_PTR)hIMC ); + if ((ui_hwnd = get_ime_ui_window())) SetWindowLongPtrW( ui_hwnd, IMMGWL_IMC, (LONG_PTR)himc ); - if (!fOpen != !data->IMC.fOpen) + if (!status != !ctx->fOpen) { - data->IMC.fOpen = fOpen; - ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS); - imc_notify_ime( data, IMN_SETOPENSTATUS, 0 ); + ctx->fOpen = status; + ImmNotifyIME( himc, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS ); + SendMessageW( ctx->hWnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0 ); } + ImmUnlockIMC( himc ); + return TRUE; }
1
0
0
0
← Newer
1
...
50
51
52
53
54
55
56
...
82
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Results per page:
10
25
50
100
200