]> Git Repo - qemu.git/blob - hw/input/adb.c
iotests: Add test for external image truncation
[qemu.git] / hw / input / adb.c
1 /*
2  * QEMU ADB support
3  *
4  * Copyright (c) 2004 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "hw/hw.h"
25 #include "hw/input/adb.h"
26 #include "ui/console.h"
27
28 /* debug ADB */
29 //#define DEBUG_ADB
30
31 #ifdef DEBUG_ADB
32 #define ADB_DPRINTF(fmt, ...) \
33 do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
34 #else
35 #define ADB_DPRINTF(fmt, ...)
36 #endif
37
38 /* ADB commands */
39 #define ADB_BUSRESET            0x00
40 #define ADB_FLUSH               0x01
41 #define ADB_WRITEREG            0x08
42 #define ADB_READREG             0x0c
43
44 /* ADB device commands */
45 #define ADB_CMD_SELF_TEST               0xff
46 #define ADB_CMD_CHANGE_ID               0xfe
47 #define ADB_CMD_CHANGE_ID_AND_ACT       0xfd
48 #define ADB_CMD_CHANGE_ID_AND_ENABLE    0x00
49
50 /* ADB default device IDs (upper 4 bits of ADB command byte) */
51 #define ADB_DEVID_DONGLE   1
52 #define ADB_DEVID_KEYBOARD 2
53 #define ADB_DEVID_MOUSE    3
54 #define ADB_DEVID_TABLET   4
55 #define ADB_DEVID_MODEM    5
56 #define ADB_DEVID_MISC     7
57
58 /* error codes */
59 #define ADB_RET_NOTPRESENT (-2)
60
61 static void adb_device_reset(ADBDevice *d)
62 {
63     qdev_reset_all(DEVICE(d));
64 }
65
66 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
67 {
68     ADBDevice *d;
69     int devaddr, cmd, i;
70
71     cmd = buf[0] & 0xf;
72     if (cmd == ADB_BUSRESET) {
73         for(i = 0; i < s->nb_devices; i++) {
74             d = s->devices[i];
75             adb_device_reset(d);
76         }
77         return 0;
78     }
79     devaddr = buf[0] >> 4;
80     for(i = 0; i < s->nb_devices; i++) {
81         d = s->devices[i];
82         if (d->devaddr == devaddr) {
83             ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
84             return adc->devreq(d, obuf, buf, len);
85         }
86     }
87     return ADB_RET_NOTPRESENT;
88 }
89
90 /* XXX: move that to cuda ? */
91 int adb_poll(ADBBusState *s, uint8_t *obuf)
92 {
93     ADBDevice *d;
94     int olen, i;
95     uint8_t buf[1];
96
97     olen = 0;
98     for(i = 0; i < s->nb_devices; i++) {
99         if (s->poll_index >= s->nb_devices)
100             s->poll_index = 0;
101         d = s->devices[s->poll_index];
102         buf[0] = ADB_READREG | (d->devaddr << 4);
103         olen = adb_request(s, obuf + 1, buf, 1);
104         /* if there is data, we poll again the same device */
105         if (olen > 0) {
106             obuf[0] = buf[0];
107             olen++;
108             break;
109         }
110         s->poll_index++;
111     }
112     return olen;
113 }
114
115 static const TypeInfo adb_bus_type_info = {
116     .name = TYPE_ADB_BUS,
117     .parent = TYPE_BUS,
118     .instance_size = sizeof(ADBBusState),
119 };
120
121 static void adb_device_realizefn(DeviceState *dev, Error **errp)
122 {
123     ADBDevice *d = ADB_DEVICE(dev);
124     ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
125
126     if (bus->nb_devices >= MAX_ADB_DEVICES) {
127         return;
128     }
129
130     bus->devices[bus->nb_devices++] = d;
131 }
132
133 static void adb_device_class_init(ObjectClass *oc, void *data)
134 {
135     DeviceClass *dc = DEVICE_CLASS(oc);
136
137     dc->realize = adb_device_realizefn;
138     dc->bus_type = TYPE_ADB_BUS;
139 }
140
141 static const TypeInfo adb_device_type_info = {
142     .name = TYPE_ADB_DEVICE,
143     .parent = TYPE_DEVICE,
144     .instance_size = sizeof(ADBDevice),
145     .abstract = true,
146     .class_init = adb_device_class_init,
147 };
148
149 /***************************************************************/
150 /* Keyboard ADB device */
151
152 #define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
153
154 typedef struct KBDState {
155     /*< private >*/
156     ADBDevice parent_obj;
157     /*< public >*/
158
159     uint8_t data[128];
160     int rptr, wptr, count;
161 } KBDState;
162
163 #define ADB_KEYBOARD_CLASS(class) \
164     OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
165 #define ADB_KEYBOARD_GET_CLASS(obj) \
166     OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
167
168 typedef struct ADBKeyboardClass {
169     /*< private >*/
170     ADBDeviceClass parent_class;
171     /*< public >*/
172
173     DeviceRealize parent_realize;
174 } ADBKeyboardClass;
175
176 static const uint8_t pc_to_adb_keycode[256] = {
177   0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
178  12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
179   2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
180  11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
181  97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
182  84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
183   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
184   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
185   0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
186   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
187   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
188   0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
189   0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
190  61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
191   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
192   0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
193 };
194
195 static void adb_kbd_put_keycode(void *opaque, int keycode)
196 {
197     KBDState *s = opaque;
198
199     if (s->count < sizeof(s->data)) {
200         s->data[s->wptr] = keycode;
201         if (++s->wptr == sizeof(s->data))
202             s->wptr = 0;
203         s->count++;
204     }
205 }
206
207 static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
208 {
209     static int ext_keycode;
210     KBDState *s = ADB_KEYBOARD(d);
211     int adb_keycode, keycode;
212     int olen;
213
214     olen = 0;
215     for(;;) {
216         if (s->count == 0)
217             break;
218         keycode = s->data[s->rptr];
219         if (++s->rptr == sizeof(s->data))
220             s->rptr = 0;
221         s->count--;
222
223         if (keycode == 0xe0) {
224             ext_keycode = 1;
225         } else {
226             if (ext_keycode)
227                 adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
228             else
229                 adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
230             obuf[0] = adb_keycode | (keycode & 0x80);
231             /* NOTE: could put a second keycode if needed */
232             obuf[1] = 0xff;
233             olen = 2;
234             ext_keycode = 0;
235             break;
236         }
237     }
238     return olen;
239 }
240
241 static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
242                            const uint8_t *buf, int len)
243 {
244     KBDState *s = ADB_KEYBOARD(d);
245     int cmd, reg, olen;
246
247     if ((buf[0] & 0x0f) == ADB_FLUSH) {
248         /* flush keyboard fifo */
249         s->wptr = s->rptr = s->count = 0;
250         return 0;
251     }
252
253     cmd = buf[0] & 0xc;
254     reg = buf[0] & 0x3;
255     olen = 0;
256     switch(cmd) {
257     case ADB_WRITEREG:
258         switch(reg) {
259         case 2:
260             /* LED status */
261             break;
262         case 3:
263             switch(buf[2]) {
264             case ADB_CMD_SELF_TEST:
265                 break;
266             case ADB_CMD_CHANGE_ID:
267             case ADB_CMD_CHANGE_ID_AND_ACT:
268             case ADB_CMD_CHANGE_ID_AND_ENABLE:
269                 d->devaddr = buf[1] & 0xf;
270                 break;
271             default:
272                 /* XXX: check this */
273                 d->devaddr = buf[1] & 0xf;
274                 d->handler = buf[2];
275                 break;
276             }
277         }
278         break;
279     case ADB_READREG:
280         switch(reg) {
281         case 0:
282             olen = adb_kbd_poll(d, obuf);
283             break;
284         case 1:
285             break;
286         case 2:
287             obuf[0] = 0x00; /* XXX: check this */
288             obuf[1] = 0x07; /* led status */
289             olen = 2;
290             break;
291         case 3:
292             obuf[0] = d->handler;
293             obuf[1] = d->devaddr;
294             olen = 2;
295             break;
296         }
297         break;
298     }
299     return olen;
300 }
301
302 static const VMStateDescription vmstate_adb_kbd = {
303     .name = "adb_kbd",
304     .version_id = 1,
305     .minimum_version_id = 1,
306     .fields = (VMStateField[]) {
307         VMSTATE_BUFFER(data, KBDState),
308         VMSTATE_INT32(rptr, KBDState),
309         VMSTATE_INT32(wptr, KBDState),
310         VMSTATE_INT32(count, KBDState),
311         VMSTATE_END_OF_LIST()
312     }
313 };
314
315 static void adb_kbd_reset(DeviceState *dev)
316 {
317     ADBDevice *d = ADB_DEVICE(dev);
318     KBDState *s = ADB_KEYBOARD(dev);
319
320     d->handler = 1;
321     d->devaddr = ADB_DEVID_KEYBOARD;
322     memset(s->data, 0, sizeof(s->data));
323     s->rptr = 0;
324     s->wptr = 0;
325     s->count = 0;
326 }
327
328 static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
329 {
330     ADBDevice *d = ADB_DEVICE(dev);
331     ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
332
333     akc->parent_realize(dev, errp);
334
335     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
336 }
337
338 static void adb_kbd_initfn(Object *obj)
339 {
340     ADBDevice *d = ADB_DEVICE(obj);
341
342     d->devaddr = ADB_DEVID_KEYBOARD;
343 }
344
345 static void adb_kbd_class_init(ObjectClass *oc, void *data)
346 {
347     DeviceClass *dc = DEVICE_CLASS(oc);
348     ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
349     ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
350
351     akc->parent_realize = dc->realize;
352     dc->realize = adb_kbd_realizefn;
353
354     adc->devreq = adb_kbd_request;
355     dc->reset = adb_kbd_reset;
356     dc->vmsd = &vmstate_adb_kbd;
357 }
358
359 static const TypeInfo adb_kbd_type_info = {
360     .name = TYPE_ADB_KEYBOARD,
361     .parent = TYPE_ADB_DEVICE,
362     .instance_size = sizeof(KBDState),
363     .instance_init = adb_kbd_initfn,
364     .class_init = adb_kbd_class_init,
365     .class_size = sizeof(ADBKeyboardClass),
366 };
367
368 /***************************************************************/
369 /* Mouse ADB device */
370
371 #define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
372
373 typedef struct MouseState {
374     /*< public >*/
375     ADBDevice parent_obj;
376     /*< private >*/
377
378     int buttons_state, last_buttons_state;
379     int dx, dy, dz;
380 } MouseState;
381
382 #define ADB_MOUSE_CLASS(class) \
383     OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
384 #define ADB_MOUSE_GET_CLASS(obj) \
385     OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
386
387 typedef struct ADBMouseClass {
388     /*< public >*/
389     ADBDeviceClass parent_class;
390     /*< private >*/
391
392     DeviceRealize parent_realize;
393 } ADBMouseClass;
394
395 static void adb_mouse_event(void *opaque,
396                             int dx1, int dy1, int dz1, int buttons_state)
397 {
398     MouseState *s = opaque;
399
400     s->dx += dx1;
401     s->dy += dy1;
402     s->dz += dz1;
403     s->buttons_state = buttons_state;
404 }
405
406
407 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
408 {
409     MouseState *s = ADB_MOUSE(d);
410     int dx, dy;
411
412     if (s->last_buttons_state == s->buttons_state &&
413         s->dx == 0 && s->dy == 0)
414         return 0;
415
416     dx = s->dx;
417     if (dx < -63)
418         dx = -63;
419     else if (dx > 63)
420         dx = 63;
421
422     dy = s->dy;
423     if (dy < -63)
424         dy = -63;
425     else if (dy > 63)
426         dy = 63;
427
428     s->dx -= dx;
429     s->dy -= dy;
430     s->last_buttons_state = s->buttons_state;
431
432     dx &= 0x7f;
433     dy &= 0x7f;
434
435     if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
436         dy |= 0x80;
437     if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
438         dx |= 0x80;
439
440     obuf[0] = dy;
441     obuf[1] = dx;
442     return 2;
443 }
444
445 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
446                              const uint8_t *buf, int len)
447 {
448     MouseState *s = ADB_MOUSE(d);
449     int cmd, reg, olen;
450
451     if ((buf[0] & 0x0f) == ADB_FLUSH) {
452         /* flush mouse fifo */
453         s->buttons_state = s->last_buttons_state;
454         s->dx = 0;
455         s->dy = 0;
456         s->dz = 0;
457         return 0;
458     }
459
460     cmd = buf[0] & 0xc;
461     reg = buf[0] & 0x3;
462     olen = 0;
463     switch(cmd) {
464     case ADB_WRITEREG:
465         ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
466         switch(reg) {
467         case 2:
468             break;
469         case 3:
470             switch(buf[2]) {
471             case ADB_CMD_SELF_TEST:
472                 break;
473             case ADB_CMD_CHANGE_ID:
474             case ADB_CMD_CHANGE_ID_AND_ACT:
475             case ADB_CMD_CHANGE_ID_AND_ENABLE:
476                 d->devaddr = buf[1] & 0xf;
477                 break;
478             default:
479                 /* XXX: check this */
480                 d->devaddr = buf[1] & 0xf;
481                 break;
482             }
483         }
484         break;
485     case ADB_READREG:
486         switch(reg) {
487         case 0:
488             olen = adb_mouse_poll(d, obuf);
489             break;
490         case 1:
491             break;
492         case 3:
493             obuf[0] = d->handler;
494             obuf[1] = d->devaddr;
495             olen = 2;
496             break;
497         }
498         ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
499                     obuf[0], obuf[1]);
500         break;
501     }
502     return olen;
503 }
504
505 static void adb_mouse_reset(DeviceState *dev)
506 {
507     ADBDevice *d = ADB_DEVICE(dev);
508     MouseState *s = ADB_MOUSE(dev);
509
510     d->handler = 2;
511     d->devaddr = ADB_DEVID_MOUSE;
512     s->last_buttons_state = s->buttons_state = 0;
513     s->dx = s->dy = s->dz = 0;
514 }
515
516 static const VMStateDescription vmstate_adb_mouse = {
517     .name = "adb_mouse",
518     .version_id = 1,
519     .minimum_version_id = 1,
520     .fields = (VMStateField[]) {
521         VMSTATE_INT32(buttons_state, MouseState),
522         VMSTATE_INT32(last_buttons_state, MouseState),
523         VMSTATE_INT32(dx, MouseState),
524         VMSTATE_INT32(dy, MouseState),
525         VMSTATE_INT32(dz, MouseState),
526         VMSTATE_END_OF_LIST()
527     }
528 };
529
530 static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
531 {
532     MouseState *s = ADB_MOUSE(dev);
533     ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
534
535     amc->parent_realize(dev, errp);
536
537     qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
538 }
539
540 static void adb_mouse_initfn(Object *obj)
541 {
542     ADBDevice *d = ADB_DEVICE(obj);
543
544     d->devaddr = ADB_DEVID_MOUSE;
545 }
546
547 static void adb_mouse_class_init(ObjectClass *oc, void *data)
548 {
549     DeviceClass *dc = DEVICE_CLASS(oc);
550     ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
551     ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
552
553     amc->parent_realize = dc->realize;
554     dc->realize = adb_mouse_realizefn;
555
556     adc->devreq = adb_mouse_request;
557     dc->reset = adb_mouse_reset;
558     dc->vmsd = &vmstate_adb_mouse;
559 }
560
561 static const TypeInfo adb_mouse_type_info = {
562     .name = TYPE_ADB_MOUSE,
563     .parent = TYPE_ADB_DEVICE,
564     .instance_size = sizeof(MouseState),
565     .instance_init = adb_mouse_initfn,
566     .class_init = adb_mouse_class_init,
567     .class_size = sizeof(ADBMouseClass),
568 };
569
570
571 static void adb_register_types(void)
572 {
573     type_register_static(&adb_bus_type_info);
574     type_register_static(&adb_device_type_info);
575     type_register_static(&adb_kbd_type_info);
576     type_register_static(&adb_mouse_type_info);
577 }
578
579 type_init(adb_register_types)
This page took 0.054974 seconds and 4 git commands to generate.