#include <X11/cursorfont.h>
#include <X11/extensions/XShm.h>
+#if !defined(__APPLE__) && !defined(__MACH__) && !defined(SUNOS)
#include <X11/extensions/xf86dga.h>
+#endif
#include <X11/extensions/xf86vmode.h>
#include "quakedef.h"
+// 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);
{NULL, NULL}
};
-//GLX_SGI_video_sync
-GLint (GLAPIENTRY *qglXGetVideoSyncSGI)(GLuint *count);
-GLint (GLAPIENTRY *qglXWaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count);
+//GLX_SGI_swap_control
+GLint (GLAPIENTRY *qglXSwapIntervalSGI)(GLint interval);
-static dllfunction_t videosyncfuncs[] =
+static dllfunction_t swapcontrolfuncs[] =
{
- {"glXGetVideoSyncSGI", (void **) &qglXGetVideoSyncSGI},
- {"glXWaitVideoSyncSGI", (void **) &qglXWaitVideoSyncSGI},
+ {"glXSwapIntervalSGI", (void **) &qglXSwapIntervalSGI},
{NULL, NULL}
};
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
- PointerMotionMask | ButtonMotionMask )
-#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask )
+ PointerMotionMask | ButtonMotionMask)
+#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | \
+ StructureNotifyMask | FocusChangeMask | EnterWindowMask | \
+ LeaveWindowMask)
-static qboolean mouse_avail = true;
-static qboolean mouse_active = false, usingmouse = false;
+static qboolean mouse_avail = true;
+static qboolean vid_usingmouse = false;
+static qboolean vid_usingvsync = false;
+static qboolean vid_usevsync = false;
static float mouse_x, mouse_y;
static int p_mouse_x, p_mouse_y;
-cvar_t vid_dga = {CVAR_SAVE, "vid_dga", "1"};
-cvar_t vid_dga_mouseaccel = {0, "vid_dga_mouseaccel", "1"};
+#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"};
+#endif
qboolean vidmode_ext = false;
static int win_x, win_y;
-static int scr_width, scr_height;
-
-static XF86VidModeModeInfo **vidmodes;
-static int num_vidmodes;
-static qboolean vidmode_active = false;
+static XF86VidModeModeInfo init_vidmode;
+static qboolean vid_isfullscreen = false;
static Visual *vidx11_visual;
static Colormap vidx11_colormap;
/*-----------------------------------------------------------------------*/
-static int XLateKey(XKeyEvent *ev)
+static int XLateKey(XKeyEvent *ev, char *ascii)
{
int key = 0;
char buf[64];
- KeySym keysym;
+ KeySym keysym, shifted;
- XLookupString(ev, buf, sizeof buf, &keysym, 0);
+ keysym = XLookupKeysym (ev, 0);
+ XLookupString(ev, buf, sizeof buf, &shifted, 0);
+ *ascii = buf[0];
switch(keysym)
{
case XK_KP_Subtract: key = K_KP_MINUS; break;
case XK_KP_Divide: key = K_KP_SLASH; break;
-#if 0
- case 0x021: key = '1';break;/* [!] */
- case 0x040: key = '2';break;/* [@] */
- case 0x023: key = '3';break;/* [#] */
- case 0x024: key = '4';break;/* [$] */
- case 0x025: key = '5';break;/* [%] */
- case 0x05e: key = '6';break;/* [^] */
- case 0x026: key = '7';break;/* [&] */
- case 0x02a: key = '8';break;/* [*] */
- case 0x028: key = '9';;break;/* [(] */
- case 0x029: key = '0';break;/* [)] */
- case 0x05f: key = '-';break;/* [_] */
- case 0x02b: key = '=';break;/* [+] */
- case 0x07c: key = '\'';break;/* [|] */
- case 0x07d: key = '[';break;/* [}] */
- case 0x07b: key = ']';break;/* [{] */
- case 0x022: key = '\'';break;/* ["] */
- case 0x03a: key = ';';break;/* [:] */
- case 0x03f: key = '/';break;/* [?] */
- case 0x03e: key = '.';break;/* [>] */
- case 0x03c: key = ',';break;/* [<] */
-#endif
+ case XK_section: key = '~'; break;
default:
- key = *(unsigned char*)buf;
- if (key >= 'A' && key <= 'Z')
- key = key - 'A' + 'a';
+ if (keysym < 32)
+ break;
+
+ if (keysym >= 'A' && keysym <= 'Z')
+ key = keysym - 'A' + 'a';
+ else
+ key = keysym;
+
break;
}
return cursor;
}
-static void install_grabs(void)
+static void IN_Activate (qboolean grab)
{
- XWindowAttributes attribs_1;
- XSetWindowAttributes attribs_2;
+ if (!vidx11_display)
+ return;
+ if (grab)
+ {
+ if (!vid_usingmouse && mouse_avail && win)
+ {
+ XWindowAttributes attribs_1;
+ XSetWindowAttributes attribs_2;
- XGetWindowAttributes(vidx11_display, win, &attribs_1);
- attribs_2.event_mask = attribs_1.your_event_mask | KEY_MASK | MOUSE_MASK;
- XChangeWindowAttributes(vidx11_display, win, CWEventMask, &attribs_2);
+ XGetWindowAttributes(vidx11_display, win, &attribs_1);
+ 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));
+ // inviso cursor
+ XDefineCursor(vidx11_display, win, CreateNullCursor(vidx11_display, win));
- XGrabPointer(vidx11_display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
+ XGrabPointer(vidx11_display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
- if (vid_dga.integer)
- {
- int MajorVersion, MinorVersion;
+#if !defined(__APPLE__) && !defined(SUNOS)
+ if (vid_dga.integer)
+ {
+ int MajorVersion, MinorVersion;
- if (!XF86DGAQueryVersion(vidx11_display, &MajorVersion, &MinorVersion))
- {
- // unable to query, probalby not supported
- Con_Printf( "Failed to detect XF86DGA Mouse\n" );
- vid_dga.integer = 0;
- }
- else
- {
- vid_dga.integer = 1;
- XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), XF86DGADirectMouse);
- XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, 0, 0);
+ 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);
+ }
+ }
+ 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);
+
+ mouse_x = mouse_y = 0;
+ cl_ignoremousemove = true;
+ vid_usingmouse = true;
}
}
else
- XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, scr_width / 2, scr_height / 2);
+ {
+ if (vid_usingmouse)
+ {
+#if !defined(__APPLE__) && !defined(SUNOS)
+ if (vid_dga.integer)
+ XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), 0);
+#endif
- XGrabKeyboard(vidx11_display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XUngrabPointer(vidx11_display, CurrentTime);
+ XUngrabKeyboard(vidx11_display, CurrentTime);
- mouse_active = true;
- mouse_x = mouse_y = 0;
+ // inviso cursor
+ if (win)
+ XUndefineCursor(vidx11_display, win);
+
+ cl_ignoremousemove = true;
+ vid_usingmouse = false;
+ }
+ }
}
-static void uninstall_grabs(void)
+static keynum_t buttonremap[18] =
{
- if (!vidx11_display || !win)
- return;
-
- if (vid_dga.integer == 1)
- XF86DGADirectVideo(vidx11_display, DefaultScreen(vidx11_display), 0);
-
- XUngrabPointer(vidx11_display, CurrentTime);
- XUngrabKeyboard(vidx11_display, CurrentTime);
-
-// inviso cursor
- XUndefineCursor(vidx11_display, win);
-
- mouse_active = false;
-}
+ K_MOUSE1,
+ K_MOUSE3,
+ K_MOUSE2,
+ K_MWHEELUP,
+ K_MWHEELDOWN,
+ K_MOUSE4,
+ K_MOUSE5,
+ K_MOUSE6,
+ K_MOUSE7,
+ K_MOUSE8,
+ K_MOUSE9,
+ K_MOUSE10,
+ K_MOUSE11,
+ K_MOUSE12,
+ K_MOUSE13,
+ K_MOUSE14,
+ K_MOUSE15,
+ K_MOUSE16,
+};
static void HandleEvents(void)
{
XEvent event;
+ int key;
+ char ascii;
qboolean dowarp = false;
if (!vidx11_display)
{
case KeyPress:
// key pressed
- Key_Event(XLateKey(&event.xkey), true);
+ key = XLateKey (&event.xkey, &ascii);
+ Key_Event(key, ascii, true);
break;
case KeyRelease:
// key released
- Key_Event(XLateKey(&event.xkey), false);
+ key = XLateKey (&event.xkey, &ascii);
+ Key_Event(key, ascii, false);
break;
case MotionNotify:
// mouse moved
- if (usingmouse)
+ if (vid_usingmouse)
{
+#if !defined(__APPLE__) && !defined(SUNOS)
if (vid_dga.integer == 1)
{
mouse_x += event.xmotion.x_root * vid_dga_mouseaccel.value;
mouse_y += event.xmotion.y_root * vid_dga_mouseaccel.value;
}
else
+#endif
{
if (!event.xmotion.send_event)
{
mouse_x += event.xmotion.x - p_mouse_x;
mouse_y += event.xmotion.y - p_mouse_y;
- if (abs(scr_width/2 - event.xmotion.x) > scr_width / 4 || abs(scr_height/2 - event.xmotion.y) > scr_height / 4)
+ 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);
+ //else
+ // ui_mouseupdate(event.xmotion.x, event.xmotion.y);
break;
case ButtonPress:
// mouse button pressed
- switch(event.xbutton.button)
- {
- case 1:
- Key_Event(K_MOUSE1, true);
- break;
- case 2:
- Key_Event(K_MOUSE3, true);
- break;
- case 3:
- Key_Event(K_MOUSE2, true);
- break;
- case 4:
- Key_Event(K_MWHEELUP, true);
- break;
- case 5:
- Key_Event(K_MWHEELDOWN, true);
- break;
- default:
- Con_Printf("HandleEvents: ButtonPress gave value %d, 1-5 expected\n", event.xbutton.button);
- break;
- }
+ if (event.xbutton.button <= 18)
+ Key_Event(buttonremap[event.xbutton.button - 1], 0, true);
+ else
+ Con_Printf("HandleEvents: ButtonPress gave value %d, 1-18 expected\n", event.xbutton.button);
break;
case ButtonRelease:
// mouse button released
- switch(event.xbutton.button)
- {
- case 1:
- Key_Event(K_MOUSE1, false);
- break;
- case 2:
- Key_Event(K_MOUSE3, false);
- break;
- case 3:
- Key_Event(K_MOUSE2, false);
- break;
- case 4:
- Key_Event(K_MWHEELUP, false);
- break;
- case 5:
- Key_Event(K_MWHEELDOWN, false);
- break;
- default:
- Con_Printf("HandleEvents: ButtonRelease gave value %d, 1-5 expected\n", event.xbutton.button);
- break;
- }
+ if (event.xbutton.button <= 18)
+ Key_Event(buttonremap[event.xbutton.button - 1], 0, false);
+ else
+ Con_Printf("HandleEvents: ButtonRelease gave value %d, 1-18 expected\n", event.xbutton.button);
break;
case CreateNotify:
break;
case ClientMessage:
// window manager messages
- if ((event.xclient.format == 32) && (event.xclient.data.l[0] == wm_delete_window_atom))
+ if ((event.xclient.format == 32) && ((unsigned int)event.xclient.data.l[0] == wm_delete_window_atom))
Sys_Quit();
break;
case MapNotify:
// window restored
vid_hidden = false;
- vid_allowhwgamma = true;
+ vid_activewindow = false;
+ VID_RestoreSystemGamma();
break;
case UnmapNotify:
// window iconified/rolledup/whatever
vid_hidden = true;
- vid_allowhwgamma = false;
+ vid_activewindow = false;
VID_RestoreSystemGamma();
break;
case FocusIn:
// window is now the input focus
- vid_allowhwgamma = true;
+ vid_activewindow = true;
break;
case FocusOut:
// window is no longer the input focus
- vid_allowhwgamma = false;
+ vid_activewindow = false;
VID_RestoreSystemGamma();
break;
case EnterNotify:
// mouse entered window
- vid_allowhwgamma = true;
break;
case LeaveNotify:
// mouse left window
- vid_allowhwgamma = false;
- VID_RestoreSystemGamma();
break;
}
}
if (dowarp)
{
/* move the mouse to the window center again */
- p_mouse_x = scr_width / 2;
- p_mouse_y = scr_height / 2;
+ 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);
}
-
}
-static void IN_DeactivateMouse( void )
+static void *prjobj = NULL;
+
+static void GL_CloseLibrary(void)
{
- if (!mouse_avail || !vidx11_display || !win)
- return;
+ if (prjobj)
+ dlclose(prjobj);
+ prjobj = NULL;
+ gl_driver[0] = 0;
+ qglXGetProcAddressARB = NULL;
+ gl_extensions = "";
+ gl_platform = "";
+ gl_platformextensions = "";
+}
- if (mouse_active)
+static int GL_OpenLibrary(const char *name)
+{
+ Con_Printf("Loading OpenGL driver %s\n", name);
+ GL_CloseLibrary();
+ if (!(prjobj = dlopen(name, RTLD_LAZY)))
{
- uninstall_grabs();
- mouse_active = false;
+ Con_Printf("Unable to open symbol list for %s\n", name);
+ return false;
}
+ strcpy(gl_driver, name);
+ return true;
}
-static void IN_ActivateMouse( void )
+void *GL_GetProcAddress(const char *name)
{
- if (!mouse_avail || !vidx11_display || !win)
- return;
-
- if (!mouse_active)
- {
- mouse_x = mouse_y = 0; // don't spazz
- install_grabs();
- mouse_active = true;
- }
+ void *p = NULL;
+ if (qglXGetProcAddressARB != NULL)
+ p = (void *) qglXGetProcAddressARB((GLubyte *)name);
+ if (p == NULL)
+ p = (void *) dlsym(prjobj, name);
+ return p;
}
void VID_Shutdown(void)
if (!ctx || !vidx11_display)
return;
- vid_hidden = true;
- usingmouse = false;
if (vidx11_display)
{
+ IN_Activate(false);
VID_RestoreSystemGamma();
- uninstall_grabs();
// FIXME: glXDestroyContext here?
- if (vidmode_active)
- XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, vidmodes[0]);
+ if (vid_isfullscreen)
+ XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, &init_vidmode);
if (win)
XDestroyWindow(vidx11_display, win);
XCloseDisplay(vidx11_display);
}
- vidmode_active = false;
+ vid_hidden = true;
+ vid_isfullscreen = false;
vidx11_display = NULL;
win = 0;
ctx = NULL;
GL_CloseLibrary();
+ Key_ClearStates ();
}
void signal_handler(int sig)
{
- printf("Received signal %d, exiting...\n", sig);
+ Con_Printf("Received signal %d, exiting...\n", sig);
VID_RestoreSystemGamma();
Sys_Quit();
exit(0);
signal(SIGTERM, signal_handler);
}
-/*
-=================
-VID_GetWindowSize
-=================
-*/
-void VID_GetWindowSize (int *x, int *y, int *width, int *height)
-{
- *x = *y = 0;
- *width = scr_width;
- *height = scr_height;
-}
-
void VID_Finish (void)
{
- int usemouse;
- if (r_render.integer)
+ qboolean vid_usemouse;
+
+ vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable;
+ if (vid_usingvsync != vid_usevsync && gl_videosyncavailable)
{
- qglFinish();
- qglXSwapBuffers(vidx11_display, win);
+ vid_usingvsync = vid_usevsync;
+ if (qglXSwapIntervalSGI (vid_usevsync))
+ 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
- usemouse = false;
- if (vid_mouse.integer && !key_consoleactive)
- usemouse = true;
- if (vidmode_active)
- usemouse = true;
- if (usemouse)
- {
- if (!usingmouse)
- {
- usingmouse = true;
- IN_ActivateMouse ();
- }
- }
- else
+ vid_usemouse = false;
+ if (vid_mouse.integer && !key_consoleactive && !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)
{
- if (usingmouse)
- {
- usingmouse = false;
- IN_DeactivateMouse ();
- }
+ if (r_speeds.integer || gl_finish.integer)
+ qglFinish();
+ qglXSwapBuffers(vidx11_display, win);
}
}
int VID_SetGamma(unsigned short *ramps)
{
+ int rampsize;
+ // FIXME: it would be good to generate ramps of the size reported by X,
+ // for instance Quadro cards seem to use 1024 color ramps not 256
+ if(!XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &rampsize))
+ return 0;
+ if(rampsize != 256)
+ return 0;
return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512);
}
int VID_GetGamma(unsigned short *ramps)
{
+ int rampsize;
+ if(!XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &rampsize))
+ return 0;
+ if(rampsize != 256)
+ return 0;
return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512);
}
void VID_Init(void)
{
+#if !defined(__APPLE__) && !defined(SUNOS)
Cvar_RegisterVariable (&vid_dga);
Cvar_RegisterVariable (&vid_dga_mouseaccel);
+#endif
InitSig(); // trap evil signals
+// COMMANDLINEOPTION: Input: -nomouse disables mouse support (see also vid_mouse cvar)
if (COM_CheckParm ("-nomouse") || COM_CheckParm("-safe"))
mouse_avail = false;
}
*attrib++ = None;
}
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int stencil)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate)
{
int i;
int attrib[32];
int MajorVersion, MinorVersion;
const char *drivername;
+#if defined(__APPLE__) && defined(__MACH__)
+ drivername = "/usr/X11R6/lib/libGL.1.dylib";
+#else
drivername = "libGL.so.1";
+#endif
+// COMMANDLINEOPTION: Linux GLX: -gl_driver <drivername> selects a GL driver library, default is libGL.so.1, useful only for using fxmesa or similar, if you don't know what this is for, you don't need it
+// COMMANDLINEOPTION: BSD GLX: -gl_driver <drivername> selects a GL driver library, default is libGL.so.1, useful only for using fxmesa or similar, if you don't know what this is for, you don't need it
+// LordHavoc: although this works on MacOSX, it's useless there (as there is only one system libGL)
i = COM_CheckParm("-gl_driver");
if (i && i < com_argc - 1)
drivername = com_argv[i + 1];
if (!(vidx11_display = XOpenDisplay(NULL)))
{
- Con_Printf("Couldn't open the X display\n");
+ Con_Print("Couldn't open the X display\n");
return false;
}
vidmode_ext = false;
else
{
- Con_Printf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion);
+ Con_DPrintf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion);
vidmode_ext = true;
}
- if ((qglXChooseVisual = GL_GetProcAddress("glXChooseVisual")) == NULL
- || (qglXCreateContext = GL_GetProcAddress("glXCreateContext")) == NULL
- || (qglXMakeCurrent = GL_GetProcAddress("glXMakeCurrent")) == NULL
- || (qglXSwapBuffers = GL_GetProcAddress("glXSwapBuffers")) == NULL
- || (qglXQueryExtensionsString = GL_GetProcAddress("glXQueryExtensionsString")) == NULL)
+ if ((qglXChooseVisual = (XVisualInfo *(GLAPIENTRY *)(Display *dpy, int screen, int *attribList))GL_GetProcAddress("glXChooseVisual")) == NULL
+ || (qglXCreateContext = (GLXContext (GLAPIENTRY *)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct))GL_GetProcAddress("glXCreateContext")) == NULL
+ || (qglXDestroyContext = (void (GLAPIENTRY *)(Display *dpy, GLXContext ctx))GL_GetProcAddress("glXDestroyContext")) == NULL
+ || (qglXMakeCurrent = (Bool (GLAPIENTRY *)(Display *dpy, GLXDrawable drawable, GLXContext ctx))GL_GetProcAddress("glXMakeCurrent")) == NULL
+ || (qglXSwapBuffers = (void (GLAPIENTRY *)(Display *dpy, GLXDrawable drawable))GL_GetProcAddress("glXSwapBuffers")) == NULL
+ || (qglXQueryExtensionsString = (const char *(GLAPIENTRY *)(Display *dpy, int screen))GL_GetProcAddress("glXQueryExtensionsString")) == NULL)
{
Con_Printf("glX functions not found in %s\n", gl_driver);
return false;
}
- VID_BuildGLXAttrib(attrib, stencil);
+ VID_BuildGLXAttrib(attrib, bpp == 32);
visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib);
if (!visinfo)
{
- Con_Printf("Couldn't get an RGB, Double-buffered, Depth visual\n");
+ Con_Print("Couldn't get an RGB, Double-buffered, Depth visual\n");
return false;
}
// 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;
// change to the mode
XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, vidmodes[best_fit]);
- vidmode_active = true;
+ vid_isfullscreen = true;
// Move the viewport to top left
XF86VidModeSetViewPort(vidx11_display, vidx11_screen, 0, 0);
}
else
fullscreen = 0;
+
+ free(vidmodes);
}
}
// LordHavoc: save the colormap for later, too
vidx11_colormap = attr.colormap = XCreateColormap(vidx11_display, root, visinfo->visual, AllocNone);
attr.event_mask = X_MASK;
- if (vidmode_active)
+ if (vid_isfullscreen)
{
mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect;
attr.override_redirect = True;
wm_delete_window_atom = XInternAtom(vidx11_display, "WM_DELETE_WINDOW", false);
XSetWMProtocols(vidx11_display, win, &wm_delete_window_atom, 1);
- if (vidmode_active)
+ if (vid_isfullscreen)
{
XMoveWindow(vidx11_display, win, 0, 0);
XRaiseWindow(vidx11_display, win);
ctx = qglXCreateContext(vidx11_display, visinfo, NULL, True);
if (!ctx)
- Sys_Error ("glXCreateContext failed\n");
+ {
+ Con_Printf ("glXCreateContext failed\n");
+ return false;
+ }
if (!qglXMakeCurrent(vidx11_display, win, ctx))
- Sys_Error ("glXMakeCurrent failed\n");
+ {
+ Con_Printf ("glXMakeCurrent failed\n");
+ return false;
+ }
XSync(vidx11_display, False);
- scr_width = width;
- scr_height = height;
-
- if ((qglGetString = GL_GetProcAddress("glGetString")) == NULL)
- Sys_Error("glGetString not found in %s", gl_driver);
+ if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
+ {
+ Con_Printf ("glGetString not found in %s\n", gl_driver);
+ return false;
+ }
- gl_renderer = qglGetString(GL_RENDERER);
- gl_vendor = qglGetString(GL_VENDOR);
- gl_version = qglGetString(GL_VERSION);
- gl_extensions = qglGetString(GL_EXTENSIONS);
+ 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);
+ gl_videosyncavailable = false;
+
+// COMMANDLINEOPTION: Linux GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions)
+// COMMANDLINEOPTION: BSD GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions)
+// COMMANDLINEOPTION: MacOSX GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions)
GL_CheckExtension("GLX_ARB_get_proc_address", getprocaddressfuncs, "-nogetprocaddress", false);
- gl_videosyncavailable = GL_CheckExtension("GLX_SGI_video_sync", videosyncfuncs, "-novideosync", false);
+// COMMANDLINEOPTION: Linux GLX: -novideosync disables GLX_SGI_swap_control
+// COMMANDLINEOPTION: BSD GLX: -novideosync disables GLX_SGI_swap_control
+// COMMANDLINEOPTION: MacOSX GLX: -novideosync disables GLX_SGI_swap_control
+ gl_videosyncavailable = GL_CheckExtension("GLX_SGI_swap_control", swapcontrolfuncs, "-novideosync", false);
- usingmouse = false;
+ vid_usingmouse = false;
+ vid_usingvsync = false;
vid_hidden = false;
- vid_allowhwgamma = true;
+ vid_activewindow = true;
GL_Init();
return true;
}
HandleEvents();
}
-/*
-===========
-IN_Commands
-===========
-*/
-void IN_Commands (void)
-{
-}
-
-void IN_Move (usercmd_t *cmd)
+void IN_Move (void)
{
if (mouse_avail)
- IN_Mouse(cmd, mouse_x, mouse_y);
- mouse_x = 0;
- mouse_y = 0;
-}
-
-static void *prjobj = NULL;
-
-int GL_OpenLibrary(const char *name)
-{
- Con_Printf("Loading GL driver %s\n", name);
- GL_CloseLibrary();
- if (!(prjobj = dlopen(name, RTLD_LAZY)))
{
- Con_Printf("Unable to open symbol list for %s\n", name);
- return false;
+ in_mouse_x = mouse_x;
+ in_mouse_y = mouse_y;
}
- strcpy(gl_driver, name);
- return true;
-}
-
-void GL_CloseLibrary(void)
-{
- if (prjobj)
- dlclose(prjobj);
- prjobj = NULL;
- gl_driver[0] = 0;
- qglXGetProcAddressARB = NULL;
- gl_extensions = "";
- gl_platform = "";
- gl_platformextensions = "";
-}
-
-void *GL_GetProcAddress(const char *name)
-{
- void *p = NULL;
- if (qglXGetProcAddressARB != NULL)
- p = (void *) qglXGetProcAddressARB(name);
- if (p == NULL)
- p = (void *) dlsym(prjobj, name);
- return p;
+ mouse_x = 0;
+ mouse_y = 0;
}