src/events/SDL_touch.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 20 Feb 2012 23:54:33 -0500
changeset 6299 3809b2eee787
parent 6138 4c64952a58fb
child 6810 b5609445aa4c
permissions -rwxr-xr-x
Fixed bug 1423 - Finger touch events don't report pressure

Philip Taylor 2012-02-19 08:34:52 PST

SDL_touch.c never actually uses the 'pressurein' arguments to
SDL_SendFingerDown/SDL_SendTouchMotion, so it doesn't report the real pressure.
Also it uses touch->pressureres which is never initialised. Also it fails to
initialise some fields of event.tfinger for certain events, so applications
might try to use bogus data.

The attached patch seems to be enough to produce generally sensible output on
Android.
jim@4640
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
jim@4640
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
jim@4640
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
jim@4640
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
jim@4640
    20
*/
jim@4640
    21
#include "SDL_config.h"
jim@4640
    22
jim@4640
    23
/* General touch handling code for SDL */
jim@4640
    24
jim@4640
    25
#include "SDL_events.h"
jim@4640
    26
#include "SDL_events_c.h"
jim@4640
    27
#include "../video/SDL_sysvideo.h"
jim@4640
    28
jimtla@4648
    29
#include <stdio.h>
jimtla@4648
    30
jim@4640
    31
jim@4640
    32
static int SDL_num_touch = 0;
jim@4641
    33
static SDL_Touch **SDL_touchPads = NULL;
jim@4640
    34
jim@4640
    35
jim@4640
    36
/* Public functions */
jim@4640
    37
int
jim@4640
    38
SDL_TouchInit(void)
jim@4640
    39
{
jim@4667
    40
  return (0);
jim@4640
    41
}
jim@4642
    42
jim@4640
    43
SDL_Touch *
jimtla@4678
    44
SDL_GetTouch(SDL_TouchID id)
jim@4640
    45
{
jim@4641
    46
    int index = SDL_GetTouchIndexId(id);
jim@4640
    47
    if (index < 0 || index >= SDL_num_touch) {
jim@4640
    48
        return NULL;
jim@4640
    49
    }
jim@4641
    50
    return SDL_touchPads[index];
jim@4640
    51
}
jim@4640
    52
jim@4642
    53
SDL_Touch *
jim@4642
    54
SDL_GetTouchIndex(int index)
jim@4641
    55
{
jim@4642
    56
    if (index < 0 || index >= SDL_num_touch) {
jim@4642
    57
        return NULL;
jim@4642
    58
    }
jim@4642
    59
    return SDL_touchPads[index];
jim@4641
    60
}
jim@4641
    61
slouken@6044
    62
static int
jimtla@4678
    63
SDL_GetFingerIndexId(SDL_Touch* touch,SDL_FingerID fingerid)
jim@4641
    64
{
jim@4641
    65
    int i;
jim@4641
    66
    for(i = 0;i < touch->num_fingers;i++)
slouken@4919
    67
        if(touch->fingers[i]->id == fingerid)
slouken@4919
    68
            return i;
jim@4641
    69
    return -1;
jim@4641
    70
}
jim@4641
    71
jim@4642
    72
jim@4642
    73
SDL_Finger *
jimtla@4678
    74
SDL_GetFinger(SDL_Touch* touch,SDL_FingerID id)
jim@4642
    75
{
jim@4642
    76
    int index = SDL_GetFingerIndexId(touch,id);
jim@4642
    77
    if(index < 0 || index >= touch->num_fingers)
slouken@4919
    78
        return NULL;
jim@4642
    79
    return touch->fingers[index];
jim@4642
    80
}
jim@4642
    81
jim@4642
    82
jim@4641
    83
int
jimtla@4678
    84
SDL_GetTouchIndexId(SDL_TouchID id)
jim@4640
    85
{
jim@4640
    86
    int index;
jim@4640
    87
    SDL_Touch *touch;
jim@4640
    88
jim@4640
    89
    for (index = 0; index < SDL_num_touch; ++index) {
jim@4641
    90
        touch = SDL_touchPads[index];
jim@4640
    91
        if (touch->id == id) {
jim@4640
    92
            return index;
jim@4640
    93
        }
jim@4640
    94
    }
jim@4640
    95
    return -1;
jim@4640
    96
}
jim@4640
    97
