src/events/SDL_mouse.c
author Sam Lantinga
Mon, 25 Aug 2008 06:33:00 +0000
changeset 2710 44e49d3fa6cf
parent 2152 003c1b5b07da
child 2712 c4e697245676
permissions -rw-r--r--
Final merge of Google Summer of Code 2008 work...

Many-mouse and tablet support
by Szymon Wilczek, mentored by Ryan C. Gordon

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