what's is wrong in my program with glutKeyboardFunc ?

it don’t work

#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#define X .525731112119133606
#define Z .850650808352039932

float nbr_degre=0.0, j=0.0, k=0.0, l=0.0 ;
static float m = 0.0 ;

void normalisation (GLfloat *v)
{
GLfloat d = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); //calcul de la longueur de la normale

/*normalisation du vecteur */

v[0] /= d;
v[1] /= d;
v[2] /= d;

}

void dessine_les_triangles (float *v1, float *v2, float *v3)
{
glBegin(GL_TRIANGLES) ; //affichage du triangle issu de la subdivision
glNormal3fv (v1);
glVertex3fv (v1);
glNormal3fv (v2);
glVertex3fv (v2);
glNormal3fv (v3);
glVertex3fv (v3);
glEnd();
}

void subdivision (GLfloat *v1, GLfloat *v2, GLfloat *v3)
{
GLfloat v12[3], v23[3], v31[3] ;
GLint i;

for (i=0 ; i<3 ; i++)
{
v12[i] = (v1[i] + v2[i])/2.0; //
v23[i] = (v2[i] + v3[i])/2.0; //calcul des nouveaux sommets des triangles
v31[i] = (v3[i] + v1[i])/2.0; //
}

normalisation (v12) ;
normalisation (v23) ;
normalisation (v31) ;

/dessine les triangles issus de la subdivision/
dessine_les_triangles (v1, v12, v31) ;
dessine_les_triangles (v2, v23, v12) ;
dessine_les_triangles (v3, v31, v23) ;
dessine_les_triangles (v12, v23, v31);
}

void display ()
{
static GLfloat tableau_entrelace [24][3] = {{1.0, 1.0, 1.0}, {-X, 0.0, Z}, {1.0, 1.0, 1.0}, {X, 0.0, Z},
{1.0, 1.0, 1.0}, {-X, 0.0, -Z}, {1.0, 1.0, 1.0}, {X, 0.0, -Z}, {1.0, 1.0, 1.0}, {0.0, Z, X},
{1.0, 1.0, 1.0}, {0.0, Z, -X}, {1.0, 1.0, 1.0}, {0.0, -Z, X}, {1.0, 1.0, 1.0}, {0.0, -Z, -X},
{1.0, 1.0, 1.0}, {Z, X, 0.0}, {1.0, 1.0, 1.0}, {-Z, X, 0.0}, {1.0, 1.0, 1.0}, {Z, -X, 0.0},
{1.0, 1.0, 1.0}, {-Z, -X, 0.0} }; //ceci est un tableau entrelacé de couleurs et de coordonnées de sommets

glInterleavedArrays (GL_C3F_V3F, 0, tableau_entrelace) ; //lecture dans le tableau entrelacé

/definition des polygones par le numéro des sommets/

static GLuint indices [20][3]= {1,4,0,4,9,0,4,5,9,8,5,4,1,8,4,1,10,8,10,3,8,8,3,5,3,2,5,
3,7,2,3,10,7,10,6,7,6,11,7,6,0,11,6,1,0,10,1,6,11,0,9,2,11,9,5,2,9,11,2,7};

glPolygonMode (GL_FRONT, GL_LINE) ; //la face avant des polygones sera rendue en fil de fer
glFrontFace (GL_CCW) ; //spécifie la face avant
glEnable (GL_CULL_FACE) ;
glCullFace (GL_BACK) ; //suppression des faces arrières

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glRotatef ( nbr_degre, j, k, l ) ;

for (GLint i= 0 ; i<20 ;i++)
{

subdivision (&tableau_entrelace [indices[i][0]*2+1][0], &tableau_entrelace [indices[i][1]*2+1][0], &tableau_entrelace [indices[i][2]*2+1][0]); // display the sphere
}

glutSwapBuffers() ; //permutte le back buffer avec le front buffer
glFlush () ;

}

void reshape (int w, int h)
{
glViewport (0, 0, w, h) ;
glMatrixMode (GL_PROJECTION) ;
glLoadIdentity () ;
glFrustum(-10.0 , 10.0, -7.5, 7.5, 15.0, 100.0);
glMatrixMode(GL_MODELVIEW); //la matrice active de modelisation/visualisation sera affectée
glLoadIdentity(); //charge la matrice identité

gluLookAt ( m , 0.0, 25.0, 0.0,0.0,0.0, 0.0, 1.0, 0.0) ; //caméra placée sur l’axe des Z et regardant vers l’origine

}

void keyboard (unsigned char key, int x, int y)
{

switch (key)
{
case ‘d’ : //fait tourner selon l’axe des Y
case ‘D’ :
m = 10 ;
glutReshapeFunc (reshape) ;
glutPostRedisplay () ;
break ;

case ‘s’ :
case ‘S’ :

break ;

case ‘e’ : //fait tourner selon l’axe des X
case ‘E’ :

break ;

case ‘x’ : //fait tourner selon l’axe des X
case ‘X’ :

break ;

}
}

void main (int argc, char** argv)

{
glutInit (&argc, argv) ;
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) ;
glutInitWindowSize (640, 480) ;
glutInitWindowPosition (250,250) ;
glutCreateWindow (argv [0]) ;

glClearColor (0.0, 0.0, 0.0, 0.0) ;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //vide la mémoire tampon des couleurs et des coordonnées de profondeur
glEnable( GL_DEPTH_TEST );

glutDisplayFunc (display) ;
glutReshapeFunc (reshape) ;
glutKeyboardFunc (keyboard) ;

glutMainLoop () ;

}