summaryrefslogtreecommitdiffstats
path: root/src/plugins/wmp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/wmp')
-rw-r--r--src/plugins/wmp/qevrvideooverlay.cpp357
-rw-r--r--src/plugins/wmp/qevrvideooverlay.h119
-rw-r--r--src/plugins/wmp/qmfactivate.cpp296
-rw-r--r--src/plugins/wmp/qmfactivate.h90
-rw-r--r--src/plugins/wmp/qwmpevents.cpp114
-rw-r--r--src/plugins/wmp/qwmpevents.h222
-rw-r--r--src/plugins/wmp/qwmpglobal.cpp68
-rw-r--r--src/plugins/wmp/qwmpglobal.h83
-rw-r--r--src/plugins/wmp/qwmpmetadata.cpp442
-rw-r--r--src/plugins/wmp/qwmpmetadata.h88
-rw-r--r--src/plugins/wmp/qwmpplayercontrol.cpp465
-rw-r--r--src/plugins/wmp/qwmpplayercontrol.h141
-rw-r--r--src/plugins/wmp/qwmpplayerservice.cpp355
-rw-r--r--src/plugins/wmp/qwmpplayerservice.h125
-rw-r--r--src/plugins/wmp/qwmpplaylist.cpp296
-rw-r--r--src/plugins/wmp/qwmpplaylist.h94
-rw-r--r--src/plugins/wmp/qwmpplaylistcontrol.cpp153
-rw-r--r--src/plugins/wmp/qwmpplaylistcontrol.h85
-rw-r--r--src/plugins/wmp/qwmpserviceprovider.cpp74
-rw-r--r--src/plugins/wmp/qwmpserviceprovider.h58
-rw-r--r--src/plugins/wmp/qwmpvideooverlay.cpp462
-rw-r--r--src/plugins/wmp/qwmpvideooverlay.h145
-rw-r--r--src/plugins/wmp/wmp.pro47
23 files changed, 4379 insertions, 0 deletions
diff --git a/src/plugins/wmp/qevrvideooverlay.cpp b/src/plugins/wmp/qevrvideooverlay.cpp
new file mode 100644
index 000000000..ff301d109
--- /dev/null
+++ b/src/plugins/wmp/qevrvideooverlay.cpp
@@ -0,0 +1,357 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qevrvideooverlay.h"
+
+#include <d3d9.h>
+#include <wmp.h>
+
+QEvrVideoOverlay::QEvrVideoOverlay(HINSTANCE evrHwnd)
+ : m_ref(1)
+ , m_evrHwnd(evrHwnd)
+ , ptrMFCreateVideoPresenter(0)
+ , m_presenter(0)
+ , m_displayControl(0)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+ , m_winId(0)
+ , m_fullScreen(0)
+{
+ ptrMFCreateVideoPresenter = reinterpret_cast<PtrMFCreateVideoPresenter>(
+ GetProcAddress(m_evrHwnd, "MFCreateVideoPresenter"));
+}
+
+QEvrVideoOverlay::~QEvrVideoOverlay()
+{
+ FreeLibrary(m_evrHwnd);
+}
+
+WId QEvrVideoOverlay::winId() const
+{
+ return m_winId;
+}
+
+void QEvrVideoOverlay::setWinId(WId id)
+{
+ m_winId = id;
+
+ if (QWidget *widget = QWidget::find(m_winId)) {
+ const QColor color = widget->palette().color(QPalette::Window);
+
+ m_windowColor = RGB(color.red(), color.green(), color.blue());
+ }
+
+ if (m_displayControl) {
+ m_displayControl->SetVideoWindow(id);
+ m_displayControl->SetAspectRatioMode(m_aspectRatioMode == Qt::KeepAspectRatio
+ ? MFVideoARMode_PreservePicture
+ : MFVideoARMode_None);
+ m_displayControl->SetBorderColor(m_windowColor);
+
+ setDisplayRect(m_displayRect);
+ }
+}
+
+QRect QEvrVideoOverlay::displayRect() const
+{
+ return m_displayRect;
+}
+
+void QEvrVideoOverlay::setDisplayRect(const QRect &rect)
+{
+ if (m_displayControl) {
+ RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 };
+
+ if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
+ SIZE size;
+ m_displayControl->GetNativeVideoSize(&size, 0);
+
+ QSize clippedSize = rect.size();
+ clippedSize.scale(size.cx, size.cy, Qt::KeepAspectRatio);
+
+ long x = (size.cx - clippedSize.width()) / 2;
+ long y = (size.cy - clippedSize.height()) / 2;
+
+ MFVideoNormalizedRect sourceRect =
+ {
+ float(x) / size.cx,
+ float(y) / size.cy,
+ float(x + clippedSize.width()) / size.cx,
+ float(y + clippedSize.height()) / size.cy
+ };
+ m_displayControl->SetVideoPosition(&sourceRect, &displayRect);
+ } else {
+ m_displayControl->SetVideoPosition(0, &displayRect);
+ }
+ }
+
+ m_displayRect = rect;
+}
+
+bool QEvrVideoOverlay::isFullScreen() const
+{
+ return m_fullScreen;
+}
+
+void QEvrVideoOverlay::setFullScreen(bool fullScreen)
+{
+ emit fullScreenChanged(m_fullScreen = fullScreen);
+}
+
+QSize QEvrVideoOverlay::nativeSize() const
+{
+ SIZE size;
+
+ if (m_displayControl && m_displayControl->GetNativeVideoSize(&size, 0) == S_OK) {
+ return QSize(size.cx, size.cy);
+ } else {
+ return QSize();
+ }
+}
+
+Qt::AspectRatioMode QEvrVideoOverlay::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void QEvrVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+
+ if (m_displayControl) {
+ m_displayControl->SetAspectRatioMode(mode == Qt::KeepAspectRatio
+ ? MFVideoARMode_PreservePicture
+ : MFVideoARMode_None);
+ setDisplayRect(m_displayRect);
+ }
+}
+
+void QEvrVideoOverlay::repaint()
+{
+ PAINTSTRUCT paint;
+
+ if (HDC dc = ::BeginPaint(m_winId, &paint)) {
+ if (m_displayControl) {
+ m_displayControl->RepaintVideo();
+ } else {
+ HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor);
+ HBRUSH brush = ::CreateSolidBrush(m_windowColor);
+ ::SelectObject(dc, pen);
+ ::SelectObject(dc, brush);
+
+ ::Rectangle(
+ dc,
+ paint.rcPaint.left,
+ paint.rcPaint.top,
+ paint.rcPaint.right,
+ paint.rcPaint.bottom);
+
+ ::DeleteObject(pen);
+ ::DeleteObject(brush);
+ }
+
+ ::EndPaint(m_winId, &paint);
+ }
+}
+
+int QEvrVideoOverlay::brightness() const
+{
+ return 0;
+}
+
+void QEvrVideoOverlay::setBrightness(int)
+{
+}
+
+int QEvrVideoOverlay::contrast() const
+{
+ return 0;
+}
+
+void QEvrVideoOverlay::setContrast(int)
+{
+}
+
+int QEvrVideoOverlay::hue() const
+{
+ return 0;
+}
+
+void QEvrVideoOverlay::setHue(int)
+{
+}
+
+int QEvrVideoOverlay::saturation() const
+{
+ return 0;
+}
+
+void QEvrVideoOverlay::setSaturation(int)
+{
+}
+
+void QEvrVideoOverlay::setDisplayControl(IMFVideoDisplayControl *control)
+{
+ if (m_displayControl)
+ m_displayControl->Release();
+
+ m_displayControl = control;
+
+ if (m_displayControl) {
+ m_displayControl->AddRef();
+ m_displayControl->SetVideoWindow(m_winId);
+ m_displayControl->SetAspectRatioMode(m_aspectRatioMode == Qt::KeepAspectRatio
+ ? MFVideoARMode_PreservePicture
+ : MFVideoARMode_None);
+ m_displayControl->SetBorderColor(m_windowColor);
+
+ setDisplayRect(m_displayRect);
+ }
+}
+
+void QEvrVideoOverlay::openStateChanged(long state)
+{
+ if (state == wmposMediaOpen) {
+ setDisplayRect(m_displayRect);
+
+ emit nativeSizeChanged();
+ }
+};
+
+// IUnknown
+HRESULT QEvrVideoOverlay::QueryInterface(REFIID riid, void **object)
+{
+ if (!object) {
+ return E_POINTER;
+ } else if (riid == __uuidof(IUnknown)
+ || riid == __uuidof(IMFAttributes)
+ || riid == __uuidof(IMFActivate)) {
+ *object = static_cast<IMFActivate *>(this);
+ } else {
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+
+ return S_OK;
+}
+
+ULONG QEvrVideoOverlay::AddRef()
+{
+ return InterlockedIncrement(&m_ref);
+}
+
+ULONG QEvrVideoOverlay::Release()
+{
+ ULONG ref = InterlockedDecrement(&m_ref);
+
+ Q_ASSERT(ref != 0);
+
+ return ref;
+}
+
+// IMFActivate
+HRESULT QEvrVideoOverlay::ActivateObject(REFIID riid, void **ppv)
+{
+ if (riid != __uuidof(IMFVideoPresenter)) {
+ return E_NOINTERFACE;
+ } else if (!ptrMFCreateVideoPresenter) {
+ return E_NOINTERFACE;
+ } else if (m_presenter) {
+ *ppv = m_presenter;
+
+ return S_OK;
+ } else {
+ IMFVideoDisplayControl *displayControl = 0;
+
+ IMFGetService *service;
+ HRESULT hr;
+ if ((hr = (*ptrMFCreateVideoPresenter)(
+ 0,
+ __uuidof(IDirect3DDevice9),
+ __uuidof(IMFVideoPresenter),
+ reinterpret_cast<void **>(&m_presenter))) != S_OK) {
+ qWarning("failed to create video presenter");
+ } else if ((hr = m_presenter->QueryInterface(
+ __uuidof(IMFGetService), reinterpret_cast<void **>(&service))) != S_OK) {
+ qWarning("failed to query IMFGetService interface");
+ } else {
+ if ((hr = service->GetService(
+ MR_VIDEO_RENDER_SERVICE,
+ __uuidof(IMFVideoDisplayControl),
+ reinterpret_cast<void **>(&displayControl))) != S_OK) {
+ qWarning("failed to get IMFVideoDisplayControl service");
+ }
+ service->Release();
+ }
+
+ setDisplayControl(displayControl);
+
+ if (m_presenter && hr != S_OK) {
+ m_presenter->Release();
+ m_presenter = 0;
+ }
+
+ *ppv = m_presenter;
+
+ return hr;
+ }
+}
+
+HRESULT QEvrVideoOverlay::ShutdownObject()
+{
+ setDisplayControl(0);
+
+ if (m_presenter) {
+ m_presenter->Release();
+ m_presenter = 0;
+ }
+ return S_OK;
+}
+
+HRESULT QEvrVideoOverlay::DetachObject()
+{
+ if (m_presenter) {
+ m_presenter->Release();
+ m_presenter = 0;
+ }
+
+ return S_OK;
+}
diff --git a/src/plugins/wmp/qevrvideooverlay.h b/src/plugins/wmp/qevrvideooverlay.h
new file mode 100644
index 000000000..247b16e96
--- /dev/null
+++ b/src/plugins/wmp/qevrvideooverlay.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVRVIDEOOVERLAY_H
+#define QEVRVIDEOOVERLAY_H
+
+#include <qvideowindowcontrol.h>
+
+#include "qmfactivate.h"
+
+#include <evr.h>
+
+QT_USE_NAMESPACE
+
+class QEvrVideoOverlay : public QVideoWindowControl, public QMFActivate
+{
+ Q_OBJECT
+public:
+ QEvrVideoOverlay(HINSTANCE evrHwnd);
+ ~QEvrVideoOverlay();
+
+ WId winId() const;
+ void setWinId(WId id);
+
+ QRect displayRect() const;
+ void setDisplayRect(const QRect &rect);
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ QSize nativeSize() const;
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ void repaint();
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ void setDisplayControl(IMFVideoDisplayControl *control);
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ // IMFActivate
+ HRESULT STDMETHODCALLTYPE ActivateObject(REFIID riid, void **ppv);
+ HRESULT STDMETHODCALLTYPE ShutdownObject();
+ HRESULT STDMETHODCALLTYPE DetachObject();
+
+public Q_SLOTS:
+ void openStateChanged(long state);
+
+private:
+ typedef HRESULT (WINAPI *PtrMFCreateVideoPresenter)(IUnknown*, REFIID, REFIID, void**);
+
+ volatile LONG m_ref;
+ HINSTANCE m_evrHwnd;
+ PtrMFCreateVideoPresenter ptrMFCreateVideoPresenter;
+ IMFVideoPresenter *m_presenter;
+ IMFVideoDisplayControl *m_displayControl;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QSize m_sizeHint;
+ QRect m_displayRect;
+ WId m_winId;
+ COLORREF m_windowColor;
+ bool m_fullScreen;
+};
+
+#endif
diff --git a/src/plugins/wmp/qmfactivate.cpp b/src/plugins/wmp/qmfactivate.cpp
new file mode 100644
index 000000000..8cd64b0e4
--- /dev/null
+++ b/src/plugins/wmp/qmfactivate.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmfactivate.h"
+
+#include <QtCore/qglobal.h>
+
+#include <Mferror.h>
+
+
+// IMFAttributes
+
+HRESULT QMFActivate::GetItem(REFGUID guidKey, PROPVARIANT *pValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pValue);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE *pType)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pType);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL *pbResult)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(Value);
+ Q_UNUSED(pbResult);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::Compare(IMFAttributes *pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, BOOL *pbResult)
+{
+ Q_UNUSED(pTheirs);
+ Q_UNUSED(MatchType);
+ Q_UNUSED(pbResult);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::GetUINT32(REFGUID guidKey, UINT32 *punValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(punValue);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetUINT64(REFGUID guidKey, UINT64 *punValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(punValue);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetDouble(REFGUID guidKey, double *pfValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pfValue);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetGUID(REFGUID guidKey, GUID *pguidValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pguidValue);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetStringLength(REFGUID guidKey, UINT32 *pcchLength)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pcchLength);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32 *pcchLength)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pwszValue);
+ Q_UNUSED(cchBufSize);
+ Q_UNUSED(pcchLength);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetAllocatedString(REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(ppwszValue);
+ Q_UNUSED(pcchLength);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetBlobSize(REFGUID guidKey, UINT32 *pcbBlobSize)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pcbBlobSize);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetBlob(REFGUID guidKey, UINT8 *pBuf, UINT32 cbBufSize, UINT32 *pcbBlobSize)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pBuf);
+ Q_UNUSED(cbBufSize);
+ Q_UNUSED(pcbBlobSize);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetAllocatedBlob(REFGUID guidKey, UINT8 **ppBuf, UINT32 *pcbSize)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(ppBuf);
+ Q_UNUSED(pcbSize);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::GetUnknown(REFGUID guidKey, REFIID riid, LPVOID *ppv)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(riid);
+ Q_UNUSED(ppv);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::SetItem(REFGUID guidKey, REFPROPVARIANT Value)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(Value);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::DeleteItem(REFGUID guidKey)
+{
+ Q_UNUSED(guidKey);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::DeleteAllItems()
+{
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetUINT32(REFGUID guidKey, UINT32 unValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(unValue);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetUINT64(REFGUID guidKey, UINT64 unValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(unValue);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetDouble(REFGUID guidKey, double fValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(fValue);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetGUID(REFGUID guidKey, REFGUID guidValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(guidValue);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetString(REFGUID guidKey, LPCWSTR wszValue)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(wszValue);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetBlob(REFGUID guidKey, const UINT8 *pBuf, UINT32 cbBufSize)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pBuf);
+ Q_UNUSED(cbBufSize);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::SetUnknown(REFGUID guidKey, IUnknown *pUnknown)
+{
+ Q_UNUSED(guidKey);
+ Q_UNUSED(pUnknown);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QMFActivate::LockStore()
+{
+ m_mutex.lock();
+
+ return S_OK;
+}
+
+HRESULT QMFActivate::UnlockStore()
+{
+ m_mutex.unlock();
+
+ return S_OK;
+}
+
+HRESULT QMFActivate::GetCount(UINT32 *pcItems)
+{
+ if (!pcItems) {
+ return E_POINTER;
+ } else {
+ *pcItems = 0;
+
+ return S_OK;
+ }
+}
+
+HRESULT QMFActivate::GetItemByIndex(UINT32 unIndex, GUID *pguidKey, PROPVARIANT *pValue)
+{
+ Q_UNUSED(unIndex);
+ Q_UNUSED(pguidKey);
+ Q_UNUSED(pValue);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
+
+HRESULT QMFActivate::CopyAllItems(IMFAttributes *pDest)
+{
+ Q_UNUSED(pDest);
+
+ return MF_E_ATTRIBUTENOTFOUND;
+}
diff --git a/src/plugins/wmp/qmfactivate.h b/src/plugins/wmp/qmfactivate.h
new file mode 100644
index 000000000..0e1692689
--- /dev/null
+++ b/src/plugins/wmp/qmfactivate.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMFACTIVATE_H
+#define QMFACTIVATE_H
+
+#include <QtCore/qmutex.h>
+
+#include <evr.h>
+
+class QMFActivate : public IMFActivate
+{
+public:
+ // IMFAttributes
+ HRESULT STDMETHODCALLTYPE GetItem(REFGUID guidKey, PROPVARIANT *pValue);
+ HRESULT STDMETHODCALLTYPE GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE *pType);
+ HRESULT STDMETHODCALLTYPE CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL *pbResult);
+ HRESULT STDMETHODCALLTYPE Compare(IMFAttributes *pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, BOOL *pbResult);
+ HRESULT STDMETHODCALLTYPE GetUINT32(REFGUID guidKey, UINT32 *punValue);
+ HRESULT STDMETHODCALLTYPE GetUINT64(REFGUID guidKey, UINT64 *punValue);
+ HRESULT STDMETHODCALLTYPE GetDouble(REFGUID guidKey, double *pfValue);
+ HRESULT STDMETHODCALLTYPE GetGUID(REFGUID guidKey, GUID *pguidValue);
+ HRESULT STDMETHODCALLTYPE GetStringLength(REFGUID guidKey, UINT32 *pcchLength);
+ HRESULT STDMETHODCALLTYPE GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32 *pcchLength);
+ HRESULT STDMETHODCALLTYPE GetAllocatedString(REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength);
+ HRESULT STDMETHODCALLTYPE GetBlobSize(REFGUID guidKey, UINT32 *pcbBlobSize);
+ HRESULT STDMETHODCALLTYPE GetBlob(REFGUID guidKey, UINT8 *pBuf, UINT32 cbBufSize, UINT32 *pcbBlobSize);
+ HRESULT STDMETHODCALLTYPE GetAllocatedBlob(REFGUID guidKey, UINT8 **ppBuf, UINT32 *pcbSize);
+ HRESULT STDMETHODCALLTYPE GetUnknown(REFGUID guidKey, REFIID riid, LPVOID *ppv);
+ HRESULT STDMETHODCALLTYPE SetItem(REFGUID guidKey, REFPROPVARIANT Value);
+ HRESULT STDMETHODCALLTYPE DeleteItem(REFGUID guidKey);
+ HRESULT STDMETHODCALLTYPE DeleteAllItems();
+ HRESULT STDMETHODCALLTYPE SetUINT32(REFGUID guidKey, UINT32 unValue);
+ HRESULT STDMETHODCALLTYPE SetUINT64(REFGUID guidKey, UINT64 unValue);
+ HRESULT STDMETHODCALLTYPE SetDouble(REFGUID guidKey, double fValue);
+ HRESULT STDMETHODCALLTYPE SetGUID(REFGUID guidKey, REFGUID guidValue);
+ HRESULT STDMETHODCALLTYPE SetString(REFGUID guidKey, LPCWSTR wszValue);
+ HRESULT STDMETHODCALLTYPE SetBlob(REFGUID guidKey, const UINT8 *pBuf, UINT32 cbBufSize);
+ HRESULT STDMETHODCALLTYPE SetUnknown(REFGUID guidKey, IUnknown *pUnknown);
+ HRESULT STDMETHODCALLTYPE LockStore();
+ HRESULT STDMETHODCALLTYPE UnlockStore();
+ HRESULT STDMETHODCALLTYPE GetCount(UINT32 *pcItems);
+ HRESULT STDMETHODCALLTYPE GetItemByIndex(UINT32 unIndex, GUID *pguidKey, PROPVARIANT *pValue);
+ HRESULT STDMETHODCALLTYPE CopyAllItems(IMFAttributes *pDest);
+
+private:
+ volatile LONG m_ref;
+ QMutex m_mutex;
+};
+
+
+#endif
diff --git a/src/plugins/wmp/qwmpevents.cpp b/src/plugins/wmp/qwmpevents.cpp
new file mode 100644
index 000000000..66df07b4a
--- /dev/null
+++ b/src/plugins/wmp/qwmpevents.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpevents.h"
+
+#include "qwmpglobal.h"
+
+QWmpEvents::QWmpEvents(IUnknown *source, QObject *parent)
+ : QObject(parent)
+ , m_ref(1)
+ , m_connectionPoint(0)
+ , m_adviseCookie(0)
+{
+ HRESULT hr;
+ IConnectionPointContainer *container = 0;
+
+ if ((hr = source->QueryInterface(
+ IID_IConnectionPointContainer, reinterpret_cast<void **>(&container))) != S_OK) {
+ qWarning("No connection point container, %x: %d", hr, qwmp_error_string(hr));
+ } else {
+ if ((hr = container->FindConnectionPoint(
+ __uuidof(IWMPEvents), &m_connectionPoint)) != S_OK) {
+ qWarning("No connection point for IWMPEvents %d", hr);
+ } else if ((hr = m_connectionPoint->Advise(
+ static_cast<IWMPEvents3 *>(this), &m_adviseCookie)) != S_OK) {
+ qWarning("Failed to link to connection point, %x, %s", hr, qwmp_error_string(hr));
+
+ m_connectionPoint->Release();
+ m_connectionPoint = 0;
+ }
+ container->Release();
+ }
+}
+
+QWmpEvents::~QWmpEvents()
+{
+ if (m_connectionPoint) {
+ m_connectionPoint->Unadvise(m_adviseCookie);
+ m_connectionPoint->Release();
+ }
+
+ Q_ASSERT(m_ref == 1);
+}
+
+// IUnknown
+HRESULT QWmpEvents::QueryInterface(REFIID riid, void **object)
+{
+ if (!object) {
+ return E_POINTER;
+ } else if (riid == __uuidof(IUnknown)
+ || riid == __uuidof(IWMPEvents)
+ || riid == __uuidof(IWMPEvents2)
+ || riid == __uuidof(IWMPEvents3)) {
+ *object = static_cast<IWMPEvents3 *>(this);
+
+ AddRef();
+
+ return S_OK;
+ } else {
+ return E_NOINTERFACE;
+ }
+}
+
+ULONG QWmpEvents::AddRef()
+{
+ return InterlockedIncrement(&m_ref);
+}
+
+ULONG QWmpEvents::Release()
+{
+ ULONG ref = InterlockedDecrement(&m_ref);
+
+ Q_ASSERT(ref != 0);
+
+ return ref;
+}
diff --git a/src/plugins/wmp/qwmpevents.h b/src/plugins/wmp/qwmpevents.h
new file mode 100644
index 000000000..1fb40309d
--- /dev/null
+++ b/src/plugins/wmp/qwmpevents.h
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPEVENTS_H
+#define QWMPEVENTS_H
+
+#include <QtCore/qobject.h>
+
+#include <wmp.h>
+
+class QWmpEvents : public QObject, public IWMPEvents3
+{
+ Q_OBJECT
+public:
+ QWmpEvents(IUnknown *source, QObject *parent = 0);
+ ~QWmpEvents();
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+Q_SIGNALS:
+
+#ifndef Q_MOC_RUN
+ // IWMPEvents
+ void STDMETHODCALLTYPE OpenStateChange(long NewState);
+ void STDMETHODCALLTYPE PlayStateChange(long NewState);
+ void STDMETHODCALLTYPE AudioLanguageChange(long LangID);
+ void STDMETHODCALLTYPE StatusChange();
+ void STDMETHODCALLTYPE ScriptCommand(BSTR scType, BSTR Param);
+ void STDMETHODCALLTYPE NewStream();
+ void STDMETHODCALLTYPE Disconnect(long Result);
+ void STDMETHODCALLTYPE Buffering(VARIANT_BOOL Start);
+ void STDMETHODCALLTYPE Error();
+ void STDMETHODCALLTYPE Warning(long WarningType, long Param, BSTR Description);
+ void STDMETHODCALLTYPE EndOfStream(long Result);
+ void STDMETHODCALLTYPE PositionChange(double oldPosition, double newPosition);
+ void STDMETHODCALLTYPE MarkerHit(long MarkerNum);
+ void STDMETHODCALLTYPE DurationUnitChange(long NewDurationUnit);
+ void STDMETHODCALLTYPE CdromMediaChange(long CdromNum);
+ void STDMETHODCALLTYPE PlaylistChange(IDispatch *Playlist, WMPPlaylistChangeEventType change);
+ void STDMETHODCALLTYPE CurrentPlaylistChange(WMPPlaylistChangeEventType change);
+ void STDMETHODCALLTYPE CurrentPlaylistItemAvailable(BSTR bstrItemName);
+ void STDMETHODCALLTYPE MediaChange(IDispatch *Item);
+ void STDMETHODCALLTYPE CurrentMediaItemAvailable(BSTR bstrItemName);
+ void STDMETHODCALLTYPE CurrentItemChange(IDispatch *pdispMedia);
+ void STDMETHODCALLTYPE MediaCollectionChange();
+ void STDMETHODCALLTYPE MediaCollectionAttributeStringAdded(
+ BSTR bstrAttribName, BSTR bstrAttribVal);
+ void STDMETHODCALLTYPE MediaCollectionAttributeStringRemoved(
+ BSTR bstrAttribName, BSTR bstrAttribVal);
+ void STDMETHODCALLTYPE MediaCollectionAttributeStringChanged(
+ BSTR bstrAttribName, BSTR bstrOldAttribVal, BSTR bstrNewAttribVal);
+ void STDMETHODCALLTYPE PlaylistCollectionChange();
+ void STDMETHODCALLTYPE PlaylistCollectionPlaylistAdded(BSTR bstrPlaylistName);
+ void STDMETHODCALLTYPE PlaylistCollectionPlaylistRemoved(BSTR bstrPlaylistName);
+ void STDMETHODCALLTYPE PlaylistCollectionPlaylistSetAsDeleted(
+ BSTR bstrPlaylistName, VARIANT_BOOL varfIsDeleted);
+ void STDMETHODCALLTYPE ModeChange(BSTR ModeName, VARIANT_BOOL NewValue);
+ void STDMETHODCALLTYPE MediaError(IDispatch *pMediaObject);
+ void STDMETHODCALLTYPE OpenPlaylistSwitch(IDispatch *pItem);
+ void STDMETHODCALLTYPE DomainChange(BSTR strDomain);
+ void STDMETHODCALLTYPE SwitchedToPlayerApplication();
+ void STDMETHODCALLTYPE SwitchedToControl();
+ void STDMETHODCALLTYPE PlayerDockedStateChange();
+ void STDMETHODCALLTYPE PlayerReconnect();
+ void STDMETHODCALLTYPE Click(short nButton, short nShiftState, long fX, long fY);
+ void STDMETHODCALLTYPE DoubleClick(short nButton, short nShiftState, long fX, long fY);
+ void STDMETHODCALLTYPE KeyDown(short nKeyCode, short nShiftState);
+ void STDMETHODCALLTYPE KeyPress(short nKeyAscii);
+ void STDMETHODCALLTYPE KeyUp(short nKeyCode, short nShiftState);
+ void STDMETHODCALLTYPE MouseDown(short nButton, short nShiftState, long fX, long fY);
+ void STDMETHODCALLTYPE MouseMove(short nButton, short nShiftState, long fX, long fY);
+ void STDMETHODCALLTYPE MouseUp(short nButton, short nShiftState, long fX, long fY);
+
+ // IWMPEvents2
+ void STDMETHODCALLTYPE DeviceConnect(IWMPSyncDevice *pDevice);
+ void STDMETHODCALLTYPE DeviceDisconnect(IWMPSyncDevice *pDevice);
+ void STDMETHODCALLTYPE DeviceStatusChange(IWMPSyncDevice *pDevice, WMPDeviceStatus NewStatus);
+ void STDMETHODCALLTYPE DeviceSyncStateChange(IWMPSyncDevice *pDevice, WMPSyncState NewState);
+ void STDMETHODCALLTYPE DeviceSyncError(IWMPSyncDevice *pDevice, IDispatch *pMedia);
+ void STDMETHODCALLTYPE CreatePartnershipComplete(IWMPSyncDevice *pDevice, HRESULT hrResult);
+
+ // IWMPEvents3
+ void STDMETHODCALLTYPE CdromRipStateChange(IWMPCdromRip *pCdromRip, WMPRipState wmprs);
+ void STDMETHODCALLTYPE CdromRipMediaError(IWMPCdromRip *pCdromRip, IDispatch *pMedia);
+ void STDMETHODCALLTYPE CdromBurnStateChange(IWMPCdromBurn *pCdromBurn, WMPBurnState wmpbs);
+ void STDMETHODCALLTYPE CdromBurnMediaError(IWMPCdromBurn *pCdromBurn, IDispatch *pMedia);
+ void STDMETHODCALLTYPE CdromBurnError(IWMPCdromBurn *pCdromBurn, HRESULT hrError);
+ void STDMETHODCALLTYPE LibraryConnect(IWMPLibrary *pLibrary);
+ void STDMETHODCALLTYPE LibraryDisconnect(IWMPLibrary *pLibrary);
+ void STDMETHODCALLTYPE FolderScanStateChange(WMPFolderScanState wmpfss);
+ void STDMETHODCALLTYPE StringCollectionChange(
+ IDispatch *pdispStringCollection,
+ WMPStringCollectionChangeEventType change,
+ long lCollectionIndex);
+ void STDMETHODCALLTYPE MediaCollectionMediaAdded(IDispatch *pdispMedia);
+ void STDMETHODCALLTYPE MediaCollectionMediaRemoved(IDispatch *pdispMedia);
+#else
+ // Declare again without STDMETHODCALLTYPE for moc's benefit.
+
+ // IWMPEvents
+ void OpenStateChange(long NewState);
+ void PlayStateChange(long NewState);
+ void AudioLanguageChange(long LangID);
+ void StatusChange();
+ void ScriptCommand(BSTR scType, BSTR Param);
+ void NewStream();
+ void Disconnect(long Result);
+ void Buffering(VARIANT_BOOL Start);
+ void Error();
+ void Warning(long WarningType, long Param, BSTR Description);
+ void EndOfStream(long Result);
+ void PositionChange(double oldPosition, double newPosition);
+ void MarkerHit(long MarkerNum);
+ void DurationUnitChange(long NewDurationUnit);
+ void CdromMediaChange(long CdromNum);
+ void PlaylistChange(IDispatch *Playlist, WMPPlaylistChangeEventType change);
+ void CurrentPlaylistChange(WMPPlaylistChangeEventType change);
+ void CurrentPlaylistItemAvailable(BSTR bstrItemName);
+ void MediaChange(IDispatch *Item);
+ void CurrentMediaItemAvailable(BSTR bstrItemName);
+ void CurrentItemChange(IDispatch *pdispMedia);
+ void MediaCollectionChange();
+ void MediaCollectionAttributeStringAdded(
+ BSTR bstrAttribName, BSTR bstrAttribVal);
+ void MediaCollectionAttributeStringRemoved(
+ BSTR bstrAttribName, BSTR bstrAttribVal);
+ void MediaCollectionAttributeStringChanged(
+ BSTR bstrAttribName, BSTR bstrOldAttribVal, BSTR bstrNewAttribVal);
+ void PlaylistCollectionChange();
+ void PlaylistCollectionPlaylistAdded(BSTR bstrPlaylistName);
+ void PlaylistCollectionPlaylistRemoved(BSTR bstrPlaylistName);
+ void PlaylistCollectionPlaylistSetAsDeleted(
+ BSTR bstrPlaylistName, VARIANT_BOOL varfIsDeleted);
+ void ModeChange(BSTR ModeName, VARIANT_BOOL NewValue);
+ void MediaError(IDispatch *pMediaObject);
+ void OpenPlaylistSwitch(IDispatch *pItem);
+ void DomainChange(BSTR strDomain);
+ void SwitchedToPlayerApplication();
+ void SwitchedToControl();
+ void PlayerDockedStateChange();
+ void PlayerReconnect();
+ void Click(short nButton, short nShiftState, long fX, long fY);
+ void DoubleClick(short nButton, short nShiftState, long fX, long fY);
+ void KeyDown(short nKeyCode, short nShiftState);
+ void KeyPress(short nKeyAscii);
+ void KeyUp(short nKeyCode, short nShiftState);
+ void MouseDown(short nButton, short nShiftState, long fX, long fY);
+ void MouseMove(short nButton, short nShiftState, long fX, long fY);
+ void MouseUp(short nButton, short nShiftState, long fX, long fY);
+
+ // IWMPEvents2
+ void DeviceConnect(IWMPSyncDevice *pDevice);
+ void DeviceDisconnect(IWMPSyncDevice *pDevice);
+ void DeviceStatusChange(IWMPSyncDevice *pDevice, WMPDeviceStatus NewStatus);
+ void DeviceSyncStateChange(IWMPSyncDevice *pDevice, WMPSyncState NewState);
+ void DeviceSyncError(IWMPSyncDevice *pDevice, IDispatch *pMedia);
+ void CreatePartnershipComplete(IWMPSyncDevice *pDevice, HRESULT hrResult);
+
+ // IWMPEvents3
+ void CdromRipStateChange(IWMPCdromRip *pCdromRip, WMPRipState wmprs);
+ void CdromRipMediaError(IWMPCdromRip *pCdromRip, IDispatch *pMedia);
+ void CdromBurnStateChange(IWMPCdromBurn *pCdromBurn, WMPBurnState wmpbs);
+ void CdromBurnMediaError(IWMPCdromBurn *pCdromBurn, IDispatch *pMedia);
+ void CdromBurnError(IWMPCdromBurn *pCdromBurn, HRESULT hrError);
+ void LibraryConnect(IWMPLibrary *pLibrary);
+ void LibraryDisconnect(IWMPLibrary *pLibrary);
+ void FolderScanStateChange(WMPFolderScanState wmpfss);
+ void StringCollectionChange(
+ IDispatch *pdispStringCollection,
+ WMPStringCollectionChangeEventType change,
+ long lCollectionIndex);
+ void MediaCollectionMediaAdded(IDispatch *pdispMedia);
+ void MediaCollectionMediaRemoved(IDispatch *pdispMedia);
+#endif
+private:
+ volatile LONG m_ref;
+ IConnectionPoint *m_connectionPoint;
+ DWORD m_adviseCookie;
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpglobal.cpp b/src/plugins/wmp/qwmpglobal.cpp
new file mode 100644
index 000000000..4196bbc4f
--- /dev/null
+++ b/src/plugins/wmp/qwmpglobal.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpglobal.h"
+
+#include <QtCore/qdebug.h>
+
+const char *qwmp_error_string(HRESULT hr)
+{
+ switch (hr) {
+ case S_OK:
+ return "OK";
+ case E_NOINTERFACE:
+ return "No such interface supported";
+ case E_POINTER:
+ return "Invalid pointer";
+ case E_FAIL:
+ return "Unspecified error";
+ case E_NOTIMPL:
+ return "Not implemented";
+ case CLASS_E_NOAGGREGATION:
+ return "Class does not support aggregation (or class object is remote)";
+ case CLASS_E_CLASSNOTAVAILABLE:
+ return "ClassFactory cannot supply requested class";
+ case CLASS_E_NOTLICENSED:
+ return "Class is not licensed for use";
+ default:
+ return "unknown error code";
+ }
+}
diff --git a/src/plugins/wmp/qwmpglobal.h b/src/plugins/wmp/qwmpglobal.h
new file mode 100644
index 000000000..f8152903f
--- /dev/null
+++ b/src/plugins/wmp/qwmpglobal.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPGLOBAL_H
+#define QWMPGLOBAL_H
+
+#include <wmp.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qurl.h>
+
+const char *qwmp_error_string(HRESULT hr);
+
+class QAutoBStr
+{
+public:
+ inline QAutoBStr(const QString &string)
+ : m_string(::SysAllocString(static_cast<const wchar_t *>(string.utf16())))
+ {
+ }
+
+ inline QAutoBStr(const QUrl &url)
+ : m_string(::SysAllocString(static_cast<const wchar_t *>(url.toString().utf16())))
+ {
+ }
+
+ inline QAutoBStr(const wchar_t *string)
+ : m_string(::SysAllocString(string))
+ {
+ }
+
+ inline ~QAutoBStr()
+ {
+ ::SysFreeString(m_string);
+ }
+
+ inline operator BSTR() const { return m_string; }
+
+private:
+ BSTR m_string;
+};
+
+
+
+#endif
diff --git a/src/plugins/wmp/qwmpmetadata.cpp b/src/plugins/wmp/qwmpmetadata.cpp
new file mode 100644
index 000000000..1f7cd0f88
--- /dev/null
+++ b/src/plugins/wmp/qwmpmetadata.cpp
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpmetadata.h"
+
+#include "qwmpevents.h"
+#include "qwmpglobal.h"
+
+#include <qmediacontent.h>
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+
+struct QWmpMetaDataKeyLookup
+{
+ QtMultimediaKit::MetaData key;
+ const wchar_t *token;
+};
+
+static const QWmpMetaDataKeyLookup qt_wmpMetaDataKeys[] =
+{
+ { QtMultimediaKit::Title, L"Title" },
+ { QtMultimediaKit::SubTitle, L"WM/SubTitle" },
+ { QtMultimediaKit::Author, L"Author" },
+ { QtMultimediaKit::Comment, L"Comment" },
+ { QtMultimediaKit::Description, L"Description" },
+ { QtMultimediaKit::Category, L"WM/Category" },
+ { QtMultimediaKit::Genre, L"WM/Genre" },
+ //{ QtMultimediaKit::Date, 0 },
+ { QtMultimediaKit::Year, L"WM/Year" },
+ { QtMultimediaKit::UserRating, L"UserRating" },
+ //{ QtMultimediaKit::MetaDatawords, 0 },
+ { QtMultimediaKit::Language, L"Language" },
+ { QtMultimediaKit::Publisher, L"WM/Publisher" },
+ { QtMultimediaKit::Copyright, L"Copyright" },
+ { QtMultimediaKit::ParentalRating, L"ParentalRating" },
+ { QtMultimediaKit::RatingOrganisation, L"RatingOrganisation" },
+
+ // Media
+ { QtMultimediaKit::Size, L"FileSize" },
+ { QtMultimediaKit::MediaType, L"MediaType" },
+ { QtMultimediaKit::Duration, L"Duration" },
+
+ // Audio
+ { QtMultimediaKit::AudioBitRate, L"AudioBitrate" },
+ { QtMultimediaKit::AudioCodec, L"AudioCodec" },
+ { QtMultimediaKit::ChannelCount, L"Channels" },
+ { QtMultimediaKit::SampleRate, L"Frequency" },
+
+ // Music
+ { QtMultimediaKit::AlbumTitle, L"WM/AlbumTitle" },
+ { QtMultimediaKit::AlbumArtist, L"WM/AlbumArtist" },
+ { QtMultimediaKit::ContributingArtist, L"Author" },
+ { QtMultimediaKit::Composer, L"WM/Composer" },
+ { QtMultimediaKit::Conductor, L"WM/Conductor" },
+ { QtMultimediaKit::Lyrics, L"WM/Lyrics" },
+ { QtMultimediaKit::Mood, L"WM/Mood" },
+ { QtMultimediaKit::TrackNumber, L"WM/TrackNumber" },
+ //{ QtMultimediaKit::TrackCount, 0 },
+ //{ QtMultimediaKit::CoverArtUrlSmall, 0 },
+ //{ QtMultimediaKit::CoverArtUrlLarge, 0 },
+
+ // Image/Video
+ //{ QtMultimediaKit::Resolution, 0 },
+ //{ QtMultimediaKit::PixelAspectRatio, 0 },
+
+ // Video
+ //{ QtMultimediaKit::FrameRate, 0 },
+ { QtMultimediaKit::VideoBitRate, L"VideoBitRate" },
+ { QtMultimediaKit::VideoCodec, L"VideoCodec" },
+
+ //{ QtMultimediaKit::PosterUrl, 0 },
+
+ // Movie
+ { QtMultimediaKit::ChapterNumber, L"ChapterNumber" },
+ { QtMultimediaKit::Director, L"WM/Director" },
+ { QtMultimediaKit::LeadPerformer, L"LeadPerformer" },
+ { QtMultimediaKit::Writer, L"WM/Writer" },
+
+ // Photos
+ { QtMultimediaKit::CameraManufacturer, L"CameraManufacturer" },
+ { QtMultimediaKit::CameraModel, L"CameraModel" },
+ { QtMultimediaKit::Event, L"Event" },
+ { QtMultimediaKit::Subject, L"Subject" }
+};
+
+QWmpMetaData::QWmpMetaData(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
+ : QMetaDataReaderControl(parent)
+ , m_media(0)
+{
+ player->get_currentMedia(&m_media);
+
+ connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
+ this, SLOT(currentItemChangeEvent(IDispatch*)));
+ connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
+}
+
+QWmpMetaData::~QWmpMetaData()
+{
+ if (m_media)
+ m_media->Release();
+}
+
+bool QWmpMetaData::isMetaDataAvailable() const
+{
+ return m_media != 0;
+}
+
+bool QWmpMetaData::isWritable() const
+{
+ return m_media != 0;
+}
+
+QVariant QWmpMetaData::metaData(QtMultimediaKit::MetaData key) const
+{
+ static const int count = sizeof(qt_wmpMetaDataKeys) / sizeof(QWmpMetaDataKeyLookup);
+
+ switch (key) {
+ case QtMultimediaKit::Date:
+ {
+ QVariant day = value(m_media, QAutoBStr(L"ReleaseDateDay"));
+ QVariant month = value(m_media, QAutoBStr(L"ReleaseDateMonth"));
+ QVariant year = value(m_media, QAutoBStr(L"ReleaseDateYear"));
+
+ if (!day.isNull() && !month.isNull() && !year.isNull())
+ return QDate(year.toInt(), month.toInt(), day.toInt());
+ }
+ break;
+ case QtMultimediaKit::CoverArtUrlSmall:
+ return albumArtUrl(m_media, "_Small.jpg");
+ case QtMultimediaKit::CoverArtUrlLarge:
+ return albumArtUrl(m_media, "_Large.jpg");
+ case QtMultimediaKit::Resolution:
+ {
+ QVariant width = value(m_media, QAutoBStr(L"WM/VideoWidth"));
+ QVariant height = value(m_media, QAutoBStr(L"WM/VideoHeight"));
+
+ if (!width.isNull() && !height.isNull())
+ return QSize(width.toInt(), height.toInt());
+ }
+ break;
+ case QtMultimediaKit::PixelAspectRatio:
+ {
+ QVariant x = value(m_media, QAutoBStr(L"PixelAspectRatioX"));
+ QVariant y = value(m_media, QAutoBStr(L"PixelAspectRatioY"));
+
+ if (!x.isNull() && !y.isNull())
+ return QSize(x.toInt(), y.toInt());
+ }
+ break;
+ case QtMultimediaKit::VideoFrameRate:
+ break;
+ default:
+ for (int i = 0; i < count; ++i) {
+ if (qt_wmpMetaDataKeys[i].key == key)
+ return value(m_media, QAutoBStr(qt_wmpMetaDataKeys[i].token));
+ }
+ break;
+ }
+ return QVariant();
+}
+
+QList<QtMultimediaKit::MetaData> QWmpMetaData::availableMetaData() const
+{
+ QList<QtMultimediaKit::MetaData> keys;
+
+ if (m_media) {
+ // WMP will return a list of all possible keys so there's no point in filtering the keys
+ // in the lookup table.
+ static const int count = sizeof(qt_wmpMetaDataKeys) / sizeof(QWmpMetaDataKeyLookup);
+ for (int i = 0; i < count; ++i)
+ keys.append(qt_wmpMetaDataKeys[i].key);
+
+ BSTR string = 0;
+ if (m_media->get_sourceURL(&string) == S_OK) {
+ QString url = QString::fromWCharArray(static_cast<const wchar_t *>(string));
+ ::SysFreeString(string);
+
+ if (m_media->getItemInfo(QAutoBStr(L"WM/WMCollectionGroupID"), &string) == S_OK) {
+ QString uuid = QString::fromWCharArray(static_cast<const wchar_t *>(string));
+ ::SysFreeString(string);
+
+ QString albumArtLarge = QLatin1String("AlbumArt_") + uuid + QLatin1String("_Large.jpg");
+ QString albumArtSmall = QLatin1String("AlbumArt_") + uuid + QLatin1String("_Small.jpg");
+
+ QDir dir = QFileInfo(url).absoluteDir();
+
+ if (dir.exists(albumArtLarge))
+ keys.append(QtMultimediaKit::CoverArtUrlLarge);
+ if (dir.exists(albumArtSmall))
+ keys.append(QtMultimediaKit::CoverArtUrlSmall);
+ }
+ }
+ }
+ return keys;
+}
+
+QVariant QWmpMetaData::extendedMetaData(const QString &key) const
+{
+ return value(m_media, QAutoBStr(key));
+}
+
+QStringList QWmpMetaData::availableExtendedMetaData() const
+{
+ return keys(m_media);
+}
+
+void QWmpMetaData::currentItemChangeEvent(IDispatch *dispatch)
+{
+ IWMPMedia *media = m_media;
+
+ m_media = 0;
+ if (dispatch)
+ dispatch->QueryInterface(__uuidof(IWMPMedia), reinterpret_cast<void **>(&m_media));
+
+ if (media) {
+ if (m_media)
+ emit metaDataChanged();
+ else
+ emit metaDataAvailableChanged(false);
+
+ media->Release();
+ } else {
+ if (m_media)
+ emit metaDataAvailableChanged(false);
+ }
+}
+
+void QWmpMetaData::mediaChangeEvent(IDispatch *dispatch)
+{
+ IWMPMedia *media = 0;
+ if (dispatch && dispatch->QueryInterface(
+ __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
+ VARIANT_BOOL isEqual = VARIANT_FALSE;
+ if (media->get_isIdentical(m_media, &isEqual) == S_OK && isEqual)
+ emit metaDataChanged();
+ media->Release();
+ }
+}
+
+
+QStringList QWmpMetaData::keys(IWMPMedia *media)
+{
+ QStringList keys;
+
+ long count = 0;
+ if (media && media->get_attributeCount(&count) == S_OK) {
+ for (long i = 0; i < count; ++i) {
+ BSTR string;
+ if (media->getAttributeName(i, &string) == S_OK) {
+ keys.append(QString::fromWCharArray(string, ::SysStringLen(string)));
+
+ ::SysFreeString(string);
+ }
+ }
+ }
+ return keys;
+}
+
+QVariant QWmpMetaData::value(IWMPMedia *media, BSTR key)
+{
+ QVariantList values;
+ IWMPMedia3 *media3 = 0;
+ if (media && media->QueryInterface(
+ __uuidof(IWMPMedia3), reinterpret_cast<void **>(&media3)) == S_OK) {
+ long count = 0;
+ media3->getAttributeCountByType(key, 0, &count);
+
+ // The count appears to only be valid for static properties, dynamic properties like
+ // PlaylistIndex will have a count of zero but return a value for index 0.
+ if (count == 0)
+ count = 1;
+
+ for (long i = 0; i < count; ++i) {
+ VARIANT var;
+ VariantInit(&var);
+
+ if (media3->getItemInfoByType(key, 0, i, &var) == S_OK) {
+ QVariant value = convertVariant(var);
+
+ if (!value.isNull())
+ values.append(value);
+
+ VariantClear(&var);
+ }
+ }
+ media3->Release();
+ }
+
+ switch (values.count()) {
+ case 0:
+ return QVariant();
+ case 1:
+ return values.first();
+ default:
+ return values;
+ }
+}
+
+QMediaContent QWmpMetaData::resources(IWMPMedia *media)
+{
+ QMediaContent content;
+
+ BSTR string = 0;
+ if (media->get_sourceURL(&string) == S_OK) {
+ QString url = QString::fromWCharArray(static_cast<const wchar_t *>(string));
+ ::SysFreeString(string);
+
+ content = QMediaContent(QUrl(url));
+ }
+
+ return content;
+}
+
+QVariant QWmpMetaData::convertVariant(const VARIANT &variant)
+{
+ switch (variant.vt) {
+ case VT_I2:
+ return variant.iVal;
+ case VT_I4:
+ return variant.lVal;
+ case VT_I8:
+ return variant.llVal;
+ case VT_UI2:
+ return variant.uiVal;
+ case VT_UI4:
+ return quint32(variant.ulVal);
+ case VT_UI8:
+ return variant.ullVal;
+ case VT_INT:
+ return variant.intVal;
+ case VT_UINT:
+ return variant.uintVal;
+ case VT_BSTR:
+ return QString::fromWCharArray(variant.bstrVal, ::SysStringLen(variant.bstrVal));
+ case VT_DISPATCH:
+ {
+ IWMPMetadataPicture *picture = 0;
+ IWMPMetadataText *text = 0;
+
+ if (variant.pdispVal->QueryInterface(
+ __uuidof(IWMPMetadataPicture), reinterpret_cast<void **>(&picture)) == S_OK) {
+ QUrl url;
+ BSTR string;
+ if (picture->get_URL(&string) == S_OK) {
+ url = QUrl(QString::fromWCharArray(string, ::SysStringLen(string)));
+
+ ::SysFreeString(string);
+ }
+ picture->Release();
+ return qVariantFromValue(url);
+ } else if (variant.pdispVal->QueryInterface(
+ __uuidof(IWMPMetadataText), reinterpret_cast<void **>(&text)) == S_OK) {
+ QString description;
+ BSTR string;
+ if (text->get_description(&string) == S_OK) {
+ description = QString::fromWCharArray(string, SysStringLen(string));
+
+ ::SysFreeString(string);
+ }
+ text->Release();
+ return description;
+ } else {
+ qWarning("Unknown dispatch type");
+ }
+ }
+ break;
+ default:
+ qWarning("Unsupported Type %d %x", variant.vt, variant.vt);
+ break;
+ }
+
+ return QVariant();
+}
+
+QVariant QWmpMetaData::albumArtUrl(IWMPMedia *media, const char *suffix)
+{
+ BSTR string = 0;
+ if (media && media->get_sourceURL(&string) == S_OK) {
+ QString url = QString::fromWCharArray(static_cast<const wchar_t *>(string));
+ ::SysFreeString(string);
+
+ if (media->getItemInfo(QAutoBStr(L"WM/WMCollectionGroupID"), &string) == S_OK) {
+ QString uuid = QString::fromWCharArray(static_cast<const wchar_t *>(string));
+ ::SysFreeString(string);
+
+ QString fileName = QLatin1String("AlbumArt_") + uuid + QLatin1String(suffix);
+
+ QDir dir = QFileInfo(url).absoluteDir();
+
+ if (dir.exists(fileName)) {
+ return qVariantFromValue(
+ QUrl(QLatin1String("file:///") + dir.absoluteFilePath(fileName)));
+ }
+ }
+ }
+ return QVariant();
+}
diff --git a/src/plugins/wmp/qwmpmetadata.h b/src/plugins/wmp/qwmpmetadata.h
new file mode 100644
index 000000000..b01a05c4e
--- /dev/null
+++ b/src/plugins/wmp/qwmpmetadata.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPMETADATA_H
+#define QWMPMETADATA_H
+
+#include <qmetadatareadercontrol.h>
+#include <qmediaresource.h>
+
+#include <wmp.h>
+
+QT_BEGIN_NAMESPACE
+class QMediaContent;
+QT_END_NAMESPACE
+
+class QWmpEvents;
+
+QT_USE_NAMESPACE
+
+class QWmpMetaData : public QMetaDataReaderControl
+{
+ Q_OBJECT
+public:
+ QWmpMetaData(IWMPCore3 *player, QWmpEvents *events, QObject *parent = 0);
+ ~QWmpMetaData();
+
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+
+ QVariant metaData(QtMultimediaKit::MetaData key) const;
+ QList<QtMultimediaKit::MetaData> availableMetaData() const;
+
+ QVariant extendedMetaData(const QString &key) const ;
+ QStringList availableExtendedMetaData() const;
+
+ static QStringList keys(IWMPMedia *media);
+ static QVariant value(IWMPMedia *media, BSTR key);
+ static QMediaContent resources(IWMPMedia *media);
+ static QVariant convertVariant(const VARIANT &variant);
+ static QVariant albumArtUrl(IWMPMedia *media, const char *suffix);
+
+private Q_SLOTS:
+ void currentItemChangeEvent(IDispatch *dispatch);
+ void mediaChangeEvent(IDispatch *dispatch);
+
+private:
+ IWMPMedia *m_media;
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpplayercontrol.cpp b/src/plugins/wmp/qwmpplayercontrol.cpp
new file mode 100644
index 000000000..be8f107b8
--- /dev/null
+++ b/src/plugins/wmp/qwmpplayercontrol.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpplayercontrol.h"
+
+#include "qwmpevents.h"
+#include "qwmpglobal.h"
+#include "qwmpmetadata.h"
+#include "qwmpplaylist.h"
+
+#include <qmediaplayer.h>
+#include <qmediaplaylist.h>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+QWmpPlayerControl::QWmpPlayerControl(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
+ : QMediaPlayerControl(parent)
+ , m_player(player)
+ , m_controls(0)
+ , m_settings(0)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_changes(0)
+ , m_buffering(false)
+ , m_audioAvailable(false)
+ , m_videoAvailable(false)
+{
+ m_player->get_controls(&m_controls);
+ m_player->get_settings(&m_settings);
+ m_player->get_network(&m_network);
+
+ if (m_settings)
+ m_settings->put_autoStart(FALSE);
+
+ WMPPlayState state = wmppsUndefined;
+ if (m_player->get_playState(&state) == S_OK)
+ playStateChangeEvent(state);
+
+ connect(events, SIGNAL(Buffering(VARIANT_BOOL)), this, SLOT(bufferingEvent(VARIANT_BOOL)));
+ connect(events, SIGNAL(PositionChange(double,double)),
+ this, SLOT(positionChangeEvent(double,double)));
+ connect(events, SIGNAL(PlayStateChange(long)), this, SLOT(playStateChangeEvent(long)));
+ connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
+ this, SLOT(currentItemChangeEvent(IDispatch*)));
+ connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
+}
+
+QWmpPlayerControl::~QWmpPlayerControl()
+{
+ if (m_controls) m_controls->Release();
+ if (m_settings) m_settings->Release();
+ if (m_network) m_network->Release();
+}
+
+QMediaPlayer::State QWmpPlayerControl::state() const
+{
+ return m_state;
+}
+
+QMediaPlayer::MediaStatus QWmpPlayerControl::mediaStatus() const
+{
+ return m_status;
+}
+
+qint64 QWmpPlayerControl::duration() const
+{
+ double duration = 0.;
+
+ IWMPMedia *media = 0;
+ if (m_controls && m_controls->get_currentItem(&media) == S_OK) {
+ media->get_duration(&duration);
+ media->Release();
+ }
+
+ return duration * 1000;
+}
+
+qint64 QWmpPlayerControl::position() const
+{
+ double position = 0.0;
+
+ if (m_controls)
+ m_controls->get_currentPosition(&position);
+
+ return position * 1000;
+}
+
+void QWmpPlayerControl::setPosition(qint64 position)
+{
+ if (m_controls)
+ m_controls->put_currentPosition(double(position) / 1000.);
+}
+
+int QWmpPlayerControl::volume() const
+{
+ long volume = 0;
+
+ if (m_settings)
+ m_settings->get_volume(&volume);
+
+ return volume;
+}
+
+void QWmpPlayerControl::setVolume(int volume)
+{
+ if (m_settings && m_settings->put_volume(volume) == S_OK)
+ emit volumeChanged(volume);
+}
+
+bool QWmpPlayerControl::isMuted() const
+{
+ VARIANT_BOOL mute = FALSE;
+
+ if (m_settings)
+ m_settings->get_mute(&mute);
+
+ return mute;
+}
+
+void QWmpPlayerControl::setMuted(bool muted)
+{
+ if (m_settings && m_settings->put_mute(muted ? TRUE : FALSE) == S_OK)
+ emit mutedChanged(muted);
+
+}
+
+int QWmpPlayerControl::bufferStatus() const
+{
+ long progress = 0;
+
+ if (m_network)
+ m_network->get_bufferingProgress(&progress);
+
+ return progress;
+}
+
+bool QWmpPlayerControl::isVideoAvailable() const
+{
+ return m_videoAvailable;
+}
+
+bool QWmpPlayerControl::isAudioAvailable() const
+{
+ return m_audioAvailable;
+}
+
+void QWmpPlayerControl::setAudioAvailable(bool available)
+{
+ if (m_audioAvailable != available)
+ emit audioAvailableChanged(m_audioAvailable = available);
+}
+
+void QWmpPlayerControl::setVideoAvailable(bool available)
+{
+ if (m_videoAvailable != available)
+ emit videoAvailableChanged(m_videoAvailable = available);
+}
+
+bool QWmpPlayerControl::isSeekable() const
+{
+ return true;
+}
+
+QMediaTimeRange QWmpPlayerControl::availablePlaybackRanges() const
+{
+ QMediaTimeRange ranges;
+
+ IWMPMedia *media = 0;
+ if (m_controls && m_controls->get_currentItem(&media) == S_OK) {
+ double duration = 0;
+ media->get_duration(&duration);
+ media->Release();
+
+ if(duration > 0)
+ ranges.addInterval(0, duration * 1000);
+ }
+
+ return ranges;
+}
+
+qreal QWmpPlayerControl::playbackRate() const
+{
+ double rate = 0.;
+
+ if (m_settings)
+ m_settings->get_rate(&rate);
+
+ return rate;
+}
+
+void QWmpPlayerControl::setPlaybackRate(qreal rate)
+{
+ if (m_settings)
+ m_settings->put_rate(rate);
+}
+
+void QWmpPlayerControl::play()
+{
+ if (m_controls)
+ m_controls->play();
+}
+
+void QWmpPlayerControl::pause()
+{
+ if (m_controls)
+ m_controls->pause();
+}
+
+void QWmpPlayerControl::stop()
+{
+ if (m_controls)
+ m_controls->stop();
+}
+
+QMediaContent QWmpPlayerControl::media() const
+{
+ QMediaResourceList resources;
+
+ QUrl tmpUrl = url();
+
+ if (!tmpUrl.isEmpty())
+ resources << QMediaResource(tmpUrl);
+
+ return resources;
+}
+
+const QIODevice *QWmpPlayerControl::mediaStream() const
+{
+ return 0;
+}
+
+void QWmpPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+ if (!content.isNull() && !stream)
+ setUrl(content.canonicalUrl());
+ else
+ setUrl(QUrl());
+}
+
+bool QWmpPlayerControl::event(QEvent *event)
+{
+ if (event->type() == QEvent::UpdateRequest) {
+ const int changes = m_changes;
+ m_changes = 0;
+
+ if (changes & DurationChanged)
+ emit durationChanged(duration());
+ if (changes & PositionChanged)
+ emit positionChanged(position());
+ if (changes & StatusChanged)
+ emit mediaStatusChanged(m_status);
+ if (changes & StateChanged)
+ emit stateChanged(m_state);
+
+ return true;
+ } else {
+ return QMediaPlayerControl::event(event);
+ }
+}
+
+void QWmpPlayerControl::scheduleUpdate(int change)
+{
+ if (m_changes == 0)
+ QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
+
+ m_changes |= change;
+}
+
+void QWmpPlayerControl::bufferingEvent(VARIANT_BOOL buffering)
+{
+ if (m_state != QMediaPlayer::StoppedState) {
+ m_status = buffering
+ ? QMediaPlayer::BufferingMedia
+ : QMediaPlayer::BufferedMedia;
+
+ scheduleUpdate(StatusChanged);
+ }
+}
+
+void QWmpPlayerControl::currentItemChangeEvent(IDispatch *)
+{
+ scheduleUpdate(DurationChanged);
+}
+
+void QWmpPlayerControl::mediaChangeEvent(IDispatch *dispatch)
+{
+ IWMPMedia *media = 0;
+ if (dispatch && dispatch->QueryInterface(
+ __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
+ IWMPMedia *currentMedia = 0;
+ if (m_controls && m_controls->get_currentItem(&currentMedia) == S_OK) {
+ VARIANT_BOOL isEqual = VARIANT_FALSE;
+ if (media->get_isIdentical(currentMedia, &isEqual) == S_OK && isEqual)
+ scheduleUpdate(DurationChanged);
+
+ currentMedia->Release();
+ }
+ media->Release();
+ }
+}
+
+void QWmpPlayerControl::positionChangeEvent(double , double)
+{
+ scheduleUpdate(PositionChanged);
+}
+
+void QWmpPlayerControl::playStateChangeEvent(long state)
+{
+ switch (state) {
+ case wmppsUndefined:
+ m_state = QMediaPlayer::StoppedState;
+ m_status = QMediaPlayer::UnknownMediaStatus;
+ scheduleUpdate(StatusChanged | StateChanged);
+ break;
+ case wmppsStopped:
+ if (m_state != QMediaPlayer::StoppedState) {
+ m_state = QMediaPlayer::StoppedState;
+ scheduleUpdate(StateChanged);
+
+ if (m_status != QMediaPlayer::EndOfMedia) {
+ m_status = QMediaPlayer::LoadedMedia;
+ scheduleUpdate(StatusChanged);
+ }
+ }
+ break;
+ case wmppsPaused:
+ if (m_state != QMediaPlayer::PausedState && m_status != QMediaPlayer::BufferedMedia) {
+ m_state = QMediaPlayer::PausedState;
+ m_status = QMediaPlayer::BufferedMedia;
+ scheduleUpdate(StatusChanged | StateChanged);
+ } else if (m_state != QMediaPlayer::PausedState) {
+ m_state = QMediaPlayer::PausedState;
+ scheduleUpdate(StateChanged);
+ } else if (m_status != QMediaPlayer::BufferedMedia) {
+ m_status = QMediaPlayer::BufferedMedia;
+
+ scheduleUpdate(StatusChanged);
+ }
+ break;
+ case wmppsPlaying:
+ case wmppsScanForward:
+ case wmppsScanReverse:
+ if (m_state != QMediaPlayer::PlayingState && m_status != QMediaPlayer::BufferedMedia) {
+ m_state = QMediaPlayer::PlayingState;
+ m_status = QMediaPlayer::BufferedMedia;
+ scheduleUpdate(StatusChanged | StateChanged);
+ } else if (m_state != QMediaPlayer::PlayingState) {
+ m_state = QMediaPlayer::PlayingState;
+ scheduleUpdate(StateChanged);
+ } else if (m_status != QMediaPlayer::BufferedMedia) {
+ m_status = QMediaPlayer::BufferedMedia;
+ scheduleUpdate(StatusChanged);
+ }
+
+ if (m_state != QMediaPlayer::PlayingState) {
+ m_state = QMediaPlayer::PlayingState;
+ scheduleUpdate(StateChanged);
+ }
+ if (m_status != QMediaPlayer::BufferedMedia) {
+ m_status = QMediaPlayer::BufferedMedia;
+ scheduleUpdate(StatusChanged);
+ }
+ break;
+ case wmppsBuffering:
+ case wmppsWaiting:
+ if (m_status != QMediaPlayer::StalledMedia && m_state != QMediaPlayer::StoppedState) {
+ m_status = QMediaPlayer::StalledMedia;
+ scheduleUpdate(StatusChanged);
+ }
+ break;
+ case wmppsMediaEnded:
+ if (m_status != QMediaPlayer::EndOfMedia && m_state != QMediaPlayer::StoppedState) {
+ m_state = QMediaPlayer::StoppedState;
+ m_status = QMediaPlayer::EndOfMedia;
+ scheduleUpdate(StatusChanged | StateChanged);
+ }
+ break;
+ case wmppsTransitioning:
+ break;
+ case wmppsReady:
+ if (m_status != QMediaPlayer::LoadedMedia) {
+ m_status = QMediaPlayer::LoadedMedia;
+ scheduleUpdate(StatusChanged);
+ }
+
+ if (m_state != QMediaPlayer::StoppedState) {
+ m_state = QMediaPlayer::StoppedState;
+ scheduleUpdate(StateChanged);
+ }
+ break;
+ case wmppsReconnecting:
+ if (m_status != QMediaPlayer::StalledMedia && m_state != QMediaPlayer::StoppedState) {
+ m_status = QMediaPlayer::StalledMedia;
+ scheduleUpdate(StatusChanged);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+QUrl QWmpPlayerControl::url() const
+{
+ BSTR string;
+ if (m_player && m_player->get_URL(&string) == S_OK) {
+ QUrl url(QString::fromWCharArray(string, SysStringLen(string)), QUrl::StrictMode);
+
+ SysFreeString(string);
+
+ return url;
+ } else {
+ return QUrl();
+ }
+}
+
+void QWmpPlayerControl::setUrl(const QUrl &url)
+{
+ if (url != QWmpPlayerControl::url() && m_player) {
+ BSTR string = SysAllocString(reinterpret_cast<const wchar_t *>(url.toString().unicode()));
+
+ m_player->put_URL(string);
+
+ SysFreeString(string);
+ }
+}
diff --git a/src/plugins/wmp/qwmpplayercontrol.h b/src/plugins/wmp/qwmpplayercontrol.h
new file mode 100644
index 000000000..d966b38b2
--- /dev/null
+++ b/src/plugins/wmp/qwmpplayercontrol.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPPLAYERCONTROL_H
+#define QWMPPLAYERCONTROL_H
+
+#include <qmediaplayercontrol.h>
+
+#include <wmp.h>
+
+class QWmpEvents;
+class QWmpPlaylist;
+
+QT_USE_NAMESPACE
+class QWmpPlayerControl : public QMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ QWmpPlayerControl(
+ IWMPCore3 *player, QWmpEvents *events, QObject *parent = 0);
+ ~QWmpPlayerControl();
+
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+ QMediaPlaylist* mediaPlaylist() const;
+ bool setMediaPlaylist(QMediaPlaylist *playlist);
+
+ qint64 duration() const;
+
+ qint64 position() const;
+ void setPosition(qint64 position);
+
+ int playlistPosition() const;
+ void setPlaylistPosition(int position);
+
+ int volume() const;
+ void setVolume(int volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ int bufferStatus() const;
+
+ bool isAudioAvailable() const;
+ void setAudioAvailable(bool available);
+
+ bool isVideoAvailable() const;
+ void setVideoAvailable(bool available);
+
+ qreal playbackRate() const;
+ void setPlaybackRate(qreal rate);
+
+ bool isSeekable() const;
+ QMediaTimeRange availablePlaybackRanges() const;
+
+ void play();
+ void pause();
+ void stop();
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ void setMedia(const QMediaContent &content, QIODevice *stream);
+
+ QUrl url() const;
+ void setUrl(const QUrl &url);
+
+ bool event(QEvent *event);
+
+ using QMediaPlayerControl::positionChanged;
+
+private Q_SLOTS:
+
+ void bufferingEvent(VARIANT_BOOL buffering);
+ void currentItemChangeEvent(IDispatch *dispatch);
+ void mediaChangeEvent(IDispatch *dispatch);
+ void positionChangeEvent(double from, double to);
+ void playStateChangeEvent(long state);
+
+private:
+ enum Change
+ {
+ StateChanged = 0x01,
+ StatusChanged = 0x02,
+ PositionChanged = 0x04,
+ DurationChanged = 0x08
+ };
+
+ void scheduleUpdate(int change);
+
+ IWMPCore3 *m_player;
+ IWMPControls *m_controls;
+ IWMPSettings *m_settings;
+ IWMPNetwork *m_network;
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_status;
+ int m_changes;
+ bool m_buffering;
+ bool m_audioAvailable;
+ bool m_videoAvailable;
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpplayerservice.cpp b/src/plugins/wmp/qwmpplayerservice.cpp
new file mode 100644
index 000000000..e185aaf46
--- /dev/null
+++ b/src/plugins/wmp/qwmpplayerservice.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpplayerservice.h"
+
+#ifdef QWMP_EVR
+#include "qevrvideooverlay.h"
+#endif
+
+#include "qwmpglobal.h"
+#include "qwmpmetadata.h"
+#include "qwmpplayercontrol.h"
+#include "qwmpplaylist.h"
+#include "qwmpplaylistcontrol.h"
+#include "qwmpvideooverlay.h"
+
+#include <qmediaplayer.h>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/quuid.h>
+#include <QtCore/qvariant.h>
+#include <QtGui/qevent.h>
+
+#include <d3d9.h>
+#include <wmprealestate.h>
+
+QWmpPlayerService::QWmpPlayerService(EmbedMode mode, QObject *parent)
+ : QMediaService(parent)
+ , m_ref(1)
+ , m_embedMode(mode)
+ , m_player(0)
+ , m_oleObject(0)
+ , m_events(0)
+ , m_control(0)
+ , m_metaData(0)
+ , m_playlist(0)
+ , m_activeVideoOverlay(0)
+ , m_oleVideoOverlay(0)
+#ifdef QWMP_EVR
+ , m_evrVideoOverlay(0)
+#endif
+{
+ HRESULT hr;
+
+ if ((hr = CoCreateInstance(
+ __uuidof(WindowsMediaPlayer),
+ 0,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(IWMPPlayer4),
+ reinterpret_cast<void **>(&m_player))) != S_OK) {
+ qWarning("failed to create media player control, %x: %s", hr, qwmp_error_string(hr));
+ } else {
+ m_events = new QWmpEvents(m_player);
+
+ if ((hr = m_player->QueryInterface(
+ __uuidof(IOleObject), reinterpret_cast<void **>(&m_oleObject))) != S_OK) {
+ qWarning("No IOleObject interface, %x: %s", hr, qwmp_error_string(hr));
+ } else if ((hr = m_oleObject->SetClientSite(this)) != S_OK) {
+ qWarning("Failed to set site, %x: %s", hr, qwmp_error_string(hr));
+ }
+
+ if (m_embedMode == LocalEmbed)
+ m_oleVideoOverlay = new QWmpVideoOverlay(m_player, m_oleObject, this);
+
+ m_metaData = new QWmpMetaData(m_player, m_events);
+ m_playlist = new QWmpPlaylistControl(m_player, m_events);
+ m_control = new QWmpPlayerControl(m_player, m_events);
+ }
+}
+
+QWmpPlayerService::~QWmpPlayerService()
+{
+ delete m_control;
+ delete m_metaData;
+ delete m_playlist;
+ delete m_events;
+
+ if (m_oleObject) {
+ m_oleObject->SetClientSite(0);
+ m_oleObject->Release();
+ delete m_oleVideoOverlay;
+ }
+
+#ifdef QWMP_EVR
+ delete m_evrVideoOverlay;
+#endif
+
+
+ if (m_player)
+ m_player->Release();
+
+ Q_ASSERT(m_ref == 1);
+}
+
+QMediaControl *QWmpPlayerService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
+ return m_control;
+ } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) {
+ return m_metaData;
+ } else if (qstrcmp(name, QMediaPlaylistControl_iid) == 0) {
+ return m_playlist;
+ } else if (qstrcmp(name, QVideoWindowControl_iid) == 0
+ && m_embedMode == LocalEmbed
+ && m_player
+ && !m_activeVideoOverlay) {
+#ifdef QWMP_EVR
+ IWMPVideoRenderConfig *config = 0;
+ if (m_player->QueryInterface(
+ __uuidof(IWMPVideoRenderConfig), reinterpret_cast<void **>(&config)) == S_OK) {
+ if (HINSTANCE evrHwnd = LoadLibrary(L"evr")) {
+ m_evrVideoOverlay = new QEvrVideoOverlay(evrHwnd);
+
+ if (SUCCEEDED(config->put_presenterActivate(
+ static_cast<IMFActivate *>(m_evrVideoOverlay)))) {
+ connect(m_events, SIGNAL(OpenStateChange(long)),
+ m_evrVideoOverlay, SLOT(openStateChanged(long)));
+ } else {
+ delete m_evrVideoOverlay;
+
+ m_evrVideoOverlay = 0;
+ }
+ }
+ config->Release();
+ }
+
+ if (m_evrVideoOverlay) {
+ m_activeVideoOverlay = m_evrVideoOverlay;
+
+ return m_evrVideoOverlay;
+ } else
+#endif
+ if (SUCCEEDED(m_player->put_uiMode(QAutoBStr(L"none")))) {
+ m_activeVideoOverlay = m_oleVideoOverlay;
+
+ return m_oleVideoOverlay;
+ }
+ }
+ return 0;
+}
+
+void QWmpPlayerService::releaseControl(QMediaControl *control)
+{
+ if (!control) {
+ qWarning("QMediaService::releaseControl():"
+ " Attempted release of null control");
+#ifdef QWMP_EVR
+ } else if (control == m_evrVideoOverlay) {
+
+ IWMPVideoRenderConfig *config = 0;
+ if (m_player->QueryInterface(
+ __uuidof(IWMPVideoRenderConfig), reinterpret_cast<void **>(&config)) == S_OK) {
+ config->put_presenterActivate(0);
+ config->Release();
+ }
+
+ delete m_evrVideoOverlay;
+
+ m_evrVideoOverlay = 0;
+ m_activeVideoOverlay = 0;
+#endif
+ } else if (control == m_oleVideoOverlay) {
+ m_player->put_uiMode(QAutoBStr(L"invisible"));
+ m_oleVideoOverlay->setWinId(0);
+
+ m_activeVideoOverlay = 0;
+ }
+}
+
+// IUnknown
+HRESULT QWmpPlayerService::QueryInterface(REFIID riid, void **object)
+{
+ if (!object) {
+ return E_POINTER;
+ } else if (riid == __uuidof(IUnknown)
+ || riid == __uuidof(IOleClientSite)) {
+ *object = static_cast<IOleClientSite *>(this);
+ } else if (riid == __uuidof(IServiceProvider)) {
+ *object = static_cast<IServiceProvider *>(this);
+ } else if (riid == __uuidof(IWMPRemoteMediaServices)) {
+ *object = static_cast<IWMPRemoteMediaServices *>(this);
+ } else if (riid == __uuidof(IOleWindow)
+ || riid == __uuidof(IOleInPlaceSite)) {
+ *object = static_cast<IOleInPlaceSite *>(m_oleVideoOverlay);
+ } else if (riid == __uuidof(IOleInPlaceUIWindow)
+ || riid == __uuidof(IOleInPlaceFrame)) {
+ *object = static_cast<IOleInPlaceFrame *>(m_oleVideoOverlay);
+ } else {
+ *object = 0;
+ }
+
+ if (*object) {
+ AddRef();
+
+ return S_OK;
+ } else {
+ return E_NOINTERFACE;
+ }
+}
+
+ULONG QWmpPlayerService::AddRef()
+{
+ return InterlockedIncrement(&m_ref);
+}
+
+ULONG QWmpPlayerService::Release()
+{
+ ULONG ref = InterlockedDecrement(&m_ref);
+
+ Q_ASSERT(ref != 0);
+
+ return ref;
+}
+
+// IOleClientSite
+HRESULT QWmpPlayerService::SaveObject()
+{
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpPlayerService::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
+{
+ Q_UNUSED(dwAssign);
+ Q_UNUSED(dwWhichMoniker);
+ Q_UNUSED(ppmk);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpPlayerService::GetContainer(IOleContainer **ppContainer)
+{
+ if (!ppContainer) {
+ return E_POINTER;
+ } else {
+ *ppContainer = 0;
+
+ return E_NOINTERFACE;
+ }
+}
+
+HRESULT QWmpPlayerService::ShowObject()
+{
+ return S_OK;
+}
+
+HRESULT QWmpPlayerService::OnShowWindow(BOOL fShow)
+{
+ Q_UNUSED(fShow);
+
+ return S_OK;
+}
+
+HRESULT QWmpPlayerService::RequestNewObjectLayout()
+{
+ return E_NOTIMPL;
+}
+
+// IServiceProvider
+HRESULT QWmpPlayerService::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
+{
+ Q_UNUSED(guidService);
+
+ if (!ppvObject) {
+ return E_POINTER;
+ } else if (riid == __uuidof(IWMPRemoteMediaServices)) {
+ *ppvObject = static_cast<IWMPRemoteMediaServices *>(this);
+
+ AddRef();
+
+ return S_OK;
+ } else {
+ return E_NOINTERFACE;
+ }
+}
+
+// IWMPRemoteMediaServices
+HRESULT QWmpPlayerService::GetServiceType(BSTR *pbstrType)
+{
+ if (!pbstrType) {
+ return E_POINTER;
+ } else if (m_embedMode == RemoteEmbed) {
+ *pbstrType = ::SysAllocString(L"Remote");
+
+ return S_OK;
+ } else {
+ *pbstrType = ::SysAllocString(L"Local");
+
+ return S_OK;
+ }
+}
+
+HRESULT QWmpPlayerService::GetApplicationName(BSTR *pbstrName)
+{
+ if (!pbstrName) {
+ return E_POINTER;
+ } else {
+ *pbstrName = ::SysAllocString(static_cast<const wchar_t *>(
+ QCoreApplication::applicationName().utf16()));
+
+ return S_OK;
+ }
+}
+
+HRESULT QWmpPlayerService::GetScriptableObject(BSTR *pbstrName, IDispatch **ppDispatch)
+{
+ Q_UNUSED(pbstrName);
+ Q_UNUSED(ppDispatch);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpPlayerService::GetCustomUIMode(BSTR *pbstrFile)
+{
+ Q_UNUSED(pbstrFile);
+
+ return E_NOTIMPL;
+}
diff --git a/src/plugins/wmp/qwmpplayerservice.h b/src/plugins/wmp/qwmpplayerservice.h
new file mode 100644
index 000000000..ba79a9a68
--- /dev/null
+++ b/src/plugins/wmp/qwmpplayerservice.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPPLAYERSERVICE_H
+#define QWMPPLAYERSERVICE_H
+
+#include "qwmpevents.h"
+
+#include <qmediaservice.h>
+
+QT_BEGIN_NAMESPACE
+class QMediaMetaData;
+class QMediaPlayerControl;
+class QMediaPlaylist;
+class QVideoWindowControl;
+QT_END_NAMESPACE
+
+#ifdef QWMP_EVR
+class QEvrVideoOverlay;
+#endif
+
+class QWmpMetaData;
+class QWmpPlayerControl;
+class QWmpPlaylist;
+class QWmpPlaylistControl;
+class QWmpVideoOverlay;
+
+QT_USE_NAMESPACE
+class QWmpPlayerService
+ : public QMediaService
+ , public IOleClientSite
+ , public IServiceProvider
+ , public IWMPRemoteMediaServices
+{
+ Q_OBJECT
+public:
+ enum EmbedMode
+ {
+ LocalEmbed,
+ RemoteEmbed
+ };
+
+ QWmpPlayerService(EmbedMode mode, QObject *parent = 0);
+ ~QWmpPlayerService();
+
+ QMediaControl *requestControl(const char *name);
+ void releaseControl(QMediaControl *control);
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ // IOleClientSite
+ HRESULT STDMETHODCALLTYPE SaveObject();
+ HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
+ HRESULT STDMETHODCALLTYPE GetContainer(IOleContainer **ppContainer);
+ HRESULT STDMETHODCALLTYPE ShowObject();
+ HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow);
+ HRESULT STDMETHODCALLTYPE RequestNewObjectLayout();
+
+ // IServiceProvider
+ HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
+
+ // IWMPRemoteMediaServices
+ HRESULT STDMETHODCALLTYPE GetServiceType(BSTR *pbstrType);
+ HRESULT STDMETHODCALLTYPE GetApplicationName(BSTR *pbstrName);
+ HRESULT STDMETHODCALLTYPE GetScriptableObject(BSTR *pbstrName, IDispatch **ppDispatch);
+ HRESULT STDMETHODCALLTYPE GetCustomUIMode(BSTR *pbstrFile);
+
+private:
+ volatile LONG m_ref;
+ const EmbedMode m_embedMode;
+ IWMPPlayer4 *m_player;
+ IOleObject *m_oleObject;
+ QWmpEvents *m_events;
+ QWmpPlayerControl *m_control;
+ QWmpMetaData *m_metaData;
+ QWmpPlaylistControl *m_playlist;
+ QVideoWindowControl *m_activeVideoOverlay;
+ QWmpVideoOverlay *m_oleVideoOverlay;
+#ifdef QWMP_EVR
+ QEvrVideoOverlay *m_evrVideoOverlay;
+#endif
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpplaylist.cpp b/src/plugins/wmp/qwmpplaylist.cpp
new file mode 100644
index 000000000..10ce753b1
--- /dev/null
+++ b/src/plugins/wmp/qwmpplaylist.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpplaylist.h"
+
+#include "qwmpevents.h"
+#include "qwmpmetadata.h"
+#include "qwmpglobal.h"
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+QWmpPlaylist::QWmpPlaylist(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
+ : QMediaPlaylistProvider(parent)
+ , m_player(player)
+ , m_playlist(0)
+ , m_count(0)
+{
+ if (m_player && m_player->get_currentPlaylist(&m_playlist) == S_OK)
+ m_playlist->get_count(&m_count);
+
+ connect(events, SIGNAL(CurrentPlaylistChange(WMPPlaylistChangeEventType)),
+ this, SLOT(currentPlaylistChangeEvent(WMPPlaylistChangeEventType)));
+ connect(events, SIGNAL(OpenPlaylistSwitch(IDispatch*)),
+ this, SLOT(openPlaylistChangeEvent(IDispatch*)));
+ connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
+}
+
+QWmpPlaylist::~QWmpPlaylist()
+{
+ if (m_playlist)
+ m_playlist->Release();
+}
+
+bool QWmpPlaylist::load(const QString &location, const char *format)
+{
+ Q_UNUSED(location);
+ Q_UNUSED(format);
+
+ return false;
+}
+
+bool QWmpPlaylist::load(QIODevice * device, const char *format)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(format);
+
+ return false;
+}
+
+bool QWmpPlaylist::save(const QString &location, const char *format)
+{
+ Q_UNUSED(location);
+ Q_UNUSED(format);
+
+ return false;
+}
+
+bool QWmpPlaylist::save(QIODevice * device, const char *format)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(format);
+
+ return false;
+}
+
+int QWmpPlaylist::mediaCount() const
+{
+ return m_count;
+}
+
+QMediaContent QWmpPlaylist::media(int pos) const
+{
+ QMediaContent content;
+
+ IWMPMedia *media = 0;
+ if (m_playlist && m_playlist->get_item(pos, &media) == S_OK) {
+ content = QWmpMetaData::resources(media);
+
+ media->Release();
+ }
+
+ return content;
+}
+
+bool QWmpPlaylist::isReadOnly() const
+{
+ return false;
+}
+
+bool QWmpPlaylist::addMedia(const QMediaContent &content)
+{
+ bool appended = false;
+
+ IWMPMedia *media = 0;
+ if (!content.isNull() && m_playlist && m_player && m_player->newMedia(
+ QAutoBStr(content.canonicalUrl()), &media) == S_OK) {
+ appended = m_playlist->appendItem(media) == S_OK;
+
+ media->Release();
+ }
+
+ return appended;
+}
+
+bool QWmpPlaylist::insertMedia(int pos, const QMediaContent &content)
+{
+ bool inserted = false;
+
+ IWMPMedia *media = 0;
+ if (m_playlist && m_player && m_player->newMedia(
+ QAutoBStr(content.canonicalUrl()), &media) == S_OK) {
+ inserted = m_playlist->insertItem(pos, media) == S_OK;
+
+ media->Release();
+ }
+
+ return inserted;
+}
+
+bool QWmpPlaylist::removeMedia(int pos)
+{
+ IWMPMedia *media = 0;
+ if (m_playlist->get_item(pos, &media) == S_OK) {
+ bool removed = m_playlist->removeItem(media) == S_OK;
+
+ media->Release();
+
+ return removed;
+ } else {
+ return false;
+ }
+}
+
+bool QWmpPlaylist::removeMedia(int start, int end)
+{
+ if (!m_playlist)
+ return false;
+
+ for (int i = start; i <= end; ++i) {
+ IWMPMedia *media = 0;
+ if (m_playlist->get_item(start, &media) == S_OK) {
+ bool removed = m_playlist->removeItem(media) == S_OK;
+
+ media->Release();
+
+ if (!removed)
+ return false;
+ }
+ }
+ return true;
+}
+
+bool QWmpPlaylist::clear()
+{
+ return m_playlist && m_playlist->clear() == S_OK;
+}
+
+QStringList QWmpPlaylist::keys(int index) const
+{
+ QStringList keys;
+
+ IWMPMedia *media = 0;
+ if (m_playlist && m_playlist->get_item(index, &media) == S_OK) {
+ keys = QWmpMetaData::keys(media);
+
+ media->Release();
+ }
+
+ return keys;
+}
+
+QVariant QWmpPlaylist::value(int index, const QString &key) const
+{
+ QVariant v;
+
+ IWMPMedia *media = 0;
+ if (m_playlist && m_playlist->get_item(index, &media) == S_OK) {
+ v = QWmpMetaData::value(media, QAutoBStr(key));
+
+ media->Release();
+ }
+
+ return v;
+}
+
+void QWmpPlaylist::shuffle()
+{
+}
+
+
+void QWmpPlaylist::currentPlaylistChangeEvent(WMPPlaylistChangeEventType change)
+{
+ Q_UNUSED(change);
+
+ long count = 0;
+ if (m_playlist && m_playlist->get_count(&count) == S_OK && count > 0) {
+ if (count > m_count) {
+ emit mediaAboutToBeInserted(m_count, count - 1);
+ m_count = count;
+ emit mediaInserted(count, m_count - 1);
+ } else if (count < m_count) {
+ emit mediaAboutToBeRemoved(count, m_count - 1);
+ m_count = count;
+ emit mediaRemoved(count, m_count - 1);
+ }
+ }
+ if (m_count > 0)
+ emit mediaChanged(0, m_count - 1);
+}
+
+void QWmpPlaylist::openPlaylistChangeEvent(IDispatch *dispatch)
+{
+ if (m_playlist && m_count > 0) {
+ emit mediaAboutToBeRemoved(0, m_count - 1);
+ m_playlist->Release();
+ m_playlist = 0;
+ m_count = 0;
+ emit mediaRemoved(0, m_count - 1);
+ } else if (m_playlist) {
+ m_playlist->Release();
+ m_playlist = 0;
+ }
+
+ IWMPPlaylist *playlist = 0;
+ if (dispatch && dispatch->QueryInterface(
+ __uuidof(IWMPPlaylist), reinterpret_cast<void **>(&playlist))) {
+
+ long count = 0;
+ if (playlist->get_count(&count) == S_OK && count > 0) {
+ emit mediaAboutToBeInserted(0, count - 1);
+ m_playlist = playlist;
+ m_count = count;
+ emit mediaInserted(0, count - 1);
+ } else {
+ m_playlist = playlist;
+ }
+ }
+}
+
+void QWmpPlaylist::mediaChangeEvent(IDispatch *dispatch)
+{
+
+ IWMPMedia *media = 0;
+ if (dispatch && dispatch->QueryInterface(
+ __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
+ VARIANT_BOOL isMember = VARIANT_FALSE;
+
+ if (media->isMemberOf(m_playlist, &isMember) == S_OK && isMember) {
+ int index = QWmpMetaData::value(media, QAutoBStr(L"PlaylistIndex")).toInt();
+
+ if (index >= 0)
+ emit mediaChanged(index, index);
+ }
+ media->Release();
+ }
+}
diff --git a/src/plugins/wmp/qwmpplaylist.h b/src/plugins/wmp/qwmpplaylist.h
new file mode 100644
index 000000000..be168a7b5
--- /dev/null
+++ b/src/plugins/wmp/qwmpplaylist.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPPLAYLIST_H
+#define QWMPPLAYLIST_H
+
+#include <qmediaplaylistprovider.h>
+
+#include <QtCore/qvariant.h>
+
+#include <wmp.h>
+
+class QWmpEvents;
+
+QT_USE_NAMESPACE
+class QWmpPlaylist : public QMediaPlaylistProvider
+{
+ Q_OBJECT
+public:
+ QWmpPlaylist(IWMPCore3 *player, QWmpEvents *events, QObject *parent = 0);
+ ~QWmpPlaylist();
+
+ bool load(const QString &location, const char *format = 0);
+ bool load(QIODevice * device, const char *format = 0);
+ bool save(const QString &location, const char *format = 0);
+ bool save(QIODevice * device, const char *format);
+
+ int mediaCount() const;
+ QMediaContent media(int pos) const;
+
+ bool isReadOnly() const;
+
+ bool addMedia(const QMediaContent &content);
+ bool insertMedia(int pos, const QMediaContent &content);
+ bool removeMedia(int pos);
+ bool removeMedia(int start, int end);
+ bool clear();
+
+ QStringList keys(int index) const;
+ QVariant value(int index, const QString &key) const;
+
+public Q_SLOTS:
+ virtual void shuffle();
+
+private Q_SLOTS:
+ void currentPlaylistChangeEvent(WMPPlaylistChangeEventType change);
+ void openPlaylistChangeEvent(IDispatch *dispatch);
+ void mediaChangeEvent(IDispatch *dispatch);
+
+private:
+ IWMPCore3 *m_player;
+ IWMPPlaylist *m_playlist;
+ long m_count;
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpplaylistcontrol.cpp b/src/plugins/wmp/qwmpplaylistcontrol.cpp
new file mode 100644
index 000000000..f4cc12f7f
--- /dev/null
+++ b/src/plugins/wmp/qwmpplaylistcontrol.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpplaylistcontrol.h"
+
+#include "qwmpevents.h"
+#include "qwmpglobal.h"
+#include "qwmpmetadata.h"
+#include "qwmpplaylist.h"
+
+QWmpPlaylistControl::QWmpPlaylistControl(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
+ : QMediaPlaylistControl(parent)
+ , m_player(player)
+ , m_controls(0)
+ , m_playlist(new QWmpPlaylist(player, events))
+ , m_playbackMode(QMediaPlaylist::Sequential)
+{
+ m_player->get_controls(&m_controls);
+
+ connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
+ this, SLOT(currentItemChangeEvent(IDispatch*)));
+}
+
+QWmpPlaylistControl::~QWmpPlaylistControl()
+{
+ if (m_controls)
+ m_controls->Release();
+
+ delete m_playlist;
+}
+
+QMediaPlaylistProvider *QWmpPlaylistControl::playlistProvider() const
+{
+ return m_playlist;
+}
+
+bool QWmpPlaylistControl::setPlaylistProvider(QMediaPlaylistProvider *playlist)
+{
+ Q_UNUSED(playlist);
+
+ return false;
+}
+
+int QWmpPlaylistControl::currentIndex() const
+{
+ int position = 0;
+
+ IWMPMedia *media = 0;
+ if (m_controls && m_player->get_currentMedia(&media) == S_OK) {
+ position = QWmpMetaData::value(media, QAutoBStr(L"PlaylistIndex")).toInt();
+
+ media->Release();
+ }
+
+ return position;
+}
+
+void QWmpPlaylistControl::setCurrentIndex(int position)
+{
+
+ IWMPPlaylist *playlist = 0;
+ if (m_player->get_currentPlaylist(&playlist) == S_OK) {
+ IWMPMedia *media = 0;
+ if (playlist->get_item(position, &media) == S_OK) {
+ m_player->put_currentMedia(media);
+
+ media->Release();
+ }
+ playlist->Release();
+ }
+}
+
+int QWmpPlaylistControl::nextIndex(int steps) const
+{
+ return currentIndex() + steps;
+}
+
+int QWmpPlaylistControl::previousIndex(int steps) const
+{
+ return currentIndex() - steps;
+}
+
+void QWmpPlaylistControl::next()
+{
+ if (m_controls)
+ m_controls->next();
+}
+
+void QWmpPlaylistControl::previous()
+{
+ if (m_controls)
+ m_controls->previous();
+}
+
+QMediaPlaylist::PlaybackMode QWmpPlaylistControl::playbackMode() const
+{
+ return m_playbackMode;
+}
+
+void QWmpPlaylistControl::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+{
+ m_playbackMode = mode;
+}
+
+void QWmpPlaylistControl::currentItemChangeEvent(IDispatch *dispatch)
+{
+ IWMPMedia *media = 0;
+ if (dispatch && dispatch->QueryInterface(
+ __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
+ int index = QWmpMetaData::value(media, QAutoBStr(L"PlaylistIndex")).toInt();
+
+ emit currentIndexChanged(index);
+ emit currentMediaChanged(m_playlist->media(index));
+ }
+}
diff --git a/src/plugins/wmp/qwmpplaylistcontrol.h b/src/plugins/wmp/qwmpplaylistcontrol.h
new file mode 100644
index 000000000..cf519aebb
--- /dev/null
+++ b/src/plugins/wmp/qwmpplaylistcontrol.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPPLAYLISTCONTROL_H
+#define QWMPPLAYLISTCONTROL_H
+
+#include <qmediaplaylistcontrol.h>
+
+#include <wmp.h>
+
+class QWmpEvents;
+class QWmpPlaylist;
+
+QT_USE_NAMESPACE
+class QWmpPlaylistControl : public QMediaPlaylistControl
+{
+ Q_OBJECT
+public:
+ QWmpPlaylistControl(IWMPCore3 *player, QWmpEvents *events, QObject *parent = 0);
+ ~QWmpPlaylistControl();
+
+ QMediaPlaylistProvider *playlistProvider() const;
+ bool setPlaylistProvider(QMediaPlaylistProvider *playlist);
+
+ int currentIndex() const;
+ void setCurrentIndex(int position);
+
+ int nextIndex(int steps) const;
+ int previousIndex(int steps) const;
+
+ void next();
+ void previous();
+
+ QMediaPlaylist::PlaybackMode playbackMode() const;
+ void setPlaybackMode(QMediaPlaylist::PlaybackMode mode);
+
+private slots:
+ void currentItemChangeEvent(IDispatch *dispatch);
+
+private:
+ IWMPCore3 *m_player;
+ IWMPControls *m_controls;
+ QWmpPlaylist *m_playlist;
+ QMediaPlaylist::PlaybackMode m_playbackMode;
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpserviceprovider.cpp b/src/plugins/wmp/qwmpserviceprovider.cpp
new file mode 100644
index 000000000..eec06008e
--- /dev/null
+++ b/src/plugins/wmp/qwmpserviceprovider.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpserviceprovider.h"
+
+#include "qwmpplayerservice.h"
+
+QStringList QWmpServiceProviderPlugin::keys() const
+{
+ return QStringList()
+ << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)
+ << QLatin1String("windowsmediaplayer");
+}
+
+QMediaService *QWmpServiceProviderPlugin::create(const QString &key)
+{
+ if (QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) == key) {
+ QByteArray providerKey = qgetenv("QT_MEDIAPLAYER_PROVIDER");
+ if (!providerKey.isNull() && qstrcmp(providerKey.constData(), "windowsmediaplayer") == 0)
+ return new QWmpPlayerService(QWmpPlayerService::RemoteEmbed);
+
+ return new QWmpPlayerService(QWmpPlayerService::LocalEmbed);
+ }
+ else if (QLatin1String("windowsmediaplayer") == key)
+ return new QWmpPlayerService(QWmpPlayerService::RemoteEmbed);
+
+ return 0;
+}
+
+void QWmpServiceProviderPlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+
+Q_EXPORT_PLUGIN2(qtmedia_wmp, QWmpServiceProviderPlugin);
diff --git a/src/plugins/wmp/qwmpserviceprovider.h b/src/plugins/wmp/qwmpserviceprovider.h
new file mode 100644
index 000000000..d58fb3bc8
--- /dev/null
+++ b/src/plugins/wmp/qwmpserviceprovider.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPSERVICEPROVIDER_H
+#define QWMPSERVICEPROVIDER_H
+
+#include <qmediaserviceprovider.h>
+#include <qmediaserviceproviderplugin.h>
+
+QT_USE_NAMESPACE
+class QWmpServiceProviderPlugin : public QMediaServiceProviderPlugin
+{
+ Q_OBJECT
+public:
+ QStringList keys() const;
+ QMediaService *create(const QString &key);
+ void release(QMediaService *service);
+};
+
+#endif
diff --git a/src/plugins/wmp/qwmpvideooverlay.cpp b/src/plugins/wmp/qwmpvideooverlay.cpp
new file mode 100644
index 000000000..95ff77b6b
--- /dev/null
+++ b/src/plugins/wmp/qwmpvideooverlay.cpp
@@ -0,0 +1,462 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwmpvideooverlay.h"
+
+#include "qwmpglobal.h"
+
+QWmpVideoOverlay::QWmpVideoOverlay(IWMPPlayer4 *player, IOleObject *object, QWmpPlayerService *service)
+ : m_service(service)
+ , m_player(player)
+ , m_object(object)
+ , m_inPlaceObject(0)
+ , m_winId(0)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+ , m_fullScreen(false)
+{
+ HRESULT hr;
+
+ if ((hr = m_object->QueryInterface(
+ __uuidof(IOleInPlaceObject),
+ reinterpret_cast<void **>(&m_inPlaceObject))) != S_OK) {
+ qWarning("No IOleInPlaceObject interface, %x: %s", hr, qwmp_error_string(hr));
+ }
+}
+
+QWmpVideoOverlay::~QWmpVideoOverlay()
+{
+ if (m_inPlaceObject)
+ m_inPlaceObject->Release();
+}
+
+WId QWmpVideoOverlay::winId() const
+{
+ return m_winId;
+}
+
+void QWmpVideoOverlay::setWinId(WId id)
+{
+ m_winId = id;
+
+ if (QWidget *widget = QWidget::find(m_winId)) {
+ const QColor color = widget->palette().color(QPalette::Window);
+
+ m_windowColor = RGB(color.red(), color.green(), color.blue());
+ }
+
+ if (m_inPlaceObject && m_winId) {
+ RECT rcPos =
+ {
+ m_displayRect.left(),
+ m_displayRect.top(),
+ m_displayRect.right(),
+ m_displayRect.bottom()
+ };
+
+ m_inPlaceObject->InPlaceDeactivate();
+ m_object->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, m_service, 0, m_winId, &rcPos);
+ }
+
+
+}
+
+extern HDC Q_GUI_EXPORT qt_win_display_dc();
+
+#define HIMETRIC_PER_INCH 2540
+#define MAP_PIX_TO_LOGHIM(x,ppli) ((HIMETRIC_PER_INCH*(x) + ((ppli)>>1)) / (ppli))
+#define MAP_LOGHIM_TO_PIX(x,ppli) (((ppli)*(x) + HIMETRIC_PER_INCH/2) / HIMETRIC_PER_INCH)
+
+QRect QWmpVideoOverlay::displayRect() const
+{
+ return m_displayRect;
+}
+
+void QWmpVideoOverlay::setDisplayRect(const QRect &rect)
+{
+ m_displayRect = rect;
+
+ if (m_inPlaceObject) {
+ HDC gdc = QT_PREPEND_NAMESPACE(qt_win_display_dc)();
+
+ SIZEL hmSize = {
+ MAP_PIX_TO_LOGHIM(rect.width(), GetDeviceCaps(gdc, LOGPIXELSX)),
+ MAP_PIX_TO_LOGHIM(rect.height(), GetDeviceCaps(gdc, LOGPIXELSY)) };
+
+ m_object->SetExtent(DVASPECT_CONTENT, &hmSize);
+
+ RECT rcClip = { rect.left(), rect.top(), rect.right(), rect.bottom() };
+
+ if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
+ QSize size = m_sizeHint;
+ size.scale(rect.width(), rect.height(), Qt::KeepAspectRatioByExpanding);
+
+ QRect positionRect(QPoint(0, 0), size);
+ positionRect.moveCenter(rect.center());
+
+ RECT rcPos =
+ {
+ positionRect.left(),
+ positionRect.top(),
+ positionRect.right(),
+ positionRect.bottom()
+ };
+
+ m_inPlaceObject->SetObjectRects(&rcPos, &rcClip);
+ } else {
+ m_inPlaceObject->SetObjectRects(&rcClip, &rcClip);
+ }
+ }
+}
+
+bool QWmpVideoOverlay::isFullScreen() const
+{
+ return m_fullScreen;
+}
+
+void QWmpVideoOverlay::setFullScreen(bool fullScreen)
+{
+ m_player->put_fullScreen(fullScreen);
+
+ emit fullScreenChanged(m_fullScreen = fullScreen);
+}
+
+QSize QWmpVideoOverlay::nativeSize() const
+{
+ return m_sizeHint;
+}
+
+void QWmpVideoOverlay::setNativeSize(const QSize &size)
+{
+ if (m_sizeHint != size) {
+ m_sizeHint = size;
+
+ emit nativeSizeChanged();
+ }
+}
+
+Qt::AspectRatioMode QWmpVideoOverlay::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void QWmpVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+
+ m_player->put_stretchToFit(mode != Qt::KeepAspectRatio);
+
+ setDisplayRect(m_displayRect);
+}
+
+void QWmpVideoOverlay::repaint()
+{
+ PAINTSTRUCT paint;
+
+ if (HDC dc = ::BeginPaint(m_winId, &paint)) {
+ HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor);
+ HBRUSH brush = ::CreateSolidBrush(m_windowColor);
+ ::SelectObject(dc, pen);
+ ::SelectObject(dc, brush);
+
+ ::Rectangle(
+ dc,
+ m_displayRect.left(),
+ m_displayRect.top(),
+ m_displayRect.right() + 1,
+ m_displayRect.bottom() + 1);
+
+ ::DeleteObject(pen);
+ ::DeleteObject(brush);
+
+ ::EndPaint(m_winId, &paint);
+ }
+}
+
+int QWmpVideoOverlay::brightness() const
+{
+ return 0;
+}
+
+void QWmpVideoOverlay::setBrightness(int)
+{
+}
+
+int QWmpVideoOverlay::contrast() const
+{
+ return 0;
+}
+
+void QWmpVideoOverlay::setContrast(int)
+{
+}
+
+int QWmpVideoOverlay::hue() const
+{
+ return 0;
+}
+
+void QWmpVideoOverlay::setHue(int)
+{
+}
+
+int QWmpVideoOverlay::saturation() const
+{
+ return 0;
+}
+
+void QWmpVideoOverlay::setSaturation(int)
+{
+}
+
+// IUnknown
+HRESULT QWmpVideoOverlay::QueryInterface(REFIID riid, void **object)
+{
+ return m_service->QueryInterface(riid, object);
+}
+
+ULONG QWmpVideoOverlay::AddRef()
+{
+ return m_service->AddRef();
+}
+
+ULONG QWmpVideoOverlay::Release()
+{
+ return m_service->Release();
+}
+
+// IOleWindow
+HRESULT QWmpVideoOverlay::GetWindow(HWND *phwnd)
+{
+ if (!phwnd) {
+ return E_POINTER;
+ } else {
+ *phwnd = m_winId;
+ return S_OK;
+ }
+}
+
+HRESULT QWmpVideoOverlay::ContextSensitiveHelp(BOOL fEnterMode)
+{
+ Q_UNUSED(fEnterMode);
+
+ return E_NOTIMPL;
+}
+
+// IOleInPlaceSite
+HRESULT QWmpVideoOverlay::CanInPlaceActivate()
+{
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::OnInPlaceActivate()
+{
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::OnUIActivate()
+{
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::GetWindowContext(
+ IOleInPlaceFrame **ppFrame,
+ IOleInPlaceUIWindow **ppDoc,
+ LPRECT lprcPosRect,
+ LPRECT lprcClipRect,
+ LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+ if (!ppFrame || !ppDoc || !lprcPosRect || !lprcClipRect || !lpFrameInfo)
+ return E_POINTER;
+
+ QueryInterface(IID_IOleInPlaceFrame, reinterpret_cast<void **>(ppFrame));
+ QueryInterface(IID_IOleInPlaceUIWindow, reinterpret_cast<void **>(ppDoc));
+
+ if (m_winId) {
+ SetRect(lprcClipRect,
+ m_displayRect.left(),
+ m_displayRect.top(),
+ m_displayRect.right(),
+ m_displayRect.bottom());
+
+ if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
+ QSize size = m_sizeHint;
+ size.scale(
+ m_displayRect.width(),
+ m_displayRect.height(),
+ Qt::KeepAspectRatioByExpanding);
+
+ QRect positionRect(QPoint(0, 0), size);
+ positionRect.moveCenter(m_displayRect.center());
+
+ SetRect(lprcPosRect,
+ positionRect.left(),
+ positionRect.top(),
+ positionRect.right(),
+ positionRect.bottom());
+ } else {
+ *lprcPosRect = *lprcClipRect;
+ }
+ } else {
+ SetRectEmpty(lprcPosRect);
+ SetRectEmpty(lprcClipRect);
+ }
+
+ lpFrameInfo->fMDIApp = FALSE;
+ lpFrameInfo->haccel = 0;
+ lpFrameInfo->cAccelEntries = 0;
+ lpFrameInfo->hwndFrame = m_winId;
+
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::Scroll(SIZE scrollExtant)
+{
+ Q_UNUSED(scrollExtant);
+
+ return S_FALSE;
+}
+
+HRESULT QWmpVideoOverlay::OnUIDeactivate(BOOL fUndoable)
+{
+ Q_UNUSED(fUndoable);
+
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::OnInPlaceDeactivate()
+{
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::DiscardUndoState()
+{
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::DeactivateAndUndo()
+{
+ if (m_inPlaceObject)
+ m_inPlaceObject->UIDeactivate();
+
+ return S_OK;
+}
+
+HRESULT QWmpVideoOverlay::OnPosRectChange(LPCRECT lprcPosRect)
+{
+ Q_UNUSED(lprcPosRect);
+
+ return S_OK;
+}
+
+// IOleInPlaceUIWindow
+HRESULT QWmpVideoOverlay::GetBorder(LPRECT lprectBorder)
+{
+ Q_UNUSED(lprectBorder);
+
+ return INPLACE_E_NOTOOLSPACE;
+}
+
+HRESULT QWmpVideoOverlay::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
+{
+ Q_UNUSED(pborderwidths);
+
+ return INPLACE_E_NOTOOLSPACE;
+}
+
+HRESULT QWmpVideoOverlay::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
+{
+ Q_UNUSED(pborderwidths);
+
+ return OLE_E_INVALIDRECT;
+}
+
+HRESULT QWmpVideoOverlay::SetActiveObject(
+ IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
+{
+ Q_UNUSED(pActiveObject);
+ Q_UNUSED(pszObjName);
+
+ return S_OK;
+}
+
+// IOleInPlaceFrame
+HRESULT QWmpVideoOverlay::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
+{
+ Q_UNUSED(hmenuShared);
+ Q_UNUSED(lpMenuWidths);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpVideoOverlay::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
+{
+ Q_UNUSED(hmenuShared);
+ Q_UNUSED(holemenu);
+ Q_UNUSED(hwndActiveObject);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpVideoOverlay::RemoveMenus(HMENU hmenuShared)
+{
+ Q_UNUSED(hmenuShared);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpVideoOverlay::SetStatusText(LPCOLESTR pszStatusText)
+{
+ Q_UNUSED(pszStatusText);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpVideoOverlay::EnableModeless(BOOL fEnable)
+{
+ Q_UNUSED(fEnable);
+
+ return E_NOTIMPL;
+}
+
+HRESULT QWmpVideoOverlay::TranslateAccelerator(LPMSG lpmsg, WORD wID)
+{
+ return TranslateAccelerator(lpmsg, static_cast<DWORD>(wID));
+}
diff --git a/src/plugins/wmp/qwmpvideooverlay.h b/src/plugins/wmp/qwmpvideooverlay.h
new file mode 100644
index 000000000..3bc1005a7
--- /dev/null
+++ b/src/plugins/wmp/qwmpvideooverlay.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWMPVIDEOOVERLAY_H
+#define QWMPVIDEOOVERLAY_H
+
+#include <qvideowindowcontrol.h>
+
+#include "qwmpplayerservice.h"
+
+#include <wmp.h>
+
+QT_USE_NAMESPACE
+class QWmpVideoOverlay
+ : public QVideoWindowControl
+ , public IOleInPlaceSite
+ , public IOleInPlaceFrame
+{
+ Q_OBJECT
+public:
+ QWmpVideoOverlay(IWMPPlayer4 *player, IOleObject *object, QWmpPlayerService *service);
+ ~QWmpVideoOverlay();
+
+ WId winId() const;
+ void setWinId(WId id);
+
+ QRect displayRect() const;
+ void setDisplayRect(const QRect &rect);
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ void repaint();
+
+ QSize nativeSize() const;
+ void setNativeSize(const QSize &size);
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ // IOleWindow
+ HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
+ HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
+
+ // IOleInPlaceSite
+ HRESULT STDMETHODCALLTYPE CanInPlaceActivate();
+ HRESULT STDMETHODCALLTYPE OnInPlaceActivate();
+ HRESULT STDMETHODCALLTYPE OnUIActivate();
+ HRESULT STDMETHODCALLTYPE GetWindowContext(
+ IOleInPlaceFrame **ppFrame,
+ IOleInPlaceUIWindow **ppDoc,
+ LPRECT lprcPosRect,
+ LPRECT lprcClipRect,
+ LPOLEINPLACEFRAMEINFO lpFrameInfo);
+ HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtant);
+ HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable);
+ HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate();
+ HRESULT STDMETHODCALLTYPE DiscardUndoState();
+ HRESULT STDMETHODCALLTYPE DeactivateAndUndo();
+ HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect);
+
+ // IOleInPlaceUIWindow
+ HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder);
+ HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths);
+ HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS pborderwidths);
+ HRESULT STDMETHODCALLTYPE SetActiveObject(
+ IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName);
+
+ // IOleInPlaceFrame
+ HRESULT STDMETHODCALLTYPE InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
+ HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject);
+ HRESULT STDMETHODCALLTYPE RemoveMenus(HMENU hmenuShared);
+ HRESULT STDMETHODCALLTYPE SetStatusText(LPCOLESTR pszStatusText);
+ HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable);
+ HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD wID);
+
+private:
+ QWmpPlayerService *m_service;
+ IWMPPlayer4 *m_player;
+ IOleObject *m_object;
+ IOleInPlaceObject *m_inPlaceObject;
+ WId m_winId;
+ COLORREF m_windowColor;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QSize m_sizeHint;
+ QRect m_displayRect;
+ bool m_fullScreen;
+};
+
+#endif
diff --git a/src/plugins/wmp/wmp.pro b/src/plugins/wmp/wmp.pro
new file mode 100644
index 000000000..1b544bbeb
--- /dev/null
+++ b/src/plugins/wmp/wmp.pro
@@ -0,0 +1,47 @@
+TEMPLATE = lib
+CONFIG += plugin
+TARGET = $$qtLibraryTarget(qtmedia_wmp)
+
+PLUGIN_TYPE=mediaservice
+
+INCLUDEPATH+=../../../src/multimedia
+include(../../../common.pri)
+
+CONFIG += mobility
+MOBILITY = multimedia
+LIBS += -lstrmiids -lole32 -lOleaut32 -luser32 -lgdi32
+
+HEADERS = \
+ qmfactivate.h \
+ qwmpevents.h \
+ qwmpglobal.h \
+ qwmpmetadata.h \
+ qwmpplayercontrol.h \
+ qwmpplayerservice.h \
+ qwmpplaylist.h \
+ qwmpplaylistcontrol.h \
+ qwmpserviceprovider.h \
+ qwmpvideooverlay.h
+
+SOURCES = \
+ qmfactivate.cpp \
+ qwmpevents.cpp \
+ qwmpglobal.cpp \
+ qwmpmetadata.cpp \
+ qwmpplayercontrol.cpp \
+ qwmpplayerservice.cpp \
+ qwmpplaylist.cpp \
+ qwmpplaylistcontrol.cpp \
+ qwmpserviceprovider.cpp \
+ qwmpvideooverlay.cpp
+
+contains(evr_enabled, yes) {
+ HEADERS += \
+ qevrvideooverlay.h
+
+ SOURCES += \
+ qevrvideooverlay.cpp
+
+ DEFINES += \
+ QWMP_EVR
+}