src/events/SDL_mouse.c
author Wim Looman <ghostunderscore@gmail.com>
Sat, 04 Feb 2012 00:13:21 +1300
changeset 6302 b0ae93a5b8d6
parent 6301 e8a69c5378e7
child 6666 018f8019ce36
permissions -rwxr-xr-x
Make mouse relative mode save the original co-ordinates to restore them
properly.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@0
     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.
slouken@0
     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:
slouken@0
    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.
slouken@0
    20
*/
slouken@1402
    21
#include "SDL_config.h"
slouken@0
    22
slouken@0
    23
/* General mouse handling code for SDL */
slouken@0
    24
slouken@0
    25
#include "SDL_events.h"
slouken@0
    26
#include "SDL_events_c.h"
slouken@1895
    27
#include "default_cursor.h"
slouken@3685
    28
#include "../video/SDL_sysvideo.h"
slouken@0
    29
slouken@0
    30
slouken@5371
    31
/* The mouse state */
slouken@4465
    32
static SDL_Mouse SDL_mouse;
slouken@0
    33
slouken@0
    34
slouken@0
    35
/* Public functions */
slouken@1895
    36
int
slouken@1895
    37
SDL_MouseInit(void)
slouken@0
    38
{
slouken@5376
    39
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5376
    40
slouken@5376
    41
    mouse->cursor_shown = SDL_TRUE;
slouken@5376
    42
slouken@1895
    43
    return (0);
slouken@1123
    44
}
slouken@0
    45
slouken@5405
    46
void
slouken@5405
    47
SDL_SetDefaultCursor(SDL_Cursor * cursor)
slouken@5405
    48
{
slouken@5405
    49
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5405
    50
slouken@5405
    51
    mouse->def_cursor = cursor;
slouken@5405
    52
    if (!mouse->cur_cursor) {
slouken@5405
    53
        SDL_SetCursor(cursor);
slouken@5405
    54
    }
slouken@5405
    55
}
slouken@5405
    56
slouken@5371
    57
SDL_Mouse *
slouken@5371
    58
SDL_GetMouse(void)
slouken@5371
    59
{
slouken@5371
    60
    return &SDL_mouse;
slouken@5371
    61
}
slouken@5371
    62
slouken@4465
    63
SDL_Window *
slouken@4465
    64
SDL_GetMouseFocus(void)
slouken@2710
    65
{
slouken@5371
    66
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@2940
    67
slouken@4465
    68
    return mouse->focus;
slouken@0
    69
}
slouken@0
    70
slouken@1895
    71
void
slouken@4465
    72
SDL_SetMouseFocus(SDL_Window * window)
slouken@0
    73
{
slouken@5371
    74
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
    75
slouken@4465
    76
    if (mouse->focus == window) {
slouken@1895
    77
        return;
slouken@1895
    78
    }
slouken@1895
    79
slouken@1895
    80
    /* See if the current window has lost focus */
slouken@1895
    81
    if (mouse->focus) {
slouken@4465
    82
        SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
slouken@1895
    83
    }
slouken@1895
    84
slouken@3685
    85
    mouse->focus = window;
slouken@1895
    86
slouken@1895
    87
    if (mouse->focus) {
slouken@4465
    88
        SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
slouken@1895
    89
    }
slouken@1895
    90
}
slouken@1895
    91
slouken@1895
    92
int
slouken@4484
    93
SDL_SendMouseMotion(SDL_Window * window, int relative, int x, int y)
slouken@1895
    94
{
slouken@5371
    95
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
    96
    int posted;
slouken@1895
    97
    int xrel;
slouken@1895
    98
    int yrel;
slouken@2860
    99
    int x_max = 0, y_max = 0;
slouken@1895
   100
slouken@4484
   101
    if (window) {
slouken@4484
   102
        SDL_SetMouseFocus(window);
slouken@4484
   103
    }
slouken@4484
   104
slouken@2710
   105
    /* the relative motion is calculated regarding the system cursor last position */
slouken@2842
   106
    if (relative) {
slouken@2842
   107
        xrel = x;
slouken@2842
   108
        yrel = y;
slouken@2860
   109
        x = (mouse->last_x + x);
slouken@2860
   110
        y = (mouse->last_y + y);
slouken@2842
   111
    } else {
slouken@2860
   112
        xrel = x - mouse->last_x;
slouken@2860
   113
        yrel = y - mouse->last_y;
slouken@2842
   114
    }
slouken@2710
   115
slouken@1895
   116
    /* Drop events that don't change state */
slouken@1895
   117
    if (!xrel && !yrel) {
slouken@1895
   118
#if 0
slouken@1895
   119
        printf("Mouse event didn't change state - dropped!\n");
slouken@1895
   120
#endif
slouken@1895
   121
        return 0;
slouken@1895
   122
    }
slouken@1895
   123
slouken@2710
   124
    /* Update internal mouse coordinates */
slouken@2710
   125
    if (mouse->relative_mode == SDL_FALSE) {
slouken@1895
   126
        mouse->x = x;
slouken@1895
   127
        mouse->y = y;
slouken@2710
   128
    } else {
slouken@2860
   129
        mouse->x += xrel;
slouken@2860
   130
        mouse->y += yrel;
slouken@2860
   131
    }
slouken@2849
   132
slouken@2860
   133
    SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
slouken@5370
   134
    --x_max;
slouken@5370
   135
    --y_max;
slouken@2849
   136
slouken@2860
   137
    /* make sure that the pointers find themselves inside the windows */
slouken@2860
   138
    /* only check if mouse->xmax is set ! */
slouken@5370
   139
    if (mouse->x > x_max) {
slouken@2860
   140
        mouse->x = x_max;
slouken@5370
   141
    }
slouken@5370
   142
    if (mouse->x < 0) {
slouken@2860
   143
        mouse->x = 0;
slouken@1895
   144
    }
slouken@2860
   145
slouken@5370
   146
    if (mouse->y > y_max) {
slouken@2860
   147
        mouse->y = y_max;
slouken@5370
   148
    }
slouken@5370
   149
    if (mouse->y < 0) {
slouken@2860
   150
        mouse->y = 0;
slouken@2860
   151
    }
slouken@2860
   152
slouken@1895
   153
    mouse->xdelta += xrel;
slouken@1895
   154
    mouse->ydelta += yrel;
slouken@1895
   155
slouken@4465
   156
#if 0 /* FIXME */
slouken@1895
   157
    /* Move the mouse cursor, if needed */
slouken@1895
   158
    if (mouse->cursor_shown && !mouse->relative_mode &&
slouken@1895
   159
        mouse->MoveCursor && mouse->cur_cursor) {
slouken@1895
   160
        mouse->MoveCursor(mouse->cur_cursor);
slouken@1895
   161
    }
slouken@4465
   162
#endif
slouken@1895
   163
slouken@1895
   164
    /* Post the event, if desired */
slouken@1895
   165
    posted = 0;
slouken@4465
   166
    if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) {
slouken@1895
   167
        SDL_Event event;
slouken@1895
   168
        event.motion.type = SDL_MOUSEMOTION;
slouken@4465
   169
        event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
slouken@1895
   170
        event.motion.state = mouse->buttonstate;
slouken@1895
   171
        event.motion.x = mouse->x;
slouken@1895
   172
        event.motion.y = mouse->y;
slouken@1895
   173
        event.motion.xrel = xrel;
slouken@1895
   174
        event.motion.yrel = yrel;
slouken@1895
   175
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   176
    }
lestat@3112
   177
    mouse->last_x = mouse->x;
lestat@3112
   178
    mouse->last_y = mouse->y;
slouken@1895
   179
    return posted;
slouken@1895
   180
}
slouken@1895
   181
slouken@1895
   182
int
slouken@4484
   183
SDL_SendMouseButton(SDL_Window * window, Uint8 state, Uint8 button)
slouken@1895
   184
{
slouken@5371
   185
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   186
    int posted;
slouken@4429
   187
    Uint32 type;
slouken@1895
   188
slouken@4484
   189
    if (window) {
slouken@4484
   190
        SDL_SetMouseFocus(window);
slouken@4484
   191
    }
slouken@4484
   192
slouken@1895
   193
    /* Figure out which event to perform */
slouken@1895
   194
    switch (state) {
slouken@1895
   195
    case SDL_PRESSED:
slouken@1895
   196
        if (mouse->buttonstate & SDL_BUTTON(button)) {
slouken@1895
   197
            /* Ignore this event, no state change */
slouken@1895
   198
            return 0;
slouken@1895
   199
        }
slouken@1895
   200
        type = SDL_MOUSEBUTTONDOWN;
slouken@1895
   201
        mouse->buttonstate |= SDL_BUTTON(button);
slouken@1895
   202
        break;
slouken@1895
   203
    case SDL_RELEASED:
slouken@2725
   204
        if (!(mouse->buttonstate & SDL_BUTTON(button))) {
kazeuser@2718
   205
            /* Ignore this event, no state change */
kazeuser@2718
   206
            return 0;
kazeuser@2718
   207
        }
slouken@1895
   208
        type = SDL_MOUSEBUTTONUP;
slouken@1895
   209
        mouse->buttonstate &= ~SDL_BUTTON(button);
slouken@1895
   210
        break;
slouken@1895
   211
    default:
slouken@1895
   212
        /* Invalid state -- bail */
slouken@1895
   213
        return 0;
slouken@1895
   214
    }
slouken@1895
   215
slouken@1895
   216
    /* Post the event, if desired */
slouken@1895
   217
    posted = 0;
slouken@4429
   218
    if (SDL_GetEventState(type) == SDL_ENABLE) {
slouken@1895
   219
        SDL_Event event;
slouken@1895
   220
        event.type = type;
slouken@1895
   221
        event.button.state = state;
slouken@1895
   222
        event.button.button = button;
slouken@1895
   223
        event.button.x = mouse->x;
slouken@1895
   224
        event.button.y = mouse->y;
slouken@3689
   225
        event.button.windowID = mouse->focus ? mouse->focus->id : 0;
slouken@1895
   226
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   227
    }
slouken@1895
   228
    return posted;
slouken@1895
   229
}
slouken@1895
   230
slouken@1895
   231
int
slouken@4484
   232
SDL_SendMouseWheel(SDL_Window * window, int x, int y)
slouken@1895
   233
{
slouken@5371
   234
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   235
    int posted;
slouken@1895
   236
slouken@4484
   237
    if (window) {
slouken@4484
   238
        SDL_SetMouseFocus(window);
slouken@4484
   239
    }
slouken@4484
   240
slouken@4465
   241
    if (!x && !y) {
slouken@1895
   242
        return 0;
slouken@1895
   243
    }
slouken@1895
   244
slouken@1895
   245
    /* Post the event, if desired */
slouken@1895
   246
    posted = 0;
slouken@4429
   247
    if (SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE) {
slouken@1895
   248
        SDL_Event event;
slouken@1895
   249
        event.type = SDL_MOUSEWHEEL;
slouken@4465
   250
        event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
slouken@2152
   251
        event.wheel.x = x;
slouken@2152
   252
        event.wheel.y = y;
slouken@1895
   253
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   254
    }
slouken@1895
   255
    return posted;
slouken@1895
   256
}
slouken@1895
   257
slouken@1895
   258
void
slouken@4465
   259
SDL_MouseQuit(void)
slouken@4465
   260
{
slouken@4465
   261
}
slouken@4465
   262
slouken@4465
   263
Uint8
slouken@4465
   264
SDL_GetMouseState(int *x, int *y)
slouken@4465
   265
{
slouken@5371
   266
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   267
slouken@4465
   268
    if (x) {
slouken@4465
   269
        *x = mouse->x;
slouken@4465
   270
    }
slouken@4465
   271
    if (y) {
slouken@4465
   272
        *y = mouse->y;
slouken@4465
   273
    }
slouken@4465
   274
    return mouse->buttonstate;
slouken@4465
   275
}
slouken@4465
   276
slouken@4465
   277
Uint8
slouken@4465
   278
SDL_GetRelativeMouseState(int *x, int *y)
slouken@4465
   279
{
slouken@5371
   280
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   281
slouken@4465
   282
    if (x) {
slouken@4465
   283
        *x = mouse->xdelta;
slouken@4465
   284
    }
slouken@4465
   285
    if (y) {
slouken@4465
   286
        *y = mouse->ydelta;
slouken@4465
   287
    }
slouken@4465
   288
    mouse->xdelta = 0;
slouken@4465
   289
    mouse->ydelta = 0;
slouken@4465
   290
    return mouse->buttonstate;
slouken@4465
   291
}
slouken@4465
   292
