/* * Mesa 3-D graphics library * Version: 3.1 * Copyright (C) 1995-1998 Brian Paul * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * This header file is based on the REAL glut.h by Mark J. Kilgard. * * The DJGPP/ALLEGRO (DJA) GLUT implementation was written by * Bernhard Tschirren (bernie-t@geocities.com) for the sole purpose * of compiling all the sample programs (which use GLUT). Therefore, * is NOT AT ALL a complete version of GLUT! */ #ifndef __AGLUT_H__ #define __AGLUT_H__ #include #include #define GLUTCALLBACK #define APIENTRY #define GLUTAPI extern #define GLUT_RGB 0 #define GLUT_RGBA GLUT_RGB #define GLUT_INDEX 1 #define GLUT_SINGLE 0 #define GLUT_DOUBLE 2 #define GLUT_ACCUM 4 #define GLUT_ALPHA 8 #define GLUT_DEPTH 16 #define GLUT_STENCIL 32 /* Mouse buttons. */ #define GLUT_LEFT_BUTTON 0 #define GLUT_MIDDLE_BUTTON 1 #define GLUT_RIGHT_BUTTON 2 /* Mouse button state. */ #define GLUT_DOWN 0 #define GLUT_UP 1 /* function keys */ #define GLUT_KEY_F1 1 #define GLUT_KEY_F2 2 #define GLUT_KEY_F3 3 #define GLUT_KEY_F4 4 #define GLUT_KEY_F5 5 #define GLUT_KEY_F6 6 #define GLUT_KEY_F7 7 #define GLUT_KEY_F8 8 #define GLUT_KEY_F9 9 #define GLUT_KEY_F10 10 #define GLUT_KEY_F11 11 #define GLUT_KEY_F12 12 /* directional keys */ #define GLUT_KEY_LEFT 100 #define GLUT_KEY_UP 101 #define GLUT_KEY_RIGHT 102 #define GLUT_KEY_DOWN 103 #define GLUT_KEY_PAGE_UP 104 #define GLUT_KEY_PAGE_DOWN 105 #define GLUT_KEY_HOME 106 #define GLUT_KEY_END 107 #define GLUT_KEY_INSERT 108 /* Entry/exit state. */ #define GLUT_LEFT 0 #define GLUT_ENTERED 1 /* Visibility state. */ #define GLUT_NOT_VISIBLE 0 #define GLUT_VISIBLE 1 /* Color index component selection values. */ #define GLUT_RED 0 #define GLUT_GREEN 1 #define GLUT_BLUE 2 /* Layers for use. */ #define GLUT_NORMAL 0 #define GLUT_OVERLAY 1 /* Stroke font constants (use these in GLUT program). */ #define GLUT_STROKE_ROMAN ((void*)0) #define GLUT_STROKE_MONO_ROMAN ((void*)1) /* Bitmap font constants (use these in GLUT program). */ #define GLUT_BITMAP_9_BY_15 ((void*)2) #define GLUT_BITMAP_8_BY_13 ((void*)3) #define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) #define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) #define GLUT_BITMAP_HELVETICA_10 ((void*)6) #define GLUT_BITMAP_HELVETICA_12 ((void*)7) #define GLUT_BITMAP_HELVETICA_18 ((void*)8) /* glutGet parameters. */ #define GLUT_WINDOW_X 100 #define GLUT_WINDOW_Y 101 #define GLUT_WINDOW_WIDTH 102 #define GLUT_WINDOW_HEIGHT 103 #define GLUT_WINDOW_BUFFER_SIZE 104 #define GLUT_WINDOW_STENCIL_SIZE 105 #define GLUT_WINDOW_DEPTH_SIZE 106 #define GLUT_WINDOW_RED_SIZE 107 #define GLUT_WINDOW_GREEN_SIZE 108 #define GLUT_WINDOW_BLUE_SIZE 109 #define GLUT_WINDOW_ALPHA_SIZE 110 #define GLUT_WINDOW_ACCUM_RED_SIZE 111 #define GLUT_WINDOW_ACCUM_GREEN_SIZE 112 #define GLUT_WINDOW_ACCUM_BLUE_SIZE 113 #define GLUT_WINDOW_ACCUM_ALPHA_SIZE 114 #define GLUT_WINDOW_DOUBLEBUFFER 115 #define GLUT_WINDOW_RGBA 116 #define GLUT_WINDOW_PARENT 117 #define GLUT_WINDOW_NUM_CHILDREN 118 #define GLUT_WINDOW_COLORMAP_SIZE 119 #define GLUT_WINDOW_NUM_SAMPLES 120 #define GLUT_WINDOW_STEREO 121 #define GLUT_WINDOW_CURSOR 122 #define GLUT_SCREEN_WIDTH 200 #define GLUT_SCREEN_HEIGHT 201 #define GLUT_SCREEN_WIDTH_MM 202 #define GLUT_SCREEN_HEIGHT_MM 203 #define GLUT_MENU_NUM_ITEMS 300 #define GLUT_DISPLAY_MODE_POSSIBLE 400 #define GLUT_INIT_WINDOW_X 500 #define GLUT_INIT_WINDOW_Y 501 #define GLUT_INIT_WINDOW_WIDTH 502 #define GLUT_INIT_WINDOW_HEIGHT 503 #define GLUT_INIT_DISPLAY_MODE 504 #define GLUT_ELAPSED_TIME 700 #define GLUT_WINDOW_FORMAT_ID 123 /* glutDeviceGet parameters. */ #define GLUT_HAS_KEYBOARD 600 #define GLUT_HAS_MOUSE 601 #define GLUT_HAS_SPACEBALL 602 #define GLUT_HAS_DIAL_AND_BUTTON_BOX 603 #define GLUT_HAS_TABLET 604 #define GLUT_NUM_MOUSE_BUTTONS 605 #define GLUT_NUM_SPACEBALL_BUTTONS 606 #define GLUT_NUM_BUTTON_BOX_BUTTONS 607 #define GLUT_NUM_DIALS 608 #define GLUT_NUM_TABLET_BUTTONS 609 #define GLUT_DEVICE_IGNORE_KEY_REPEAT 610 #define GLUT_DEVICE_KEY_REPEAT 611 #define GLUT_HAS_JOYSTICK 612 #define GLUT_OWNS_JOYSTICK 613 #define GLUT_JOYSTICK_BUTTONS 614 #define GLUT_JOYSTICK_AXES 615 #define GLUT_JOYSTICK_POLL_RATE 616 /* glutLayerGet parameters. */ #define GLUT_OVERLAY_POSSIBLE 800 #define GLUT_LAYER_IN_USE 801 #define GLUT_HAS_OVERLAY 802 #define GLUT_TRANSPARENT_INDEX 803 #define GLUT_NORMAL_DAMAGED 804 #define GLUT_OVERLAY_DAMAGED 805 /* glutVideoResizeGet parameters. */ #define GLUT_VIDEO_RESIZE_POSSIBLE 900 #define GLUT_VIDEO_RESIZE_IN_USE 901 #define GLUT_VIDEO_RESIZE_X_DELTA 902 #define GLUT_VIDEO_RESIZE_Y_DELTA 903 #define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904 #define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905 #define GLUT_VIDEO_RESIZE_X 906 #define GLUT_VIDEO_RESIZE_Y 907 #define GLUT_VIDEO_RESIZE_WIDTH 908 #define GLUT_VIDEO_RESIZE_HEIGHT 909 /* glutUseLayer parameters. */ #define GLUT_NORMAL 0 #define GLUT_OVERLAY 1 /* glutGetModifiers return mask. */ #define GLUT_ACTIVE_SHIFT 1 #define GLUT_ACTIVE_CTRL 2 #define GLUT_ACTIVE_ALT 4 /* glutSetCursor parameters. */ /* Basic arrows. */ #define GLUT_CURSOR_RIGHT_ARROW 0 #define GLUT_CURSOR_LEFT_ARROW 1 /* Symbolic cursor shapes. */ #define GLUT_CURSOR_INFO 2 #define GLUT_CURSOR_DESTROY 3 #define GLUT_CURSOR_HELP 4 #define GLUT_CURSOR_CYCLE 5 #define GLUT_CURSOR_SPRAY 6 #define GLUT_CURSOR_WAIT 7 #define GLUT_CURSOR_TEXT 8 #define GLUT_CURSOR_CROSSHAIR 9 /* Directional cursors. */ #define GLUT_CURSOR_UP_DOWN 10 #define GLUT_CURSOR_LEFT_RIGHT 11 /* Sizing cursors. */ #define GLUT_CURSOR_TOP_SIDE 12 #define GLUT_CURSOR_BOTTOM_SIDE 13 #define GLUT_CURSOR_LEFT_SIDE 14 #define GLUT_CURSOR_RIGHT_SIDE 15 #define GLUT_CURSOR_TOP_LEFT_CORNER 16 #define GLUT_CURSOR_TOP_RIGHT_CORNER 17 #define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 #define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 /* Inherit from parent window. */ #define GLUT_CURSOR_INHERIT 100 /* Blank cursor. */ #define GLUT_CURSOR_NONE 101 /* Fullscreen crosshair (if available). */ #define GLUT_CURSOR_FULL_CROSSHAIR 102 /* GLUT initialization sub-API. */ GLUTAPI void APIENTRY glutInit(int *argcp, char **argv); GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y); GLUTAPI void APIENTRY glutInitWindowSize(int width, int height); GLUTAPI void APIENTRY glutMainLoop(void); /* GLUT window sub-API. */ GLUTAPI int APIENTRY glutCreateWindow(const char *title); GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); GLUTAPI void APIENTRY glutDestroyWindow(int win); GLUTAPI void APIENTRY glutPostRedisplay(void); GLUTAPI void APIENTRY glutSwapBuffers(void); GLUTAPI int APIENTRY glutGetWindow(void); GLUTAPI void APIENTRY glutSetWindow(int win); GLUTAPI void APIENTRY glutSetWindowTitle(const char *title); GLUTAPI void APIENTRY glutSetIconTitle(const char *title); GLUTAPI void APIENTRY glutPositionWindow(int x, int y); GLUTAPI void APIENTRY glutReshapeWindow(int width, int height); GLUTAPI void APIENTRY glutPopWindow(void); GLUTAPI void APIENTRY glutPushWindow(void); GLUTAPI void APIENTRY glutIconifyWindow(void); GLUTAPI void APIENTRY glutShowWindow(void); GLUTAPI void APIENTRY glutHideWindow(void); /* GLUT overlay sub-API. */ GLUTAPI void APIENTRY glutEstablishOverlay(void); GLUTAPI void APIENTRY glutRemoveOverlay(void); GLUTAPI void APIENTRY glutUseLayer(GLenum layer); GLUTAPI void APIENTRY glutPostOverlayRedisplay(void); GLUTAPI void APIENTRY glutShowOverlay(void); GLUTAPI void APIENTRY glutHideOverlay(void); /* GLUT menu sub-API. */ GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *)(int)); GLUTAPI void APIENTRY glutDestroyMenu(int menu); GLUTAPI int APIENTRY glutGetMenu(void); GLUTAPI void APIENTRY glutSetMenu(int menu); GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value); GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu); GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); GLUTAPI void APIENTRY glutRemoveMenuItem(int item); GLUTAPI void APIENTRY glutAttachMenu(int button); GLUTAPI void APIENTRY glutDetachMenu(int button); /* GLUT window callback sub-API. */ GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK * func)(void)); GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK * func)(int width, int height)); GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK * func)(unsigned char key, int x, int y)); GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK * func)(int button, int state, int x, int y)); GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK * func)(int x, int y)); GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK * func)(int x, int y)); GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK * func)(int state)); GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK * func)(int state)); GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK * func)(void)); GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK * func)(int value), int value); GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK * func)(int state)); GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK * func)(int key, int x, int y)); GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK * func)(int x, int y, int z)); GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK * func)(int x, int y, int z)); GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK * func)(int button, int state)); GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK * func)(int button, int state)); GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK * func)(int dial, int value)); GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK * func)(int x, int y)); GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK * func)(int button, int state, int x, int y)); GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK * func)(int status, int x, int y)); GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK * func)(void)); GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK * func)(int state)); /* GLUT color index sub-API. */ GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component); GLUTAPI void APIENTRY glutCopyColormap(int win); /* GLUT state retrieval sub-API. */ GLUTAPI int APIENTRY glutGet(GLenum type); GLUTAPI int APIENTRY glutDeviceGet(GLenum type); /* GLUT font sub-API */ GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character); GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character); GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character); GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character); /* GLUT pre-built models sub-API */ GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); GLUTAPI void APIENTRY glutWireCube(GLdouble size); GLUTAPI void APIENTRY glutSolidCube(GLdouble size); GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); GLUTAPI void APIENTRY glutWireDodecahedron(void); GLUTAPI void APIENTRY glutSolidDodecahedron(void); GLUTAPI void APIENTRY glutWireTeapot(GLdouble size); GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size); GLUTAPI void APIENTRY glutWireOctahedron(void); GLUTAPI void APIENTRY glutSolidOctahedron(void); GLUTAPI void APIENTRY glutWireTetrahedron(void); GLUTAPI void APIENTRY glutSolidTetrahedron(void); GLUTAPI void APIENTRY glutWireIcosahedron(void); GLUTAPI void APIENTRY glutSolidIcosahedron(void); #endif /* __AGLUT_H__ */ ='n319' href='#n319'>319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
/*
 * Mesa 3-D graphics library
 * Version:  7.3
 *
 * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


#include "glheader.h"
#include "context.h"
#include "shaders.h"
#include "shader/shader_api.h"


/** Define this to enable shader substitution (see below) */
#define SHADER_SUBST 0



/**
 * These are basically just wrappers/adaptors for calling the
 * ctx->Driver.foobar() GLSL-related functions.
 *
 * Things are biased toward the OpenGL 2.0 functions rather than the
 * ARB extensions (i.e. the ARB functions are layered on the 2.0 functions).
 *
 * The general idea here is to allow enough modularity such that a
 * completely different GLSL implemenation can be plugged in and co-exist
 * with Mesa's native GLSL code.
 */



void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.AttachShader(ctx, program, shader);
}


void GLAPIENTRY
_mesa_AttachShader(GLuint program, GLuint shader)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.AttachShader(ctx, program, shader);
}


void GLAPIENTRY
_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
                            const GLcharARB *name)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.BindAttribLocation(ctx, program, index, name);
}


void GLAPIENTRY
_mesa_CompileShaderARB(GLhandleARB shaderObj)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.CompileShader(ctx, shaderObj);
}


GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.CreateShader(ctx, type);
}


GLhandleARB GLAPIENTRY
_mesa_CreateShaderObjectARB(GLenum type)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.CreateShader(ctx, type);
}


GLuint GLAPIENTRY
_mesa_CreateProgram(void)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.CreateProgram(ctx);
}


GLhandleARB GLAPIENTRY
_mesa_CreateProgramObjectARB(void)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.CreateProgram(ctx);
}


void GLAPIENTRY
_mesa_DeleteObjectARB(GLhandleARB obj)
{
   if (obj) {
      GET_CURRENT_CONTEXT(ctx);
      if (ctx->Driver.IsProgram(ctx, obj)) {
         ctx->Driver.DeleteProgram2(ctx, obj);
      }
      else if (ctx->Driver.IsShader(ctx, obj)) {
         ctx->Driver.DeleteShader(ctx, obj);
      }
      else {
         /* error? */
      }
   }
}


void GLAPIENTRY
_mesa_DeleteProgram(GLuint name)
{
   if (name) {
      GET_CURRENT_CONTEXT(ctx);
      ctx->Driver.DeleteProgram2(ctx, name);
   }
}


void GLAPIENTRY
_mesa_DeleteShader(GLuint name)
{
   if (name) {
      GET_CURRENT_CONTEXT(ctx);
      ctx->Driver.DeleteShader(ctx, name);
   }
}


void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.DetachShader(ctx, program, shader);
}


void GLAPIENTRY
_mesa_DetachShader(GLuint program, GLuint shader)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.DetachShader(ctx, program, shader);
}


void GLAPIENTRY
_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
                         GLsizei maxLength, GLsizei * length, GLint * size,
                         GLenum * type, GLcharARB * name)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetActiveAttrib(ctx, program, index, maxLength, length, size,
                               type, name);
}


void GLAPIENTRY
_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
                          GLsizei maxLength, GLsizei * length, GLint * size,
                          GLenum * type, GLcharARB * name)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetActiveUniform(ctx, program, index, maxLength, length, size,
                                type, name);
}


void GLAPIENTRY
_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
                            GLsizei * count, GLhandleARB * obj)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetAttachedShaders(ctx, container, maxCount, count, obj);
}


void GLAPIENTRY
_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
                         GLsizei *count, GLuint *obj)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetAttachedShaders(ctx, program, maxCount, count, obj);
}


GLint GLAPIENTRY
_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.GetAttribLocation(ctx, program, name);
}


void GLAPIENTRY
_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
                    GLcharARB * infoLog)
{
   GET_CURRENT_CONTEXT(ctx);
   /* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */
   if (ctx->Driver.IsProgram(ctx, object)) {
      ctx->Driver.GetProgramInfoLog(ctx, object, maxLength, length, infoLog);
   }
   else if (ctx->Driver.IsShader(ctx, object)) {
      ctx->Driver.GetShaderInfoLog(ctx, object, maxLength, length, infoLog);
   }
   else {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
   }
}


void GLAPIENTRY
_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);
   /* Implement in terms of GetProgramiv, GetShaderiv */
   if (ctx->Driver.IsProgram(ctx, object)) {
      if (pname == GL_OBJECT_TYPE_ARB) {
	 *params = GL_PROGRAM_OBJECT_ARB;
      }
      else {
	 ctx->Driver.GetProgramiv(ctx, object, pname, params);
      }
   }
   else if (ctx->Driver.IsShader(ctx, object)) {
      if (pname == GL_OBJECT_TYPE_ARB) {
	 *params = GL_SHADER_OBJECT_ARB;
      }
      else {
	 ctx->Driver.GetShaderiv(ctx, object, pname, params);
      }
   }
   else {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
   }
}