jim@4640
    98
int
jim@4642
    99
SDL_AddTouch(const SDL_Touch * touch, char *name)
jim@4640
   100
{
jim@4641
   101
    SDL_Touch **touchPads;
slouken@5076
   102
    int index;
slouken@5076
   103
    size_t length;
jim@4640
   104
jim@4640
   105
    if (SDL_GetTouchIndexId(touch->id) != -1) {
jim@4640
   106
        SDL_SetError("Touch ID already in use");
jim@4640
   107
    }
jim@4640
   108
jim@4640
   109
    /* Add the touch to the list of touch */
jim@4641
   110
    touchPads = (SDL_Touch **) SDL_realloc(SDL_touchPads,
jim@4640
   111
                                      (SDL_num_touch + 1) * sizeof(*touch));
jim@4641
   112
    if (!touchPads) {
jim@4640
   113
        SDL_OutOfMemory();
jim@4640
   114
        return -1;
jim@4640
   115
    }
jim@4640
   116
jim@4641
   117
    SDL_touchPads = touchPads;
jim@4640
   118
    index = SDL_num_touch++;
jim@4640
   119
jim@4641
   120
    SDL_touchPads[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchPads[index]));
jim@4641
   121
    if (!SDL_touchPads[index]) {
jim@4640
   122
        SDL_OutOfMemory();
jim@4640
   123
        return -1;
jim@4640
   124
    }
slouken@5455
   125
    SDL_memcpy(SDL_touchPads[index], touch, sizeof(*touch));
jim@4640
   126
jim@4640
   127
    /* we're setting the touch properties */
jim@4640
   128
    length = 0;
jim@4640
   129
    length = SDL_strlen(name);
jim@4641
   130
    SDL_touchPads[index]->focus = 0;
jim@4641
   131
    SDL_touchPads[index]->name = SDL_malloc((length + 2) * sizeof(char));
jim@4642
   132
    SDL_strlcpy(SDL_touchPads[index]->name, name, length + 1);   
jim@4642
   133
jim@4642
   134
    SDL_touchPads[index]->num_fingers = 0;
jim@4646
   135
    SDL_touchPads[index]->max_fingers = 1;
jim@4646
   136
    SDL_touchPads[index]->fingers = (SDL_Finger **) SDL_malloc(sizeof(SDL_Finger*));
jim@4646
   137
    SDL_touchPads[index]->fingers[0] = NULL;
jim@4642
   138
    SDL_touchPads[index]->buttonstate = 0;
jim@4642
   139
    SDL_touchPads[index]->relative_mode = SDL_FALSE;
jim@4642
   140
    SDL_touchPads[index]->flush_motion = SDL_FALSE;
jim@4641
   141
    
jimtla@4678
   142
    SDL_touchPads[index]->xres = (1<<(16-1));
jimtla@4678
   143
    SDL_touchPads[index]->yres = (1<<(16-1));
slouken@6299
   144
    SDL_touchPads[index]->pressureres = (1<<(16-1));
jim@4657
   145
    //Do I want this here? Probably
jim@4657
   146
    SDL_GestureAddTouch(SDL_touchPads[index]);
jim@4657
   147
jim@4640
   148
    return index;
jim@4640
   149
}
jim@4640
   150
jim@4640
   151
void
jimtla@4678
   152
SDL_DelTouch(SDL_TouchID id)
jim@4640
   153
{
jim@4641
   154
    int index = SDL_GetTouchIndexId(id);
jim@4641
   155
    SDL_Touch *touch = SDL_GetTouch(id);
jim@4640
   156
jim@4640
   157
    if (!touch) {
jim@4640
   158
        return;
jim@4640
   159
    }
jim@4640
   160
jim@4641
   161
    
jim@4640
   162
    SDL_free(touch->name);
jim@4640
   163
 
jim@4640
   164
    if (touch->FreeTouch) {
jim@4640
   165
        touch->FreeTouch(touch);
jim@4640
   166
    }
jim@4640
   167
    SDL_free(touch);
jim@4640
   168
jim@4641
   169
    SDL_num_touch--;
jim@4641
   170
    SDL_touchPads[index] = SDL_touchPads[SDL_num_touch];
jim@4640
   171
}
jim@4640
   172
