src/events/SDL_mouse.c
author Szymon Wilczek
Fri, 06 Jun 2008 15:23:29 +0000
branchgsoc2008_manymouse
changeset 3760 64f346a83ed3
parent 2152 003c1b5b07da
child 3763 81ea7d9a6624
permissions -rw-r--r--
http://wilku.ravenlord.ws/doku.php?id=documentation for information how things work. Currently implemented: detecting many pointing devices and pressure detection. Still a bug. Each program has to be comipled with a flag -lXi
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
slouken@1895
    31
static int SDL_num_mice;
slouken@1895
    32
static int SDL_current_mouse;
slouken@1895
    33
static SDL_Mouse **SDL_mice;
kazeuser@3760
    34
int *SDL_IdIndex;
kazeuser@3760
    35
int SDL_highestId;
slouken@0
    36
slouken@0
    37
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@3760
    55
SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name)
slouken@0
    56
{
slouken@1895
    57
    SDL_Mouse **mice;
slouken@1895
    58
    int selected_mouse;
kazeuser@3760
    59
    char* temp_name;
slouken@1895
    60
    /* Add the mouse to the list of mice */
slouken@1895
    61
    if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
slouken@1895
    62
        mice =
slouken@1895
    63
            (SDL_Mouse **) SDL_realloc(SDL_mice,
slouken@1895
    64
                                       (SDL_num_mice + 1) * sizeof(*mice));
slouken@1895
    65
        if (!mice) {
slouken@1895
    66
            SDL_OutOfMemory();
slouken@1895
    67
            return -1;
slouken@1895
    68
        }
slouken@0
    69
slouken@1895
    70
        SDL_mice = mice;
slouken@1895
    71
        index = SDL_num_mice++;
slouken@1895
    72
    }
slouken@1895
    73
    SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
slouken@1895
    74
    if (!SDL_mice[index]) {
slouken@1895
    75
        SDL_OutOfMemory();
slouken@1895
    76
        return -1;
slouken@1895
    77
    }
slouken@1895
    78
    *SDL_mice[index] = *mouse;
kazeuser@3760
    79
    SDL_mice[index]->name=SDL_malloc(strlen(name)*sizeof(char));
kazeuser@3760
    80
    strcpy(SDL_mice[index]->name,name);
slouken@1895
    81
    SDL_mice[index]->cursor_shown = SDL_TRUE;
slouken@1895
    82
    selected_mouse = SDL_SelectMouse(index);
slouken@1895
    83
    SDL_mice[index]->cur_cursor = NULL;
slouken@1895
    84
    SDL_mice[index]->def_cursor =
slouken@1895
    85
        SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
slouken@1895
    86
                         DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
slouken@1895
    87
    SDL_SetCursor(SDL_mice[index]->def_cursor);
slouken@1895
    88
    SDL_SelectMouse(selected_mouse);
slouken@1895
    89
slouken@1895
    90
    return index;
slouken@1123
    91
}
slouken@0
    92
slouken@1895
    93
void
slouken@1895
    94
SDL_DelMouse(int index)
slouken@1895
    95
{
slouken@1895
    96
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
    97
slouken@1895
    98
    if (!mouse) {
slouken@1895
    99
        return;
slouken@1895
   100
    }
slouken@1895
   101
slouken@1895
   102
    mouse->def_cursor = NULL;
kazeuser@3760
   103
    SDL_free(mouse->name);
slouken@1895
   104
    while (mouse->cursors) {
slouken@1895
   105
        SDL_FreeCursor(mouse->cursors);
slouken@1895
   106
    }
slouken@1895
   107
slouken@1895
   108
    if (mouse->FreeMouse) {
slouken@1895
   109
        mouse->FreeMouse(mouse);
slouken@1895
   110
    }
slouken@1895
   111
    SDL_free(mouse);
slouken@1895
   112
slouken@1895
   113
    SDL_mice[index] = NULL;
slouken@1895
   114
}
slouken@1895
   115
