/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2006 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

/* This is the XFree86 Xv extension implementation of YUV video overlays */

#if SDL_VIDEO_DRIVER_X11_XV

#include <X11/Xlib.h>
#ifndef NO_SHARED_MEMORY
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif
#include "../Xext/extensions/Xvlib.h"

#include "SDL_x11yuv_c.h"
#include "../SDL_yuvfuncs.h"

#define XFREE86_REFRESH_HACK
#ifdef XFREE86_REFRESH_HACK
#include "SDL_x11image_c.h"
#endif

/* Workaround when pitch != width */
#define PITCH_WORKAROUND

/* Fix for the NVidia GeForce 2 - use the last available adaptor */
/*#define USE_LAST_ADAPTOR*/  /* Apparently the NVidia drivers are fixed */

/* The functions used to manipulate software video overlays */
static struct private_yuvhwfuncs x11_yuvfuncs = {
	X11_LockYUVOverlay,
	X11_UnlockYUVOverlay,
	X11_DisplayYUVOverlay,
	X11_FreeYUVOverlay
};

struct private_yuvhwdata {
	int port;
#ifndef NO_SHARED_MEMORY
	int yuv_use_mitshm;
	XShmSegmentInfo yuvshm;
#endif
	SDL_NAME(XvImage) *image;
};


static int (*X_handler)(Display *, XErrorEvent *) = NULL;

#ifndef NO_SHARED_MEMORY
/* Shared memory error handler routine */
static int shm_error;
static int shm_errhandler(Display *d, XErrorEvent *e)
{
        if ( e->error_code == BadAccess ) {
        	shm_error = True;
        	return(0);
        } else
		return(X_handler(d,e));
}
#endif /* !NO_SHARED_MEMORY */

static int xv_error;
static int xv_errhandler(Display *d, XErrorEvent *e)
{
        if ( e->error_code == BadMatch ) {
        	xv_error = True;
        	return(0);
        } else
		return(X_handler(d,e));
}

SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
{
	SDL_Overlay *overlay;
	struct private_yuvhwdata *hwdata;
	int xv_port;
	unsigned int i, j, k;
	unsigned int adaptors;
	SDL_NAME(XvAdaptorInfo) *ainfo;
	int bpp;
#ifndef NO_SHARED_MEMORY
	XShmSegmentInfo *yuvshm;
#endif

	/* Look for the XVideo extension with a valid port for this format */
	xv_port = -1;
	if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) &&
	     (Success == SDL_NAME(XvQueryAdaptors)(GFX_Display,
	                                 RootWindow(GFX_Display, SDL_Screen),
	                                 &adaptors, &ainfo)) ) {
#ifdef USE_LAST_ADAPTOR
		for ( i=0; i < adaptors; ++i )
#else
		for ( i=0; (i < adaptors) && (xv_port == -1); ++i )
#endif /* USE_LAST_ADAPTOR */
		{
			/* Check to see if the visual can be used */
			if ( BUGGY_XFREE86(<=, 4001) ) {
				int visual_ok = 0;
				for ( j=0; j<ainfo[i].num_formats; ++j ) {
					if ( ainfo[i].formats[j].visual_id ==
							SDL_Visual->visualid ) {
						visual_ok = 1;
						break;
					}
				}
				if ( ! visual_ok ) {
					continue;
				}
			}
			if ( (ainfo[i].type & XvInputMask) &&
			     (ainfo[i].type & XvImageMask) ) {
				int num_formats;
				SDL_NAME(XvImageFormatValues) *formats;
				formats = SDL_NAME(XvListImageFormats)(GFX_Display,
				              ainfo[i].base_id, &num_formats);
#ifdef USE_LAST_ADAPTOR
				for ( j=0; j < num_formats; ++j )
#else
				for ( j=0; (j < num_formats) && (xv_port == -1); ++j )
#endif /* USE_LAST_ADAPTOR */
				{
					if ( (Uint32)formats[j].id == format ) {
						for ( k=0; k < ainfo[i].num_ports; ++k ) {
							if ( Success == SDL_NAME(XvGrabPort)(GFX_Display, ainfo[i].base_id+k, CurrentTime) ) {
								xv_port = ainfo[i].base_id+k;
								break;
							}
						}
					}
				}
				if ( formats ) {
					XFree(formats);
				}
			}
		}
		SDL_NAME(XvFreeAdaptorInfo)(ainfo);
	}

	/* Precalculate the bpp for the pitch workaround below */
	switch (format) {
	    /* Add any other cases we need to support... */
	    case SDL_YUY2_OVERLAY:
	    case SDL_UYVY_OVERLAY:
	    case SDL_YVYU_OVERLAY:
		bpp = 2;
		break;
	    default:
		bpp = 1;
		break;
	}