slouken@4465
   293
void
slouken@3685
   294
SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
slouken@1895
   295
{
slouken@5371
   296
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   297
slouken@1895
   298
    if (mouse->WarpMouse) {
slouken@5371
   299
        mouse->WarpMouse(window, x, y);
slouken@1895
   300
    } else {
slouken@4484
   301
        SDL_SendMouseMotion(window, 0, x, y);
slouken@1895
   302
    }
slouken@1895
   303
}
slouken@1895
   304
slouken@4465
   305
int
slouken@4465
   306
SDL_SetRelativeMouseMode(SDL_bool enabled)
slouken@4465
   307
{
slouken@5371
   308
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   309
slouken@5406
   310
    if (enabled == mouse->relative_mode) {
slouken@5406
   311
        return 0;
slouken@5406
   312
    }
slouken@5406
   313
slouken@5406
   314
    if (!mouse->SetRelativeMouseMode) {
slouken@5406
   315
        SDL_Unsupported();
slouken@5406
   316
        return -1;
slouken@5406
   317
    }
slouken@5406
   318
slouken@5406
   319
    if (mouse->SetRelativeMouseMode(enabled) < 0) {
slouken@5406
   320
        return -1;
slouken@5406
   321
    }
slouken@4465
   322
slouken@4465
   323
    /* Set the relative mode */
slouken@4465
   324
    mouse->relative_mode = enabled;
slouken@4465
   325
ghostunderscore@6302
   326
    if (enabled) {
ghostunderscore@6302
   327
        /* Save the expected mouse position */
ghostunderscore@6302
   328
        mouse->original_x = mouse->x;
ghostunderscore@6302
   329
        mouse->original_y = mouse->y;
ghostunderscore@6302
   330
    } else if (mouse->focus) {
slouken@4465
   331
        /* Restore the expected mouse position */
ghostunderscore@6302
   332
        SDL_WarpMouseInWindow(mouse->focus, mouse->original_x, mouse->original_y);
slouken@4465
   333
    }
slouken@4465
   334
slouken@5406
   335
    /* Flush pending mouse motion */
slouken@5406
   336
    SDL_FlushEvent(SDL_MOUSEMOTION);
slouken@5406
   337
slouken@4465
   338
    /* Update cursor visibility */
slouken@4465
   339
    SDL_SetCursor(NULL);
slouken@4465
   340
slouken@4465
   341
    return 0;
slouken@4465
   342
}
slouken@4465
   343
slouken@4465
   344
SDL_bool
slouken@4465
   345
SDL_GetRelativeMouseMode()
slouken@4465
   346
{
slouken@5371
   347
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   348
slouken@4465
   349
    return mouse->relative_mode;
slouken@4465
   350
}
slouken@4465
   351
slouken@1895
   352
SDL_Cursor *
slouken@1895
   353
SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
slouken@1895
   354
                 int w, int h, int hot_x, int hot_y)
slouken@1895
   355
{
slouken@1895
   356
    SDL_Surface *surface;
slouken@1895
   357
    SDL_Cursor *cursor;
slouken@1895
   358
    int x, y;
slouken@1895
   359
    Uint32 *pixel;
slouken@4465
   360
    Uint8 datab = 0, maskb = 0;
slouken@1895
   361
    const Uint32 black = 0xFF000000;
slouken@1895
   362
    const Uint32 white = 0xFFFFFFFF;
slouken@1895
   363
    const Uint32 transparent = 0x00000000;
slouken@1895
   364
slouken@1895
   365
    /* Make sure the width is a multiple of 8 */
slouken@1895
   366
    w = ((w + 7) & ~7);
slouken@1895
   367
slouken@1895
   368
    /* Create the surface from a bitmap */
slouken@5473
   369
    surface = SDL_CreateRGBSurface(0, w, h, 32,
slouken@5473
   370
                                   0x00FF0000,
slouken@5473
   371
                                   0x0000FF00,
slouken@5473
   372
                                   0x000000FF,
slouken@5473
   373
                                   0xFF000000);
slouken@1895
   374
    if (!surface) {
slouken@1895
   375
        return NULL;
slouken@1895
   376
    }
slouken@1895
   377
    for (y = 0; y < h; ++y) {
slouken@1895
   378
        pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
slouken@1895
   379
        for (x = 0; x < w; ++x) {
slouken@1895
   380
            if ((x % 8) == 0) {
slouken@1895
   381
                datab = *data++;
slouken@1895
   382
                maskb = *mask++;
slouken@1895
   383
            }
slouken@1895
   384
            if (maskb & 0x80) {
slouken@1895
   385
                *pixel++ = (datab & 0x80) ? black : white;
slouken@1895
   386
            } else {
slouken@1895
   387
                *pixel++ = (datab & 0x80) ? black : transparent;
slouken@1895
   388
            }
slouken@1895
   389
            datab <<= 1;
slouken@1895
   390
            maskb <<= 1;
slouken@1895
   391
        }
slouken@1895
   392
    }
slouken@1895
   393
slouken@5473
   394
    cursor = SDL_CreateColorCursor(surface, hot_x, hot_y);
slouken@5473
   395
slouken@5473
   396
    SDL_FreeSurface(surface);
slouken@5473
   397
slouken@5473
   398
    return cursor;
slouken@5473
   399
}
slouken@5473
   400
