[PATCH 3/3] wineoss: Move midi_init to the unixlib.

Andrew Eikum aeikum at codeweavers.com
Tue Apr 19 08:40:46 CDT 2022


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Tue, Apr 19, 2022 at 07:38:44AM +0100, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at 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, &params);
>  
> -    /* 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)
> -- 
> 2.25.1
> 
> 



More information about the wine-devel mailing list