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