20#if defined(EXPERIMENTAL_DEVICE_CHANGE_HANDLER)
22#if defined(HAVE_DEVICE_CHANGE)
31#include <mmdeviceapi.h>
32#include <audioclient.h>
34class DeviceChangeListener final :
public IMMNotificationClient,
35 public DeviceChangeInterface
38 DeviceChangeListener()
46 virtual ~DeviceChangeListener()
50 mEnumerator->UnregisterEndpointNotificationCallback(
this);
62 ULONG STDMETHODCALLTYPE AddRef()
64 return InterlockedIncrement(&mRefCnt);
67 ULONG STDMETHODCALLTYPE
Release()
69 ULONG cnt = InterlockedDecrement(&mRefCnt);
77 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
79 if (riid == IID_IUnknown)
82 *ppvInterface = (IUnknown *)
this;
84 else if (riid == __uuidof(IMMNotificationClient))
87 *ppvInterface = (IMMNotificationClient *)
this;
100 HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged( EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
105 HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId)
110 HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId)
115 HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
128 HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId,
const PROPERTYKEY
key)
139 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
141 CLSCTX_INPROC_SERVER,
142 __uuidof(IMMDeviceEnumerator),
143 (
void**)&mEnumerator);
144 if (hr == S_OK && mEnumerator)
146 mEnumerator->RegisterEndpointNotificationCallback(
this);
149 return hr == S_OK && mEnumerator;
152 void Enable(
bool enable)
161 IMMDeviceEnumerator *mEnumerator;
164#elif defined(__WXGTK__)
171class DeviceChangeListener final :
public DeviceChangeInterface
174 DeviceChangeListener()
181 virtual ~DeviceChangeListener()
185 pthread_cancel(mThread);
195 return pthread_create(&mThread, NULL, DeviceChangeListener::Listener,
this) == 0;
198 void Enable(
bool enable)
203 static void *Listener(
void *parm)
205 DeviceChangeListener *This = (DeviceChangeListener *) parm;
208 struct udev *udev = udev_new();
215 struct udev_monitor *mon = udev_monitor_new_from_netlink(udev,
"udev");
218 udev_monitor_enable_receiving(mon);
221 int fd = udev_monitor_get_fd(mon);
230 if (select(fd + 1, &
set, NULL, NULL, NULL) < 0)
235 if (FD_ISSET(fd, &
set))
237 struct udev_device *dev = udev_monitor_receive_device(mon);
241 wxPrintf(
"Got Device\n");
242 wxPrintf(
" Node: %s\n", udev_device_get_devnode(dev));
243 wxPrintf(
" Subsystem: %s\n", udev_device_get_subsystem(dev));
244 wxPrintf(
" Devtype: %s\n", udev_device_get_devtype(dev));
245 wxPrintf(
" Action: %s\n", udev_device_get_action(dev));
249 This->mEnabled =
false;
255 udev_device_unref(dev);
271#elif defined(__WXMAC__)
273#include <CoreAudio/CoreAudio.h>
275class DeviceChangeListener final :
public DeviceChangeInterface
278 DeviceChangeListener()
285 virtual ~DeviceChangeListener()
289 AudioObjectPropertyAddress property_address;
291 property_address.mSelector = kAudioHardwarePropertyDevices;
292 property_address.mScope = kAudioObjectPropertyScopeGlobal;
293 property_address.mElement = kAudioObjectPropertyElementMaster;
295 AudioObjectRemovePropertyListener(kAudioObjectSystemObject,
297 DeviceChangeListener::Listener,
308 AudioObjectPropertyAddress property_address;
310 property_address.mSelector = kAudioHardwarePropertyDevices;
311 property_address.mScope = kAudioObjectPropertyScopeGlobal;
312 property_address.mElement = kAudioObjectPropertyElementMaster;
314 mListening = AudioObjectAddPropertyListener(kAudioObjectSystemObject,
316 DeviceChangeListener::Listener,
321 void Enable(
bool enable)
326 static OSStatus Listener(AudioObjectID objectID,
327 UInt32 numberAddresses,
328 const AudioObjectPropertyAddress inAddresses[],
331 DeviceChangeListener *This = (DeviceChangeListener *) clientData;
333 for (
int i = 0; i < numberAddresses; i++)
336 wxPrintf(
"address %d\n", i);
337 wxPrintf(
"selector %08x\n", inAddresses[i].mSelector);
338 wxPrintf(
"scope %08x\n", inAddresses[i].mScope);
339 wxPrintf(
"element %08x\n", inAddresses[i].mElement);
343 This->mEnabled =
false;
360BEGIN_EVENT_TABLE(DeviceChangeHandler, wxEvtHandler)
361 EVT_TIMER(wxID_ANY, DeviceChangeHandler::OnTimer)
364DeviceChangeHandler::DeviceChangeHandler()
367 mTimer.SetOwner(
this);
368 mListener = std::make_unique<DeviceChangeListener>();
369 mListener->SetHandler(
this);
370 mListener->Enable(
true);
373 mSubscription = this->Subscribe(*
this, &DeviceChangeHandler::OnChange);
376DeviceChangeHandler::~DeviceChangeHandler()
379 mListener->Enable(
false);
382void DeviceChangeHandler::Enable(
bool enable)
384 mListener->Enable(enable);
390 mTimer.Start(500,
true);
393void DeviceChangeHandler::OnTimer(wxTimerEvent & evt)
395 DeviceChangeNotification();
396 mListener->Enable(
true);
Toolkit-neutral facade for basic user interface services.
An object that sends messages to an open-ended list of subscribed callbacks.
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
void Release(wxWindow *handler)
AuthorizationHandler handler