/*
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice including the dates of first publication and
 * either this permission notice or a reference to
 * http://oss.sgi.com/projects/FreeB/
 * shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 * shall not be used in advertising or otherwise to promote the sale, use or
 * other dealings in this Software without prior written authorization from
 * Silicon Graphics, Inc.
 */

/*
 * (C) Copyright IBM Corporation 2005
 * All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
 * IBM,
 * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "packrender.h"
#include "indirect.h"

/**
 * Send a large image to the server.  If necessary, a buffer is allocated
 * to hold the unpacked data that is copied from the clients memory.
 * 
 * \param gc        Current GLX context
 * \param compsize  Size, in bytes, of the image portion
 * \param dim       Number of dimensions of the image
 * \param width     Width of the image
 * \param height    Height of the image, must be 1 for 1D images
 * \param depth     Depth of the image, must be 1 for 1D or 2D images
 * \param format    Format of the image
 * \param type      Data type of the image
 * \param src       Pointer to the image data
 * \param pc        Pointer to end of the command header
 * \param modes     Pointer to the pixel unpack data
 *
 * \todo
 * Modify this function so that \c NULL images are sent using
 * \c __glXSendLargeChunk instead of __glXSendLargeCommand.  Doing this
 * will eliminate the need to allocate a buffer for that case.
 */
void
__glXSendLargeImage(struct glx_context * gc, GLint compsize, GLint dim,
                    GLint width, GLint height, GLint depth,
                    GLenum format, GLenum type, const GLvoid * src,
                    GLubyte * pc, GLubyte * modes)
{
    /* Allocate a temporary holding buffer */
    GLubyte *buf = (GLubyte *) Xmalloc(compsize);
    if (!buf) {
	__glXSetError(gc, GL_OUT_OF_MEMORY);
	return;
    }

    /* Apply pixel store unpack modes to copy data into buf */
    if (src != NULL) {
	(*gc->fillImage) (gc, dim, width, height, depth, format, type,
			  src, buf, modes);
    }
    else {
	if (dim < 3) {
	    (void) memcpy(modes, __glXDefaultPixelStore + 4, 20);
	}
	else {
	    (void) memcpy(modes, __glXDefaultPixelStore + 0, 36);
	}
    }

    /* Send large command */
    __glXSendLargeCommand(gc, gc->pc, pc - gc->pc, buf, compsize);

    /* Free buffer */
    Xfree((char *) buf);
}

/************************************************************************/

/**
 * Implement GLX protocol for \c glSeparableFilter2D.
 */
void
__indirect_glSeparableFilter2D(GLenum target, GLenum internalformat,
                               GLsizei width, GLsizei height, GLenum format,
                               GLenum type, const GLvoid * row,
                               const GLvoid * column)
{
   __GLX_DECLARE_VARIABLES();
   GLuint compsize2, hdrlen, totalhdrlen, image1len, image2len;

   __GLX_LOAD_VARIABLES();
   compsize = __glImageSize(width, 1, 1, format, type, 0);
   compsize2 = __glImageSize(height, 1, 1, format, type, 0);
   totalhdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
   hdrlen = __GLX_PAD(__GLX_CONV_FILT_HDR_SIZE);
   image1len = __GLX_PAD(compsize);
   image2len = __GLX_PAD(compsize2);
   cmdlen = totalhdrlen + image1len + image2len;
   if (!gc->currentDpy)
      return;

   if (cmdlen <= gc->maxSmallRenderCommandSize) {
      /* Use GLXRender protocol to send small command */
      __GLX_BEGIN_VARIABLE_WITH_PIXEL(X_GLrop_SeparableFilter2D, cmdlen);
      __GLX_PUT_LONG(0, target);
      __GLX_PUT_LONG(4, internalformat);
      __GLX_PUT_LONG(8, width);
      __GLX_PUT_LONG(12, height);
      __GLX_PUT_LONG(16, format);
      __GLX_PUT_LONG(20, type);
      pc += hdrlen;
      if (compsize > 0) {
         (*gc->fillImage) (gc, 1, width, 1, 1, format, type,
                           row, pc, pixelHeaderPC);
         pc += image1len;
      }
      if (compsize2 > 0) {
         (*gc->fillImage) (gc, 1, height, 1, 1, format, type,
                           column, pc, NULL);
         pc += image2len;
      }
      if ((compsize == 0) && (compsize2 == 0)) {
         /* Setup default store modes */
         (void) memcpy(pixelHeaderPC, __glXDefaultPixelStore + 4, 20);
      }
      __GLX_END(0);
   }
   else {
      GLubyte *buf;
      const GLint bufsize = image1len + image2len;

      /* Use GLXRenderLarge protocol to send command */
      __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(X_GLrop_SeparableFilter2D,
                                            cmdlen + 4);
      __GLX_PUT_LONG(0, target);
      __GLX_PUT_LONG(4, internalformat);
      __GLX_PUT_LONG(8, width);
      __GLX_PUT_LONG(12, height);
      __GLX_PUT_LONG(16, format);
      __GLX_PUT_LONG(20, type);
      pc += hdrlen;

      /* Allocate a temporary holding buffer */
      buf = (GLubyte *) Xmalloc(bufsize);
      if (!buf) {
         __glXSetError(gc, GL_OUT_OF_MEMORY);
         return;
      }
      (*gc->fillImage) (gc, 1, width, 1, 1, format, type, row, buf,
                        pixelHeaderPC);

      (*gc->fillImage) (gc, 1, height, 1, 1, format, type, column,
                        buf + image1len, pixelHeaderPC);

      /* Send large command */
      __glXSendLargeCommand(gc, gc->pc, (GLint) (pc - gc->pc), buf,
                            bufsize);
      /* Free buffer */
      Xfree((char *) buf);
   }
}