#if 0
    /*
     * !!! FIXME:
     * "Here are some diffs for X11 and yuv.  Note that the last part 2nd
     *  diff should probably be a new call to XvQueryAdaptorFree with ainfo
     *  and the number of adaptors, instead of the loop through like I did."
     *
     *  ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this
     *  for you, so we end up with a double-free. I need to look at this
     *  more closely...  --ryan.
     */
 	for ( i=0; i < adaptors; ++i ) {
 	  if (ainfo[i].name != NULL) Xfree(ainfo[i].name);
 	  if (ainfo[i].formats != NULL) Xfree(ainfo[i].formats);
   	}
 	Xfree(ainfo);
#endif

	if ( xv_port == -1 ) {
		SDL_SetError("No available video ports for requested format");
		return(NULL);
	}

	/* Enable auto-painting of the overlay colorkey */
	{
		static const char *attr[] = { "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" };
		unsigned int i;

		SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, True);
		X_handler = XSetErrorHandler(xv_errhandler);
		for ( i=0; i < sizeof(attr)/(sizeof attr[0]); ++i ) {
			Atom a;

			xv_error = False;
			a = XInternAtom(GFX_Display, attr[i], True);
			if ( a != None ) {
     				SDL_NAME(XvSetPortAttribute)(GFX_Display, xv_port, a, 1);
				XSync(GFX_Display, True);
				if ( ! xv_error ) {
					break;
				}
			}
		}
		XSetErrorHandler(X_handler);
		SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, False);
	}

	/* Create the overlay structure */
	overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
	if ( overlay == NULL ) {
		SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime);
		SDL_OutOfMemory();
		return(NULL);
	}
	SDL_memset(overlay, 0, (sizeof *overlay));

	/* Fill in the basic members */
	overlay->format = format;
	overlay->w = width;
	overlay->h = height;

	/* Set up the YUV surface function structure */
	overlay->hwfuncs = &x11_yuvfuncs;
	overlay->hw_overlay = 1;

	/* Create the pixel data and lookup tables */
	hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
	overlay->hwdata = hwdata;
	if ( hwdata == NULL ) {
		SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime);
		SDL_OutOfMemory();
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	hwdata->port = xv_port;
#ifndef NO_SHARED_MEMORY
	yuvshm = &hwdata->yuvshm;
	SDL_memset(yuvshm, 0, sizeof(*yuvshm));
	hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format,
						   0, width, height, yuvshm);
#ifdef PITCH_WORKAROUND
	if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) {
		/* Ajust overlay width according to pitch */ 
		XFree(hwdata->image);
		width = hwdata->image->pitches[0] / bpp;
		hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format,
							   0, width, height, yuvshm);
	}
#endif /* PITCH_WORKAROUND */
	hwdata->yuv_use_mitshm = (hwdata->image != NULL);
	if ( hwdata->yuv_use_mitshm ) {
		yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
				       IPC_CREAT | 0777);
		if ( yuvshm->shmid >= 0 ) {
			yuvshm->shmaddr = (char *)shmat(yuvshm->shmid, 0, 0);
			yuvshm->readOnly = False;
			if ( yuvshm->shmaddr != (char *)-1 ) {
				shm_error = False;
				X_handler = XSetErrorHandler(shm_errhandler);
				XShmAttach(GFX_Display, yuvshm);
				XSync(GFX_Display, True);
				XSetErrorHandler(X_handler);
				if ( shm_error )
					shmdt(yuvshm->shmaddr);
			} else {
				shm_error = True;
			}
			shmctl(yuvshm->shmid, IPC_RMID, NULL);
		} else {
			shm_error = True;
		}
		if ( shm_error ) {
			XFree(hwdata->image);
			hwdata->yuv_use_mitshm = 0;
		} else {
			hwdata->image->data = yuvshm->shmaddr;
		}
	}
	if ( !hwdata->yuv_use_mitshm )
