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.

890 lines
23 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1998 Microsoft Corporation
  4. *
  5. * Abstract:
  6. *
  7. * Handle all the device associations.
  8. *
  9. * Revision History:
  10. *
  11. * 12/03/1998 andrewgo
  12. * Created it.
  13. *
  14. \**************************************************************************/
  15. #include "precomp.hpp"
  16. #include "compatibledib.hpp"
  17. BOOL gbUseD3DHAL = TRUE;
  18. /**************************************************************************\
  19. *
  20. * Function Description:
  21. *
  22. * Creates a GpDevice class that represents the (meta) desktop.
  23. *
  24. * Arguments:
  25. *
  26. * [IN] hdc - Owned DC representing the device. Note that this has to
  27. * live for the lifetime of this 'GpDevice' object. Caller
  28. * is responsible for deletion or management of the HDC.
  29. *
  30. * Return Value:
  31. *
  32. * IsValid() is FALSE in the event of failure.
  33. *
  34. * History:
  35. *
  36. * 12/04/1998 andrewgo
  37. * Created it.
  38. *
  39. \**************************************************************************/
  40. GpDevice::GpDevice(
  41. HDC hdc
  42. )
  43. {
  44. hMonitor = NULL;
  45. Buffers[0] = NULL;
  46. __try
  47. {
  48. DeviceLock.Initialize();
  49. }
  50. __except(EXCEPTION_EXECUTE_HANDLER)
  51. {
  52. // We couldn't allocate the criticalSection
  53. // Return an error
  54. WARNING(("Unable to allocate the DeviceLock"));
  55. SetValid(FALSE);
  56. return;
  57. }
  58. DeviceHdc = hdc;
  59. BufferWidth = 0;
  60. DIBSectionBitmap = NULL;
  61. DIBSection = NULL;
  62. ScanDci = NULL;
  63. pdd = NULL;
  64. pd3d = NULL;
  65. pdds = NULL;
  66. pd3dDevice = NULL;
  67. DIBSectionHdc = CreateCompatibleDC(hdc);
  68. if ((GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) &&
  69. (GetDeviceCaps(hdc, BITSPIXEL) <= 8))
  70. {
  71. // Query and cache color palette
  72. // !!! [agodfrey] This is hard to maintain. We have much the same
  73. // palette code spread all over the place. It should be abstracted
  74. // into a single location. I've marked each instance with
  75. // <SystemPalette>.
  76. Palette = (ColorPalette*) GpMalloc(sizeof(ColorPalette) + sizeof(ARGB)*256);
  77. if (Palette == NULL)
  78. {
  79. WARNING(("Unable to allocate color palette"));
  80. SetValid(FALSE);
  81. return;
  82. }
  83. INT i;
  84. INT numEntries;
  85. PALETTEENTRY palEntry[256];
  86. // [agodfrey] On Win9x, GetSystemPaletteEntries(hdc, 0, 256, NULL)
  87. // doesn't do what MSDN says it does. It seems to return the number
  88. // of entries in the logical palette of the DC instead. So we have
  89. // to make it up ourselves.
  90. numEntries = (1 << (GetDeviceCaps(hdc, BITSPIXEL) *
  91. GetDeviceCaps(hdc, PLANES)));
  92. ASSERT(numEntries <= 256);
  93. GetSystemPaletteEntries(hdc, 0, numEntries, &palEntry[0]);
  94. Palette->Count = numEntries;
  95. for (i=0; i<numEntries; i++)
  96. {
  97. Palette->Entries[i] = Color::MakeARGB(0xFF,
  98. palEntry[i].peRed,
  99. palEntry[i].peGreen,
  100. palEntry[i].peBlue);
  101. }
  102. }
  103. else
  104. {
  105. Palette = NULL;
  106. }
  107. ScreenOffsetX = 0;
  108. ScreenOffsetY = 0;
  109. ScreenWidth = GetDeviceCaps(hdc, HORZRES);
  110. ScreenHeight = GetDeviceCaps(hdc, VERTRES);
  111. ScanDci = new EpScanGdiDci(this, TRUE);
  112. ScanGdi = new EpScanGdiDci(this);
  113. SetValid((ScanDci != NULL) && (ScanGdi != NULL) && (DIBSectionHdc != NULL));
  114. }
  115. /**************************************************************************\
  116. *
  117. * Function Description:
  118. *
  119. * Creates a GpDevice class that represents a device associated with
  120. * a particular monitor on the desktop.
  121. *
  122. * Arguments:
  123. *
  124. * [IN] hMonitor - Identifies the monitor on the system.
  125. *
  126. * Return Value:
  127. *
  128. * IsValid() is FALSE in the event of failure.
  129. *
  130. * History:
  131. *
  132. * 10/13/1999 bhouse
  133. * Created it.
  134. *
  135. \**************************************************************************/
  136. GpDevice::GpDevice(
  137. HMONITOR inMonitor
  138. )
  139. {
  140. hMonitor = NULL;
  141. Buffers[0] = NULL;
  142. MONITORINFOEXA mi;
  143. mi.cbSize = sizeof(mi);
  144. DIBSectionBitmap = NULL;
  145. DIBSection = NULL;
  146. ScanDci = NULL;
  147. ScanGdi = NULL;
  148. pdd = NULL;
  149. pd3d = NULL;
  150. pdds = NULL;
  151. pd3dDevice = NULL;
  152. DIBSectionHdc = NULL;
  153. Palette = NULL;
  154. __try
  155. {
  156. DeviceLock.Initialize();
  157. }
  158. __except(EXCEPTION_EXECUTE_HANDLER)
  159. {
  160. // We couldn't allocate the criticalSection
  161. // Return an error
  162. WARNING(("Unable to allocate the DeviceLock"));
  163. SetValid(FALSE);
  164. return;
  165. }
  166. SetValid(FALSE);
  167. if(Globals::GetMonitorInfoFunction == NULL)
  168. {
  169. WARNING(("GpDevice with HMONITOR called with no multi-monitor support"));
  170. }
  171. else if(Globals::GetMonitorInfoFunction(inMonitor, &mi))
  172. {
  173. HDC hdc;
  174. if (Globals::IsNt)
  175. {
  176. hdc = CreateDCA("Display", mi.szDevice, NULL, NULL);
  177. }
  178. else
  179. {
  180. hdc = CreateDCA(NULL, mi.szDevice, NULL, NULL);
  181. }
  182. // Note: because we created the hdc, the ~GpDevice destructor is
  183. // responsible for for its deletion. We currently recognize this
  184. // case by a non-NULL hMonitor.
  185. if(hdc != NULL)
  186. {
  187. hMonitor = inMonitor;
  188. DeviceHdc = hdc;
  189. BufferWidth = 0;
  190. DIBSectionHdc = CreateCompatibleDC(hdc);
  191. if ((GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) &&
  192. (GetDeviceCaps(hdc, BITSPIXEL) <= 8))
  193. {
  194. // Query and cache color palette
  195. // <SystemPalette>
  196. Palette = (ColorPalette*) GpMalloc(sizeof(ColorPalette) + sizeof(ARGB)*256);
  197. if (Palette == NULL)
  198. {
  199. WARNING(("Unable to allocate color palette"));
  200. return;
  201. }
  202. INT i;
  203. INT numEntries;
  204. PALETTEENTRY palEntry[256];
  205. // [agodfrey] On Win9x, GetSystemPaletteEntries(hdc, 0, 256, NULL)
  206. // doesn't do what MSDN says it does. It seems to return the number
  207. // of entries in the logical palette of the DC instead. So we have
  208. // to make it up ourselves.
  209. numEntries = (1 << (GetDeviceCaps(hdc, BITSPIXEL) *
  210. GetDeviceCaps(hdc, PLANES)));
  211. ASSERT(numEntries <= 256);
  212. GetSystemPaletteEntries(hdc, 0, numEntries, &palEntry[0]);
  213. Palette->Count = numEntries;
  214. for (i=0; i<numEntries; i++)
  215. {
  216. Palette->Entries[i] = Color::MakeARGB(0xFF,
  217. palEntry[i].peRed,
  218. palEntry[i].peGreen,
  219. palEntry[i].peBlue);
  220. }
  221. }
  222. ScreenOffsetX = mi.rcMonitor.left;
  223. ScreenOffsetY = mi.rcMonitor.top;
  224. ScreenWidth = (mi.rcMonitor.right - mi.rcMonitor.left);
  225. ScreenHeight = (mi.rcMonitor.bottom - mi.rcMonitor.top);
  226. ScanDci = new EpScanGdiDci(this, TRUE);
  227. ScanGdi = new EpScanGdiDci(this);
  228. #if HW_ACCELERATION_SUPPORT
  229. if(InitializeDirectDrawGlobals())
  230. {
  231. HRESULT hr = Globals::DirectDrawEnumerateExFunction(
  232. GpDevice::EnumDirectDrawCallback,
  233. this,
  234. DDENUM_ATTACHEDSECONDARYDEVICES);
  235. if(pdd == NULL)
  236. {
  237. // This could happen if this is a single monitor
  238. // machine. Try again to create the DirectDraw Object.
  239. hr = Globals::DirectDrawCreateExFunction(NULL,
  240. &pdd,
  241. IID_IDirectDraw7,
  242. NULL);
  243. if(hr != DD_OK)
  244. {
  245. WARNING(("Unable to create monitor Direct Draw interface"));
  246. }
  247. hr = pdd->SetCooperativeLevel(NULL, DDSCL_NORMAL);
  248. if(hr != DD_OK)
  249. {
  250. WARNING(("Unable to set cooperative level for monitor device"));
  251. pdd->Release();
  252. pdd = NULL;
  253. }
  254. }
  255. if(pdd != NULL)
  256. {
  257. DDSURFACEDESC2 sd;
  258. memset(&sd, 0, sizeof(sd));
  259. sd.dwSize = sizeof(sd);
  260. sd.dwFlags = DDSD_CAPS;
  261. sd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
  262. hr = pdd->CreateSurface(&sd, &pdds, NULL);
  263. if(hr != DD_OK)
  264. {
  265. WARNING(("Unable to create primary surface for monitor"));
  266. }
  267. hr = pdd->QueryInterface(IID_IDirect3D7, (void **) &pd3d);
  268. if(hr != DD_OK)
  269. {
  270. WARNING(("Unable to get monitor D3D interface"));
  271. }
  272. if(pd3d != NULL && pdds != NULL)
  273. {
  274. if(gbUseD3DHAL)
  275. hr = pd3d->CreateDevice(IID_IDirect3DHALDevice, pdds, &pd3dDevice);
  276. else
  277. hr = pd3d->CreateDevice(IID_IDirect3DRGBDevice, pdds, &pd3dDevice);
  278. if(hr != DD_OK)
  279. {
  280. WARNING(("Unable to create D3D device"));
  281. }
  282. if(pd3dDevice != NULL)
  283. {
  284. pddsRenderTarget = pdds;
  285. hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, 0);
  286. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0);
  287. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT);
  288. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, FALSE);
  289. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
  290. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
  291. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE);
  292. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
  293. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
  294. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
  295. if(hr == DD_OK) hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_TEXTUREPERSPECTIVE, FALSE);
  296. // Setup viewport
  297. D3DVIEWPORT7 viewData;
  298. viewData.dwX = 0;
  299. viewData.dwY = 0;
  300. viewData.dwWidth = ScreenWidth;
  301. viewData.dwHeight = ScreenHeight;
  302. viewData.dvMinZ = 0.0f;
  303. viewData.dvMaxZ = 1.0f;
  304. if(hr == DD_OK) hr = pd3dDevice->SetViewport(&viewData);
  305. if(hr != DD_OK)
  306. {
  307. WARNING(("Failed setting default D3D state"));
  308. pd3d->Release();
  309. pd3d = NULL;
  310. }
  311. }
  312. }
  313. }
  314. }
  315. #endif // HW_ACCELERATION_SUPPORT
  316. SetValid((ScanDci != NULL) && (ScanGdi != NULL) && (DIBSectionHdc != NULL));
  317. }
  318. else
  319. {
  320. WARNING(("Failed creating HDC from HMONITOR"));
  321. }
  322. }
  323. }
  324. /**************************************************************************\
  325. *
  326. * Function Description:
  327. *
  328. * Callback function used to D3D Device Enumeration
  329. *
  330. * Arguments:
  331. *
  332. * See D3D SDK
  333. *
  334. * Return Value:
  335. *
  336. * See D3D SDK
  337. *
  338. * History:
  339. *
  340. * 10/11/1999 bhouse
  341. * Created it.
  342. *
  343. \**************************************************************************/
  344. BOOL GpDevice::EnumDirectDrawCallback(
  345. GUID * lpGUID,
  346. LPSTR lpDriverDescription,
  347. LPSTR lpDriverName,
  348. LPVOID lpContext,
  349. HMONITOR hMonitor)
  350. {
  351. GpDevice * device = (GpDevice *) lpContext;
  352. if(device->hMonitor == hMonitor && lpGUID)
  353. {
  354. HRESULT hr = Globals::DirectDrawCreateExFunction(lpGUID,
  355. &device->pdd,
  356. IID_IDirectDraw7,
  357. NULL);
  358. if(hr != DD_OK)
  359. {
  360. WARNING(("Unable to create monitor Direct Draw interface"));
  361. }
  362. hr = device->pdd->SetCooperativeLevel(NULL, DDSCL_NORMAL);
  363. if(hr != DD_OK)
  364. {
  365. WARNING(("Unable to set cooperative level for monitor device"));
  366. device->pdd->Release();
  367. device->pdd = NULL;
  368. }
  369. return(FALSE);
  370. }
  371. return(TRUE);
  372. }
  373. /**************************************************************************\
  374. *
  375. * Function Description:
  376. *
  377. * Destroys a GpDevice class.
  378. *
  379. * Arguments:
  380. *
  381. * None
  382. *
  383. * Return Value:
  384. *
  385. * NONE
  386. *
  387. * History:
  388. *
  389. * 12/04/1998 andrewgo
  390. * Created it.
  391. *
  392. \**************************************************************************/
  393. GpDevice::~GpDevice(
  394. VOID
  395. )
  396. {
  397. DeviceLock.Uninitialize();
  398. #if 0
  399. // !!!TODO: Find out why we are getting an access fault when we try and
  400. // release the pd3d7 interface
  401. if(pd3dDevice != NULL)
  402. pd3dDevice->Release();
  403. if(pd3d != NULL)
  404. pd3d->Release();
  405. #endif
  406. if(pdds != NULL)
  407. pdds->Release();
  408. if(pdd != NULL)
  409. pdd->Release();
  410. DeleteObject(DIBSectionBitmap);
  411. DeleteDC(DIBSectionHdc);
  412. if (hMonitor != NULL)
  413. {
  414. // If GpDevice was created by the GpDevice(HMONITOR) contructor,
  415. // then the HDC was created by the object. Therefore, in that case
  416. // the destructor is responsible for deletion.
  417. if (DeviceHdc != NULL)
  418. {
  419. DeleteDC(DeviceHdc);
  420. }
  421. }
  422. GpFree(Buffers[0]);
  423. GpFree(Palette);
  424. delete ScanDci;
  425. delete ScanGdi;
  426. SetValid(FALSE); // so we don't use a deleted object
  427. }
  428. /**************************************************************************\
  429. *
  430. * Function Description:
  431. *
  432. * Returns 5 scan buffers of a specified width, from a cache in
  433. * the device.
  434. *
  435. * One is a DIBSection which is compatible with the device (or 8bpp if
  436. * the device format is smaller than 8bpp.)
  437. *
  438. * Arguments:
  439. *
  440. * [IN] width - Specifies the requested width in pixels
  441. * [OUT] [OPTIONAL] dibSection - Returns the pointer to the DIBSection
  442. * [OUT] [OPTIONAL] hdcDibSection - Returns an HDC to the DIBSection
  443. * [OUT] [OPTIONAL] dstFormat - Returns the format of the DIBSection.
  444. * [OUT] [OPTIONAL] buffers - Returns an array of 5 pointers to
  445. * buffers, each big enough to hold <width> pixels in 64bpp.
  446. *
  447. * Return Value:
  448. *
  449. * FALSE if there was an allocation error.
  450. *
  451. * History:
  452. *
  453. * 12/04/1998 andrewgo
  454. * Created it.
  455. * 01/21/2000 agodfrey
  456. * Changed it to create just 1 DIBSection, and 4 memory buffers.
  457. *
  458. \**************************************************************************/
  459. BOOL
  460. GpDevice::GetScanBuffers(
  461. INT width,
  462. VOID **dibSection,
  463. HDC *hdcDibSection,
  464. PixelFormatID *dstFormat,
  465. VOID *buffers[5]
  466. )
  467. {
  468. // If BufferWidth is 0 this means that the DIBSectionBitmap should be
  469. // recreated. This is used, for instance, when switching bit depths
  470. // to a palettized format.
  471. if (width > BufferWidth)
  472. {
  473. if (DIBSectionBitmap != NULL)
  474. {
  475. DeleteObject(DIBSectionBitmap);
  476. }
  477. DIBSectionBitmap = CreateSemiCompatibleDIB(
  478. DeviceHdc,
  479. width,
  480. 1,
  481. Palette,
  482. &DIBSection,
  483. &BufferFormat);
  484. if (DIBSectionBitmap)
  485. {
  486. BufferWidth = width;
  487. SelectObject(DIBSectionHdc, DIBSectionBitmap);
  488. }
  489. else
  490. {
  491. BufferWidth = 0;
  492. }
  493. // Allocate the 5 memory buffers from one chunk.
  494. if (Buffers[0])
  495. {
  496. GpFree(Buffers[0]);
  497. }
  498. Buffers[0] = GpMalloc(sizeof(ARGB64) * width * 5);
  499. if (Buffers[0])
  500. {
  501. int i;
  502. for (i=1;i<5;i++)
  503. {
  504. Buffers[i] = static_cast<BYTE *>(Buffers[i-1]) +
  505. sizeof(ARGB64) * width;
  506. }
  507. }
  508. else
  509. {
  510. BufferWidth = 0;
  511. }
  512. }
  513. if (dibSection != NULL)
  514. {
  515. *dibSection = DIBSection;
  516. }
  517. if (hdcDibSection != NULL)
  518. {
  519. *hdcDibSection = DIBSectionHdc;
  520. }
  521. if (buffers != NULL)
  522. {
  523. int i;
  524. for (i=0;i<5;i++)
  525. {
  526. buffers[i] = Buffers[i];
  527. }
  528. }
  529. if (dstFormat != NULL)
  530. {
  531. *dstFormat = BufferFormat;
  532. }
  533. return(BufferWidth != 0);
  534. }
  535. /**************************************************************************\
  536. *
  537. * Function Description:
  538. *
  539. * Constructor of GpDeviceList
  540. *
  541. * Arguments:
  542. *
  543. * NONE
  544. *
  545. * Return Value:
  546. *
  547. * NONE
  548. *
  549. * History:
  550. *
  551. * 10/08/1999 bhouse
  552. * Created it.
  553. *
  554. \**************************************************************************/
  555. GpDeviceList::GpDeviceList()
  556. {
  557. mNumDevices = 0;
  558. mDevices = NULL;
  559. }
  560. /**************************************************************************\
  561. *
  562. * Function Description:
  563. *
  564. * Destructor of GpDeviceList
  565. *
  566. * Arguments:
  567. *
  568. * NONE
  569. *
  570. * Return Value:
  571. *
  572. * NONE
  573. *
  574. * History:
  575. *
  576. * 10/08/1999 bhouse
  577. * Created it.
  578. *
  579. \**************************************************************************/
  580. GpDeviceList::~GpDeviceList()
  581. {
  582. GpFree(mDevices);
  583. }
  584. /**************************************************************************\
  585. *
  586. * Function Description:
  587. *
  588. * Add device to device list.
  589. *
  590. * Arguments:
  591. *
  592. * inDevice - device to add
  593. *
  594. * Return Value:
  595. *
  596. * Ok if device was successfully added otherwise OutOfMemory
  597. *
  598. * History:
  599. *
  600. * 10/08/1999 bhouse
  601. * Created it.
  602. *
  603. \**************************************************************************/
  604. GpStatus GpDeviceList::AddDevice(GpDevice * inDevice)
  605. {
  606. GpDevice ** newList = (GpDevice **) GpMalloc((mNumDevices + 1) * sizeof(GpDevice *));
  607. if(newList == NULL)
  608. return OutOfMemory;
  609. memcpy(newList, mDevices, (mNumDevices * sizeof(GpDevice *)));
  610. newList[mNumDevices++] = inDevice;
  611. GpFree(mDevices);
  612. mDevices = newList;
  613. return Ok;
  614. }
  615. /**************************************************************************\
  616. *
  617. * Function Description:
  618. *
  619. * Add device to device list.
  620. *
  621. * Arguments:
  622. *
  623. * inSurface - surface for which we need to find matching D3DDevice
  624. *
  625. * Return Value:
  626. *
  627. * GpDevice if found otherwise NULL
  628. *
  629. * History:
  630. *
  631. * 10/08/1999 bhouse
  632. * Created it.
  633. *
  634. \**************************************************************************/
  635. GpDevice * GpDeviceList::FindD3DDevice(IDirectDrawSurface7 * inSurface)
  636. {
  637. HRESULT hr;
  638. IUnknown * unknown;
  639. hr = inSurface->GetDDInterface((void **) &unknown);
  640. if(hr != DD_OK)
  641. return NULL;
  642. IDirectDraw7 * pddMatch;
  643. hr = unknown->QueryInterface(IID_IDirectDraw7, (void **) &pddMatch);
  644. if(hr != DD_OK)
  645. return NULL;
  646. #if 0
  647. IDirect3D7 * pd3dMatch;
  648. hr = pddMatch->QueryInterface(IID_IDirect3D7, (void **) &pd3dMatch);
  649. if(hr != DD_OK)
  650. {
  651. pddMatch->Release();
  652. return NULL;
  653. }
  654. GpDevice * device = NULL;
  655. for(INT i = 0; i < mNumDevices; i++)
  656. {
  657. if(mDevices[i]->pd3d == pd3dMatch)
  658. {
  659. device = mDevices[i];
  660. break;
  661. }
  662. }
  663. pd3dMatch->Release();
  664. #else
  665. GpDevice * device = NULL;
  666. for(INT i = 0; i < mNumDevices; i++)
  667. {
  668. if(mDevices[i]->pdd == pddMatch)
  669. {
  670. device = mDevices[i];
  671. break;
  672. }
  673. }
  674. #endif
  675. pddMatch->Release();
  676. return device;
  677. }
  678. #if 0
  679. /**************************************************************************\
  680. *
  681. * Function Description:
  682. *
  683. * Callback function used to D3D Device Enumeration
  684. *
  685. * Arguments:
  686. *
  687. * See D3D SDK
  688. *
  689. * Return Value:
  690. *
  691. * See D3D SDK
  692. *
  693. * History:
  694. *
  695. * 10/11/1999 bhouse
  696. * Created it.
  697. *
  698. \**************************************************************************/
  699. HRESULT GpDeviceList::EnumD3DDevicesCallback(
  700. LPSTR lpDevDesc,
  701. LPSTR lpDevName,
  702. LPD3DDEVICEDESC7 * d3dDevDesc,
  703. LPVOID lpContext)
  704. {
  705. GpDeviceList * devList = (GpDeviceList *) lpContext;
  706. }
  707. /**************************************************************************\
  708. *
  709. * Function Description:
  710. *
  711. * Build a device list.
  712. *
  713. * Arguments:
  714. *
  715. * NONE
  716. *
  717. * Return Value:
  718. *
  719. * NONE
  720. *
  721. * History:
  722. *
  723. * 10/08/1999 bhouse
  724. * Created it.
  725. *
  726. \**************************************************************************/
  727. void GpDeviceList::Build(void)
  728. {
  729. if(!InitializeDirectDrawGlobals())
  730. return;
  731. HRESULT hr;
  732. hr = Globals::Direct3D->EnumDevices(EnumD3DDevicesCallback, this);
  733. }
  734. #endif