# Trapping mouse inside window in OpenGL with GLUT?

I perfectly understand that GLUT is limited and the following problem can't probably be solved with OpenGL/GLUT, but since I don't know exactly if it can or not, I better just ask. Maybe I'm doing something wrong or forgetting something important. Or probably not and GLUT doesn't get better than this.

My problem is that I can't trap the mouse inside the window. Well, actually, I can, the code below does just that. I trap the mouse inside the window and I can use the mouse freely to rotate the world. The problem? If I move the mouse too fast I can get way from window prison.

Is there a way around this with OpenGL/GLUT or the only option is another library or make some calls to the Windows API directly? Enough words, here's my current code:

void processPassiveMouseMotion(int x, int y) {
static int centerX = glutGet(GLUT_WINDOW_WIDTH) / 2;
static int centerY = glutGet(GLUT_WINDOW_HEIGHT) / 2;

CameraAngle.x = -1.0f * (y - centerY);
CameraAngle.y = -1.0f * (x - centerX);

if(CameraAngle.x != 0.0f || CameraAngle.y != 0.0f) {
SceneCamera.Rotate(CameraAngle);
glutPostRedisplay();

glutWarpPointer(centerX, centerY);
}
}

glutPassiveMotionFunc(processPassiveMouseMotion);


To the best of my knowledge this is Windows-API specific - this functionality doesn't even exist on all platforms. If you want to dig through my code you can find a working Windows implementation (LockMouseCursor is the entry point into the OS module, ClipCursor is the actual Windows function that does the trapping, but there's some niceties surrounding that function - it shouldn't be too tough to decipher.)

I also have a Linux implementation in pure X (again, start with LockMouseCursor) but I've never found a usable OSX API for it. If you end up needing one or coming up with one, check my Stackoverflow question on the matter :)

• Thank you, I'll keep this post in mind as reference. You're dealing with Windows APIs as I suspected being the only good way to achieve this but I didn't want to go that route. Not that I don't know how, because I do as I've done it before, but for what I'm tyring to do, it's not worth trouble and it's not a priority. – rfgamaral Mar 23 '11 at 12:34

With a quick search through the GLUT spec, GLUT does not seem to have mouse capture capabilities. The best you can do (like you seem to be doing) is to warp the cursor to the center and hope the user isn't fast enough (or isn't using a tablet) =)

Or, you could switch to SDL or SFML, as GLUT is only designed for testing, not "real" software.

• While I agree with your comment in general, I want to strongly urge against SDL because oh man SDL has major problems. SFML is great, use that! – ZorbaTHut Mar 23 '11 at 7:01
• They both have their sides, and I like SDL, so.. =) – Jari Komppa Mar 23 '11 at 7:28
• Please don't get this the wrong way but, this is the second time you're telling me to switch. While I appreciate anyone's answer, if I insist on posting GLUT specific questions, maybe I have a good reason for this and can't switch? I've already realized how GLUT sucks, but I have to put up with it, it's not my choice. Sorry if I sound harsh, but I hate when people insist like this, I "heard" you the first time. – rfgamaral Mar 23 '11 at 12:28
• I'm voting your answer up because I'm ignoring that last paragraph. :) – rfgamaral Mar 23 '11 at 12:35
• Nazgulled, sorry if I seem to be repeating things, I don't really track whose questions I'm answering =). Additionally, people will end up finding this question through searches, and I also want to answer to them, not only to you. – Jari Komppa Mar 23 '11 at 13:36

Try a newer version of freeglut; My v2.6, traps cursor with glutWarpPointer without any possibility of escape by mouse.

In my case, modify

glutWarpPointer(centerX, centerY);


to something like

if (x != centerX || y != centerY) glutWarpPointer(centerX, centerY);


perfectly solved the problem.

The problem is caused by glutWarpPointer triggering another passive motion event to (centerX, centerY), which results in a loop and/or floods the event queue. To avoid it, simply check if the mouse is at (centerX, centerY), if so, don't warp.