Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

360 lines
9.6 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pointer.c
  3. *
  4. * This module contains the hardware pointer support for the display
  5. * driver.
  6. *
  7. * Copyright (c) 1994-1995 Microsoft Corporation
  8. \**************************************************************************/
  9. #include "precomp.h"
  10. // This should match the miniport definition:
  11. #define VIDEO_MODE_LOCAL_POINTER 0x08
  12. // Look-up table for masking the right edge of the given pointer bitmap:
  13. BYTE gajMask[] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFc, 0xFE };
  14. /******************************Public*Routine******************************\
  15. * VOID DrvMovePointer
  16. *
  17. * NOTE: Because we have set GCAPS_ASYNCMOVE, this call may occur at any
  18. * time, even while we're executing another drawing call!
  19. *
  20. * Consequently, we have to explicitly synchronize any shared
  21. * resources. In our case, since we touch the CRTC register here
  22. * and in the banking code, we synchronize access using a critical
  23. * section.
  24. *
  25. \**************************************************************************/
  26. VOID DrvMovePointer(
  27. SURFOBJ* pso,
  28. LONG x,
  29. LONG y,
  30. RECTL* prcl)
  31. {
  32. VIDEO_POINTER_POSITION Position;
  33. PDEV* ppdev;
  34. DWORD returnedDataLength;
  35. ppdev = (PDEV*) pso->dhpdev;
  36. #if MULTI_BOARDS
  37. {
  38. if (x != -1)
  39. {
  40. OH* poh;
  41. poh = ((DSURF*) pso->dhsurf)->poh;
  42. x += poh->x;
  43. y += poh->y;
  44. }
  45. }
  46. #endif
  47. if (x == -1)
  48. {
  49. ppdev->bPointerEnabled = FALSE;
  50. EngDeviceIoControl(ppdev->hDriver,
  51. IOCTL_VIDEO_DISABLE_POINTER,
  52. NULL,
  53. 0,
  54. NULL,
  55. 0,
  56. &returnedDataLength);
  57. }
  58. else
  59. {
  60. Position.Column = (short) (x - ppdev->ptlHotSpot.x);
  61. Position.Row = (short) (y - ppdev->ptlHotSpot.y);
  62. if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_LOCAL_POINTER)
  63. {
  64. // This is rather dumb:
  65. IO_CURSOR_X(ppdev, ppdev->pjIoBase, Position.Column + CURSOR_CX);
  66. IO_CURSOR_Y(ppdev, ppdev->pjIoBase, Position.Row + CURSOR_CY);
  67. }
  68. else
  69. {
  70. EngDeviceIoControl(ppdev->hDriver,
  71. IOCTL_VIDEO_SET_POINTER_POSITION,
  72. &Position,
  73. sizeof(VIDEO_POINTER_POSITION),
  74. NULL,
  75. 0,
  76. &returnedDataLength);
  77. }
  78. // Don't forget to turn on the pointer, if it was off:
  79. if (!ppdev->bPointerEnabled)
  80. {
  81. ppdev->bPointerEnabled = TRUE;
  82. EngDeviceIoControl(ppdev->hDriver,
  83. IOCTL_VIDEO_ENABLE_POINTER,
  84. NULL,
  85. 0,
  86. NULL,
  87. 0,
  88. &returnedDataLength);
  89. }
  90. }
  91. }
  92. /******************************Public*Routine******************************\
  93. * VOID DrvSetPointerShape
  94. *
  95. * Sets the new pointer shape.
  96. *
  97. \**************************************************************************/
  98. ULONG DrvSetPointerShape(
  99. SURFOBJ* pso,
  100. SURFOBJ* psoMsk,
  101. SURFOBJ* psoColor,
  102. XLATEOBJ* pxlo,
  103. LONG xHot,
  104. LONG yHot,
  105. LONG x,
  106. LONG y,
  107. RECTL* prcl,
  108. FLONG fl)
  109. {
  110. VIDEO_POINTER_ATTRIBUTES* pPointerAttributes;
  111. PDEV* ppdev;
  112. ULONG cx;
  113. ULONG cy;
  114. LONG cjWhole;
  115. LONG cjDst;
  116. BYTE* pjSrc;
  117. BYTE* pjDst;
  118. LONG lSrcDelta;
  119. LONG lDstDelta;
  120. LONG i;
  121. DWORD returnedDataLength;
  122. ppdev = (PDEV*) pso->dhpdev;
  123. pPointerAttributes = ppdev->pPointerAttributes;
  124. if (pPointerAttributes == NULL)
  125. {
  126. // There are no hardware pointer capabilities:
  127. return(SPS_DECLINE);
  128. }
  129. cx = psoMsk->sizlBitmap.cx;
  130. cy = psoMsk->sizlBitmap.cy / 2;
  131. if ((cx > ppdev->PointerCapabilities.MaxWidth) ||
  132. (cy > ppdev->PointerCapabilities.MaxHeight) ||
  133. (psoColor != NULL) ||
  134. !(fl & SPS_CHANGE) ||
  135. (cx & 0x7))
  136. {
  137. goto HideAndDecline;
  138. }
  139. #if MULTI_BOARDS
  140. {
  141. if (x != -1)
  142. {
  143. OH* poh;
  144. poh = ((DSURF*) pso->dhsurf)->poh;
  145. x += poh->x;
  146. y += poh->y;
  147. }
  148. }
  149. #endif
  150. cjWhole = cx / 8;
  151. cjDst = pPointerAttributes->WidthInBytes * pPointerAttributes->Height;
  152. // Copy AND bits:
  153. pjSrc = psoMsk->pvScan0;
  154. lSrcDelta = psoMsk->lDelta;
  155. pjDst = pPointerAttributes->Pixels;
  156. lDstDelta = pPointerAttributes->WidthInBytes;
  157. memset(pjDst, -1, cjDst); // Pad unused AND bits
  158. for (i = cy; i != 0; i--)
  159. {
  160. memcpy(pjDst, pjSrc, cjWhole);
  161. pjSrc += lSrcDelta;
  162. pjDst += lDstDelta;
  163. }
  164. // Copy XOR bits:
  165. pjDst = pPointerAttributes->Pixels + ppdev->cjXorMaskStartOffset;
  166. memset(pjDst, 0, cjDst); // Pad unused XOR bits
  167. for (i = cy; i != 0; i--)
  168. {
  169. memcpy(pjDst, pjSrc, cjWhole);
  170. pjSrc += lSrcDelta;
  171. pjDst += lDstDelta;
  172. }
  173. // Initialize the pointer attributes:
  174. ppdev->ptlHotSpot.x = xHot;
  175. ppdev->ptlHotSpot.y = yHot;
  176. pPointerAttributes->Column = (short) (x - xHot);
  177. pPointerAttributes->Row = (short) (y - yHot);
  178. pPointerAttributes->Enable = (x != -1);
  179. pPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER;
  180. if (fl & SPS_ANIMATESTART)
  181. pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START;
  182. else if (fl & SPS_ANIMATEUPDATE)
  183. pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE;
  184. if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_LOCAL_POINTER)
  185. {
  186. // This is rather dumb:
  187. IO_CURSOR_X(ppdev, ppdev->pjIoBase, pPointerAttributes->Column + CURSOR_CX);
  188. IO_CURSOR_Y(ppdev, ppdev->pjIoBase, pPointerAttributes->Row + CURSOR_CY);
  189. }
  190. // Send the bits to the miniport:
  191. ppdev->bPointerEnabled = pPointerAttributes->Enable;
  192. if (EngDeviceIoControl(ppdev->hDriver,
  193. IOCTL_VIDEO_SET_POINTER_ATTR,
  194. ppdev->pPointerAttributes,
  195. ppdev->cjPointerAttributes,
  196. NULL,
  197. 0,
  198. &returnedDataLength))
  199. {
  200. goto HideAndDecline;
  201. }
  202. return(SPS_ACCEPT_NOEXCLUDE);
  203. HideAndDecline:
  204. DrvMovePointer(pso, -1, -1, NULL);
  205. return(SPS_DECLINE);
  206. }
  207. /******************************Public*Routine******************************\
  208. * VOID vDisablePointer
  209. *
  210. \**************************************************************************/
  211. VOID vDisablePointer(
  212. PDEV* ppdev)
  213. {
  214. // Nothing to do, really
  215. }
  216. /******************************Public*Routine******************************\
  217. * VOID vAssertModePointer
  218. *
  219. \**************************************************************************/
  220. VOID vAssertModePointer(
  221. PDEV* ppdev,
  222. BOOL bEnable)
  223. {
  224. // Nothing to do, really
  225. }
  226. /******************************Public*Routine******************************\
  227. * BOOL bEnablePointer
  228. *
  229. \**************************************************************************/
  230. BOOL bEnablePointer(
  231. PDEV* ppdev)
  232. {
  233. return(TRUE);
  234. }
  235. /******************************Public*Routine******************************\
  236. * BOOL bInitializePointer
  237. *
  238. * Initialize pointer during driver PDEV initialization -- early enough
  239. * so that we can affect what 'flGraphicsCaps' are passed back to GDI,
  240. * so that we can set GCAPS_ASYNCMOVE appropriately.
  241. *
  242. \**************************************************************************/
  243. BOOL bInitializePointer(
  244. PDEV* ppdev)
  245. {
  246. VIDEO_POINTER_ATTRIBUTES* pPointerAttributes;
  247. LONG cjWidth;
  248. LONG cjMaxPointer;
  249. DWORD returnedDataLength;
  250. if (!EngDeviceIoControl(ppdev->hDriver,
  251. IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES,
  252. NULL,
  253. 0,
  254. &ppdev->PointerCapabilities,
  255. sizeof(ppdev->PointerCapabilities),
  256. &returnedDataLength))
  257. {
  258. if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)
  259. {
  260. cjWidth = (ppdev->PointerCapabilities.MaxWidth + 7) / 8;
  261. cjMaxPointer = 2 * cjWidth * ppdev->PointerCapabilities.MaxHeight;
  262. ppdev->cjXorMaskStartOffset = cjMaxPointer / 2;
  263. ppdev->cjPointerAttributes = sizeof(VIDEO_POINTER_ATTRIBUTES)
  264. + cjMaxPointer;
  265. pPointerAttributes = (VIDEO_POINTER_ATTRIBUTES*)
  266. EngAllocMem(0, ppdev->cjPointerAttributes, ALLOC_TAG);
  267. if (pPointerAttributes != NULL)
  268. {
  269. ppdev->pPointerAttributes = pPointerAttributes;
  270. pPointerAttributes->WidthInBytes
  271. = cjWidth;
  272. pPointerAttributes->Width
  273. = ppdev->PointerCapabilities.MaxWidth;
  274. pPointerAttributes->Height
  275. = ppdev->PointerCapabilities.MaxHeight;
  276. }
  277. }
  278. }
  279. // We were successful even if the miniport doesn't support a
  280. // hardware pointer:
  281. return(TRUE);
  282. }
  283. /******************************Public*Routine******************************\
  284. * VOID vUnitializePointer
  285. *
  286. * Undoes bInitializePointer.
  287. *
  288. \**************************************************************************/
  289. VOID vUninitializePointer(
  290. PDEV* ppdev)
  291. {
  292. EngFreeMem(ppdev->pPointerAttributes);
  293. }