/*
    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
*/

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

#ifdef XFREE86_XV

#include <X11/Xlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xvlib.h>

#include "SDL_video.h"
#include "SDL_x11yuv_c.h"
#include "SDL_yuvfuncs.h"

/* 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;
	XShmSegmentInfo yuvshm;
	XvImage *image;
};


SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
{
	SDL_Overlay *overlay;
	struct private_yuvhwdata *hwdata;
	int xv_port;
	int i, j;
	int adaptors;
	XvAdaptorInfo *ainfo;
	XShmSegmentInfo *yuvshm;

	xv_port = -1;
	if ( (Success == XvQueryExtension(GFX_Display, &j, &j, &j, &j, &j)) &&
	     (Success == XvQueryAdaptors(GFX_Display,
	                                 RootWindow(GFX_Display, SDL_Screen),
	                                 &adaptors, &ainfo)) ) {
		for ( i=0; (i<adaptors) && (xv_port == -1); ++i ) {
			if ( (ainfo[i].type & XvInputMask) &&
			     (ainfo[i].type & XvImageMask) ) {
				int num_formats;
				XvImageFormatValues *formats;
				formats = XvListImageFormats(GFX_Display,
				              ainfo[i].base_id, &num_formats);
				for ( j=0; j<num_formats; ++j ) {
					if ( (Uint32)formats[j].id == format ) {
						xv_port = ainfo[i].base_id;
						break;
					}
				}
			}
		}
	}
	if ( xv_port == -1 ) {
		SDL_SetError("No available video ports for requested format");
		return(NULL);
	}

	/* Create the overlay structure */
	overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
	if ( overlay == NULL ) {
		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;

	/* Create the pixel data and lookup tables */
	hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
	overlay->hwdata = hwdata;
	if ( hwdata == NULL ) {
		SDL_OutOfMemory();
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	yuvshm = &hwdata->yuvshm;
	SDL_memset(yuvshm, 0, sizeof(*yuvshm));
	hwdata->port = xv_port;
	hwdata->image = XvShmCreateImage(GFX_Display, xv_port, format,
	                                 0, width, height, yuvshm);
	if ( hwdata->image == NULL ) {
		SDL_OutOfMemory();
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
	                       IPC_CREAT | 0777);
	if ( yuvshm->shmid < 0 ) {
		SDL_SetError("Unable to get %d bytes shared memory",
		             hwdata->image->data_size);
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	yuvshm->shmaddr  = (caddr_t) shmat(yuvshm->shmid, 0, 0);
	yuvshm->readOnly = False;
	hwdata->image->data = yuvshm->shmaddr;

	XShmAttach(GFX_Display, yuvshm);
	XSync(GFX_Display, False);
	shmctl(yuvshm->shmid, IPC_RMID, 0);

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

int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
{
	overlay->pixels = overlay->hwdata->image->data;
	/* What should the pitch be set to? */
	return(0);
}

void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
{
	overlay->pixels = NULL;
}

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

	hwdata = overlay->hwdata;
	XvShmPutImage(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
	              hwdata->image, 0, 0, overlay->w, overlay->h,
	              dstrect->x, dstrect->y, dstrect->w, dstrect->h, False);
	XSync(GFX_Display, False);
	return(0);
}

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

	hwdata = overlay->hwdata;
	if ( hwdata ) {
		if ( hwdata->yuvshm.shmaddr ) {
			XShmDetach(GFX_Display, &hwdata->yuvshm);
			shmdt(hwdata->yuvshm.shmaddr);
		}
		if ( hwdata->image ) {
			XFree(hwdata->image);
		}
		SDL_free(hwdata);
	}
}

#endif /* XFREE86_XV */
