Mercurial > sdl-ios-xcode
annotate src/thread/bsdi/SDL_syssem.c @ 664:abfdc08eb289
Date: Sun, 3 Aug 2003 22:07:57 +0200
From: Max Horn
Subject: SDL OSX fullscreen FIX
the attached patch fixes the fullscreen problems on SDL/OSX. The cause
was that click events are bounded by winRect. Now, winRect is set to
the size of the video surface. But if you e.g. request a 640x420
surface, you might get a 640x480 "real" surface. Still,
SDL_VideoSurface->h will be set to 420! Thus, the upper 60 pixels in my
example received no mouse down events.
My fix simply disables this clipping when in full screen mode - after
all, all clicks then should be inside the screen surface. Higher SDL
functions ensure that the coordinates then are clipped to 640x420. It
works fine in all my tests here. I don't know if it's the right thing
to do in multi screen scenarios, though.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 04 Aug 2003 01:00:30 +0000 |
parents | f6ffac90895c |
children | b8d311d90021 |
rev | line source |
---|---|
256 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
271
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
256 | 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 #include <stdlib.h> | |
29 #include "SDL_error.h" | |
30 #include "SDL_thread.h" | |
31 #include "SDL_timer.h" | |
32 | |
33 #ifdef SDL_USE_PTHREADS | |
34 | |
35 #include <stdio.h> | |
36 #include <stdlib.h> | |
37 #include <unistd.h> /* For getpid() */ | |
38 #include <pthread.h> | |
39 | |
40 | |
41 /* | |
42 * This is semaphore.h inlined here so that BSD/OS POSIX semaphore are | |
43 * completely selfcontained without requiring any additional include files | |
44 * or libraries not present in the stock system | |
45 */ | |
46 | |
47 /* semaphore.h: POSIX 1003.1b semaphores */ | |
48 | |
49 /*- | |
50 * Copyright (c) 1996, 1997 | |
51 * HD Associates, Inc. All rights reserved. | |
52 * | |
53 * Redistribution and use in source and binary forms, with or without | |
54 * modification, are permitted provided that the following conditions | |
55 * are met: | |
56 * 1. Redistributions of source code must retain the above copyright | |
57 * notice, this list of conditions and the following disclaimer. | |
58 * 2. Redistributions in binary form must reproduce the above copyright | |
59 * notice, this list of conditions and the following disclaimer in the | |
60 * documentation and/or other materials provided with the distribution. | |
61 * 3. All advertising materials mentioning features or use of this software | |
62 * must display the following acknowledgement: | |
63 * This product includes software developed by HD Associates, Inc | |
64 * 4. Neither the name of the author nor the names of any co-contributors | |
65 * may be used to endorse or promote products derived from this software | |
66 * without specific prior written permission. | |
67 * | |
68 * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND | |
69 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
70 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
71 * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE | |
72 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
73 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
74 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
75 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
76 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
77 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
78 * SUCH DAMAGE. | |
79 * | |
80 * $FreeBSD: src/sys/posix4/semaphore.h,v 1.6 2000/01/20 07:55:42 jasone Exp $ | |
81 */ | |
82 | |
83 #include <machine/limits.h> | |
84 | |
85 #include <sys/types.h> | |
86 #include <fcntl.h> | |
87 | |
88 /* Opaque type definition. */ | |
89 struct sem; | |
90 typedef struct sem *sem_t; | |
91 | |
92 #define SEM_FAILED ((sem_t *)0) | |
93 #define SEM_VALUE_MAX UINT_MAX | |
94 | |
95 #include <sys/cdefs.h> | |
96 | |
97 __BEGIN_DECLS | |
98 int sem_init __P((sem_t *, int, unsigned int)); | |
99 int sem_destroy __P((sem_t *)); | |
100 sem_t *sem_open __P((const char *, int, ...)); | |
101 int sem_close __P((sem_t *)); | |
102 int sem_unlink __P((const char *)); | |
103 int sem_wait __P((sem_t *)); | |
104 int sem_trywait __P((sem_t *)); | |
105 int sem_post __P((sem_t *)); | |
106 int sem_getvalue __P((sem_t *, int *)); | |
107 __END_DECLS | |
108 | |
109 /* END of inlined semaphore.h */ | |
110 | |
111 /* Wrapper around POSIX 1003.1b semaphores */ | |
112 | |
113 struct SDL_semaphore { | |
114 sem_t *sem; | |
115 sem_t sem_data; | |
116 }; | |
117 | |
118 /* Create a semaphore, initialized with value */ | |
119 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) | |
120 { | |
121 SDL_sem *sem = (SDL_sem *) malloc(sizeof(SDL_sem)); | |
122 if ( sem ) { | |
123 if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) { | |
124 SDL_SetError("sem_init() failed"); | |
125 free(sem); | |
126 sem = NULL; | |
127 } else { | |
128 sem->sem = &sem->sem_data; | |
129 } | |
130 } else { | |
131 SDL_OutOfMemory(); | |
132 } | |
133 return sem; | |
134 } | |
135 | |
136 void SDL_DestroySemaphore(SDL_sem *sem) | |
137 { | |
138 if ( sem ) { | |
139 sem_destroy(sem->sem); | |
140 free(sem); | |
141 } | |
142 } | |
143 | |
144 int SDL_SemTryWait(SDL_sem *sem) | |
145 { | |
146 int retval; | |
147 | |
148 if ( ! sem ) { | |
149 SDL_SetError("Passed a NULL semaphore"); | |
150 return -1; | |
151 } | |
152 retval = SDL_MUTEX_TIMEDOUT; | |
153 if ( sem_trywait(sem->sem) == 0 ) | |
154 retval = 0; | |
155 return retval; | |
156 } | |
157 | |
158 int SDL_SemWait(SDL_sem *sem) | |
159 { | |
160 int retval; | |
161 | |
162 if ( ! sem ) { | |
163 SDL_SetError("Passed a NULL semaphore"); | |
164 return -1; | |
165 } | |
166 | |
167 retval = sem_wait(sem->sem); | |
168 if ( retval < 0 ) { | |
169 SDL_SetError("sem_wait() failed"); | |
170 } | |
171 return retval; | |
172 } | |
173 | |
174 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) | |
175 { | |
176 int retval; | |
177 | |
178 if ( ! sem ) { | |
179 SDL_SetError("Passed a NULL semaphore"); | |
180 return -1; | |
181 } | |
182 | |
183 /* Try the easy cases first */ | |
184 if ( timeout == 0 ) { | |
185 return SDL_SemTryWait(sem); | |
186 } | |
187 if ( timeout == SDL_MUTEX_MAXWAIT ) { | |
188 return SDL_SemWait(sem); | |
189 } | |
190 | |
191 /* Ack! We have to busy wait... */ | |
192 timeout += SDL_GetTicks(); | |
193 do { | |
194 retval = SDL_SemTryWait(sem); | |
195 if ( retval == 0 ) { | |
196 break; | |
197 } | |
198 SDL_Delay(1); | |
199 } while ( SDL_GetTicks() < timeout ); | |
200 | |
201 return retval; | |
202 } | |
203 | |
204 Uint32 SDL_SemValue(SDL_sem *sem) | |
205 { | |
206 int ret = 0; | |
207 if ( sem ) { | |
208 sem_getvalue(sem->sem, &ret); | |
209 if ( ret < 0 ) { | |
210 ret = 0; | |
211 } | |
212 } | |
213 return (Uint32)ret; | |
214 } | |
215 | |
216 int SDL_SemPost(SDL_sem *sem) | |
217 { | |
218 int retval; | |
219 | |
220 if ( ! sem ) { | |
221 SDL_SetError("Passed a NULL semaphore"); | |
222 return -1; | |
223 } | |
224 | |
225 retval = sem_post(sem->sem); | |
226 if ( retval < 0 ) { | |
227 SDL_SetError("sem_post() failed"); | |
228 } | |
229 return retval; | |
230 } | |
231 | |
232 /* | |
233 * BEGIN inlined uthread_sem.c. This is done here so that no extra libraries | |
234 * or include files not present in BSD/OS are required | |
235 */ | |
236 | |
237 /* | |
238 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. | |
239 * All rights reserved. | |
240 * | |
241 * Redistribution and use in source and binary forms, with or without | |
242 * modification, are permitted provided that the following conditions | |
243 * are met: | |
244 * 1. Redistributions of source code must retain the above copyright | |
245 * notice(s), this list of conditions and the following disclaimer as | |
246 * the first lines of this file unmodified other than the possible | |
247 * addition of one or more copyright notices. | |
248 * 2. Redistributions in binary form must reproduce the above copyright | |
249 * notice(s), this list of conditions and the following disclaimer in | |
250 * the documentation and/or other materials provided with the | |
251 * distribution. | |
252 * | |
253 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY | |
254 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
255 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
256 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE | |
257 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
258 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
259 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
260 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
261 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
262 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
263 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
264 * | |
265 * $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $ | |
266 */ | |
267 | |
268 #include <errno.h> | |
269 #include <pthread.h> | |
270 | |
271 /* Begin thread_private.h kluge */ | |
272 /* | |
273 * These come out of (or should go into) thread_private.h - rather than have | |
274 * to copy (or symlink) the files from the source tree these definitions are | |
275 * inlined here. Obviously these go away when this module is part of libc. | |
276 */ | |
277 struct sem { | |
278 #define SEM_MAGIC ((u_int32_t) 0x09fa4012) | |
279 u_int32_t magic; | |
280 pthread_mutex_t lock; | |
281 pthread_cond_t gtzero; | |
282 u_int32_t count; | |
283 u_int32_t nwaiters; | |
284 }; | |
285 | |
286 extern pthread_once_t _thread_init_once; | |
287 extern int _threads_initialized; | |
288 extern void _thread_init __P((void)); | |
289 #define THREAD_INIT() \ | |
290 (void) pthread_once(&_thread_init_once, _thread_init) | |
291 #define THREAD_SAFE() \ | |
292 (_threads_initialized != 0) | |
293 | |
294 #define _SEM_CHECK_VALIDITY(sem) \ | |
295 if ((*(sem))->magic != SEM_MAGIC) { \ | |
296 errno = EINVAL; \ | |
297 retval = -1; \ | |
298 goto RETURN; \ | |
299 } | |
300 /* End thread_private.h kluge */ | |
301 | |
302 int | |
303 sem_init(sem_t *sem, int pshared, unsigned int value) | |
304 { | |
305 int retval; | |
306 | |
307 if (!THREAD_SAFE()) | |
308 THREAD_INIT(); | |
309 | |
310 /* | |
311 * Range check the arguments. | |
312 */ | |
313 if (pshared != 0) { | |
314 /* | |
315 * The user wants a semaphore that can be shared among | |
316 * processes, which this implementation can't do. Sounds like a | |
317 * permissions problem to me (yeah right). | |
318 */ | |
319 errno = EPERM; | |
320 retval = -1; | |
321 goto RETURN; | |
322 } | |
323 | |
324 if (value > SEM_VALUE_MAX) { | |
325 errno = EINVAL; | |
326 retval = -1; | |
327 goto RETURN; | |
328 } | |
329 | |
330 *sem = (sem_t)malloc(sizeof(struct sem)); | |
331 if (*sem == NULL) { | |
332 errno = ENOSPC; | |
333 retval = -1; | |
334 goto RETURN; | |
335 } | |
336 | |
337 /* | |
338 * Initialize the semaphore. | |
339 */ | |
340 if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) { | |
341 free(*sem); | |
342 errno = ENOSPC; | |
343 retval = -1; | |
344 goto RETURN; | |
345 } | |
346 | |
347 if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) { | |
348 pthread_mutex_destroy(&(*sem)->lock); | |
349 free(*sem); | |
350 errno = ENOSPC; | |
351 retval = -1; | |
352 goto RETURN; | |
353 } | |
354 | |
355 (*sem)->count = (u_int32_t)value; | |
356 (*sem)->nwaiters = 0; | |
357 (*sem)->magic = SEM_MAGIC; | |
358 | |
359 retval = 0; | |
360 RETURN: | |
361 return retval; | |
362 } | |
363 | |
364 int | |
365 sem_destroy(sem_t *sem) | |
366 { | |
367 int retval; | |
368 | |
369 _SEM_CHECK_VALIDITY(sem); | |
370 | |
371 /* Make sure there are no waiters. */ | |
372 pthread_mutex_lock(&(*sem)->lock); | |
373 if ((*sem)->nwaiters > 0) { | |
374 pthread_mutex_unlock(&(*sem)->lock); | |
375 errno = EBUSY; | |
376 retval = -1; | |
377 goto RETURN; | |
378 } | |
379 pthread_mutex_unlock(&(*sem)->lock); | |
380 | |
381 pthread_mutex_destroy(&(*sem)->lock); | |
382 pthread_cond_destroy(&(*sem)->gtzero); | |
383 (*sem)->magic = 0; | |
384 | |
385 free(*sem); | |
386 | |
387 retval = 0; | |
388 RETURN: | |
389 return retval; | |
390 } | |
391 | |
392 sem_t * | |
393 sem_open(const char *name, int oflag, ...) | |
394 { | |
395 errno = ENOSYS; | |
396 return SEM_FAILED; | |
397 } | |
398 | |
399 int | |
400 sem_close(sem_t *sem) | |
401 { | |
402 errno = ENOSYS; | |
403 return -1; | |
404 } | |
405 | |
406 int | |
407 sem_unlink(const char *name) | |
408 { | |
409 errno = ENOSYS; | |
410 return -1; | |
411 } | |
412 | |
413 int | |
414 sem_wait(sem_t *sem) | |
415 { | |
416 int retval; | |
417 | |
418 pthread_testcancel(); | |
419 | |
420 _SEM_CHECK_VALIDITY(sem); | |
421 | |
422 pthread_mutex_lock(&(*sem)->lock); | |
423 | |
424 while ((*sem)->count == 0) { | |
425 (*sem)->nwaiters++; | |
426 pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); | |
427 (*sem)->nwaiters--; | |
428 } | |
429 (*sem)->count--; | |
430 | |
431 pthread_mutex_unlock(&(*sem)->lock); | |
432 | |
433 retval = 0; | |
434 RETURN: | |
435 | |
436 pthread_testcancel(); | |
437 return retval; | |
438 } | |
439 | |
440 int | |
441 sem_trywait(sem_t *sem) | |
442 { | |
443 int retval; | |
444 | |
445 _SEM_CHECK_VALIDITY(sem); | |
446 | |
447 pthread_mutex_lock(&(*sem)->lock); | |
448 | |
449 if ((*sem)->count > 0) { | |
450 (*sem)->count--; | |
451 retval = 0; | |
452 } else { | |
453 errno = EAGAIN; | |
454 retval = -1; | |
455 } | |
456 | |
457 pthread_mutex_unlock(&(*sem)->lock); | |
458 | |
459 RETURN: | |
460 return retval; | |
461 } | |
462 | |
463 int | |
464 sem_post(sem_t *sem) | |
465 { | |
466 int retval; | |
467 | |
468 _SEM_CHECK_VALIDITY(sem); | |
469 | |
470 pthread_mutex_lock(&(*sem)->lock); | |
471 | |
472 (*sem)->count++; | |
473 if ((*sem)->nwaiters > 0) { | |
474 /* | |
475 * We must use pthread_cond_broadcast() rather than | |
476 * pthread_cond_signal() in order to assure that the highest | |
477 * priority thread is run by the scheduler, since | |
478 * pthread_cond_signal() signals waiting threads in FIFO order. | |
479 */ | |
480 pthread_cond_broadcast(&(*sem)->gtzero); | |
481 } | |
482 | |
483 pthread_mutex_unlock(&(*sem)->lock); | |
484 | |
485 retval = 0; | |
486 RETURN: | |
487 return retval; | |
488 } | |
489 | |
490 int | |
491 sem_getvalue(sem_t *sem, int *sval) | |
492 { | |
493 int retval; | |
494 | |
495 _SEM_CHECK_VALIDITY(sem); | |
496 | |
497 pthread_mutex_lock(&(*sem)->lock); | |
498 *sval = (int)(*sem)->count; | |
499 pthread_mutex_unlock(&(*sem)->lock); | |
500 | |
501 retval = 0; | |
502 RETURN: | |
503 return retval; | |
504 } | |
505 | |
506 /* END of inlined uthread_sem.c */ | |
507 #endif /* SDL_USE_PTHREADS */ |