src/events/SDL_mouse.c
author Szymon Wilczek
Tue, 05 Aug 2008 14:10:11 +0000
branchgsoc2008_manymouse
changeset 3774 8b5b67000dc0
parent 3771 8cc36a399a12
child 3776 a9c2a7071874
permissions -rw-r--r--
Cursor support added
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* General mouse handling code for SDL */
slouken@0
    25
slouken@0
    26
#include "SDL_events.h"
slouken@0
    27
#include "SDL_events_c.h"
slouken@1895
    28
#include "default_cursor.h"
slouken@0
    29
slouken@0
    30
kazeuser@3767
    31
static int SDL_num_mice=0;
kazeuser@3767
    32
static int SDL_current_mouse=-1;
kazeuser@3767
    33
static SDL_Mouse **SDL_mice=NULL;
kazeuser@3767
    34
static int *SDL_IdIndex=NULL;
kazeuser@3767
    35
static int SDL_highestId=-1;
kazeuser@3771
    36
static int last_x, last_y;/*the last reported x and y coordinates by the system cursor*/
kazeuser@3771
    37
int x_max, y_max; /*current window width and height*/
slouken@0
    38
/* Public functions */
slouken@1895
    39
int
slouken@1895
    40
SDL_MouseInit(void)
slouken@1895
    41
{
slouken@1895
    42
    return (0);
slouken@1895
    43
}
slouken@1895
    44
slouken@1895
    45
SDL_Mouse *
slouken@1895
    46
SDL_GetMouse(int index)
slouken@1895
    47
{
slouken@1895
    48
    if (index < 0 || index >= SDL_num_mice) {
slouken@1895
    49
        return NULL;
slouken@1895
    50
    }
slouken@1895
    51
    return SDL_mice[index];
slouken@1895
    52
}
slouken@1895
    53
slouken@1895
    54
int
kazeuser@3774
    55
SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name,int pressure_max,\
kazeuser@3774
    56
int pressure_min, int ends)
slouken@0
    57
{
slouken@1895
    58
    SDL_Mouse **mice;
slouken@1895
    59
    int selected_mouse;
kazeuser@3769
    60
	int length;
kazeuser@3769
    61
slouken@1895
    62
    /* Add the mouse to the list of mice */
slouken@1895
    63
    if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
slouken@1895
    64
        mice =
slouken@1895
    65
            (SDL_Mouse **) SDL_realloc(SDL_mice,
slouken@1895
    66
                                       (SDL_num_mice + 1) * sizeof(*mice));
slouken@1895
    67
        if (!mice) {
slouken@1895
    68
            SDL_OutOfMemory();
slouken@1895
    69
            return -1;
slouken@1895
    70
        }
slouken@0
    71
slouken@1895
    72
        SDL_mice = mice;
slouken@1895
    73
        index = SDL_num_mice++;
slouken@1895
    74
    }
slouken@1895
    75
    SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
slouken@1895
    76
    if (!SDL_mice[index]) {
slouken@1895
    77
        SDL_OutOfMemory();
slouken@1895
    78
        return -1;
slouken@1895
    79
    }
slouken@1895
    80
    *SDL_mice[index] = *mouse;
kazeuser@3771
    81
kazeuser@3771
    82
	/*we're setting the mouse properties*/
kazeuser@3769
    83
	length=0;
kazeuser@3769
    84
	length=SDL_strlen(name);
kazeuser@3769
    85
    SDL_mice[index]->name=SDL_malloc((length+1)*sizeof(char));
kazeuser@3769
    86
    SDL_strlcpy(SDL_mice[index]->name,name,length);
kazeuser@3766
    87
    SDL_mice[index]->pressure_max=pressure_max;
kazeuser@3766
    88
    SDL_mice[index]->pressure_min=pressure_min;
slouken@1895
    89
    SDL_mice[index]->cursor_shown = SDL_TRUE;
slouken@1895
    90
    selected_mouse = SDL_SelectMouse(index);
slouken@1895
    91
    SDL_mice[index]->cur_cursor = NULL;
slouken@1895
    92
    SDL_mice[index]->def_cursor =
slouken@1895
    93
        SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
slouken@1895
    94
                         DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
slouken@1895
    95
    SDL_SetCursor(SDL_mice[index]->def_cursor);
kazeuser@3771
    96
	/*we're assuming that all mouses are in the computer sensing zone*/
kazeuser@3764
    97
    SDL_mice[index]->proximity=SDL_TRUE;
kazeuser@3771
    98
	/*we're assuming that all mouses are working in the absolute position mode
kazeuser@3771
    99
	thanx to that, the users that don't want to use many mouses don't have to
kazeuser@3771
   100
	worry about anything*/
kazeuser@3764
   101
    SDL_mice[index]->relative_mode=SDL_FALSE;
kazeuser@3774
   102
    SDL_mice[index]->current_end=0;
kazeuser@3774
   103
    SDL_mice[index]->total_ends=ends;
slouken@1895
   104
    SDL_SelectMouse(selected_mouse);
slouken@1895
   105
slouken@1895
   106
    return index;
slouken@1123
   107
}
slouken@0
   108
slouken@1895
   109
void
slouken@1895
   110
SDL_DelMouse(int index)
slouken@1895
   111
{
slouken@1895
   112
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   113
slouken@1895
   114
    if (!mouse) {
slouken@1895
   115
        return;
slouken@1895
   116
    }
slouken@1895
   117
slouken@1895
   118
    mouse->def_cursor = NULL;
kazeuser@3760
   119
    SDL_free(mouse->name);
slouken@1895
   120
    while (mouse->cursors) {
slouken@1895
   121
        SDL_FreeCursor(mouse->cursors);
slouken@1895
   122
    }
slouken@1895
   123
slouken@1895
   124
    if (mouse->FreeMouse) {
slouken@1895
   125
        mouse->FreeMouse(mouse);
slouken@1895
   126
    }
slouken@1895
   127
    SDL_free(mouse);
slouken@1895
   128
slouken@1895
   129
    SDL_mice[index] = NULL;
slouken@1895
   130
}
slouken@1895
   131
slouken@1895
   132
void
slouken@1895
   133
SDL_ResetMouse(int index)
slouken@1895
   134
{
slouken@1895
   135
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   136
slouken@1895
   137
    if (!mouse) {
slouken@1895
   138
        return;
slouken@1895
   139
    }
slouken@1895
   140
slouken@1895
   141
    /* FIXME */
slouken@1895
   142
}
slouken@1895
   143
slouken@1895
   144
void
slouken@1895
   145
SDL_MouseQuit(void)
slouken@460
   146
{
slouken@1895
   147
    int i;
slouken@1895
   148
slouken@1895
   149
    for (i = 0; i < SDL_num_mice; ++i) {
slouken@1895
   150
        SDL_DelMouse(i);
slouken@1895
   151
    }
slouken@1895
   152
    SDL_num_mice = 0;
slouken@1895
   153
    SDL_current_mouse = 0;
slouken@1895
   154
slouken@1895
   155
    if (SDL_mice) {
slouken@1895
   156
        SDL_free(SDL_mice);
slouken@1895
   157
        SDL_mice = NULL;
slouken@1895
   158
    }
slouken@1895
   159
}
slouken@1895
   160
slouken@1895
   161
int
slouken@1895
   162
SDL_GetNumMice(void)
slouken@1895
   163
{
slouken@1895
   164
    return SDL_num_mice;
slouken@1895
   165
}
slouken@1895
   166
slouken@1895
   167
int
slouken@1895
   168
SDL_SelectMouse(int index)
slouken@1895
   169
{
slouken@1895
   170
    if (index >= 0 && index < SDL_num_mice) {
slouken@1895
   171
        SDL_current_mouse = index;
slouken@1895
   172
    }
slouken@1895
   173
    return SDL_current_mouse;
slouken@1895
   174
}
slouken@1895
   175
slouken@1895
   176
SDL_WindowID
slouken@1895
   177
SDL_GetMouseFocusWindow()
slouken@1895
   178
{
slouken@1895
   179
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   180
slouken@1895
   181
    if (!mouse) {
slouken@1895
   182
        return 0;
slouken@1895
   183
    }
slouken@1895
   184
    return mouse->focus;
slouken@460
   185
}
slouken@460
   186
icculus@2049
   187
static int SDLCALL
slouken@1895
   188
FlushMouseMotion(void *param, SDL_Event * event)
slouken@1895
   189
{
slouken@1895
   190
    if (event->type == SDL_MOUSEMOTION
slouken@1895
   191
        && event->motion.which == (Uint8) SDL_current_mouse) {
slouken@1895
   192
        return 0;
slouken@1895
   193
    } else {
slouken@1895
   194
        return 1;
slouken@1895
   195
    }
slouken@1895
   196
}
slouken@1895
   197
slouken@1895
   198
int
kazeuser@3764
   199
SDL_SetRelativeMouseMode(SDL_bool enabled, int index)
slouken@0
   200
{
kazeuser@3764
   201
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   202
slouken@1895
   203
    if (!mouse) {
slouken@1895
   204
        return -1;
slouken@1895
   205
    }
slouken@1895
   206
slouken@1895
   207
    /* Flush pending mouse motion */
slouken@1895
   208
    mouse->flush_motion = SDL_TRUE;
slouken@1895
   209
    SDL_PumpEvents();
slouken@1895
   210
    mouse->flush_motion = SDL_FALSE;
slouken@1895
   211
    SDL_FilterEvents(FlushMouseMotion, mouse);
slouken@1895
   212
slouken@1895
   213
    /* Set the relative mode */
slouken@1895
   214
    mouse->relative_mode = enabled;
slouken@1895
   215
slouken@1895
   216
    /* Update cursor visibility */
slouken@1895
   217
    SDL_SetCursor(NULL);
slouken@1895
   218
slouken@1895
   219
    if (!enabled) {
slouken@1895
   220
        /* Restore the expected mouse position */
slouken@1895
   221
        SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
slouken@1895
   222
    }
slouken@1895
   223
    return 0;
slouken@1895
   224
}
slouken@1895
   225