jim@4640
   173
void
jim@4640
   174
SDL_TouchQuit(void)
jim@4640
   175
{
jim@4640
   176
    int i;
jim@4640
   177
jim@4641
   178
    for (i = SDL_num_touch-1; i > 0 ; --i) {
jim@4640
   179
        SDL_DelTouch(i);
jim@4640
   180
    }
jim@4640
   181
    SDL_num_touch = 0;
jim@4640
   182
jim@4641
   183
    if (SDL_touchPads) {
jim@4641
   184
        SDL_free(SDL_touchPads);
jim@4641
   185
        SDL_touchPads = NULL;
jim@4640
   186
    }
jim@4640
   187
}
jim@4640
   188
jim@4640
   189
int
jim@4640
   190
SDL_GetNumTouch(void)
jim@4640
   191
{
jim@4640
   192
    return SDL_num_touch;
jim@4640
   193
}
slouken@6044
   194
jim@4641
   195
SDL_Window *
jimtla@4678
   196
SDL_GetTouchFocusWindow(SDL_TouchID id)
jim@4640
   197
{
jim@4641
   198
    SDL_Touch *touch = SDL_GetTouch(id);
jim@4640
   199
jim@4640
   200
    if (!touch) {
jim@4640
   201
        return 0;
jim@4640
   202
    }
jim@4640
   203
    return touch->focus;
jim@4640
   204
}
jim@4640
   205
jim@4640
   206
void
jimtla@4678
   207
