Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
2414bb40
Commit
2414bb40
authored
Oct 26, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Nov 13, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmime: Clear all pending messages in IDirectMusicPerformance_Stop.
parent
fe171ec8
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
158 additions
and
39 deletions
+158
-39
dmime_private.h
dlls/dmime/dmime_private.h
+3
-1
performance.c
dlls/dmime/performance.c
+132
-33
segmentstate.c
dlls/dmime/segmentstate.c
+22
-1
dmime.c
dlls/dmime/tests/dmime.c
+1
-4
No files found.
dlls/dmime/dmime_private.h
View file @
2414bb40
...
...
@@ -76,8 +76,10 @@ extern HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME sta
IDirectMusicPerformance8
*
performance
,
IDirectMusicSegmentState
**
ret_iface
);
extern
HRESULT
segment_state_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
HRESULT
segment_state_tick
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
HRESULT
segment_state_stop
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
HRESULT
segment_state_end_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
BOOL
segment_state_has_segment
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicSegment
*
segment
);
extern
BOOL
segment_state_has_track
(
IDirectMusicSegmentState
*
iface
,
DWORD
track_id
);
extern
HRESULT
wave_track_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IDirectMusicTrack8
**
ret_iface
);
...
...
@@ -88,7 +90,7 @@ extern HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, M
extern
HRESULT
performance_send_segment_tick
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
);
extern
HRESULT
performance_send_segment_end
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
);
IDirectMusicSegmentState
*
state
,
BOOL
abort
);
/*****************************************************************************
* Auxiliary definitions
...
...
dlls/dmime/performance.c
View file @
2414bb40
...
...
@@ -336,24 +336,28 @@ HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MUSIC_TIM
}
HRESULT
performance_send_segment_end
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
)
IDirectMusicSegmentState
*
state
,
BOOL
abort
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
HRESULT
hr
;
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
-
1450
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGALMOSTEND
,
(
IUnknown
*
)
state
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGEND
,
(
IUnknown
*
)
state
)))
return
hr
;
if
(
!
abort
)
{
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
-
1450
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGALMOSTEND
,
(
IUnknown
*
)
state
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGEND
,
(
IUnknown
*
)
state
)))
return
hr
;
}
if
(
FAILED
(
hr
=
performance_send_pmsg
(
This
,
music_time
,
DMUS_PMSGF_TOOL_IMMEDIATE
,
DMUS_PMSGT_DIRTY
,
NULL
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_performance
,
GUID_NOTIFICATION_PERFORMANCE
,
DMUS_NOTIFICATION_MUSICSTOPPED
,
NULL
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_pmsg
(
This
,
music_time
,
DMUS_PMSGF_TOOL_ATTIME
,
if
(
FAILED
(
hr
=
performance_send_pmsg
(
This
,
music_time
,
abort
?
DMUS_PMSGF_TOOL_IMMEDIATE
:
DMUS_PMSGF_TOOL_ATTIME
,
DMUS_PMSGT_INTERNAL_SEGMENT_END
,
(
IUnknown
*
)
state
)))
return
hr
;
...
...
@@ -557,13 +561,118 @@ static void enum_segment_states(struct performance *This, IDirectMusicSegment *s
}
}
static
HRESULT
WINAPI
performance_Stop
(
IDirectMusicPerformance8
*
iface
,
IDirectMusicSegment
*
pSegment
,
IDirectMusicSegmentState
*
pSegmentState
,
MUSIC_TIME
mtTime
,
DWORD
dwFlags
)
static
BOOL
message_needs_flushing
(
struct
message
*
message
,
IDirectMusicSegmentState
*
state
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
)
;
if
(
!
state
)
return
TRUE
;
FIXME
(
"(%p, %p, %p, %ld, %ld): stub
\n
"
,
This
,
pSegment
,
pSegmentState
,
mtTime
,
dwFlags
);
return
S_OK
;
switch
(
message
->
msg
.
dwType
)
{
case
DMUS_PMSGT_MIDI
:
case
DMUS_PMSGT_NOTE
:
case
DMUS_PMSGT_CURVE
:
case
DMUS_PMSGT_PATCH
:
case
DMUS_PMSGT_WAVE
:
if
(
!
segment_state_has_track
(
state
,
message
->
msg
.
dwVirtualTrackID
))
return
FALSE
;
break
;
case
DMUS_PMSGT_NOTIFICATION
:
{
DMUS_NOTIFICATION_PMSG
*
notif
=
(
DMUS_NOTIFICATION_PMSG
*
)
&
message
->
msg
;
if
(
!
IsEqualGUID
(
&
notif
->
guidNotificationType
,
&
GUID_NOTIFICATION_SEGMENT
))
return
FALSE
;
if
((
IDirectMusicSegmentState
*
)
message
->
msg
.
punkUser
!=
state
)
return
FALSE
;
break
;
}
case
DMUS_PMSGT_INTERNAL_SEGMENT_TICK
:
case
DMUS_PMSGT_INTERNAL_SEGMENT_END
:
if
((
IDirectMusicSegmentState
*
)
message
->
msg
.
punkUser
!=
state
)
return
FALSE
;
break
;
default:
FIXME
(
"Unhandled message type %#lx
\n
"
,
message
->
msg
.
dwType
);
break
;
}
return
TRUE
;
}
static
void
performance_flush_messages
(
struct
performance
*
This
,
IDirectMusicSegmentState
*
state
)
{
IDirectMusicPerformance
*
iface
=
(
IDirectMusicPerformance
*
)
&
This
->
IDirectMusicPerformance8_iface
;
struct
message
*
message
,
*
next
;
HRESULT
hr
;
LIST_FOR_EACH_ENTRY_SAFE
(
message
,
next
,
&
This
->
messages
,
struct
message
,
entry
)
{
if
(
!
message_needs_flushing
(
message
,
state
))
continue
;
list_remove
(
&
message
->
entry
);
list_init
(
&
message
->
entry
);
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_FreePMsg
(
iface
,
&
message
->
msg
)))
ERR
(
"Failed to free message %p, hr %#lx
\n
"
,
message
,
hr
);
}
LIST_FOR_EACH_ENTRY_SAFE
(
message
,
next
,
&
This
->
notifications
,
struct
message
,
entry
)
{
if
(
!
message_needs_flushing
(
message
,
state
))
continue
;
list_remove
(
&
message
->
entry
);
list_init
(
&
message
->
entry
);
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_FreePMsg
(
iface
,
&
message
->
msg
)))
ERR
(
"Failed to free message %p, hr %#lx
\n
"
,
message
,
hr
);
}
}
static
HRESULT
WINAPI
performance_Stop
(
IDirectMusicPerformance8
*
iface
,
IDirectMusicSegment
*
segment
,
IDirectMusicSegmentState
*
state
,
MUSIC_TIME
music_time
,
DWORD
flags
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
struct
list
states
=
LIST_INIT
(
states
);
struct
state_entry
*
entry
,
*
next
;
HRESULT
hr
;
FIXME
(
"(%p, %p, %p, %ld, %ld): semi-stub
\n
"
,
This
,
segment
,
state
,
music_time
,
flags
);
if
(
music_time
)
FIXME
(
"time parameter %lu not implemented
\n
"
,
music_time
);
if
(
flags
!=
DMUS_SEGF_DEFAULT
)
FIXME
(
"flags parameter %#lx not implemented
\n
"
,
flags
);
if
(
!
music_time
&&
FAILED
(
hr
=
IDirectMusicPerformance8_GetTime
(
iface
,
NULL
,
&
music_time
)))
return
hr
;
EnterCriticalSection
(
&
This
->
safe
);
if
(
!
state
)
enum_segment_states
(
This
,
segment
,
&
states
);
else
if
((
entry
=
malloc
(
sizeof
(
*
entry
))))
{
entry
->
state
=
state
;
IDirectMusicSegmentState_AddRef
(
entry
->
state
);
list_add_tail
(
&
states
,
&
entry
->
entry
);
}
if
(
!
segment
&&
!
state
)
performance_flush_messages
(
This
,
NULL
);
else
LIST_FOR_EACH_ENTRY
(
entry
,
&
states
,
struct
state_entry
,
entry
)
performance_flush_messages
(
This
,
entry
->
state
);
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
next
,
&
states
,
struct
state_entry
,
entry
)
{
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGABORT
,
(
IUnknown
*
)
entry
->
state
)))
ERR
(
"Failed to send DMUS_NOTIFICATION_SEGABORT, hr %#lx
\n
"
,
hr
);
if
(
FAILED
(
hr
=
segment_state_stop
(
entry
->
state
,
iface
)))
ERR
(
"Failed to stop segment state, hr %#lx
\n
"
,
hr
);
IDirectMusicSegmentState_Release
(
entry
->
state
);
list_remove
(
&
entry
->
entry
);
free
(
entry
);
}
LeaveCriticalSection
(
&
This
->
safe
);
return
S_OK
;
}
static
HRESULT
WINAPI
performance_GetSegmentState
(
IDirectMusicPerformance8
*
iface
,
...
...
@@ -1257,7 +1366,8 @@ static HRESULT WINAPI performance_AdjustTime(IDirectMusicPerformance8 *iface, RE
static
HRESULT
WINAPI
performance_CloseDown
(
IDirectMusicPerformance8
*
iface
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
struct
message
*
message
,
*
next
;
struct
list
states
=
LIST_INIT
(
states
);
struct
state_entry
*
entry
,
*
next
;
HANDLE
message_thread
;
HRESULT
hr
;
...
...
@@ -1277,28 +1387,17 @@ static HRESULT WINAPI performance_CloseDown(IDirectMusicPerformance8 *iface)
This
->
notification_performance
=
FALSE
;
This
->
notification_segment
=
FALSE
;
LIST_FOR_EACH_ENTRY_SAFE
(
message
,
next
,
&
This
->
messages
,
struct
message
,
entry
)
{
list_remove
(
&
message
->
entry
);
list_init
(
&
message
->
entry
);
if
(
message
->
msg
.
dwType
==
DMUS_PMSGT_INTERNAL_SEGMENT_END
)
hr
=
IDirectMusicTool_ProcessPMsg
(
&
This
->
IDirectMusicTool_iface
,
(
IDirectMusicPerformance
*
)
iface
,
&
message
->
msg
);
else
hr
=
DMUS_S_FREE
;
enum_segment_states
(
This
,
NULL
,
&
states
);
performance_flush_messages
(
This
,
NULL
);
if
(
hr
==
DMUS_S_FREE
&&
FAILED
(
hr
=
IDirectMusicPerformance8_FreePMsg
(
iface
,
&
message
->
msg
)))
WARN
(
"Failed to free message %p, hr %#lx
\n
"
,
message
,
hr
);
}
LIST_FOR_EACH_ENTRY_SAFE
(
message
,
next
,
&
This
->
notifications
,
struct
message
,
entry
)
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
next
,
&
states
,
struct
state_entry
,
entry
)
{
list_remove
(
&
message
->
entry
);
list_init
(
&
message
->
entry
);
if
(
FAILED
(
hr
=
segment_state_end_play
(
entry
->
state
,
iface
)))
ERR
(
"Failed to stop segment state, hr %#lx
\n
"
,
hr
);
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_FreePMsg
(
iface
,
&
message
->
msg
)))
WARN
(
"Failed to free message %p, hr %#lx
\n
"
,
message
,
hr
);
IDirectMusicSegmentState_Release
(
entry
->
state
);
list_remove
(
&
entry
->
entry
);
free
(
entry
);
}
performance_set_primary_segment
(
This
,
NULL
);
...
...
dlls/dmime/segmentstate.c
View file @
2414bb40
...
...
@@ -303,7 +303,7 @@ static HRESULT segment_state_play_chunk(struct segment_state *This, IDirectMusic
{
MUSIC_TIME
end_time
=
This
->
start_time
+
This
->
played
;
if
(
FAILED
(
hr
=
performance_send_segment_end
(
performance
,
end_time
,
iface
)))
if
(
FAILED
(
hr
=
performance_send_segment_end
(
performance
,
end_time
,
iface
,
FALSE
)))
{
ERR
(
"Failed to send segment end, hr %#lx
\n
"
,
hr
);
return
hr
;
...
...
@@ -345,6 +345,16 @@ HRESULT segment_state_tick(IDirectMusicSegmentState *iface, IDirectMusicPerforma
return
segment_state_play_chunk
(
This
,
performance
,
10000000
,
0
);
}
HRESULT
segment_state_stop
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
)
{
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
TRACE
(
"%p %p
\n
"
,
iface
,
performance
);
This
->
played
=
This
->
end_point
-
This
->
start_point
;
return
performance_send_segment_end
(
performance
,
This
->
start_time
+
This
->
played
,
iface
,
TRUE
);
}
HRESULT
segment_state_end_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
)
{
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
...
...
@@ -369,3 +379,14 @@ BOOL segment_state_has_segment(IDirectMusicSegmentState *iface, IDirectMusicSegm
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
return
!
segment
||
This
->
segment
==
segment
;
}
BOOL
segment_state_has_track
(
IDirectMusicSegmentState
*
iface
,
DWORD
track_id
)
{
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
struct
track_entry
*
entry
;
LIST_FOR_EACH_ENTRY
(
entry
,
&
This
->
tracks
,
struct
track_entry
,
entry
)
if
(
entry
->
track_id
==
track_id
)
return
TRUE
;
return
FALSE
;
}
dlls/dmime/tests/dmime.c
View file @
2414bb40
...
...
@@ -3322,14 +3322,11 @@ static void test_notification_pmsg(void)
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
ret
=
test_tool_wait_message
(
tool
,
50
,
(
DMUS_PMSG
**
)
&
notif
);
todo_wine
ok
(
!
ret
,
"got %#lx
\n
"
,
ret
);
if
(
!
ret
)
{
ok
(
!
ret
,
"got %#lx
\n
"
,
ret
);
check_dmus_notification_pmsg
(
notif
,
music_time
,
DMUS_PMSGF_TOOL_IMMEDIATE
,
&
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGABORT
,
state
);
hr
=
IDirectMusicPerformance_FreePMsg
(
performance
,
(
DMUS_PMSG
*
)
notif
);
ok
(
hr
==
S_OK
,
"got %#lx
\n
"
,
hr
);
}
ret
=
test_tool_wait_message
(
tool
,
500
,
&
msg
);
ok
(
!
ret
,
"got %#lx
\n
"
,
ret
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment