src/events/SDL_mouse.c
author Sam Lantinga
Sat, 04 Oct 2008 06:46:59 +0000
changeset 2765 f55c87ae336b
parent 2727 76c2fc9696ea
child 2794 f7872b7a8732
permissions -rw-r--r--
Final merge of Google Summer of Code 2008 work...

Bring SDL to iPhone and iPod Touch
by Holmes Futrell, mentored by Sam Lantinga
     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 = -1;
   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 
   378     if (!mouse) {
   379         return 0;
   380     }
   381 
   382     last_x = x;
   383     last_y = y;
   384     if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   385         SDL_Event event;
   386         event.proximity.which = (Uint8) index;
   387         event.proximity.x = x;
   388         event.proximity.y = y;
   389         event.proximity.cursor = mouse->current_end;
   390         event.proximity.type = type;
   391         posted = (SDL_PushEvent(&event) > 0);
   392         if (type == SDL_PROXIMITYIN) {
   393             mouse->proximity = SDL_TRUE;
   394         } else {
   395             mouse->proximity = SDL_FALSE;
   396         }
   397     }
   398     return posted;
   399 }
   400 
   401 int
   402 SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
   403 {
   404     int index = SDL_GetMouseIndexId(id);
   405     SDL_Mouse *mouse = SDL_GetMouse(index);
   406     int posted;
   407     int xrel;
   408     int yrel;
   409 
   410     /* while using the relative mode and many windows, we have to be sure,
   411        that the pointers find themselves inside the windows */
   412     if (x > x_max) {
   413         x = x_max;
   414     }
   415     if (y > y_max) {
   416         y = y_max;
   417     }
   418 
   419     if (!mouse || mouse->flush_motion) {
   420         return 0;
   421     }
   422 
   423     /* if the mouse is out of proximity we don't to want to have any motion from it */
   424     if (mouse->proximity == SDL_FALSE) {
   425         last_x = x;
   426         last_y = y;
   427         return 0;
   428     }
   429 
   430     /* the relative motion is calculated regarding the system cursor last position */
   431 
   432     xrel = x - last_x;
   433     yrel = y - last_y;
   434 
   435     /* Drop events that don't change state */
   436     if (!xrel && !yrel) {
   437 #if 0
   438         printf("Mouse event didn't change state - dropped!\n");
   439 #endif
   440         return 0;
   441     }
   442 
   443     /* Update internal mouse coordinates */
   444     if (mouse->relative_mode == SDL_FALSE) {
   445         mouse->x = x;
   446         mouse->y = y;
   447     } else {
   448         if (mouse->x + xrel > x_max) {
   449             mouse->x = x_max;
   450         } else if (mouse->x + xrel < 0) {
   451             mouse->x = 0;
   452         } else {
   453             mouse->x += xrel;
   454         }
   455         if (mouse->y + yrel > y_max) {
   456             mouse->y = y_max;
   457         } else if (mouse->y + yrel < 0) {
   458             mouse->y = 0;
   459         } else {
   460             mouse->y += yrel;
   461         }
   462     }
   463     mouse->xdelta += xrel;
   464     mouse->ydelta += yrel;
   465     mouse->pressure = pressure;
   466 
   467     /* Move the mouse cursor, if needed */
   468     if (mouse->cursor_shown && !mouse->relative_mode &&
   469         mouse->MoveCursor && mouse->cur_cursor) {
   470         mouse->MoveCursor(mouse->cur_cursor);
   471     }
   472 
   473     /* Post the event, if desired */
   474     posted = 0;
   475     if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE &&
   476         mouse->proximity == SDL_TRUE) {
   477         SDL_Event event;
   478         event.motion.type = SDL_MOUSEMOTION;
   479         event.motion.which = (Uint8) index;
   480         event.motion.state = mouse->buttonstate;
   481         event.motion.x = mouse->x;
   482         event.motion.y = mouse->y;
   483         event.motion.pressure = mouse->pressure;
   484         event.motion.xrel = xrel;
   485         event.motion.yrel = yrel;
   486         event.motion.windowID = mouse->focus;
   487         event.motion.pressure_max = mouse->pressure_max;
   488         event.motion.pressure_min = mouse->pressure_min;
   489         event.motion.cursor = mouse->current_end;
   490         posted = (SDL_PushEvent(&event) > 0);
   491     }
   492     last_x = x;
   493     last_y = y;
   494     return posted;
   495 }
   496 
   497 int
   498 SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
   499 {
   500     int index = SDL_GetMouseIndexId(id);
   501     SDL_Mouse *mouse = SDL_GetMouse(index);
   502     int posted;
   503     Uint8 type;
   504 
   505     if (!mouse) {
   506         return 0;
   507     }
   508 
   509     /* Figure out which event to perform */
   510     switch (state) {
   511     case SDL_PRESSED:
   512         if (mouse->buttonstate & SDL_BUTTON(button)) {
   513             /* Ignore this event, no state change */
   514             return 0;
   515         }
   516         type = SDL_MOUSEBUTTONDOWN;
   517         mouse->buttonstate |= SDL_BUTTON(button);
   518         break;
   519     case SDL_RELEASED:
   520         if (!(mouse->buttonstate & SDL_BUTTON(button))) {
   521             /* Ignore this event, no state change */
   522             return 0;
   523         }
   524         type = SDL_MOUSEBUTTONUP;
   525         mouse->buttonstate &= ~SDL_BUTTON(button);
   526         break;
   527     default:
   528         /* Invalid state -- bail */
   529         return 0;
   530     }
   531 
   532     /* Post the event, if desired */
   533     posted = 0;
   534     if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   535         SDL_Event event;
   536         event.type = type;
   537         event.button.which = (Uint8) index;
   538         event.button.state = state;
   539         event.button.button = button;
   540         event.button.x = mouse->x;
   541         event.button.y = mouse->y;
   542         event.button.windowID = mouse->focus;
   543         posted = (SDL_PushEvent(&event) > 0);
   544     }
   545     return posted;
   546 }
   547 
   548 int
   549 SDL_SendMouseWheel(int index, int x, int y)
   550 {
   551     SDL_Mouse *mouse = SDL_GetMouse(index);
   552     int posted;
   553 
   554     if (!mouse || (!x && !y)) {
   555         return 0;
   556     }
   557 
   558     /* Post the event, if desired */
   559     posted = 0;
   560     if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
   561         SDL_Event event;
   562         event.type = SDL_MOUSEWHEEL;
   563         event.wheel.which = (Uint8) index;
   564         event.wheel.x = x;
   565         event.wheel.y = y;
   566         event.wheel.windowID = mouse->focus;
   567         posted = (SDL_PushEvent(&event) > 0);
   568     }
   569     return posted;
   570 }
   571 
   572 void
   573 SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
   574 {
   575     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   576 
   577     if (!mouse) {
   578         return;
   579     }
   580 
   581     if (mouse->WarpMouse) {
   582         mouse->WarpMouse(mouse, windowID, x, y);
   583     } else {
   584         SDL_SetMouseFocus(SDL_current_mouse, windowID);
   585         SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
   586     }
   587 }
   588 
   589 SDL_Cursor *
   590 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
   591                  int w, int h, int hot_x, int hot_y)
   592 {
   593     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   594     SDL_Surface *surface;
   595     SDL_Cursor *cursor;
   596     int x, y;
   597     Uint32 *pixel;
   598     Uint8 datab, maskb;
   599     const Uint32 black = 0xFF000000;
   600     const Uint32 white = 0xFFFFFFFF;
   601     const Uint32 transparent = 0x00000000;
   602 
   603     if (!mouse) {
   604         SDL_SetError("No mice are initialized");
   605         return NULL;
   606     }
   607 
   608     if (!mouse->CreateCursor) {
   609         SDL_SetError("Current mouse doesn't have cursor support");
   610         return NULL;
   611     }
   612 
   613     /* Sanity check the hot spot */
   614     if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
   615         SDL_SetError("Cursor hot spot doesn't lie within cursor");
   616         return NULL;
   617     }
   618 
   619     /* Make sure the width is a multiple of 8 */
   620     w = ((w + 7) & ~7);
   621 
   622     /* Create the surface from a bitmap */
   623     surface =
   624         SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
   625                              0xFF000000);
   626     if (!surface) {
   627         return NULL;
   628     }
   629     for (y = 0; y < h; ++y) {
   630         pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
   631         for (x = 0; x < w; ++x) {
   632             if ((x % 8) == 0) {
   633                 datab = *data++;
   634                 maskb = *mask++;
   635             }
   636             if (maskb & 0x80) {
   637                 *pixel++ = (datab & 0x80) ? black : white;
   638             } else {
   639                 *pixel++ = (datab & 0x80) ? black : transparent;
   640             }
   641             datab <<= 1;
   642             maskb <<= 1;
   643         }
   644     }
   645 
   646     cursor = mouse->CreateCursor(surface, hot_x, hot_y);
   647     if (cursor) {
   648         cursor->mouse = mouse;
   649         cursor->next = mouse->cursors;
   650         mouse->cursors = cursor;
   651     }
   652 
   653     SDL_FreeSurface(surface);
   654 
   655     return cursor;
   656 }
   657 
   658 /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
   659    if this is desired for any reason.  This is used when setting
   660    the video mode and when the SDL window gains the mouse focus.
   661  */
   662 void
   663 SDL_SetCursor(SDL_Cursor * cursor)
   664 {
   665     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   666 
   667     if (!mouse) {
   668         SDL_SetError("No mice are initialized");
   669         return;
   670     }
   671 
   672     /* Set the new cursor */
   673     if (cursor) {
   674         /* Make sure the cursor is still valid for this mouse */
   675         SDL_Cursor *found;
   676         for (found = mouse->cursors; found; found = found->next) {
   677             if (found == cursor) {
   678                 break;
   679             }
   680         }
   681         if (!found) {
   682             SDL_SetError("Cursor not associated with the current mouse");
   683             return;
   684         }
   685         mouse->cur_cursor = cursor;
   686     } else {
   687         cursor = mouse->cur_cursor;
   688     }
   689 
   690     if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
   691         if (mouse->ShowCursor) {
   692             mouse->ShowCursor(cursor);
   693         }
   694     } else {
   695         if (mouse->ShowCursor) {
   696             mouse->ShowCursor(NULL);
   697         }
   698     }
   699 }
   700 
   701 SDL_Cursor *
   702 SDL_GetCursor(void)
   703 {
   704     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   705 
   706     if (!mouse) {
   707         return NULL;
   708     }
   709     return mouse->cur_cursor;
   710 }
   711 
   712 void
   713 SDL_FreeCursor(SDL_Cursor * cursor)
   714 {
   715     SDL_Mouse *mouse;
   716     SDL_Cursor *curr, *prev;
   717 
   718     if (!cursor) {
   719         return;
   720     }
   721     mouse = cursor->mouse;
   722 
   723     if (cursor == mouse->def_cursor) {
   724         return;
   725     }
   726     if (cursor == mouse->cur_cursor) {
   727         SDL_SetCursor(mouse->def_cursor);
   728     }
   729 
   730     for (prev = NULL, curr = mouse->cursors; curr;
   731          prev = curr, curr = curr->next) {
   732         if (curr == cursor) {
   733             if (prev) {
   734                 prev->next = curr->next;
   735             } else {
   736                 mouse->cursors = curr->next;
   737             }
   738 
   739             if (mouse->FreeCursor) {
   740                 mouse->FreeCursor(curr);
   741             }
   742             return;
   743         }
   744     }
   745 }
   746 
   747 int
   748 SDL_ShowCursor(int toggle)
   749 {
   750     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   751     SDL_bool shown;
   752 
   753     if (!mouse) {
   754         return 0;
   755     }
   756 
   757     shown = mouse->cursor_shown;
   758     if (toggle >= 0) {
   759         if (toggle) {
   760             mouse->cursor_shown = SDL_TRUE;
   761         } else {
   762             mouse->cursor_shown = SDL_FALSE;
   763         }
   764         if (mouse->cursor_shown != shown) {
   765             SDL_SetCursor(NULL);
   766         }
   767     }
   768     return shown;
   769 }
   770 
   771 char *
   772 SDL_GetMouseName(int index)
   773 {
   774     SDL_Mouse *mouse = SDL_GetMouse(index);
   775     if (!mouse) {
   776         return NULL;
   777     }
   778     return mouse->name;
   779 }
   780 
   781 void
   782 SDL_UpdateCoordinates(int x, int y)
   783 {
   784     x_max = x;
   785     y_max = y;
   786 }
   787 
   788 void
   789 SDL_ChangeEnd(int id, int end)
   790 {
   791     int index = SDL_GetMouseIndexId(id);
   792     SDL_Mouse *mouse = SDL_GetMouse(index);
   793 
   794     if (mouse) {
   795         mouse->current_end = end;
   796     }
   797 }
   798 
   799 int
   800 SDL_GetCursorsNumber(int index)
   801 {
   802     SDL_Mouse *mouse = SDL_GetMouse(index);
   803 
   804     if (!mouse) {
   805         return -1;
   806     }
   807     return mouse->total_ends;
   808 }
   809 
   810 int
   811 SDL_GetCurrentCursor(int index)
   812 {
   813     SDL_Mouse *mouse = SDL_GetMouse(index);
   814 
   815     if (!mouse) {
   816         return -1;
   817     }
   818     return mouse->current_end;
   819 }
   820 
   821 /* vi: set ts=4 sw=4 expandtab: */