1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31#include "packrender.h"
32#include "indirect.h"
33#include "indirect_size.h"
34
35/*
36** This file contains routines that might need to be transported as
37** GLXRender or GLXRenderLarge commands, and these commands don't
38** use the pixel header.  See renderpix.c for those routines.
39*/
40
41void
42__indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
43                   GLint order, const GLdouble * pnts)
44{
45   __GLX_DECLARE_VARIABLES();
46   GLint k;
47
48   __GLX_LOAD_VARIABLES();
49   k = __glMap1d_size(target);
50   if (k == 0) {
51      __glXSetError(gc, GL_INVALID_ENUM);
52      return;
53   }
54   else if (stride < k || order <= 0) {
55      __glXSetError(gc, GL_INVALID_VALUE);
56      return;
57   }
58   compsize = k * order * __GLX_SIZE_FLOAT64;
59   cmdlen = 28 + compsize;
60   if (!gc->currentDpy)
61      return;
62
63   if (cmdlen <= gc->maxSmallRenderCommandSize) {
64      /* Use GLXRender protocol to send small command */
65      __GLX_BEGIN_VARIABLE(X_GLrop_Map1d, cmdlen);
66      __GLX_PUT_DOUBLE(4, u1);
67      __GLX_PUT_DOUBLE(12, u2);
68      __GLX_PUT_LONG(20, target);
69      __GLX_PUT_LONG(24, order);
70      /*
71       ** NOTE: the doubles that follow are not aligned because of 3
72       ** longs preceeding
73       */
74      __glFillMap1d(k, order, stride, pnts, (pc + 28));
75      __GLX_END(cmdlen);
76   }
77   else {
78      /* Use GLXRenderLarge protocol to send command */
79      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d, cmdlen + 4);
80      __GLX_PUT_DOUBLE(8, u1);
81      __GLX_PUT_DOUBLE(16, u2);
82      __GLX_PUT_LONG(24, target);
83      __GLX_PUT_LONG(28, order);
84
85      /*
86       ** NOTE: the doubles that follow are not aligned because of 3
87       ** longs preceeding
88       */
89      if (stride != k) {
90         GLubyte *buf;
91
92         buf = (GLubyte *) Xmalloc(compsize);
93         if (!buf) {
94            __glXSetError(gc, GL_OUT_OF_MEMORY);
95            return;
96         }
97         __glFillMap1d(k, order, stride, pnts, buf);
98         __glXSendLargeCommand(gc, pc, 32, buf, compsize);
99         Xfree((char *) buf);
100      }
101      else {
102         /* Data is already packed.  Just send it out */
103         __glXSendLargeCommand(gc, pc, 32, pnts, compsize);
104      }
105   }
106}
107
108void
109__indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
110                   GLint order, const GLfloat * pnts)
111{
112   __GLX_DECLARE_VARIABLES();
113   GLint k;
114
115   __GLX_LOAD_VARIABLES();
116   k = __glMap1f_size(target);
117   if (k == 0) {
118      __glXSetError(gc, GL_INVALID_ENUM);
119      return;
120   }
121   else if (stride < k || order <= 0) {
122      __glXSetError(gc, GL_INVALID_VALUE);
123      return;
124   }
125   compsize = k * order * __GLX_SIZE_FLOAT32;
126   cmdlen = 20 + compsize;
127   if (!gc->currentDpy)
128      return;
129
130   /*
131    ** The order that arguments are packed is different from the order
132    ** for glMap1d.
133    */
134   if (cmdlen <= gc->maxSmallRenderCommandSize) {
135      /* Use GLXRender protocol to send small command */
136      __GLX_BEGIN_VARIABLE(X_GLrop_Map1f, cmdlen);
137      __GLX_PUT_LONG(4, target);
138      __GLX_PUT_FLOAT(8, u1);
139      __GLX_PUT_FLOAT(12, u2);
140      __GLX_PUT_LONG(16, order);
141      __glFillMap1f(k, order, stride, pnts, (GLubyte *) (pc + 20));
142      __GLX_END(cmdlen);
143   }
144   else {
145      /* Use GLXRenderLarge protocol to send command */
146      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f, cmdlen + 4);
147      __GLX_PUT_LONG(8, target);
148      __GLX_PUT_FLOAT(12, u1);
149      __GLX_PUT_FLOAT(16, u2);
150      __GLX_PUT_LONG(20, order);
151
152      if (stride != k) {
153         GLubyte *buf;
154
155         buf = (GLubyte *) Xmalloc(compsize);
156         if (!buf) {
157            __glXSetError(gc, GL_OUT_OF_MEMORY);
158            return;
159         }
160         __glFillMap1f(k, order, stride, pnts, buf);
161         __glXSendLargeCommand(gc, pc, 24, buf, compsize);
162         Xfree((char *) buf);
163      }
164      else {
165         /* Data is already packed.  Just send it out */
166         __glXSendLargeCommand(gc, pc, 24, pnts, compsize);
167      }
168   }
169}
170
171void
172__indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr,
173                   GLint uord, GLdouble v1, GLdouble v2, GLint vstr,
174                   GLint vord, const GLdouble * pnts)
175{
176   __GLX_DECLARE_VARIABLES();
177   GLint k;
178
179   __GLX_LOAD_VARIABLES();
180   k = __glMap2d_size(target);
181   if (k == 0) {
182      __glXSetError(gc, GL_INVALID_ENUM);
183      return;
184   }
185   else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
186      __glXSetError(gc, GL_INVALID_VALUE);
187      return;
188   }
189   compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
190   cmdlen = 48 + compsize;
191   if (!gc->currentDpy)
192      return;
193
194   if (cmdlen <= gc->maxSmallRenderCommandSize) {
195      /* Use GLXRender protocol to send small command */
196      __GLX_BEGIN_VARIABLE(X_GLrop_Map2d, cmdlen);
197      __GLX_PUT_DOUBLE(4, u1);
198      __GLX_PUT_DOUBLE(12, u2);
199      __GLX_PUT_DOUBLE(20, v1);
200      __GLX_PUT_DOUBLE(28, v2);
201      __GLX_PUT_LONG(36, target);
202      __GLX_PUT_LONG(40, uord);
203      __GLX_PUT_LONG(44, vord);
204      /*
205       ** Pack into a u-major ordering.
206       ** NOTE: the doubles that follow are not aligned because of 5
207       ** longs preceeding
208       */
209      __glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble *) (pc + 48));
210      __GLX_END(cmdlen);
211   }
212   else {
213      /* Use GLXRenderLarge protocol to send command */
214      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d, cmdlen + 4);
215      __GLX_PUT_DOUBLE(8, u1);
216      __GLX_PUT_DOUBLE(16, u2);
217      __GLX_PUT_DOUBLE(24, v1);
218      __GLX_PUT_DOUBLE(32, v2);
219      __GLX_PUT_LONG(40, target);
220      __GLX_PUT_LONG(44, uord);
221      __GLX_PUT_LONG(48, vord);
222
223      /*
224       ** NOTE: the doubles that follow are not aligned because of 5
225       ** longs preceeding
226       */
227      if ((vstr != k) || (ustr != k * vord)) {
228         GLdouble *buf;
229
230         buf = (GLdouble *) Xmalloc(compsize);
231         if (!buf) {
232            __glXSetError(gc, GL_OUT_OF_MEMORY);
233            return;
234         }
235         /*
236          ** Pack into a u-major ordering.
237          */
238         __glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
239         __glXSendLargeCommand(gc, pc, 52, buf, compsize);
240         Xfree((char *) buf);
241      }
242      else {
243         /* Data is already packed.  Just send it out */
244         __glXSendLargeCommand(gc, pc, 52, pnts, compsize);
245      }
246   }
247}
248
249void
250__indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr,
251                   GLint uord, GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
252                   const GLfloat * pnts)
253{
254   __GLX_DECLARE_VARIABLES();
255   GLint k;
256
257   __GLX_LOAD_VARIABLES();
258   k = __glMap2f_size(target);
259   if (k == 0) {
260      __glXSetError(gc, GL_INVALID_ENUM);
261      return;
262   }
263   else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
264      __glXSetError(gc, GL_INVALID_VALUE);
265      return;
266   }
267   compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
268   cmdlen = 32 + compsize;
269   if (!gc->currentDpy)
270      return;
271
272   /*
273    ** The order that arguments are packed is different from the order
274    ** for glMap2d.
275    */
276   if (cmdlen <= gc->maxSmallRenderCommandSize) {
277      /* Use GLXRender protocol to send small command */
278      __GLX_BEGIN_VARIABLE(X_GLrop_Map2f, cmdlen);
279      __GLX_PUT_LONG(4, target);
280      __GLX_PUT_FLOAT(8, u1);
281      __GLX_PUT_FLOAT(12, u2);
282      __GLX_PUT_LONG(16, uord);
283      __GLX_PUT_FLOAT(20, v1);
284      __GLX_PUT_FLOAT(24, v2);
285      __GLX_PUT_LONG(28, vord);
286      /*
287       ** Pack into a u-major ordering.
288       */
289      __glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat *) (pc + 32));
290      __GLX_END(cmdlen);
291   }
292   else {
293      /* Use GLXRenderLarge protocol to send command */
294      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f, cmdlen + 4);
295      __GLX_PUT_LONG(8, target);
296      __GLX_PUT_FLOAT(12, u1);
297      __GLX_PUT_FLOAT(16, u2);
298      __GLX_PUT_LONG(20, uord);
299      __GLX_PUT_FLOAT(24, v1);
300      __GLX_PUT_FLOAT(28, v2);
301      __GLX_PUT_LONG(32, vord);
302
303      if ((vstr != k) || (ustr != k * vord)) {
304         GLfloat *buf;
305
306         buf = (GLfloat *) Xmalloc(compsize);
307         if (!buf) {
308            __glXSetError(gc, GL_OUT_OF_MEMORY);
309            return;
310         }
311         /*
312          ** Pack into a u-major ordering.
313          */
314         __glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
315         __glXSendLargeCommand(gc, pc, 36, buf, compsize);
316         Xfree((char *) buf);
317      }
318      else {
319         /* Data is already packed.  Just send it out */
320         __glXSendLargeCommand(gc, pc, 36, pnts, compsize);
321      }
322   }
323}
324
325void
326__indirect_glEnable(GLenum cap)
327{
328   __GLX_DECLARE_VARIABLES();
329
330   __GLX_LOAD_VARIABLES();
331   if (!gc->currentDpy)
332      return;
333
334   switch (cap) {
335   case GL_COLOR_ARRAY:
336   case GL_EDGE_FLAG_ARRAY:
337   case GL_INDEX_ARRAY:
338   case GL_NORMAL_ARRAY:
339   case GL_TEXTURE_COORD_ARRAY:
340   case GL_VERTEX_ARRAY:
341   case GL_SECONDARY_COLOR_ARRAY:
342   case GL_FOG_COORD_ARRAY:
343      __indirect_glEnableClientState(cap);
344      return;
345   default:
346      break;
347   }
348
349   __GLX_BEGIN(X_GLrop_Enable, 8);
350   __GLX_PUT_LONG(4, cap);
351   __GLX_END(8);
352}
353
354void
355__indirect_glDisable(GLenum cap)
356{
357   __GLX_DECLARE_VARIABLES();
358
359   __GLX_LOAD_VARIABLES();
360   if (!gc->currentDpy)
361      return;
362
363   switch (cap) {
364   case GL_COLOR_ARRAY:
365   case GL_EDGE_FLAG_ARRAY:
366   case GL_INDEX_ARRAY:
367   case GL_NORMAL_ARRAY:
368   case GL_TEXTURE_COORD_ARRAY:
369   case GL_VERTEX_ARRAY:
370   case GL_SECONDARY_COLOR_ARRAY:
371   case GL_FOG_COORD_ARRAY:
372      __indirect_glDisableClientState(cap);
373      return;
374   default:
375      break;
376   }
377
378   __GLX_BEGIN(X_GLrop_Disable, 8);
379   __GLX_PUT_LONG(4, cap);
380   __GLX_END(8);
381}
382