pointer.c revision c87c6e10b608762972b76bfc734daaec9070b50b
/** @file
* VirtualBox X11 Additions graphics driver utility functions
*/
/*
* Copyright (C) 2006-2012 Oracle Corporation
*
* 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.
*/
#include <VBox/VBoxGuestLib.h>
#ifndef PCIACCESS
# include <xf86Pci.h>
# include <Pci.h>
#endif
#include "xf86.h"
#define NEED_XF86_TYPES
#include "compiler.h"
#include "cursorstr.h"
#include "servermd.h"
#include "vboxvideo.h"
#ifdef XORG_7X
# include <stdlib.h>
#endif
#define VBOX_MAX_CURSOR_WIDTH 64
#define VBOX_MAX_CURSOR_HEIGHT 64
/**************************************************************************
* Debugging functions and macros *
**************************************************************************/
/* #define DEBUG_POINTER */
#ifdef DEBUG
#else /* DEBUG_VIDEO not defined */
# define PUT_PIXEL(c) do { } while(0)
#endif /* DEBUG_VIDEO not defined */
/** Macro to printf an error message and return from a function */
do \
{ \
return RetVal; \
} \
while (0)
/** Structure to pass cursor image data between realise_cursor() and
* load_cursor_image(). The members match the parameters to
* @a VBoxHGSMIUpdatePointerShape(). */
struct vboxCursorImage
{
};
#ifdef DEBUG_POINTER
static void
{
size_t x, y;
unsigned short pitch;
unsigned char *mask;
image += sizeof(struct vboxCursorImage);
TRACE_ENTRY();
{
for (x = 0; x < w; ++x)
{
ErrorF (" ");
else
{
if (c == bg)
ErrorF("Y");
else
ErrorF("X");
}
}
ErrorF("\n");
}
}
#endif
/**************************************************************************
* Main functions *
**************************************************************************/
void
{
TRACE_ENTRY();
TRACE_EXIT();
}
static void
{
int rc;
}
static void
{
int rc;
if (!pVBox->fUseHardwareCursor)
return;
0, 0, 0, 0, NULL, 0);
}
static void
unsigned char *pvImage)
{
int rc;
struct vboxCursorImage *pImage;
#ifdef DEBUG_POINTER
#endif
}
static void
{
/* ErrorF("vbox_set_cursor_colors NOT IMPLEMENTED\n"); */
}
static void
{
/* This currently does nothing. */
}
static void
{
}
static void
{
}
static void
{
}
static Bool
{
return pVBox->fUseHardwareCursor;
}
static unsigned char
color_to_byte(unsigned c)
{
return (c >> 8) & 0xff;
}
static unsigned char *
{
unsigned short w, h, x, y;
struct vboxCursorImage *pImage;
if (!w || !h || w > VBOX_MAX_CURSOR_WIDTH || h > VBOX_MAX_CURSOR_HEIGHT)
"Error invalid cursor dimensions %dx%d\n", w, h);
"Error invalid cursor hotspot location %dx%d (max %dx%d)\n",
sizeRgba = w * h * 4;
if (!c)
"Error failed to alloc %lu bytes for cursor\n",
(unsigned long) sizeRequest);
pImage = (struct vboxCursorImage *)p;
TRACE_LOG ("w=%d h=%d sm=%d sr=%d p=%d\n",
/*
* Xorg:
* The mask is a bitmap indicating which parts of the cursor are
* transparent and which parts are drawn. The source is a bitmap
* indicating which parts of the non-transparent portion of the
* the cursor should be painted in the foreground color and which
* should be painted in the background color. By default, set bits
* indicate the opaque part of the mask bitmap and clear bits
* indicate the transparent part.
* VBox:
* The color data is the XOR mask. The AND mask bits determine
* which pixels of the color data (XOR mask) will replace (overwrite)
* the screen pixels (AND mask bit = 0) and which ones will be XORed
* with existing screen pixels (AND mask bit = 1).
* For example when you have the AND mask all 0, then you see the
* correct mouse pointer image surrounded by black square.
*/
y < h;
{
for (x = 0; x < w; ++x)
{
{
/* opaque, leave AND mask bit at 0 */
{
PUT_PIXEL('X');
}
else
{
PUT_PIXEL('*');
}
}
else
{
/* transparent, set AND mask bit */
m[x / 8] |= 1 << (7 - (x % 8));
/* don't change the screen pixel */
*cp++ = 0;
PUT_PIXEL(' ');
}
}
PUT_PIXEL('\n');
}
#ifdef DEBUG_POINTER
ErrorF("shape = %p\n", p);
vbox_show_shape(w, h, bc, c);
#endif
return p;
}
#ifdef ARGB_CURSOR
static Bool
{
if (!pVBox->fUseHardwareCursor)
return FALSE;
return FALSE;
return TRUE;
}
static void
{
unsigned short w, h;
unsigned char *pm;
CARD8 *p;
int scrnIndex;
int rc;
/* Mask must be generated for alpha cursors, that is required by VBox. */
/* note: (michael) the next struct must be 32bit aligned. */
if (!w || !h || w > VBOX_MAX_CURSOR_WIDTH || h > VBOX_MAX_CURSOR_HEIGHT)
"Error invalid cursor dimensions %dx%d\n", w, h);
"Error invalid cursor hotspot location %dx%d (max %dx%d)\n",
if (!p)
"Error failed to alloc %lu bytes for cursor\n",
(unsigned long)sizeData);
/* Emulate the AND mask. */
pm = p;
/* Init AND mask to 1 */
/*
* The additions driver must provide the AND mask for alpha cursors. The host frontend
* which can handle alpha channel, will ignore the AND mask and draw an alpha cursor.
* But if the host does not support ARGB, then it simply uses the AND mask and the color
* data to draw a normal color cursor.
*/
{
unsigned char bitmask = 0x80;
{
if (bitmask == 0)
bitmask = 0x80;
}
/* Point to next source and dest scans */
pc += w;
}
free(p);
}
#endif
{
TRACE_ENTRY();
if (!pCurs) {
"Failed to create X Window cursor information structures for virtual mouse.\n");
}
if (rc) {
#ifdef ARGB_CURSOR
#endif
}
if (!rc)
"Failed to enable mouse pointer integration.\n");
return rc;
}