/*
 * Copyright © 2010 Intel Corporation
 *
 * 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@bitplanet.net)
 */

#include <stdbool.h>

#include "glapi.h"
#include "glxclient.h"
#include "indirect.h"
#include "util/debug.h"

#ifndef GLX_USE_APPLEGL

extern struct _glapi_table *__glXNewIndirectAPI(void);

/*
** All indirect rendering contexts will share the same indirect dispatch table.
*/
static struct _glapi_table *IndirectAPI = NULL;

static void
indirect_destroy_context(struct glx_context *gc)
{
   __glXFreeVertexArrayState(gc);

   free((char *) gc->vendor);
   free((char *) gc->renderer);
   free((char *) gc->version);
   free((char *) gc->extensions);
   __glFreeAttributeState(gc);
   free((char *) gc->buf);
   free((char *) gc->client_state_private);
   free((char *) gc);
}

static Bool
SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id,
                       GLXContextTag gc_tag, GLXDrawable draw,
                       GLXDrawable read, GLXContextTag *out_tag)
{
   xGLXMakeCurrentReply reply;
   Bool ret;
   int opcode = __glXSetupForCommand(dpy);

   LockDisplay(dpy);

   if (draw == read) {
      xGLXMakeCurrentReq *req;

      GetReq(GLXMakeCurrent, req);
      req->reqType = opcode;
      req->glxCode = X_GLXMakeCurrent;
      req->drawable = draw;
      req->context = gc_id;
      req->oldContextTag = gc_tag;
   }
   else {
      struct glx_display *priv = __glXInitialize(dpy);

      /* If the server can support the GLX 1.3 version, we should
       * perfer that.  Not only that, some servers support GLX 1.3 but
       * not the SGI extension.
       */

      if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
         xGLXMakeContextCurrentReq *req;

         GetReq(GLXMakeContextCurrent, req);
         req->reqType = opcode;
         req->glxCode = X_GLXMakeContextCurrent;
         req->drawable = draw;
         req->readdrawable = read;
         req->context = gc_id;
         req->oldContextTag = gc_tag;
      }
      else {
         xGLXVendorPrivateWithReplyReq *vpreq;
         xGLXMakeCurrentReadSGIReq *req;

         GetReqExtra(GLXVendorPrivateWithReply,
                     sz_xGLXMakeCurrentReadSGIReq -
                     sz_xGLXVendorPrivateWithReplyReq, vpreq);
         req = (xGLXMakeCurrentReadSGIReq *) vpreq;
         req->reqType = opcode;
         req->glxCode = X_GLXVendorPrivateWithReply;
         req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
         req->drawable = draw;
         req->readable = read;
         req->context = gc_id;
         req->oldContextTag = gc_tag;
      }
   }

   ret = _XReply(dpy, (xReply *) &reply, 0, False);

   if (out_tag)
      *out_tag = reply.contextTag;

   UnlockDisplay(dpy);
   SyncHandle();

   return ret;
}

static int
indirect_bind_context(struct glx_context *gc, struct glx_context *old,
		      GLXDrawable draw, GLXDrawable read)
{
   GLXContextTag tag;
   Display *dpy = gc->psc->dpy;
   Bool sent;

   if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) {
      tag = old->currentContextTag;
      old->currentContextTag = 0;
   } else {
      tag = 0;
   }

   sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read,
				 &gc->currentContextTag);

   if (sent) {
      if (!IndirectAPI)
         IndirectAPI = __glXNewIndirectAPI();
      _glapi_set_dispatch(IndirectAPI);

      /* The indirect vertex array state must to be initialised after we
       * have setup the context, as it needs to query server attributes.
       *
       * At the point this is called gc->currentDpy is not initialized
       * nor is the thread's current context actually set. Hence the
       * cleverness before the GetString calls.
       */
      __GLXattribute *state = gc->client_state_private;
      if (state && state->array_state == NULL) {
         gc->currentDpy = gc->psc->dpy;
         __glXSetCurrentContext(gc);
         __indirect_glGetString(GL_EXTENSIONS);
         __indirect_glGetString(GL_VERSION);
         __glXInitVertexArrayState(gc);
      }
   }

   return !sent;
}

static void
indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
{
   Display *dpy = gc->psc->dpy;

   if (gc == new)
      return;
   
   /* We are either switching to no context, away from an indirect
    * context to a direct context or from one dpy to another and have
    * to send a request to the dpy to unbind the previous context.
    */
   if (!new || new->isDirect || new->psc->dpy != dpy) {
      SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None,
                             NULL);
      gc->currentContextTag = 0;
   }
}

