VirtualBox

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

Last change on this file since 8061 was 4540, checked in by vboxsync, 17 years ago

Implemented notification for guest about an active VRDP connection.

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