VirtualBox

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

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

Additions/WINNT: reverted r51445

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