src/events/SDL_mouse.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 10 Jun 2009 14:00:21 +0000
changeset 3191 91b335df6fc8
parent 3188 102b7880543a
child 3195 08747e24a50f
permissions -rw-r--r--
Fixed bug #750
Since many different event structures include windowID it should be placed near
the beginning of the structure (preferably right after type) so it's position
is the same between different events.

This is to avoid code like this:
if (event.type == SDL_WINDOWEVENT)
win = event.window.windowID;
else if ((SDL_EVENTMASK(event.type) & SDL_KEYEVENTMASK) != 0)
win = event.key.windowID;
else if (event.type == SDL_TEXTINPUT)
win = event.text.windowID;
else if (event.type == SDL_MOUSEMOTION)
win = event.motion.windowID;
else if ((SDL_EVENTMASK(event.type) & (SDL_MOUBUTTONDOWNMASK |
SDL_MOUBUTTONUPMASK)) != 0)
win = event.button.windowID;
else if (event.type == SDL_MOUSEWHEEL)
win = event.wheel.windowID;
...

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