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