Release 20050930.
[wine/gsoc-2012-control.git] / programs / winecfg / audio.c
blobcd64916ca1f89661ff78893254ba68929aa8263c
1 /*
2 * Audio management UI code
4 * Copyright 2004 Chris Morgan
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
23 #include "wine/port.h"
25 #include <assert.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winreg.h>
34 #include <wine/debug.h>
35 #include <shellapi.h>
36 #include <objbase.h>
37 #include <shlguid.h>
38 #include <shlwapi.h>
39 #include <shlobj.h>
40 #include <mmsystem.h>
42 #include "winecfg.h"
43 #include "resource.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
47 static const char* DSound_HW_Accels[] = {
48 "Full",
49 "Standard",
50 "Basic",
51 "Emulation",
52 NULL
55 /* Select the correct entry in the combobox based on drivername */
56 static void selectAudioDriver(HWND hDlg, const char *drivername)
58 int i;
59 const AUDIO_DRIVER *pAudioDrv = NULL;
61 if ((pAudioDrv = getAudioDrivers()))
63 for (i = 0; *pAudioDrv->szName; i++, pAudioDrv++)
65 if (!strcmp (pAudioDrv->szDriver, drivername))
67 set_reg_key(config_key, "Drivers", "Audio", (char *) pAudioDrv->szDriver);
68 SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); /* enable apply button */
69 SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_SETCURSEL,
70 (WPARAM) i, 0);
76 static void configureAudioDriver(HWND hDlg, const char *drivername)
78 int i;
79 const AUDIO_DRIVER *pAudioDrv = NULL;
81 if ((pAudioDrv = getAudioDrivers()))
83 for (i = 0; *pAudioDrv->szName; i++, pAudioDrv++)
85 if (!strcmp (pAudioDrv->szDriver, drivername))
87 if (strlen(pAudioDrv->szDriver) != 0)
89 HDRVR hdrvr;
90 char wine_driver[MAX_NAME_LENGTH + 8];
91 sprintf(wine_driver, "wine%s.drv", pAudioDrv->szDriver);
92 hdrvr = OpenDriverA(wine_driver, 0, 0);
93 if (hdrvr != 0)
95 if (SendDriverMessage(hdrvr, DRV_QUERYCONFIGURE, 0, 0) != 0)
97 DRVCONFIGINFO dci;
98 LONG lRes;
99 dci.dwDCISize = sizeof (dci);
100 dci.lpszDCISectionName = NULL;
101 dci.lpszDCIAliasName = NULL;
102 lRes = SendDriverMessage(hdrvr, DRV_CONFIGURE, 0, (LONG)&dci);
104 CloseDriver(hdrvr, 0, 0);
106 else
108 char str[1024];
109 sprintf(str, "Couldn't open %s!", wine_driver);
110 MessageBox(NULL, str, "Fixme", MB_OK | MB_ICONERROR);
113 break;
119 static void initAudioDlg (HWND hDlg)
121 char *curAudioDriver = get_reg_key(config_key, "Drivers", "Audio", "alsa");
122 const AUDIO_DRIVER *pAudioDrv = NULL;
123 int i;
124 char* buf = NULL;
126 WINE_TRACE("\n");
128 pAudioDrv = getAudioDrivers ();
129 for (i = 0; *pAudioDrv->szName; i++, pAudioDrv++) {
130 SendDlgItemMessage (hDlg, IDC_AUDIO_DRIVER, CB_ADDSTRING,
131 0, (LPARAM) pAudioDrv->szName);
132 if (!strcmp (pAudioDrv->szDriver, curAudioDriver)) {
133 SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_SETCURSEL, i, 0);
138 SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_RESETCONTENT, 0, 0);
139 for (i = 0; NULL != DSound_HW_Accels[i]; ++i) {
140 SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_ADDSTRING, 0, (LPARAM) DSound_HW_Accels[i]);
142 buf = get_reg_key(config_key, keypath("DirectSound"), "HardwareAcceleration", "Full");
143 for (i = 0; NULL != DSound_HW_Accels[i]; ++i) {
144 if (strcmp(buf, DSound_HW_Accels[i]) == 0) {
145 SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_SETCURSEL, i, 0);
146 break ;
149 if (NULL == DSound_HW_Accels[i]) {
150 WINE_ERR("Invalid Direct Sound HW Accel read from registry (%s)\n", buf);
152 HeapFree(GetProcessHeap(), 0, buf);
154 buf = get_reg_key(config_key, keypath("DirectSound"), "EmulDriver", "N");
155 if (IS_OPTION_TRUE(*buf))
156 CheckDlgButton(hDlg, IDC_DSOUND_DRV_EMUL, BST_CHECKED);
157 else
158 CheckDlgButton(hDlg, IDC_DSOUND_DRV_EMUL, BST_UNCHECKED);
159 HeapFree(GetProcessHeap(), 0, buf);
163 static const char *audioAutoDetect(void)
165 struct stat buf;
166 const char *argv_new[4];
167 int fd;
169 const char *driversFound[10];
170 const char *name[10];
171 int numFound = 0;
173 argv_new[0] = "/bin/sh";
174 argv_new[1] = "-c";
175 argv_new[3] = NULL;
177 /* try to detect oss */
178 fd = open("/dev/dsp", O_WRONLY | O_NONBLOCK);
179 if(fd)
181 close(fd);
182 driversFound[numFound] = "oss";
183 name[numFound] = "OSS";
184 numFound++;
187 /* try to detect alsa */
188 if(!stat("/proc/asound", &buf))
190 driversFound[numFound] = "alsa";
191 name[numFound] = "ALSA";
192 numFound++;
195 /* try to detect arts */
196 argv_new[2] = "ps awx|grep artsd|grep -v grep|grep artsd > /dev/null";
197 if(!spawnvp(_P_WAIT, "/bin/sh", argv_new))
199 driversFound[numFound] = "arts";
200 name[numFound] = "aRts";
201 numFound++;
204 /* try to detect jack */
205 argv_new[2] = "ps awx|grep jackd|grep -v grep|grep jackd > /dev/null";
206 if(!spawnvp(_P_WAIT, "/bin/sh", argv_new))
208 driversFound[numFound] = "jack";
209 name[numFound] = "JACK";
210 numFound++;
213 /* try to detect EsounD */
214 argv_new[2] = "ps awx|grep esd|grep -v grep|grep esd > /dev/null";
215 if(!spawnvp(_P_WAIT, "/bin/sh", argv_new))
217 driversFound[numFound] = "esd";
218 name[numFound] = "EsounD";
219 numFound++;
222 /* try to detect nas */
223 /* TODO */
225 /* try to detect audioIO (solaris) */
226 /* TODO */
228 if(numFound == 0)
230 MessageBox(NULL, "Could not detect any audio devices/servers", "Failed", MB_OK);
231 return "";
233 else
235 /* TODO: possibly smarter handling of multiple drivers? */
236 char text[128];
237 snprintf(text, sizeof(text), "Found %s", name[0]);
238 MessageBox(NULL, (LPCTSTR)text, "Successful", MB_OK);
239 return driversFound[0];
244 INT_PTR CALLBACK
245 AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
247 switch (uMsg) {
248 case WM_COMMAND:
249 switch (LOWORD(wParam)) {
250 case IDC_AUDIO_AUTODETECT:
251 selectAudioDriver(hDlg, audioAutoDetect());
252 break;
253 case IDC_AUDIO_DRIVER:
254 if ((HIWORD(wParam) == CBN_SELCHANGE) ||
255 (HIWORD(wParam) == CBN_SELCHANGE))
257 const AUDIO_DRIVER *pAudioDrv = getAudioDrivers();
258 int selected_driver = SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_GETCURSEL, 0, 0);
259 selectAudioDriver(hDlg, (char*)pAudioDrv[selected_driver].szDriver);
261 break;
262 case IDC_AUDIO_CONFIGURE:
264 const AUDIO_DRIVER *pAudioDrv = getAudioDrivers();
265 int selected_driver = SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_GETCURSEL, 0, 0);
266 configureAudioDriver(hDlg, (char*)pAudioDrv[selected_driver].szDriver);
268 break;
269 case IDC_AUDIO_CONTROL_PANEL:
270 MessageBox(NULL, "Launching audio control panel not implemented yet!", "Fixme", MB_OK | MB_ICONERROR);
271 break;
272 case IDC_DSOUND_HW_ACCEL:
273 if (HIWORD(wParam) == CBN_SELCHANGE) {
274 int selected_dsound_accel;
275 SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
276 selected_dsound_accel = SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_GETCURSEL, 0, 0);
277 set_reg_key(config_key, keypath("DirectSound"), "HardwareAcceleration", DSound_HW_Accels[selected_dsound_accel]);
279 break;
280 case IDC_DSOUND_DRV_EMUL:
281 if (HIWORD(wParam) == BN_CLICKED) {
282 SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
283 if (IsDlgButtonChecked(hDlg, IDC_DSOUND_DRV_EMUL) == BST_CHECKED)
284 set_reg_key(config_key, keypath("DirectSound"), "EmulDriver", "Y");
285 else
286 set_reg_key(config_key, keypath("DirectSound"), "EmulDriver", "N");
288 break;
290 break;
292 case WM_SHOWWINDOW:
293 set_window_title(hDlg);
294 break;
296 case WM_NOTIFY:
297 switch(((LPNMHDR)lParam)->code) {
298 case PSN_KILLACTIVE:
299 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
300 break;
301 case PSN_APPLY:
302 apply();
303 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
304 break;
305 case PSN_SETACTIVE:
306 break;
308 break;
310 case WM_INITDIALOG:
311 initAudioDlg(hDlg);
312 break;
315 return FALSE;