src/events/SDL_mouse.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. SDL_MouseInit
  2. SDL_GetMouseState
  3. SDL_GetRelativeMouseState
  4. ClipOffset
  5. SDL_PrivateMouseMotion
  6. SDL_PrivateMouseButton

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 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     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_mouse.c,v 1.3.2.10 2001/02/10 07:20:04 hercules Exp $";
  26 #endif
  27 
  28 /* General mouse handling code for SDL */
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 
  34 #include "SDL_events.h"
  35 #include "SDL_events_c.h"
  36 #include "SDL_cursor_c.h"
  37 #include "SDL_sysvideo.h"
  38 
  39 
  40 /* These are static for our mouse handling code */
  41 static Sint16 SDL_MouseX = 0;
  42 static Sint16 SDL_MouseY = 0;
  43 static Sint16 SDL_DeltaX = 0;
  44 static Sint16 SDL_DeltaY = 0;
  45 static Uint8  SDL_ButtonState = 0;
  46 
  47 
  48 /* Public functions */
  49 int SDL_MouseInit(void)
     /* [<][>][^][v][top][bottom][index][help] */
  50 {
  51         /* The mouse is at (0,0) */
  52         SDL_MouseX = 0;
  53         SDL_MouseY = 0;
  54         SDL_DeltaX = 0;
  55         SDL_DeltaY = 0;
  56         SDL_ButtonState = 0;
  57 
  58         /* That's it! */
  59         return(0);
  60 }
  61 
  62 Uint8 SDL_GetMouseState (int *x, int *y)
     /* [<][>][^][v][top][bottom][index][help] */
  63 {
  64         if ( x )
  65                 *x = SDL_MouseX;
  66         if ( y )
  67                 *y = SDL_MouseY;
  68         return(SDL_ButtonState);
  69 }
  70 
  71 Uint8 SDL_GetRelativeMouseState (int *x, int *y)
     /* [<][>][^][v][top][bottom][index][help] */
  72 {
  73         if ( x )
  74                 *x = SDL_DeltaX;
  75         if ( y )
  76                 *y = SDL_DeltaY;
  77         SDL_DeltaX = 0;
  78         SDL_DeltaY = 0;
  79         return(SDL_ButtonState);
  80 }
  81 
  82 static void ClipOffset(Sint16 *x, Sint16 *y)
     /* [<][>][^][v][top][bottom][index][help] */
  83 {
  84         /* This clips absolute mouse coordinates when the apparent
  85            display surface is smaller than the real display surface.
  86          */
  87         if ( SDL_VideoSurface->offset ) {
  88                 *y -= SDL_VideoSurface->offset/SDL_VideoSurface->pitch;
  89                 *x -= (SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/
  90                                 SDL_VideoSurface->format->BytesPerPixel;
  91         }
  92 }
  93 
  94 /* These are global for SDL_eventloop.c */
  95 int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97         int posted;
  98         Uint16 X, Y;
  99         Sint16 Xrel;
 100         Sint16 Yrel;
 101 
 102         /* Don't handle mouse motion if there's no cursor surface */
 103         if ( SDL_VideoSurface == NULL ) {
 104                 return(0);
 105         }
 106 
 107         /* Default buttonstate is the current one */
 108         if ( ! buttonstate ) {
 109                 buttonstate = SDL_ButtonState;
 110         }
 111 
 112         Xrel = x;
 113         Yrel = y;
 114         if ( relative ) {
 115                 /* Push the cursor around */
 116                 x = (SDL_MouseX+x);
 117                 y = (SDL_MouseY+y);
 118         } else {
 119                 /* Do we need to clip {x,y} ? */
 120                 ClipOffset(&x, &y);
 121         }
 122 
 123         /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
 124         if ( x < 0 )
 125                 X = 0;
 126         else
 127         if ( x >= SDL_VideoSurface->w )
 128                 X = SDL_VideoSurface->w-1;
 129         else
 130                 X = (Uint16)x;
 131 
 132         if ( y < 0 )
 133                 Y = 0;
 134         else
 135         if ( y >= SDL_VideoSurface->h )
 136                 Y = SDL_VideoSurface->h-1;
 137         else
 138                 Y = (Uint16)y;
 139 
 140         /* If not relative mode, generate relative motion from clamped X/Y.
 141            This prevents lots of extraneous large delta relative motion when
 142            the screen is windowed mode and the mouse is outside the window.
 143         */
 144         if ( ! relative ) {
 145                 Xrel = X-SDL_MouseX;
 146                 Yrel = Y-SDL_MouseY;
 147         }
 148 
 149         /* Update internal mouse state */
 150         SDL_ButtonState = buttonstate;
 151         SDL_MouseX = X;
 152         SDL_MouseY = Y;
 153         SDL_DeltaX += Xrel;
 154         SDL_DeltaY += Yrel;
 155         SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
 156 
 157         /* Post the event, if desired */
 158         posted = 0;
 159         if ( SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE ) {
 160                 SDL_Event event;
 161                 memset(&event, 0, sizeof(event));
 162                 event.type = SDL_MOUSEMOTION;
 163                 event.motion.state = buttonstate;
 164                 event.motion.x = X;
 165                 event.motion.y = Y;
 166                 event.motion.xrel = Xrel;
 167                 event.motion.yrel = Yrel;
 168                 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
 169                         posted = 1;
 170                         SDL_PushEvent(&event);
 171                 }
 172         }
 173         return(posted);
 174 }
 175 
 176 int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y)
     /* [<][>][^][v][top][bottom][index][help] */
 177 {
 178         SDL_Event event;
 179         int posted;
 180         int move_mouse;
 181         Uint8 buttonstate;
 182 
 183         memset(&event, 0, sizeof(event));
 184 
 185         /* Check parameters */
 186         if ( x || y ) {
 187                 ClipOffset(&x, &y);
 188                 move_mouse = 1;
 189                 /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
 190                 if ( x < 0 )
 191                         x = 0;
 192                 else
 193                 if ( x >= SDL_VideoSurface->w )
 194                         x = SDL_VideoSurface->w-1;
 195 
 196                 if ( y < 0 )
 197                         y = 0;
 198                 else
 199                 if ( y >= SDL_VideoSurface->h )
 200                         y = SDL_VideoSurface->h-1;
 201         } else {
 202                 move_mouse = 0;
 203         }
 204         if ( ! x )
 205                 x = SDL_MouseX;
 206         if ( ! y )
 207                 y = SDL_MouseY;
 208 
 209         /* Figure out which event to perform */
 210         buttonstate = SDL_ButtonState;
 211         switch ( state ) {
 212                 case SDL_PRESSED:
 213                         event.type = SDL_MOUSEBUTTONDOWN;
 214                         buttonstate |= SDL_BUTTON(button);
 215                         break;
 216                 case SDL_RELEASED:
 217                         event.type = SDL_MOUSEBUTTONUP;
 218                         buttonstate &= ~SDL_BUTTON(button);
 219                         break;
 220                 default:
 221                         /* Invalid state -- bail */
 222                         return(0);
 223         }
 224 
 225         /* Update internal mouse state */
 226         SDL_ButtonState = buttonstate;
 227         if ( move_mouse ) {
 228                 SDL_MouseX = x;
 229                 SDL_MouseY = y;
 230                 SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
 231         }
 232 
 233         /* Post the event, if desired */
 234         posted = 0;
 235         if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
 236                 event.button.state = state;
 237                 event.button.button = button;
 238                 event.button.x = x;
 239                 event.button.y = y;
 240                 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
 241                         posted = 1;
 242                         SDL_PushEvent(&event);
 243                 }
 244         }
 245         return(posted);
 246 }
 247 

/* [<][>][^][v][top][bottom][index][help] */