/*
 * Copyright © 2008 Red Hat, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Soft-
 * ware"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, provided that the above copyright
 * notice(s) and this permission notice appear in all copies of the Soft-
 * ware and that both the above copyright notice(s) and this permission
 * notice appear in supporting documentation.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
 * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
 * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
 * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
 * MANCE OF THIS SOFTWARE.
 *
 * Except as contained in this notice, the name of a copyright holder shall
 * not be used in advertising or otherwise to promote the sale, use or
 * other dealings in this Software without prior written authorization of
 * the copyright holder.
 *
 * Authors:
 *   Kristian Høgsberg (krh@redhat.com)
 */


#define NEED_REPLIES
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include "xf86drm.h"
#include "va_dri2.h"
#include "va_dri2str.h"
#include "va_dri2tokens.h"

#ifndef DRI2DriverDRI
#define DRI2DriverDRI 0
#endif

static int
VA_DRI2Error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code);

static VA_DRI2Buffer *
VA_DRI2GetBuffers_internal(XExtDisplayInfo *info,
                           Display *dpy, XID drawable,
                           int *width, int *height,
                           unsigned int *attachments,
                           int count,
                           int *outCount);

static char va_dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo _va_dri2_info_data;
static XExtensionInfo *va_dri2Info = &_va_dri2_info_data;
static XEXT_GENERATE_CLOSE_DISPLAY (VA_DRI2CloseDisplay, va_dri2Info)
static /* const */ XExtensionHooks va_dri2ExtensionHooks = {
    NULL,				/* create_gc */
    NULL,				/* copy_gc */
    NULL,				/* flush_gc */
    NULL,				/* free_gc */
    NULL,				/* create_font */
    NULL,				/* free_font */
    VA_DRI2CloseDisplay,		/* close_display */
    NULL,				/* wire_to_event */
    NULL,				/* event_to_wire */
    VA_DRI2Error,			/* error */
    NULL,				/* error_string */
};

static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, va_dri2Info, 
				   va_dri2ExtensionName, 
				   &va_dri2ExtensionHooks, 
				   0, NULL)

static CARD32 _va_resource_x_error_drawable = 0;
static Bool   _va_resource_x_error_matched = False;

#define VA_EnterResourceError(drawable)                 \
  do {                                                  \
    _va_resource_x_error_drawable = (drawable);         \
    _va_resource_x_error_matched = False;               \
  } while (0)

#define VA_LeaveResourceError()                 \
  do {                                          \
    _va_resource_x_error_drawable = 0;          \
  } while (0)

#define VA_ResourceErrorMatched()               \
  (_va_resource_x_error_matched)

static int
VA_DRI2Error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code)
{
    if (_va_resource_x_error_drawable == err->resourceID) {
      _va_resource_x_error_matched = True;
      return True;
    }

    return False;
}

Bool VA_DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);

    if (XextHasExtension(info)) {
	*eventBase = info->codes->first_event;
	*errorBase = info->codes->first_error;
	return True;
    }

    return False;
}

Bool VA_DRI2QueryVersion(Display *dpy, int *major, int *minor)
{
    XExtDisplayInfo *info = DRI2FindDisplay (dpy);
    xDRI2QueryVersionReply rep;
    xDRI2QueryVersionReq *req;

    XextCheckExtension (dpy, info, va_dri2ExtensionName, False);

    LockDisplay(dpy);
    GetReq(DRI2QueryVersion, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2QueryVersion;
    req->majorVersion = DRI2_MAJOR;
    req->minorVersion = DRI2_MINOR;
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	return False;
    }
    *major = rep.majorVersion;
    *minor = rep.minorVersion;
    UnlockDisplay(dpy);
    SyncHandle();

    return True;
}

Bool VA_DRI2Connect(Display *dpy, XID window,
		 char **driverName, char **deviceName)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2ConnectReply rep;
    xDRI2ConnectReq *req;

    XextCheckExtension (dpy, info, va_dri2ExtensionName, False);

    LockDisplay(dpy);
    GetReq(DRI2Connect, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2Connect;
    req->window = window;
    req->driverType = DRI2DriverDRI;
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	return False;
    }

    if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
	UnlockDisplay(dpy);
	SyncHandle();
	return False;
    }

    *driverName = Xmalloc(rep.driverNameLength + 1);
    if (*driverName == NULL) {
	_XEatData(dpy, 
		  ((rep.driverNameLength + 3) & ~3) +
		  ((rep.deviceNameLength + 3) & ~3));
	UnlockDisplay(dpy);
	SyncHandle();
	return False;
    }
    _XReadPad(dpy, *driverName, rep.driverNameLength);
    (*driverName)[rep.driverNameLength] = '\0';

    *deviceName = Xmalloc(rep.deviceNameLength + 1);
    if (*deviceName == NULL) {
	Xfree(*driverName);
	_XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
	UnlockDisplay(dpy);
	SyncHandle();
	return False;
    }
    _XReadPad(dpy, *deviceName, rep.deviceNameLength);
    (*deviceName)[rep.deviceNameLength] = '\0';

    UnlockDisplay(dpy);
    SyncHandle();

    return True;
}

