/* * Send a mouse event from the client to the guest OS * * The QEMU mouse can be in either relative, or absolute mode. * Movement is sent separately from button state, which has to * be encoded as virtual key events. We also don't actually get * given any button up/down events, so have to track changes in * the button state. */ static void xenfb_mouse_event(void *opaque, int dx, int dy, int dz, int button_state) { struct XenInput *xenfb = opaque; DisplaySurface *surface = qemu_console_surface(xenfb->c.con); int dw = surface_width(surface); int dh = surface_height(surface); int i; trace_xenfb_mouse_event(opaque, dx, dy, dz, button_state, xenfb->abs_pointer_wanted); if (xenfb->abs_pointer_wanted) xenfb_send_position(xenfb, dx * (dw - 1) / 0x7fff, dy * (dh - 1) / 0x7fff, dz); else xenfb_send_motion(xenfb, dx, dy, dz); for (i = 0 ; i < 8 ; i++) { int lastDown = xenfb->button_state & (1 << i); int down = button_state & (1 << i); if (down == lastDown) continue; if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0) return; } xenfb->button_state = button_state; }
static void xenfb_mouse_sync(DeviceState *dev) { struct XenInput *xenfb = (struct XenInput *)dev; trace_xenfb_mouse_event(xenfb, xenfb->axis[INPUT_AXIS_X], xenfb->axis[INPUT_AXIS_Y], xenfb->wheel, 0, xenfb->abs_pointer_wanted); if (xenfb->abs_pointer_wanted) { xenfb_send_position(xenfb, xenfb->axis[INPUT_AXIS_X], xenfb->axis[INPUT_AXIS_Y], xenfb->wheel); } else { xenfb_send_motion(xenfb, xenfb->axis[INPUT_AXIS_X], xenfb->axis[INPUT_AXIS_Y], xenfb->wheel); xenfb->axis[INPUT_AXIS_X] = 0; xenfb->axis[INPUT_AXIS_Y] = 0; } xenfb->wheel = 0; }