Mercurial > sdl-ios-xcode
comparison src/events/SDL_touch.c @ 4919:716b2cbf4c9e
First pass at Windows multi-touch gesture support
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 30 Nov 2010 17:58:51 -0800 |
parents | d6adaafcfb10 |
children | 8bf5781fc582 |
comparison
equal
deleted
inserted
replaced
4918:f5f70fed2c4c | 4919:716b2cbf4c9e |
---|---|
63 int | 63 int |
64 SDL_GetFingerIndexId(SDL_Touch* touch,SDL_FingerID fingerid) | 64 SDL_GetFingerIndexId(SDL_Touch* touch,SDL_FingerID fingerid) |
65 { | 65 { |
66 int i; | 66 int i; |
67 for(i = 0;i < touch->num_fingers;i++) | 67 for(i = 0;i < touch->num_fingers;i++) |
68 if(touch->fingers[i]->id == fingerid) | 68 if(touch->fingers[i]->id == fingerid) |
69 return i; | 69 return i; |
70 return -1; | 70 return -1; |
71 } | 71 } |
72 | 72 |
73 | 73 |
74 SDL_Finger * | 74 SDL_Finger * |
75 SDL_GetFinger(SDL_Touch* touch,SDL_FingerID id) | 75 SDL_GetFinger(SDL_Touch* touch,SDL_FingerID id) |
76 { | 76 { |
77 int index = SDL_GetFingerIndexId(touch,id); | 77 int index = SDL_GetFingerIndexId(touch,id); |
78 if(index < 0 || index >= touch->num_fingers) | 78 if(index < 0 || index >= touch->num_fingers) |
79 return NULL; | 79 return NULL; |
80 return touch->fingers[index]; | 80 return touch->fingers[index]; |
81 } | 81 } |
82 | 82 |
83 | 83 |
84 int | 84 int |
257 int index; | 257 int index; |
258 SDL_Finger **fingers; | 258 SDL_Finger **fingers; |
259 //printf("Adding Finger...\n"); | 259 //printf("Adding Finger...\n"); |
260 if (SDL_GetFingerIndexId(touch,finger->id) != -1) { | 260 if (SDL_GetFingerIndexId(touch,finger->id) != -1) { |
261 SDL_SetError("Finger ID already in use"); | 261 SDL_SetError("Finger ID already in use"); |
262 } | 262 } |
263 | 263 |
264 /* Add the touch to the list of touch */ | 264 /* Add the touch to the list of touch */ |
265 if(touch->num_fingers >= touch->max_fingers){ | 265 if(touch->num_fingers >= touch->max_fingers){ |
266 //printf("Making room for it!\n"); | 266 //printf("Making room for it!\n"); |
267 fingers = (SDL_Finger **) SDL_realloc(touch->fingers, | 267 fingers = (SDL_Finger **) SDL_realloc(touch->fingers, |
268 (touch->num_fingers + 1) * sizeof(SDL_Finger *)); | 268 (touch->num_fingers + 1) * sizeof(SDL_Finger *)); |
269 touch->max_fingers = touch->num_fingers+1; | 269 touch->max_fingers = touch->num_fingers+1; |
270 if (!fingers) { | 270 if (!fingers) { |
271 SDL_OutOfMemory(); | 271 SDL_OutOfMemory(); |
272 return -1; | 272 return -1; |
273 } else { | 273 } else { |
274 touch->max_fingers = touch->num_fingers+1; | 274 touch->max_fingers = touch->num_fingers+1; |
275 touch->fingers = fingers; | 275 touch->fingers = fingers; |
276 } | 276 } |
277 } | 277 } |
278 | 278 |
279 index = touch->num_fingers; | 279 index = touch->num_fingers; |
280 //printf("Max_Fingers: %i Index: %i\n",touch->max_fingers,index); | 280 //printf("Max_Fingers: %i Index: %i\n",touch->max_fingers,index); |
281 | 281 |
282 touch->fingers[index] = (SDL_Finger *) SDL_malloc(sizeof(SDL_Finger)); | 282 touch->fingers[index] = (SDL_Finger *) SDL_malloc(sizeof(SDL_Finger)); |
308 } | 308 } |
309 | 309 |
310 | 310 |
311 int | 311 int |
312 SDL_SendFingerDown(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, | 312 SDL_SendFingerDown(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, |
313 float xin, float yin, float pressurein) | 313 float xin, float yin, float pressurein) |
314 { | 314 { |
315 int posted; | 315 int posted; |
316 Uint16 x; | 316 Uint16 x; |
317 Uint16 y; | 317 Uint16 y; |
318 Uint16 pressure; | 318 Uint16 pressure; |
319 SDL_Finger *finger; | 319 SDL_Finger *finger; |
320 | 320 |
321 SDL_Touch* touch = SDL_GetTouch(id); | 321 SDL_Touch* touch = SDL_GetTouch(id); |
322 | 322 |
323 if(!touch) { | 323 if(!touch) { |
324 return SDL_TouchNotFoundError(id); | 324 return SDL_TouchNotFoundError(id); |
330 y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres)); | 330 y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres)); |
331 pressure = (Uint16)((yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres)); | 331 pressure = (Uint16)((yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres)); |
332 | 332 |
333 finger = SDL_GetFinger(touch,fingerid); | 333 finger = SDL_GetFinger(touch,fingerid); |
334 if(down) { | 334 if(down) { |
335 if(finger == NULL) { | 335 if(finger == NULL) { |
336 SDL_Finger nf; | 336 SDL_Finger nf; |
337 nf.id = fingerid; | 337 nf.id = fingerid; |
338 nf.x = x; | 338 nf.x = x; |
339 nf.y = y; | 339 nf.y = y; |
340 nf.pressure = pressure; | 340 nf.pressure = pressure; |
341 nf.xdelta = 0; | 341 nf.xdelta = 0; |
342 nf.ydelta = 0; | 342 nf.ydelta = 0; |
343 nf.last_x = x; | 343 nf.last_x = x; |
344 nf.last_y = y; | 344 nf.last_y = y; |
345 nf.last_pressure = pressure; | 345 nf.last_pressure = pressure; |
346 nf.down = SDL_FALSE; | 346 nf.down = SDL_FALSE; |
347 if(SDL_AddFinger(touch,&nf) < 0) return 0; | 347 if(SDL_AddFinger(touch,&nf) < 0) return 0; |
348 finger = SDL_GetFinger(touch,fingerid); | 348 finger = SDL_GetFinger(touch,fingerid); |
349 } | 349 } |
350 else if(finger->down) return 0; | 350 else if(finger->down) return 0; |
351 if(xin < touch->x_min || yin < touch->y_min) return 0; //should defer if only a partial input | 351 if(xin < touch->x_min || yin < touch->y_min) return 0; //should defer if only a partial input |
352 posted = 0; | 352 posted = 0; |
353 if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) { | 353 if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) { |
354 SDL_Event event; | 354 SDL_Event event; |
355 event.tfinger.type = SDL_FINGERDOWN; | 355 event.tfinger.type = SDL_FINGERDOWN; |
356 event.tfinger.touchId = id; | 356 event.tfinger.touchId = id; |
357 event.tfinger.x = x; | 357 event.tfinger.x = x; |
358 event.tfinger.y = y; | 358 event.tfinger.y = y; |
359 event.tfinger.pressure = pressure; | 359 event.tfinger.pressure = pressure; |
360 event.tfinger.state = touch->buttonstate; | 360 event.tfinger.state = touch->buttonstate; |
361 event.tfinger.windowID = touch->focus ? touch->focus->id : 0; | 361 event.tfinger.windowID = touch->focus ? touch->focus->id : 0; |
362 event.tfinger.fingerId = fingerid; | 362 event.tfinger.fingerId = fingerid; |
363 posted = (SDL_PushEvent(&event) > 0); | 363 posted = (SDL_PushEvent(&event) > 0); |
364 } | 364 } |
365 if(posted) finger->down = SDL_TRUE; | 365 if(posted) finger->down = SDL_TRUE; |
366 return posted; | 366 return posted; |
367 } | 367 } |
368 else { | 368 else { |
369 if(finger == NULL) { | 369 if(finger == NULL) { |
370 SDL_SetError("Finger not found."); | 370 SDL_SetError("Finger not found."); |
371 return 0; | 371 return 0; |
372 } | 372 } |
373 posted = 0; | 373 posted = 0; |
374 if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) { | 374 if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) { |
375 SDL_Event event; | 375 SDL_Event event; |
376 event.tfinger.type = SDL_FINGERUP; | 376 event.tfinger.type = SDL_FINGERUP; |
377 event.tfinger.touchId = id; | 377 event.tfinger.touchId = id; |
378 event.tfinger.state = touch->buttonstate; | 378 event.tfinger.state = touch->buttonstate; |
379 event.tfinger.windowID = touch->focus ? touch->focus->id : 0; | 379 event.tfinger.windowID = touch->focus ? touch->focus->id : 0; |
380 event.tfinger.fingerId = fingerid; | 380 event.tfinger.fingerId = fingerid; |
381 //I don't trust the coordinates passed on fingerUp | 381 //I don't trust the coordinates passed on fingerUp |
382 event.tfinger.x = finger->x; | 382 event.tfinger.x = finger->x; |
383 event.tfinger.y = finger->y; | 383 event.tfinger.y = finger->y; |
384 event.tfinger.dx = 0; | 384 event.tfinger.dx = 0; |
385 event.tfinger.dy = 0; | 385 event.tfinger.dy = 0; |
386 | 386 |
387 if(SDL_DelFinger(touch,fingerid) < 0) return 0; | 387 if(SDL_DelFinger(touch,fingerid) < 0) return 0; |
388 posted = (SDL_PushEvent(&event) > 0); | 388 posted = (SDL_PushEvent(&event) > 0); |
389 } | 389 } |
390 return posted; | 390 return posted; |
391 } | 391 } |
392 } | 392 } |
393 | 393 |
394 int | 394 int |
395 SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, int relative, | 395 SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, int relative, |
396 float xin, float yin, float pressurein) | 396 float xin, float yin, float pressurein) |
397 { | 397 { |
398 int index = SDL_GetTouchIndexId(id); | 398 int index = SDL_GetTouchIndexId(id); |
399 SDL_Touch *touch = SDL_GetTouch(id); | 399 SDL_Touch *touch = SDL_GetTouch(id); |
400 SDL_Finger *finger = SDL_GetFinger(touch,fingerid); | 400 SDL_Finger *finger = SDL_GetFinger(touch,fingerid); |
401 int posted; | 401 int posted; |
402 Sint16 xrel, yrel; | 402 Sint16 xrel, yrel; |
403 float x_max = 0, y_max = 0; | 403 float x_max = 0, y_max = 0; |
404 Uint16 x; | 404 Uint16 x; |
405 Uint16 y; | 405 Uint16 y; |
406 Uint16 pressure; | 406 Uint16 pressure; |
407 | 407 |
408 if (!touch) { | 408 if (!touch) { |
409 return SDL_TouchNotFoundError(id); | 409 return SDL_TouchNotFoundError(id); |
410 } | 410 } |
411 | 411 |
412 //scale to Integer coordinates | 412 //scale to Integer coordinates |
413 x = (Uint16)((xin+touch->x_min)*(touch->xres)/(touch->native_xres)); | 413 x = (Uint16)((xin+touch->x_min)*(touch->xres)/(touch->native_xres)); |
414 y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres)); | 414 y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres)); |
415 pressure = (Uint16)((yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres)); | 415 pressure = (Uint16)((yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres)); |
416 if(touch->flush_motion) { | 416 if(touch->flush_motion) { |
417 return 0; | 417 return 0; |
418 } | 418 } |
419 | 419 |
420 if(finger == NULL || !finger->down) { | 420 if(finger == NULL || !finger->down) { |
421 return SDL_SendFingerDown(id,fingerid,SDL_TRUE,xin,yin,pressurein); | 421 return SDL_SendFingerDown(id,fingerid,SDL_TRUE,xin,yin,pressurein); |
422 } else { | 422 } else { |
423 /* the relative motion is calculated regarding the last position */ | 423 /* the relative motion is calculated regarding the last position */ |
424 if (relative) { | 424 if (relative) { |
425 xrel = x; | 425 xrel = x; |
426 yrel = y; | 426 yrel = y; |
427 x = (finger->last_x + x); | 427 x = (finger->last_x + x); |
428 y = (finger->last_y + y); | 428 y = (finger->last_y + y); |
429 } else { | 429 } else { |
430 if(xin < touch->x_min) x = finger->last_x; /*If movement is only in one axis,*/ | 430 if(xin < touch->x_min) x = finger->last_x; /*If movement is only in one axis,*/ |
431 if(yin < touch->y_min) y = finger->last_y; /*The other is marked as -1*/ | 431 if(yin < touch->y_min) y = finger->last_y; /*The other is marked as -1*/ |
432 if(pressurein < touch->pressure_min) pressure = finger->last_pressure; | 432 if(pressurein < touch->pressure_min) pressure = finger->last_pressure; |
433 xrel = x - finger->last_x; | 433 xrel = x - finger->last_x; |
434 yrel = y - finger->last_y; | 434 yrel = y - finger->last_y; |
435 //printf("xrel,yrel (%i,%i)\n",(int)xrel,(int)yrel); | 435 //printf("xrel,yrel (%i,%i)\n",(int)xrel,(int)yrel); |
436 } | 436 } |
437 | 437 |
438 /* Drop events that don't change state */ | 438 /* Drop events that don't change state */ |
439 if (!xrel && !yrel) { | 439 if (!xrel && !yrel) { |
440 #if 0 | 440 #if 0 |
441 printf("Touch event didn't change state - dropped!\n"); | 441 printf("Touch event didn't change state - dropped!\n"); |
442 #endif | 442 #endif |
443 return 0; | 443 return 0; |
444 } | 444 } |
445 | 445 |
446 /* Update internal touch coordinates */ | 446 /* Update internal touch coordinates */ |
447 | 447 |
448 finger->x = x; | 448 finger->x = x; |
449 finger->y = y; | 449 finger->y = y; |
450 | 450 |
451 /*Should scale to window? Normalize? Maintain Aspect?*/ | 451 /*Should scale to window? Normalize? Maintain Aspect?*/ |
452 //SDL_GetWindowSize(touch->focus, &x_max, &y_max); | 452 //SDL_GetWindowSize(touch->focus, &x_max, &y_max); |
453 | 453 |
454 /* make sure that the pointers find themselves inside the windows */ | 454 /* make sure that the pointers find themselves inside the windows */ |
455 /* only check if touch->xmax is set ! */ | 455 /* only check if touch->xmax is set ! */ |
456 /* | 456 /* |
457 if (x_max && touch->x > x_max) { | 457 if (x_max && touch->x > x_max) { |
458 touch->x = x_max; | 458 touch->x = x_max; |
459 } else if (touch->x < 0) { | 459 } else if (touch->x < 0) { |
460 touch->x = 0; | 460 touch->x = 0; |
461 } | 461 } |
462 | 462 |
463 if (y_max && touch->y > y_max) { | 463 if (y_max && touch->y > y_max) { |
464 touch->y = y_max; | 464 touch->y = y_max; |
465 } else if (touch->y < 0) { | 465 } else if (touch->y < 0) { |
466 touch->y = 0; | 466 touch->y = 0; |
467 } | 467 } |
468 */ | 468 */ |
469 finger->xdelta = xrel; | 469 finger->xdelta = xrel; |
470 finger->ydelta = yrel; | 470 finger->ydelta = yrel; |
471 finger->pressure = pressure; | 471 finger->pressure = pressure; |
472 | 472 |
473 | 473 |
474 | 474 |
475 /* Post the event, if desired */ | 475 /* Post the event, if desired */ |
476 posted = 0; | 476 posted = 0; |
477 if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) { | 477 if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) { |
478 SDL_Event event; | 478 SDL_Event event; |
479 event.tfinger.type = SDL_FINGERMOTION; | 479 event.tfinger.type = SDL_FINGERMOTION; |
480 event.tfinger.touchId = id; | 480 event.tfinger.touchId = id; |
481 event.tfinger.fingerId = fingerid; | 481 event.tfinger.fingerId = fingerid; |
482 event.tfinger.x = x; | 482 event.tfinger.x = x; |
483 event.tfinger.y = y; | 483 event.tfinger.y = y; |
484 event.tfinger.dx = xrel; | 484 event.tfinger.dx = xrel; |
485 event.tfinger.dy = yrel; | 485 event.tfinger.dy = yrel; |
486 | 486 |
487 event.tfinger.pressure = pressure; | 487 event.tfinger.pressure = pressure; |
488 event.tfinger.state = touch->buttonstate; | 488 event.tfinger.state = touch->buttonstate; |
489 event.tfinger.windowID = touch->focus ? touch->focus->id : 0; | 489 event.tfinger.windowID = touch->focus ? touch->focus->id : 0; |
490 posted = (SDL_PushEvent(&event) > 0); | 490 posted = (SDL_PushEvent(&event) > 0); |
491 } | 491 } |
492 finger->last_x = finger->x; | 492 finger->last_x = finger->x; |
493 finger->last_y = finger->y; | 493 finger->last_y = finger->y; |
494 finger->last_pressure = finger->pressure; | 494 finger->last_pressure = finger->pressure; |
495 return posted; | 495 return posted; |
496 } | 496 } |
497 } | 497 } |
498 int | 498 int |
499 SDL_SendTouchButton(SDL_TouchID id, Uint8 state, Uint8 button) | 499 SDL_SendTouchButton(SDL_TouchID id, Uint8 state, Uint8 button) |
500 { | 500 { |