Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/wineoss.drv/Makefile.in | 3 +- dlls/wineoss.drv/midi.c | 276 +++-------------------------- dlls/wineoss.drv/oss.c | 1 + dlls/wineoss.drv/ossmidi.c | 335 +++++++++++++++++++++++++++++++++++ dlls/wineoss.drv/unixlib.h | 38 ++++ 5 files changed, 403 insertions(+), 250 deletions(-) create mode 100644 dlls/wineoss.drv/ossmidi.c
diff --git a/dlls/wineoss.drv/Makefile.in b/dlls/wineoss.drv/Makefile.in index d48db94b929..04b438da71e 100644 --- a/dlls/wineoss.drv/Makefile.in +++ b/dlls/wineoss.drv/Makefile.in @@ -13,4 +13,5 @@ C_SRCS = \ midipatch.c \ mmaux.c \ mmdevdrv.c \ - oss.c + oss.c \ + ossmidi.c diff --git a/dlls/wineoss.drv/midi.c b/dlls/wineoss.drv/midi.c index 1cf19b7be1a..626b3d43d83 100644 --- a/dlls/wineoss.drv/midi.c +++ b/dlls/wineoss.drv/midi.c @@ -1,15 +1,10 @@ -/* -*- tab-width: 8; c-basic-offset: 4 -*- */ - /* - * Sample MIDI Wine Driver for Open Sound System (basically Linux) + * MIDI driver for OSS (PE-side) * - * Copyright 1994 Martin Ayotte - * Copyright 1998 Luiz Otavio L. Zorzella (init procedures) - * Copyright 1998/1999 Eric POUECH : - * 98/7 changes for making this MIDI driver work on OSS - * current support is limited to MIDI ports of OSS systems - * 98/9 rewriting MCI code for MIDI - * 98/11 split in midi.c and mcimidi.c + * Copyright 1994 Martin Ayotte + * Copyright 1998 Luiz Otavio L. Zorzella (init procedures) + * Copyright 1998, 1999 Eric POUECH + * Copyright 2022 Huw Davies * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -57,35 +52,19 @@ #include "winbase.h" #include "wingdi.h" #include "winuser.h" -#include "winnls.h" +#include "winternl.h" #include "mmddk.h" +#include "audioclient.h" + #include "wine/debug.h" +#include "wine/unixlib.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; - unsigned char incoming[3]; - unsigned char incPrev; - char incLen; - DWORD startTime; - MIDIINCAPSW caps; -} WINE_MIDIIN; - -typedef struct { - BOOL bEnabled; - MIDIOPENDESC midiDesc; - WORD wFlags; - LPMIDIHDR lpQueueHdr; - void* lpExtra; /* according to port type (MIDI, FM...), extra data when needed */ - MIDIOUTCAPSW caps; -} 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; @@ -119,37 +98,6 @@ static HANDLE hThread; static int midiOpenSeq(void); static int midiCloseSeq(void);
-/************************************************************************** - * MIDI_unixToWindowsDeviceType [internal] - * - * return the Windows equivalent to a Unix Device Type - * - */ -static int MIDI_UnixToWindowsDeviceType(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 UNIX to - Windows Sound type */ - - switch (type) { - case SYNTH_TYPE_FM: return MOD_FMSYNTH; - case SYNTH_TYPE_SAMPLE: return MOD_SYNTH; - case SYNTH_TYPE_MIDI: return MOD_MIDIPORT; - default: - ERR("Cannot determine the type of this midi device. " - "Assuming FM Synth\n"); - return MOD_FMSYNTH; - } -} - static int MIDI_loadcount; /************************************************************************** * OSS_MidiInit [internal] @@ -158,9 +106,8 @@ static int MIDI_loadcount; */ static LRESULT OSS_MidiInit(void) { - int i, status, numsynthdevs = 255, nummididevs = 255; - struct synth_info sinfo; - struct midi_info minfo; + struct midi_init_params params; + UINT err;
TRACE("(%i)\n", MIDI_loadcount); if (MIDI_loadcount++) @@ -168,187 +115,18 @@ static LRESULT OSS_MidiInit(void)
TRACE("Initializing the MIDI variables.\n");
- /* try to open device */ - if (midiOpenSeq() == -1) { - return -1; - } - - /* find how many Synth devices are there in the system */ - status = ioctl(midiSeqFD, SNDCTL_SEQ_NRSYNTHS, &numsynthdevs); - - if (status == -1) { - ERR("ioctl for nr synth failed.\n"); - midiCloseSeq(); - return -1; - } - - if (numsynthdevs > MAX_MIDIOUTDRV) { - ERR("MAX_MIDIOUTDRV (%d) was enough for the number of devices (%d). " - "Some FM devices will not be available.\n",MAX_MIDIOUTDRV,numsynthdevs); - numsynthdevs = MAX_MIDIOUTDRV; - } - - for (i = 0; i < numsynthdevs; i++) { - /* 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[i].caps.wMid = 0x00FF; - MidiOutDev[i].caps.wPid = 0x0001; /* FIXME Product ID */ - /* Product Version. We simply say "1" */ - MidiOutDev[i].caps.vDriverVersion = 0x001; - /* The following are mandatory for MOD_MIDIPORT */ - MidiOutDev[i].caps.wChannelMask = 0xFFFF; - MidiOutDev[i].caps.wVoices = 0; - MidiOutDev[i].caps.wNotes = 0; - MidiOutDev[i].caps.dwSupport = 0; - - sinfo.device = i; - status = ioctl(midiSeqFD, SNDCTL_SYNTH_INFO, &sinfo); - if (status == -1) { - static const WCHAR fmt[] = {'W','i','n','e',' ','O','S','S',' ','M','i','d','i',' ','O','u','t',' ','#','%','d',' ','d','i','s','a','b','l','e','d',0}; - ERR("ioctl for synth info failed on %d, disabling it.\n", i); - - wsprintfW(MidiOutDev[i].caps.szPname, fmt, i); - - MidiOutDev[i].caps.wTechnology = MOD_MIDIPORT; - MidiOutDev[i].bEnabled = FALSE; - } else { - MultiByteToWideChar(CP_UNIXCP, 0, sinfo.name, -1, MidiOutDev[i].caps.szPname, - ARRAY_SIZE(MidiOutDev[i].caps.szPname)); - MidiOutDev[i].caps.wTechnology = MIDI_UnixToWindowsDeviceType(sinfo.synth_type); - - if (MOD_MIDIPORT != MidiOutDev[i].caps.wTechnology) { - /* FIXME Do we have this information? - * Assuming the soundcards can handle - * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but - * not MIDICAPS_CACHE. - */ - MidiOutDev[i].caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; - MidiOutDev[i].caps.wVoices = sinfo.nr_voices; - - /* 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[i].caps.wNotes = sinfo.nr_voices; - } - MidiOutDev[i].bEnabled = TRUE; - - /* We also have the information sinfo.synth_subtype, not used here - */ - if (sinfo.capabilities & SYNTH_CAP_INPUT) { - FIXME("Synthesizer supports MIDI in. Not yet supported.\n"); - } - TRACE("SynthOut[%d]\tOSS info: synth type=%d/%d capa=%lx\n", - i, sinfo.synth_type, sinfo.synth_subtype, (long)sinfo.capabilities); - } - - TRACE("SynthOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n", - i, wine_dbgstr_w(MidiOutDev[i].caps.szPname), - MidiOutDev[i].caps.wTechnology, - MidiOutDev[i].caps.wVoices, MidiOutDev[i].caps.wNotes, - MidiOutDev[i].caps.wChannelMask, MidiOutDev[i].caps.dwSupport); - } - - /* find how many MIDI devices are there in the system */ - status = ioctl(midiSeqFD, SNDCTL_SEQ_NRMIDIS, &nummididevs); - if (status == -1) { - ERR("ioctl on nr midi failed.\n"); - nummididevs = 0; - goto wrapup; - } + params.err = &err; + OSS_CALL(midi_init, ¶ms);
- /* FIXME: the two restrictions below could be loosened in some cases */ - if (numsynthdevs + nummididevs > MAX_MIDIOUTDRV) { - ERR("MAX_MIDIOUTDRV was not enough for the number of devices. " - "Some MIDI devices will not be available.\n"); - nummididevs = MAX_MIDIOUTDRV - numsynthdevs; + if (!err) + { + MidiInDev = params.srcs; + MidiOutDev = params.dests; + MODM_NumDevs = params.num_dests; + MODM_NumFMSynthDevs = params.num_synths; + MIDM_NumDevs = params.num_srcs; } - - if (nummididevs > MAX_MIDIINDRV) { - ERR("MAX_MIDIINDRV (%d) was not enough for the number of devices (%d). " - "Some MIDI devices will not be available.\n",MAX_MIDIINDRV,nummididevs); - nummididevs = MAX_MIDIINDRV; - } - - for (i = 0; i < nummididevs; i++) { - minfo.device = i; - status = ioctl(midiSeqFD, SNDCTL_MIDI_INFO, &minfo); - if (status == -1) WARN("ioctl on midi info for device %d failed.\n", i); - - /* This whole part is somewhat obscure to me. I'll keep trying to dig - info about it. If you happen to know, please tell us. The very - descriptive minfo.dev_type was not used here. - */ - /* Manufacturer 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[numsynthdevs + i].caps.wMid = 0x00FF; - MidiOutDev[numsynthdevs + i].caps.wPid = 0x0001; /* FIXME Product ID */ - /* Product Version. We simply say "1" */ - MidiOutDev[numsynthdevs + i].caps.vDriverVersion = 0x001; - if (status == -1) { - static const WCHAR fmt[] = {'W','i','n','e',' ','O','S','S',' ','M','i','d','i',' ','O','u','t',' ','#','%','d',' ','d','i','s','a','b','l','e','d',0}; - wsprintfW(MidiOutDev[numsynthdevs + i].caps.szPname, fmt, numsynthdevs + i); - MidiOutDev[numsynthdevs + i].bEnabled = FALSE; - } else { - MultiByteToWideChar(CP_UNIXCP, 0, minfo.name, -1, - MidiOutDev[numsynthdevs + i].caps.szPname, - ARRAY_SIZE(MidiOutDev[numsynthdevs + i].caps.szPname)); - MidiOutDev[numsynthdevs + i].bEnabled = TRUE; - } - MidiOutDev[numsynthdevs + i].caps.wTechnology = MOD_MIDIPORT; - MidiOutDev[numsynthdevs + i].caps.wVoices = 0; - MidiOutDev[numsynthdevs + i].caps.wNotes = 0; - MidiOutDev[numsynthdevs + i].caps.wChannelMask= 0xFFFF; - MidiOutDev[numsynthdevs + i].caps.dwSupport = 0; - - /* This whole part is somewhat obscure to me. I'll keep trying to dig - info about it. If you happen to know, please tell us. The very - descriptive minfo.dev_type was not used here. - */ - /* 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[i].caps.wMid = 0x00FF; - MidiInDev[i].caps.wPid = 0x0001; /* FIXME Product ID */ - /* Product Version. We simply say "1" */ - MidiInDev[i].caps.vDriverVersion = 0x001; - if (status == -1) { - static const WCHAR fmt[] = {'W','i','n','e',' ','O','S','S',' ','M','i','d','i',' ','I','n',' ','#','%','d',' ','d','i','s','a','b','l','e','d',0}; - wsprintfW(MidiInDev[i].caps.szPname, fmt, numsynthdevs + i); - MidiInDev[i].state = -1; - } else { - MultiByteToWideChar(CP_UNIXCP, 0, minfo.name, -1, MidiInDev[i].caps.szPname, - ARRAY_SIZE(MidiInDev[i].caps.szPname)); - MidiInDev[i].state = 0; - } - MidiInDev[i].caps.dwSupport = 0; /* mandatory with MIDIINCAPS */ - - TRACE("OSS info: midi[%d] dev-type=%d capa=%lx\n" - "\tMidiOut[%d] name='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n" - "\tMidiIn [%d] name='%s' support=%d\n", - i, minfo.dev_type, (long)minfo.capabilities, - numsynthdevs + i, wine_dbgstr_w(MidiOutDev[numsynthdevs + i].caps.szPname), - MidiOutDev[numsynthdevs + i].caps.wTechnology, - MidiOutDev[numsynthdevs + i].caps.wVoices, MidiOutDev[numsynthdevs + i].caps.wNotes, - MidiOutDev[numsynthdevs + i].caps.wChannelMask, MidiOutDev[numsynthdevs + i].caps.dwSupport, - i, wine_dbgstr_w(MidiInDev[i].caps.szPname), MidiInDev[i].caps.dwSupport); - } - - wrapup: - /* windows does not seem to differentiate Synth from MIDI devices */ - MODM_NumFMSynthDevs = numsynthdevs; - MODM_NumDevs = numsynthdevs + nummididevs; - - MIDM_NumDevs = nummididevs; - - /* close file and exit */ - midiCloseSeq(); - - return 0; + return err; }
/************************************************************************** @@ -363,8 +141,8 @@ static LRESULT OSS_MidiExit(void) if (--MIDI_loadcount) return 1;
- ZeroMemory(MidiInDev, sizeof(MidiInDev)); - ZeroMemory(MidiOutDev, sizeof(MidiOutDev)); + MidiInDev = NULL; + MidiOutDev = NULL;
MODM_NumDevs = 0; MODM_NumFMSynthDevs = 0; diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c index b4e2cbda704..4f3c0bcb2cf 100644 --- a/dlls/wineoss.drv/oss.c +++ b/dlls/wineoss.drv/oss.c @@ -1405,4 +1405,5 @@ unixlib_entry_t __wine_unix_call_funcs[] = set_volumes, set_event_handle, is_started, + midi_init, }; diff --git a/dlls/wineoss.drv/ossmidi.c b/dlls/wineoss.drv/ossmidi.c new file mode 100644 index 00000000000..75fbf6d7bee --- /dev/null +++ b/dlls/wineoss.drv/ossmidi.c @@ -0,0 +1,335 @@ +/* + * MIDI driver for OSS (unixlib) + * + * Copyright 1994 Martin Ayotte + * Copyright 1998 Luiz Otavio L. Zorzella (init procedures) + * Copyright 1998, 1999 Eric POUECH + * Copyright 2022 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include <stdarg.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/soundcard.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" +#include "audioclient.h" + +#include "wine/debug.h" +#include "wine/unixlib.h" + +#include "unixlib.h" + +static unsigned int num_dests, num_srcs, num_synths, seq_refs; +static struct midi_dest dests[MAX_MIDIOUTDRV]; +static struct midi_src srcs[MAX_MIDIINDRV]; + +WINE_DEFAULT_DEBUG_CHANNEL(midi); + +static int oss_to_win_device_type(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 UNIX to + Windows Sound type */ + + switch (type) + { + case SYNTH_TYPE_FM: return MOD_FMSYNTH; + case SYNTH_TYPE_SAMPLE: return MOD_SYNTH; + case SYNTH_TYPE_MIDI: return MOD_MIDIPORT; + default: + ERR("Cannot determine the type of this midi device. " + "Assuming FM Synth\n"); + return MOD_FMSYNTH; + } +} + +static int seq_open(void) +{ + static int midi_warn = 1; + static int fd = -1; + + if (seq_refs <= 0) + { + const char* device = getenv("MIDIDEV"); + + if (!device) device = "/dev/sequencer"; + fd = open(device, O_RDWR, 0); + if (fd == -1) + { + if (midi_warn) + { + WARN("Can't open MIDI device '%s' ! (%s). If your program needs this (probably not): %s\n", + device, strerror(errno), + errno == ENOENT ? "create it ! ("man MAKEDEV" ?)" : + errno == ENODEV ? "load MIDI sequencer kernel driver !" : + errno == EACCES ? "grant access ! ("man chmod")" : ""); + } + midi_warn = 0; + return -1; + } + fcntl(fd, F_SETFD, 1); /* set close on exec flag */ + ioctl(fd, SNDCTL_SEQ_RESET); + } + seq_refs++; + return fd; +} + +static int seq_close(int fd) +{ + if (--seq_refs == 0) + close(fd); + + return 0; +} + +NTSTATUS midi_init(void *args) +{ + struct midi_init_params *params = args; + int i, status, synth_devs = 255, midi_devs = 255, fd, len; + struct synth_info sinfo; + struct midi_info minfo; + struct midi_dest *dest; + struct midi_src *src; + + /* try to open device */ + fd = seq_open(); + if (fd == -1) + { + *params->err = -1; + return STATUS_SUCCESS; + } + + /* find how many Synth devices are there in the system */ + status = ioctl(fd, SNDCTL_SEQ_NRSYNTHS, &synth_devs); + if (status == -1) + { + ERR("ioctl for nr synth failed.\n"); + seq_close(fd); + *params->err = -1; + return STATUS_SUCCESS; + } + + if (synth_devs > MAX_MIDIOUTDRV) + { + ERR("MAX_MIDIOUTDRV (%d) was enough for the number of devices (%d). " + "Some FM devices will not be available.\n", MAX_MIDIOUTDRV, synth_devs); + synth_devs = MAX_MIDIOUTDRV; + } + + for (i = 0, dest = dests; i < synth_devs; i++, dest++) + { + /* 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; + + sinfo.device = i; + status = ioctl(fd, SNDCTL_SYNTH_INFO, &sinfo); + if (status == -1) + { + char buf[255]; + + ERR("ioctl for synth info failed on %d, disabling it.\n", i); + + sprintf(buf, "Wine OSS Midi Out #%d disabled", i); + len = ntdll_umbstowcs(buf, strlen(buf) + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname)); + dest->caps.szPname[len - 1] = '\0'; + dest->caps.wTechnology = MOD_MIDIPORT; + dest->bEnabled = FALSE; + } + else + { + len = ntdll_umbstowcs(sinfo.name, strlen(sinfo.name) + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname)); + dest->caps.szPname[len - 1] = '\0'; + dest->caps.wTechnology = oss_to_win_device_type(sinfo.synth_type); + + if (dest->caps.wTechnology != MOD_MIDIPORT) + { + /* 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 = sinfo.nr_voices; + + /* 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 = sinfo.nr_voices; + } + dest->bEnabled = TRUE; + + /* We also have the information sinfo.synth_subtype, not used here + */ + if (sinfo.capabilities & SYNTH_CAP_INPUT) + FIXME("Synthesizer supports MIDI in. Not yet supported.\n"); + + TRACE("SynthOut[%d]\tOSS info: synth type=%d/%d capa=%lx\n", + i, sinfo.synth_type, sinfo.synth_subtype, (long)sinfo.capabilities); + } + + TRACE("SynthOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n", + i, wine_dbgstr_w(dest->caps.szPname), dest->caps.wTechnology, + dest->caps.wVoices, dest->caps.wNotes, dest->caps.wChannelMask, dest->caps.dwSupport); + } + + /* find how many MIDI devices are there in the system */ + status = ioctl(fd, SNDCTL_SEQ_NRMIDIS, &midi_devs); + if (status == -1) + { + ERR("ioctl on nr midi failed.\n"); + midi_devs = 0; + goto wrapup; + } + + /* FIXME: the two restrictions below could be loosened in some cases */ + if (synth_devs + midi_devs > MAX_MIDIOUTDRV) + { + ERR("MAX_MIDIOUTDRV was not enough for the number of devices. " + "Some MIDI devices will not be available.\n"); + midi_devs = MAX_MIDIOUTDRV - synth_devs; + } + + if (midi_devs > MAX_MIDIINDRV) + { + ERR("MAX_MIDIINDRV (%d) was not enough for the number of devices (%d). " + "Some MIDI devices will not be available.\n", MAX_MIDIINDRV, midi_devs); + midi_devs = MAX_MIDIINDRV; + } + + dest = dests + synth_devs; + src = srcs; + for (i = 0; i < midi_devs; i++, dest++, src++) + { + minfo.device = i; + status = ioctl(fd, SNDCTL_MIDI_INFO, &minfo); + if (status == -1) WARN("ioctl on midi info for device %d failed.\n", i); + + /* Manufacturer 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; + if (status == -1) + { + char buf[255]; + + sprintf(buf, "Wine OSS Midi Out #%d disabled", synth_devs + i); + len = ntdll_umbstowcs(buf, strlen(buf) + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname)); + dest->caps.szPname[len - 1] = '\0'; + dest->bEnabled = FALSE; + } + else + { + len = ntdll_umbstowcs(minfo.name, strlen(minfo.name) + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname)); + dest->caps.szPname[len - 1] = '\0'; + dest->bEnabled = TRUE; + } + dest->caps.wTechnology = MOD_MIDIPORT; + dest->caps.wVoices = 0; + dest->caps.wNotes = 0; + dest->caps.wChannelMask = 0xFFFF; + dest->caps.dwSupport = 0; + + /* 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; + if (status == -1) + { + char buf[ARRAY_SIZE(dest->caps.szPname)]; + + sprintf(buf, "Wine OSS Midi In #%d disabled", synth_devs + i); + len = ntdll_umbstowcs(buf, strlen(buf) + 1, src->caps.szPname, ARRAY_SIZE(src->caps.szPname)); + src->caps.szPname[len - 1] = '\0'; + src->state = -1; + } + else + { + len = ntdll_umbstowcs(minfo.name, strlen(minfo.name) + 1, src->caps.szPname, ARRAY_SIZE(src->caps.szPname)); + src->caps.szPname[len - 1] = '\0'; + src->state = 0; + } + src->caps.dwSupport = 0; /* mandatory with MIDIINCAPS */ + + TRACE("OSS info: midi[%d] dev-type=%d capa=%lx\n" + "\tMidiOut[%d] name='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n" + "\tMidiIn [%d] name='%s' support=%d\n", + i, minfo.dev_type, (long)minfo.capabilities, + synth_devs + i, wine_dbgstr_w(dest->caps.szPname), dest->caps.wTechnology, + dest->caps.wVoices, dest->caps.wNotes, dest->caps.wChannelMask, dest->caps.dwSupport, + i, wine_dbgstr_w(src->caps.szPname), src->caps.dwSupport); + } + +wrapup: + /* windows does not seem to differentiate Synth from MIDI devices */ + num_synths = synth_devs; + num_dests = synth_devs + midi_devs; + num_srcs = midi_devs; + + /* close file and exit */ + seq_close(fd); + + *params->err = 0; + params->num_srcs = num_srcs; + params->num_dests = num_dests; + params->num_synths = num_synths; + params->srcs = srcs; + params->dests = dests; + + return STATUS_SUCCESS; +} diff --git a/dlls/wineoss.drv/unixlib.h b/dlls/wineoss.drv/unixlib.h index 1ed152fe794..2b30c5992c7 100644 --- a/dlls/wineoss.drv/unixlib.h +++ b/dlls/wineoss.drv/unixlib.h @@ -209,6 +209,41 @@ struct is_started_params HRESULT result; };
+#include <mmddk.h> /* temporary */ + +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; + unsigned char incoming[3]; + unsigned char incPrev; + char incLen; + UINT startTime; + MIDIINCAPSW caps; +} WINE_MIDIIN; + +typedef struct midi_dest +{ + BOOL bEnabled; + MIDIOPENDESC midiDesc; + WORD wFlags; + MIDIHDR *lpQueueHdr; + void *lpExtra; /* according to port type (MIDI, FM...), extra data when needed */ + MIDIOUTCAPSW caps; +} WINE_MIDIOUT; + +struct midi_init_params +{ + UINT *err; + unsigned int num_dests; + unsigned int num_srcs; + unsigned int num_synths; + struct midi_dest *dests; + struct midi_src *srcs; +}; + enum oss_funcs { oss_test_connect, @@ -234,8 +269,11 @@ enum oss_funcs oss_set_volumes, oss_set_event_handle, oss_is_started, + oss_midi_init, };
+NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN; + extern unixlib_handle_t oss_handle;
#define OSS_CALL(func, params) __wine_unix_call(oss_handle, oss_ ## func, params)