src/events/SDL_mouse.c
author Bob Pendleton
Tue, 09 Jun 2009 03:27:48 +0000
changeset 3176 8c12052ddc7b
parent 3112 8f3fd508734b
child 3179 9b34679fda8b
permissions -rw-r--r--
make sure that mouse.z == 0 until it is used.
     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.xrel = xrel;
   470         event.motion.yrel = yrel;
   471         event.motion.windowID = mouse->focus;
   472         event.motion.pressure_max = mouse->pressure_max;
   473         event.motion.pressure_min = mouse->pressure_min;
   474         event.motion.cursor = mouse->current_end;
   475         posted = (SDL_PushEvent(&event) > 0);
   476     }
   477     mouse->last_x = mouse->x;
   478     mouse->last_y = mouse->y;
   479     return posted;
   480 }
   481 
   482 int
   483 SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
   484 {
   485     int index = SDL_GetMouseIndexId(id);
   486     SDL_Mouse *mouse = SDL_GetMouse(index);
   487     int posted;
   488     Uint8 type;
   489 
   490     if (!mouse) {
   491         return 0;
   492     }
   493 
   494     /* Figure out which event to perform */
   495     switch (state) {
   496     case SDL_PRESSED:
   497         if (mouse->buttonstate & SDL_BUTTON(button)) {
   498             /* Ignore this event, no state change */
   499             return 0;
   500         }
   501         type = SDL_MOUSEBUTTONDOWN;
   502         mouse->buttonstate |= SDL_BUTTON(button);
   503         break;
   504     case SDL_RELEASED:
   505         if (!(mouse->buttonstate & SDL_BUTTON(button))) {
   506             /* Ignore this event, no state change */
   507             return 0;
   508         }
   509         type = SDL_MOUSEBUTTONUP;
   510         mouse->buttonstate &= ~SDL_BUTTON(button);
   511         break;
   512     default:
   513         /* Invalid state -- bail */
   514         return 0;
   515     }
   516 
   517     /* Post the event, if desired */
   518     posted = 0;
   519     if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   520         SDL_Event event;
   521         event.type = type;
   522         event.button.which = (Uint8) index;
   523         event.button.state = state;
   524         event.button.button = button;
   525         event.button.x = mouse->x;
   526         event.button.y = mouse->y;
   527         event.button.windowID = mouse->focus;
   528         posted = (SDL_PushEvent(&event) > 0);
   529     }
   530     return posted;
   531 }
   532 
   533 int
   534 SDL_SendMouseWheel(int index, int x, int y)
   535 {
   536     SDL_Mouse *mouse = SDL_GetMouse(index);
   537     int posted;
   538 
   539     if (!mouse || (!x && !y)) {
   540         return 0;
   541     }
   542 
   543     /* Post the event, if desired */
   544     posted = 0;
   545     if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
   546         SDL_Event event;
   547         event.type = SDL_MOUSEWHEEL;
   548         event.wheel.which = (Uint8) index;
   549         event.wheel.x = x;
   550         event.wheel.y = y;
   551         event.wheel.windowID = mouse->focus;
   552         posted = (SDL_PushEvent(&event) > 0);
   553     }
   554     return posted;
   555 }
   556 
   557 void
   558 SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
   559 {
   560     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   561 
   562     if (!mouse) {
   563         return;
   564     }
   565 
   566     if (mouse->WarpMouse) {
   567         mouse->WarpMouse(mouse, windowID, x, y);
   568     } else {
   569         SDL_SetMouseFocus(SDL_current_mouse, windowID);
   570         SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
   571     }
   572 }
   573 
   574 SDL_Cursor *
   575 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
   576                  int w, int h, int hot_x, int hot_y)
   577 {
   578     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   579     SDL_Surface *surface;
   580     SDL_Cursor *cursor;
   581     int x, y;
   582     Uint32 *pixel;
   583     Uint8 datab, maskb;
   584     const Uint32 black = 0xFF000000;
   585     const Uint32 white = 0xFFFFFFFF;
   586     const Uint32 transparent = 0x00000000;
   587 
   588     if (!mouse) {
   589         SDL_SetError("No mice are initialized");
   590         return NULL;
   591     }
   592 
   593     if (!mouse->CreateCursor) {
   594         SDL_SetError("Current mouse doesn't have cursor support");
   595         return NULL;
   596     }
   597 
   598     /* Sanity check the hot spot */
   599     if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
   600         SDL_SetError("Cursor hot spot doesn't lie within cursor");
   601         return NULL;
   602     }
   603 
   604     /* Make sure the width is a multiple of 8 */
   605     w = ((w + 7) & ~7);
   606 
   607     /* Create the surface from a bitmap */
   608     surface =
   609         SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
   610                              0xFF000000);
   611     if (!surface) {
   612         return NULL;
   613     }
   614     for (y = 0; y < h; ++y) {
   615         pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
   616         for (x = 0; x < w; ++x) {
   617             if ((x % 8) == 0) {
   618                 datab = *data++;
   619                 maskb = *mask++;
   620             }
   621             if (maskb & 0x80) {
   622                 *pixel++ = (datab & 0x80) ? black : white;
   623             } else {
   624                 *pixel++ = (datab & 0x80) ? black : transparent;
   625             }
   626             datab <<= 1;
   627             maskb <<= 1;
   628         }
   629     }
   630 
   631     cursor = mouse->CreateCursor(surface, hot_x, hot_y);
   632     if (cursor) {
   633         cursor->mouse = mouse;
   634         cursor->next = mouse->cursors;
   635         mouse->cursors = cursor;
   636     }
   637 
   638     SDL_FreeSurface(surface);
   639 
   640     return cursor;
   641 }
   642 
   643 /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
   644    if this is desired for any reason.  This is used when setting
   645    the video mode and when the SDL window gains the mouse focus.
   646  */
   647 void
   648 SDL_SetCursor(SDL_Cursor * cursor)
   649 {
   650     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   651 
   652     if (!mouse) {
   653         SDL_SetError("No mice are initialized");
   654         return;
   655     }
   656 
   657     /* Set the new cursor */
   658     if (cursor) {
   659         /* Make sure the cursor is still valid for this mouse */
   660         SDL_Cursor *found;
   661         for (found = mouse->cursors; found; found = found->next) {
   662             if (found == cursor) {
   663                 break;
   664             }
   665         }
   666         if (!found) {
   667             SDL_SetError("Cursor not associated with the current mouse");
   668             return;
   669         }
   670         mouse->cur_cursor = cursor;
   671     } else {
   672         cursor = mouse->cur_cursor;
   673     }
   674 
   675     if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
   676         if (mouse->ShowCursor) {
   677             mouse->ShowCursor(cursor);
   678         }
   679     } else {
   680         if (mouse->ShowCursor) {
   681             mouse->ShowCursor(NULL);
   682         }
   683     }
   684 }
   685 
   686 SDL_Cursor *
   687 SDL_GetCursor(void)
   688 {
   689     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   690 
   691     if (!mouse) {
   692         return NULL;
   693     }
   694     return mouse->cur_cursor;
   695 }
   696 
   697 void
   698 SDL_FreeCursor(SDL_Cursor * cursor)
   699 {
   700     SDL_Mouse *mouse;
   701     SDL_Cursor *curr, *prev;
   702 
   703     if (!cursor) {
   704         return;
   705     }
   706     mouse = cursor->mouse;
   707 
   708     if (cursor == mouse->def_cursor) {
   709         return;
   710     }
   711     if (cursor == mouse->cur_cursor) {
   712         SDL_SetCursor(mouse->def_cursor);
   713     }
   714 
   715     for (prev = NULL, curr = mouse->cursors; curr;
   716          prev = curr, curr = curr->next) {
   717         if (curr == cursor) {
   718             if (prev) {
   719                 prev->next = curr->next;
   720             } else {
   721                 mouse->cursors = curr->next;
   722             }
   723 
   724             if (mouse->FreeCursor) {
   725                 mouse->FreeCursor(curr);
   726             }
   727             return;
   728         }
   729     }
   730 }
   731 
   732 int
   733 SDL_ShowCursor(int toggle)
   734 {
   735     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   736     SDL_bool shown;
   737 
   738     if (!mouse) {
   739         return 0;
   740     }
   741 
   742     shown = mouse->cursor_shown;
   743     if (toggle >= 0) {
   744         if (toggle) {
   745             mouse->cursor_shown = SDL_TRUE;
   746         } else {
   747             mouse->cursor_shown = SDL_FALSE;
   748         }
   749         if (mouse->cursor_shown != shown) {
   750             SDL_SetCursor(NULL);
   751         }
   752     }
   753     return shown;
   754 }
   755 
   756 char *
   757 SDL_GetMouseName(int index)
   758 {
   759     SDL_Mouse *mouse = SDL_GetMouse(index);
   760     if (!mouse) {
   761         return NULL;
   762     }
   763     return mouse->name;
   764 }
   765 
   766 void
   767 SDL_ChangeEnd(int id, int end)
   768 {
   769     int index = SDL_GetMouseIndexId(id);
   770     SDL_Mouse *mouse = SDL_GetMouse(index);
   771 
   772     if (mouse) {
   773         mouse->current_end = end;
   774     }
   775 }
   776 
   777 int
   778 SDL_GetCursorsNumber(int index)
   779 {
   780     SDL_Mouse *mouse = SDL_GetMouse(index);
   781 
   782     if (!mouse) {
   783         return -1;
   784     }
   785     return mouse->total_ends;
   786 }
   787 
   788 int
   789 SDL_GetCurrentCursor(int index)
   790 {
   791     SDL_Mouse *mouse = SDL_GetMouse(index);
   792 
   793     if (!mouse) {
   794         return -1;
   795     }
   796     return mouse->current_end;
   797 }
   798 
   799 /* vi: set ts=4 sw=4 expandtab: */