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

#include "glheader.h"
#include "packsingle.h"
#include "indirect.h"
#include "dispatch.h"
#include "glapi.h"
#include "glthread.h"
#include "glapioffsets.h"
#include <GL/glxproto.h>

void __indirect_glGetSeparableFilter(GLenum target, GLenum format, GLenum type,
			  GLvoid *row, GLvoid *column, GLvoid *span)
{
    __GLX_SINGLE_DECLARE_VARIABLES();
    const __GLXattribute * state;
    xGLXGetSeparableFilterReply reply;
    GLubyte *rowBuf, *colBuf;

    if (!dpy) return;
    __GLX_SINGLE_LOAD_VARIABLES();
    state = gc->client_state_private;

    /* Send request */
    __GLX_SINGLE_BEGIN(X_GLsop_GetSeparableFilter, __GLX_PAD(13));
    __GLX_SINGLE_PUT_LONG(0,target);
    __GLX_SINGLE_PUT_LONG(4,format);
    __GLX_SINGLE_PUT_LONG(8,type);
    __GLX_SINGLE_PUT_CHAR(12,state->storePack.swapEndian);
    __GLX_SINGLE_READ_XREPLY();
    compsize = reply.length << 2;

    if (compsize != 0) {
	GLint width, height;
	GLint widthsize, heightsize;

	width = reply.width;
	height = reply.height;

	widthsize = __glImageSize(width,1,1,format, type, 0);
	heightsize = __glImageSize(height,1,1,format, type, 0);

	/* Allocate a holding buffer to transform the data from */
	rowBuf = (GLubyte*) Xmalloc(widthsize);
	if (!rowBuf) {
	    /* Throw data away */
	    _XEatData(dpy, compsize);
	    __glXSetError(gc, GL_OUT_OF_MEMORY);
	    UnlockDisplay(dpy);
	    SyncHandle();
	    return;
	} else {
	    __GLX_SINGLE_GET_CHAR_ARRAY(((char*)rowBuf),widthsize);
	    __glEmptyImage(gc, 1, width, 1, 1, format, type, rowBuf, row);
	    Xfree((char*) rowBuf);
	}
	colBuf = (GLubyte*) Xmalloc(heightsize);
	if (!colBuf) {
	    /* Throw data away */
	    _XEatData(dpy, compsize - __GLX_PAD(widthsize));
	    __glXSetError(gc, GL_OUT_OF_MEMORY);
	    UnlockDisplay(dpy);
	    SyncHandle();
	    return;
	} else {
	    __GLX_SINGLE_GET_CHAR_ARRAY(((char*)colBuf),heightsize);
	    __glEmptyImage(gc, 1, height, 1, 1, format, type, colBuf, column);
	    Xfree((char*) colBuf);
	}
    } else {
	/*
	** don't modify user's buffer.
	*/
    }
    __GLX_SINGLE_END();
    
}


#define CONCAT(a,b) a ## b
#define NAME(o) CONCAT(gl_dispatch_stub_, o)

void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum type,
					GLvoid *row, GLvoid *column, GLvoid *span)
{
    __GLXcontext * const gc = __glXGetCurrentContext();

#ifdef GLX_DIRECT_RENDERING
    if (gc->driContext) {
	CALL_GetSeparableFilter(GET_DISPATCH(),
				(target, format, type, row, column, span));
	return;
    } else 
#endif
    {
        Display *const dpy = gc->currentDpy;
	const GLuint cmdlen = __GLX_PAD(13);

	if (dpy != NULL) {
	    const __GLXattribute * const state = gc->client_state_private;
	    xGLXGetSeparableFilterReply reply;
	    GLubyte const *pc =
	      __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
				      X_GLvop_GetSeparableFilterEXT, cmdlen);
	    unsigned compsize;


	    (void) memcpy((void *) (pc + 0), (void *) (&target), 4);
	    (void) memcpy((void *) (pc + 4), (void *) (&format), 4);
	    (void) memcpy((void *) (pc + 8), (void *) (&type), 4);
	    *(int8_t *) (pc + 12) = state->storePack.swapEndian;

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

	    compsize = reply.length << 2;

	    if (compsize != 0) {
		const GLint width = reply.width;
		const GLint height = reply.height;
		const GLint widthsize =
		  __glImageSize(width, 1, 1, format, type, 0);
		const GLint heightsize =
		  __glImageSize(height, 1, 1, format, type, 0);
		GLubyte * const buf =
		  (GLubyte*) Xmalloc((widthsize > heightsize) ? widthsize : heightsize);

		if (buf == NULL) {
		    /* Throw data away */
		    _XEatData(dpy, compsize);
		    __glXSetError(gc, GL_OUT_OF_MEMORY);

		    UnlockDisplay(dpy);
		    SyncHandle();
		    return;
		} else {
		    int extra;
		    
		    extra = 4 - (widthsize & 3);
		    _XRead(dpy, (char *)buf, widthsize);
		    if (extra < 4) {
			_XEatData(dpy, extra);
		    }

		    __glEmptyImage(gc, 1, width, 1, 1, format, type, buf,
				   row);

		    extra = 4 - (heightsize & 3);
		    _XRead(dpy, (char *)buf, heightsize);
		    if (extra < 4) {
			_XEatData(dpy, extra);
		    }

		    __glEmptyImage(gc, 1, height, 1, 1, format, type, buf,
				   column);

		    Xfree((char*) buf);
		}
	    }
	}
    }
}
