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