slouken@1895
   226
SDL_bool
slouken@1895
   227
SDL_GetRelativeMouseMode()
slouken@1895
   228
{
slouken@1895
   229
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   230
slouken@1895
   231
    if (!mouse) {
slouken@1895
   232
        return SDL_FALSE;
slouken@1895
   233
    }
slouken@1895
   234
    return mouse->relative_mode;
slouken@1895
   235
}
slouken@1895
   236
slouken@1895
   237
Uint8
slouken@1895
   238
SDL_GetMouseState(int *x, int *y)
slouken@1895
   239
{
slouken@1895
   240
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   241
slouken@1895
   242
    if (!mouse) {
slouken@1895
   243
        if (x) {
slouken@1895
   244
            *x = 0;
slouken@1895
   245
        }
slouken@1895
   246
        if (y) {
slouken@1895
   247
            *y = 0;
slouken@1895
   248
        }
slouken@1895
   249
        return 0;
slouken@1895
   250
    }
slouken@1895
   251
slouken@1895
   252
    if (x) {
slouken@1895
   253
        *x = mouse->x;
slouken@1895
   254
    }
slouken@1895
   255
    if (y) {
slouken@1895
   256
        *y = mouse->y;
slouken@1895
   257
    }
slouken@1895
   258
    return mouse->buttonstate;
slouken@0
   259
}
slouken@0
   260
slouken@1895
   261
Uint8
slouken@1895
   262
SDL_GetRelativeMouseState(int *x, int *y)
slouken@0
   263
{
slouken@1895
   264
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   265
slouken@1895
   266
    if (!mouse) {
slouken@1895
   267
        if (x) {
slouken@1895
   268
            *x = 0;
slouken@1895
   269
        }
slouken@1895
   270
        if (y) {
slouken@1895
   271
            *y = 0;
slouken@1895
   272
        }
slouken@1895
   273
        return 0;
slouken@1895
   274
    }
slouken@1895
   275
slouken@1895
   276
    if (x) {
slouken@1895
   277
        *x = mouse->xdelta;
slouken@1895
   278
    }
slouken@1895
   279
    if (y) {
slouken@1895
   280
        *y = mouse->ydelta;
slouken@1895
   281
    }
slouken@1895
   282
    mouse->xdelta = 0;
slouken@1895
   283
    mouse->ydelta = 0;
slouken@1895
   284
    return mouse->buttonstate;
slouken@0
   285
}
slouken@0
   286
slouken@1895
   287
void
kazeuser@3760
   288
SDL_SetMouseFocus(int id, SDL_WindowID windowID)
slouken@0
   289
{
kazeuser@3760
   290
    int index = SDL_GetIndexById(id);
slouken@1895
   291
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   292
    int i;
slouken@1895
   293
    SDL_bool focus;
slouken@1895
   294
slouken@1895
   295
    if (!mouse || (mouse->focus == windowID)) {
slouken@1895
   296
        return;
slouken@1895
   297
    }
slouken@1895
   298
slouken@1895
   299
    /* See if the current window has lost focus */
slouken@1895
   300
    if (mouse->focus) {
slouken@1895
   301
        focus = SDL_FALSE;
slouken@1895
   302
        for (i = 0; i < SDL_num_mice; ++i) {
slouken@1895
   303
            SDL_Mouse *check;
slouken@1895
   304
            if (i != index) {
slouken@1895
   305
                check = SDL_GetMouse(i);
slouken@1895
   306
                if (check && check->focus == mouse->focus) {
slouken@1895
   307
                    focus = SDL_TRUE;
slouken@1895
   308
                    break;
slouken@1895
   309
                }
slouken@1895
   310
            }
slouken@1895
   311
        }
slouken@1895
   312
        if (!focus) {
slouken@1895
   313
            SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
slouken@1895
   314
        }
slouken@1895
   315
    }
slouken@1895
   316
slouken@1895
   317
    mouse->focus = windowID;
slouken@1895
   318
slouken@1895
   319
    if (mouse->focus) {
slouken@1895
   320
        focus = SDL_FALSE;
slouken@1895
   321
        for (i = 0; i < SDL_num_mice; ++i) {
slouken@1895
   322
            SDL_Mouse *check;
slouken@1895
   323
            if (i != index) {
slouken@1895
   324
                check = SDL_GetMouse(i);
slouken@1895
   325
                if (check && check->focus == mouse->focus) {
slouken@1895
   326
                    focus = SDL_TRUE;
slouken@1895
   327
                    break;
slouken@1895
   328
                }
slouken@1895
   329
            }
slouken@1895
   330
        }
slouken@1895
   331
        if (!focus) {
slouken@1895
   332
            SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
slouken@1895
   333
        }
slouken@1895
   334
    }
slouken@0
   335
}
slouken@0
   336
