Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58631
-- v15: windows.media.playback.mediaplayer: Implement IActivationFactory::ActivateInstance(). windows.media.playback.backgroundmediaplayer: Add IBackgroundMediaPlayerStatics stub. include: Add IMediaPlayer definition. widl: Support additional deprecated declarations. windows.media.playback.backgroundmediaplayer: Add stub dll. include: Add windows.media.playback.idl.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/Makefile.in | 1 + include/windows.media.playback.idl | 130 +++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 include/windows.media.playback.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 2913b018a9b..cd748b8f00d 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -906,6 +906,7 @@ SOURCES = \ windows.media.faceanalysis.idl \ windows.media.idl \ windows.media.mediaproperties.idl \ + windows.media.playback.idl \ windows.media.render.idl \ windows.media.speechrecognition.idl \ windows.media.speechsynthesis.idl \ diff --git a/include/windows.media.playback.idl b/include/windows.media.playback.idl new file mode 100644 index 00000000000..132949e4a7d --- /dev/null +++ b/include/windows.media.playback.idl @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; +import "windows.foundation.idl"; +import "windows.devices.enumeration.idl"; +import "windows.foundation.numerics.idl"; +import "windows.graphics.directx.direct3d11.idl"; +import "windows.media.idl"; +/* import "windows.media.audio.idl"; */ +/* import "windows.media.casting.idl"; */ +import "windows.media.core.idl"; +import "windows.media.mediaproperties.idl"; +/* import "windows.media.protection.idl"; */ +import "windows.storage.idl"; +import "windows.storage.streams.idl"; +import "windows.ui.composition.idl"; + +namespace Windows.Media.Playback { + interface IBackgroundMediaPlayerStatics; + interface IMediaPlayer; + interface IMediaPlayerDataReceivedEventArgs; + + runtimeclass BackgroundMediaPlayer; + runtimeclass MediaPlayer; + runtimeclass MediaPlayerDataReceivedEventArgs; + + declare { + interface Windows.Foundation.EventHandler<Windows.Media.Playback.MediaPlayerDataReceivedEventArgs *>; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.BackgroundMediaPlayer), + deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), + uuid(856ddbc1-55f7-471f-a0f2-68ac4c904592) + ] + interface IBackgroundMediaPlayerStatics : IInspectable + { + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), propget] HRESULT Current([out, retval] Windows.Media.Playback.MediaPlayer **player); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), eventadd] HRESULT MessageReceivedFromBackground( + [in] Windows.Foundation.EventHandler<Windows.Media.Playback.MediaPlayerDataReceivedEventArgs *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), eventremove] HRESULT MessageReceivedFromBackground([in] EventRegistrationToken token); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), eventadd] HRESULT MessageReceivedFromForeground( + [in] Windows.Foundation.EventHandler<Windows.Media.Playback.MediaPlayerDataReceivedEventArgs *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), eventremove] HRESULT MessageReceivedFromForeground([in] EventRegistrationToken token); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0)] HRESULT SendMessageToBackground([in] Windows.Foundation.Collections.ValueSet *value); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0)] HRESULT SendMessageToForeground([in] Windows.Foundation.Collections.ValueSet *value); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0)] HRESULT IsMediaPlaying([out, retval] boolean *value); + [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0)] HRESULT Shutdown(); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.MediaPlayerDataReceivedEventArgs), + uuid(c75a9405-c801-412a-835b-83fc0e622a8e) + ] + interface IMediaPlayerDataReceivedEventArgs : IInspectable + { + [propget] HRESULT Data([out, retval] Windows.Foundation.Collections.ValueSet **value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), + marshaling_behavior(agile), + static(Windows.Media.Playback.IBackgroundMediaPlayerStatics, Windows.Foundation.UniversalApiContract, 1.0), + threading(both) + ] + runtimeclass BackgroundMediaPlayer + { + } + + [ + activatable(Windows.Foundation.UniversalApiContract, 3.0), + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + threading(both) + ] + runtimeclass MediaPlayer + { + [default] interface Windows.Media.Playback.IMediaPlayer; + /* interface Windows.Media.Playback.IMediaPlayerSource; */ + /* [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Media.Playback.IMediaPlayerSource2; */ + /* [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Media.Playback.IMediaPlayer2; */ + /* [contract(Windows.Foundation.UniversalApiContract, 2.0)] interface Windows.Media.Playback.IMediaPlayerEffects; */ + [contract(Windows.Foundation.UniversalApiContract, 3.0)] interface Windows.Foundation.IClosable; + /* [contract(Windows.Foundation.UniversalApiContract, 3.0)] interface Windows.Media.Playback.IMediaPlayer3; */ + /* [contract(Windows.Foundation.UniversalApiContract, 3.0)] interface Windows.Media.Playback.IMediaPlayer4; */ + /* [contract(Windows.Foundation.UniversalApiContract, 3.0)] interface Windows.Media.Playback.IMediaPlayerEffects2; */ + /* [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.Media.Playback.IMediaPlayer5; */ + /* [contract(Windows.Foundation.UniversalApiContract, 5.0)] interface Windows.Media.Playback.IMediaPlayer6; */ + /* [contract(Windows.Foundation.UniversalApiContract, 6.0)] interface Windows.Media.Playback.IMediaPlayer7; */ + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass MediaPlayerDataReceivedEventArgs + { + [default] interface Windows.Media.Playback.IMediaPlayerDataReceivedEventArgs; + } +}
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + .../Makefile.in | 6 + .../classes.idl | 28 ++++ .../main.c | 140 ++++++++++++++++++ .../private.h | 38 +++++ .../tests/Makefile.in | 5 + .../tests/playback.c | 86 +++++++++++ ....media.playback.backgroundmediaplayer.spec | 3 + 8 files changed, 308 insertions(+) create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/Makefile.in create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/classes.idl create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/main.c create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/private.h create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/tests/Makefile.in create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c create mode 100644 dlls/windows.media.playback.backgroundmediaplayer/windows.media.playback.backgroundmediaplayer.spec
diff --git a/configure.ac b/configure.ac index 2cc5398d178..a243ffe31a2 100644 --- a/configure.ac +++ b/configure.ac @@ -3292,6 +3292,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.media.devices) WINE_CONFIG_MAKEFILE(dlls/windows.media.devices/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media.mediacontrol) WINE_CONFIG_MAKEFILE(dlls/windows.media.mediacontrol/tests) +WINE_CONFIG_MAKEFILE(dlls/windows.media.playback.backgroundmediaplayer) +WINE_CONFIG_MAKEFILE(dlls/windows.media.playback.backgroundmediaplayer/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media) diff --git a/dlls/windows.media.playback.backgroundmediaplayer/Makefile.in b/dlls/windows.media.playback.backgroundmediaplayer/Makefile.in new file mode 100644 index 00000000000..88c79aa6636 --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/Makefile.in @@ -0,0 +1,6 @@ +MODULE = windows.media.playback.backgroundmediaplayer.dll +IMPORTS = combase + +SOURCES = \ + classes.idl \ + main.c diff --git a/dlls/windows.media.playback.backgroundmediaplayer/classes.idl b/dlls/windows.media.playback.backgroundmediaplayer/classes.idl new file mode 100644 index 00000000000..ce531d7fac0 --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/classes.idl @@ -0,0 +1,28 @@ +/* + * Runtime Classes for windows.media.playback.backgroundmediaplayer.dll + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register +#pragma winrt ns_prefix + +import "windows.media.playback.idl"; + +namespace Windows.Media.Playback { + runtimeclass BackgroundMediaPlayer; +} diff --git a/dlls/windows.media.playback.backgroundmediaplayer/main.c b/dlls/windows.media.playback.backgroundmediaplayer/main.c new file mode 100644 index 00000000000..1eb3e09990f --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/main.c @@ -0,0 +1,140 @@ +/* WinRT Windows.Media.Playback.BackgroundMediaPlayer Implementation + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "initguid.h" +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(playback); + +struct background_media_player_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct background_media_player_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct background_media_player_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct background_media_player_statics *impl = impl_from_IActivationFactory( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct background_media_player_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct background_media_player_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + /* IUnknown methods */ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct background_media_player_statics background_media_player_statics = +{ + {&factory_vtbl}, + 1, +}; + +static IActivationFactory *background_media_player_factory = &background_media_player_statics.IActivationFactory_iface; + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid( clsid ), debugstr_guid( riid ), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "class %s, factory %p.\n", debugstr_hstring( classid ), factory ); + + *factory = NULL; + + if (!wcscmp( buffer, RuntimeClass_Windows_Media_Playback_BackgroundMediaPlayer )) + IActivationFactory_QueryInterface( background_media_player_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.media.playback.backgroundmediaplayer/private.h b/dlls/windows.media.playback.backgroundmediaplayer/private.h new file mode 100644 index 00000000000..8202db332cd --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/private.h @@ -0,0 +1,38 @@ +/* WinRT Windows.Media.Playback.BackgroundMediaPlayer Implementation + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINDOWS_MEDIA_PLAYBACK_BACKGROUNDMEDIAPLAYER_PRIVATE_H +#define __WINE_WINDOWS_MEDIA_PLAYBACK_BACKGROUNDMEDIAPLAYER_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Media_Playback +#include "windows.media.playback.h" + +#endif diff --git a/dlls/windows.media.playback.backgroundmediaplayer/tests/Makefile.in b/dlls/windows.media.playback.backgroundmediaplayer/tests/Makefile.in new file mode 100644 index 00000000000..de29ce8f980 --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.media.playback.backgroundmediaplayer.dll +IMPORTS = combase + +SOURCES = \ + playback.c diff --git a/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c b/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c new file mode 100644 index 00000000000..a596e899294 --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Media_Playback +#include "windows.media.playback.h" + +#include "wine/test.h" + +#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) +static void check_interface_( unsigned int line, void *obj, const IID *iid ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + IUnknown_Release( unk ); +} + +static void test_BackgroundMediaPlayer_Statics(void) +{ + static const WCHAR *background_media_player_statics_name = L"Windows.Media.Playback.BackgroundMediaPlayer"; + IActivationFactory *factory = (void *)0xdeadbeef; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( background_media_player_statics_name, wcslen( background_media_player_statics_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( str ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( background_media_player_statics_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(playback) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_BackgroundMediaPlayer_Statics(); + + RoUninitialize(); +} diff --git a/dlls/windows.media.playback.backgroundmediaplayer/windows.media.playback.backgroundmediaplayer.spec b/dlls/windows.media.playback.backgroundmediaplayer/windows.media.playback.backgroundmediaplayer.spec new file mode 100644 index 00000000000..20a8bfa98ea --- /dev/null +++ b/dlls/windows.media.playback.backgroundmediaplayer/windows.media.playback.backgroundmediaplayer.spec @@ -0,0 +1,3 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr)
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/attribute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/widl/attribute.c b/tools/widl/attribute.c index 0268cde417f..1288d004317 100644 --- a/tools/widl/attribute.c +++ b/tools/widl/attribute.c @@ -170,7 +170,7 @@ struct allowed_attr allowed_attr[] = /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" }, /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" }, /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" }, - /* ATTR_DEPRECATED */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "deprecated" }, + /* ATTR_DEPRECATED */ { 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, "deprecated" }, /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" }, /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL }, /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/windows.media.playback.idl | 266 +++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+)
diff --git a/include/windows.media.playback.idl b/include/windows.media.playback.idl index 132949e4a7d..4f09cc90679 100644 --- a/include/windows.media.playback.idl +++ b/include/windows.media.playback.idl @@ -39,18 +39,64 @@ import "windows.storage.streams.idl"; import "windows.ui.composition.idl";
namespace Windows.Media.Playback { + typedef enum MediaPlayerError MediaPlayerError; + typedef enum MediaPlayerState MediaPlayerState; + interface IBackgroundMediaPlayerStatics; interface IMediaPlayer; interface IMediaPlayerDataReceivedEventArgs; + interface IMediaPlayerFailedEventArgs; + interface IMediaPlayerRateChangedEventArgs; + interface IPlaybackMediaMarker; + interface IPlaybackMediaMarkerFactory; + interface IPlaybackMediaMarkerReachedEventArgs; + interface IPlaybackMediaMarkerSequence;
runtimeclass BackgroundMediaPlayer; runtimeclass MediaPlayer; runtimeclass MediaPlayerDataReceivedEventArgs; + runtimeclass MediaPlayerFailedEventArgs; + runtimeclass MediaPlayerRateChangedEventArgs; + runtimeclass PlaybackMediaMarker; + runtimeclass PlaybackMediaMarkerSequence; + runtimeclass PlaybackMediaMarkerReachedEventArgs;
declare { + interface Windows.Foundation.Collections.IIterable<Windows.Media.Playback.PlaybackMediaMarker *>; + interface Windows.Foundation.Collections.IIterator<Windows.Media.Playback.PlaybackMediaMarker *>; interface Windows.Foundation.EventHandler<Windows.Media.Playback.MediaPlayerDataReceivedEventArgs *>; + interface Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *>; + interface Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, Windows.Media.Playback.MediaPlayerFailedEventArgs *>; + interface Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, Windows.Media.Playback.MediaPlayerRateChangedEventArgs *>; + interface Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, Windows.Media.Playback.PlaybackMediaMarkerReachedEventArgs *>; }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum MediaPlayerError + { + Unknown = 0, + Aborted = 1, + NetworkError = 2, + DecodingError = 3, + SourceNotSupported = 4, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + deprecated("Use MediaPlaybackState", deprecate, Windows.Foundation.UniversalApiContract, 3.0) + ] + enum MediaPlayerState + { + Closed = 0, + Opening = 1, + Buffering = 2, + Playing = 3, + Paused = 4, + Stopped = 5, + }; + [ contract(Windows.Foundation.UniversalApiContract, 1.0), exclusiveto(Windows.Media.Playback.BackgroundMediaPlayer), @@ -76,6 +122,111 @@ namespace Windows.Media.Playback { [deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0)] HRESULT Shutdown(); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.MediaPlayer), + uuid(381a83cb-6fff-499b-8d64-2885dfc1249e) + ] + interface IMediaPlayer : IInspectable + { + [propget] HRESULT AutoPlay([out, retval] boolean *value); + [propput] HRESULT AutoPlay([in] boolean value); + [deprecated("Use PlaybackSession.NaturalDuration", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT NaturalDuration([out, retval] Windows.Foundation.TimeSpan *value); + [deprecated("Use PlaybackSession.Position", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT Position([out, retval] Windows.Foundation.TimeSpan *value); + [deprecated("Use PlaybackSession.Position", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propput] HRESULT Position([in] Windows.Foundation.TimeSpan value); + [deprecated("Use PlaybackSession.BufferingProgress", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT BufferingProgress([out, retval] DOUBLE *value); + [deprecated("Use PlaybackSession.State", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT CurrentState([out, retval] Windows.Media.Playback.MediaPlayerState *value); + [deprecated("Use PlaybackSession.CanSeek", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT CanSeek([out, retval] boolean *value); + [deprecated("Use PlaybackSession.CanPause", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT CanPause([out, retval] boolean *value); + [propget] HRESULT IsLoopingEnabled([out, retval] boolean *value); + [propput] HRESULT IsLoopingEnabled([in] boolean value); + [deprecated("Use PlaybackSession.IsProtected", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT IsProtected([out, retval] boolean *value); + [propget] HRESULT IsMuted([out, retval] boolean *value); + [propput] HRESULT IsMuted([in] boolean value); + [deprecated("Use PlaybackSession.PlaybackRate", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propget] HRESULT PlaybackRate([out, retval] DOUBLE *value); + [deprecated("Use PlaybackSession.PlaybackRate", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [propput] HRESULT PlaybackRate([in] DOUBLE value); + [propget] HRESULT Volume([out, retval] DOUBLE *value); + [propput] HRESULT Volume([in] DOUBLE value); + [deprecated("Use media tracks on MediaPlaybackItem", deprecate, Windows.Foundation.UniversalApiContract, 2.0)] + [propget] HRESULT PlaybackMediaMarkers([out, retval] Windows.Media.Playback.PlaybackMediaMarkerSequence **value); + [eventadd] HRESULT MediaOpened( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT MediaOpened([in] EventRegistrationToken token); + [eventadd] HRESULT MediaEnded( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT MediaEnded([in] EventRegistrationToken token); + [eventadd] HRESULT MediaFailed( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, Windows.Media.Playback.MediaPlayerFailedEventArgs *> *value, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT MediaFailed([in] EventRegistrationToken token); + [deprecated("Use PlaybackSession.PlaybackStateChanged", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventadd] HRESULT CurrentStateChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use PlaybackSession.PlaybackStateChanged", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventremove] HRESULT CurrentStateChanged([in] EventRegistrationToken token); + [deprecated("Use media tracks on MediaPlaybackItem", deprecate, Windows.Foundation.UniversalApiContract, 2.0)] + [eventadd] HRESULT PlaybackMediaMarkerReached( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, Windows.Media.Playback.PlaybackMediaMarkerReachedEventArgs *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use media tracks on MediaPlaybackItem", deprecate, Windows.Foundation.UniversalApiContract, 2.0)] + [eventremove] HRESULT PlaybackMediaMarkerReached([in] EventRegistrationToken token); + [deprecated("Use PlaybackSession.PlaybackRateChanged", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventadd] HRESULT MediaPlayerRateChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, Windows.Media.Playback.MediaPlayerRateChangedEventArgs *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use PlaybackSession.PlaybackRateChanged", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventremove] HRESULT MediaPlayerRateChanged([in] EventRegistrationToken token); + [eventadd] HRESULT VolumeChanged( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [eventremove] HRESULT VolumeChanged([in] EventRegistrationToken token); + [deprecated("Use PlaybackSession.SeekCompleted", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventadd] HRESULT SeekCompleted( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use PlaybackSession.SeekCompleted", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventremove] HRESULT SeekCompleted([in] EventRegistrationToken token); + [deprecated("Use PlaybackSession.BufferingStarted", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventadd] HRESULT BufferingStarted( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use PlaybackSession.BufferingStarted", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventremove] HRESULT BufferingStarted([in] EventRegistrationToken token); + [deprecated("Use PlaybackSession.BufferingEnded", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventadd] HRESULT BufferingEnded( + [in] Windows.Foundation.TypedEventHandler<Windows.Media.Playback.MediaPlayer *, IInspectable *> *value, + [out, retval] EventRegistrationToken *token + ); + [deprecated("Use PlaybackSession.BufferingEnded", deprecate, Windows.Foundation.UniversalApiContract, 3.0)] + [eventremove] HRESULT BufferingEnded([in] EventRegistrationToken token); + HRESULT Play(); + HRESULT Pause(); + [deprecated("Use Source", deprecate, Windows.Foundation.UniversalApiContract, 2.0)] + HRESULT SetUriSource([in] Windows.Foundation.Uri *value); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), exclusiveto(Windows.Media.Playback.MediaPlayerDataReceivedEventArgs), @@ -86,6 +237,74 @@ namespace Windows.Media.Playback { [propget] HRESULT Data([out, retval] Windows.Foundation.Collections.ValueSet **value); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.MediaPlayerFailedEventArgs), + uuid(2744e9b9-a7e3-4f16-bac4-7914ebc08301) + ] + interface IMediaPlayerFailedEventArgs : IInspectable + { + [propget] HRESULT Error([out, retval] Windows.Media.Playback.MediaPlayerError *value); + [propget] HRESULT ExtendedErrorCode([out, retval] HRESULT *value); + [propget] HRESULT ErrorMessage([out, retval] HSTRING *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.MediaPlayerRateChangedEventArgs), + uuid(40600d58-3b61-4bb2-989f-fc65608b6cab) + ] + interface IMediaPlayerRateChangedEventArgs : IInspectable + { + [propget] HRESULT NewRate([out, retval] DOUBLE *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.PlaybackMediaMarker), + uuid(c4d22f5c-3c1c-4444-b6b9-778b0422d41a) + ] + interface IPlaybackMediaMarker : IInspectable + { + [propget] HRESULT Time([out, retval] Windows.Foundation.TimeSpan *value); + [propget] HRESULT MediaMarkerType([out, retval] HSTRING *value); + [propget] HRESULT Text([out, retval] HSTRING *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.PlaybackMediaMarker), + uuid(8c530a78-e0ae-4e1a-a8c8-e23f982a937b) + ] + interface IPlaybackMediaMarkerFactory : IInspectable + { + HRESULT CreateFromTime([in] Windows.Foundation.TimeSpan value, [out, retval] Windows.Media.Playback.PlaybackMediaMarker **marker); + HRESULT Create([in] Windows.Foundation.TimeSpan value, [in] HSTRING media_market_type, [in] HSTRING text, [out, retval] Windows.Media.Playback.PlaybackMediaMarker **marker); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.PlaybackMediaMarkerReachedEventArgs), + uuid(578cd1b9-90e2-4e60-abc4-8740b01f6196) + ] + interface IPlaybackMediaMarkerReachedEventArgs : IInspectable + { + [propget] HRESULT PlaybackMediaMarker([out, retval] Windows.Media.Playback.PlaybackMediaMarker **value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.Playback.PlaybackMediaMarkerSequence), + uuid(f2810cee-638b-46cf-8817-1d111fe9d8c4) + ] + interface IPlaybackMediaMarkerSequence : IInspectable + requires Windows.Foundation.Collections.IIterable<Windows.Media.Playback.PlaybackMediaMarker *> + { + [propget] HRESULT Size([out, retval] UINT32 *value); + HRESULT Insert([in] Windows.Media.Playback.PlaybackMediaMarker *value); + HRESULT Clear(); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), deprecated("Use MediaPlayer", deprecate, Windows.Foundation.UniversalApiContract, 4.0), @@ -127,4 +346,51 @@ namespace Windows.Media.Playback { { [default] interface Windows.Media.Playback.IMediaPlayerDataReceivedEventArgs; } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass MediaPlayerFailedEventArgs + { + [default] interface Windows.Media.Playback.IMediaPlayerFailedEventArgs; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass MediaPlayerRateChangedEventArgs + { + [default] interface Windows.Media.Playback.IMediaPlayerRateChangedEventArgs; + } + + [ + activatable(Windows.Media.Playback.IPlaybackMediaMarkerFactory, Windows.Foundation.UniversalApiContract, 1.0), + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass PlaybackMediaMarker + { + [default] interface Windows.Media.Playback.IPlaybackMediaMarker; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass PlaybackMediaMarkerSequence + { + [default] interface Windows.Media.Playback.IPlaybackMediaMarkerSequence; + interface Windows.Foundation.Collections.IIterable<Windows.Media.Playback.PlaybackMediaMarker *>; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass PlaybackMediaMarkerReachedEventArgs + { + [default] interface Windows.Media.Playback.IPlaybackMediaMarkerReachedEventArgs; + } }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../main.c | 91 +++++++++++++++++++ .../private.h | 38 ++++++++ .../tests/playback.c | 6 ++ 3 files changed, 135 insertions(+)
diff --git a/dlls/windows.media.playback.backgroundmediaplayer/main.c b/dlls/windows.media.playback.backgroundmediaplayer/main.c index 1eb3e09990f..66382520957 100644 --- a/dlls/windows.media.playback.backgroundmediaplayer/main.c +++ b/dlls/windows.media.playback.backgroundmediaplayer/main.c @@ -27,6 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(playback); struct background_media_player_statics { IActivationFactory IActivationFactory_iface; + IBackgroundMediaPlayerStatics IBackgroundMediaPlayerStatics_iface; LONG ref; };
@@ -51,6 +52,13 @@ static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID return S_OK; }
+ if (IsEqualGUID( iid, &IID_IBackgroundMediaPlayerStatics )) + { + *out = &impl->IBackgroundMediaPlayerStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); *out = NULL; return E_NOINTERFACE; @@ -110,9 +118,92 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+DEFINE_IINSPECTABLE( background_media_player_statics, IBackgroundMediaPlayerStatics, struct background_media_player_statics, IActivationFactory_iface ) + +static HRESULT WINAPI background_media_player_statics_get_Current( IBackgroundMediaPlayerStatics *iface, IMediaPlayer **player ) +{ + FIXME( "iface %p, player %p stub!\n", iface, player ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_add_MessageReceivedFromBackground( IBackgroundMediaPlayerStatics *iface, + IEventHandler_MediaPlayerDataReceivedEventArgs *value, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_remove_MessageReceivedFromBackground( IBackgroundMediaPlayerStatics *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_add_MessageReceivedFromForeground( IBackgroundMediaPlayerStatics *iface, + IEventHandler_MediaPlayerDataReceivedEventArgs *value, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_remove_MessageReceivedFromForeground( IBackgroundMediaPlayerStatics *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_SendMessageToBackground( IBackgroundMediaPlayerStatics *iface, IPropertySet *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_SendMessageToForeground( IBackgroundMediaPlayerStatics *iface, IPropertySet *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_IsMediaPlaying( IBackgroundMediaPlayerStatics *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI background_media_player_statics_Shutdown( IBackgroundMediaPlayerStatics *iface ) +{ + FIXME( "iface %p stub!\n", iface ); + return E_NOTIMPL; +} + +static const struct IBackgroundMediaPlayerStaticsVtbl background_media_player_statics_vtbl = +{ + /* IUnknown methods */ + background_media_player_statics_QueryInterface, + background_media_player_statics_AddRef, + background_media_player_statics_Release, + /* IInspectable methods */ + background_media_player_statics_GetIids, + background_media_player_statics_GetRuntimeClassName, + background_media_player_statics_GetTrustLevel, + /* IBackgroundMediaPlayerStatics methods */ + background_media_player_statics_get_Current, + background_media_player_statics_add_MessageReceivedFromBackground, + background_media_player_statics_remove_MessageReceivedFromBackground, + background_media_player_statics_add_MessageReceivedFromForeground, + background_media_player_statics_remove_MessageReceivedFromForeground, + background_media_player_statics_SendMessageToBackground, + background_media_player_statics_SendMessageToForeground, + background_media_player_statics_IsMediaPlaying, + background_media_player_statics_Shutdown, +}; + static struct background_media_player_statics background_media_player_statics = { {&factory_vtbl}, + {&background_media_player_statics_vtbl}, 1, };
diff --git a/dlls/windows.media.playback.backgroundmediaplayer/private.h b/dlls/windows.media.playback.backgroundmediaplayer/private.h index 8202db332cd..63115ff2a6f 100644 --- a/dlls/windows.media.playback.backgroundmediaplayer/private.h +++ b/dlls/windows.media.playback.backgroundmediaplayer/private.h @@ -35,4 +35,42 @@ #define WIDL_using_Windows_Media_Playback #include "windows.media.playback.h"
+#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ + static inline impl_type *impl_from( iface_type *iface ) \ + { \ + return CONTAINING_RECORD( iface, impl_type, iface_mem ); \ + } \ + static HRESULT WINAPI pfx##_QueryInterface( iface_type *iface, REFIID iid, void **out ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_QueryInterface( (IInspectable *)(expr), iid, out ); \ + } \ + static ULONG WINAPI pfx##_AddRef( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_AddRef( (IInspectable *)(expr) ); \ + } \ + static ULONG WINAPI pfx##_Release( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_Release( (IInspectable *)(expr) ); \ + } \ + static HRESULT WINAPI pfx##_GetIids( iface_type *iface, ULONG *iid_count, IID **iids ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetIids( (IInspectable *)(expr), iid_count, iids ); \ + } \ + static HRESULT WINAPI pfx##_GetRuntimeClassName( iface_type *iface, HSTRING *class_name ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetRuntimeClassName( (IInspectable *)(expr), class_name ); \ + } \ + static HRESULT WINAPI pfx##_GetTrustLevel( iface_type *iface, TrustLevel *trust_level ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetTrustLevel( (IInspectable *)(expr), trust_level ); \ + } +#define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \ + DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface ) + #endif diff --git a/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c b/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c index a596e899294..a99c4080e1b 100644 --- a/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c +++ b/dlls/windows.media.playback.backgroundmediaplayer/tests/playback.c @@ -48,6 +48,7 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) static void test_BackgroundMediaPlayer_Statics(void) { static const WCHAR *background_media_player_statics_name = L"Windows.Media.Playback.BackgroundMediaPlayer"; + IBackgroundMediaPlayerStatics *background_media_player_statics = (void *)0xdeadbeef; IActivationFactory *factory = (void *)0xdeadbeef; HSTRING str; HRESULT hr; @@ -69,6 +70,11 @@ static void test_BackgroundMediaPlayer_Statics(void) check_interface( factory, &IID_IInspectable ); check_interface( factory, &IID_IAgileObject );
+ hr = IActivationFactory_QueryInterface( factory, &IID_IBackgroundMediaPlayerStatics, (void **)&background_media_player_statics ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + ref = IBackgroundMediaPlayerStatics_Release( background_media_player_statics ); + ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref ); }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + .../Makefile.in | 6 + .../classes.idl | 28 + .../windows.media.playback.mediaplayer/main.c | 532 ++++++++++++++++++ .../private.h | 39 ++ .../tests/Makefile.in | 5 + .../tests/mediaplayer.c | 102 ++++ .../windows.media.playback.mediaplayer.spec | 3 + 8 files changed, 717 insertions(+) create mode 100644 dlls/windows.media.playback.mediaplayer/Makefile.in create mode 100644 dlls/windows.media.playback.mediaplayer/classes.idl create mode 100644 dlls/windows.media.playback.mediaplayer/main.c create mode 100644 dlls/windows.media.playback.mediaplayer/private.h create mode 100644 dlls/windows.media.playback.mediaplayer/tests/Makefile.in create mode 100644 dlls/windows.media.playback.mediaplayer/tests/mediaplayer.c create mode 100644 dlls/windows.media.playback.mediaplayer/windows.media.playback.mediaplayer.spec
diff --git a/configure.ac b/configure.ac index a243ffe31a2..0f639b6670d 100644 --- a/configure.ac +++ b/configure.ac @@ -3294,6 +3294,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.media.mediacontrol) WINE_CONFIG_MAKEFILE(dlls/windows.media.mediacontrol/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media.playback.backgroundmediaplayer) WINE_CONFIG_MAKEFILE(dlls/windows.media.playback.backgroundmediaplayer/tests) +WINE_CONFIG_MAKEFILE(dlls/windows.media.playback.mediaplayer) +WINE_CONFIG_MAKEFILE(dlls/windows.media.playback.mediaplayer/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media) diff --git a/dlls/windows.media.playback.mediaplayer/Makefile.in b/dlls/windows.media.playback.mediaplayer/Makefile.in new file mode 100644 index 00000000000..9fa6895c9ea --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/Makefile.in @@ -0,0 +1,6 @@ +MODULE = windows.media.playback.mediaplayer.dll +IMPORTS = combase + +SOURCES = \ + classes.idl \ + main.c diff --git a/dlls/windows.media.playback.mediaplayer/classes.idl b/dlls/windows.media.playback.mediaplayer/classes.idl new file mode 100644 index 00000000000..5ad7ee41448 --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/classes.idl @@ -0,0 +1,28 @@ +/* + * Runtime Classes for windows.media.playback.mediaplayer.dll + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register +#pragma winrt ns_prefix + +import "windows.media.playback.idl"; + +namespace Windows.Media.Playback { + runtimeclass MediaPlayer; +} diff --git a/dlls/windows.media.playback.mediaplayer/main.c b/dlls/windows.media.playback.mediaplayer/main.c new file mode 100644 index 00000000000..08d170c88df --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/main.c @@ -0,0 +1,532 @@ +/* WinRT Windows.Media.Playback.MediaPlayer Implementation + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "initguid.h" +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mediaplayer); + +struct media_player +{ + IMediaPlayer IMediaPlayer_iface; + LONG ref; +}; + +static inline struct media_player *impl_from_IMediaPlayer( IMediaPlayer *iface ) +{ + return CONTAINING_RECORD( iface, struct media_player, IMediaPlayer_iface ); +} + +static HRESULT WINAPI media_player_QueryInterface( IMediaPlayer *iface, REFIID iid, void **out ) +{ + struct media_player *impl = impl_from_IMediaPlayer( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IMediaPlayer )) + { + *out = &impl->IMediaPlayer_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI media_player_AddRef( IMediaPlayer *iface ) +{ + struct media_player *impl = impl_from_IMediaPlayer( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI media_player_Release( IMediaPlayer *iface ) +{ + struct media_player *impl = impl_from_IMediaPlayer( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI media_player_GetIids( IMediaPlayer *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_GetRuntimeClassName( IMediaPlayer *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_GetTrustLevel( IMediaPlayer *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_AutoPlay( IMediaPlayer *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_put_AutoPlay( IMediaPlayer *iface, boolean value ) +{ + FIXME( "iface %p, value %d stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_NaturalDuration( IMediaPlayer *iface, TimeSpan *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_Position( IMediaPlayer *iface, TimeSpan *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_put_Position( IMediaPlayer *iface, TimeSpan value ) +{ + FIXME( "iface %p, value %I64d stub!\n", iface, value.Duration ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_BufferingProgress( IMediaPlayer *iface, DOUBLE *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_CurrentState( IMediaPlayer *iface, MediaPlayerState *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_CanSeek( IMediaPlayer *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_CanPause( IMediaPlayer *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_IsLoopingEnabled( IMediaPlayer *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_put_IsLoopingEnabled( IMediaPlayer *iface, boolean value ) +{ + FIXME( "iface %p, value %d stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_IsProtected( IMediaPlayer *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_IsMuted( IMediaPlayer *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_put_IsMuted( IMediaPlayer *iface, boolean value ) +{ + FIXME( "iface %p, value %d stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_PlaybackRate( IMediaPlayer *iface, DOUBLE *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_put_PlaybackRate( IMediaPlayer *iface, DOUBLE value ) +{ + FIXME( "iface %p, value %lf stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_Volume( IMediaPlayer *iface, DOUBLE *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_put_Volume( IMediaPlayer *iface, DOUBLE value ) +{ + FIXME( "iface %p, value %lf stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_get_PlaybackMediaMarkers( IMediaPlayer *iface, IPlaybackMediaMarkerSequence **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_MediaOpened( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_MediaOpened( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_MediaEnded( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_MediaEnded( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_MediaFailed( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_MediaPlayerFailedEventArgs *value, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_MediaFailed( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_CurrentStateChanged( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_CurrentStateChanged( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_PlaybackMediaMarkerReached( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_PlaybackMediaMarkerReachedEventArgs *value, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_PlaybackMediaMarkerReached( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_MediaPlayerRateChanged( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_MediaPlayerRateChangedEventArgs *value, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_MediaPlayerRateChanged( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_VolumeChanged( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_VolumeChanged( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_SeekCompleted( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_SeekCompleted( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_BufferingStarted( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_BufferingStarted( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_add_BufferingEnded( IMediaPlayer *iface, ITypedEventHandler_MediaPlayer_IInspectable *value, EventRegistrationToken *token ) +{ + FIXME( "iface %p, value %p, token %p stub!\n", iface, value, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_remove_BufferingEnded( IMediaPlayer *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_Play( IMediaPlayer *iface ) +{ + FIXME( "iface %p stub!\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_Pause( IMediaPlayer *iface ) +{ + FIXME( "iface %p stub!\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_player_SetUriSource( IMediaPlayer *iface, IUriRuntimeClass *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IMediaPlayerVtbl media_player_vtbl = +{ + /* IUnknown methods */ + media_player_QueryInterface, + media_player_AddRef, + media_player_Release, + /* IInspectable methods */ + media_player_GetIids, + media_player_GetRuntimeClassName, + media_player_GetTrustLevel, + /* IMediaPlayer methods */ + media_player_get_AutoPlay, + media_player_put_AutoPlay, + media_player_get_NaturalDuration, + media_player_get_Position, + media_player_put_Position, + media_player_get_BufferingProgress, + media_player_get_CurrentState, + media_player_get_CanSeek, + media_player_get_CanPause, + media_player_get_IsLoopingEnabled, + media_player_put_IsLoopingEnabled, + media_player_get_IsProtected, + media_player_get_IsMuted, + media_player_put_IsMuted, + media_player_get_PlaybackRate, + media_player_put_PlaybackRate, + media_player_get_Volume, + media_player_put_Volume, + media_player_get_PlaybackMediaMarkers, + media_player_add_MediaOpened, + media_player_remove_MediaOpened, + media_player_add_MediaEnded, + media_player_remove_MediaEnded, + media_player_add_MediaFailed, + media_player_remove_MediaFailed, + media_player_add_CurrentStateChanged, + media_player_remove_CurrentStateChanged, + media_player_add_PlaybackMediaMarkerReached, + media_player_remove_PlaybackMediaMarkerReached, + media_player_add_MediaPlayerRateChanged, + media_player_remove_MediaPlayerRateChanged, + media_player_add_VolumeChanged, + media_player_remove_VolumeChanged, + media_player_add_SeekCompleted, + media_player_remove_SeekCompleted, + media_player_add_BufferingStarted, + media_player_remove_BufferingStarted, + media_player_add_BufferingEnded, + media_player_remove_BufferingEnded, + media_player_Play, + media_player_Pause, + media_player_SetUriSource, +}; + +struct media_player_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct media_player_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct media_player_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct media_player_statics *impl = impl_from_IActivationFactory( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct media_player_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct media_player_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + struct media_player *impl; + + TRACE( "iface %p, instance %p.\n", iface, instance ); + + if (!(impl = calloc( 1, sizeof( *impl ) ))) + { + *instance = NULL; + return E_OUTOFMEMORY; + } + + impl->IMediaPlayer_iface.lpVtbl = &media_player_vtbl; + impl->ref = 1; + + *instance = (IInspectable *)&impl->IMediaPlayer_iface; + return S_OK; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + /* IUnknown methods */ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct media_player_statics media_player_statics = +{ + {&factory_vtbl}, + 1, +}; + +static IActivationFactory *media_player_factory = &media_player_statics.IActivationFactory_iface; + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid( clsid ), debugstr_guid( riid ), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "class %s, factory %p.\n", debugstr_hstring( classid ), factory ); + + *factory = NULL; + + if (!wcscmp( buffer, RuntimeClass_Windows_Media_Playback_MediaPlayer )) + IActivationFactory_QueryInterface( media_player_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.media.playback.mediaplayer/private.h b/dlls/windows.media.playback.mediaplayer/private.h new file mode 100644 index 00000000000..e356abcff28 --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/private.h @@ -0,0 +1,39 @@ +/* WinRT Windows.Media.Playback.MediaPlayer Implementation + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINDOWS_MEDIA_PLAYBACK_MEDIAPLAYER_PRIVATE_H +#define __WINE_WINDOWS_MEDIA_PLAYBACK_MEDIAPLAYER_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Media +#define WIDL_using_Windows_Media_Playback +#include "windows.media.playback.h" + +#endif diff --git a/dlls/windows.media.playback.mediaplayer/tests/Makefile.in b/dlls/windows.media.playback.mediaplayer/tests/Makefile.in new file mode 100644 index 00000000000..20894397845 --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.media.playback.mediaplayer.dll +IMPORTS = combase + +SOURCES = \ + mediaplayer.c diff --git a/dlls/windows.media.playback.mediaplayer/tests/mediaplayer.c b/dlls/windows.media.playback.mediaplayer/tests/mediaplayer.c new file mode 100644 index 00000000000..6262190e81d --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/tests/mediaplayer.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Media_Playback +#include "windows.media.playback.h" + +#include "wine/test.h" + +#define check_interface( obj, iid, supported ) check_interface_( __LINE__, obj, iid, supported ) +static void check_interface_( unsigned int line, void *obj, const IID *iid, BOOL supported ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_(__FILE__, line)( hr == S_OK || (!supported && hr == E_NOINTERFACE), "got hr %#lx.\n", hr ); + if (SUCCEEDED(hr)) IUnknown_Release( unk ); +} + +static void test_MediaPlayer_Statics(void) +{ + static const WCHAR *media_player_name = L"Windows.Media.Playback.MediaPlayer"; + IActivationFactory *factory = (void *)0xdeadbeef; + IMediaPlayer *media_player = (void *)0xdeadbeef; + IInspectable *inspectable = (void *)0xdeadbeef; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( media_player_name, wcslen( media_player_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + WindowsDeleteString( str ); + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( media_player_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown, TRUE ); + check_interface( factory, &IID_IInspectable, TRUE ); + check_interface( factory, &IID_IAgileObject, FALSE ); + check_interface( factory, &IID_IMediaPlayer, FALSE ); + + hr = RoActivateInstance( str, &inspectable ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + WindowsDeleteString( str ); + + hr = IInspectable_QueryInterface( inspectable, &IID_IMediaPlayer, (void **)&media_player ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + check_interface( media_player, &IID_IAgileObject, TRUE ); + + ref = IMediaPlayer_Release( media_player ); + ok( ref == 1, "got ref %ld.\n", ref ); + ref = IInspectable_Release( inspectable ); + ok( ref == 0, "got ref %ld.\n", ref ); + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(mediaplayer) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_MediaPlayer_Statics(); + + RoUninitialize(); +} diff --git a/dlls/windows.media.playback.mediaplayer/windows.media.playback.mediaplayer.spec b/dlls/windows.media.playback.mediaplayer/windows.media.playback.mediaplayer.spec new file mode 100644 index 00000000000..20a8bfa98ea --- /dev/null +++ b/dlls/windows.media.playback.mediaplayer/windows.media.playback.mediaplayer.spec @@ -0,0 +1,3 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr)
On Thu Sep 4 07:33:21 2025 +0000, Hans Leidekker wrote:
I did some testing with midlrt and it turns out that the 'deprecated' attribute is allowed on enums, enum members, structs and struct fields in addition to what we allow now. This patch should help. [widl.diff](/uploads/c6bf9e5115fd15f6b661fcf75b5b596b/widl.diff)
Thanks, added you as the author of the patch.
- Comment references to undefined member interfaces. - Support attribute deprecated for enum
This merge request was approved by Mohamad Al-Jaf.
This merge request was closed by Mohamad Al-Jaf.