Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
March 2022
- 80 participants
- 950 discussions
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/alsa.c | 181 ++++++++++++++++++++++++++++++++++-
dlls/winealsa.drv/mmdevdrv.c | 177 ++++------------------------------
dlls/winealsa.drv/unixlib.h | 13 +++
3 files changed, 213 insertions(+), 158 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
index c199a2e603d..085066622c0 100644
--- a/dlls/winealsa.drv/alsa.c
+++ b/dlls/winealsa.drv/alsa.c
@@ -34,13 +34,13 @@
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
+#include "initguid.h"
#include "mmdeviceapi.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "wine/unixlib.h"
-#include "initguid.h"
#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(alsa);
@@ -2241,6 +2241,184 @@ static NTSTATUS is_started(void *args)
return alsa_unlock_result(stream, ¶ms->result, stream->started ? S_OK : S_FALSE);
}
+static unsigned int alsa_probe_num_speakers(char *name)
+{
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *params;
+ int err;
+ unsigned int max_channels = 0;
+
+ if ((err = snd_pcm_open(&handle, name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
+ WARN("The device \"%s\" failed to open: %d (%s).\n",
+ name, err, snd_strerror(err));
+ return 0;
+ }
+
+ params = malloc(snd_pcm_hw_params_sizeof());
+ if (!params) {
+ WARN("Out of memory.\n");
+ snd_pcm_close(handle);
+ return 0;
+ }
+
+ if ((err = snd_pcm_hw_params_any(handle, params)) < 0) {
+ WARN("snd_pcm_hw_params_any failed for \"%s\": %d (%s).\n",
+ name, err, snd_strerror(err));
+ goto exit;
+ }
+
+ if ((err = snd_pcm_hw_params_get_channels_max(params,
+ &max_channels)) < 0){
+ WARN("Unable to get max channels: %d (%s)\n", err, snd_strerror(err));
+ goto exit;
+ }
+
+exit:
+ free(params);
+ snd_pcm_close(handle);
+
+ return max_channels;
+}
+
+enum AudioDeviceConnectionType {
+ AudioDeviceConnectionType_Unknown = 0,
+ AudioDeviceConnectionType_PCI,
+ AudioDeviceConnectionType_USB
+};
+
+static NTSTATUS get_prop_value(void *args)
+{
+ struct get_prop_value_params *params = args;
+ const char *name = params->alsa_name;
+ EDataFlow flow = params->flow;
+ const GUID *guid = params->guid;
+ const PROPERTYKEY *prop = params->prop;
+ PROPVARIANT *out = params->value;
+ static const PROPERTYKEY devicepath_key = { /* undocumented? - {b3f8fa53-0004-438e-9003-51a46e139bfc},2 */
+ {0xb3f8fa53, 0x0004, 0x438e, {0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc}}, 2
+ };
+
+ if(IsEqualPropertyKey(*prop, devicepath_key))
+ {
+ char uevent[MAX_PATH];
+ FILE *fuevent;
+ int card, device;
+
+ /* only implemented for identifiable devices, i.e. not "default" */
+ if(!sscanf(name, "plughw:%u,%u", &card, &device)){
+ params->result = E_NOTIMPL;
+ return STATUS_SUCCESS;
+ }
+ sprintf(uevent, "/sys/class/sound/card%u/device/uevent", card);
+ fuevent = fopen(uevent, "r");
+
+ if(fuevent){
+ enum AudioDeviceConnectionType connection = AudioDeviceConnectionType_Unknown;
+ USHORT vendor_id = 0, product_id = 0;
+ char line[256];
+
+ while (fgets(line, sizeof(line), fuevent)) {
+ char *val;
+ size_t val_len;
+
+ if((val = strchr(line, '='))) {
+ val[0] = 0;
+ val++;
+
+ val_len = strlen(val);
+ if(val_len > 0 && val[val_len - 1] == '\n') { val[val_len - 1] = 0; }
+
+ if(!strcmp(line, "PCI_ID")){
+ connection = AudioDeviceConnectionType_PCI;
+ if(sscanf(val, "%hX:%hX", &vendor_id, &product_id)<2){
+ WARN("Unexpected input when reading PCI_ID in uevent file.\n");
+ connection = AudioDeviceConnectionType_Unknown;
+ break;
+ }
+ }else if(!strcmp(line, "DEVTYPE") && !strcmp(val,"usb_interface"))
+ connection = AudioDeviceConnectionType_USB;
+ else if(!strcmp(line, "PRODUCT"))
+ if(sscanf(val, "%hx/%hx/", &vendor_id, &product_id)<2){
+ WARN("Unexpected input when reading PRODUCT in uevent file.\n");
+ connection = AudioDeviceConnectionType_Unknown;
+ break;
+ }
+ }
+ }
+
+ fclose(fuevent);
+
+ if(connection == AudioDeviceConnectionType_USB || connection == AudioDeviceConnectionType_PCI){
+ UINT serial_number;
+ char buf[128];
+ int len;
+
+ /* As hardly any audio devices have serial numbers, Windows instead
+ appears to use a persistent random number. We emulate this here
+ by instead using the last 8 hex digits of the GUID. */
+ serial_number = (guid->Data4[4] << 24) | (guid->Data4[5] << 16) | (guid->Data4[6] << 8) | guid->Data4[7];
+
+ if(connection == AudioDeviceConnectionType_USB)
+ sprintf(buf, "{1}.USB\\VID_%04X&PID_%04X\\%u&%08X",
+ vendor_id, product_id, device, serial_number);
+ else /* AudioDeviceConnectionType_PCI */
+ sprintf(buf, "{1}.HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X\\%u&%08X",
+ vendor_id, product_id, device, serial_number);
+
+ len = strlen(buf) + 1;
+ if(*params->buffer_size < len * sizeof(WCHAR)){
+ params->result = E_NOT_SUFFICIENT_BUFFER;
+ *params->buffer_size = len * sizeof(WCHAR);
+ return STATUS_SUCCESS;
+ }
+ out->vt = VT_LPWSTR;
+ out->pwszVal = params->buffer;
+ ntdll_umbstowcs(buf, len, out->pwszVal, len);
+ params->result = S_OK;
+ return STATUS_SUCCESS;
+ }
+ }else{
+ WARN("Could not open %s for reading\n", uevent);
+ params->result = E_NOTIMPL;
+ return STATUS_SUCCESS;
+ }
+ } else if (flow != eCapture && IsEqualPropertyKey(*prop, PKEY_AudioEndpoint_PhysicalSpeakers)) {
+ unsigned int num_speakers, card, device;
+ char hwname[255];
+
+ if (sscanf(name, "plughw:%u,%u", &card, &device))
+ sprintf(hwname, "hw:%u,%u", card, device); /* must be hw rather than plughw to work */
+ else
+ strcpy(hwname, name);
+
+ num_speakers = alsa_probe_num_speakers(hwname);
+ if (num_speakers == 0){
+ params->result = E_FAIL;
+ return STATUS_SUCCESS;
+ }
+ out->vt = VT_UI4;
+
+ if (num_speakers > 6)
+ out->ulVal = KSAUDIO_SPEAKER_STEREO;
+ else if (num_speakers == 6)
+ out->ulVal = KSAUDIO_SPEAKER_5POINT1;
+ else if (num_speakers >= 4)
+ out->ulVal = KSAUDIO_SPEAKER_QUAD;
+ else if (num_speakers >= 2)
+ out->ulVal = KSAUDIO_SPEAKER_STEREO;
+ else if (num_speakers == 1)
+ out->ulVal = KSAUDIO_SPEAKER_MONO;
+
+ params->result = S_OK;
+ return STATUS_SUCCESS;
+ }
+
+ TRACE("Unimplemented property %s,%u\n", wine_dbgstr_guid(&prop->fmtid), prop->pid);
+
+ params->result = E_NOTIMPL;
+ return STATUS_SUCCESS;
+}
+
unixlib_entry_t __wine_unix_call_funcs[] =
{
get_endpoint_ids,
@@ -2265,4 +2443,5 @@ unixlib_entry_t __wine_unix_call_funcs[] =
set_volumes,
set_event_handle,
is_started,
+ get_prop_value,
};
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index c2ec3dd54af..389c40b47de 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -49,8 +49,6 @@
#include "audioclient.h"
#include "audiopolicy.h"
-#include <alsa/asoundlib.h>
-
#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(alsa);
@@ -2444,58 +2442,12 @@ HRESULT WINAPI AUDDRV_GetAudioSessionManager(IMMDevice *device,
return S_OK;
}
-static unsigned int alsa_probe_num_speakers(char *name) {
- snd_pcm_t *handle;
- snd_pcm_hw_params_t *params;
- int err;
- unsigned int max_channels = 0;
-
- if ((err = snd_pcm_open(&handle, name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
- WARN("The device \"%s\" failed to open: %d (%s).\n",
- name, err, snd_strerror(err));
- return 0;
- }
-
- params = HeapAlloc(GetProcessHeap(), 0, snd_pcm_hw_params_sizeof());
- if (!params) {
- WARN("Out of memory.\n");
- snd_pcm_close(handle);
- return 0;
- }
-
- if ((err = snd_pcm_hw_params_any(handle, params)) < 0) {
- WARN("snd_pcm_hw_params_any failed for \"%s\": %d (%s).\n",
- name, err, snd_strerror(err));
- goto exit;
- }
-
- if ((err = snd_pcm_hw_params_get_channels_max(params,
- &max_channels)) < 0){
- WARN("Unable to get max channels: %d (%s)\n", err, snd_strerror(err));
- goto exit;
- }
-
-exit:
- HeapFree(GetProcessHeap(), 0, params);
- snd_pcm_close(handle);
-
- return max_channels;
-}
-
-enum AudioDeviceConnectionType {
- AudioDeviceConnectionType_Unknown = 0,
- AudioDeviceConnectionType_PCI,
- AudioDeviceConnectionType_USB
-};
-
HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARIANT *out)
{
+ struct get_prop_value_params params;
char name[256];
EDataFlow flow;
-
- static const PROPERTYKEY devicepath_key = { /* undocumented? - {b3f8fa53-0004-438e-9003-51a46e139bfc},2 */
- {0xb3f8fa53, 0x0004, 0x438e, {0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc}}, 2
- };
+ unsigned int size = 0;
TRACE("%s, (%s,%u), %p\n", wine_dbgstr_guid(guid), wine_dbgstr_guid(&prop->fmtid), prop->pid, out);
@@ -2505,116 +2457,27 @@ HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARI
return E_NOINTERFACE;
}
- if(IsEqualPropertyKey(*prop, devicepath_key))
- {
- char uevent[MAX_PATH];
- FILE *fuevent;
- int card, device;
-
- /* only implemented for identifiable devices, i.e. not "default" */
- if(!sscanf(name, "plughw:%u,%u", &card, &device))
- return E_NOTIMPL;
-
- sprintf(uevent, "/sys/class/sound/card%u/device/uevent", card);
- fuevent = fopen(uevent, "r");
-
- if(fuevent){
- enum AudioDeviceConnectionType connection = AudioDeviceConnectionType_Unknown;
- USHORT vendor_id = 0, product_id = 0;
- char line[256];
-
- while (fgets(line, sizeof(line), fuevent)) {
- char *val;
- size_t val_len;
-
- if((val = strchr(line, '='))) {
- val[0] = 0;
- val++;
-
- val_len = strlen(val);
- if(val_len > 0 && val[val_len - 1] == '\n') { val[val_len - 1] = 0; }
-
- if(!strcmp(line, "PCI_ID")){
- connection = AudioDeviceConnectionType_PCI;
- if(sscanf(val, "%hX:%hX", &vendor_id, &product_id)<2){
- WARN("Unexpected input when reading PCI_ID in uevent file.\n");
- connection = AudioDeviceConnectionType_Unknown;
- break;
- }
- }else if(!strcmp(line, "DEVTYPE") && !strcmp(val,"usb_interface"))
- connection = AudioDeviceConnectionType_USB;
- else if(!strcmp(line, "PRODUCT"))
- if(sscanf(val, "%hx/%hx/", &vendor_id, &product_id)<2){
- WARN("Unexpected input when reading PRODUCT in uevent file.\n");
- connection = AudioDeviceConnectionType_Unknown;
- break;
- }
- }
- }
-
- fclose(fuevent);
-
- if(connection == AudioDeviceConnectionType_USB || connection == AudioDeviceConnectionType_PCI){
- static const WCHAR usbformatW[] = { '{','1','}','.','U','S','B','\\','V','I','D','_',
- '%','0','4','X','&','P','I','D','_','%','0','4','X','\\',
- '%','u','&','%','0','8','X',0 }; /* "{1}.USB\VID_%04X&PID_%04X\%u&%08X" */
- static const WCHAR pciformatW[] = { '{','1','}','.','H','D','A','U','D','I','O','\\','F','U','N','C','_','0','1','&',
- 'V','E','N','_','%','0','4','X','&','D','E','V','_',
- '%','0','4','X','\\','%','u','&','%','0','8','X',0 }; /* "{1}.HDAUDIO\FUNC_01&VEN_%04X&DEV_%04X\%u&%08X" */
- UINT serial_number;
-
- /* As hardly any audio devices have serial numbers, Windows instead
- appears to use a persistent random number. We emulate this here
- by instead using the last 8 hex digits of the GUID. */
- serial_number = (guid->Data4[4] << 24) | (guid->Data4[5] << 16) | (guid->Data4[6] << 8) | guid->Data4[7];
-
- out->vt = VT_LPWSTR;
- out->pwszVal = CoTaskMemAlloc(128 * sizeof(WCHAR));
-
- if(!out->pwszVal)
- return E_OUTOFMEMORY;
-
- if(connection == AudioDeviceConnectionType_USB)
- sprintfW( out->pwszVal, usbformatW, vendor_id, product_id, device, serial_number);
- else if(connection == AudioDeviceConnectionType_PCI)
- sprintfW( out->pwszVal, pciformatW, vendor_id, product_id, device, serial_number);
-
- return S_OK;
- }
- }else{
- WARN("Could not open %s for reading\n", uevent);
- return E_NOTIMPL;
- }
- } else if (flow != eCapture && IsEqualPropertyKey(*prop, PKEY_AudioEndpoint_PhysicalSpeakers)) {
- unsigned int num_speakers, card, device;
- char hwname[255];
-
- if (sscanf(name, "plughw:%u,%u", &card, &device))
- sprintf(hwname, "hw:%u,%u", card, device); /* must be hw rather than plughw to work */
- else
- strcpy(hwname, name);
-
- num_speakers = alsa_probe_num_speakers(hwname);
- if (num_speakers == 0)
- return E_FAIL;
+ params.alsa_name = name;
+ params.flow = flow;
+ params.guid = guid;
+ params.prop = prop;
+ params.value = out;
+ params.buffer = NULL;
+ params.buffer_size = &size;
- out->vt = VT_UI4;
+ while(1) {
+ ALSA_CALL(get_prop_value, ¶ms);
- if (num_speakers > 6)
- out->ulVal = KSAUDIO_SPEAKER_STEREO;
- else if (num_speakers == 6)
- out->ulVal = KSAUDIO_SPEAKER_5POINT1;
- else if (num_speakers >= 4)
- out->ulVal = KSAUDIO_SPEAKER_QUAD;
- else if (num_speakers >= 2)
- out->ulVal = KSAUDIO_SPEAKER_STEREO;
- else if (num_speakers == 1)
- out->ulVal = KSAUDIO_SPEAKER_MONO;
+ if(params.result != E_NOT_SUFFICIENT_BUFFER)
+ break;
- return S_OK;
+ CoTaskMemFree(params.buffer);
+ params.buffer = CoTaskMemAlloc(*params.buffer_size);
+ if(!params.buffer)
+ return E_OUTOFMEMORY;
}
+ if(FAILED(params.result))
+ CoTaskMemFree(params.buffer);
- TRACE("Unimplemented property %s,%u\n", wine_dbgstr_guid(&prop->fmtid), prop->pid);
-
- return E_NOTIMPL;
+ return params.result;
}
diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
index 4326f79a50b..c2de48cef65 100644
--- a/dlls/winealsa.drv/unixlib.h
+++ b/dlls/winealsa.drv/unixlib.h
@@ -195,6 +195,18 @@ struct is_started_params
HRESULT result;
};
+struct get_prop_value_params
+{
+ const char *alsa_name;
+ EDataFlow flow;
+ const GUID *guid;
+ const PROPERTYKEY *prop;
+ HRESULT result;
+ PROPVARIANT *value;
+ void *buffer; /* caller allocated buffer to hold value's strings */
+ unsigned int *buffer_size;
+};
+
enum alsa_funcs
{
alsa_get_endpoint_ids,
@@ -219,6 +231,7 @@ enum alsa_funcs
alsa_set_volumes,
alsa_set_event_handle,
alsa_is_started,
+ alsa_get_prop_value,
};
extern unixlib_handle_t alsa_handle;
--
2.25.1
4
6
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/alsamidi.c | 57 ++++++++++++++++++++++++++++++++++++
dlls/winealsa.drv/midi.c | 47 -----------------------------
2 files changed, 57 insertions(+), 47 deletions(-)
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
index 04d1cb08c09..44b16693d16 100644
--- a/dlls/winealsa.drv/alsamidi.c
+++ b/dlls/winealsa.drv/alsamidi.c
@@ -462,6 +462,60 @@ static UINT midi_out_open(WORD dev_id, MIDIOPENDESC *midi_desc, UINT flags, stru
return MMSYSERR_NOERROR;
}
+static UINT midi_out_close(WORD dev_id, struct notify_context *notify)
+{
+ struct midi_dest *dest;
+
+ TRACE("(%04X);\n", dev_id);
+
+ if (dev_id >= num_dests)
+ {
+ WARN("bad device ID : %d\n", dev_id);
+ return MMSYSERR_BADDEVICEID;
+ }
+
+ dest = dests + dev_id;
+
+ if (dest->midiDesc.hMidi == 0)
+ {
+ WARN("device not opened !\n");
+ return MMSYSERR_ERROR;
+ }
+
+ /* FIXME: should test that no pending buffer is still in the queue for
+ * playing */
+
+ if (dest->seq == NULL)
+ {
+ WARN("can't close !\n");
+ return MMSYSERR_ERROR;
+ }
+
+ switch (dest->caps.wTechnology)
+ {
+ case MOD_FMSYNTH:
+ case MOD_MIDIPORT:
+ case MOD_SYNTH:
+ seq_lock();
+ TRACE("Deleting port :%d, connected to %d:%d\n", dest->port_out, dest->addr.client, dest->addr.port);
+ snd_seq_delete_simple_port(dest->seq, dest->port_out);
+ dest->port_out = -1;
+ seq_unlock();
+ seq_close();
+ dest->seq = NULL;
+ break;
+ default:
+ WARN("Technology not supported (yet) %d !\n", dest->caps.wTechnology);
+ return MMSYSERR_NOTENABLED;
+ }
+
+ set_out_notify(notify, dest, dev_id, MOM_CLOSE, 0, 0);
+
+ dest->midiDesc.hMidi = 0;
+
+ return MMSYSERR_NOERROR;
+}
+
NTSTATUS midi_out_message(void *args)
{
struct midi_out_message_params *params = args;
@@ -479,6 +533,9 @@ NTSTATUS midi_out_message(void *args)
case MODM_OPEN:
*params->err = midi_out_open(params->dev_id, (MIDIOPENDESC *)params->param_1, params->param_2, params->notify);
break;
+ case MODM_CLOSE:
+ *params->err = midi_out_close(params->dev_id, params->notify);
+ break;
default:
TRACE("Unsupported message\n");
*params->err = MMSYSERR_NOTSUPPORTED;
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index c77d479162b..5f8d855c9fb 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -122,7 +122,6 @@ static void MIDI_NotifyClient(UINT wDevID, WORD wMsg,
wDevID, wMsg, dwParam1, dwParam2);
switch (wMsg) {
- case MOM_CLOSE:
case MOM_DONE:
case MOM_POSITIONCB:
if (wDevID > MODM_NumDevs) return;
@@ -631,50 +630,6 @@ static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPSW lpCaps, DWORD dwSize)
return MMSYSERR_NOERROR;
}
-/**************************************************************************
- * modClose [internal]
- */
-static DWORD modClose(WORD wDevID)
-{
- int ret = MMSYSERR_NOERROR;
-
- TRACE("(%04X);\n", wDevID);
-
- if (MidiOutDev[wDevID].midiDesc.hMidi == 0) {
- WARN("device not opened !\n");
- return MMSYSERR_ERROR;
- }
- /* FIXME: should test that no pending buffer is still in the queue for
- * playing */
-
- if (MidiOutDev[wDevID].seq == NULL) {
- WARN("can't close !\n");
- return MMSYSERR_ERROR;
- }
-
- switch (MidiOutDev[wDevID].caps.wTechnology) {
- case MOD_FMSYNTH:
- case MOD_MIDIPORT:
- case MOD_SYNTH:
- seq_lock();
- TRACE("Deleting port :%d, connected to %d:%d\n", MidiOutDev[wDevID].port_out, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);
- snd_seq_delete_simple_port(MidiOutDev[wDevID].seq, MidiOutDev[wDevID].port_out);
- MidiOutDev[wDevID].port_out = -1;
- seq_unlock();
- midiCloseSeq();
- MidiOutDev[wDevID].seq = NULL;
- break;
- default:
- WARN("Technology not supported (yet) %d !\n",
- MidiOutDev[wDevID].caps.wTechnology);
- return MMSYSERR_NOTENABLED;
- }
-
- MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L);
- MidiOutDev[wDevID].midiDesc.hMidi = 0;
- return ret;
-}
-
/**************************************************************************
* modData [internal]
*/
@@ -1051,8 +1006,6 @@ DWORD WINAPI ALSA_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
case DRVM_INIT:
ALSA_MidiInit();
return 0;
- case MODM_CLOSE:
- return modClose(wDevID);
case MODM_DATA:
return modData(wDevID, dwParam1);
case MODM_LONGDATA:
--
2.25.1
1
0
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/alsa.c | 1 +
dlls/winealsa.drv/alsamidi.c | 133 +++++++++++++++++++++++++++++++++++
dlls/winealsa.drv/midi.c | 127 +++++++--------------------------
dlls/winealsa.drv/unixlib.h | 26 +++++++
4 files changed, 186 insertions(+), 101 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
index 16c0c7c387d..6d307eb84bf 100644
--- a/dlls/winealsa.drv/alsa.c
+++ b/dlls/winealsa.drv/alsa.c
@@ -2445,6 +2445,7 @@ unixlib_entry_t __wine_unix_call_funcs[] =
is_started,
get_prop_value,
midi_init,
+ midi_out_message,
midi_seq_lock, /* temporary */
midi_seq_open,
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
index a90d5b30fcf..04d1cb08c09 100644
--- a/dlls/winealsa.drv/alsamidi.c
+++ b/dlls/winealsa.drv/alsamidi.c
@@ -353,3 +353,136 @@ NTSTATUS midi_init(void *args)
return STATUS_SUCCESS;
}
+
+static void set_out_notify(struct notify_context *notify, struct midi_dest *dest, WORD dev_id, WORD msg,
+ UINT_PTR param_1, UINT_PTR param_2)
+{
+ notify->send_notify = TRUE;
+ notify->dev_id = dev_id;
+ notify->msg = msg;
+ notify->param_1 = param_1;
+ notify->param_2 = param_2;
+ notify->callback = dest->midiDesc.dwCallback;
+ notify->flags = dest->wFlags;
+ notify->device = dest->midiDesc.hMidi;
+ notify->instance = dest->midiDesc.dwInstance;
+}
+
+static UINT midi_out_open(WORD dev_id, MIDIOPENDESC *midi_desc, UINT flags, struct notify_context *notify)
+{
+ int ret;
+ int port_out;
+ char port_out_name[32];
+ snd_seq_t *midi_seq;
+ struct midi_dest *dest;
+
+ TRACE("(%04X, %p, %08X);\n", dev_id, midi_desc, flags);
+
+ if (midi_desc == NULL)
+ {
+ WARN("Invalid Parameter !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ if (dev_id >= num_dests)
+ {
+ TRACE("MAX_MIDIOUTDRV reached !\n");
+ return MMSYSERR_BADDEVICEID;
+ }
+ dest = dests + dev_id;
+ if (dest->midiDesc.hMidi != 0)
+ {
+ WARN("device already open !\n");
+ return MMSYSERR_ALLOCATED;
+ }
+ if (!dest->bEnabled)
+ {
+ WARN("device disabled !\n");
+ return MIDIERR_NODEVICE;
+ }
+ if ((flags & ~CALLBACK_TYPEMASK) != 0)
+ {
+ WARN("bad dwFlags\n");
+ return MMSYSERR_INVALFLAG;
+ }
+
+ switch (dest->caps.wTechnology)
+ {
+ case MOD_FMSYNTH:
+ case MOD_MIDIPORT:
+ case MOD_SYNTH:
+ if (!(midi_seq = seq_open(NULL)))
+ return MMSYSERR_ALLOCATED;
+ break;
+ default:
+ WARN("Technology not supported (yet) %d !\n", dest->caps.wTechnology);
+ return MMSYSERR_NOTENABLED;
+ }
+
+ dest->wFlags = HIWORD(flags & CALLBACK_TYPEMASK);
+ dest->midiDesc = *midi_desc;
+ dest->seq = midi_seq;
+
+ seq_lock();
+ /* Create a port dedicated to a specific device */
+ /* Keep the old name without a number for the first port */
+ if (dev_id)
+ sprintf(port_out_name, "WINE ALSA Output #%d", dev_id);
+
+ port_out = snd_seq_create_simple_port(midi_seq, dev_id ? port_out_name : "WINE ALSA Output",
+ SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_SUBS_WRITE,
+ SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
+
+ if (port_out < 0)
+ {
+ TRACE("Unable to create output port\n");
+ dest->port_out = -1;
+ }
+ else
+ {
+ TRACE("Output port %d created successfully\n", port_out);
+ dest->port_out = port_out;
+
+ /* Connect our app port to the device port */
+ ret = snd_seq_connect_to(midi_seq, port_out, dest->addr.client, dest->addr.port);
+
+ /* usually will happen when the port is already connected */
+ /* other errors should not be fatal either */
+ if (ret < 0)
+ WARN("Could not connect port %d to %d:%d: %s\n", dev_id, dest->addr.client,
+ dest->addr.port, snd_strerror(ret));
+ }
+ seq_unlock();
+
+ if (port_out < 0)
+ return MMSYSERR_NOTENABLED;
+
+ TRACE("Output port :%d connected %d:%d\n", port_out, dest->addr.client, dest->addr.port);
+
+ set_out_notify(notify, dest, dev_id, MOM_OPEN, 0, 0);
+ return MMSYSERR_NOERROR;
+}
+
+NTSTATUS midi_out_message(void *args)
+{
+ struct midi_out_message_params *params = args;
+
+ params->notify->send_notify = FALSE;
+
+ switch (params->msg)
+ {
+ case DRVM_EXIT:
+ case DRVM_ENABLE:
+ case DRVM_DISABLE:
+ /* FIXME: Pretend this is supported */
+ *params->err = MMSYSERR_NOERROR;
+ break;
+ case MODM_OPEN:
+ *params->err = midi_out_open(params->dev_id, (MIDIOPENDESC *)params->param_1, params->param_2, params->notify);
+ break;
+ default:
+ TRACE("Unsupported message\n");
+ *params->err = MMSYSERR_NOTSUPPORTED;
+ }
+
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index 535f3dbd348..c77d479162b 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -79,6 +79,14 @@ static void seq_unlock(void)
ALSA_CALL(midi_seq_lock, (void *)(UINT_PTR)0);
}
+static void notify_client(struct notify_context *notify)
+{
+ TRACE("dev_id = %d msg = %d param1 = %04lX param2 = %04lX\n", notify->dev_id, notify->msg, notify->param_1, notify->param_2);
+
+ DriverCallback(notify->callback, notify->flags, notify->device, notify->msg,
+ notify->instance, notify->param_1, notify->param_2);
+}
+
/*======================================================================*
* Low level MIDI implementation *
*======================================================================*/
@@ -114,7 +122,6 @@ static void MIDI_NotifyClient(UINT wDevID, WORD wMsg,
wDevID, wMsg, dwParam1, dwParam2);
switch (wMsg) {
- case MOM_OPEN:
case MOM_CLOSE:
case MOM_DONE:
case MOM_POSITIONCB:
@@ -624,96 +631,6 @@ static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPSW lpCaps, DWORD dwSize)
return MMSYSERR_NOERROR;
}
-/**************************************************************************
- * modOpen [internal]
- */
-static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
-{
- int ret;
- int port_out;
- char port_out_name[32];
- snd_seq_t *midi_seq;
-
- TRACE("(%04X, %p, %08X);\n", wDevID, lpDesc, dwFlags);
- if (lpDesc == NULL) {
- WARN("Invalid Parameter !\n");
- return MMSYSERR_INVALPARAM;
- }
- if (wDevID >= MODM_NumDevs) {
- TRACE("MAX_MIDIOUTDRV reached !\n");
- return MMSYSERR_BADDEVICEID;
- }
- if (MidiOutDev[wDevID].midiDesc.hMidi != 0) {
- WARN("device already open !\n");
- return MMSYSERR_ALLOCATED;
- }
- if (!MidiOutDev[wDevID].bEnabled) {
- WARN("device disabled !\n");
- return MIDIERR_NODEVICE;
- }
- if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) {
- WARN("bad dwFlags\n");
- return MMSYSERR_INVALFLAG;
- }
-
- switch (MidiOutDev[wDevID].caps.wTechnology) {
- case MOD_FMSYNTH:
- case MOD_MIDIPORT:
- case MOD_SYNTH:
- if (!(midi_seq = midiOpenSeq(NULL))) {
- return MMSYSERR_ALLOCATED;
- }
- break;
- default:
- WARN("Technology not supported (yet) %d !\n",
- MidiOutDev[wDevID].caps.wTechnology);
- return MMSYSERR_NOTENABLED;
- }
-
- MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
- MidiOutDev[wDevID].midiDesc = *lpDesc;
- MidiOutDev[wDevID].seq = midi_seq;
-
- seq_lock();
- /* Create a port dedicated to a specific device */
- /* Keep the old name without a number for the first port */
- if (wDevID)
- sprintf(port_out_name, "WINE ALSA Output #%d", wDevID);
-
- port_out = snd_seq_create_simple_port(midi_seq, wDevID?port_out_name:"WINE ALSA Output",
- SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
- SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION);
-
- if (port_out < 0) {
- TRACE("Unable to create output port\n");
- MidiOutDev[wDevID].port_out = -1;
- } else {
- TRACE("Output port %d created successfully\n", port_out);
- MidiOutDev[wDevID].port_out = port_out;
-
- /* Connect our app port to the device port */
- ret = snd_seq_connect_to(midi_seq, port_out, MidiOutDev[wDevID].addr.client,
- MidiOutDev[wDevID].addr.port);
-
- /* usually will happen when the port is already connected */
- /* other errors should not be fatal either */
- if (ret < 0)
- WARN("Could not connect port %d to %d:%d: %s\n",
- wDevID, MidiOutDev[wDevID].addr.client,
- MidiOutDev[wDevID].addr.port, snd_strerror(ret));
- }
- seq_unlock();
-
- if (port_out < 0)
- return MMSYSERR_NOTENABLED;
-
- TRACE("Output port :%d connected %d:%d\n",port_out,MidiOutDev[wDevID].addr.client,MidiOutDev[wDevID].addr.port);
-
- MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L);
- return MMSYSERR_NOERROR;
-}
-
-
/**************************************************************************
* modClose [internal]
*/
@@ -1123,6 +1040,10 @@ DWORD WINAPI ALSA_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
DWORD WINAPI ALSA_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
+ struct midi_out_message_params params;
+ struct notify_context notify;
+ UINT err;
+
TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",
wDevID, wMsg, dwUser, dwParam1, dwParam2);
@@ -1130,13 +1051,6 @@ DWORD WINAPI ALSA_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
case DRVM_INIT:
ALSA_MidiInit();
return 0;
- case DRVM_EXIT:
- case DRVM_ENABLE:
- case DRVM_DISABLE:
- /* FIXME: Pretend this is supported */
- return 0;
- case MODM_OPEN:
- return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
case MODM_CLOSE:
return modClose(wDevID);
case MODM_DATA:
@@ -1157,10 +1071,21 @@ DWORD WINAPI ALSA_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
return 0;
case MODM_RESET:
return modReset(wDevID);
- default:
- TRACE("Unsupported message\n");
}
- return MMSYSERR_NOTSUPPORTED;
+
+ params.dev_id = wDevID;
+ params.msg = wMsg;
+ params.user = dwUser;
+ params.param_1 = dwParam1;
+ params.param_2 = dwParam2;
+ params.err = &err;
+ params.notify = ¬ify;
+
+ ALSA_CALL(midi_out_message, ¶ms);
+
+ if (!err && notify.send_notify) notify_client(¬ify);
+
+ return err;
}
/**************************************************************************
diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
index d69ab980f42..e3cd7123101 100644
--- a/dlls/winealsa.drv/unixlib.h
+++ b/dlls/winealsa.drv/unixlib.h
@@ -241,6 +241,30 @@ struct midi_init_params
void *dests, *srcs;
};
+struct notify_context
+{
+ BOOL send_notify;
+ WORD dev_id;
+ WORD msg;
+ UINT_PTR param_1;
+ UINT_PTR param_2;
+ UINT_PTR callback;
+ UINT flags;
+ HANDLE device;
+ UINT_PTR instance;
+};
+
+struct midi_out_message_params
+{
+ UINT dev_id;
+ UINT msg;
+ UINT_PTR user;
+ UINT_PTR param_1;
+ UINT_PTR param_2;
+ UINT *err;
+ struct notify_context *notify;
+};
+
struct midi_seq_open_params
{
int close;
@@ -274,12 +298,14 @@ enum alsa_funcs
alsa_is_started,
alsa_get_prop_value,
alsa_midi_init,
+ alsa_midi_out_message,
alsa_midi_seq_lock, /* temporary */
alsa_midi_seq_open,
};
NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
+NTSTATUS midi_out_message(void *args) DECLSPEC_HIDDEN;
NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
NTSTATUS midi_seq_open(void *args) DECLSPEC_HIDDEN;
--
2.25.1
1
0
[PATCH 4/6] winealsa: Add a temporary syscall to return the snd_seq handle.
by Huw Davies 15 Mar '22
by Huw Davies 15 Mar '22
15 Mar '22
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/alsa.c | 1 +
dlls/winealsa.drv/alsamidi.c | 47 +++++++++++++++++++++++++++++-----
dlls/winealsa.drv/midi.c | 49 ++++++++----------------------------
dlls/winealsa.drv/unixlib.h | 9 +++++++
4 files changed, 62 insertions(+), 44 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
index 76e4b98caaf..16c0c7c387d 100644
--- a/dlls/winealsa.drv/alsa.c
+++ b/dlls/winealsa.drv/alsa.c
@@ -2447,4 +2447,5 @@ unixlib_entry_t __wine_unix_call_funcs[] =
midi_init,
midi_seq_lock, /* temporary */
+ midi_seq_open,
};
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
index 9e7962f46cd..a90d5b30fcf 100644
--- a/dlls/winealsa.drv/alsamidi.c
+++ b/dlls/winealsa.drv/alsamidi.c
@@ -55,6 +55,7 @@ static struct midi_dest dests[MAX_MIDIOUTDRV];
static struct midi_src srcs[MAX_MIDIINDRV];
static snd_seq_t *midi_seq;
static unsigned int seq_refs;
+static int port_in = -1;
static void seq_lock(void)
{
@@ -74,7 +75,7 @@ NTSTATUS midi_seq_lock(void *args)
return STATUS_SUCCESS;
}
-static int seq_open(void)
+static snd_seq_t *seq_open(int *port_in_ret)
{
static int midi_warn;
@@ -87,12 +88,28 @@ static int seq_open(void)
WARN("Error opening ALSA sequencer.\n");
midi_warn = 1;
seq_unlock();
- return -1;
+ return NULL;
}
+ snd_seq_set_client_name(midi_seq, "WINE midi driver");
}
seq_refs++;
+
+ if (port_in_ret)
+ {
+ if (port_in < 0)
+ {
+ port_in = snd_seq_create_simple_port(midi_seq, "WINE ALSA Input",
+ SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_SUBS_WRITE,
+ SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
+ if (port_in < 0)
+ TRACE("Unable to create input port\n");
+ else
+ TRACE("Input port %d created successfully\n", port_in);
+ }
+ *port_in_ret = port_in;
+ }
seq_unlock();
- return 0;
+ return midi_seq;
}
static void seq_close(void)
@@ -100,12 +117,29 @@ static void seq_close(void)
seq_lock();
if (--seq_refs == 0)
{
+ if (port_in >= 0)
+ {
+ snd_seq_delete_simple_port(midi_seq, port_in);
+ port_in = -1;
+ }
snd_seq_close(midi_seq);
midi_seq = NULL;
}
seq_unlock();
}
+NTSTATUS midi_seq_open(void *args)
+{
+ struct midi_seq_open_params *params = args;
+
+ if (!params->close)
+ params->seq = seq_open(params->port_in);
+ else
+ seq_close();
+
+ return STATUS_SUCCESS;
+}
+
static int alsa_to_win_device_type(unsigned int type)
{
/* MOD_MIDIPORT output port
@@ -270,6 +304,7 @@ NTSTATUS midi_init(void *args)
static BOOL init_done;
snd_seq_client_info_t *cinfo;
snd_seq_port_info_t *pinfo;
+ snd_seq_t *seq;
int external;
if (init_done) {
@@ -281,7 +316,7 @@ NTSTATUS midi_init(void *args)
init_done = TRUE;
/* try to open device */
- if (seq_open() == -1) {
+ if (!(seq = seq_open(NULL))) {
*params->err = ERROR_OPEN_FAILED;
return STATUS_SUCCESS;
}
@@ -292,10 +327,10 @@ NTSTATUS midi_init(void *args)
/* Add internal ports first, followed by external */
for (external = 0; external < 2; external++) {
snd_seq_client_info_set_client(cinfo, -1);
- while (snd_seq_query_next_client(midi_seq, cinfo) >= 0) {
+ while (snd_seq_query_next_client(seq, cinfo) >= 0) {
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
snd_seq_port_info_set_port(pinfo, -1);
- while (snd_seq_query_next_port(midi_seq, pinfo) >= 0) {
+ while (snd_seq_query_next_port(seq, pinfo) >= 0) {
unsigned int cap = snd_seq_port_info_get_capability(pinfo);
unsigned int type = snd_seq_port_info_get_type(pinfo);
if (!external == !(type & SND_SEQ_PORT_TYPE_PORT))
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index fae6ddf8615..535f3dbd348 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -55,12 +55,8 @@ static int MODM_NumDevs = 0;
/* this is the total number of MIDI out devices found */
static int MIDM_NumDevs = 0;
-static snd_seq_t* midiSeq = NULL;
-static int numOpenMidiSeq = 0;
static int numStartedMidiIn = 0;
-static int port_in;
-
static CRITICAL_SECTION crit_sect; /* protects all MidiIn buffer queues */
static CRITICAL_SECTION_DEBUG critsect_debug =
{
@@ -152,40 +148,18 @@ static void MIDI_NotifyClient(UINT wDevID, WORD wMsg,
DriverCallback(dwCallBack, uFlags, hDev, wMsg, dwInstance, dwParam1, dwParam2);
}
-static BOOL midi_warn = TRUE;
/**************************************************************************
* midiOpenSeq [internal]
*/
static snd_seq_t *midiOpenSeq(int *port_in_ret)
{
- seq_lock();
- if (numOpenMidiSeq == 0) {
- if (snd_seq_open(&midiSeq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
- {
- if (midi_warn)
- {
- WARN("Error opening ALSA sequencer.\n");
- }
- midi_warn = FALSE;
- seq_unlock();
- return NULL;
- }
+ struct midi_seq_open_params params;
- /* Setting the client name is the only init to do */
- snd_seq_set_client_name(midiSeq, "WINE midi driver");
+ params.port_in = port_in_ret;
+ params.close = 0;
+ ALSA_CALL(midi_seq_open, ¶ms);
- port_in = snd_seq_create_simple_port(midiSeq, "WINE ALSA Input",
- SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
- SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION);
- if (port_in < 0)
- TRACE("Unable to create input port\n");
- else
- TRACE("Input port %d created successfully\n", port_in);
- }
- numOpenMidiSeq++;
- seq_unlock();
- if (port_in_ret) *port_in_ret = port_in;
- return midiSeq;
+ return params.seq;
}
/**************************************************************************
@@ -193,13 +167,12 @@ static snd_seq_t *midiOpenSeq(int *port_in_ret)
*/
static int midiCloseSeq(void)
{
- seq_lock();
- if (--numOpenMidiSeq == 0) {
- snd_seq_delete_simple_port(midiSeq, port_in);
- snd_seq_close(midiSeq);
- midiSeq = NULL;
- }
- seq_unlock();
+ struct midi_seq_open_params params;
+
+ params.port_in = NULL;
+ params.close = 1;
+ ALSA_CALL(midi_seq_open, ¶ms);
+
return 0;
}
diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
index e0ae16b97d9..d69ab980f42 100644
--- a/dlls/winealsa.drv/unixlib.h
+++ b/dlls/winealsa.drv/unixlib.h
@@ -241,6 +241,13 @@ struct midi_init_params
void *dests, *srcs;
};
+struct midi_seq_open_params
+{
+ int close;
+ snd_seq_t *seq;
+ int *port_in;
+};
+
enum alsa_funcs
{
alsa_get_endpoint_ids,
@@ -269,11 +276,13 @@ enum alsa_funcs
alsa_midi_init,
alsa_midi_seq_lock, /* temporary */
+ alsa_midi_seq_open,
};
NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
+NTSTATUS midi_seq_open(void *args) DECLSPEC_HIDDEN;
extern unixlib_handle_t alsa_handle;
--
2.25.1
1
0
[PATCH 3/6] winealsa: Store the snd_seq handle and the input port in the device data.
by Huw Davies 15 Mar '22
by Huw Davies 15 Mar '22
15 Mar '22
This is to avoid accessing more global variables and generally
makes things a bit cleaner.
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/midi.c | 85 ++++++++++++++++++++-----------------
dlls/winealsa.drv/unixlib.h | 3 ++
2 files changed, 49 insertions(+), 39 deletions(-)
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index 988429ab934..fae6ddf8615 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -156,7 +156,7 @@ static BOOL midi_warn = TRUE;
/**************************************************************************
* midiOpenSeq [internal]
*/
-static int midiOpenSeq(BOOL create_client)
+static snd_seq_t *midiOpenSeq(int *port_in_ret)
{
seq_lock();
if (numOpenMidiSeq == 0) {
@@ -168,25 +168,24 @@ static int midiOpenSeq(BOOL create_client)
}
midi_warn = FALSE;
seq_unlock();
- return -1;
+ return NULL;
}
- if (create_client) {
- /* Setting the client name is the only init to do */
- snd_seq_set_client_name(midiSeq, "WINE midi driver");
-
- port_in = snd_seq_create_simple_port(midiSeq, "WINE ALSA Input",
- SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
- SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION);
- if (port_in < 0)
- TRACE("Unable to create input port\n");
- else
- TRACE("Input port %d created successfully\n", port_in);
- }
+ /* Setting the client name is the only init to do */
+ snd_seq_set_client_name(midiSeq, "WINE midi driver");
+
+ port_in = snd_seq_create_simple_port(midiSeq, "WINE ALSA Input",
+ SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
+ SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION);
+ if (port_in < 0)
+ TRACE("Unable to create input port\n");
+ else
+ TRACE("Input port %d created successfully\n", port_in);
}
numOpenMidiSeq++;
seq_unlock();
- return 0;
+ if (port_in_ret) *port_in_ret = port_in;
+ return midiSeq;
}
/**************************************************************************
@@ -314,8 +313,9 @@ static void handle_midi_event(snd_seq_event_t *ev)
}
}
-static DWORD WINAPI midRecThread(LPVOID arg)
+static DWORD WINAPI midRecThread(void *arg)
{
+ snd_seq_t *midi_seq = arg;
int npfd;
struct pollfd *pfd;
int ret;
@@ -325,9 +325,9 @@ static DWORD WINAPI midRecThread(LPVOID arg)
while(!end_thread) {
TRACE("Thread loop\n");
seq_lock();
- npfd = snd_seq_poll_descriptors_count(midiSeq, POLLIN);
+ npfd = snd_seq_poll_descriptors_count(midi_seq, POLLIN);
pfd = HeapAlloc(GetProcessHeap(), 0, npfd * sizeof(struct pollfd));
- snd_seq_poll_descriptors(midiSeq, pfd, npfd, POLLIN);
+ snd_seq_poll_descriptors(midi_seq, pfd, npfd, POLLIN);
seq_unlock();
/* Check if an event is present */
@@ -337,9 +337,9 @@ static DWORD WINAPI midRecThread(LPVOID arg)
}
/* Note: This definitely does not work.
- * while(snd_seq_event_input_pending(midiSeq, 0) > 0) {
+ * while(snd_seq_event_input_pending(midi_seq, 0) > 0) {
snd_seq_event_t* ev;
- snd_seq_event_input(midiSeq, &ev);
+ snd_seq_event_input(midi_seq, &ev);
....................
snd_seq_free_event(ev);
}*/
@@ -348,7 +348,7 @@ static DWORD WINAPI midRecThread(LPVOID arg)
snd_seq_event_t *ev;
seq_lock();
- snd_seq_event_input(midiSeq, &ev);
+ snd_seq_event_input(midi_seq, &ev);
seq_unlock();
if (ev) {
@@ -357,10 +357,10 @@ static DWORD WINAPI midRecThread(LPVOID arg)
}
seq_lock();
- ret = snd_seq_event_input_pending(midiSeq, 0);
+ ret = snd_seq_event_input_pending(midi_seq, 0);
seq_unlock();
} while(ret > 0);
-
+
HeapFree(GetProcessHeap(), 0, pfd);
}
return 0;
@@ -387,7 +387,8 @@ static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPSW lpCaps, DWORD dwSize)
*/
static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
{
- int ret = 0;
+ int ret = 0, port_in;
+ snd_seq_t *midi_seq;
TRACE("(%04X, %p, %08X);\n", wDevID, lpDesc, dwFlags);
@@ -420,7 +421,7 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
return MMSYSERR_INVALFLAG;
}
- if (midiOpenSeq(TRUE) < 0) {
+ if (!(midi_seq = midiOpenSeq(&port_in))) {
return MMSYSERR_ERROR;
}
@@ -430,10 +431,12 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
MidiInDev[wDevID].midiDesc = *lpDesc;
MidiInDev[wDevID].state = 0;
MidiInDev[wDevID].startTime = 0;
+ MidiInDev[wDevID].seq = midi_seq;
+ MidiInDev[wDevID].port_in = port_in;
/* Connect our app port to the device port */
seq_lock();
- ret = snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client,
+ ret = snd_seq_connect_from(midi_seq, port_in, MidiInDev[wDevID].addr.client,
MidiInDev[wDevID].addr.port);
seq_unlock();
if (ret < 0)
@@ -443,7 +446,7 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
if (numStartedMidiIn++ == 0) {
end_thread = 0;
- hThread = CreateThread(NULL, 0, midRecThread, NULL, 0, NULL);
+ hThread = CreateThread(NULL, 0, midRecThread, midi_seq, 0, NULL);
if (!hThread) {
numStartedMidiIn = 0;
WARN("Couldn't create thread for midi-in\n");
@@ -479,7 +482,7 @@ static DWORD midClose(WORD wDevID)
return MIDIERR_STILLPLAYING;
}
- if (midiSeq == NULL) {
+ if (MidiInDev[wDevID].seq == NULL) {
WARN("ooops !\n");
return MMSYSERR_ERROR;
}
@@ -494,12 +497,13 @@ static DWORD midClose(WORD wDevID)
}
seq_lock();
- snd_seq_disconnect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port);
+ snd_seq_disconnect_from(MidiInDev[wDevID].seq, MidiInDev[wDevID].port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port);
seq_unlock();
midiCloseSeq();
MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L);
MidiInDev[wDevID].midiDesc.hMidi = 0;
+ MidiInDev[wDevID].seq = NULL;
return ret;
}
@@ -655,6 +659,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
int ret;
int port_out;
char port_out_name[32];
+ snd_seq_t *midi_seq;
TRACE("(%04X, %p, %08X);\n", wDevID, lpDesc, dwFlags);
if (lpDesc == NULL) {
@@ -682,7 +687,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
case MOD_FMSYNTH:
case MOD_MIDIPORT:
case MOD_SYNTH:
- if (midiOpenSeq(TRUE) < 0) {
+ if (!(midi_seq = midiOpenSeq(NULL))) {
return MMSYSERR_ALLOCATED;
}
break;
@@ -694,6 +699,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
MidiOutDev[wDevID].midiDesc = *lpDesc;
+ MidiOutDev[wDevID].seq = midi_seq;
seq_lock();
/* Create a port dedicated to a specific device */
@@ -701,7 +707,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
if (wDevID)
sprintf(port_out_name, "WINE ALSA Output #%d", wDevID);
- port_out = snd_seq_create_simple_port(midiSeq, wDevID?port_out_name:"WINE ALSA Output",
+ port_out = snd_seq_create_simple_port(midi_seq, wDevID?port_out_name:"WINE ALSA Output",
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION);
@@ -713,7 +719,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
MidiOutDev[wDevID].port_out = port_out;
/* Connect our app port to the device port */
- ret = snd_seq_connect_to(midiSeq, port_out, MidiOutDev[wDevID].addr.client,
+ ret = snd_seq_connect_to(midi_seq, port_out, MidiOutDev[wDevID].addr.client,
MidiOutDev[wDevID].addr.port);
/* usually will happen when the port is already connected */
@@ -751,7 +757,7 @@ static DWORD modClose(WORD wDevID)
/* FIXME: should test that no pending buffer is still in the queue for
* playing */
- if (midiSeq == NULL) {
+ if (MidiOutDev[wDevID].seq == NULL) {
WARN("can't close !\n");
return MMSYSERR_ERROR;
}
@@ -762,10 +768,11 @@ static DWORD modClose(WORD wDevID)
case MOD_SYNTH:
seq_lock();
TRACE("Deleting port :%d, connected to %d:%d\n", MidiOutDev[wDevID].port_out, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);
- snd_seq_delete_simple_port(midiSeq, MidiOutDev[wDevID].port_out);
+ snd_seq_delete_simple_port(MidiOutDev[wDevID].seq, MidiOutDev[wDevID].port_out);
MidiOutDev[wDevID].port_out = -1;
seq_unlock();
- midiCloseSeq();
+ midiCloseSeq();
+ MidiOutDev[wDevID].seq = NULL;
break;
default:
WARN("Technology not supported (yet) %d !\n",
@@ -792,7 +799,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;
if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;
- if (midiSeq == NULL) {
+ if (MidiOutDev[wDevID].seq == NULL) {
WARN("can't play !\n");
return MIDIERR_NODEVICE;
}
@@ -886,7 +893,7 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
}
if (handled) {
seq_lock();
- snd_seq_event_output_direct(midiSeq, &event);
+ snd_seq_event_output_direct(MidiOutDev[wDevID].seq, &event);
seq_unlock();
}
}
@@ -919,7 +926,7 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;
if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;
- if (midiSeq == NULL) {
+ if (MidiOutDev[wDevID].seq == NULL) {
WARN("can't play !\n");
return MIDIERR_NODEVICE;
}
@@ -977,7 +984,7 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
snd_seq_ev_set_subs(&event);
snd_seq_ev_set_sysex(&event, lpMidiHdr->dwBufferLength + len_add, lpNewData ? lpNewData : lpData);
seq_lock();
- snd_seq_event_output_direct(midiSeq, &event);
+ snd_seq_event_output_direct(MidiOutDev[wDevID].seq, &event);
seq_unlock();
HeapFree(GetProcessHeap(), 0, lpNewData);
break;
diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
index adac72183ee..e0ae16b97d9 100644
--- a/dlls/winealsa.drv/unixlib.h
+++ b/dlls/winealsa.drv/unixlib.h
@@ -218,7 +218,9 @@ typedef struct midi_src
MIDIHDR *lpQueueHdr;
UINT startTime;
MIDIINCAPSW caps;
+ snd_seq_t *seq;
snd_seq_addr_t addr;
+ int port_in;
} WINE_MIDIIN;
typedef struct midi_dest
@@ -227,6 +229,7 @@ typedef struct midi_dest
MIDIOPENDESC midiDesc;
WORD wFlags;
MIDIOUTCAPSW caps;
+ snd_seq_t *seq;
snd_seq_addr_t addr;
int port_out;
} WINE_MIDIOUT;
--
2.25.1
1
0
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/alsa.c | 1 +
dlls/winealsa.drv/alsamidi.c | 256 +++++++++++++++++++++++++++++++++++
dlls/winealsa.drv/midi.c | 240 ++------------------------------
dlls/winealsa.drv/unixlib.h | 34 +++++
4 files changed, 305 insertions(+), 226 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
index cdc3d81d8cc..76e4b98caaf 100644
--- a/dlls/winealsa.drv/alsa.c
+++ b/dlls/winealsa.drv/alsa.c
@@ -2444,6 +2444,7 @@ unixlib_entry_t __wine_unix_call_funcs[] =
set_event_handle,
is_started,
get_prop_value,
+ midi_init,
midi_seq_lock, /* temporary */
};
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
index ab4de4f7f9e..9e7962f46cd 100644
--- a/dlls/winealsa.drv/alsamidi.c
+++ b/dlls/winealsa.drv/alsamidi.c
@@ -31,6 +31,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <pthread.h>
+#include <alsa/asoundlib.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -38,13 +39,23 @@
#include "winbase.h"
#include "winternl.h"
#include "mmdeviceapi.h"
+#include "mmddk.h"
+#include "wine/debug.h"
#include "wine/unixlib.h"
#include "unixlib.h"
+WINE_DEFAULT_DEBUG_CHANNEL(midi);
+
static pthread_mutex_t seq_mutex = PTHREAD_MUTEX_INITIALIZER;
+static unsigned int num_dests, num_srcs;
+static struct midi_dest dests[MAX_MIDIOUTDRV];
+static struct midi_src srcs[MAX_MIDIINDRV];
+static snd_seq_t *midi_seq;
+static unsigned int seq_refs;
+
static void seq_lock(void)
{
pthread_mutex_lock(&seq_mutex);
@@ -62,3 +73,248 @@ NTSTATUS midi_seq_lock(void *args)
return STATUS_SUCCESS;
}
+
+static int seq_open(void)
+{
+ static int midi_warn;
+
+ seq_lock();
+ if (seq_refs == 0)
+ {
+ if (snd_seq_open(&midi_seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
+ {
+ if (!midi_warn)
+ WARN("Error opening ALSA sequencer.\n");
+ midi_warn = 1;
+ seq_unlock();
+ return -1;
+ }
+ }
+ seq_refs++;
+ seq_unlock();
+ return 0;
+}
+
+static void seq_close(void)
+{
+ seq_lock();
+ if (--seq_refs == 0)
+ {
+ snd_seq_close(midi_seq);
+ midi_seq = NULL;
+ }
+ seq_unlock();
+}
+
+static int alsa_to_win_device_type(unsigned int type)
+{
+ /* MOD_MIDIPORT output port
+ * MOD_SYNTH generic internal synth
+ * MOD_SQSYNTH square wave internal synth
+ * MOD_FMSYNTH FM internal synth
+ * MOD_MAPPER MIDI mapper
+ * MOD_WAVETABLE hardware wavetable internal synth
+ * MOD_SWSYNTH software internal synth
+ */
+
+ /* FIXME Is this really the correct equivalence from ALSA to
+ Windows Sound type? */
+
+ if (type & SND_SEQ_PORT_TYPE_SYNTH)
+ return MOD_FMSYNTH;
+
+ if (type & (SND_SEQ_PORT_TYPE_DIRECT_SAMPLE|SND_SEQ_PORT_TYPE_SAMPLE))
+ return MOD_SYNTH;
+
+ if (type & (SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION))
+ return MOD_MIDIPORT;
+
+ ERR("Cannot determine the type (alsa type is %x) of this midi device. Assuming FM Synth\n", type);
+ return MOD_FMSYNTH;
+}
+
+static void port_add(snd_seq_client_info_t* cinfo, snd_seq_port_info_t* pinfo, unsigned int cap, unsigned int type)
+{
+ char name[MAXPNAMELEN];
+ unsigned int len;
+ struct midi_dest *dest;
+ struct midi_src *src;
+
+ if (cap & SND_SEQ_PORT_CAP_WRITE) {
+ TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
+ snd_seq_client_info_get_name(cinfo),
+ snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
+ snd_seq_port_info_get_port(pinfo),
+ snd_seq_port_info_get_name(pinfo),
+ type);
+
+ if (num_dests >= MAX_MIDIOUTDRV)
+ return;
+ if (!type)
+ return;
+
+ dest = dests + num_dests;
+ dest->addr = *snd_seq_port_info_get_addr(pinfo);
+
+ /* Manufac ID. We do not have access to this with soundcard.h
+ * Does not seem to be a problem, because in mmsystem.h only
+ * Microsoft's ID is listed.
+ */
+ dest->caps.wMid = 0x00FF;
+ dest->caps.wPid = 0x0001; /* FIXME Product ID */
+ /* Product Version. We simply say "1" */
+ dest->caps.vDriverVersion = 0x001;
+ /* The following are mandatory for MOD_MIDIPORT */
+ dest->caps.wChannelMask = 0xFFFF;
+ dest->caps.wVoices = 0;
+ dest->caps.wNotes = 0;
+ dest->caps.dwSupport = 0;
+
+ /* Try to use both client and port names, if this is too long take the port name only.
+ In the second case the port name should be explicit enough due to its big size.
+ */
+ len = strlen(snd_seq_port_info_get_name(pinfo));
+ if ( (strlen(snd_seq_client_info_get_name(cinfo)) + len + 3) < sizeof(name) ) {
+ sprintf(name, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
+ len = strlen(name);
+ } else {
+ len = min(len, sizeof(name) - 1);
+ memcpy(name, snd_seq_port_info_get_name(pinfo), len);
+ name[len] = '\0';
+ }
+ ntdll_umbstowcs( name, len + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname));
+
+ dest->caps.wTechnology = alsa_to_win_device_type(type);
+
+ if (MOD_MIDIPORT != dest->caps.wTechnology) {
+ /* FIXME Do we have this information?
+ * Assuming the soundcards can handle
+ * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
+ * not MIDICAPS_CACHE.
+ */
+ dest->caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
+ dest->caps.wVoices = 16;
+
+ /* FIXME Is it possible to know the maximum
+ * number of simultaneous notes of a soundcard ?
+ * I believe we don't have this information, but
+ * it's probably equal or more than wVoices
+ */
+ dest->caps.wNotes = 16;
+ }
+ dest->bEnabled = TRUE;
+ dest->port_out = -1;
+
+ TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n"
+ "\tALSA info: midi dev-type=%x, capa=0\n",
+ num_dests, wine_dbgstr_w(dest->caps.szPname),
+ dest->caps.wTechnology,
+ dest->caps.wVoices, dest->caps.wNotes,
+ dest->caps.wChannelMask, dest->caps.dwSupport,
+ type);
+
+ num_dests++;
+ }
+ if (cap & SND_SEQ_PORT_CAP_READ) {
+ TRACE("IN (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
+ snd_seq_client_info_get_name(cinfo),
+ snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
+ snd_seq_port_info_get_port(pinfo),
+ snd_seq_port_info_get_name(pinfo),
+ type);
+
+ if (num_srcs >= MAX_MIDIINDRV)
+ return;
+ if (!type)
+ return;
+
+ src = srcs + num_srcs;
+ src->addr = *snd_seq_port_info_get_addr(pinfo);
+
+ /* Manufac ID. We do not have access to this with soundcard.h
+ * Does not seem to be a problem, because in mmsystem.h only
+ * Microsoft's ID is listed.
+ */
+ src->caps.wMid = 0x00FF;
+ src->caps.wPid = 0x0001; /* FIXME Product ID */
+ /* Product Version. We simply say "1" */
+ src->caps.vDriverVersion = 0x001;
+ src->caps.dwSupport = 0; /* mandatory with MIDIINCAPS */
+
+ /* Try to use both client and port names, if this is too long take the port name only.
+ In the second case the port name should be explicit enough due to its big size.
+ */
+ len = strlen(snd_seq_port_info_get_name(pinfo));
+ if ( (strlen(snd_seq_client_info_get_name(cinfo)) + len + 3) < sizeof(name) ) {
+ sprintf(name, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
+ len = strlen(name);
+ } else {
+ len = min(len, sizeof(name) - 1);
+ memcpy(name, snd_seq_port_info_get_name(pinfo), len);
+ name[len] = '\0';
+ }
+ ntdll_umbstowcs( name, len + 1, src->caps.szPname, ARRAY_SIZE(src->caps.szPname));
+ src->state = 0;
+
+ TRACE("MidiIn [%d]\tname='%s' support=%d\n"
+ "\tALSA info: midi dev-type=%x, capa=0\n",
+ num_srcs, wine_dbgstr_w(src->caps.szPname), src->caps.dwSupport, type);
+
+ num_srcs++;
+ }
+}
+
+NTSTATUS midi_init(void *args)
+{
+ struct midi_init_params *params = args;
+ static BOOL init_done;
+ snd_seq_client_info_t *cinfo;
+ snd_seq_port_info_t *pinfo;
+ int external;
+
+ if (init_done) {
+ *params->err = ERROR_ALREADY_INITIALIZED;
+ return STATUS_SUCCESS;
+ }
+
+ TRACE("Initializing the MIDI variables.\n");
+ init_done = TRUE;
+
+ /* try to open device */
+ if (seq_open() == -1) {
+ *params->err = ERROR_OPEN_FAILED;
+ return STATUS_SUCCESS;
+ }
+
+ cinfo = calloc( 1, snd_seq_client_info_sizeof() );
+ pinfo = calloc( 1, snd_seq_port_info_sizeof() );
+
+ /* Add internal ports first, followed by external */
+ for (external = 0; external < 2; external++) {
+ snd_seq_client_info_set_client(cinfo, -1);
+ while (snd_seq_query_next_client(midi_seq, cinfo) >= 0) {
+ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_port(pinfo, -1);
+ while (snd_seq_query_next_port(midi_seq, pinfo) >= 0) {
+ unsigned int cap = snd_seq_port_info_get_capability(pinfo);
+ unsigned int type = snd_seq_port_info_get_type(pinfo);
+ if (!external == !(type & SND_SEQ_PORT_TYPE_PORT))
+ port_add(cinfo, pinfo, cap, type);
+ }
+ }
+ }
+
+ seq_close();
+ free( cinfo );
+ free( pinfo );
+
+ *params->err = NOERROR;
+ params->num_dests = num_dests;
+ params->num_srcs = num_srcs;
+ params->dests = dests;
+ params->srcs = srcs;
+
+ TRACE("End\n");
+
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index c90b061da64..988429ab934 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -43,33 +43,12 @@
#include "wine/debug.h"
#include "wine/unixlib.h"
-#include <alsa/asoundlib.h>
-
#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(midi);
-typedef struct {
- int state; /* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
- MIDIOPENDESC midiDesc;
- WORD wFlags;
- LPMIDIHDR lpQueueHdr;
- DWORD startTime;
- MIDIINCAPSW caps;
- snd_seq_addr_t addr;
-} WINE_MIDIIN;
-
-typedef struct {
- BOOL bEnabled;
- MIDIOPENDESC midiDesc;
- WORD wFlags;
- MIDIOUTCAPSW caps;
- snd_seq_addr_t addr;
- int port_out;
-} WINE_MIDIOUT;
-
-static WINE_MIDIIN MidiInDev [MAX_MIDIINDRV ];
-static WINE_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
+static WINE_MIDIIN *MidiInDev;
+static WINE_MIDIOUT *MidiOutDev;
/* this is the total number of MIDI out devices found (synth and port) */
static int MODM_NumDevs = 0;
@@ -124,39 +103,6 @@ static void error_handler(const char* file, int line, const char* function, int
}
#endif
-/**************************************************************************
- * MIDI_unixToWindowsDeviceType [internal]
- *
- * return the Windows equivalent to a Unix Device Type
- *
- */
-static int MIDI_AlsaToWindowsDeviceType(unsigned int type)
-{
- /* MOD_MIDIPORT output port
- * MOD_SYNTH generic internal synth
- * MOD_SQSYNTH square wave internal synth
- * MOD_FMSYNTH FM internal synth
- * MOD_MAPPER MIDI mapper
- * MOD_WAVETABLE hardware wavetable internal synth
- * MOD_SWSYNTH software internal synth
- */
-
- /* FIXME Is this really the correct equivalence from ALSA to
- Windows Sound type? */
-
- if (type & SND_SEQ_PORT_TYPE_SYNTH)
- return MOD_FMSYNTH;
-
- if (type & (SND_SEQ_PORT_TYPE_DIRECT_SAMPLE|SND_SEQ_PORT_TYPE_SAMPLE))
- return MOD_SYNTH;
-
- if (type & (SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION))
- return MOD_MIDIPORT;
-
- ERR("Cannot determine the type (alsa type is %x) of this midi device. Assuming FM Synth\n", type);
- return MOD_FMSYNTH;
-}
-
/**************************************************************************
* MIDI_NotifyClient [internal]
*/
@@ -1121,134 +1067,6 @@ static DWORD modReset(WORD wDevID)
}
-/**************************************************************************
- * ALSA_AddMidiPort [internal]
- *
- * Helper for ALSA_MidiInit
- */
-static void ALSA_AddMidiPort(snd_seq_client_info_t* cinfo, snd_seq_port_info_t* pinfo, unsigned int cap, unsigned int type)
-{
- char midiPortName[MAXPNAMELEN];
-
- if (cap & SND_SEQ_PORT_CAP_WRITE) {
- TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
- snd_seq_client_info_get_name(cinfo),
- snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
- snd_seq_port_info_get_port(pinfo),
- snd_seq_port_info_get_name(pinfo),
- type);
-
- if (MODM_NumDevs >= MAX_MIDIOUTDRV)
- return;
- if (!type)
- return;
-
- MidiOutDev[MODM_NumDevs].addr = *snd_seq_port_info_get_addr(pinfo);
-
- /* Manufac ID. We do not have access to this with soundcard.h
- * Does not seem to be a problem, because in mmsystem.h only
- * Microsoft's ID is listed.
- */
- MidiOutDev[MODM_NumDevs].caps.wMid = 0x00FF;
- MidiOutDev[MODM_NumDevs].caps.wPid = 0x0001; /* FIXME Product ID */
- /* Product Version. We simply say "1" */
- MidiOutDev[MODM_NumDevs].caps.vDriverVersion = 0x001;
- /* The following are mandatory for MOD_MIDIPORT */
- MidiOutDev[MODM_NumDevs].caps.wChannelMask = 0xFFFF;
- MidiOutDev[MODM_NumDevs].caps.wVoices = 0;
- MidiOutDev[MODM_NumDevs].caps.wNotes = 0;
- MidiOutDev[MODM_NumDevs].caps.dwSupport = 0;
-
- /* Try to use both client and port names, if this is too long take the port name only.
- In the second case the port name should be explicit enough due to its big size.
- */
- if ( (strlen(snd_seq_client_info_get_name(cinfo)) + strlen(snd_seq_port_info_get_name(pinfo)) + 3) < MAXPNAMELEN ) {
- sprintf(midiPortName, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
- } else {
- lstrcpynA(midiPortName, snd_seq_port_info_get_name(pinfo), MAXPNAMELEN);
- }
- MultiByteToWideChar(CP_UNIXCP, 0, midiPortName, -1, MidiOutDev[MODM_NumDevs].caps.szPname,
- ARRAY_SIZE(MidiOutDev[MODM_NumDevs].caps.szPname));
-
- MidiOutDev[MODM_NumDevs].caps.wTechnology = MIDI_AlsaToWindowsDeviceType(type);
-
- if (MOD_MIDIPORT != MidiOutDev[MODM_NumDevs].caps.wTechnology) {
- /* FIXME Do we have this information?
- * Assuming the soundcards can handle
- * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
- * not MIDICAPS_CACHE.
- */
- MidiOutDev[MODM_NumDevs].caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
- MidiOutDev[MODM_NumDevs].caps.wVoices = 16;
-
- /* FIXME Is it possible to know the maximum
- * number of simultaneous notes of a soundcard ?
- * I believe we don't have this information, but
- * it's probably equal or more than wVoices
- */
- MidiOutDev[MODM_NumDevs].caps.wNotes = 16;
- }
- MidiOutDev[MODM_NumDevs].bEnabled = TRUE;
- MidiOutDev[MODM_NumDevs].port_out = -1;
-
- TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n"
- "\tALSA info: midi dev-type=%x, capa=0\n",
- MODM_NumDevs, wine_dbgstr_w(MidiOutDev[MODM_NumDevs].caps.szPname),
- MidiOutDev[MODM_NumDevs].caps.wTechnology,
- MidiOutDev[MODM_NumDevs].caps.wVoices, MidiOutDev[MODM_NumDevs].caps.wNotes,
- MidiOutDev[MODM_NumDevs].caps.wChannelMask, MidiOutDev[MODM_NumDevs].caps.dwSupport,
- type);
-
- MODM_NumDevs++;
- }
- if (cap & SND_SEQ_PORT_CAP_READ) {
- TRACE("IN (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
- snd_seq_client_info_get_name(cinfo),
- snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
- snd_seq_port_info_get_port(pinfo),
- snd_seq_port_info_get_name(pinfo),
- type);
-
- if (MIDM_NumDevs >= MAX_MIDIINDRV)
- return;
- if (!type)
- return;
-
- MidiInDev[MIDM_NumDevs].addr = *snd_seq_port_info_get_addr(pinfo);
-
- /* Manufac ID. We do not have access to this with soundcard.h
- * Does not seem to be a problem, because in mmsystem.h only
- * Microsoft's ID is listed.
- */
- MidiInDev[MIDM_NumDevs].caps.wMid = 0x00FF;
- MidiInDev[MIDM_NumDevs].caps.wPid = 0x0001; /* FIXME Product ID */
- /* Product Version. We simply say "1" */
- MidiInDev[MIDM_NumDevs].caps.vDriverVersion = 0x001;
- MidiInDev[MIDM_NumDevs].caps.dwSupport = 0; /* mandatory with MIDIINCAPS */
-
- /* Try to use both client and port names, if this is too long take the port name only.
- In the second case the port name should be explicit enough due to its big size.
- */
- if ( (strlen(snd_seq_client_info_get_name(cinfo)) + strlen(snd_seq_port_info_get_name(pinfo)) + 3) < MAXPNAMELEN ) {
- sprintf(midiPortName, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
- } else {
- lstrcpynA(midiPortName, snd_seq_port_info_get_name(pinfo), MAXPNAMELEN);
- }
- MultiByteToWideChar(CP_UNIXCP, 0, midiPortName, -1, MidiInDev[MIDM_NumDevs].caps.szPname,
- ARRAY_SIZE(MidiInDev[MIDM_NumDevs].caps.szPname));
- MidiInDev[MIDM_NumDevs].state = 0;
-
- TRACE("MidiIn [%d]\tname='%s' support=%d\n"
- "\tALSA info: midi dev-type=%x, capa=0\n",
- MIDM_NumDevs, wine_dbgstr_w(MidiInDev[MIDM_NumDevs].caps.szPname),
- MidiInDev[MIDM_NumDevs].caps.dwSupport,
- type);
-
- MIDM_NumDevs++;
- }
-}
-
-
/*======================================================================*
* MIDI entry points *
*======================================================================*/
@@ -1260,49 +1078,19 @@ static void ALSA_AddMidiPort(snd_seq_client_info_t* cinfo, snd_seq_port_info_t*
*/
static BOOL ALSA_MidiInit(void)
{
- static BOOL bInitDone = FALSE;
- snd_seq_client_info_t *cinfo;
- snd_seq_port_info_t *pinfo;
- int external;
-
- if (bInitDone)
- return TRUE;
-
- TRACE("Initializing the MIDI variables.\n");
- bInitDone = TRUE;
-
- /* try to open device */
- if (midiOpenSeq(FALSE) == -1) {
- return TRUE;
+ struct midi_init_params params;
+ UINT err;
+
+ params.err = &err;
+ ALSA_CALL(midi_init, ¶ms);
+
+ if (!err)
+ {
+ MODM_NumDevs = params.num_dests;
+ MIDM_NumDevs = params.num_srcs;
+ MidiOutDev = params.dests;
+ MidiInDev = params.srcs;
}
-
-#if 0 /* Debug purpose */
- snd_lib_error_set_handler(error_handler);
-#endif
- cinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_client_info_sizeof() );
- pinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_port_info_sizeof() );
-
- /* Add internal ports first, followed by external */
- for (external = 0; external < 2; external++) {
- snd_seq_client_info_set_client(cinfo, -1);
- while (snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
- snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
- snd_seq_port_info_set_port(pinfo, -1);
- while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
- unsigned int cap = snd_seq_port_info_get_capability(pinfo);
- unsigned int type = snd_seq_port_info_get_type(pinfo);
- if (!external == !(type & SND_SEQ_PORT_TYPE_PORT))
- ALSA_AddMidiPort(cinfo, pinfo, cap, type);
- }
- }
- }
-
- /* close file and exit */
- midiCloseSeq();
- HeapFree( GetProcessHeap(), 0, cinfo );
- HeapFree( GetProcessHeap(), 0, pinfo );
-
- TRACE("End\n");
return TRUE;
}
diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
index 89afcb71bec..adac72183ee 100644
--- a/dlls/winealsa.drv/unixlib.h
+++ b/dlls/winealsa.drv/unixlib.h
@@ -207,6 +207,37 @@ struct get_prop_value_params
unsigned int *buffer_size;
};
+#include <alsa/asoundlib.h>
+#include "mmddk.h"
+
+typedef struct midi_src
+{
+ int state; /* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
+ MIDIOPENDESC midiDesc;
+ WORD wFlags;
+ MIDIHDR *lpQueueHdr;
+ UINT startTime;
+ MIDIINCAPSW caps;
+ snd_seq_addr_t addr;
+} WINE_MIDIIN;
+
+typedef struct midi_dest
+{
+ BOOL bEnabled;
+ MIDIOPENDESC midiDesc;
+ WORD wFlags;
+ MIDIOUTCAPSW caps;
+ snd_seq_addr_t addr;
+ int port_out;
+} WINE_MIDIOUT;
+
+struct midi_init_params
+{
+ UINT *err;
+ unsigned int num_dests, num_srcs;
+ void *dests, *srcs;
+};
+
enum alsa_funcs
{
alsa_get_endpoint_ids,
@@ -232,10 +263,13 @@ enum alsa_funcs
alsa_set_event_handle,
alsa_is_started,
alsa_get_prop_value,
+ alsa_midi_init,
alsa_midi_seq_lock, /* temporary */
};
+NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
+
NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
extern unixlib_handle_t alsa_handle;
--
2.25.1
1
0
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winealsa.drv/midi.c | 38 ++++++++++++++------------------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index dff77ce88d8..c90b061da64 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -1263,6 +1263,7 @@ static BOOL ALSA_MidiInit(void)
static BOOL bInitDone = FALSE;
snd_seq_client_info_t *cinfo;
snd_seq_port_info_t *pinfo;
+ int external;
if (bInitDone)
return TRUE;
@@ -1281,30 +1282,19 @@ static BOOL ALSA_MidiInit(void)
cinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_client_info_sizeof() );
pinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_port_info_sizeof() );
- /* First, search for all internal midi devices */
- snd_seq_client_info_set_client(cinfo, -1);
- while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
- snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
- snd_seq_port_info_set_port(pinfo, -1);
- while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
- unsigned int cap = snd_seq_port_info_get_capability(pinfo);
- unsigned int type = snd_seq_port_info_get_type(pinfo);
- if (!(type & SND_SEQ_PORT_TYPE_PORT))
- ALSA_AddMidiPort(cinfo, pinfo, cap, type);
- }
- }
-
- /* Second, search for all external ports */
- snd_seq_client_info_set_client(cinfo, -1);
- while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
- snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
- snd_seq_port_info_set_port(pinfo, -1);
- while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
- unsigned int cap = snd_seq_port_info_get_capability(pinfo);
- unsigned int type = snd_seq_port_info_get_type(pinfo);
- if (type & SND_SEQ_PORT_TYPE_PORT)
- ALSA_AddMidiPort(cinfo, pinfo, cap, type);
- }
+ /* Add internal ports first, followed by external */
+ for (external = 0; external < 2; external++) {
+ snd_seq_client_info_set_client(cinfo, -1);
+ while (snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
+ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_port(pinfo, -1);
+ while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
+ unsigned int cap = snd_seq_port_info_get_capability(pinfo);
+ unsigned int type = snd_seq_port_info_get_type(pinfo);
+ if (!external == !(type & SND_SEQ_PORT_TYPE_PORT))
+ ALSA_AddMidiPort(cinfo, pinfo, cap, type);
+ }
+ }
}
/* close file and exit */
--
2.25.1
1
0
[PATCH 1/4] winebus.sys: Add HID haptics simple controllers for the triggers.
by Rémi Bernon 15 Mar '22
by Rémi Bernon 15 Mar '22
15 Mar '22
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winebus.sys/bus_sdl.c | 7 +++---
dlls/winebus.sys/bus_udev.c | 7 +++---
dlls/winebus.sys/hid.c | 44 +++++++++++++++++++++++++++++++--
dlls/winebus.sys/unix_private.h | 5 +++-
dlls/winebus.sys/unixlib.c | 6 +++--
5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index aedef50d3f7..aab629de5da 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -432,13 +432,14 @@ static void sdl_device_stop(struct unix_device *iface)
}
static NTSTATUS sdl_device_haptics_start(struct unix_device *iface, UINT duration_ms,
- USHORT rumble_intensity, USHORT buzz_intensity)
+ USHORT rumble_intensity, USHORT buzz_intensity,
+ USHORT left_intensity, USHORT right_intensity)
{
struct sdl_device *impl = impl_from_unix_device(iface);
SDL_HapticEffect effect;
- TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface, duration_ms,
- rumble_intensity, buzz_intensity);
+ TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u, left_intensity %u, right_intensity %u.\n",
+ iface, duration_ms, rumble_intensity, buzz_intensity, left_intensity, right_intensity);
if (!(impl->effect_support & EFFECT_SUPPORT_HAPTICS)) return STATUS_NOT_SUPPORTED;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index db173b63fb5..6b4bf09a773 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -867,7 +867,8 @@ static void lnxev_device_read_report(struct unix_device *iface)
}
static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, UINT duration_ms,
- USHORT rumble_intensity, USHORT buzz_intensity)
+ USHORT rumble_intensity, USHORT buzz_intensity,
+ USHORT left_intensity, USHORT right_intensity)
{
struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
struct ff_effect effect =
@@ -877,8 +878,8 @@ static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, UINT durat
};
struct input_event event;
- TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface,
- duration_ms, rumble_intensity, buzz_intensity);
+ TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u, left_intensity %u, right_intensity %u.\n",
+ iface, duration_ms, rumble_intensity, buzz_intensity, left_intensity, right_intensity);
effect.replay.length = duration_ms;
effect.u.rumble.strong_magnitude = rumble_intensity;
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 5b18da5d8ed..de0c3bb0848 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -335,6 +335,8 @@ struct hid_haptics_intensity
{
UINT16 rumble_intensity;
UINT16 buzz_intensity;
+ UINT16 left_intensity;
+ UINT16 right_intensity;
};
#include "poppack.h"
@@ -389,6 +391,15 @@ BOOL hid_device_add_haptics(struct unix_device *iface)
OUTPUT(1, Data|Var|Abs),
END_COLLECTION,
};
+ const BYTE trigger_template_begin[] =
+ {
+ USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
+ COLLECTION(1, Physical),
+ };
+ const BYTE trigger_template_end[] =
+ {
+ END_COLLECTION,
+ };
iface->hid_haptics.features_report = haptics_features_report;
iface->hid_haptics.intensity_report = haptics_intensity_report;
@@ -398,12 +409,36 @@ BOOL hid_device_add_haptics(struct unix_device *iface)
iface->hid_haptics.features.buzz.waveform = HID_USAGE_HAPTICS_WAVEFORM_BUZZ;
iface->hid_haptics.features.buzz.duration = 0;
iface->hid_haptics.features.buzz.cutoff_time_ms = 1000;
+ iface->hid_haptics.features.left.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
+ iface->hid_haptics.features.left.duration = 0;
+ iface->hid_haptics.features.left.cutoff_time_ms = 1000;
+ iface->hid_haptics.features.right.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
+ iface->hid_haptics.features.right.duration = 0;
+ iface->hid_haptics.features.right.cutoff_time_ms = 1000;
if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
return FALSE;
if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
return FALSE;
+ if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_Z))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin)))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end)))
+ return FALSE;
+
+ if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_RZ))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin)))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end)))
+ return FALSE;
+
return TRUE;
}
@@ -1071,12 +1106,15 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
io->Information = sizeof(*report) + 1;
assert(packet->reportBufferLen == io->Information);
- if (!report->rumble_intensity && !report->buzz_intensity)
+ if (!report->rumble_intensity && !report->buzz_intensity && !report->left_intensity && !report->right_intensity)
io->Status = iface->hid_vtbl->haptics_stop(iface);
else
{
duration_ms = min(haptics->features.rumble.cutoff_time_ms, haptics->features.buzz.cutoff_time_ms);
- io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity);
+ duration_ms = min(duration_ms, haptics->features.left.cutoff_time_ms);
+ duration_ms = min(duration_ms, haptics->features.right.cutoff_time_ms);
+ io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity,
+ report->left_intensity, report->right_intensity);
}
}
else if (packet->reportId == physical->device_control_report)
@@ -1287,6 +1325,8 @@ static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PA
haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms;
haptics->features.buzz.cutoff_time_ms = features->buzz.cutoff_time_ms;
+ haptics->features.left.cutoff_time_ms = features->left.cutoff_time_ms;
+ haptics->features.right.cutoff_time_ms = features->right.cutoff_time_ms;
io->Status = STATUS_SUCCESS;
}
else
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index 0763d084823..ab8060611a4 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -107,7 +107,8 @@ struct hid_device_vtbl
NTSTATUS (*start)(struct unix_device *iface);
void (*stop)(struct unix_device *iface);
NTSTATUS (*haptics_start)(struct unix_device *iface, UINT duration_ms,
- USHORT rumble_intensity, USHORT buzz_intensity);
+ USHORT rumble_intensity, USHORT buzz_intensity,
+ USHORT left_intensity, USHORT right_intensity);
NTSTATUS (*haptics_stop)(struct unix_device *iface);
NTSTATUS (*physical_device_control)(struct unix_device *iface, USAGE control);
NTSTATUS (*physical_device_set_gain)(struct unix_device *iface, BYTE percent);
@@ -135,6 +136,8 @@ struct hid_haptics_features
{
struct hid_haptics_feature rumble;
struct hid_haptics_feature buzz;
+ struct hid_haptics_feature left;
+ struct hid_haptics_feature right;
};
#include "poppack.h"
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 88cc513125a..1edd90627e5 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -103,7 +103,8 @@ static void mouse_stop(struct unix_device *iface)
}
static NTSTATUS mouse_haptics_start(struct unix_device *iface, UINT duration,
- USHORT rumble_intensity, USHORT buzz_intensity)
+ USHORT rumble_intensity, USHORT buzz_intensity,
+ USHORT left_intensity, USHORT right_intensity)
{
return STATUS_NOT_SUPPORTED;
}
@@ -193,7 +194,8 @@ static void keyboard_stop(struct unix_device *iface)
}
static NTSTATUS keyboard_haptics_start(struct unix_device *iface, UINT duration,
- USHORT rumble_intensity, USHORT buzz_intensity)
+ USHORT rumble_intensity, USHORT buzz_intensity,
+ USHORT left_intensity, USHORT right_intensity)
{
return STATUS_NOT_SUPPORTED;
}
--
2.35.1
1
3
- (U)I4 is a (U)LONG
- so migrate all helper functions and .idl to use LONG instead of ints
- renamed accordingly the variables (i => l, ui => ul)
- renamed accordingly method names s/Widget_int_ptr/Widget_long_ptr/
Note: we cannot use long yet as LONG isn't yet defined as a long.
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/oleaut32/tests/tmarshal.c | 85 +++++++++++++++++++-------------------
dlls/oleaut32/tests/tmarshal.idl | 12 +++--
2 files changed, 49 insertions(+), 48 deletions(-)
diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index 80ed7bed525..3c9d9a98a84 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -1104,17 +1104,17 @@ static HRESULT WINAPI Widget_VarArg_Ref_Run(
return S_OK;
}
-static HRESULT WINAPI Widget_basetypes_in(IWidget *iface, signed char c, short s, int i, hyper h,
- unsigned char uc, unsigned short us, unsigned int ui, MIDL_uhyper uh,
+static HRESULT WINAPI Widget_basetypes_in(IWidget *iface, signed char c, short s, LONG l, hyper h,
+ unsigned char uc, unsigned short us, ULONG ul, MIDL_uhyper uh,
float f, double d, STATE st)
{
ok(c == 5, "Got char %d.\n", c);
ok(s == -123, "Got short %d.\n", s);
- ok(i == -100000, "Got int %d.\n", i);
+ ok(l == -100000, "Got int %d.\n", l);
ok(h == (LONGLONG)-100000 * 1000000, "Got hyper %s.\n", wine_dbgstr_longlong(h));
ok(uc == 0, "Got unsigned char %u.\n", uc);
ok(us == 456, "Got unsigned short %u.\n", us);
- ok(ui == 0xdeadbeef, "Got unsigned int %i.\n", ui);
+ ok(ul == 0xdeadbeef, "Got unsigned int %u.\n", ul);
ok(uh == (ULONGLONG)1234567890 * 9876543210, "Got unsigned hyper %s.\n", wine_dbgstr_longlong(uh));
ok(f == (float)M_PI, "Got float %f.\n", f);
ok(d == M_E, "Got double %f.\n", d);
@@ -1123,17 +1123,17 @@ static HRESULT WINAPI Widget_basetypes_in(IWidget *iface, signed char c, short s
return S_OK;
}
-static HRESULT WINAPI Widget_basetypes_out(IWidget *iface, signed char *c, short *s, int *i, hyper *h,
- unsigned char *uc, unsigned short *us, unsigned int *ui, MIDL_uhyper *uh,
+static HRESULT WINAPI Widget_basetypes_out(IWidget *iface, signed char *c, short *s, LONG *l, hyper *h,
+ unsigned char *uc, unsigned short *us, ULONG *ul, MIDL_uhyper *uh,
float *f, double *d, STATE *st)
{
*c = 10;
*s = -321;
- *i = -200000;
+ *l = -200000;
*h = (LONGLONG)-200000 * 1000000;
*uc = 254;
*us = 256;
- *ui = 0xf00dfade;
+ *ul = 0xf00dfade;
*uh = (((ULONGLONG)0xabcdef01) << 32) | (ULONGLONG)0x23456789;
*f = M_LN2;
*d = M_LN10;
@@ -1153,7 +1153,7 @@ static HRESULT WINAPI Widget_float_abi(IWidget *iface, float f, double d, int i,
return S_OK;
}
-static HRESULT WINAPI Widget_int_ptr(IWidget *iface, int *in, int *out, int *in_out)
+static HRESULT WINAPI Widget_long_ptr(IWidget *iface, LONG *in, LONG *out, LONG *in_out)
{
ok(*in == 123, "Got [in] %d.\n", *in);
if (testmode == 0) /* Invoke() */
@@ -1169,7 +1169,7 @@ static HRESULT WINAPI Widget_int_ptr(IWidget *iface, int *in, int *out, int *in_
return S_OK;
}
-static HRESULT WINAPI Widget_int_ptr_ptr(IWidget *iface, int **in, int **out, int **in_out)
+static HRESULT WINAPI Widget_long_ptr_ptr(IWidget *iface, LONG **in, LONG **out, LONG **in_out)
{
ok(!*out, "Got [out] %p.\n", *out);
if (testmode == 0)
@@ -1637,8 +1637,8 @@ static const struct IWidgetVtbl Widget_VTable =
Widget_basetypes_in,
Widget_basetypes_out,
Widget_float_abi,
- Widget_int_ptr,
- Widget_int_ptr_ptr,
+ Widget_long_ptr,
+ Widget_long_ptr_ptr,
Widget_iface_in,
Widget_iface_out,
Widget_iface_ptr,
@@ -1980,11 +1980,12 @@ static void test_marshal_basetypes(IWidget *widget, IDispatch *disp)
signed char c;
short s;
+ LONG l;
int i, i2, *pi;
hyper h;
unsigned char uc;
unsigned short us;
- unsigned int ui;
+ ULONG ul;
MIDL_uhyper uh;
float f;
double d;
@@ -2009,46 +2010,46 @@ static void test_marshal_basetypes(IWidget *widget, IDispatch *disp)
0xdeadbeef, (ULONGLONG)1234567890 * 9876543210, M_PI, M_E, STATE_WIDGETIFIED);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- c = s = i = h = uc = us = ui = uh = f = d = st = 0;
+ c = s = l = h = uc = us = ul = uh = f = d = st = 0;
V_VT(&arg[10]) = VT_BYREF|VT_I1; V_I1REF(&arg[10]) = &c;
V_VT(&arg[9]) = VT_BYREF|VT_I2; V_I2REF(&arg[9]) = &s;
- V_VT(&arg[8]) = VT_BYREF|VT_I4; V_I4REF(&arg[8]) = &i;
+ V_VT(&arg[8]) = VT_BYREF|VT_I4; V_I4REF(&arg[8]) = &l;
V_VT(&arg[7]) = VT_BYREF|VT_I8; V_I8REF(&arg[7]) = &h;
V_VT(&arg[6]) = VT_BYREF|VT_UI1; V_UI1REF(&arg[6]) = &uc;
V_VT(&arg[5]) = VT_BYREF|VT_UI2; V_UI2REF(&arg[5]) = &us;
- V_VT(&arg[4]) = VT_BYREF|VT_UI4; V_UI4REF(&arg[4]) = &ui;
+ V_VT(&arg[4]) = VT_BYREF|VT_UI4; V_UI4REF(&arg[4]) = &ul;
V_VT(&arg[3]) = VT_BYREF|VT_UI8; V_UI8REF(&arg[3]) = &uh;
V_VT(&arg[2]) = VT_BYREF|VT_R4; V_R4REF(&arg[2]) = &f;
V_VT(&arg[1]) = VT_BYREF|VT_R8; V_R8REF(&arg[1]) = &d;
- V_VT(&arg[0]) = VT_BYREF|VT_I4; V_I4REF(&arg[0]) = (int *)&st;
+ V_VT(&arg[0]) = VT_BYREF|VT_I4; V_I4REF(&arg[0]) = (LONG *)&st;
hr = IDispatch_Invoke(disp, DISPID_TM_BASETYPES_OUT, &IID_NULL, LOCALE_NEUTRAL,
DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(c == 10, "Got char %d.\n", c);
ok(s == -321, "Got short %d.\n", s);
- ok(i == -200000, "Got int %d.\n", i);
+ ok(l == -200000, "Got int %d.\n", l);
ok(h == (LONGLONG)-200000 * 1000000L, "Got hyper %s.\n", wine_dbgstr_longlong(h));
ok(uc == 254, "Got unsigned char %u.\n", uc);
ok(us == 256, "Got unsigned short %u.\n", us);
- ok(ui == 0xf00dfade, "Got unsigned int %i.\n", ui);
+ ok(ul == 0xf00dfade, "Got unsigned int %i.\n", ul);
ok(uh == ((((ULONGLONG)0xabcdef01) << 32) | (ULONGLONG)0x23456789),
"Got unsigned hyper %s.\n", wine_dbgstr_longlong(uh));
ok(f == (float)M_LN2, "Got float %f.\n", f);
ok(d == M_LN10, "Got double %f.\n", d);
ok(st == STATE_UNWIDGETIFIED, "Got state %u.\n", st);
- c = s = i = h = uc = us = ui = uh = f = d = st = 0;
+ c = s = l = h = uc = us = ul = uh = f = d = st = 0;
- hr = IWidget_basetypes_out(widget, &c, &s, &i, &h, &uc, &us, &ui, &uh, &f, &d, &st);
+ hr = IWidget_basetypes_out(widget, &c, &s, &l, &h, &uc, &us, &ul, &uh, &f, &d, &st);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(c == 10, "Got char %d.\n", c);
ok(s == -321, "Got short %d.\n", s);
- ok(i == -200000, "Got int %d.\n", i);
+ ok(l == -200000, "Got int %d.\n", l);
ok(h == (LONGLONG)-200000 * 1000000L, "Got hyper %s.\n", wine_dbgstr_longlong(h));
ok(uc == 254, "Got unsigned char %u.\n", uc);
ok(us == 256, "Got unsigned short %u.\n", us);
- ok(ui == 0xf00dfade, "Got unsigned int %i.\n", ui);
+ ok(ul == 0xf00dfade, "Got unsigned int %i.\n", ul);
ok(uh == ((((ULONGLONG)0xabcdef01) << 32) | (ULONGLONG)0x23456789),
"Got unsigned hyper %s.\n", wine_dbgstr_longlong(uh));
ok(f == (float)M_LN2, "Got float %f.\n", f);
@@ -2073,7 +2074,7 @@ static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
{
VARIANTARG arg[3];
DISPPARAMS dispparams = {arg, NULL, ARRAY_SIZE(arg), 0};
- int in, out, in_out, *in_ptr, *out_ptr, *in_out_ptr;
+ LONG in, out, in_out, *in_ptr, *out_ptr, *in_out_ptr;
HRESULT hr;
testmode = 0;
@@ -2096,26 +2097,26 @@ static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
in = 123;
out = 456;
in_out = 789;
- hr = IWidget_int_ptr(widget, &in, &out, &in_out);
+ hr = IWidget_long_ptr(widget, &in, &out, &in_out);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(in == 123, "Got [in] %d.\n", in);
ok(out == 654, "Got [out] %d.\n", out);
ok(in_out == 321, "Got [in, out] %d.\n", in_out);
out = in_out = -1;
- hr = IWidget_int_ptr(widget, NULL, &out, &in_out);
+ hr = IWidget_long_ptr(widget, NULL, &out, &in_out);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(!out, "[out] parameter should have been cleared.\n");
ok(in_out == -1, "[in, out] parameter should not have been cleared.\n");
in = in_out = -1;
- hr = IWidget_int_ptr(widget, &in, NULL, &in_out);
+ hr = IWidget_long_ptr(widget, &in, NULL, &in_out);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(in == -1, "[in] parameter should not have been cleared.\n");
ok(in_out == -1, "[in, out] parameter should not have been cleared.\n");
in = out = -1;
- hr = IWidget_int_ptr(widget, &in, &out, NULL);
+ hr = IWidget_long_ptr(widget, &in, &out, NULL);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(in == -1, "[in] parameter should not have been cleared.\n");
ok(!out, "[out] parameter should have been cleared.\n");
@@ -2125,14 +2126,14 @@ static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
testmode = 0;
in_ptr = out_ptr = in_out_ptr = NULL;
- hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
+ hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
ok(hr == S_OK, "Got hr %#x\n", hr);
ok(!in_ptr, "Got [in] %p.\n", in_ptr);
ok(!out_ptr, "Got [out] %p.\n", out_ptr);
ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
testmode = 1;
- hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
+ hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
ok(hr == S_OK, "Got hr %#x\n", hr);
ok(*out_ptr == 654, "Got [out] %d.\n", *out_ptr);
ok(*in_out_ptr == 321, "Got [in, out] %d.\n", *in_out_ptr);
@@ -2146,7 +2147,7 @@ static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
in_ptr = ∈
out_ptr = &out;
in_out_ptr = &in_out;
- hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
+ hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(out_ptr != &out, "[out] ptr should have changed.\n");
ok(in_out_ptr == &in_out, "[in, out] ptr should not have changed.\n");
@@ -2157,27 +2158,27 @@ static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
in_ptr = out_ptr = NULL;
in_out = 789;
in_out_ptr = &in_out;
- hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
+ hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
out_ptr = &out;
in_out_ptr = &in_out;
- hr = IWidget_int_ptr_ptr(widget, NULL, &out_ptr, &in_out_ptr);
+ hr = IWidget_long_ptr_ptr(widget, NULL, &out_ptr, &in_out_ptr);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(!out_ptr, "[out] parameter should have been cleared.\n");
ok(in_out_ptr == &in_out, "[in, out] parameter should not have been cleared.\n");
in_ptr = ∈
in_out_ptr = &in_out;
- hr = IWidget_int_ptr_ptr(widget, &in_ptr, NULL, &in_out_ptr);
+ hr = IWidget_long_ptr_ptr(widget, &in_ptr, NULL, &in_out_ptr);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
ok(in_out_ptr == &in_out, "[in, out] parameter should not have been cleared.\n");
in_ptr = ∈
out_ptr = &out;
- hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, NULL);
+ hr = IWidget_long_ptr_ptr(widget, &in_ptr, &out_ptr, NULL);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
ok(!out_ptr, "[out] parameter should have been cleared.\n");
@@ -2634,7 +2635,7 @@ static void test_marshal_array(IWidget *widget, IDispatch *disp)
array_t in, out, in_out;
MYSTRUCT struct_in[2];
HRESULT hr;
- int i = 2;
+ LONG l = 2;
memcpy(in, test_array1, sizeof(array_t));
memcpy(out, test_array2, sizeof(array_t));
@@ -2646,7 +2647,7 @@ static void test_marshal_array(IWidget *widget, IDispatch *disp)
ok(!memcmp(&in_out, &test_array6, sizeof(array_t)), "Arrays didn't match.\n");
V_VT(&var_in[0]) = VT_I4; V_I4(&var_in[0]) = 1;
- V_VT(&var_in[1]) = VT_BYREF|VT_I4; V_I4REF(&var_in[1]) = &i;
+ V_VT(&var_in[1]) = VT_BYREF|VT_I4; V_I4REF(&var_in[1]) = &l;
V_VT(&var_out[0]) = VT_I4; V_I4(&var_out[0]) = 3;
V_VT(&var_out[1]) = VT_I4; V_I4(&var_out[1]) = 4;
V_VT(&var_in_out[0]) = VT_I4; V_I4(&var_in_out[0]) = 5;
@@ -2656,8 +2657,8 @@ static void test_marshal_array(IWidget *widget, IDispatch *disp)
ok(V_VT(&var_in[0]) == VT_I4, "Got wrong type %u.\n", V_VT(&var_in[0]));
ok(V_I4(&var_in[0]) == 1, "Got wrong value %d.\n", V_I4(&var_in[0]));
ok(V_VT(&var_in[1]) == (VT_BYREF|VT_I4), "Got wrong type %u.\n", V_VT(&var_in[1]));
- ok(V_I4REF(&var_in[1]) == &i, "Got wrong value %p.\n", V_I4REF(&var_in[1]));
- ok(i == 2, "Got wrong value %d.\n", i);
+ ok(V_I4REF(&var_in[1]) == &l, "Got wrong value %p.\n", V_I4REF(&var_in[1]));
+ ok(l == 2, "Got wrong value %d.\n", l);
ok(V_VT(&var_out[0]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_out[0]));
ok(V_I1(&var_out[0]) == 9, "Got wrong value %u.\n", V_VT(&var_out[0]));
ok(V_VT(&var_out[1]) == VT_BSTR, "Got wrong type %u.\n", V_VT(&var_out[1]));
@@ -3054,7 +3055,7 @@ static void test_typelibmarshal(void)
the_state = STATE_WIDGETIFIED;
VariantInit(&vararg[0]);
V_VT(&vararg[0]) = VT_BYREF|VT_I4;
- V_I4REF(&vararg[0]) = (int *)&the_state;
+ V_I4REF(&vararg[0]) = (LONG *)&the_state;
dispparams.cNamedArgs = 1;
dispparams.cArgs = 1;
dispparams.rgdispidNamedArgs = &dispidNamed;
@@ -3416,7 +3417,7 @@ static void test_typelibmarshal(void)
uval = 666;
VariantInit(&vararg[0]);
V_VT(&vararg[0]) = VT_UI4|VT_BYREF;
- V_UI4REF(&vararg[0]) = &uval;
+ V_UI4REF(&vararg[0]) = (ULONG *)&uval;
dispparams.cNamedArgs = 0;
dispparams.cArgs = 1;
dispparams.rgvarg = vararg;
@@ -3425,7 +3426,7 @@ static void test_typelibmarshal(void)
ok_ole_success(hr, ITypeInfo_Invoke);
ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
ok(V_VT(&vararg[0]) == (VT_UI4|VT_BYREF), "arg VT not unmarshalled correctly: %x\n", V_VT(&vararg[0]));
- ok(V_UI4REF(&vararg[0]) == &uval, "Byref pointer not preserved: %p/%p\n", &uval, V_UI4REF(&vararg[0]));
+ ok(V_UI4REF(&vararg[0]) == (ULONG *)&uval, "Byref pointer not preserved: %p/%p\n", &uval, V_UI4REF(&vararg[0]));
ok(*V_UI4REF(&vararg[0]) == 42, "Expected 42 to be returned instead of %u\n", *V_UI4REF(&vararg[0]));
VariantClear(&varresult);
VariantClear(&vararg[0]);
diff --git a/dlls/oleaut32/tests/tmarshal.idl b/dlls/oleaut32/tests/tmarshal.idl
index a594f9137d8..e1c5a8557b7 100644
--- a/dlls/oleaut32/tests/tmarshal.idl
+++ b/dlls/oleaut32/tests/tmarshal.idl
@@ -291,23 +291,23 @@ cpp_quote("struct Coclass3 { ICoclass1 *iface; };")
HRESULT VarArg_Ref_Run([in] BSTR name, [in] SAFEARRAY(VARIANT) *params, [out, retval] VARIANT *result);
[id(DISPID_TM_BASETYPES_IN)]
- HRESULT basetypes_in([in] signed char c, [in] short s, [in] int i, [in] hyper h,
- [in] unsigned char uc, [in] unsigned short us, [in] unsigned int ui,
+ HRESULT basetypes_in([in] signed char c, [in] short s, [in] long l, [in] hyper h,
+ [in] unsigned char uc, [in] unsigned short us, [in] unsigned long ul,
[in] unsigned hyper uh, [in] float f, [in] double d, [in] STATE st);
[id(DISPID_TM_BASETYPES_OUT)]
- HRESULT basetypes_out([out] signed char *c, [out] short *s, [out] int *i, [out] hyper *h,
- [out] unsigned char *uc, [out] unsigned short *us, [out] unsigned int *ui,
+ HRESULT basetypes_out([out] signed char *c, [out] short *s, [out] long *l, [out] hyper *h,
+ [out] unsigned char *uc, [out] unsigned short *us, [out] unsigned long *ul,
[out] unsigned hyper *uh, [out] float *f, [out] double *d, [out] STATE *st);
[id(DISPID_TM_FLOAT_ABI)]
HRESULT float_abi([in] float f, [in] double d, [in] int i, [in] float f2, [in] double d2);
[id(DISPID_TM_INT_PTR)]
- HRESULT int_ptr([in] int *in, [out] int *out, [in, out] int *in_out);
+ HRESULT long_ptr([in] long *in, [out] long *out, [in, out] long *in_out);
[id(DISPID_TM_INT_PTR_PTR)]
- HRESULT int_ptr_ptr([in] int **in, [out] int **out, [in, out] int **in_out);
+ HRESULT long_ptr_ptr([in] long **in, [out] long **out, [in, out] long **in_out);
[id(DISPID_TM_IFACE_IN)]
HRESULT iface_in([in] IUnknown *unk, [in] IDispatch *disp, [in] ISomethingFromDispatch *sfd);
2
3
may I ask the status of those patches?
227544-227549 CreateProcess on Cui
228501 cmd filename completion
228539-228540 support for pseudo env vars
and fixes to debugger
228665-228667 (fixes to debugger)
227243-227246 (winedbg on wow64)
TIA
1
1