slouken@1895
   337
int
kazeuser@3763
   338
SDL_SendProximity(int id, int x, int y, int type)
kazeuser@3763
   339
{
kazeuser@3763
   340
    int index=SDL_GetIndexById(id);
kazeuser@3763
   341
    int posted=0;
kazeuser@3770
   342
	last_x=x;
kazeuser@3770
   343
	last_y=y;
kazeuser@3763
   344
    if(SDL_ProcessEvents[type]==SDL_ENABLE)
kazeuser@3763
   345
    {
kazeuser@3763
   346
        SDL_Event event;
kazeuser@3764
   347
        event.proximity.which=(Uint8)index;
kazeuser@3763
   348
        event.proximity.x=x;
kazeuser@3763
   349
        event.proximity.y=y;
kazeuser@3763
   350
        event.type=type;
kazeuser@3763
   351
        event.proximity.type=type;
kazeuser@3763
   352
        posted = (SDL_PushEvent(&event) > 0);
kazeuser@3764
   353
        if(type==SDL_PROXIMITYIN)
kazeuser@3764
   354
        {
kazeuser@3764
   355
            SDL_mice[index]->proximity=SDL_TRUE;
kazeuser@3764
   356
        }
kazeuser@3764
   357
        else
kazeuser@3764
   358
        {
kazeuser@3764
   359
            SDL_mice[index]->proximity=SDL_FALSE;
kazeuser@3764
   360
        }
kazeuser@3763
   361
    }
kazeuser@3763
   362
    return posted;
kazeuser@3763
   363
}
kazeuser@3763
   364
kazeuser@3763
   365
int
kazeuser@3760
   366
SDL_SendMouseMotion(int id, int relative, int x, int y,int z)
slouken@0
   367
{
kazeuser@3760
   368
    int index=SDL_GetIndexById(id);
slouken@1895
   369
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   370
    int posted;
slouken@1895
   371
    int xrel;
slouken@1895
   372
    int yrel;
kazeuser@3771
   373
	/*while using the relative mode and many windows, we have to be sure,
kazeuser@3771
   374
	that the pointers find themselves inside the windows*/
kazeuser@3769
   375
	if(x>x_max)
kazeuser@3769
   376
	{
kazeuser@3769
   377
		x=x_max;
kazeuser@3769
   378
	}
kazeuser@3769
   379
	if(y>y_max)
kazeuser@3769
   380
	{
kazeuser@3769
   381
		y=y_max;
kazeuser@3769
   382
	}
kazeuser@3771
   383
slouken@1895
   384
    if (!mouse || mouse->flush_motion) {
slouken@1895
   385
        return 0;
slouken@1895
   386
    }
kazeuser@3771
   387
kazeuser@3771
   388
	/*if the mouse is out of proximity we don't to want to have any motion from it*/
kazeuser@3764
   389
    if(mouse->proximity==SDL_FALSE)
kazeuser@3764
   390
    {
kazeuser@3764
   391
        last_x=x;
kazeuser@3764
   392
        last_y=y;
kazeuser@3764
   393
        return 0;
kazeuser@3764
   394
    }
kazeuser@3771
   395
kazeuser@3771
   396
	/*the relative motion is calculated regarding the system cursor last position*/
kazeuser@3771
   397
kazeuser@3771
   398
    xrel = x - last_x;
kazeuser@3771
   399
    yrel = y - last_y;
slouken@0
   400
slouken@1895
   401
    /* Drop events that don't change state */
slouken@1895
   402
    if (!xrel && !yrel) {
slouken@1895
   403
#if 0
slouken@1895
   404
        printf("Mouse event didn't change state - dropped!\n");
slouken@1895
   405
#endif
slouken@1895
   406
        return 0;
slouken@1895
   407
    }
slouken@0
   408
kazeuser@3771
   409
    /* Update internal mouse coordinates */
kazeuser@3764
   410
    if (mouse->relative_mode==SDL_FALSE) {
slouken@1895
   411
        mouse->x = x;
slouken@1895
   412
        mouse->y = y;
slouken@1895
   413
    }
kazeuser@3764
   414
    else
kazeuser@3764
   415
    {
kazeuser@3764
   416
        if(mouse->x+xrel>x_max)
kazeuser@3764
   417
        {
kazeuser@3764
   418
            mouse->x=x_max;
kazeuser@3764
   419
        }
kazeuser@3764
   420
        else if(mouse->x+xrel<0)
kazeuser@3764
   421
        {
kazeuser@3764
   422
            mouse->x=0;
kazeuser@3764
   423
        }
kazeuser@3764
   424
        else
kazeuser@3764
   425
        {
kazeuser@3764
   426
            mouse->x+=xrel;
kazeuser@3764
   427
        }
kazeuser@3764
   428
        if(mouse->y+yrel>y_max)
kazeuser@3764
   429
        {
kazeuser@3764
   430
            mouse->y=y_max;
kazeuser@3764
   431
        }
kazeuser@3764
   432
        else if(mouse->y+yrel<0)
kazeuser@3764
   433
        {
kazeuser@3764
   434
            mouse->y=0;
kazeuser@3764
   435
        }
kazeuser@3764
   436
        else
kazeuser@3764
   437
        {
kazeuser@3764
   438
            mouse->y+=yrel;
kazeuser@3764
   439
        }
kazeuser@3764
   440
    }
slouken@1895
   441
    mouse->xdelta += xrel;
slouken@1895
   442
    mouse->ydelta += yrel;
kazeuser@3765
   443
    mouse->pressure=z;
slouken@1895
   444
slouken@1895
   445
    /* Move the mouse cursor, if needed */
slouken@1895
   446
    if (mouse->cursor_shown && !mouse->relative_mode &&
slouken@1895
   447
        mouse->MoveCursor && mouse->cur_cursor) {
slouken@1895
   448
        mouse->MoveCursor(mouse->cur_cursor);
slouken@1895
   449
    }
slouken@0
   450
slouken@1895
   451
    /* Post the event, if desired */
slouken@1895
   452
    posted = 0;
kazeuser@3764
   453
    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE && SDL_mice[index]->proximity==SDL_TRUE) {
slouken@1895
   454
        SDL_Event event;
slouken@1895
   455
        event.motion.type = SDL_MOUSEMOTION;
kazeuser@3769
   456
		event.motion.which = (Uint8) index;
slouken@1895
   457
        event.motion.state = mouse->buttonstate;
slouken@1895
   458
        event.motion.x = mouse->x;
slouken@1895
   459
        event.motion.y = mouse->y;
kazeuser@3765
   460
        event.motion.pressure= mouse->pressure;
slouken@1895
   461
        event.motion.xrel = xrel;
slouken@1895
   462
        event.motion.yrel = yrel;
slouken@1895
   463
        event.motion.windowID = mouse->focus;
kazeuser@3766
   464
        event.motion.pressure_max=mouse->pressure_max;
kazeuser@3766
   465
        event.motion.pressure_min=mouse->pressure_min;
kazeuser@3774
   466
		event.motion.cursor=SDL_mice[index]->current_end;
slouken@1895
   467
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   468
    }
