winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
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
List overview
wine-devel
March 2022
----- 2025 -----
July 2025
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-devel@winehq.org
80 participants
950 discussions
Start a n
N
ew thread
[PATCH 1/4] winealsa: Move get_prop_value to the unixlib.
by Huw Davies
15 Mar '22
15 Mar '22
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 "
…
[View More]
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
[View Less]
4
6
0
0
[PATCH 6/6] winealsa: Move MODM_CLOSE to the unixlib.
by Huw Davies
15 Mar '22
15 Mar '22
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,
…
[View More]
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
[View Less]
1
0
0
0
[PATCH 5/6] winealsa: Move MODM_OPEN to the unixlib.
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 | 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/
…
[View More]
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
[View Less]
1
0
0
0
[PATCH 4/6] winealsa: Add a temporary syscall to return the snd_seq handle.
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
…
[View More]
@@ -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
[View Less]
1
0
0
0
[PATCH 3/6] winealsa: Store the snd_seq handle and the input port in the device data.
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 @@
…
[View More]
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
[View Less]
1
0
0
0
[PATCH 2/6] winealsa: Move midi_init to unixlib.
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 | 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.
…
[View More]
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
[View Less]
1
0
0
0
[PATCH 1/6] winealsa: Combine two loops into one.
by Huw Davies
15 Mar '22
15 Mar '22
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 *
…
[View More]
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
[View Less]
1
0
0
0
[PATCH 1/4] winebus.sys: Add HID haptics simple controllers for the triggers.
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/
…
[View More]
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
[View Less]
1
3
0
0
[PATCH 1/2] dlls/oleaut32/tests: use correct integral type
by Eric Pouech
15 Mar '22
15 Mar '22
- (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,
…
[View More]
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);
[View Less]
2
3
0
0
status of patches
by Eric Pouech
15 Mar '22
15 Mar '22
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
0
0
← Newer
1
...
48
49
50
51
52
53
54
...
95
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
Results per page:
10
25
50
100
200