Constify all needlessly non-const winecfg structs.
[wine] / programs / winecfg / audio.c
1 /*
2  * Audio management UI code
3  *
4  * Copyright 2004 Chris Morgan
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <assert.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
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
41 #include "winecfg.h"
42 #include "resource.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
45
46 /* Select the correct entry in the combobox based on drivername */
47 static void selectAudioDriver(HWND hDlg, const char *drivername)
48 {
49   int i;
50   const AUDIO_DRIVER *pAudioDrv = NULL;
51
52   if ((pAudioDrv = getAudioDrivers()))
53   {
54     for (i = 0; *pAudioDrv->szName; i++, pAudioDrv++)
55     {
56       if (!strcmp (pAudioDrv->szDriver, drivername))
57       {
58         set_reg_key(config_key, "Drivers", "Audio", (char *) pAudioDrv->szDriver);
59         SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); /* enable apply button */
60         SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_SETCURSEL,
61                            (WPARAM) i, 0);
62       }
63     }
64   }
65 }
66
67 static void initAudioDlg (HWND hDlg)
68 {
69     char *curAudioDriver = get_reg_key(config_key, "Drivers", "Audio", "alsa");
70     const AUDIO_DRIVER *pAudioDrv = NULL;
71     int i;
72
73     WINE_TRACE("\n");
74
75     pAudioDrv = getAudioDrivers ();
76     for (i = 0; *pAudioDrv->szName; i++, pAudioDrv++) {
77         SendDlgItemMessage (hDlg, IDC_AUDIO_DRIVER, CB_ADDSTRING, 
78                 0, (LPARAM) pAudioDrv->szName);
79         if (!strcmp (pAudioDrv->szDriver, curAudioDriver)) {
80             SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_SETCURSEL, i, 0);
81         }
82     }
83 }
84
85 static const char *audioAutoDetect(void)
86 {
87   struct stat buf;
88   const char *argv_new[4];
89   int fd;
90
91   const char *driversFound[10];
92   const char *name[10];
93   int numFound = 0;
94
95   argv_new[0] = "/bin/sh";
96   argv_new[1] = "-c";
97   argv_new[3] = NULL;
98
99   /* try to detect oss */
100   fd = open("/dev/dsp", O_WRONLY | O_NONBLOCK);
101   if(fd)
102   {
103     close(fd);
104     driversFound[numFound] = "oss";
105     name[numFound] = "OSS";
106     numFound++;
107   }
108   
109     /* try to detect alsa */
110   if(!stat("/proc/asound", &buf))
111   {
112     driversFound[numFound] = "alsa";
113     name[numFound] = "ALSA";
114     numFound++;
115   }
116
117   /* try to detect arts */
118   argv_new[2] = "ps awx|grep artsd|grep -v grep|grep artsd > /dev/null";
119   if(!spawnvp(_P_WAIT, "/bin/sh", argv_new))
120   {
121     driversFound[numFound] = "arts";
122     name[numFound] = "aRts";
123     numFound++;
124   }
125
126   /* try to detect jack */
127   argv_new[2] = "ps awx|grep jackd|grep -v grep|grep jackd > /dev/null";
128   if(!spawnvp(_P_WAIT, "/bin/sh", argv_new))
129   {
130     driversFound[numFound] = "jack";
131     name[numFound] = "JACK";
132     numFound++;
133   }
134
135   /* try to detect nas */
136   /* TODO */
137
138   /* try to detect audioIO (solaris) */
139   /* TODO */
140
141   if(numFound == 0)
142   {
143     MessageBox(NULL, "Could not detect any audio devices/servers", "Failed", MB_OK);
144     return "";
145   }
146   else
147   {
148     /* TODO: possibly smarter handling of multiple drivers? */
149     char text[128];
150     snprintf(text, sizeof(text), "Found %s", name[0]);
151     MessageBox(NULL, (LPCTSTR)text, "Successful", MB_OK);
152     return driversFound[0];
153   }
154 }
155
156
157 INT_PTR CALLBACK
158 AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
159 {
160   switch (uMsg) {
161       case WM_COMMAND:
162         switch (LOWORD(wParam)) {
163            case IDC_AUDIO_AUTODETECT:
164               selectAudioDriver(hDlg, audioAutoDetect());
165               break;
166            case IDC_AUDIO_DRIVER:
167              if ((HIWORD(wParam) == CBN_SELCHANGE) ||
168                  (HIWORD(wParam) == CBN_SELCHANGE))
169              {
170                 const AUDIO_DRIVER *pAudioDrv = getAudioDrivers();
171                 int selected_driver = SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_GETCURSEL, 0, 0);
172                 selectAudioDriver(hDlg, (char*)pAudioDrv[selected_driver].szDriver);
173              }
174              break;
175         }
176         break;
177
178       case WM_SHOWWINDOW:
179         set_window_title(hDlg);
180         break;
181         
182       case WM_NOTIFY:
183         switch(((LPNMHDR)lParam)->code) {
184             case PSN_KILLACTIVE:
185               SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
186               break;
187             case PSN_APPLY:
188               apply();
189               SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
190               break;
191             case PSN_SETACTIVE:
192               break;
193         }
194         break;
195
196   case WM_INITDIALOG:
197     initAudioDlg(hDlg);
198     break;
199   }
200
201   return FALSE;
202 }