kazeuser@3764
   469
    last_x=x;
kazeuser@3764
   470
    last_y=y;
slouken@1895
   471
    return posted;
slouken@1895
   472
}
slouken@1895
   473
slouken@1895
   474
int
kazeuser@3760
   475
SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
slouken@1895
   476
{
kazeuser@3760
   477
    int index=SDL_GetIndexById(id);
slouken@1895
   478
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   479
    int posted;
slouken@1895
   480
    Uint8 type;
slouken@1895
   481
slouken@1895
   482
    if (!mouse) {
slouken@1895
   483
        return 0;
slouken@1895
   484
    }
slouken@0
   485
slouken@1895
   486
    /* Figure out which event to perform */
slouken@1895
   487
    switch (state) {
slouken@1895
   488
    case SDL_PRESSED:
slouken@1895
   489
        if (mouse->buttonstate & SDL_BUTTON(button)) {
slouken@1895
   490
            /* Ignore this event, no state change */
slouken@1895
   491
            return 0;
slouken@1895
   492
        }
slouken@1895
   493
        type = SDL_MOUSEBUTTONDOWN;
slouken@1895
   494
        mouse->buttonstate |= SDL_BUTTON(button);
slouken@1895
   495
        break;
slouken@1895
   496
    case SDL_RELEASED:
kazeuser@3760
   497
        //if (!(mouse->buttonstate & SDL_BUTTON(button))) {
kazeuser@3760
   498
        //    /* Ignore this event, no state change */
kazeuser@3760
   499
        //    return 0;
kazeuser@3760
   500
        //}*/
slouken@1895
   501
        type = SDL_MOUSEBUTTONUP;
slouken@1895
   502
        mouse->buttonstate &= ~SDL_BUTTON(button);
slouken@1895
   503
        break;
slouken@1895
   504
    default:
slouken@1895
   505
        /* Invalid state -- bail */
slouken@1895
   506
        return 0;
slouken@1895
   507
    }
slouken@0
   508
slouken@1895
   509
    /* Post the event, if desired */
slouken@1895
   510
    posted = 0;
slouken@1895
   511
    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
slouken@1895
   512
        SDL_Event event;
slouken@1895
   513
        event.type = type;
slouken@1895
   514
        event.button.which = (Uint8) index;
slouken@1895
   515
        event.button.state = state;
slouken@1895
   516
        event.button.button = button;
slouken@1895
   517
        event.button.x = mouse->x;
slouken@1895
   518
        event.button.y = mouse->y;
slouken@1895
   519
        event.button.windowID = mouse->focus;
slouken@1895
   520
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   521
    }
