diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c index 80e677b3064..535699a4059 100644 --- a/dlls/winealsa.drv/alsamidi.c +++ b/dlls/winealsa.drv/alsamidi.c @@ -105,6 +105,20 @@ NTSTATUS midi_in_lock(void *args) return STATUS_SUCCESS; } +static void set_in_notify(struct notify_context *notify, struct midi_src *src, 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 = src->midiDesc.dwCallback; + notify->flags = src->wFlags; + notify->device = src->midiDesc.hMidi; + notify->instance = src->midiDesc.dwInstance; +} + static snd_seq_t *seq_open(int *port_in_ret) { static int midi_warn; @@ -928,6 +942,36 @@ static UINT midi_in_get_devcaps(WORD dev_id, MIDIINCAPSW *caps, UINT size) return MMSYSERR_NOERROR; } +static DWORD midi_in_reset(WORD dev_id, struct notify_context *notify) +{ + UINT cur_time = NtGetTickCount(); + UINT err = MMSYSERR_NOERROR; + struct midi_src *src; + MIDIHDR *hdr; + + TRACE("(%04X);\n", dev_id); + + if (dev_id >= num_srcs) return MMSYSERR_BADDEVICEID; + src = srcs + dev_id; + if (src->state == -1) return MIDIERR_NODEVICE; + + in_buffer_lock(); + + if (src->lpQueueHdr) + { + hdr = src->lpQueueHdr; + src->lpQueueHdr = hdr->lpNext; + hdr->dwFlags &= ~MHDR_INQUEUE; + hdr->dwFlags |= MHDR_DONE; + set_in_notify(notify, src, dev_id, MIM_LONGDATA, (DWORD_PTR)hdr, cur_time - src->startTime); + if (src->lpQueueHdr) err = ERROR_RETRY; /* ask the client to call again */ + } + + in_buffer_unlock(); + + return err; +} + NTSTATUS midi_out_message(void *args) { struct midi_out_message_params *params = args; @@ -987,6 +1031,8 @@ NTSTATUS midi_in_message(void *args) { struct midi_in_message_params *params = args; + params->notify->send_notify = FALSE; + switch (params->msg) { case DRVM_EXIT: @@ -1010,6 +1056,9 @@ NTSTATUS midi_in_message(void *args) case MIDM_GETNUMDEVS: *params->err = num_srcs; break; + case MIDM_RESET: + *params->err = midi_in_reset(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 72649eca89c..5639bf67369 100644 --- a/dlls/winealsa.drv/midi.c +++ b/dlls/winealsa.drv/midi.c @@ -459,31 +459,6 @@ static DWORD midClose(WORD wDevID) return ret; } -/************************************************************************** - * midReset [internal] - */ -static DWORD midReset(WORD wDevID) -{ - DWORD dwTime = GetTickCount(); - - TRACE("(%04X);\n", wDevID); - - if (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID; - if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; - - in_buffer_lock(); - while (MidiInDev[wDevID].lpQueueHdr) { - LPMIDIHDR lpMidiHdr = MidiInDev[wDevID].lpQueueHdr; - MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; - lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; - lpMidiHdr->dwFlags |= MHDR_DONE; - MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime - MidiInDev[wDevID].startTime); - } - in_buffer_unlock(); - - return MMSYSERR_NOERROR; -} - /************************************************************************** * midStart [internal] */ @@ -545,6 +520,7 @@ DWORD WINAPI ALSA_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { struct midi_in_message_params params; + struct notify_context notify; UINT err; TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n", @@ -557,8 +533,6 @@ DWORD WINAPI ALSA_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, return midOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2); case MIDM_CLOSE: return midClose(wDevID); - case MIDM_RESET: - return midReset(wDevID); case MIDM_START: return midStart(wDevID); case MIDM_STOP: @@ -571,8 +545,13 @@ DWORD WINAPI ALSA_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, params.param_1 = dwParam1; params.param_2 = dwParam2; params.err = &err; + params.notify = ¬ify; - ALSA_CALL(midi_in_message, ¶ms); + do + { + ALSA_CALL(midi_in_message, ¶ms); + if ((!err || err == ERROR_RETRY) && notify.send_notify) notify_client(¬ify); + } while (err == ERROR_RETRY); return err; } diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h index 263e83eda57..6d5bcb64cf0 100644 --- a/dlls/winealsa.drv/unixlib.h +++ b/dlls/winealsa.drv/unixlib.h @@ -262,6 +262,7 @@ struct midi_in_message_params UINT_PTR param_1; UINT_PTR param_2; UINT *err; + struct notify_context *notify; }; struct midi_seq_open_params