Revision dcfda673

b/Makefile.objs
89 89
common-obj-y += eeprom93xx.o
90 90
common-obj-y += scsi-disk.o cdrom.o
91 91
common-obj-y += scsi-generic.o scsi-bus.o
92
common-obj-y += hid.o
92 93
common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
93 94
common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o
94 95
common-obj-$(CONFIG_SSI) += ssi.o
b/hw/hid.c
1
/*
2
 * QEMU HID devices
3
 *
4
 * Copyright (c) 2005 Fabrice Bellard
5
 * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
#include "hw.h"
26
#include "console.h"
27
#include "hid.h"
28

  
29
#define HID_USAGE_ERROR_ROLLOVER        0x01
30
#define HID_USAGE_POSTFAIL              0x02
31
#define HID_USAGE_ERROR_UNDEFINED       0x03
32

  
33
/* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
34
 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
35
static const uint8_t hid_usage_keys[0x100] = {
36
    0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
37
    0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
38
    0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
39
    0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
40
    0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
41
    0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
42
    0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
43
    0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
44
    0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
45
    0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
46
    0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
47
    0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
48
    0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
49
    0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
50
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51
    0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
52

  
53
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56
    0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
57
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59
    0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
60
    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61
    0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
62
    0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
63
    0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
64
    0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
65
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69
};
70

  
71
bool hid_has_events(HIDState *hs)
72
{
73
    return hs->n > 0;
74
}
75

  
76
static void hid_pointer_event_clear(HIDPointerEvent *e, int buttons)
77
{
78
    e->xdx = e->ydy = e->dz = 0;
79
    e->buttons_state = buttons;
80
}
81

  
82
static void hid_pointer_event_combine(HIDPointerEvent *e, int xyrel,
83
                                      int x1, int y1, int z1) {
84
    if (xyrel) {
85
        e->xdx += x1;
86
        e->ydy += y1;
87
    } else {
88
        e->xdx = x1;
89
        e->ydy = y1;
90
        /* Windows drivers do not like the 0/0 position and ignore such
91
         * events. */
92
        if (!(x1 | y1)) {
93
            x1 = 1;
94
        }
95
    }
96
    e->dz += z1;
97
}
98

  
99
static void hid_pointer_event(void *opaque,
100
                              int x1, int y1, int z1, int buttons_state)
