comparison src/events/SDL_mouse.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children e8157fcb3114
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
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$";
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)
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)
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)
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)
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)
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)
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