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