X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=vid_glx.c;h=40cebe1b10cde7f910958db4b500a2e37be35797;hp=3969fe16b196c08c8bf2216bd3d7d248a9d72904;hb=dd0b4a35240b6b0e8612e41af439ead7981ec8cd;hpb=64a00997d5d76bae2e6aae5e2de6ac17ea3504a9 diff --git a/vid_glx.c b/vid_glx.c index 3969fe16..40cebe1b 100644 --- a/vid_glx.c +++ b/vid_glx.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#include // TODO possibly ifdef this out on non-supporting systems... Solaris (as always)? #include #include "quakedef.h" @@ -88,14 +89,14 @@ Atom wm_delete_window_atom; 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; static qboolean vid_x11_dgasupported = false; static int vid_x11_gammarampsize = 0; -static float mouse_x, mouse_y; -static int p_mouse_x, p_mouse_y; #if !defined(__APPLE__) && !defined(SUNOS) cvar_t vid_dgamouse = {CVAR_SAVE, "vid_dgamouse", "1", "make use of DGA mouse input"}; @@ -249,17 +250,49 @@ static Cursor CreateNullCursor(Display *display, Window root) return cursor; } -void VID_GrabMouse(qboolean grab) +void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor) { - if (!vidx11_display) +#if !defined(__APPLE__) && !defined(SUNOS) + qboolean usedgamouse; +#endif + + if (!vidx11_display || !win) return; - if (grab) - { + + if (relative) + fullscreengrab = true; + + if (!mouse_avail) + fullscreengrab = relative = hidecursor = false; + #if !defined(__APPLE__) && !defined(SUNOS) - if(vid_usingmouse && (vid_usingdgamouse != !!vid_dgamouse.integer)) - VID_GrabMouse(false); // ungrab first! + usedgamouse = relative && vid_dgamouse.integer; + 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; @@ -268,13 +301,9 @@ void VID_GrabMouse(qboolean grab) 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); @@ -283,15 +312,8 @@ void VID_GrabMouse(qboolean grab) #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); - - mouse_x = mouse_y = 0; cl_ignoremousemoves = 2; vid_usingmouse = true; -#if !defined(__APPLE__) && !defined(SUNOS) - vid_usingdgamouse = !!vid_dgamouse.integer; -#endif } } else @@ -299,21 +321,23 @@ void VID_GrabMouse(qboolean grab) 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] = @@ -371,28 +395,26 @@ static void HandleEvents(void) if (vid_usingmouse) { #if !defined(__APPLE__) && !defined(SUNOS) - if (vid_dgamouse.integer == 1 && vid_x11_dgasupported) + if (vid_usingdgamouse) { - mouse_x += event.xmotion.x_root; - mouse_y += event.xmotion.y_root; + in_mouse_x += event.xmotion.x_root; + in_mouse_y += event.xmotion.y_root; } else #endif { - if (!event.xmotion.send_event) { - mouse_x += event.xmotion.x - p_mouse_x; - mouse_y += event.xmotion.y - p_mouse_y; + 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) dowarp = true; } - p_mouse_x = event.xmotion.x; - p_mouse_y = event.xmotion.y; } } - //else - // ui_mouseupdate(event.xmotion.x, event.xmotion.y); + in_windowmouse_x = event.xmotion.x; + in_windowmouse_y = event.xmotion.y; break; case ButtonPress: @@ -437,20 +459,28 @@ static void HandleEvents(void) Sys_Quit(0); break; case MapNotify: + if (vid.fullscreen) + break; // window restored vid_hidden = false; VID_RestoreSystemGamma(); break; case UnmapNotify: + if (vid.fullscreen) + break; // window iconified/rolledup/whatever vid_hidden = true; VID_RestoreSystemGamma(); break; case FocusIn: + if (vid.fullscreen) + break; // window is now the input focus vid_activewindow = true; break; case FocusOut: + if (vid.fullscreen) + break; // window is no longer the input focus vid_activewindow = false; VID_RestoreSystemGamma(); @@ -467,9 +497,16 @@ static void HandleEvents(void) if (dowarp) { /* move the mouse to the window center again */ - p_mouse_x = vid.width / 2; - p_mouse_y = vid.height / 2; - XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, p_mouse_x, p_mouse_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); } } @@ -515,7 +552,7 @@ void VID_Shutdown(void) if (!ctx || !vidx11_display) return; - VID_GrabMouse(false); + VID_SetMouse(false, false, false); VID_RestoreSystemGamma(); // FIXME: glXDestroyContext here? @@ -664,6 +701,9 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate return false; } + // make autorepeat send keypress/keypress/.../keyrelease instead of intervening keyrelease + XkbSetDetectableAutoRepeat(vidx11_display, true, NULL); + vidx11_screen = DefaultScreen(vidx11_display); root = RootWindow(vidx11_display, vidx11_screen); @@ -858,7 +898,9 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate // 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; @@ -899,11 +941,4 @@ void Sys_SendKeyEvents(void) void IN_Move (void) { - if (mouse_avail) - { - in_mouse_x = mouse_x; - in_mouse_y = mouse_y; - } - mouse_x = 0; - mouse_y = 0; }