slouken@1895
   116
void
slouken@1895
   117
SDL_ResetMouse(int index)
slouken@1895
   118
{
slouken@1895
   119
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   120
slouken@1895
   121
    if (!mouse) {
slouken@1895
   122
        return;
slouken@1895
   123
    }
slouken@1895
   124
slouken@1895
   125
    /* FIXME */
slouken@1895
   126
}
slouken@1895
   127
slouken@1895
   128
void
slouken@1895
   129
SDL_MouseQuit(void)
slouken@460
   130
{
slouken@1895
   131
    int i;
slouken@1895
   132
slouken@1895
   133
    for (i = 0; i < SDL_num_mice; ++i) {
slouken@1895
   134
        SDL_DelMouse(i);
slouken@1895
   135
    }
slouken@1895
   136
    SDL_num_mice = 0;
slouken@1895
   137
    SDL_current_mouse = 0;
slouken@1895
   138
slouken@1895
   139
    if (SDL_mice) {
slouken@1895
   140
        SDL_free(SDL_mice);
slouken@1895
   141
        SDL_mice = NULL;
slouken@1895
   142
    }
slouken@1895
   143
}
slouken@1895
   144
slouken@1895
   145
int
slouken@1895
   146
SDL_GetNumMice(void)
slouken@1895
   147
{
slouken@1895
   148
    return SDL_num_mice;
slouken@1895
   149
}
slouken@1895
   150
slouken@1895
   151
int
slouken@1895
   152
SDL_SelectMouse(int index)
slouken@1895
   153
{
slouken@1895
   154
    if (index >= 0 && index < SDL_num_mice) {
slouken@1895
   155
        SDL_current_mouse = index;
slouken@1895
   156
    }
slouken@1895
   157
    return SDL_current_mouse;
slouken@1895
   158
}
slouken@1895
   159
slouken@1895
   160
SDL_WindowID
slouken@1895
   161
SDL_GetMouseFocusWindow()
slouken@1895
   162
{
slouken@1895
   163
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   164
slouken@1895
   165
    if (!mouse) {
slouken@1895
   166
        return 0;
slouken@1895
   167
    }
slouken@1895
   168
    return mouse->focus;
slouken@460
   169
}
slouken@460
   170
icculus@2049
   171
static int SDLCALL
slouken@1895
   172
FlushMouseMotion(void *param, SDL_Event * event)
slouken@1895
   173
{
slouken@1895
   174
    if (event->type == SDL_MOUSEMOTION
slouken@1895
   175
        && event->motion.which == (Uint8) SDL_current_mouse) {
slouken@1895
   176
        return 0;
slouken@1895
   177
    } else {
slouken@1895
   178
        return 1;
slouken@1895
   179
    }
slouken@1895
   180
}
slouken@1895
   181
slouken@1895
   182
int
slouken@1895
   183
SDL_SetRelativeMouseMode(SDL_bool enabled)
slouken@0
   184
{
slouken@1895
   185
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   186
slouken@1895
   187
    if (!mouse) {
slouken@1895
   188
        return -1;
slouken@1895
   189
    }
slouken@1895
   190
slouken@1895
   191
    /* Flush pending mouse motion */
slouken@1895
   192
    mouse->flush_motion = SDL_TRUE;
slouken@1895
   193
    SDL_PumpEvents();
slouken@1895
   194
    mouse->flush_motion = SDL_FALSE;
slouken@1895
   195
    SDL_FilterEvents(FlushMouseMotion, mouse);
slouken@1895
   196
slouken@1895
   197
    /* Set the relative mode */
slouken@1895
   198
    mouse->relative_mode = enabled;
slouken@1895
   199
slouken@1895
   200
    /* Update cursor visibility */
slouken@1895
   201
    SDL_SetCursor(NULL);
slouken@1895
   202
slouken@1895
   203
    if (!enabled) {
slouken@1895
   204
        /* Restore the expected mouse position */
slouken@1895
   205
        SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
slouken@1895
   206
    }
slouken@1895
   207
    return 0;
slouken@1895
   208
}
slouken@1895
   209