slouken@5473
   401
SDL_Cursor *
slouken@5473
   402
SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
slouken@5473
   403
{
slouken@5473
   404
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5473
   405
    SDL_Surface *temp = NULL;
slouken@5473
   406
    SDL_Cursor *cursor;
slouken@5473
   407
slouken@5473
   408
    if (!surface) {
slouken@5473
   409
        SDL_SetError("Passed NULL cursor surface");
slouken@5473
   410
        return NULL;
slouken@5473
   411
    }
slouken@5473
   412
slouken@5473
   413
    if (!mouse->CreateCursor) {
slouken@5473
   414
        SDL_SetError("Cursors are not currently supported");
slouken@5473
   415
        return NULL;
slouken@5473
   416
    }
slouken@5473
   417
slouken@5473
   418
    /* Sanity check the hot spot */
slouken@5473
   419
    if ((hot_x < 0) || (hot_y < 0) ||
slouken@5473
   420
        (hot_x >= surface->w) || (hot_y >= surface->h)) {
slouken@5473
   421
        SDL_SetError("Cursor hot spot doesn't lie within cursor");
slouken@5473
   422
        return NULL;
slouken@5473
   423
    }
slouken@5473
   424
slouken@5473
   425
    if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
slouken@5473
   426
        temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
slouken@5473
   427
        if (!temp) {
slouken@5473
   428
            return NULL;
slouken@5473
   429
        }
slouken@5473
   430
        surface = temp;
slouken@5473
   431
    }
slouken@5473
   432
slouken@1895
   433
    cursor = mouse->CreateCursor(surface, hot_x, hot_y);
slouken@1895
   434
    if (cursor) {
slouken@1895
   435
        cursor->next = mouse->cursors;
slouken@1895
   436
        mouse->cursors = cursor;
slouken@1895
   437
    }
slouken@1895
   438
slouken@5473
   439
    if (temp) {
slouken@5473
   440
        SDL_FreeSurface(temp);
slouken@5473
   441
    }
slouken@1895
   442
slouken@1895
   443
    return cursor;
slouken@1895
   444
}
slouken@1895
   445
slouken@1895
   446
/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
slouken@1895
   447
   if this is desired for any reason.  This is used when setting
slouken@1895
   448
   the video mode and when the SDL window gains the mouse focus.
slouken@1895
   449
 */
slouken@1895
   450
void
slouken@1895
   451