101
{
102
    HIDState *hs = opaque;
103
    unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
104
    unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
105

  
106
    /* We combine events where feasible to keep the queue small.  We shouldn't
107
     * combine anything with the first event of a particular button state, as
108
     * that would change the location of the button state change.  When the
109
     * queue is empty, a second event is needed because we don't know if
110
     * the first event changed the button state.  */
111
    if (hs->n == QUEUE_LENGTH) {
112
        /* Queue full.  Discard old button state, combine motion normally.  */
113
        hs->ptr.queue[use_slot].buttons_state = buttons_state;
114
    } else if (hs->n < 2 ||
115
               hs->ptr.queue[use_slot].buttons_state != buttons_state ||
116
               hs->ptr.queue[previous_slot].buttons_state !=
117
               hs->ptr.queue[use_slot].buttons_state) {
118
        /* Cannot or should not combine, so add an empty item to the queue.  */
119
        QUEUE_INCR(use_slot);
120
        hs->n++;
121
        hid_pointer_event_clear(&hs->ptr.queue[use_slot], buttons_state);
122
    }
123
    hid_pointer_event_combine(&hs->ptr.queue[use_slot],
124
                              hs->kind == HID_MOUSE,
125
                              x1, y1, z1);
126
    hs->event(hs);
127
}
128

  
129
static void hid_keyboard_event(void *opaque, int keycode)
130
{
131
    HIDState *hs = opaque;
132
    int slot;
133

  
134
    if (hs->n == QUEUE_LENGTH) {
135
        fprintf(stderr, "usb-kbd: warning: key event queue full\n");
136
        return;
137
    }
138
    slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
139
    hs->kbd.keycodes[slot] = keycode;
140
    hs->event(hs);
141
}
142

  
143
static void hid_keyboard_process_keycode(HIDState *hs)
144
{
145
    uint8_t hid_code, key;
146
    int i, keycode, slot;
147

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

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

  
158
    switch (hid_code) {
159
    case 0x00:
160
        return;
161

  
162
    case 0xe0:
163
        if (hs->kbd.modifiers & (1 << 9)) {
164
            hs->kbd.modifiers ^= 3 << 8;
165
            return;
166
        }
167
    case 0xe1 ... 0xe7:
168
        if (keycode & (1 << 7)) {
169
            hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
170
            return;
171
        }
172
    case 0xe8 ... 0xef:
173
        hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
174
        return;
175
    }
176

  
177
    if (keycode & (1 << 7)) {
178
        for (i = hs->kbd.keys - 1; i >= 0; i--) {
179
            if (hs->kbd.key[i] == hid_code) {
180
                hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
181
                hs->kbd.key[hs->kbd.keys] = 0x00;
182
                break;
183
            }
184
        }
185
        if (i < 0) {
186
            return;
187
        }
188
    } else {
189
        for (i = hs->kbd.keys - 1; i >= 0; i--) {
190
            if (hs->kbd.key[i] == hid_code) {
191
                break;
192
            }
193
        }
194
        if (i < 0) {
195
            if (hs->kbd.keys < sizeof(hs->kbd.key)) {
196
                hs->kbd.key[hs->kbd.keys++] = hid_code;
197
            }
198
        } else {
199
            return;
200
        }
201
    }
202
}
203

  
204
static inline int int_clamp(int val, int vmin, int vmax)
205
{
206
    if (val < vmin) {
207
        return vmin;
208
    } else if (val > vmax) {
209
        return vmax;
210
    } else {
211
        return val;
212
    }
213
}
214

  
215
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
216
{
217
    int dx, dy, dz, b, l;
218
    int index;
219
    HIDPointerEvent *e;
220

  
221
    if (!hs->ptr.mouse_grabbed) {
222
        qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
223
        hs->ptr.mouse_grabbed = 1;
224
    }
225

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

  
231
    if (hs->kind == HID_MOUSE) {
232
        dx = int_clamp(e->xdx, -127, 127);
233
        dy = int_clamp(e->ydy, -127, 127);
234
        e->xdx -= dx;
235
        e->ydy -= dy;
236
    } else {
237
        dx = e->xdx;
238
        dy = e->ydy;
239
    }
240
    dz = int_clamp(e->dz, -127, 127);
241
    e->dz -= dz;
242

  
243
    b = 0;
244
    if (e->buttons_state & MOUSE_EVENT_LBUTTON) {
245
        b |= 0x01;
246
    }
247
    if (e->buttons_state & MOUSE_EVENT_RBUTTON) {
248
        b |= 0x02;
249
    }
250
    if (e->buttons_state & MOUSE_EVENT_MBUTTON) {
251
        b |= 0x04;
252
    }
253

  
254
    if (hs->n &&
255
        !e->dz &&
256
        (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
257
        /* that deals with this event */
258
        QUEUE_INCR(hs->head);
259
        hs->n--;
260
    }
261

  
262
    /* Appears we have to invert the wheel direction */
263
    dz = 0 - dz;
264
    l = 0;
265
    switch (hs->kind) {
266
    case HID_MOUSE:
267
        if (len > l) {
268
            buf[l++] = b;
269
        }
270
        if (len > l) {
271
            buf[l++] = dx;
272
        }
273
        if (len > l) {
274
            buf[l++] = dy;
275
        }
276
        if (len > l) {
277
            buf[l++] = dz;
278
        }
279
        break;
280

  
281
    case HID_TABLET:
282
        if (len > l) {
283
            buf[l++] = b;
284
        }
285
        if (len > l) {
286
            buf[l++] = dx & 0xff;
287
        }
288
        if (len > l) {
289
            buf[l++] = dx >> 8;
290
        }
291
        if (len > l) {
292
            buf[l++] = dy & 0xff;
293
        }
294
        if (len > l) {
295
            buf[l++] = dy >> 8;
296
        }
297
        if (len > l) {
298
            buf[l++] = dz;
299
        }
300
        break;
301

  
302
    default:
303
        abort();
304
    }
305

  
306
    return l;
307
}
308

  
309
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
310
{
311
    if (len < 2) {
312
        return 0;
313
    }
314

  
315
    hid_keyboard_process_keycode(hs);
316

  
317
    buf[0] = hs->kbd.modifiers & 0xff;
318
    buf[1] = 0;
319
    if (hs->kbd.keys > 6) {
320
        memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
321
    } else {
322
        memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
323
    }
324

  
325
    return MIN(8, len);
326
}
327

  
328
int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
329
{
330
    if (len > 0) {
331
        int ledstate = 0;
332
        /* 0x01: Num Lock LED
333
         * 0x02: Caps Lock LED
334
         * 0x04: Scroll Lock LED
335
         * 0x08: Compose LED
336
         * 0x10: Kana LED */
337
        hs->kbd.leds = buf[0];
338
        if (hs->kbd.leds & 0x04) {
339
            ledstate |= QEMU_SCROLL_LOCK_LED;
340
        }
341
        if (hs->kbd.leds & 0x01) {
342
            ledstate |= QEMU_NUM_LOCK_LED;
343
        }
344
        if (hs->kbd.leds & 0x02) {
345
            ledstate |= QEMU_CAPS_LOCK_LED;
346
        }
347
        kbd_put_ledstate(ledstate);
348
    }
349
    return 0;
350
}
351

  
352
void hid_reset(HIDState *hs)
353
{
354
    switch (hs->kind) {
355
    case HID_KEYBOARD:
356
        qemu_add_kbd_event_handler(hid_keyboard_event, hs);
357
        memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
358
        memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
359
        hs->kbd.keys = 0;
360
        break;
361
    case HID_MOUSE:
362
    case HID_TABLET:
363
        memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
364
        break;
365
    }
366
    hs->head = 0;
367
    hs->n = 0;
368
}
369

  
370
void hid_free(HIDState *hs)
371
{
372
    switch (hs->kind) {
373
    case HID_KEYBOARD:
374
        qemu_remove_kbd_event_handler();
375
        break;
376
    case HID_MOUSE:
377
    case HID_TABLET:
378
        qemu_remove_mouse_event_handler(hs->ptr.eh_entry);
379
        break;
380
    }
381
}
382

  
383
void hid_init(HIDState *hs, int kind, HIDEventFunc event)
384
{
385
    hs->kind = kind;
386
    hs->event = event;
387

  
388
    if (hs->kind == HID_MOUSE) {
389
        hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
390
                                                        0, "QEMU HID Mouse");
391
    } else if (hs->kind == HID_TABLET) {
392
        hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
393
                                                        1, "QEMU HID Tablet");
394
    }
