VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/pointer.c@ 16605

Last change on this file since 16605 was 16605, checked in by vboxsync, 16 years ago

header updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.9 KB
Line 
1/******************************Module*Header*******************************\
2*
3* Copyright (C) 2006-2007 Sun Microsystems, Inc.
4*
5* This file is part of VirtualBox Open Source Edition (OSE), as
6* available from http://www.virtualbox.org. This file is free software;
7* you can redistribute it and/or modify it under the terms of the GNU
8* General Public License (GPL) as published by the Free Software
9* Foundation, in version 2 as it comes in the "COPYING" file of the
10* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
11* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
12*
13* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
14* Clara, CA 95054 USA or visit http://www.sun.com if you need
15* additional information or have any questions.
16*
17* Based in part on Microsoft DDK sample code
18*
19* *******************
20* * GDI SAMPLE CODE *
21* *******************
22*
23* Module Name: pointer.c *
24* *
25* This module contains the hardware Pointer support for the framebuffer *
26* *
27* Copyright (c) 1992-1998 Microsoft Corporation *
28\**************************************************************************/
29
30#include "driver.h"
31
32#include <VBox/VBoxGuest.h> /* for VBOX_MOUSE_POINTER_* flags */
33
34#ifndef SPS_ALPHA
35#define SPS_ALPHA 0x00000010L
36#endif
37
38BOOL bCopyColorPointer(
39PPDEV ppdev,
40SURFOBJ *psoScreen,
41SURFOBJ *psoMask,
42SURFOBJ *psoColor,
43XLATEOBJ *pxlo,
44FLONG fl);
45
46BOOL bCopyMonoPointer(
47PPDEV ppdev,
48SURFOBJ *psoMask);
49
50BOOL bSetHardwarePointerShape(
51SURFOBJ *pso,
52SURFOBJ *psoMask,
53SURFOBJ *psoColor,
54XLATEOBJ *pxlo,
55LONG x,
56LONG y,
57FLONG fl);
58
59/******************************Public*Routine******************************\
60* DrvMovePointer
61*
62* Moves the hardware pointer to a new position.
63*
64\**************************************************************************/
65
66VOID DrvMovePointer
67(
68 SURFOBJ *pso,
69 LONG x,
70 LONG y,
71 RECTL *prcl
72)
73{
74 PPDEV ppdev = (PPDEV) pso->dhpdev;
75 DWORD returnedDataLength;
76 VIDEO_POINTER_POSITION NewPointerPosition;
77
78 // We don't use the exclusion rectangle because we only support
79 // hardware Pointers. If we were doing our own Pointer simulations
80 // we would want to update prcl so that the engine would call us
81 // to exclude out pointer before drawing to the pixels in prcl.
82
83 UNREFERENCED_PARAMETER(prcl);
84
85 // Convert the pointer's position from relative to absolute
86 // coordinates (this is only significant for multiple board
87 // support).
88
89 x -= ppdev->ptlOrg.x;
90 y -= ppdev->ptlOrg.y;
91
92 // If x is -1 after the offset then take down the cursor.
93
94 if (x == -1)
95 {
96 //
97 // A new position of (-1,-1) means hide the pointer.
98 //
99
100 if (EngDeviceIoControl(ppdev->hDriver,
101 IOCTL_VIDEO_DISABLE_POINTER,
102 NULL,
103 0,
104 NULL,
105 0,
106 &returnedDataLength))
107 {
108 //
109 // Not the end of the world, print warning in checked build.
110 //
111
112 DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_DISABLE_POINTER\n"));
113 }
114 }
115 else
116 {
117 NewPointerPosition.Column = (SHORT) x - (SHORT) (ppdev->ptlHotSpot.x);
118 NewPointerPosition.Row = (SHORT) y - (SHORT) (ppdev->ptlHotSpot.y);
119
120 //
121 // Call miniport driver to move Pointer.
122 //
123
124 if (EngDeviceIoControl(ppdev->hDriver,
125 IOCTL_VIDEO_SET_POINTER_POSITION,
126 &NewPointerPosition,
127 sizeof(VIDEO_POINTER_POSITION),
128 NULL,
129 0,
130 &returnedDataLength))
131 {
132 //
133 // Not the end of the world, print warning in checked build.
134 //
135
136 DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_SET_POINTER_POSITION\n"));
137 }
138 }
139}
140
141/******************************Public*Routine******************************\
142* DrvSetPointerShape
143*
144* Sets the new pointer shape.
145*
146\**************************************************************************/
147
148ULONG DrvSetPointerShape
149(
150 SURFOBJ *pso,
151 SURFOBJ *psoMask,
152 SURFOBJ *psoColor,
153 XLATEOBJ *pxlo,
154 LONG xHot,
155 LONG yHot,
156 LONG x,
157 LONG y,
158 RECTL *prcl,
159 FLONG fl
160)
161{
162 PPDEV ppdev = (PPDEV) pso->dhpdev;
163 DWORD returnedDataLength;
164
165 DISPDBG((0, "DISP bSetHardwarePointerShape SPS_ALPHA = %d\n", fl & SPS_ALPHA));
166
167 // We don't use the exclusion rectangle because we only support
168 // hardware Pointers. If we were doing our own Pointer simulations
169 // we would want to update prcl so that the engine would call us
170 // to exclude out pointer before drawing to the pixels in prcl.
171 UNREFERENCED_PARAMETER(prcl);
172
173 if (ppdev->pPointerAttributes == (PVIDEO_POINTER_ATTRIBUTES) NULL)
174 {
175 // Mini-port has no hardware Pointer support.
176 return(SPS_ERROR);
177 }
178
179 ppdev->ptlHotSpot.x = xHot;
180 ppdev->ptlHotSpot.y = yHot;
181
182 if (!bSetHardwarePointerShape(pso,psoMask,psoColor,pxlo,x,y,fl))
183 {
184 if (ppdev->fHwCursorActive) {
185 ppdev->fHwCursorActive = FALSE;
186
187 if (EngDeviceIoControl(ppdev->hDriver,
188 IOCTL_VIDEO_DISABLE_POINTER,
189 NULL,
190 0,
191 NULL,
192 0,
193 &returnedDataLength)) {
194
195 DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n"));
196 }
197 }
198
199 //
200 // Mini-port declines to realize this Pointer
201 //
202
203 return(SPS_DECLINE);
204 }
205 else
206 {
207 ppdev->fHwCursorActive = TRUE;
208 }
209
210 return(SPS_ACCEPT_NOEXCLUDE);
211}
212
213/******************************Public*Routine******************************\
214* bSetHardwarePointerShape
215*
216* Changes the shape of the Hardware Pointer.
217*
218* Returns: True if successful, False if Pointer shape can't be hardware.
219*
220\**************************************************************************/
221
222BOOL bSetHardwarePointerShape(
223SURFOBJ *pso,
224SURFOBJ *psoMask,
225SURFOBJ *psoColor,
226XLATEOBJ *pxlo,
227LONG x,
228LONG y,
229FLONG fl)
230{
231 PPDEV ppdev = (PPDEV) pso->dhpdev;
232 PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
233 DWORD returnedDataLength;
234
235 if (psoColor != (SURFOBJ *) NULL)
236 {
237 if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) &&
238 bCopyColorPointer(ppdev, pso, psoMask, psoColor, pxlo, fl))
239 {
240 pPointerAttributes->Flags = VIDEO_MODE_COLOR_POINTER;
241 } else {
242 return(FALSE);
243 }
244
245 } else {
246
247 if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER) &&
248 bCopyMonoPointer(ppdev, psoMask))
249 {
250 pPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER;
251 } else {
252 return(FALSE);
253 }
254 }
255
256 //
257 // Initialize Pointer attributes and position
258 //
259
260 if (x == -1)
261 {
262 /* Pointer should be created invisible */
263 pPointerAttributes->Column = -1;
264 pPointerAttributes->Row = -1;
265 pPointerAttributes->Enable = VBOX_MOUSE_POINTER_SHAPE;
266 }
267 else
268 {
269 /* New coordinates of pointer's hot spot */
270 pPointerAttributes->Column = (SHORT)(x) - (SHORT)(ppdev->ptlHotSpot.x);
271 pPointerAttributes->Row = (SHORT)(y) - (SHORT)(ppdev->ptlHotSpot.y);
272 pPointerAttributes->Enable = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
273 }
274
275
276 /* VBOX: We have to pass to miniport hot spot coordinates and alpha flag.
277 * They will be encoded in the pPointerAttributes::Enable field.
278 * High word will contain hot spot info and low word - flags.
279 */
280
281 pPointerAttributes->Enable |= (ppdev->ptlHotSpot.y & 0xFF) << 24;
282 pPointerAttributes->Enable |= (ppdev->ptlHotSpot.x & 0xFF) << 16;
283
284 if (fl & SPS_ALPHA)
285 {
286 pPointerAttributes->Enable |= VBOX_MOUSE_POINTER_ALPHA;
287 }
288
289 //
290 // set animate flags
291 //
292
293 if (fl & SPS_ANIMATESTART) {
294 pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START;
295 } else if (fl & SPS_ANIMATEUPDATE) {
296 pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE;
297 }
298
299
300 //
301 // Set the new Pointer shape.
302 //
303
304 if (EngDeviceIoControl(ppdev->hDriver,
305 IOCTL_VIDEO_SET_POINTER_ATTR,
306 pPointerAttributes,
307 ppdev->cjPointerAttributes,
308 NULL,
309 0,
310 &returnedDataLength)) {
311
312 DISPDBG((1, "DISP:Failed IOCTL_VIDEO_SET_POINTER_ATTR call\n"));
313 return(FALSE);
314 }
315
316 //
317 // Set new pointer position
318 //
319
320 if (x != -1) {
321 VIDEO_POINTER_POSITION vpp;
322
323 vpp.Column = pPointerAttributes->Column;
324 vpp.Row = pPointerAttributes->Row;
325
326 if (EngDeviceIoControl(ppdev->hDriver,
327 IOCTL_VIDEO_SET_POINTER_POSITION,
328 &vpp,
329 sizeof (vpp),
330 NULL,
331 0,
332 &returnedDataLength)) {
333
334 // Should never fail, informational message.
335 DISPDBG((1, "DISP:Failed IOCTL_VIDEO_SET_POINTER_POSITION call\n"));
336 }
337 }
338
339 return(TRUE);
340}
341
342/******************************Public*Routine******************************\
343* bCopyMonoPointer
344*
345* Copies two monochrome masks into a buffer of the maximum size handled by the
346* miniport, with any extra bits set to 0. The masks are converted to topdown
347* form if they aren't already. Returns TRUE if we can handle this pointer in
348* hardware, FALSE if not.
349*
350\**************************************************************************/
351
352BOOL bCopyMonoPointer(
353 PPDEV ppdev,
354 SURFOBJ *psoMask)
355{
356 PBYTE pjSrc = NULL;
357
358 ULONG cy = 0;
359
360 PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
361
362 PBYTE pjDstAnd = pPointerAttributes->Pixels;
363 ULONG cjAnd = 0;
364 PBYTE pjDstXor = pPointerAttributes->Pixels;
365
366 ULONG cxSrc = psoMask->sizlBitmap.cx;
367 ULONG cySrc = psoMask->sizlBitmap.cy / 2; /* /2 because both masks are in there */
368
369 // Make sure the new pointer isn't too big to handle,
370 // strip the size to 64x64 if necessary
371 if (cxSrc > ppdev->PointerCapabilities.MaxWidth)
372 {
373 cxSrc = ppdev->PointerCapabilities.MaxWidth;
374 }
375
376 if (cySrc > ppdev->PointerCapabilities.MaxHeight)
377 {
378 cySrc = ppdev->PointerCapabilities.MaxWidth;
379 }
380
381 /* Size of AND mask in bytes */
382 cjAnd = ((cxSrc + 7) / 8) * cySrc;
383
384 /* Pointer to XOR mask is 4-bytes aligned */
385 pjDstXor += (cjAnd + 3) & ~3;
386
387 pPointerAttributes->Width = cxSrc;
388 pPointerAttributes->Height = cySrc;
389 pPointerAttributes->WidthInBytes = cxSrc * 4;
390
391 /* Init AND mask to 1 */
392 RtlFillMemory (pjDstAnd, cjAnd, 0xFF);
393
394 /*
395 * Copy AND mask.
396 */
397
398 DISPDBG((0, "DISP bCopyMonoPointer going to copy AND mask\n"));
399
400 pjSrc = (PBYTE)psoMask->pvScan0;
401
402 for (cy = 0; cy < cySrc; cy++)
403 {
404 RtlCopyMemory (pjDstAnd, pjSrc, (cxSrc + 7) / 8);
405
406 // Point to next source and dest scans
407 pjSrc += psoMask->lDelta;
408 pjDstAnd += (cxSrc + 7) / 8;
409 }
410
411 DISPDBG((0, "DISP bCopyMonoPointer AND mask copied\n"));
412
413 DISPDBG((0, "DISP bCopyMonoPointer going to create RGB0 XOR mask\n"));
414
415 for (cy = 0; cy < cySrc; ++cy)
416 {
417 ULONG cx;
418
419 UCHAR bitmask = 0x80;
420
421 for (cx = 0; cx < cxSrc; cx++, bitmask >>= 1)
422 {
423 if (bitmask == 0)
424 {
425 bitmask = 0x80;
426 }
427
428 if (pjSrc[cx / 8] & bitmask)
429 {
430 *(ULONG *)&pjDstXor[cx * 4] = 0x00FFFFFF;
431 }
432 else
433 {
434 *(ULONG *)&pjDstXor[cx * 4] = 0;
435 }
436 }
437
438 // Point to next source and dest scans
439 pjSrc += psoMask->lDelta;
440 pjDstXor += cxSrc * 4;
441 }
442
443 DISPDBG((0, "DISP bCopyMonoPointer created RGB0 XOR mask\n"));
444
445 return(TRUE);
446}
447
448/******************************Public*Routine******************************\
449* bCopyColorPointer
450*
451* Copies the mono and color masks into the buffer of maximum size
452* handled by the miniport with any extra bits set to 0. Color translation
453* is handled at this time. The masks are converted to topdown form if they
454* aren't already. Returns TRUE if we can handle this pointer in hardware,
455* FALSE if not.
456*
457\**************************************************************************/
458BOOL bCopyColorPointer(
459PPDEV ppdev,
460SURFOBJ *psoScreen,
461SURFOBJ *psoMask,
462SURFOBJ *psoColor,
463XLATEOBJ *pxlo,
464FLONG fl)
465{
466 /* Format of "hardware" pointer is:
467 * 1 bpp AND mask with byte aligned scanlines,
468 * B G R A bytes of XOR mask that starts on the next 4 byte aligned offset after AND mask.
469 *
470 * If fl & SPS_ALPHA then A bytes contain alpha channel information.
471 * Otherwise A bytes are undefined (but will be 0).
472 *
473 */
474
475 /* To simplify this function we use the following method:
476 * for pointers with alpha channel
477 * we have BGRA values in psoColor and will simply copy them to pPointerAttributes->Pixels
478 * for color pointers
479 * always convert supplied bitmap to 32 bit BGR0
480 * copy AND mask and new BGR0 XOR mask to pPointerAttributes->Pixels
481 */
482
483 HSURF hsurf32bpp = NULL;
484 SURFOBJ *pso32bpp = NULL;
485
486 PBYTE pjSrcAnd = NULL;
487 PBYTE pjSrcXor = NULL;
488
489 ULONG cy = 0;
490
491 PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
492
493 PBYTE pjDstAnd = pPointerAttributes->Pixels;
494 ULONG cjAnd = 0;
495 PBYTE pjDstXor = pPointerAttributes->Pixels;
496
497 ULONG cxSrc = psoColor->sizlBitmap.cx;
498 ULONG cySrc = psoColor->sizlBitmap.cy;
499
500 // Make sure the new pointer isn't too big to handle,
501 // strip the size to 64x64 if necessary
502 if (cxSrc > ppdev->PointerCapabilities.MaxWidth)
503 {
504 cxSrc = ppdev->PointerCapabilities.MaxWidth;
505 }
506
507 if (cySrc > ppdev->PointerCapabilities.MaxHeight)
508 {
509 cySrc = ppdev->PointerCapabilities.MaxWidth;
510 }
511
512 /* Size of AND mask in bytes */
513 cjAnd = ((cxSrc + 7) / 8) * cySrc;
514
515 /* Pointer to XOR mask is 4-bytes aligned */
516 pjDstXor += (cjAnd + 3) & ~3;
517
518 pPointerAttributes->Width = cxSrc;
519 pPointerAttributes->Height = cySrc;
520 pPointerAttributes->WidthInBytes = cxSrc * 4;
521
522 /* Init AND mask to 1 */
523 RtlFillMemory (pjDstAnd, cjAnd, 0xFF);
524
525 if (fl & SPS_ALPHA)
526 {
527 PBYTE pjSrcAlpha = (PBYTE)psoColor->pvScan0;
528
529 DISPDBG((0, "DISP bCopyColorPointer SPS_ALPHA\n"));
530
531 pso32bpp = psoColor;
532
533 /*
534 * Emulate AND mask to provide viewable mouse pointer for
535 * hardware which does not support alpha channel.
536 */
537
538 DISPDBG((0, "DISP bCopyColorPointer going to emulate AND mask\n"));
539
540 for (cy = 0; cy < cySrc; cy++)
541 {
542 ULONG cx;
543
544 UCHAR bitmask = 0x80;
545
546 for (cx = 0; cx < cxSrc; cx++, bitmask >>= 1)
547 {
548 if (bitmask == 0)
549 {
550 bitmask = 0x80;
551 }
552
553 if (pjSrcAlpha[cx * 4 + 3] > 0x7f)
554 {
555 pjDstAnd[cx / 8] &= ~bitmask;
556 }
557 }
558
559 // Point to next source and dest scans
560 pjSrcAlpha += pso32bpp->lDelta;
561 pjDstAnd += (cxSrc + 7) / 8;
562 }
563
564 DISPDBG((0, "DISP bCopyColorPointer AND mask emulated\n"));
565 }
566 else
567 {
568 if (!psoMask)
569 {
570 /* This can not be, mask must be supplied for a color pointer. */
571 return (FALSE);
572 }
573
574 /*
575 * Copy AND mask.
576 */
577
578 DISPDBG((0, "DISP bCopyColorPointer going to copy AND mask\n"));
579
580 pjSrcAnd = (PBYTE)psoMask->pvScan0;
581
582 for (cy = 0; cy < cySrc; cy++)
583 {
584 RtlCopyMemory (pjDstAnd, pjSrcAnd, (cxSrc + 7) / 8);
585
586 // Point to next source and dest scans
587 pjSrcAnd += psoMask->lDelta;
588 pjDstAnd += (cxSrc + 7) / 8;
589 }
590
591 DISPDBG((0, "DISP bCopyColorPointer AND mask copied\n"));
592
593 /*
594 * Convert given psoColor to 32 bit BGR0.
595 */
596
597 DISPDBG((0, "DISP bCopyColorPointer psoScreen t = %d, f = %d, psoColor t = %d, f = %d, pxlo = %p, psoColor->lDelta = %d, ->cx = %d\n",
598 psoScreen->iType, psoScreen->iBitmapFormat, psoColor->iType, psoColor->iBitmapFormat, pxlo, psoColor->lDelta, psoColor->sizlBitmap.cx));
599
600 if (psoColor->iType == STYPE_BITMAP
601 && psoColor->iBitmapFormat == BMF_32BPP)
602 {
603 /* The psoColor is already in desired format */
604 DISPDBG((0, "DISP bCopyColorPointer XOR mask already in 32 bpp\n"));
605 pso32bpp = psoColor;
606 }
607 else
608 {
609 HSURF hsurfBitmap = NULL;
610 SURFOBJ *psoBitmap = NULL;
611
612 SIZEL sizl = psoColor->sizlBitmap;
613
614 if ((pxlo != NULL && pxlo->flXlate != XO_TRIVIAL)
615 || (psoColor->iType != STYPE_BITMAP))
616 {
617 /* Convert the unknown format to a screen format bitmap. */
618
619 RECTL rclDst;
620 POINTL ptlSrc;
621
622 DISPDBG((0, "DISP bCopyColorPointer going to convert XOR mask to bitmap\n"));
623
624 hsurfBitmap = (HSURF)EngCreateBitmap (sizl, 0, psoScreen->iBitmapFormat, BMF_TOPDOWN, NULL);
625
626 if (hsurfBitmap == NULL)
627 {
628 return FALSE;
629 }
630
631 psoBitmap = EngLockSurface (hsurfBitmap);
632
633 if (psoBitmap == NULL)
634 {
635 EngDeleteSurface (hsurfBitmap);
636 return FALSE;
637 }
638
639 /* Now do the bitmap conversion using EngCopyBits(). */
640
641 rclDst.left = 0;
642 rclDst.top = 0;
643 rclDst.right = sizl.cx;
644 rclDst.bottom = sizl.cy;
645
646 ptlSrc.x = 0;
647 ptlSrc.y = 0;
648
649 if (!EngCopyBits (psoBitmap, psoColor, NULL, pxlo, &rclDst, &ptlSrc))
650 {
651 EngUnlockSurface (psoBitmap);
652 EngDeleteSurface (hsurfBitmap);
653 return FALSE;
654 }
655
656 DISPDBG((0, "DISP bCopyColorPointer XOR mask converted to bitmap\n"));
657 }
658 else
659 {
660 DISPDBG((0, "DISP bCopyColorPointer XOR mask is already a bitmap\n"));
661 psoBitmap = psoColor;
662 }
663
664 /* Create 32 bpp surface for XOR mask */
665 hsurf32bpp = (HSURF)EngCreateBitmap (sizl, 0, BMF_32BPP, BMF_TOPDOWN, NULL);
666
667 if (hsurf32bpp != NULL)
668 {
669 pso32bpp = EngLockSurface (hsurf32bpp);
670
671 if (pso32bpp == NULL)
672 {
673 EngDeleteSurface (hsurf32bpp);
674 hsurf32bpp = NULL;
675 }
676 }
677
678 if (pso32bpp)
679 {
680 /* Convert psoBitmap bits to pso32bpp bits for known formats */
681 if (psoBitmap->iBitmapFormat == BMF_8BPP && ppdev->pPal)
682 {
683 PBYTE src = (PBYTE)psoBitmap->pvScan0;
684 PBYTE dst = (PBYTE)pso32bpp->pvScan0;
685
686 PPALETTEENTRY pPal = ppdev->pPal;
687 ULONG cPalette = 256; /* 256 is hardcoded in the driver in palette.c */
688
689 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 8 bpp to 32 bpp palette: %d entries\n", cPalette));
690
691 for (cy = 0; cy < (ULONG)sizl.cy; cy++)
692 {
693 ULONG cx;
694
695 PBYTE d = dst;
696
697 for (cx = 0; cx < (ULONG)sizl.cx; cx++)
698 {
699 BYTE index = src[cx];
700
701 *d++ = pPal[index].peBlue; /* B */
702 *d++ = pPal[index].peGreen; /* G */
703 *d++ = pPal[index].peRed; /* R */
704 *d++ = 0; /* destination is 32 bpp */
705 }
706
707 /* Point to next source and dest scans */
708 src += psoBitmap->lDelta;
709 dst += pso32bpp->lDelta;
710 }
711
712 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 8 bpp to 32 bpp completed\n"));
713 }
714 else if (psoBitmap->iBitmapFormat == BMF_16BPP)
715 {
716 PBYTE src = (PBYTE)psoBitmap->pvScan0;
717 PBYTE dst = (PBYTE)pso32bpp->pvScan0;
718
719 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 16 bpp to 32 bpp\n"));
720
721 for (cy = 0; cy < (ULONG)sizl.cy; cy++)
722 {
723 ULONG cx;
724
725 PBYTE d = dst;
726
727 for (cx = 0; cx < (ULONG)sizl.cx; cx++)
728 {
729 USHORT usSrc = *(USHORT *)&src[cx * 2];
730
731 *d++ = (BYTE)( usSrc << 3); /* B */
732 *d++ = (BYTE)((usSrc >> 5) << 2); /* G */
733 *d++ = (BYTE)((usSrc >> 11) << 3); /* R */
734 *d++ = 0; /* destination is 32 bpp */
735 }
736
737 /* Point to next source and dest scans */
738 src += psoBitmap->lDelta;
739 dst += pso32bpp->lDelta;
740 }
741
742 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 16 bpp to 32 bpp completed\n"));
743 }
744 else if (psoBitmap->iBitmapFormat == BMF_24BPP)
745 {
746 PBYTE src = (PBYTE)psoBitmap->pvScan0;
747 PBYTE dst = (PBYTE)pso32bpp->pvScan0;
748
749 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 24 bpp to 32 bpp\n"));
750
751 for (cy = 0; cy < (ULONG)sizl.cy; cy++)
752 {
753 ULONG cx;
754
755 PBYTE s = src;
756 PBYTE d = dst;
757
758 for (cx = 0; cx < (ULONG)sizl.cx; cx++)
759 {
760 *d++ = *s++; /* B */
761 *d++ = *s++; /* G */
762 *d++ = *s++; /* R */
763 *d++ = 0; /* destination is 32 bpp */
764 }
765
766 /* Point to next source and dest scans */
767 src += psoBitmap->lDelta;
768 dst += pso32bpp->lDelta;
769 }
770
771 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 24 bpp to 32 bpp completed\n"));
772 }
773 else if (psoBitmap->iBitmapFormat == BMF_32BPP)
774 {
775 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 32 bpp to 32 bpp, pso32bpp->cjBits = %d, psoBitmap->cjBits = %d\n", pso32bpp->cjBits, psoBitmap->cjBits));
776
777 RtlCopyMemory (pso32bpp->pvBits, psoBitmap->pvBits, min(pso32bpp->cjBits, psoBitmap->cjBits));
778
779 DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 32 bpp to 32 bpp completed\n"));
780 }
781 else
782 {
783 DISPDBG((0, "DISP bCopyColorPointer XOR mask unsupported bpp\n"));
784
785 EngUnlockSurface (pso32bpp);
786 pso32bpp = NULL;
787 EngDeleteSurface (hsurf32bpp);
788 hsurf32bpp = NULL;
789 }
790 }
791
792 if (hsurfBitmap)
793 {
794 EngUnlockSurface (psoBitmap);
795 psoBitmap = NULL;
796 EngDeleteSurface (hsurfBitmap);
797 hsurfBitmap = NULL;
798 }
799 }
800 }
801
802 if (!pso32bpp)
803 {
804 return (FALSE);
805 }
806
807 /*
808 * pso is 32 bit BGRX bitmap. Copy it to Pixels
809 */
810
811 pjSrcXor = (PBYTE)pso32bpp->pvScan0;
812
813 for (cy = 0; cy < cySrc; cy++)
814 {
815 /* 32 bit bitmap is being copied */
816 RtlCopyMemory (pjDstXor, pjSrcXor, cxSrc * 4);
817
818 /* Point to next source and dest scans */
819 pjSrcXor += pso32bpp->lDelta;
820 pjDstXor += pPointerAttributes->WidthInBytes;
821 }
822
823 if (pso32bpp != psoColor)
824 {
825 /* Deallocate the temporary 32 bit pso */
826 EngUnlockSurface (pso32bpp);
827 EngDeleteSurface (hsurf32bpp);
828 }
829
830 return (TRUE);
831}
832
833
834/******************************Public*Routine******************************\
835* bInitPointer
836*
837* Initialize the Pointer attributes.
838*
839\**************************************************************************/
840
841BOOL bInitPointer(PPDEV ppdev, DEVINFO *pdevinfo)
842{
843 DWORD returnedDataLength;
844
845 ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL;
846 ppdev->cjPointerAttributes = 0; // initialized in screen.c
847
848 //
849 // Ask the miniport whether it provides pointer support.
850 //
851
852 if (EngDeviceIoControl(ppdev->hDriver,
853 IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES,
854 &ppdev->ulMode,
855 sizeof(PVIDEO_MODE),
856 &ppdev->PointerCapabilities,
857 sizeof(ppdev->PointerCapabilities),
858 &returnedDataLength))
859 {
860 return(FALSE);
861 }
862
863 //
864 // If neither mono nor color hardware pointer is supported, there's no
865 // hardware pointer support and we're done.
866 //
867
868 if ((!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)) &&
869 (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER)))
870 {
871 return(TRUE);
872 }
873
874 //
875 // Note: The buffer itself is allocated after we set the
876 // mode. At that time we know the pixel depth and we can
877 // allocate the correct size for the color pointer if supported.
878 //
879
880 //
881 // Set the asynchronous support status (async means miniport is capable of
882 // drawing the Pointer at any time, with no interference with any ongoing
883 // drawing operation)
884 //
885
886 if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_ASYNC_POINTER)
887 {
888 pdevinfo->flGraphicsCaps |= GCAPS_ASYNCMOVE;
889 }
890 else
891 {
892 pdevinfo->flGraphicsCaps &= ~GCAPS_ASYNCMOVE;
893 }
894
895 /* VBOX supports pointers with alpha channel */
896 pdevinfo->flGraphicsCaps2 |= GCAPS2_ALPHACURSOR;
897
898 return(TRUE);
899}
900
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette