mmaux.c 6.49 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1
/*
2
 * Sample AUXILIARY Wine Driver
Alexandre Julliard's avatar
Alexandre Julliard committed
3 4
 *
 * Copyright 1994 Martin Ayotte
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * 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
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
22
#include "wine/port.h"
23

24
#include <stdarg.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
25
#include <stdlib.h>
26
#include <string.h>
27 28 29
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
30
#include <fcntl.h>
31 32 33
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
34 35 36
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
37
#include <sys/soundcard.h>
38

39
#include "windef.h"
40
#include "winbase.h"
41
#include "mmddk.h"
42
#include "wine/unicode.h"
43
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
44

45
WINE_DEFAULT_DEBUG_CHANNEL(mmaux);
46

Alexandre Julliard's avatar
Alexandre Julliard committed
47
#define MIXER_DEV "/dev/mixer"
48

Alexandre Julliard's avatar
Alexandre Julliard committed
49 50
static int	NumDev = 6;

Alexandre Julliard's avatar
Alexandre Julliard committed
51 52
/*-----------------------------------------------------------------------*/

53
static LRESULT OSS_AuxInit(void)
54 55
{
    int	mixer;
56
    TRACE("()\n");
57 58 59 60 61 62 63 64

    if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
	WARN("mixer device not available !\n");
	NumDev = 0;
    } else {
	close(mixer);
	NumDev = 6;
    }
65 66 67 68 69
    return 0;
}

/*-----------------------------------------------------------------------*/

70
static LRESULT OSS_AuxExit(void)
71 72 73
{
    TRACE("()\n");
    return 0;
74
}
Alexandre Julliard's avatar
Alexandre Julliard committed
75 76

/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
77 78
 * 				AUX_GetDevCaps			[internal]
 */
79
static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPSW lpCaps, DWORD dwSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
80
{
81
    int 	mixer, volume;
82
    static const WCHAR ini[] = {'O','S','S',' ','A','u','x',' ','#','0',0};
83

84
    TRACE("(%04X, %p, %u);\n", wDevID, lpCaps, dwSize);
85
    if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
86
    if (wDevID >= NumDev) return MMSYSERR_BADDEVICEID;
87 88 89 90 91
    if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
	WARN("mixer device not available !\n");
	return MMSYSERR_NOTENABLED;
    }
    if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
Alexandre Julliard's avatar
Alexandre Julliard committed
92
	close(mixer);
93
	WARN("unable to read mixer !\n");
94 95 96 97
	return MMSYSERR_NOTENABLED;
    }
    close(mixer);
    lpCaps->wMid = 0xAA;
98
    lpCaps->wPid = 0x55 + wDevID;
99
    lpCaps->vDriverVersion = 0x0100;
100
    strcpyW(lpCaps->szPname, ini);
101 102
    lpCaps->szPname[9] = '0' + wDevID; /* 6  at max */
    lpCaps->wTechnology = wDevID == 2 ? AUXCAPS_CDAUDIO : AUXCAPS_AUXIN;
103
    lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
104

105
    return MMSYSERR_NOERROR;
Alexandre Julliard's avatar
Alexandre Julliard committed
106 107 108 109
}


/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
110 111
 * 				AUX_GetVolume			[internal]
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
112
static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
Alexandre Julliard's avatar
Alexandre Julliard committed
113
{
114
    int 	mixer, volume, left, right, cmd;
115

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
    TRACE("(%04X, %p);\n", wDevID, lpdwVol);
    if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
    if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
	WARN("mixer device not available !\n");
	return MMSYSERR_NOTENABLED;
    }
    switch(wDevID) {
    case 0:
	TRACE("SOUND_MIXER_READ_PCM !\n");
	cmd = SOUND_MIXER_READ_PCM;
	break;
    case 1:
	TRACE("SOUND_MIXER_READ_SYNTH !\n");
	cmd = SOUND_MIXER_READ_SYNTH;
	break;
    case 2:
	TRACE("SOUND_MIXER_READ_CD !\n");
	cmd = SOUND_MIXER_READ_CD;
	break;
    case 3:
	TRACE("SOUND_MIXER_READ_LINE !\n");
	cmd = SOUND_MIXER_READ_LINE;
	break;
    case 4:
	TRACE("SOUND_MIXER_READ_MIC !\n");
	cmd = SOUND_MIXER_READ_MIC;
	break;
    case 5:
	TRACE("SOUND_MIXER_READ_VOLUME !\n");
	cmd = SOUND_MIXER_READ_VOLUME;
	break;
    default:
	WARN("invalid device id=%04X !\n", wDevID);
149
	close(mixer);
Alexandre Julliard's avatar
Alexandre Julliard committed
150
	return MMSYSERR_NOTENABLED;
151 152
    }
    if (ioctl(mixer, cmd, &volume) == -1) {
153
	WARN("unable to read mixer !\n");
154
	close(mixer);
155 156 157 158 159 160 161 162
	return MMSYSERR_NOTENABLED;
    }
    close(mixer);
    left  = LOBYTE(LOWORD(volume));
    right = HIBYTE(LOWORD(volume));
    TRACE("left=%d right=%d !\n", left, right);
    *lpdwVol = MAKELONG((left * 0xFFFFL) / 100, (right * 0xFFFFL) / 100);
    return MMSYSERR_NOERROR;
