mesa: change ctx->Driver.ProgramStringNotify() to return GLboolean

GL_TRUE indicates that the driver accepts the program.
GL_FALSE indicates the program can't be compiled/translated by the
driver for some reason (too many resources used, etc).

Propogate this result up to the GL API: set GL_INVALID_OPERATION
error if glProgramString() was called.  Set shader program link
status to GL_FALSE if glLinkProgram() was called.

At this point, drivers still don't do any program checking and
always return GL_TRUE.
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
index 7461380..7e3040a 100644
--- a/src/mesa/shader/arbprogram.c
+++ b/src/mesa/shader/arbprogram.c
@@ -489,8 +489,13 @@
       return;
    }
 
-   if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
-      ctx->Driver.ProgramStringNotify( ctx, target, base );
+   if (ctx->Program.ErrorPos == -1) {
+      /* finally, give the program to the driver for translation/checking */
+      if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glProgramStringARB(rejected by driver");
+      }
+   }
 }
 
 
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index e04a05b..ab7b203 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -378,8 +378,11 @@
    }
    if (ctx->ATIFragmentShader.Current->cur_pass > 1)
       ctx->ATIFragmentShader.Current->NumPasses = 2;
-   else ctx->ATIFragmentShader.Current->NumPasses = 1;
-   ctx->ATIFragmentShader.Current->cur_pass=0;
+   else
+      ctx->ATIFragmentShader.Current->NumPasses = 1;
+
+   ctx->ATIFragmentShader.Current->cur_pass = 0;
+
 #if MESA_DEBUG_ATI_FS
    for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
       for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
@@ -402,8 +405,13 @@
       }
    }
 #endif
-   if (ctx->Driver.ProgramStringNotify)
-      ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL );
+
+   if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) {
+      ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
+      /* XXX is this the right error? */
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glEndFragmentShaderATI(driver rejected shader)");
+   }
 }
 
 void GLAPIENTRY
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index d53580f..e8eaa9c 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -1715,7 +1715,11 @@
           */
          FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
          _mesa_update_shader_textures_used(program);
-         ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+         /* Do we need to care about the return value here?
+          * This should not be the first time the driver was notified of
+          * this program.
+          */
+         (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
       }
    }
    else {
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 21497b3..df524ce 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -719,6 +719,7 @@
 {
    const struct gl_vertex_program *vertProg = NULL;
    const struct gl_fragment_program *fragProg = NULL;
+   GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
    GLuint numSamplers = 0;
    GLuint i;
 
@@ -871,8 +872,8 @@
       _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
 
       /* notify driver that a new fragment program has been compiled/linked */
-      ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                                      &shProg->FragmentProgram->Base);
+      vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+                                                 &shProg->FragmentProgram->Base);
       if (ctx->Shader.Flags & GLSL_DUMP) {
          _mesa_printf("Mesa pre-link fragment program:\n");
          _mesa_print_program(&fragProg->Base);
@@ -889,8 +890,8 @@
       _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
 
       /* notify driver that a new vertex program has been compiled/linked */
-      ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
-                                      &shProg->VertexProgram->Base);
+      fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+                                                   &shProg->VertexProgram->Base);
       if (ctx->Shader.Flags & GLSL_DUMP) {
          _mesa_printf("Mesa pre-link vertex program:\n");
          _mesa_print_program(&vertProg->Base);
@@ -918,6 +919,12 @@
       }
    }
 
-   shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+   if (!vertNotify || !fragNotify) {
+      /* driver rejected one/both of the vertex/fragment programs */
+      link_error(shProg, "Vertex and/or fragment program rejected by driver\n");
+   }
+   else {
+      shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+   }
 }