src/events/SDL_mouse.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 01 Jan 2017 18:33:28 -0800
changeset 10737 3406a0f8b041
parent 10676 5c4eaca2517a
child 10780 4ea5472ed455
permissions -rw-r--r--
Updated copyright for 2017
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 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
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@0
    22
slouken@0
    23
/* General mouse handling code for SDL */
slouken@0
    24
slouken@6666
    25
#include "SDL_assert.h"
slouken@8071
    26
#include "SDL_hints.h"
slouken@8066
    27
#include "SDL_timer.h"
slouken@0
    28
#include "SDL_events.h"
slouken@0
    29
#include "SDL_events_c.h"
slouken@1895
    30
#include "default_cursor.h"
slouken@3685
    31
#include "../video/SDL_sysvideo.h"
slouken@0
    32
gabomdq@7678
    33
/* #define DEBUG_MOUSE */
slouken@0
    34
slouken@5371
    35
/* The mouse state */
slouken@4465
    36
static SDL_Mouse SDL_mouse;
slouken@8066
    37
static Uint32 SDL_double_click_time = 500;
slouken@8066
    38
static int SDL_double_click_radius = 1;
slouken@0
    39
jorgen@7089
    40
static int
jorgen@7089
    41
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
slouken@0
    42
slouken@10673
    43
static void
slouken@10673
    44
SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
slouken@10673
    45
{
slouken@10673
    46
    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
slouken@10673
    47
slouken@10676
    48
    if (hint && *hint) {
slouken@10676
    49
        mouse->normal_speed_scale = (float)SDL_atof(hint);
slouken@10676
    50
    } else {
slouken@10676
    51
        mouse->normal_speed_scale = 1.0f;
slouken@10676
    52
    }
slouken@10673
    53
}
slouken@10673
    54
slouken@10673
    55
static void
slouken@10673
    56
SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
slouken@10673
    57
{
slouken@10673
    58
    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
slouken@10673
    59
slouken@10676
    60
    if (hint && *hint) {
slouken@10676
    61
        mouse->relative_speed_scale = (float)SDL_atof(hint);
slouken@10676
    62
    } else {
slouken@10676
    63
        mouse->relative_speed_scale = 1.0f;
slouken@10676
    64
    }
slouken@10673
    65
}
slouken@10673
    66
slouken@0
    67
/* Public functions */
slouken@1895
    68
int
slouken@1895
    69
SDL_MouseInit(void)
slouken@0
    70
{
slouken@5376
    71
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5376
    72
slouken@10673
    73
    SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
slouken@10673
    74
                        SDL_MouseNormalSpeedScaleChanged, mouse);
slouken@10673
    75
slouken@10673
    76
    SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
slouken@10673
    77
                        SDL_MouseRelativeSpeedScaleChanged, mouse);
slouken@10673
    78
slouken@5376
    79
    mouse->cursor_shown = SDL_TRUE;
slouken@5376
    80
slouken@1895
    81
    return (0);
slouken@1123
    82
}
slouken@0
    83
slouken@5405
    84
void
slouken@5405
    85
SDL_SetDefaultCursor(SDL_Cursor * cursor)
slouken@5405
    86
{
slouken@5405
    87
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5405
    88
slouken@5405
    89
    mouse->def_cursor = cursor;
slouken@5405
    90
    if (!mouse->cur_cursor) {
slouken@5405
    91
        SDL_SetCursor(cursor);
slouken@5405
    92
    }
slouken@5405
    93
}
slouken@5405
    94
slouken@5371
    95
SDL_Mouse *
slouken@5371
    96
SDL_GetMouse(void)
slouken@5371
    97
{
slouken@5371
    98
    return &SDL_mouse;
slouken@5371
    99
}
slouken@5371
   100
slouken@8066
   101
void
slouken@8066
   102
SDL_SetDoubleClickTime(Uint32 interval)
slouken@8066
   103
{
slouken@8066
   104
    SDL_double_click_time = interval;
slouken@8066
   105
}
slouken@8066
   106
slouken@4465
   107
SDL_Window *
slouken@4465
   108
SDL_GetMouseFocus(void)
slouken@2710
   109
{
slouken@5371
   110
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@2940
   111
slouken@4465
   112
    return mouse->focus;
slouken@0
   113
}
slouken@0
   114
slouken@10609
   115
#if 0
slouken@1895
   116
void
slouken@6666
   117
SDL_ResetMouse(void)
slouken@6666
   118
{
slouken@6666
   119
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@6666
   120
    Uint8 i;
slouken@6666
   121
slouken@6666
   122
#ifdef DEBUG_MOUSE
slouken@6666
   123
    printf("Resetting mouse\n");
slouken@6666
   124
#endif
slouken@6666
   125
    for (i = 1; i <= sizeof(mouse->buttonstate)*8; ++i) {
slouken@6666
   126
        if (mouse->buttonstate & SDL_BUTTON(i)) {
slouken@6950
   127
            SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, i);
slouken@6666
   128
        }
slouken@6666
   129
    }
slouken@6666
   130
    SDL_assert(mouse->buttonstate == 0);
slouken@6666
   131
}
slouken@10609
   132
#endif
slouken@6666
   133
slouken@6666
   134
void
slouken@4465
   135
SDL_SetMouseFocus(SDL_Window * window)
slouken@0
   136
{
slouken@5371
   137
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   138
slouken@4465
   139
    if (mouse->focus == window) {
slouken@1895
   140
        return;
slouken@1895
   141
    }
slouken@1895
   142
slouken@6829
   143
    /* Actually, this ends up being a bad idea, because most operating
slouken@6829
   144
       systems have an implicit grab when you press the mouse button down
slouken@6829
   145
       so you can drag things out of the window and then get the mouse up
slouken@6829
   146
       when it happens.  So, #if 0...
slouken@6829
   147
    */
slouken@6829
   148
#if 0
slouken@6666
   149
    if (mouse->focus && !window) {
slouken@6666
   150
        /* We won't get anymore mouse messages, so reset mouse state */
slouken@6666
   151
        SDL_ResetMouse();
slouken@6666
   152
    }
slouken@6829
   153
#endif
slouken@6666
   154
slouken@1895
   155
    /* See if the current window has lost focus */
slouken@1895
   156
    if (mouse->focus) {
slouken@4465
   157
        SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
slouken@1895
   158
    }
slouken@1895
   159
slouken@3685
   160
    mouse->focus = window;
slouken@1895
   161
slouken@1895
   162
    if (mouse->focus) {
slouken@4465
   163
        SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
slouken@1895
   164
    }
slouken@6666
   165
slouken@6666
   166
    /* Update cursor visibility */
slouken@6666
   167
    SDL_SetCursor(NULL);
slouken@6666
   168
}
slouken@6666
   169
slouken@6666
   170
/* Check to see if we need to synthesize focus events */
slouken@6666
   171
static SDL_bool
slouken@6673
   172
SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate)
slouken@6666
   173
{
slouken@6666
   174
    SDL_Mouse *mouse = SDL_GetMouse();
icculus@8927
   175
    SDL_bool inWindow = SDL_TRUE;
slouken@6666
   176
slouken@8983
   177
    if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) {
icculus@8927
   178
        int w, h;
icculus@8927
   179
        SDL_GetWindowSize(window, &w, &h);
icculus@8927
   180
        if (x < 0 || y < 0 || x >= w || y >= h) {
icculus@8927
   181
            inWindow = SDL_FALSE;
icculus@8927
   182
        }
slouken@6666
   183
    }
slouken@6667
   184
icculus@8783
   185
/* Linux doesn't give you mouse events outside your window unless you grab
icculus@8783
   186
   the pointer.
icculus@8783
   187
icculus@8783
   188
   Windows doesn't give you mouse events outside your window unless you call
icculus@8783
   189
   SetCapture().
icculus@8783
   190
icculus@8783
   191
   Both of these are slightly scary changes, so for now we'll punt and if the
icculus@8783
   192
   mouse leaves the window you'll lose mouse focus and reset button state.
icculus@8783
   193
*/
icculus@8783
   194
#ifdef SUPPORT_DRAG_OUTSIDE_WINDOW
icculus@8783
   195
    if (!inWindow && !buttonstate) {
icculus@8783
   196
#else
slouken@6667
   197
    if (!inWindow) {
icculus@8783
   198
#endif
slouken@6666
   199
        if (window == mouse->focus) {
slouken@6666
   200
#ifdef DEBUG_MOUSE
jorgen@7089
   201
            printf("Mouse left window, synthesizing move & focus lost event\n");
slouken@6666
   202
#endif
jorgen@7089
   203
            SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
slouken@6666
   204
            SDL_SetMouseFocus(NULL);
slouken@6666
   205
        }
slouken@6666
   206
        return SDL_FALSE;
slouken@6666
   207
    }
slouken@6666
   208
slouken@6666
   209
    if (window != mouse->focus) {
slouken@6666
   210
#ifdef DEBUG_MOUSE
jorgen@7097
   211
         printf("Mouse entered window, synthesizing focus gain & move event\n");
slouken@6666
   212
#endif
jorgen@7097
   213
         SDL_SetMouseFocus(window);
jorgen@7097
   214
         SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
slouken@6666
   215
    }
slouken@6666
   216
    return SDL_TRUE;
slouken@1895
   217
}
slouken@1895
   218
slouken@1895
   219
int
slouken@6950
   220
SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y)
slouken@1895
   221
{
jorgen@7089
   222
    if (window && !relative) {
jorgen@7089
   223
        SDL_Mouse *mouse = SDL_GetMouse();
jorgen@7089
   224
        if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) {
jorgen@7089
   225
            return 0;
jorgen@7089
   226
        }
jorgen@7089
   227
    }
jorgen@7089
   228
jorgen@7089
   229
    return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y);
jorgen@7089
   230
}
jorgen@7089
   231
jorgen@7089
   232
static int
slouken@10673
   233
GetScaledMouseDelta(float scale, int value, float *accum)
slouken@10673
   234
{
slouken@10673
   235
    if (scale != 1.0f) {
slouken@10673
   236
        *accum += scale * value;
slouken@10673
   237
        if (*accum >= 0.0f) {
slouken@10673
   238
            value = (int)SDL_floor(*accum);
slouken@10673
   239
        } else {
slouken@10673
   240
            value = (int)SDL_ceil(*accum);
slouken@10673
   241
        }
slouken@10673
   242
        *accum -= value;
slouken@10673
   243
    }
slouken@10673
   244
    return value;
slouken@10673
   245
}
slouken@10673
   246
slouken@10673
   247
static int
jorgen@7089
   248
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y)
jorgen@7089
   249
{
slouken@5371
   250
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   251
    int posted;
slouken@1895
   252
    int xrel;
slouken@1895
   253
    int yrel;
slouken@1895
   254
slouken@8071
   255
    if (mouse->relative_mode_warp) {
slouken@8071
   256
        int center_x = 0, center_y = 0;
slouken@8071
   257
        SDL_GetWindowSize(window, &center_x, &center_y);
slouken@8071
   258
        center_x /= 2;
slouken@8071
   259
        center_y /= 2;
slouken@8071
   260
        if (x == center_x && y == center_y) {
slouken@8071
   261
            mouse->last_x = center_x;
slouken@8071
   262
            mouse->last_y = center_y;
slouken@8071
   263
            return 0;
slouken@8071
   264
        }
slouken@8071
   265
        SDL_WarpMouseInWindow(window, center_x, center_y);
slouken@8071
   266
    }
slouken@8071
   267
slouken@2842
   268
    if (relative) {
slouken@10673
   269
        if (mouse->relative_mode) {
slouken@10673
   270
            x = GetScaledMouseDelta(mouse->relative_speed_scale, x, &mouse->scale_accum_x);
slouken@10673
   271
            y = GetScaledMouseDelta(mouse->relative_speed_scale, y, &mouse->scale_accum_y);
slouken@10673
   272
        } else {
slouken@10673
   273
            x = GetScaledMouseDelta(mouse->normal_speed_scale, x, &mouse->scale_accum_x);
slouken@10673
   274
            y = GetScaledMouseDelta(mouse->normal_speed_scale, y, &mouse->scale_accum_y);
slouken@10673
   275
        }
slouken@2842
   276
        xrel = x;
slouken@2842
   277
        yrel = y;
slouken@8071
   278
        x = (mouse->last_x + xrel);
slouken@8071
   279
        y = (mouse->last_y + yrel);
slouken@2842
   280
    } else {
slouken@2860
   281
        xrel = x - mouse->last_x;
slouken@2860
   282
        yrel = y - mouse->last_y;
slouken@2842
   283
    }
slouken@2710
   284
slouken@1895
   285
    /* Drop events that don't change state */
slouken@1895
   286
    if (!xrel && !yrel) {
slouken@6666
   287
#ifdef DEBUG_MOUSE
slouken@1895
   288
        printf("Mouse event didn't change state - dropped!\n");
slouken@1895
   289
#endif
slouken@1895
   290
        return 0;
slouken@1895
   291
    }
slouken@1895
   292
slouken@2710
   293
    /* Update internal mouse coordinates */
slouken@8071
   294
    if (!mouse->relative_mode) {
slouken@1895
   295
        mouse->x = x;
slouken@1895
   296
        mouse->y = y;
slouken@2710
   297
    } else {
slouken@2860
   298
        mouse->x += xrel;
slouken@2860
   299
        mouse->y += yrel;
slouken@2860
   300
    }
slouken@2849
   301
icculus@8927
   302
    /* make sure that the pointers find themselves inside the windows,
icculus@8927
   303
       unless we have the mouse captured. */
slouken@8983
   304
    if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) {
icculus@8927
   305
        int x_max = 0, y_max = 0;
slouken@2849
   306
icculus@8927
   307
        // !!! FIXME: shouldn't this be (window) instead of (mouse->focus)?
icculus@8927
   308
        SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
icculus@8927
   309
        --x_max;
icculus@8927
   310
        --y_max;
slouken@2860
   311
icculus@8927
   312
        if (mouse->x > x_max) {
icculus@8927
   313
            mouse->x = x_max;
icculus@8927
   314
        }
icculus@8927
   315
        if (mouse->x < 0) {
icculus@8927
   316
            mouse->x = 0;
icculus@8927
   317
        }
icculus@8927
   318
icculus@8927
   319
        if (mouse->y > y_max) {
icculus@8927
   320
            mouse->y = y_max;
icculus@8927
   321
        }
icculus@8927
   322
        if (mouse->y < 0) {
icculus@8927
   323
            mouse->y = 0;
icculus@8927
   324
        }
slouken@2860
   325
    }
slouken@2860
   326
slouken@1895
   327
    mouse->xdelta += xrel;
slouken@1895
   328
    mouse->ydelta += yrel;
slouken@1895
   329
slouken@1895
   330
    /* Move the mouse cursor, if needed */
slouken@1895
   331
    if (mouse->cursor_shown && !mouse->relative_mode &&
slouken@1895
   332
        mouse->MoveCursor && mouse->cur_cursor) {
slouken@1895
   333
        mouse->MoveCursor(mouse->cur_cursor);
slouken@1895
   334
    }
slouken@1895
   335
slouken@1895
   336
    /* Post the event, if desired */
slouken@1895
   337
    posted = 0;
slouken@4465
   338
    if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) {
slouken@1895
   339
        SDL_Event event;
slouken@1895
   340
        event.motion.type = SDL_MOUSEMOTION;
slouken@4465
   341
        event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
slouken@6950
   342
        event.motion.which = mouseID;
slouken@1895
   343
        event.motion.state = mouse->buttonstate;
slouken@1895
   344
        event.motion.x = mouse->x;
slouken@1895
   345
        event.motion.y = mouse->y;
slouken@1895
   346
        event.motion.xrel = xrel;
slouken@1895
   347
        event.motion.yrel = yrel;
slouken@1895
   348
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   349
    }
slouken@9448
   350
    if (relative) {
slouken@9448
   351
        mouse->last_x = mouse->x;
slouken@9448
   352
        mouse->last_y = mouse->y;
slouken@9448
   353
    } else {
slouken@9448
   354
        /* Use unclamped values if we're getting events outside the window */
slouken@9448
   355
        mouse->last_x = x;
slouken@9448
   356
        mouse->last_y = y;
slouken@9448
   357
    }
slouken@1895
   358
    return posted;
slouken@1895
   359
}
slouken@1895
   360
slouken@8066
   361
static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
slouken@8066
   362
{
slouken@8066
   363
    if (button >= mouse->num_clickstates) {
slouken@8066
   364
        int i, count = button + 1;
philipp@9334
   365
        SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
philipp@9334
   366
        if (!clickstate) {
slouken@8066
   367
            return NULL;
slouken@8066
   368
        }
philipp@9334
   369
        mouse->clickstate = clickstate;
slouken@8066
   370
slouken@8066
   371
        for (i = mouse->num_clickstates; i < count; ++i) {
slouken@8066
   372
            SDL_zero(mouse->clickstate[i]);
slouken@8066
   373
        }
slouken@8066
   374
        mouse->num_clickstates = count;
slouken@8066
   375
    }
slouken@8066
   376
    return &mouse->clickstate[button];
slouken@8066
   377
}
slouken@8066
   378
slime73@10366
   379
static int
slime73@10366
   380
SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
slouken@1895
   381
{
slouken@5371
   382
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   383
    int posted;
slouken@4429
   384
    Uint32 type;
slouken@6673
   385
    Uint32 buttonstate = mouse->buttonstate;
slouken@4484
   386
slouken@1895
   387
    /* Figure out which event to perform */
slouken@1895
   388
    switch (state) {
slouken@1895
   389
    case SDL_PRESSED:
slouken@1895
   390
        type = SDL_MOUSEBUTTONDOWN;
slouken@6666
   391
        buttonstate |= SDL_BUTTON(button);
slouken@1895
   392
        break;
slouken@1895
   393
    case SDL_RELEASED:
slouken@1895
   394
        type = SDL_MOUSEBUTTONUP;
slouken@6666
   395
        buttonstate &= ~SDL_BUTTON(button);
slouken@1895
   396
        break;
slouken@1895
   397
    default:
slouken@1895
   398
        /* Invalid state -- bail */
slouken@1895
   399
        return 0;
slouken@1895
   400
    }
slouken@1895
   401
slouken@6666
   402
    /* We do this after calculating buttonstate so button presses gain focus */
slouken@6666
   403
    if (window && state == SDL_PRESSED) {
slouken@6666
   404
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
slouken@6666
   405
    }
slouken@6666
   406
slouken@6666
   407
    if (buttonstate == mouse->buttonstate) {
slouken@6666
   408
        /* Ignore this event, no state change */
slouken@6666
   409
        return 0;
slouken@6666
   410
    }
slouken@6666
   411
    mouse->buttonstate = buttonstate;
slouken@6666
   412
slime73@10366
   413
    if (clicks < 0) {
slime73@10366
   414
        SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
philipp@10390
   415
        if (clickstate) {
philipp@10390
   416
            if (state == SDL_PRESSED) {
philipp@10390
   417
                Uint32 now = SDL_GetTicks();
slouken@8066
   418
philipp@10390
   419
                if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
philipp@10390
   420
                    SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
philipp@10390
   421
                    SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
philipp@10390
   422
                    clickstate->click_count = 0;
philipp@10390
   423
                }
philipp@10390
   424
                clickstate->last_timestamp = now;
philipp@10390
   425
                clickstate->last_x = mouse->x;
philipp@10390
   426
                clickstate->last_y = mouse->y;
philipp@10390
   427
                if (clickstate->click_count < 255) {
philipp@10390
   428
                    ++clickstate->click_count;
philipp@10390
   429
                }
slouken@8066
   430
            }
philipp@10390
   431
            clicks = clickstate->click_count;
philipp@10390
   432
        } else {
philipp@10390
   433
            clicks = 1;
slouken@8066
   434
        }
slouken@8066
   435
    }
slouken@8066
   436
slouken@1895
   437
    /* Post the event, if desired */
slouken@1895
   438
    posted = 0;
slouken@4429
   439
    if (SDL_GetEventState(type) == SDL_ENABLE) {
slouken@1895
   440
        SDL_Event event;
slouken@1895
   441
        event.type = type;
slouken@6950
   442
        event.button.windowID = mouse->focus ? mouse->focus->id : 0;
slouken@6950
   443
        event.button.which = mouseID;
slouken@1895
   444
        event.button.state = state;
slouken@1895
   445
        event.button.button = button;
slime73@10366
   446
        event.button.clicks = (Uint8) SDL_min(clicks, 255);
slouken@1895
   447
        event.button.x = mouse->x;
slouken@1895
   448
        event.button.y = mouse->y;
slouken@1895
   449
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   450
    }
slouken@6666
   451
slouken@6666
   452
    /* We do this after dispatching event so button releases can lose focus */
slouken@6666
   453
    if (window && state == SDL_RELEASED) {
slouken@6666
   454
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
slouken@6666
   455
    }
slime73@10366
   456
    
slime73@10366
   457
    return posted;
slime73@10366
   458
}
slouken@6666
   459
slime73@10366
   460
int
slime73@10366
   461
SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
slime73@10366
   462
{
slime73@10366
   463
    clicks = SDL_max(clicks, 0);
slime73@10366
   464
    return SDL_PrivateSendMouseButton(window, mouseID, state, button, clicks);
slime73@10366
   465
}
slime73@10366
   466
slime73@10366
   467
int
slime73@10366
   468
SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
slime73@10366
   469
{
slime73@10366
   470
    return SDL_PrivateSendMouseButton(window, mouseID, state, button, -1);
slouken@1895
   471
}
slouken@1895
   472
slouken@1895
   473
int
urkle@9257
   474
SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction)
slouken@1895
   475
{
slouken@5371
   476
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   477
    int posted;
slouken@1895
   478
slouken@4484
   479
    if (window) {
slouken@4484
   480
        SDL_SetMouseFocus(window);
slouken@4484
   481
    }
slouken@4484
   482
slouken@4465
   483
    if (!x && !y) {
slouken@1895
   484
        return 0;
slouken@1895
   485
    }
slouken@1895
   486
slouken@1895
   487
    /* Post the event, if desired */
slouken@1895
   488
    posted = 0;
slouken@4429
   489
    if (SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE) {
slouken@1895
   490
        SDL_Event event;
slouken@1895
   491
        event.type = SDL_MOUSEWHEEL;
slouken@4465
   492
        event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
slouken@6950
   493
        event.wheel.which = mouseID;
slouken@2152
   494
        event.wheel.x = x;
slouken@2152
   495
        event.wheel.y = y;
urkle@9257
   496
        event.wheel.direction = (Uint32)direction;
slouken@1895
   497
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   498
    }
slouken@1895
   499
    return posted;
slouken@1895
   500
}
slouken@1895
   501
slouken@1895
   502
void
slouken@4465
   503
SDL_MouseQuit(void)
slouken@4465
   504
{
slouken@7493
   505
    SDL_Cursor *cursor, *next;
slouken@7493
   506
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@7493
   507
slouken@9161
   508
    if (mouse->CaptureMouse) {
slouken@9161
   509
        SDL_CaptureMouse(SDL_FALSE);
slouken@9161
   510
    }
slouken@8049
   511
    SDL_SetRelativeMouseMode(SDL_FALSE);
slouken@7493
   512
    SDL_ShowCursor(1);
slouken@7493
   513
slouken@7493
   514
    cursor = mouse->cursors;
slouken@7493
   515
    while (cursor) {
slouken@7493
   516
        next = cursor->next;
slouken@7493
   517
        SDL_FreeCursor(cursor);
slouken@7493
   518
        cursor = next;
slouken@7493
   519
    }
slouken@7493
   520
slouken@7493
   521
    if (mouse->def_cursor && mouse->FreeCursor) {
slouken@7493
   522
        mouse->FreeCursor(mouse->def_cursor);
slouken@7493
   523
    }
slouken@7493
   524
slouken@8066
   525
    if (mouse->clickstate) {
slouken@8066
   526
        SDL_free(mouse->clickstate);
slouken@8066
   527
    }
slouken@8066
   528
slouken@7493
   529
    SDL_zerop(mouse);
slouken@10673
   530
slouken@10673
   531
    SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
slouken@10673
   532
                        SDL_MouseNormalSpeedScaleChanged, mouse);
slouken@10673
   533
slouken@10673
   534
    SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
slouken@10673
   535
                        SDL_MouseRelativeSpeedScaleChanged, mouse);
slouken@4465
   536
}
slouken@4465
   537
slouken@6673
   538
Uint32
slouken@4465
   539
SDL_GetMouseState(int *x, int *y)
slouken@4465
   540
{
slouken@5371
   541
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   542
slouken@4465
   543
    if (x) {
slouken@4465
   544
        *x = mouse->x;
slouken@4465
   545
    }
slouken@4465
   546
    if (y) {
slouken@4465
   547
        *y = mouse->y;
slouken@4465
   548
    }
slouken@4465
   549
    return mouse->buttonstate;
slouken@4465
   550
}
slouken@4465
   551
slouken@6673
   552
Uint32
slouken@4465
   553
SDL_GetRelativeMouseState(int *x, int *y)
slouken@4465
   554
{
slouken@5371
   555
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   556
slouken@4465
   557
    if (x) {
slouken@4465
   558
        *x = mouse->xdelta;
slouken@4465
   559
    }
slouken@4465
   560
    if (y) {
slouken@4465
   561
        *y = mouse->ydelta;
slouken@4465
   562
    }
slouken@4465
   563
    mouse->xdelta = 0;
slouken@4465
   564
    mouse->ydelta = 0;
slouken@4465
   565
    return mouse->buttonstate;
slouken@4465
   566
}
slouken@4465
   567
icculus@8945
   568
Uint32
icculus@8952
   569
SDL_GetGlobalMouseState(int *x, int *y)
icculus@8945
   570
{
icculus@8945
   571
    SDL_Mouse *mouse = SDL_GetMouse();
icculus@8945
   572
    int tmpx, tmpy;
icculus@8945
   573
icculus@8945
   574
    /* make sure these are never NULL for the backend implementations... */
icculus@8945
   575
    if (!x) {
icculus@8945
   576
        x = &tmpx;
icculus@8945
   577
    }
icculus@8945
   578
    if (!y) {
icculus@8945
   579
        y = &tmpy;
icculus@8945
   580
    }
icculus@8945
   581
icculus@8945
   582
    *x = *y = 0;
icculus@8945
   583
icculus@8952
   584
    if (!mouse->GetGlobalMouseState) {
icculus@8945
   585
        SDL_assert(0 && "This should really be implemented for every target.");
icculus@8945
   586
        return 0;
icculus@8945
   587
    }
icculus@8945
   588
icculus@8952
   589
    return mouse->GetGlobalMouseState(x, y);
icculus@8945
   590
}
icculus@8945
   591
slouken@4465
   592
void
slouken@3685
   593
SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
slouken@1895
   594
{
slouken@5371
   595
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@7191
   596
icculus@8953
   597
    if (window == NULL) {
slouken@7191
   598
        window = mouse->focus;
icculus@8944
   599
    }
slouken@7191
   600
icculus@8953
   601
    if (window == NULL) {
slouken@7191
   602
        return;
icculus@8944
   603
    }
slouken@1895
   604
slouken@1895
   605
    if (mouse->WarpMouse) {
slouken@5371
   606
        mouse->WarpMouse(window, x, y);
slouken@1895
   607
    } else {
slouken@6950
   608
        SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y);
slouken@1895
   609
    }
slouken@1895
   610
}
slouken@1895
   611
icculus@9807
   612
int
slouken@8815
   613
SDL_WarpMouseGlobal(int x, int y)
slouken@8815
   614
{
slouken@8815
   615
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@8815
   616
slouken@8815
   617
    if (mouse->WarpMouseGlobal) {
icculus@9807
   618
        return mouse->WarpMouseGlobal(x, y);
slouken@8815
   619
    }
icculus@9807
   620
icculus@9807
   621
    return SDL_Unsupported();
slouken@8815
   622
}
slouken@8815
   623
slouken@8071
   624
static SDL_bool
slouken@8071
   625
ShouldUseRelativeModeWarp(SDL_Mouse *mouse)
slouken@8071
   626
{
slouken@8071
   627
    if (!mouse->SetRelativeMouseMode) {
slouken@8071
   628
        return SDL_TRUE;
slouken@8071
   629
    }
slouken@8071
   630
slouken@10499
   631
    return SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE);
slouken@8071
   632
}
slouken@8071
   633
slouken@4465
   634
int
slouken@4465
   635
SDL_SetRelativeMouseMode(SDL_bool enabled)
slouken@4465
   636
{
slouken@5371
   637
    SDL_Mouse *mouse = SDL_GetMouse();
jorgen@7107
   638
    SDL_Window *focusWindow = SDL_GetKeyboardFocus();
slouken@4465
   639
slouken@5406
   640
    if (enabled == mouse->relative_mode) {
slouken@5406
   641
        return 0;
slouken@5406
   642
    }
slouken@5406
   643
jorgen@7107
   644
    if (enabled && focusWindow) {
jorgen@7107
   645
        /* Center it in the focused window to prevent clicks from going through
jorgen@7107
   646
         * to background windows.
jorgen@7107
   647
         */
jorgen@7107
   648
        SDL_SetMouseFocus(focusWindow);
jorgen@7107
   649
        SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
jorgen@7107
   650
    }
jorgen@7107
   651
slouken@8071
   652
    /* Set the relative mode */
slouken@8071
   653
    if (!enabled && mouse->relative_mode_warp) {
slouken@8071
   654
        mouse->relative_mode_warp = SDL_FALSE;
slouken@8071
   655
    } else if (enabled && ShouldUseRelativeModeWarp(mouse)) {
slouken@8071
   656
        mouse->relative_mode_warp = SDL_TRUE;
slouken@8071
   657
    } else if (mouse->SetRelativeMouseMode(enabled) < 0) {
slouken@8269
   658
        if (enabled) {
philipp@8776
   659
            /* Fall back to warp mode if native relative mode failed */
slouken@8269
   660
            mouse->relative_mode_warp = SDL_TRUE;
slouken@8269
   661
        }
slouken@5406
   662
    }
slouken@4465
   663
    mouse->relative_mode = enabled;
slouken@10673
   664
    mouse->scale_accum_x = 0.0f;
slouken@10673
   665
    mouse->scale_accum_y = 0.0f;
slouken@4465
   666
slouken@8071
   667
    if (mouse->focus) {
slouken@8071
   668
        SDL_UpdateWindowGrab(mouse->focus);
slouken@8071
   669
slouken@8071
   670
        /* Put the cursor back to where the application expects it */
slouken@8071
   671
        if (!enabled) {
slouken@8071
   672
            SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
slouken@8071
   673
        }
slouken@4465
   674
    }
slouken@4465
   675
slouken@8071
   676
    /* Flush pending mouse motion - ideally we would pump events, but that's not always safe */
slouken@5406
   677
    SDL_FlushEvent(SDL_MOUSEMOTION);
slouken@5406
   678
slouken@4465
   679
    /* Update cursor visibility */
slouken@4465
   680
    SDL_SetCursor(NULL);
slouken@4465
   681
slouken@4465
   682
    return 0;
slouken@4465
   683
}
slouken@4465
   684
slouken@4465
   685
SDL_bool
slouken@4465
   686
SDL_GetRelativeMouseMode()
slouken@4465
   687
{
slouken@5371
   688
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@4465
   689
slouken@4465
   690
    return mouse->relative_mode;
slouken@4465
   691
}
slouken@4465
   692
icculus@8955
   693
int
icculus@8955
   694
SDL_CaptureMouse(SDL_bool enabled)
icculus@8955
   695
{
icculus@8955
   696
    SDL_Mouse *mouse = SDL_GetMouse();
icculus@8955
   697
    SDL_Window *focusWindow;
icculus@8955
   698
    SDL_bool isCaptured;
icculus@8955
   699
icculus@8955
   700
    if (!mouse->CaptureMouse) {
icculus@8955
   701
        return SDL_Unsupported();
icculus@8955
   702
    }
icculus@8955
   703
icculus@8955
   704
    focusWindow = SDL_GetKeyboardFocus();
icculus@8955
   705
icculus@8955
   706
    isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE);
icculus@8955
   707
    if (isCaptured == enabled) {
icculus@8955
   708
        return 0;  /* already done! */
icculus@8955
   709
    }
icculus@8955
   710
icculus@8955
   711
    if (enabled) {
icculus@8955
   712
        if (!focusWindow) {
icculus@8955
   713
            return SDL_SetError("No window has focus");
icculus@8955
   714
        } else if (mouse->CaptureMouse(focusWindow) == -1) {
icculus@8955
   715
            return -1;  /* CaptureMouse() should call SetError */
icculus@8955
   716
        }
icculus@8955
   717
        focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE;
icculus@8955
   718
    } else {
icculus@8955
   719
        if (mouse->CaptureMouse(NULL) == -1) {
icculus@8955
   720
            return -1;  /* CaptureMouse() should call SetError */
icculus@8955
   721
        }
icculus@8955
   722
        focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
icculus@8955
   723
    }
icculus@8955
   724
icculus@8955
   725
    return 0;
icculus@8955
   726
}
icculus@8955
   727
slouken@1895
   728
SDL_Cursor *
slouken@1895
   729
SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
slouken@1895
   730
                 int w, int h, int hot_x, int hot_y)
slouken@1895
   731
{
slouken@1895
   732
    SDL_Surface *surface;
slouken@1895
   733
    SDL_Cursor *cursor;
slouken@1895
   734
    int x, y;
slouken@1895
   735
    Uint32 *pixel;
slouken@4465
   736
    Uint8 datab = 0, maskb = 0;
slouken@1895
   737
    const Uint32 black = 0xFF000000;
slouken@1895
   738
    const Uint32 white = 0xFFFFFFFF;
slouken@1895
   739
    const Uint32 transparent = 0x00000000;
slouken@1895
   740
slouken@1895
   741
    /* Make sure the width is a multiple of 8 */
slouken@1895
   742
    w = ((w + 7) & ~7);
slouken@1895
   743
slouken@1895
   744
    /* Create the surface from a bitmap */
slouken@5473
   745
    surface = SDL_CreateRGBSurface(0, w, h, 32,
slouken@5473
   746
                                   0x00FF0000,
slouken@5473
   747
                                   0x0000FF00,
slouken@5473
   748
                                   0x000000FF,
slouken@5473
   749
                                   0xFF000000);
slouken@1895
   750
    if (!surface) {
slouken@1895
   751
        return NULL;
slouken@1895
   752
    }
slouken@1895
   753
    for (y = 0; y < h; ++y) {
slouken@1895
   754
        pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
slouken@1895
   755
        for (x = 0; x < w; ++x) {
slouken@1895
   756
            if ((x % 8) == 0) {
slouken@1895
   757
                datab = *data++;
slouken@1895
   758
                maskb = *mask++;
slouken@1895
   759
            }
slouken@1895
   760
            if (maskb & 0x80) {
slouken@1895
   761
                *pixel++ = (datab & 0x80) ? black : white;
slouken@1895
   762
            } else {
slouken@1895
   763
                *pixel++ = (datab & 0x80) ? black : transparent;
slouken@1895
   764
            }
slouken@1895
   765
            datab <<= 1;
slouken@1895
   766
            maskb <<= 1;
slouken@1895
   767
        }
slouken@1895
   768
    }
slouken@1895
   769
slouken@5473
   770
    cursor = SDL_CreateColorCursor(surface, hot_x, hot_y);
slouken@5473
   771
slouken@5473
   772
    SDL_FreeSurface(surface);
slouken@5473
   773
slouken@5473
   774
    return cursor;
slouken@5473
   775
}
slouken@5473
   776
slouken@5473
   777
SDL_Cursor *
slouken@5473
   778
SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
slouken@5473
   779
{
slouken@5473
   780
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@5473
   781
    SDL_Surface *temp = NULL;
slouken@5473
   782
    SDL_Cursor *cursor;
slouken@5473
   783
slouken@5473
   784
    if (!surface) {
slouken@5473
   785
        SDL_SetError("Passed NULL cursor surface");
slouken@5473
   786
        return NULL;
slouken@5473
   787
    }
slouken@5473
   788
slouken@5473
   789
    if (!mouse->CreateCursor) {
slouken@5473
   790
        SDL_SetError("Cursors are not currently supported");
slouken@5473
   791
        return NULL;
slouken@5473
   792
    }
slouken@5473
   793
slouken@5473
   794
    /* Sanity check the hot spot */
slouken@5473
   795
    if ((hot_x < 0) || (hot_y < 0) ||
slouken@5473
   796
        (hot_x >= surface->w) || (hot_y >= surface->h)) {
slouken@5473
   797
        SDL_SetError("Cursor hot spot doesn't lie within cursor");
slouken@5473
   798
        return NULL;
slouken@5473
   799
    }
slouken@5473
   800
slouken@5473
   801
    if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
slouken@5473
   802
        temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
slouken@5473
   803
        if (!temp) {
slouken@5473
   804
            return NULL;
slouken@5473
   805
        }
slouken@5473
   806
        surface = temp;
slouken@5473
   807
    }
slouken@5473
   808
slouken@1895
   809
    cursor = mouse->CreateCursor(surface, hot_x, hot_y);
slouken@1895
   810
    if (cursor) {
slouken@1895
   811
        cursor->next = mouse->cursors;
slouken@1895
   812
        mouse->cursors = cursor;
slouken@1895
   813
    }
slouken@1895
   814
slouken@7720
   815
    SDL_FreeSurface(temp);
slouken@1895
   816
slouken@1895
   817
    return cursor;
slouken@1895
   818
}
slouken@1895
   819
mikesart@6675
   820
SDL_Cursor *
mikesart@6675
   821
SDL_CreateSystemCursor(SDL_SystemCursor id)
mikesart@6675
   822
{
mikesart@6675
   823
    SDL_Mouse *mouse = SDL_GetMouse();
mikesart@6675
   824
    SDL_Cursor *cursor;
mikesart@6675
   825
mikesart@6675
   826
    if (!mouse->CreateSystemCursor) {
mikesart@6675
   827
        SDL_SetError("CreateSystemCursor is not currently supported");
mikesart@6675
   828
        return NULL;
mikesart@6675
   829
    }
mikesart@6675
   830
slouken@7191
   831
    cursor = mouse->CreateSystemCursor(id);
mikesart@6675
   832
    if (cursor) {
mikesart@6675
   833
        cursor->next = mouse->cursors;
mikesart@6675
   834
        mouse->cursors = cursor;
mikesart@6675
   835
    }
mikesart@6675
   836
slouken@7191
   837
    return cursor;
mikesart@6675
   838
}
mikesart@6675
   839
slouken@1895
   840
/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
slouken@1895
   841
   if this is desired for any reason.  This is used when setting
slouken@1895
   842
   the video mode and when the SDL window gains the mouse focus.
slouken@1895
   843
 */
slouken@1895
   844
void
slouken@1895
   845
SDL_SetCursor(SDL_Cursor * cursor)
slouken@1895
   846
{
slouken@5371
   847
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   848
slouken@1895
   849
    /* Set the new cursor */
slouken@1895
   850
    if (cursor) {
slouken@1895
   851
        /* Make sure the cursor is still valid for this mouse */
slouken@5405
   852
        if (cursor != mouse->def_cursor) {
slouken@5405
   853
            SDL_Cursor *found;
slouken@5405
   854
            for (found = mouse->cursors; found; found = found->next) {
slouken@5405
   855
                if (found == cursor) {
slouken@5405
   856
                    break;
slouken@5405
   857
                }
slouken@1895
   858
            }
slouken@5405
   859
            if (!found) {
slouken@5405
   860
                SDL_SetError("Cursor not associated with the current mouse");
slouken@5405
   861
                return;
slouken@5405
   862
            }
slouken@1895
   863
        }
slouken@1895
   864
        mouse->cur_cursor = cursor;
slouken@1895
   865
    } else {
ghostunderscore@6301
   866
        if (mouse->focus) {
ghostunderscore@6301
   867
            cursor = mouse->cur_cursor;
ghostunderscore@6301
   868
        } else {
ghostunderscore@6301
   869
            cursor = mouse->def_cursor;
ghostunderscore@6301
   870
        }
slouken@1895
   871
    }
slouken@1895
   872
slouken@1895
   873
    if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
slouken@1895
   874
        if (mouse->ShowCursor) {
slouken@1895
   875
            mouse->ShowCursor(cursor);
slouken@1895
   876
        }
slouken@1895
   877
    } else {
slouken@1895
   878
        if (mouse->ShowCursor) {
slouken@1895
   879
            mouse->ShowCursor(NULL);
slouken@1895
   880
        }
slouken@1895
   881
    }
slouken@1895
   882
}
slouken@1895
   883
slouken@1895
   884
SDL_Cursor *
slouken@1895
   885
SDL_GetCursor(void)
slouken@1895
   886
{
slouken@5371
   887
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   888
slouken@1895
   889
    if (!mouse) {
slouken@1895
   890
        return NULL;
slouken@1895
   891
    }
slouken@1895
   892
    return mouse->cur_cursor;
slouken@1895
   893
}
slouken@1895
   894
jorgen@7104
   895
SDL_Cursor *
jorgen@7104
   896
SDL_GetDefaultCursor(void)
jorgen@7104
   897
{
jorgen@7104
   898
    SDL_Mouse *mouse = SDL_GetMouse();
jorgen@7104
   899
jorgen@7104
   900
    if (!mouse) {
jorgen@7104
   901
        return NULL;
jorgen@7104
   902
    }
jorgen@7104
   903
    return mouse->def_cursor;
jorgen@7104
   904
}
jorgen@7104
   905
slouken@1895
   906
void
slouken@1895
   907
SDL_FreeCursor(SDL_Cursor * cursor)
slouken@1895
   908
{
slouken@5371
   909
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   910
    SDL_Cursor *curr, *prev;
slouken@1895
   911
slouken@1895
   912
    if (!cursor) {
slouken@1895
   913
        return;
slouken@1895
   914
    }
slouken@1895
   915
slouken@1895
   916
    if (cursor == mouse->def_cursor) {
slouken@1895
   917
        return;
slouken@1895
   918
    }
slouken@1895
   919
    if (cursor == mouse->cur_cursor) {
slouken@1895
   920
        SDL_SetCursor(mouse->def_cursor);
slouken@1895
   921
    }
slouken@1895
   922
slouken@1895
   923
    for (prev = NULL, curr = mouse->cursors; curr;
slouken@1895
   924
         prev = curr, curr = curr->next) {
slouken@1895
   925
        if (curr == cursor) {
slouken@1895
   926
            if (prev) {
slouken@1895
   927
                prev->next = curr->next;
slouken@1895
   928
            } else {
slouken@1895
   929
                mouse->cursors = curr->next;
slouken@1895
   930
            }
slouken@1895
   931
slouken@1895
   932
            if (mouse->FreeCursor) {
slouken@1895
   933
                mouse->FreeCursor(curr);
slouken@1895
   934
            }
slouken@1895
   935
            return;
slouken@1895
   936
        }
slouken@1895
   937
    }
slouken@1895
   938
}
slouken@1895
   939
slouken@1895
   940
int
slouken@1895
   941
SDL_ShowCursor(int toggle)
slouken@1895
   942
{
slouken@5371
   943
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@1895
   944
    SDL_bool shown;
slouken@1895
   945
slouken@1895
   946
    if (!mouse) {
slouken@1895
   947
        return 0;
slouken@1895
   948
    }
slouken@1895
   949
slouken@1895
   950
    shown = mouse->cursor_shown;
slouken@1895
   951
    if (toggle >= 0) {
slouken@1895
   952
        if (toggle) {
slouken@1895
   953
            mouse->cursor_shown = SDL_TRUE;
slouken@1895
   954
        } else {
slouken@1895
   955
            mouse->cursor_shown = SDL_FALSE;
slouken@1895
   956
        }
slouken@1895
   957
        if (mouse->cursor_shown != shown) {
slouken@1895
   958
            SDL_SetCursor(NULL);
slouken@1895
   959
        }
slouken@1895
   960
    }
slouken@1895
   961
    return shown;
slouken@1895
   962
}
slouken@1895
   963
jorgen@7097
   964
/* vi: set ts=4 sw=4 expandtab: */