slouken@1895
   210
SDL_bool
slouken@1895
   211
SDL_GetRelativeMouseMode()
slouken@1895
   212
{
slouken@1895
   213
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   214
slouken@1895
   215
    if (!mouse) {
slouken@1895
   216
        return SDL_FALSE;
slouken@1895
   217
    }
slouken@1895
   218
    return mouse->relative_mode;
slouken@1895
   219
}
slouken@1895
   220
slouken@1895
   221
Uint8
slouken@1895
   222
SDL_GetMouseState(int *x, int *y)
slouken@1895
   223
{
slouken@1895
   224
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   225
slouken@1895
   226
    if (!mouse) {
slouken@1895
   227
        if (x) {
slouken@1895
   228
            *x = 0;
slouken@1895
   229
        }
slouken@1895
   230
        if (y) {
slouken@1895
   231
            *y = 0;
slouken@1895
   232
        }
slouken@1895
   233
        return 0;
slouken@1895
   234
    }
slouken@1895
   235
slouken@1895
   236
    if (x) {
slouken@1895
   237
        *x = mouse->x;
slouken@1895
   238
    }
slouken@1895
   239
    if (y) {
slouken@1895
   240
        *y = mouse->y;
slouken@1895
   241
    }
slouken@1895
   242
    return mouse->buttonstate;
slouken@0
   243
}
slouken@0
   244
slouken@1895
   245
Uint8
slouken@1895
   246
SDL_GetRelativeMouseState(int *x, int *y)
slouken@0
   247
{
slouken@1895
   248
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   249
slouken@1895
   250
    if (!mouse) {
slouken@1895
   251
        if (x) {
slouken@1895
   252
            *x = 0;
slouken@1895
   253
        }
slouken@1895
   254
        if (y) {
slouken@1895
   255
            *y = 0;
slouken@1895
   256
        }
slouken@1895
   257
        return 0;
slouken@1895
   258
    }
slouken@1895
   259
slouken@1895
   260
    if (x) {
slouken@1895
   261
        *x = mouse->xdelta;
slouken@1895
   262
    }
slouken@1895
   263
    if (y) {
slouken@1895
   264
        *y = mouse->ydelta;
slouken@1895
   265
    }
slouken@1895
   266
    mouse->xdelta = 0;
slouken@1895
   267
    mouse->ydelta = 0;
slouken@1895
   268
    return mouse->buttonstate;
slouken@0
   269
}
slouken@0
   270
slouken@1895
   271
void
kazeuser@3760
   272
SDL_SetMouseFocus(int id, SDL_WindowID windowID)
slouken@0
   273
{
kazeuser@3760
   274
    int index = SDL_GetIndexById(id);
slouken@1895
   275
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   276
    int i;
slouken@1895
   277
    SDL_bool focus;
slouken@1895
   278
slouken@1895
   279
    if (!mouse || (mouse->focus == windowID)) {
slouken@1895
   280
        return;
slouken@1895
   281
    }
slouken@1895
   282
slouken@1895
   283
    /* See if the current window has lost focus */
slouken@1895
   284
    if (mouse->focus) {
slouken@1895
   285
        focus = SDL_FALSE;
slouken@1895
   286
        for (i = 0; i < SDL_num_mice; ++i) {
slouken@1895
   287
            SDL_Mouse *check;
slouken@1895
   288
            if (i != index) {
slouken@1895
   289
                check = SDL_GetMouse(i);
slouken@1895
   290
                if (check && check->focus == mouse->focus) {
slouken@1895
   291
                    focus = SDL_TRUE;
slouken@1895
   292
                    break;
slouken@1895
   293
                }
slouken@1895
   294
            }
slouken@1895
   295
        }
slouken@1895
   296
        if (!focus) {
slouken@1895
   297
            SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
slouken@1895
   298
        }
slouken@1895
   299
    }
slouken@1895
   300
slouken@1895
   301
    mouse->focus = windowID;
slouken@1895
   302
slouken@1895
   303
    if (mouse->focus) {
slouken@1895
   304
        focus = SDL_FALSE;
slouken@1895
   305
        for (i = 0; i < SDL_num_mice; ++i) {
slouken@1895
   306
            SDL_Mouse *check;
slouken@1895
   307
            if (i != index) {
slouken@1895
   308
                check = SDL_GetMouse(i);
slouken@1895
   309
                if (check && check->focus == mouse->focus) {
slouken@1895
   310
                    focus = SDL_TRUE;
slouken@1895
   311
                    break;
slouken@1895
   312
                }
slouken@1895
   313
            }
slouken@1895
   314
        }
slouken@1895
   315
        if (!focus) {
slouken@1895
   316
            SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
slouken@1895
   317
        }
slouken@1895
   318
    }
slouken@0
   319
}
slouken@0
   320
