Revision 09b26c5e

b/hw/ps2.c
560 560
    s->common.update_arg = update_arg;
561 561
    ps2_reset(&s->common);
562 562
    register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
563
    qemu_add_mouse_event_handler(ps2_mouse_event, s);
563
    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0);
564 564
    qemu_register_reset(ps2_reset, &s->common);
565 565
    return s;
566 566
}
b/hw/usb-hid.c
30 30
#define SET_IDLE     0x210a
31 31
#define SET_PROTOCOL 0x210b
32 32

  
33
#define USB_MOUSE  1
34
#define USB_TABLET 2
35

  
33 36
typedef struct USBMouseState {
34 37
    USBDevice dev;
35 38
    int dx, dy, dz, buttons_state;
39
    int x, y;
40
    int kind;
41
    int mouse_grabbed;
36 42
} USBMouseState;
37 43

  
38 44
/* mostly the same values as the Bochs USB Mouse device */
......
93 99
	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
94 100
	0x05,       /*  u8  if_iInterface; */
95 101
     
102
        /* HID descriptor */
103
        0x09,        /*  u8  bLength; */
104
        0x21,        /*  u8 bDescriptorType; */
105
        0x01, 0x00,  /*  u16 HID_class */
106
        0x00,        /*  u8 country_code */
107
        0x01,        /*  u8 num_descriptors */
108
        0x22,        /*  u8 type; Report */
109
        50, 0,       /*  u16 len */
110

  
96 111
	/* one endpoint (status change endpoint) */
97 112
	0x07,       /*  u8  ep_bLength; */
98 113
	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
......
100 115
 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
101 116
 	0x03, 0x00, /*  u16 ep_wMaxPacketSize; */
102 117
	0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
118
};
119

  
120
static const uint8_t qemu_tablet_config_descriptor[] = {
121
	/* one configuration */
122
	0x09,       /*  u8  bLength; */
123
	0x02,       /*  u8  bDescriptorType; Configuration */
124
	0x22, 0x00, /*  u16 wTotalLength; */
125
	0x01,       /*  u8  bNumInterfaces; (1) */
126
	0x01,       /*  u8  bConfigurationValue; */
127
	0x04,       /*  u8  iConfiguration; */
128
	0xa0,       /*  u8  bmAttributes; 
129
				 Bit 7: must be set,
130
				     6: Self-powered,
131
				     5: Remote wakeup,
132
				     4..0: resvd */
133
	50,         /*  u8  MaxPower; */
134
      
135
	/* USB 1.1:
136
	 * USB 2.0, single TT organization (mandatory):
137
	 *	one interface, protocol 0
138
	 *
139
	 * USB 2.0, multiple TT organization (optional):
140
	 *	two interfaces, protocols 1 (like single TT)
141
	 *	and 2 (multiple TT mode) ... config is
142
	 *	sometimes settable
143
	 *	NOT IMPLEMENTED
144
	 */
145

  
146
	/* one interface */
147
	0x09,       /*  u8  if_bLength; */
148
	0x04,       /*  u8  if_bDescriptorType; Interface */
149
	0x00,       /*  u8  if_bInterfaceNumber; */
150
	0x00,       /*  u8  if_bAlternateSetting; */
151
	0x01,       /*  u8  if_bNumEndpoints; */
152
	0x03,       /*  u8  if_bInterfaceClass; */
153
	0x01,       /*  u8  if_bInterfaceSubClass; */
154
	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
155
	0x05,       /*  u8  if_iInterface; */
103 156

  
104 157
        /* HID descriptor */
105 158
        0x09,        /*  u8  bLength; */
......
108 161
        0x00,        /*  u8 country_code */
109 162
        0x01,        /*  u8 num_descriptors */
110 163
        0x22,        /*  u8 type; Report */
111
        50, 0,       /*  u16 len */
164
        74, 0,       /*  u16 len */
165

  
166
	/* one endpoint (status change endpoint) */
167
	0x07,       /*  u8  ep_bLength; */
168
	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
169
	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
170
 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
171
 	0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
172
	0x03,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
112 173
};
113 174

  
114 175
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
......
121 182
    0xC0, 0xC0,
