1848b8605Smrg/*
2848b8605Smrg * (C) Copyright IBM Corporation 2005
3848b8605Smrg * 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, sub license,
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 and this permission notice (including the next
13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the
14848b8605Smrg * Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * IBM,
20848b8605Smrg * AND/OR THEIR SUPPLIERS 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
26848b8605Smrg#include <inttypes.h>
27848b8605Smrg#include <GL/gl.h>
28848b8605Smrg#include "indirect.h"
29848b8605Smrg#include "glxclient.h"
30848b8605Smrg#include "indirect_vertex_array.h"
31848b8605Smrg#include <GL/glxproto.h>
32848b8605Smrg
33848b8605Smrg#if !defined(__GNUC__)
34848b8605Smrg#  define __builtin_expect(x, y) x
35848b8605Smrg#endif
36848b8605Smrg
37848b8605Smrgstatic void
38848b8605Smrgdo_vertex_attrib_enable(GLuint index, GLboolean val)
39848b8605Smrg{
40848b8605Smrg   struct glx_context *gc = __glXGetCurrentContext();
41848b8605Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
42848b8605Smrg
43848b8605Smrg   if (!__glXSetArrayEnable(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB,
44848b8605Smrg                            index, val)) {
45848b8605Smrg      __glXSetError(gc, GL_INVALID_ENUM);
46848b8605Smrg   }
47848b8605Smrg}
48848b8605Smrg
49848b8605Smrg
50848b8605Smrgvoid
51848b8605Smrg__indirect_glEnableVertexAttribArray(GLuint index)
52848b8605Smrg{
53848b8605Smrg   do_vertex_attrib_enable(index, GL_TRUE);
54848b8605Smrg}
55848b8605Smrg
56848b8605Smrg
57848b8605Smrgvoid
58848b8605Smrg__indirect_glDisableVertexAttribArray(GLuint index)
59848b8605Smrg{
60848b8605Smrg   do_vertex_attrib_enable(index, GL_FALSE);
61848b8605Smrg}
62848b8605Smrg
63848b8605Smrg
64848b8605Smrgstatic void
65848b8605Smrgget_parameter(unsigned opcode, unsigned size, GLenum target, GLuint index,
66848b8605Smrg              void *params)
67848b8605Smrg{
68848b8605Smrg   struct glx_context *const gc = __glXGetCurrentContext();
69848b8605Smrg   Display *const dpy = gc->currentDpy;
70848b8605Smrg   const GLuint cmdlen = 12;
71848b8605Smrg
72848b8605Smrg   if (__builtin_expect(dpy != NULL, 1)) {
73848b8605Smrg      GLubyte const *pc = __glXSetupVendorRequest(gc,
74848b8605Smrg                                                  X_GLXVendorPrivateWithReply,
75848b8605Smrg                                                  opcode, cmdlen);
76848b8605Smrg
77848b8605Smrg      *((GLenum *) (pc + 0)) = target;
78848b8605Smrg      *((GLuint *) (pc + 4)) = index;
79848b8605Smrg      *((GLuint *) (pc + 8)) = 0;
80848b8605Smrg
81848b8605Smrg      (void) __glXReadReply(dpy, size, params, GL_FALSE);
82848b8605Smrg      UnlockDisplay(dpy);
83848b8605Smrg      SyncHandle();
84848b8605Smrg   }
85848b8605Smrg   return;
86848b8605Smrg}
87848b8605Smrg
88848b8605Smrg
89848b8605Smrgvoid
90848b8605Smrg__indirect_glGetProgramEnvParameterfvARB(GLenum target, GLuint index,
91848b8605Smrg                                         GLfloat * params)
92848b8605Smrg{
93848b8605Smrg   get_parameter(1296, 4, target, index, params);
94848b8605Smrg}
95848b8605Smrg
96848b8605Smrg
97848b8605Smrgvoid
98848b8605Smrg__indirect_glGetProgramEnvParameterdvARB(GLenum target, GLuint index,
99848b8605Smrg                                         GLdouble * params)
100848b8605Smrg{
101848b8605Smrg   get_parameter(1297, 8, target, index, params);
102848b8605Smrg}
103848b8605Smrg
104848b8605Smrg
105848b8605Smrgvoid
106848b8605Smrg__indirect_glGetProgramLocalParameterfvARB(GLenum target, GLuint index,
107848b8605Smrg                                           GLfloat * params)
108848b8605Smrg{
109848b8605Smrg   get_parameter(1305, 4, target, index, params);
110848b8605Smrg}
111848b8605Smrg
112848b8605Smrg
113848b8605Smrgvoid
114848b8605Smrg__indirect_glGetProgramLocalParameterdvARB(GLenum target, GLuint index,
115848b8605Smrg                                           GLdouble * params)
116848b8605Smrg{
117848b8605Smrg   get_parameter(1306, 8, target, index, params);
118848b8605Smrg}
119848b8605Smrg
120848b8605Smrg
121848b8605Smrgvoid
122848b8605Smrg__indirect_glGetVertexAttribPointerv(GLuint index, GLenum pname,
123848b8605Smrg                                       GLvoid ** pointer)
124848b8605Smrg{
125848b8605Smrg   struct glx_context *const gc = __glXGetCurrentContext();
126848b8605Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
127848b8605Smrg
128848b8605Smrg   if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
129848b8605Smrg      __glXSetError(gc, GL_INVALID_ENUM);
130848b8605Smrg   }
131848b8605Smrg
132848b8605Smrg   if (!__glXGetArrayPointer(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB,
133848b8605Smrg                             index, pointer)) {
134848b8605Smrg      __glXSetError(gc, GL_INVALID_VALUE);
135848b8605Smrg   }
136848b8605Smrg}
137848b8605Smrg
138848b8605Smrg
139848b8605Smrg/**
140848b8605Smrg * Get the selected attribute from the vertex array state vector.
141848b8605Smrg *
142848b8605Smrg * \returns
143848b8605Smrg * On success \c GL_TRUE is returned.  Otherwise, \c GL_FALSE is returned.
144848b8605Smrg */
145848b8605Smrgstatic GLboolean
146848b8605Smrgget_attrib_array_data(__GLXattribute * state, GLuint index, GLenum cap,
147848b8605Smrg                      GLintptr * data)
148848b8605Smrg{
149848b8605Smrg   GLboolean retval = GL_FALSE;
150848b8605Smrg   const GLenum attrib = GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB;
151848b8605Smrg
152848b8605Smrg   switch (cap) {
153848b8605Smrg   case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
154848b8605Smrg      retval = __glXGetArrayEnable(state, attrib, index, data);
155848b8605Smrg      break;
156848b8605Smrg
157848b8605Smrg   case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
158848b8605Smrg      retval = __glXGetArraySize(state, attrib, index, data);
159848b8605Smrg      break;
160848b8605Smrg
161848b8605Smrg   case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
162848b8605Smrg      retval = __glXGetArrayStride(state, attrib, index, data);
163848b8605Smrg      break;
164848b8605Smrg
165848b8605Smrg   case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
166848b8605Smrg      retval = __glXGetArrayType(state, attrib, index, data);
167848b8605Smrg      break;
168848b8605Smrg
169848b8605Smrg   case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
170848b8605Smrg      retval = __glXGetArrayNormalized(state, attrib, index, data);
171848b8605Smrg      break;
172848b8605Smrg   }
173848b8605Smrg
174848b8605Smrg
175848b8605Smrg   return retval;
176848b8605Smrg}
177848b8605Smrg
178848b8605Smrg
179848b8605Smrgstatic void
180848b8605Smrgget_vertex_attrib(struct glx_context * gc, unsigned vop,
181848b8605Smrg                  GLuint index, GLenum pname, xReply * reply)
182848b8605Smrg{
183848b8605Smrg   Display *const dpy = gc->currentDpy;
184848b8605Smrg   GLubyte *const pc = __glXSetupVendorRequest(gc,
185848b8605Smrg                                               X_GLXVendorPrivateWithReply,
186848b8605Smrg                                               vop, 8);
187848b8605Smrg
188848b8605Smrg   *((uint32_t *) (pc + 0)) = index;
189848b8605Smrg   *((uint32_t *) (pc + 4)) = pname;
190848b8605Smrg
191848b8605Smrg   (void) _XReply(dpy, reply, 0, False);
192848b8605Smrg}
193848b8605Smrg
194848b8605Smrg
195848b8605Smrgvoid
196848b8605Smrg__indirect_glGetVertexAttribiv(GLuint index, GLenum pname, GLint * params)
197848b8605Smrg{
198848b8605Smrg   struct glx_context *const gc = __glXGetCurrentContext();
199848b8605Smrg   Display *const dpy = gc->currentDpy;
200848b8605Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
201848b8605Smrg   xGLXSingleReply reply;
202848b8605Smrg
203848b8605Smrg
204848b8605Smrg   get_vertex_attrib(gc, 1303, index, pname, (xReply *) & reply);
205848b8605Smrg
206848b8605Smrg   if (reply.size != 0) {
207848b8605Smrg      GLintptr data;
208848b8605Smrg
209848b8605Smrg
210848b8605Smrg      if (get_attrib_array_data(state, index, pname, &data)) {
211848b8605Smrg         *params = (GLint) data;
212848b8605Smrg      }
213848b8605Smrg      else {
214848b8605Smrg         if (reply.size == 1) {
215848b8605Smrg            *params = (GLint) reply.pad3;
216848b8605Smrg         }
217848b8605Smrg         else {
218848b8605Smrg            _XRead(dpy, (void *) params, 4 * reply.size);
219848b8605Smrg         }
220848b8605Smrg      }
221848b8605Smrg   }
222848b8605Smrg
223848b8605Smrg   UnlockDisplay(dpy);
224848b8605Smrg   SyncHandle();
225848b8605Smrg}
226848b8605Smrg
227848b8605Smrg
228848b8605Smrgvoid
229848b8605Smrg__indirect_glGetVertexAttribfv(GLuint index, GLenum pname,
230848b8605Smrg                                  GLfloat * params)
231848b8605Smrg{
232848b8605Smrg   struct glx_context *const gc = __glXGetCurrentContext();
233848b8605Smrg   Display *const dpy = gc->currentDpy;
234848b8605Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
235848b8605Smrg   xGLXSingleReply reply;
236848b8605Smrg
237848b8605Smrg
238848b8605Smrg   get_vertex_attrib(gc, 1302, index, pname, (xReply *) & reply);
239848b8605Smrg
240848b8605Smrg   if (reply.size != 0) {
241848b8605Smrg      GLintptr data;
242848b8605Smrg
243848b8605Smrg
244848b8605Smrg      if (get_attrib_array_data(state, index, pname, &data)) {
245848b8605Smrg         *params = (GLfloat) data;
246848b8605Smrg      }
247848b8605Smrg      else {
248848b8605Smrg         if (reply.size == 1) {
249848b8605Smrg            (void) memcpy(params, &reply.pad3, sizeof(GLfloat));
250848b8605Smrg         }
251848b8605Smrg         else {
252848b8605Smrg            _XRead(dpy, (void *) params, 4 * reply.size);
253848b8605Smrg         }
254848b8605Smrg      }
255848b8605Smrg   }
256848b8605Smrg
257848b8605Smrg   UnlockDisplay(dpy);
258848b8605Smrg   SyncHandle();
259848b8605Smrg}
260848b8605Smrg
261848b8605Smrg
262848b8605Smrgvoid
263848b8605Smrg__indirect_glGetVertexAttribdv(GLuint index, GLenum pname,
264848b8605Smrg                                  GLdouble * params)
265848b8605Smrg{
266848b8605Smrg   struct glx_context *const gc = __glXGetCurrentContext();
267848b8605Smrg   Display *const dpy = gc->currentDpy;
268848b8605Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
269848b8605Smrg   xGLXSingleReply reply;
270848b8605Smrg
271848b8605Smrg
272848b8605Smrg   get_vertex_attrib(gc, 1301, index, pname, (xReply *) & reply);
273848b8605Smrg
274848b8605Smrg   if (reply.size != 0) {
275848b8605Smrg      GLintptr data;
276848b8605Smrg
277848b8605Smrg
278848b8605Smrg      if (get_attrib_array_data(state, index, pname, &data)) {
279848b8605Smrg         *params = (GLdouble) data;
280848b8605Smrg      }
281848b8605Smrg      else {
282848b8605Smrg         if (reply.size == 1) {
283848b8605Smrg            (void) memcpy(params, &reply.pad3, sizeof(GLdouble));
284848b8605Smrg         }
285848b8605Smrg         else {
286848b8605Smrg            _XRead(dpy, (void *) params, 8 * reply.size);
287848b8605Smrg         }
288848b8605Smrg      }
289848b8605Smrg   }
290848b8605Smrg
291848b8605Smrg   UnlockDisplay(dpy);
292848b8605Smrg   SyncHandle();
293848b8605Smrg}
294