diff --git a/programs/winecfg/En.rc b/programs/winecfg/En.rc index 043d74f0c43..dfa545191b0 100644 --- a/programs/winecfg/En.rc +++ b/programs/winecfg/En.rc @@ -155,16 +155,14 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Audio driver: ",IDC_STATIC,10,20,60,8 COMBOBOX IDC_AUDIO_DRIVER,70,18,85,85,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Autodetect",IDC_AUDIO_AUTODETECT,170,20,49,14 - PUSHBUTTON "Configure",IDC_AUDIO_CONFIGURE,170,40,49,14 - PUSHBUTTON "Control Panel",IDC_AUDIO_CONTROL_PANEL,170,60,49,14 - - GROUPBOX " DirectSound ",IDC_STATIC,8,75,244,120 - - LTEXT "Hardware Acceleration: ",IDC_STATIC,15,85,90,10 - COMBOBOX IDC_DSOUND_HW_ACCEL,100,83,150,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Driver Emulation",IDC_DSOUND_DRV_EMUL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,100,230,10 - + PUSHBUTTON "Autodetect",IDC_AUDIO_AUTODETECT,170,20,59,14 + PUSHBUTTON "Configure",IDC_AUDIO_CONFIGURE,170,40,59,14 + PUSHBUTTON "Control Panel",IDC_AUDIO_CONTROL_PANEL,170,60,59,14 + CONTROL "Devices",IDC_AUDIO_TREE,"SysTreeView32",WS_BORDER | WS_TABSTOP,10,40,150,160 + GROUPBOX " DirectSound ",IDC_STATIC,8,205,244,60 + LTEXT "Hardware Acceleration: ",IDC_STATIC,15,215,90,10 + COMBOBOX IDC_DSOUND_HW_ACCEL,100,213,150,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Driver Emulation",IDC_DSOUND_DRV_EMUL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,230,230,10 END IDD_APPEARANCE DIALOG DISCARDABLE 0, 0, 260, 250 diff --git a/programs/winecfg/audio.c b/programs/winecfg/audio.c index 8239a5f5dc7..87f38991a3f 100644 --- a/programs/winecfg/audio.c +++ b/programs/winecfg/audio.c @@ -38,12 +38,17 @@ #include #include #include +#include +#include +#include #include "winecfg.h" #include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(winecfg); +typedef DWORD (WINAPI * MessagePtr)(UINT, UINT, DWORD, DWORD, DWORD); + static const char* DSound_HW_Accels[] = { "Full", "Standard", @@ -116,6 +121,264 @@ static void configureAudioDriver(HWND hDlg, const char *drivername) } } +static void initAudioDeviceTree(HWND hDlg) +{ + const AUDIO_DRIVER *pAudioDrv = NULL; + int i, j; + TVINSERTSTRUCT insert; + HTREEITEM root, driver[10]; + HWND tree = NULL; + + tree = GetDlgItem(hDlg, IDC_AUDIO_TREE); + + if (!tree) + return; + + SetWindowLong(tree, GWL_STYLE, GetWindowLong(tree, GWL_STYLE) | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT); + + insert.hParent = TVI_ROOT; + insert.hInsertAfter = TVI_LAST; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "Sound Drivers"; + insert.item.cChildren = 1; + + root = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + pAudioDrv = getAudioDrivers(); + + for (i = 0; *pAudioDrv->szName; i++, pAudioDrv++) { + HDRVR hdrv; + char name[MAX_PATH]; + char text[MAX_PATH]; + + if (strlen(pAudioDrv->szDriver) == 0) + continue; + + sprintf(name, "wine%s.drv", pAudioDrv->szDriver); + sprintf(text, "%s Driver", pAudioDrv->szName); + + hdrv = OpenDriverA(name, 0, 0); + if (hdrv == 0) /* no driver loaded */ + { + insert.hParent = root; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = text; + + driver[i] = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + else + { + HINSTANCE lib; + + lib = LoadLibrary(name); + if (lib) + { + int num_wod = 0, num_wid = 0, num_mod = 0, num_mid = 0, num_aux = 0, num_mxd = 0; + MessagePtr wodMessagePtr = (MessagePtr)GetProcAddress(lib, "wodMessage"); + MessagePtr widMessagePtr = (MessagePtr)GetProcAddress(lib, "widMessage"); + MessagePtr modMessagePtr = (MessagePtr)GetProcAddress(lib, "modMessage"); + MessagePtr midMessagePtr = (MessagePtr)GetProcAddress(lib, "midMessage"); + MessagePtr auxMessagePtr = (MessagePtr)GetProcAddress(lib, "auxMessage"); + MessagePtr mxdMessagePtr = (MessagePtr)GetProcAddress(lib, "mxdMessage"); + + if (wodMessagePtr) + num_wod = wodMessagePtr(0, WODM_GETNUMDEVS, 0, 0, 0); + + if (widMessagePtr) + num_wid = widMessagePtr(0, WIDM_GETNUMDEVS, 0, 0, 0); + + if (modMessagePtr) + num_mod = modMessagePtr(0, MODM_GETNUMDEVS, 0, 0, 0); + + if (midMessagePtr) + num_mid = midMessagePtr(0, MIDM_GETNUMDEVS, 0, 0, 0); + + if (auxMessagePtr) + num_aux = auxMessagePtr(0, AUXDM_GETNUMDEVS, 0, 0, 0); + + if (mxdMessagePtr) + num_mxd = mxdMessagePtr(0, MXDM_GETNUMDEVS, 0, 0, 0); + + if (num_wod == 0 && num_wid == 0 && num_mod == 0 && num_mid == 0 && num_aux == 0 && num_mxd == 0) + { + insert.hParent = root; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = text; + + driver[i] = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + else + { + HTREEITEM type; + + insert.hParent = root; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = text; + insert.item.cChildren = 1; + + driver[i] = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + if (num_wod) + { + insert.hParent = driver[i]; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "Wave Out Devices"; + insert.item.cChildren = 1; + + type = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + for (j = 0; j < num_wod; j++) + { + WAVEOUTCAPSW caps; + char szPname[MAXPNAMELEN]; + + wodMessagePtr(j, WODM_GETDEVCAPS, 0, (DWORD)&caps, sizeof(caps)); + WideCharToMultiByte(CP_ACP, 0, caps.szPname, -1, szPname, MAXPNAMELEN, 0, 0); + + insert.hParent = type; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = szPname; + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + } + + if (num_wid) + { + insert.hParent = driver[i]; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "Wave In Devices"; + insert.item.cChildren = 1; + + type = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + for (j = 0; j < num_wid; j++) + { + WAVEINCAPSW caps; + char szPname[MAXPNAMELEN]; + + widMessagePtr(j, WIDM_GETDEVCAPS, 0, (DWORD)&caps, sizeof(caps)); + WideCharToMultiByte(CP_ACP, 0, caps.szPname, -1, szPname, MAXPNAMELEN, 0, 0); + + insert.hParent = type; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = szPname; + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + } + + if (num_mod) + { + insert.hParent = driver[i]; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "MIDI Out Devices"; + insert.item.cChildren = 1; + + type = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + for (j = 0; j < num_mod; j++) + { + MIDIOUTCAPSW caps; + char szPname[MAXPNAMELEN]; + + modMessagePtr(j, MODM_GETDEVCAPS, 0, (DWORD)&caps, sizeof(caps)); + WideCharToMultiByte(CP_ACP, 0, caps.szPname, -1, szPname, MAXPNAMELEN, 0, 0); + + insert.hParent = type; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = szPname; + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + } + + if (num_mid) + { + insert.hParent = driver[i]; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "MIDI In Devices"; + insert.item.cChildren = 1; + + type = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + for (j = 0; j < num_mid; j++) + { + MIDIINCAPSW caps; + char szPname[MAXPNAMELEN]; + + midMessagePtr(j, MIDM_GETDEVCAPS, 0, (DWORD)&caps, sizeof(caps)); + WideCharToMultiByte(CP_ACP, 0, caps.szPname, -1, szPname, MAXPNAMELEN, 0, 0); + + insert.hParent = type; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = szPname; + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + } + + if (num_aux) + { + insert.hParent = driver[i]; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "Aux Devices"; + insert.item.cChildren = 1; + + type = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + for (j = 0; j < num_aux; j++) + { + AUXCAPSW caps; + char szPname[MAXPNAMELEN]; + + auxMessagePtr(j, AUXDM_GETDEVCAPS, 0, (DWORD)&caps, sizeof(caps)); + WideCharToMultiByte(CP_ACP, 0, caps.szPname, -1, szPname, MAXPNAMELEN, 0, 0); + + insert.hParent = type; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = szPname; + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + } + + if (num_mxd) + { + insert.hParent = driver[i]; + insert.item.mask = TVIF_TEXT | TVIF_CHILDREN; + insert.item.pszText = "Mixer Devices"; + insert.item.cChildren = 1; + + type = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + + for (j = 0; j < num_mxd; j++) + { + MIXERCAPSW caps; + char szPname[MAXPNAMELEN]; + + mxdMessagePtr(j, MXDM_GETDEVCAPS, 0, (DWORD)&caps, sizeof(caps)); + WideCharToMultiByte(CP_ACP, 0, caps.szPname, -1, szPname, MAXPNAMELEN, 0, 0); + + insert.hParent = type; + insert.item.mask = TVIF_TEXT; + insert.item.pszText = szPname; + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_INSERTITEM, 0, (LPARAM)&insert); + } + } + } + FreeLibrary(lib); + } + } + } + + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_SELECTITEM, 0, 0); + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_EXPAND, TVE_EXPAND, (LPARAM)root); + for (j = 0; j < i; j++) + SendDlgItemMessage(hDlg, IDC_AUDIO_TREE, TVM_EXPAND, TVE_EXPAND, (LPARAM)driver[j]); +} + static void initAudioDlg (HWND hDlg) { char *curAudioDriver = get_reg_key(config_key, "Drivers", "Audio", "alsa"); @@ -134,6 +397,7 @@ static void initAudioDlg (HWND hDlg) } } + initAudioDeviceTree(hDlg); SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_RESETCONTENT, 0, 0); for (i = 0; NULL != DSound_HW_Accels[i]; ++i) { diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h index 1a4244416b6..bed9c1b14bb 100644 --- a/programs/winecfg/resource.h +++ b/programs/winecfg/resource.h @@ -139,6 +139,7 @@ #define IDC_AUDIO_CONTROL_PANEL 1303 #define IDC_DSOUND_HW_ACCEL 1304 #define IDC_DSOUND_DRV_EMUL 1305 +#define IDC_AUDIO_TREE 1306 /* appearance tab */ #define IDC_THEME_COLORCOMBO 1401