static void
indirect_wait_gl(struct glx_context *gc)
{
   xGLXWaitGLReq *req;
   Display *dpy = gc->currentDpy;

   /* Flush any pending commands out */
   __glXFlushRenderBuffer(gc, gc->pc);

   /* Send the glXWaitGL request */
   LockDisplay(dpy);
   GetReq(GLXWaitGL, req);
   req->reqType = gc->majorOpcode;
   req->glxCode = X_GLXWaitGL;
   req->contextTag = gc->currentContextTag;
   UnlockDisplay(dpy);
   SyncHandle();
}

static void
indirect_wait_x(struct glx_context *gc)
{
   xGLXWaitXReq *req;
   Display *dpy = gc->currentDpy;

   /* Flush any pending commands out */
   __glXFlushRenderBuffer(gc, gc->pc);

   LockDisplay(dpy);
   GetReq(GLXWaitX, req);
   req->reqType = gc->majorOpcode;
   req->glxCode = X_GLXWaitX;
   req->contextTag = gc->currentContextTag;
   UnlockDisplay(dpy);
   SyncHandle();
}

static void
indirect_use_x_font(struct glx_context *gc,
		    Font font, int first, int count, int listBase)
{
   xGLXUseXFontReq *req;
   Display *dpy = gc->currentDpy;

   /* Flush any pending commands out */
   __glXFlushRenderBuffer(gc, gc->pc);

   /* Send the glXUseFont request */
   LockDisplay(dpy);
   GetReq(GLXUseXFont, req);
   req->reqType = gc->majorOpcode;
   req->glxCode = X_GLXUseXFont;
   req->contextTag = gc->currentContextTag;
   req->font = font;
   req->first = first;
   req->count = count;
   req->listBase = listBase;
   UnlockDisplay(dpy);
   SyncHandle();
}

static void
indirect_bind_tex_image(Display * dpy,
			GLXDrawable drawable,
			int buffer, const int *attrib_list)
{
   xGLXVendorPrivateReq *req;
   struct glx_context *gc = __glXGetCurrentContext();
   CARD32 *drawable_ptr;
   INT32 *buffer_ptr;
   CARD32 *num_attrib_ptr;
   CARD32 *attrib_ptr;
   CARD8 opcode;
   unsigned int i;

   i = 0;
   if (attrib_list) {
      while (attrib_list[i * 2] != None)
         i++;
   }

   opcode = __glXSetupForCommand(dpy);
   if (!opcode)
      return;

   LockDisplay(dpy);
   GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
   req->reqType = opcode;
   req->glxCode = X_GLXVendorPrivate;
   req->vendorCode = X_GLXvop_BindTexImageEXT;
   req->contextTag = gc->currentContextTag;

   drawable_ptr = (CARD32 *) (req + 1);
   buffer_ptr = (INT32 *) (drawable_ptr + 1);
   num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
   attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);

   *drawable_ptr = drawable;
   *buffer_ptr = buffer;
   *num_attrib_ptr = (CARD32) i;

   i = 0;
   if (attrib_list) {
      while (attrib_list[i * 2] != None) {
         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
         i++;
      }
   }

   UnlockDisplay(dpy);
   SyncHandle();
}

static void
indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
{
   xGLXVendorPrivateReq *req;
   struct glx_context *gc = __glXGetCurrentContext();
   CARD32 *drawable_ptr;
   INT32 *buffer_ptr;
   CARD8 opcode;

   opcode = __glXSetupForCommand(dpy);
   if (!opcode)
      return;

   LockDisplay(dpy);
   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
   req->reqType = opcode;
   req->glxCode = X_GLXVendorPrivate;
   req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
   req->contextTag = gc->currentContextTag;

   drawable_ptr = (CARD32 *) (req + 1);
   buffer_ptr = (INT32 *) (drawable_ptr + 1);

   *drawable_ptr = drawable;
   *buffer_ptr = buffer;

   UnlockDisplay(dpy);
   SyncHandle();
}

static const struct glx_context_vtable indirect_context_vtable = {
   .destroy             = indirect_destroy_context,
   .bind                = indirect_bind_context,
   .unbind              = indirect_unbind_context,
   .wait_gl             = indirect_wait_gl,
   .wait_x              = indirect_wait_x,
   .use_x_font          = indirect_use_x_font,
   .bind_tex_image      = indirect_bind_tex_image,
   .release_tex_image   = indirect_release_tex_image,
   .get_proc_address    = NULL,
};

