Exemple #1
0
static void usb_pointer_event(void *hs_v, int x1, int y1, int z1,
			      int buttons_state) {
    /* We combine events where feasible to keep the queue small.
     * We shouldn't combine anything with the first event with
     * a particular button state, as that would change the
     * location of the button state change. */
    USBHIDState *hs= hs_v;
    USBPointerState *s = &hs->ptr;
    unsigned use_slot= (s->tail-1) & QUEUEINDEXMASK;
    unsigned previous_slot= (use_slot-1) & QUEUEINDEXMASK;

    if (s->tail == s->head) {
        use_slot= s->tail;
        QUEUE_INCR(s->tail);
        usb_pointer_event_clear(&s->queue[use_slot], buttons_state);
    } else if (use_slot == s->head ||
	s->queue[use_slot].buttons_state != buttons_state ||
	s->queue[previous_slot].buttons_state != buttons_state) {
	/* can't or shouldn't combine this event with previous one */
	use_slot= s->tail;
	QUEUE_INCR(s->tail);
	if (use_slot == s->head) {
	    /* queue full, oh well, discard something */
	    s->head++;  s->head &= QUEUEINDEXMASK;
	    /* but we preserve the relative motions */
	    usb_pointer_event_combine(&s->queue[s->head], s->xyrel,
				      s->queue[use_slot].xdx,
				      s->queue[use_slot].ydy,
				      s->queue[use_slot].dz);
	}
	usb_pointer_event_clear(&s->queue[use_slot], buttons_state);
    }
    usb_pointer_event_combine(&s->queue[use_slot],s->xyrel, x1,y1,z1);
}
Exemple #2
0
static void hid_keyboard_process_keycode(HIDState *hs)
{
    uint8_t hid_code, key;
    int i, keycode, slot;

    if (hs->n == 0) {
        return;
    }
    slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
    keycode = hs->kbd.keycodes[slot];

    key = keycode & 0x7f;
    hid_code = hid_usage_keys[key | ((hs->kbd.modifiers >> 1) & (1 << 7))];
    hs->kbd.modifiers &= ~(1 << 8);

    switch (hid_code) {
    case 0x00:
        return;

    case 0xe0:
        if (hs->kbd.modifiers & (1 << 9)) {
            hs->kbd.modifiers ^= 3 << 8;
            return;
        }
    case 0xe1 ... 0xe7:
        if (keycode & (1 << 7)) {
            hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
            return;
        }
    case 0xe8 ... 0xef:
        hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
        return;
    }

    if (keycode & (1 << 7)) {
        for (i = hs->kbd.keys - 1; i >= 0; i--) {
            if (hs->kbd.key[i] == hid_code) {
                hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
                hs->kbd.key[hs->kbd.keys] = 0x00;
                break;
            }
        }
        if (i < 0) {
            return;
        }
    } else {
        for (i = hs->kbd.keys - 1; i >= 0; i--) {
            if (hs->kbd.key[i] == hid_code) {
                break;
            }
        }
        if (i < 0) {
            if (hs->kbd.keys < sizeof(hs->kbd.key)) {
                hs->kbd.key[hs->kbd.keys++] = hid_code;
            }
        } else {
            return;
        }
    }
}
Exemple #3
0
static void hid_pointer_event(void *opaque,
                              int x1, int y1, int z1, int buttons_state)
{
    HIDState *hs = opaque;
    unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
    unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;

    /* We combine events where feasible to keep the queue small.  We shouldn't
     * combine anything with the first event of a particular button state, as
     * that would change the location of the button state change.  When the
     * queue is empty, a second event is needed because we don't know if
     * the first event changed the button state.  */
    if (hs->n == QUEUE_LENGTH) {
        /* Queue full.  Discard old button state, combine motion normally.  */
        hs->ptr.queue[use_slot].buttons_state = buttons_state;
    } else if (hs->n < 2 ||
               hs->ptr.queue[use_slot].buttons_state != buttons_state ||
               hs->ptr.queue[previous_slot].buttons_state !=
               hs->ptr.queue[use_slot].buttons_state) {
        /* Cannot or should not combine, so add an empty item to the queue.  */
        QUEUE_INCR(use_slot);
        hs->n++;
        hid_pointer_event_clear(&hs->ptr.queue[use_slot], buttons_state);
    }
    hid_pointer_event_combine(&hs->ptr.queue[use_slot],
                              hs->kind == HID_MOUSE,
                              x1, y1, z1);
    hs->event(hs);
}
Exemple #4
0
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
{
    int dx, dy, dz, b, l;
    int index;
    HIDPointerEvent *e;

    hs->idle_pending = false;

    hid_pointer_activate(hs);

    /* When the buffer is empty, return the last event.  Relative
       movements will all be zero.  */
    index = (hs->n ? hs->head : hs->head - 1);
    e = &hs->ptr.queue[index & QUEUE_MASK];

    if (hs->kind == HID_MOUSE) {
        dx = int_clamp(e->xdx, -127, 127);
        dy = int_clamp(e->ydy, -127, 127);
        e->xdx -= dx;
        e->ydy -= dy;
    } else {
        dx = e->xdx;
        dy = e->ydy;
    }
    dz = int_clamp(e->dz, -127, 127);
    e->dz -= dz;

    b = 0;
    if (e->buttons_state & MOUSE_EVENT_LBUTTON) {
        b |= 0x01;
    }
    if (e->buttons_state & MOUSE_EVENT_RBUTTON) {
        b |= 0x02;
    }
    if (e->buttons_state & MOUSE_EVENT_MBUTTON) {
        b |= 0x04;
    }

    if (hs->n &&
        !e->dz &&
        (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
        /* that deals with this event */
        QUEUE_INCR(hs->head);
        hs->n--;
    }

    /* Appears we have to invert the wheel direction */
    dz = 0 - dz;
    l = 0;
    switch (hs->kind) {
    case HID_MOUSE:
        if (len > l) {
            buf[l++] = b;
        }
        if (len > l) {
            buf[l++] = dx;
        }
        if (len > l) {
            buf[l++] = dy;
        }
        if (len > l) {
            buf[l++] = dz;
        }
        break;

    case HID_TABLET:
        if (len > l) {
            buf[l++] = b;
        }
        if (len > l) {
            buf[l++] = dx & 0xff;
        }
        if (len > l) {
            buf[l++] = dx >> 8;
        }
        if (len > l) {
            buf[l++] = dy & 0xff;
        }
        if (len > l) {
            buf[l++] = dy >> 8;
        }
Exemple #5
0
static int usb_pointer_poll(USBHIDState *hs, uint8_t *buf, int len)
{
    int dx, dy, dz, b, l;
    USBPointerState *s = &hs->ptr;
    USBPointerEvent *e;

    if (usb_suppress_report(hs, s->head == s->tail))
	return USB_RET_NAK;

    if (!s->mouse_grabbed) {
	s->eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, hs,
                                          !s->xyrel, "QEMU USB Pointer");
	s->mouse_grabbed = 1;
    }

    if (s->head == s->tail)
        /* use the last report */
        s->head = (s->head - 1) & QUEUEINDEXMASK;

    e = &s->queue[s->head];

    dz = int_clamp(e->dz, -127, 127);

    if (s->xyrel) {
        dx = int_clamp(e->xdx, -127, 127);
        dy = int_clamp(e->ydy, -127, 127);
	e->xdx -= dx;
	e->ydy -= dy;
    } else {
        dx = e->xdx;
        dy = e->ydy;
    }
    /* Appears we have to invert the wheel direction */
    dz = 0 - dz;

    if (!(e->dz ||
	  (s->xyrel && (e->xdx || e->ydy)))) {
	/* that deals with this event */
	QUEUE_INCR(s->head);
    }

    b = 0;
    if (e->buttons_state & MOUSE_EVENT_LBUTTON)
        b |= 0x01;
    if (e->buttons_state & MOUSE_EVENT_RBUTTON)
        b |= 0x02;
    if (e->buttons_state & MOUSE_EVENT_MBUTTON)
        b |= 0x04;

    switch (hs->kind) {
    case USB_MOUSE:
	l = 0;
	if (len > l)
	    buf[l ++] = b;
	if (len > l)
	    buf[l ++] = dx;
	if (len > l)
	    buf[l ++] = dy;
	if (len > l)
	    buf[l ++] = dz;
	break;

    case USB_TABLET:
	/* Appears we have to invert the wheel direction */
	dz = 0 - dz;

	buf[0] = b;
	buf[1] = dx & 0xff;
	buf[2] = dx >> 8;
	buf[3] = dy & 0xff;
	buf[4] = dy >> 8;
	buf[5] = dz;
	l = 6;
	break;

    default:
	abort();
    }

    return l;
}