slouken@1895
   522
    return posted;
slouken@1895
   523
}
slouken@1283
   524
slouken@1895
   525
int
slouken@2152
   526
SDL_SendMouseWheel(int index, int x, int y)
slouken@1895
   527
{
slouken@1895
   528
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   529
    int posted;
slouken@1895
   530
slouken@2152
   531
    if (!mouse || (!x && !y)) {
slouken@1895
   532
        return 0;
slouken@1895
   533
    }
slouken@0
   534
slouken@1895
   535
    /* Post the event, if desired */
slouken@1895
   536
    posted = 0;
slouken@1895
   537
    if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
slouken@1895
   538
        SDL_Event event;
slouken@1895
   539
        event.type = SDL_MOUSEWHEEL;
slouken@1895
   540
        event.wheel.which = (Uint8) index;
slouken@2152
   541
        event.wheel.x = x;
slouken@2152
   542
        event.wheel.y = y;
slouken@1895
   543
        event.wheel.windowID = mouse->focus;
slouken@1895
   544
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   545
    }
slouken@1895
   546
    return posted;
slouken@1895
   547
}
slouken@1895
   548
slouken@1895
   549
void
slouken@1895
   550
SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
slouken@1895
   551
{
slouken@1895
   552
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   553
slouken@1895
   554
    if (!mouse) {
slouken@1895
   555
        return;
slouken@1895
   556
    }
slouken@1895
   557
slouken@1895
   558
    if (mouse->WarpMouse) {
slouken@1895
   559
        mouse->WarpMouse(mouse, windowID, x, y);
slouken@1895
   560
    } else {
slouken@1895
   561
        SDL_SetMouseFocus(SDL_current_mouse, windowID);
kazeuser@3760
   562
        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y,0);
slouken@1895
   563
    }
slouken@0
   564
}
slouken@0
   565
slouken@1895
   566
SDL_Cursor *
slouken@1895
   567
SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
slouken@1895
   568
                 int w, int h, int hot_x, int hot_y)
slouken@0
   569
{
slouken@1895
   570
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   571
    SDL_Surface *surface;
slouken@1895
   572
    SDL_Cursor *cursor;
slouken@1895
   573
    int x, y;
slouken@1895
   574
    Uint32 *pixel;
slouken@1895
   575
    Uint8 datab, maskb;
slouken@1895
   576
    const Uint32 black = 0xFF000000;
slouken@1895
   577
    const Uint32 white = 0xFFFFFFFF;
slouken@1895
   578
    const Uint32 transparent = 0x00000000;
slouken@0
   579
slouken@1895
   580
    if (!mouse) {
slouken@1895
   581
        SDL_SetError("No mice are initialized");
slouken@1895
   582
        return NULL;
slouken@1895
   583
    }
slouken@0
   584
slouken@1895
   585
    if (!mouse->CreateCursor) {
slouken@1895
   586
        SDL_SetError("Current mouse doesn't have cursor support");
slouken@1895
   587
        return NULL;
slouken@1895
   588
    }
slouken@1895
   589
slouken@1895
   590
    /* Sanity check the hot spot */
slouken@1895
   591
    if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
slouken@1895
   592
        SDL_SetError("Cursor hot spot doesn't lie within cursor");
slouken@1895
   593
        return NULL;
slouken@1895
   594
    }
slouken@1895
   595
slouken@1895
   596
    /* Make sure the width is a multiple of 8 */
slouken@1895
   597
    w = ((w + 7) & ~7);
slouken@0
   598
kazeuser@3769
   599
    /* Create the surface from a bitmap*/
slouken@1895
   600
    surface =
slouken@1895
   601
        SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
slouken@1895
   602
                             0xFF000000);
slouken@1895
   603
    if (!surface) {
slouken@1895
   604
        return NULL;
slouken@1895
   605
    }
slouken@1895
   606
    for (y = 0; y < h; ++y) {
slouken@1895
   607
        pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
slouken@1895
   608
        for (x = 0; x < w; ++x) {
slouken@1895
   609
            if ((x % 8) == 0) {
slouken@1895
   610
                datab = *data++;
slouken@1895
   611
                maskb = *mask++;
slouken@1895
   612
            }
slouken@1895
   613
            if (maskb & 0x80) {
slouken@1895
   614
                *pixel++ = (datab & 0x80) ? black : white;
slouken@1895
   615
            } else {
slouken@1895
   616
                *pixel++ = (datab & 0x80) ? black : transparent;
slouken@1895
   617
            }
slouken@1895
   618
            datab <<= 1;
slouken@1895
   619
            maskb <<= 1;
slouken@1895
   620
        }
slouken@1895
   621
    }
