]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/qemu/files/qemu-usb-wacom-0.8.2.patch
qemu: add cvs version from 20060723. bb files contain fix for building qemu with...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / qemu / files / qemu-usb-wacom-0.8.2.patch
1 diff -pNaur qemu-cvs-ts-orig/hw/usb-wacom.c qemu-cvs-ts/hw/usb-wacom.c
2 --- qemu-cvs-ts-orig/hw/usb-wacom.c     1970-01-01 01:00:00.000000000 +0100
3 +++ qemu-cvs-ts/hw/usb-wacom.c  2006-09-22 20:44:26.000000000 +0200
4 @@ -0,0 +1,408 @@
5 +/*
6 + * Wacom PenPartner USB tablet emulation.
7 + *
8 + * Copyright (c) 2006 Openedhand Ltd.
9 + *
10 + * Author: Andrzej Zaborowski <balrog@zabor.org>
11 + *
12 + * Based on hw/usb-hid.c:
13 + * Copyright (c) 2005 Fabrice Bellard
14 + *
15 + * Permission is hereby granted, free of charge, to any person obtaining a copy
16 + * of this software and associated documentation files (the "Software"), to deal
17 + * in the Software without restriction, including without limitation the rights
18 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 + * copies of the Software, and to permit persons to whom the Software is
20 + * furnished to do so, subject to the following conditions:
21 + *
22 + * The above copyright notice and this permission notice shall be included in
23 + * all copies or substantial portions of the Software.
24 + *
25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31 + * THE SOFTWARE.
32 + */
33 +#include "vl.h"
34 +
35 +/* Interface requests */
36 +#define WACOM_GET_REPORT       0x2101
37 +#define WACOM_SET_REPORT       0x2109
38 +
39 +/* HID interface requests */
40 +#define HID_GET_REPORT         0xa101
41 +#define HID_GET_IDLE           0xa102
42 +#define HID_GET_PROTOCOL       0xa103
43 +#define HID_SET_IDLE           0x210a
44 +#define HID_SET_PROTOCOL       0x210b
45 +
46 +#define WACOM_MODE_HID         1
47 +#define WACOM_MODE_WACOM       2
48 +
49 +typedef struct USBWacomState {
50 +    USBDevice dev;
51 +    int dx, dy, dz, buttons_state;
52 +    int x, y;
53 +    int mouse_grabbed;
54 +    int mode;
55 +} USBWacomState;
56 +
57 +static const uint8_t qemu_wacom_dev_descriptor[] = {
58 +    0x12,      /*  u8 bLength; */
59 +    0x01,      /*  u8 bDescriptorType; Device */
60 +    0x10, 0x10,        /*  u16 bcdUSB; v1.10 */
61 +
62 +    0x00,      /*  u8  bDeviceClass; */
63 +    0x00,      /*  u8  bDeviceSubClass; */
64 +    0x00,      /*  u8  bDeviceProtocol; [ low/full speeds only ] */
65 +    0x08,      /*  u8  bMaxPacketSize0; 8 Bytes */
66 +
67 +    0x6a, 0x05,        /*  u16 idVendor; */
68 +    0x00, 0x00,        /*  u16 idProduct; */
69 +    0x10, 0x42,        /*  u16 bcdDevice */
70 +
71 +    0x01,      /*  u8  iManufacturer; */
72 +    0x02,      /*  u8  iProduct; */
73 +    0x00,      /*  u8  iSerialNumber; */
74 +    0x01,      /*  u8  bNumConfigurations; */
75 +};
76 +
77 +static const uint8_t qemu_wacom_config_descriptor[] = {
78 +    /* one configuration */
79 +    0x09,      /*  u8  bLength; */
80 +    0x02,      /*  u8  bDescriptorType; Configuration */
81 +    0x22, 0x00,        /*  u16 wTotalLength; */
82 +    0x01,      /*  u8  bNumInterfaces; (1) */
83 +    0x01,      /*  u8  bConfigurationValue; */
84 +    0x00,      /*  u8  iConfiguration; */
85 +    0x80,      /*  u8  bmAttributes; 
86 +                                Bit 7: must be set,
87 +                                    6: Self-powered,
88 +                                    5: Remote wakeup,
89 +                                    4..0: resvd */
90 +    40,                /*  u8  MaxPower; */
91 +
92 +    /* one interface */
93 +    0x09,      /*  u8  if_bLength; */
94 +    0x04,      /*  u8  if_bDescriptorType; Interface */
95 +    0x00,      /*  u8  if_bInterfaceNumber; */
96 +    0x00,      /*  u8  if_bAlternateSetting; */
97 +    0x01,      /*  u8  if_bNumEndpoints; */
98 +    0x03,      /*  u8  if_bInterfaceClass; HID */
99 +    0x01,      /*  u8  if_bInterfaceSubClass; Boot */
100 +    0x02,      /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
101 +    0x00,      /*  u8  if_iInterface; */
102 +
103 +    /* HID descriptor */
104 +    0x09,      /*  u8  bLength; */
105 +    0x21,      /*  u8  bDescriptorType; */
106 +    0x01, 0x10,        /*  u16 HID_class */
107 +    0x00,      /*  u8  country_code */
108 +    0x01,      /*  u8  num_descriptors */
109 +    0x22,      /*  u8  type; Report */
110 +    0x6e, 0x00,        /*  u16 len */
111 +
112 +    /* one endpoint (status change endpoint) */
113 +    0x07,      /*  u8  ep_bLength; */
114 +    0x05,      /*  u8  ep_bDescriptorType; Endpoint */
115 +    0x81,      /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
116 +    0x03,      /*  u8  ep_bmAttributes; Interrupt */
117 +    0x08, 0x00,        /*  u16 ep_wMaxPacketSize; */
118 +    0x0a,      /*  u8  ep_bInterval; */
119 +};
120 +
121 +static void usb_mouse_event(void *opaque,
122 +                            int dx1, int dy1, int dz1, int buttons_state)
123 +{
124 +    USBWacomState *s = opaque;
125 +
126 +    s->dx += dx1;
127 +    s->dy += dy1;
128 +    s->dz += dz1;
129 +    s->buttons_state = buttons_state;
130 +}
131 +
132 +static void usb_wacom_event(void *opaque,
133 +                            int x, int y, int dz, int buttons_state)
134 +{
135 +    USBWacomState *s = opaque;
136 +
137 +    s->x = x;
138 +    s->y = y;
139 +    s->dz += dz;
140 +    s->buttons_state = buttons_state;
141 +}
142 +
143 +static inline int int_clamp(int val, int vmin, int vmax)
144 +{
145 +    if (val < vmin)
146 +        return vmin;
147 +    else if (val > vmax)
148 +        return vmax;
149 +    else
150 +        return val;
151 +}
152 +
153 +static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
154 +{
155 +    int dx, dy, dz, b, l;
156 +
157 +    if (!s->mouse_grabbed) {
158 +        qemu_add_mouse_event_handler(usb_mouse_event, s, 1);
159 +        s->mouse_grabbed = 1;
160 +    }
161 +
162 +    dx = int_clamp(s->dx, -128, 127);
163 +    dy = int_clamp(s->dy, -128, 127);
164 +    dz = int_clamp(s->dz, -128, 127);
165 +
166 +    s->dx -= dx;
167 +    s->dy -= dy;
168 +    s->dz -= dz;
169 +
170 +    b = 0;
171 +    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
172 +        b |= 0x01;
173 +    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
174 +        b |= 0x02;
175 +    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
176 +        b |= 0x04;
177 +
178 +    buf[0] = b;
179 +    buf[1] = dx;
180 +    buf[2] = dy;
181 +    l = 3;
182 +    if (len >= 4) {
183 +        buf[3] = dz;
184 +        l = 4;
185 +    }
186 +    return l;
187 +}
188 +
189 +static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
190 +{
191 +    int b;
192 +
193 +    if (!s->mouse_grabbed) {
194 +        qemu_add_mouse_event_handler(usb_wacom_event, s, 1);
195 +        s->mouse_grabbed = 1;
196 +    }
197 +
198 +    b = 0;
199 +    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
200 +        b |= 0x01;
201 +    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
202 +        b |= 0x02;
203 +    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
204 +        b |= 0x04;
205 +
206 +    if (len < 7)
207 +        return 0;
208 +
209 +    buf[0] = s->mode;
210 +    buf[1] = s->x & 0xff;
211 +    buf[2] = s->x >> 8;
212 +    buf[3] = s->y & 0xff;
213 +    buf[4] = s->y >> 8;
214 +    if (b) {
215 +        buf[5] = 0x40;
216 +        buf[6] = 0;
217 +    } else {
218 +        buf[5] = 0x00;
219 +        buf[6] = (unsigned char) -120;
220 +    }
221 +
222 +    return 7;
223 +}
224 +
225 +static void usb_wacom_handle_reset(USBDevice *dev)
226 +{
227 +    USBWacomState *s = (USBWacomState *) dev;
228 +
229 +    s->dx = 0;
230 +    s->dy = 0;
231 +    s->dz = 0;
232 +    s->x = 0;
233 +    s->y = 0;
234 +    s->buttons_state = 0;
235 +    s->mode = WACOM_MODE_HID;
236 +}
237 +
238 +static int usb_wacom_handle_control(USBDevice *dev, int request, int value,
239 +                                    int index, int length, uint8_t *data)
240 +{
241 +    USBWacomState *s = (USBWacomState *) dev;
242 +    int ret = 0;
243 +
244 +    switch (request) {
245 +    case DeviceRequest | USB_REQ_GET_STATUS:
246 +        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
247 +            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
248 +        data[1] = 0x00;
249 +        ret = 2;
250 +        break;
251 +    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
252 +        if (value == USB_DEVICE_REMOTE_WAKEUP) {
253 +            dev->remote_wakeup = 0;
254 +        } else {
255 +            goto fail;
256 +        }
257 +        ret = 0;
258 +        break;
259 +    case DeviceOutRequest | USB_REQ_SET_FEATURE:
260 +        if (value == USB_DEVICE_REMOTE_WAKEUP) {
261 +            dev->remote_wakeup = 1;
262 +        } else {
263 +            goto fail;
264 +        }
265 +        ret = 0;
266 +        break;
267 +    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
268 +        dev->addr = value;
269 +        ret = 0;
270 +        break;
271 +    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
272 +        switch (value >> 8) {
273 +        case USB_DT_DEVICE:
274 +            memcpy(data, qemu_wacom_dev_descriptor, 
275 +                   sizeof(qemu_wacom_dev_descriptor));
276 +            ret = sizeof(qemu_wacom_dev_descriptor);
277 +            break;
278 +        case USB_DT_CONFIG:
279 +                   memcpy(data, qemu_wacom_config_descriptor, 
280 +                   sizeof(qemu_wacom_config_descriptor));
281 +            ret = sizeof(qemu_wacom_config_descriptor);
282 +            break;
283 +        case USB_DT_STRING:
284 +            switch (value & 0xff) {
285 +            case 0:
286 +                /* language ids */
287 +                data[0] = 4;
288 +                data[1] = 3;
289 +                data[2] = 0x09;
290 +                data[3] = 0x04;
291 +                ret = 4;
292 +                break;
293 +            case 1:
294 +                /* serial number */
295 +                ret = set_usb_string(data, "1");
296 +                break;
297 +            case 2:
298 +               ret = set_usb_string(data, "Wacom PenPartner");
299 +                break;
300 +            case 3:
301 +                /* vendor description */
302 +                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
303 +                break;
304 +            case 4:
305 +                ret = set_usb_string(data, "Wacom Tablet");
306 +                break;
307 +            case 5:
308 +                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
309 +                break;
310 +            default:
311 +                goto fail;
312 +            }
313 +            break;
314 +        default:
315 +            goto fail;
316 +        }
317 +        break;
318 +    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
319 +        data[0] = 1;
320 +        ret = 1;
321 +        break;
322 +    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
323 +        ret = 0;
324 +        break;
325 +    case DeviceRequest | USB_REQ_GET_INTERFACE:
326 +        data[0] = 0;
327 +        ret = 1;
328 +        break;
329 +    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
330 +        ret = 0;
331 +        break;
332 +    case WACOM_SET_REPORT:
333 +        qemu_add_mouse_event_handler(NULL, NULL, 0);
334 +       s->mouse_grabbed = 0;
335 +        s->mode = data[0];
336 +        ret = 0;
337 +        break;
338 +    case WACOM_GET_REPORT:
339 +        data[0] = 0;
340 +        data[1] = s->mode;
341 +        ret = 2;
342 +        break;
343 +    /* USB HID requests */
344 +    case HID_GET_REPORT:
345 +        if (s->mode == WACOM_MODE_HID)
346 +            ret = usb_mouse_poll(s, data, length);
347 +        else if (s->mode == WACOM_MODE_WACOM)
348 +            ret = usb_wacom_poll(s, data, length);
349 +        break;
350 +    case HID_SET_IDLE:
351 +        ret = 0;
352 +        break;
353 +    default:
354 +    fail:
355 +        ret = USB_RET_STALL;
356 +        break;
357 +    }
358 +    return ret;
359 +}
360 +
361 +static int usb_wacom_handle_data(USBDevice *dev, int pid, 
362 +                                 uint8_t devep, uint8_t *data, int len)
363 +{
364 +    USBWacomState *s = (USBWacomState *) dev;
365 +    int ret = 0;
366 +
367 +    switch (pid) {
368 +    case USB_TOKEN_IN:
369 +        if (devep == 1) {
370 +            if (s->mode == WACOM_MODE_HID)
371 +                ret = usb_mouse_poll(s, data, len);
372 +            else if (s->mode == WACOM_MODE_WACOM)
373 +                ret = usb_wacom_poll(s, data, len);
374 +            break;
375 +        }
376 +        /* Fall through.  */
377 +    case USB_TOKEN_OUT:
378 +    default:
379 +        ret = USB_RET_STALL;
380 +        break;
381 +    }
382 +    return ret;
383 +}
384 +
385 +static void usb_wacom_handle_destroy(USBDevice *dev)
386 +{
387 +    USBWacomState *s = (USBWacomState *) dev;
388 +
389 +    qemu_add_mouse_event_handler(NULL, NULL, 0);
390 +    qemu_free(s);
391 +}
392 +
393 +USBDevice *usb_wacom_init(void)
394 +{
395 +    USBWacomState *s;
396 +
397 +    s = qemu_mallocz(sizeof(USBWacomState));
398 +    if (!s)
399 +        return NULL;
400 +    s->dev.speed = USB_SPEED_FULL;
401 +    s->dev.handle_packet = usb_generic_handle_packet;
402 +
403 +    s->dev.handle_reset = usb_wacom_handle_reset;
404 +    s->dev.handle_control = usb_wacom_handle_control;
405 +    s->dev.handle_data = usb_wacom_handle_data;
406 +    s->dev.handle_destroy = usb_wacom_handle_destroy;
407 +
408 +    pstrcpy(s->dev.devname, sizeof(s->dev.devname),
409 +            "QEMU PenPartner Tablet");
410 +
411 +    return (USBDevice *) s;
412 +}
413 diff -pNaur qemu-cvs-ts-orig/hw/usb.h qemu-cvs-ts/hw/usb.h
414 --- qemu-cvs-ts-orig/hw/usb.h   2006-08-12 03:04:27.000000000 +0200
415 +++ qemu-cvs-ts/hw/usb.h        2006-09-21 01:40:40.000000000 +0200
416 @@ -218,3 +218,6 @@ USBDevice *usb_tablet_init(void);
417  
418  /* usb-msd.c */
419  USBDevice *usb_msd_init(const char *filename);
420 +
421 +/* usb-wacom.c */
422 +USBDevice *usb_wacom_init(void);
423 diff -pNaur qemu-cvs-ts-orig/vl.c qemu-cvs-ts/vl.c
424 --- qemu-cvs-ts-orig/vl.c       2006-09-10 16:39:54.000000000 +0200
425 +++ qemu-cvs-ts/vl.c    2006-09-21 01:45:16.000000000 +0200
426 @@ -3765,6 +3765,8 @@ static int usb_device_add(const char *de
427         dev = usb_tablet_init();
428      } else if (strstart(devname, "disk:", &p)) {
429          dev = usb_msd_init(p);
430 +    } else if (!strcmp(devname, "wacom-tablet")) {
431 +        dev = usb_wacom_init();
432      } else {
433          return -1;
434      }
435 diff -pNaur qemu-cvs-ts-orig/Makefile.target qemu-cvs-ts/Makefile.target
436 --- qemu-cvs-ts-orig/Makefile.target    2006-09-18 03:15:29.000000000 +0200
437 +++ qemu-cvs-ts/Makefile.target 2006-09-21 02:32:19.000000000 +0200
438 @@ -330,6 +330,7 @@ VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a
439  
440  # USB layer
441  VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
442 +VL_OBJS+= usb-wacom.o
443  
444  # PCI network cards
445  VL_OBJS+= ne2000.o rtl8139.o pcnet.o