This is a common problem. 
What you need to do is the following.
Start out with you helicopter pointing down the Z axis. Then turn it 90 degrees up (pitch/X axis). If you now apply heading, and do it wrong, you make it spin around sidewise, since you told it to rotate on the Y axis.
However, this Y axis is still in world space, and thus, you also need to turn the Y axis 90 degrees up. (So that it points in the original Z axis direction)
How to do this? Well, the best way is, if you want to be able to keep turning the helicopter frame after frame and perform all kinds of wicked rotations, then your solution is the following:
Your helicopter needs to remember where it is. (This is the same as aligning the Y axis with the helicopter).
This is done by storing the matrix for it from frame to frame, and then reinserting it before each new rotation.
So, for your helicopter (or one for each) you need an array of 16 floats (or doubles). Store this in the helicopter struct/class for convenience.
float heliMatrix [16]; // This needs to start out as the indentity matrix.
Then, when you update your helicopter, do this:
// Return to where the helicopter was
glLoadMatrix (heliMatrix);
glRotatef (xRot, 1, 0, 0);
glRotatef (yRot, 0, 1, 0);
glRotatef (zRot, 0, 0, 1);
// Draw helicopter
// Remember where the helicopter is.
glGetFloatv (GL_MODELVIEW_MATRIX, heliMatrix);
The only crux here is that xRot, yRot and zRot must be the CHANGE in rotation per frame, not the real angle to rotate to.
This should produce what you want.
[This message has been edited by NordFenris (edited 10-04-2002).]