winealsa: Move MIDM_OPEN and MIDM_CLOSE to the unixlib.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
32746a292d
commit
33d7dd9268
|
@ -3,7 +3,7 @@ MODULE = winealsa.drv
|
|||
UNIXLIB = winealsa.so
|
||||
IMPORTS = uuid ole32 advapi32
|
||||
DELAYIMPORTS = winmm
|
||||
EXTRALIBS = $(ALSA_LIBS)
|
||||
EXTRALIBS = $(ALSA_LIBS) $(PTHREAD_LIBS)
|
||||
|
||||
EXTRADLLFLAGS = -mcygwin
|
||||
|
||||
|
|
|
@ -2449,8 +2449,4 @@ unixlib_entry_t __wine_unix_call_funcs[] =
|
|||
midi_out_message,
|
||||
midi_in_message,
|
||||
midi_notify_wait,
|
||||
|
||||
midi_seq_lock, /* temporary */
|
||||
midi_seq_open,
|
||||
midi_handle_event,
|
||||
};
|
||||
|
|
|
@ -60,6 +60,19 @@ struct midi_dest
|
|||
int port_out;
|
||||
};
|
||||
|
||||
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_t *seq;
|
||||
snd_seq_addr_t addr;
|
||||
int port_in;
|
||||
};
|
||||
|
||||
static pthread_mutex_t seq_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t in_buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -70,6 +83,10 @@ static snd_seq_t *midi_seq;
|
|||
static unsigned int seq_refs;
|
||||
static int port_in = -1;
|
||||
|
||||
static unsigned int num_midi_in_started;
|
||||
static int rec_cancel_pipe[2];
|
||||
static pthread_t rec_thread_id;
|
||||
|
||||
static pthread_mutex_t notify_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t notify_cond = PTHREAD_COND_INITIALIZER;
|
||||
static BOOL notify_quit;
|
||||
|
@ -87,14 +104,6 @@ static void seq_unlock(void)
|
|||
pthread_mutex_unlock(&seq_mutex);
|
||||
}
|
||||
|
||||
NTSTATUS midi_seq_lock(void *args)
|
||||
{
|
||||
if (args) seq_lock();
|
||||
else seq_unlock();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void in_buffer_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&in_buffer_mutex);
|
||||
|
@ -233,18 +242,6 @@ static void seq_close(void)
|
|||
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
|
||||
|
@ -458,8 +455,6 @@ NTSTATUS midi_init(void *args)
|
|||
free( pinfo );
|
||||
|
||||
*params->err = NOERROR;
|
||||
params->num_srcs = num_srcs;
|
||||
params->srcs = srcs;
|
||||
|
||||
TRACE("End\n");
|
||||
|
||||
|
@ -1033,9 +1028,8 @@ static void handle_regular_event(struct midi_src *src, snd_seq_event_t *ev)
|
|||
}
|
||||
}
|
||||
|
||||
NTSTATUS midi_handle_event(void *args)
|
||||
static void midi_handle_event(snd_seq_event_t *ev)
|
||||
{
|
||||
snd_seq_event_t *ev = args;
|
||||
struct midi_src *src;
|
||||
|
||||
/* Find the target device */
|
||||
|
@ -1043,14 +1037,193 @@ NTSTATUS midi_handle_event(void *args)
|
|||
if ((ev->source.client == src->addr.client) && (ev->source.port == src->addr.port))
|
||||
break;
|
||||
if ((src == srcs + num_srcs) || (src->state != 1))
|
||||
return STATUS_SUCCESS;
|
||||
return;
|
||||
|
||||
if (ev->type == SND_SEQ_EVENT_SYSEX)
|
||||
handle_sysex_event(src, ev->data.ext.ptr, ev->data.ext.len);
|
||||
else
|
||||
handle_regular_event(src, ev);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
static void *rec_thread_proc(void *arg)
|
||||
{
|
||||
snd_seq_t *midi_seq = (snd_seq_t *)arg;
|
||||
int num_fds;
|
||||
struct pollfd *pollfd;
|
||||
int ret;
|
||||
|
||||
/* Add on one for the read end of the cancel pipe */
|
||||
num_fds = snd_seq_poll_descriptors_count(midi_seq, POLLIN) + 1;
|
||||
pollfd = malloc(num_fds * sizeof(struct pollfd));
|
||||
|
||||
while(1)
|
||||
{
|
||||
pollfd[0].fd = rec_cancel_pipe[0];
|
||||
pollfd[0].events = POLLIN;
|
||||
|
||||
seq_lock();
|
||||
snd_seq_poll_descriptors(midi_seq, pollfd + 1, num_fds - 1, POLLIN);
|
||||
seq_unlock();
|
||||
|
||||
/* Check if an event is present */
|
||||
if (poll(pollfd, num_fds, -1) <= 0)
|
||||
continue;
|
||||
|
||||
if (pollfd[0].revents & POLLIN) /* cancelled */
|
||||
break;
|
||||
|
||||
do
|
||||
{
|
||||
snd_seq_event_t *ev;
|
||||
|
||||
seq_lock();
|
||||
snd_seq_event_input(midi_seq, &ev);
|
||||
seq_unlock();
|
||||
|
||||
if (ev)
|
||||
{
|
||||
midi_handle_event(ev);
|
||||
snd_seq_free_event(ev);
|
||||
}
|
||||
|
||||
seq_lock();
|
||||
ret = snd_seq_event_input_pending(midi_seq, 0);
|
||||
seq_unlock();
|
||||
} while(ret > 0);
|
||||
}
|
||||
|
||||
free(pollfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT midi_in_open(WORD dev_id, MIDIOPENDESC *desc, UINT flags, struct notify_context *notify)
|
||||
{
|
||||
struct midi_src *src;
|
||||
int ret = 0, port_in;
|
||||
snd_seq_t *midi_seq;
|
||||
|
||||
TRACE("(%04X, %p, %08X);\n", dev_id, desc, flags);
|
||||
|
||||
if (!desc)
|
||||
{
|
||||
WARN("Invalid Parameter !\n");
|
||||
return MMSYSERR_INVALPARAM;
|
||||
}
|
||||
|
||||
/* FIXME: check that contents of desc are correct */
|
||||
|
||||
if (dev_id >= num_srcs)
|
||||
{
|
||||
WARN("dev_id too large (%u) !\n", dev_id);
|
||||
return MMSYSERR_BADDEVICEID;
|
||||
}
|
||||
src = srcs + dev_id;
|
||||
|
||||
if (src->state == -1)
|
||||
{
|
||||
WARN("device disabled\n");
|
||||
return MIDIERR_NODEVICE;
|
||||
}
|
||||
if (src->midiDesc.hMidi)
|
||||
{
|
||||
WARN("device already open !\n");
|
||||
return MMSYSERR_ALLOCATED;
|
||||
}
|
||||
if (flags & MIDI_IO_STATUS)
|
||||
{
|
||||
WARN("No support for MIDI_IO_STATUS in flags yet, ignoring it\n");
|
||||
flags &= ~MIDI_IO_STATUS;
|
||||
}
|
||||
if (flags & ~CALLBACK_TYPEMASK)
|
||||
{
|
||||
FIXME("Bad flags %08X\n", flags);
|
||||
return MMSYSERR_INVALFLAG;
|
||||
}
|
||||
|
||||
if (!(midi_seq = seq_open(&port_in)))
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
src->wFlags = HIWORD(flags & CALLBACK_TYPEMASK);
|
||||
|
||||
src->lpQueueHdr = NULL;
|
||||
src->midiDesc = *desc;
|
||||
src->state = 0;
|
||||
src->startTime = 0;
|
||||
src->seq = midi_seq;
|
||||
src->port_in = port_in;
|
||||
|
||||
/* Connect our app port to the device port */
|
||||
seq_lock();
|
||||
ret = snd_seq_connect_from(midi_seq, port_in, src->addr.client, src->addr.port);
|
||||
seq_unlock();
|
||||
if (ret < 0)
|
||||
return MMSYSERR_NOTENABLED;
|
||||
|
||||
TRACE("Input port :%d connected %d:%d\n", port_in, src->addr.client, src->addr.port);
|
||||
|
||||
if (num_midi_in_started++ == 0)
|
||||
{
|
||||
pipe(rec_cancel_pipe);
|
||||
if (pthread_create(&rec_thread_id, NULL, rec_thread_proc, midi_seq))
|
||||
{
|
||||
close(rec_cancel_pipe[0]);
|
||||
close(rec_cancel_pipe[1]);
|
||||
num_midi_in_started = 0;
|
||||
WARN("Couldn't create thread for midi-in\n");
|
||||
seq_close();
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
set_in_notify(notify, src, dev_id, MIM_OPEN, 0, 0);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static UINT midi_in_close(WORD dev_id, struct notify_context *notify)
|
||||
{
|
||||
struct midi_src *src;
|
||||
|
||||
TRACE("(%04X);\n", dev_id);
|
||||
|
||||
if (dev_id >= num_srcs)
|
||||
{
|
||||
WARN("dev_id too big (%u) !\n", dev_id);
|
||||
return MMSYSERR_BADDEVICEID;
|
||||
}
|
||||
src = srcs + dev_id;
|
||||
if (!src->midiDesc.hMidi)
|
||||
{
|
||||
WARN("device not opened !\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
if (src->lpQueueHdr)
|
||||
return MIDIERR_STILLPLAYING;
|
||||
|
||||
if (src->seq == NULL)
|
||||
{
|
||||
WARN("ooops !\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
if (--num_midi_in_started == 0)
|
||||
{
|
||||
TRACE("Stopping thread for midi-in\n");
|
||||
write(rec_cancel_pipe[1], "x", 1);
|
||||
pthread_join(rec_thread_id, NULL);
|
||||
close(rec_cancel_pipe[0]);
|
||||
close(rec_cancel_pipe[1]);
|
||||
TRACE("Stopped thread for midi-in\n");
|
||||
}
|
||||
|
||||
seq_lock();
|
||||
snd_seq_disconnect_from(src->seq, src->port_in, src->addr.client, src->addr.port);
|
||||
seq_unlock();
|
||||
seq_close();
|
||||
|
||||
set_in_notify(notify, src, dev_id, MIM_CLOSE, 0, 0);
|
||||
src->midiDesc.hMidi = 0;
|
||||
src->seq = NULL;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static UINT midi_in_add_buffer(WORD dev_id, MIDIHDR *hdr, UINT hdr_size)
|
||||
|
@ -1257,6 +1430,12 @@ NTSTATUS midi_in_message(void *args)
|
|||
/* FIXME: Pretend this is supported */
|
||||
*params->err = MMSYSERR_NOERROR;
|
||||
break;
|
||||
case MIDM_OPEN:
|
||||
*params->err = midi_in_open(params->dev_id, (MIDIOPENDESC *)params->param_1, params->param_2, params->notify);
|
||||
break;
|
||||
case MIDM_CLOSE:
|
||||
*params->err = midi_in_close(params->dev_id, params->notify);
|
||||
break;
|
||||
case MIDM_ADDBUFFER:
|
||||
*params->err = midi_in_add_buffer(params->dev_id, (MIDIHDR *)params->param_1, params->param_2);
|
||||
break;
|
||||
|
|
|
@ -47,26 +47,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(midi);
|
||||
|
||||
static WINE_MIDIIN *MidiInDev;
|
||||
|
||||
/* this is the total number of MIDI out devices found */
|
||||
static int MIDM_NumDevs = 0;
|
||||
|
||||
static int numStartedMidiIn = 0;
|
||||
|
||||
static int rec_cancel_pipe[2];
|
||||
static HANDLE hThread;
|
||||
|
||||
static void seq_lock(void)
|
||||
{
|
||||
ALSA_CALL(midi_seq_lock, (void *)(UINT_PTR)1);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -75,264 +55,6 @@ static void notify_client(struct notify_context *notify)
|
|||
notify->instance, notify->param_1, notify->param_2);
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* Low level MIDI implementation *
|
||||
*======================================================================*/
|
||||
|
||||
#if 0 /* Debug Purpose */
|
||||
static void error_handler(const char* file, int line, const char* function, int err, const char* fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
if (err == ENOENT)
|
||||
return;
|
||||
va_start(arg, fmt);
|
||||
fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function);
|
||||
vfprintf(stderr, fmt, arg);
|
||||
if (err)
|
||||
fprintf(stderr, ": %s", snd_strerror(err));
|
||||
putc('\n', stderr);
|
||||
va_end(arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* MIDI_NotifyClient [internal]
|
||||
*/
|
||||
static void MIDI_NotifyClient(UINT wDevID, WORD wMsg,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
DWORD_PTR dwCallBack;
|
||||
UINT uFlags;
|
||||
HANDLE hDev;
|
||||
DWORD_PTR dwInstance;
|
||||
|
||||
TRACE("wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",
|
||||
wDevID, wMsg, dwParam1, dwParam2);
|
||||
|
||||
switch (wMsg) {
|
||||
case MIM_OPEN:
|
||||
case MIM_CLOSE:
|
||||
if (wDevID > MIDM_NumDevs) return;
|
||||
|
||||
dwCallBack = MidiInDev[wDevID].midiDesc.dwCallback;
|
||||
uFlags = MidiInDev[wDevID].wFlags;
|
||||
hDev = MidiInDev[wDevID].midiDesc.hMidi;
|
||||
dwInstance = MidiInDev[wDevID].midiDesc.dwInstance;
|
||||
break;
|
||||
default:
|
||||
ERR("Unsupported MSW-MIDI message %u\n", wMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
DriverCallback(dwCallBack, uFlags, hDev, wMsg, dwInstance, dwParam1, dwParam2);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* midiOpenSeq [internal]
|
||||
*/
|
||||
static snd_seq_t *midiOpenSeq(int *port_in_ret)
|
||||
{
|
||||
struct midi_seq_open_params params;
|
||||
|
||||
params.port_in = port_in_ret;
|
||||
params.close = 0;
|
||||
ALSA_CALL(midi_seq_open, ¶ms);
|
||||
|
||||
return params.seq;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* midiCloseSeq [internal]
|
||||
*/
|
||||
static int midiCloseSeq(void)
|
||||
{
|
||||
struct midi_seq_open_params params;
|
||||
|
||||
params.port_in = NULL;
|
||||
params.close = 1;
|
||||
ALSA_CALL(midi_seq_open, ¶ms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD WINAPI midRecThread(void *arg)
|
||||
{
|
||||
snd_seq_t *midi_seq = arg;
|
||||
int num_fds;
|
||||
struct pollfd *pollfd;
|
||||
int ret;
|
||||
|
||||
/* Add on one for the read end of the cancel pipe */
|
||||
num_fds = snd_seq_poll_descriptors_count(midi_seq, POLLIN) + 1;
|
||||
pollfd = malloc(num_fds * sizeof(struct pollfd));
|
||||
|
||||
while(1) {
|
||||
pollfd[0].fd = rec_cancel_pipe[0];
|
||||
pollfd[0].events = POLLIN;
|
||||
|
||||
seq_lock();
|
||||
snd_seq_poll_descriptors(midi_seq, pollfd + 1, num_fds - 1, POLLIN);
|
||||
seq_unlock();
|
||||
|
||||
/* Check if an event is present */
|
||||
if (poll(pollfd, num_fds, -1) <= 0)
|
||||
continue;
|
||||
|
||||
if (pollfd[0].revents & POLLIN) /* cancelled */
|
||||
break;
|
||||
|
||||
do {
|
||||
snd_seq_event_t *ev;
|
||||
|
||||
seq_lock();
|
||||
snd_seq_event_input(midi_seq, &ev);
|
||||
seq_unlock();
|
||||
|
||||
if (ev) {
|
||||
ALSA_CALL(midi_handle_event, ev);
|
||||
snd_seq_free_event(ev);
|
||||
}
|
||||
|
||||
seq_lock();
|
||||
ret = snd_seq_event_input_pending(midi_seq, 0);
|
||||
seq_unlock();
|
||||
} while(ret > 0);
|
||||
}
|
||||
|
||||
free(pollfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* midOpen [internal]
|
||||
*/
|
||||
static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
|
||||
{
|
||||
int ret = 0, port_in;
|
||||
snd_seq_t *midi_seq;
|
||||
|
||||
TRACE("(%04X, %p, %08X);\n", wDevID, lpDesc, dwFlags);
|
||||
|
||||
if (lpDesc == NULL) {
|
||||
WARN("Invalid Parameter !\n");
|
||||
return MMSYSERR_INVALPARAM;
|
||||
}
|
||||
|
||||
/* FIXME :
|
||||
* how to check that content of lpDesc is correct ?
|
||||
*/
|
||||
if (wDevID >= MIDM_NumDevs) {
|
||||
WARN("wDevID too large (%u) !\n", wDevID);
|
||||
return MMSYSERR_BADDEVICEID;
|
||||
}
|
||||
if (MidiInDev[wDevID].state == -1) {
|
||||
WARN("device disabled\n");
|
||||
return MIDIERR_NODEVICE;
|
||||
}
|
||||
if (MidiInDev[wDevID].midiDesc.hMidi != 0) {
|
||||
WARN("device already open !\n");
|
||||
return MMSYSERR_ALLOCATED;
|
||||
}
|
||||
if ((dwFlags & MIDI_IO_STATUS) != 0) {
|
||||
WARN("No support for MIDI_IO_STATUS in dwFlags yet, ignoring it\n");
|
||||
dwFlags &= ~MIDI_IO_STATUS;
|
||||
}
|
||||
if ((dwFlags & ~CALLBACK_TYPEMASK) != 0) {
|
||||
FIXME("Bad dwFlags\n");
|
||||
return MMSYSERR_INVALFLAG;
|
||||
}
|
||||
|
||||
if (!(midi_seq = midiOpenSeq(&port_in))) {
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
|
||||
|
||||
MidiInDev[wDevID].lpQueueHdr = NULL;
|
||||
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(midi_seq, port_in, MidiInDev[wDevID].addr.client,
|
||||
MidiInDev[wDevID].addr.port);
|
||||
seq_unlock();
|
||||
if (ret < 0)
|
||||
return MMSYSERR_NOTENABLED;
|
||||
|
||||
TRACE("Input port :%d connected %d:%d\n",port_in,MidiInDev[wDevID].addr.client,MidiInDev[wDevID].addr.port);
|
||||
|
||||
if (numStartedMidiIn++ == 0) {
|
||||
pipe(rec_cancel_pipe);
|
||||
hThread = CreateThread(NULL, 0, midRecThread, midi_seq, 0, NULL);
|
||||
if (!hThread) {
|
||||
close(rec_cancel_pipe[0]);
|
||||
close(rec_cancel_pipe[1]);
|
||||
numStartedMidiIn = 0;
|
||||
WARN("Couldn't create thread for midi-in\n");
|
||||
midiCloseSeq();
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
TRACE("Created thread for midi-in\n");
|
||||
}
|
||||
|
||||
MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* midClose [internal]
|
||||
*/
|
||||
static DWORD midClose(WORD wDevID)
|
||||
{
|
||||
int ret = MMSYSERR_NOERROR;
|
||||
|
||||
TRACE("(%04X);\n", wDevID);
|
||||
|
||||
if (wDevID >= MIDM_NumDevs) {
|
||||
WARN("wDevID too big (%u) !\n", wDevID);
|
||||
return MMSYSERR_BADDEVICEID;
|
||||
}
|
||||
if (MidiInDev[wDevID].midiDesc.hMidi == 0) {
|
||||
WARN("device not opened !\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
if (MidiInDev[wDevID].lpQueueHdr != 0) {
|
||||
return MIDIERR_STILLPLAYING;
|
||||
}
|
||||
|
||||
if (MidiInDev[wDevID].seq == NULL) {
|
||||
WARN("ooops !\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
if (--numStartedMidiIn == 0) {
|
||||
TRACE("Stopping thread for midi-in\n");
|
||||
write(rec_cancel_pipe[1], "x", 1);
|
||||
if (WaitForSingleObject(hThread, 5000) != WAIT_OBJECT_0) {
|
||||
WARN("Thread end not signaled, force termination\n");
|
||||
TerminateThread(hThread, 0);
|
||||
}
|
||||
close(rec_cancel_pipe[0]);
|
||||
close(rec_cancel_pipe[1]);
|
||||
TRACE("Stopped thread for midi-in\n");
|
||||
}
|
||||
|
||||
seq_lock();
|
||||
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;
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* MIDI entry points *
|
||||
*======================================================================*/
|
||||
|
@ -350,11 +72,6 @@ static BOOL ALSA_MidiInit(void)
|
|||
params.err = &err;
|
||||
ALSA_CALL(midi_init, ¶ms);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
MIDM_NumDevs = params.num_srcs;
|
||||
MidiInDev = params.srcs;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -374,10 +91,6 @@ DWORD WINAPI ALSA_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
|
|||
case DRVM_INIT:
|
||||
ALSA_MidiInit();
|
||||
return 0;
|
||||
case MIDM_OPEN:
|
||||
return midOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
|
||||
case MIDM_CLOSE:
|
||||
return midClose(wDevID);
|
||||
}
|
||||
|
||||
params.dev_id = wDevID;
|
||||
|
|
|
@ -207,27 +207,9 @@ 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_t *seq;
|
||||
snd_seq_addr_t addr;
|
||||
int port_in;
|
||||
} WINE_MIDIIN;
|
||||
|
||||
struct midi_init_params
|
||||
{
|
||||
UINT *err;
|
||||
unsigned int num_srcs;
|
||||
void *srcs;
|
||||
};
|
||||
|
||||
struct notify_context
|
||||
|
@ -271,13 +253,6 @@ struct midi_notify_wait_params
|
|||
struct notify_context *notify;
|
||||
};
|
||||
|
||||
struct midi_seq_open_params
|
||||
{
|
||||
int close;
|
||||
snd_seq_t *seq;
|
||||
int *port_in;
|
||||
};
|
||||
|
||||
enum alsa_funcs
|
||||
{
|
||||
alsa_get_endpoint_ids,
|
||||
|
@ -308,10 +283,6 @@ enum alsa_funcs
|
|||
alsa_midi_out_message,
|
||||
alsa_midi_in_message,
|
||||
alsa_midi_notify_wait,
|
||||
|
||||
alsa_midi_seq_lock, /* temporary */
|
||||
alsa_midi_seq_open,
|
||||
alsa_midi_handle_event,
|
||||
};
|
||||
|
||||
NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
|
||||
|
@ -320,10 +291,6 @@ NTSTATUS midi_out_message(void *args) DECLSPEC_HIDDEN;
|
|||
NTSTATUS midi_in_message(void *args) DECLSPEC_HIDDEN;
|
||||
NTSTATUS midi_notify_wait(void *args) DECLSPEC_HIDDEN;
|
||||
|
||||
NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
|
||||
NTSTATUS midi_seq_open(void *args) DECLSPEC_HIDDEN;
|
||||
NTSTATUS midi_handle_event(void *args) DECLSPEC_HIDDEN;
|
||||
|
||||
extern unixlib_handle_t alsa_handle;
|
||||
|
||||
#define ALSA_CALL(func, params) __wine_unix_call(alsa_handle, alsa_ ## func, params)
|
||||
|
|
Loading…
Reference in New Issue