Merge pull request #4407 from Montellese/jsonrpc_fix_datetime_reset
[vuplus_xbmc] / xbmc / win32 / IMMNotificationClient.h
1 //#pragma once
2 /*
3  *      Copyright (C) 2014 Team XBMC
4  *      http://xbmc.org
5  *
6  *  This Program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2, or (at your option)
9  *  any later version.
10  *
11  *  This Program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with XBMC; see the file COPYING.  If not, see
18  *  <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include <Audioclient.h>
23 #include <mmdeviceapi.h>
24 #include "system.h" // for SAFE_RELEASE
25 #include "utils/log.h"
26 #include "cores/AudioEngine/AEFactory.h"
27
28 class CMMNotificationClient : public IMMNotificationClient
29 {
30   LONG _cRef;
31   IMMDeviceEnumerator *_pEnumerator;
32
33
34 public:
35   CMMNotificationClient() : _cRef(1), _pEnumerator(NULL)
36   {
37   }
38
39   ~CMMNotificationClient()
40   {
41     SAFE_RELEASE(_pEnumerator);
42   }
43
44   // IUnknown methods -- AddRef, Release, and QueryInterface
45
46   ULONG STDMETHODCALLTYPE AddRef()
47   {
48     return InterlockedIncrement(&_cRef);
49   }
50
51   ULONG STDMETHODCALLTYPE Release()
52   {
53     ULONG ulRef = InterlockedDecrement(&_cRef);
54     if (0 == ulRef)
55     {
56       delete this;
57     }
58     return ulRef;
59   }
60
61   HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
62   {
63     if (IID_IUnknown == riid)
64     {
65       AddRef();
66       *ppvInterface = (IUnknown*)this;
67     }
68     else if (__uuidof(IMMNotificationClient) == riid)
69     {
70       AddRef();
71       *ppvInterface = (IMMNotificationClient*)this;
72     }
73     else
74     {
75       *ppvInterface = NULL;
76       return E_NOINTERFACE;
77     }
78     return S_OK;
79   }
80
81   // Callback methods for device-event notifications.
82
83   HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
84   {
85     // if the default device changes this function is called four times.
86     // therefore we call CAEFactory::DeviceChange() only for one role.
87     char  *pszFlow = "?????";
88     char  *pszRole = "?????";
89
90     switch (flow)
91     {
92     case eRender:
93       pszFlow = "eRender";
94       break;
95     case eCapture:
96       pszFlow = "eCapture";
97       break;
98     }
99
100     switch (role)
101     {
102     case eConsole:
103       pszRole = "eConsole";
104       break;
105     case eMultimedia:
106       pszRole = "eMultimedia";
107       break;
108     case eCommunications:
109       pszRole = "eCommunications";
110       CAEFactory::DeviceChange();
111       break;
112     }
113
114     CLog::Log(LOGDEBUG, "%s: New default device: flow = %s, role = %s", __FUNCTION__, pszFlow, pszRole);
115     return S_OK;
116   }
117
118   HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId)
119   {
120     CLog::Log(LOGDEBUG, "%s: Added device: %s", __FUNCTION__, pwstrDeviceId);
121     CAEFactory::DeviceChange();
122     return S_OK;
123   }
124
125   HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId)
126   {
127     CLog::Log(LOGDEBUG, "%s: Removed device: %s", __FUNCTION__, pwstrDeviceId);
128     CAEFactory::DeviceChange();
129     return S_OK;
130   }
131
132   HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
133   {
134     char  *pszState = "?????";
135
136     switch (dwNewState)
137     {
138     case DEVICE_STATE_ACTIVE:
139       pszState = "ACTIVE";
140       break;
141     case DEVICE_STATE_DISABLED:
142       pszState = "DISABLED";
143       break;
144     case DEVICE_STATE_NOTPRESENT:
145       pszState = "NOTPRESENT";
146       break;
147     case DEVICE_STATE_UNPLUGGED:
148       pszState = "UNPLUGGED";
149       break;
150     }
151     CLog::Log(LOGDEBUG, "%s: New device state is DEVICE_STATE_%s", __FUNCTION__, pszState);
152     CAEFactory::DeviceChange();
153     return S_OK;
154   }
155
156   HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
157   {
158     CLog::Log(LOGDEBUG, "%s: Changed device property of %s is {%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}#%d", 
159               __FUNCTION__, pwstrDeviceId, key.fmtid.Data1, key.fmtid.Data2, key.fmtid.Data3,
160                                            key.fmtid.Data4[0], key.fmtid.Data4[1],
161                                            key.fmtid.Data4[2], key.fmtid.Data4[3],
162                                            key.fmtid.Data4[4], key.fmtid.Data4[5],
163                                            key.fmtid.Data4[6], key.fmtid.Data4[7],
164                                            key.pid);
165     return S_OK;
166   }
167 };