[PATCH 7/7] wmp: Implement minimal headless WMP
Anton Romanov
theli.ua at gmail.com
Tue Jan 30 11:58:01 CST 2018
Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---
dlls/wmp/player.c | 328 +++++++++++++++++++++++++++++++++++++++++++------
dlls/wmp/wmp_private.h | 35 ++++++
2 files changed, 325 insertions(+), 38 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
index 69979be21d..e12fed7d3a 100644
--- a/dlls/wmp/player.c
+++ b/dlls/wmp/player.c
@@ -17,12 +17,14 @@
*/
#include "wmp_private.h"
+#include "wmpids.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
-static void update_state(WindowsMediaPlayer *wmp, int state);
+static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state);
+static void media_change(WindowsMediaPlayer *wmp, LONG type, IDispatch *pItem);
static inline WindowsMediaPlayer *impl_from_IWMPNetwork(IWMPNetwork *iface)
{
@@ -44,6 +46,20 @@ static inline WindowsMediaPlayer *impl_from_IWMPControls(IWMPControls *iface)
return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPControls_iface);
}
+HRESULT WINAPI WMPControls_play(IWMPControls *iface)
+{
+ HRESULT hres;
+ WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
+ TRACE("(%p)\n", This);
+ hres = IMediaControl_Run(This->media_control);
+ if (SUCCEEDED(hres))
+ {
+ update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_PLAYING);
+ media_change(This, DISPID_WMPCOREEVENT_MEDIACHANGE, (IDispatch*)&This->IWMPMedia_iface);
+ }
+ return hres;
+}
+
static HRESULT WINAPI WMPPlayer4_QueryInterface(IWMPPlayer4 *iface, REFIID riid, void **ppv)
{
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
@@ -105,15 +121,49 @@ static HRESULT WINAPI WMPPlayer4_close(IWMPPlayer4 *iface)
static HRESULT WINAPI WMPPlayer4_get_URL(IWMPPlayer4 *iface, BSTR *pbstrURL)
{
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
- FIXME("(%p)->(%p)\n", This, pbstrURL);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p)\n", This, pbstrURL);
+ if (!pbstrURL)
+ return E_POINTER;
+
+ *pbstrURL = This->url;
+
+ return S_OK;
}
static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url)
{
+ HRESULT hres;
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
- FIXME("(%p)->(%s)\n", This, debugstr_w(url));
- return E_NOTIMPL;
+ TRACE("(%p)->(%s)\n", This, debugstr_w(url));
+ if (!url)
+ return E_POINTER;
+ if (This->url) {
+ heap_free(This->url);
+ }
+ This->url = heap_strdupW(url);
+
+ if (!This->url)
+ return E_OUTOFMEMORY;
+
+ update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGING);
+ update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING);
+ media_change(This, DISPID_WMPCOREEVENT_CURRENTITEMCHANGE, (IDispatch*)&This->IWMPMedia_iface);
+ update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGED);
+ update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA);
+ media_change(This, DISPID_WMPCOREEVENT_CURRENTITEMCHANGE, (IDispatch*)&This->IWMPMedia_iface);
+ update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_OPENING_UNKNOWN_URL);
+ update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING);
+ media_change(This, DISPID_WMPCOREEVENT_CURRENTITEMCHANGE, (IDispatch*)&This->IWMPMedia_iface);
+
+ hres = IGraphBuilder_RenderFile(This->pFilterGraph, url, NULL);
+ if (SUCCEEDED(hres)) {
+ update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN);
+ }
+
+ if (SUCCEEDED(hres) && This->autoStart)
+ WMPControls_play((IWMPControls*)This);
+
+ return hres;
}
static HRESULT WINAPI WMPPlayer4_get_openState(IWMPPlayer4 *iface, WMPOpenState *pwmpos)
@@ -504,15 +554,19 @@ static HRESULT WINAPI WMPSettings_get_isAvailable(IWMPSettings *iface, BSTR item
static HRESULT WINAPI WMPSettings_get_autoStart(IWMPSettings *iface, VARIANT_BOOL *p)
{
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p)\n", This, p);
+ if (!p)
+ return E_POINTER;
+ *p = This->autoStart;
+ return S_OK;
}
static HRESULT WINAPI WMPSettings_put_autoStart(IWMPSettings *iface, VARIANT_BOOL v)
{
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
- FIXME("(%p)->(%x)\n", This, v);
- return E_NOTIMPL;
+ TRACE("(%p)->(%x)\n", This, v);
+ This->autoStart = v;
+ return S_OK;
}
static HRESULT WINAPI WMPSettings_get_baseURL(IWMPSettings *iface, BSTR *p)
@@ -546,15 +600,21 @@ static HRESULT WINAPI WMPSettings_put_defaultFrame(IWMPSettings *iface, BSTR v)
static HRESULT WINAPI WMPSettings_get_invokeURLs(IWMPSettings *iface, VARIANT_BOOL *p)
{
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
+ // Leaving as FIXME as we don't currently use this
FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ if (!p)
+ return E_POINTER;
+ *p = This->invokeURLs;
+ return S_OK;
}
static HRESULT WINAPI WMPSettings_put_invokeURLs(IWMPSettings *iface, VARIANT_BOOL v)
{
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
+ // Leaving as FIXME as we don't currently use this
FIXME("(%p)->(%x)\n", This, v);
- return E_NOTIMPL;
+ This->invokeURLs = v;
+ return S_OK;
}
static HRESULT WINAPI WMPSettings_get_mute(IWMPSettings *iface, VARIANT_BOOL *p)
@@ -615,16 +675,26 @@ static HRESULT WINAPI WMPSettings_put_balance(IWMPSettings *iface, LONG v)
static HRESULT WINAPI WMPSettings_get_volume(IWMPSettings *iface, LONG *p)
{
+ HRESULT hres;
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p)\n", This, p);
+ hres = IBasicAudio_get_Volume(This->basic_audio, p);
+ /* IBasicAudio - [-10000, 0], wmp - [0, 100] */
+ if (SUCCEEDED(hres))
+ *p = (*p + 10000) * 100 / 10000;
+ return hres;
}
static HRESULT WINAPI WMPSettings_put_volume(IWMPSettings *iface, LONG v)
{
+ HRESULT hres;
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
- FIXME("(%p)->(%d)\n", This, v);
- return E_NOTIMPL;
+ TRACE("(%p)->(%d)\n", This, v);
+ /* IBasicAudio - [-10000, 0], wmp - [0, 100] */
+ v = 10000 * v / 100 - 10000;
+ hres = IBasicAudio_put_Volume(This->basic_audio, v);
+ TRACE("ret: %d", hres);
+ return hres;
}
static HRESULT WINAPI WMPSettings_getMode(IWMPSettings *iface, BSTR mode, VARIANT_BOOL *p)
@@ -644,15 +714,21 @@ static HRESULT WINAPI WMPSettings_setMode(IWMPSettings *iface, BSTR mode, VARIAN
static HRESULT WINAPI WMPSettings_get_enableErrorDialogs(IWMPSettings *iface, VARIANT_BOOL *p)
{
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
+ // Leaving as FIXME as we don't currently use this
FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+ if (!p)
+ return E_POINTER;
+ *p = This->enableErrorDialogs;
+ return S_OK;
}
static HRESULT WINAPI WMPSettings_put_enableErrorDialogs(IWMPSettings *iface, VARIANT_BOOL v)
{
WindowsMediaPlayer *This = impl_from_IWMPSettings(iface);
+ // Leaving as FIXME as we don't currently use this
FIXME("(%p)->(%x)\n", This, v);
- return E_NOTIMPL;
+ This->enableErrorDialogs = v;
+ return S_OK;
}
static const IWMPSettingsVtbl WMPSettingsVtbl = {
@@ -689,9 +765,124 @@ static const IWMPSettingsVtbl WMPSettingsVtbl = {
};
void destroy_player(WindowsMediaPlayer* wmp) {
+ /* shutdown event thread */
+ if (wmp->event_thread)
+ {
+ SetEvent(wmp->stop_event);
+ WaitForSingleObject(wmp->event_thread, INFINITE);
+ CloseHandle(wmp->event_thread);
+ CloseHandle(wmp->stop_event);
+ }
+
+ if (wmp->media_seeking)
+ IMediaSeeking_Release(wmp->media_seeking);
+ if (wmp->media_event)
+ IBasicAudio_Release(wmp->basic_audio);
+ if (wmp->media_event)
+ IMediaEvent_Release(wmp->media_event);
+ if (wmp->media_control)
+ IMediaControl_Release(wmp->media_control);
+ if (wmp->pFilterGraph)
+ IGraphBuilder_Release(wmp->pFilterGraph);
+ if (wmp->url)
+ heap_free(wmp->url);
heap_free(wmp);
}
+static void status_change(WindowsMediaPlayer *wmp)
+{
+ DISPPARAMS dispparams;
+
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 0;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.rgvarg = NULL;
+
+ call_sink(wmp->wmpocx, DISPID_WMPCOREEVENT_STATUSCHANGE,
+ &dispparams);
+}
+
+static void media_change(WindowsMediaPlayer *wmp, LONG type, IDispatch *pItem)
+{
+ DISPPARAMS dispparams;
+ VARIANTARG params[1];
+
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 0;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.rgvarg = params;
+
+ V_VT(params) = VT_DISPATCH;
+ V_DISPATCH(params) = pItem;
+
+ call_sink(wmp->wmpocx, type,
+ &dispparams);
+ status_change(wmp);
+}
+static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state)
+{
+ DISPPARAMS dispparams;
+ VARIANTARG params[1];
+
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 0;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.rgvarg = params;
+
+ V_VT(params) = VT_UI4;
+ V_UI4(params) = state;
+
+ call_sink(wmp->wmpocx, type,
+ &dispparams);
+ status_change(wmp);
+}
+
+static DWORD CALLBACK WMP_event_thread(LPVOID parm)
+{
+ WindowsMediaPlayer* wmp = (WindowsMediaPlayer *)parm;
+ HRESULT hr;
+ HANDLE handle[2];
+ DWORD n = 0, ret = 0;
+
+ handle[n++] = wmp->stop_event;
+ IMediaEvent_GetEventHandle(wmp->media_event, (OAEVENT *)&handle[n++]);
+ for (;;) {
+ DWORD r;
+
+ r = WaitForMultipleObjects(n, handle, FALSE, INFINITE);
+ if (r == WAIT_OBJECT_0) {
+ TRACE("got stop event\n");
+ break;
+ }
+ else if (r == WAIT_OBJECT_0+1) {
+ LONG event_code;
+ LONG_PTR p1, p2;
+ do {
+ hr = IMediaEvent_GetEvent(wmp->media_event, &event_code, &p1, &p2, 0);
+ if (SUCCEEDED(hr)) {
+ TRACE("got event_code = 0x%02x\n", event_code);
+ /* For now we only handle EC_COMPLETE */
+ if (event_code == EC_COMPLETE) {
+ update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_MEDIA_ENDED);
+ media_change(wmp, DISPID_WMPCOREEVENT_MEDIACHANGE, (IDispatch*)&wmp->IWMPMedia_iface);
+ update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING);
+ update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED);
+ }
+
+ IMediaEvent_FreeEventParams(wmp->media_event, event_code, p1, p2);
+ }
+ } while (hr == S_OK);
+ }
+ else {
+ TRACE("Unknown error (%d)\n", (int)r);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
HRESULT WINAPI WMPControls_fastForward(IWMPControls *iface)
{
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
@@ -723,8 +914,14 @@ HRESULT WINAPI WMPControls_get_currentMarker(IWMPControls *iface, LONG *plMarker
HRESULT WINAPI WMPControls_get_currentPosition(IWMPControls *iface, DOUBLE *pdCurrentPosition)
{
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
- FIXME("(%p)->(%p)\n", This, pdCurrentPosition);
- return E_NOTIMPL;
+ HRESULT hres;
+ LONGLONG currentPosition;
+
+ TRACE("(%p)->(%p)\n", This, pdCurrentPosition);
+ hres = IMediaSeeking_GetCurrentPosition(This->media_seeking, ¤tPosition);
+ *pdCurrentPosition = (DOUBLE) currentPosition / 10000000.0f;
+ TRACE("hres: %d, pos: %f\n", hres, *pdCurrentPosition);
+ return hres;
}
HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *pbstrCurrentPosition)
@@ -736,9 +933,22 @@ HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *
static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstrItem, VARIANT_BOOL *pIsAvailable)
{
+ HRESULT hres = E_NOTIMPL;
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
- FIXME("(%p)->(%s)\n", This, debugstr_w(bstrItem));
- return E_NOTIMPL;
+ static const WCHAR currentPosition[] = {'c','u','r','r','e','n','t','P','o','s','i','t','i','o','n',0};
+ TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrItem), pIsAvailable);
+ if (strcmpW(currentPosition, bstrItem) == 0) {
+ DWORD capabilities;
+ hres = IMediaSeeking_GetCapabilities(This->media_seeking, &capabilities);
+ *pIsAvailable = (capabilities & AM_SEEKING_CanSeekAbsolute) ?
+ VARIANT_TRUE : VARIANT_FALSE;
+ } else {
+ FIXME("%s not implemented\n", debugstr_w(bstrItem));
+ }
+ hres = S_OK;
+ *pIsAvailable = VARIANT_TRUE;
+
+ return hres;
}
HRESULT WINAPI WMPControls_next(IWMPControls *iface)
@@ -755,13 +965,6 @@ HRESULT WINAPI WMPControls_pause(IWMPControls *iface)
return E_NOTIMPL;
}
-HRESULT WINAPI WMPControls_play(IWMPControls *iface)
-{
- WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
-}
-
HRESULT WINAPI WMPControls_playItem(IWMPControls *iface, IWMPMedia *pIWMPMedia)
{
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
@@ -792,16 +995,27 @@ HRESULT WINAPI WMPControls_put_currentMarker(IWMPControls *iface, LONG lMarker)
HRESULT WINAPI WMPControls_put_currentPosition(IWMPControls *iface, DOUBLE dCurrentPosition)
{
+ LONGLONG Current;
+ HRESULT hres;
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
- FIXME("(%p)->(%f)\n", This, dCurrentPosition);
- return E_NOTIMPL;
+ TRACE("(%p)->(%f)\n", This, dCurrentPosition);
+ Current = 10000000 * dCurrentPosition;
+ hres = IMediaSeeking_SetPositions(This->media_seeking, &Current,
+ AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
+
+ return hres;
}
HRESULT WINAPI WMPControls_stop(IWMPControls *iface)
{
+ HRESULT hres;
WindowsMediaPlayer *This = impl_from_IWMPControls(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
+ TRACE("(%p)\n", This);
+ update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING);
+ hres = IMediaControl_Stop(This->media_control);
+ if (SUCCEEDED(hres))
+ update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED);
+ return hres;
}
static HRESULT WINAPI WMPControls_QueryInterface(IWMPControls *iface, REFIID riid, void **ppv)
@@ -946,9 +1160,15 @@ HRESULT WINAPI WMPMedia_getMarkerName(IWMPMedia *iface, LONG MarkerNum, BSTR *pb
HRESULT WINAPI WMPMedia_get_duration(IWMPMedia *iface, DOUBLE *pDuration)
{
+ LONGLONG duration;
+ HRESULT hres;
WindowsMediaPlayer *This = impl_from_IWMPMedia(iface);
- FIXME("(%p)->(%p)\n", This, pDuration);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p)\n", This, pDuration);
+ hres = IMediaSeeking_GetDuration(This->media_seeking, &duration);
+ if (SUCCEEDED(hres))
+ *pDuration = (DOUBLE)duration / 10000000.0f;
+ TRACE("%d, %f, %lld\n", hres, *pDuration, duration);
+ return hres;
}
HRESULT WINAPI WMPMedia_get_durationString(IWMPMedia *iface, BSTR *pbstrDuration)
@@ -1189,8 +1409,9 @@ static HRESULT WINAPI WMPNetwork_get_bufferingCount(IWMPNetwork *iface, LONG *pl
static HRESULT WINAPI WMPNetwork_get_bufferingProgress(IWMPNetwork *iface, LONG *plBufferingProgress)
{
WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface);
- FIXME("(%p)->(%p)\n", This, plBufferingProgress);
- return E_NOTIMPL;
+ FIXME("stub, returning 100 (%p)->(%p)\n", This, plBufferingProgress);
+ *plBufferingProgress = 100;
+ return S_OK;
}
static HRESULT WINAPI WMPNetwork_get_bufferingTime(IWMPNetwork *iface, LONG *plBufferingTime)
@@ -1315,8 +1536,9 @@ static HRESULT WINAPI WMPNetwork_put_maxBandwidth(IWMPNetwork *iface, LONG lMaxB
static HRESULT WINAPI WMPNetwork_get_downloadProgress(IWMPNetwork *iface, LONG *plDownloadProgress)
{
WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface);
- FIXME("(%p)->(%p)\n", This, plDownloadProgress);
- return E_NOTIMPL;
+ FIXME("stub, returning 100 (%p)->(%p)\n", This, plDownloadProgress);
+ *plDownloadProgress = 100;
+ return S_OK;
}
static HRESULT WINAPI WMPNetwork_get_encodedFrameRate(IWMPNetwork *iface, LONG *plFrameRate)
@@ -1373,11 +1595,41 @@ static const IWMPNetworkVtbl WMPNetworkVtbl = {
HRESULT init_player(WindowsMediaPlayer *wmp)
{
+ HRESULT hres;
+
wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl;
wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl;
wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl;
wmp->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl;
wmp->IWMPNetwork_iface.lpVtbl = &WMPNetworkVtbl;
+ wmp->invokeURLs = TRUE;
+ wmp->autoStart = TRUE;
+
+
+ hres = CoCreateInstance(&CLSID_FilterGraph,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ &IID_IGraphBuilder,
+ (void **)&wmp->pFilterGraph);
+ if (SUCCEEDED(hres))
+ hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IMediaControl, (void**)&wmp->media_control);
+ if (SUCCEEDED(hres))
+ hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IMediaEvent, (void**)&wmp->media_event);
+ if (SUCCEEDED(hres))
+ hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IBasicAudio, (void**)&wmp->basic_audio);
+ if (SUCCEEDED(hres))
+ hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IMediaSeeking, (void**)&wmp->media_seeking);
+ if (SUCCEEDED(hres))
+ hres = IMediaSeeking_SetTimeFormat(wmp->media_seeking, &TIME_FORMAT_MEDIA_TIME);
+ if (SUCCEEDED(hres))
+ {
+ wmp->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+ wmp->event_thread = CreateThread(NULL, 0, WMP_event_thread, wmp, 0, NULL);
+ }
+ if (!wmp->event_thread) {
+ TRACE("Can't create thread\n");
+ return E_FAIL;
+ }
return S_OK;
}
diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index 5b79fafa07..6816c5893a 100644
--- a/dlls/wmp/wmp_private.h
+++ b/dlls/wmp/wmp_private.h
@@ -21,6 +21,8 @@
#include "windows.h"
#include "ole2.h"
#include "wmp.h"
+#include "wine/unicode.h"
+#include "dshow.h"
typedef struct {
IConnectionPoint IConnectionPoint_iface;
@@ -54,6 +56,23 @@ struct WindowsMediaPlayer {
SIZEL extent;
ConnectionPoint *wmpocx;
+
+ /* Settings */
+ VARIANT_BOOL autoStart;
+ VARIANT_BOOL invokeURLs;
+ VARIANT_BOOL enableErrorDialogs;
+ BSTR url;
+
+ /* DirectShow stuff */
+ IGraphBuilder* pFilterGraph;
+ IMediaControl* media_control;
+ IMediaEvent* media_event;
+ IBasicAudio * basic_audio;
+ IMediaSeeking * media_seeking;
+
+ /* Async event notification */
+ HANDLE event_thread;
+ HANDLE stop_event;
};
HRESULT init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
@@ -83,3 +102,19 @@ static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
}
+
+static inline WCHAR *heap_strdupW(const WCHAR *str)
+{
+ WCHAR *ret;
+
+ if(str) {
+ size_t size = strlenW(str)+1;
+ ret = heap_alloc(size*sizeof(WCHAR));
+ if(ret)
+ memcpy(ret, str, size*sizeof(WCHAR));
+ }else {
+ ret = NULL;
+ }
+
+ return ret;
+}
--
2.15.1
More information about the wine-devel
mailing list