Module: wine Branch: master Commit: 3de1bc035ede848b5661da7d4ad8af5220a5ae28 URL: https://gitlab.winehq.org/wine/wine/-/commit/3de1bc035ede848b5661da7d4ad8af5...
Author: Rémi Bernon rbernon@codeweavers.com Date: Sat Oct 7 10:48:36 2023 +0200
dmime: Send DMUS_PMSGT_NOTIFICATION messages from the performance.
Keeping the segment state referenced until its playback ends.
---
dlls/dmime/performance.c | 72 ++++++++++++++++++++++++++++++++++++++++++------ dlls/dmime/tests/dmime.c | 34 ++++------------------- 2 files changed, 69 insertions(+), 37 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 0215b19a23c..40a78bc40ce 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -66,6 +66,9 @@ struct performance IReferenceClock *master_clock; REFERENCE_TIME init_time; struct list messages; + + BOOL notification_performance; + BOOL notification_segment; };
struct message @@ -225,6 +228,32 @@ static HRESULT performance_send_dirty_pmsg(struct performance *This, MUSIC_TIME return hr; }
+static HRESULT performance_send_notification_pmsg(struct performance *This, MUSIC_TIME music_time, BOOL stamp, + GUID type, DWORD option, IUnknown *object) +{ + IDirectMusicPerformance8 *performance = &This->IDirectMusicPerformance8_iface; + IDirectMusicGraph *graph = &This->IDirectMusicGraph_iface; + DMUS_NOTIFICATION_PMSG *msg; + HRESULT hr; + + if (FAILED(hr = IDirectMusicPerformance8_AllocPMsg(performance, sizeof(*msg), (DMUS_PMSG **)&msg))) + return hr; + + msg->mtTime = music_time; + msg->dwFlags = DMUS_PMSGF_MUSICTIME | DMUS_PMSGF_TOOL_QUEUE; + msg->dwType = DMUS_PMSGT_NOTIFICATION; + if ((msg->punkUser = object)) IUnknown_AddRef(object); + msg->guidNotificationType = type; + msg->dwNotificationOption = option; + + /* only stamp the message if notifications are enabled, otherwise send them directly to the output tool */ + if ((stamp && FAILED(hr = IDirectMusicGraph_StampPMsg(graph, (DMUS_PMSG *)msg))) + || FAILED(hr = IDirectMusicPerformance8_SendPMsg(performance, (DMUS_PMSG *)msg))) + IDirectMusicPerformance8_FreePMsg(performance, (DMUS_PMSG *)msg); + + return hr; +} + static int pchannel_block_compare(const void *key, const struct wine_rb_entry *entry) { const struct pchannel_block *b = WINE_RB_ENTRY_VALUE(entry, const struct pchannel_block, entry); @@ -703,20 +732,32 @@ static HRESULT WINAPI performance_GetNotificationPMsg(IDirectMusicPerformance8 * /*return S_OK;*/ }
-static HRESULT WINAPI performance_AddNotificationType(IDirectMusicPerformance8 *iface, REFGUID rguidNotificationType) +static HRESULT WINAPI performance_AddNotificationType(IDirectMusicPerformance8 *iface, REFGUID type) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); + struct performance *This = impl_from_IDirectMusicPerformance8(iface);
- FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType)); - return S_OK; + FIXME("(%p, %s): stub\n", This, debugstr_dmguid(type)); + + if (IsEqualGUID(type, &GUID_NOTIFICATION_PERFORMANCE)) + This->notification_performance = TRUE; + if (IsEqualGUID(type, &GUID_NOTIFICATION_SEGMENT)) + This->notification_segment = TRUE; + + return S_OK; }
-static HRESULT WINAPI performance_RemoveNotificationType(IDirectMusicPerformance8 *iface, REFGUID rguidNotificationType) +static HRESULT WINAPI performance_RemoveNotificationType(IDirectMusicPerformance8 *iface, REFGUID type) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); + struct performance *This = impl_from_IDirectMusicPerformance8(iface);
- FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType)); - return S_OK; + FIXME("(%p, %s): stub\n", This, debugstr_dmguid(type)); + + if (IsEqualGUID(type, &GUID_NOTIFICATION_PERFORMANCE)) + This->notification_performance = FALSE; + if (IsEqualGUID(type, &GUID_NOTIFICATION_SEGMENT)) + This->notification_segment = FALSE; + + return S_OK; }
static HRESULT perf_dmport_create(struct performance *perf, DMUS_PORTPARAMS *params) @@ -1122,11 +1163,26 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, }
hr = IDirectMusicSegment_GetLength(segment, &length); + if (SUCCEEDED(hr)) + hr = performance_send_notification_pmsg(This, start_time, This->notification_performance, + GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED, NULL); + if (SUCCEEDED(hr)) + hr = performance_send_notification_pmsg(This, start_time, This->notification_segment, + GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART, (IUnknown *)state); if (SUCCEEDED(hr)) hr = performance_send_dirty_pmsg(This, start_time);
+ if (SUCCEEDED(hr)) + hr = performance_send_notification_pmsg(This, start_time + length, This->notification_segment, + GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND, (IUnknown *)state); + if (SUCCEEDED(hr)) + hr = performance_send_notification_pmsg(This, start_time + length, This->notification_segment, + GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND, (IUnknown *)state); if (SUCCEEDED(hr)) hr = performance_send_dirty_pmsg(This, start_time + length); + if (SUCCEEDED(hr)) + hr = performance_send_notification_pmsg(This, start_time + length, This->notification_performance, + GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED, NULL);
if (SUCCEEDED(hr) && segment_state) { diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index 2b7f08eef7a..c8c330860a8 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -3109,66 +3109,45 @@ static void test_notification_pmsg(void)
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)¬if); ok(!ret, "got %#lx\n", ret); - if (notif->dwType == DMUS_PMSGT_NOTIFICATION) - { check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED); - } hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); ok(hr == S_OK, "got %#lx\n", hr);
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)¬if); ok(!ret, "got %#lx\n", ret); - if (notif->dwType == DMUS_PMSGT_NOTIFICATION) - { check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART); - } hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); ok(hr == S_OK, "got %#lx\n", hr);
ret = test_tool_wait_message(tool, 500, &msg); - todo_wine ok(!ret, "got %#lx\n", ret); - if (!ret) - { + ok(!ret, "got %#lx\n", ret); ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType); hr = IDirectMusicPerformance_FreePMsg(performance, msg); ok(hr == S_OK, "got %#lx\n", hr); - }
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)¬if); - todo_wine ok(!ret, "got %#lx\n", ret); - if (!ret) - { + ok(!ret, "got %#lx\n", ret); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); ok(hr == S_OK, "got %#lx\n", hr); - }
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)¬if); - todo_wine ok(!ret, "got %#lx\n", ret); - if (!ret) - { + ok(!ret, "got %#lx\n", ret); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); ok(hr == S_OK, "got %#lx\n", hr); - }
ret = test_tool_wait_message(tool, 500, &msg); - todo_wine ok(!ret, "got %#lx\n", ret); - if (!ret) - { + ok(!ret, "got %#lx\n", ret); ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType); hr = IDirectMusicPerformance_FreePMsg(performance, msg); ok(hr == S_OK, "got %#lx\n", hr); - }
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)¬if); - todo_wine ok(!ret, "got %#lx\n", ret); - if (!ret) - { + ok(!ret, "got %#lx\n", ret); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); ok(hr == S_OK, "got %#lx\n", hr); - }
ret = test_tool_wait_message(tool, 100, &msg); ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret); @@ -3246,10 +3225,7 @@ static void test_notification_pmsg(void)
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)¬if); ok(!ret, "got %#lx\n", ret); - if (notif->dwType == DMUS_PMSGT_NOTIFICATION) - { check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART); - } hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); ok(hr == S_OK, "got %#lx\n", hr);