Your question isn't quite right. Don't ask "Once you rotate something, the axis are no longer the same (x,y) so how can you find out how much to rotate in which axis?", ask "how can I rotate around global axes rather than local axes?". You want a rotation around your global x always to be a rotation around global x, not a rotation around your object's local x axis. You don't rotate differently according to the current state, you just change what you're conceptually rotating around.
First of all, you're probably storing, say rotX, rotY and rotZ and calling glRotatef to apply a rotation? That's not good enough for what you want to do. What you're doing is describing orientation by Euler angles. You'll always encounter gimbal lock, which is where some values for one of the axes turn the other two axes into the same axis. So you lose a degree of freedom. Check out the article for a proper explanation.
Because you'll be very happy with them as an OpenGL coder, suppose you were instead storing object orientation directly as a matrix called M. You store the rotation as the matrix you apply to achieve the rotation. There's no explicit concept of angles or axes.
Suppose you want to rotate around x. You generate a suitable rotation matrix around the x axis, call it R. Such a matrix would be the thing OpenGL would build internally to carry out glRotatef(angle, 1, 0, 0).
Then you actually have two options — replace M with MR or replace M with RM. Matrix multiplication isn't commutative, so those aren't the same. Just like using the OpenGL matrix stack to translate six to the left and then rotate by 40 degrees produces a different result to rotating by 40 degrees and then translating six to the left.
In this case R is the object, so MR is postmultiplication and RM is premultiplication. Multiplication of matrices creates a matrix that, when applied to a vector, has the same effect as applying the second one and then applying the first one. So if you postmultiplied, you'd get the result as though you'd rotated the object by the new rotation and then all the ones that preceded it. That's obviously the wrong way around. You want the new modification to take effect after all other modifications to date. So you premultiply. And then store the result as the new M.
That's all there is to it, actually. You can knock up a quick proof of concept using the GL matrix stack explicitly, like:
// ... I assume the modelview stack is active, M is an array of 16 floats ...
// ensure whatever's on the stack currently is kept safe
glPushMatrix();
// but we don't actually care what it was, so load the identity
glLoadIdentity();
// build our rotation matrix first
glRotatef(changeAroundX, 1, 0, 0);
glRotatef(changeAroundY, 0, 1, 0);
// multiply by M. OpenGL postmultiplies by the newer matrix, so this
// is premultiplying M by whatever we just loaded
glMultMatrixf(M);
// read the new M back
glGetFloatv(GL_MODELVIEW_MATRIX, M);
// and pretend we never touched the stack
glPopMatrix();
Then use glMultMatrixf(M) in place of glRotatef to apply the current object rotation. This is only a proof of concept because you'll quickly get some nasty numerical errors in M, just resulting from the high amount of manipulation you're doing to it. You can fix M as you go along but if you already have quaternion code and are happy with them, it might be smarter to go down that route. Just replace the logical matrix ops with the quaternion equivalents.