Fix GetTempPath32 if count=0.
[wine] / multimedia / mixer.c
1 /*
2  * Sample MIXER Wine Driver for Linux
3  *
4  * Copyright 1997 Marcus Meissner
5  */
6
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <sys/ioctl.h>
11 #include "windows.h"
12 #include "user.h"
13 #include "driver.h"
14 #include "multimedia.h"
15 #include "debug.h"
16
17 #define MIXER_DEV "/dev/mixer"
18
19 /**************************************************************************
20  *                              MIX_GetDevCaps                  [internal]
21  */
22 static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
23 {
24 #ifdef HAVE_OSS
25         int             mixer,mask;
26
27         TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
28         if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
29         if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
30                 WARN(mmaux, "mixer device not available !\n");
31                 return MMSYSERR_NOTENABLED;
32         }
33         lpCaps->wMid = 0xAA;
34         lpCaps->wPid = 0x55;
35         lpCaps->vDriverVersion = 0x0100;
36         strcpy(lpCaps->szPname,"WINE Generic Mixer");
37         if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
38                 close(mixer);
39                 perror("ioctl mixer SOUND_MIXER_DEVMASK");
40                 return MMSYSERR_NOTENABLED;
41         }
42         /* FIXME: can the Linux Mixer differ between multiple mixertargets? */
43         lpCaps->cDestinations = 1;
44         lpCaps->fdwSupport = 0; /* No bits defined yet */
45
46         close(mixer);
47         return MMSYSERR_NOERROR;
48 #else
49         return MMSYSERR_NOTENABLED;
50 #endif
51 }
52
53 #ifdef HAVE_OSS
54 static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
55 static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
56 #endif
57
58 /**************************************************************************
59  *                              MIX_GetLineInfo                 [internal]
60  */
61 static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
62 {
63 #ifdef HAVE_OSS
64         int             mixer,i,j,devmask,recsrc,recmask;
65
66         TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
67         if (lpml == NULL) return MMSYSERR_NOTENABLED;
68         if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
69                 return MMSYSERR_NOTENABLED;
70
71         if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
72                 close(mixer);
73                 perror("ioctl mixer SOUND_MIXER_DEVMASK");
74                 return MMSYSERR_NOTENABLED;
75         }
76         if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
77                 close(mixer);
78                 perror("ioctl mixer SOUND_MIXER_RECSRC");
79                 return MMSYSERR_NOTENABLED;
80         }
81         if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
82                 close(mixer);
83                 perror("ioctl mixer SOUND_MIXER_RECMASK");
84                 return MMSYSERR_NOTENABLED;
85         }
86         lpml->cbStruct = sizeof(MIXERLINE16);
87         /* FIXME: set all the variables correctly... the lines below
88          * are very wrong...
89          */
90         lpml->fdwLine   = MIXERLINE_LINEF_ACTIVE;
91         lpml->cChannels = 2;
92
93         switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
94         case MIXER_GETLINEINFOF_DESTINATION:
95                 /* FIXME: Linux doesn't seem to support multiple outputs? 
96                  * So we have only one outputtype, Speaker.
97                  */
98                 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
99                 /* we have all connections found in the devmask */
100                 lpml->cConnections = 0;
101                 for (j=0;j<31;j++)
102                         if (devmask & (1<<j))
103                                 lpml->cConnections++;
104                 break;
105         case MIXER_GETLINEINFOF_SOURCE:
106                 for (i=j=0;j<31;j++) {
107                         if (devmask & (1<<j)) {
108                                 if (lpml->dwSource == i)
109                                         break;
110                                 i++;
111                         }
112                 }
113                 strcpy(lpml->szShortName,sdlabels[i]);
114                 strcpy(lpml->szName,sdnames[i]);
115                 lpml->dwLineID = i;
116                 switch (i) {
117                 case SOUND_MIXER_SYNTH:
118                         lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
119                         lpml->fdwLine   |= MIXERLINE_LINEF_SOURCE;
120                         break;
121                 case SOUND_MIXER_CD:
122                         lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
123                         lpml->fdwLine   |= MIXERLINE_LINEF_SOURCE;
124                         break;
125                 case SOUND_MIXER_LINE:
126                         lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
127                         lpml->fdwLine   |= MIXERLINE_LINEF_SOURCE;
128                         break;
129                 case SOUND_MIXER_MIC:
130                         lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
131                         lpml->fdwLine   |= MIXERLINE_LINEF_SOURCE;
132                         break;
133                 case SOUND_MIXER_PCM:
134                         lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
135                         lpml->fdwLine   |= MIXERLINE_LINEF_SOURCE;
136                         break;
137                 default:
138                         ERR(mmaux,"Mixertype %d not handle.\n",i);
139                         break;
140                 }
141                 break;
142         case MIXER_GETLINEINFOF_LINEID:
143                 FIXME(mmaux,"_LINEID (%ld) not implemented yet.\n",lpml->dwLineID);
144                 break;
145         case MIXER_GETLINEINFOF_COMPONENTTYPE:
146                 FIXME(mmaux," _COMPONENTTYPE not implemented yet.\n");
147                 break;
148         case MIXER_GETLINEINFOF_TARGETTYPE:
149                 FIXME(mmaux,"_TARGETTYPE not implemented yet.\n");
150                 break;
151         }
152         lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
153         close(mixer);
154         return MMSYSERR_NOERROR;
155 #else
156         return MMSYSERR_NOTENABLED;
157 #endif
158 }
159
160 /**************************************************************************
161  *                              MIX_GetLineInfo                 [internal]
162  */
163 static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
164 {
165 #ifdef HAVE_OSS
166
167         TRACE(mmaux,"(%04X, %p, %lu);\n",wDevID,lpmod,flags);
168         if (lpmod == NULL) return MMSYSERR_NOTENABLED;
169         /* hmm. We don't keep the mixer device open. So just pretend it works */
170         return MMSYSERR_NOERROR;
171 #else
172         return MMSYSERR_NOTENABLED;
173 #endif
174 }
175
176 /**************************************************************************
177  *                              mixMessage                      [sample driver]
178  */
179 DWORD WINAPI mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
180                                         DWORD dwParam1, DWORD dwParam2)
181 {
182         TRACE(mmaux,"(%04X, %04X, %08lX, %08lX, %08lX);\n", 
183                         wDevID, wMsg, dwUser, dwParam1, dwParam2);
184         switch(wMsg) {
185         case MXDM_GETDEVCAPS:
186                 return MIX_GetDevCaps(wDevID,(LPMIXERCAPS16)dwParam1,dwParam2);
187         case MXDM_GETLINEINFO:
188                 return MIX_GetLineInfo(wDevID,(LPMIXERLINE16)dwParam1,dwParam2);
189         case MXDM_GETNUMDEVS:
190                 TRACE(mmsys,"return 1;\n");
191                 return 1;
192         case MXDM_OPEN:
193                 return MIX_Open(wDevID,(LPMIXEROPENDESC)dwParam1,dwParam2);
194         default:
195                 WARN(mmaux,"unknown message %d!\n",wMsg);
196         }
197         return MMSYSERR_NOTSUPPORTED;
198 }
199