slouken@1895
   321
int
kazeuser@3760
   322
SDL_SendMouseMotion(int id, int relative, int x, int y,int z)
slouken@0
   323
{
kazeuser@3760
   324
    int index=SDL_GetIndexById(id);
slouken@1895
   325
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   326
    int posted;
slouken@1895
   327
    int xrel;
slouken@1895
   328
    int yrel;
slouken@1895
   329
slouken@1895
   330
    if (!mouse || mouse->flush_motion) {
slouken@1895
   331
        return 0;
slouken@1895
   332
    }
slouken@0
   333
slouken@1895
   334
    if (relative) {
slouken@1895
   335
        /* Push the cursor around */
slouken@1895
   336
        xrel = x;
slouken@1895
   337
        yrel = y;
slouken@1895
   338
        x = (mouse->x + xrel);
slouken@1895
   339
        y = (mouse->y + yrel);
slouken@1895
   340
    } else {
slouken@1895
   341
        xrel = x - mouse->x;
slouken@1895
   342
        yrel = y - mouse->y;
slouken@1895
   343
    }
slouken@0
   344
slouken@1895
   345
    /* Drop events that don't change state */
slouken@1895
   346
    if (!xrel && !yrel) {
slouken@1895
   347
#if 0
slouken@1895
   348
        printf("Mouse event didn't change state - dropped!\n");
slouken@1895
   349
#endif
slouken@1895
   350
        return 0;
slouken@1895
   351
    }
slouken@0
   352
slouken@1895
   353
    /* Update internal mouse state */
slouken@1895
   354
    if (!mouse->relative_mode) {
slouken@1895
   355
        mouse->x = x;
slouken@1895
   356
        mouse->y = y;
slouken@1895
   357
    }
slouken@1895
   358
    mouse->xdelta += xrel;
slouken@1895
   359
    mouse->ydelta += yrel;
kazeuser@3760
   360
    mouse->z=z;
slouken@1895
   361
slouken@1895
   362
    /* Move the mouse cursor, if needed */
slouken@1895
   363
    if (mouse->cursor_shown && !mouse->relative_mode &&
slouken@1895
   364
        mouse->MoveCursor && mouse->cur_cursor) {
slouken@1895
   365
        mouse->MoveCursor(mouse->cur_cursor);
slouken@1895
   366
    }
slouken@0
   367
slouken@1895
   368
    /* Post the event, if desired */
slouken@1895
   369
    posted = 0;
slouken@1895
   370
    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) {
slouken@1895
   371
        SDL_Event event;
slouken@1895
   372
        event.motion.type = SDL_MOUSEMOTION;
slouken@1895
   373
        event.motion.which = (Uint8) index;
slouken@1895
   374
        event.motion.state = mouse->buttonstate;
slouken@1895
   375
        event.motion.x = mouse->x;
slouken@1895
   376
        event.motion.y = mouse->y;
kazeuser@3760
   377
        event.motion.z = mouse->z;
slouken@1895
   378
        event.motion.xrel = xrel;
slouken@1895
   379
        event.motion.yrel = yrel;
slouken@1895
   380
        event.motion.windowID = mouse->focus;
slouken@1895
   381
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   382
    }
slouken@1895
   383
    return posted;
slouken@1895
   384
}
slouken@1895
   385
slouken@1895
   386
int
kazeuser@3760
   387
SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
slouken@1895
   388
{
kazeuser@3760
   389
    int index=SDL_GetIndexById(id);
slouken@1895
   390
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   391
    int posted;
slouken@1895
   392
    Uint8 type;
slouken@1895
   393
slouken@1895
   394
    if (!mouse) {
slouken@1895
   395
        return 0;
slouken@1895
   396
    }
slouken@0
   397
slouken@1895
   398
    /* Figure out which event to perform */
slouken@1895
   399
    switch (state) {
slouken@1895
   400
    case SDL_PRESSED:
slouken@1895
   401
        if (mouse->buttonstate & SDL_BUTTON(button)) {
slouken@1895
   402
            /* Ignore this event, no state change */
slouken@1895
   403
            return 0;
slouken@1895
   404
        }
slouken@1895
   405
        type = SDL_MOUSEBUTTONDOWN;
slouken@1895
   406
        mouse->buttonstate |= SDL_BUTTON(button);
slouken@1895
   407
        break;
slouken@1895
   408
    case SDL_RELEASED:
kazeuser@3760
   409
        //if (!(mouse->buttonstate & SDL_BUTTON(button))) {
kazeuser@3760
   410
        //    /* Ignore this event, no state change */
kazeuser@3760
   411
        //    return 0;
kazeuser@3760
   412
        //}*/
slouken@1895
   413
        type = SDL_MOUSEBUTTONUP;
slouken@1895
   414
        mouse->buttonstate &= ~SDL_BUTTON(button);
slouken@1895
   415
        break;
slouken@1895
   416
    default:
slouken@1895
   417
        /* Invalid state -- bail */
slouken@1895
   418
        return 0;
slouken@1895
   419
    }
slouken@0
   420
slouken@1895
   421
    /* Post the event, if desired */
slouken@1895
   422
    posted = 0;
slouken@1895
   423
    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
slouken@1895
   424
        SDL_Event event;
slouken@1895
   425
        event.type = type;
slouken@1895
   426
        event.button.which = (Uint8) index;
slouken@1895
   427
        event.button.state = state;
slouken@1895
   428
        event.button.button = button;
slouken@1895
   429
        event.button.x = mouse->x;
slouken@1895
   430
        event.button.y = mouse->y;
slouken@1895
   431
        event.button.windowID = mouse->focus;
slouken@1895
   432
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   433
    }
slouken@1895
   434
    return posted;
slouken@1895
   435
}
slouken@1283
   436
slouken@1895
   437
int
slouken@2152
   438
SDL_SendMouseWheel(int index, int x, int y)
slouken@1895
   439
{
slouken@1895
   440
    SDL_Mouse *mouse = SDL_GetMouse(index);
slouken@1895
   441
    int posted;
slouken@1895
   442
slouken@2152
   443
    if (!mouse || (!x && !y)) {
slouken@1895
   444
        return 0;
slouken@1895
   445
    }
slouken@0
   446
slouken@1895
   447
    /* Post the event, if desired */
slouken@1895
   448
    posted = 0;
slouken@1895
   449
    if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
slouken@1895
   450
        SDL_Event event;
slouken@1895
   451
        event.type = SDL_MOUSEWHEEL;
slouken@1895
   452
        event.wheel.which = (Uint8) index;
slouken@2152
   453
        event.wheel.x = x;
slouken@2152
   454
        event.wheel.y = y;
slouken@1895
   455
        event.wheel.windowID = mouse->focus;
slouken@1895
   456
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   457
    }
slouken@1895
   458
    return posted;
slouken@1895
   459
}
slouken@1895
   460
