pkgsrc/emulators/wine/patches/patch-dlls_wineoss.drv_mmdevdrv.c
adam ebc7be42e7 Changes 1.6.2:
- Color management support updated to liblcms version 2.
- Various bug fixes.
2014-01-17 09:01:58 +00:00

311 lines
8.8 KiB
C

$NetBSD: patch-dlls_wineoss.drv_mmdevdrv.c,v 1.1 2014/01/17 09:01:58 adam Exp $
Restore OSSv3 support for NetBSD.
--- dlls/wineoss.drv/mmdevdrv.c.orig 2013-11-15 19:30:24.000000000 +0000
+++ dlls/wineoss.drv/mmdevdrv.c
@@ -55,6 +55,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(oss);
+#ifndef HAVE_OSSv4
+#define OSS_DEVNODE_SIZE 255
+#endif
+
#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
static const REFERENCE_TIME DefaultPeriod = 200000;
@@ -111,7 +115,9 @@ struct ACImpl {
float *vols;
int fd;
+#ifdef HAVE_OSSv4
oss_audioinfo ai;
+#endif
char devnode[OSS_DEVNODE_SIZE];
BOOL initted, playing;
@@ -269,7 +275,9 @@ enum DriverPriority {
int WINAPI AUDDRV_GetPriority(void)
{
int mixer_fd;
+#ifdef HAVE_OSSv4
oss_sysinfo sysinfo;
+#endif
/* Attempt to determine if we are running on OSS or ALSA's OSS
* compatibility layer. There is no official way to do that, so just check
@@ -282,6 +290,7 @@ int WINAPI AUDDRV_GetPriority(void)
return Priority_Unavailable;
}
+#ifdef HAVE_OSSv4
sysinfo.version[0] = 0xFF;
sysinfo.versionnum = ~0;
if(ioctl(mixer_fd, SNDCTL_SYSINFO, &sysinfo) < 0){
@@ -289,9 +298,11 @@ int WINAPI AUDDRV_GetPriority(void)
close(mixer_fd);
return Priority_Unavailable;
}
+#endif
close(mixer_fd);
+#ifdef HAVE_OSSv4
if(sysinfo.version[0] < '4' || sysinfo.version[0] > '9'){
TRACE("Priority_Low: sysinfo.version[0]: %x\n", sysinfo.version[0]);
return Priority_Low;
@@ -300,6 +311,7 @@ int WINAPI AUDDRV_GetPriority(void)
TRACE("Priority_Low: sysinfo.versionnum: %x\n", sysinfo.versionnum);
return Priority_Low;
}
+#endif
TRACE("Priority_Preferred: Seems like valid OSS!\n");
@@ -406,29 +418,34 @@ static UINT get_default_index(EDataFlow
{
int fd = -1, err;
UINT i;
+#ifdef HAVE_OSSv4
oss_audioinfo ai;
+#endif
const char *devnode;
OSSDevice *dev_item;
if(flow == eRender)
- fd = open("/dev/dsp", O_WRONLY | O_NONBLOCK);
+ fd = open("/dev/audio", O_WRONLY | O_NONBLOCK);
else
- fd = open("/dev/dsp", O_RDONLY | O_NONBLOCK);
+ fd = open("/dev/audio", O_RDONLY | O_NONBLOCK);
if(fd < 0){
WARN("Couldn't open default device!\n");
return 0;
}
+#ifdef HAVE_OSSv4
ai.dev = -1;
if((err = ioctl(fd, SNDCTL_ENGINEINFO, &ai)) < 0){
WARN("SNDCTL_ENGINEINFO failed: %d (%s)\n", err, strerror(errno));
close(fd);
return 0;
}
+#endif
close(fd);
+#ifdef HAVE_OSSv4
TRACE("Default devnode: %s\n", ai.devnode);
devnode = oss_clean_devnode(ai.devnode);
i = 0;
@@ -439,6 +456,7 @@ static UINT get_default_index(EDataFlow
++i;
}
}
+#endif
WARN("Couldn't find default device! Choosing first.\n");
return 0;
@@ -448,7 +466,9 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDa
UINT *num, UINT *def_index)
{
int i, mixer_fd;
+#ifdef HAVE_OSSv4
oss_sysinfo sysinfo;
+#endif
static int print_once = 0;
static const WCHAR outW[] = {'O','u','t',':',' ',0};
@@ -462,6 +482,7 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDa
return AUDCLNT_E_SERVICE_NOT_RUNNING;
}
+#ifdef HAVE_OSSv4
if(ioctl(mixer_fd, SNDCTL_SYSINFO, &sysinfo) < 0){
close(mixer_fd);
@@ -574,6 +595,55 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDa
}
}
+#else
+ *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
+ *guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
+
+ *num = 0;
+ const char *devnode;
+ OSSDevice *dev_item;
+ devnode = oss_clean_devnode("/dev/audio");
+ size_t len, prefix_len;
+ const WCHAR *prefix;
+
+ dev_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*dev_item));
+
+ dev_item->flow = flow;
+ get_device_guid(flow, devnode, &dev_item->guid);
+ strcpy(dev_item->devnode, devnode);
+
+ (*guids)[*num] = dev_item->guid;
+
+ len = MultiByteToWideChar(CP_UNIXCP, 0, "OSS AUDIO", -1, NULL, 0);
+ if(flow == eRender){
+ prefix = outW;
+ prefix_len = (sizeof(outW) / sizeof(*outW)) - 1;
+ len += prefix_len;
+ }else{
+ prefix = inW;
+ prefix_len = (sizeof(inW) / sizeof(*inW)) - 1;
+ len += prefix_len;
+ }
+ (*ids)[*num] = HeapAlloc(GetProcessHeap(), 0,
+ len * sizeof(WCHAR));
+ if(!(*ids)[*num]){
+ for(i = 0; i < *num; ++i)
+ HeapFree(GetProcessHeap(), 0, (*ids)[i]);
+ HeapFree(GetProcessHeap(), 0, *ids);
+ HeapFree(GetProcessHeap(), 0, *guids);
+ HeapFree(GetProcessHeap(), 0, dev_item);
+ close(mixer_fd);
+ return E_OUTOFMEMORY;
+ }
+ memcpy((*ids)[*num], prefix, prefix_len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_UNIXCP, 0, "OSS_AUDIO", -1,
+ (*ids)[*num] + prefix_len, len - prefix_len);
+
+ list_add_tail(&g_devices, &dev_item->entry);
+
+ (*num)++;
+#endif
+
close(mixer_fd);
*def_index = get_default_index(flow);
@@ -625,6 +695,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(G
This->dataflow = oss_dev->flow;
+#ifdef HAVE_OSSv4
This->ai.dev = -1;
if(ioctl(This->fd, SNDCTL_ENGINEINFO, &This->ai) < 0){
WARN("Unable to get audio info for device %s: %d (%s)\n", oss_dev->devnode,
@@ -633,9 +704,11 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(G
HeapFree(GetProcessHeap(), 0, This);
return E_FAIL;
}
+#endif
strcpy(This->devnode, oss_dev->devnode);
+#ifdef HAVE_OSSv4
TRACE("OSS audioinfo:\n");
TRACE("devnode: %s\n", This->ai.devnode);
TRACE("name: %s\n", This->ai.name);
@@ -648,6 +721,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(G
TRACE("max_rate: %d\n", This->ai.max_rate);
TRACE("min_channels: %d\n", This->ai.min_channels);
TRACE("max_channels: %d\n", This->ai.max_channels);
+#endif
This->IAudioClient_iface.lpVtbl = &AudioClient_Vtbl;
This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
@@ -794,10 +868,12 @@ static int get_oss_format(const WAVEFORM
return AFMT_U8;
case 16:
return AFMT_S16_LE;
+#ifdef HAVE_OSSv4
case 24:
return AFMT_S24_LE;
case 32:
return AFMT_S32_LE;
+#endif
}
return -1;
}
@@ -1241,10 +1317,14 @@ static HRESULT WINAPI AudioClient_IsForm
outpwfx = NULL;
}
+#ifndef __NetBSD__
if(This->dataflow == eRender)
fd = open(This->devnode, O_WRONLY | O_NONBLOCK, 0);
else if(This->dataflow == eCapture)
fd = open(This->devnode, O_RDONLY | O_NONBLOCK, 0);
+#else
+ fd = This->fd;
+#endif
if(fd < 0){
WARN("Unable to open device %s: %d (%s)\n", This->devnode, errno,
@@ -1254,7 +1334,9 @@ static HRESULT WINAPI AudioClient_IsForm
ret = setup_oss_device(mode, fd, pwfx, outpwfx);
+#ifndef __NetBSD__
close(fd);
+#endif
return ret;
}
@@ -1272,11 +1354,19 @@ static HRESULT WINAPI AudioClient_GetMix
return E_POINTER;
*pwfx = NULL;
- if(This->dataflow == eRender)
+ if(This->dataflow == eRender) {
+#if HAVE_OSSv4
formats = This->ai.oformats;
- else if(This->dataflow == eCapture)
+#else
+ formats = AFMT_S16_LE;
+#endif
+ } else if(This->dataflow == eCapture) {
+#if HAVE_OSSv4
formats = This->ai.iformats;
- else
+#else
+ formats = AFMT_S16_LE;
+#endif
+ } else
return E_UNEXPECTED;
fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
@@ -1295,12 +1385,14 @@ static HRESULT WINAPI AudioClient_GetMix
}else if(formats & AFMT_U8){
fmt->Format.wBitsPerSample = 8;
fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+#ifdef HAVE_OSSv4
}else if(formats & AFMT_S32_LE){
fmt->Format.wBitsPerSample = 32;
fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
}else if(formats & AFMT_S24_LE){
fmt->Format.wBitsPerSample = 24;
fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+#endif
}else{
WARN("Didn't recognize any available OSS formats: %x\n", formats);
CoTaskMemFree(fmt);
@@ -1309,16 +1401,22 @@ static HRESULT WINAPI AudioClient_GetMix
/* some OSS drivers are buggy, so set reasonable defaults if
* the reported values seem wacky */
+#ifdef HAVE_OSSv4
fmt->Format.nChannels = max(This->ai.max_channels, This->ai.min_channels);
if(fmt->Format.nChannels == 0 || fmt->Format.nChannels > 8)
+#endif
fmt->Format.nChannels = 2;
+#ifdef HAVE_OSSv4
if(This->ai.max_rate == 0)
+#endif
fmt->Format.nSamplesPerSec = 44100;
+#ifdef HAVE_OSSv4
else
fmt->Format.nSamplesPerSec = min(This->ai.max_rate, 44100);
if(fmt->Format.nSamplesPerSec < This->ai.min_rate)
fmt->Format.nSamplesPerSec = This->ai.min_rate;
+#endif
fmt->dwChannelMask = get_channel_mask(fmt->Format.nChannels);