/**
 * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
 * function called \c __glXAllocateClientState that allocates the memory and
 * does all the initialization (including the pixel pack / unpack).
 *
 * \note
 * This function is \b not the place to validate the context creation
 * parameters.  It is just the allocator for the \c glx_context.
 */
_X_HIDDEN struct glx_context *
indirect_create_context(struct glx_screen *psc,
			struct glx_config *mode,
			struct glx_context *shareList, int renderType)
{
   struct glx_context *gc;
   int bufSize;
   CARD8 opcode;
   __GLXattribute *state;

   opcode = __glXSetupForCommand(psc->dpy);
   if (!opcode) {
      return NULL;
   }

   /* Allocate our context record */
   gc = calloc(1, sizeof *gc);
   if (!gc) {
      /* Out of memory */
      return NULL;
   }

   glx_context_init(gc, psc, mode);
   gc->isDirect = GL_FALSE;
   gc->vtable = &indirect_context_vtable;
   state = calloc(1, sizeof(struct __GLXattributeRec));
   gc->renderType = renderType;

   if (state == NULL) {
      /* Out of memory */
      free(gc);
      return NULL;
   }
   gc->client_state_private = state;
   state->NoDrawArraysProtocol = env_var_as_boolean("LIBGL_NO_DRAWARRAYS", false);

   /*
    ** Create a temporary buffer to hold GLX rendering commands.  The size
    ** of the buffer is selected so that the maximum number of GLX rendering
    ** commands can fit in a single X packet and still have room in the X
    ** packet for the GLXRenderReq header.
    */

   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
   gc->buf = malloc(bufSize);
   if (!gc->buf) {
      free(gc->client_state_private);
      free(gc);
      return NULL;
   }
   gc->bufSize = bufSize;

   /* Fill in the new context */
   gc->renderMode = GL_RENDER;

   state->storePack.alignment = 4;
   state->storeUnpack.alignment = 4;

   gc->attributes.stackPointer = &gc->attributes.stack[0];

   gc->pc = gc->buf;
   gc->bufEnd = gc->buf + bufSize;
   gc->isDirect = GL_FALSE;
   if (__glXDebug) {
      /*
       ** Set limit register so that there will be one command per packet
       */
      gc->limit = gc->buf;
   }
   else {
      gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
   }
   gc->majorOpcode = opcode;

   /*
    ** Constrain the maximum drawing command size allowed to be
    ** transfered using the X_GLXRender protocol request.  First
    ** constrain by a software limit, then constrain by the protocl
    ** limit.
    */
   if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
      bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
   }
   if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
      bufSize = __GLX_MAX_RENDER_CMD_SIZE;
   }
   gc->maxSmallRenderCommandSize = bufSize;
   

   return gc;
}

_X_HIDDEN struct glx_context *
indirect_create_context_attribs(struct glx_screen *base,
				struct glx_config *config_base,
				struct glx_context *shareList,
				unsigned num_attribs,
				const uint32_t *attribs,
				unsigned *error)
{
   int renderType = GLX_RGBA_TYPE;
   unsigned i;

   /* The error parameter is only used on the server so that correct GLX
    * protocol errors can be generated.  On the client, it can be ignored.
    */
   (void) error;

   /* All of the attribute validation for indirect contexts is handled on the
    * server, so there's not much to do here. Still, we need to parse the
    * attributes to correctly set renderType.
    */
   for (i = 0; i < num_attribs; i++) {
      if (attribs[i * 2] == GLX_RENDER_TYPE)
         renderType = attribs[i * 2 + 1];
   }

   return indirect_create_context(base, config_base, shareList, renderType);
}

static const struct glx_screen_vtable indirect_screen_vtable = {
   .create_context         = indirect_create_context,
   .create_context_attribs = indirect_create_context_attribs,
   .query_renderer_integer = NULL,
   .query_renderer_string  = NULL,
};

_X_HIDDEN struct glx_screen *
indirect_create_screen(int screen, struct glx_display * priv)
{
   struct glx_screen *psc;

   psc = calloc(1, sizeof *psc);
   if (psc == NULL)
      return NULL;

   glx_screen_init(psc, screen, priv);
   psc->vtable = &indirect_screen_vtable;

   return psc;
}

#endif
