146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2006 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Lesser General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2.1 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Lesser General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Lesser General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free Software 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <stdio.h> 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <unistd.h> 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_endian.h" 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../../events/SDL_events_c.h" 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_x11image_c.h" 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef NO_SHARED_MEMORY 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Shared memory error handler routine */ 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int shm_error; 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int (*X_handler)(Display *, XErrorEvent *) = NULL; 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int shm_errhandler(Display *d, XErrorEvent *e) 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( e->error_code == BadAccess ) { 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shm_error = True; 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(X_handler(d,e)); 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void try_mitshm(_THIS, SDL_Surface *screen) 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Dynamic X11 may not have SHM entry points on this box. */ 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ((use_mitshm) && (!SDL_X11_HAVE_SHM)) 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner use_mitshm = 0; 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if(!use_mitshm) 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner IPC_CREAT | 0777); 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( shminfo.shmid >= 0 ) { 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shminfo.readOnly = False; 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( shminfo.shmaddr != (char *)-1 ) { 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shm_error = False; 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner X_handler = XSetErrorHandler(shm_errhandler); 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XShmAttach(SDL_Display, &shminfo); 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(SDL_Display, True); 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSetErrorHandler(X_handler); 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( shm_error ) 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shmdt(shminfo.shmaddr); 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shm_error = True; 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shmctl(shminfo.shmid, IPC_RMID, NULL); 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shm_error = True; 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( shm_error ) 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner use_mitshm = 0; 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( use_mitshm ) 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->pixels = shminfo.shmaddr; 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* ! NO_SHARED_MEMORY */ 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Various screen update functions available */ 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint X11_SetupImage(_THIS, SDL_Surface *screen) 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef NO_SHARED_MEMORY 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner try_mitshm(this, screen); 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if(use_mitshm) { 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->hidden->depth, ZPixmap, 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shminfo.shmaddr, &shminfo, 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->w, screen->h); 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if(!SDL_Ximage) { 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XShmDetach(SDL_Display, &shminfo); 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(SDL_Display, False); 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shmdt(shminfo.shmaddr); 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->pixels = NULL; 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner goto error; 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->UpdateRects = X11_MITSHMUpdate; 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if(!use_mitshm) 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* not NO_SHARED_MEMORY */ 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int bpp; 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->pixels = SDL_malloc(screen->h*screen->pitch); 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( screen->pixels == NULL ) { 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bpp = screen->format->BytesPerPixel; 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->hidden->depth, ZPixmap, 0, 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (char *)screen->pixels, 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->w, screen->h, 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32, 0); 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_Ximage == NULL ) 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner goto error; 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* XPutImage will convert byte sex automatically */ 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ? MSBFirst : LSBFirst; 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->UpdateRects = X11_NormalUpdate; 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->pitch = SDL_Ximage->bytes_per_line; 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnererror: 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Couldn't create XImage"); 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return 1; 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid X11_DestroyImage(_THIS, SDL_Surface *screen) 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_Ximage ) { 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XDestroyImage(SDL_Ximage); 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef NO_SHARED_MEMORY 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( use_mitshm ) { 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XShmDetach(SDL_Display, &shminfo); 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(SDL_Display, False); 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner shmdt(shminfo.shmaddr); 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* ! NO_SHARED_MEMORY */ 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_Ximage = NULL; 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( screen ) { 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->pixels = NULL; 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Determine the number of CPUs in the system */ 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int num_CPU(void) 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static int num_cpus = 0; 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if(!num_cpus) { 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#if defined(__LINUX__) 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char line[BUFSIZ]; 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FILE *pstat = fopen("/proc/stat", "r"); 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( pstat ) { 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( fgets(line, sizeof(line), pstat) ) { 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_memcmp(line, "cpu", 3) == 0 && line[3] != ' ') { 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ++num_cpus; 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fclose(pstat); 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#elif defined(__IRIX__) 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner num_cpus = sysconf(_SC_NPROC_ONLN); 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#elif defined(_SC_NPROCESSORS_ONLN) 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* number of processors online (SVR4.0MP compliant machines) */ 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner num_cpus = sysconf(_SC_NPROCESSORS_ONLN); 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#elif defined(_SC_NPROCESSORS_CONF) 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* number of processors configured (SVR4.0MP compliant machines) */ 17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner num_cpus = sysconf(_SC_NPROCESSORS_CONF); 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( num_cpus <= 0 ) { 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner num_cpus = 1; 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return num_cpus; 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int retval; 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner X11_DestroyImage(this, screen); 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( flags & SDL_OPENGL ) { /* No image when using GL */ 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner retval = 0; 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner retval = X11_SetupImage(this, screen); 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* We support asynchronous blitting on the display */ 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( flags & SDL_ASYNCBLIT ) { 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* This is actually slower on single-CPU systems, 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner probably because of CPU contention between the 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner X server and the application. 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Note: Is this still true with XFree86 4.0? 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( num_CPU() > 1 ) { 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner screen->flags |= SDL_ASYNCBLIT; 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(retval); 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* We don't actually allow hardware surfaces other than the main one */ 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint X11_AllocHWSurface(_THIS, SDL_Surface *surface) 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid X11_FreeHWSurface(_THIS, SDL_Surface *surface) 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint X11_LockHWSurface(_THIS, SDL_Surface *surface) 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (surface == SDL_VideoSurface) && blit_queued ) { 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(GFX_Display, False); 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner blit_queued = 0; 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid X11_UnlockHWSurface(_THIS, SDL_Surface *surface) 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint X11_FlipHWSurface(_THIS, SDL_Surface *surface) 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i = 0; i < numrects; ++i) { 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner rects[i].x, rects[i].y, 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner rects[i].x, rects[i].y, rects[i].w, rects[i].h); 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XFlush(GFX_Display); 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner blit_queued = 1; 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(GFX_Display, False); 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef NO_SHARED_MEMORY 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<numrects; ++i ) { 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner rects[i].x, rects[i].y, 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner rects[i].x, rects[i].y, rects[i].w, rects[i].h, 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner False); 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XFlush(GFX_Display); 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner blit_queued = 1; 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(GFX_Display, False); 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* ! NO_SHARED_MEMORY */ 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* There's a problem with the automatic refreshing of the display. 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Even though the XVideo code uses the GFX_Display to update the 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner video memory, it appears that updating the window asynchronously 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner from a different thread will cause "blackouts" of the window. 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This is a sort of a hacked workaround for the problem. 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int enable_autorefresh = 1; 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid X11_DisableAutoRefresh(_THIS) 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner --enable_autorefresh; 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid X11_EnableAutoRefresh(_THIS) 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ++enable_autorefresh; 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid X11_RefreshDisplay(_THIS) 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Don't refresh a display that doesn't have an image (like GL) 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Instead, post an expose event so the application can refresh. 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! SDL_Ximage || (enable_autorefresh <= 0) ) { 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_PrivateExpose(); 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef NO_SHARED_MEMORY 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( this->UpdateRects == X11_MITSHMUpdate ) { 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, 0, 0, 0, this->screen->w, this->screen->h, 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner False); 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* ! NO_SHARED_MEMORY */ 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, 0, 0, 0, this->screen->w, this->screen->h); 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner XSync(SDL_Display, False); 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 319