X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=vid_glx.c;h=4050a1c8f531ca5b90cf4bf2d05ecb2371ef628d;hb=eb59c580e111af2abb37775ef320151776fe84d1;hp=ff98510818116e663898d39b73ba7d81776ae714;hpb=ecddae3859018ea01887528f3248f03a138be6c3;p=xonotic%2Fdarkplaces.git diff --git a/vid_glx.c b/vid_glx.c index ff985108..4050a1c8 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,18 +89,18 @@ Atom wm_delete_window_atom; static qboolean mouse_avail = true; +static qboolean vid_usingmousegrab = false; static qboolean vid_usingmouse = false; -static qboolean vid_usingdgamouse = 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"}; +static qboolean vid_usingdgamouse = false; #endif qboolean vidmode_ext = false; @@ -249,17 +250,47 @@ static Cursor CreateNullCursor(Display *display, Window root) return cursor; } -static void IN_Activate (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)) - IN_Activate(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; @@ -268,13 +299,9 @@ static void IN_Activate (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,13 +310,8 @@ static void IN_Activate (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; - vid_usingdgamouse = !!vid_dgamouse.integer; } } else @@ -297,21 +319,23 @@ static void IN_Activate (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] = @@ -369,28 +393,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: @@ -435,20 +457,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(); @@ -465,9 +495,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); } } @@ -513,18 +550,16 @@ void VID_Shutdown(void) if (!ctx || !vidx11_display) return; - if (vidx11_display) - { - IN_Activate(false); - VID_RestoreSystemGamma(); - - // FIXME: glXDestroyContext here? - if (vid_isfullscreen) - XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, &init_vidmode); - if (win) - XDestroyWindow(vidx11_display, win); - XCloseDisplay(vidx11_display); - } + VID_SetMouse(false, false, false); + VID_RestoreSystemGamma(); + + // FIXME: glXDestroyContext here? + if (vid_isfullscreen) + XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, &init_vidmode); + if (win) + XDestroyWindow(vidx11_display, win); + XCloseDisplay(vidx11_display); + vid_hidden = true; vid_isfullscreen = false; vidx11_display = NULL; @@ -556,10 +591,8 @@ void InitSig(void) signal(SIGTERM, signal_handler); } -void VID_Finish (qboolean allowmousegrab) +void VID_Finish (void) { - qboolean vid_usemouse; - vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable; if (vid_usingvsync != vid_usevsync && gl_videosyncavailable) { @@ -568,16 +601,6 @@ void VID_Finish (qboolean allowmousegrab) Con_Print("glXSwapIntervalSGI didn't accept the vid_vsync change, it will take effect on next vid_restart (GLX_SGI_swap_control does not allow turning off vsync)\n"); } - // handle the mouse state when windowed if that's changed - vid_usemouse = false; - if (allowmousegrab && vid_mouse.integer && !key_consoleactive && (key_dest != key_game || !cls.demoplayback)) - vid_usemouse = true; - if (!vid_activewindow) - vid_usemouse = false; - if (vid_isfullscreen) - vid_usemouse = true; - IN_Activate(vid_usemouse); - if (r_render.integer) { CHECKGLERROR @@ -616,20 +639,20 @@ void VID_Init(void) void VID_BuildGLXAttrib(int *attrib, qboolean stencil, qboolean stereobuffer, int samples) { *attrib++ = GLX_RGBA; - *attrib++ = GLX_RED_SIZE;*attrib++ = 1; - *attrib++ = GLX_GREEN_SIZE;*attrib++ = 1; - *attrib++ = GLX_BLUE_SIZE;*attrib++ = 1; + *attrib++ = GLX_RED_SIZE;*attrib++ = stencil ? 8 : 5; + *attrib++ = GLX_GREEN_SIZE;*attrib++ = stencil ? 8 : 5; + *attrib++ = GLX_BLUE_SIZE;*attrib++ = stencil ? 8 : 5; *attrib++ = GLX_DOUBLEBUFFER; - *attrib++ = GLX_DEPTH_SIZE;*attrib++ = 1; + *attrib++ = GLX_DEPTH_SIZE;*attrib++ = stencil ? 24 : 16; // if stencil is enabled, ask for alpha too if (stencil) { *attrib++ = GLX_STENCIL_SIZE;*attrib++ = 8; - *attrib++ = GLX_ALPHA_SIZE;*attrib++ = 1; + *attrib++ = GLX_ALPHA_SIZE;*attrib++ = 8; } if (stereobuffer) *attrib++ = GLX_STEREO; - if (samples) + if (samples > 1) { *attrib++ = GLX_SAMPLE_BUFFERS_ARB; *attrib++ = 1; @@ -676,6 +699,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); @@ -702,6 +728,13 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate VID_BuildGLXAttrib(attrib, bpp == 32, stereobuffer, samples); visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib); + if (!visinfo && (samples == 1)) + { + /* Some Mesa drivers reject sample buffers with 1 sample, so try + * entirely without one */ + VID_BuildGLXAttrib(attrib, bpp == 32, stereobuffer, 0); + visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib); + } if (!visinfo) { Con_Print("Couldn't get an RGB, Double-buffered, Depth visual\n"); @@ -848,19 +881,10 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate return false; } - gl_renderer = (const char *)qglGetString(GL_RENDERER); - gl_vendor = (const char *)qglGetString(GL_VENDOR); - gl_version = (const char *)qglGetString(GL_VERSION); gl_extensions = (const char *)qglGetString(GL_EXTENSIONS); gl_platform = "GLX"; gl_platformextensions = qglXQueryExtensionsString(vidx11_display, vidx11_screen); - Con_DPrintf("GL_VENDOR: %s\n", gl_vendor); - Con_DPrintf("GL_RENDERER: %s\n", gl_renderer); - Con_DPrintf("GL_VERSION: %s\n", gl_version); - Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions); - Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions); - gl_videosyncavailable = false; // COMMANDLINEOPTION: Linux GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions) @@ -872,7 +896,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; @@ -913,11 +939,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; }