Beispiel #1
0
/*
 * 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;
}
/*
 * 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;
    int dw = ds_get_width(xenfb->c.ds);
    int dh = ds_get_height(xenfb->c.ds);
    int i;

    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;
}
Beispiel #3
0
/* 
 * Send a key event from the client to the guest OS
 * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
 * We have to turn this into a Linux Input layer keycode.
 * 
 * Extra complexity from the fact that with extended scancodes 
 * (like those produced by arrow keys) this method gets called
 * twice, but we only want to send a single event. So we have to
 * track the '0xe0' scancode state & collapse the extended keys
 * as needed.
 * 
 * Wish we could just send scancodes straight to the guest which
 * already has code for dealing with this...
 */
static void xenfb_key_event(void *opaque, int scancode)
{
    static int extended = 0;
    int down = 1;
    if (scancode == 0xe0) {
        extended = 1;
        return;
    } else if (scancode & 0x80) {
        scancode &= 0x7f;
        down = 0;
    }
    if (extended) {
        scancode |= 0x80;
        extended = 0;
    }
    xenfb_send_key(opaque, down, scancode2linux[scancode]);
}
Beispiel #4
0
/*
 * Send a key event from the client to the guest OS
 * QEMU gives us a QCode.
 * We have to turn this into a Linux Input layer keycode.
 *
 * Wish we could just send scancodes straight to the guest which
 * already has code for dealing with this...
 */
static void xenfb_key_event(DeviceState *dev, QemuConsole *src,
                            InputEvent *evt)
{
    struct XenInput *xenfb = (struct XenInput *)dev;
    InputKeyEvent *key = evt->u.key.data;
    int qcode = qemu_input_key_value_to_qcode(key->key);
    int lnx;

    if (qcode < qemu_input_map_qcode_to_linux_len) {
        lnx = qemu_input_map_qcode_to_linux[qcode];

        if (lnx) {
            trace_xenfb_key_event(xenfb, lnx, key->down);
            xenfb_send_key(xenfb, key->down, lnx);
        }
    }
}
/*
 * Send a key event from the client to the guest OS
 * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
 * We have to turn this into a Linux Input layer keycode.
 *
 * Extra complexity from the fact that with extended scancodes
 * (like those produced by arrow keys) this method gets called
 * twice, but we only want to send a single event. So we have to
 * track the '0xe0' scancode state & collapse the extended keys
 * as needed.
 *
 * Wish we could just send scancodes straight to the guest which
 * already has code for dealing with this...
 */
static void xenfb_key_event(void *opaque, int scancode)
{
    struct XenInput *xenfb = opaque;
    int down = 1;

    if (scancode == 0xe0) {
	xenfb->extended = 1;
	return;
    } else if (scancode & 0x80) {
	scancode &= 0x7f;
	down = 0;
    }
    if (xenfb->extended) {
	scancode |= 0x80;
	xenfb->extended = 0;
    }
    xenfb_send_key(xenfb, down, scancode2linux[scancode]);
}
Beispiel #6
0
/*
 * 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)
{
    int i;
    struct xenfb *xenfb = opaque;
    if (xenfb->abs_pointer_wanted)
	    xenfb_send_position(xenfb,
                                dx * (xenfb->ds->width - 1) / 0x7fff,
                                dy * (xenfb->ds->height - 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;
}
Beispiel #7
0
/*
 * 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(DeviceState *dev, QemuConsole *src,
                              InputEvent *evt)
{
    struct XenInput *xenfb = (struct XenInput *)dev;
    InputBtnEvent *btn;
    InputMoveEvent *move;
    QemuConsole *con;
    DisplaySurface *surface;
    int scale;

    switch (evt->type) {
    case INPUT_EVENT_KIND_BTN:
        btn = evt->u.btn.data;
        switch (btn->button) {
        case INPUT_BUTTON_LEFT:
            xenfb_send_key(xenfb, btn->down, BTN_LEFT);
            break;
        case INPUT_BUTTON_RIGHT:
            xenfb_send_key(xenfb, btn->down, BTN_LEFT + 1);
            break;
        case INPUT_BUTTON_MIDDLE:
            xenfb_send_key(xenfb, btn->down, BTN_LEFT + 2);
            break;
        case INPUT_BUTTON_WHEEL_UP:
            if (btn->down) {
                xenfb->wheel--;
            }
            break;
        case INPUT_BUTTON_WHEEL_DOWN:
            if (btn->down) {
                xenfb->wheel++;
            }
            break;
        default:
            break;
        }
        break;

    case INPUT_EVENT_KIND_ABS:
        move = evt->u.abs.data;
        if (xenfb->raw_pointer_wanted) {
            xenfb->axis[move->axis] = move->value;
        } else {
            con = qemu_console_lookup_by_index(0);
            if (!con) {
                xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
                return;
            }
            surface = qemu_console_surface(con);
            switch (move->axis) {
            case INPUT_AXIS_X:
                scale = surface_width(surface) - 1;
                break;
            case INPUT_AXIS_Y:
                scale = surface_height(surface) - 1;
                break;
            default:
                scale = 0x8000;
                break;
            }
            xenfb->axis[move->axis] = move->value * scale / 0x7fff;
        }
        break;

    case INPUT_EVENT_KIND_REL:
        move = evt->u.rel.data;
        xenfb->axis[move->axis] += move->value;
        break;

    default:
        break;
    }
}