1/*
2 * Mesa 3-D graphics library
3 * Version:  7.1
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * 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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26
27#include "glheader.h"
28#include "context.h"
29#include "get.h"
30#include "enums.h"
31#include "extensions.h"
32#include "mfeatures.h"
33#include "mtypes.h"
34
35
36/**
37 * Return the string for a glGetString(GL_SHADING_LANGUAGE_VERSION) query.
38 */
39static const GLubyte *
40shading_language_version(struct gl_context *ctx)
41{
42   switch (ctx->API) {
43   case API_OPENGL:
44   case API_OPENGL_CORE:
45      if (!ctx->Extensions.ARB_shader_objects) {
46         _mesa_error(ctx, GL_INVALID_ENUM, "glGetString");
47         return (const GLubyte *) 0;
48      }
49
50      switch (ctx->Const.GLSLVersion) {
51      case 110:
52         return (const GLubyte *) "1.10";
53      case 120:
54         return (const GLubyte *) "1.20";
55      case 130:
56         return (const GLubyte *) "1.30";
57      case 140:
58         return (const GLubyte *) "1.40";
59      case 150:
60         return (const GLubyte *) "1.50";
61      case 330:
62         return (const GLubyte *) "3.30";
63      case 400:
64         return (const GLubyte *) "4.00";
65      case 410:
66         return (const GLubyte *) "4.10";
67      case 420:
68         return (const GLubyte *) "4.20";
69      default:
70         _mesa_problem(ctx,
71                       "Invalid GLSL version in shading_language_version()");
72         return (const GLubyte *) 0;
73      }
74      break;
75
76   case API_OPENGLES2:
77      return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16";
78
79   case API_OPENGLES:
80      /* fall-through */
81
82   default:
83      _mesa_problem(ctx, "Unexpected API value in shading_language_version()");
84      return (const GLubyte *) 0;
85   }
86}
87
88
89/**
90 * Query string-valued state.  The return value should _not_ be freed by
91 * the caller.
92 *
93 * \param name  the state variable to query.
94 *
95 * \sa glGetString().
96 *
97 * Tries to get the string from dd_function_table::GetString, otherwise returns
98 * the hardcoded strings.
99 */
100const GLubyte * GLAPIENTRY
101_mesa_GetString( GLenum name )
102{
103   GET_CURRENT_CONTEXT(ctx);
104   static const char *vendor = "Brian Paul";
105   static const char *renderer = "Mesa";
106
107   if (!ctx)
108      return NULL;
109
110   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
111
112   /* this is a required driver function */
113   assert(ctx->Driver.GetString);
114   {
115      /* Give the driver the chance to handle this query */
116      const GLubyte *str = (*ctx->Driver.GetString)(ctx, name);
117      if (str)
118         return str;
119   }
120
121   switch (name) {
122      case GL_VENDOR:
123         return (const GLubyte *) vendor;
124      case GL_RENDERER:
125         return (const GLubyte *) renderer;
126      case GL_VERSION:
127         return (const GLubyte *) ctx->VersionString;
128      case GL_EXTENSIONS:
129         if (ctx->API == API_OPENGL_CORE) {
130            _mesa_error(ctx, GL_INVALID_ENUM, "glGetString(GL_EXTENSIONS)");
131            return (const GLubyte *) 0;
132         }
133         return (const GLubyte *) ctx->Extensions.String;
134#if FEATURE_ARB_shading_language_100 || FEATURE_ES2
135      case GL_SHADING_LANGUAGE_VERSION:
136         if (ctx->API == API_OPENGLES)
137            break;
138	 return shading_language_version(ctx);
139#endif
140#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program || \
141    FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
142      case GL_PROGRAM_ERROR_STRING_NV:
143         if (ctx->API == API_OPENGL &&
144             (ctx->Extensions.NV_fragment_program ||
145              ctx->Extensions.ARB_fragment_program ||
146              ctx->Extensions.NV_vertex_program ||
147              ctx->Extensions.ARB_vertex_program)) {
148            return (const GLubyte *) ctx->Program.ErrorString;
149         }
150         break;
151#endif
152      default:
153         break;
154   }
155
156   _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" );
157   return (const GLubyte *) 0;
158}
159
160
161/**
162 * GL3
163 */
164const GLubyte * GLAPIENTRY
165_mesa_GetStringi(GLenum name, GLuint index)
166{
167   GET_CURRENT_CONTEXT(ctx);
168
169   if (!ctx)
170      return NULL;
171
172   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
173
174   switch (name) {
175   case GL_EXTENSIONS:
176      if (index >= _mesa_get_extension_count(ctx)) {
177         _mesa_error(ctx, GL_INVALID_VALUE, "glGetStringi(index=%u)", index);
178         return (const GLubyte *) 0;
179      }
180      return _mesa_get_enabled_extension(ctx, index);
181   default:
182      _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" );
183      return (const GLubyte *) 0;
184   }
185}
186
187
188
189/**
190 * Return pointer-valued state, such as a vertex array pointer.
191 *
192 * \param pname  names state to be queried
193 * \param params  returns the pointer value
194 *
195 * \sa glGetPointerv().
196 *
197 * Tries to get the specified pointer via dd_function_table::GetPointerv,
198 * otherwise gets the specified pointer from the current context.
199 */
200void GLAPIENTRY
201_mesa_GetPointerv( GLenum pname, GLvoid **params )
202{
203   GET_CURRENT_CONTEXT(ctx);
204   const GLuint clientUnit = ctx->Array.ActiveTexture;
205   ASSERT_OUTSIDE_BEGIN_END(ctx);
206
207   if (!params)
208      return;
209
210   if (MESA_VERBOSE & VERBOSE_API)
211      _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname));
212
213   switch (pname) {
214      case GL_VERTEX_ARRAY_POINTER:
215         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
216            goto invalid_pname;
217         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Ptr;
218         break;
219      case GL_NORMAL_ARRAY_POINTER:
220         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
221            goto invalid_pname;
222         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr;
223         break;
224      case GL_COLOR_ARRAY_POINTER:
225         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
226            goto invalid_pname;
227         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr;
228         break;
229      case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
230         if (ctx->API != API_OPENGL)
231            goto invalid_pname;
232         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr;
233         break;
234      case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
235         if (ctx->API != API_OPENGL)
236            goto invalid_pname;
237         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Ptr;
238         break;
239      case GL_INDEX_ARRAY_POINTER:
240         if (ctx->API != API_OPENGL)
241            goto invalid_pname;
242         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr;
243         break;
244      case GL_TEXTURE_COORD_ARRAY_POINTER:
245         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
246            goto invalid_pname;
247         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr;
248         break;
249      case GL_EDGE_FLAG_ARRAY_POINTER:
250         if (ctx->API != API_OPENGL)
251            goto invalid_pname;
252         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr;
253         break;
254      case GL_FEEDBACK_BUFFER_POINTER:
255         if (ctx->API != API_OPENGL)
256            goto invalid_pname;
257         *params = ctx->Feedback.Buffer;
258         break;
259      case GL_SELECTION_BUFFER_POINTER:
260         if (ctx->API != API_OPENGL)
261            goto invalid_pname;
262         *params = ctx->Select.Buffer;
263         break;
264#if FEATURE_point_size_array
265      case GL_POINT_SIZE_ARRAY_POINTER_OES:
266         if (ctx->API != API_OPENGLES)
267            goto invalid_pname;
268         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr;
269         break;
270#endif
271      case GL_DEBUG_CALLBACK_FUNCTION_ARB:
272         if (!_mesa_is_desktop_gl(ctx))
273            goto invalid_pname;
274         *params = (GLvoid *) ctx->Debug.Callback;
275         break;
276      case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
277         if (!_mesa_is_desktop_gl(ctx))
278            goto invalid_pname;
279         *params = ctx->Debug.CallbackData;
280         break;
281      default:
282         goto invalid_pname;
283   }
284
285   return;
286
287invalid_pname:
288   _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
289   return;
290}
291
292
293/**
294 * Returns the current GL error code, or GL_NO_ERROR.
295 * \return current error code
296 *
297 * Returns __struct gl_contextRec::ErrorValue.
298 */
299GLenum GLAPIENTRY
300_mesa_GetError( void )
301{
302   GET_CURRENT_CONTEXT(ctx);
303   GLenum e = ctx->ErrorValue;
304   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
305
306   if (MESA_VERBOSE & VERBOSE_API)
307      _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
308
309   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
310   ctx->ErrorDebugCount = 0;
311   return e;
312}
313
314/**
315 * Returns an error code specified by GL_ARB_robustness, or GL_NO_ERROR.
316 * \return current context status
317 */
318GLenum GLAPIENTRY
319_mesa_GetGraphicsResetStatusARB( void )
320{
321   GET_CURRENT_CONTEXT(ctx);
322   GLenum status = ctx->ResetStatus;
323
324   if (MESA_VERBOSE & VERBOSE_API)
325      _mesa_debug(ctx, "glGetGraphicsResetStatusARB"
326                       "(always returns GL_NO_ERROR)\n");
327
328   return status;
329}
330