122 183
};
123 184

  
185
static const uint8_t qemu_tablet_hid_report_descriptor[] = {
186
        0x05, 0x01, /* Usage Page Generic Desktop */
187
        0x09, 0x01, /* Usage Mouse */
188
        0xA1, 0x01, /* Collection Application */
189
        0x09, 0x01, /* Usage Pointer */
190
        0xA1, 0x00, /* Collection Physical */
191
        0x05, 0x09, /* Usage Page Button */
192
        0x19, 0x01, /* Usage Minimum Button 1 */
193
        0x29, 0x03, /* Usage Maximum Button 3 */
194
        0x15, 0x00, /* Logical Minimum 0 */
195
        0x25, 0x01, /* Logical Maximum 1 */
196
        0x95, 0x03, /* Report Count 3 */
197
        0x75, 0x01, /* Report Size 1 */
198
        0x81, 0x02, /* Input (Data, Var, Abs) */
199
        0x95, 0x01, /* Report Count 1 */
200
        0x75, 0x05, /* Report Size 5 */
201
        0x81, 0x01, /* Input (Cnst, Var, Abs) */
202
        0x05, 0x01, /* Usage Page Generic Desktop */
203
        0x09, 0x30, /* Usage X */
204
        0x09, 0x31, /* Usage Y */
205
        0x15, 0x00, /* Logical Minimum 0 */
206
        0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
207
        0x35, 0x00, /* Physical Minimum 0 */
208
        0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
209
        0x75, 0x10, /* Report Size 16 */
210
        0x95, 0x02, /* Report Count 2 */
211
        0x81, 0x02, /* Input (Data, Var, Abs) */
212
        0x05, 0x01, /* Usage Page Generic Desktop */
213
        0x09, 0x38, /* Usage Wheel */
214
        0x15, 0x81, /* Logical Minimum -127 */
215
        0x25, 0x7F, /* Logical Maximum 127 */
216
        0x35, 0x00, /* Physical Minimum 0 (same as logical) */
217
        0x45, 0x00, /* Physical Maximum 0 (same as logical) */
218
        0x75, 0x08, /* Report Size 8 */
219
        0x95, 0x01, /* Report Count 1 */
220
        0x81, 0x02, /* Input (Data, Var, Rel) */
221
        0xC0,       /* End Collection */
222
        0xC0,       /* End Collection */
223
};
224

  
124 225
static void usb_mouse_event(void *opaque,
125 226
                            int dx1, int dy1, int dz1, int buttons_state)
126 227
{
......
132 233
    s->buttons_state = buttons_state;
133 234
}
134 235

  
236
static void usb_tablet_event(void *opaque,
237
			     int x, int y, int dz, int buttons_state)
238
{
239
    USBMouseState *s = opaque;
240

  
241
    s->x = x;
242
    s->y = y;
243
    s->dz += dz;
244
    s->buttons_state = buttons_state;
245
}
246

  
135 247
static inline int int_clamp(int val, int vmin, int vmax)
136 248
{
137 249
    if (val < vmin)
......
146 258
{
147 259
    int dx, dy, dz, b, l;
148 260

  
261
    if (!s->mouse_grabbed) {
262
	qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
263
	s->mouse_grabbed = 1;
264
    }
265
    
149 266
    dx = int_clamp(s->dx, -128, 127);
150 267
    dy = int_clamp(s->dy, -128, 127);
151 268
    dz = int_clamp(s->dz, -128, 127);
......
173 290
    return l;
174 291
}
175 292

  
293
static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
294
{
295
    int dz, b, l;
296

  
297
    if (!s->mouse_grabbed) {
298
	qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
299
	s->mouse_grabbed = 1;
300
    }
301
    
302
    dz = int_clamp(s->dz, -128, 127);
303
    s->dz -= dz;
304

  
305
    /* Appears we have to invert the wheel direction */
306
    dz = 0 - dz;
307
    b = 0;
308
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
309
        b |= 0x01;
310
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
311
        b |= 0x02;
312
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
313
        b |= 0x04;
314

  
315
    buf[0] = b;
316
    buf[1] = s->x & 0xff;
317
    buf[2] = s->x >> 8;
318
    buf[3] = s->y & 0xff;
319
    buf[4] = s->y >> 8;
320
    buf[5] = dz;
321
    l = 6;
322

  
323
    return l;
324
}
325

  
176 326
static void usb_mouse_handle_reset(USBDevice *dev)
177 327
{
178 328
    USBMouseState *s = (USBMouseState *)dev;
......
180 330
    s->dx = 0;
181 331
    s->dy = 0;
182 332
    s->dz = 0;
333
    s->x = 0;
334
    s->y = 0;
183 335
    s->buttons_state = 0;
184 336
}
185 337

  
......
187 339
                                  int index, int length, uint8_t *data)
