Commit 3de1bc03 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmime: Send DMUS_PMSGT_NOTIFICATION messages from the performance.

Keeping the segment state referenced until its playback ends.
parent 664caf6e
...@@ -66,6 +66,9 @@ struct performance ...@@ -66,6 +66,9 @@ struct performance
IReferenceClock *master_clock; IReferenceClock *master_clock;
REFERENCE_TIME init_time; REFERENCE_TIME init_time;
struct list messages; struct list messages;
BOOL notification_performance;
BOOL notification_segment;
}; };
struct message struct message
...@@ -225,6 +228,32 @@ static HRESULT performance_send_dirty_pmsg(struct performance *This, MUSIC_TIME ...@@ -225,6 +228,32 @@ static HRESULT performance_send_dirty_pmsg(struct performance *This, MUSIC_TIME
return hr; 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) 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); 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 * ...@@ -703,20 +732,32 @@ static HRESULT WINAPI performance_GetNotificationPMsg(IDirectMusicPerformance8 *
/*return S_OK;*/ /*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)); FIXME("(%p, %s): stub\n", This, debugstr_dmguid(type));
return S_OK;
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)); FIXME("(%p, %s): stub\n", This, debugstr_dmguid(type));
return S_OK;
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) static HRESULT perf_dmport_create(struct performance *perf, DMUS_PORTPARAMS *params)
...@@ -1123,10 +1164,25 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, ...@@ -1123,10 +1164,25 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface,
hr = IDirectMusicSegment_GetLength(segment, &length); hr = IDirectMusicSegment_GetLength(segment, &length);
if (SUCCEEDED(hr)) 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); hr = performance_send_dirty_pmsg(This, start_time);
if (SUCCEEDED(hr)) 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); 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) if (SUCCEEDED(hr) && segment_state)
{ {
......
...@@ -3109,66 +3109,45 @@ static void test_notification_pmsg(void) ...@@ -3109,66 +3109,45 @@ static void test_notification_pmsg(void)
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif); ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif);
ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (notif->dwType == DMUS_PMSGT_NOTIFICATION)
{
check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED);
}
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif); ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif);
ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (notif->dwType == DMUS_PMSGT_NOTIFICATION)
{
check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART);
}
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
ret = test_tool_wait_message(tool, 500, &msg); ret = test_tool_wait_message(tool, 500, &msg);
todo_wine ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (!ret)
{
ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType); ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType);
hr = IDirectMusicPerformance_FreePMsg(performance, msg); hr = IDirectMusicPerformance_FreePMsg(performance, msg);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
}
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif); ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif);
todo_wine ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (!ret)
{
check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND);
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
}
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif); ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif);
todo_wine ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (!ret)
{
check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND);
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
}
ret = test_tool_wait_message(tool, 500, &msg); ret = test_tool_wait_message(tool, 500, &msg);
todo_wine ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (!ret)
{
ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType); ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType);
hr = IDirectMusicPerformance_FreePMsg(performance, msg); hr = IDirectMusicPerformance_FreePMsg(performance, msg);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
}
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif); ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif);
todo_wine ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (!ret)
{
check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED);
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
}
ret = test_tool_wait_message(tool, 100, &msg); ret = test_tool_wait_message(tool, 100, &msg);
ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret); ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret);
...@@ -3246,10 +3225,7 @@ static void test_notification_pmsg(void) ...@@ -3246,10 +3225,7 @@ static void test_notification_pmsg(void)
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif); ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&notif);
ok(!ret, "got %#lx\n", ret); ok(!ret, "got %#lx\n", ret);
if (notif->dwType == DMUS_PMSGT_NOTIFICATION)
{
check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART); check_dmus_notification_pmsg(notif, &GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART);
}
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif); hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)notif);
ok(hr == S_OK, "got %#lx\n", hr); ok(hr == S_OK, "got %#lx\n", hr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment