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