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.

632 lines
16 KiB

  1. /*************************************************************************/
  2. /* Copyright (C) 1999 Microsoft Corporation */
  3. /* File: msdvd.cpp */
  4. /* Description: Implementation of CMSWebDVD. */
  5. /* Author: David Janecek */
  6. /*************************************************************************/
  7. #include "stdafx.h"
  8. #include "MSDVD.h"
  9. #include "ddrawobj.h"
  10. #define COMPILE_MULTIMON_STUBS
  11. #define HMONITOR_DECLARED // to cover up DDraw Monitor redefinition
  12. #include <multimon.h>
  13. extern GUID IID_IDDrawNonExclModeVideo = {
  14. 0xec70205c,0x45a3,0x4400,{0xa3,0x65,0xc4,0x47,0x65,0x78,0x45,0xc7}};
  15. /*****************************Private*Routine******************************\
  16. * UpdateCurrentMonitor
  17. *
  18. * Updates the "m_lpCurMonitor" global to match the specified DDraw GUID
  19. *
  20. * History:
  21. * Wed 11/17/1999 - StEstrop - Created
  22. *
  23. \**************************************************************************/
  24. HRESULT CMSWebDVD::UpdateCurrentMonitor(
  25. const AMDDRAWGUID* lpguid
  26. )
  27. {
  28. if (lpguid->lpGUID)
  29. {
  30. for (AMDDRAWMONITORINFO* lpCurMonitor = &m_lpInfo[0];
  31. lpCurMonitor < &m_lpInfo[m_dwNumDevices]; lpCurMonitor++)
  32. {
  33. if (lpCurMonitor->guid.lpGUID &&
  34. *lpCurMonitor->guid.lpGUID == *lpguid->lpGUID)
  35. {
  36. m_lpCurMonitor = lpCurMonitor;
  37. return S_OK;
  38. }
  39. }
  40. }
  41. else
  42. {
  43. for (AMDDRAWMONITORINFO* lpCurMonitor = &m_lpInfo[0];
  44. lpCurMonitor < &m_lpInfo[m_dwNumDevices]; lpCurMonitor++)
  45. {
  46. if (lpguid->lpGUID == lpCurMonitor->guid.lpGUID)
  47. {
  48. m_lpCurMonitor = lpCurMonitor;
  49. return S_OK;
  50. }
  51. }
  52. }
  53. return E_FAIL;
  54. }
  55. /******************************Public*Routine******************************\
  56. * DisplayChange
  57. *
  58. *
  59. *
  60. * History:
  61. * Sat 11/27/1999 - StEstrop - Created
  62. *
  63. \**************************************************************************/
  64. HRESULT
  65. CMSWebDVD::DisplayChange(
  66. HMONITOR hMon,
  67. const AMDDRAWGUID* lpguid
  68. )
  69. {
  70. HRESULT hr = E_FAIL;
  71. if(!m_pDvdGB){
  72. return(E_FAIL);
  73. }/* end of if statement */
  74. CDDrawDVD* pDDrawObj = new CDDrawDVD(this);
  75. if(NULL == pDDrawObj){
  76. return (E_OUTOFMEMORY);
  77. }/* end if statement */
  78. HWND hwnd;
  79. hr = GetUsableWindow(&hwnd);
  80. if(FAILED(hr)){
  81. delete pDDrawObj;
  82. return(hr);
  83. }/* end of if statement */
  84. hr = pDDrawObj->SetupDDraw(lpguid, hwnd);
  85. if (FAILED(hr))
  86. {
  87. delete pDDrawObj;
  88. return hr;
  89. }
  90. IDDrawNonExclModeVideo* pDDXMV;
  91. hr = m_pDvdGB->GetDvdInterface(IID_IDDrawNonExclModeVideo,
  92. (LPVOID *)&pDDXMV) ;
  93. if (FAILED(hr))
  94. {
  95. delete pDDrawObj;
  96. return hr;
  97. }
  98. LPDIRECTDRAW pDDObj = pDDrawObj->GetDDrawObj();
  99. LPDIRECTDRAWSURFACE pDDPrimary = pDDrawObj->GetDDrawSurf();
  100. hr = pDDXMV->SetCallbackInterface(NULL, 0) ;
  101. if (FAILED(hr)){
  102. pDDXMV->Release() ; // release before returning
  103. return hr;
  104. }/* end of if statement */
  105. hr = pDDXMV->DisplayModeChanged(hMon, pDDObj, pDDPrimary);
  106. if (SUCCEEDED(hr)) {
  107. delete m_pDDrawDVD;
  108. m_pDDrawDVD = pDDrawObj;
  109. hr = UpdateCurrentMonitor(lpguid);
  110. }
  111. else {
  112. delete pDDrawObj;
  113. }
  114. hr = pDDXMV->SetCallbackInterface(m_pDDrawDVD->GetCallbackInterface(), 0) ;
  115. if (SUCCEEDED(hr))
  116. {
  117. hr = SetColorKey(DEFAULT_COLOR_KEY);
  118. }/* end of it statement */
  119. pDDXMV->Release();
  120. return hr;
  121. }
  122. /******************************Public*Routine******************************\
  123. * ChangeMonitor
  124. *
  125. * Tells the OVMixer that we want to change to another monitor.
  126. *
  127. * History:
  128. * Wed 11/17/1999 - StEstrop - Created
  129. *
  130. \**************************************************************************/
  131. HRESULT
  132. CMSWebDVD::ChangeMonitor(
  133. HMONITOR hMon,
  134. const AMDDRAWGUID* lpguid
  135. )
  136. {
  137. HRESULT hr = E_FAIL;
  138. if(!m_pDvdGB){
  139. return(E_FAIL);
  140. }/* end of if statement */
  141. CDDrawDVD* pDDrawObj = new CDDrawDVD(this);
  142. if(NULL == pDDrawObj){
  143. return (E_OUTOFMEMORY);
  144. }/* end if statement */
  145. HWND hwnd;
  146. hr = GetUsableWindow(&hwnd);
  147. if(FAILED(hr)){
  148. delete pDDrawObj;
  149. return(hr);
  150. }/* end of if statement */
  151. hr = pDDrawObj->SetupDDraw(lpguid, hwnd);
  152. if (FAILED(hr))
  153. {
  154. delete pDDrawObj;
  155. return hr;
  156. }
  157. IDDrawNonExclModeVideo* pDDXMV;
  158. hr = m_pDvdGB->GetDvdInterface(IID_IDDrawNonExclModeVideo,
  159. (LPVOID *)&pDDXMV) ;
  160. if (FAILED(hr))
  161. {
  162. delete pDDrawObj;
  163. return hr;
  164. }
  165. LPDIRECTDRAW pDDObj = pDDrawObj->GetDDrawObj();
  166. LPDIRECTDRAWSURFACE pDDPrimary = pDDrawObj->GetDDrawSurf();
  167. hr = pDDXMV->SetCallbackInterface(NULL, 0) ;
  168. if (FAILED(hr)){
  169. pDDXMV->Release() ; // release before returning
  170. return hr;
  171. }/* end of if statement */
  172. hr = pDDXMV->ChangeMonitor(hMon, pDDObj, pDDPrimary);
  173. if (SUCCEEDED(hr)) {
  174. delete m_pDDrawDVD;
  175. m_pDDrawDVD = pDDrawObj;
  176. hr = UpdateCurrentMonitor(lpguid);
  177. }
  178. else {
  179. delete pDDrawObj;
  180. }
  181. hr = pDDXMV->SetCallbackInterface(m_pDDrawDVD->GetCallbackInterface(), 0) ;
  182. if (SUCCEEDED(hr))
  183. {
  184. hr = SetColorKey(DEFAULT_COLOR_KEY);
  185. }/* end of it statement */
  186. pDDXMV->Release();
  187. return hr;
  188. }
  189. /******************************Public*Routine******************************\
  190. * RestoreSurfaces
  191. *
  192. * Tells the OVMixer to restore its internal DDraw surfaces
  193. *
  194. * History:
  195. * Wed 11/17/1999 - StEstrop - Created
  196. *
  197. \**************************************************************************/
  198. HRESULT
  199. CMSWebDVD::RestoreSurfaces()
  200. {
  201. if(!m_pDvdGB){
  202. return(E_FAIL);
  203. }/* end of if statement */
  204. IDDrawNonExclModeVideo* pDDXMV;
  205. HRESULT hr = m_pDvdGB->GetDvdInterface(IID_IDDrawNonExclModeVideo,
  206. (LPVOID *)&pDDXMV) ;
  207. if (FAILED(hr))
  208. {
  209. return hr;
  210. }
  211. hr = pDDXMV->RestoreSurfaces();
  212. pDDXMV->Release();
  213. return hr;
  214. }
  215. /*************************************************************************/
  216. /* Function: RefreshDDrawGuids */
  217. /*************************************************************************/
  218. HRESULT CMSWebDVD::RefreshDDrawGuids()
  219. {
  220. IDDrawNonExclModeVideo* pDDXMV;
  221. if(!m_pDvdGB){
  222. return(E_FAIL);
  223. }/* end of if statement */
  224. HRESULT hr = m_pDvdGB->GetDvdInterface(IID_IDDrawNonExclModeVideo,
  225. (LPVOID *)&pDDXMV) ;
  226. if (FAILED(hr))
  227. {
  228. return hr;
  229. }
  230. GUID IID_IAMSpecifyDDrawConnectionDevice = {
  231. 0xc5265dba,0x3de3,0x4919,{0x94,0x0b,0x5a,0xc6,0x61,0xc8,0x2e,0xf4}};
  232. IAMSpecifyDDrawConnectionDevice* pSDDC;
  233. hr = pDDXMV->QueryInterface(IID_IAMSpecifyDDrawConnectionDevice, (LPVOID *)&pSDDC);
  234. if (FAILED(hr))
  235. {
  236. pDDXMV->Release();
  237. return hr;
  238. }
  239. DWORD dwNumDevices;
  240. AMDDRAWMONITORINFO* lpInfo;
  241. hr = pSDDC->GetDDrawGUIDs(&dwNumDevices, &lpInfo);
  242. if (SUCCEEDED(hr)) {
  243. CoTaskMemFree(m_lpInfo);
  244. m_lpCurMonitor = NULL;
  245. m_lpInfo = lpInfo;
  246. m_dwNumDevices = dwNumDevices;
  247. }
  248. pSDDC->Release();
  249. pDDXMV->Release();
  250. return hr;
  251. }/* end of function RefreshDDrawGuids */
  252. /*****************************Private*Routine******************************\
  253. * IsWindowOnWrongMonitor
  254. *
  255. * Use the same algorithm that the OVMixer uses to determine if we are on
  256. * the wrong monitor or not.
  257. *
  258. * If we are on the wrong monitor *lphMon contains the monitor handle of the
  259. * new monitor to use.
  260. *
  261. * History:
  262. * Wed 11/17/1999 - StEstrop - Created
  263. *
  264. \**************************************************************************/
  265. bool CMSWebDVD::IsWindowOnWrongMonitor(
  266. HMONITOR* lphMon)
  267. {
  268. if (!m_lpCurMonitor)
  269. {
  270. return false;
  271. }
  272. HWND hwnd;
  273. HRESULT hr = GetUsableWindow(&hwnd);
  274. if(FAILED(hr)){
  275. return(false);
  276. }/* end of if statement */
  277. RECT rc;
  278. hr = GetClientRectInScreen(&rc);
  279. if(FAILED(hr)){
  280. return(false);
  281. }/* end of if statement */
  282. *lphMon = m_lpCurMonitor->hMon;
  283. if (GetSystemMetrics(SM_CMONITORS) > 1 && !::IsIconic(hwnd))
  284. {
  285. LPRECT lprcMonitor = &m_lpCurMonitor->rcMonitor;
  286. if (rc.left < lprcMonitor->left || rc.right > lprcMonitor->right ||
  287. rc.top < lprcMonitor->top || rc.bottom > lprcMonitor->bottom)
  288. {
  289. HMONITOR hMon = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
  290. if (*lphMon != hMon)
  291. {
  292. *lphMon = hMon;
  293. return true;
  294. }
  295. }
  296. }
  297. return false;
  298. }
  299. /*****************************Private*Routine******************************\
  300. * DDrawGuidFromHMonitor
  301. *
  302. * Return the DDraw guid from the specified hMonitor handle.
  303. *
  304. * History:
  305. * Wed 11/17/1999 - StEstrop - Created
  306. *
  307. \**************************************************************************/
  308. HRESULT CMSWebDVD::DDrawGuidFromHMonitor(
  309. HMONITOR hMon,
  310. AMDDRAWGUID* lpGUID
  311. )
  312. {
  313. AMDDRAWMONITORINFO* lpCurMonitor = &m_lpInfo[0];
  314. #if 1
  315. if (m_dwNumDevices == 1) {
  316. *lpGUID = lpCurMonitor->guid;
  317. return S_OK;
  318. }
  319. #endif
  320. for (; lpCurMonitor < &m_lpInfo[m_dwNumDevices]; lpCurMonitor++)
  321. {
  322. if (lpCurMonitor->hMon == hMon) {
  323. *lpGUID = lpCurMonitor->guid;
  324. return S_OK;
  325. }
  326. }
  327. return E_FAIL;
  328. }
  329. struct MONITORDATA {
  330. HMONITOR hMonPB;
  331. BOOL fMsgShouldBeDrawn;
  332. };
  333. /*****************************Private*Routine******************************\
  334. * MonitorEnumProc
  335. *
  336. * On Multi-Monitor systems make sure that the part of the window that is not
  337. * on the primary monitor is black.
  338. *
  339. * History:
  340. * Thu 06/03/1999 - StEstrop - Created
  341. *
  342. \**************************************************************************/
  343. BOOL CALLBACK
  344. MonitorEnumProc(
  345. HMONITOR hMonitor, // handle to display monitor
  346. HDC hdc, // handle to monitor-appropriate device context
  347. LPRECT lprcMonitor, // pointer to monitor intersection rectangle
  348. LPARAM dwData // data passed from EnumDisplayMonitors
  349. )
  350. {
  351. MONITORDATA* lpmd = (MONITORDATA*)dwData;
  352. //COLORREF clrOld = GetBkColor(hdc);
  353. if (lpmd->hMonPB != hMonitor)
  354. {
  355. //SetBkColor(hdc, RGB(0,0,0));
  356. lpmd->fMsgShouldBeDrawn = TRUE;
  357. }
  358. else
  359. { // put your own color key here
  360. ;//SetBkColor(hdc, RGB(255,0,255));
  361. }
  362. //ExtTextOut(hdc, 0, 0, ETO_OPAQUE, lprcMonitor, NULL, 0, NULL);
  363. //SetBkColor(hdc, clrOld);
  364. return TRUE;
  365. }
  366. /*************************************************************************/
  367. /* Function: OnDispChange */
  368. /*************************************************************************/
  369. LRESULT CMSWebDVD::OnDispChange(UINT /* uMsg */, WPARAM wParam,
  370. LPARAM lParam, BOOL& bHandled){
  371. if(::IsWindow(m_hWnd)){
  372. bHandled = FALSE;
  373. return(0);
  374. //do not handle this in windowed mode
  375. }/* end of if statement */
  376. RECT rc;
  377. HRESULT hr = GetClientRectInScreen(&rc);
  378. if(FAILED(hr)){
  379. return(-1);
  380. }/* end of if statement */
  381. HMONITOR hMon = ::MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
  382. AMDDRAWGUID guid;
  383. hr = RefreshDDrawGuids();
  384. if(FAILED(hr)){
  385. return -1;
  386. }/* end of if statement */
  387. hr = DDrawGuidFromHMonitor(hMon, &guid);
  388. if(FAILED(hr)){
  389. return -1;
  390. }/* end of if statement */
  391. hr = DisplayChange(hMon, &guid);
  392. if(FAILED(hr)){
  393. return -1;
  394. }/* end of if statement */
  395. return 0;
  396. }/* end of function OnDispChange */
  397. /*************************************************************************/
  398. /* Function: HandleMultiMonMove */
  399. /* Description: Moves the playback to another monitor when needed. */
  400. /*************************************************************************/
  401. HRESULT CMSWebDVD::HandleMultiMonMove(){
  402. HRESULT hr = S_FALSE;
  403. if (::GetSystemMetrics(SM_CMONITORS) > 1){
  404. HMONITOR hMon;
  405. if (IsWindowOnWrongMonitor(&hMon)) {
  406. AMDDRAWGUID guid;
  407. hr = DDrawGuidFromHMonitor(hMon, &guid);
  408. if(FAILED(hr)){
  409. return(hr);
  410. }/* end of if statement */
  411. hr = ChangeMonitor(hMon, &guid);
  412. if(FAILED(hr)){
  413. m_MonitorWarn = TRUE;
  414. InvalidateRgn();
  415. return(hr);
  416. }/* end of if statement */
  417. }/* end of if statement */
  418. //
  419. // We always have to invalidate the windows client area, otherwise
  420. // we handle the Multi-Mon case very badly.
  421. //
  422. //::InvalidateRect(hWnd, NULL, FALSE);
  423. InvalidateRgn();
  424. return(hr);
  425. }/* end of if statement */
  426. return(hr);
  427. }/* end of function HandleMultiMonMove */
  428. /*************************************************************************/
  429. /* Function: HandleMultiMonPaint */
  430. /*************************************************************************/
  431. HRESULT CMSWebDVD::HandleMultiMonPaint(HDC hDC){
  432. if (::GetSystemMetrics(SM_CMONITORS) > 1){
  433. MONITORDATA md;
  434. md.hMonPB = m_lpCurMonitor ? m_lpCurMonitor->hMon : (HMONITOR)NULL;
  435. md.fMsgShouldBeDrawn = FALSE;
  436. RECT rc;
  437. HRESULT hr = GetClientRectInScreen(&rc);
  438. if(FAILED(hr)){
  439. return(hr);
  440. }/* end of if statement */
  441. //EnumDisplayMonitors(hDC, NULL, MonitorEnumProc, (LPARAM)&md);
  442. EnumDisplayMonitors(NULL, &rc, MonitorEnumProc, (LPARAM)&md);
  443. if (m_MonitorWarn && md.fMsgShouldBeDrawn){
  444. TCHAR strBuffer[MAX_PATH];
  445. if(!::LoadString(_Module.m_hInstResource, IDS_MOVE_TO_OTHER_MON, strBuffer, MAX_PATH)){
  446. return(E_UNEXPECTED);
  447. }/* end of if statement */
  448. SetBkColor(hDC, RGB(0,0,0));
  449. SetTextColor(hDC, RGB(255,255,0));
  450. if(FAILED(hr)){
  451. return(hr);
  452. }/* end of if statement */
  453. DrawText(hDC, strBuffer, -1, &m_rcPos, DT_CENTER | DT_WORDBREAK);
  454. }/* end of if statement */
  455. return(S_OK);
  456. }/* end of if statement */
  457. return(S_FALSE);
  458. }/* end of function HandleMultiMonPaint */
  459. /*************************************************************************/
  460. /* Function: InvalidateRgn */
  461. /* Description: Invalidates the whole rect in case we need to repaint it.*/
  462. /*************************************************************************/
  463. HRESULT CMSWebDVD::InvalidateRgn(bool fErase){
  464. HRESULT hr = S_OK;
  465. if(m_bWndLess){
  466. m_spInPlaceSite->InvalidateRgn(NULL ,fErase ? TRUE: FALSE);
  467. }
  468. else {
  469. if(NULL == m_hWnd){
  470. hr = E_FAIL;
  471. return(hr);
  472. }/* end of if statement */
  473. if(::IsWindow(m_hWnd)){
  474. ::InvalidateRgn(m_hWnd, NULL, fErase ? TRUE: FALSE); // see if we can get by by not erasing..
  475. }
  476. else {
  477. hr = E_UNEXPECTED;
  478. }/* end of if statement */
  479. }/* end of if statement */
  480. return(hr);
  481. }/* end of function InvalidateRgn */
  482. /*************************************************************************/
  483. /* End of file: monitor.cpp */
  484. /*************************************************************************/