VirtualBox

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

Last change on this file since 22446 was 22446, checked in by vboxsync, 15 years ago

Additions/WINNT: re-enable the host mouse cursor when the guest requests it

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