SDL_SetTouchFocus(SDL_TouchID id, SDL_Window * window)
jim@4640
   208
{
jim@4640
   209
    int index = SDL_GetTouchIndexId(id);
jim@4641
   210
    SDL_Touch *touch = SDL_GetTouch(id);
jim@4640
   211
    int i;
jim@4640
   212
    SDL_bool focus;
jim@4640
   213
jim@4640
   214
    if (!touch || (touch->focus == window)) {
jim@4640
   215
        return;
jim@4640
   216
    }
jim@4640
   217
jim@4640
   218
    /* See if the current window has lost focus */
jim@4640
   219
    if (touch->focus) {
jim@4640
   220
        focus = SDL_FALSE;
jim@4640
   221
        for (i = 0; i < SDL_num_touch; ++i) {
jim@4640
   222
            SDL_Touch *check;
jim@4640
   223
            if (i != index) {
jim@4641
   224
                check = SDL_touchPads[i];
jim@4640
   225
                if (check && check->focus == touch->focus) {
jim@4640
   226
                    focus = SDL_TRUE;
jim@4640
   227
                    break;
jim@4640
   228
                }
jim@4640
   229
            }
jim@4640
   230
        }
jim@4640
   231
        if (!focus) {
jim@4640
   232
            SDL_SendWindowEvent(touch->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
jim@4640
   233
        }
jim@4640
   234
    }
jim@4640
   235
jim@4640
   236
    touch->focus = window;
jim@4640
   237
jim@4640
   238
    if (touch->focus) {
jim@4640
   239
        focus = SDL_FALSE;
jim@4640
   240
        for (i = 0; i < SDL_num_touch; ++i) {
jim@4640
   241
            SDL_Touch *check;
jim@4640
   242
            if (i != index) {
jim@4641
   243
                check = SDL_touchPads[i];
jim@4640
   244
                if (check && check->focus == touch->focus) {
jim@4640
   245
                    focus = SDL_TRUE;
jim@4640
   246
                    break;
jim@4640
   247
                }
jim@4640
   248
            }
jim@4640
   249
        }
jim@4640
   250
        if (!focus) {
jim@4640
   251
            SDL_SendWindowEvent(touch->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
jim@4640
   252
        }
jim@4640
   253
    }
jim@4640
   254
}
jim@4640
   255
jim@4641
   256
int 
jimtla@4678
   257
SDL_AddFinger(SDL_Touch* touch,SDL_Finger *finger)
jim@4640
   258
{
jim@4641
   259
    int index;
jim@4641
   260
    SDL_Finger **fingers;
jim@4646
   261
    //printf("Adding Finger...\n");
jimtla@4678
   262
    if (SDL_GetFingerIndexId(touch,finger->id) != -1) {
jim@4641
   263
        SDL_SetError("Finger ID already in use");
slouken@4919
   264
        }
jim@4640
   265
jim@4641
   266
    /* Add the touch to the list of touch */
jim@4646
   267
    if(touch->num_fingers  >= touch->max_fingers){
slouken@4919
   268
                //printf("Making room for it!\n");
slouken@4919
   269
                fingers = (SDL_Finger **) SDL_realloc(touch->fingers,
slouken@4919
   270
                                                     (touch->num_fingers + 1) * sizeof(SDL_Finger *));
slouken@4919
   271
                touch->max_fingers = touch->num_fingers+1;
slouken@4919
   272
                if (!fingers) {
slouken@4919
   273
                        SDL_OutOfMemory();
slouken@4919
   274
                        return -1;
slouken@4919
   275
                } else {
slouken@4919
   276
                        touch->max_fingers = touch->num_fingers+1;
slouken@4919
   277
                        touch->fingers = fingers;
slouken@4919
   278
                }
slouken@4919
   279
        }
jim@4645
   280
jim@4646
   281
    index = touch->num_fingers;
jim@4646
   282
    //printf("Max_Fingers: %i Index: %i\n",touch->max_fingers,index);
jim@4641
   283
jim@4646
   284
    touch->fingers[index] = (SDL_Finger *) SDL_malloc(sizeof(SDL_Finger));
jim@4641
   285
    if (!touch->fingers[index]) {
jim@4641
   286
        SDL_OutOfMemory();
jim@4641
   287
        return -1;
jim@4641
   288
    }
jimtla@4678
   289
    *(touch->fingers[index]) = *finger;
jim@4646
   290
    touch->num_fingers++;
jim@4641
   291
jim@4641
   292
    return index;
jim@4640
   293
}
jim@4640
   294
jim@4640
   295
int
jimtla@4678
   296
SDL_DelFinger(SDL_Touch* touch,SDL_FingerID fingerid)
jim@4641
   297
{
jim@4642
   298
    int index = SDL_GetFingerIndexId(touch,fingerid);
jim@4641
   299
    SDL_Finger* finger = SDL_GetFinger(touch,fingerid);
jim@4641
   300
jim@4641
   301
    if (!finger) {
jimtla@4648
   302
        return -1;
jim@4641
   303
    }
jim@4641
   304
 
jim@4641
   305
jim@4641
   306
    SDL_free(finger);
jim@4641
   307
    touch->num_fingers--;
jim@4641
   308
    touch->fingers[index] = touch->fingers[touch->num_fingers];
jim@4655
   309
    return 0;
jim@4641
   310
}
jim@4641
   311
jim@4641
   312
jim@4641
   313
int
jimtla@4678
   314
SDL_SendFingerDown(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, 
slouken@4919
   315
                   float xin, float yin, float pressurein)
jim@4641
   316
{
jim@4643
   317
    int posted;
slouken@4919
   318
        Uint16 x;
slouken@4919
   319
        Uint16 y;
slouken@4919
   320
        Uint16 pressure;
slouken@4919
   321
        SDL_Finger *finger;
aschiffler@4865
   322
jim@4641
   323
    SDL_Touch* touch = SDL_GetTouch(id);
jim@4643
   324
jim@4674
   325
    if(!touch) {
jim@4674
   326
      return SDL_TouchNotFoundError(id);
jim@4674
   327
    }
jim@4683
   328
jim@4683
   329
    
jimtla@4678
   330
    //scale to Integer coordinates
aschiffler@4865
   331
    x = (Uint16)((xin+touch->x_min)*(touch->xres)/(touch->native_xres));
aschiffler@4865
   332
    y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres));
slouken@6299
   333
    pressure = (Uint16)((pressurein+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres));
jim@4683
   334
    
aschiffler@4865
   335
    finger = SDL_GetFinger(touch,fingerid);
jim@4641
   336
    if(down) {
slouken@4919
   337
        if(finger == NULL) {
slouken@4919
   338
            SDL_Finger nf;
slouken@4919
   339
            nf.id = fingerid;
slouken@4919
   340
            nf.x = x;
slouken@4919
   341
            nf.y = y;
slouken@4919
   342
            nf.pressure = pressure;
slouken@4919
   343
            nf.xdelta = 0;
slouken@4919
   344
            nf.ydelta = 0;
slouken@4919
   345
            nf.last_x = x;
slouken@4919
   346
            nf.last_y = y;
slouken@4919
   347
            nf.last_pressure = pressure;
slouken@4919
   348
            nf.down = SDL_FALSE;
slouken@4919
   349
            if(SDL_AddFinger(touch,&nf) < 0) return 0;
slouken@4919
   350
            finger = SDL_GetFinger(touch,fingerid);
slouken@4919
   351
        }
slouken@4919
   352
        else if(finger->down) return 0;
slouken@4919
   353
        if(xin < touch->x_min || yin < touch->y_min) return 0; //should defer if only a partial input
slouken@4919
   354
        posted = 0;
slouken@4919
   355
        if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
slouken@4919
   356
            SDL_Event event;
slouken@4919
   357
            event.tfinger.type = SDL_FINGERDOWN;
slouken@4919
   358
            event.tfinger.touchId = id;
slouken@4919
   359
            event.tfinger.x = x;
slouken@4919
   360
            event.tfinger.y = y;
slouken@6299
   361
            event.tfinger.dx = 0;
slouken@6299
   362
            event.tfinger.dy = 0;
slouken@4919
   363
            event.tfinger.pressure = pressure;
slouken@4919
   364
            event.tfinger.state = touch->buttonstate;
slouken@4919
   365
            event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
slouken@4919
   366
            event.tfinger.fingerId = fingerid;
slouken@4919
   367
            posted = (SDL_PushEvent(&event) > 0);
slouken@4919
   368
        }
slouken@4919
   369
        if(posted) finger->down = SDL_TRUE;
slouken@4919
   370
        return posted;
jim@4641
   371
    }
