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 
41 void
__indirect_glMap1d(GLenum target,GLdouble u1,GLdouble u2,GLint stride,GLint order,const GLdouble * pnts)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 
108 void
__indirect_glMap1f(GLenum target,GLfloat u1,GLfloat u2,GLint stride,GLint order,const GLfloat * pnts)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 
171 void
__indirect_glMap2d(GLenum target,GLdouble u1,GLdouble u2,GLint ustr,GLint uord,GLdouble v1,GLdouble v2,GLint vstr,GLint vord,const GLdouble * pnts)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 
249 void
__indirect_glMap2f(GLenum target,GLfloat u1,GLfloat u2,GLint ustr,GLint uord,GLfloat v1,GLfloat v2,GLint vstr,GLint vord,const GLfloat * pnts)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 
325 void
__indirect_glEnable(GLenum cap)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 
354 void
__indirect_glDisable(GLenum cap)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