mmdevapi: Attempt to determine default devices from the registry.
This uses a new, Wine-specific registry key <HKCU\Software\Wine\Drivers\wine<driver>.drv> to determine the correct device to use for the various defaults. The drivers still supply their own defaults which will be chosen if no registry entry is defined. For portability we use a driver-specific key in order to support default devices for each of the driver backends.
This commit is contained in:
parent
b07a82c01d
commit
66724f617e
|
@ -909,21 +909,79 @@ static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, E
|
|||
static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)
|
||||
{
|
||||
MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface);
|
||||
WCHAR reg_key[256];
|
||||
HKEY key;
|
||||
HRESULT hr;
|
||||
|
||||
static const WCHAR slashW[] = {'\\',0};
|
||||
static const WCHAR reg_out_nameW[] = {'D','e','f','a','u','l','t','O','u','t','p','u','t',0};
|
||||
static const WCHAR reg_vout_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','O','u','t','p','u','t',0};
|
||||
static const WCHAR reg_in_nameW[] = {'D','e','f','a','u','l','t','I','n','p','u','t',0};
|
||||
static const WCHAR reg_vin_nameW[] = {'D','e','f','a','u','l','t','V','o','i','c','e','I','n','p','u','t',0};
|
||||
|
||||
TRACE("(%p)->(%u,%u,%p)\n", This, flow, role, device);
|
||||
|
||||
if (!device)
|
||||
return E_POINTER;
|
||||
|
||||
if((flow != eRender && flow != eCapture) ||
|
||||
(role != eConsole && role != eMultimedia && role != eCommunications)){
|
||||
WARN("Unknown flow (%u) or role (%u)\n", flow, role);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*device = NULL;
|
||||
|
||||
if(!drvs.module_name[0])
|
||||
return E_NOTFOUND;
|
||||
|
||||
lstrcpyW(reg_key, drv_keyW);
|
||||
lstrcatW(reg_key, slashW);
|
||||
lstrcatW(reg_key, drvs.module_name);
|
||||
|
||||
if(RegOpenKeyW(HKEY_CURRENT_USER, reg_key, &key) == ERROR_SUCCESS){
|
||||
const WCHAR *reg_x_name, *reg_vx_name;
|
||||
WCHAR def_id[256];
|
||||
DWORD size = sizeof(def_id);
|
||||
|
||||
if(flow == eRender){
|
||||
reg_x_name = reg_out_nameW;
|
||||
reg_vx_name = reg_vout_nameW;
|
||||
}else{
|
||||
reg_x_name = reg_in_nameW;
|
||||
reg_vx_name = reg_vin_nameW;
|
||||
}
|
||||
|
||||
if(role == eCommunications &&
|
||||
RegQueryValueExW(key, reg_vx_name, 0, NULL,
|
||||
(BYTE*)def_id, &size) == ERROR_SUCCESS){
|
||||
hr = IMMDeviceEnumerator_GetDevice(iface, def_id, device);
|
||||
if(SUCCEEDED(hr)){
|
||||
RegCloseKey(key);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
TRACE("Unable to find voice device %s\n", wine_dbgstr_w(def_id));
|
||||
}
|
||||
|
||||
if(RegQueryValueExW(key, reg_x_name, 0, NULL,
|
||||
(BYTE*)def_id, &size) == ERROR_SUCCESS){
|
||||
hr = IMMDeviceEnumerator_GetDevice(iface, def_id, device);
|
||||
if(SUCCEEDED(hr)){
|
||||
RegCloseKey(key);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
TRACE("Unable to find device %s\n", wine_dbgstr_w(def_id));
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
if (flow == eRender)
|
||||
*device = &MMDevice_def_play->IMMDevice_iface;
|
||||
else if (flow == eCapture)
|
||||
*device = &MMDevice_def_rec->IMMDevice_iface;
|
||||
else
|
||||
{
|
||||
WARN("Unknown flow %u\n", flow);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
*device = &MMDevice_def_rec->IMMDevice_iface;
|
||||
|
||||
if (!*device)
|
||||
return E_NOTFOUND;
|
||||
|
|
|
@ -53,6 +53,9 @@ static HINSTANCE instance;
|
|||
|
||||
DriverFuncs drvs;
|
||||
|
||||
const WCHAR drv_keyW[] = {'S','o','f','t','w','a','r','e','\\',
|
||||
'W','i','n','e','\\','D','r','i','v','e','r','s',0};
|
||||
|
||||
static const char *get_priority_string(int prio)
|
||||
{
|
||||
switch(prio){
|
||||
|
@ -106,8 +109,6 @@ static BOOL load_driver(const WCHAR *name, DriverFuncs *driver)
|
|||
|
||||
static BOOL init_driver(void)
|
||||
{
|
||||
static const WCHAR drv_key[] = {'S','o','f','t','w','a','r','e','\\',
|
||||
'W','i','n','e','\\','D','r','i','v','e','r','s',0};
|
||||
static const WCHAR drv_value[] = {'A','u','d','i','o',0};
|
||||
|
||||
static WCHAR default_list[] = {'a','l','s','a',',','o','s','s',',',
|
||||
|
@ -120,7 +121,7 @@ static BOOL init_driver(void)
|
|||
if(drvs.module)
|
||||
return TRUE;
|
||||
|
||||
if(RegOpenKeyW(HKEY_CURRENT_USER, drv_key, &key) == ERROR_SUCCESS){
|
||||
if(RegOpenKeyW(HKEY_CURRENT_USER, drv_keyW, &key) == ERROR_SUCCESS){
|
||||
DWORD size = sizeof(reg_list);
|
||||
|
||||
if(RegQueryValueExW(key, drv_value, 0, NULL, (BYTE*)reg_list,
|
||||
|
|
|
@ -75,3 +75,5 @@ typedef struct MMDevice {
|
|||
|
||||
extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolume **ppv) DECLSPEC_HIDDEN;
|
||||
|
||||
extern const WCHAR drv_keyW[] DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue