~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/usb-hid.c

  • Committer: blueswir1
  • Date: 2007-11-25 08:48:16 UTC
  • Revision ID: git-v1:b76482e76560345c00e7d6c89199ced204a926d2
 Fix buffer mux handling for unconnected serial ports


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3737 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
    int protocol;
68
68
    int idle;
69
69
    int changed;
70
 
    void *datain_opaque;
71
 
    void (*datain)(void *);
72
70
} USBHIDState;
73
71
 
74
72
/* mostly the same values as the Bochs USB Mouse device */
136
134
        0x00,        /*  u8 country_code */
137
135
        0x01,        /*  u8 num_descriptors */
138
136
        0x22,        /*  u8 type; Report */
139
 
        52, 0,       /*  u16 len */
 
137
        50, 0,       /*  u16 len */
140
138
 
141
139
        /* one endpoint (status change endpoint) */
142
140
        0x07,       /*  u8  ep_bLength; */
143
141
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
144
142
        0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
145
143
        0x03,       /*  u8  ep_bmAttributes; Interrupt */
146
 
        0x04, 0x00, /*  u16 ep_wMaxPacketSize; */
 
144
        0x03, 0x00, /*  u16 ep_wMaxPacketSize; */
147
145
        0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
148
146
};
149
147
 
258
256
};
259
257
 
260
258
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
261
 
    0x05, 0x01,         /* Usage Page (Generic Desktop) */
262
 
    0x09, 0x02,         /* Usage (Mouse) */
263
 
    0xa1, 0x01,         /* Collection (Application) */
264
 
    0x09, 0x01,         /*   Usage (Pointer) */
265
 
    0xa1, 0x00,         /*   Collection (Physical) */
266
 
    0x05, 0x09,         /*     Usage Page (Button) */
267
 
    0x19, 0x01,         /*     Usage Minimum (1) */
268
 
    0x29, 0x03,         /*     Usage Maximum (3) */
269
 
    0x15, 0x00,         /*     Logical Minimum (0) */
270
 
    0x25, 0x01,         /*     Logical Maximum (1) */
271
 
    0x95, 0x03,         /*     Report Count (3) */
272
 
    0x75, 0x01,         /*     Report Size (1) */
273
 
    0x81, 0x02,         /*     Input (Data, Variable, Absolute) */
274
 
    0x95, 0x01,         /*     Report Count (1) */
275
 
    0x75, 0x05,         /*     Report Size (5) */
276
 
    0x81, 0x01,         /*     Input (Constant) */
277
 
    0x05, 0x01,         /*     Usage Page (Generic Desktop) */
278
 
    0x09, 0x30,         /*     Usage (X) */
279
 
    0x09, 0x31,         /*     Usage (Y) */
280
 
    0x09, 0x38,         /*     Usage (Wheel) */
281
 
    0x15, 0x81,         /*     Logical Minimum (-0x7f) */
282
 
    0x25, 0x7f,         /*     Logical Maximum (0x7f) */
283
 
    0x75, 0x08,         /*     Report Size (8) */
284
 
    0x95, 0x03,         /*     Report Count (3) */
285
 
    0x81, 0x06,         /*     Input (Data, Variable, Relative) */
286
 
    0xc0,               /*   End Collection */
287
 
    0xc0,               /* End Collection */
 
259
    0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
 
260
    0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
 
261
    0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
 
262
    0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
 
263
    0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
 
264
    0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
 
265
    0xC0, 0xC0,
288
266
};
289
267
 
290
268
static const uint8_t qemu_tablet_hid_report_descriptor[] = {
291
 
    0x05, 0x01,         /* Usage Page (Generic Desktop) */
292
 
    0x09, 0x01,         /* Usage (Pointer) */
293
 
    0xa1, 0x01,         /* Collection (Application) */
294
 
    0x09, 0x01,         /*   Usage (Pointer) */
295
 
    0xa1, 0x00,         /*   Collection (Physical) */
296
 
    0x05, 0x09,         /*     Usage Page (Button) */
297
 
    0x19, 0x01,         /*     Usage Minimum (1) */
298
 
    0x29, 0x03,         /*     Usage Maximum (3) */
299
 
    0x15, 0x00,         /*     Logical Minimum (0) */
300
 
    0x25, 0x01,         /*     Logical Maximum (1) */
301
 
    0x95, 0x03,         /*     Report Count (3) */
302
 
    0x75, 0x01,         /*     Report Size (1) */
303
 
    0x81, 0x02,         /*     Input (Data, Variable, Absolute) */
304
 
    0x95, 0x01,         /*     Report Count (1) */
305
 
    0x75, 0x05,         /*     Report Size (5) */
306
 
    0x81, 0x01,         /*     Input (Constant) */
307
 
    0x05, 0x01,         /*     Usage Page (Generic Desktop) */
308
 
    0x09, 0x30,         /*     Usage (X) */
309
 
    0x09, 0x31,         /*     Usage (Y) */
310
 
    0x15, 0x00,         /*     Logical Minimum (0) */
311
 
    0x26, 0xff, 0x7f,   /*     Logical Maximum (0x7fff) */
312
 
    0x35, 0x00,         /*     Physical Minimum (0) */
313
 
    0x46, 0xff, 0x7f,   /*     Physical Maximum (0x7fff) */
314
 
    0x75, 0x10,         /*     Report Size (16) */
315
 
    0x95, 0x02,         /*     Report Count (2) */
316
 
    0x81, 0x02,         /*     Input (Data, Variable, Absolute) */
317
 
    0x05, 0x01,         /*     Usage Page (Generic Desktop) */
318
 
    0x09, 0x38,         /*     Usage (Wheel) */
319
 
    0x15, 0x81,         /*     Logical Minimum (-0x7f) */
320
 
    0x25, 0x7f,         /*     Logical Maximum (0x7f) */
321
 
    0x35, 0x00,         /*     Physical Minimum (same as logical) */
322
 
    0x45, 0x00,         /*     Physical Maximum (same as logical) */
323
 
    0x75, 0x08,         /*     Report Size (8) */
324
 
    0x95, 0x01,         /*     Report Count (1) */
325
 
    0x81, 0x06,         /*     Input (Data, Variable, Relative) */
326
 
    0xc0,               /*   End Collection */
327
 
    0xc0,               /* End Collection */
 
269
        0x05, 0x01, /* Usage Page Generic Desktop */
 
270
        0x09, 0x01, /* Usage Mouse */
 
271
        0xA1, 0x01, /* Collection Application */
 
272
        0x09, 0x01, /* Usage Pointer */
 
273
        0xA1, 0x00, /* Collection Physical */
 
274
        0x05, 0x09, /* Usage Page Button */
 
275
        0x19, 0x01, /* Usage Minimum Button 1 */
 
276
        0x29, 0x03, /* Usage Maximum Button 3 */
 
277
        0x15, 0x00, /* Logical Minimum 0 */
 
278
        0x25, 0x01, /* Logical Maximum 1 */
 
279
        0x95, 0x03, /* Report Count 3 */
 
280
        0x75, 0x01, /* Report Size 1 */
 
281
        0x81, 0x02, /* Input (Data, Var, Abs) */
 
282
        0x95, 0x01, /* Report Count 1 */
 
283
        0x75, 0x05, /* Report Size 5 */
 
284
        0x81, 0x01, /* Input (Cnst, Var, Abs) */
 
285
        0x05, 0x01, /* Usage Page Generic Desktop */
 
286
        0x09, 0x30, /* Usage X */
 
287
        0x09, 0x31, /* Usage Y */
 
288
        0x15, 0x00, /* Logical Minimum 0 */
 
289
        0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
 
290
        0x35, 0x00, /* Physical Minimum 0 */
 
291
        0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
 
292
        0x75, 0x10, /* Report Size 16 */
 
293
        0x95, 0x02, /* Report Count 2 */
 
294
        0x81, 0x02, /* Input (Data, Var, Abs) */
 
295
        0x05, 0x01, /* Usage Page Generic Desktop */
 
296
        0x09, 0x38, /* Usage Wheel */
 
297
        0x15, 0x81, /* Logical Minimum -127 */
 
298
        0x25, 0x7F, /* Logical Maximum 127 */
 
299
        0x35, 0x00, /* Physical Minimum 0 (same as logical) */
 
300
        0x45, 0x00, /* Physical Maximum 0 (same as logical) */
 
301
        0x75, 0x08, /* Report Size 8 */
 
302
        0x95, 0x01, /* Report Count 1 */
 
303
        0x81, 0x02, /* Input (Data, Var, Rel) */
 
304
        0xC0,       /* End Collection */
 
305
        0xC0,       /* End Collection */
328
306
};
329
307
 
330
308
static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
404
382
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405
383
};
406
384
 
407
 
static void usb_hid_changed(USBHIDState *hs)
408
 
{
409
 
    hs->changed = 1;
410
 
 
411
 
    if (hs->datain)
412
 
        hs->datain(hs->datain_opaque);
413
 
}
414
 
 
415
385
static void usb_mouse_event(void *opaque,
416
386
                            int dx1, int dy1, int dz1, int buttons_state)
417
387
{
422
392
    s->dy += dy1;
423
393
    s->dz += dz1;
424
394
    s->buttons_state = buttons_state;
425
 
 
426
 
    usb_hid_changed(hs);
 
395
    hs->changed = 1;
427
396
}
428
397
 
429
398
static void usb_tablet_event(void *opaque,
436
405
    s->y = y;
437
406
    s->dz += dz;
438
407
    s->buttons_state = buttons_state;
439
 
 
440
 
    usb_hid_changed(hs);
 
408
    hs->changed = 1;
441
409
}
442
410
 
443
411
static void usb_keyboard_event(void *opaque, int keycode)
451
419
    hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
452
420
    s->modifiers &= ~(1 << 8);
453
421
 
 
422
    hs->changed = 1;
 
423
 
454
424
    switch (hid_code) {
455
425
    case 0x00:
456
426
        return;
475
445
            if (s->key[i] == hid_code) {
476
446
                s->key[i] = s->key[-- s->keys];
477
447
                s->key[s->keys] = 0x00;
478
 
                usb_hid_changed(hs);
479
 
                break;
 
448
                return;
480
449
            }
481
 
        if (i < 0)
482
 
            return;
483
450
    } else {
484
451
        for (i = s->keys - 1; i >= 0; i --)
485
452
            if (s->key[i] == hid_code)
486
 
                break;
487
 
        if (i < 0) {
488
 
            if (s->keys < sizeof(s->key))
489
 
                s->key[s->keys ++] = hid_code;
490
 
        } else
491
 
            return;
 
453
                return;
 
454
        if (s->keys < sizeof(s->key))
 
455
            s->key[s->keys ++] = hid_code;
492
456
    }
493
 
 
494
 
    usb_hid_changed(hs);
495
457
}
496
458
 
497
459
static inline int int_clamp(int val, int vmin, int vmax)
515
477
        s->mouse_grabbed = 1;
516
478
    }
517
479
 
518
 
    dx = int_clamp(s->dx, -127, 127);
519
 
    dy = int_clamp(s->dy, -127, 127);
520
 
    dz = int_clamp(s->dz, -127, 127);
 
480
    dx = int_clamp(s->dx, -128, 127);
 
481
    dy = int_clamp(s->dy, -128, 127);
 
482
    dz = int_clamp(s->dz, -128, 127);
521
483
 
522
484
    s->dx -= dx;
523
485
    s->dy -= dy;
524
486
    s->dz -= dz;
525
487
 
526
 
    /* Appears we have to invert the wheel direction */
527
 
    dz = 0 - dz;
528
 
 
529
488
    b = 0;
530
489
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
531
490
        b |= 0x01;
534
493
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
535
494
        b |= 0x04;
536
495
 
537
 
    l = 0;
538
 
    if (len > l)
539
 
        buf[l ++] = b;
540
 
    if (len > l)
541
 
        buf[l ++] = dx;
542
 
    if (len > l)
543
 
        buf[l ++] = dy;
544
 
    if (len > l)
545
 
        buf[l ++] = dz;
 
496
    buf[0] = b;
 
497
    buf[1] = dx;
 
498
    buf[2] = dy;
 
499
    l = 3;
 
500
    if (len >= 4) {
 
501
        buf[3] = dz;
 
502
        l = 4;
 
503
    }
546
504
    return l;
547
505
}
548
506
 
557
515
        s->mouse_grabbed = 1;
558
516
    }
559
517
 
560
 
    dz = int_clamp(s->dz, -127, 127);
 
518
    dz = int_clamp(s->dz, -128, 127);
561
519
    s->dz -= dz;
562
520
 
563
521
    /* Appears we have to invert the wheel direction */
912
870
 
913
871
    return (USBDevice *) s;
914
872
}
915
 
 
916
 
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
917
 
{
918
 
    USBHIDState *s = (USBHIDState *)dev;
919
 
 
920
 
    s->datain_opaque = opaque;
921
 
    s->datain = datain;
922
 
}