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.

469 lines
14 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: pointer.c *
  8. * *
  9. * This module contains the hardware Pointer support for the framebuffer *
  10. * *
  11. * Copyright (c) 1992-1998 Microsoft Corporation *
  12. \**************************************************************************/
  13. #include "driver.h"
  14. BOOL bCopyColorPointer(
  15. PPDEV ppdev,
  16. SURFOBJ *psoMask,
  17. SURFOBJ *psoColor,
  18. XLATEOBJ *pxlo);
  19. BOOL bCopyMonoPointer(
  20. PPDEV ppdev,
  21. SURFOBJ *psoMask);
  22. BOOL bSetHardwarePointerShape(
  23. SURFOBJ *pso,
  24. SURFOBJ *psoMask,
  25. SURFOBJ *psoColor,
  26. XLATEOBJ *pxlo,
  27. LONG x,
  28. LONG y,
  29. FLONG fl);
  30. /******************************Public*Routine******************************\
  31. * DrvMovePointer
  32. *
  33. * Moves the hardware pointer to a new position.
  34. *
  35. \**************************************************************************/
  36. VOID DrvMovePointer
  37. (
  38. SURFOBJ *pso,
  39. LONG x,
  40. LONG y,
  41. RECTL *prcl
  42. )
  43. {
  44. PPDEV ppdev = (PPDEV) pso->dhpdev;
  45. DWORD returnedDataLength;
  46. VIDEO_POINTER_POSITION NewPointerPosition;
  47. // We don't use the exclusion rectangle because we only support
  48. // hardware Pointers. If we were doing our own Pointer simulations
  49. // we would want to update prcl so that the engine would call us
  50. // to exclude out pointer before drawing to the pixels in prcl.
  51. UNREFERENCED_PARAMETER(prcl);
  52. // Convert the pointer's position from relative to absolute
  53. // coordinates (this is only significant for multiple board
  54. // support).
  55. x -= ppdev->ptlOrg.x;
  56. y -= ppdev->ptlOrg.y;
  57. // If x is -1 after the offset then take down the cursor.
  58. if (x == -1)
  59. {
  60. //
  61. // A new position of (-1,-1) means hide the pointer.
  62. //
  63. if (EngDeviceIoControl(ppdev->hDriver,
  64. IOCTL_VIDEO_DISABLE_POINTER,
  65. NULL,
  66. 0,
  67. NULL,
  68. 0,
  69. &returnedDataLength))
  70. {
  71. //
  72. // Not the end of the world, print warning in checked build.
  73. //
  74. DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_DISABLE_POINTER\n"));
  75. }
  76. }
  77. else
  78. {
  79. NewPointerPosition.Column = (SHORT) x - (SHORT) (ppdev->ptlHotSpot.x);
  80. NewPointerPosition.Row = (SHORT) y - (SHORT) (ppdev->ptlHotSpot.y);
  81. //
  82. // Call miniport driver to move Pointer.
  83. //
  84. if (EngDeviceIoControl(ppdev->hDriver,
  85. IOCTL_VIDEO_SET_POINTER_POSITION,
  86. &NewPointerPosition,
  87. sizeof(VIDEO_POINTER_POSITION),
  88. NULL,
  89. 0,
  90. &returnedDataLength))
  91. {
  92. //
  93. // Not the end of the world, print warning in checked build.
  94. //
  95. DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_SET_POINTER_POSITION\n"));
  96. }
  97. }
  98. }
  99. /******************************Public*Routine******************************\
  100. * DrvSetPointerShape
  101. *
  102. * Sets the new pointer shape.
  103. *
  104. \**************************************************************************/
  105. ULONG DrvSetPointerShape
  106. (
  107. SURFOBJ *pso,
  108. SURFOBJ *psoMask,
  109. SURFOBJ *psoColor,
  110. XLATEOBJ *pxlo,
  111. LONG xHot,
  112. LONG yHot,
  113. LONG x,
  114. LONG y,
  115. RECTL *prcl,
  116. FLONG fl
  117. )
  118. {
  119. PPDEV ppdev = (PPDEV) pso->dhpdev;
  120. DWORD returnedDataLength;
  121. // We don't use the exclusion rectangle because we only support
  122. // hardware Pointers. If we were doing our own Pointer simulations
  123. // we would want to update prcl so that the engine would call us
  124. // to exclude out pointer before drawing to the pixels in prcl.
  125. UNREFERENCED_PARAMETER(prcl);
  126. if (ppdev->pPointerAttributes == (PVIDEO_POINTER_ATTRIBUTES) NULL)
  127. {
  128. // Mini-port has no hardware Pointer support.
  129. return(SPS_ERROR);
  130. }
  131. // See if we are being asked to hide the pointer
  132. if (psoMask == (SURFOBJ *) NULL)
  133. {
  134. if (EngDeviceIoControl(ppdev->hDriver,
  135. IOCTL_VIDEO_DISABLE_POINTER,
  136. NULL,
  137. 0,
  138. NULL,
  139. 0,
  140. &returnedDataLength))
  141. {
  142. //
  143. // It should never be possible to fail.
  144. // Message supplied for debugging.
  145. //
  146. DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n"));
  147. }
  148. return(TRUE);
  149. }
  150. ppdev->ptlHotSpot.x = xHot;
  151. ppdev->ptlHotSpot.y = yHot;
  152. if (!bSetHardwarePointerShape(pso,psoMask,psoColor,pxlo,x,y,fl))
  153. {
  154. if (ppdev->fHwCursorActive) {
  155. ppdev->fHwCursorActive = FALSE;
  156. if (EngDeviceIoControl(ppdev->hDriver,
  157. IOCTL_VIDEO_DISABLE_POINTER,
  158. NULL,
  159. 0,
  160. NULL,
  161. 0,
  162. &returnedDataLength)) {
  163. DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n"));
  164. }
  165. }
  166. //
  167. // Mini-port declines to realize this Pointer
  168. //
  169. return(SPS_DECLINE);
  170. }
  171. else
  172. {
  173. ppdev->fHwCursorActive = TRUE;
  174. }
  175. return(SPS_ACCEPT_NOEXCLUDE);
  176. }
  177. /******************************Public*Routine******************************\
  178. * bSetHardwarePointerShape
  179. *
  180. * Changes the shape of the Hardware Pointer.
  181. *
  182. * Returns: True if successful, False if Pointer shape can't be hardware.
  183. *
  184. \**************************************************************************/
  185. BOOL bSetHardwarePointerShape(
  186. SURFOBJ *pso,
  187. SURFOBJ *psoMask,
  188. SURFOBJ *psoColor,
  189. XLATEOBJ *pxlo,
  190. LONG x,
  191. LONG y,
  192. FLONG fl)
  193. {
  194. PPDEV ppdev = (PPDEV) pso->dhpdev;
  195. PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
  196. DWORD returnedDataLength;
  197. if (psoColor != (SURFOBJ *) NULL)
  198. {
  199. if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) &&
  200. bCopyColorPointer(ppdev, psoMask, psoColor, pxlo))
  201. {
  202. pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER;
  203. } else {
  204. return(FALSE);
  205. }
  206. } else {
  207. if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER) &&
  208. bCopyMonoPointer(ppdev, psoMask))
  209. {
  210. pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER;
  211. } else {
  212. return(FALSE);
  213. }
  214. }
  215. //
  216. // Initialize Pointer attributes and position
  217. //
  218. pPointerAttributes->Enable = 1;
  219. //
  220. // if x,y = -1,-1 then pass them directly to the miniport so that
  221. // the cursor will be disabled
  222. pPointerAttributes->Column = (SHORT)(x);
  223. pPointerAttributes->Row = (SHORT)(y);
  224. if ((x != -1) || (y != -1)) {
  225. pPointerAttributes->Column -= (SHORT)(ppdev->ptlHotSpot.x);
  226. pPointerAttributes->Row -= (SHORT)(ppdev->ptlHotSpot.y);
  227. }
  228. //
  229. // set animate flags
  230. //
  231. if (fl & SPS_ANIMATESTART) {
  232. pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START;
  233. } else if (fl & SPS_ANIMATEUPDATE) {
  234. pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE;
  235. }
  236. //
  237. // Set the new Pointer shape.
  238. //
  239. if (EngDeviceIoControl(ppdev->hDriver,
  240. IOCTL_VIDEO_SET_POINTER_ATTR,
  241. pPointerAttributes,
  242. ppdev->cjPointerAttributes,
  243. NULL,
  244. 0,
  245. &returnedDataLength)) {
  246. DISPDBG((1, "DISP:Failed IOCTL_VIDEO_SET_POINTER_ATTR call\n"));
  247. return(FALSE);
  248. }
  249. return(TRUE);
  250. }
  251. /******************************Public*Routine******************************\
  252. * bCopyMonoPointer
  253. *
  254. * Copies two monochrome masks into a buffer of the maximum size handled by the
  255. * miniport, with any extra bits set to 0. The masks are converted to topdown
  256. * form if they aren't already. Returns TRUE if we can handle this pointer in
  257. * hardware, FALSE if not.
  258. *
  259. \**************************************************************************/
  260. BOOL bCopyMonoPointer(
  261. PPDEV ppdev,
  262. SURFOBJ *pso)
  263. {
  264. ULONG cy;
  265. PBYTE pjSrcAnd, pjSrcXor;
  266. LONG lDeltaSrc, lDeltaDst;
  267. LONG lSrcWidthInBytes;
  268. ULONG cxSrc = pso->sizlBitmap.cx;
  269. ULONG cySrc = pso->sizlBitmap.cy;
  270. ULONG cxSrcBytes;
  271. PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
  272. PBYTE pjDstAnd = pPointerAttributes->Pixels;
  273. PBYTE pjDstXor = pPointerAttributes->Pixels;
  274. // Make sure the new pointer isn't too big to handle
  275. // (*2 because both masks are in there)
  276. if ((cxSrc > ppdev->PointerCapabilities.MaxWidth) ||
  277. (cySrc > (ppdev->PointerCapabilities.MaxHeight * 2)))
  278. {
  279. return(FALSE);
  280. }
  281. pjDstXor += ((ppdev->PointerCapabilities.MaxWidth + 7) / 8) *
  282. ppdev->pPointerAttributes->Height;
  283. // set the desk and mask to 0xff
  284. RtlFillMemory(pjDstAnd, ppdev->pPointerAttributes->WidthInBytes *
  285. ppdev->pPointerAttributes->Height, 0xFF);
  286. // Zero the dest XOR mask
  287. RtlZeroMemory(pjDstXor, ppdev->pPointerAttributes->WidthInBytes *
  288. ppdev->pPointerAttributes->Height);
  289. cxSrcBytes = (cxSrc + 7) / 8;
  290. if ((lDeltaSrc = pso->lDelta) < 0)
  291. {
  292. lSrcWidthInBytes = -lDeltaSrc;
  293. } else {
  294. lSrcWidthInBytes = lDeltaSrc;
  295. }
  296. pjSrcAnd = (PBYTE) pso->pvBits;
  297. // If the incoming pointer bitmap is bottomup, we'll flip it to topdown to
  298. // save the miniport some work
  299. if (!(pso->fjBitmap & BMF_TOPDOWN))
  300. {
  301. // Copy from the bottom
  302. pjSrcAnd += lSrcWidthInBytes * (cySrc - 1);
  303. }
  304. // Height of just AND mask
  305. cySrc = cySrc / 2;
  306. // Point to XOR mask
  307. pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc);
  308. // Offset from end of one dest scan to start of next
  309. lDeltaDst = ppdev->pPointerAttributes->WidthInBytes;
  310. for (cy = 0; cy < cySrc; ++cy)
  311. {
  312. RtlCopyMemory(pjDstAnd, pjSrcAnd, cxSrcBytes);
  313. RtlCopyMemory(pjDstXor, pjSrcXor, cxSrcBytes);
  314. // Point to next source and dest scans
  315. pjSrcAnd += lDeltaSrc;
  316. pjSrcXor += lDeltaSrc;
  317. pjDstAnd += lDeltaDst;
  318. pjDstXor += lDeltaDst;
  319. }
  320. return(TRUE);
  321. }
  322. /******************************Public*Routine******************************\
  323. * bCopyColorPointer
  324. *
  325. * Copies the mono and color masks into the buffer of maximum size
  326. * handled by the miniport with any extra bits set to 0. Color translation
  327. * is handled at this time. The masks are converted to topdown form if they
  328. * aren't already. Returns TRUE if we can handle this pointer in hardware,
  329. * FALSE if not.
  330. *
  331. \**************************************************************************/
  332. BOOL bCopyColorPointer(
  333. PPDEV ppdev,
  334. SURFOBJ *psoMask,
  335. SURFOBJ *psoColor,
  336. XLATEOBJ *pxlo)
  337. {
  338. return(FALSE);
  339. }
  340. /******************************Public*Routine******************************\
  341. * bInitPointer
  342. *
  343. * Initialize the Pointer attributes.
  344. *
  345. \**************************************************************************/
  346. BOOL bInitPointer(PPDEV ppdev, DEVINFO *pdevinfo)
  347. {
  348. DWORD returnedDataLength;
  349. ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL;
  350. ppdev->cjPointerAttributes = 0; // initialized in screen.c
  351. //
  352. // Ask the miniport whether it provides pointer support.
  353. //
  354. if (EngDeviceIoControl(ppdev->hDriver,
  355. IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES,
  356. &ppdev->ulMode,
  357. sizeof(PVIDEO_MODE),
  358. &ppdev->PointerCapabilities,
  359. sizeof(ppdev->PointerCapabilities),
  360. &returnedDataLength))
  361. {
  362. return(FALSE);
  363. }
  364. //
  365. // If neither mono nor color hardware pointer is supported, there's no
  366. // hardware pointer support and we're done.
  367. //
  368. if ((!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)) &&
  369. (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER)))
  370. {
  371. return(TRUE);
  372. }
  373. //
  374. // Note: The buffer itself is allocated after we set the
  375. // mode. At that time we know the pixel depth and we can
  376. // allocate the correct size for the color pointer if supported.
  377. //
  378. //
  379. // Set the asynchronous support status (async means miniport is capable of
  380. // drawing the Pointer at any time, with no interference with any ongoing
  381. // drawing operation)
  382. //
  383. if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_ASYNC_POINTER)
  384. {
  385. pdevinfo->flGraphicsCaps |= GCAPS_ASYNCMOVE;
  386. }
  387. else
  388. {
  389. pdevinfo->flGraphicsCaps &= ~GCAPS_ASYNCMOVE;
  390. }
  391. return(TRUE);
  392. }