jim@4641
   372
    else {
slouken@4868
   373
        if(finger == NULL) {
slouken@4868
   374
            SDL_SetError("Finger not found.");
slouken@4868
   375
            return 0;
slouken@4868
   376
        }      
slouken@4919
   377
        posted = 0;
slouken@4919
   378
        if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
slouken@4919
   379
            SDL_Event event;
slouken@4919
   380
            event.tfinger.type = SDL_FINGERUP;
slouken@4919
   381
            event.tfinger.touchId =  id;
slouken@4919
   382
            event.tfinger.state = touch->buttonstate;
slouken@4919
   383
            event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
slouken@4919
   384
            event.tfinger.fingerId = fingerid;
slouken@4919
   385
            //I don't trust the coordinates passed on fingerUp
slouken@4919
   386
            event.tfinger.x = finger->x; 
slouken@4919
   387
            event.tfinger.y = finger->y;
slouken@4919
   388
            event.tfinger.dx = 0;
slouken@4919
   389
            event.tfinger.dy = 0;
slouken@6299
   390
            event.tfinger.pressure = pressure;
jim@4683
   391
slouken@4919
   392
            if(SDL_DelFinger(touch,fingerid) < 0) return 0;
slouken@4919
   393
            posted = (SDL_PushEvent(&event) > 0);
slouken@4919
   394
        }        
slouken@4919
   395
        return posted;
jim@4641
   396
    }
jim@4641
   397
}
jim@4641
   398
jim@4641
   399
int
jimtla@4678
   400
SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, int relative, 
slouken@4919
   401
                    float xin, float yin, float pressurein)
jim@4640
   402
{
slouken@5124
   403
    SDL_Touch *touch;
slouken@5124
   404
    SDL_Finger *finger;
jim@4640
   405
    int posted;
jim@4683
   406
    Sint16 xrel, yrel;
slouken@5124
   407
    Uint16 x;
slouken@5124
   408
    Uint16 y;
slouken@5124
   409
    Uint16 pressure;
jim@4655
   410
    
slouken@5124
   411
    touch = SDL_GetTouch(id);
jim@4674
   412
    if (!touch) {
jim@4674
   413
      return SDL_TouchNotFoundError(id);
jim@4674
   414
    }
jimtla@4678
   415
jimtla@4678
   416
    //scale to Integer coordinates
aschiffler@4865
   417
    x = (Uint16)((xin+touch->x_min)*(touch->xres)/(touch->native_xres));
aschiffler@4865
   418
    y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres));
slouken@6299
   419
    pressure = (Uint16)((pressurein+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres));