slouken@0
   622
slouken@1895
   623
    cursor = mouse->CreateCursor(surface, hot_x, hot_y);
slouken@1895
   624
    if (cursor) {
slouken@1895
   625
        cursor->mouse = mouse;
slouken@1895
   626
        cursor->next = mouse->cursors;
slouken@1895
   627
        mouse->cursors = cursor;
slouken@1895
   628
    }
slouken@0
   629
slouken@1895
   630
    SDL_FreeSurface(surface);
slouken@1895
   631
slouken@1895
   632
    return cursor;
slouken@0
   633
}
slouken@0
   634
slouken@1895
   635
/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
slouken@1895
   636
   if this is desired for any reason.  This is used when setting
slouken@1895
   637
   the video mode and when the SDL window gains the mouse focus.
slouken@1895
   638
 */
slouken@1895
   639
void
slouken@1895
   640
SDL_SetCursor(SDL_Cursor * cursor)
slouken@1895
   641
{
slouken@1895
   642
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   643
slouken@1895
   644
    if (!mouse) {
slouken@1895
   645
        SDL_SetError("No mice are initialized");
slouken@1895
   646
        return;
slouken@1895
   647
    }
slouken@1895
   648
slouken@1895
   649
    /* Set the new cursor */
slouken@1895
   650
    if (cursor) {
slouken@1895
   651
        /* Make sure the cursor is still valid for this mouse */
slouken@1895
   652
        SDL_Cursor *found;
slouken@1895
   653
        for (found = mouse->cursors; found; found = found->next) {
slouken@1895
   654
            if (found == cursor) {
slouken@1895
   655
                break;
slouken@1895
   656
            }
slouken@1895
   657
        }
slouken@1895
   658
        if (!found) {
slouken@1895
   659
            SDL_SetError("Cursor not associated with the current mouse");
slouken@1895
   660
            return;
slouken@1895
   661
        }
slouken@1895
   662
        mouse->cur_cursor = cursor;
slouken@1895
   663
    } else {
slouken@1895
   664
        cursor = mouse->cur_cursor;
slouken@1895
   665
    }
slouken@1895
   666
slouken@1895
   667
    if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
slouken@1895
   668
        if (mouse->ShowCursor) {
slouken@1895
   669
            mouse->ShowCursor(cursor);
slouken@1895
   670
        }
slouken@1895
   671
    } else {
slouken@1895
   672
        if (mouse->ShowCursor) {
slouken@1895
   673
            mouse->ShowCursor(NULL);
slouken@1895
   674
        }
slouken@1895
   675
    }
slouken@1895
   676
}
slouken@1895
   677
slouken@1895
   678
SDL_Cursor *
slouken@1895
   679
SDL_GetCursor(void)
slouken@1895
   680
{
slouken@1895
   681
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   682
slouken@1895
   683
    if (!mouse) {
slouken@1895
   684
        return NULL;
slouken@1895
   685
    }
slouken@1895
   686
    return mouse->cur_cursor;
slouken@1895
   687
}
slouken@1895
   688
slouken@1895
   689
void
slouken@1895
   690
SDL_FreeCursor(SDL_Cursor * cursor)
slouken@1895
   691
{
slouken@1895
   692
    SDL_Mouse *mouse;
slouken@1895
   693
    SDL_Cursor *curr, *prev;
slouken@1895
   694
slouken@1895
   695
    if (!cursor) {
slouken@1895
   696
        return;
slouken@1895
   697
    }
slouken@1895
   698
    mouse = cursor->mouse;
slouken@1895
   699
slouken@1895
   700
    if (cursor == mouse->def_cursor) {
slouken@1895
   701
        return;
slouken@1895
   702
    }
slouken@1895
   703
    if (cursor == mouse->cur_cursor) {
slouken@1895
   704
        SDL_SetCursor(mouse->def_cursor);
slouken@1895
   705
    }
slouken@1895
   706
slouken@1895
   707
    for (prev = NULL, curr = mouse->cursors; curr;
slouken@1895
   708
         prev = curr, curr = curr->next) {
slouken@1895
   709
        if (curr == cursor) {
slouken@1895
   710
            if (prev) {
slouken@1895
   711
                prev->next = curr->next;
slouken@1895
   712
            } else {
slouken@1895
   713
                mouse->cursors = curr->next;
slouken@1895
   714
            }
slouken@1895
   715
slouken@1895
   716
            if (mouse->FreeCursor) {
slouken@1895
   717
                mouse->FreeCursor(curr);
slouken@1895
   718
            }
slouken@1895
   719
            return;
slouken@1895
   720
        }
slouken@1895
   721
    }
slouken@1895
   722
}
slouken@1895
   723
slouken@1895
   724
