pointer.c revision 35396ee506ef68dd1c161f1ef2c3c0b68a146ff2
/******************************Module*Header*******************************\
*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: pointer.c *
* *
* This module contains the hardware Pointer support for the framebuffer *
* *
* Copyright (c) 1992-1998 Microsoft Corporation *
\**************************************************************************/
#include "driver.h"
#ifndef SPS_ALPHA
#define SPS_ALPHA 0x00000010L
#endif
LONG x,
LONG y,
/******************************Public*Routine******************************\
* DrvMovePointer
*
* Moves the hardware pointer to a new position.
*
\**************************************************************************/
(
LONG x,
LONG y,
)
{
// We don't use the exclusion rectangle because we only support
// hardware Pointers. If we were doing our own Pointer simulations
// we would want to update prcl so that the engine would call us
// to exclude out pointer before drawing to the pixels in prcl.
// Convert the pointer's position from relative to absolute
// coordinates (this is only significant for multiple board
// support).
// If x is -1 after the offset then take down the cursor.
if (x == -1)
{
//
// A new position of (-1,-1) means hide the pointer.
//
NULL,
0,
NULL,
0,
{
//
// Not the end of the world, print warning in checked build.
//
}
}
else
{
//
// Call miniport driver to move Pointer.
//
sizeof(VIDEO_POINTER_POSITION),
NULL,
0,
{
//
// Not the end of the world, print warning in checked build.
//
}
}
}
/******************************Public*Routine******************************\
* DrvSetPointerShape
*
* Sets the new pointer shape.
*
\**************************************************************************/
(
LONG x,
LONG y,
)
{
// We don't use the exclusion rectangle because we only support
// hardware Pointers. If we were doing our own Pointer simulations
// we would want to update prcl so that the engine would call us
// to exclude out pointer before drawing to the pixels in prcl.
{
// Mini-port has no hardware Pointer support.
return(SPS_ERROR);
}
{
if (ppdev->fHwCursorActive) {
NULL,
0,
NULL,
0,
&returnedDataLength)) {
}
}
//
// Mini-port declines to realize this Pointer
//
return(SPS_DECLINE);
}
else
{
}
return(SPS_ACCEPT_NOEXCLUDE);
}
/******************************Public*Routine******************************\
* bSetHardwarePointerShape
*
* Changes the shape of the Hardware Pointer.
*
* Returns: True if successful, False if Pointer shape can't be hardware.
*
\**************************************************************************/
LONG x,
LONG y,
{
{
{
} else {
return(FALSE);
}
} else {
{
} else {
return(FALSE);
}
}
//
// Initialize Pointer attributes and position
//
if (x == -1)
{
/* Pointer should be created invisible */
}
else
{
/* New coordinates of pointer's hot spot */
}
/* VBOX: We have to pass to miniport hot spot coordinates and alpha flag.
* They will be encoded in the pPointerAttributes::Enable field.
* High word will contain hot spot info and low word - flags.
*/
{
}
//
// set animate flags
//
if (fl & SPS_ANIMATESTART) {
} else if (fl & SPS_ANIMATEUPDATE) {
}
//
// Set the new Pointer shape.
//
NULL,
0,
&returnedDataLength)) {
return(FALSE);
}
//
// Set new pointer position
//
if (x != -1) {
&vpp,
sizeof (vpp),
NULL,
0,
&returnedDataLength)) {
// Should never fail, informational message.
}
}
return(TRUE);
}
/******************************Public*Routine******************************\
* bCopyMonoPointer
*
* Copies two monochrome masks into a buffer of the maximum size handled by the
* miniport, with any extra bits set to 0. The masks are converted to topdown
* form if they aren't already. Returns TRUE if we can handle this pointer in
* hardware, FALSE if not.
*
\**************************************************************************/
{
// Make sure the new pointer isn't too big to handle,
// strip the size to 64x64 if necessary
{
}
{
}
/* Size of AND mask in bytes */
/* Pointer to XOR mask is 4-bytes aligned */
/* Init AND mask to 1 */
/*
* Copy AND mask.
*/
DISPDBG((0, "DISP bCopyMonoPointer going to copy AND mask\n"));
{
// Point to next source and dest scans
}
DISPDBG((0, "DISP bCopyMonoPointer AND mask copied\n"));
DISPDBG((0, "DISP bCopyMonoPointer going to create RGB0 XOR mask\n"));
{
{
if (bitmask == 0)
{
bitmask = 0x80;
}
{
}
else
{
}
}
// Point to next source and dest scans
}
DISPDBG((0, "DISP bCopyMonoPointer created RGB0 XOR mask\n"));
return(TRUE);
}
/******************************Public*Routine******************************\
* bCopyColorPointer
*
* Copies the mono and color masks into the buffer of maximum size
* handled by the miniport with any extra bits set to 0. Color translation
* is handled at this time. The masks are converted to topdown form if they
* aren't already. Returns TRUE if we can handle this pointer in hardware,
* FALSE if not.
*
\**************************************************************************/
{
/* Format of "hardware" pointer is:
* 1 bpp AND mask with byte aligned scanlines,
* B G R A bytes of XOR mask that starts on the next 4 byte aligned offset after AND mask.
*
* If fl & SPS_ALPHA then A bytes contain alpha channel information.
* Otherwise A bytes are undefined (but will be 0).
*
*/
/* To simplify this function we use the following method:
* for pointers with alpha channel
* we have BGRA values in psoColor and will simply copy them to pPointerAttributes->Pixels
* for color pointers
* always convert supplied bitmap to 32 bit BGR0
* copy AND mask and new BGR0 XOR mask to pPointerAttributes->Pixels
*/
// Make sure the new pointer isn't too big to handle,
// strip the size to 64x64 if necessary
{
}
{
}
/* Size of AND mask in bytes */
/* Pointer to XOR mask is 4-bytes aligned */
/* Init AND mask to 1 */
{
DISPDBG((0, "DISP bCopyColorPointer SPS_ALPHA\n"));
/*
* Emulate AND mask to provide viewable mouse pointer for
* hardware which does not support alpha channel.
*/
DISPDBG((0, "DISP bCopyColorPointer going to emulate AND mask\n"));
{
{
if (bitmask == 0)
{
bitmask = 0x80;
}
{
}
}
// Point to next source and dest scans
}
DISPDBG((0, "DISP bCopyColorPointer AND mask emulated\n"));
}
else
{
if (!psoMask)
{
/* This can not be, mask must be supplied for a color pointer. */
return (FALSE);
}
/*
* Copy AND mask.
*/
DISPDBG((0, "DISP bCopyColorPointer going to copy AND mask\n"));
{
// Point to next source and dest scans
}
DISPDBG((0, "DISP bCopyColorPointer AND mask copied\n"));
/*
* Convert given psoColor to 32 bit BGR0.
*/
DISPDBG((0, "DISP bCopyColorPointer psoScreen t = %d, f = %d, psoColor t = %d, f = %d, pxlo = %p, psoColor->lDelta = %d, ->cx = %d\n",
psoScreen->iType, psoScreen->iBitmapFormat, psoColor->iType, psoColor->iBitmapFormat, pxlo, psoColor->lDelta, psoColor->sizlBitmap.cx));
{
/* The psoColor is already in desired format */
DISPDBG((0, "DISP bCopyColorPointer XOR mask already in 32 bpp\n"));
}
else
{
{
/* Convert the unknown format to a screen format bitmap. */
DISPDBG((0, "DISP bCopyColorPointer going to convert XOR mask to bitmap\n"));
if (hsurfBitmap == NULL)
{
return FALSE;
}
{
return FALSE;
}
/* Now do the bitmap conversion using EngCopyBits(). */
ptlSrc.x = 0;
ptlSrc.y = 0;
{
return FALSE;
}
DISPDBG((0, "DISP bCopyColorPointer XOR mask converted to bitmap\n"));
}
else
{
DISPDBG((0, "DISP bCopyColorPointer XOR mask is already a bitmap\n"));
}
/* Create 32 bpp surface for XOR mask */
if (hsurf32bpp != NULL)
{
{
hsurf32bpp = NULL;
}
}
if (pso32bpp)
{
/* Convert psoBitmap bits to pso32bpp bits for known formats */
{
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 8 bpp to 32 bpp palette: %d entries\n", cPalette));
{
{
*d++ = 0; /* destination is 32 bpp */
}
/* Point to next source and dest scans */
}
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 8 bpp to 32 bpp completed\n"));
}
{
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 16 bpp to 32 bpp\n"));
{
{
*d++ = 0; /* destination is 32 bpp */
}
/* Point to next source and dest scans */
}
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 16 bpp to 32 bpp completed\n"));
}
{
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 24 bpp to 32 bpp\n"));
{
{
*d++ = *s++; /* B */
*d++ = *s++; /* G */
*d++ = *s++; /* R */
*d++ = 0; /* destination is 32 bpp */
}
/* Point to next source and dest scans */
}
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 24 bpp to 32 bpp completed\n"));
}
{
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 32 bpp to 32 bpp, pso32bpp->cjBits = %d, psoBitmap->cjBits = %d\n", pso32bpp->cjBits, psoBitmap->cjBits));
DISPDBG((0, "DISP bCopyColorPointer XOR mask conv 32 bpp to 32 bpp completed\n"));
}
else
{
DISPDBG((0, "DISP bCopyColorPointer XOR mask unsupported bpp\n"));
hsurf32bpp = NULL;
}
}
if (hsurfBitmap)
{
hsurfBitmap = NULL;
}
}
}
if (!pso32bpp)
{
return (FALSE);
}
/*
* pso is 32 bit BGRX bitmap. Copy it to Pixels
*/
{
/* 32 bit bitmap is being copied */
/* Point to next source and dest scans */
}
{
/* Deallocate the temporary 32 bit pso */
}
return (TRUE);
}
/******************************Public*Routine******************************\
* bInitPointer
*
* Initialize the Pointer attributes.
*
\**************************************************************************/
{
//
// Ask the miniport whether it provides pointer support.
//
sizeof(PVIDEO_MODE),
sizeof(ppdev->PointerCapabilities),
{
return(FALSE);
}
//
// If neither mono nor color hardware pointer is supported, there's no
// hardware pointer support and we're done.
//
{
return(TRUE);
}
//
// Note: The buffer itself is allocated after we set the
// mode. At that time we know the pixel depth and we can
// allocate the correct size for the color pointer if supported.
//
//
// Set the asynchronous support status (async means miniport is capable of
// drawing the Pointer at any time, with no interference with any ongoing
// drawing operation)
//
{
}
else
{
}
/* VBOX supports pointers with alpha channel */
return(TRUE);
}