slouken@1895
   461
void
slouken@1895
   462
SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
slouken@1895
   463
{
slouken@1895
   464
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   465
slouken@1895
   466
    if (!mouse) {
slouken@1895
   467
        return;
slouken@1895
   468
    }
slouken@1895
   469
slouken@1895
   470
    if (mouse->WarpMouse) {
slouken@1895
   471
        mouse->WarpMouse(mouse, windowID, x, y);
slouken@1895
   472
    } else {
slouken@1895
   473
        SDL_SetMouseFocus(SDL_current_mouse, windowID);
kazeuser@3760
   474
        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y,0);
slouken@1895
   475
    }
slouken@0
   476
}
slouken@0
   477
slouken@1895
   478
SDL_Cursor *
slouken@1895
   479
SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
slouken@1895
   480
                 int w, int h, int hot_x, int hot_y)
slouken@0
   481
{
slouken@1895
   482
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   483
    SDL_Surface *surface;
slouken@1895
   484
    SDL_Cursor *cursor;
slouken@1895
   485
    int x, y;
slouken@1895
   486
    Uint32 *pixel;
slouken@1895
   487
    Uint8 datab, maskb;
slouken@1895
   488
    const Uint32 black = 0xFF000000;
slouken@1895
   489
    const Uint32 white = 0xFFFFFFFF;
slouken@1895
   490
    const Uint32 transparent = 0x00000000;
slouken@0
   491
slouken@1895
   492
    if (!mouse) {
slouken@1895
   493
        SDL_SetError("No mice are initialized");
slouken@1895
   494
        return NULL;
slouken@1895
   495
    }
slouken@0
   496
slouken@1895
   497
    if (!mouse->CreateCursor) {
slouken@1895
   498
        SDL_SetError("Current mouse doesn't have cursor support");
slouken@1895
   499
        return NULL;
slouken@1895
   500
    }
slouken@1895
   501
slouken@1895
   502
    /* Sanity check the hot spot */
slouken@1895
   503
    if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
slouken@1895
   504
        SDL_SetError("Cursor hot spot doesn't lie within cursor");
slouken@1895
   505
        return NULL;
slouken@1895
   506
    }
slouken@1895
   507
slouken@1895
   508
    /* Make sure the width is a multiple of 8 */
slouken@1895
   509
    w = ((w + 7) & ~7);
slouken@0
   510
slouken@1895
   511
    /* Create the surface from a bitmap */
slouken@1895
   512
    surface =
slouken@1895
   513
        SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
slouken@1895
   514
                             0xFF000000);
slouken@1895
   515
    if (!surface) {
slouken@1895
   516
        return NULL;
slouken@1895
   517
    }
slouken@1895
   518
    for (y = 0; y < h; ++y) {
slouken@1895
   519
        pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
slouken@1895
   520
        for (x = 0; x < w; ++x) {
slouken@1895
   521
            if ((x % 8) == 0) {
slouken@1895
   522
                datab = *data++;
slouken@1895
   523
                maskb = *mask++;
slouken@1895
   524
            }
slouken@1895
   525
            if (maskb & 0x80) {
slouken@1895
   526
                *pixel++ = (datab & 0x80) ? black : white;
slouken@1895
   527
            } else {
slouken@1895
   528
                *pixel++ = (datab & 0x80) ? black : transparent;
slouken@1895
   529
            }
slouken@1895
   530
            datab <<= 1;
slouken@1895
   531
            maskb <<= 1;
slouken@1895
   532
        }
slouken@1895
   533
    }
slouken@0
   534
slouken@1895
   535
    cursor = mouse->CreateCursor(surface, hot_x, hot_y);
slouken@1895
   536
    if (cursor) {
slouken@1895
   537
        cursor->mouse = mouse;
slouken@1895
   538
        cursor->next = mouse->cursors;
slouken@1895
   539
        mouse->cursors = cursor;
slouken@1895
   540
    }
slouken@0
   541
