1 /* 2 * (C) Copyright IBM Corporation 2005 3 * 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, sub license, 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 and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * IBM, 20 * AND/OR THEIR SUPPLIERS 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 26 #include <inttypes.h> 27 #include <GL/gl.h> 28 #include "indirect.h" 29 #include "glxclient.h" 30 #include "indirect_vertex_array.h" 31 #include <GL/glxproto.h> 32 33 #if !defined(__GNUC__) 34 # define __builtin_expect(x, y) x 35 #endif 36 37 static void 38 do_vertex_attrib_enable(GLuint index, GLboolean val) 39 { 40 struct glx_context *gc = __glXGetCurrentContext(); 41 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 42 43 if (!__glXSetArrayEnable(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB, 44 index, val)) { 45 __glXSetError(gc, GL_INVALID_ENUM); 46 } 47 } 48 49 50 void 51 __indirect_glEnableVertexAttribArrayARB(GLuint index) 52 { 53 do_vertex_attrib_enable(index, GL_TRUE); 54 } 55 56 57 void 58 __indirect_glDisableVertexAttribArrayARB(GLuint index) 59 { 60 do_vertex_attrib_enable(index, GL_FALSE); 61 } 62 63 64 static void 65 get_parameter(unsigned opcode, unsigned size, GLenum target, GLuint index, 66 void *params) 67 { 68 struct glx_context *const gc = __glXGetCurrentContext(); 69 Display *const dpy = gc->currentDpy; 70 const GLuint cmdlen = 12; 71 72 if (__builtin_expect(dpy != NULL, 1)) { 73 GLubyte const *pc = __glXSetupVendorRequest(gc, 74 X_GLXVendorPrivateWithReply, 75 opcode, cmdlen); 76 77 *((GLenum *) (pc + 0)) = target; 78 *((GLuint *) (pc + 4)) = index; 79 *((GLuint *) (pc + 8)) = 0; 80 81 (void) __glXReadReply(dpy, size, params, GL_FALSE); 82 UnlockDisplay(dpy); 83 SyncHandle(); 84 } 85 return; 86 } 87 88 89 void 90 __indirect_glGetProgramEnvParameterfvARB(GLenum target, GLuint index, 91 GLfloat * params) 92 { 93 get_parameter(1296, 4, target, index, params); 94 } 95 96 97 void 98 __indirect_glGetProgramEnvParameterdvARB(GLenum target, GLuint index, 99 GLdouble * params) 100 { 101 get_parameter(1297, 8, target, index, params); 102 } 103 104 105 void 106 __indirect_glGetProgramLocalParameterfvARB(GLenum target, GLuint index, 107 GLfloat * params) 108 { 109 get_parameter(1305, 4, target, index, params); 110 } 111 112 113 void 114 __indirect_glGetProgramLocalParameterdvARB(GLenum target, GLuint index, 115 GLdouble * params) 116 { 117 get_parameter(1306, 8, target, index, params); 118 } 119 120 121 void 122 __indirect_glGetVertexAttribPointervNV(GLuint index, GLenum pname, 123 GLvoid ** pointer) 124 { 125 struct glx_context *const gc = __glXGetCurrentContext(); 126 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 127 128 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { 129 __glXSetError(gc, GL_INVALID_ENUM); 130 } 131 132 if (!__glXGetArrayPointer(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB, 133 index, pointer)) { 134 __glXSetError(gc, GL_INVALID_VALUE); 135 } 136 } 137 138 139 /** 140 * Get the selected attribute from the vertex array state vector. 141 * 142 * \returns 143 * On success \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. 144 */ 145 static GLboolean 146 get_attrib_array_data(__GLXattribute * state, GLuint index, GLenum cap, 147 GLintptr * data) 148 { 149 GLboolean retval = GL_FALSE; 150 const GLenum attrib = GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB; 151 152 switch (cap) { 153 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: 154 retval = __glXGetArrayEnable(state, attrib, index, data); 155 break; 156 157 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: 158 retval = __glXGetArraySize(state, attrib, index, data); 159 break; 160 161 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: 162 retval = __glXGetArrayStride(state, attrib, index, data); 163 break; 164 165 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: 166 retval = __glXGetArrayType(state, attrib, index, data); 167 break; 168 169 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: 170 retval = __glXGetArrayNormalized(state, attrib, index, data); 171 break; 172 } 173 174 175 return retval; 176 } 177 178 179 static void 180 get_vertex_attrib(struct glx_context * gc, unsigned vop, 181 GLuint index, GLenum pname, xReply * reply) 182 { 183 Display *const dpy = gc->currentDpy; 184 GLubyte *const pc = __glXSetupVendorRequest(gc, 185 X_GLXVendorPrivateWithReply, 186 vop, 8); 187 188 *((uint32_t *) (pc + 0)) = index; 189 *((uint32_t *) (pc + 4)) = pname; 190 191 (void) _XReply(dpy, reply, 0, False); 192 } 193 194 195 void 196 __indirect_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint * params) 197 { 198 struct glx_context *const gc = __glXGetCurrentContext(); 199 Display *const dpy = gc->currentDpy; 200 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 201 xGLXSingleReply reply; 202 203 204 get_vertex_attrib(gc, 1303, index, pname, (xReply *) & reply); 205 206 if (reply.size != 0) { 207 GLintptr data; 208 209 210 if (get_attrib_array_data(state, index, pname, &data)) { 211 *params = (GLint) data; 212 } 213 else { 214 if (reply.size == 1) { 215 *params = (GLint) reply.pad3; 216 } 217 else { 218 _XRead(dpy, (void *) params, 4 * reply.size); 219 } 220 } 221 } 222 223 UnlockDisplay(dpy); 224 SyncHandle(); 225 } 226 227 228 void 229 __indirect_glGetVertexAttribfvARB(GLuint index, GLenum pname, 230 GLfloat * params) 231 { 232 struct glx_context *const gc = __glXGetCurrentContext(); 233 Display *const dpy = gc->currentDpy; 234 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 235 xGLXSingleReply reply; 236 237 238 get_vertex_attrib(gc, 1302, index, pname, (xReply *) & reply); 239 240 if (reply.size != 0) { 241 GLintptr data; 242 243 244 if (get_attrib_array_data(state, index, pname, &data)) { 245 *params = (GLfloat) data; 246 } 247 else { 248 if (reply.size == 1) { 249 (void) memcpy(params, &reply.pad3, sizeof(GLfloat)); 250 } 251 else { 252 _XRead(dpy, (void *) params, 4 * reply.size); 253 } 254 } 255 } 256 257 UnlockDisplay(dpy); 258 SyncHandle(); 259 } 260 261 262 void 263 __indirect_glGetVertexAttribdvARB(GLuint index, GLenum pname, 264 GLdouble * params) 265 { 266 struct glx_context *const gc = __glXGetCurrentContext(); 267 Display *const dpy = gc->currentDpy; 268 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 269 xGLXSingleReply reply; 270 271 272 get_vertex_attrib(gc, 1301, index, pname, (xReply *) & reply); 273 274 if (reply.size != 0) { 275 GLintptr data; 276 277 278 if (get_attrib_array_data(state, index, pname, &data)) { 279 *params = (GLdouble) data; 280 } 281 else { 282 if (reply.size == 1) { 283 (void) memcpy(params, &reply.pad3, sizeof(GLdouble)); 284 } 285 else { 286 _XRead(dpy, (void *) params, 8 * reply.size); 287 } 288 } 289 } 290 291 UnlockDisplay(dpy); 292 SyncHandle(); 293 } 294