Mercurial > sdl-ios-xcode
comparison src/events/SDL_mouse.c @ 1670:eef792d31de8 SDL-1.3
Work in progress. :)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 07 Jun 2006 16:10:28 +0000 |
parents | 4da1ee79c9af |
children | 89f7510fe17a |
comparison
equal
deleted
inserted
replaced
1669:9857d21967bb | 1670:eef792d31de8 |
---|---|
23 | 23 |
24 /* General mouse handling code for SDL */ | 24 /* General mouse handling code for SDL */ |
25 | 25 |
26 #include "SDL_events.h" | 26 #include "SDL_events.h" |
27 #include "SDL_events_c.h" | 27 #include "SDL_events_c.h" |
28 #include "../video/SDL_cursor_c.h" | 28 #include "SDL_mouse_c.h" |
29 #include "../video/SDL_sysvideo.h" | 29 |
30 | 30 |
31 | 31 static int SDL_num_mice; |
32 /* These are static for our mouse handling code */ | 32 static int SDL_current_mouse; |
33 static Sint16 SDL_MouseX = 0; | 33 static SDL_Mouse *SDL_mice; |
34 static Sint16 SDL_MouseY = 0; | |
35 static Sint16 SDL_DeltaX = 0; | |
36 static Sint16 SDL_DeltaY = 0; | |
37 static Uint8 SDL_ButtonState = 0; | |
38 | 34 |
39 | 35 |
40 /* Public functions */ | 36 /* Public functions */ |
41 int | 37 int |
42 SDL_MouseInit(void) | 38 SDL_MouseInit(void) |
43 { | 39 { |
44 /* The mouse is at (0,0) */ | |
45 SDL_MouseX = 0; | |
46 SDL_MouseY = 0; | |
47 SDL_DeltaX = 0; | |
48 SDL_DeltaY = 0; | |
49 SDL_ButtonState = 0; | |
50 | |
51 /* That's it! */ | |
52 return (0); | 40 return (0); |
41 } | |
42 | |
43 int | |
44 SDL_AddMouse(SDL_WindowID focus, int x, int y, Uint8 buttonstate) | |
45 { | |
46 SDL_Mouse *new_mice; | |
47 int index; | |
48 SDL_Mouse *mouse; | |
49 | |
50 new_mice = | |
51 (SDL_Mouse *) SDL_realloc(SDL_mice, | |
52 (SDL_num_mice + 1) * sizeof(*new_mice)); | |
53 if (!new_mice) { | |
54 SDL_OutOfMemory(); | |
55 return -1; | |
56 } | |
57 | |
58 index = SDL_num_mice++; | |
59 mouse = &SDL_mice[index]; | |
60 mouse->focus = focus; | |
61 mouse->x = x; | |
62 mouse->y = y; | |
63 mouse->xdelta = 0; | |
64 mouse->ydelta = 0; | |
65 mouse->buttonstate = buttonstate; | |
66 | |
67 return index; | |
68 } | |
69 | |
70 SDL_Mouse * | |
71 SDL_GetMouse(int index) | |
72 { | |
73 if (index < 0 || index >= SDL_num_mice) { | |
74 return NULL; | |
75 } | |
76 return &SDL_mice[index]; | |
53 } | 77 } |
54 | 78 |
55 void | 79 void |
56 SDL_MouseQuit(void) | 80 SDL_MouseQuit(void) |
57 { | 81 { |
58 } | 82 SDL_num_mice = 0; |
59 | 83 SDL_current_mouse = 0; |
60 /* We lost the mouse, so post button up messages for all pressed buttons */ | 84 |
61 void | 85 if (SDL_mice) { |
62 SDL_ResetMouse(void) | 86 SDL_free(SDL_mice); |
63 { | 87 SDL_mice = NULL; |
64 Uint8 i; | 88 } |
65 for (i = 0; i < sizeof(SDL_ButtonState) * 8; ++i) { | 89 } |
66 if (SDL_ButtonState & SDL_BUTTON(i)) { | 90 |
67 SDL_PrivateMouseButton(SDL_RELEASED, i, 0, 0); | 91 int |
68 } | 92 SDL_GetNumMice(void) |
69 } | 93 { |
94 return SDL_num_mice; | |
95 } | |
96 | |
97 int | |
98 SDL_SelectMouse(int index) | |
99 { | |
100 if (index >= 0 && index < SDL_num_mice) { | |
101 SDL_current_mouse = index; | |
102 } | |
103 return SDL_current_mouse; | |
104 } | |
105 | |
106 SDL_WindowID | |
107 SDL_GetMouseFocusWindow() | |
108 { | |
109 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | |
110 | |
111 if (!mouse) { | |
112 return 0; | |
113 } | |
114 return mouse->focus; | |
70 } | 115 } |
71 | 116 |
72 Uint8 | 117 Uint8 |
73 SDL_GetMouseState(int *x, int *y) | 118 SDL_GetMouseState(int *x, int *y) |
74 { | 119 { |
120 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); | |
121 | |
122 if (!mouse) { | |
123 if (x) { | |
124 *x = 0; | |
125 } | |
126 if (y) { | |
127 *y = 0; | |
128 } | |
129 return 0; | |
130 } | |
131 | |
75 if (x) { | 132 if (x) { |
76 *x = SDL_MouseX; | 133 *x = mouse->x; |
77 } | 134 } |
78 if (y) { | 135 if (y) { |
79 *y = SDL_MouseY; | 136 *y = mouse->y; |
80 } | 137 } |
81 return (SDL_ButtonState); | 138 return mouse->buttonstate; |
82 } | 139 } |
83 | 140 |
84 Uint8 | 141 Uint8 |
85 SDL_GetRelativeMouseState(int *x, int *y) | 142 SDL_GetRelativeMouseState(int *x, int *y) |
86 { | 143 { |
87 if (x) | 144 SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); |
88 *x = SDL_DeltaX; | 145 |
89 if (y) | 146 if (!mouse) { |
90 *y = SDL_DeltaY; | 147 if (x) { |
91 SDL_DeltaX = 0; | 148 *x = 0; |
92 SDL_DeltaY = 0; | 149 } |
93 return (SDL_ButtonState); | 150 if (y) { |
94 } | 151 *y = 0; |
95 | 152 } |
96 static void | 153 return 0; |
97 ClipOffset(Sint16 * x, Sint16 * y) | 154 } |
98 { | 155 |
99 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 156 if (x) { |
100 | 157 *x = mouse->xdelta; |
101 /* This clips absolute mouse coordinates when the apparent | 158 } |
102 display surface is smaller than the real display surface. | 159 if (y) { |
103 */ | 160 *y = mouse->ydelta; |
104 if (SDL_VideoSurface->offset) { | 161 } |
105 *y -= SDL_VideoSurface->offset / SDL_VideoSurface->pitch; | 162 mouse->xdelta = 0; |
106 *x -= (SDL_VideoSurface->offset % SDL_VideoSurface->pitch) / | 163 mouse->ydelta = 0; |
107 SDL_VideoSurface->format->BytesPerPixel; | 164 return mouse->buttonstate; |
108 } | 165 } |
109 } | 166 |
110 | 167 int |
111 /* These are global for SDL_eventloop.c */ | 168 SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x, |
112 int | 169 int y) |
113 SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) | 170 { |
114 { | 171 SDL_Mouse *mouse = SDL_GetMouse(index); |
115 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
116 int posted; | 172 int posted; |
117 Uint16 X, Y; | 173 int xrel; |
118 Sint16 Xrel; | 174 int yrel; |
119 Sint16 Yrel; | 175 |
120 | 176 if (!mouse) { |
121 /* Don't handle mouse motion if there's no cursor surface */ | 177 return 0; |
122 if (SDL_VideoSurface == NULL) { | 178 } |
123 return (0); | 179 |
124 } | 180 if (windowID) { |
125 | 181 mouse->focus = windowID; |
126 /* Default buttonstate is the current one */ | 182 } |
127 if (!buttonstate) { | 183 |
128 buttonstate = SDL_ButtonState; | |
129 } | |
130 | |
131 Xrel = x; | |
132 Yrel = y; | |
133 if (relative) { | 184 if (relative) { |
134 /* Push the cursor around */ | 185 /* Push the cursor around */ |
135 x = (SDL_MouseX + x); | 186 xrel = x; |
136 y = (SDL_MouseY + y); | 187 yrel = y; |
188 x = (mouse->x + xrel); | |
189 y = (mouse->y + yrel); | |
137 } else { | 190 } else { |
138 /* Do we need to clip {x,y} ? */ | 191 xrel = x - mouse->x; |
139 ClipOffset(&x, &y); | 192 yrel = y - mouse->y; |
140 } | |
141 | |
142 /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */ | |
143 if (x < 0) | |
144 X = 0; | |
145 else if (x >= SDL_VideoSurface->w) | |
146 X = SDL_VideoSurface->w - 1; | |
147 else | |
148 X = (Uint16) x; | |
149 | |
150 if (y < 0) | |
151 Y = 0; | |
152 else if (y >= SDL_VideoSurface->h) | |
153 Y = SDL_VideoSurface->h - 1; | |
154 else | |
155 Y = (Uint16) y; | |
156 | |
157 /* If not relative mode, generate relative motion from clamped X/Y. | |
158 This prevents lots of extraneous large delta relative motion when | |
159 the screen is windowed mode and the mouse is outside the window. | |
160 */ | |
161 if (!relative) { | |
162 Xrel = X - SDL_MouseX; | |
163 Yrel = Y - SDL_MouseY; | |
164 } | 193 } |
165 | 194 |
166 /* Drop events that don't change state */ | 195 /* Drop events that don't change state */ |
167 if (!Xrel && !Yrel) { | 196 if (!xrel && !yrel) { |
168 #if 0 | 197 #if 0 |
169 printf("Mouse event didn't change state - dropped!\n"); | 198 printf("Mouse event didn't change state - dropped!\n"); |
170 #endif | 199 #endif |
171 return (0); | 200 return 0; |
172 } | 201 } |
173 | 202 |
174 /* Update internal mouse state */ | 203 /* Update internal mouse state */ |
175 SDL_ButtonState = buttonstate; | 204 mouse->xdelta += xrel; |
176 SDL_MouseX = X; | 205 mouse->ydelta += yrel; |
177 SDL_MouseY = Y; | |
178 SDL_DeltaX += Xrel; | |
179 SDL_DeltaY += Yrel; | |
180 SDL_MoveCursor(SDL_MouseX, SDL_MouseY); | |
181 | 206 |
182 /* Post the event, if desired */ | 207 /* Post the event, if desired */ |
183 posted = 0; | 208 posted = 0; |
184 if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) { | 209 if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) { |
185 SDL_Event event; | 210 SDL_Event event; |
186 SDL_memset(&event, 0, sizeof(event)); | 211 event.motion.type = SDL_MOUSEMOTION; |
187 event.type = SDL_MOUSEMOTION; | 212 event.motion.which = (Uint8) index; |
188 event.motion.state = buttonstate; | 213 event.motion.state = mouse->buttonstate; |
189 event.motion.x = X; | 214 event.motion.x = mouse->x; |
190 event.motion.y = Y; | 215 event.motion.y = mouse->y; |
191 event.motion.xrel = Xrel; | 216 event.motion.xrel = xrel; |
192 event.motion.yrel = Yrel; | 217 event.motion.yrel = yrel; |
218 event.motion.windowID = mouse->focus; | |
193 if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) { | 219 if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) { |
194 posted = 1; | 220 posted = 1; |
195 SDL_PushEvent(&event); | 221 SDL_PushEvent(&event); |
196 } | 222 } |
197 } | 223 } |
198 return (posted); | 224 return posted; |
199 } | 225 } |
200 | 226 |
201 int | 227 int |
202 SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y) | 228 SDL_PrivateMouseButton(int index, SDL_WindowID windowID, Uint8 state, |
203 { | 229 Uint8 button) |
204 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 230 { |
205 SDL_Event event; | 231 SDL_Mouse *mouse = SDL_GetMouse(index); |
206 int posted; | 232 int posted; |
207 int move_mouse; | 233 Uint8 type; |
208 Uint8 buttonstate; | 234 |
209 | 235 if (!mouse) { |
210 SDL_memset(&event, 0, sizeof(event)); | 236 return 0; |
211 | 237 } |
212 /* Check parameters */ | 238 |
213 if (x || y) { | 239 if (windowID) { |
214 ClipOffset(&x, &y); | 240 mouse->focus = windowID; |
215 move_mouse = 1; | 241 } |
216 /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */ | |
217 if (x < 0) | |
218 x = 0; | |
219 else if (x >= SDL_VideoSurface->w) | |
220 x = SDL_VideoSurface->w - 1; | |
221 | |
222 if (y < 0) | |
223 y = 0; | |
224 else if (y >= SDL_VideoSurface->h) | |
225 y = SDL_VideoSurface->h - 1; | |
226 } else { | |
227 move_mouse = 0; | |
228 } | |
229 if (!x) | |
230 x = SDL_MouseX; | |
231 if (!y) | |
232 y = SDL_MouseY; | |
233 | 242 |
234 /* Figure out which event to perform */ | 243 /* Figure out which event to perform */ |
235 buttonstate = SDL_ButtonState; | |
236 switch (state) { | 244 switch (state) { |
237 case SDL_PRESSED: | 245 case SDL_PRESSED: |
238 event.type = SDL_MOUSEBUTTONDOWN; | 246 if (mouse->buttonstate & SDL_BUTTON(button)) { |
239 buttonstate |= SDL_BUTTON(button); | 247 /* Ignore this event, no state change */ |
248 return 0; | |
249 } | |
250 type = SDL_MOUSEBUTTONDOWN; | |
251 mouse->buttonstate |= SDL_BUTTON(button); | |
240 break; | 252 break; |
241 case SDL_RELEASED: | 253 case SDL_RELEASED: |
242 event.type = SDL_MOUSEBUTTONUP; | 254 if (!(mouse->buttonstate & SDL_BUTTON(button))) { |
243 buttonstate &= ~SDL_BUTTON(button); | 255 /* Ignore this event, no state change */ |
256 return 0; | |
257 } | |
258 type = SDL_MOUSEBUTTONUP; | |
259 mouse->buttonstate &= ~SDL_BUTTON(button); | |
244 break; | 260 break; |
245 default: | 261 default: |
246 /* Invalid state -- bail */ | 262 /* Invalid state -- bail */ |
247 return (0); | 263 return 0; |
248 } | |
249 | |
250 /* Update internal mouse state */ | |
251 SDL_ButtonState = buttonstate; | |
252 if (move_mouse) { | |
253 SDL_MouseX = x; | |
254 SDL_MouseY = y; | |
255 SDL_MoveCursor(SDL_MouseX, SDL_MouseY); | |
256 } | 264 } |
257 | 265 |
258 /* Post the event, if desired */ | 266 /* Post the event, if desired */ |
259 posted = 0; | 267 posted = 0; |
260 if (SDL_ProcessEvents[event.type] == SDL_ENABLE) { | 268 if (SDL_ProcessEvents[type] == SDL_ENABLE) { |
269 SDL_Event event; | |
270 event.type = type; | |
271 event.button.which = (Uint8) index; | |
261 event.button.state = state; | 272 event.button.state = state; |
262 event.button.button = button; | 273 event.button.button = button; |
263 event.button.x = x; | 274 event.button.x = mouse->x; |
264 event.button.y = y; | 275 event.button.y = mouse->y; |
276 event.button.windowID = windowID; | |
265 if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) { | 277 if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) { |
266 posted = 1; | 278 posted = 1; |
267 SDL_PushEvent(&event); | 279 SDL_PushEvent(&event); |
268 } | 280 } |
269 } | 281 } |
270 return (posted); | 282 return posted; |
271 } | 283 } |
272 | 284 |
273 /* vi: set ts=4 sw=4 expandtab: */ | 285 /* vi: set ts=4 sw=4 expandtab: */ |