VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

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