X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=vid_glx.c;h=7f5fbe051eb359f4c47cc74f90f8e1cc00f32f53;hb=e948a0f3bad7d2b3f86175630c8e67a5f634c099;hp=cc503fda5e474a92d26b2b52e18a40d0c5fac42e;hpb=7a326060eaf7fee38b91dd9dfb6bf10bcad7e108;p=xonotic%2Fdarkplaces.git diff --git a/vid_glx.c b/vid_glx.c index cc503fda..7f5fbe05 100644 --- a/vid_glx.c +++ b/vid_glx.c @@ -17,12 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//#include -//#include -//#include -//#include -//#include -//#include #include #include @@ -31,8 +25,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#include "quakedef.h" + #include #include +#include #include #if !defined(__APPLE__) && !defined(__MACH__) && !defined(SUNOS) @@ -40,11 +37,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #include -#include "quakedef.h" +#include "nexuiz.xpm" +#include "darkplaces.xpm" // Tell startup code that we have a client int cl_available = true; +// note: if we used the XRandR extension we could support refresh rates +qboolean vid_supportrefreshrate = false; + //GLX prototypes XVisualInfo *(GLAPIENTRY *qglXChooseVisual)(Display *dpy, int screen, int *attribList); GLXContext (GLAPIENTRY *qglXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); @@ -90,20 +91,21 @@ static qboolean mouse_avail = true; static qboolean vid_usingmouse = 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_dga = {CVAR_SAVE, "vid_dga", "1"}; -cvar_t vid_dga_mouseaccel = {0, "vid_dga_mouseaccel", "1"}; +cvar_t vid_dgamouse = {CVAR_SAVE, "vid_dgamouse", "1", "make use of DGA mouse input"}; #endif qboolean vidmode_ext = false; static int win_x, win_y; -static XF86VidModeModeInfo **vidmodes; -static int num_vidmodes; +static XF86VidModeModeInfo init_vidmode; static qboolean vid_isfullscreen = false; static Visual *vidx11_visual; @@ -194,6 +196,7 @@ static int XLateKey(XKeyEvent *ev, char *ascii) case XK_Alt_L: case XK_Meta_L: + case XK_ISO_Level3_Shift: case XK_Alt_R: case XK_Meta_R: key = K_ALT; break; @@ -202,7 +205,7 @@ static int XLateKey(XKeyEvent *ev, char *ascii) case XK_Insert:key = K_INS; break; case XK_KP_Insert: key = K_KP_INS; break; - case XK_KP_Multiply: key = '*'; break; + case XK_KP_Multiply: key = K_KP_MULTIPLY; break; case XK_KP_Add: key = K_KP_PLUS; break; case XK_KP_Subtract: key = K_KP_MINUS; break; case XK_KP_Divide: key = K_KP_SLASH; break; @@ -266,28 +269,17 @@ static void IN_Activate (qboolean grab) XGrabPointer(vidx11_display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); #if !defined(__APPLE__) && !defined(SUNOS) - if (vid_dga.integer) + if (vid_dgamouse.integer && vid_x11_dgasupported) { - int MajorVersion, MinorVersion; - - if (!XF86DGAQueryVersion(vidx11_display, &MajorVersion, &MinorVersion)) - { - // unable to query, probably not supported - Con_Print( "Failed to detect XF86DGA Mouse\n" ); - Cvar_SetValueQuick(&vid_dga, 0); - XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); - } - else - { - XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), XF86DGADirectMouse); - XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, 0, 0); - } + XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), XF86DGADirectMouse); + XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, 0, 0); } else #endif XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); - XGrabKeyboard(vidx11_display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); + if (vid_grabkeyboard.integer || vid_isfullscreen) + XGrabKeyboard(vidx11_display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); mouse_x = mouse_y = 0; cl_ignoremousemove = true; @@ -299,7 +291,7 @@ static void IN_Activate (qboolean grab) if (vid_usingmouse) { #if !defined(__APPLE__) && !defined(SUNOS) - if (vid_dga.integer) + if (vid_x11_dgasupported) XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), 0); #endif @@ -371,10 +363,10 @@ static void HandleEvents(void) if (vid_usingmouse) { #if !defined(__APPLE__) && !defined(SUNOS) - if (vid_dga.integer == 1) + if (vid_dgamouse.integer == 1 && vid_x11_dgasupported) { - mouse_x += event.xmotion.x_root * vid_dga_mouseaccel.value; - mouse_y += event.xmotion.y_root * vid_dga_mouseaccel.value; + mouse_x += event.xmotion.x_root; + mouse_y += event.xmotion.y_root; } else #endif @@ -421,26 +413,29 @@ static void HandleEvents(void) // window changed size/location win_x = event.xconfigure.x; win_y = event.xconfigure.y; + if(vid_resizable.integer < 2) + { + vid.width = event.xconfigure.width; + vid.height = event.xconfigure.height; + } break; case DestroyNotify: // window has been destroyed - Sys_Quit(); + Sys_Quit(0); break; case ClientMessage: // window manager messages if ((event.xclient.format == 32) && ((unsigned int)event.xclient.data.l[0] == wm_delete_window_atom)) - Sys_Quit(); + Sys_Quit(0); break; case MapNotify: // window restored vid_hidden = false; - vid_activewindow = false; VID_RestoreSystemGamma(); break; case UnmapNotify: // window iconified/rolledup/whatever vid_hidden = true; - vid_activewindow = false; VID_RestoreSystemGamma(); break; case FocusIn: @@ -488,12 +483,12 @@ static int GL_OpenLibrary(const char *name) { Con_Printf("Loading OpenGL driver %s\n", name); GL_CloseLibrary(); - if (!(prjobj = dlopen(name, RTLD_LAZY))) + if (!(prjobj = dlopen(name, RTLD_LAZY | RTLD_GLOBAL))) { Con_Printf("Unable to open symbol list for %s\n", name); return false; } - strcpy(gl_driver, name); + strlcpy(gl_driver, name, sizeof(gl_driver)); return true; } @@ -519,7 +514,7 @@ void VID_Shutdown(void) // FIXME: glXDestroyContext here? if (vid_isfullscreen) - XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, vidmodes[0]); + XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, &init_vidmode); if (win) XDestroyWindow(vidx11_display, win); XCloseDisplay(vidx11_display); @@ -538,8 +533,7 @@ void signal_handler(int sig) { Con_Printf("Received signal %d, exiting...\n", sig); VID_RestoreSystemGamma(); - Sys_Quit(); - exit(0); + Sys_Quit(1); } void InitSig(void) @@ -556,7 +550,7 @@ void InitSig(void) signal(SIGTERM, signal_handler); } -void VID_Finish (void) +void VID_Finish (qboolean allowmousegrab) { qboolean vid_usemouse; @@ -568,9 +562,9 @@ void VID_Finish (void) 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 + // handle the mouse state when windowed if that's changed vid_usemouse = false; - if (vid_mouse.integer && !key_consoleactive && !cls.demoplayback) + if (allowmousegrab && vid_mouse.integer && !key_consoleactive && (key_dest != key_game || !cls.demoplayback)) vid_usemouse = true; if (!vid_activewindow) vid_usemouse = false; @@ -580,35 +574,40 @@ void VID_Finish (void) if (r_render.integer) { + CHECKGLERROR if (r_speeds.integer || gl_finish.integer) - qglFinish(); - qglXSwapBuffers(vidx11_display, win); + { + qglFinish();CHECKGLERROR + } + qglXSwapBuffers(vidx11_display, win);CHECKGLERROR } + + if (vid_x11_hardwaregammasupported) + VID_UpdateGamma(false, vid_x11_gammarampsize); } -int VID_SetGamma(unsigned short *ramps) +int VID_SetGamma(unsigned short *ramps, int rampsize) { - return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512); + return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, rampsize, ramps, ramps + rampsize, ramps + rampsize*2); } -int VID_GetGamma(unsigned short *ramps) +int VID_GetGamma(unsigned short *ramps, int rampsize) { - return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512); + return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, rampsize, ramps, ramps + rampsize, ramps + rampsize*2); } void VID_Init(void) { #if !defined(__APPLE__) && !defined(SUNOS) - Cvar_RegisterVariable (&vid_dga); - Cvar_RegisterVariable (&vid_dga_mouseaccel); + Cvar_RegisterVariable (&vid_dgamouse); #endif InitSig(); // trap evil signals // COMMANDLINEOPTION: Input: -nomouse disables mouse support (see also vid_mouse cvar) - if (COM_CheckParm ("-nomouse") || COM_CheckParm("-safe")) + if (COM_CheckParm ("-nomouse")) mouse_avail = false; } -void VID_BuildGLXAttrib(int *attrib, int stencil) +void VID_BuildGLXAttrib(int *attrib, qboolean stencil, qboolean stereobuffer) { *attrib++ = GLX_RGBA; *attrib++ = GLX_RED_SIZE;*attrib++ = 1; @@ -622,14 +621,19 @@ void VID_BuildGLXAttrib(int *attrib, int stencil) *attrib++ = GLX_STENCIL_SIZE;*attrib++ = 8; *attrib++ = GLX_ALPHA_SIZE;*attrib++ = 1; } + if (stereobuffer) + *attrib++ = GLX_STEREO; *attrib++ = None; } -int VID_InitMode(int fullscreen, int width, int height, int bpp) +int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer) { int i; int attrib[32]; XSetWindowAttributes attr; + XClassHint *clshints; + XWMHints *wmhints; + XSizeHints *szhints; unsigned long mask; Window root; XVisualInfo *visinfo; @@ -683,7 +687,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp) return false; } - VID_BuildGLXAttrib(attrib, bpp == 32); + VID_BuildGLXAttrib(attrib, bpp == 32, stereobuffer); visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib); if (!visinfo) { @@ -698,6 +702,14 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp) // Are we going fullscreen? If so, let's change video mode if (fullscreen) { + XF86VidModeModeLine *current_vidmode; + XF86VidModeModeInfo **vidmodes; + int num_vidmodes; + + // This nice hack comes from the SDL source code + current_vidmode = (XF86VidModeModeLine*)((char*)&init_vidmode + sizeof(init_vidmode.dotclock)); + XF86VidModeGetModeLine(vidx11_display, vidx11_screen, (int*)&init_vidmode.dotclock, current_vidmode); + XF86VidModeGetAllModeLines(vidx11_display, vidx11_screen, &num_vidmodes, &vidmodes); best_dist = 9999999; best_fit = -1; @@ -734,6 +746,8 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp) } else fullscreen = 0; + + free(vidmodes); } } @@ -757,7 +771,30 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp) mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(vidx11_display, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); - XStoreName(vidx11_display, win, gamename); + + wmhints = XAllocWMHints(); + if(XpmCreatePixmapFromData(vidx11_display, win, + (gamemode == GAME_NEXUIZ) ? nexuiz_xpm : darkplaces_xpm, + &wmhints->icon_pixmap, &wmhints->icon_mask, NULL) == XpmSuccess) + wmhints->flags |= IconPixmapHint | IconMaskHint; + + clshints = XAllocClassHint(); + clshints->res_name = strdup(gamename); + clshints->res_class = strdup("DarkPlaces"); + + szhints = XAllocSizeHints(); + if(vid_resizable.integer == 0) + { + szhints->min_width = szhints->max_width = width; + szhints->min_height = szhints->max_height = height; + szhints->flags |= PMinSize | PMaxSize; + } + + XmbSetWMProperties(vidx11_display, win, gamename, gamename, (char **) com_argv, com_argc, szhints, wmhints, clshints); + XFree(clshints); + XFree(wmhints); + XFree(szhints); + //XStoreName(vidx11_display, win, gamename); XMapWindow(vidx11_display, win); // LordHavoc: making the close button on a window do the right thing @@ -820,12 +857,38 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp) vid_usingvsync = false; vid_hidden = false; vid_activewindow = true; + vid_x11_hardwaregammasupported = XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &vid_x11_gammarampsize) != 0; +#if !defined(__APPLE__) && !defined(SUNOS) + vid_x11_dgasupported = XF86DGAQueryVersion(vidx11_display, &MajorVersion, &MinorVersion); + if (!vid_x11_dgasupported) + Con_Print( "Failed to detect XF86DGA Mouse extension\n" ); +#endif GL_Init(); return true; } void Sys_SendKeyEvents(void) { + static qboolean sound_active = true; + + // enable/disable sound on focus gain/loss + if (!vid_hidden && (vid_activewindow || !snd_mutewhenidle.integer)) + { + if (!sound_active) + { + S_UnblockSound (); + sound_active = true; + } + } + else + { + if (sound_active) + { + S_BlockSound (); + sound_active = false; + } + } + HandleEvents(); }