slouken@1895
   542
    SDL_FreeSurface(surface);
slouken@1895
   543
slouken@1895
   544
    return cursor;
slouken@0
   545
}
slouken@0
   546
slouken@1895
   547
/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
slouken@1895
   548
   if this is desired for any reason.  This is used when setting
slouken@1895
   549
   the video mode and when the SDL window gains the mouse focus.
slouken@1895
   550
 */
slouken@1895
   551
void
slouken@1895
   552
SDL_SetCursor(SDL_Cursor * cursor)
slouken@1895
   553
{
slouken@1895
   554
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   555
slouken@1895
   556
    if (!mouse) {
slouken@1895
   557
        SDL_SetError("No mice are initialized");
slouken@1895
   558
        return;
slouken@1895
   559
    }
slouken@1895
   560
slouken@1895
   561
    /* Set the new cursor */
slouken@1895
   562
    if (cursor) {
slouken@1895
   563
        /* Make sure the cursor is still valid for this mouse */
slouken@1895
   564
        SDL_Cursor *found;
slouken@1895
   565
        for (found = mouse->cursors; found; found = found->next) {
slouken@1895
   566
            if (found == cursor) {
slouken@1895
   567
                break;
slouken@1895
   568
            }
slouken@1895
   569
        }
slouken@1895
   570
        if (!found) {
slouken@1895
   571
            SDL_SetError("Cursor not associated with the current mouse");
slouken@1895
   572
            return;
slouken@1895
   573
        }
slouken@1895
   574
        mouse->cur_cursor = cursor;
slouken@1895
   575
    } else {
slouken@1895
   576
        cursor = mouse->cur_cursor;
slouken@1895
   577
    }
slouken@1895
   578
slouken@1895
   579
    if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
slouken@1895
   580
        if (mouse->ShowCursor) {
slouken@1895
   581
            mouse->ShowCursor(cursor);
slouken@1895
   582
        }
slouken@1895
   583
    } else {
slouken@1895
   584
        if (mouse->ShowCursor) {
slouken@1895
   585
            mouse->ShowCursor(NULL);
slouken@1895
   586
        }
slouken@1895
   587
    }
slouken@1895
   588
}
slouken@1895
   589
slouken@1895
   590
SDL_Cursor *
slouken@1895
   591
SDL_GetCursor(void)
slouken@1895
   592
{
slouken@1895
   593
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   594
slouken@1895
   595
    if (!mouse) {
slouken@1895
   596
        return NULL;
slouken@1895
   597
    }
slouken@1895
   598
    return mouse->cur_cursor;
slouken@1895
   599
}
slouken@1895
   600
slouken@1895
   601
void
slouken@1895
   602
SDL_FreeCursor(SDL_Cursor * cursor)
slouken@1895
   603
{
slouken@1895
   604
    SDL_Mouse *mouse;
slouken@1895
   605
    SDL_Cursor *curr, *prev;
slouken@1895
   606
slouken@1895
   607
    if (!cursor) {
slouken@1895
   608
        return;
slouken@1895
   609
    }
slouken@1895
   610
    mouse = cursor->mouse;
slouken@1895
   611
slouken@1895
   612
    if (cursor == mouse->def_cursor) {
slouken@1895
   613
        return;
slouken@1895
   614
    }
slouken@1895
   615
    if (cursor == mouse->cur_cursor) {
slouken@1895
   616
        SDL_SetCursor(mouse->def_cursor);
slouken@1895
   617
    }
slouken@1895
   618
slouken@1895
   619
    for (prev = NULL, curr = mouse->cursors; curr;
slouken@1895
   620
         prev = curr, curr = curr->next) {
slouken@1895
   621
        if (curr == cursor) {
slouken@1895
   622
            if (prev) {
slouken@1895
   623
                prev->next = curr->next;
slouken@1895
   624
            } else {
slouken@1895
   625
                mouse->cursors = curr->next;
slouken@1895
   626
            }
slouken@1895
   627
slouken@1895
   628
            if (mouse->FreeCursor) {
slouken@1895
   629
                mouse->FreeCursor(curr);
slouken@1895
   630
            }
slouken@1895
   631
            return;
slouken@1895
   632
        }
slouken@1895
   633
    }
slouken@1895
   634
}
slouken@1895
   635
