Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Tue, Mar 15, 2022 at 04:19:02PM +0000, Huw Davies wrote:
Signed-off-by: Huw Davies huw@codeweavers.com
dlls/winealsa.drv/alsa.c | 1 + dlls/winealsa.drv/alsamidi.c | 133 +++++++++++++++++++++++++++++++++++ dlls/winealsa.drv/midi.c | 127 +++++++-------------------------- dlls/winealsa.drv/unixlib.h | 26 +++++++ 4 files changed, 186 insertions(+), 101 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index 16c0c7c387d..6d307eb84bf 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -2445,6 +2445,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = is_started, get_prop_value, midi_init,
midi_out_message,
midi_seq_lock, /* temporary */ midi_seq_open,
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c index e1fca85b3b4..a7a5a211484 100644 --- a/dlls/winealsa.drv/alsamidi.c +++ b/dlls/winealsa.drv/alsamidi.c @@ -362,3 +362,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