static qboolean mouse_avail = true;
+static qboolean vid_usingmousegrab = false;
static qboolean vid_usingmouse = false;
+static qboolean vid_usinghidecursor = false;
static qboolean vid_usingvsync = false;
static qboolean vid_usevsync = false;
static qboolean vid_x11_hardwaregammasupported = false;
return cursor;
}
-void VID_GrabMouse(qboolean grab)
+void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
{
- if (!vidx11_display)
+ qboolean usedgamouse;
+
+ if (!vidx11_display || !win)
return;
- if (grab)
- {
+
+ if (relative)
+ fullscreengrab = true;
+
+ if (!mouse_avail)
+ fullscreengrab = relative = hidecursor = false;
+
+ usedgamouse = relative && vid_dgamouse.integer;
#if !defined(__APPLE__) && !defined(SUNOS)
- if(vid_usingmouse && (vid_usingdgamouse != !!vid_dgamouse.integer))
- VID_GrabMouse(false); // ungrab first!
+ if (!vid_x11_dgasupported)
+ usedgamouse = false;
+ if (fullscreengrab && vid_usingmouse && (vid_usingdgamouse != usedgamouse))
+ VID_SetMouse(false, false, false); // ungrab first!
#endif
- if (!vid_usingmouse && mouse_avail && win)
+
+ if (vid_usingmousegrab != fullscreengrab)
+ {
+ vid_usingmousegrab = fullscreengrab;
+ cl_ignoremousemoves = 2;
+ if (fullscreengrab)
+ {
+ XGrabPointer(vidx11_display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
+ if (vid_grabkeyboard.integer || vid_isfullscreen)
+ XGrabKeyboard(vidx11_display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ }
+ else
+ {
+ XUngrabPointer(vidx11_display, CurrentTime);
+ XUngrabKeyboard(vidx11_display, CurrentTime);
+ }
+ }
+
+ if (relative)
+ {
+ if (!vid_usingmouse)
{
XWindowAttributes attribs_1;
XSetWindowAttributes attribs_2;
attribs_2.event_mask = attribs_1.your_event_mask | KEY_MASK | MOUSE_MASK;
XChangeWindowAttributes(vidx11_display, win, CWEventMask, &attribs_2);
- // inviso cursor
- XDefineCursor(vidx11_display, win, CreateNullCursor(vidx11_display, win));
-
- XGrabPointer(vidx11_display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
-
#if !defined(__APPLE__) && !defined(SUNOS)
- if (vid_dgamouse.integer && vid_x11_dgasupported)
+ vid_usingdgamouse = usedgamouse;
+ if (usedgamouse)
{
XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), XF86DGADirectMouse);
XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, 0, 0);
#endif
XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
- if (vid_grabkeyboard.integer || vid_isfullscreen)
- XGrabKeyboard(vidx11_display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
-
cl_ignoremousemoves = 2;
vid_usingmouse = true;
-#if !defined(__APPLE__) && !defined(SUNOS)
- vid_usingdgamouse = !!vid_dgamouse.integer;
-#endif
}
}
else
if (vid_usingmouse)
{
#if !defined(__APPLE__) && !defined(SUNOS)
- if (vid_x11_dgasupported)
+ if (vid_usingdgamouse)
XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), 0);
+ vid_usingdgamouse = false;
#endif
-
- XUngrabPointer(vidx11_display, CurrentTime);
- XUngrabKeyboard(vidx11_display, CurrentTime);
-
- // inviso cursor
- if (win)
- XUndefineCursor(vidx11_display, win);
-
cl_ignoremousemoves = 2;
vid_usingmouse = false;
}
}
+
+ if (vid_usinghidecursor != hidecursor)
+ {
+ vid_usinghidecursor = hidecursor;
+ if (hidecursor)
+ XDefineCursor(vidx11_display, win, CreateNullCursor(vidx11_display, win));
+ else
+ XUndefineCursor(vidx11_display, win);
+ }
}
static keynum_t buttonremap[18] =
case MotionNotify:
// mouse moved
- if (vid.mouseaim)
+ if (vid_usingmouse)
{
#if !defined(__APPLE__) && !defined(SUNOS)
- if (vid_dgamouse.integer == 1 && vid_x11_dgasupported)
+ if (vid_usingdgamouse)
{
in_mouse_x += event.xmotion.x_root;
in_mouse_y += event.xmotion.y_root;
{
in_mouse_x += event.xmotion.x - in_windowmouse_x;
in_mouse_y += event.xmotion.y - in_windowmouse_y;
- if (abs(vid.width/2 - event.xmotion.x) + abs(vid.height/2 - event.xmotion.y))
- //if (abs(vid.width/2 - event.xmotion.x) > vid.width / 4 || abs(vid.height/2 - event.xmotion.y) > vid.height / 4)
+ //if (abs(vid.width/2 - event.xmotion.x) + abs(vid.height/2 - event.xmotion.y))
+ if (abs(vid.width/2 - event.xmotion.x) > vid.width / 4 || abs(vid.height/2 - event.xmotion.y) > vid.height / 4)
dowarp = true;
}
}
if (dowarp)
{
/* move the mouse to the window center again */
- in_windowmouse_x = (int)(vid.width / 2);
- in_windowmouse_y = (int)(vid.height / 2);
- XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, (int)in_windowmouse_x, (int)in_windowmouse_y);
+ // we'll catch the warp motion by its send_event flag, updating the
+ // stored mouse position without adding any delta motion
+ XEvent event;
+ event.type = MotionNotify;
+ event.xmotion.display = vidx11_display;
+ event.xmotion.window = win;
+ event.xmotion.x = vid.width / 2;
+ event.xmotion.y = vid.height / 2;
+ XSendEvent(vidx11_display, win, False, PointerMotionMask, &event);
+ XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
}
}
if (!ctx || !vidx11_display)
return;
- VID_GrabMouse(false);
+ VID_SetMouse(false, false, false);
VID_RestoreSystemGamma();
// FIXME: glXDestroyContext here?
// COMMANDLINEOPTION: MacOSX GLX: -novideosync disables GLX_SGI_swap_control
gl_videosyncavailable = GL_CheckExtension("GLX_SGI_swap_control", swapcontrolfuncs, "-novideosync", false);
+ vid_usingmousegrab = false;
vid_usingmouse = false;
+ vid_usinghidecursor = false;
vid_usingvsync = false;
vid_hidden = false;
vid_activewindow = true;