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.

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