Bool VA_DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2AuthenticateReq *req;
    xDRI2AuthenticateReply rep;

    XextCheckExtension (dpy, info, va_dri2ExtensionName, False);

    LockDisplay(dpy);
    GetReq(DRI2Authenticate, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2Authenticate;
    req->window = window;
    req->magic = magic;

    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	return False;
    }

    UnlockDisplay(dpy);
    SyncHandle();

    return rep.authenticated;
}

void VA_DRI2CreateDrawable(Display *dpy, XID drawable)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2CreateDrawableReq *req;

    XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName);

    LockDisplay(dpy);
    GetReq(DRI2CreateDrawable, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2CreateDrawable;
    req->drawable = drawable;
    UnlockDisplay(dpy);
    SyncHandle();
}

void VA_DRI2DestroyDrawable(Display *dpy, XID drawable)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2DestroyDrawableReq *req;
    unsigned int attachement = 0; // FRONT_LEFT
    VA_DRI2Buffer *buffers;

    XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName);

    XSync(dpy, False);

    LockDisplay(dpy);
    /*
     * We have no way of catching DRI2DestroyDrawable errors because
     * this message doesn't have a defined answer. So we test whether
     * the drawable is still alive by sending DRIGetBuffers first and
     * checking whether we get an error.
     */
    VA_EnterResourceError(drawable);

    buffers = VA_DRI2GetBuffers_internal(info, dpy, drawable,
                                         NULL, NULL,
                                         &attachement, 1, NULL);
    VA_LeaveResourceError();
    if (buffers)
      XFree(buffers);
    if (VA_ResourceErrorMatched()) {
      UnlockDisplay(dpy);
      SyncHandle();
      return;
    }

    GetReq(DRI2DestroyDrawable, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2DestroyDrawable;
    req->drawable = drawable;
    UnlockDisplay(dpy);
    SyncHandle();
}

VA_DRI2Buffer *VA_DRI2GetBuffers_internal(XExtDisplayInfo *info,
                                          Display *dpy, XID drawable,
                                          int *width, int *height,
                                          unsigned int *attachments, int count,
                                          int *outCount)
{
    xDRI2GetBuffersReply rep;
    xDRI2GetBuffersReq *req;
    VA_DRI2Buffer *buffers;
    xDRI2Buffer repBuffer;
    CARD32 *p;
    int i;

    GetReqExtra(DRI2GetBuffers, count * 4, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2GetBuffers;
    req->drawable = drawable;
    req->count = count;
    p = (CARD32 *) &req[1];
    for (i = 0; i < count; i++)
	p[i] = attachments[i];

    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
	return NULL;
    }

    if (width)
      *width = rep.width;
    if (height)
      *height = rep.height;
    if (outCount)
      *outCount = rep.count;

    buffers = Xmalloc(rep.count * sizeof buffers[0]);
    if (buffers == NULL) {
	_XEatData(dpy, rep.count * sizeof repBuffer);
	return NULL;
    }

    for (i = 0; i < rep.count; i++) {
	_XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
	buffers[i].attachment = repBuffer.attachment;
	buffers[i].name = repBuffer.name;
	buffers[i].pitch = repBuffer.pitch;
	buffers[i].cpp = repBuffer.cpp;
	buffers[i].flags = repBuffer.flags;
    }

    return buffers;
}

VA_DRI2Buffer *VA_DRI2GetBuffers(Display *dpy, XID drawable,
			   int *width, int *height,
			   unsigned int *attachments, int count,
			   int *outCount)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    VA_DRI2Buffer *buffers;

    XextCheckExtension (dpy, info, va_dri2ExtensionName, False);

    LockDisplay(dpy);

    buffers = VA_DRI2GetBuffers_internal(info, dpy, drawable, width, height,
                                         attachments, count, outCount);

    UnlockDisplay(dpy);
    SyncHandle();

    return buffers;
}

void VA_DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
		    CARD32 dest, CARD32 src)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2CopyRegionReq *req;
    xDRI2CopyRegionReply rep;

    XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName);

    LockDisplay(dpy);
    GetReq(DRI2CopyRegion, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2CopyRegion;
    req->drawable = drawable;
    req->region = region;
    req->dest = dest;
    req->src = src;

    _XReply(dpy, (xReply *)&rep, 0, xFalse);

    UnlockDisplay(dpy);
    SyncHandle();
}

static void
load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
              CARD64 remainder)
{
    req->target_msc_hi = target >> 32;
    req->target_msc_lo = target & 0xffffffff;
    req->divisor_hi = divisor >> 32;
    req->divisor_lo = divisor & 0xffffffff;
    req->remainder_hi = remainder >> 32;
    req->remainder_lo = remainder & 0xffffffff;
}

static CARD64
vals_to_card64(CARD32 lo, CARD32 hi)
{
    return (CARD64)hi << 32 | lo;
}

void VA_DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
                        CARD64 divisor, CARD64 remainder, CARD64 *count)
{
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2SwapBuffersReq *req;
    xDRI2SwapBuffersReply rep;

    XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName);

    LockDisplay(dpy);
    GetReq(DRI2SwapBuffers, req);
    req->reqType = info->codes->major_opcode;
    req->dri2ReqType = X_DRI2SwapBuffers;
    req->drawable = drawable;
    load_swap_req(req, target_msc, divisor, remainder);

    _XReply(dpy, (xReply *)&rep, 0, xFalse);

    *count = vals_to_card64(rep.swap_lo, rep.swap_hi);

    UnlockDisplay(dpy);
    SyncHandle();
}
