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: */