1 /* $Id: imports.c,v 1.27 2002/12/06 03:10:59 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
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,
34 * Some drivers will want to override/replace this file with something
35 * specialized, but that'll be rare.
37 * Eventually, I want to move roll the glheader.h file into this.
39 * The OpenGL SI's __GLimports structure allows per-context specification of
40 * replacements for the standard C lib functions. In practice that's probably
41 * never needed; compile-time replacements are far more likely.
43 * The _mesa_foo() functions defined here don't in general take a context
44 * parameter. I guess we can change that someday, if need be.
45 * So for now, the __GLimports stuff really isn't used.
55 #define MAXSTRING 4000 /* for vsnprintf() */
58 #define vsnprintf _vsnprintf
59 #elif defined(__IBMC__) || defined(__IBMCPP__) || defined(VMS)
60 extern int vsnprintf(char *str
, size_t count
, const char *fmt
, va_list arg
);
64 /**********************************************************************/
65 /* Wrappers for standard C library functions */
66 /**********************************************************************/
69 * Functions still needed:
77 _mesa_malloc(size_t bytes
)
79 #if defined(XFree86LOADER) && defined(IN_MODULE)
80 return xf86malloc(bytes
);
88 _mesa_calloc(size_t bytes
)
90 #if defined(XFree86LOADER) && defined(IN_MODULE)
91 return xf86calloc(1, bytes
);
93 return calloc(1, bytes
);
101 #if defined(XFree86LOADER) && defined(IN_MODULE)
110 _mesa_align_malloc(size_t bytes
, unsigned long alignment
)
112 unsigned long ptr
, buf
;
114 ASSERT( alignment
> 0 );
116 /* Allocate extra memory to accomodate rounding up the address for
117 * alignment and to record the real malloc address.
119 ptr
= (unsigned long) _mesa_malloc(bytes
+ alignment
+ sizeof(void *));
123 buf
= (ptr
+ alignment
+ sizeof(void *)) & ~(unsigned long)(alignment
- 1);
124 *(unsigned long *)(buf
- sizeof(void *)) = ptr
;
127 /* mark the non-aligned area */
128 while ( ptr
< buf
- sizeof(void *) ) {
129 *(unsigned long *)ptr
= 0xcdcdcdcd;
130 ptr
+= sizeof(unsigned long);
139 _mesa_align_calloc(size_t bytes
, unsigned long alignment
)
141 unsigned long ptr
, buf
;
143 ASSERT( alignment
> 0 );
145 ptr
= (unsigned long) _mesa_calloc(bytes
+ alignment
+ sizeof(void *));
149 buf
= (ptr
+ alignment
+ sizeof(void *)) & ~(unsigned long)(alignment
- 1);
150 *(unsigned long *)(buf
- sizeof(void *)) = ptr
;
153 /* mark the non-aligned area */
154 while ( ptr
< buf
- sizeof(void *) ) {
155 *(unsigned long *)ptr
= 0xcdcdcdcd;
156 ptr
+= sizeof(unsigned long);
165 _mesa_align_free(void *ptr
)
168 _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr
- sizeof(void *))) );
170 /* The actuall address to free is stuffed in the word immediately
171 * before the address the client sees.
173 void **cubbyHole
= (void **) ((char *) ptr
- sizeof(void *));
174 void *realAddr
= *cubbyHole
;
175 _mesa_free(realAddr
);
181 _mesa_memcpy(void *dest
, const void *src
, size_t n
)
183 #if defined(XFree86LOADER) && defined(IN_MODULE)
184 return xf86memcpy(dest
, src
, n
);
185 #elif defined(SUNOS4)
186 return memcpy((char *) dest
, (char *) src
, (int) n
);
188 return memcpy(dest
, src
, n
);
194 _mesa_memset( void *dst
, int val
, size_t n
)
196 #if defined(XFree86LOADER) && defined(IN_MODULE)
197 xf86memset( dst
, val
, n
);
198 #elif defined(SUNOS4)
199 memset( (char *) dst
, (int) val
, (int) n
);
207 _mesa_memset16( unsigned short *dst
, unsigned short val
, size_t n
)
215 _mesa_bzero( void *dst
, size_t n
)
217 #if defined(XFree86LOADER) && defined(IN_MODULE)
218 xf86memset( dst
, 0, n
);
219 #elif defined(__FreeBSD__)
230 #if defined(XFree86LOADER) && defined(IN_MODULE)
241 #if defined(XFree86LOADER) && defined(IN_MODULE)
252 #if defined(XFree86LOADER) && defined(IN_MODULE)
261 _mesa_pow(double x
, double y
)
263 #if defined(XFree86LOADER) && defined(IN_MODULE)
264 return xf86pow(x
, y
);
272 _mesa_getenv( const char *var
)
274 #if defined(XFree86LOADER) && defined(IN_MODULE)
275 return xf86getenv(var
);
283 _mesa_strstr( const char *haystack
, const char *needle
)
285 #if defined(XFree86LOADER) && defined(IN_MODULE)
286 return xf86strstr(haystack
, needle
);
288 return strstr(haystack
, needle
);
294 _mesa_strncat( char *dest
, const char *src
, size_t n
)
296 #if defined(XFree86LOADER) && defined(IN_MODULE)
297 return xf86strncat(dest
, src
, n
);
299 return strncat(dest
, src
, n
);
305 _mesa_strcpy( char *dest
, const char *src
)
307 #if defined(XFree86LOADER) && defined(IN_MODULE)
308 return xf86strcpy(dest
, src
);
310 return strcpy(dest
, src
);
316 _mesa_strncpy( char *dest
, const char *src
, size_t n
)
318 #if defined(XFree86LOADER) && defined(IN_MODULE)
319 return xf86strncpy(dest
, src
, n
);
321 return strncpy(dest
, src
, n
);
327 _mesa_strlen( const char *s
)
329 #if defined(XFree86LOADER) && defined(IN_MODULE)
330 return xf86strlen(s
);
338 _mesa_strcmp( const char *s1
, const char *s2
)
340 #if defined(XFree86LOADER) && defined(IN_MODULE)
341 return xf86strcmp(s1
, s2
);
343 return strcmp(s1
, s2
);
349 _mesa_strncmp( const char *s1
, const char *s2
, size_t n
)
351 #if defined(XFree86LOADER) && defined(IN_MODULE)
352 return xf86strncmp(s1
, s2
, n
);
354 return strncmp(s1
, s2
, n
);
360 _mesa_atoi(const char *s
)
362 #if defined(XFree86LOADER) && defined(IN_MODULE)
371 _mesa_sprintf( char *str
, const char *fmt
, ... )
375 va_start( args
, fmt
);
377 #if defined(XFree86LOADER) && defined(IN_MODULE)
378 r
= xf86vsprintf( str
, fmt
, args
);
380 r
= vsprintf( str
, fmt
, args
);
387 _mesa_printf( const char *fmtString
, ... )
391 va_start( args
, fmtString
);
392 vsnprintf(s
, MAXSTRING
, fmtString
, args
);
394 #if defined(XFree86LOADER) && defined(IN_MODULE)
403 _mesa_warning( GLcontext
*ctx
, const char *fmtString
, ... )
409 va_start( args
, fmtString
);
410 (void) vsnprintf( str
, MAXSTRING
, fmtString
, args
);
413 debug
= GL_TRUE
; /* always print warning */
415 debug
= _mesa_getenv("MESA_DEBUG") ? GL_TRUE
: GL_FALSE
;
418 #if defined(XFree86LOADER) && defined(IN_MODULE)
419 xf86fprintf(stderr
, "Mesa warning: %s\n", str
);
421 fprintf(stderr
, "Mesa warning: %s\n", str
);
428 * This function is called when the Mesa user has stumbled into a code
429 * path which may not be implemented fully or correctly.
432 _mesa_problem( const GLcontext
*ctx
, const char *fmtString
, ... )
438 va_start( args
, fmtString
);
439 vsnprintf( str
, MAXSTRING
, fmtString
, args
);
442 #if defined(XFree86LOADER) && defined(IN_MODULE)
443 xf86fprintf(stderr
, "Mesa implementation error: %s\n", str
);
444 xf86fprintf(stderr
, "Please report to the DRI project at dri.sourceforge.net\n");
446 fprintf(stderr
, "Mesa implementation error: %s\n", str
);
447 fprintf(stderr
, "Please report to the Mesa bug database at www.mesa3d.org\n" );
453 * If in debug mode, print error message to stdout.
454 * Also, record the error code by calling _mesa_record_error().
455 * Input: ctx - the GL context
456 * error - the error value
457 * fmtString - printf-style format string, followed by optional args
460 _mesa_error( GLcontext
*ctx
, GLenum error
, const char *fmtString
, ... )
462 const char *debugEnv
;
465 debugEnv
= _mesa_getenv("MESA_DEBUG");
468 if (debugEnv
&& _mesa_strstr(debugEnv
, "silent"))
481 char where
[MAXSTRING
];
484 va_start( args
, fmtString
);
485 vsnprintf( where
, MAXSTRING
, fmtString
, args
);
490 errstr
= "GL_NO_ERROR";
492 case GL_INVALID_VALUE
:
493 errstr
= "GL_INVALID_VALUE";
495 case GL_INVALID_ENUM
:
496 errstr
= "GL_INVALID_ENUM";
498 case GL_INVALID_OPERATION
:
499 errstr
= "GL_INVALID_OPERATION";
501 case GL_STACK_OVERFLOW
:
502 errstr
= "GL_STACK_OVERFLOW";
504 case GL_STACK_UNDERFLOW
:
505 errstr
= "GL_STACK_UNDERFLOW";
507 case GL_OUT_OF_MEMORY
:
508 errstr
= "GL_OUT_OF_MEMORY";
510 case GL_TABLE_TOO_LARGE
:
511 errstr
= "GL_TABLE_TOO_LARGE";
517 _mesa_debug(ctx
, "Mesa user error: %s in %s\n", errstr
, where
);
520 _mesa_record_error(ctx
, error
);
525 * Call this to report debug information. Uses stderr.
528 _mesa_debug( const GLcontext
*ctx
, const char *fmtString
, ... )
532 va_start(args
, fmtString
);
533 vsnprintf(s
, MAXSTRING
, fmtString
, args
);
535 #if defined(XFree86LOADER) && defined(IN_MODULE)
536 xf86fprintf(stderr
, "Mesa: %s", s
);
538 fprintf(stderr
, "Mesa: %s", s
);
544 /**********************************************************************/
545 /* Default Imports Wrapper */
546 /**********************************************************************/
549 default_malloc(__GLcontext
*gc
, size_t size
)
552 return _mesa_malloc(size
);
556 default_calloc(__GLcontext
*gc
, size_t numElem
, size_t elemSize
)
559 return _mesa_calloc(numElem
* elemSize
);
563 default_realloc(__GLcontext
*gc
, void *oldAddr
, size_t newSize
)
566 #if defined(XFree86LOADER) && defined(IN_MODULE)
567 return xf86realloc(oldAddr
, newSize
);
569 return realloc(oldAddr
, newSize
);
574 default_free(__GLcontext
*gc
, void *addr
)
581 default_getenv( __GLcontext
*gc
, const char *var
)
584 return _mesa_getenv(var
);
588 default_warning(__GLcontext
*gc
, char *str
)
590 _mesa_warning(gc
, str
);
594 default_fatal(__GLcontext
*gc
, char *str
)
596 _mesa_problem(gc
, str
);
601 default_atoi(__GLcontext
*gc
, const char *str
)
608 default_sprintf(__GLcontext
*gc
, char *str
, const char *fmt
, ...)
612 va_start( args
, fmt
);
613 r
= vsprintf( str
, fmt
, args
);
619 default_fopen(__GLcontext
*gc
, const char *path
, const char *mode
)
621 return fopen(path
, mode
);
625 default_fclose(__GLcontext
*gc
, void *stream
)
627 return fclose((FILE *) stream
);
631 default_fprintf(__GLcontext
*gc
, void *stream
, const char *fmt
, ...)
635 va_start( args
, fmt
);
636 r
= vfprintf( (FILE *) stream
, fmt
, args
);
641 /* XXX this really is driver-specific and can't be here */
642 static __GLdrawablePrivate
*
643 default_GetDrawablePrivate(__GLcontext
*gc
)
652 * Initialize a __GLimports object to point to the functions in
653 * this file. This is to be called from device drivers.
654 * Input: imports - the object to init
655 * driverCtx - pointer to device driver-specific data
658 _mesa_init_default_imports(__GLimports
*imports
, void *driverCtx
)
660 imports
->malloc
= default_malloc
;
661 imports
->calloc
= default_calloc
;
662 imports
->realloc
= default_realloc
;
663 imports
->free
= default_free
;
664 imports
->warning
= default_warning
;
665 imports
->fatal
= default_fatal
;
666 imports
->getenv
= default_getenv
; /* not used for now */
667 imports
->atoi
= default_atoi
;
668 imports
->sprintf
= default_sprintf
;
669 imports
->fopen
= default_fopen
;
670 imports
->fclose
= default_fclose
;
671 imports
->fprintf
= default_fprintf
;
672 imports
->getDrawablePrivate
= default_GetDrawablePrivate
;
673 imports
->other
= driverCtx
;