src/events/SDL_mouse.c
author Ryan C. Gordon
Wed, 16 Dec 2009 19:50:51 +0000
changeset 3585 f8816ffa210b
parent 3572 6bb9952d5029
child 3685 64ce267332c6
permissions -rw-r--r--
Initial band-aids on SDL_GetMouseState() API breakage. More work to come.

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