VBoxUtils.c revision a2760a4d593af57a19ec32cdfd1723b68495df8c
/** @file
*
* VirtualBox Linux Additions mouse driver utility functions
*/
/*
* Copyright (C) 2006-2007 innotek GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* 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/VBoxGuest.h>
#include "VBoxUtils.h"
#include "xf86.h"
#define NEED_XF86_TYPES
#include "xf86_ansic.h"
#include "compiler.h"
#include <asm/ioctl.h>
/* the vboxadd module file handle */
static int g_vboxaddHandle = -1;
/* the request structure */
static VMMDevReqMouseStatus *g_vmmreqMouseStatus = NULL;
/**
* Initialise mouse integration. Returns 0 on success and 1 on failure
* (for example, if the VBox kernel module is not loaded).
*/
int VBoxMouseInit(void)
{
VMMDevReqMouseStatus req;
/* return immediately if already initialized */
if (g_vboxaddHandle != -1)
return 0;
/* open the driver */
g_vboxaddHandle = open(VBOXGUEST_DEVICE_NAME, O_RDWR, 0);
if (g_vboxaddHandle < 0)
{
ErrorF("Unable to open the virtual machine device: %s\n",
strerror(errno));
return 1;
}
/* prepare the request structure */
g_vmmreqMouseStatus = malloc(vmmdevGetRequestSize(VMMDevReq_GetMouseStatus));
if (!g_vmmreqMouseStatus)
{
ErrorF("Ran out of memory while querying the virtual machine for the mouse capabilities.\n");
return 1;
}
vmmdevInitRequest((VMMDevRequestHeader*)g_vmmreqMouseStatus, VMMDevReq_GetMouseStatus);
/* tell the host that we want absolute coordinates */
vmmdevInitRequest((VMMDevRequestHeader*)&req, VMMDevReq_SetMouseStatus);
req.mouseFeatures = VBOXGUEST_MOUSE_GUEST_CAN_ABSOLUTE | VBOXGUEST_MOUSE_GUEST_NEEDS_HOST_CURSOR;
req.pointerXPos = 0;
req.pointerYPos = 0;
if (ioctl(g_vboxaddHandle, IOCTL_VBOXGUEST_VMMREQUEST, (void*)&req) < 0)
{
ErrorF("Error sending mouse pointer capabilities to VMM! rc = %d (%s)\n",
errno, strerror(errno));
return 1;
}
/* everything is fine, put out some branding */
xf86Msg(X_INFO, "VirtualBox mouse pointer integration available.\n");
return 0;
}
/**
* Queries the absolute mouse position from the host.
*
* Returns 0 on success.
* Returns 1 when the host doesn't want absolute coordinates (no coordinates returned)
* Otherwise > 1 which means unsuccessful.
*/
int VBoxMouseQueryPosition(unsigned int *abs_x, unsigned int *abs_y)
{
/* If we failed to initialise, say that we don't want absolute co-ordinates. */
if (g_vboxaddHandle < 0)
return 1;
/* perform VMM request */
if (ioctl(g_vboxaddHandle, IOCTL_VBOXGUEST_VMMREQUEST, (void*)g_vmmreqMouseStatus) >= 0)
{
if (VBOX_SUCCESS(g_vmmreqMouseStatus->header.rc))
{
/* does the host want absolute coordinates? */
if (g_vmmreqMouseStatus->mouseFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE)
{
*abs_x = g_vmmreqMouseStatus->pointerXPos;
*abs_y = g_vmmreqMouseStatus->pointerYPos;
return 0;
}
else
return 1;
}
else
{
ErrorF("Error querying host mouse position! header.rc = %d\n", g_vmmreqMouseStatus->header.rc);
}
}
else
{
ErrorF("Error performing VMM request! errno = %d (%s)\n",
errno, strerror(errno));
}
/* error! */
return 2;
}
int VBoxMouseFini(void)
{
VMMDevReqMouseStatus req;
/* If we are not initialised, there is nothing to do */
if (g_vboxaddHandle < 0)
return 0;
/* tell VMM that we no longer support absolute mouse handling */
vmmdevInitRequest((VMMDevRequestHeader*)&req, VMMDevReq_SetMouseStatus);
req.mouseFeatures = 0;
req.pointerXPos = 0;
req.pointerYPos = 0;
if (ioctl(g_vboxaddHandle, IOCTL_VBOXGUEST_VMMREQUEST, (void*)&req) < 0)
{
ErrorF("ioctl to vboxadd module failed, rc = %d (%s)\n",
errno, strerror(errno));
}
free(g_vmmreqMouseStatus);
g_vmmreqMouseStatus = NULL;
close(g_vboxaddHandle);
g_vboxaddHandle = -1;
return 0;
}