Source code of Windows XP (NT5)
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.

815 lines
20 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: ddraw4obj.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // dDrawObj.cpp : Implementation of CDirectApp and DLL registration.
  11. #include "stdafx.h"
  12. #include "Direct.h"
  13. #include "dms.h"
  14. #include "DDraw4Obj.h"
  15. #include "ddClipperObj.h"
  16. #include "ddSurface4Obj.h"
  17. #include "ddPaletteObj.h"
  18. #include "ddEnumModesObj.h"
  19. #include "ddEnumSurfacesObj.h"
  20. #include "d3d7Obj.h"
  21. extern BOOL is4Bit;
  22. extern HRESULT CopyInDDSurfaceDesc2(DDSURFACEDESC2 *,DDSurfaceDesc2*);
  23. extern HRESULT CopyOutDDSurfaceDesc2(DDSurfaceDesc2*,DDSURFACEDESC2 *);
  24. ///////////////////////////////////////////////////////////////////
  25. // InternalAddRef
  26. ///////////////////////////////////////////////////////////////////
  27. DWORD C_dxj_DirectDraw4Object::InternalAddRef(){
  28. DWORD i;
  29. i=CComObjectRoot::InternalAddRef();
  30. DPF2(1,"DDraw4 [%d] AddRef %d \n",creationid,i);
  31. return i;
  32. }
  33. ///////////////////////////////////////////////////////////////////
  34. // InternalRelease
  35. ///////////////////////////////////////////////////////////////////
  36. DWORD C_dxj_DirectDraw4Object::InternalRelease(){
  37. DWORD i;
  38. i=CComObjectRoot::InternalRelease();
  39. DPF2(1,"DDraw4 [%d] Release %d \n",creationid,i);
  40. return i;
  41. }
  42. ///////////////////////////////////////////////////////////////////
  43. // C_dxj_DirectDraw4Object
  44. ///////////////////////////////////////////////////////////////////
  45. C_dxj_DirectDraw4Object::C_dxj_DirectDraw4Object(){
  46. DPF1(1,"Constructor Creation DirectDraw4Object[%d] \n ",g_creationcount);
  47. m__dxj_DirectDraw4= NULL;
  48. parent = NULL;
  49. pinterface = NULL;
  50. nextobj = g_dxj_DirectDraw4;
  51. creationid = ++g_creationcount;
  52. g_dxj_DirectDraw4 = (void *)this;
  53. m_hwnd=NULL;
  54. }
  55. ///////////////////////////////////////////////////////////////////
  56. // ~C_dxj_DirectDraw4Object
  57. ///////////////////////////////////////////////////////////////////
  58. C_dxj_DirectDraw4Object::~C_dxj_DirectDraw4Object()
  59. {
  60. DPF(1,"Entering ~DirectDraw4Object destructor \n");
  61. C_dxj_DirectDraw4Object *prev=NULL;
  62. for(C_dxj_DirectDraw4Object *ptr=(C_dxj_DirectDraw4Object *)g_dxj_DirectDraw4; ptr; ptr=(C_dxj_DirectDraw4Object *)ptr->nextobj)
  63. {
  64. if(ptr == this)
  65. {
  66. if(prev)
  67. prev->nextobj = ptr->nextobj;
  68. else
  69. g_dxj_DirectDraw4 = (void*)ptr->nextobj;
  70. DPF(1," DirectDraw4Object found in g_dxj list now removed\n");
  71. break;
  72. }
  73. prev = ptr;
  74. }
  75. if(m__dxj_DirectDraw4){
  76. int count = IUNK(m__dxj_DirectDraw4)->Release();
  77. DPF1(1,"DirectX IDirectDraw4 Ref count [%d] \n",count);
  78. if(count==0) m__dxj_DirectDraw4 = NULL;
  79. }
  80. if(parent) IUNK(parent)->Release();
  81. }
  82. ///////////////////////////////////////////////////////////////////
  83. // InternalGetObject
  84. // InternalSetObject
  85. // restoreDisplayMode
  86. // flipToGDISurface
  87. // setDisplayMode
  88. ///////////////////////////////////////////////////////////////////
  89. GETSET_OBJECT(_dxj_DirectDraw4);
  90. PASS_THROUGH_R(_dxj_DirectDraw4, restoreDisplayMode, RestoreDisplayMode)
  91. PASS_THROUGH_R(_dxj_DirectDraw4, flipToGDISurface, FlipToGDISurface)
  92. PASS_THROUGH5_R(_dxj_DirectDraw4, setDisplayMode, SetDisplayMode, long,long,long,long,long)
  93. ///////////////////////////////////////////////////////////////////
  94. // getMonitorFrequency
  95. ///////////////////////////////////////////////////////////////////
  96. STDMETHODIMP C_dxj_DirectDraw4Object::getMonitorFrequency(long *ret)
  97. {
  98. HRESULT hr;
  99. hr=m__dxj_DirectDraw4->GetMonitorFrequency((DWORD*)ret);
  100. return hr;
  101. }
  102. ///////////////////////////////////////////////////////////////////
  103. // getGDISurface
  104. ///////////////////////////////////////////////////////////////////
  105. STDMETHODIMP C_dxj_DirectDraw4Object::getGDISurface(I_dxj_DirectDrawSurface4 **rv)
  106. {
  107. LPDIRECTDRAWSURFACE4 lp4=NULL;
  108. if ( is4Bit )
  109. return E_FAIL;
  110. *rv = NULL;
  111. HRESULT hr = DD_OK;
  112. if( ( hr=m__dxj_DirectDraw4->GetGDISurface(&lp4) ) != DD_OK)
  113. return hr;
  114. INTERNAL_CREATE(_dxj_DirectDrawSurface4, lp4, rv);
  115. return hr;
  116. }
  117. ///////////////////////////////////////////////////////////////////
  118. // getVerticalBlankStatus
  119. ///////////////////////////////////////////////////////////////////
  120. STDMETHODIMP C_dxj_DirectDraw4Object::getVerticalBlankStatus( long *status)
  121. {
  122. if ( is4Bit )
  123. return E_FAIL;
  124. return m__dxj_DirectDraw4->GetVerticalBlankStatus((int *)status);
  125. }
  126. ///////////////////////////////////////////////////////////////////
  127. // setCooperativeLevel
  128. ///////////////////////////////////////////////////////////////////
  129. STDMETHODIMP C_dxj_DirectDraw4Object::setCooperativeLevel( HWnd hwn, long flags)
  130. {
  131. if ( is4Bit )
  132. return E_FAIL;
  133. m_hwnd = (HWND)hwn;
  134. return m__dxj_DirectDraw4->SetCooperativeLevel((HWND)hwn, (DWORD)flags);
  135. }
  136. ///////////////////////////////////////////////////////////////////
  137. // waitForVerticalBlank
  138. ///////////////////////////////////////////////////////////////////
  139. STDMETHODIMP C_dxj_DirectDraw4Object::waitForVerticalBlank(long flags,long handle, long *status)
  140. {
  141. if ( is4Bit )
  142. return E_FAIL;
  143. *status = m__dxj_DirectDraw4->WaitForVerticalBlank(flags, (void *)handle);
  144. return S_OK;
  145. }
  146. ///////////////////////////////////////////////////////////////////
  147. // createClipper
  148. ///////////////////////////////////////////////////////////////////
  149. STDMETHODIMP C_dxj_DirectDraw4Object::createClipper(long flags, I_dxj_DirectDrawClipper **val)
  150. {
  151. if ( is4Bit )
  152. return E_FAIL;
  153. DPF1(1,"enter DDraw4[%d]::createClipper ",creationid);
  154. //
  155. // need to create one of MY surfaces!
  156. //
  157. LPDIRECTDRAWCLIPPER ddc;
  158. HRESULT hr = DD_OK;
  159. if( (hr=m__dxj_DirectDraw4->CreateClipper( flags, &ddc, NULL)) != DD_OK )
  160. return hr;
  161. INTERNAL_CREATE(_dxj_DirectDrawClipper, ddc, val);
  162. DPF1(1,"exit DDraw4[%d]::createClipper ",creationid);
  163. return hr;
  164. }
  165. ///////////////////////////////////////////////////////////////////
  166. // createPalette
  167. ///////////////////////////////////////////////////////////////////
  168. STDMETHODIMP C_dxj_DirectDraw4Object::createPalette(long flags, SAFEARRAY **pe, I_dxj_DirectDrawPalette **val)
  169. {
  170. LPPALETTEENTRY ppe;
  171. if ( is4Bit )
  172. return E_FAIL;
  173. if (!ISSAFEARRAY1D(pe,(DWORD)256)) return E_INVALIDARG;
  174. ppe = (LPPALETTEENTRY)((SAFEARRAY*)*pe)->pvData;
  175. LPDIRECTDRAWPALETTE ddp;
  176. HRESULT hr = DD_OK;
  177. *val = NULL;
  178. if( (hr=m__dxj_DirectDraw4->CreatePalette( flags, (LPPALETTEENTRY)ppe, &ddp, NULL)) == DD_OK )
  179. {
  180. INTERNAL_CREATE( _dxj_DirectDrawPalette, ddp, val);
  181. }
  182. return hr;
  183. }
  184. ///////////////////////////////////////////////////////////////////
  185. // createSurface
  186. ///////////////////////////////////////////////////////////////////
  187. STDMETHODIMP C_dxj_DirectDraw4Object::createSurface(DDSurfaceDesc2 *dd, I_dxj_DirectDrawSurface4 **retval)
  188. {
  189. HRESULT retv;
  190. LPDIRECTDRAWSURFACE4 dds4; // DirectX object pointer
  191. DDSURFACEDESC2 ddsd;
  192. DPF1(1,"enter DDraw4[%d]::createSurface ",creationid);
  193. if ( is4Bit )
  194. return E_FAIL;
  195. if(! (dd && retval) )
  196. return E_POINTER;
  197. CopyInDDSurfaceDesc2(&ddsd,dd);
  198. //docdoc: CreateSurface returns error if 'punk' is anything but NULL
  199. retv = m__dxj_DirectDraw4->CreateSurface( &ddsd, &dds4, NULL);
  200. if FAILED(retv) return retv;
  201. INTERNAL_CREATE(_dxj_DirectDrawSurface4, dds4, retval);
  202. dd->lpSurface = NULL;
  203. DPF1(1,"exit DDraw4[%d]::createSurface ",creationid);
  204. return S_OK;
  205. }
  206. ///////////////////////////////////////////////////////////////////
  207. // duplicateSurface
  208. ///////////////////////////////////////////////////////////////////
  209. STDMETHODIMP C_dxj_DirectDraw4Object::duplicateSurface(I_dxj_DirectDrawSurface4 *ddIn, I_dxj_DirectDrawSurface4 **ddOut)
  210. {
  211. HRESULT retval;
  212. if ( is4Bit )
  213. return E_FAIL;
  214. //
  215. // need to create one of MY surfaces!
  216. //
  217. LPDIRECTDRAWSURFACE4 lpddout4=NULL;
  218. DO_GETOBJECT_NOTNULL( LPDIRECTDRAWSURFACE4, lpddin, ddIn);
  219. if( (retval = m__dxj_DirectDraw4->DuplicateSurface(lpddin, &lpddout4)) != DD_OK )
  220. return retval;
  221. INTERNAL_CREATE( _dxj_DirectDrawSurface4, lpddout4, ddOut);
  222. return S_OK;
  223. }
  224. ///////////////////////////////////////////////////////////////////
  225. // getCaps
  226. ///////////////////////////////////////////////////////////////////
  227. STDMETHODIMP C_dxj_DirectDraw4Object::getCaps(DDCaps *driverCaps, DDCaps *HELcaps)
  228. {
  229. if ( is4Bit )
  230. return E_FAIL;
  231. if (!driverCaps) return E_INVALIDARG;
  232. if (!HELcaps) return E_INVALIDARG;
  233. ((DDCAPS*)driverCaps)->dwSize=sizeof(DDCAPS);
  234. ((DDCAPS*)HELcaps)->dwSize=sizeof(DDCAPS);
  235. HRESULT hr = m__dxj_DirectDraw4->GetCaps((DDCAPS*)driverCaps, (DDCAPS*)HELcaps);
  236. return hr;
  237. }
  238. ///////////////////////////////////////////////////////////////////
  239. // getDisplayMode
  240. ///////////////////////////////////////////////////////////////////
  241. STDMETHODIMP C_dxj_DirectDraw4Object::getDisplayMode(DDSurfaceDesc2 *desc)
  242. {
  243. HRESULT retval;
  244. DDSURFACEDESC2 ddsd;
  245. if (!desc) return E_INVALIDARG;
  246. CopyInDDSurfaceDesc2(&ddsd,desc);
  247. retval = m__dxj_DirectDraw4->GetDisplayMode(&ddsd);
  248. if( retval != S_OK)
  249. return retval;
  250. CopyOutDDSurfaceDesc2(desc,&ddsd);
  251. desc->lpSurface = NULL;
  252. return S_OK;
  253. }
  254. ///////////////////////////////////////////////////////////////////
  255. // getAvailableTotalMem
  256. ///////////////////////////////////////////////////////////////////
  257. STDMETHODIMP C_dxj_DirectDraw4Object::getAvailableTotalMem(DDSCaps2 *ddsCaps, long *m)
  258. {
  259. return m__dxj_DirectDraw4->GetAvailableVidMem((LPDDSCAPS2)ddsCaps, (unsigned long *)m, NULL);
  260. }
  261. ///////////////////////////////////////////////////////////////////
  262. // getFreeMem
  263. ///////////////////////////////////////////////////////////////////
  264. STDMETHODIMP C_dxj_DirectDraw4Object::getFreeMem(DDSCaps2 *ddsCaps, long *m)
  265. {
  266. return m__dxj_DirectDraw4->GetAvailableVidMem((LPDDSCAPS2)ddsCaps, NULL, (unsigned long *)m);
  267. }
  268. ///////////////////////////////////////////////////////////////////
  269. // getNumFourCCCodes
  270. ///////////////////////////////////////////////////////////////////
  271. STDMETHODIMP C_dxj_DirectDraw4Object::getNumFourCCCodes(long *retval)
  272. {
  273. return m__dxj_DirectDraw4->GetFourCCCodes((DWORD*)retval, NULL);
  274. }
  275. ///////////////////////////////////////////////////////////////////
  276. // getScanLine
  277. ///////////////////////////////////////////////////////////////////
  278. STDMETHODIMP C_dxj_DirectDraw4Object::getScanLine(long *lines, long *status)
  279. {
  280. *status = (long)m__dxj_DirectDraw4->GetScanLine((DWORD*)lines);
  281. return S_OK;
  282. }
  283. ///////////////////////////////////////////////////////////////////
  284. // loadPaletteFromBitmap
  285. ///////////////////////////////////////////////////////////////////
  286. STDMETHODIMP C_dxj_DirectDraw4Object::loadPaletteFromBitmap(BSTR bName, I_dxj_DirectDrawPalette **retval)
  287. {
  288. USES_CONVERSION;
  289. IDirectDrawPalette* ddpal;
  290. int i;
  291. int n;
  292. int fh;
  293. HRSRC h;
  294. LPBITMAPINFOHEADER lpbi;
  295. PALETTEENTRY ape[256];
  296. RGBQUAD * prgb;
  297. HRESULT hr=S_OK;
  298. if ( is4Bit ) return E_FAIL;
  299. LPCTSTR szBitmap = W2T(bName);
  300. for (i=0; i<256; i++) // build a 332 palette as the default
  301. {
  302. ape[i].peRed = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
  303. ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
  304. ape[i].peBlue = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
  305. ape[i].peFlags = (BYTE)0;
  306. }
  307. //
  308. // get a pointer to the bitmap resource.
  309. //
  310. if (szBitmap && (h = FindResource(NULL, szBitmap, RT_BITMAP)))
  311. {
  312. lpbi = (LPBITMAPINFOHEADER)LockResource(LoadResource(NULL, h));
  313. if (!lpbi){
  314. DPF(1,"lock resource failed\n");
  315. return E_OUTOFMEMORY; // error return...
  316. }
  317. prgb = (RGBQUAD*)((BYTE*)lpbi + lpbi->biSize);
  318. if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
  319. n = 0;
  320. else if (lpbi->biBitCount > 8)
  321. n = 0;
  322. else if (lpbi->biClrUsed == 0)
  323. n = 1 << lpbi->biBitCount;
  324. else
  325. n = lpbi->biClrUsed;
  326. //
  327. // a DIB color table has its colors stored BGR not RGB
  328. // so flip them around.
  329. //
  330. for(i=0; i<n; i++ )
  331. {
  332. ape[i].peRed = prgb[i].rgbRed;
  333. ape[i].peGreen = prgb[i].rgbGreen;
  334. ape[i].peBlue = prgb[i].rgbBlue;
  335. ape[i].peFlags = 0;
  336. }
  337. }
  338. else if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
  339. {
  340. BITMAPFILEHEADER bf;
  341. BITMAPINFOHEADER bi;
  342. _lread(fh, &bf, sizeof(bf));
  343. _lread(fh, &bi, sizeof(bi));
  344. _lread(fh, ape, sizeof(ape));
  345. _lclose(fh);
  346. if (bi.biSize != sizeof(BITMAPINFOHEADER))
  347. n = 0;
  348. else if (bi.biBitCount > 8)
  349. n = 0;
  350. else if (bi.biClrUsed == 0)
  351. n = 1 << bi.biBitCount;
  352. else
  353. n = bi.biClrUsed;
  354. //
  355. // a DIB color table has its colors stored BGR not RGB
  356. // so flip them around.
  357. //
  358. for(i=0; i<n; i++ )
  359. {
  360. BYTE r = ape[i].peRed;
  361. ape[i].peRed = ape[i].peBlue;
  362. ape[i].peBlue = r;
  363. }
  364. }
  365. m__dxj_DirectDraw4->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL);
  366. if( ddpal )
  367. {
  368. INTERNAL_CREATE(_dxj_DirectDrawPalette, ddpal, retval);
  369. }
  370. else
  371. {
  372. //
  373. // no object, set the return value to NULL as well.
  374. //
  375. *retval = NULL;
  376. hr = E_FAIL;
  377. }
  378. return hr;
  379. }
  380. ///////////////////////////////////////////////////////////////////
  381. // createSurfaceFromFile
  382. ///////////////////////////////////////////////////////////////////
  383. STDMETHODIMP C_dxj_DirectDraw4Object::createSurfaceFromFile(BSTR file, DDSurfaceDesc2 *desc, I_dxj_DirectDrawSurface4 **surf)
  384. {
  385. DPF1(1,"enter DDraw4[%d]::createSurfaceFromFile ",creationid);
  386. HDC hdc;
  387. HDC hdcImage;
  388. BITMAP bm;
  389. HRESULT hr;
  390. HBITMAP hbm;
  391. HRESULT retv;
  392. LPDIRECTDRAWSURFACE4 dds4; // DirectX object pointer
  393. LPSTR szFileName=NULL;
  394. int width=0;
  395. int height=0;
  396. if ( is4Bit )
  397. return E_FAIL;
  398. if(! (desc && surf) )
  399. return E_POINTER;
  400. USES_CONVERSION;
  401. szFileName=W2T(file);
  402. //If width and height are zero then we will generate our own width and
  403. //height from the bitmap.
  404. //The LoadImage api however doesnt work propery without size params
  405. //Consider there must be a way to make it work.
  406. if ((desc->lWidth!=0)&&(desc->lHeight!=0)&&(desc->lFlags & DDSD_WIDTH)&&(desc->lFlags & DDSD_HEIGHT))
  407. {
  408. width=desc->lWidth ;
  409. height=desc->lHeight;
  410. }
  411. if (desc->lFlags==0) {
  412. desc->lFlags=DDSD_CAPS;
  413. ((DDSURFACEDESC*)desc)->ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
  414. }
  415. if (!szFileName) return CTL_E_FILENOTFOUND;
  416. hbm = (HBITMAP)LoadImage((HINSTANCE)NULL, szFileName, IMAGE_BITMAP,
  417. width, height,
  418. LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  419. if (!hbm) return CTL_E_FILENOTFOUND;
  420. // get size of the bitmap
  421. //
  422. GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
  423. width=bm.bmWidth;
  424. height=bm.bmHeight;
  425. desc->lFlags = desc->lFlags | DDSD_WIDTH | DDSD_HEIGHT;
  426. if ((desc->lWidth==0)||(desc->lHeight==0))
  427. {
  428. desc->lWidth =width;
  429. desc->lHeight =height;
  430. }
  431. DDSURFACEDESC2 ddsd;
  432. CopyInDDSurfaceDesc2(&ddsd,desc);
  433. if( (retv = m__dxj_DirectDraw4->CreateSurface(&ddsd, &dds4, NULL)) != DD_OK )
  434. return retv;
  435. CopyOutDDSurfaceDesc2(desc,&ddsd);
  436. INTERNAL_CREATE(_dxj_DirectDrawSurface4, dds4, surf);
  437. desc->lpSurface = NULL;
  438. //
  439. // make sure this surface is restored.
  440. //
  441. dds4->Restore();
  442. //
  443. // select bitmap into a memoryDC so we can use it.
  444. //
  445. hdcImage = CreateCompatibleDC(NULL);
  446. SelectObject(hdcImage, hbm);
  447. if (!hdcImage){
  448. DeleteObject(hbm);
  449. return E_FAIL;
  450. }
  451. if ((hr = dds4->GetDC(&hdc)) == DD_OK)
  452. {
  453. StretchBlt(hdc, 0, 0, desc->lWidth , desc->lHeight, hdcImage,
  454. 0, 0, width, height, SRCCOPY);
  455. dds4->ReleaseDC(hdc);
  456. }
  457. DeleteDC(hdcImage);
  458. if (hbm) DeleteObject(hbm);
  459. DPF1(buffer,"exit DDraw4[%d]::createSurfaceFromFile",creationid);
  460. return S_OK;
  461. }
  462. ///////////////////////////////////////////////////////////////////
  463. // createSurfaceFromResource
  464. ///////////////////////////////////////////////////////////////////
  465. STDMETHODIMP C_dxj_DirectDraw4Object::createSurfaceFromResource(BSTR resFile, BSTR resourceName, DDSurfaceDesc2 *desc, I_dxj_DirectDrawSurface4 **surf)
  466. {
  467. DPF1(1,"enter DDraw4[%d]::createSurfaceFromResource ",creationid);
  468. if ( is4Bit )
  469. return E_FAIL;
  470. if(! (desc && surf) )
  471. return E_POINTER;
  472. HRESULT hr;
  473. HRSRC hres=NULL;
  474. HGLOBAL hglob=NULL;
  475. HDC hdc;
  476. HDC hdcImage;
  477. BITMAP bm;
  478. HBITMAP hbm;
  479. HRESULT retv;
  480. LPDIRECTDRAWSURFACE4 dds4; // DirectX object pointer
  481. LPSTR szResName=NULL;
  482. if (!resourceName) return E_INVALIDARG;
  483. if (!surf) return E_INVALIDARG;
  484. HMODULE hMod=NULL;
  485. USES_CONVERSION;
  486. if ((resFile) &&(resFile[0]!=0)){
  487. // NOTE: we used to call
  488. // GetModuleHandleW but it returned 0 on w98
  489. // so we use the ANSI version which works on w98
  490. LPCTSTR pszName = W2T(resFile);
  491. hMod= GetModuleHandle(pszName);
  492. }
  493. else {
  494. hMod= GetModuleHandle(NULL);
  495. }
  496. LPCTSTR pszName2 = W2T(resourceName);
  497. hbm = (HBITMAP)LoadImage((HINSTANCE)hMod,
  498. pszName2,
  499. IMAGE_BITMAP,
  500. 0, 0,
  501. LR_CREATEDIBSECTION);
  502. if (!hbm){
  503. return E_FAIL;
  504. }
  505. // get size of the bitmap
  506. //
  507. GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
  508. DWORD width=bm.bmWidth;
  509. DWORD height=bm.bmHeight;
  510. desc->lFlags = desc->lFlags | DDSD_WIDTH | DDSD_HEIGHT;
  511. if ((desc->lWidth==0)||(desc->lHeight==0))
  512. {
  513. desc->lWidth =width;
  514. desc->lHeight =height;
  515. }
  516. DDSURFACEDESC2 ddsd;
  517. CopyInDDSurfaceDesc2(&ddsd,desc);
  518. if( (retv = m__dxj_DirectDraw4->CreateSurface(&ddsd, &dds4, NULL)) != DD_OK )
  519. {
  520. if (hbm) DeleteObject(hbm);
  521. return retv;
  522. }
  523. CopyOutDDSurfaceDesc2(desc,&ddsd);
  524. INTERNAL_CREATE(_dxj_DirectDrawSurface4, dds4, surf);
  525. desc->lpSurface = NULL;
  526. //
  527. // make sure this surface is restored.
  528. //
  529. dds4->Restore();
  530. //
  531. // select bitmap into a memoryDC so we can use it.
  532. //
  533. hdcImage = CreateCompatibleDC(NULL);
  534. if (!hdcImage){
  535. DeleteObject(hbm);
  536. return E_OUTOFMEMORY;
  537. }
  538. SelectObject(hdcImage, hbm);
  539. if ((hr = dds4->GetDC(&hdc)) == DD_OK)
  540. {
  541. StretchBlt(hdc, 0, 0, desc->lWidth , desc->lHeight, hdcImage,
  542. 0, 0, width, height, SRCCOPY);
  543. dds4->ReleaseDC(hdc);
  544. }
  545. DeleteDC(hdcImage);
  546. if (hbm) DeleteObject(hbm);
  547. DPF1(1r,"exit DDraw4[%d]::createSurfaceFromFile",creationid);
  548. return S_OK;
  549. }
  550. ///////////////////////////////////////////////////////////////////
  551. // getFourCCCodes
  552. ///////////////////////////////////////////////////////////////////
  553. STDMETHODIMP C_dxj_DirectDraw4Object::getFourCCCodes(SAFEARRAY **ppsa)
  554. {
  555. DWORD count= ((SAFEARRAY*)*ppsa)->rgsabound[0].cElements;
  556. if ( ((SAFEARRAY*)*ppsa)->cDims!=1) return E_INVALIDARG;
  557. return m__dxj_DirectDraw4->GetFourCCCodes(&count,(DWORD*)((SAFEARRAY*)*ppsa)->pvData);
  558. }
  559. ///////////////////////////////////////////////////////////////////
  560. // getDisplayModesEnum
  561. ///////////////////////////////////////////////////////////////////
  562. STDMETHODIMP C_dxj_DirectDraw4Object::getDisplayModesEnum(
  563. /* [in] */ long flags,
  564. /* [in] */ DDSurfaceDesc2 *ddsd,
  565. /* [retval][out] */ I_dxj_DirectDrawEnumModes __RPC_FAR *__RPC_FAR *retval)
  566. {
  567. HRESULT hr;
  568. hr=C_dxj_DirectDrawEnumModesObject::create(m__dxj_DirectDraw4,flags, ddsd, retval);
  569. return hr;
  570. }
  571. ///////////////////////////////////////////////////////////////////
  572. // testCooperativeLevel
  573. ///////////////////////////////////////////////////////////////////
  574. STDMETHODIMP C_dxj_DirectDraw4Object::testCooperativeLevel(
  575. /* [in,out] */ long *status)
  576. {
  577. HRESULT hr;
  578. hr=m__dxj_DirectDraw4->TestCooperativeLevel();
  579. *status=(long)hr;
  580. return S_OK;
  581. }
  582. ///////////////////////////////////////////////////////////////////
  583. // restoreAllSurfaces
  584. ///////////////////////////////////////////////////////////////////
  585. STDMETHODIMP C_dxj_DirectDraw4Object::restoreAllSurfaces()
  586. {
  587. HRESULT hr;
  588. hr=m__dxj_DirectDraw4->RestoreAllSurfaces();
  589. return hr;
  590. }
  591. STDMETHODIMP C_dxj_DirectDraw4Object::getSurfaceFromDC(long hdc, I_dxj_DirectDrawSurface4 **ret)
  592. {
  593. HRESULT hr;
  594. LPDIRECTDRAWSURFACE4 pDDS=NULL;
  595. hr=m__dxj_DirectDraw4->GetSurfaceFromDC((HDC)hdc,&pDDS);
  596. if FAILED(hr) return hr;
  597. INTERNAL_CREATE(_dxj_DirectDrawSurface4,pDDS,ret);
  598. return hr;
  599. }