Feedback about this page and suggestions for improvements are always welcome on the vbox-dev mailing list<1>!
Investigating problems with mouse input in VirtualBox
This page gives a quick overview of the way (or ways) in which mouse input to virtual machines works in VirtualBox and some ways to get a closer look at what is happening in order to understand when things go wrong. Please feel free to suggest improvements!
How mouse input reaches guest systems
In order to let the user control the guest system with the host input devices, VirtualBox emulates input devices inside the virtual machine. The simplest case is when the host pointer is captured and VirtualBox is only emulating a standard (PS/2 or USB) mouse. In this case, when the user moves the host pointer to the left, VirtualBox simulates left movement on the emulated mouse, and when the user clicks the right button a right button click is simulated on the guest mouse.
When mouse integration is enabled, this becomes slightly more complicated. VirtualBox emulates a graphics tablet (similar to a touch screen), which can send exact positions instead of just "left", "right", "up", "down". Unfortunately these positions are not in pixels on the screen, but in percentages - e.g. 56 percent along the X axis from the left to the right edge and 73 percent along the Y axis from the top to the bottom edge. For this to work correctly, the guest and the host have to agree about which positions on the tablet correspond to which positions on the guest screens - e.g. virtual screen one might go from 0 to 50 percent along the X axis and from 0 to 100 on the Y axis, while virtual screen two might go from 50 to 100 on X and also from 0 to 100 on Y. This corresponds to screen two laid out to the right of screen one, with the right edge of screen one exactly matching the left edge of screen two. If host and guest agree about this layout then mouse integration can work. Otherwise the position of clicks in the guest will not correctly match the pointer location.
This is further complicate by the fact that for historical reasons (i.e. it seemed like a good idea at the time), the Guest Additions input device sends position information but not button information. So it needs to be used in conjunction with another device which can send the button information (this can actually happen on physical laptops too, with multiple touch pad and touch point devices and various sets of buttons), and the two can get very slightly out of synchronisation, causing strange effects. This will be fixed as soon as there is nothing else more important needing fixing, which is not likely to happen for a long time. This does not happen when using the emulated USB graphics tablet device, which also has buttons, but that device does not always map well to multiple guest screens.
General flow of mouse input
Like many things in VirtualBox, mouse input follows a chain which starts at the "front-end" - usually the VirtualBox application window which displays the virtual machine, or the built-in remote desktop server - and works its way through to the guest operating system which sees the input through virtual devices using native or VirtualBox guest drivers. If something is going wrong then getting as much information as possible about what is happening at each point in the chain is a good way of finding out more.
Each front-end has its own way of getting at mouse input. The remote desktop server receives mouse events from the viewer application (rdesktop, Microsoft Remote Desktop Connection client) so the first place to look for problems is making sure that these are sending the right input. How to do this is something outside of our scope, but if problems are visible using remote desktop connections but not accessing a machine directly this is worth following up.
The standard VirtualBox application window gets its mouse input from the operating system. When VirtualBox is using the X11 windowing system (Linux, Solaris, FreeBSD) you can get a closer look at that input using the "xev" command line tool - "xev -id <window id>", where you can find the <window id> by running "xwininfo -tree", clicking on the window and trying out windows in the list with the right size. Ideas about how to do similar things for Windows and OS X are welcome! (This was written by a Linux developer.)
"Main" is the equivalent of a telephone switchboard inside the VirtualBox application, where all the different components are connected to each other. The front-end picks up mouse input in its own way and passes it on to Main in a standard format. Main passes the information on to virtual devices inside the virtual machine (see below). You can get a look at the information flowing through Main by running VirtualBox with the environment variable "VBOX_RELEASE_LOG=+main.e.l3" set. This will add information about mouse events (and, be warned, potentially lots of other things, as Main is a very busy component) to the virtual machine log file.
When a guest operating system is run in a VirtualBox virtual machine it sees that it is running on a machine with a number of devices present. This will usually include (simulated) input devices, and we are interested in the emulated PS/2 mouse, the emulated USB mouse and graphics tablet and the Guest Additions pointer device. When you enable logging for pointer events, it is useful to set the environment variable RT_RELEASE_LOG_FLAGS=time to print the time of all events. This helps you match information in the guest and in the host.
- The first of these is the most basic method of mouse input into the guest system and simulates a traditional pre-USB mouse. It can provide information about mouse movement to the left, right, up and down (no exact positions), up to five mouse buttons and horizontal and vertical wheel scrolling. The guest operating system has a standard driver which works with this device. To see what information Main is sending to this device, run VirtualBox with the environment variable "VBOX_RELEASE_LOG=+dev_kbd.e.l3.f" set and look in the virtual machine's log file.
- The second device is the virtual USB mouse. This can provide all the information that the PS/2 mouse can, and in addition, if the guest operating system understands this, it can provide the exact position of the mouse pointer. If the guest uses this information then the position of the mouse pointer in the guest window should always match the position of the host pointer. If the guest mis-understands this information there is likely to be a systematic difference between the two positions. Currently there is no way of getting as much information about information flowing through this device as there is for the PS/2 mouse.
- The third device of interest is the VirtualBox "guest" device which provides a number of services for integrating applications in a virtual machine with the desktop and services of the host machine running VirtualBox. We are interested in its "mouse integration" function which sends the position of the host mouse pointer to the guest. The guest operating system needs a special driver for the guest device, which usually comes with VirtualBox, to get this information. The guest device does not provide information about mouse button clicks - this is still sent to one of the other devices. You can take a look at information flowing through this device - which includes guest requests for mouse pointer information - by setting the environment variable "VBOX_RELEASE_LOG=+dev_vmm.e.l2.l3.f".
Guest operating systems
It is also worth using any tools available in guest operating systems to find out what mouse information they are seeing at the end of the chain. In guests running the X Window system (Linux, Solaris, FreeBSD), the "xev" command line tool is useful for this and the file "/var/log/Xorg.0.log" and its variants also provide useful inforamation. In many you can also get information through the "xinput" command line tool. On many Linux systems the "evtest" command line tool is also useful. Examples:
- If a Linux guest to clicks, use the keyboard to start xev and see if it is reporting mouse movement events at all, and if so if it is reporting clicks.
- If the pointer position is wrong inside a Linux guest, compare what xev reports and what the host log file does. Move the pointer then leave it in one place for a while to make it easy to match the two sets of logging (both will show a time period without events).
Suggestions for Windows guests are welcome!