395
}
b/hw/hid.h
1
#ifndef QEMU_HID_H
2
#define QEMU_HID_H
3

  
4
#define HID_MOUSE     1
5
#define HID_TABLET    2
6
#define HID_KEYBOARD  3
7

  
8
typedef struct HIDPointerEvent {
9
    int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */
10
    int32_t dz, buttons_state;
11
} HIDPointerEvent;
12

  
13
#define QUEUE_LENGTH    16 /* should be enough for a triple-click */
14
#define QUEUE_MASK      (QUEUE_LENGTH-1u)
15
#define QUEUE_INCR(v)   ((v)++, (v) &= QUEUE_MASK)
16

  
17
typedef struct HIDState HIDState;
18
typedef void (*HIDEventFunc)(HIDState *s);
19

  
20
typedef struct HIDMouseState {
21
    HIDPointerEvent queue[QUEUE_LENGTH];
22
    int mouse_grabbed;
23
    QEMUPutMouseEntry *eh_entry;
24
} HIDMouseState;
25

  
26
typedef struct HIDKeyboardState {
27
    uint32_t keycodes[QUEUE_LENGTH];
28
    uint16_t modifiers;
29
    uint8_t leds;
30
    uint8_t key[16];
31
    int32_t keys;
32
} HIDKeyboardState;
33

  
34
struct HIDState {
35
    union {
36
        HIDMouseState ptr;
37
        HIDKeyboardState kbd;
38
    };
39
    uint32_t head; /* index into circular queue */
40
    uint32_t n;
41
    int kind;
42
    HIDEventFunc event;
43
};
44

  
45
void hid_init(HIDState *hs, int kind, HIDEventFunc event);
46
void hid_reset(HIDState *hs);
47
void hid_free(HIDState *hs);
48

  
49
bool hid_has_events(HIDState *hs);
50
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len);
51
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len);
52
int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len);
53

  
54
#endif /* QEMU_HID_H */
b/hw/usb-hid.c
27 27
#include "usb.h"
28 28
#include "usb-desc.h"
29 29
#include "qemu-timer.h"
30
#include "hid.h"
30 31

  
31 32
/* HID interface requests */
32 33
#define GET_REPORT   0xa101
......
41 42
#define USB_DT_REPORT 0x22
42 43
#define USB_DT_PHY    0x23
43 44

  
44
#define HID_MOUSE     1
45
#define HID_TABLET    2
46
#define HID_KEYBOARD  3
47

  
48
typedef struct HIDPointerEvent {
49
    int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */
50
    int32_t dz, buttons_state;
51
} HIDPointerEvent;
52

  
53
#define QUEUE_LENGTH    16 /* should be enough for a triple-click */
54
#define QUEUE_MASK      (QUEUE_LENGTH-1u)
55
#define QUEUE_INCR(v)   ((v)++, (v) &= QUEUE_MASK)
56

  
57
typedef struct HIDState HIDState;
58
typedef void (*HIDEventFunc)(HIDState *s);
59

  
60
typedef struct HIDMouseState {
61
    HIDPointerEvent queue[QUEUE_LENGTH];
62
    int mouse_grabbed;
63
    QEMUPutMouseEntry *eh_entry;
64
} HIDMouseState;
65

  
66
typedef struct HIDKeyboardState {
67
    uint32_t keycodes[QUEUE_LENGTH];
68
    uint16_t modifiers;
69
    uint8_t leds;
70
    uint8_t key[16];
71
    int32_t keys;
72
} HIDKeyboardState;
73

  
74
struct HIDState {
75
    union {
76
        HIDMouseState ptr;
77
        HIDKeyboardState kbd;
78
    };
79
    uint32_t head; /* index into circular queue */
80
    uint32_t n;
81
    int kind;
82
    HIDEventFunc event;
83
};
84

  
85 45
typedef struct USBHIDState {
86 46
    USBDevice dev;
87 47
    HIDState hid;
......
401 361
    0xc0,		/* End Collection */
402 362
};
403 363

  
404
#define USB_HID_USAGE_ERROR_ROLLOVER	0x01
405
#define USB_HID_USAGE_POSTFAIL		0x02
406
#define USB_HID_USAGE_ERROR_UNDEFINED	0x03
407

  
408
/* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
409
 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
410
static const uint8_t usb_hid_usage_keys[0x100] = {
411
    0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
412
    0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
413
    0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
414
    0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
415
    0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
416
    0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
417
    0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
418
    0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
419
    0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
420
    0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
421
    0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
422
    0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
423
    0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
424
    0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
425
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426
    0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
427

  
428
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431
    0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
432
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434
    0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
435
    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436
    0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
437
    0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
438
    0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
439
    0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
440
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444
};
445

  
446
static bool hid_has_events(HIDState *hs)
447
{
448
    return hs->n > 0;
449
}
450

  
451 364
static void usb_hid_changed(HIDState *hs)
452 365
{
453 366
    USBHIDState *us = container_of(hs, USBHIDState, hid);
......
459 372
    usb_wakeup(&us->dev);
460 373
}
461 374

  
462
static void hid_pointer_event_clear(HIDPointerEvent *e, int buttons)
463
{
464
    e->xdx = e->ydy = e->dz = 0;
465
    e->buttons_state = buttons;
466
}
467

  
468
static void hid_pointer_event_combine(HIDPointerEvent *e, int xyrel,
469
                                      int x1, int y1, int z1) {
470
    if (xyrel) {
471
        e->xdx += x1;
472
        e->ydy += y1;
473
    } else {
474
        e->xdx = x1;
475
        e->ydy = y1;
476
        /* Windows drivers do not like the 0/0 position and ignore such
477
         * events. */
