Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-//#include <termios.h>
-//#include <sys/ioctl.h>
-//#include <sys/stat.h>
-//#include <sys/vt.h>
-//#include <stdarg.h>
-//#include <stdio.h>
#include <signal.h>
#include <dlfcn.h>
#include <X11/Xutil.h>
#include <GL/glx.h>
+#include "quakedef.h"
+
#include <X11/keysym.h>
#include <X11/cursorfont.h>
+#include <X11/xpm.h>
#include <X11/extensions/XShm.h>
#if !defined(__APPLE__) && !defined(__MACH__) && !defined(SUNOS)
#endif
#include <X11/extensions/xf86vmode.h>
-#include "quakedef.h"
+#include "nexuiz.xpm"
+#include "darkplaces.xpm"
// Tell startup code that we have a client
int cl_available = 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)
-// FIXME: vid_dga_mouseaccel is poorly named, it is actually the multiplier for mouse movement, not an acceleration (which would be a power function or something)
-cvar_t vid_dga = {CVAR_SAVE, "vid_dga", "1", "make use of DGA mouse input"};
-cvar_t vid_dga_mouseaccel = {0, "vid_dga_mouseaccel", "1", "speed of mouse when using DGA mouse input"};
+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;
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;
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;
return;
if (grab)
{
+#if !defined(__APPLE__) && !defined(SUNOS)
+ if(vid_usingmouse && (vid_usingdgamouse != !!vid_dgamouse.integer))
+ IN_Activate(false); // ungrab first!
+#endif
if (!vid_usingmouse && mouse_avail && win)
{
XWindowAttributes attribs_1;
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;
+ 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_dga.integer)
+ if (vid_x11_dgasupported)
XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), 0);
#endif
if (win)
XUndefineCursor(vidx11_display, win);
- cl_ignoremousemove = true;
+ cl_ignoremousemoves = 2;
vid_usingmouse = false;
}
}
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
// 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:
{
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;
}
{
Con_Printf("Received signal %d, exiting...\n", sig);
VID_RestoreSystemGamma();
- Sys_Quit();
- exit(0);
+ Sys_Quit(1);
}
void InitSig(void)
void VID_Finish (qboolean allowmousegrab)
{
- int rampsize;
qboolean vid_usemouse;
vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable;
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 (allowmousegrab && 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;
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(XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &rampsize))
- VID_UpdateGamma(false, rampsize);
+ if (vid_x11_hardwaregammasupported)
+ VID_UpdateGamma(false, vid_x11_gammarampsize);
}
int VID_SetGamma(unsigned short *ramps, int rampsize)
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, 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 > 1)
+ {
+ *attrib++ = GLX_SAMPLE_BUFFERS_ARB;
+ *attrib++ = 1;
+ *attrib++ = GLX_SAMPLES_ARB;
+ *attrib++ = samples;
}
*attrib++ = None;
}
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer, int samples)
{
int i;
int attrib[32];
XSetWindowAttributes attr;
+ XClassHint *clshints;
+ XWMHints *wmhints;
+ XSizeHints *szhints;
unsigned long mask;
Window root;
XVisualInfo *visinfo;
return false;
}
- VID_BuildGLXAttrib(attrib, bpp == 32);
+ 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");
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
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);
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();
}