void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
                              GLfloat *params)
{
   GLint iparams[1];  /* XXX is one element enough? */
   _mesa_GetObjectParameterivARB(object, pname, iparams);
   params[0] = (GLfloat) iparams[0];
}


void GLAPIENTRY
_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetProgramiv(ctx, program, pname, params);
}


void GLAPIENTRY
_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetShaderiv(ctx, shader, pname, params);
}


void GLAPIENTRY
_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
                        GLsizei *length, GLchar *infoLog)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetProgramInfoLog(ctx, program, bufSize, length, infoLog);
}


void GLAPIENTRY
_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
                       GLsizei *length, GLchar *infoLog)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetShaderInfoLog(ctx, shader, bufSize, length, infoLog);
}


void GLAPIENTRY
_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
                         GLsizei *length, GLcharARB *sourceOut)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetShaderSource(ctx, shader, maxLength, length, sourceOut);
}


void GLAPIENTRY
_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetUniformfv(ctx, program, location, params);
}


void GLAPIENTRY
_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.GetUniformiv(ctx, program, location, params);
}



#if 0
GLint GLAPIENTRY
_mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.GetUniformLocation(ctx, program, name);
}
#endif


GLhandleARB GLAPIENTRY
_mesa_GetHandleARB(GLenum pname)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.GetHandle(ctx, pname);
}


GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.GetUniformLocation(ctx, programObj, name);
}


GLboolean GLAPIENTRY
_mesa_IsProgram(GLuint name)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.IsProgram(ctx, name);
}


GLboolean GLAPIENTRY
_mesa_IsShader(GLuint name)
{
   GET_CURRENT_CONTEXT(ctx);
   return ctx->Driver.IsShader(ctx, name);
}


void GLAPIENTRY
_mesa_LinkProgramARB(GLhandleARB programObj)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.LinkProgram(ctx, programObj);
}



/**
 * Read shader source code from a file.
 * Useful for debugging to override an app's shader.
 */
static GLcharARB *
_mesa_read_shader(const char *fname)
{
   const int max = 50*1000;
   FILE *f = fopen(fname, "r");
   GLcharARB *buffer, *shader;
   int len;

   if (!f) {
      return NULL;
   }

   buffer = (char *) malloc(max);
   len = fread(buffer, 1, max, f);
   buffer[len] = 0;

   fclose(f);

   shader = _mesa_strdup(buffer);
   free(buffer);

   return shader;
}


/**
 * Called via glShaderSource() and glShaderSourceARB() API functions.
 * Basically, concatenate the source code strings into one long string
 * and pass it to ctx->Driver.ShaderSource().
 */
