Mercurial > sdl-ios-xcode
comparison src/events/SDL_events.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | 290b5baf2fca |
children | 542c78b6fb12 |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
32 #include "../joystick/SDL_joystick_c.h" | 32 #include "../joystick/SDL_joystick_c.h" |
33 #endif | 33 #endif |
34 | 34 |
35 /* Public data -- the event filter */ | 35 /* Public data -- the event filter */ |
36 SDL_EventFilter SDL_EventOK = NULL; | 36 SDL_EventFilter SDL_EventOK = NULL; |
37 void *SDL_EventOKParam; | |
37 Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; | 38 Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; |
38 static Uint32 SDL_eventstate = 0; | 39 static Uint32 SDL_eventstate = 0; |
39 | 40 |
40 /* Private data -- event queue */ | 41 /* Private data -- event queue */ |
41 #define MAXEVENTS 128 | 42 #define MAXEVENTS 128 |
42 static struct { | 43 static struct |
43 SDL_mutex *lock; | 44 { |
44 int active; | 45 SDL_mutex *lock; |
45 int head; | 46 int active; |
46 int tail; | 47 int head; |
47 SDL_Event event[MAXEVENTS]; | 48 int tail; |
48 int wmmsg_next; | 49 SDL_Event event[MAXEVENTS]; |
49 struct SDL_SysWMmsg wmmsg[MAXEVENTS]; | 50 int wmmsg_next; |
51 struct SDL_SysWMmsg wmmsg[MAXEVENTS]; | |
50 } SDL_EventQ; | 52 } SDL_EventQ; |
51 | 53 |
52 /* Private data -- event locking structure */ | 54 /* Private data -- event locking structure */ |
53 static struct { | 55 static struct |
54 SDL_mutex *lock; | 56 { |
55 int safe; | 57 SDL_mutex *lock; |
58 int safe; | |
56 } SDL_EventLock; | 59 } SDL_EventLock; |
57 | 60 |
58 /* Thread functions */ | 61 /* Thread functions */ |
59 static SDL_Thread *SDL_EventThread = NULL; /* Thread handle */ | 62 static SDL_Thread *SDL_EventThread = NULL; /* Thread handle */ |
60 static Uint32 event_thread; /* The event thread id */ | 63 static Uint32 event_thread; /* The event thread id */ |
61 | 64 |
62 void SDL_Lock_EventThread(void) | 65 void |
63 { | 66 SDL_Lock_EventThread(void) |
64 if ( SDL_EventThread && (SDL_ThreadID() != event_thread) ) { | 67 { |
65 /* Grab lock and spin until we're sure event thread stopped */ | 68 if (SDL_EventThread && (SDL_ThreadID() != event_thread)) { |
66 SDL_mutexP(SDL_EventLock.lock); | 69 /* Grab lock and spin until we're sure event thread stopped */ |
67 while ( ! SDL_EventLock.safe ) { | 70 SDL_mutexP(SDL_EventLock.lock); |
68 SDL_Delay(1); | 71 while (!SDL_EventLock.safe) { |
69 } | 72 SDL_Delay(1); |
70 } | 73 } |
71 } | 74 } |
72 void SDL_Unlock_EventThread(void) | 75 } |
73 { | 76 void |
74 if ( SDL_EventThread && (SDL_ThreadID() != event_thread) ) { | 77 SDL_Unlock_EventThread(void) |
75 SDL_mutexV(SDL_EventLock.lock); | 78 { |
76 } | 79 if (SDL_EventThread && (SDL_ThreadID() != event_thread)) { |
80 SDL_mutexV(SDL_EventLock.lock); | |
81 } | |
77 } | 82 } |
78 | 83 |
79 #ifdef __OS2__ | 84 #ifdef __OS2__ |
80 /* | 85 /* |
81 * We'll increase the priority of GobbleEvents thread, so it will process | 86 * We'll increase the priority of GobbleEvents thread, so it will process |
85 #define INCL_DOSPROCESS | 90 #define INCL_DOSPROCESS |
86 #include <os2.h> | 91 #include <os2.h> |
87 #include <time.h> | 92 #include <time.h> |
88 #endif | 93 #endif |
89 | 94 |
90 static int SDLCALL SDL_GobbleEvents(void *unused) | 95 static int SDLCALL |
91 { | 96 SDL_GobbleEvents(void *unused) |
92 event_thread = SDL_ThreadID(); | 97 { |
98 event_thread = SDL_ThreadID(); | |
93 | 99 |
94 #ifdef __OS2__ | 100 #ifdef __OS2__ |
95 #ifdef USE_DOSSETPRIORITY | 101 #ifdef USE_DOSSETPRIORITY |
96 /* Increase thread priority, so it will process events in time for sure! */ | 102 /* Increase thread priority, so it will process events in time for sure! */ |
97 DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, +16, 0); | 103 DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, +16, 0); |
98 #endif | 104 #endif |
99 #endif | 105 #endif |
100 | 106 |
101 while ( SDL_EventQ.active ) { | 107 while (SDL_EventQ.active) { |
102 SDL_VideoDevice *video = current_video; | 108 SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
103 SDL_VideoDevice *this = current_video; | 109 |
104 | 110 /* Get events from the video subsystem */ |
105 /* Get events from the video subsystem */ | 111 if (_this) { |
106 if ( video ) { | 112 _this->PumpEvents(_this); |
107 video->PumpEvents(this); | 113 } |
108 } | 114 |
109 | 115 /* Queue pending key-repeat events */ |
110 /* Queue pending key-repeat events */ | 116 SDL_CheckKeyRepeat(); |
111 SDL_CheckKeyRepeat(); | |
112 | 117 |
113 #if !SDL_JOYSTICK_DISABLED | 118 #if !SDL_JOYSTICK_DISABLED |
114 /* Check for joystick state change */ | 119 /* Check for joystick state change */ |
115 if ( SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK) ) { | 120 if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) { |
116 SDL_JoystickUpdate(); | 121 SDL_JoystickUpdate(); |
117 } | 122 } |
118 #endif | 123 #endif |
119 | 124 |
120 /* Give up the CPU for the rest of our timeslice */ | 125 /* Give up the CPU for the rest of our timeslice */ |
121 SDL_EventLock.safe = 1; | 126 SDL_EventLock.safe = 1; |
122 if ( SDL_timer_running ) { | 127 if (SDL_timer_running) { |
123 SDL_ThreadedTimerCheck(); | 128 SDL_ThreadedTimerCheck(); |
124 } | 129 } |
125 SDL_Delay(1); | 130 SDL_Delay(1); |
126 | 131 |
127 /* Check for event locking. | 132 /* Check for event locking. |
128 On the P of the lock mutex, if the lock is held, this thread | 133 On the P of the lock mutex, if the lock is held, this thread |
129 will wait until the lock is released before continuing. The | 134 will wait until the lock is released before continuing. The |
130 safe flag will be set, meaning that the other thread can go | 135 safe flag will be set, meaning that the other thread can go |
131 about it's business. The safe flag is reset before the V, | 136 about it's business. The safe flag is reset before the V, |
132 so as soon as the mutex is free, other threads can see that | 137 so as soon as the mutex is free, other threads can see that |
133 it's not safe to interfere with the event thread. | 138 it's not safe to interfere with the event thread. |
134 */ | 139 */ |
135 SDL_mutexP(SDL_EventLock.lock); | 140 SDL_mutexP(SDL_EventLock.lock); |
136 SDL_EventLock.safe = 0; | 141 SDL_EventLock.safe = 0; |
137 SDL_mutexV(SDL_EventLock.lock); | 142 SDL_mutexV(SDL_EventLock.lock); |
138 } | 143 } |
139 SDL_SetTimerThreaded(0); | 144 SDL_SetTimerThreaded(0); |
140 event_thread = 0; | 145 event_thread = 0; |
141 return(0); | 146 return (0); |
142 } | 147 } |
143 | 148 |
144 static int SDL_StartEventThread(Uint32 flags) | 149 static int |
145 { | 150 SDL_StartEventThread(Uint32 flags) |
146 /* Reset everything to zero */ | 151 { |
147 SDL_EventThread = NULL; | 152 /* Reset everything to zero */ |
148 SDL_memset(&SDL_EventLock, 0, sizeof(SDL_EventLock)); | 153 SDL_EventThread = NULL; |
149 | 154 SDL_memset(&SDL_EventLock, 0, sizeof(SDL_EventLock)); |
150 /* Create the lock and set ourselves active */ | 155 |
156 /* Create the lock and set ourselves active */ | |
151 #if !SDL_THREADS_DISABLED | 157 #if !SDL_THREADS_DISABLED |
152 SDL_EventQ.lock = SDL_CreateMutex(); | 158 SDL_EventQ.lock = SDL_CreateMutex(); |
153 if ( SDL_EventQ.lock == NULL ) { | 159 if (SDL_EventQ.lock == NULL) { |
154 #ifdef __MACOS__ /* MacOS classic you can't multithread, so no lock needed */ | 160 #ifdef __MACOS__ /* MacOS classic you can't multithread, so no lock needed */ |
155 ; | 161 ; |
156 #else | 162 #else |
157 return(-1); | 163 return (-1); |
158 #endif | 164 #endif |
159 } | 165 } |
160 #endif /* !SDL_THREADS_DISABLED */ | 166 #endif /* !SDL_THREADS_DISABLED */ |
161 SDL_EventQ.active = 1; | 167 SDL_EventQ.active = 1; |
162 | 168 |
163 if ( (flags&SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { | 169 if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) { |
164 SDL_EventLock.lock = SDL_CreateMutex(); | 170 SDL_EventLock.lock = SDL_CreateMutex(); |
165 if ( SDL_EventLock.lock == NULL ) { | 171 if (SDL_EventLock.lock == NULL) { |
166 return(-1); | 172 return (-1); |
167 } | 173 } |
168 SDL_EventLock.safe = 0; | 174 SDL_EventLock.safe = 0; |
169 | 175 |
170 /* The event thread will handle timers too */ | 176 /* The event thread will handle timers too */ |
171 SDL_SetTimerThreaded(2); | 177 SDL_SetTimerThreaded(2); |
172 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) | 178 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) |
173 #undef SDL_CreateThread | 179 #undef SDL_CreateThread |
174 SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL); | 180 SDL_EventThread = |
181 SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL); | |
175 #else | 182 #else |
176 SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL); | 183 SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL); |
177 #endif | 184 #endif |
178 if ( SDL_EventThread == NULL ) { | 185 if (SDL_EventThread == NULL) { |
179 return(-1); | 186 return (-1); |
180 } | 187 } |
181 } else { | 188 } else { |
182 event_thread = 0; | 189 event_thread = 0; |
183 } | 190 } |
184 return(0); | 191 return (0); |
185 } | 192 } |
186 | 193 |
187 static void SDL_StopEventThread(void) | 194 static void |
188 { | 195 SDL_StopEventThread(void) |
189 SDL_EventQ.active = 0; | 196 { |
190 if ( SDL_EventThread ) { | 197 SDL_EventQ.active = 0; |
191 SDL_WaitThread(SDL_EventThread, NULL); | 198 if (SDL_EventThread) { |
192 SDL_EventThread = NULL; | 199 SDL_WaitThread(SDL_EventThread, NULL); |
193 SDL_DestroyMutex(SDL_EventLock.lock); | 200 SDL_EventThread = NULL; |
194 } | 201 SDL_DestroyMutex(SDL_EventLock.lock); |
202 } | |
195 #ifndef IPOD | 203 #ifndef IPOD |
196 SDL_DestroyMutex(SDL_EventQ.lock); | 204 SDL_DestroyMutex(SDL_EventQ.lock); |
197 #endif | 205 #endif |
198 } | 206 } |
199 | 207 |
200 Uint32 SDL_EventThreadID(void) | 208 Uint32 |
201 { | 209 SDL_EventThreadID(void) |
202 return(event_thread); | 210 { |
211 return (event_thread); | |
203 } | 212 } |
204 | 213 |
205 /* Public functions */ | 214 /* Public functions */ |
206 | 215 |
207 void SDL_StopEventLoop(void) | 216 void |
208 { | 217 SDL_StopEventLoop(void) |
209 /* Halt the event thread, if running */ | 218 { |
210 SDL_StopEventThread(); | 219 /* Halt the event thread, if running */ |
211 | 220 SDL_StopEventThread(); |
212 /* Shutdown event handlers */ | 221 |
213 SDL_AppActiveQuit(); | 222 /* Shutdown event handlers */ |
214 SDL_KeyboardQuit(); | 223 SDL_KeyboardQuit(); |
215 SDL_MouseQuit(); | 224 SDL_MouseQuit(); |
216 SDL_QuitQuit(); | 225 SDL_QuitQuit(); |
217 | 226 |
218 /* Clean out EventQ */ | 227 /* Clean out EventQ */ |
219 SDL_EventQ.head = 0; | 228 SDL_EventQ.head = 0; |
220 SDL_EventQ.tail = 0; | 229 SDL_EventQ.tail = 0; |
221 SDL_EventQ.wmmsg_next = 0; | 230 SDL_EventQ.wmmsg_next = 0; |
222 } | 231 } |
223 | 232 |
224 /* This function (and associated calls) may be called more than once */ | 233 /* This function (and associated calls) may be called more than once */ |
225 int SDL_StartEventLoop(Uint32 flags) | 234 int |
226 { | 235 SDL_StartEventLoop(Uint32 flags) |
227 int retcode; | 236 { |
228 | 237 int retcode; |
229 /* Clean out the event queue */ | 238 |
230 SDL_EventThread = NULL; | 239 /* Clean out the event queue */ |
231 SDL_EventQ.lock = NULL; | 240 SDL_EventThread = NULL; |
232 SDL_StopEventLoop(); | 241 SDL_EventQ.lock = NULL; |
233 | 242 SDL_StopEventLoop(); |
234 /* No filter to start with, process most event types */ | 243 |
235 SDL_EventOK = NULL; | 244 /* No filter to start with, process most event types */ |
236 SDL_memset(SDL_ProcessEvents,SDL_ENABLE,sizeof(SDL_ProcessEvents)); | 245 SDL_EventOK = NULL; |
237 SDL_eventstate = ~0; | 246 SDL_memset(SDL_ProcessEvents, SDL_ENABLE, sizeof(SDL_ProcessEvents)); |
238 /* It's not save to call SDL_EventState() yet */ | 247 SDL_eventstate = ~0; |
239 SDL_eventstate &= ~(0x00000001 << SDL_SYSWMEVENT); | 248 /* It's not save to call SDL_EventState() yet */ |
240 SDL_ProcessEvents[SDL_SYSWMEVENT] = SDL_IGNORE; | 249 SDL_eventstate &= ~(0x00000001 << SDL_SYSWMEVENT); |
241 | 250 SDL_ProcessEvents[SDL_SYSWMEVENT] = SDL_IGNORE; |
242 /* Initialize event handlers */ | 251 |
243 retcode = 0; | 252 /* Initialize event handlers */ |
244 retcode += SDL_AppActiveInit(); | 253 retcode = 0; |
245 retcode += SDL_KeyboardInit(); | 254 retcode += SDL_KeyboardInit(); |
246 retcode += SDL_MouseInit(); | 255 retcode += SDL_MouseInit(); |
247 retcode += SDL_QuitInit(); | 256 retcode += SDL_QuitInit(); |
248 if ( retcode < 0 ) { | 257 if (retcode < 0) { |
249 /* We don't expect them to fail, but... */ | 258 /* We don't expect them to fail, but... */ |
250 return(-1); | 259 return (-1); |
251 } | 260 } |
252 | 261 |
253 /* Create the lock and event thread */ | 262 /* Create the lock and event thread */ |
254 if ( SDL_StartEventThread(flags) < 0 ) { | 263 if (SDL_StartEventThread(flags) < 0) { |
255 SDL_StopEventLoop(); | 264 SDL_StopEventLoop(); |
256 return(-1); | 265 return (-1); |
257 } | 266 } |
258 return(0); | 267 return (0); |
259 } | 268 } |
260 | 269 |
261 | 270 |
262 /* Add an event to the event queue -- called with the queue locked */ | 271 /* Add an event to the event queue -- called with the queue locked */ |
263 static int SDL_AddEvent(SDL_Event *event) | 272 static int |
264 { | 273 SDL_AddEvent(SDL_Event * event) |
265 int tail, added; | 274 { |
266 | 275 int tail, added; |
267 tail = (SDL_EventQ.tail+1)%MAXEVENTS; | 276 |
268 if ( tail == SDL_EventQ.head ) { | 277 tail = (SDL_EventQ.tail + 1) % MAXEVENTS; |
269 /* Overflow, drop event */ | 278 if (tail == SDL_EventQ.head) { |
270 added = 0; | 279 /* Overflow, drop event */ |
271 } else { | 280 added = 0; |
272 SDL_EventQ.event[SDL_EventQ.tail] = *event; | 281 } else { |
273 if (event->type == SDL_SYSWMEVENT) { | 282 SDL_EventQ.event[SDL_EventQ.tail] = *event; |
274 /* Note that it's possible to lose an event */ | 283 if (event->type == SDL_SYSWMEVENT) { |
275 int next = SDL_EventQ.wmmsg_next; | 284 /* Note that it's possible to lose an event */ |
276 SDL_EventQ.wmmsg[next] = *event->syswm.msg; | 285 int next = SDL_EventQ.wmmsg_next; |
277 SDL_EventQ.event[SDL_EventQ.tail].syswm.msg = | 286 SDL_EventQ.wmmsg[next] = *event->syswm.msg; |
278 &SDL_EventQ.wmmsg[next]; | 287 SDL_EventQ.event[SDL_EventQ.tail].syswm.msg = |
279 SDL_EventQ.wmmsg_next = (next+1)%MAXEVENTS; | 288 &SDL_EventQ.wmmsg[next]; |
280 } | 289 SDL_EventQ.wmmsg_next = (next + 1) % MAXEVENTS; |
281 SDL_EventQ.tail = tail; | 290 } |
282 added = 1; | 291 SDL_EventQ.tail = tail; |
283 } | 292 added = 1; |
284 return(added); | 293 } |
294 return (added); | |
285 } | 295 } |
286 | 296 |
287 /* Cut an event, and return the next valid spot, or the tail */ | 297 /* Cut an event, and return the next valid spot, or the tail */ |
288 /* -- called with the queue locked */ | 298 /* -- called with the queue locked */ |
289 static int SDL_CutEvent(int spot) | 299 static int |
290 { | 300 SDL_CutEvent(int spot) |
291 if ( spot == SDL_EventQ.head ) { | 301 { |
292 SDL_EventQ.head = (SDL_EventQ.head+1)%MAXEVENTS; | 302 if (spot == SDL_EventQ.head) { |
293 return(SDL_EventQ.head); | 303 SDL_EventQ.head = (SDL_EventQ.head + 1) % MAXEVENTS; |
294 } else | 304 return (SDL_EventQ.head); |
295 if ( (spot+1)%MAXEVENTS == SDL_EventQ.tail ) { | 305 } else if ((spot + 1) % MAXEVENTS == SDL_EventQ.tail) { |
296 SDL_EventQ.tail = spot; | 306 SDL_EventQ.tail = spot; |
297 return(SDL_EventQ.tail); | 307 return (SDL_EventQ.tail); |
298 } else | 308 } else |
299 /* We cut the middle -- shift everything over */ | 309 /* We cut the middle -- shift everything over */ |
300 { | 310 { |
301 int here, next; | 311 int here, next; |
302 | 312 |
303 /* This can probably be optimized with SDL_memcpy() -- careful! */ | 313 /* This can probably be optimized with SDL_memcpy() -- careful! */ |
304 if ( --SDL_EventQ.tail < 0 ) { | 314 if (--SDL_EventQ.tail < 0) { |
305 SDL_EventQ.tail = MAXEVENTS-1; | 315 SDL_EventQ.tail = MAXEVENTS - 1; |
306 } | 316 } |
307 for ( here=spot; here != SDL_EventQ.tail; here = next ) { | 317 for (here = spot; here != SDL_EventQ.tail; here = next) { |
308 next = (here+1)%MAXEVENTS; | 318 next = (here + 1) % MAXEVENTS; |
309 SDL_EventQ.event[here] = SDL_EventQ.event[next]; | 319 SDL_EventQ.event[here] = SDL_EventQ.event[next]; |
310 } | 320 } |
311 return(spot); | 321 return (spot); |
312 } | 322 } |
313 /* NOTREACHED */ | 323 /* NOTREACHED */ |
314 } | 324 } |
315 | 325 |
316 /* Lock the event queue, take a peep at it, and unlock it */ | 326 /* Lock the event queue, take a peep at it, and unlock it */ |
317 int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, | 327 int |
318 Uint32 mask) | 328 SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, |
319 { | 329 Uint32 mask) |
320 int i, used; | 330 { |
321 | 331 int i, used; |
322 /* Don't look after we've quit */ | 332 |
323 if ( ! SDL_EventQ.active ) { | 333 /* Don't look after we've quit */ |
324 return(-1); | 334 if (!SDL_EventQ.active) { |
325 } | 335 return (-1); |
326 /* Lock the event queue */ | 336 } |
327 used = 0; | 337 /* Lock the event queue */ |
328 if ( SDL_mutexP(SDL_EventQ.lock) == 0 ) { | 338 used = 0; |
329 if ( action == SDL_ADDEVENT ) { | 339 if (SDL_mutexP(SDL_EventQ.lock) == 0) { |
330 for ( i=0; i<numevents; ++i ) { | 340 if (action == SDL_ADDEVENT) { |
331 used += SDL_AddEvent(&events[i]); | 341 for (i = 0; i < numevents; ++i) { |
332 } | 342 used += SDL_AddEvent(&events[i]); |
333 } else { | 343 } |
334 SDL_Event tmpevent; | 344 } else { |
335 int spot; | 345 SDL_Event tmpevent; |
336 | 346 int spot; |
337 /* If 'events' is NULL, just see if they exist */ | 347 |
338 if ( events == NULL ) { | 348 /* If 'events' is NULL, just see if they exist */ |
339 action = SDL_PEEKEVENT; | 349 if (events == NULL) { |
340 numevents = 1; | 350 action = SDL_PEEKEVENT; |
341 events = &tmpevent; | 351 numevents = 1; |
342 } | 352 events = &tmpevent; |
343 spot = SDL_EventQ.head; | 353 } |
344 while ((used < numevents)&&(spot != SDL_EventQ.tail)) { | 354 spot = SDL_EventQ.head; |
345 if ( mask & SDL_EVENTMASK(SDL_EventQ.event[spot].type) ) { | 355 while ((used < numevents) && (spot != SDL_EventQ.tail)) { |
346 events[used++] = SDL_EventQ.event[spot]; | 356 if (mask & SDL_EVENTMASK(SDL_EventQ.event[spot].type)) { |
347 if ( action == SDL_GETEVENT ) { | 357 events[used++] = SDL_EventQ.event[spot]; |
348 spot = SDL_CutEvent(spot); | 358 if (action == SDL_GETEVENT) { |
349 } else { | 359 spot = SDL_CutEvent(spot); |
350 spot = (spot+1)%MAXEVENTS; | 360 } else { |
351 } | 361 spot = (spot + 1) % MAXEVENTS; |
352 } else { | 362 } |
353 spot = (spot+1)%MAXEVENTS; | 363 } else { |
354 } | 364 spot = (spot + 1) % MAXEVENTS; |
355 } | 365 } |
356 } | 366 } |
357 SDL_mutexV(SDL_EventQ.lock); | 367 } |
358 } else { | 368 SDL_mutexV(SDL_EventQ.lock); |
359 SDL_SetError("Couldn't lock event queue"); | 369 } else { |
360 used = -1; | 370 SDL_SetError("Couldn't lock event queue"); |
361 } | 371 used = -1; |
362 return(used); | 372 } |
373 return (used); | |
374 } | |
375 | |
376 SDL_bool | |
377 SDL_HasEvent(Uint32 mask) | |
378 { | |
379 return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask) > 0); | |
363 } | 380 } |
364 | 381 |
365 /* Run the system dependent event loops */ | 382 /* Run the system dependent event loops */ |
366 void SDL_PumpEvents(void) | 383 void |
367 { | 384 SDL_PumpEvents(void) |
368 if ( !SDL_EventThread ) { | 385 { |
369 SDL_VideoDevice *video = current_video; | 386 if (!SDL_EventThread) { |
370 SDL_VideoDevice *this = current_video; | 387 SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
371 | 388 |
372 /* Get events from the video subsystem */ | 389 /* Get events from the video subsystem */ |
373 if ( video ) { | 390 if (_this) { |
374 video->PumpEvents(this); | 391 _this->PumpEvents(_this); |
375 } | 392 } |
376 | 393 |
377 /* Queue pending key-repeat events */ | 394 /* Queue pending key-repeat events */ |
378 SDL_CheckKeyRepeat(); | 395 SDL_CheckKeyRepeat(); |
379 | 396 |
380 #if !SDL_JOYSTICK_DISABLED | 397 #if !SDL_JOYSTICK_DISABLED |
381 /* Check for joystick state change */ | 398 /* Check for joystick state change */ |
382 if ( SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK) ) { | 399 if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) { |
383 SDL_JoystickUpdate(); | 400 SDL_JoystickUpdate(); |
384 } | 401 } |
385 #endif | 402 #endif |
386 } | 403 } |
387 } | 404 } |
388 | 405 |
389 /* Public functions */ | 406 /* Public functions */ |
390 | 407 |
391 int SDL_PollEvent (SDL_Event *event) | 408 int |
392 { | 409 SDL_PollEvent(SDL_Event * event) |
393 SDL_PumpEvents(); | 410 { |
394 | 411 SDL_PumpEvents(); |
395 /* We can't return -1, just return 0 (no event) on error */ | 412 |
396 if ( SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS) <= 0 ) | 413 /* We can't return -1, just return 0 (no event) on error */ |
397 return 0; | 414 if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS) <= 0) |
398 return 1; | 415 return 0; |
399 } | 416 return 1; |
400 | 417 } |
401 int SDL_WaitEvent (SDL_Event *event) | 418 |
402 { | 419 int |
403 while ( 1 ) { | 420 SDL_WaitEvent(SDL_Event * event) |
404 SDL_PumpEvents(); | 421 { |
405 switch(SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) { | 422 while (1) { |
406 case -1: return 0; | 423 SDL_PumpEvents(); |
407 case 1: return 1; | 424 switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) { |
408 case 0: SDL_Delay(10); | 425 case -1: |
409 } | 426 return 0; |
410 } | 427 case 1: |
411 } | 428 return 1; |
412 | 429 case 0: |
413 int SDL_PushEvent(SDL_Event *event) | 430 SDL_Delay(10); |
414 { | 431 } |
415 if ( SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0) <= 0 ) | 432 } |
416 return -1; | 433 } |
417 return 0; | 434 |
418 } | 435 int |
419 | 436 SDL_PushEvent(SDL_Event * event) |
420 void SDL_SetEventFilter (SDL_EventFilter filter) | 437 { |
421 { | 438 if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) { |
422 SDL_Event bitbucket; | 439 return 0; |
423 | 440 } |
424 /* Set filter and discard pending events */ | 441 if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0) <= 0) { |
425 SDL_EventOK = filter; | 442 return -1; |
426 while ( SDL_PollEvent(&bitbucket) > 0 ) | 443 } |
427 ; | 444 return 1; |
428 } | 445 } |
429 | 446 |
430 SDL_EventFilter SDL_GetEventFilter(void) | 447 void |
431 { | 448 SDL_SetEventFilter(SDL_EventFilter filter, void *userdata) |
432 return(SDL_EventOK); | 449 { |
433 } | 450 SDL_Event bitbucket; |
434 | 451 |
435 Uint8 SDL_EventState (Uint8 type, int state) | 452 /* Set filter and discard pending events */ |
436 { | 453 SDL_EventOK = filter; |
437 SDL_Event bitbucket; | 454 SDL_EventOKParam = userdata; |
438 Uint8 current_state; | 455 while (SDL_PollEvent(&bitbucket) > 0); |
439 | 456 } |
440 /* If SDL_ALLEVENTS was specified... */ | 457 |
441 if ( type == 0xFF ) { | 458 SDL_bool |
442 current_state = SDL_IGNORE; | 459 SDL_GetEventFilter(SDL_EventFilter * filter, void **userdata) |
443 for ( type=0; type<SDL_NUMEVENTS; ++type ) { | 460 { |
444 if ( SDL_ProcessEvents[type] != SDL_IGNORE ) { | 461 if (filter) { |
445 current_state = SDL_ENABLE; | 462 *filter = SDL_EventOK; |
446 } | 463 } |
447 SDL_ProcessEvents[type] = state; | 464 if (userdata) { |
448 if ( state == SDL_ENABLE ) { | 465 *userdata = SDL_EventOKParam; |
449 SDL_eventstate |= (0x00000001 << (type)); | 466 } |
450 } else { | 467 return SDL_EventOK ? SDL_TRUE : SDL_FALSE; |
451 SDL_eventstate &= ~(0x00000001 << (type)); | 468 } |
452 } | 469 |
453 } | 470 void |
454 while ( SDL_PollEvent(&bitbucket) > 0 ) | 471 SDL_FilterEvents(SDL_EventFilter filter, void *userdata) |
455 ; | 472 { |
456 return(current_state); | 473 if (SDL_mutexP(SDL_EventQ.lock) == 0) { |
457 } | 474 int spot; |
458 | 475 |
459 /* Just set the state for one event type */ | 476 spot = SDL_EventQ.head; |
460 current_state = SDL_ProcessEvents[type]; | 477 while (spot != SDL_EventQ.tail) { |
461 switch (state) { | 478 if (filter(userdata, &SDL_EventQ.event[spot])) { |
462 case SDL_IGNORE: | 479 spot = (spot + 1) % MAXEVENTS; |
463 case SDL_ENABLE: | 480 } else { |
464 /* Set state and discard pending events */ | 481 spot = SDL_CutEvent(spot); |
465 SDL_ProcessEvents[type] = state; | 482 } |
466 if ( state == SDL_ENABLE ) { | 483 } |
467 SDL_eventstate |= (0x00000001 << (type)); | 484 } |
468 } else { | 485 SDL_mutexV(SDL_EventQ.lock); |
469 SDL_eventstate &= ~(0x00000001 << (type)); | 486 } |
470 } | 487 |
471 while ( SDL_PollEvent(&bitbucket) > 0 ) | 488 Uint8 |
472 ; | 489 SDL_EventState(Uint8 type, int state) |
473 break; | 490 { |
474 default: | 491 SDL_Event bitbucket; |
475 /* Querying state? */ | 492 Uint8 current_state; |
476 break; | 493 |
477 } | 494 /* If SDL_ALLEVENTS was specified... */ |
478 return(current_state); | 495 if (type == 0xFF) { |
496 current_state = SDL_IGNORE; | |
497 for (type = 0; type < SDL_NUMEVENTS; ++type) { | |
498 if (SDL_ProcessEvents[type] != SDL_IGNORE) { | |
499 current_state = SDL_ENABLE; | |
500 } | |
501 SDL_ProcessEvents[type] = state; | |
502 if (state == SDL_ENABLE) { | |
503 SDL_eventstate |= (0x00000001 << (type)); | |
504 } else { | |
505 SDL_eventstate &= ~(0x00000001 << (type)); | |
506 } | |
507 } | |
508 while (SDL_PollEvent(&bitbucket) > 0); | |
509 return (current_state); | |
510 } | |
511 | |
512 /* Just set the state for one event type */ | |
513 current_state = SDL_ProcessEvents[type]; | |
514 switch (state) { | |
515 case SDL_IGNORE: | |
516 case SDL_ENABLE: | |
517 /* Set state and discard pending events */ | |
518 SDL_ProcessEvents[type] = state; | |
519 if (state == SDL_ENABLE) { | |
520 SDL_eventstate |= (0x00000001 << (type)); | |
521 } else { | |
522 SDL_eventstate &= ~(0x00000001 << (type)); | |
523 } | |
524 while (SDL_PollEvent(&bitbucket) > 0); | |
525 break; | |
526 default: | |
527 /* Querying state? */ | |
528 break; | |
529 } | |
530 return (current_state); | |
479 } | 531 } |
480 | 532 |
481 /* This is a generic event handler. | 533 /* This is a generic event handler. |
482 */ | 534 */ |
483 int SDL_PrivateSysWMEvent(SDL_SysWMmsg *message) | 535 int |
484 { | 536 SDL_SendSysWMEvent(SDL_SysWMmsg * message) |
485 int posted; | 537 { |
486 | 538 int posted; |
487 posted = 0; | 539 |
488 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | 540 posted = 0; |
489 SDL_Event event; | 541 if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { |
490 SDL_memset(&event, 0, sizeof(event)); | 542 SDL_Event event; |
491 event.type = SDL_SYSWMEVENT; | 543 SDL_memset(&event, 0, sizeof(event)); |
492 event.syswm.msg = message; | 544 event.type = SDL_SYSWMEVENT; |
493 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { | 545 event.syswm.msg = message; |
494 posted = 1; | 546 posted = (SDL_PushEvent(&event) > 0); |
495 SDL_PushEvent(&event); | 547 } |
496 } | 548 /* Update internal event state */ |
497 } | 549 return (posted); |
498 /* Update internal event state */ | 550 } |
499 return(posted); | 551 |
500 } | 552 /* vi: set ts=4 sw=4 expandtab: */ |