Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
9.2 KiB

  1. //--------------------------------------------------------------------------;
  2. //
  3. // File: speakers.cpp
  4. //
  5. // Copyright (c) 1997 Microsoft Corporation. All rights reserved
  6. //
  7. //--------------------------------------------------------------------------;
  8. #include "mmcpl.h"
  9. #include <windowsx.h>
  10. #ifdef DEBUG
  11. #undef DEBUG
  12. #include <mmsystem.h>
  13. #define DEBUG
  14. #else
  15. #include <mmsystem.h>
  16. #endif
  17. #include <commctrl.h>
  18. #include <prsht.h>
  19. #include <regstr.h>
  20. #include "utils.h"
  21. #include "medhelp.h"
  22. #include <dsound.h>
  23. #include "advaudio.h"
  24. #include "speakers.h"
  25. #include "dslevel.h"
  26. /////////////
  27. // defines
  28. /////////////
  29. #define NUMCONFIG (MAX_SPEAKER_TYPE + 1)
  30. //////////
  31. // Globals
  32. //////////
  33. DWORD gdwSpeakerTable[NUMCONFIG] =
  34. {
  35. DSSPEAKER_DIRECTOUT,
  36. DSSPEAKER_HEADPHONE,
  37. SPEAKERS_DEFAULT_CONFIG,
  38. DSSPEAKER_MONO,
  39. DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW),
  40. DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW),
  41. DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW),
  42. DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE),
  43. DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW),
  44. DSSPEAKER_QUAD,
  45. DSSPEAKER_SURROUND,
  46. DSSPEAKER_5POINT1,
  47. DSSPEAKER_7POINT1
  48. };
  49. DWORD gdwImageID[NUMCONFIG] =
  50. {
  51. IDB_NOSPEAKERS,
  52. IDB_HEADPHONES,
  53. IDB_STEREODESKTOP,
  54. IDB_MONOLAPTOP,
  55. IDB_STEREOLAPTOP,
  56. IDB_STEREOMONITOR,
  57. IDB_STEREOCPU,
  58. IDB_MOUNTEDSTEREO,
  59. IDB_STEREOKEYBOARD,
  60. IDB_QUADRAPHONIC,
  61. IDB_SURROUND,
  62. IDB_SURROUND_5_1,
  63. IDB_SURROUND_7_1
  64. };
  65. HBITMAP ghBitmaps[NUMCONFIG];
  66. //////////////
  67. // Help ID's
  68. //////////////
  69. #pragma data_seg(".text")
  70. const static DWORD aAdvSpeakerHelp[] =
  71. {
  72. IDC_SPEAKERCONFIG, IDH_SPEAKERS_PICKER,
  73. IDC_IMAGEFRAME, IDH_SPEAKERS_IMAGE,
  74. IDC_ICON_4, IDH_COMM_GROUPBOX,
  75. IDC_TEXT_22, IDH_COMM_GROUPBOX,
  76. IDC_TEXT_23, IDH_SPEAKERS_PICKER,
  77. 0, 0
  78. };
  79. #pragma data_seg()
  80. //////////////
  81. // Functions
  82. //////////////
  83. //
  84. // Verifies that the speakers type and config match, if not, change type to match config using default type
  85. //
  86. void VerifySpeakerConfig(DWORD dwSpeakerConfig, LPDWORD pdwSpeakerType)
  87. {
  88. if (pdwSpeakerType)
  89. {
  90. DWORD dwType = *pdwSpeakerType;
  91. if (gdwSpeakerTable[dwType] != dwSpeakerConfig) // the type doesn't match the config, pick a default type
  92. {
  93. switch (dwSpeakerConfig)
  94. {
  95. case DSSPEAKER_DIRECTOUT:
  96. *pdwSpeakerType = TYPE_NOSPEAKERS;
  97. break;
  98. case DSSPEAKER_HEADPHONE:
  99. *pdwSpeakerType = TYPE_HEADPHONES;
  100. break;
  101. case DSSPEAKER_MONO:
  102. *pdwSpeakerType = TYPE_MONOLAPTOP;
  103. break;
  104. case DSSPEAKER_STEREO:
  105. *pdwSpeakerType = TYPE_STEREODESKTOP;
  106. break;
  107. case DSSPEAKER_QUAD:
  108. *pdwSpeakerType = TYPE_QUADRAPHONIC;
  109. break;
  110. case DSSPEAKER_SURROUND:
  111. *pdwSpeakerType = TYPE_SURROUND;
  112. break;
  113. case DSSPEAKER_5POINT1:
  114. *pdwSpeakerType = TYPE_SURROUND_5_1;
  115. break;
  116. case DSSPEAKER_7POINT1:
  117. *pdwSpeakerType = TYPE_SURROUND_7_1;
  118. break;
  119. default:
  120. {
  121. if (DSSPEAKER_CONFIG(dwSpeakerConfig) == DSSPEAKER_STEREO)
  122. {
  123. DWORD dwAngle = DSSPEAKER_GEOMETRY(dwSpeakerConfig);
  124. DWORD dwMiddle = DSSPEAKER_GEOMETRY_NARROW +
  125. ((DSSPEAKER_GEOMETRY_WIDE - DSSPEAKER_GEOMETRY_NARROW) >> 1);
  126. if (dwAngle <= dwMiddle)
  127. {
  128. *pdwSpeakerType = TYPE_STEREOCPU;
  129. }
  130. else
  131. {
  132. *pdwSpeakerType = TYPE_STEREODESKTOP;
  133. }
  134. }
  135. }
  136. break;
  137. }
  138. }
  139. }
  140. }
  141. //
  142. // Given a speaker type, returns the DirectSound config for it
  143. //
  144. DWORD GetSpeakerConfigFromType(DWORD dwType)
  145. {
  146. DWORD dwConfig = SPEAKERS_DEFAULT_CONFIG;
  147. if (dwType < (DWORD)NUMCONFIG)
  148. {
  149. dwConfig = gdwSpeakerTable[dwType];
  150. }
  151. return(dwConfig);
  152. }
  153. //
  154. // Called when first started up, it determines the current state of the device's speaker state
  155. // and fills out the controls as appropriate
  156. //
  157. BOOL InitSpeakerDlg(HWND hwnd, BOOL fImagesOnly)
  158. {
  159. TCHAR str[255];
  160. int item;
  161. DWORD dwIndex;
  162. HWND hwndCombo;
  163. if (!fImagesOnly)
  164. {
  165. SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_RESETCONTENT,0,0);
  166. }
  167. for (item = 0; item < NUMCONFIG; item++)
  168. {
  169. if (!fImagesOnly)
  170. {
  171. LoadString( ghInst, IDS_SPEAKER1 + item, str, sizeof( str )/sizeof(TCHAR) );
  172. SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_INSERTSTRING, (WPARAM) -1, (LPARAM) str);
  173. }
  174. if (ghBitmaps[item] != NULL)
  175. {
  176. DeleteObject( (HGDIOBJ) ghBitmaps[item]);
  177. ghBitmaps[item] = NULL;
  178. }
  179. ghBitmaps[item] = (HBITMAP) LoadImage(ghInst,MAKEINTATOM(gdwImageID[item]), IMAGE_BITMAP,
  180. 0, 0, LR_LOADMAP3DCOLORS);
  181. }
  182. dwIndex = gAudData.current.dwSpeakerType;
  183. SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_SETCURSEL, (WPARAM) dwIndex, 0);
  184. SendDlgItemMessage(hwnd, IDC_IMAGEFRAME, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) ghBitmaps[dwIndex]);
  185. // Enable/disable the combo box appropriately
  186. hwndCombo = GetDlgItem( hwnd, IDC_SPEAKERCONFIG );
  187. if (hwndCombo)
  188. {
  189. // Check if we can set the speaker configuration
  190. if (FAILED(CheckDSSpeakerConfigPriv(gAudData.devGuid, gAudData.fRecord, NULL)))
  191. {
  192. // No - disable the combo box
  193. EnableWindow( hwndCombo, FALSE );
  194. }
  195. else
  196. {
  197. // Yes - enable the combo box
  198. EnableWindow( hwndCombo, TRUE );
  199. }
  200. }
  201. return(TRUE);
  202. }
  203. //
  204. // called to delete all loaded bitmaps
  205. //
  206. void DumpBitmaps(void)
  207. {
  208. int item;
  209. for (item = 0; item < NUMCONFIG; item++)
  210. {
  211. if (ghBitmaps[item] != NULL)
  212. {
  213. DeleteObject( (HGDIOBJ) ghBitmaps[item]);
  214. ghBitmaps[item] = NULL;
  215. }
  216. }
  217. }
  218. //
  219. // called by dialog handler when speaker type is changed
  220. //
  221. void ChangeSpeakers(HWND hwnd)
  222. {
  223. DWORD dwIndex;
  224. dwIndex = (DWORD)SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_GETCURSEL,0,0);
  225. if (dwIndex != CB_ERR)
  226. {
  227. gAudData.current.dwSpeakerType = dwIndex;
  228. gAudData.current.dwSpeakerConfig = GetSpeakerConfigFromType(gAudData.current.dwSpeakerType);
  229. SendDlgItemMessage(hwnd, IDC_IMAGEFRAME, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) ghBitmaps[dwIndex]);
  230. ToggleApplyButton(hwnd);
  231. }
  232. }
  233. //
  234. // Dialog event handler
  235. //
  236. INT_PTR CALLBACK SpeakerHandler(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  237. {
  238. BOOL fReturnVal = TRUE;
  239. switch (msg)
  240. {
  241. default:
  242. fReturnVal = FALSE;
  243. break;
  244. case WM_INITDIALOG:
  245. {
  246. fReturnVal = InitSpeakerDlg(hDlg, FALSE);
  247. }
  248. break;
  249. case WM_DESTROY:
  250. {
  251. DumpBitmaps();
  252. }
  253. break;
  254. case WM_CONTEXTMENU:
  255. {
  256. WinHelp((HWND)wParam, gszHelpFile, HELP_CONTEXTMENU, (UINT_PTR)(LPTSTR)aAdvSpeakerHelp);
  257. fReturnVal = TRUE;
  258. }
  259. break;
  260. case WM_HELP:
  261. {
  262. WinHelp((HWND) ((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (UINT_PTR)(LPTSTR)aAdvSpeakerHelp);
  263. fReturnVal = TRUE;
  264. }
  265. break;
  266. case WM_SYSCOLORCHANGE:
  267. {
  268. fReturnVal = InitSpeakerDlg(hDlg, TRUE);
  269. }
  270. break;
  271. case WM_COMMAND:
  272. {
  273. switch (LOWORD(wParam))
  274. {
  275. case IDC_SPEAKERCONFIG:
  276. {
  277. if (HIWORD(wParam) == CBN_SELCHANGE)
  278. {
  279. ChangeSpeakers(hDlg);
  280. }
  281. }
  282. break;
  283. default:
  284. fReturnVal = FALSE;
  285. break;
  286. }
  287. break;
  288. }
  289. case WM_NOTIFY:
  290. {
  291. LPNMHDR pnmh = (LPNMHDR) lParam;
  292. switch (pnmh->code)
  293. {
  294. case PSN_APPLY:
  295. {
  296. ApplyCurrentSettings(&gAudData);
  297. }
  298. }
  299. }
  300. }
  301. return fReturnVal;
  302. }