SDL_SetCursor(SDL_Cursor * cursor)
slouken@1895
   452
{
slouken@5371
   453
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   454
slouken@1895
   455
    /* Set the new cursor */
slouken@1895
   456
    if (cursor) {
slouken@1895
   457
        /* Make sure the cursor is still valid for this mouse */
slouken@5405
   458
        if (cursor != mouse->def_cursor) {
slouken@5405
   459
            SDL_Cursor *found;
slouken@5405
   460
            for (found = mouse->cursors; found; found = found->next) {
slouken@5405
   461
                if (found == cursor) {
slouken@5405
   462
                    break;
slouken@5405
   463
                }
slouken@1895
   464
            }
slouken@5405
   465
            if (!found) {
slouken@5405
   466
                SDL_SetError("Cursor not associated with the current mouse");
slouken@5405
   467
                return;
slouken@5405
   468
            }
slouken@1895
   469
        }
slouken@1895
   470
        mouse->cur_cursor = cursor;
slouken@1895
   471
    } else {
ghostunderscore@6301
   472
        if (mouse->focus) {
ghostunderscore@6301
   473
            cursor = mouse->cur_cursor;
ghostunderscore@6301
   474
        } else {
ghostunderscore@6301
   475
            cursor = mouse->def_cursor;
ghostunderscore@6301
   476
        }
slouken@1895
   477
    }
slouken@1895
   478
slouken@1895
   479
    if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
slouken@1895
   480
        if (mouse->ShowCursor) {
slouken@1895
   481
            mouse->ShowCursor(cursor);
slouken@1895
   482
        }
slouken@1895
   483
    } else {
slouken@1895
   484
        if (mouse->ShowCursor) {
slouken@1895
   485
            mouse->ShowCursor(NULL);
slouken@1895
   486
        }
slouken@1895
   487
    }
slouken@1895
   488
}
slouken@1895
   489
slouken@1895
   490
SDL_Cursor *
slouken@1895
   491
SDL_GetCursor(void)
slouken@1895
   492
{
slouken@5371
   493
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   494
slouken@1895
   495
    if (!mouse) {
slouken@1895
   496
        return NULL;
slouken@1895
   497
    }
slouken@1895
   498
    return mouse->cur_cursor;
slouken@1895
   499
}
slouken@1895
   500
slouken@1895
   501
void
slouken@1895
   502
SDL_FreeCursor(SDL_Cursor * cursor)
slouken@1895
   503
{
slouken@5371
   504
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   505
    SDL_Cursor *curr, *prev;
slouken@1895
   506
slouken@1895
   507
    if (!cursor) {
slouken@1895
   508
        return;
slouken@1895
   509
    }
slouken@1895
   510
slouken@1895
   511
    if (cursor == mouse->def_cursor) {
slouken@1895
   512
        return;
slouken@1895
   513
    }
slouken@1895
   514
    if (cursor == mouse->cur_cursor) {
slouken@1895
   515
        SDL_SetCursor(mouse->def_cursor);
slouken@1895
   516
    }
slouken@1895
   517
slouken@1895
   518
    for (prev = NULL, curr = mouse->cursors; curr;
slouken@1895
   519
         prev = curr, curr = curr->next) {
slouken@1895
   520
        if (curr == cursor) {
slouken@1895
   521
            if (prev) {
slouken@1895
   522
                prev->next = curr->next;
slouken@1895
   523
            } else {
slouken@1895
   524
                mouse->cursors = curr->next;
slouken@1895
   525
            }
slouken@1895
   526
slouken@1895
   527
            if (mouse->FreeCursor) {
slouken@1895
   528
                mouse->FreeCursor(curr);
slouken@1895
   529
            }
slouken@1895
   530
            return;
slouken@1895
   531
        }
slouken@1895
   532
    }
slouken@1895
   533
}
slouken@1895
   534
slouken@1895
   535
int
slouken@1895
   536
SDL_ShowCursor(int toggle)
slouken@1895
   537
{
slouken@5371
   538
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   539
    SDL_bool shown;
slouken@1895
   540
slouken@1895
   541
    if (!mouse) {
slouken@1895
   542
        return 0;
slouken@1895
   543
    }
slouken@1895
   544
slouken@1895
   545
    shown = mouse->cursor_shown;
slouken@1895
   546
    if (toggle >= 0) {
slouken@1895
   547
        if (toggle) {
slouken@1895
   548
            mouse->cursor_shown = SDL_TRUE;
slouken@1895
   549
        } else {
slouken@1895
   550
            mouse->cursor_shown = SDL_FALSE;
slouken@1895
   551
        }
slouken@1895
   552
        if (mouse->cursor_shown != shown) {
slouken@1895
   553
            SDL_SetCursor(NULL);
slouken@1895
   554
        }
slouken@1895
   555
    }
slouken@1895
   556
    return shown;
slouken@1895
   557
}
slouken@1895
   558
slouken@1895
   559
/* vi: set ts=4 sw=4 expandtab: */