summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@fido2.homeip.net>2008-10-21 18:52:02 -0700
committerPhilip Langdale <philipl@fido2.homeip.net>2008-10-21 18:52:02 -0700
commit370a0ffa789c1c64d5343153bdb5ddccd502a361 (patch)
treeb25d204a4fd2c6641c3db2b7790282d81c3e7cd6 /shared
parent4c26f5cffba924daa514134e6c6dfcbc3c391d27 (diff)
Move shared vmmouse files into a separate static lib so we can
share it with the vmmouse detection utility I'm about to add.
Diffstat (limited to 'shared')
-rw-r--r--shared/Makefile.am29
-rw-r--r--shared/vmmouse_client.c339
-rw-r--r--shared/vmmouse_client.h73
-rw-r--r--shared/vmmouse_defs.h66
-rw-r--r--shared/vmmouse_proto.c147
-rw-r--r--shared/vmmouse_proto.h131
6 files changed, 785 insertions, 0 deletions
diff --git a/shared/Makefile.am b/shared/Makefile.am
new file mode 100644
index 0000000..feedffa
--- /dev/null
+++ b/shared/Makefile.am
@@ -0,0 +1,29 @@
+# Copyright 2008 VMware, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# VMWARE, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+INCLUDES = -I$(srcdir)
+
+noinst_LTLIBRARIES = lib@DRIVER_NAME@.la
+lib@DRIVER_NAME@_la_SOURCES = @DRIVER_NAME@_defs.h \
+ @DRIVER_NAME@_client.c @DRIVER_NAME@_client.h \
+ @DRIVER_NAME@_proto.c @DRIVER_NAME@_proto.h
+
+
+
diff --git a/shared/vmmouse_client.c b/shared/vmmouse_client.c
new file mode 100644
index 0000000..f34c223
--- /dev/null
+++ b/shared/vmmouse_client.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2002-2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmmouse_client.c --
+ *
+ * VMware Virtual Mouse Client
+ *
+ * This module provides functions to enable, operate and process
+ * packets via the VMMouse module hosted in the VMX.
+ *
+ */
+
+#include "vmmouse_client.h"
+#include "vmmouse_proto.h"
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMMouseClientVMCheck --
+ *
+ * Checks if we're running in a VM by sending the GETVERSION command.
+ *
+ * Returns:
+ * 0 if we're running natively/the version command failed,
+ * 1 if we're in a VM.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+VMMouseClientVMCheck(void)
+{
+ VMMouseProtoCmd vmpc;
+
+ vmpc.in.vEbx = ~VMMOUSE_PROTO_MAGIC;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_GETVERSION;
+ VMMouseProto_SendCmd(&vmpc);
+
+ /*
+ * ebx should contain VMMOUSE_PROTO_MAGIC
+ * eax should contain version
+ */
+ if (vmpc.out.vEbx != VMMOUSE_PROTO_MAGIC || vmpc.out.vEax == 0xffffffff) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMMouseClient_Disable --
+ *
+ * Tries to disable VMMouse communication mode on the host.
+ * The caller is responsible for maintaining state (we don't check
+ * if we're enabled before attempting to disable the VMMouse).
+ *
+ * Results:
+ * TRUE if we successfully disable the VMMouse communication mode,
+ * FALSE if something went wrong.
+ *
+ * Side effects:
+ * Disables the absolute positioning mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+VMMouseClient_Disable(void)
+{
+ uint32_t status;
+ VMMouseProtoCmd vmpc;
+
+ VMwareLog(("VMMouseClient_Disable: writing disable command to port\n"));
+ vmpc.in.vEbx = VMMOUSE_CMD_DISABLE;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND;
+ VMMouseProto_SendCmd(&vmpc);
+ /*
+ * We should get 0xffff in the flags now.
+ */
+ vmpc.in.vEbx = 0;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS;
+ VMMouseProto_SendCmd(&vmpc);
+ status = vmpc.out.vEax;
+ if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR) {
+ VMwareLog(("VMMouseClient_Disable: wrong status returned\n"));
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMMouseClient_Enable --
+ *
+ * Public Enable entry point. The driver calls this once it feels
+ * ready to deal with VMMouse stuff. For now, we just try to enable
+ * and return the result, but conceivably we could do more.
+ *
+ * Results:
+ * TRUE if the enable succeeds, FALSE otherwise.
+ *
+ * Side effects:
+ * Causes host-side state change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+VMMouseClient_Enable(void) {
+
+ uint32_t status;
+ uint32_t data;
+ VMMouseProtoCmd vmpc;
+
+ /*
+ * First, make sure we're in a VM; i.e. in dualboot configurations we might
+ * find ourselves running on real hardware.
+ */
+
+ if (!VMMouseClientVMCheck()) {
+ return FALSE;
+ }
+
+ VMwareLog(("VMMouseClientVMCheck succeeded, checking VMMOUSE version\n"));
+ VMwareLog(("VMMouseClient_Enable: READ_ID 0x%08x, VERSION_ID 0x%08x\n",
+ VMMOUSE_CMD_READ_ID, VMMOUSE_VERSION_ID));
+
+ /*
+ * We probe for the VMMouse backend by sending the ENABLE
+ * command to the mouse. We should get back the VERSION_ID on
+ * the data port.
+ */
+ vmpc.in.vEbx = VMMOUSE_CMD_READ_ID;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND;
+ VMMouseProto_SendCmd(&vmpc);
+
+ /*
+ * Check whether the VMMOUSE_VERSION_ID is available to read
+ */
+ vmpc.in.vEbx = 0;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS;
+ VMMouseProto_SendCmd(&vmpc);
+ status = vmpc.out.vEax;
+ if ((status & 0x0000ffff) == 0) {
+ VMwareLog(("VMMouseClient_Enable: no data on port."));
+ return FALSE;
+ }
+
+ /*
+ * Get the VMMOUSE_VERSION_ID then
+ */
+ /* Get just one item */
+ vmpc.in.vEbx = 1;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_DATA;
+ VMMouseProto_SendCmd(&vmpc);
+ data = vmpc.out.vEax;
+ if (data!= VMMOUSE_VERSION_ID) {
+ VMwareLog(("VMMouseClient_Enable: data was not VERSION_ID"));
+ return FALSE;
+ }
+
+ /*
+ * To quote Jeremy, "Go Go Go!"
+ */
+
+ VMwareLog(("VMMouseClient_Enable: go go go!\n"));
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMMouseClient_GetInput --
+ *
+ * Retrieves a 4-word input packet from the VMMouse data port and
+ * stores it in the specified input structure.
+ *
+ * Results:
+ * The number of packets in the queue, including the retrieved
+ * packet.
+ *
+ * Side effects:
+ * Could cause host state change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned int
+VMMouseClient_GetInput (PVMMOUSE_INPUT_DATA pvmmouseInput) {
+
+ uint32_t status;
+ uint16_t numWords;
+ uint32_t packetInfo;
+ VMMouseProtoCmd vmpc;
+
+ /*
+ * The status dword has two parts: the high 16 bits are
+ * for flags, the low 16-bits are the number of DWORDs
+ * waiting in the data queue. VMMOUSE_ERROR is a special
+ * case that indicates there's something wrong on the
+ * host end, e.g. the VMMouse was disabled on the host-side.
+ */
+ vmpc.in.vEbx = 0;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS;
+ VMMouseProto_SendCmd(&vmpc);
+ status = vmpc.out.vEax;
+ if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
+ VMwareLog(("VMMouseClient_GetInput: VMMOUSE_ERROR status, abort!\n"));
+ return VMMOUSE_ERROR;
+ }
+
+ /*
+ * We don't use the status flags, just get the words
+ */
+ numWords = status & 0x0000ffff;
+
+ if ((numWords % 4) != 0) {
+ VMwareLog(("VMMouseClient_GetInput: invalid status numWords, abort!\n"));
+ return (0);
+ }
+
+ if (numWords == 0) {
+ return (0);
+ }
+
+ /*
+ * The VMMouse uses a 4-dword packet protocol:
+ * DWORD 0: Button State and per-packet flags
+ * DWORD 1: X position (absolute or relative)
+ * DWORD 2: Y position (absolute or relative)
+ * DWORD 3: Z position (relative)
+ */
+ /* Get 4 items at once */
+ vmpc.in.vEbx = 4;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_DATA;
+ VMMouseProto_SendCmd(&vmpc);
+ packetInfo = vmpc.out.vEax;
+ pvmmouseInput->Flags = (packetInfo & 0xffff0000) >> 16;
+ pvmmouseInput->Buttons = (packetInfo & 0x0000ffff);
+
+ /* Note that Z is always signed, and X/Y are signed in relative mode. */
+ pvmmouseInput->X = (int)vmpc.out.vEbx;
+ pvmmouseInput->Y = (int)vmpc.out.vEcx;
+ pvmmouseInput->Z = (int)vmpc.out.vEdx;
+
+ /*
+ * Return number of packets (including this one) in queue.
+ */
+ return (numWords >> 2);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMMouseClient_RequestRelative --
+ *
+ * Request that the host switch to posting relative packets. It's just
+ * advisory, so we make no guarantees about if/when the switch will
+ * happen.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Host may start posting relative packets in the near future.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+VMMouseClient_RequestRelative(void)
+{
+ VMMouseProtoCmd vmpc;
+
+ VMwareLog(("VMMouseClient: requesting relative mode\n"));
+ vmpc.in.vEbx = VMMOUSE_CMD_REQUEST_RELATIVE;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND;
+ VMMouseProto_SendCmd(&vmpc);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMMouseClient_RequestAbsolute --
+ *
+ * Request that the host switch to posting absolute packets. It's just
+ * advisory, so we make no guarantees about if/when the switch will
+ * happen.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Host may start posting absolute packets in the near future.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+VMMouseClient_RequestAbsolute(void)
+{
+ VMMouseProtoCmd vmpc;
+
+ VMwareLog(("VMMouseClient: requesting absolute mode\n"));
+ vmpc.in.vEbx = VMMOUSE_CMD_REQUEST_ABSOLUTE;
+ vmpc.in.command = VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND;
+ VMMouseProto_SendCmd(&vmpc);
+}
diff --git a/shared/vmmouse_client.h b/shared/vmmouse_client.h
new file mode 100644
index 0000000..b01bf08
--- /dev/null
+++ b/shared/vmmouse_client.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2002-2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmmouse_client.h --
+ *
+ * VMware Virtual Mouse Client
+ *
+ * This module provides functions to enable/disable, operate and
+ * process packets via the VMMouse absolute positioning module
+ * hosted in the VMX.
+ *
+ */
+
+#ifndef _VMMOUSE_CLIENT_H_
+#define _VMMOUSE_CLIENT_H_
+
+#include "xf86_OSproc.h"
+
+/*
+ * VMMouse Input packet data structure
+ */
+typedef struct _VMMOUSE_INPUT_DATA {
+ unsigned short Flags;
+ unsigned short Buttons;
+ int X;
+ int Y;
+ int Z;
+} VMMOUSE_INPUT_DATA, *PVMMOUSE_INPUT_DATA;
+
+/*
+ * Public Functions
+ */
+Bool VMMouseClient_Enable(void);
+void VMMouseClient_Disable(void);
+unsigned int VMMouseClient_GetInput(PVMMOUSE_INPUT_DATA pvmmouseInput);
+void VMMouseClient_RequestRelative(void);
+void VMMouseClient_RequestAbsolute(void);
+
+#ifdef VMX86_DEVEL
+#define VMwareLog(args) ErrorF args
+#else
+#define VMwareLog(args)
+#endif
+
+#include "vmmouse_defs.h"
+
+#endif /* _VMMOUSE_CLIENT_H_ */
+
diff --git a/shared/vmmouse_defs.h b/shared/vmmouse_defs.h
new file mode 100644
index 0000000..8dc769e
--- /dev/null
+++ b/shared/vmmouse_defs.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2002-2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmmouse_defs.h --
+ *
+ * VMware Virtual Mouse Protocol definitions. These constants
+ * are shared by the host-side VMMouse module and
+ * the guest tools/drivers.
+ *
+ */
+
+#ifndef _VMMOUSE_DEFS_H_
+#define _VMMOUSE_DEFS_H_
+
+/*
+ * Command related defines
+ */
+#define VMMOUSE_CMD_READ_ID 0x45414552
+#define VMMOUSE_CMD_DISABLE 0x000000f5
+#define VMMOUSE_CMD_REQUEST_RELATIVE 0x4c455252
+#define VMMOUSE_CMD_REQUEST_ABSOLUTE 0x53424152
+
+/*
+ * Data related defines
+ */
+#define VMMOUSE_VERSION_ID_STR "JUB4"
+#define VMMOUSE_VERSION_ID 0x3442554a
+
+/*
+ * Device related defines
+ */
+#define VMMOUSE_ERROR 0xffff0000
+
+/*
+ * VMMouse Input button flags
+ */
+#define VMMOUSE_LEFT_BUTTON 0x20
+#define VMMOUSE_RIGHT_BUTTON 0x10
+#define VMMOUSE_MIDDLE_BUTTON 0x08
+
+#endif
diff --git a/shared/vmmouse_proto.c b/shared/vmmouse_proto.c
new file mode 100644
index 0000000..b50e071
--- /dev/null
+++ b/shared/vmmouse_proto.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 1999-2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmmouse_proto.c --
+ *
+ * The communication protocol between the guest and the vmmouse
+ * virtual device.
+ */
+
+
+#include "vmmouse_proto.h"
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMMouseProtoInOut --
+ *
+ * Send a low-bandwidth basic request (16 bytes) to vmware, and return its
+ * reply (24 bytes).
+ *
+ * Results:
+ * Host-side response returned in cmd IN/OUT parameter.
+ *
+ * Side effects:
+ * Pokes the communication port.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+VMMouseProtoInOut(VMMouseProtoCmd *cmd) // IN/OUT
+{
+#ifdef __x86_64__
+ uint64_t dummy;
+
+ __asm__ __volatile__(
+ "pushq %%rax" "\n\t"
+ "movq 40(%%rax), %%rdi" "\n\t"
+ "movq 32(%%rax), %%rsi" "\n\t"
+ "movq 24(%%rax), %%rdx" "\n\t"
+ "movq 16(%%rax), %%rcx" "\n\t"
+ "movq 8(%%rax), %%rbx" "\n\t"
+ "movq (%%rax), %%rax" "\n\t"
+ "inl %%dx, %%eax" "\n\t" /* NB: There is no inq instruction */
+ "xchgq %%rax, (%%rsp)" "\n\t"
+ "movq %%rdi, 40(%%rax)" "\n\t"
+ "movq %%rsi, 32(%%rax)" "\n\t"
+ "movq %%rdx, 24(%%rax)" "\n\t"
+ "movq %%rcx, 16(%%rax)" "\n\t"
+ "movq %%rbx, 8(%%rax)" "\n\t"
+ "popq (%%rax)"
+ : "=a" (dummy)
+ : "0" (cmd)
+ /*
+ * vmware can modify the whole VM state without the compiler knowing
+ * it. So far it does not modify EFLAGS. --hpreg
+ */
+ : "rbx", "rcx", "rdx", "rsi", "rdi", "memory"
+ );
+#else
+#ifdef __i386__
+ uint32_t dummy;
+
+ __asm__ __volatile__(
+ "pushl %%ebx" "\n\t"
+ "pushl %%eax" "\n\t"
+ "movl 20(%%eax), %%edi" "\n\t"
+ "movl 16(%%eax), %%esi" "\n\t"
+ "movl 12(%%eax), %%edx" "\n\t"
+ "movl 8(%%eax), %%ecx" "\n\t"
+ "movl 4(%%eax), %%ebx" "\n\t"
+ "movl (%%eax), %%eax" "\n\t"
+ "inl %%dx, %%eax" "\n\t"
+ "xchgl %%eax, (%%esp)" "\n\t"
+ "movl %%edi, 20(%%eax)" "\n\t"
+ "movl %%esi, 16(%%eax)" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "movl %%ebx, 4(%%eax)" "\n\t"
+ "popl (%%eax)" "\n\t"
+ "popl %%ebx"
+ : "=a" (dummy)
+ : "0" (cmd)
+ /*
+ * vmware can modify the whole VM state without the compiler knowing
+ * it. So far it does not modify EFLAGS. --hpreg
+ */
+ : "ecx", "edx", "esi", "edi", "memory"
+ );
+#else
+#error "VMMouse is only supported on x86 and x86-64."
+#endif
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMMouseProto_SendCmd --
+ *
+ * Send a request (16 bytes) to vmware, and synchronously return its
+ * reply (24 bytes).
+ *
+ * Result:
+ * None
+ *
+ * Side-effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+VMMouseProto_SendCmd(VMMouseProtoCmd *cmd) // IN/OUT
+{
+ cmd->in.magic = VMMOUSE_PROTO_MAGIC;
+ cmd->in.port = VMMOUSE_PROTO_PORT;
+
+ VMMouseProtoInOut(cmd);
+}
diff --git a/shared/vmmouse_proto.h b/shared/vmmouse_proto.h
new file mode 100644
index 0000000..a2eb1e4
--- /dev/null
+++ b/shared/vmmouse_proto.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1999-2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmmouse_proto.h --
+ *
+ * The communication protocol between the guest and the vmmouse
+ * virtual device.
+ */
+
+
+#ifndef _VMMOUSE_PROTO_H_
+#define _VMMOUSE_PROTO_H_
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+
+#ifdef HAVE_XORG_SERVER_1_1_0
+#include <unistd.h>
+#else
+#include "xf86_libc.h"
+#endif
+
+#if !defined __i386__ && !defined __x86_64__
+#error The vmmouse protocol is only supported on x86 architectures.
+#endif
+
+#define VMMOUSE_PROTO_MAGIC 0x564D5868
+#define VMMOUSE_PROTO_PORT 0x5658
+
+#define VMMOUSE_PROTO_CMD_GETVERSION 10
+#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39
+#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS 40
+#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41
+
+#define DECLARE_REG32_STRUCT(_r) \
+ union { \
+ struct { \
+ uint16_t low; \
+ uint16_t high; \
+ } vE##_r##_; \
+ uint32_t vE##_r; \
+ }
+
+#ifdef __x86_64__
+
+#define DECLARE_REG64_STRUCT(_r) \
+ union { \
+ DECLARE_REG32_STRUCT(_r); \
+ struct { \
+ uint32_t low; \
+ uint32_t high; \
+ } vR##_r##_; \
+ uint64_t vR##_r; \
+ }
+
+#define DECLARE_REG_STRUCT(x) DECLARE_REG64_STRUCT(x)
+
+#else
+
+#define DECLARE_REG_STRUCT(x) DECLARE_REG32_STRUCT(x)
+
+#endif
+
+typedef union {
+ struct {
+ union {
+ uint32_t magic;
+ DECLARE_REG_STRUCT(ax);
+ };
+ union {
+ size_t size;
+ DECLARE_REG_STRUCT(bx);
+ };
+ union {
+ uint16_t command;
+ DECLARE_REG_STRUCT(cx);
+ };
+ union {
+ uint16_t port;
+ DECLARE_REG_STRUCT(dx);
+ };
+ DECLARE_REG_STRUCT(si);
+ DECLARE_REG_STRUCT(di);
+ } in;
+ struct {
+ DECLARE_REG_STRUCT(ax);
+ DECLARE_REG_STRUCT(bx);
+ DECLARE_REG_STRUCT(cx);
+ DECLARE_REG_STRUCT(dx);
+ DECLARE_REG_STRUCT(si);
+ DECLARE_REG_STRUCT(di);
+ } out;
+} VMMouseProtoCmd;
+
+
+void
+VMMouseProto_SendCmd(VMMouseProtoCmd *cmd); // IN/OUT
+
+
+#undef DECLARE_REG_STRUCT
+
+#endif /* _VMMOUSE_PROTO_H_ */