#endif /* NO_SHARED_MEMORY */
	{
		hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format,
							0, width, height);

#ifdef PITCH_WORKAROUND
		if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) {
			/* Ajust overlay width according to pitch */ 
			XFree(hwdata->image);
			width = hwdata->image->pitches[0] / bpp;
			hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format,
								0, width, height);
		}
#endif /* PITCH_WORKAROUND */
		if ( hwdata->image == NULL ) {
			SDL_SetError("Couldn't create XVideo image");
			SDL_FreeYUVOverlay(overlay);
			return(NULL);
		}
		hwdata->image->data = SDL_malloc(hwdata->image->data_size);
		if ( hwdata->image->data == NULL ) {
			SDL_OutOfMemory();
			SDL_FreeYUVOverlay(overlay);
			return(NULL);
		}
	}

	/* Find the pitch and offset values for the overlay */
	overlay->planes = hwdata->image->num_planes;
	overlay->pitches = (Uint16 *)SDL_malloc(overlay->planes * sizeof(Uint16));
	overlay->pixels = (Uint8 **)SDL_malloc(overlay->planes * sizeof(Uint8 *));
	if ( !overlay->pitches || !overlay->pixels ) {
		SDL_OutOfMemory();
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	for ( i=0; i<overlay->planes; ++i ) {
		overlay->pitches[i] = hwdata->image->pitches[i];
		overlay->pixels[i] = (Uint8 *)hwdata->image->data +
		                              hwdata->image->offsets[i];
	}

#ifdef XFREE86_REFRESH_HACK
	/* Work around an XFree86 X server bug (?)
	   We can't perform normal updates in windows that have video
	   being output to them.  See SDL_x11image.c for more details.
	 */
	X11_DisableAutoRefresh(this);
#endif

	/* We're all done.. */
	return(overlay);
}

int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
{
	return(0);
}

void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
{
	return;
}

int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
{
	struct private_yuvhwdata *hwdata;

	hwdata = overlay->hwdata;

#ifndef NO_SHARED_MEMORY
	if ( hwdata->yuv_use_mitshm ) {
		SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
	              hwdata->image,
		      src->x, src->y, src->w, src->h,
		      dst->x, dst->y, dst->w, dst->h, False);
	}
	else
#endif
	{
		SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
				     hwdata->image,
		                     src->x, src->y, src->w, src->h,
		                     dst->x, dst->y, dst->w, dst->h);
	}
	XSync(GFX_Display, False);
	return(0);
}

void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
{
	struct private_yuvhwdata *hwdata;

	hwdata = overlay->hwdata;
	if ( hwdata ) {
		SDL_NAME(XvUngrabPort)(GFX_Display, hwdata->port, CurrentTime);
#ifndef NO_SHARED_MEMORY
		if ( hwdata->yuv_use_mitshm ) {
			XShmDetach(GFX_Display, &hwdata->yuvshm);
			shmdt(hwdata->yuvshm.shmaddr);
		}
#endif
		if ( hwdata->image ) {
			XFree(hwdata->image);
		}
		SDL_free(hwdata);
	}
	if ( overlay->pitches ) {
		SDL_free(overlay->pitches);
		overlay->pitches = NULL;
	}
	if ( overlay->pixels ) {
		SDL_free(overlay->pixels);
		overlay->pixels = NULL;
	}
#ifdef XFREE86_REFRESH_HACK
	X11_EnableAutoRefresh(this);
#endif
}

#endif /* SDL_VIDEO_DRIVER_X11_XV */