slouken@1895
   636
int
slouken@1895
   637
SDL_ShowCursor(int toggle)
slouken@1895
   638
{
slouken@1895
   639
    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
slouken@1895
   640
    SDL_bool shown;
slouken@1895
   641
slouken@1895
   642
    if (!mouse) {
slouken@1895
   643
        return 0;
slouken@1895
   644
    }
slouken@1895
   645
slouken@1895
   646
    shown = mouse->cursor_shown;
slouken@1895
   647
    if (toggle >= 0) {
slouken@1895
   648
        if (toggle) {
slouken@1895
   649
            mouse->cursor_shown = SDL_TRUE;
slouken@1895
   650
        } else {
slouken@1895
   651
            mouse->cursor_shown = SDL_FALSE;
slouken@1895
   652
        }
slouken@1895
   653
        if (mouse->cursor_shown != shown) {
slouken@1895
   654
            SDL_SetCursor(NULL);
slouken@1895
   655
        }
slouken@1895
   656
    }
slouken@1895
   657
    return shown;
slouken@1895
   658
}
slouken@1895
   659
kazeuser@3760
   660
void SDL_SetIndexId(int id, int index)
kazeuser@3760
   661
{
kazeuser@3760
   662
    if(id>SDL_highestId)
kazeuser@3760
   663
    {
kazeuser@3760
   664
        int *indexes;
kazeuser@3760
   665
        indexes =
kazeuser@3760
   666
            (int*) SDL_realloc(SDL_IdIndex,
kazeuser@3760
   667
                                       (id + 1) * sizeof(int));
kazeuser@3760
   668
        if (!indexes) {
kazeuser@3760
   669
            SDL_OutOfMemory();
kazeuser@3760
   670
            return -1;
kazeuser@3760
   671
        }
kazeuser@3760
   672
        SDL_IdIndex=indexes;
kazeuser@3760
   673
        SDL_IdIndex[id]=index;
kazeuser@3760
   674
        SDL_highestId=id;
kazeuser@3760
   675
    }
kazeuser@3760
   676
    else
kazeuser@3760
   677
    {
kazeuser@3760
   678
        SDL_IdIndex[id]=index;
kazeuser@3760
   679
    }
kazeuser@3760
   680
}
kazeuser@3760
   681
kazeuser@3760
   682
int SDL_GetIndexById(int id)
kazeuser@3760
   683
{
kazeuser@3760
   684
    if(id>SDL_highestId)
kazeuser@3760
   685
    {
kazeuser@3760
   686
        return -1;
kazeuser@3760
   687
    }
kazeuser@3760
   688
    else
kazeuser@3760
   689
    {
kazeuser@3760
   690
        return SDL_IdIndex[id];
kazeuser@3760
   691
    }
kazeuser@3760
   692
}
kazeuser@3760
   693
kazeuser@3760
   694
int SDL_GetNumOfMice(void)
kazeuser@3760
   695
{
kazeuser@3760
   696
    return SDL_num_mice;
kazeuser@3760
   697
}
kazeuser@3760
   698
kazeuser@3760
   699
char* SDL_GetMouseName(int index)
kazeuser@3760
   700
{
kazeuser@3760
   701
    SDL_Mouse* mouse = SDL_GetMouse(index);
kazeuser@3760
   702
    if(!mouse)
kazeuser@3760
   703
    {
kazeuser@3760
   704
        return NULL;
kazeuser@3760
   705
    }
kazeuser@3760
   706
    return mouse->name;
kazeuser@3760
   707
}
kazeuser@3760
   708
kazeuser@3760
   709
slouken@1895
   710
/* vi: set ts=4 sw=4 expandtab: */