478
        if (!(x1 | y1)) {
479
            x1 = 1;
480
        }
481
    }
482
    e->dz += z1;
483
}
484

  
485
static void hid_pointer_event(void *opaque,
486
                              int x1, int y1, int z1, int buttons_state)
487
{
488
    HIDState *hs = opaque;
489
    unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
490
    unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
491

  
492
    /* We combine events where feasible to keep the queue small.  We shouldn't
493
     * combine anything with the first event of a particular button state, as
494
     * that would change the location of the button state change.  When the
495
     * queue is empty, a second event is needed because we don't know if
496
     * the first event changed the button state.  */
497
    if (hs->n == QUEUE_LENGTH) {
498
        /* Queue full.  Discard old button state, combine motion normally.  */
499
        hs->ptr.queue[use_slot].buttons_state = buttons_state;
500
    } else if (hs->n < 2 ||
501
               hs->ptr.queue[use_slot].buttons_state != buttons_state ||
502
               hs->ptr.queue[previous_slot].buttons_state !=
503
               hs->ptr.queue[use_slot].buttons_state) {
504
        /* Cannot or should not combine, so add an empty item to the queue.  */
505
        QUEUE_INCR(use_slot);
506
        hs->n++;
507
        hid_pointer_event_clear(&hs->ptr.queue[use_slot], buttons_state);
508
    }
509
    hid_pointer_event_combine(&hs->ptr.queue[use_slot],
510
                              hs->kind == HID_MOUSE,
511
                              x1, y1, z1);
512
    hs->event(hs);
513
}
514

  
515
static void hid_keyboard_event(void *opaque, int keycode)
516
{
517
    HIDState *hs = opaque;
518
    int slot;
519

  
520
    if (hs->n == QUEUE_LENGTH) {
521
        fprintf(stderr, "usb-kbd: warning: key event queue full\n");
522
        return;
523
    }
524
    slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
525
    hs->kbd.keycodes[slot] = keycode;
526
    hs->event(hs);
527
}
528

  
529
static void hid_keyboard_process_keycode(HIDState *hs)
530
{
531
    uint8_t hid_code, key;
532
    int i, keycode, slot;
533

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

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

  
544
    switch (hid_code) {
545
    case 0x00:
546
        return;
547

  
548
    case 0xe0:
549
        if (hs->kbd.modifiers & (1 << 9)) {
550
            hs->kbd.modifiers ^= 3 << 8;
551
            return;
552
        }
553
    case 0xe1 ... 0xe7:
554
        if (keycode & (1 << 7)) {
555
            hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
556
            return;
557
        }
558
    case 0xe8 ... 0xef:
559
        hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
560
        return;
561
    }
562

  
563
    if (keycode & (1 << 7)) {
564
        for (i = hs->kbd.keys - 1; i >= 0; i--) {
565
            if (hs->kbd.key[i] == hid_code) {
566
                hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
567
                hs->kbd.key[hs->kbd.keys] = 0x00;
568
                break;
569
            }
570
        }
571
        if (i < 0) {
572
            return;
573
        }
574
    } else {
575
        for (i = hs->kbd.keys - 1; i >= 0; i--) {
576
            if (hs->kbd.key[i] == hid_code) {
577
                break;
578
            }
579
        }
580
        if (i < 0) {
581
            if (hs->kbd.keys < sizeof(hs->kbd.key)) {
582
                hs->kbd.key[hs->kbd.keys++] = hid_code;
583
            }
584
        } else {
585
            return;
586
        }
587
    }
588
}
589

  
590
static inline int int_clamp(int val, int vmin, int vmax)
591
{
592
    if (val < vmin)
593
        return vmin;
594
    else if (val > vmax)
595
        return vmax;
596
    else
597
        return val;
598
}
599

  
600
static int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
601
{
602
    int dx, dy, dz, b, l;
603
    int index;
604
    HIDPointerEvent *e;
605

  
606
    if (!hs->ptr.mouse_grabbed) {
607
        qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
608
        hs->ptr.mouse_grabbed = 1;
609
    }
610

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

  
616
    if (hs->kind == HID_MOUSE) {
617
        dx = int_clamp(e->xdx, -127, 127);
618
        dy = int_clamp(e->ydy, -127, 127);
619
        e->xdx -= dx;
620
        e->ydy -= dy;
621
    } else {
622
        dx = e->xdx;
623
        dy = e->ydy;
624
    }
625
    dz = int_clamp(e->dz, -127, 127);
626
    e->dz -= dz;
627

  
628
    b = 0;
629
    if (e->buttons_state & MOUSE_EVENT_LBUTTON)
630
        b |= 0x01;
631
    if (e->buttons_state & MOUSE_EVENT_RBUTTON)
632
        b |= 0x02;
633
    if (e->buttons_state & MOUSE_EVENT_MBUTTON)
634
        b |= 0x04;
635

  
636
    if (hs->n &&
637
        !e->dz &&
638
        (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
639
        /* that deals with this event */
640
        QUEUE_INCR(hs->head);
641
        hs->n--;
642
    }
643

  
644
    /* Appears we have to invert the wheel direction */
645
    dz = 0 - dz;
646
    l = 0;
647
    switch (hs->kind) {
648
    case HID_MOUSE:
649
        if (len > l)
650
            buf[l++] = b;
651
        if (len > l)
652
            buf[l++] = dx;
653
        if (len > l)
654
            buf[l++] = dy;
655
        if (len > l)
656
            buf[l++] = dz;
657
        break;
658

  
659
    case HID_TABLET:
660
        if (len > l)
661
            buf[l++] = b;
662
        if (len > l)
663
            buf[l++] = dx & 0xff;
664
        if (len > l)
665
            buf[l++] = dx >> 8;
666
        if (len > l)
667
            buf[l++] = dy & 0xff;
668
        if (len > l)
669
            buf[l++] = dy >> 8;
670
        if (len > l)
671
            buf[l++] = dz;
672
        break;
673

  
674
    default:
675
        abort();
676
    }
677

  
678
    return l;
679
}
680

  
681
static int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
682
{
683
    if (len < 2)
684
        return 0;
685

  
686
    hid_keyboard_process_keycode(hs);
687

  
688
    buf[0] = hs->kbd.modifiers & 0xff;
689
    buf[1] = 0;
690
    if (hs->kbd.keys > 6) {
691
        memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
692
    } else {
693
        memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
694
    }
695

  
696
    return MIN(8, len);
697
}
698

  
699
static int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
700
{
701
    if (len > 0) {
702
        int ledstate = 0;
703
        /* 0x01: Num Lock LED
704
         * 0x02: Caps Lock LED
705
         * 0x04: Scroll Lock LED
706
         * 0x08: Compose LED
707
         * 0x10: Kana LED */
708
        hs->kbd.leds = buf[0];
709
        if (hs->kbd.leds & 0x04) {
710
            ledstate |= QEMU_SCROLL_LOCK_LED;
711
        }
712
        if (hs->kbd.leds & 0x01) {
713
            ledstate |= QEMU_NUM_LOCK_LED;
714
        }
715
        if (hs->kbd.leds & 0x02) {
716
            ledstate |= QEMU_CAPS_LOCK_LED;
717
        }
718
        kbd_put_ledstate(ledstate);
719
    }
720
    return 0;
721
}
722

  
723
static void hid_handle_reset(HIDState *hs)
724
{
725
    switch (hs->kind) {
726
    case HID_KEYBOARD:
727
        qemu_add_kbd_event_handler(hid_keyboard_event, hs);
728
        memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
729
        memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
730
        hs->kbd.keys = 0;
731
        break;
732
    case HID_MOUSE:
733
    case HID_TABLET:
734
        memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
735
        break;
736
    }
737
    hs->head = 0;
738
    hs->n = 0;
739
}
740

  
741 375
static void usb_hid_handle_reset(USBDevice *dev)
742 376
{
743 377
    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
744 378

  
745
    hid_handle_reset(&us->hid);
379
    hid_reset(&us->hid);
746 380
    us->protocol = 1;
747 381
    us->idle = 0;
748 382
}
......
875 509
    return ret;
876 510
}
877 511

  
878
static void hid_free(HIDState *hs)
879
{
880
    switch (hs->kind) {
881
    case HID_KEYBOARD:
882
        qemu_remove_kbd_event_handler();
883
        break;
884
    case HID_MOUSE:
885
    case HID_TABLET:
886
        qemu_remove_mouse_event_handler(hs->ptr.eh_entry);
887
        break;
888
    }
889
}
890

  
891 512
static void usb_hid_handle_destroy(USBDevice *dev)
892 513
{
893 514
    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
......
895 516
    hid_free(&us->hid);
896 517
}
897 518

  
898
static void hid_init(HIDState *hs, int kind, HIDEventFunc event)
899
{
900
    hs->kind = kind;
901
    hs->event = event;
902

  
903
    if (hs->kind == HID_MOUSE) {
904
        hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
905
                                                        0, "QEMU HID Mouse");
906
    } else if (hs->kind == HID_TABLET) {
907
        hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
908
                                                        1, "QEMU HID Tablet");
909
    }
910
}
911

  
912 519
static int usb_hid_initfn(USBDevice *dev, int kind)
913 520
{
914 521
    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);

Also available in: Unified diff