imports.c revision c2656d588be17ba4bd453d2164b84f606be83dd2
1/* $Id: imports.c,v 1.17 2002/08/01 15:10:23 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  4.1
6 *
7 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Imports are services which the device driver or window system or
30 * operating system provides to the core renderer.  The core renderer (Mesa)
31 * will call these functions in order to do memory allocation, simple I/O,
32 * etc.
33 *
34 * Some drivers will want to override/replace this file with something
35 * specialized, but most Mesa drivers will be able to call
36 *_mesa_init_default_imports() and go with what's here.
37 *
38 * Eventually, I'd like to move most of the stuff in glheader.h and mem.[ch]
39 * into imports.[ch].  Then we'll really have one, single place where
40 * all OS-related dependencies are isolated.
41 */
42
43
44#include "glheader.h"
45#include "mtypes.h"
46#include "context.h"
47#include "imports.h"
48#include "mem.h"
49
50#define MAXSTRING 4000  /* for vsnprintf() */
51
52
53static void *
54_mesa_Malloc(__GLcontext *gc, size_t size)
55{
56   return MALLOC(size);
57}
58
59static void *
60_mesa_Calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
61{
62   return CALLOC(numElem * elemSize);
63}
64
65static void *
66_mesa_Realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
67{
68   return realloc(oldAddr, newSize);
69}
70
71static void
72_mesa_Free(__GLcontext *gc, void *addr)
73{
74   FREE(addr);
75}
76
77
78/* Must be before '#undef getenv' for inclusion in XFree86.
79 */
80static char * CAPI
81_mesa_getenv(__GLcontext *gc, const char *var)
82{
83   (void) gc;
84/* Whacko XFree86 macro:
85 */
86#ifdef getenv
87#undef getenv
88#endif
89   return getenv(var);
90}
91
92
93static void
94warning(__GLcontext *gc, char *str)
95{
96   GLboolean debug;
97#ifdef DEBUG
98   debug = GL_TRUE;
99#else
100   if (_mesa_getenv(gc , "MESA_DEBUG"))
101      debug = GL_TRUE;
102   else
103      debug = GL_FALSE;
104#endif
105   if (debug) {
106      fprintf(stderr, "Mesa warning: %s\n", str);
107   }
108}
109
110
111void
112_mesa_fatal(__GLcontext *gc, char *str)
113{
114   (void) gc;
115   fprintf(stderr, "%s\n", str);
116   abort();
117}
118
119
120static int CAPI
121_mesa_atoi(__GLcontext *gc, const char *str)
122{
123   (void) gc;
124   return atoi(str);
125}
126
127
128int CAPI
129_mesa_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
130{
131   int r;
132   va_list args;
133   va_start( args, fmt );
134   r = vsprintf( str, fmt, args );
135   va_end( args );
136   return r;
137}
138
139
140static void * CAPI
141_mesa_fopen(__GLcontext *gc, const char *path, const char *mode)
142{
143   return fopen(path, mode);
144}
145
146
147static int CAPI
148_mesa_fclose(__GLcontext *gc, void *stream)
149{
150   return fclose((FILE *) stream);
151}
152
153
154static int CAPI
155_mesa_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
156{
157   int r;
158   va_list args;
159   va_start( args, fmt );
160   r = vfprintf( (FILE *) stream, fmt, args );
161   va_end( args );
162   return r;
163}
164
165
166/* XXX this really is driver-specific and can't be here */
167static __GLdrawablePrivate *
168_mesa_GetDrawablePrivate(__GLcontext *gc)
169{
170   return NULL;
171}
172
173
174
175void
176_mesa_warning(__GLcontext *gc, const char *fmtString, ...)
177{
178   char str[MAXSTRING];
179   va_list args;
180   va_start( args, fmtString );
181   (void) vsnprintf( str, MAXSTRING, fmtString, args );
182   va_end( args );
183   warning(gc, str);
184}
185
186
187/*
188 * This function is called when the Mesa user has stumbled into a code
189 * path which may not be implemented fully or correctly.
190 */
191void
192_mesa_problem( const GLcontext *ctx, const char *s )
193{
194   if (ctx) {
195      ctx->imports.fprintf((GLcontext *) ctx, stderr, "Mesa implementation error: %s\n", s);
196#ifdef XF86DRI
197      ctx->imports.fprintf((GLcontext *) ctx, stderr, "Please report to the DRI bug database at dri.sourceforge.net\n");
198#else
199      ctx->imports.fprintf((GLcontext *) ctx, stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
200#endif
201   }
202   else {
203      /* what can we do if we don't have a context???? */
204      fprintf( stderr, "Mesa implementation error: %s\n", s );
205#ifdef XF86DRI
206      fprintf( stderr, "Please report to the DRI bug database at dri.sourceforge.net\n");
207#else
208      fprintf( stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
209#endif
210   }
211}
212
213
214/*
215 * If in debug mode, print error message to stdout.
216 * Also, record the error code by calling _mesa_record_error().
217 * Input:  ctx - the GL context
218 *         error - the error value
219 *         fmtString - printf-style format string, followed by optional args
220 */
221void
222_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
223{
224   const char *debugEnv;
225   GLboolean debug;
226
227   debugEnv = _mesa_getenv(ctx, "MESA_DEBUG");
228
229#ifdef DEBUG
230   if (debugEnv && strstr(debugEnv, "silent"))
231      debug = GL_FALSE;
232   else
233      debug = GL_TRUE;
234#else
235   if (debugEnv)
236      debug = GL_TRUE;
237   else
238      debug = GL_FALSE;
239#endif
240
241   if (debug) {
242      va_list args;
243      char where[MAXSTRING];
244      const char *errstr;
245
246      va_start( args, fmtString );
247      vsnprintf( where, MAXSTRING, fmtString, args );
248      va_end( args );
249
250      switch (error) {
251	 case GL_NO_ERROR:
252	    errstr = "GL_NO_ERROR";
253	    break;
254	 case GL_INVALID_VALUE:
255	    errstr = "GL_INVALID_VALUE";
256	    break;
257	 case GL_INVALID_ENUM:
258	    errstr = "GL_INVALID_ENUM";
259	    break;
260	 case GL_INVALID_OPERATION:
261	    errstr = "GL_INVALID_OPERATION";
262	    break;
263	 case GL_STACK_OVERFLOW:
264	    errstr = "GL_STACK_OVERFLOW";
265	    break;
266	 case GL_STACK_UNDERFLOW:
267	    errstr = "GL_STACK_UNDERFLOW";
268	    break;
269	 case GL_OUT_OF_MEMORY:
270	    errstr = "GL_OUT_OF_MEMORY";
271	    break;
272         case GL_TABLE_TOO_LARGE:
273            errstr = "GL_TABLE_TOO_LARGE";
274            break;
275	 default:
276	    errstr = "unknown";
277	    break;
278      }
279      _mesa_debug(ctx, "Mesa user error: %s in %s\n", errstr, where);
280   }
281
282   _mesa_record_error(ctx, error);
283}
284
285
286/*
287 * Call this to report debug information.  Uses stderr.
288 */
289void
290_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
291{
292   char s[MAXSTRING];
293   va_list args;
294   va_start(args, fmtString);
295   vsnprintf(s, MAXSTRING, fmtString, args);
296   if (ctx)
297      (void) ctx->imports.fprintf( (__GLcontext *) ctx, stderr, s );
298   else
299      fprintf( stderr, s );
300   va_end(args);
301}
302
303
304/*
305 * A wrapper for printf.  Uses stdout.
306 */
307void
308_mesa_printf( const GLcontext *ctx, const char *fmtString, ... )
309{
310   char s[MAXSTRING];
311   va_list args;
312   va_start( args, fmtString );
313   vsnprintf(s, MAXSTRING, fmtString, args);
314   if (ctx)
315      (void) ctx->imports.fprintf( (__GLcontext *) ctx, stdout, s );
316   else
317      printf( s );
318   va_end( args );
319}
320
321
322/*
323 * Initialize a __GLimports object to point to the functions in
324 * this file.  This is to be called from device drivers.
325 * Input:  imports - the object to init
326 *         driverCtx - pointer to device driver-specific data
327 */
328void
329_mesa_init_default_imports(__GLimports *imports, void *driverCtx)
330{
331   imports->malloc = _mesa_Malloc;
332   imports->calloc = _mesa_Calloc;
333   imports->realloc = _mesa_Realloc;
334   imports->free = _mesa_Free;
335   imports->warning = warning;
336   imports->fatal = _mesa_fatal;
337   imports->getenv = _mesa_getenv;
338   imports->atoi = _mesa_atoi;
339   imports->sprintf = _mesa_sprintf;
340   imports->fopen = _mesa_fopen;
341   imports->fclose = _mesa_fclose;
342   imports->fprintf = _mesa_fprintf;
343   imports->getDrawablePrivate = _mesa_GetDrawablePrivate;
344   imports->other = driverCtx;
345}
346