Mercurial > sdl-ios-xcode
view 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 |
line wrap: on
line source
/* SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com */ #ifdef SAVE_RCSID static char rcsid = "@(#) $Id$"; #endif #include <stdlib.h> #include "SDL_error.h" #include "SDL_thread.h" #include "SDL_timer.h" #ifdef SDL_USE_PTHREADS #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* For getpid() */ #include <pthread.h> /* * This is semaphore.h inlined here so that BSD/OS POSIX semaphore are * completely selfcontained without requiring any additional include files * or libraries not present in the stock system */ /* semaphore.h: POSIX 1003.1b semaphores */ /*- * Copyright (c) 1996, 1997 * HD Associates, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by HD Associates, Inc * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/sys/posix4/semaphore.h,v 1.6 2000/01/20 07:55:42 jasone Exp $ */ #include <machine/limits.h> #include <sys/types.h> #include <fcntl.h> /* Opaque type definition. */ struct sem; typedef struct sem *sem_t; #define SEM_FAILED ((sem_t *)0) #define SEM_VALUE_MAX UINT_MAX #include <sys/cdefs.h> __BEGIN_DECLS int sem_init __P((sem_t *, int, unsigned int)); int sem_destroy __P((sem_t *)); sem_t *sem_open __P((const char *, int, ...)); int sem_close __P((sem_t *)); int sem_unlink __P((const char *)); int sem_wait __P((sem_t *)); int sem_trywait __P((sem_t *)); int sem_post __P((sem_t *)); int sem_getvalue __P((sem_t *, int *)); __END_DECLS /* END of inlined semaphore.h */ /* Wrapper around POSIX 1003.1b semaphores */ struct SDL_semaphore { sem_t *sem; sem_t sem_data; }; /* Create a semaphore, initialized with value */ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { SDL_sem *sem = (SDL_sem *) malloc(sizeof(SDL_sem)); if ( sem ) { if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) { SDL_SetError("sem_init() failed"); free(sem); sem = NULL; } else { sem->sem = &sem->sem_data; } } else { SDL_OutOfMemory(); } return sem; } void SDL_DestroySemaphore(SDL_sem *sem) { if ( sem ) { sem_destroy(sem->sem); free(sem); } } int SDL_SemTryWait(SDL_sem *sem) { int retval; if ( ! sem ) { SDL_SetError("Passed a NULL semaphore"); return -1; } retval = SDL_MUTEX_TIMEDOUT; if ( sem_trywait(sem->sem) == 0 ) retval = 0; return retval; } int SDL_SemWait(SDL_sem *sem) { int retval; if ( ! sem ) { SDL_SetError("Passed a NULL semaphore"); return -1; } retval = sem_wait(sem->sem); if ( retval < 0 ) { SDL_SetError("sem_wait() failed"); } return retval; } int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) { int retval; if ( ! sem ) { SDL_SetError("Passed a NULL semaphore"); return -1; } /* Try the easy cases first */ if ( timeout == 0 ) { return SDL_SemTryWait(sem); } if ( timeout == SDL_MUTEX_MAXWAIT ) { return SDL_SemWait(sem); } /* Ack! We have to busy wait... */ timeout += SDL_GetTicks(); do { retval = SDL_SemTryWait(sem); if ( retval == 0 ) { break; } SDL_Delay(1); } while ( SDL_GetTicks() < timeout ); return retval; } Uint32 SDL_SemValue(SDL_sem *sem) { int ret = 0; if ( sem ) { sem_getvalue(sem->sem, &ret); if ( ret < 0 ) { ret = 0; } } return (Uint32)ret; } int SDL_SemPost(SDL_sem *sem) { int retval; if ( ! sem ) { SDL_SetError("Passed a NULL semaphore"); return -1; } retval = sem_post(sem->sem); if ( retval < 0 ) { SDL_SetError("sem_post() failed"); } return retval; } /* * BEGIN inlined uthread_sem.c. This is done here so that no extra libraries * or include files not present in BSD/OS are required */ /* * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $ */ #include <errno.h> #include <pthread.h> /* Begin thread_private.h kluge */ /* * These come out of (or should go into) thread_private.h - rather than have * to copy (or symlink) the files from the source tree these definitions are * inlined here. Obviously these go away when this module is part of libc. */ struct sem { #define SEM_MAGIC ((u_int32_t) 0x09fa4012) u_int32_t magic; pthread_mutex_t lock; pthread_cond_t gtzero; u_int32_t count; u_int32_t nwaiters; }; extern pthread_once_t _thread_init_once; extern int _threads_initialized; extern void _thread_init __P((void)); #define THREAD_INIT() \ (void) pthread_once(&_thread_init_once, _thread_init) #define THREAD_SAFE() \ (_threads_initialized != 0) #define _SEM_CHECK_VALIDITY(sem) \ if ((*(sem))->magic != SEM_MAGIC) { \ errno = EINVAL; \ retval = -1; \ goto RETURN; \ } /* End thread_private.h kluge */ int sem_init(sem_t *sem, int pshared, unsigned int value) { int retval; if (!THREAD_SAFE()) THREAD_INIT(); /* * Range check the arguments. */ if (pshared != 0) { /* * The user wants a semaphore that can be shared among * processes, which this implementation can't do. Sounds like a * permissions problem to me (yeah right). */ errno = EPERM; retval = -1; goto RETURN; } if (value > SEM_VALUE_MAX) { errno = EINVAL; retval = -1; goto RETURN; } *sem = (sem_t)malloc(sizeof(struct sem)); if (*sem == NULL) { errno = ENOSPC; retval = -1; goto RETURN; } /* * Initialize the semaphore. */ if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) { free(*sem); errno = ENOSPC; retval = -1; goto RETURN; } if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) { pthread_mutex_destroy(&(*sem)->lock); free(*sem); errno = ENOSPC; retval = -1; goto RETURN; } (*sem)->count = (u_int32_t)value; (*sem)->nwaiters = 0; (*sem)->magic = SEM_MAGIC; retval = 0; RETURN: return retval; } int sem_destroy(sem_t *sem) { int retval; _SEM_CHECK_VALIDITY(sem); /* Make sure there are no waiters. */ pthread_mutex_lock(&(*sem)->lock); if ((*sem)->nwaiters > 0) { pthread_mutex_unlock(&(*sem)->lock); errno = EBUSY; retval = -1; goto RETURN; } pthread_mutex_unlock(&(*sem)->lock); pthread_mutex_destroy(&(*sem)->lock); pthread_cond_destroy(&(*sem)->gtzero); (*sem)->magic = 0; free(*sem); retval = 0; RETURN: return retval; } sem_t * sem_open(const char *name, int oflag, ...) { errno = ENOSYS; return SEM_FAILED; } int sem_close(sem_t *sem) { errno = ENOSYS; return -1; } int sem_unlink(const char *name) { errno = ENOSYS; return -1; } int sem_wait(sem_t *sem) { int retval; pthread_testcancel(); _SEM_CHECK_VALIDITY(sem); pthread_mutex_lock(&(*sem)->lock); while ((*sem)->count == 0) { (*sem)->nwaiters++; pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); (*sem)->nwaiters--; } (*sem)->count--; pthread_mutex_unlock(&(*sem)->lock); retval = 0; RETURN: pthread_testcancel(); return retval; } int sem_trywait(sem_t *sem) { int retval; _SEM_CHECK_VALIDITY(sem); pthread_mutex_lock(&(*sem)->lock); if ((*sem)->count > 0) { (*sem)->count--; retval = 0; } else { errno = EAGAIN; retval = -1; } pthread_mutex_unlock(&(*sem)->lock); RETURN: return retval; } int sem_post(sem_t *sem) { int retval; _SEM_CHECK_VALIDITY(sem); pthread_mutex_lock(&(*sem)->lock); (*sem)->count++; if ((*sem)->nwaiters > 0) { /* * We must use pthread_cond_broadcast() rather than * pthread_cond_signal() in order to assure that the highest * priority thread is run by the scheduler, since * pthread_cond_signal() signals waiting threads in FIFO order. */ pthread_cond_broadcast(&(*sem)->gtzero); } pthread_mutex_unlock(&(*sem)->lock); retval = 0; RETURN: return retval; } int sem_getvalue(sem_t *sem, int *sval) { int retval; _SEM_CHECK_VALIDITY(sem); pthread_mutex_lock(&(*sem)->lock); *sval = (int)(*sem)->count; pthread_mutex_unlock(&(*sem)->lock); retval = 0; RETURN: return retval; } /* END of inlined uthread_sem.c */ #endif /* SDL_USE_PTHREADS */