No longer derive 'ati_fragment_shader' from 'program' class.  Only the
program->Id and program->RefCount fields were used and ATI fragment shaders
didn't have too much in common with ARB/NV vertex/fragment programs anyway.
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index a554994..f10b40a 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -61,9 +61,12 @@
 			fp=CALLOC_STRUCT(fragment_program);
 			return _mesa_init_fragment_program(ctx, fp, target, id);
 #endif
+#if 00
+                /* _mesa_new_ati_fragment_shader() is now called instead */
 		case GL_FRAGMENT_SHADER_ATI:
 			afs=CALLOC_STRUCT(ati_fragment_shader);
 			return _mesa_init_ati_fragment_shader(ctx, afs, target, id);
+#endif
 		default:
 			_mesa_problem(ctx, "Bad target in r300NewProgram");
 	}
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index b25300a..8fd9af7 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -100,6 +100,7 @@
 #include "histogram.h"
 #include "hint.h"
 #include "hash.h"
+#include "atifragshader.h"
 #include "light.h"
 #include "lines.h"
 #include "macros.h"
@@ -692,7 +693,8 @@
       goto cleanup;
 #endif
 #if FEATURE_ATI_fragment_shader
-   ss->DefaultFragmentShader = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, 0);
+   ss->ATIShaders = _mesa_NewHashTable();
+   ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
    if (!ss->DefaultFragmentShader)
       goto cleanup;
 #endif
@@ -760,7 +762,7 @@
 #endif
 #if FEATURE_ATI_fragment_shader
    if (ss->DefaultFragmentShader)
-      ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentShader);
+      _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
 #endif
 #if FEATURE_ARB_vertex_buffer_object
    if (ss->BufferObjects)
@@ -867,7 +869,7 @@
    _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
 #endif
 #if FEATURE_ATI_fragment_shader
-   _mesa_delete_program(ctx, ss->DefaultFragmentShader);
+   _mesa_free(ss->DefaultFragmentShader);
 #endif
 
 #if FEATURE_ARB_vertex_buffer_object
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index ec21bdc..4841e6a 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1699,7 +1699,7 @@
 
 
 /**
- * NV_fragment_program runtime state
+ * State used during execution of fragment programs.
  */
 struct fp_machine
 {
@@ -1709,21 +1709,6 @@
    GLuint CondCodes[4];
 };
 
-/**
- * ATI_fragment_shader runtime state
- */
-#define ATI_FS_INPUT_PRIMARY 0
-#define ATI_FS_INPUT_SECONDARY 1
-
-/* 6 register sets - 2 inputs (primary, secondary) */
-struct atifs_machine
-{
-   GLfloat Registers[6][4];
-   GLfloat PrevPassRegisters[6][4];
-   GLfloat Inputs[2][4];
-   GLuint pass;
-};
-
 
 /**
  * Names of the various vertex/fragment program register files, etc.
@@ -1748,8 +1733,6 @@
 
 /** Vertex and fragment instructions */
 struct prog_instruction;
-struct atifs_instruction;
-struct atifs_setupinst;
 struct program_parameter_list;
 
 
@@ -1819,22 +1802,6 @@
    GLboolean UsesKill;
 };
 
-struct ati_fragment_shader
-{
-   struct program Base;
-   struct atifs_instruction *Instructions[2];
-   struct atifs_setupinst *SetupInst[2];
-   GLfloat Constants[8][4];
-   GLuint localConstDef;
-   GLubyte numArithInstr[2];
-   GLubyte regsAssigned[2];
-   GLubyte NumPasses;
-   GLubyte cur_pass;
-   GLubyte last_optype;
-   GLboolean interpinp1;
-   GLboolean isValid;
-   GLuint swizzlerq;
-};
 
 /**
  * State common to vertex and fragment programs.
@@ -1852,7 +1819,7 @@
 struct gl_vertex_program_state
 {
    GLboolean Enabled;                  /**< GL_VERTEX_PROGRAM_NV */
-   GLboolean _Enabled;                 /**< Really enabled? */
+   GLboolean _Enabled;                 /**< Enabled and valid program? */
    GLboolean PointSizeEnabled;         /**< GL_VERTEX_PROGRAM_POINT_SIZE_NV */
    GLboolean TwoSideEnabled;           /**< GL_VERTEX_PROGRAM_TWO_SIDE_NV */
    struct vertex_program *Current;     /**< ptr to currently bound program */
@@ -1881,13 +1848,13 @@
 
 
 /**
- * State for GL_ARB/NV_fragment_program
+ * Context state for GL_ARB/NV_fragment_program
  */
 struct gl_fragment_program_state
 {
    GLboolean Enabled;                    /* GL_VERTEX_PROGRAM_NV */
-   GLboolean _Enabled;                   /* Really enabled? */
-   GLboolean _Active;                    /* Really really enabled? */
+   GLboolean _Enabled;                   /* Enabled and valid program? */
+   GLboolean _Active;
    struct fragment_program *Current;     /* ptr to currently bound program */
    struct fragment_program *_Current;    /* ptr to currently active program 
 					    (including internal programs) */
@@ -1904,19 +1871,63 @@
 
 
 /**
- * State for GL_ATI_fragment_shader
+ * ATI_fragment_shader runtime state
+ */
+#define ATI_FS_INPUT_PRIMARY 0
+#define ATI_FS_INPUT_SECONDARY 1
+
+struct atifs_instruction;
+struct atifs_setupinst;
+
+/**
+ * State for executing ATI fragment shader.
+ */
+struct atifs_machine
+{
+   GLfloat Registers[6][4];         /** six temporary registers */
+   GLfloat PrevPassRegisters[6][4];
+   GLfloat Inputs[2][4];   /** Primary, secondary input colors */
+};
+
+
+/**
+ * ATI fragment shader
+ */
+struct ati_fragment_shader
+{
+   GLuint Id;
+   GLint RefCount;
+   struct atifs_instruction *Instructions[2];
+   struct atifs_setupinst *SetupInst[2];
+   GLfloat Constants[8][4];
+   GLbitfield LocalConstDef;  /** Indicates which constants have been set */
+   GLubyte numArithInstr[2];
+   GLubyte regsAssigned[2];
+   GLubyte NumPasses;         /** 1 or 2 */
+   GLubyte cur_pass;
+   GLubyte last_optype;
+   GLboolean interpinp1;
+   GLboolean isValid;
+   GLuint swizzlerq;
+};
+
+/**
+ * Context state for GL_ATI_fragment_shader
  */
 struct gl_ati_fragment_shader_state
 {
    GLboolean Enabled;
-   GLboolean _Enabled;
+   GLboolean _Enabled;                      /** enabled and valid shader? */
    GLboolean Compiling;
-   GLfloat globalConstants[8][4];
+   GLfloat GlobalConstants[8][4];
    struct atifs_machine Machine;            /* machine state */
    struct ati_fragment_shader *Current;
 };
 
 
+/**
+ * Occlusion/timer query object.
+ */
 struct gl_query_object
 {
    GLuint Id;
@@ -1926,6 +1937,9 @@
 };
 
 
+/**
+ * Context state for query objects.
+ */
 struct gl_query_state
 {
    struct _mesa_HashTable *QueryObjects;
@@ -1934,6 +1948,9 @@
 };
 
 
+/**
+ * Context state for vertex/fragment shaders.
+ */
 struct gl_shader_objects_state
 {
    struct gl2_program_intf **current_program;
@@ -1972,11 +1989,13 @@
 #if FEATURE_ARB_fragment_program
    struct program *DefaultFragmentProgram;
 #endif
-#if FEATURE_ATI_fragment_shader
-   struct program *DefaultFragmentShader;
-#endif
    /*@}*/
 
+#if FEATURE_ATI_fragment_shader
+   struct _mesa_HashTable *ATIShaders;
+   struct ati_fragment_shader *DefaultFragmentShader;
+#endif
+
 #if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
    struct _mesa_HashTable *BufferObjects;
 #endif
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 7eb68db..562a0c5 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -934,7 +934,7 @@
    ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
       && ctx->FragmentProgram.Current->Base.Instructions;
    ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
-      && ctx->ATIFragmentShader.Current->Base.Instructions;
+      && ctx->ATIFragmentShader.Current->Instructions;
       
    ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
    ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index e16c029..d349a49 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -32,7 +32,42 @@
 
 #define MESA_DEBUG_ATI_FS 0
 
-extern struct program _mesa_DummyProgram;
+static struct ati_fragment_shader DummyShader;
+
+
+/**
+ * Allocate and initialize a new ATI fragment shader object.
+ */
+struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
+{
+   struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
+   (void) ctx;
+   if (s) {
+      s->Id = id;
+      s->RefCount = 1;
+   }
+   return s;
+}
+
+
+/**
+ * Delete the given ati fragment shader
+ */
+void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s)
+{
+   GLuint i;
+   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
+      if (s->Instructions[i])
+         _mesa_free(s->Instructions[i]);
+      if (s->SetupInst[i])
+         _mesa_free(s->SetupInst[i]);
+   }
+   _mesa_free(s);
+}
+
+
 
 static void
 new_arith_inst(struct ati_fragment_shader *prog)
@@ -165,9 +200,9 @@
       return 0;
    }
 
-   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, range);
+   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);
    for (i = 0; i < range; i++) {
-      _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram);
+      _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);
    }
 
    return first;
@@ -176,9 +211,9 @@
 void GLAPIENTRY
 _mesa_BindFragmentShaderATI(GLuint id)
 {
-   struct program *prog;
    GET_CURRENT_CONTEXT(ctx);
    struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct ati_fragment_shader *newProg;
 
    if (ctx->ATIFragmentShader.Compiling) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");
@@ -187,41 +222,43 @@
 
    FLUSH_VERTICES(ctx, _NEW_PROGRAM);
 
-   if (curProg->Base.Id == id) {
+   if (curProg->Id == id) {
       return;
    }
 
-   if (curProg->Base.Id != 0) {
-      curProg->Base.RefCount--;
-      if (curProg->Base.RefCount <= 0) {
-	 _mesa_HashRemove(ctx->Shared->Programs, id);
+   /* unbind current */
+   if (curProg->Id != 0) {
+      curProg->RefCount--;
+      if (curProg->RefCount <= 0) {
+	 _mesa_HashRemove(ctx->Shared->ATIShaders, id);
       }
    }
 
-   /* Go bind */
+   /* find new shader */
    if (id == 0) {
-      prog = ctx->Shared->DefaultFragmentShader;
+      newProg = ctx->Shared->DefaultFragmentShader;
    }
    else {
-      prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
-      if (!prog || prog == &_mesa_DummyProgram) {
+      newProg = (struct ati_fragment_shader *)
+         _mesa_HashLookup(ctx->Shared->ATIShaders, id);
+      if (!newProg || newProg == &DummyShader) {
 	 /* allocate a new program now */
-	 prog = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, id);
-	 if (!prog) {
+	 newProg = _mesa_new_ati_fragment_shader(ctx, id);
+	 if (!newProg) {
 	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
 	    return;
 	 }
-	 _mesa_HashInsert(ctx->Shared->Programs, id, prog);
+	 _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
       }
 
    }
 
    /* do actual bind */
-   ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) prog;
+   ctx->ATIFragmentShader.Current = newProg;
 
    ASSERT(ctx->ATIFragmentShader.Current);
-   if (prog)
-      prog->RefCount++;
+   if (newProg)
+      newProg->RefCount++;
 
    /*if (ctx->Driver.BindProgram)
       ctx->Driver.BindProgram(ctx, target, prog); */
@@ -238,38 +275,29 @@
    }
 
    if (id != 0) {
-      struct program *prog = (struct program *)
-	 _mesa_HashLookup(ctx->Shared->Programs, id);
-      if (prog == &_mesa_DummyProgram) {
-	 _mesa_HashRemove(ctx->Shared->Programs, id);
+      struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
+	 _mesa_HashLookup(ctx->Shared->ATIShaders, id);
+      if (prog == &DummyShader) {
+	 _mesa_HashRemove(ctx->Shared->ATIShaders, id);
       }
       else if (prog) {
 	 if (ctx->ATIFragmentShader.Current &&
-	     ctx->ATIFragmentShader.Current->Base.Id == id) {
+	     ctx->ATIFragmentShader.Current->Id == id) {
 	     FLUSH_VERTICES(ctx, _NEW_PROGRAM);
 	    _mesa_BindFragmentShaderATI(0);
 	 }
       }
-#if 0
-      if (!prog->DeletePending) {
-	 prog->DeletePending = GL_TRUE;
-	 prog->RefCount--;
-      }
-      if (prog->RefCount <= 0) {
-	 _mesa_HashRemove(ctx->Shared->Programs, id);
-	 ctx->Driver.DeleteProgram(ctx, prog);
-      }
-#else
+
       /* The ID is immediately available for re-use now */
-      _mesa_HashRemove(ctx->Shared->Programs, id);
+      _mesa_HashRemove(ctx->Shared->ATIShaders, id);
       prog->RefCount--;
       if (prog->RefCount <= 0) {
-	 ctx->Driver.DeleteProgram(ctx, prog);
+         _mesa_free(prog);
       }
-#endif
    }
 }
 
+
 void GLAPIENTRY
 _mesa_BeginFragmentShaderATI(void)
 {
@@ -307,7 +335,7 @@
    }
 
 /* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
-   ctx->ATIFragmentShader.Current->localConstDef = 0;
+   ctx->ATIFragmentShader.Current->LocalConstDef = 0;
    ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
    ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
    ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
@@ -720,10 +748,10 @@
    if (ctx->ATIFragmentShader.Compiling) {
       struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
       COPY_4V(curProg->Constants[dstindex], value);
-      curProg->localConstDef |= 1 << dstindex;
+      curProg->LocalConstDef |= 1 << dstindex;
    }
    else {
       FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-      COPY_4V(ctx->ATIFragmentShader.globalConstants[dstindex], value);
+      COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
    }
 }
diff --git a/src/mesa/shader/atifragshader.h b/src/mesa/shader/atifragshader.h
index 9621502..32fb3a8 100644
--- a/src/mesa/shader/atifragshader.h
+++ b/src/mesa/shader/atifragshader.h
@@ -57,6 +57,15 @@
    GLenum swizzle;
 };
 
+
+extern struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id);
+
+extern void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx,
+                                 struct ati_fragment_shader *s);
+
+
 extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range);
 
 extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id);
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 6e0805c..28b982b 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -88,11 +88,12 @@
    ctx->FragmentProgram.Current->Base.RefCount++;
 #endif
 
+   /* XXX probably move this stuff */
 #if FEATURE_ATI_fragment_shader
    ctx->ATIFragmentShader.Enabled = GL_FALSE;
    ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
    assert(ctx->ATIFragmentShader.Current);
-   ctx->ATIFragmentShader.Current->Base.RefCount++;
+   ctx->ATIFragmentShader.Current->RefCount++;
 #endif
 }
 
@@ -117,11 +118,13 @@
          ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
    }
 #endif
+   /* XXX probably move this stuff */
 #if FEATURE_ATI_fragment_shader
    if (ctx->ATIFragmentShader.Current) {
-      ctx->ATIFragmentShader.Current->Base.RefCount--;
-      if (ctx->ATIFragmentShader.Current->Base.RefCount <= 0)
-	ctx->Driver.DeleteProgram(ctx, &(ctx->ATIFragmentShader.Current->Base));
+      ctx->ATIFragmentShader.Current->RefCount--;
+      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
+         _mesa_free(ctx->ATIFragmentShader.Current);
+      }
    }
 #endif
    _mesa_free((void *) ctx->Program.ErrorString);
@@ -234,21 +237,6 @@
       return NULL;
 }
 
-/**
- * Initialize a new ATI fragment shader object.
- */
-struct program *
-_mesa_init_ati_fragment_shader( GLcontext *ctx,
-                                struct ati_fragment_shader *prog,
-                                GLenum target, GLuint id )
-{
-   if (prog) 
-      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
-   else
-      return NULL;
-}
-
-
 
 /**
  * Allocate and initialize a new fragment/vertex program object but
@@ -273,10 +261,6 @@
    case GL_FRAGMENT_PROGRAM_ARB:
       return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(fragment_program),
 					  target, id );
-   case GL_FRAGMENT_SHADER_ATI:
-      return _mesa_init_ati_fragment_shader( ctx, CALLOC_STRUCT(ati_fragment_shader),
-					  target, id );
-
    default:
       _mesa_problem(ctx, "bad target in _mesa_new_program");
       return NULL;
@@ -311,17 +295,6 @@
    if (prog->Parameters)
       _mesa_free_parameter_list(prog->Parameters);
 
-   if (prog->Target == GL_FRAGMENT_SHADER_ATI) {
-      struct ati_fragment_shader *atifs = (struct ati_fragment_shader *)prog;
-      GLuint i;
-      for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-	 if (atifs->Instructions[i])
-	    _mesa_free(atifs->Instructions[i]);
-	 if (atifs->SetupInst[i])
-	    _mesa_free(atifs->SetupInst[i]);
-      }
-   }
-
    _mesa_free(prog);
 }
 
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index ab72f45..a1ee334 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -106,11 +106,6 @@
                             GLenum target, GLuint id);
 
 extern struct program *
-_mesa_init_ati_fragment_shader(GLcontext *ctx,
-                               struct ati_fragment_shader *prog,
-                               GLenum target, GLuint id );
-
-extern struct program *
 _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id);
 
 extern void
diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c
index 0c695ca..36ada5f 100644
--- a/src/mesa/swrast/s_atifragshader.c
+++ b/src/mesa/swrast/s_atifragshader.c
@@ -28,8 +28,6 @@
 #include "program.h"
 
 #include "s_atifragshader.h"
-#include "s_nvfragprog.h"
-#include "s_span.h"
 
 
 /**
@@ -346,12 +344,12 @@
 		  SETUP_SRC_REG(optype, i,
 				machine->Registers[index - GL_REG_0_ATI]);
 	       else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
-		  if (shader->localConstDef & (1 << (index - GL_CON_0_ATI))) {
+		  if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) {
 		     SETUP_SRC_REG(optype, i,
 				shader->Constants[index - GL_CON_0_ATI]);
 		  } else {
 		     SETUP_SRC_REG(optype, i,
-				ctx->ATIFragmentShader.globalConstants[index - GL_CON_0_ATI]);
+				ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]);
 		  }
 	       }
 	       else if (index == GL_ONE)
@@ -557,7 +555,6 @@
    for (i = 0; i < 6; i++) {
       for (j = 0; j < 4; j++)
 	 ctx->ATIFragmentShader.Machine.Registers[i][j] = 0.0;
-
    }
 
    ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][0] =
@@ -577,8 +574,6 @@
       CHAN_TO_FLOAT(span->array->spec[col][2]);
    ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][3] =
       CHAN_TO_FLOAT(span->array->spec[col][3]);
-
-   ctx->ATIFragmentShader.Machine.pass = 0;
 }
 
 
@@ -615,10 +610,7 @@
 	    UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]);
 	 }
       }
-
    }
 
-
    ctx->_CurrentProgram = 0;
-
 }