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