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