void GLAPIENTRY
_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
                      const GLcharARB ** string, const GLint * length)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint *offsets;
   GLsizei i, totalLength;
   GLcharARB *source;
   GLuint checksum;

   if (!shaderObj || string == NULL) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
      return;
   }

   /*
    * This array holds offsets of where the appropriate string ends, thus the
    * last element will be set to the total length of the source code.
    */
   offsets = (GLint *) malloc(count * sizeof(GLint));
   if (offsets == NULL) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
      return;
   }

   for (i = 0; i < count; i++) {
      if (string[i] == NULL) {
         free((GLvoid *) offsets);
         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
         return;
      }
      if (length == NULL || length[i] < 0)
         offsets[i] = strlen(string[i]);
      else
         offsets[i] = length[i];
      /* accumulate string lengths */
      if (i > 0)
         offsets[i] += offsets[i - 1];
   }

   /* Total length of source string is sum off all strings plus two.
    * One extra byte for terminating zero, another extra byte to silence
    * valgrind warnings in the parser/grammer code.
    */
   totalLength = offsets[count - 1] + 2;
   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
   if (source == NULL) {
      free((GLvoid *) offsets);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
      return;
   }

   for (i = 0; i < count; i++) {
      GLint start = (i > 0) ? offsets[i - 1] : 0;
      memcpy(source + start, string[i],
             (offsets[i] - start) * sizeof(GLcharARB));
   }
   source[totalLength - 1] = '\0';
   source[totalLength - 2] = '\0';

   if (SHADER_SUBST) {
      /* Compute the shader's source code checksum then try to open a file
       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
       * original shader source code.  For debugging.
       */
      char filename[100];
      GLcharARB *newSource;

      checksum = _mesa_str_checksum(source);

      sprintf(filename, "newshader_%d", checksum);

      newSource = _mesa_read_shader(filename);
      if (newSource) {
         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
                       shaderObj, checksum, filename);
         free(source);
         source = newSource;
      }
   }      

   ctx->Driver.ShaderSource(ctx, shaderObj, source);

   if (SHADER_SUBST) {
      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
      if (sh)
         sh->SourceChecksum = checksum; /* save original checksum */
   }

   free(offsets);
}


void GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
}

void GLAPIENTRY
_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
{
   GET_CURRENT_CONTEXT(ctx);
   GLfloat v[2];
   v[0] = v0;
   v[1] = v1;
   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
}

void GLAPIENTRY
_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
   GET_CURRENT_CONTEXT(ctx);
   GLfloat v[3];
   v[0] = v0;
   v[1] = v1;
   v[2] = v2;
   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
}

void GLAPIENTRY
_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
                   GLfloat v3)
{
   GET_CURRENT_CONTEXT(ctx);
   GLfloat v[4];
   v[0] = v0;
   v[1] = v1;
   v[2] = v2;
   v[3] = v3;
   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
}

void GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
}

void GLAPIENTRY
_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint v[2];
   v[0] = v0;
   v[1] = v1;
   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
}

void GLAPIENTRY
_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint v[3];
   v[0] = v0;
   v[1] = v1;
   v[2] = v2;
   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
}

void GLAPIENTRY
_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint v[4];
   v[0] = v0;
   v[1] = v1;
   v[2] = v2;
   v[3] = v3;
   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
}

void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
}

void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
}

void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
}

void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
}

void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
}

void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
}

void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
}

void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC4);
}


void GLAPIENTRY
_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat * value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 4, 4, location, count, transpose, value);
}


/**
 * Non-square UniformMatrix are OpenGL 2.1
 */
void GLAPIENTRY
_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
                         const GLfloat *value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
                         const GLfloat *value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
                         const GLfloat *value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
                         const GLfloat *value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
                         const GLfloat *value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
}

void GLAPIENTRY
_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
                         const GLfloat *value)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.UniformMatrix(ctx, 4, 3, location, count, transpose, value);
}


void GLAPIENTRY
_mesa_UseProgramObjectARB(GLhandleARB program)
{
   GET_CURRENT_CONTEXT(ctx);
   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
   ctx->Driver.UseProgram(ctx, program);
}


void GLAPIENTRY
_mesa_ValidateProgramARB(GLhandleARB program)
{
   GET_CURRENT_CONTEXT(ctx);
   ctx->Driver.ValidateProgram(ctx, program);
}