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