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.

2517 lines
69 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddsover.c
  6. * Content: DirectDraw Surface overlay support:
  7. * UpdateOverlay
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 27-jan-95 craige split out of ddsurf.c, enhanced
  12. * 31-jan-95 craige and even more ongoing work...
  13. * 03-feb-95 craige performance tuning, ongoing work
  14. * 27-feb-95 craige new sync. macros
  15. * 08-mar-95 craige new APIs: GetOverlayPosition, GetOverlayZOrder
  16. * SetOverlayZOrder, SetOverlayPosition
  17. * 19-mar-95 craige use HRESULTs
  18. * 01-apr-95 craige happy fun joy updated header file
  19. * 03-apr-95 craige made update overlay work again
  20. * 06-may-95 craige use driver-level csects only
  21. * 14-may-95 craige cleaned out obsolete junk
  22. * 15-may-95 kylej deleted GetOverlayZOrder, SetOverlayZOrder,
  23. * InsertOverlayZOrder. Added UpdateOverlayZOrder
  24. * and EnumOverlayZOrders.
  25. * 17-jun-95 craige new surface structure
  26. * 25-jun-95 craige one ddraw mutex
  27. * 26-jun-95 craige reorganized surface structure
  28. * 28-jun-95 craige ENTER_DDRAW at very start of fns; tweaks in UpdateOverlay;
  29. * verify stretching; disabled alpha
  30. * 30-jun-95 craige small bug fixes; verify rectangle alignment
  31. * 04-jul-95 craige YEEHAW: new driver struct; SEH
  32. * 10-jul-95 craige support Get/SetOverlayPosition
  33. * 10-jul-95 kylej mirroring caps and flags
  34. * 13-jul-95 craige changed Get/SetOverlayPosition to use LONG
  35. * 31-jul-95 craige validate flags
  36. * 19-aug-95 davidmay don't check rectangles when hiding overlay
  37. * 10-dec-95 colinmc added execute buffer support
  38. * 02-jan-96 kylej handle new interface structs
  39. * 12-feb-96 colinmc surface lost flag moved from global to local object
  40. * 23-apr-96 kylej use dwMinOverlayStretch and dwMaxOverlayStretch
  41. * validate that entire dest rect is in overlayed surface
  42. * 29-jan-97 smac Removed old ring 0 code
  43. * 03-mar-97 smac Added kernel mode interface
  44. * 19-nov-98 jvanaken Overlays with alpha blending
  45. *
  46. ***************************************************************************/
  47. #include "ddrawpr.h"
  48. #undef DPF_MODNAME
  49. #define DPF_MODNAME "UpdateOverlay"
  50. /*
  51. * checkOverlayStretching
  52. *
  53. * check and see if we can stretch or not
  54. */
  55. HRESULT checkOverlayStretching(
  56. LPDDRAWI_DIRECTDRAW_GBL pdrv,
  57. DWORD dest_height,
  58. DWORD dest_width,
  59. DWORD src_height,
  60. DWORD src_width,
  61. DWORD src_caps,
  62. BOOL emulate )
  63. {
  64. DWORD caps;
  65. DWORD basecaps;
  66. BOOL fail;
  67. DWORD dwMinStretch;
  68. DWORD dwMaxStretch;
  69. fail = FALSE;
  70. if( emulate )
  71. {
  72. basecaps = pdrv->ddHELCaps.dwCaps;
  73. caps = pdrv->ddHELCaps.dwFXCaps;
  74. if( src_caps & DDSCAPS_LIVEVIDEO )
  75. {
  76. dwMinStretch = pdrv->ddHELCaps.dwMinLiveVideoStretch;
  77. dwMaxStretch = pdrv->ddHELCaps.dwMaxLiveVideoStretch;
  78. }
  79. else if( src_caps & DDSCAPS_HWCODEC )
  80. {
  81. dwMinStretch = pdrv->ddHELCaps.dwMinHwCodecStretch;
  82. dwMaxStretch = pdrv->ddHELCaps.dwMaxHwCodecStretch;
  83. }
  84. else
  85. {
  86. dwMinStretch = pdrv->ddHELCaps.dwMinOverlayStretch;
  87. dwMaxStretch = pdrv->ddHELCaps.dwMaxOverlayStretch;
  88. }
  89. }
  90. else
  91. {
  92. basecaps = pdrv->ddCaps.dwCaps;
  93. caps = pdrv->ddCaps.dwFXCaps;
  94. if( src_caps & DDSCAPS_LIVEVIDEO )
  95. {
  96. dwMinStretch = pdrv->ddCaps.dwMinLiveVideoStretch;
  97. dwMaxStretch = pdrv->ddCaps.dwMaxLiveVideoStretch;
  98. }
  99. else if( src_caps & DDSCAPS_HWCODEC )
  100. {
  101. dwMinStretch = pdrv->ddCaps.dwMinHwCodecStretch;
  102. dwMaxStretch = pdrv->ddCaps.dwMaxHwCodecStretch;
  103. }
  104. else
  105. {
  106. dwMinStretch = pdrv->ddCaps.dwMinOverlayStretch;
  107. dwMaxStretch = pdrv->ddCaps.dwMaxOverlayStretch;
  108. }
  109. }
  110. /*
  111. * Check against dwMinOverlayStretch
  112. */
  113. if( src_width*dwMinStretch > dest_width*1000 )
  114. {
  115. return DDERR_INVALIDPARAMS;
  116. }
  117. /*
  118. * Check against dwMaxOverlayStretch
  119. */
  120. if( (dwMaxStretch != 0) && (src_width*dwMaxStretch < dest_width*1000) )
  121. {
  122. return DDERR_INVALIDPARAMS;
  123. }
  124. if( (src_height == dest_height) && (src_width == dest_width) )
  125. {
  126. // not stretching.
  127. return DD_OK;
  128. }
  129. /*
  130. * If we are here, we must be trying to stretch.
  131. * can we even stretch at all?
  132. */
  133. if( !(basecaps & DDCAPS_OVERLAYSTRETCH))
  134. {
  135. return DDERR_NOSTRETCHHW;
  136. }
  137. /*
  138. * verify height
  139. */
  140. if( src_height != dest_height )
  141. {
  142. if( src_height > dest_height )
  143. {
  144. /*
  145. * can we shrink Y arbitrarily?
  146. */
  147. if( !(caps & DDFXCAPS_OVERLAYSHRINKY) )
  148. {
  149. /*
  150. * see if this is a non-integer shrink
  151. */
  152. if( (src_height % dest_height) != 0 )
  153. {
  154. return DDERR_NOSTRETCHHW;
  155. /*
  156. * see if we can integer shrink
  157. */
  158. }
  159. else if( !(caps & DDFXCAPS_OVERLAYSHRINKYN) )
  160. {
  161. return DDERR_NOSTRETCHHW;
  162. }
  163. }
  164. }
  165. else
  166. {
  167. if( !(caps & DDFXCAPS_OVERLAYSTRETCHY) )
  168. {
  169. /*
  170. * see if this is a non-integer stretch
  171. */
  172. if( (dest_height % src_height) != 0 )
  173. {
  174. return DDERR_NOSTRETCHHW;
  175. /*
  176. * see if we can integer stretch
  177. */
  178. }
  179. else if( !(caps & DDFXCAPS_OVERLAYSTRETCHYN) )
  180. {
  181. return DDERR_NOSTRETCHHW;
  182. }
  183. }
  184. }
  185. }
  186. /*
  187. * verify width
  188. */
  189. if( src_width != dest_width )
  190. {
  191. if( src_width > dest_width )
  192. {
  193. if( !(caps & DDFXCAPS_OVERLAYSHRINKX) )
  194. {
  195. /*
  196. * see if this is a non-integer shrink
  197. */
  198. if( (src_width % dest_width) != 0 )
  199. {
  200. return DDERR_NOSTRETCHHW;
  201. /*
  202. * see if we can integer shrink
  203. */
  204. }
  205. else if( !(caps & DDFXCAPS_OVERLAYSHRINKXN) )
  206. {
  207. return DDERR_NOSTRETCHHW;
  208. }
  209. }
  210. }
  211. else
  212. {
  213. if( !(caps & DDFXCAPS_OVERLAYSTRETCHX) )
  214. {
  215. /*
  216. * see if this is a non-integer stretch
  217. */
  218. if( (dest_width % src_width) != 0 )
  219. {
  220. return DDERR_NOSTRETCHHW;
  221. }
  222. if( !(caps & DDFXCAPS_OVERLAYSTRETCHXN) )
  223. {
  224. return DDERR_NOSTRETCHHW;
  225. }
  226. }
  227. }
  228. }
  229. return DD_OK;
  230. } /* checkOverlayStretching */
  231. /*
  232. * checkOverlayFlags
  233. */
  234. static HRESULT checkOverlayFlags(
  235. LPDDRAWI_DIRECTDRAW_GBL pdrv,
  236. LPDWORD lpdwFlags,
  237. LPDDRAWI_DDRAWSURFACE_INT this_src_int,
  238. LPDDRAWI_DDRAWSURFACE_LCL this_dest_lcl,
  239. LPDDHAL_UPDATEOVERLAYDATA puod,
  240. LPDDOVERLAYFX lpDDOverlayFX,
  241. BOOL emulate )
  242. {
  243. LPDDRAWI_DDRAWSURFACE_LCL this_src_lcl;
  244. DWORD basecaps;
  245. DWORD baseckeycaps;
  246. DWORD dwFlags;
  247. this_src_lcl = this_src_int->lpLcl;
  248. dwFlags= * lpdwFlags;
  249. if( emulate )
  250. {
  251. basecaps = pdrv->ddHELCaps.dwCaps;
  252. baseckeycaps = pdrv->ddHELCaps.dwCKeyCaps;
  253. }
  254. else
  255. {
  256. basecaps = pdrv->ddCaps.dwCaps;
  257. baseckeycaps = pdrv->ddCaps.dwCKeyCaps;
  258. }
  259. /*
  260. * Handle auto-flipping
  261. */
  262. if( dwFlags & DDOVER_AUTOFLIP )
  263. {
  264. DWORD rc;
  265. rc = IsValidAutoFlipSurface( this_src_int );
  266. if( rc == IVAS_NOAUTOFLIPPING )
  267. {
  268. DPF_ERR( "AUTOFLIPPING not valid" );
  269. return DDERR_INVALIDPARAMS;
  270. }
  271. else if( rc == IVAS_SOFTWAREAUTOFLIPPING )
  272. {
  273. /*
  274. * Software autoflipping only
  275. */
  276. this_src_lcl->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_SOFTWAREAUTOFLIP;
  277. }
  278. }
  279. /*
  280. * Handle bob
  281. */
  282. if( dwFlags & DDOVER_BOB )
  283. {
  284. /*
  285. * Fail if bob caps not specified
  286. */
  287. if( dwFlags & DDOVER_INTERLEAVED )
  288. {
  289. if( !( pdrv->ddCaps.dwCaps2 & DDCAPS2_CANBOBINTERLEAVED ) )
  290. {
  291. DPF_ERR( "Device doesn't support DDOVER_BOB while interleaved!" );
  292. return DDERR_INVALIDPARAMS;
  293. }
  294. }
  295. else
  296. {
  297. if( !( pdrv->ddCaps.dwCaps2 & DDCAPS2_CANBOBNONINTERLEAVED ) )
  298. {
  299. DPF_ERR( "Device doesn't support DDOVER_BOB!" );
  300. return DDERR_INVALIDPARAMS;
  301. }
  302. }
  303. /*
  304. * Is the surface fed by a video port?
  305. */
  306. if( ( this_src_lcl->ddsCaps.dwCaps & DDSCAPS_VIDEOPORT ) &&
  307. ( this_src_lcl->lpSurfMore->lpVideoPort != NULL ) )
  308. {
  309. /*
  310. * Yes - fail (at least for DX5) if they are bobbing and not
  311. * autofliiping. This is because this support is broken in DX5.
  312. */
  313. if( !( dwFlags & ( DDOVER_AUTOFLIP | DDOVER_INTERLEAVED ) ) )
  314. {
  315. DPF_ERR( "DDOVER_BOB specified without autoflip or interleaved!" );
  316. return DDERR_INVALIDPARAMS;
  317. }
  318. if( MustSoftwareBob( this_src_int ) )
  319. {
  320. dwFlags &= ~DDOVER_BOBHARDWARE;
  321. }
  322. else
  323. {
  324. dwFlags |= DDOVER_BOBHARDWARE;
  325. }
  326. }
  327. else
  328. {
  329. /*
  330. * Don't allow non-VPE clients to use bob unless the
  331. * driver can handle it.
  332. */
  333. if( !( pdrv->ddCaps.dwCaps2 & DDCAPS2_CANFLIPODDEVEN ) )
  334. {
  335. DPF_ERR( "Device does not support DDCAPS2_CANFLIPODDEVEN" );
  336. return DDERR_INVALIDPARAMS;
  337. }
  338. if( dwFlags & DDOVER_BOBHARDWARE )
  339. {
  340. DPF_ERR( "DDOVER_BOBHARDWARE only valid when used with a video port" );
  341. return DDERR_INVALIDPARAMS;
  342. }
  343. }
  344. }
  345. else if( dwFlags & DDOVER_BOBHARDWARE )
  346. {
  347. DPF_ERR( "DDOVER_BOBHARDWARE specified w/o DDOVER_BOB" );
  348. return DDERR_INVALIDPARAMS;
  349. }
  350. /*
  351. * ALPHA DISABLED FOR REV 1
  352. */
  353. #pragma message( REMIND( "Alpha disabled for rev 1" ) )
  354. #ifdef USE_ALPHA
  355. /*
  356. * verify alpha
  357. */
  358. if( dwFlags & DDOVER_ANYALPHA )
  359. {
  360. /*
  361. * dest
  362. */
  363. if( dwFlags & DDOVER_ALPHADEST )
  364. {
  365. if( dwFlags & (DDOVER_ALPHASRC |
  366. DDOVER_ALPHADESTCONSTOVERRIDE |
  367. DDOVER_ALPHADESTSURFACEOVERRIDE) )
  368. {
  369. DPF_ERR( "ALPHADEST and other alpha sources specified" );
  370. return DDERR_INVALIDPARAMS;
  371. }
  372. psurf_lcl = FindAttached( this_dest_lcl, DDSCAPS_ALPHA );
  373. if( psurf_lcl == NULL )
  374. {
  375. DPF_ERR( "ALPHADEST requires an attached alpha to the dest" );
  376. return DDERR_INVALIDPARAMS;
  377. }
  378. psurf = psurf_lcl->lpGbl;
  379. dwFlags &= ~DDOVER_ALPHADEST;
  380. dwFlags |= DDOVER_ALPHADESTSURFACEOVERRIDE;
  381. puod->overlayFX.lpDDSAlphaDest = (LPDIRECTDRAWSURFACE) psurf;
  382. }
  383. else if( dwFlags & DDOVER_ALPHADESTCONSTOVERRIDE )
  384. {
  385. if( dwFlags & ( DDOVER_ALPHADESTSURFACEOVERRIDE) )
  386. {
  387. DPF_ERR( "ALPHADESTCONSTOVERRIDE and other alpha sources specified" );
  388. return DDERR_INVALIDPARAMS;
  389. }
  390. puod->overlayFX.dwConstAlphaDestBitDepth =
  391. lpDDOverlayFX->dwConstAlphaDestBitDepth;
  392. puod->overlayFX.dwConstAlphaDest = lpDDOverlayFX->dwConstAlphaDest;
  393. }
  394. else if( dwFlags & DDOVER_ALPHADESTSURFACEOVERRIDE )
  395. {
  396. psurf_lcl = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDOverlayFX->lpDDSAlphaDest;
  397. if( !VALID_DIRECTDRAWSURFACE_PTR( psurf_lcl ) )
  398. {
  399. DPF_ERR( "ALPHASURFACEOVERRIDE requires surface ptr" );
  400. return DDERR_INVALIDPARAMS;
  401. }
  402. psurf = psurf_lcl->lpGbl;
  403. if( SURFACE_LOST( psurf_lcl ) )
  404. {
  405. return DDERR_SURFACELOST;
  406. }
  407. puod->overlayFX.lpDDSAlphaDest = (LPDIRECTDRAWSURFACE) psurf;
  408. }
  409. /*
  410. * source
  411. */
  412. if( dwFlags & DDOVER_ALPHASRC )
  413. {
  414. if( dwFlags & (DDOVER_ALPHASRC |
  415. DDOVER_ALPHASRCCONSTOVERRIDE |
  416. DDOVER_ALPHASRCSURFACEOVERRIDE) )
  417. {
  418. DPF_ERR( "ALPHASRC and other alpha sources specified" );
  419. return DDERR_INVALIDPARAMS;
  420. }
  421. psurf_lcl = FindAttached( this_dest_lcl, DDSCAPS_ALPHA );
  422. if( psurf_lcl == NULL )
  423. {
  424. DPF_ERR( "ALPHASRC requires an attached alpha to the dest" );
  425. return DDERR_INVALIDPARAMS;
  426. }
  427. psurf = psurf_lcl->lpGbl;
  428. dwFlags &= ~DDOVER_ALPHASRC;
  429. dwFlags |= DDOVER_ALPHASRCSURFACEOVERRIDE;
  430. puod->overlayFX.lpDDSAlphaSrc = (LPDIRECTDRAWSURFACE) psurf;
  431. }
  432. else if( dwFlags & DDOVER_ALPHASRCCONSTOVERRIDE )
  433. {
  434. if( dwFlags & ( DDOVER_ALPHASRCSURFACEOVERRIDE) )
  435. {
  436. DPF_ERR( "ALPHASRCCONSTOVERRIDE and other alpha sources specified" );
  437. return DDERR_INVALIDPARAMS;
  438. }
  439. puod->overlayFX.dwConstAlphaSrcBitDepth =
  440. lpDDOverlayFX->dwConstAlphaSrcBitDepth;
  441. puod->overlayFX.dwConstAlphaSrc = lpDDOverlayFX->dwConstAlphaSrc;
  442. }
  443. else if( dwFlags & DDOVER_ALPHASRCSURFACEOVERRIDE )
  444. {
  445. psurf_lcl = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDOverlayFX->lpDDSAlphaSrc;
  446. if( !VALID_DIRECTDRAWSURFACE_PTR( psurf_lcl ) )
  447. {
  448. DPF_ERR( "ALPHASURFACEOVERRIDE requires surface ptr" );
  449. return DDERR_INVALIDPARAMS;
  450. }
  451. psurf = psurf_lcl->lpGbl;
  452. if( SURFACE_LOST( psurf_lcl ) )
  453. {
  454. return DDERR_SURFACELOST;
  455. }
  456. puod->overlayFX.lpDDSAlphaSrc = (LPDIRECTDRAWSURFACE) psurf;
  457. }
  458. }
  459. #endif
  460. /*
  461. * verify color key overrides
  462. */
  463. if( dwFlags & (DDOVER_KEYSRCOVERRIDE|DDOVER_KEYDESTOVERRIDE) )
  464. {
  465. if( !(basecaps & DDCAPS_COLORKEY) )
  466. {
  467. DPF_ERR( "KEYOVERRIDE specified, colorkey not supported" );
  468. return DDERR_NOCOLORKEYHW;
  469. }
  470. if( dwFlags & DDOVER_KEYSRCOVERRIDE )
  471. {
  472. if( !(baseckeycaps & DDCKEYCAPS_SRCOVERLAY) )
  473. {
  474. DPF_ERR( "KEYSRCOVERRIDE specified, not supported" );
  475. return DDERR_NOCOLORKEYHW;
  476. }
  477. puod->overlayFX.dckSrcColorkey = lpDDOverlayFX->dckSrcColorkey;
  478. }
  479. if( dwFlags & DDOVER_KEYDESTOVERRIDE )
  480. {
  481. if( !(baseckeycaps & DDCKEYCAPS_DESTOVERLAY) )
  482. {
  483. DPF_ERR( "KEYDESTOVERRIDE specified, not supported" );
  484. return DDERR_NOCOLORKEYHW;
  485. }
  486. puod->overlayFX.dckDestColorkey = lpDDOverlayFX->dckDestColorkey;
  487. }
  488. }
  489. /*
  490. * verify src color key
  491. */
  492. if( dwFlags & DDOVER_KEYSRC )
  493. {
  494. if( dwFlags & DDOVER_KEYSRCOVERRIDE )
  495. {
  496. DPF_ERR( "KEYSRC specified with KEYSRCOVERRIDE" );
  497. return DDERR_INVALIDPARAMS;
  498. }
  499. if( !(this_src_lcl->dwFlags & DDRAWISURF_HASCKEYSRCOVERLAY) )
  500. {
  501. DPF_ERR( "KEYSRC specified, but no color key" );
  502. return DDERR_INVALIDPARAMS;
  503. }
  504. puod->overlayFX.dckSrcColorkey = this_src_lcl->ddckCKSrcOverlay;
  505. dwFlags &= ~DDOVER_KEYSRC;
  506. dwFlags |= DDOVER_KEYSRCOVERRIDE;
  507. }
  508. /*
  509. * verify dest color key
  510. */
  511. if( dwFlags & DDOVER_KEYDEST )
  512. {
  513. if( dwFlags & DDOVER_KEYDESTOVERRIDE )
  514. {
  515. DPF_ERR( "KEYDEST specified with KEYDESTOVERRIDE" );
  516. return DDERR_INVALIDPARAMS;
  517. }
  518. if( !(this_dest_lcl->dwFlags & DDRAWISURF_HASCKEYDESTOVERLAY) )
  519. {
  520. DPF_ERR( "KEYDEST specified, but no color key" );
  521. return DDERR_INVALIDPARAMS;
  522. }
  523. puod->overlayFX.dckDestColorkey = this_dest_lcl->ddckCKDestOverlay;
  524. dwFlags &= ~DDOVER_KEYDEST;
  525. dwFlags |= DDOVER_KEYDESTOVERRIDE;
  526. }
  527. *lpdwFlags = dwFlags;
  528. return DD_OK;
  529. } /* checkOverlayFlags */
  530. /*
  531. * flags we need to call checkOverlayFlags for
  532. */
  533. #define FLAGS_TO_CHECK \
  534. (DDOVER_KEYSRCOVERRIDE| DDOVER_KEYDESTOVERRIDE | \
  535. DDOVER_KEYSRC | DDOVER_KEYDEST | DDOVER_OVERRIDEBOBWEAVE | \
  536. DDOVER_AUTOFLIP | DDOVER_BOB )
  537. /*
  538. * Return a pointer to the DDPIXELFORMAT structure that
  539. * describes the specified surface's pixel format.
  540. */
  541. static DWORD getPixelFormatFlags(LPDDRAWI_DDRAWSURFACE_LCL surf_lcl)
  542. {
  543. if (surf_lcl->dwFlags & DDRAWISURF_HASPIXELFORMAT)
  544. {
  545. // surface contains explicitly defined pixel format
  546. return surf_lcl->lpGbl->ddpfSurface.dwFlags;
  547. }
  548. // surface's pixel format is implicit -- same as primary's
  549. return surf_lcl->lpSurfMore->lpDD_lcl->lpGbl->vmiData.ddpfDisplay.dwFlags;
  550. } /* getPixelFormatFlags */
  551. #if 0
  552. /*
  553. * checkOverlayAlpha -- See if we can do specified alpha-blending operation.
  554. */
  555. static HRESULT checkOverlayAlpha(
  556. LPDDRAWI_DIRECTDRAW_GBL pdrv,
  557. LPDWORD lpdwFlags,
  558. LPDDRAWI_DDRAWSURFACE_LCL src_surf_lcl,
  559. LPDDHAL_UPDATEOVERLAYDATA puod,
  560. LPDDOVERLAYFX lpDDOverlayFX,
  561. BOOL emulate )
  562. {
  563. DDARGB argb = { 255, 255, 255, 255 };
  564. DWORD fxcaps = 0;
  565. DWORD alphacaps = 0;
  566. DWORD pfflags = getPixelFormatFlags(src_surf_lcl);
  567. DWORD dwFlags = *lpdwFlags;
  568. if( emulate )
  569. {
  570. fxcaps = pdrv->ddHELCaps.dwFXCaps;
  571. if (pdrv->lpddHELMoreCaps)
  572. {
  573. alphacaps = pdrv->lpddHELMoreCaps->dwAlphaCaps;
  574. }
  575. }
  576. else
  577. {
  578. fxcaps = pdrv->ddCaps.dwFXCaps;
  579. if (pdrv->lpddMoreCaps)
  580. {
  581. alphacaps = pdrv->lpddMoreCaps->dwAlphaCaps;
  582. }
  583. }
  584. // Is any type of alpha blending required for this overlay?
  585. if (!(pfflags & DDPF_ALPHAPIXELS) && !(dwFlags & DDOVER_ARGBSCALEFACTORS))
  586. {
  587. return DD_OK; // no alpha blending is needed
  588. }
  589. // Yes, verify that the driver supports alpha blending.
  590. if (!(fxcaps & DDFXCAPS_OVERLAYALPHA))
  591. {
  592. DPF_ERR("Driver can't do alpha blending on overlays");
  593. return DDERR_NOALPHAHW;
  594. }
  595. // Is dest color keying also enabled for this overlay?
  596. if ((dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE)) &&
  597. !(alphacaps &DDALPHACAPS_OVERLAYALPHAANDKEYDEST))
  598. {
  599. DPF_ERR("Driver can't do alpha blending and dest color key on same overlay");
  600. return DDERR_UNSUPPORTED;
  601. }
  602. // Get ARGB scaling factors from DDOVERLAYFX structure.
  603. *(LPDWORD)&argb = ~0; // default = ARGB scaling disabled (all ones)
  604. if (dwFlags & DDOVER_ARGBSCALEFACTORS)
  605. {
  606. if( !(*lpdwFlags & DDOVER_DDFX) )
  607. {
  608. DPF_ERR("Must specify DDOVER_DDFX with DDOVER_ARGBSCALEFACTORS");
  609. return DDERR_INVALIDPARAMS;
  610. }
  611. argb = lpDDOverlayFX->ddargbScaleFactors; // ARGB scaling enabled
  612. }
  613. // Does the source surface have an alpha channel?
  614. if (pfflags & DDPF_ALPHAPIXELS)
  615. {
  616. /*
  617. * Yes, verify that the driver can handle an alpha channel.
  618. * (This check is a bit redundant since the driver has already blessed
  619. * the format of this overlay surface by allowing it to be created.)
  620. */
  621. if (!(alphacaps & DDALPHACAPS_OVERLAYALPHAPIXELS))
  622. {
  623. DPF_ERR("Driver can't handle source surface's alpha channel");
  624. return DDERR_NOALPHAHW;
  625. }
  626. // Ignore source color key flags if source has alpha channel.
  627. if (dwFlags & (DDOVER_KEYSRC | DDOVER_KEYSRCOVERRIDE))
  628. {
  629. *lpdwFlags &= ~(DDOVER_KEYSRC | DDOVER_KEYSRCOVERRIDE);
  630. }
  631. /*
  632. * Are we asking the driver to handle both ARGB scaling and
  633. * an alpha channel when it can't do both at the same time?
  634. */
  635. if (*(LPDWORD)&argb != ~0 &&
  636. !(alphacaps & DDALPHACAPS_OVERLAYALPHAANDARGBSCALING))
  637. {
  638. if (!(dwFlags & DDOVER_DEGRADEARGBSCALING))
  639. {
  640. DPF_ERR("Driver can't handle alpha channel and ARGB scaling at same time");
  641. return DDERR_INVALIDPARAMS;
  642. }
  643. // We're allowed to degrade ARGB scaling, so turn it off.
  644. *(LPDWORD)&argb = ~0;
  645. }
  646. /*
  647. * Are color components in pixel format premultiplied by the
  648. * alpha component or not? In either case, verify that the
  649. * driver supports the specified alpha format.
  650. */
  651. if (pfflags & DDPF_ALPHAPREMULT)
  652. {
  653. // Source pixel format uses premultiplied alpha.
  654. if (!(alphacaps & DDALPHACAPS_OVERLAYPREMULT))
  655. {
  656. DPF_ERR("No driver support for premultiplied alpha");
  657. return DDERR_NOALPHAHW;
  658. }
  659. }
  660. else
  661. {
  662. // Source pixel format uses NON-premultiplied alpha.
  663. if (!(alphacaps & DDALPHACAPS_OVERLAYNONPREMULT))
  664. {
  665. DPF_ERR("No driver support for non-premultiplied alpha");
  666. return DDERR_NOALPHAHW;
  667. }
  668. /*
  669. * We allow only one-factor ARGB scaling with a source surface
  670. * that has a non-premultiplied alpha pixel format.
  671. * The following code enforces this rule.
  672. */
  673. if (*(LPDWORD)&argb != ~0)
  674. {
  675. // ARGB scaling is enabled. Check for one-factor scaling.
  676. DWORD val = 0x01010101UL*argb.alpha;
  677. if (*(LPDWORD)&argb != val)
  678. {
  679. // Uh-oh. This is NOT one-factor ARGB scaling.
  680. if (!(dwFlags & DDABLT_DEGRADEARGBSCALING))
  681. {
  682. DPF_ERR("Can't do 2- or 4-mult ARGB scaling if source has non-premultiplied alpha");
  683. return DDERR_INVALIDPARAMS;
  684. }
  685. // We're allowed to degrade to one-factor scaling.
  686. *(LPDWORD)&argb = val;
  687. }
  688. }
  689. }
  690. }
  691. // Is ARGB scaling is enabled?
  692. if (*(LPDWORD)&argb != ~0UL)
  693. {
  694. // Yes, ARGB scaling is enabled. Is DEGRADESCALEFACTORS flag set?
  695. if (dwFlags & DDOVER_DEGRADEARGBSCALING)
  696. {
  697. /*
  698. * Yes, if necessary, we are permitted to degrade the ARGB
  699. * scaling factors to values the driver can handle.
  700. */
  701. if (!(alphacaps & (DDALPHACAPS_OVERLAYARGBSCALE1F |
  702. DDALPHACAPS_OVERLAYARGBSCALE2F |
  703. DDALPHACAPS_OVERLAYARGBSCALE4F)))
  704. {
  705. /*
  706. * Driver can't do any kind of ARGB scaling at all, so just
  707. * disable ARGB scaling by setting all four factors to 255.
  708. */
  709. *(LPDWORD)&argb = ~0UL;
  710. }
  711. else if (!(alphacaps & (DDALPHACAPS_OVERLAYARGBSCALE2F |
  712. DDALPHACAPS_OVERLAYARGBSCALE4F)))
  713. {
  714. /*
  715. * The driver can do only one-factor ARGB scaling, so set the
  716. * three color factors to the same value as the alpha factor.
  717. */
  718. *(LPDWORD)&argb = 0x01010101UL*argb.alpha;
  719. }
  720. else if (!(alphacaps & DDALPHACAPS_OVERLAYARGBSCALE4F))
  721. {
  722. /*
  723. * Driver can do only 2-factor ARGB scaling, so make sure
  724. * all three color factors are set to the same value.
  725. */
  726. if ((argb.red != argb.green) || (argb.red != argb.blue))
  727. {
  728. /*
  729. * Set all three color factors to value "fact", which is the
  730. * weighted average of their specified values (Fr,Fg,Fb):
  731. * fact = .299*Fr + .587*Fg + .114*Fb
  732. */
  733. DWORD fact = 19595UL*argb.red + 38470UL*argb.green +
  734. 7471UL*argb.blue;
  735. argb.red =
  736. argb.green =
  737. argb.blue = (BYTE)(fact >> 16);
  738. }
  739. }
  740. /*
  741. * Does driver use saturated arithmetic to do alpha blending?
  742. */
  743. if (!(alphacaps & DDALPHACAPS_OVERLAYSATURATE))
  744. {
  745. /*
  746. * The driver can't do saturated arithmetic, so ensure that none
  747. * of the color factors exceeds the value of the alpha factor.
  748. */
  749. if (argb.red > argb.alpha)
  750. {
  751. argb.red = argb.alpha;
  752. }
  753. if (argb.green > argb.alpha)
  754. {
  755. argb.green = argb.alpha;
  756. }
  757. if (argb.blue > argb.alpha)
  758. {
  759. argb.blue = argb.alpha;
  760. }
  761. }
  762. }
  763. else
  764. {
  765. /*
  766. * We are not permitted to degrade the ARGB scaling factors, so if
  767. * the driver can't handle them as specified, the call must fail.
  768. * We permit a color factor to be larger than the alpha factor
  769. * only if the hardware uses saturated arithmetic. (Otherwise, we
  770. * would risk integer overflow when we calculate the color values.)
  771. */
  772. if (!(alphacaps & DDALPHACAPS_OVERLAYSATURATE) &&
  773. ((argb.red > argb.alpha) || (argb.green > argb.alpha) ||
  774. (argb.blue > argb.alpha)))
  775. {
  776. DPF_ERR("Driver can't handle specified ARGB scaling factors");
  777. return DDERR_NOALPHAHW;
  778. }
  779. // Can the driver handle any ARGB scaling at all?
  780. if (!(alphacaps & (DDALPHACAPS_OVERLAYARGBSCALE1F |
  781. DDALPHACAPS_OVERLAYARGBSCALE2F |
  782. DDALPHACAPS_OVERLAYARGBSCALE4F)))
  783. {
  784. DPF_ERR("Driver can't handle any ARGB scaling at all");
  785. return DDERR_NOALPHAHW;
  786. }
  787. if ((argb.red != argb.green) || (argb.red != argb.blue))
  788. {
  789. /*
  790. * Driver must be capable of doing 4-factor ARGB scaling.
  791. */
  792. if (!(alphacaps & DDALPHACAPS_OVERLAYARGBSCALE4F))
  793. {
  794. DPF_ERR("Driver can't handle 4-factor ARGB scaling");
  795. return DDERR_NOALPHAHW;
  796. }
  797. }
  798. else if (argb.red != argb.alpha)
  799. {
  800. /*
  801. * Driver must be capable of doing 2-factor ARGB scaling.
  802. */
  803. if (!(alphacaps & (DDALPHACAPS_OVERLAYARGBSCALE2F |
  804. DDALPHACAPS_OVERLAYARGBSCALE4F)))
  805. {
  806. DPF_ERR("Driver can't handle 2-factor ARGB scaling");
  807. return DDERR_NOALPHAHW;
  808. }
  809. }
  810. }
  811. }
  812. // Save any modifications made to values of ARGB scaling factors.
  813. puod->overlayFX.ddargbScaleFactors = argb;
  814. return DD_OK;
  815. } /* checkOverlayAlpha */
  816. #endif
  817. /*
  818. * checkOverlayEmulation
  819. */
  820. __inline HRESULT checkOverlayEmulation(
  821. LPDDRAWI_DIRECTDRAW_GBL pdrv,
  822. LPDDRAWI_DDRAWSURFACE_LCL this_src_lcl,
  823. LPDDRAWI_DDRAWSURFACE_LCL this_dest_lcl,
  824. LPBOOL pemulation )
  825. {
  826. /*
  827. * check if emulated or hardware
  828. */
  829. if( (this_dest_lcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) ||
  830. (this_src_lcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) )
  831. {
  832. if( !(pdrv->ddHELCaps.dwCaps & DDCAPS_OVERLAY) )
  833. {
  834. DPF_ERR( "can't emulate overlays" );
  835. return DDERR_UNSUPPORTED;
  836. }
  837. *pemulation = TRUE;
  838. }
  839. /*
  840. * hardware overlays
  841. */
  842. else
  843. {
  844. if( !(pdrv->ddCaps.dwCaps & DDCAPS_OVERLAY) )
  845. {
  846. DPF_ERR( "no hardware overlay support" );
  847. return DDERR_NOOVERLAYHW;
  848. }
  849. *pemulation = FALSE;
  850. }
  851. return DD_OK;
  852. } /* checkOverlayEmulation */
  853. #ifdef WIN95
  854. /*
  855. * WillCauseOverlayArtifacts
  856. *
  857. * There is a latency between the time Update overlay is called and all of
  858. * the kernel mode surfaces structures are updated. If UpdateOverlay
  859. * updates the src pointer and an autoflip occurs before the kernel surface
  860. * data gets updated, it will cause a very visble jump. This function tries
  861. * to determine when this is the case so we can work around it by temporarily
  862. * disabling the video.
  863. */
  864. BOOL WillCauseOverlayArtifacts( LPDDRAWI_DDRAWSURFACE_LCL this_src_lcl,
  865. LPDDHAL_UPDATEOVERLAYDATA lpHALData )
  866. {
  867. if( ( this_src_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE ) &&
  868. !( lpHALData->dwFlags & DDOVER_HIDE ) &&
  869. ( ( lpHALData->rSrc.left != this_src_lcl->rcOverlaySrc.left ) ||
  870. ( lpHALData->rSrc.top != this_src_lcl->rcOverlaySrc.top ) ) )
  871. {
  872. return TRUE;
  873. }
  874. return FALSE;
  875. }
  876. #endif
  877. /*
  878. * DD_Surface_UpdateOverlay
  879. */
  880. HRESULT DDAPI DD_Surface_UpdateOverlay(
  881. LPDIRECTDRAWSURFACE lpDDSrcSurface,
  882. LPRECT lpSrcRect,
  883. LPDIRECTDRAWSURFACE lpDDDestSurface,
  884. LPRECT lpDestRect,
  885. DWORD dwFlags,
  886. LPDDOVERLAYFX lpDDOverlayFX )
  887. {
  888. DWORD rc;
  889. DDHAL_UPDATEOVERLAYDATA uod;
  890. LPDDRAWI_DDRAWSURFACE_INT this_src_int;
  891. LPDDRAWI_DDRAWSURFACE_LCL this_src_lcl;
  892. LPDDRAWI_DDRAWSURFACE_GBL this_src;
  893. LPDDRAWI_DDRAWSURFACE_INT this_dest_int;
  894. LPDDRAWI_DDRAWSURFACE_LCL this_dest_lcl;
  895. LPDDRAWI_DDRAWSURFACE_GBL this_dest;
  896. LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl;
  897. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  898. RECT rsrc;
  899. RECT rdest;
  900. BOOL emulation;
  901. DWORD dest_width;
  902. DWORD dest_height;
  903. DWORD src_width;
  904. DWORD src_height;
  905. LPDDHALSURFCB_UPDATEOVERLAY uohalfn;
  906. LPDDHALSURFCB_UPDATEOVERLAY uofn;
  907. HRESULT ddrval;
  908. #ifdef WIN95
  909. BOOL bAutoflipDisabled;
  910. #endif
  911. ENTER_DDRAW();
  912. DPF(2,A,"ENTERAPI: DD_Surface_UpdateOverlay");
  913. /*
  914. * validate parameters
  915. */
  916. TRY
  917. {
  918. this_src_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSrcSurface;
  919. if( !VALID_DIRECTDRAWSURFACE_PTR( this_src_int ) )
  920. {
  921. LEAVE_DDRAW();
  922. return DDERR_INVALIDOBJECT;
  923. }
  924. this_src_lcl = this_src_int->lpLcl;
  925. this_src = this_src_lcl->lpGbl;
  926. if( SURFACE_LOST( this_src_lcl ) )
  927. {
  928. LEAVE_DDRAW();
  929. return DDERR_SURFACELOST;
  930. }
  931. this_dest_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDDestSurface;
  932. if( !VALID_DIRECTDRAWSURFACE_PTR( this_dest_int ) )
  933. {
  934. LEAVE_DDRAW();
  935. return DDERR_INVALIDOBJECT;
  936. }
  937. this_dest_lcl = this_dest_int->lpLcl;
  938. this_dest = this_dest_lcl->lpGbl;
  939. if( SURFACE_LOST( this_dest_lcl ) )
  940. {
  941. LEAVE_DDRAW();
  942. return DDERR_SURFACELOST;
  943. }
  944. //
  945. // For now, if either surface is optimized, quit
  946. //
  947. if ((this_src_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED) ||
  948. (this_dest_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED))
  949. {
  950. DPF_ERR( "It is an optimized surface" );
  951. LEAVE_DDRAW();
  952. return DDERR_ISOPTIMIZEDSURFACE;
  953. }
  954. if( dwFlags & ~DDOVER_VALID )
  955. {
  956. DPF_ERR( "invalid flags" );
  957. LEAVE_DDRAW();
  958. return DDERR_INVALIDPARAMS;
  959. }
  960. if( lpDestRect != NULL )
  961. {
  962. if( !VALID_RECT_PTR( lpDestRect ) )
  963. {
  964. DPF_ERR( "invalid dest rect" );
  965. LEAVE_DDRAW();
  966. return DDERR_INVALIDRECT;
  967. }
  968. }
  969. if( lpSrcRect != NULL )
  970. {
  971. if( !VALID_RECT_PTR( lpSrcRect ) )
  972. {
  973. DPF_ERR( "invalid src rect" );
  974. LEAVE_DDRAW();
  975. return DDERR_INVALIDRECT;
  976. }
  977. }
  978. if( lpDDOverlayFX != NULL )
  979. {
  980. if( !VALID_DDOVERLAYFX_PTR( lpDDOverlayFX ) )
  981. {
  982. DPF_ERR( "invalid overlayfx" );
  983. LEAVE_DDRAW();
  984. return DDERR_INVALIDPARAMS;
  985. }
  986. }
  987. else
  988. {
  989. if( dwFlags & DDOVER_DDFX )
  990. {
  991. DPF_ERR( "DDOVER_DDFX requires valid DDOverlayFX structure" );
  992. LEAVE_DDRAW();
  993. return DDERR_INVALIDPARAMS;
  994. }
  995. }
  996. pdrv_lcl = this_dest_lcl->lpSurfMore->lpDD_lcl;
  997. pdrv = pdrv_lcl->lpGbl;
  998. /*
  999. * make sure the source surface is an overlay surface
  1000. */
  1001. if( !(this_src_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
  1002. {
  1003. DPF_ERR( "Source is not an overlay surface" );
  1004. LEAVE_DDRAW();
  1005. return DDERR_NOTAOVERLAYSURFACE;
  1006. }
  1007. /*
  1008. * make sure the destination is not an execute buffer
  1009. */
  1010. if( this_dest_lcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER )
  1011. {
  1012. DPF_ERR( "Invalid surface type: cannot overlay" );
  1013. LEAVE_DDRAW();
  1014. return DDERR_INVALIDSURFACETYPE;
  1015. }
  1016. /*
  1017. * Make sure that both surfaces belong to the same device.
  1018. */
  1019. if (this_src_lcl->lpSurfMore->lpDD_lcl->lpGbl != this_dest_lcl->lpSurfMore->lpDD_lcl->lpGbl)
  1020. {
  1021. DPF_ERR("Source and Destination surface must belong to the same device");
  1022. LEAVE_DDRAW();
  1023. return DDERR_DEVICEDOESNTOWNSURFACE;
  1024. }
  1025. /*
  1026. * check if emulated or not
  1027. */
  1028. ddrval = checkOverlayEmulation( pdrv, this_src_lcl, this_dest_lcl, &emulation );
  1029. if( ddrval != DD_OK )
  1030. {
  1031. LEAVE_DDRAW();
  1032. return ddrval;
  1033. }
  1034. #ifdef TOOMUCHOVERLAYVALIDATION
  1035. /*
  1036. * check if showing/hiding
  1037. */
  1038. if( dwFlags & DDOVER_SHOW )
  1039. {
  1040. if( this_src_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE )
  1041. {
  1042. DPF_ERR( "Overlay already shown" );
  1043. LEAVE_DDRAW();
  1044. return DDERR_GENERIC;
  1045. }
  1046. }
  1047. else if ( dwFlags & DDOVER_HIDE )
  1048. {
  1049. if( !(this_src_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE) )
  1050. {
  1051. DPF_ERR( "Overlay already hidden" );
  1052. LEAVE_DDRAW();
  1053. return DDERR_GENERIC;
  1054. }
  1055. }
  1056. #endif
  1057. /*
  1058. * set new rectangles if needed
  1059. */
  1060. if( lpDestRect == NULL )
  1061. {
  1062. MAKE_SURF_RECT( this_dest, this_dest_lcl, rdest );
  1063. lpDestRect = &rdest;
  1064. }
  1065. if( lpSrcRect == NULL )
  1066. {
  1067. MAKE_SURF_RECT( this_src, this_src_lcl, rsrc );
  1068. lpSrcRect = &rsrc;
  1069. }
  1070. /*
  1071. * Check if ring 0 interface is overriding what the client
  1072. * tells us to do
  1073. */
  1074. #ifdef WIN95
  1075. if( !( dwFlags & DDOVER_HIDE) )
  1076. {
  1077. OverrideOverlay( this_src_int, &dwFlags );
  1078. }
  1079. #endif
  1080. /*
  1081. * validate the rectangle dimensions
  1082. */
  1083. dest_height = lpDestRect->bottom - lpDestRect->top;
  1084. dest_width = lpDestRect->right - lpDestRect->left;
  1085. if( ((int)dest_height <= 0) || ((int)dest_width <= 0) ||
  1086. ((int)lpDestRect->top < 0) || ((int)lpDestRect->left < 0) ||
  1087. ((DWORD) lpDestRect->bottom > (DWORD) this_dest->wHeight) ||
  1088. ((DWORD) lpDestRect->right > (DWORD) this_dest->wWidth) )
  1089. {
  1090. DPF_ERR( "Invalid destination rect dimensions" );
  1091. LEAVE_DDRAW();
  1092. return DDERR_INVALIDRECT;
  1093. }
  1094. src_height = lpSrcRect->bottom - lpSrcRect->top;
  1095. src_width = lpSrcRect->right - lpSrcRect->left;
  1096. if( ((int)src_height <= 0) || ((int)src_width <= 0) ||
  1097. ((int)lpSrcRect->top < 0) || ((int)lpSrcRect->left < 0) ||
  1098. ((DWORD) lpSrcRect->bottom > (DWORD) this_src->wHeight) ||
  1099. ((DWORD) lpSrcRect->right > (DWORD) this_src->wWidth) )
  1100. {
  1101. DPF_ERR( "Invalid source rect dimensions" );
  1102. LEAVE_DDRAW();
  1103. return DDERR_INVALIDRECT;
  1104. }
  1105. /*
  1106. * validate alignment
  1107. */
  1108. if( !emulation )
  1109. {
  1110. if( pdrv->ddCaps.dwCaps & (DDCAPS_ALIGNBOUNDARYDEST |
  1111. DDCAPS_ALIGNSIZEDEST |
  1112. DDCAPS_ALIGNBOUNDARYSRC |
  1113. DDCAPS_ALIGNSIZESRC) )
  1114. {
  1115. if( pdrv->ddCaps.dwCaps & DDCAPS_ALIGNBOUNDARYDEST )
  1116. {
  1117. #if 0
  1118. /* GEE: I don't believe this code should be here
  1119. * only test alignment on width on height
  1120. */
  1121. if( (lpDestRect->top % pdrv->ddCaps.dwAlignBoundaryDest) != 0 )
  1122. {
  1123. DPF_ERR( "Destination top is not aligned correctly" );
  1124. LEAVE_DDRAW();
  1125. return DDERR_YALIGN;
  1126. }
  1127. #endif
  1128. if( (lpDestRect->left % pdrv->ddCaps.dwAlignBoundaryDest) != 0 )
  1129. {
  1130. DPF_ERR( "Destination left is not aligned correctly" );
  1131. LEAVE_DDRAW();
  1132. return DDERR_XALIGN;
  1133. }
  1134. }
  1135. if( pdrv->ddCaps.dwCaps & DDCAPS_ALIGNBOUNDARYSRC )
  1136. {
  1137. #if 0
  1138. /* GEE: I don't believe this code should be here
  1139. * only test alignment on width on height
  1140. */
  1141. if( (lpSrcRect->top % pdrv->ddCaps.dwAlignBoundarySrc) != 0 )
  1142. {
  1143. DPF_ERR( "Source top is not aligned correctly" );
  1144. LEAVE_DDRAW();
  1145. return DDERR_YALIGN;
  1146. }
  1147. #endif
  1148. if( (lpSrcRect->left % pdrv->ddCaps.dwAlignBoundarySrc) != 0 )
  1149. {
  1150. DPF_ERR( "Source left is not aligned correctly" );
  1151. LEAVE_DDRAW();
  1152. return DDERR_XALIGN;
  1153. }
  1154. }
  1155. if( pdrv->ddCaps.dwCaps & DDCAPS_ALIGNSIZEDEST )
  1156. {
  1157. if( (dest_width % pdrv->ddCaps.dwAlignSizeDest) != 0 )
  1158. {
  1159. DPF_ERR( "Destination width is not aligned correctly" );
  1160. LEAVE_DDRAW();
  1161. return DDERR_XALIGN;
  1162. }
  1163. #if 0
  1164. /* GEE: I don't believe this code should be here
  1165. * only test alignment for x axis
  1166. */
  1167. if( (dest_height % pdrv->ddCaps.dwAlignSizeDest) != 0 )
  1168. {
  1169. DPF_ERR( "Destination height is not aligned correctly" );
  1170. LEAVE_DDRAW();
  1171. return DDERR_HEIGHTALIGN;
  1172. }
  1173. #endif
  1174. }
  1175. if( pdrv->ddCaps.dwCaps & DDCAPS_ALIGNSIZESRC )
  1176. {
  1177. if( (src_width % pdrv->ddCaps.dwAlignSizeSrc) != 0 )
  1178. {
  1179. DPF_ERR( "Source width is not aligned correctly" );
  1180. LEAVE_DDRAW();
  1181. return DDERR_XALIGN;
  1182. }
  1183. #if 0
  1184. /* GEE: I don't believe this code should be here
  1185. * only test alignment for x axis
  1186. */
  1187. if( (src_height % pdrv->ddCaps.dwAlignSizeSrc) != 0 )
  1188. {
  1189. DPF_ERR( "Source height is not aligned correctly" );
  1190. LEAVE_DDRAW();
  1191. return DDERR_HEIGHTALIGN;
  1192. }
  1193. #endif
  1194. }
  1195. }
  1196. }
  1197. /*
  1198. * validate if stretching
  1199. */
  1200. if( !( dwFlags & DDOVER_HIDE) )
  1201. {
  1202. ddrval = checkOverlayStretching( pdrv,
  1203. dest_height,
  1204. dest_width,
  1205. src_height,
  1206. src_width,
  1207. this_src_lcl->ddsCaps.dwCaps,
  1208. emulation );
  1209. if( ddrval != DD_OK )
  1210. {
  1211. LEAVE_DDRAW();
  1212. return ddrval;
  1213. }
  1214. }
  1215. /*
  1216. * If the surface has recieved data from a video port, we will
  1217. * set/clear the DDOVER_INTERLEAVED flag accordingly. This
  1218. * makes life a little easier on the HAL.
  1219. */
  1220. if( ( this_src_lcl->ddsCaps.dwCaps & DDSCAPS_VIDEOPORT ) &&
  1221. ( this_src_lcl->lpGbl->dwGlobalFlags & DDRAWISURFGBL_VPORTDATA ) )
  1222. {
  1223. if( this_src_lcl->lpGbl->dwGlobalFlags & DDRAWISURFGBL_VPORTINTERLEAVED )
  1224. {
  1225. dwFlags |= DDOVER_INTERLEAVED;
  1226. }
  1227. else
  1228. {
  1229. dwFlags &= ~DDOVER_INTERLEAVED;
  1230. }
  1231. }
  1232. #if 0
  1233. /*
  1234. * If any kind of alpha blending is requested, make sure the specified
  1235. * alpha parameters are correct and that the driver supports alpha blending.
  1236. * If source has alpha channel, this call clears source color-key flags.
  1237. */
  1238. ddrval = checkOverlayAlpha( pdrv,
  1239. &dwFlags,
  1240. this_src_lcl,
  1241. &uod,
  1242. lpDDOverlayFX,
  1243. emulation );
  1244. if( ddrval != DD_OK )
  1245. {
  1246. LEAVE_DDRAW();
  1247. return ddrval;
  1248. }
  1249. #endif
  1250. /*
  1251. * any flags at all? if not, blow the whole thing off...
  1252. */
  1253. uod.overlayFX.dwSize = sizeof( DDOVERLAYFX );
  1254. if( dwFlags & FLAGS_TO_CHECK )
  1255. {
  1256. ddrval = checkOverlayFlags( pdrv,
  1257. &dwFlags,
  1258. this_src_int,
  1259. this_dest_lcl,
  1260. &uod,
  1261. lpDDOverlayFX,
  1262. emulation );
  1263. if( ddrval != DD_OK )
  1264. {
  1265. LEAVE_DDRAW();
  1266. return ddrval;
  1267. }
  1268. }
  1269. // check for overlay mirroring capability
  1270. if( dwFlags & DDOVER_DDFX )
  1271. {
  1272. if( lpDDOverlayFX->dwDDFX & DDOVERFX_MIRRORLEFTRIGHT )
  1273. {
  1274. if( !( pdrv->ddBothCaps.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT ) )
  1275. {
  1276. if( pdrv->ddHELCaps.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT )
  1277. {
  1278. emulation = TRUE;
  1279. }
  1280. }
  1281. }
  1282. if( lpDDOverlayFX->dwDDFX & DDOVERFX_MIRRORUPDOWN )
  1283. {
  1284. if( !( pdrv->ddBothCaps.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN ) )
  1285. {
  1286. if( pdrv->ddHELCaps.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN )
  1287. {
  1288. emulation = TRUE;
  1289. }
  1290. }
  1291. }
  1292. uod.overlayFX.dwDDFX = lpDDOverlayFX->dwDDFX;
  1293. // deinterlacing is a hint - if not supported by hardware, mask it off
  1294. if ( lpDDOverlayFX->dwDDFX & DDOVERFX_DEINTERLACE )
  1295. {
  1296. if ( !( pdrv->ddCaps.dwFXCaps & DDFXCAPS_OVERLAYDEINTERLACE ) )
  1297. {
  1298. uod.overlayFX.dwDDFX &= ~DDOVERFX_DEINTERLACE;
  1299. }
  1300. }
  1301. }
  1302. /*
  1303. * pick fns to use
  1304. */
  1305. if( emulation )
  1306. {
  1307. uofn = pdrv_lcl->lpDDCB->HELDDSurface.UpdateOverlay;
  1308. uohalfn = uofn;
  1309. }
  1310. else
  1311. {
  1312. uofn = pdrv_lcl->lpDDCB->HALDDSurface.UpdateOverlay;
  1313. uohalfn = pdrv_lcl->lpDDCB->cbDDSurfaceCallbacks.UpdateOverlay;
  1314. }
  1315. }
  1316. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  1317. {
  1318. DPF_ERR( "Exception encountered validating parameters" );
  1319. LEAVE_DDRAW();
  1320. return DDERR_INVALIDPARAMS;
  1321. }
  1322. /*
  1323. * call the driver
  1324. */
  1325. #ifdef WIN95
  1326. bAutoflipDisabled = FALSE;
  1327. #endif
  1328. if( uohalfn != NULL )
  1329. {
  1330. BOOL original_visible;
  1331. // Set the visible flag according to the show and hide bits
  1332. // If the HAL call fails, restore the visible bit to its original
  1333. // state. The HEL uses the DDSCAPS_VISIBLE bit to determine
  1334. // whether or not to display the overlay.
  1335. if( this_src_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE )
  1336. {
  1337. original_visible = TRUE;
  1338. }
  1339. else
  1340. {
  1341. original_visible = FALSE;
  1342. }
  1343. if( dwFlags & DDOVER_SHOW )
  1344. {
  1345. this_src_lcl->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
  1346. }
  1347. else if ( dwFlags & DDOVER_HIDE )
  1348. {
  1349. this_src_lcl->ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
  1350. }
  1351. uod.UpdateOverlay = uohalfn;
  1352. uod.lpDD = pdrv;
  1353. uod.lpDDSrcSurface = this_src_lcl;
  1354. uod.lpDDDestSurface = this_dest_lcl;
  1355. uod.rDest = *(LPRECTL) lpDestRect;
  1356. uod.rSrc = *(LPRECTL) lpSrcRect;
  1357. uod.dwFlags = dwFlags;
  1358. if( this_src->dwGlobalFlags & DDRAWISURFGBL_SOFTWAREAUTOFLIP )
  1359. {
  1360. uod.dwFlags &= ~( DDOVER_AUTOFLIP | DDOVER_BOBHARDWARE );
  1361. #ifdef WIN95
  1362. if( WillCauseOverlayArtifacts( this_src_lcl, &uod ) )
  1363. {
  1364. // Eliminate artifacts by temporarily freezing the video
  1365. EnableAutoflip( GetVideoPortFromSurface( this_src_int ), FALSE );
  1366. bAutoflipDisabled = TRUE;
  1367. }
  1368. #endif
  1369. }
  1370. /*
  1371. * Don't call the HAL if we're in a DOS box (the busy bit will be set),
  1372. * but we also cant fail or this might cause a regression.
  1373. */
  1374. #ifdef WIN95
  1375. if( ( *(pdrv->lpwPDeviceFlags) & BUSY ) &&
  1376. ( pdrv->dwSurfaceLockCount == 0) ) // Don't fail if it's busy due to a lock
  1377. {
  1378. rc = DDHAL_DRIVER_HANDLED;
  1379. uod.ddRVal = DD_OK;
  1380. }
  1381. else
  1382. #endif
  1383. {
  1384. #ifndef WINNT
  1385. // Hack to work around s3 driver bug: it crushes the dest surface's
  1386. // dwReserved1 with the src pointer!!!
  1387. UINT_PTR dwTemp = uod.lpDDDestSurface->lpGbl->dwReserved1;
  1388. #endif
  1389. DOHALCALL( UpdateOverlay, uofn, uod, rc, emulation );
  1390. #ifndef WINNT
  1391. // Note the STB video rage 2 driver trashes uod.lpDDDestSurface and
  1392. // uod.lpDDSrcSurface pointers, so we must check the driver name first.
  1393. if (((*(LPWORD)(&pdrv->dd32BitDriverData.szName)) == ((WORD)'S' + (((WORD)'3')<<8))) &&
  1394. (uod.lpDDDestSurface->lpGbl->dwReserved1 != dwTemp) &&
  1395. (uod.lpDDDestSurface->lpGbl->dwReserved1 == (UINT_PTR)uod.lpDDSrcSurface))
  1396. {
  1397. uod.lpDDDestSurface->lpGbl->dwReserved1 = dwTemp;
  1398. }
  1399. #endif
  1400. }
  1401. /*
  1402. * If it failed due to hardware autoflipping or bobbing interleaved
  1403. * data using a video port, try again w/o
  1404. */
  1405. if( ( rc == DDHAL_DRIVER_HANDLED ) &&
  1406. ( uod.ddRVal != DD_OK ) && ( ( uod.dwFlags & DDOVER_AUTOFLIP ) ||
  1407. ( uod.dwFlags & DDOVER_BOBHARDWARE ) ) &&
  1408. CanSoftwareAutoflip( GetVideoPortFromSurface( this_src_int ) ) )
  1409. {
  1410. uod.dwFlags &= ~( DDOVER_AUTOFLIP | DDOVER_BOBHARDWARE );
  1411. DOHALCALL( UpdateOverlay, uofn, uod, rc, emulation );
  1412. if( ( rc == DDHAL_DRIVER_HANDLED ) &&
  1413. ( uod.ddRVal == DD_OK ) )
  1414. {
  1415. if( dwFlags & DDOVER_AUTOFLIP )
  1416. {
  1417. this_src_lcl->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_SOFTWAREAUTOFLIP;
  1418. RequireSoftwareAutoflip( this_src_int );
  1419. }
  1420. if( dwFlags & DDOVER_BOBHARDWARE )
  1421. {
  1422. RequireSoftwareBob( this_src_int );
  1423. }
  1424. }
  1425. }
  1426. // if the HAL call failed, restore the visible bit
  1427. if( ( rc != DDHAL_DRIVER_HANDLED ) || ( uod.ddRVal != DD_OK ) )
  1428. {
  1429. if( original_visible )
  1430. {
  1431. this_src_lcl->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
  1432. }
  1433. else
  1434. {
  1435. this_src_lcl->ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
  1436. }
  1437. }
  1438. if( rc == DDHAL_DRIVER_HANDLED )
  1439. {
  1440. if( uod.ddRVal == DD_OK )
  1441. {
  1442. LPDDRAWI_DDRAWSURFACE_INT surf_first;
  1443. LPDDRAWI_DDRAWSURFACE_INT surf_temp;
  1444. /*
  1445. * Store this info for later use. If the surface is part
  1446. * of a chain, store this data for each of the surfaces in
  1447. * the chain.
  1448. */
  1449. surf_first = surf_temp = this_src_int;
  1450. do
  1451. {
  1452. surf_temp->lpLcl->lOverlayX = uod.rDest.left;
  1453. surf_temp->lpLcl->lOverlayY = uod.rDest.top;
  1454. surf_temp->lpLcl->rcOverlayDest.left = uod.rDest.left;
  1455. surf_temp->lpLcl->rcOverlayDest.top = uod.rDest.top;
  1456. surf_temp->lpLcl->rcOverlayDest.right = uod.rDest.right;
  1457. surf_temp->lpLcl->rcOverlayDest.bottom = uod.rDest.bottom;
  1458. surf_temp->lpLcl->rcOverlaySrc.left = uod.rSrc.left;
  1459. surf_temp->lpLcl->rcOverlaySrc.top = uod.rSrc.top;
  1460. surf_temp->lpLcl->rcOverlaySrc.right = uod.rSrc.right;
  1461. surf_temp->lpLcl->rcOverlaySrc.bottom = uod.rSrc.bottom;
  1462. surf_temp->lpLcl->lpSurfMore->dwOverlayFlags = dwFlags;
  1463. if( dwFlags & DDOVER_DDFX )
  1464. {
  1465. if( surf_temp->lpLcl->lpSurfMore->lpddOverlayFX == NULL )
  1466. {
  1467. surf_temp->lpLcl->lpSurfMore->lpddOverlayFX =
  1468. (LPDDOVERLAYFX) MemAlloc( sizeof( DDOVERLAYFX ) );
  1469. }
  1470. if( surf_temp->lpLcl->lpSurfMore->lpddOverlayFX != NULL )
  1471. {
  1472. memcpy( surf_temp->lpLcl->lpSurfMore->lpddOverlayFX,
  1473. lpDDOverlayFX, sizeof( DDOVERLAYFX) );
  1474. }
  1475. }
  1476. #ifdef WIN95
  1477. UpdateKernelSurface( surf_temp->lpLcl );
  1478. #endif
  1479. surf_temp = FindAttachedFlip( surf_temp );
  1480. } while( ( surf_temp != NULL ) && ( surf_temp->lpLcl != surf_first->lpLcl ) );
  1481. /*
  1482. * update refcnt if this is a new surface we are overlaying
  1483. */
  1484. if( this_src_lcl->lpSurfaceOverlaying != this_dest_int )
  1485. {
  1486. if(this_src_lcl->lpSurfaceOverlaying != NULL)
  1487. {
  1488. /*
  1489. * This overlay was previously overlaying another surface.
  1490. */
  1491. DD_Surface_Release(
  1492. (LPDIRECTDRAWSURFACE)(this_src_lcl->lpSurfaceOverlaying) );
  1493. }
  1494. this_src_lcl->lpSurfaceOverlaying = this_dest_int;
  1495. /*
  1496. * addref overlayed surface so that it won't be destroyed until
  1497. * all surfaces which overlay it are destroyed.
  1498. */
  1499. DD_Surface_AddRef( (LPDIRECTDRAWSURFACE) this_dest_int );
  1500. }
  1501. }
  1502. #ifdef WIN95
  1503. if( bAutoflipDisabled )
  1504. {
  1505. EnableAutoflip( GetVideoPortFromSurface( this_src_int ), TRUE );
  1506. }
  1507. #endif
  1508. LEAVE_DDRAW();
  1509. return uod.ddRVal;
  1510. }
  1511. #ifdef WIN95
  1512. if( bAutoflipDisabled )
  1513. {
  1514. EnableAutoflip( GetVideoPortFromSurface( this_src_int ), TRUE );
  1515. }
  1516. #endif
  1517. }
  1518. LEAVE_DDRAW();
  1519. return DDERR_UNSUPPORTED;
  1520. } /* DD_Surface_UpdateOverlay */
  1521. #undef DPF_MODNAME
  1522. #define DPF_MODNAME "GetOverlayPosition"
  1523. /*
  1524. * DD_Surface_GetOverlayPosition
  1525. */
  1526. HRESULT DDAPI DD_Surface_GetOverlayPosition(
  1527. LPDIRECTDRAWSURFACE lpDDSurface,
  1528. LPLONG lplXPos,
  1529. LPLONG lplYPos)
  1530. {
  1531. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  1532. LPDDRAWI_DDRAWSURFACE_INT this_int;
  1533. LPDDRAWI_DDRAWSURFACE_LCL this_lcl;
  1534. LPDDRAWI_DDRAWSURFACE_GBL this;
  1535. ENTER_DDRAW();
  1536. DPF(2,A,"ENTERAPI: DD_Surface_GetOverlayPosition");
  1537. TRY
  1538. {
  1539. this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  1540. if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
  1541. {
  1542. LEAVE_DDRAW();
  1543. return DDERR_INVALIDOBJECT;
  1544. }
  1545. this_lcl = this_int->lpLcl;
  1546. this = this_lcl->lpGbl;
  1547. if( !VALID_DWORD_PTR( lplXPos ) )
  1548. {
  1549. LEAVE_DDRAW();
  1550. return DDERR_INVALIDPARAMS;
  1551. }
  1552. *lplXPos = 0;
  1553. if( !VALID_DWORD_PTR( lplYPos ) )
  1554. {
  1555. LEAVE_DDRAW();
  1556. return DDERR_INVALIDPARAMS;
  1557. }
  1558. *lplYPos = 0;
  1559. if( SURFACE_LOST( this_lcl ) )
  1560. {
  1561. LEAVE_DDRAW();
  1562. return DDERR_SURFACELOST;
  1563. }
  1564. pdrv = this->lpDD;
  1565. //
  1566. // For now, if the current surface is optimized, quit
  1567. //
  1568. if (this_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED)
  1569. {
  1570. DPF_ERR( "It is an optimized surface" );
  1571. LEAVE_DDRAW();
  1572. return DDERR_ISOPTIMIZEDSURFACE;
  1573. }
  1574. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
  1575. {
  1576. DPF_ERR( "Surface is not an overlay surface" );
  1577. LEAVE_DDRAW();
  1578. return DDERR_NOTAOVERLAYSURFACE;
  1579. }
  1580. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE) )
  1581. {
  1582. DPF_ERR( "Overlay surface is not visible" );
  1583. LEAVE_DDRAW();
  1584. return DDERR_OVERLAYNOTVISIBLE;
  1585. }
  1586. if( this_lcl->lpSurfaceOverlaying == NULL )
  1587. {
  1588. DPF_ERR( "Overlay not activated" );
  1589. LEAVE_DDRAW();
  1590. return DDERR_NOOVERLAYDEST;
  1591. }
  1592. }
  1593. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  1594. {
  1595. DPF_ERR( "Exception encountered validating parameters" );
  1596. LEAVE_DDRAW();
  1597. return DDERR_INVALIDPARAMS;
  1598. }
  1599. *lplXPos = this_lcl->lOverlayX;
  1600. *lplYPos = this_lcl->lOverlayY;
  1601. LEAVE_DDRAW();
  1602. return DD_OK;
  1603. } /* DD_Surface_GetOverlayPosition */
  1604. #undef DPF_MODNAME
  1605. #define DPF_MODNAME "SetOverlayPosition"
  1606. /*
  1607. * DD_Surface_SetOverlayPosition
  1608. */
  1609. HRESULT DDAPI DD_Surface_SetOverlayPosition(
  1610. LPDIRECTDRAWSURFACE lpDDSurface,
  1611. LONG lXPos,
  1612. LONG lYPos)
  1613. {
  1614. LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl;
  1615. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  1616. LPDDRAWI_DDRAWSURFACE_INT psurfover_int;
  1617. LPDDRAWI_DDRAWSURFACE_LCL psurfover_lcl;
  1618. LPDDRAWI_DDRAWSURFACE_INT this_int;
  1619. LPDDRAWI_DDRAWSURFACE_LCL this_lcl;
  1620. LPDDRAWI_DDRAWSURFACE_GBL this;
  1621. BOOL emulation;
  1622. LPDDHALSURFCB_SETOVERLAYPOSITION sophalfn;
  1623. LPDDHALSURFCB_SETOVERLAYPOSITION sopfn;
  1624. DDHAL_SETOVERLAYPOSITIONDATA sopd;
  1625. HRESULT ddrval;
  1626. DWORD rc;
  1627. ENTER_DDRAW();
  1628. DPF(2,A,"ENTERAPI: DD_Surface_SetOverlayPosition");
  1629. TRY
  1630. {
  1631. this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  1632. if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
  1633. {
  1634. LEAVE_DDRAW();
  1635. return DDERR_INVALIDOBJECT;
  1636. }
  1637. this_lcl = this_int->lpLcl;
  1638. this = this_lcl->lpGbl;
  1639. if( SURFACE_LOST( this_lcl ) )
  1640. {
  1641. LEAVE_DDRAW();
  1642. return DDERR_SURFACELOST;
  1643. }
  1644. pdrv_lcl = this_lcl->lpSurfMore->lpDD_lcl;
  1645. pdrv = pdrv_lcl->lpGbl;
  1646. //
  1647. // For now, if the current surface is optimized, quit
  1648. //
  1649. if (this_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED)
  1650. {
  1651. DPF_ERR( "It is an optimized surface" );
  1652. LEAVE_DDRAW();
  1653. return DDERR_ISOPTIMIZEDSURFACE;
  1654. }
  1655. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
  1656. {
  1657. DPF_ERR( "Surface is not an overlay surface" );
  1658. LEAVE_DDRAW();
  1659. return DDERR_NOTAOVERLAYSURFACE;
  1660. }
  1661. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE) )
  1662. {
  1663. DPF_ERR( "Overlay surface is not visible" );
  1664. LEAVE_DDRAW();
  1665. return DDERR_OVERLAYNOTVISIBLE;
  1666. }
  1667. psurfover_int = this_lcl->lpSurfaceOverlaying;
  1668. if( psurfover_int == NULL )
  1669. {
  1670. DPF_ERR( "Overlay not activated" );
  1671. LEAVE_DDRAW();
  1672. return DDERR_NOOVERLAYDEST;
  1673. }
  1674. psurfover_lcl = psurfover_int->lpLcl;
  1675. if( (lYPos > (LONG) psurfover_lcl->lpGbl->wHeight -
  1676. (this_lcl->rcOverlayDest.bottom - this_lcl->rcOverlayDest.top)) ||
  1677. (lXPos > (LONG) psurfover_lcl->lpGbl->wWidth -
  1678. (this_lcl->rcOverlayDest.right - this_lcl->rcOverlayDest.left) ) ||
  1679. (lYPos < 0) ||
  1680. (lXPos < 0) )
  1681. {
  1682. DPF_ERR( "Invalid overlay position" );
  1683. LEAVE_DDRAW();
  1684. return DDERR_INVALIDPOSITION;
  1685. }
  1686. }
  1687. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  1688. {
  1689. DPF_ERR( "Exception encountered validating parameters" );
  1690. LEAVE_DDRAW();
  1691. return DDERR_INVALIDPARAMS;
  1692. }
  1693. /*
  1694. * check if emulated or not
  1695. */
  1696. ddrval = checkOverlayEmulation( pdrv, this_lcl, psurfover_lcl, &emulation );
  1697. if( ddrval != DD_OK )
  1698. {
  1699. LEAVE_DDRAW();
  1700. return ddrval;
  1701. }
  1702. /*
  1703. * pick fns to use
  1704. */
  1705. if( emulation )
  1706. {
  1707. sopfn = pdrv_lcl->lpDDCB->HELDDSurface.SetOverlayPosition;
  1708. sophalfn = sopfn;
  1709. }
  1710. else
  1711. {
  1712. sopfn = pdrv_lcl->lpDDCB->HALDDSurface.SetOverlayPosition;
  1713. sophalfn = pdrv_lcl->lpDDCB->cbDDSurfaceCallbacks.SetOverlayPosition;
  1714. }
  1715. /*
  1716. * call the driver
  1717. */
  1718. if( sophalfn != NULL )
  1719. {
  1720. sopd.SetOverlayPosition = sophalfn;
  1721. sopd.lpDD = pdrv;
  1722. sopd.lpDDSrcSurface = this_lcl;
  1723. sopd.lpDDDestSurface = psurfover_lcl;
  1724. sopd.lXPos = lXPos;
  1725. sopd.lYPos = lYPos;
  1726. /*
  1727. * Don't call the HAL if we're in a DOS box (the busy bit will be set),
  1728. * but we also cant fail or this might cause a regression.
  1729. */
  1730. #if WIN95
  1731. if( *(pdrv->lpwPDeviceFlags) & BUSY )
  1732. {
  1733. rc = DDHAL_DRIVER_HANDLED;
  1734. sopd.ddRVal = DD_OK;
  1735. }
  1736. else
  1737. #endif
  1738. {
  1739. DOHALCALL( SetOverlayPosition, sopfn, sopd, rc, emulation );
  1740. }
  1741. if( rc == DDHAL_DRIVER_HANDLED )
  1742. {
  1743. LEAVE_DDRAW();
  1744. if( sopd.ddRVal == DD_OK )
  1745. {
  1746. this_lcl->lOverlayX = lXPos;
  1747. this_lcl->lOverlayY = lYPos;
  1748. this_lcl->rcOverlayDest.right =
  1749. ( this_lcl->rcOverlayDest.right -
  1750. this_lcl->rcOverlayDest.left ) + lXPos;
  1751. this_lcl->rcOverlayDest.left = lXPos;
  1752. this_lcl->rcOverlayDest.bottom =
  1753. ( this_lcl->rcOverlayDest.bottom -
  1754. this_lcl->rcOverlayDest.top ) + lYPos;
  1755. this_lcl->rcOverlayDest.top = lYPos;
  1756. }
  1757. return sopd.ddRVal;
  1758. }
  1759. }
  1760. LEAVE_DDRAW();
  1761. return DDERR_UNSUPPORTED;
  1762. } /* DD_Surface_SetOverlayPosition */
  1763. #undef DPF_MODNAME
  1764. #define DPF_MODNAME "UpdateOverlayZOrder"
  1765. /*
  1766. * DD_Surface_UpdateOverlayZOrder
  1767. */
  1768. HRESULT DDAPI DD_Surface_UpdateOverlayZOrder(
  1769. LPDIRECTDRAWSURFACE lpDDSurface,
  1770. DWORD dwFlags,
  1771. LPDIRECTDRAWSURFACE lpDDSReference)
  1772. {
  1773. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  1774. LPDDRAWI_DDRAWSURFACE_INT this_int;
  1775. LPDDRAWI_DDRAWSURFACE_LCL this_lcl;
  1776. LPDDRAWI_DDRAWSURFACE_GBL this;
  1777. LPDDRAWI_DDRAWSURFACE_INT psurf_ref_int;
  1778. LPDDRAWI_DDRAWSURFACE_LCL psurf_ref_lcl;
  1779. LPDDRAWI_DDRAWSURFACE_GBL psurf_ref;
  1780. LPDBLNODE pdbnNode;
  1781. LPDBLNODE pdbnRef;
  1782. DWORD ddrval;
  1783. ENTER_DDRAW();
  1784. DPF(2,A,"ENTERAPI: DD_Surface_UpdateOverlayZOrder");
  1785. /*
  1786. * validate parameters
  1787. */
  1788. TRY
  1789. {
  1790. this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  1791. if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
  1792. {
  1793. LEAVE_DDRAW();
  1794. return DDERR_INVALIDOBJECT;
  1795. }
  1796. this_lcl = this_int->lpLcl;
  1797. this = this_lcl->lpGbl;
  1798. pdrv = this->lpDD;
  1799. //
  1800. // For now, if the current surface is optimized, quit
  1801. //
  1802. if (this_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED)
  1803. {
  1804. DPF_ERR( "It is an optimized surface" );
  1805. LEAVE_DDRAW();
  1806. return DDERR_ISOPTIMIZEDSURFACE;
  1807. }
  1808. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
  1809. {
  1810. DPF_ERR( "Surface is not an overlay surface" );
  1811. LEAVE_DDRAW();
  1812. return DDERR_NOTAOVERLAYSURFACE;
  1813. }
  1814. switch(dwFlags)
  1815. {
  1816. case DDOVERZ_SENDTOFRONT:
  1817. pdbnNode = &(this_lcl->dbnOverlayNode);
  1818. // the reference node is the root
  1819. pdbnRef = &(this->lpDD->dbnOverlayRoot);
  1820. // Delete surface from current position
  1821. pdbnNode->prev->next = pdbnNode->next;
  1822. pdbnNode->next->prev = pdbnNode->prev;
  1823. // insert this node after the root node
  1824. pdbnNode->next = pdbnRef->next;
  1825. pdbnNode->prev = pdbnRef;
  1826. pdbnRef->next = pdbnNode;
  1827. pdbnNode->next->prev = pdbnNode;
  1828. break;
  1829. case DDOVERZ_SENDTOBACK:
  1830. pdbnNode = &(this_lcl->dbnOverlayNode);
  1831. // the reference node is the root
  1832. pdbnRef = &(this->lpDD->dbnOverlayRoot);
  1833. // Delete surface from current position
  1834. pdbnNode->prev->next = pdbnNode->next;
  1835. pdbnNode->next->prev = pdbnNode->prev;
  1836. // insert this node before the root node
  1837. pdbnNode->next = pdbnRef;
  1838. pdbnNode->prev = pdbnRef->prev;
  1839. pdbnRef->prev = pdbnNode;
  1840. pdbnNode->prev->next = pdbnNode;
  1841. break;
  1842. case DDOVERZ_MOVEFORWARD:
  1843. pdbnNode = &(this_lcl->dbnOverlayNode);
  1844. // the reference node is the previous node
  1845. pdbnRef = pdbnNode->prev;
  1846. if(pdbnRef != &(this->lpDD->dbnOverlayRoot)) // node already first?
  1847. {
  1848. // move node forward one position by inserting before ref node
  1849. // Delete surface from current position
  1850. pdbnNode->prev->next = pdbnNode->next;
  1851. pdbnNode->next->prev = pdbnNode->prev;
  1852. // insert this node before the ref node
  1853. pdbnNode->next = pdbnRef;
  1854. pdbnNode->prev = pdbnRef->prev;
  1855. pdbnRef->prev = pdbnNode;
  1856. pdbnNode->prev->next = pdbnNode;
  1857. }
  1858. break;
  1859. case DDOVERZ_MOVEBACKWARD:
  1860. pdbnNode = &(this_lcl->dbnOverlayNode);
  1861. // the reference node is the next node
  1862. pdbnRef = pdbnNode->next;
  1863. if(pdbnRef != &(this->lpDD->dbnOverlayRoot)) // node already last?
  1864. {
  1865. // move node backward one position by inserting after ref node
  1866. // Delete surface from current position
  1867. pdbnNode->prev->next = pdbnNode->next;
  1868. pdbnNode->next->prev = pdbnNode->prev;
  1869. // insert this node after the reference node
  1870. pdbnNode->next = pdbnRef->next;
  1871. pdbnNode->prev = pdbnRef;
  1872. pdbnRef->next = pdbnNode;
  1873. pdbnNode->next->prev = pdbnNode;
  1874. }
  1875. break;
  1876. case DDOVERZ_INSERTINBACKOF:
  1877. case DDOVERZ_INSERTINFRONTOF:
  1878. psurf_ref_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSReference;
  1879. if( !VALID_DIRECTDRAWSURFACE_PTR( psurf_ref_int ) )
  1880. {
  1881. DPF_ERR( "Invalid reference surface ptr" );
  1882. LEAVE_DDRAW();
  1883. return DDERR_INVALIDOBJECT;
  1884. }
  1885. psurf_ref_lcl = psurf_ref_int->lpLcl;
  1886. psurf_ref = psurf_ref_lcl->lpGbl;
  1887. if( !(psurf_ref_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
  1888. {
  1889. DPF_ERR( "reference surface is not an overlay" );
  1890. LEAVE_DDRAW();
  1891. return DDERR_NOTAOVERLAYSURFACE;
  1892. }
  1893. if (this_lcl->lpSurfMore->lpDD_lcl->lpGbl != psurf_ref_lcl->lpSurfMore->lpDD_lcl->lpGbl)
  1894. {
  1895. DPF_ERR("Surfaces must belong to the same device");
  1896. LEAVE_DDRAW();
  1897. return DDERR_DEVICEDOESNTOWNSURFACE;
  1898. }
  1899. // Search for the reference surface in the Z Order list
  1900. pdbnNode = &(this->lpDD->dbnOverlayRoot); // pdbnNode points to root
  1901. for(pdbnRef=pdbnNode->next;
  1902. pdbnRef != pdbnNode;
  1903. pdbnRef = pdbnRef->next )
  1904. {
  1905. if( pdbnRef->object == psurf_ref_lcl )
  1906. {
  1907. break;
  1908. }
  1909. }
  1910. if(pdbnRef == pdbnNode) // didn't find the reference node
  1911. {
  1912. DPF_ERR( "Reference Surface not in Z Order list" );
  1913. LEAVE_DDRAW();
  1914. return DDERR_INVALIDPARAMS;
  1915. }
  1916. pdbnNode = &(this_lcl->dbnOverlayNode); // pdbnNode points to this node
  1917. // Delete this surface from its current position
  1918. pdbnNode->prev->next = pdbnNode->next;
  1919. pdbnNode->next->prev = pdbnNode->prev;
  1920. if(dwFlags == DDOVERZ_INSERTINFRONTOF)
  1921. {
  1922. // insert this node before the ref node
  1923. pdbnNode->next = pdbnRef;
  1924. pdbnNode->prev = pdbnRef->prev;
  1925. pdbnRef->prev = pdbnNode;
  1926. pdbnNode->prev->next = pdbnNode;
  1927. }
  1928. else
  1929. {
  1930. // insert this node after the ref node
  1931. pdbnNode->next = pdbnRef->next;
  1932. pdbnNode->prev = pdbnRef;
  1933. pdbnRef->next = pdbnNode;
  1934. pdbnNode->next->prev = pdbnNode;
  1935. }
  1936. break;
  1937. default:
  1938. DPF_ERR( "Invalid dwFlags in UpdateOverlayZOrder" );
  1939. LEAVE_DDRAW();
  1940. return DDERR_INVALIDPARAMS;
  1941. }
  1942. }
  1943. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  1944. {
  1945. DPF_ERR( "Exception encountered validating parameters" );
  1946. LEAVE_DDRAW();
  1947. return DDERR_INVALIDPARAMS;
  1948. }
  1949. /*
  1950. * If this surface is overlaying an emulated surface, we must notify
  1951. * the HEL that it needs to eventually update the part of the surface
  1952. * touched by this overlay.
  1953. */
  1954. ddrval = DD_OK;
  1955. if( this_lcl->lpSurfaceOverlaying != NULL )
  1956. {
  1957. /*
  1958. * We have a pointer to the surface being overlayed, check to
  1959. * see if it is being emulated.
  1960. */
  1961. if( this_lcl->lpSurfaceOverlaying->lpLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY )
  1962. {
  1963. /*
  1964. * Mark the destination region of this overlay as dirty.
  1965. */
  1966. DD_Surface_AddOverlayDirtyRect(
  1967. (LPDIRECTDRAWSURFACE)(this_lcl->lpSurfaceOverlaying),
  1968. &(this_lcl->rcOverlayDest) );
  1969. }
  1970. /*
  1971. * If the overlay is on, call down to the HAL
  1972. */
  1973. if( this_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE )
  1974. {
  1975. if( ( this_lcl->lpSurfMore->dwOverlayFlags & DDOVER_DDFX ) &&
  1976. ( this_lcl->lpSurfMore->lpddOverlayFX != NULL ) )
  1977. {
  1978. ddrval = DD_Surface_UpdateOverlay(
  1979. (LPDIRECTDRAWSURFACE) this_int,
  1980. &(this_lcl->rcOverlaySrc),
  1981. (LPDIRECTDRAWSURFACE) this_lcl->lpSurfaceOverlaying,
  1982. &(this_lcl->rcOverlayDest),
  1983. this_lcl->lpSurfMore->dwOverlayFlags,
  1984. this_lcl->lpSurfMore->lpddOverlayFX );
  1985. }
  1986. else
  1987. {
  1988. ddrval = DD_Surface_UpdateOverlay(
  1989. (LPDIRECTDRAWSURFACE) this_int,
  1990. &(this_lcl->rcOverlaySrc),
  1991. (LPDIRECTDRAWSURFACE) this_lcl->lpSurfaceOverlaying,
  1992. &(this_lcl->rcOverlayDest),
  1993. this_lcl->lpSurfMore->dwOverlayFlags,
  1994. NULL );
  1995. }
  1996. }
  1997. }
  1998. LEAVE_DDRAW();
  1999. return ddrval;
  2000. } /* DD_Surface_UpdateOverlayZOrder */
  2001. #undef DPF_MODNAME
  2002. #define DPF_MODNAME "EnumOverlayZOrders"
  2003. /*
  2004. * DD_Surface_EnumOverlayZOrders
  2005. */
  2006. HRESULT DDAPI DD_Surface_EnumOverlayZOrders(
  2007. LPDIRECTDRAWSURFACE lpDDSurface,
  2008. DWORD dwFlags,
  2009. LPVOID lpContext,
  2010. LPDDENUMSURFACESCALLBACK lpfnCallback)
  2011. {
  2012. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  2013. LPDDRAWI_DDRAWSURFACE_INT this_int;
  2014. LPDDRAWI_DDRAWSURFACE_LCL this_lcl;
  2015. LPDDRAWI_DDRAWSURFACE_GBL this;
  2016. LPDBLNODE pRoot;
  2017. LPDBLNODE pdbn;
  2018. DDSURFACEDESC2 ddsd;
  2019. DWORD rc;
  2020. ENTER_DDRAW();
  2021. DPF(2,A,"ENTERAPI: DD_Surface_EnumOverlayZOrders");
  2022. /*
  2023. * validate parameters
  2024. */
  2025. TRY
  2026. {
  2027. this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  2028. if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
  2029. {
  2030. LEAVE_DDRAW();
  2031. return DDERR_INVALIDOBJECT;
  2032. }
  2033. this_lcl = this_int->lpLcl;
  2034. if( !VALIDEX_CODE_PTR( lpfnCallback ) )
  2035. {
  2036. DPF_ERR( "Invalid callback routine" );
  2037. LEAVE_DDRAW();
  2038. return DDERR_INVALIDPARAMS;
  2039. }
  2040. this = this_lcl->lpGbl;
  2041. pdrv = this->lpDD;
  2042. pRoot = &(pdrv->dbnOverlayRoot); // save address of root node
  2043. }
  2044. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  2045. {
  2046. DPF_ERR( "Exception encountered validating parameters" );
  2047. LEAVE_DDRAW();
  2048. return DDERR_INVALIDPARAMS;
  2049. }
  2050. //
  2051. // If the current surface is optimized, quit
  2052. //
  2053. if (this_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED)
  2054. {
  2055. DPF_ERR( "It is an optimized surface" );
  2056. LEAVE_DDRAW();
  2057. return DDERR_ISOPTIMIZEDSURFACE;
  2058. }
  2059. if( dwFlags == DDENUMOVERLAYZ_FRONTTOBACK )
  2060. {
  2061. pdbn = pRoot->next;
  2062. while(pdbn != pRoot)
  2063. {
  2064. LPDIRECTDRAWSURFACE7 intReturned = (LPDIRECTDRAWSURFACE7) pdbn->object_int;
  2065. FillDDSurfaceDesc2( pdbn->object, &ddsd );
  2066. if (LOWERTHANSURFACE4(this_int))
  2067. {
  2068. ddsd.dwSize = sizeof(DDSURFACEDESC);
  2069. DD_Surface_QueryInterface( (LPDIRECTDRAWSURFACE) intReturned, & IID_IDirectDrawSurface, (void**) & intReturned );
  2070. }
  2071. else if (this_int->lpVtbl == &ddSurface4Callbacks)
  2072. {
  2073. DD_Surface_QueryInterface( (LPDIRECTDRAWSURFACE) intReturned, & IID_IDirectDrawSurface4, (void**) & intReturned );
  2074. }
  2075. else
  2076. {
  2077. DD_Surface_QueryInterface( (LPDIRECTDRAWSURFACE) intReturned, & IID_IDirectDrawSurface7, (void**) & intReturned );
  2078. }
  2079. rc = lpfnCallback( (LPDIRECTDRAWSURFACE)intReturned, (LPDDSURFACEDESC) &ddsd, lpContext );
  2080. if( rc == 0)
  2081. {
  2082. break;
  2083. }
  2084. pdbn = pdbn->next;
  2085. }
  2086. }
  2087. else if( dwFlags == DDENUMOVERLAYZ_BACKTOFRONT )
  2088. {
  2089. pdbn = pRoot->prev;
  2090. while(pdbn != pRoot)
  2091. {
  2092. LPDIRECTDRAWSURFACE7 intReturned = (LPDIRECTDRAWSURFACE7) pdbn->object_int;
  2093. FillDDSurfaceDesc2( pdbn->object, &ddsd );
  2094. if (LOWERTHANSURFACE4(this_int))
  2095. {
  2096. ddsd.dwSize = sizeof(DDSURFACEDESC);
  2097. DD_Surface_QueryInterface( (LPDIRECTDRAWSURFACE) intReturned, & IID_IDirectDrawSurface, (void**) & intReturned );
  2098. }
  2099. else if (this_int->lpVtbl == &ddSurface4Callbacks)
  2100. {
  2101. DD_Surface_QueryInterface( (LPDIRECTDRAWSURFACE) intReturned, & IID_IDirectDrawSurface4, (void**) & intReturned );
  2102. }
  2103. else
  2104. {
  2105. DD_Surface_QueryInterface( (LPDIRECTDRAWSURFACE) intReturned, & IID_IDirectDrawSurface7, (void**) & intReturned );
  2106. }
  2107. rc = lpfnCallback( (LPDIRECTDRAWSURFACE)intReturned, (LPDDSURFACEDESC) &ddsd, lpContext );
  2108. if( rc == 0)
  2109. {
  2110. break;
  2111. }
  2112. pdbn = pdbn->prev;
  2113. }
  2114. }
  2115. else
  2116. {
  2117. DPF_ERR( "Invalid dwFlags in EnumOverlayZOrders" );
  2118. LEAVE_DDRAW();
  2119. return DDERR_INVALIDPARAMS;
  2120. }
  2121. LEAVE_DDRAW();
  2122. return DD_OK;
  2123. } /* DD_Surface_EnumOverlayZOrders */
  2124. #undef DPF_MODNAME
  2125. #define DPF_MODNAME "AddOverlayDirtyRect"
  2126. /*
  2127. * DD_Surface_AddOverlayDirtyRect
  2128. */
  2129. HRESULT DDAPI DD_Surface_AddOverlayDirtyRect(
  2130. LPDIRECTDRAWSURFACE lpDDSurface,
  2131. LPRECT lpRect )
  2132. {
  2133. LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl;
  2134. LPDDRAWI_DDRAWSURFACE_INT this_int;
  2135. LPDDRAWI_DDRAWSURFACE_LCL this_lcl;
  2136. LPDDRAWI_DDRAWSURFACE_GBL this;
  2137. DDHAL_UPDATEOVERLAYDATA uod;
  2138. DWORD rc;
  2139. ENTER_DDRAW();
  2140. DPF(2,A,"ENTERAPI: DD_Surface_AddOverlayDirtyRect");
  2141. /*
  2142. * validate parameters
  2143. */
  2144. TRY
  2145. {
  2146. this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  2147. if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
  2148. {
  2149. LEAVE_DDRAW();
  2150. return DDERR_INVALIDOBJECT;
  2151. }
  2152. this_lcl = this_int->lpLcl;
  2153. if( this_lcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER )
  2154. {
  2155. DPF_ERR( "Invalid surface type: does not support overlays" );
  2156. LEAVE_DDRAW();
  2157. return DDERR_INVALIDSURFACETYPE;
  2158. }
  2159. if( !VALID_RECT_PTR( lpRect ) )
  2160. {
  2161. DPF_ERR( "invalid Rect" );
  2162. LEAVE_DDRAW();
  2163. return DDERR_INVALIDPARAMS;
  2164. }
  2165. this = this_lcl->lpGbl;
  2166. pdrv_lcl = this_lcl->lpSurfMore->lpDD_lcl;
  2167. /*
  2168. * make sure rectangle is OK
  2169. */
  2170. if( (lpRect->left < 0) ||
  2171. (lpRect->top < 0) ||
  2172. (lpRect->left > lpRect->right) ||
  2173. (lpRect->top > lpRect->bottom) ||
  2174. (lpRect->bottom > (int) (DWORD) this->wHeight) ||
  2175. (lpRect->right > (int) (DWORD) this->wWidth) )
  2176. {
  2177. DPF_ERR( "invalid Rect" );
  2178. LEAVE_DDRAW();
  2179. return DDERR_INVALIDPARAMS;
  2180. }
  2181. }
  2182. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  2183. {
  2184. DPF_ERR( "Exception encountered validating parameters" );
  2185. LEAVE_DDRAW();
  2186. return DDERR_INVALIDPARAMS;
  2187. }
  2188. //
  2189. // If the current surface is optimized, quit
  2190. //
  2191. if (this_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED)
  2192. {
  2193. DPF_ERR( "It is an optimized surface" );
  2194. LEAVE_DDRAW();
  2195. return DDERR_ISOPTIMIZEDSURFACE;
  2196. }
  2197. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) )
  2198. {
  2199. // If this surface is not emulated, there is nothing to be done.
  2200. LEAVE_DDRAW();
  2201. return DD_OK;
  2202. }
  2203. else
  2204. {
  2205. if( pdrv_lcl->lpDDCB->HELDDSurface.UpdateOverlay == NULL )
  2206. {
  2207. LEAVE_DDRAW();
  2208. return DDERR_UNSUPPORTED;
  2209. }
  2210. uod.overlayFX.dwSize = sizeof( DDOVERLAYFX );
  2211. uod.lpDD = this->lpDD;
  2212. uod.lpDDDestSurface = this_lcl;
  2213. uod.rDest = *(LPRECTL) lpRect;
  2214. uod.lpDDSrcSurface = this_lcl;
  2215. uod.rSrc = *(LPRECTL) lpRect;
  2216. uod.dwFlags = DDOVER_ADDDIRTYRECT;
  2217. rc = pdrv_lcl->lpDDCB->HELDDSurface.UpdateOverlay( &uod );
  2218. if( rc == DDHAL_DRIVER_HANDLED )
  2219. {
  2220. if( uod.ddRVal == DD_OK )
  2221. {
  2222. DPF( 2, "Added dirty rect to surface = %08lx", this );
  2223. }
  2224. LEAVE_DDRAW();
  2225. return uod.ddRVal;
  2226. }
  2227. else
  2228. {
  2229. LEAVE_DDRAW();
  2230. return DDERR_INVALIDPARAMS;
  2231. }
  2232. }
  2233. } /* DD_Surface_AddOverlayDirtyRect */
  2234. #undef DPF_MODNAME
  2235. #define DPF_MODNAME "UpdateOverlayDisplay"
  2236. /*
  2237. * DD_Surface_UpdateOverlayDisplay
  2238. */
  2239. HRESULT DDAPI DD_Surface_UpdateOverlayDisplay(
  2240. LPDIRECTDRAWSURFACE lpDDSurface,
  2241. DWORD dwFlags )
  2242. {
  2243. LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl;
  2244. LPDDRAWI_DDRAWSURFACE_INT this_int;
  2245. LPDDRAWI_DDRAWSURFACE_LCL this_lcl;
  2246. LPDDRAWI_DDRAWSURFACE_GBL this;
  2247. DDHAL_UPDATEOVERLAYDATA uod;
  2248. DWORD rc;
  2249. ENTER_DDRAW();
  2250. DPF(2,A,"ENTERAPI: DD_Surface_UpdateOverlayDisplay");
  2251. /*
  2252. * validate parameters
  2253. */
  2254. TRY
  2255. {
  2256. this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
  2257. if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
  2258. {
  2259. LEAVE_DDRAW();
  2260. return DDERR_INVALIDOBJECT;
  2261. }
  2262. this_lcl = this_int->lpLcl;
  2263. if( dwFlags & ~(DDOVER_REFRESHDIRTYRECTS | DDOVER_REFRESHALL) )
  2264. {
  2265. LEAVE_DDRAW();
  2266. return DDERR_INVALIDPARAMS;
  2267. }
  2268. this = this_lcl->lpGbl;
  2269. pdrv_lcl = this_lcl->lpSurfMore->lpDD_lcl;
  2270. if( this_lcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER )
  2271. {
  2272. DPF_ERR( "Invalid surface type: does not support overlays" );
  2273. LEAVE_DDRAW();
  2274. return DDERR_INVALIDSURFACETYPE;
  2275. }
  2276. //
  2277. // For now, if the current surface is optimized, quit
  2278. //
  2279. if (this_lcl->ddsCaps.dwCaps & DDSCAPS_OPTIMIZED)
  2280. {
  2281. DPF_ERR( "It is an optimized surface" );
  2282. LEAVE_DDRAW();
  2283. return DDERR_ISOPTIMIZEDSURFACE;
  2284. }
  2285. if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) )
  2286. {
  2287. // If this surface is not emulated, there is nothing to be done.
  2288. LEAVE_DDRAW();
  2289. return DD_OK;
  2290. }
  2291. if( pdrv_lcl->lpDDCB->HELDDSurface.UpdateOverlay == NULL )
  2292. {
  2293. LEAVE_DDRAW();
  2294. return DDERR_UNSUPPORTED;
  2295. }
  2296. uod.overlayFX.dwSize = sizeof( DDOVERLAYFX );
  2297. uod.lpDD = this->lpDD;
  2298. uod.lpDDDestSurface = this_lcl;
  2299. MAKE_SURF_RECT( this, this_lcl, uod.rDest );
  2300. uod.lpDDSrcSurface = this_lcl;
  2301. MAKE_SURF_RECT( this, this_lcl, uod.rSrc );
  2302. uod.dwFlags = dwFlags;
  2303. }
  2304. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  2305. {
  2306. DPF_ERR( "Exception encountered validating parameters" );
  2307. LEAVE_DDRAW();
  2308. return DDERR_INVALIDPARAMS;
  2309. }
  2310. /*
  2311. * invoke the HEL
  2312. */
  2313. rc = pdrv_lcl->lpDDCB->HELDDSurface.UpdateOverlay( &uod );
  2314. if( rc == DDHAL_DRIVER_HANDLED )
  2315. {
  2316. if( uod.ddRVal == DD_OK )
  2317. {
  2318. DPF( 2, "Refreshed overlayed surface = %08lx", this );
  2319. }
  2320. LEAVE_DDRAW();
  2321. return uod.ddRVal;
  2322. }
  2323. LEAVE_DDRAW();
  2324. return DDERR_UNSUPPORTED;
  2325. } /* DD_Surface_UpdateOverlayDisplay */