1848b8605Smrg/*
2848b8605Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3848b8605Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4848b8605Smrg *
5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6848b8605Smrg * copy of this software and associated documentation files (the "Software"),
7848b8605Smrg * to deal in the Software without restriction, including without limitation
8848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
10848b8605Smrg * Software is furnished to do so, subject to the following conditions:
11848b8605Smrg *
12848b8605Smrg * The above copyright notice including the dates of first publication and
13848b8605Smrg * either this permission notice or a reference to
14848b8605Smrg * http://oss.sgi.com/projects/FreeB/
15848b8605Smrg * shall be included in all copies or substantial portions of the Software.
16848b8605Smrg *
17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20848b8605Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21848b8605Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22848b8605Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23848b8605Smrg * SOFTWARE.
24848b8605Smrg *
25848b8605Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26848b8605Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27848b8605Smrg * other dealings in this Software without prior written authorization from
28848b8605Smrg * Silicon Graphics, Inc.
29848b8605Smrg */
30848b8605Smrg
31848b8605Smrg#include "packsingle.h"
32848b8605Smrg#include "indirect.h"
33848b8605Smrg#include "glapi.h"
34848b8605Smrg#include <GL/glxproto.h>
35848b8605Smrg
36848b8605Smrgvoid
37848b8605Smrg__indirect_glGetSeparableFilter(GLenum target, GLenum format, GLenum type,
38848b8605Smrg                                GLvoid * row, GLvoid * column, GLvoid * span)
39848b8605Smrg{
40848b8605Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
41848b8605Smrg   const __GLXattribute *state;
42848b8605Smrg   xGLXGetSeparableFilterReply reply;
43848b8605Smrg   GLubyte *rowBuf, *colBuf;
44848b8605Smrg
45848b8605Smrg   if (!dpy)
46848b8605Smrg      return;
47848b8605Smrg   __GLX_SINGLE_LOAD_VARIABLES();
48848b8605Smrg   state = gc->client_state_private;
49848b8605Smrg
50848b8605Smrg   /* Send request */
51848b8605Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetSeparableFilter, __GLX_PAD(13));
52848b8605Smrg   __GLX_SINGLE_PUT_LONG(0, target);
53848b8605Smrg   __GLX_SINGLE_PUT_LONG(4, format);
54848b8605Smrg   __GLX_SINGLE_PUT_LONG(8, type);
55848b8605Smrg   __GLX_SINGLE_PUT_CHAR(12, state->storePack.swapEndian);
56848b8605Smrg   __GLX_SINGLE_READ_XREPLY();
57848b8605Smrg   compsize = reply.length << 2;
58848b8605Smrg
59848b8605Smrg   if (compsize != 0) {
60848b8605Smrg      GLint width, height;
61848b8605Smrg      GLint widthsize, heightsize;
62848b8605Smrg
63848b8605Smrg      width = reply.width;
64848b8605Smrg      height = reply.height;
65848b8605Smrg
66848b8605Smrg      widthsize = __glImageSize(width, 1, 1, format, type, 0);
67848b8605Smrg      heightsize = __glImageSize(height, 1, 1, format, type, 0);
68848b8605Smrg
69848b8605Smrg      /* Allocate a holding buffer to transform the data from */
70848b8605Smrg      rowBuf = malloc(widthsize);
71848b8605Smrg      if (!rowBuf) {
72848b8605Smrg         /* Throw data away */
73848b8605Smrg         _XEatData(dpy, compsize);
74848b8605Smrg         __glXSetError(gc, GL_OUT_OF_MEMORY);
75848b8605Smrg         UnlockDisplay(dpy);
76848b8605Smrg         SyncHandle();
77848b8605Smrg         return;
78848b8605Smrg      }
79848b8605Smrg      else {
80848b8605Smrg         __GLX_SINGLE_GET_CHAR_ARRAY(((char *) rowBuf), widthsize);
81848b8605Smrg         __glEmptyImage(gc, 1, width, 1, 1, format, type, rowBuf, row);
82848b8605Smrg         free((char *) rowBuf);
83848b8605Smrg      }
84848b8605Smrg      colBuf = malloc(heightsize);
85848b8605Smrg      if (!colBuf) {
86848b8605Smrg         /* Throw data away */
87848b8605Smrg         _XEatData(dpy, compsize - __GLX_PAD(widthsize));
88848b8605Smrg         __glXSetError(gc, GL_OUT_OF_MEMORY);
89848b8605Smrg         UnlockDisplay(dpy);
90848b8605Smrg         SyncHandle();
91848b8605Smrg         return;
92848b8605Smrg      }
93848b8605Smrg      else {
94848b8605Smrg         __GLX_SINGLE_GET_CHAR_ARRAY(((char *) colBuf), heightsize);
95848b8605Smrg         __glEmptyImage(gc, 1, height, 1, 1, format, type, colBuf, column);
96848b8605Smrg         free((char *) colBuf);
97848b8605Smrg      }
98848b8605Smrg   }
99848b8605Smrg   else {
100848b8605Smrg      /*
101848b8605Smrg       ** don't modify user's buffer.
102848b8605Smrg       */
103848b8605Smrg   }
104848b8605Smrg   __GLX_SINGLE_END();
105848b8605Smrg
106848b8605Smrg}
107848b8605Smrg
108848b8605Smrg
109848b8605Smrg/* it is defined to gl_dispatch_stub_NNN in indirect.h */
110848b8605Smrgvoid gl_dispatch_stub_GetSeparableFilterEXT (GLenum target, GLenum format,
111848b8605Smrg                                             GLenum type, GLvoid * row,
112848b8605Smrg                                             GLvoid * column, GLvoid * span)
113848b8605Smrg{
114848b8605Smrg   struct glx_context *const gc = __glXGetCurrentContext();
115848b8605Smrg
116848b8605Smrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
117848b8605Smrg   if (gc->isDirect) {
118848b8605Smrg      const _glapi_proc *const table = (_glapi_proc *) GET_DISPATCH();
119848b8605Smrg      PFNGLGETSEPARABLEFILTEREXTPROC p =
120848b8605Smrg         (PFNGLGETSEPARABLEFILTEREXTPROC) table[359];
121848b8605Smrg
122848b8605Smrg      p(target, format, type, row, column, span);
123848b8605Smrg      return;
124848b8605Smrg   }
125848b8605Smrg   else
126848b8605Smrg#endif
127848b8605Smrg   {
128848b8605Smrg      Display *const dpy = gc->currentDpy;
129848b8605Smrg      const GLuint cmdlen = __GLX_PAD(13);
130848b8605Smrg
131848b8605Smrg      if (dpy != NULL) {
132848b8605Smrg         const __GLXattribute *const state = gc->client_state_private;
133848b8605Smrg         xGLXGetSeparableFilterReply reply;
134848b8605Smrg         GLubyte const *pc =
135848b8605Smrg            __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
136848b8605Smrg                                    X_GLvop_GetSeparableFilterEXT, cmdlen);
137848b8605Smrg         unsigned compsize;
138848b8605Smrg
139848b8605Smrg
140848b8605Smrg         (void) memcpy((void *) (pc + 0), (void *) (&target), 4);
141848b8605Smrg         (void) memcpy((void *) (pc + 4), (void *) (&format), 4);
142848b8605Smrg         (void) memcpy((void *) (pc + 8), (void *) (&type), 4);
143848b8605Smrg         *(int8_t *) (pc + 12) = state->storePack.swapEndian;
144848b8605Smrg
145848b8605Smrg         (void) _XReply(dpy, (xReply *) & reply, 0, False);
146848b8605Smrg
147848b8605Smrg         compsize = reply.length << 2;
148848b8605Smrg
149848b8605Smrg         if (compsize != 0) {
150848b8605Smrg            const GLint width = reply.width;
151848b8605Smrg            const GLint height = reply.height;
152848b8605Smrg            const GLint widthsize =
153848b8605Smrg               __glImageSize(width, 1, 1, format, type, 0);
154848b8605Smrg            const GLint heightsize =
155848b8605Smrg               __glImageSize(height, 1, 1, format, type, 0);
156848b8605Smrg            GLubyte *const buf =
157848b8605Smrg               malloc((widthsize > heightsize) ? widthsize : heightsize);
158848b8605Smrg
159848b8605Smrg            if (buf == NULL) {
160848b8605Smrg               /* Throw data away */
161848b8605Smrg               _XEatData(dpy, compsize);
162848b8605Smrg               __glXSetError(gc, GL_OUT_OF_MEMORY);
163848b8605Smrg
164848b8605Smrg               UnlockDisplay(dpy);
165848b8605Smrg               SyncHandle();
166848b8605Smrg               return;
167848b8605Smrg            }
168848b8605Smrg            else {
169848b8605Smrg               int extra;
170848b8605Smrg
171848b8605Smrg               extra = 4 - (widthsize & 3);
172848b8605Smrg               _XRead(dpy, (char *) buf, widthsize);
173848b8605Smrg               if (extra < 4) {
174848b8605Smrg                  _XEatData(dpy, extra);
175848b8605Smrg               }
176848b8605Smrg
177848b8605Smrg               __glEmptyImage(gc, 1, width, 1, 1, format, type, buf, row);
178848b8605Smrg
179848b8605Smrg               extra = 4 - (heightsize & 3);
180848b8605Smrg               _XRead(dpy, (char *) buf, heightsize);
181848b8605Smrg               if (extra < 4) {
182848b8605Smrg                  _XEatData(dpy, extra);
183848b8605Smrg               }
184848b8605Smrg
185848b8605Smrg               __glEmptyImage(gc, 1, height, 1, 1, format, type, buf, column);
186848b8605Smrg
187848b8605Smrg               free((char *) buf);
188848b8605Smrg            }
189848b8605Smrg         }
190848b8605Smrg      }
191848b8605Smrg   }
192848b8605Smrg}
193