int
slouken@1895
   725
SDL_ShowCursor(int toggle)
slouken@1895
   726
{
slouken@1895
   727
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   728
    SDL_bool shown;
slouken@1895
   729
slouken@1895
   730
    if (!mouse) {
slouken@1895
   731
        return 0;
slouken@1895
   732
    }
slouken@1895
   733
slouken@1895
   734
    shown = mouse->cursor_shown;
slouken@1895
   735
    if (toggle >= 0) {
slouken@1895
   736
        if (toggle) {
slouken@1895
   737
            mouse->cursor_shown = SDL_TRUE;
slouken@1895
   738
        } else {
slouken@1895
   739
            mouse->cursor_shown = SDL_FALSE;
slouken@1895
   740
        }
slouken@1895
   741
        if (mouse->cursor_shown != shown) {
slouken@1895
   742
            SDL_SetCursor(NULL);
slouken@1895
   743
        }
slouken@1895
   744
    }
slouken@1895
   745
    return shown;
slouken@1895
   746
}
slouken@1895
   747
kazeuser@3767
   748
int SDL_SetIndexId(int id, int index)
kazeuser@3760
   749
{
kazeuser@3760
   750
    if(id>SDL_highestId)
kazeuser@3760
   751
    {
kazeuser@3760
   752
        int *indexes;
kazeuser@3760
   753
        indexes =
kazeuser@3760
   754
            (int*) SDL_realloc(SDL_IdIndex,
kazeuser@3760
   755
                                       (id + 1) * sizeof(int));
kazeuser@3760
   756
        if (!indexes) {
kazeuser@3760
   757
            SDL_OutOfMemory();
kazeuser@3760
   758
            return -1;
kazeuser@3760
   759
        }
kazeuser@3760
   760
        SDL_IdIndex=indexes;
kazeuser@3760
   761
        SDL_IdIndex[id]=index;
kazeuser@3760
   762
        SDL_highestId=id;
kazeuser@3760
   763
    }
kazeuser@3760
   764
    else
kazeuser@3760
   765
    {
kazeuser@3760
   766
        SDL_IdIndex[id]=index;
kazeuser@3760
   767
    }
kazeuser@3767
   768
	return 1;
kazeuser@3760
   769
}
kazeuser@3760
   770
kazeuser@3760
   771
int SDL_GetIndexById(int id)
kazeuser@3760
   772
{
kazeuser@3760
   773
    if(id>SDL_highestId)
kazeuser@3760
   774
    {
kazeuser@3760
   775
        return -1;
kazeuser@3760
   776
    }
kazeuser@3760
   777
    else
kazeuser@3760
   778
    {
kazeuser@3760
   779
        return SDL_IdIndex[id];
kazeuser@3760
   780
    }
kazeuser@3760
   781
}
kazeuser@3760
   782
kazeuser@3760
   783
int SDL_GetNumOfMice(void)
kazeuser@3760
   784
{
kazeuser@3760
   785
    return SDL_num_mice;
kazeuser@3760
   786
}
kazeuser@3760
   787
kazeuser@3760
   788
char* SDL_GetMouseName(int index)
kazeuser@3760
   789
{
kazeuser@3760
   790
    SDL_Mouse* mouse = SDL_GetMouse(index);
kazeuser@3760
   791
    if(!mouse)
kazeuser@3760
   792
    {
kazeuser@3760
   793
        return NULL;
kazeuser@3760
   794
    }
kazeuser@3760
   795
    return mouse->name;
kazeuser@3760
   796
}
kazeuser@3760
   797
kazeuser@3764
   798
void SDL_UpdateCoordinates(int x, int y)
kazeuser@3764
   799
{
kazeuser@3764
   800
    x_max=x;
kazeuser@3764
   801
    y_max=y;
kazeuser@3764
   802
}
kazeuser@3774
   803
kazeuser@3774
   804
void SDL_ChangeEnd(int id, int end)
kazeuser@3774
   805
{
kazeuser@3774
   806
	int index=SDL_GetIndexById(id);
kazeuser@3774
   807
	SDL_mice[index]->current_end=end;
kazeuser@3774
   808
}
kazeuser@3774
   809
kazeuser@3774
   810
int SDL_GetCursorsNumber(int index)
kazeuser@3774
   811
{
kazeuser@3774
   812
	if(index>=SDL_num_mice)
kazeuser@3774
   813
	{
kazeuser@3774
   814
		return -1;
kazeuser@3774
   815
	}
kazeuser@3774
   816
	if(SDL_mice[index]==NULL)
kazeuser@3774
   817
	{
kazeuser@3774
   818
		return -1;
kazeuser@3774
   819
	}
kazeuser@3774
   820
	return SDL_mice[index]->total_ends;
kazeuser@3774
   821
}
slouken@1895
   822
/* vi: set ts=4 sw=4 expandtab: */
kazeuser@3769
   823