188 340
{
189 341
    USBMouseState *s = (USBMouseState *)dev;
190
    int ret;
342
    int ret = 0;
191 343

  
192 344
    switch(request) {
193 345
    case DeviceRequest | USB_REQ_GET_STATUS:
......
224 376
            ret = sizeof(qemu_mouse_dev_descriptor);
225 377
            break;
226 378
        case USB_DT_CONFIG:
227
            memcpy(data, qemu_mouse_config_descriptor, 
228
                   sizeof(qemu_mouse_config_descriptor));
229
            ret = sizeof(qemu_mouse_config_descriptor);
379
	    if (s->kind == USB_MOUSE) {
380
		memcpy(data, qemu_mouse_config_descriptor, 
381
		       sizeof(qemu_mouse_config_descriptor));
382
		ret = sizeof(qemu_mouse_config_descriptor);
383
	    } else if (s->kind == USB_TABLET) {
384
		memcpy(data, qemu_tablet_config_descriptor, 
385
		       sizeof(qemu_tablet_config_descriptor));
386
		ret = sizeof(qemu_tablet_config_descriptor);
387
	    }		
230 388
            break;
231 389
        case USB_DT_STRING:
232 390
            switch(value & 0xff) {
......
244 402
                break;
245 403
            case 2:
246 404
                /* product description */
247
                ret = set_usb_string(data, "QEMU USB Mouse");
405
		if (s->kind == USB_MOUSE)
406
		    ret = set_usb_string(data, "QEMU USB Mouse");
407
		else if (s->kind == USB_TABLET)
408
		    ret = set_usb_string(data, "QEMU USB Tablet");
248 409
                break;
249 410
            case 3:
250 411
                /* vendor description */
......
282 443
    case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
283 444
        switch(value >> 8) {
284 445
        case 0x22:
285
            memcpy(data, qemu_mouse_hid_report_descriptor, 
286
                   sizeof(qemu_mouse_hid_report_descriptor));
287
            ret = sizeof(qemu_mouse_hid_report_descriptor);
288
            break;
446
	    if (s->kind == USB_MOUSE) {
447
		memcpy(data, qemu_mouse_hid_report_descriptor, 
448
		       sizeof(qemu_mouse_hid_report_descriptor));
449
		ret = sizeof(qemu_mouse_hid_report_descriptor);
450
	    } else if (s->kind == USB_TABLET) {
451
		memcpy(data, qemu_tablet_hid_report_descriptor, 
452
		       sizeof(qemu_tablet_hid_report_descriptor));
453
		ret = sizeof(qemu_tablet_hid_report_descriptor);
454
	    }
455
	    break;
289 456
        default:
290 457
            goto fail;
291 458
        }
292 459
        break;
293 460
    case GET_REPORT:
294
        ret = usb_mouse_poll(s, data, length);
461
	if (s->kind == USB_MOUSE)
462
	    ret = usb_mouse_poll(s, data, length);
463
	else if (s->kind == USB_TABLET)
464
	    ret = usb_tablet_poll(s, data, length);
295 465
        break;
296 466
    case SET_IDLE:
297 467
        ret = 0;
......
308 478
                                 uint8_t devep, uint8_t *data, int len)
309 479
{
310 480
    USBMouseState *s = (USBMouseState *)dev;
311
    int ret;
481
    int ret = 0;
312 482

  
313 483
    switch(pid) {
314 484
    case USB_TOKEN_IN:
315 485
        if (devep == 1) {
316
            ret = usb_mouse_poll(s, data, len);
486
	    if (s->kind == USB_MOUSE)
487
		ret = usb_mouse_poll(s, data, len);
488
	    else if (s->kind == USB_TABLET)
489
		ret = usb_tablet_poll(s, data, len);
317 490
        } else {
318 491
            goto fail;
319 492
        }
......
327 500
    return ret;
328 501
}
329 502

  
503
USBDevice *usb_tablet_init(void)
504
{
505
    USBMouseState *s;
506

  
507
    s = qemu_mallocz(sizeof(USBMouseState));
508
    if (!s)
509
        return NULL;
510
    s->dev.speed = USB_SPEED_FULL;
511
    s->dev.handle_packet = usb_generic_handle_packet;
512

  
513
    s->dev.handle_reset = usb_mouse_handle_reset;
514
    s->dev.handle_control = usb_mouse_handle_control;
515
    s->dev.handle_data = usb_mouse_handle_data;
516
    s->kind = USB_TABLET;
517

  
518
    return (USBDevice *)s;
519
}
520

  
330 521
USBDevice *usb_mouse_init(void)
331 522
{
332 523
    USBMouseState *s;
......
340 531
    s->dev.handle_reset = usb_mouse_handle_reset;
341 532
    s->dev.handle_control = usb_mouse_handle_control;
342 533
    s->dev.handle_data = usb_mouse_handle_data;
534
    s->kind = USB_MOUSE;
343 535

  
344
    qemu_add_mouse_event_handler(usb_mouse_event, s);
345
    
346 536
    return (USBDevice *)s;
347 537
}
b/hw/usb.h
163 163

  
164 164
/* usb-hid.c */
165 165
USBDevice *usb_mouse_init(void);
166
USBDevice *usb_tablet_init(void);
b/sdl.c
39 39
static int gui_fullscreen_initial_grab;
40 40
static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
41 41
static uint8_t modifiers_state[256];
42
static int width, height;
43
static SDL_Cursor *sdl_cursor_normal;
44
static SDL_Cursor *sdl_cursor_hidden;
45
static int absolute_enabled = 0;
42 46

  
43 47
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
44 48
{
......
56 60
    if (gui_fullscreen)
57 61
        flags |= SDL_FULLSCREEN;
58 62

  
63
    width = w;
64
    height = h;
65

  
59 66
 again:
60 67
    screen = SDL_SetVideoMode(w, h, 0, flags);
61 68
    if (!screen) {
......
271 278
    SDL_WM_SetCaption(buf, "QEMU");
272 279
}
273 280

  
281
static void sdl_hide_cursor(void)
282
{
283
    SDL_SetCursor(sdl_cursor_hidden);
284
}
285

  
286
static void sdl_show_cursor(void)
287
{
288
    if (!kbd_mouse_is_absolute()) {
289
	SDL_SetCursor(sdl_cursor_normal);
290
    }
291
}
292

  
274 293
static void sdl_grab_start(void)
275 294
{
276
    SDL_ShowCursor(0);
295
    sdl_hide_cursor();
277 296
    SDL_WM_GrabInput(SDL_GRAB_ON);
278 297
    /* dummy read to avoid moving the mouse */
279 298
    SDL_GetRelativeMouseState(NULL, NULL);
......
284 303
static void sdl_grab_end(void)
285 304
{
286 305
    SDL_WM_GrabInput(SDL_GRAB_OFF);
287
    SDL_ShowCursor(1);
306
    sdl_show_cursor();
288 307
    gui_grab = 0;
289 308
    sdl_update_caption();
290 309
}
......
300 319
        buttons |= MOUSE_EVENT_RBUTTON;
301 320
    if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
302 321
        buttons |= MOUSE_EVENT_MBUTTON;
322

  
323
    if (kbd_mouse_is_absolute()) {
324
	if (!absolute_enabled) {
325
	    sdl_hide_cursor();
326
	    if (gui_grab) {
327
		sdl_grab_end();
328
	    }
329
	    absolute_enabled = 1;
330
	}
331

  
332
	SDL_GetMouseState(&dx, &dy);
333
	dx = dx * 0x7FFF / width;
334
	dy = dy * 0x7FFF / height;
335
    }
336

  
303 337
    kbd_mouse_event(dx, dy, dz, buttons);
304 338
}
305 339

  
......
423 457
            qemu_system_shutdown_request();
424 458
            break;
425 459
        case SDL_MOUSEMOTION:
426
            if (gui_grab) {
460
            if (gui_grab || kbd_mouse_is_absolute()) {
427 461
                sdl_send_mouse_event(0);
428 462
            }
429 463
            break;
......
431 465
        case SDL_MOUSEBUTTONUP:
432 466
            {
433 467
                SDL_MouseButtonEvent *bev = &ev->button;
434
                if (!gui_grab) {
468
                if (!gui_grab && !kbd_mouse_is_absolute()) {
435 469
                    if (ev->type == SDL_MOUSEBUTTONDOWN &&
436 470
                        (bev->state & SDL_BUTTON_LMASK)) {
437 471
                        /* start grabbing all events */
......
441 475
                    int dz;
442 476
                    dz = 0;
443 477
#ifdef SDL_BUTTON_WHEELUP
444
                    if (bev->button == SDL_BUTTON_WHEELUP) {
478
                    if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
445 479
                        dz = -1;
446
                    } else if (bev->button == SDL_BUTTON_WHEELDOWN) {
480
                    } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
447 481
                        dz = 1;
448 482
                    }
449 483
#endif               
......
471 505
void sdl_display_init(DisplayState *ds, int full_screen)
472 506
{
473 507
    int flags;
508
    uint8_t data = 0;
474 509

  
475 510
#if defined(__APPLE__)
476 511
    /* always use generic keymaps */
......
504 539
    SDL_EnableUNICODE(1);
505 540
    gui_grab = 0;
506 541

  
542
    sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
543
    sdl_cursor_normal = SDL_GetCursor();
544

  
507 545
    atexit(sdl_cleanup);
508 546
    if (full_screen) {
509 547
        gui_fullscreen = 1;
b/vl.c
474 474
static void *qemu_put_kbd_event_opaque;
475 475
static QEMUPutMouseEvent *qemu_put_mouse_event;
476 476
static void *qemu_put_mouse_event_opaque;
477
static int qemu_put_mouse_event_absolute;
477 478

  
478 479
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
479 480
{
......
481 482
    qemu_put_kbd_event = func;
482 483
}
483 484

  
484
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
485
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
485 486
{
486 487
    qemu_put_mouse_event_opaque = opaque;
487 488
    qemu_put_mouse_event = func;
489
    qemu_put_mouse_event_absolute = absolute;
488 490
}
489 491

  
490 492
void kbd_put_keycode(int keycode)
......
502 504
    }
503 505
}
504 506

  
507
int kbd_mouse_is_absolute(void)
508
{
509
    return qemu_put_mouse_event_absolute;
510
}
511

  
505 512
/***********************************************************/
506 513
/* timers */
507 514

  
......
3242 3249
        dev = usb_mouse_init();
3243 3250
        if (!dev)
3244 3251
            return -1;
3252
    } else if (!strcmp(devname, "tablet")) {
3253
	dev = usb_tablet_init();
3254
	if (!dev)
3255
	    return -1;
3245 3256
    } else {
3246 3257
        return -1;
3247 3258
    }
b/vl.h
158 158
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
159 159

  
160 160
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
161
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
161
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute);
162 162

  
163 163
void kbd_put_keycode(int keycode);
164 164
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
165
int kbd_mouse_is_absolute(void);
165 166

  
166 167
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
167 168
   constants) */

Also available in: Unified diff