Alexandre Julliard's avatar
Alexandre Julliard committed
163 164 165
}

/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
166 167
 * 				AUX_SetVolume			[internal]
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
168
static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
Alexandre Julliard's avatar
Alexandre Julliard committed
169
{
170
    int 	mixer;
171 172
    int		volume, left, right;
    int		cmd;
173

174
    TRACE("(%04X, %08X);\n", wDevID, dwParam);
175

176 177 178
    left   = (LOWORD(dwParam) * 100) >> 16;
    right  = (HIWORD(dwParam) * 100) >> 16;
    volume = (right << 8) | left;
179

180 181 182 183
    if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
	WARN("mixer device not available !\n");
	return MMSYSERR_NOTENABLED;
    }
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    switch(wDevID) {
    case 0:
	TRACE("SOUND_MIXER_WRITE_PCM !\n");
	cmd = SOUND_MIXER_WRITE_PCM;
	break;
    case 1:
	TRACE("SOUND_MIXER_WRITE_SYNTH !\n");
	cmd = SOUND_MIXER_WRITE_SYNTH;
	break;
    case 2:
	TRACE("SOUND_MIXER_WRITE_CD !\n");
	cmd = SOUND_MIXER_WRITE_CD;
	break;
    case 3:
	TRACE("SOUND_MIXER_WRITE_LINE !\n");
	cmd = SOUND_MIXER_WRITE_LINE;
	break;
    case 4:
	TRACE("SOUND_MIXER_WRITE_MIC !\n");
	cmd = SOUND_MIXER_WRITE_MIC;
	break;
    case 5:
	TRACE("SOUND_MIXER_WRITE_VOLUME !\n");
	cmd = SOUND_MIXER_WRITE_VOLUME;
	break;
    default:
	WARN("invalid device id=%04X !\n", wDevID);
212
	close(mixer);
Alexandre Julliard's avatar
Alexandre Julliard committed
213
	return MMSYSERR_NOTENABLED;
214 215
    }
    if (ioctl(mixer, cmd, &volume) == -1) {
216
	WARN("unable to set mixer !\n");
217
	close(mixer);
218 219 220 221
	return MMSYSERR_NOTENABLED;
    }
    close(mixer);
    return MMSYSERR_NOERROR;
Alexandre Julliard's avatar
Alexandre Julliard committed
222 223 224
}

/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
225
 *		auxMessage (WINEOSS.2)
Alexandre Julliard's avatar
Alexandre Julliard committed
226
 */
227 228
DWORD WINAPI OSS_auxMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
			    DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Alexandre Julliard's avatar
Alexandre Julliard committed
229
{
230
    TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",
231
	  wDevID, wMsg, dwUser, dwParam1, dwParam2);
232 233

    switch (wMsg) {
234
    case DRVM_INIT:
235
        return OSS_AuxInit();
236
    case DRVM_EXIT:
237
        return OSS_AuxExit();
238 239 240 241 242
    case DRVM_ENABLE:
    case DRVM_DISABLE:
	/* FIXME: Pretend this is supported */
	return 0;
    case AUXDM_GETDEVCAPS:
243
	return AUX_GetDevCaps(wDevID, (LPAUXCAPSW)dwParam1, dwParam2);
244 245 246 247 248 249 250 251 252 253 254
    case AUXDM_GETNUMDEVS:
	TRACE("return %d;\n", NumDev);
	return NumDev;
    case AUXDM_GETVOLUME:
	return AUX_GetVolume(wDevID, (LPDWORD)dwParam1);
    case AUXDM_SETVOLUME:
	return AUX_SetVolume(wDevID, dwParam1);
    default:
	WARN("unknown message !\n");
    }
    return MMSYSERR_NOTSUPPORTED;
Alexandre Julliard's avatar
Alexandre Julliard committed
255
}