jim@4674
   420
    if(touch->flush_motion) {
slouken@4919
   421
        return 0;
jim@4640
   422
    }
jim@4654
   423
    
slouken@5124
   424
    finger = SDL_GetFinger(touch,fingerid);
jim@4655
   425
    if(finger == NULL || !finger->down) {
slouken@4919
   426
        return SDL_SendFingerDown(id,fingerid,SDL_TRUE,xin,yin,pressurein);        
jim@4654
   427
    } else {
slouken@4919
   428
        /* the relative motion is calculated regarding the last position */
slouken@4919
   429
        if (relative) {
slouken@4919
   430
            xrel = x;
slouken@4919
   431
            yrel = y;
slouken@4919
   432
            x = (finger->last_x + x);
slouken@4919
   433
            y = (finger->last_y + y);
slouken@4919
   434
        } else {
slouken@4919
   435
            if(xin < touch->x_min) x = finger->last_x; /*If movement is only in one axis,*/
slouken@4919
   436
            if(yin < touch->y_min) y = finger->last_y; /*The other is marked as -1*/
slouken@4919
   437
            if(pressurein < touch->pressure_min) pressure = finger->last_pressure;
slouken@4919
   438
            xrel = x - finger->last_x;
slouken@4919
   439
            yrel = y - finger->last_y;
slouken@4919
   440
            //printf("xrel,yrel (%i,%i)\n",(int)xrel,(int)yrel);
slouken@4919
   441
        }
slouken@4919
   442
        
slouken@4919
   443
        /* Drop events that don't change state */
slouken@4919
   444
        if (!xrel && !yrel) {
jim@4654
   445
#if 0
slouken@4919
   446
            printf("Touch event didn't change state - dropped!\n");
jim@4654
   447
#endif
slouken@4919
   448
            return 0;
slouken@4919
   449
        }
slouken@4919
   450
        
slouken@4919
   451
        /* Update internal touch coordinates */
slouken@4919
   452
        
slouken@4919
   453
        finger->x = x;
slouken@4919
   454
        finger->y = y;
slouken@4919
   455
        
slouken@4919
   456
        /*Should scale to window? Normalize? Maintain Aspect?*/
slouken@4919
   457
        //SDL_GetWindowSize(touch->focus, &x_max, &y_max);
slouken@4919
   458
        
slouken@4919
   459
        /* make sure that the pointers find themselves inside the windows */
slouken@4919
   460
        /* only check if touch->xmax is set ! */
slouken@4919
   461
        /*
slouken@4919
   462
          if (x_max && touch->x > x_max) {
slouken@4919
   463
          touch->x = x_max;
slouken@4919
   464
          } else if (touch->x < 0) {
slouken@4919
   465
          touch->x = 0;
slouken@4919
   466
          }
slouken@4919
   467
          
slouken@4919
   468
          if (y_max && touch->y > y_max) {
slouken@4919
   469
          touch->y = y_max;
slouken@4919
   470
          } else if (touch->y < 0) {
slouken@4919
   471
          touch->y = 0;
slouken@4919
   472
          }
slouken@4919
   473
        */
slouken@4919
   474
        finger->xdelta = xrel;
slouken@4919
   475
        finger->ydelta = yrel;
slouken@4919
   476
        finger->pressure = pressure;
slouken@4919
   477
        
slouken@4919
   478
        
slouken@4919
   479
        
slouken@4919
   480
        /* Post the event, if desired */
slouken@4919
   481
        posted = 0;
slouken@4919
   482
        if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
slouken@4919
   483
            SDL_Event event;
slouken@4919
   484
            event.tfinger.type = SDL_FINGERMOTION;
slouken@4919
   485
            event.tfinger.touchId = id;
slouken@4919
   486
            event.tfinger.fingerId = fingerid;
slouken@4919
   487
            event.tfinger.x = x;
slouken@4919
   488
            event.tfinger.y = y;
slouken@4919
   489
            event.tfinger.dx = xrel;
slouken@4919
   490
            event.tfinger.dy = yrel;            
slouken@4919
   491
                
slouken@4919
   492
            event.tfinger.pressure = pressure;
slouken@4919
   493
            event.tfinger.state = touch->buttonstate;
slouken@4919
   494
            event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
slouken@4919
   495
            posted = (SDL_PushEvent(&event) > 0);
slouken@4919
   496
        }
