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.

490 lines
21 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: sprite.hxx
  3. *
  4. * Sprite objects.
  5. *
  6. * Created: 16-Sep-1997
  7. * Author: J. Andrew Goossen [andrewgo]
  8. *
  9. * Copyright (c) 1997-1999 Microsoft Corporation
  10. *
  11. \**************************************************************************/
  12. #ifndef GDIFLAGS_ONLY // used for gdikdx
  13. #define DEBUG_SPRITES 0
  14. #define TEXTURE_DEMO 0
  15. #if TEXTURE_DEMO
  16. extern HDEV ghdevTextureParent;
  17. BOOL TexTexture(VOID*, ULONG);
  18. HDC hdcTexture(ULONG);
  19. #endif
  20. // Function exports to be called from the multi-monitor code:
  21. VOID vSpEnableMultiMon(HDEV, ULONG, HDEV*);
  22. VOID vSpDisableMultiMon(HDEV);
  23. // Functions to handle enabling, disabling, and deletion of sprites:
  24. BOOL bSpEnableSprites(HDEV);
  25. VOID vSpDisableSprites(HDEV, CLEANUPTYPE = CLEANUP_NONE);
  26. VOID vSpDynamicModeChange(HDEV, HDEV);
  27. // Tear-down and redraw functions:
  28. class EWNDOBJ;
  29. VOID vSpHideSprites(HDEV, BOOL);
  30. BOOL bSpSpritesVisible(HDEV);
  31. BOOL bSpTearDownSprites(HDEV, RECTL*, BOOL = FALSE);
  32. VOID vSpUnTearDownSprites(HDEV, RECTL*, BOOL = FALSE);
  33. VOID vSpWndobjChange(HDEV, EWNDOBJ*);
  34. // SpTextOut should be called in place of EngTextOut, to handle direct
  35. // rendering even when a sprite is present:
  36. BOOL SpTextOut(
  37. SURFOBJ* pso,
  38. STROBJ* pstro,
  39. FONTOBJ* pfo,
  40. CLIPOBJ* pco,
  41. RECTL* prclExtra,
  42. RECTL* prclOpaque,
  43. BRUSHOBJ* pboFore,
  44. BRUSHOBJ* pboOpaque,
  45. POINTL* pptlOrg,
  46. MIX mix);
  47. // Duplicate of declaration in alphablt.hxx:
  48. class EBLENDOBJ : public _BLENDOBJ
  49. {
  50. public:
  51. XLATEOBJ *pxloSrcTo32;
  52. XLATEOBJ *pxloDstTo32;
  53. XLATEOBJ *pxlo32ToDst;
  54. };
  55. // Global variable that defines a (0, 0) offset:
  56. extern POINTL gptlZero;
  57. // Handy forward declarations:
  58. class SPRITE;
  59. typedef struct _SPRITESTATE SPRITESTATE;
  60. typedef struct _METASPRITE METASPRITE;
  61. /********************************Struct************************************\
  62. * struct SPRITESCAN
  63. *
  64. * An 'area' list is analagous to a region, and subdivides the screen
  65. * into horizontally-biased adjacent rectangles that describe where
  66. * sprites are, and are not.
  67. *
  68. \**************************************************************************/
  69. typedef struct _SPRITERANGE {
  70. LONG xLeft;
  71. LONG xRight;
  72. SPRITE* pSprite; // NULL if no sprite covers this region
  73. } SPRITERANGE;
  74. typedef struct _SPRITESCAN {
  75. LONG yTop;
  76. LONG yBottom;
  77. SIZE_T siztScan; // Size of this scan's data
  78. SIZE_T siztPrevious; // Size of previous scan's data
  79. SPRITERANGE aRange[1];
  80. } SPRITESCAN;
  81. inline SPRITESCAN* pSpNextScan(
  82. SPRITESCAN* pScan)
  83. {
  84. return((SPRITESCAN*) ((BYTE*) pScan + pScan->siztScan));
  85. }
  86. inline SPRITESCAN* pSpPreviousScan(
  87. SPRITESCAN* pScan)
  88. {
  89. return((SPRITESCAN*) ((BYTE*) pScan - pScan->siztPrevious));
  90. }
  91. inline SPRITERANGE* pSpLastRange(
  92. SPRITESCAN* pScan)
  93. {
  94. return(((SPRITERANGE*) ((BYTE*) pScan + pScan->siztScan)) - 1);
  95. }
  96. /*********************************Class************************************\
  97. * class SPRITE
  98. *
  99. * Identifies a sprite and contains all the information relevant to it.
  100. *
  101. \**************************************************************************/
  102. #endif // GDIFLAGS_ONLY used for gdikdx
  103. #define SPRITE_FLAG_CLIPPING_OBSCURED 0x0001 // Sprite is completely
  104. // obscured by clipping
  105. #define SPRITE_FLAG_JUST_TRANSFERRED 0x0002 // Used for vSpDynamicModeChange
  106. // to denote a sprite that has
  107. // already been handled
  108. #define SPRITE_FLAG_NO_WINDOW 0x0004 // Marks the meta-sprite for
  109. // deletion in low memory
  110. // mode changes, when user
  111. // unsets the layered flag
  112. // on a window
  113. #define SPRITE_FLAG_EFFECTIVELY_OPAQUE 0x0008 // Sprite is to be drawn as
  114. // opaque, even if ULW_OPAQUE
  115. // isn't specified
  116. #define SPRITE_FLAG_HIDDEN 0x0010 // Sprite is hidden
  117. #define SPRITE_FLAG_VISIBLE 0x0020 // Sprite is visible (counted
  118. // in SPRITESTATE::cVisible)
  119. // Private define for cursors. Watch out for overlap with the
  120. // other ULW_ private defines in gre.h (like ULW_NOREPAINT)!
  121. #define ULW_CURSOR 0x04000000
  122. #define ULW_DRAGRECT 0x02000000
  123. #if ((ULW_CURSOR | ULW_DRAGRECT) & (ULW_VALID | ULW_NOREPAINT))
  124. #error ULW_ flags overlap! Must fix!
  125. #endif
  126. #ifndef GDIFLAGS_ONLY // used for gdikdx
  127. typedef struct _SpriteCachedAttributes{ // Cached attributes for sprite
  128. ULONG dwShape; // Shape as specified by ULW_ flags
  129. BLENDFUNCTION bf; // Alpha value
  130. COLORREF crKey; // Color key (transparent color)
  131. } SpriteCachedAttributes;
  132. class SPRITE
  133. {
  134. public:
  135. FLONG fl; // Miscellaneous SPRITE_FLAG flags
  136. DWORD dwShape; // Shape as specified by flags in
  137. // UpdateLayeredWindow, plus
  138. // miscellaneous SPRITE_FLAG flags
  139. METASPRITE* pMetaSprite; // Points to the corresponding meta
  140. // sprite when running multi-mon
  141. SPRITESTATE* pState; // Points to PDEV related sprite state
  142. SPRITE* pNextZ; // Next sprite, bottom-most to top-most
  143. SPRITE* pNextY; // Next sprite, in increasing 'y'
  144. SPRITE* pPreviousY; // Previous sprite, in decreasing 'y'
  145. SPRITE* pNextActive; // Next sprite in active list
  146. #if DEBUG_SPRITES
  147. SPRITE* pNextVisible; // Next visible sprite
  148. #endif
  149. ULONG z; // Sprite z-order, starting at 0 with the
  150. // backmost sprite
  151. HWND hwnd; // Associated window
  152. RECTL rclSprite; // Bounds of sprite on the screen, taking
  153. // into account any transformations.
  154. // This is the effective 'current' size
  155. // of the underlay-buffer. For
  156. // both US_TRANSFORM_TRANSLATE and
  157. // US_TRANSFORM_SCALE, this is also the
  158. // destination rectangle.
  159. RECTL rclSrc; // Sprite's source rectangle
  160. SURFOBJ* psoMask; // Masks surface, for cursor sprites
  161. // (will be NULL if not a cursor)
  162. SURFOBJ* psoShape; // Copied and transformed sprite surface
  163. POINTL OffShape; // Offtor offset that should be added to
  164. // any coordinates before drawing on
  165. // this surface
  166. PALETTE* ppalShape; // Reference to surface palette of mode
  167. // in which sprite was originally created
  168. ULONG iModeFormat; // STYPE_ bitmap format of mode in which
  169. // sprite was originally created
  170. FLONG flModeMasks; // Combined red and blue masks of mode in
  171. // which sprite was originally created
  172. SURFOBJ* psoUnderlay; // Screen bits that underlay the sprite
  173. POINTL OffUnderlay; // Offtor offset that should be added
  174. // to any coordinates before drawing on
  175. // this surface
  176. SIZEL sizlHint; // Sprite size hint supplied at sprite
  177. // creation sprite time
  178. REGION* prgnClip; // Sprite's clip region (may be NULL)
  179. BLENDFUNCTION BlendFunction; // Blend information for US_SHAPE_ALPHA
  180. ULONG iTransparent; // Transparent color for US_SHAPE_COLORKEY
  181. RECTL rclUnderlay; // Location and size of underlay-buffer.
  182. // This always bounds 'rclSprite'
  183. POINTL ptlDst; // The most recent destination location that
  184. // the application passed us
  185. SpriteCachedAttributes cachedAttributes; // Cached attributes for alpha value,
  186. // color key, and shape
  187. ULONG ulTimeStamp; // When the sprite was last drawn
  188. };
  189. /*********************************Class************************************\
  190. * struct METASPRITE
  191. *
  192. * On a multi-mon system, USER needs to be able to address as a single
  193. * entity a sprite that actually exists as separate sprites on each
  194. * individual device.
  195. *
  196. * This structure thus represents the multi-mon meta-sprite object that
  197. * references multiple device specific sprites.
  198. *
  199. \**************************************************************************/
  200. typedef struct _METASPRITE {
  201. FLONG fl; // Miscellaneous SPRITE_FLAG flags
  202. HWND hwnd; // Associated window
  203. METASPRITE* pNext; // Next meta-sprite in list
  204. ULONG chSprite; // Size of apSprite array
  205. SPRITE* apSprite[1]; // Array of device specific sprites
  206. } METASPRITE;
  207. /********************************Struct************************************\
  208. * struct SPRITESTATE
  209. *
  210. * Contains all the device-global sprite state. This is simply kept in
  211. * the PDEV.
  212. *
  213. \**************************************************************************/
  214. typedef struct _SPRITESTATE {
  215. HDEV hdev; // Handle back to the PDEV, in case we
  216. // forget
  217. BOOL bHooked; // TRUE if DDI is currently being hooked
  218. SPRITE* pListZ; // z-sorted linked list of sprites, from
  219. // bottom-most to top-most
  220. SPRITE* pListY; // y-sorted linked list of sprites, from
  221. // highest to lowest.
  222. SURFOBJ* psoScreen; // Pointer to primary surface
  223. RECTL rclScreen; // Dimensions of screen
  224. ULONG cVisible; // Count of currently visible sprites
  225. #if DEBUG_SPRITES
  226. SPRITE* pListVisible; // Tracking for all visible sprites
  227. #endif
  228. ULONG cMultiMon; // Count of multi-mon devices attached
  229. // to this PDEV; zero if this is not
  230. // a multi-mon meta PDEV
  231. HDEV* ahdevMultiMon; // Points to an array of child HDEVs
  232. // when a multi-mon meta PDEV
  233. METASPRITE* pListMeta; // List of meta-sprites when a multi-mon
  234. // PDEV
  235. BOOL bInsideDriverCall; // TRUE if we're currently in the
  236. // middle of a Drv call from an
  237. // Sp routine. This is so we
  238. // catch cases of Sp->Drv->Eng->Sp
  239. // calls
  240. FLONG flOriginalSurfFlags; // Original psurf->SurfFlags values
  241. ULONG iOriginalType; // Original psurf->iType value
  242. FLONG flSpriteSurfFlags; // Current psurf->SurfFlag values
  243. ULONG iSpriteType; // Current psurf->iType value, will
  244. // be STYPE_DEVICE when sprites
  245. // are visible
  246. ULONG iModeFormat; // STYPE_ bitmap format of current mode
  247. FLONG flModeMasks; // Combined red and blue masks of current
  248. // mode
  249. BOOL bValidRange; // TRUE if 'pRange' is currently valid;
  250. // FALSE if it's out-of-date and has to
  251. // be re-generated
  252. SPRITESCAN* pRange; // Points to the beginning of the sprite
  253. // range structure that describes the
  254. // screen
  255. VOID* pRangeLimit; // Denotes last possible SPRITERANGE that
  256. // can be stuck in the buffer (note that
  257. // this does NOT point to the last scan
  258. // record!)
  259. SURFOBJ* psoComposite; // Off-screen composition buffer
  260. REGION* prgnUncovered; // Clip region describing portions of desk-
  261. // top not covered by sprites
  262. REGION* prgnTmp; // Temporary region for constructing a
  263. // clip object for drawing calls
  264. XCLIPOBJ coTmp; // Corresponding temporary clip object
  265. REGION* prgnRectangular; // Temporary region for when we need a
  266. // DC_RECT clip object
  267. XCLIPOBJ coRectangular; // Corresponding rectangular clip object
  268. SURFOBJ* psoHitTest; // 1x1 surface used for hit-testing
  269. REGION* prgnUnlocked; // Points to a region describing the areas
  270. // of the screen that aren't covered by
  271. // DirectDraw locks; NULL if there are
  272. // no current DirectDraw screen locks
  273. HRGN hrgn; // Handy region for processing
  274. // vSpUpdateVisRgn calls
  275. // These are for handling software mouse cursors and drag-rectangles when
  276. // moving windows and 'Show window contents while dragging' isn't
  277. // enabled.
  278. SPRITE* pSpriteCursor; // Software cursor sprite
  279. LONG xHotCursor; // Software cursor's current hot spot
  280. LONG yHotCursor;
  281. // Software cursor trail state
  282. // pSpriteCursors[0] is always the current cursor
  283. SPRITE* pTopCursor; // Top most cursor
  284. SPRITE* pBottomCursor; // Cursor lowest in Z order
  285. ULONG ulNumCursors; // Number of cursors at top of sprite list
  286. ULONG ulTrailTimeStamp; // Last time we did mouse trail maintenance
  287. ULONG ulTrailPeriod; // How long between mouse trail maintenance
  288. BOOL bHaveDragRect; // TRUE if there's an active dragrect
  289. HANDLE ahDragSprite[4]; // Handles to 4 sprites that make up the
  290. // dragrect; NULL if no active dragrect
  291. ULONG ulDragDimension; // Dimension of dragrect side, in pixels
  292. RECTL rclDragClip; // Rectangle to clip dragrect against
  293. // These point to the driver's true hooked routines (or the corresponding Eng
  294. // equivalent if the driver hasn't hooked that call):
  295. PFN_DrvStrokePath pfnStrokePath;
  296. PFN_DrvFillPath pfnFillPath;
  297. PFN_DrvPaint pfnPaint;
  298. PFN_DrvBitBlt pfnBitBlt;
  299. PFN_DrvCopyBits pfnCopyBits;
  300. PFN_DrvStretchBlt pfnStretchBlt;
  301. PFN_DrvTextOut pfnTextOut;
  302. PFN_DrvLineTo pfnLineTo;
  303. PFN_DrvTransparentBlt pfnTransparentBlt;
  304. PFN_DrvAlphaBlend pfnAlphaBlend;
  305. PFN_DrvPlgBlt pfnPlgBlt;
  306. PFN_DrvGradientFill pfnGradientFill;
  307. PFN_DrvSaveScreenBits pfnSaveScreenBits;
  308. PFN_DrvStretchBltROP pfnStretchBltROP;
  309. PFN_DrvDrawStream pfnDrawStream;
  310. } SPRITESTATE;
  311. /*********************************Class************************************\
  312. * class ENUMAREAS
  313. *
  314. * Class for enumerating the horizontally biased rectangles composing the
  315. * sprite regions under a rectangle.
  316. *
  317. \**************************************************************************/
  318. class ENUMAREAS
  319. {
  320. private:
  321. ULONG iDir; // Enumeration direction
  322. LONG xBoundsLeft; // Bounds of enumeration
  323. LONG yBoundsTop;
  324. LONG xBoundsRight;
  325. LONG yBoundsBottom;
  326. LONG yTop; // Current scan top
  327. LONG yBottom; // Current scan bottom
  328. SPRITESCAN* pScan; // Current scan
  329. SPRITERANGE* pRange; // Current range
  330. SPRITESCAN* pScanLayer; // Current scan in 'bEnumLayers' traversal
  331. SPRITERANGE* pRangeLayer; // Current range in 'bEnumLayers' traversal
  332. BOOL bValidRange; // Have the sprite ranges been recomputed
  333. // successfully?
  334. public:
  335. ENUMAREAS(SPRITESTATE* _pSpriteData, RECTL* prclBounds,
  336. ULONG iDirection = CD_RIGHTDOWN);
  337. BOOL bValid() {return bValidRange;}
  338. BOOL bEnum(SPRITE** ppSprite, RECTL* prcl);
  339. BOOL bEnumLayers(SPRITE** ppSprite);
  340. VOID vResetLayers();
  341. BOOL bAdvanceToTopMostOpaqueLayer(SPRITE** ppSprite);
  342. };
  343. /*********************************Class************************************\
  344. * class ENUMUNCOVERED
  345. *
  346. * Class for all the uncovered ranges of a sprite-region.
  347. *
  348. \**************************************************************************/
  349. class ENUMUNCOVERED
  350. {
  351. private:
  352. LONG yBoundsBottom;
  353. SPRITESCAN* pScan;
  354. SPRITESCAN* pNextScan;
  355. SPRITERANGE* pRange;
  356. public:
  357. ENUMUNCOVERED(SPRITESTATE* pState);
  358. BOOL bEnum(RECTL* prcl);
  359. };
  360. /*********************************Class************************************\
  361. * class ENUMUNDERLAYS
  362. *
  363. * Class for enumerating all the sprite underlays and non-sprite underlays
  364. * touched by a drawing call.
  365. *
  366. \**************************************************************************/
  367. class ENUMUNDERLAYS
  368. {
  369. private:
  370. SPRITESTATE* pState;
  371. CLIPOBJ* pcoOriginal; // Points to object passed to constructor
  372. SURFOBJ* psoOriginal; // Points to object passed to constructor
  373. SPRITE* pCurrentSprite; // Current sprite in enumeration
  374. RECTL rclBounds; // Copy of the drawing bounds intersected
  375. // with the clip bounds
  376. RECTL rclSaveBounds; // Saved copy of 'pco->rclBounds', which
  377. // we modify
  378. CLIPOBJ* pcoClip; // Points to effective clip object
  379. BOOL bSpriteTouched; // TRUE if we drew under a sprite
  380. BOOL bDone; // TRUE if no more bEnum's needed
  381. BOOL bResetSurfFlag; // TRUE if we should reset the SurfFlag
  382. // when done
  383. public:
  384. ENUMUNDERLAYS(SURFOBJ* pso, CLIPOBJ* pco, RECTL* prclDraw);
  385. BOOL bEnum(SURFOBJ** ppso, POINTL*, CLIPOBJ** ppco);
  386. };
  387. /*********************************Class************************************\
  388. * class SPRITELOCK
  389. *
  390. * This class is responsible for reseting whatever sprite state is
  391. * necessary so that we can call the driver directly, bypassing any sprite
  392. * code.
  393. *
  394. * Must be called with the DEVLOCK already held, because we're
  395. * messing with the screen surface.
  396. *
  397. \***************************************************************************/
  398. class SPRITELOCK
  399. {
  400. private:
  401. SPRITESTATE* pState;
  402. BOOL bWasAlreadyInsideDriverCall;
  403. public:
  404. SPRITELOCK(PDEVOBJ& po);
  405. ~SPRITELOCK();
  406. };
  407. /*********************************Class************************************\
  408. * class UNDODESKTOPCOORD
  409. *
  410. * This class is responsible for converting any WO_RGN_DESKTOP_COORD
  411. * WNDOBJs temporarily back to device-relative coordinates.
  412. *
  413. \***************************************************************************/
  414. class UNDODESKTOPCOORD
  415. {
  416. EWNDOBJ* pwoUndo;
  417. LONG xUndo;
  418. LONG yUndo;
  419. public:
  420. UNDODESKTOPCOORD(EWNDOBJ* pwo, SPRITESTATE* pState);
  421. ~UNDODESKTOPCOORD();
  422. };
  423. #endif // GDIFLAGS_ONLY used for gdikdx