src/events/SDL_mouse.c
author Sam Lantinga
Wed, 10 Jun 2009 13:34:20 +0000
changeset 3186 51750b7a966f
parent 3179 9b34679fda8b
child 3188 102b7880543a
permissions -rw-r--r--
indent
     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         event.proximity.windowID = mouse->focus;
   373         posted = (SDL_PushEvent(&event) > 0);
   374         if (type == SDL_PROXIMITYIN) {
   375             mouse->proximity = SDL_TRUE;
   376         } else {
   377             mouse->proximity = SDL_FALSE;
   378         }
   379     }
   380     return posted;
   381 }
   382 
   383 int
   384 SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
   385 {
   386     int index = SDL_GetMouseIndexId(id);
   387     SDL_Mouse *mouse = SDL_GetMouse(index);
   388     int posted;
   389     int xrel;
   390     int yrel;
   391     int x_max = 0, y_max = 0;
   392 
   393     if (!mouse || mouse->flush_motion) {
   394         return 0;
   395     }
   396 
   397     /* if the mouse is out of proximity we don't to want to have any motion from it */
   398     if (mouse->proximity == SDL_FALSE) {
   399         mouse->last_x = x;
   400         mouse->last_y = y;
   401         return 0;
   402     }
   403 
   404     /* the relative motion is calculated regarding the system cursor last position */
   405     if (relative) {
   406         xrel = x;
   407         yrel = y;
   408         x = (mouse->last_x + x);
   409         y = (mouse->last_y + y);
   410     } else {
   411         xrel = x - mouse->last_x;
   412         yrel = y - mouse->last_y;
   413     }
   414 
   415     /* Drop events that don't change state */
   416     if (!xrel && !yrel) {
   417 #if 0
   418         printf("Mouse event didn't change state - dropped!\n");
   419 #endif
   420         return 0;
   421     }
   422 
   423     /* Update internal mouse coordinates */
   424     if (mouse->relative_mode == SDL_FALSE) {
   425         mouse->x = x;
   426         mouse->y = y;
   427     } else {
   428         mouse->x += xrel;
   429         mouse->y += yrel;
   430     }
   431 
   432     SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
   433 
   434     /* make sure that the pointers find themselves inside the windows */
   435     /* only check if mouse->xmax is set ! */
   436     if (x_max && mouse->x > x_max) {
   437         mouse->x = x_max;
   438     } else if (mouse->x < 0) {
   439         mouse->x = 0;
   440     }
   441 
   442     if (y_max && mouse->y > y_max) {
   443         mouse->y = y_max;
   444     } else if (mouse->y < 0) {
   445         mouse->y = 0;
   446     }
   447 
   448     mouse->xdelta += xrel;
   449     mouse->ydelta += yrel;
   450     mouse->pressure = pressure;
   451 
   452     /* Move the mouse cursor, if needed */
   453     if (mouse->cursor_shown && !mouse->relative_mode &&
   454         mouse->MoveCursor && mouse->cur_cursor) {
   455         mouse->MoveCursor(mouse->cur_cursor);
   456     }
   457 
   458     /* Post the event, if desired */
   459     posted = 0;
   460     if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE &&
   461         mouse->proximity == SDL_TRUE) {
   462         SDL_Event event;
   463         event.motion.type = SDL_MOUSEMOTION;
   464         event.motion.which = (Uint8) index;
   465         event.motion.state = mouse->buttonstate;
   466         event.motion.x = mouse->x;
   467         event.motion.y = mouse->y;
   468         event.motion.z = mouse->z;
   469         event.motion.pressure = mouse->pressure;
   470         event.motion.pressure_max = mouse->pressure_max;
   471         event.motion.pressure_min = mouse->pressure_min;
   472         event.motion.rotation = 0;
   473         event.motion.tilt = 0;
   474         event.motion.cursor = mouse->current_end;
   475         event.motion.xrel = xrel;
   476         event.motion.yrel = yrel;
   477         event.motion.windowID = mouse->focus;
   478         posted = (SDL_PushEvent(&event) > 0);
   479     }
   480     mouse->last_x = mouse->x;
   481     mouse->last_y = mouse->y;
   482     return posted;
   483 }
   484 
   485 int
   486 SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
   487 {
   488     int index = SDL_GetMouseIndexId(id);
   489     SDL_Mouse *mouse = SDL_GetMouse(index);
   490     int posted;
   491     Uint8 type;
   492 
   493     if (!mouse) {
   494         return 0;
   495     }
   496 
   497     /* Figure out which event to perform */
   498     switch (state) {
   499     case SDL_PRESSED:
   500         if (mouse->buttonstate & SDL_BUTTON(button)) {
   501             /* Ignore this event, no state change */
   502             return 0;
   503         }
   504         type = SDL_MOUSEBUTTONDOWN;
   505         mouse->buttonstate |= SDL_BUTTON(button);
   506         break;
   507     case SDL_RELEASED:
   508         if (!(mouse->buttonstate & SDL_BUTTON(button))) {
   509             /* Ignore this event, no state change */
   510             return 0;
   511         }
   512         type = SDL_MOUSEBUTTONUP;
   513         mouse->buttonstate &= ~SDL_BUTTON(button);
   514         break;
   515     default:
   516         /* Invalid state -- bail */
   517         return 0;
   518     }
   519 
   520     /* Post the event, if desired */
   521     posted = 0;
   522     if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   523         SDL_Event event;
   524         event.type = type;
   525         event.button.which = (Uint8) index;
   526         event.button.state = state;
   527         event.button.button = button;
   528         event.button.x = mouse->x;
   529         event.button.y = mouse->y;
   530         event.button.windowID = mouse->focus;
   531         posted = (SDL_PushEvent(&event) > 0);
   532     }
   533     return posted;
   534 }
   535 
   536 int
   537 SDL_SendMouseWheel(int index, int x, int y)
   538 {
   539     SDL_Mouse *mouse = SDL_GetMouse(index);
   540     int posted;
   541 
   542     if (!mouse || (!x && !y)) {
   543         return 0;
   544     }
   545 
   546     /* Post the event, if desired */
   547     posted = 0;
   548     if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
   549         SDL_Event event;
   550         event.type = SDL_MOUSEWHEEL;
   551         event.wheel.which = (Uint8) index;
   552         event.wheel.x = x;
   553         event.wheel.y = y;
   554         event.wheel.windowID = mouse->focus;
   555         posted = (SDL_PushEvent(&event) > 0);
   556     }
   557     return posted;
   558 }
   559 
   560 void
   561 SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
   562 {
   563     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   564 
   565     if (!mouse) {
   566         return;
   567     }
   568 
   569     if (mouse->WarpMouse) {
   570         mouse->WarpMouse(mouse, windowID, x, y);
   571     } else {
   572         SDL_SetMouseFocus(SDL_current_mouse, windowID);
   573         SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
   574     }
   575 }
   576 
   577 SDL_Cursor *
   578 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
   579                  int w, int h, int hot_x, int hot_y)
   580 {
   581     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   582     SDL_Surface *surface;
   583     SDL_Cursor *cursor;
   584     int x, y;
   585     Uint32 *pixel;
   586     Uint8 datab, maskb;
   587     const Uint32 black = 0xFF000000;
   588     const Uint32 white = 0xFFFFFFFF;
   589     const Uint32 transparent = 0x00000000;
   590 
   591     if (!mouse) {
   592         SDL_SetError("No mice are initialized");
   593         return NULL;
   594     }
   595 
   596     if (!mouse->CreateCursor) {
   597         SDL_SetError("Current mouse doesn't have cursor support");
   598         return NULL;
   599     }
   600 
   601     /* Sanity check the hot spot */
   602     if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
   603         SDL_SetError("Cursor hot spot doesn't lie within cursor");
   604         return NULL;
   605     }
   606 
   607     /* Make sure the width is a multiple of 8 */
   608     w = ((w + 7) & ~7);
   609 
   610     /* Create the surface from a bitmap */
   611     surface =
   612         SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
   613                              0xFF000000);
   614     if (!surface) {
   615         return NULL;
   616     }
   617     for (y = 0; y < h; ++y) {
   618         pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
   619         for (x = 0; x < w; ++x) {
   620             if ((x % 8) == 0) {
   621                 datab = *data++;
   622                 maskb = *mask++;
   623             }
   624             if (maskb & 0x80) {
   625                 *pixel++ = (datab & 0x80) ? black : white;
   626             } else {
   627                 *pixel++ = (datab & 0x80) ? black : transparent;
   628             }
   629             datab <<= 1;
   630             maskb <<= 1;
   631         }
   632     }
   633 
   634     cursor = mouse->CreateCursor(surface, hot_x, hot_y);
   635     if (cursor) {
   636         cursor->mouse = mouse;
   637         cursor->next = mouse->cursors;
   638         mouse->cursors = cursor;
   639     }
   640 
   641     SDL_FreeSurface(surface);
   642 
   643     return cursor;
   644 }
   645 
   646 /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
   647    if this is desired for any reason.  This is used when setting
   648    the video mode and when the SDL window gains the mouse focus.
   649  */
   650 void
   651 SDL_SetCursor(SDL_Cursor * cursor)
   652 {
   653     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   654 
   655     if (!mouse) {
   656         SDL_SetError("No mice are initialized");
   657         return;
   658     }
   659 
   660     /* Set the new cursor */
   661     if (cursor) {
   662         /* Make sure the cursor is still valid for this mouse */
   663         SDL_Cursor *found;
   664         for (found = mouse->cursors; found; found = found->next) {
   665             if (found == cursor) {
   666                 break;
   667             }
   668         }
   669         if (!found) {
   670             SDL_SetError("Cursor not associated with the current mouse");
   671             return;
   672         }
   673         mouse->cur_cursor = cursor;
   674     } else {
   675         cursor = mouse->cur_cursor;
   676     }
   677 
   678     if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
   679         if (mouse->ShowCursor) {
   680             mouse->ShowCursor(cursor);
   681         }
   682     } else {
   683         if (mouse->ShowCursor) {
   684             mouse->ShowCursor(NULL);
   685         }
   686     }
   687 }
   688 
   689 SDL_Cursor *
   690 SDL_GetCursor(void)
   691 {
   692     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   693 
   694     if (!mouse) {
   695         return NULL;
   696     }
   697     return mouse->cur_cursor;
   698 }
   699 
   700 void
   701 SDL_FreeCursor(SDL_Cursor * cursor)
   702 {
   703     SDL_Mouse *mouse;
   704     SDL_Cursor *curr, *prev;
   705 
   706     if (!cursor) {
   707         return;
   708     }
   709     mouse = cursor->mouse;
   710 
   711     if (cursor == mouse->def_cursor) {
   712         return;
   713     }
   714     if (cursor == mouse->cur_cursor) {
   715         SDL_SetCursor(mouse->def_cursor);
   716     }
   717 
   718     for (prev = NULL, curr = mouse->cursors; curr;
   719          prev = curr, curr = curr->next) {
   720         if (curr == cursor) {
   721             if (prev) {
   722                 prev->next = curr->next;
   723             } else {
   724                 mouse->cursors = curr->next;
   725             }
   726 
   727             if (mouse->FreeCursor) {
   728                 mouse->FreeCursor(curr);
   729             }
   730             return;
   731         }
   732     }
   733 }
   734 
   735 int
   736 SDL_ShowCursor(int toggle)
   737 {
   738     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   739     SDL_bool shown;
   740 
   741     if (!mouse) {
   742         return 0;
   743     }
   744 
   745     shown = mouse->cursor_shown;
   746     if (toggle >= 0) {
   747         if (toggle) {
   748             mouse->cursor_shown = SDL_TRUE;
   749         } else {
   750             mouse->cursor_shown = SDL_FALSE;
   751         }
   752         if (mouse->cursor_shown != shown) {
   753             SDL_SetCursor(NULL);
   754         }
   755     }
   756     return shown;
   757 }
   758 
   759 char *
   760 SDL_GetMouseName(int index)
   761 {
   762     SDL_Mouse *mouse = SDL_GetMouse(index);
   763     if (!mouse) {
   764         return NULL;
   765     }
   766     return mouse->name;
   767 }
   768 
   769 void
   770 SDL_ChangeEnd(int id, int end)
   771 {
   772     int index = SDL_GetMouseIndexId(id);
   773     SDL_Mouse *mouse = SDL_GetMouse(index);
   774 
   775     if (mouse) {
   776         mouse->current_end = end;
   777     }
   778 }
   779 
   780 int
   781 SDL_GetCursorsNumber(int index)
   782 {
   783     SDL_Mouse *mouse = SDL_GetMouse(index);
   784 
   785     if (!mouse) {
   786         return -1;
   787     }
   788     return mouse->total_ends;
   789 }
   790 
   791 int
   792 SDL_GetCurrentCursor(int index)
   793 {
   794     SDL_Mouse *mouse = SDL_GetMouse(index);
   795 
   796     if (!mouse) {
   797         return -1;
   798     }
   799     return mouse->current_end;
   800 }
   801 
   802 /* vi: set ts=4 sw=4 expandtab: */