slouken@4919
   497
        finger->last_x = finger->x;
slouken@4919
   498
        finger->last_y = finger->y;
slouken@4919
   499
        finger->last_pressure = finger->pressure;
slouken@4919
   500
        return posted;
jim@4655
   501
    }
jim@4640
   502
}
slouken@5124
   503
jim@4640
   504
int
jimtla@4678
   505
SDL_SendTouchButton(SDL_TouchID id, Uint8 state, Uint8 button)
jim@4640
   506
{
slouken@5124
   507
    SDL_Touch *touch;
jim@4640
   508
    int posted;
jim@4640
   509
    Uint32 type;
jim@4640
   510
jim@4674
   511
    
slouken@5124
   512
    touch = SDL_GetTouch(id);
jim@4640
   513
    if (!touch) {
jim@4674
   514
      return SDL_TouchNotFoundError(id);
jim@4640
   515
    }
jim@4640
   516
jim@4640
   517
    /* Figure out which event to perform */
jim@4640
   518
    switch (state) {
jim@4640
   519
    case SDL_PRESSED:
jim@4640
   520
        if (touch->buttonstate & SDL_BUTTON(button)) {
jim@4640
   521
            /* Ignore this event, no state change */
jim@4640
   522
            return 0;
jim@4640
   523
        }
jim@4640
   524
        type = SDL_TOUCHBUTTONDOWN;
jim@4640
   525
        touch->buttonstate |= SDL_BUTTON(button);
jim@4640
   526
        break;
jim@4640
   527
    case SDL_RELEASED:
jim@4640
   528
        if (!(touch->buttonstate & SDL_BUTTON(button))) {
jim@4640
   529
            /* Ignore this event, no state change */
jim@4640
   530
            return 0;
jim@4640
   531
        }
jim@4640
   532
        type = SDL_TOUCHBUTTONUP;
jim@4640
   533
        touch->buttonstate &= ~SDL_BUTTON(button);
jim@4640
   534
        break;
jim@4640
   535
    default:
jim@4640
   536
        /* Invalid state -- bail */
jim@4640
   537
        return 0;
jim@4640
   538
    }
jim@4640
   539
jim@4640
   540
    /* Post the event, if desired */
jim@4640
   541
    posted = 0;
jim@4640
   542
    if (SDL_GetEventState(type) == SDL_ENABLE) {
jim@4640
   543
        SDL_Event event;
jim@4640
   544
        event.type = type;
jimtla@4676
   545
        event.tbutton.touchId = touch->id;
jim@4641
   546
        event.tbutton.state = state;
jim@4641
   547
        event.tbutton.button = button;
jim@4641
   548
        event.tbutton.windowID = touch->focus ? touch->focus->id : 0;
jim@4640
   549
        posted = (SDL_PushEvent(&event) > 0);
jim@4640
   550
    }
jim@4640
   551
    return posted;
jim@4640
   552
}
jim@4640
   553
jim@4641
   554
char *
jimtla@4678
   555
SDL_GetTouchName(SDL_TouchID id)
jim@4640
   556
{
jim@4641
   557
    SDL_Touch *touch = SDL_GetTouch(id);
jim@4640
   558
    if (!touch) {
jim@4640
   559
        return NULL;
jim@4640
   560
    }
jim@4640
   561
    return touch->name;
jim@4640
   562
}
jim@4640
   563
jimtla@4678
   564
int SDL_TouchNotFoundError(SDL_TouchID id) {
slouken@4868
   565
  //int i;
slouken@4868
   566
  SDL_SetError("ERROR: Cannot send touch on non-existent device with id: %li make sure SDL_AddTouch has been called\n",id);
slouken@4868
   567
#if 0
jim@4674
   568
  printf("ERROR: There are %i touches installed with Id's:\n",SDL_num_touch);
jim@4674
   569
  for(i=0;i < SDL_num_touch;i++) {
jimtla@4676
   570
    printf("ERROR: %li\n",SDL_touchPads[i]->id);
jim@4674
   571
  }
slouken@4868
   572
#endif
jim@4674
   573
  return 0;
jim@4674
   574
}
jim@4640
   575
/* vi: set ts=4 sw=4 expandtab: */