diff --git a/include/client.h b/include/client.h index 88b72f6..8eae42d 100644 --- a/include/client.h +++ b/include/client.h @@ -349,8 +349,6 @@ extern cvar_t *m_yaw; extern cvar_t *m_forward; extern cvar_t *m_side; -extern cvar_t *_windowed_mouse; - extern cvar_t *name; diff --git a/include/context_x11.h b/include/context_x11.h index a6ba888..658d4ec 100644 --- a/include/context_x11.h +++ b/include/context_x11.h @@ -33,10 +33,15 @@ #include #include +#include void GetEvent( void ); extern Display *x_disp; +extern int x_screen; +extern Window x_root; +extern XVisualInfo *x_visinfo; +extern Visual *x_vis; extern Window x_win; extern qboolean doShm; extern int x_shmeventtype; @@ -48,5 +53,10 @@ void x11_process_event( void ); void x11_process_events( void ); void x11_open_display( void ); void x11_close_display( void ); +void x11_create_null_cursor(void); +void x11_set_vidmode(int width, int height); +void x11_restore_vidmode(void); +void x11_create_window(int width, int height); +void x11_grab_keyboard(void); #endif // __CONTEXT_X11_H__ diff --git a/include/dga_check.h b/include/dga_check.h index 87fa7b7..a70ccba 100644 --- a/include/dga_check.h +++ b/include/dga_check.h @@ -33,6 +33,8 @@ #include +#include "cvar.h" + extern cvar_t *vid_dga_mouseaccel; /* diff --git a/include/input.h b/include/input.h index 906c355..64448c0 100644 --- a/include/input.h +++ b/include/input.h @@ -30,6 +30,7 @@ #define _INPUT_H #include "protocol.h" +#include "cvar.h" #define freelook (in_mlook.state&1 || cl_freelook->value) @@ -49,4 +50,6 @@ void IN_Move (usercmd_t *cmd); void IN_ModeChanged (void); // called whenever screen dimensions change +extern cvar_t *_windowed_mouse; + #endif // _INPUT_H diff --git a/source/context_x11.c b/source/context_x11.c index 01757bb..3215913 100644 --- a/source/context_x11.c +++ b/source/context_x11.c @@ -49,11 +49,20 @@ #include #include #include +#include -#include -#include -#include -#include +#ifdef HAVE_VIDMODE +# include +#endif + +#include "context_x11.h" +#include "dga_check.h" +#include "qtypes.h" +#include "vid.h" +#include "sys.h" +#include "console.h" +#include "cvar.h" +#include "input.h" static void (*event_handlers[LASTEvent]) (XEvent *); qboolean oktodraw = false; @@ -62,6 +71,27 @@ int x_shmeventtype; static int x_disp_ref_count = 0; Display *x_disp = NULL; +int x_screen; +Window x_root = None; +XVisualInfo *x_visinfo; +Visual *x_vis; +Window x_win; +Cursor nullcursor = None; +static Atom aWMDelete = 0; + +#define X_MASK (VisibilityChangeMask | StructureNotifyMask | ExposureMask) + +#ifdef HAVE_VIDMODE +static XF86VidModeModeInfo **vidmodes; +static int nummodes, hasvidmode = 0; +#endif + +cvar_t *vid_fullscreen; + +static int xss_timeout; +static int xss_interval; +static int xss_blanking; +static int xss_exposures; qboolean x11_add_event(int event, void (*event_handler)(XEvent *)) @@ -138,6 +168,9 @@ x11_open_display( void ) Sys_Error("x11_open_display: Could not open display [%s]\n", XDisplayName( NULL )); } + x_screen = DefaultScreen (x_disp); + x_root = RootWindow (x_disp, x_screen); + // catch signals signal(SIGHUP, TragicDeath); signal(SIGINT, TragicDeath); @@ -162,8 +195,163 @@ x11_open_display( void ) void x11_close_display( void ) { + if (nullcursor != None) { + XFreeCursor(x_disp, nullcursor); + nullcursor = None; + } if (!--x_disp_ref_count) { XCloseDisplay( x_disp ); x_disp = NULL; } } + +/* + x11_create_null_cursor + + Create an empty cursor +*/ +void +x11_create_null_cursor(void) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + + if (nullcursor != None) return; + + cursormask = XCreatePixmap(x_disp, x_root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(x_disp, cursormask, GCFunction, &xgc); + XFillRectangle(x_disp, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + nullcursor = XCreatePixmapCursor(x_disp, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(x_disp,cursormask); + XFreeGC(x_disp,gc); + XDefineCursor(x_disp, x_win, nullcursor); +} + +void +x11_set_vidmode(int width, int height) +{ + int i; + + vid_fullscreen = Cvar_Get ("vid_fullscreen","0",0,"None"); + + XGetScreenSaver (x_disp, &xss_timeout, &xss_interval, &xss_blanking, + &xss_exposures); + XSetScreenSaver (x_disp, 0, xss_interval, xss_blanking, + xss_exposures); + +#ifdef XMESA + const char *str = getenv("MESA_GLX_FX"); + if (str != NULL && *str != 'd') { + if (tolower(*str) == 'w') { + Cvar_Set (vid_fullscreen, "0"); + } else { + Cvar_Set (vid_fullscreen, "1"); + } + } +#endif + +#ifdef HAVE_VIDMODE + hasvidmode = VID_CheckVMode(x_disp, NULL, NULL); + if (hasvidmode) { + if (! XF86VidModeGetAllModeLines(x_disp, DefaultScreen(x_disp), + &nummodes, &vidmodes) + || nummodes <= 0) { + hasvidmode = 0; + } + } + Con_SafePrintf ("hasvidmode = %i\nnummodes = %i\n", hasvidmode, nummodes); + + if (hasvidmode && vid_fullscreen->value) { + int smallest_mode=0, x=MAXINT, y=MAXINT; + + // FIXME: does this depend on mode line order in XF86Config? + for (i=0; ividmodes[i]->hdisplay || y>vidmodes[i]->vdisplay) { + smallest_mode=i; + x=vidmodes[i]->hdisplay; + y=vidmodes[i]->vdisplay; + } + printf("%dx%d\n",vidmodes[i]->hdisplay,vidmodes[i]->vdisplay); + } + // chose the smallest mode that our window fits into; + for (i=smallest_mode; + i!=(smallest_mode+1)%nummodes; + i=(i?i-1:nummodes-1)) { + if (vidmodes[i]->hdisplay>=width + && vidmodes[i]->vdisplay>=height) { + XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp), + vidmodes[i]); + break; + } + } + XF86VidModeSetViewPort(x_disp, DefaultScreen (x_disp), 0, 0); + _windowed_mouse = Cvar_Get ("_windowed_mouse","1",CVAR_ARCHIVE|CVAR_ROM,"None"); + } else +#endif + _windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None"); +} + +void +x11_create_window(int width, int height) +{ + XSetWindowAttributes attr; + unsigned long mask; + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(x_disp, x_root, x_vis, AllocNone); + attr.event_mask = X_MASK; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + if (hasvidmode && vid_fullscreen->value) { + attr.override_redirect=1; + mask|=CWOverrideRedirect; + } + + x_win = XCreateWindow(x_disp, x_root, 0, 0, width, height, + 0, x_visinfo->depth, InputOutput, + x_vis, mask, &attr); + /* Give it a title */ + XStoreName(x_disp, x_win, "XQuake"); + + /* Make window respond to Delete events */ + aWMDelete = XInternAtom(x_disp, "WM_DELETE_WINDOW", False); + XSetWMProtocols(x_disp, x_win, &aWMDelete, 1); + + XMapWindow(x_disp, x_win); + XRaiseWindow(x_disp, x_win); +} + +void +x11_restore_vidmode(void) +{ + XSetScreenSaver (x_disp, xss_timeout, xss_interval, xss_blanking, + xss_exposures); + +#ifdef HAVE_VIDMODE + if (hasvidmode) { + XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp), + vidmodes[0]); + XFree(vidmodes); + } +#endif +} + +void +x11_grab_keyboard(void) +{ +#ifdef HAVE_VIDMODE + if (hasvidmode && vid_fullscreen->value) { + XGrabKeyboard(x_disp, x_win, 1, GrabModeAsync, GrabModeAsync, + CurrentTime); + } +#endif +} diff --git a/source/in_x11.c b/source/in_x11.c index f7857c8..e50c650 100644 --- a/source/in_x11.c +++ b/source/in_x11.c @@ -427,6 +427,8 @@ IN_Init(void) _windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None"); m_filter = Cvar_Get ("m_filter","0",CVAR_ARCHIVE,"None"); + XAutoRepeatOff(x_disp); + if (COM_CheckParm("-nomouse")) return 1; #ifdef HAVE_DGA in_dgamouse = Cvar_Get ("in_dgamouse", "0", CVAR_ROM, diff --git a/source/menu.c b/source/menu.c index 90e0358..61d3aa0 100644 --- a/source/menu.c +++ b/source/menu.c @@ -43,6 +43,7 @@ #include "screen.h" #include "client.h" #include "console.h" +#include "input.h" #include "view.h" void (*vid_menudrawfn)(void); diff --git a/source/vid_glx.c b/source/vid_glx.c index 385d7a3..99feb96 100644 --- a/source/vid_glx.c +++ b/source/vid_glx.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_DLFCN_H # include @@ -56,9 +57,6 @@ #ifdef HAVE_DGA # include #endif -#ifdef HAVE_VIDMODE -# include -#endif #ifdef XMESA # include @@ -74,7 +72,9 @@ #include "keys.h" #include "menu.h" #include "sys.h" +#include "quakefs.h" #include "draw.h" +#include "input.h" #include "sbar.h" #include "context_x11.h" #include "dga_check.h" @@ -84,26 +84,16 @@ static qboolean vid_initialized = false; -static int screen; -Window x_win; static GLXContext ctx = NULL; -static Cursor nullcursor = None; - -#define X_MASK (VisibilityChangeMask | StructureNotifyMask) unsigned short d_8to16table[256]; unsigned int d_8to24table[256]; unsigned char d_15to8table[65536]; cvar_t *vid_mode; -cvar_t *vid_fullscreen; extern cvar_t *gl_triplebuffer; extern cvar_t *in_dga_mouseaccel; -#ifdef HAVE_VIDMODE -static XF86VidModeModeInfo **vidmodes; -static int nummodes, hasvidmode = 0; -#endif #ifdef HAVE_DGA static int hasdgavideo = 0; static int hasdga = 0; @@ -149,35 +139,6 @@ int gl_mtex_enum = TEXTURE0_SGIS; qboolean gl_arb_mtex = false; qboolean gl_mtexable = false; -/* -====================== -Create an empty cursor -====================== -*/ - -static void -CreateNullCursor(Display *display, Window root) -{ - Pixmap cursormask; - XGCValues xgc; - GC gc; - XColor dummycolour; - - if (nullcursor != None) return; - - cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); - xgc.function = GXclear; - gc = XCreateGC(display, cursormask, GCFunction, &xgc); - XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); - dummycolour.pixel = 0; - dummycolour.red = 0; - dummycolour.flags = 04; - nullcursor = XCreatePixmapCursor(display, cursormask, cursormask, - &dummycolour,&dummycolour, 0,0); - XFreePixmap(display,cursormask); - XFreeGC(display,gc); -} - /*-----------------------------------------------------------------------*/ void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) @@ -198,28 +159,13 @@ VID_Shutdown(void) XDestroyWindow(x_disp, x_win); glXDestroyContext(x_disp, ctx); -#ifdef HAVE_VIDMODE - if (hasvidmode) { - int i; - - XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp), - vidmodes[0]); - for (i = 0; i < nummodes; i++) { - // if (vidmodes[i]->privsize) XFree(vidmodes[i]->private); - } - XFree(vidmodes); - } -#endif + x11_restore_vidmode(); #ifdef HAVE_DLOPEN if (dlhand) { dlclose(dlhand); dlhand = NULL; } #endif - if (nullcursor != None) { - XFreeCursor(x_disp, nullcursor); - nullcursor = None; - } x11_close_display(); } #if 0 @@ -510,13 +456,8 @@ void VID_Init(unsigned char *palette) }; char gldir[MAX_OSPATH]; int width = 640, height = 480; - XSetWindowAttributes attr; - unsigned long mask; - Window root; - XVisualInfo *visinfo; vid_mode = Cvar_Get ("vid_mode","0",0,"None"); - vid_fullscreen = Cvar_Get ("vid_fullscreen","0",0,"None"); #ifdef HAVE_DGA in_dga_mouseaccel = Cvar_Get("vid_dga_mouseaccel","1",CVAR_ARCHIVE, "None"); @@ -555,14 +496,12 @@ void VID_Init(unsigned char *palette) x11_open_display(); - screen = DefaultScreen(x_disp); - root = RootWindow(x_disp, screen); - - visinfo = glXChooseVisual(x_disp, screen, attrib); - if (!visinfo) { + x_visinfo = glXChooseVisual(x_disp, x_screen, attrib); + if (!x_visinfo) { fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual\n"); exit(1); } + x_vis = x_visinfo->visual; #ifdef HAVE_DGA { @@ -575,17 +514,6 @@ void VID_Init(unsigned char *palette) } Con_SafePrintf ("hasdga = %i\nhasdgavideo = %i\n", hasdga, hasdgavideo); #endif -#ifdef HAVE_VIDMODE - hasvidmode = VID_CheckVMode(x_disp, NULL, NULL); - if (hasvidmode) { - if (! XF86VidModeGetAllModeLines(x_disp, DefaultScreen(x_disp), - &nummodes, &vidmodes) - || nummodes <= 0) { - hasvidmode = 0; - } - } - Con_SafePrintf ("hasvidmode = %i\nnummodes = %i\n", hasvidmode, nummodes); -#endif #ifdef HAVE_DLOPEN dlhand = dlopen(NULL, RTLD_LAZY); if (dlhand) { @@ -617,69 +545,19 @@ void VID_Init(unsigned char *palette) // hasdga = 0; } - /* window attributes */ - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap(x_disp, root, visinfo->visual, AllocNone); - attr.event_mask = X_MASK; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - -#ifdef HAVE_VIDMODE - if (hasvidmode && vid_fullscreen->value) { - int smallest_mode=0, x=MAXINT, y=MAXINT; - - attr.override_redirect=1; - mask|=CWOverrideRedirect; - - // FIXME: does this depend on mode line order in XF86Config? - for (i=0; ividmodes[i]->hdisplay || y>vidmodes[i]->vdisplay) { - smallest_mode=i; - x=vidmodes[i]->hdisplay; - y=vidmodes[i]->vdisplay; - } - printf("%dx%d\n",vidmodes[i]->hdisplay,vidmodes[i]->vdisplay); - } - // chose the smallest mode that our window fits into; - for (i=smallest_mode; - i!=(smallest_mode+1)%nummodes; - i=(i?i-1:nummodes-1)) { - if (vidmodes[i]->hdisplay>=width - && vidmodes[i]->vdisplay>=height) { - XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp), - vidmodes[i]); - break; - } - } - XF86VidModeSetViewPort(x_disp, DefaultScreen (x_disp), 0, 0); - _windowed_mouse = Cvar_Get ("_windowed_mouse","1",CVAR_ARCHIVE|CVAR_ROM,"None"); - } else -#endif - _windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None"); - - x_win = XCreateWindow(x_disp, root, 0, 0, width, height, - 0, visinfo->depth, InputOutput, - visinfo->visual, mask, &attr); - XMapWindow(x_disp, x_win); - XRaiseWindow(x_disp, x_win); - + x11_set_vidmode(width, height); + x11_create_window(width, height); /* Invisible cursor */ - CreateNullCursor(x_disp, x_win); - XDefineCursor(x_disp, x_win, nullcursor); + x11_create_null_cursor(); XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0, vid.width+2, vid.height+2); -#ifdef HAVE_VIDMODE - if (hasvidmode && vid_fullscreen->value) { - XGrabKeyboard(x_disp, x_win, 1, GrabModeAsync, GrabModeAsync, - CurrentTime); - } -#endif + x11_grab_keyboard(); XSync(x_disp, 0); - ctx = glXCreateContext(x_disp, visinfo, NULL, True); + ctx = glXCreateContext(x_disp, x_visinfo, NULL, True); glXMakeCurrent(x_disp, x_win, ctx); diff --git a/source/vid_x11.c b/source/vid_x11.c index da2172a..1a8cd84 100644 --- a/source/vid_x11.c +++ b/source/vid_x11.c @@ -79,18 +79,8 @@ extern viddef_t vid; // global video state unsigned short d_8to16table[256]; -Window x_win; static Colormap x_cmap; static GC x_gc; -static Visual *x_vis; -static XVisualInfo *x_visinfo; -static Atom aWMDelete = 0; -static Cursor nullcursor = None; - -#ifdef HAVE_VIDMODE -static XF86VidModeModeInfo **vidmodes; -static int nummodes, hasvidmode = 0; -#endif int XShmQueryExtension(Display *); int XShmGetEventBase(Display *); @@ -121,40 +111,6 @@ static long X11_highhunkmark; int scr_width, scr_height; -#define STD_EVENT_MASK \ - ( VisibilityChangeMask | ExposureMask | StructureNotifyMask) - - -/* -====================== -Create an empty cursor -====================== -*/ - -static void -CreateNullCursor(Display *display, Window root) -{ - Pixmap cursormask; - XGCValues xgc; - GC gc; - XColor dummycolour; - - if (nullcursor != None) return; - - cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); - xgc.function = GXclear; - gc = XCreateGC(display, cursormask, GCFunction, &xgc); - XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); - dummycolour.pixel = 0; - dummycolour.red = 0; - dummycolour.flags = 04; - nullcursor = XCreatePixmapCursor(display, cursormask, cursormask, - &dummycolour,&dummycolour, 0,0); - XFreePixmap(display,cursormask); - XFreeGC(display,gc); -} - - static void shiftmask_init( void ) { @@ -522,18 +478,6 @@ void VID_Init (unsigned char *palette) // open the display x11_open_display(); -#ifdef HAVE_VIDMODE - hasvidmode = VID_CheckVMode(x_disp, NULL, NULL); - if (hasvidmode) { - if (! XF86VidModeGetAllModeLines(x_disp, DefaultScreen(x_disp), - &nummodes, &vidmodes) - || nummodes <= 0) { - hasvidmode = 0; - } - } - Con_SafePrintf ("hasvidmode = %i\nnummodes = %i\n", hasvidmode, nummodes); -#endif - // check for command-line window size if ((pnum=COM_CheckParm("-winsize"))) { @@ -573,15 +517,15 @@ void VID_Init (unsigned char *palette) // If not specified, use default visual else { - int screen; - screen = XDefaultScreen(x_disp); template.visualid = - XVisualIDFromVisual(XDefaultVisual(x_disp, screen)); + XVisualIDFromVisual(XDefaultVisual(x_disp, x_screen)); template_mask = VisualIDMask; } // pick a visual- warn if more than one was available x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals); + x_vis = x_visinfo->visual; + if (num_visuals > 1) { printf("Found more than one visual id at depth %d:\n", template.depth); for (i=0 ; ibits_per_rgb); } - x_vis = x_visinfo->visual; - /* Setup attributes for main window */ - { - int attribmask = CWEventMask | CWBorderPixel; - XSetWindowAttributes attribs; - - attribs.event_mask = STD_EVENT_MASK; - attribs.border_pixel = 0; - -#ifdef HAVE_VIDMODE - if (hasvidmode && vid_fullscreen->value) { - int smallest_mode=0, x=INT_MAX, y=INT_MAX; - - attribs.override_redirect=1; - attribmask|=CWOverrideRedirect; - - // FIXME: does this depend on mode line order in XF86Config? - for (i=0; ividmodes[i]->hdisplay || y>vidmodes[i]->vdisplay) { - smallest_mode=i; - x=vidmodes[i]->hdisplay; - y=vidmodes[i]->vdisplay; - } - printf("%dx%d\n",vidmodes[i]->hdisplay,vidmodes[i]->vdisplay); - } - // chose the smallest mode that our window fits into; - for (i=smallest_mode; - i!=(smallest_mode+1)%nummodes; - i=(i?i-1:nummodes-1)) { - if (vidmodes[i]->hdisplay>=vid.width - && vidmodes[i]->vdisplay>=vid.height) { - XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp), - vidmodes[i]); - break; - } - } - XF86VidModeSetViewPort(x_disp, DefaultScreen (x_disp), 0, 0); - _windowed_mouse = Cvar_Get ("_windowed_mouse","1",CVAR_ARCHIVE|CVAR_ROM,"None"); - } else -#endif - _windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None"); + x11_set_vidmode(vid.width, vid.height); /* Create the main window */ - x_win = XCreateWindow(x_disp, - XRootWindow(x_disp, x_visinfo->screen), - 0, 0, vid.width, vid.height, - 0, /* borderwidth */ - x_visinfo->depth, InputOutput, x_vis, - attribmask, &attribs); + x11_create_window(vid.width, vid.height); + + /* Invisible cursor */ + x11_create_null_cursor(); scr_width = vid.width; scr_height = vid.height; - /* Give it a title */ - XStoreName(x_disp, x_win, "XQuake"); - - /* Make window respond to Delete events */ - aWMDelete = XInternAtom(x_disp, "WM_DELETE_WINDOW", False); - XSetWMProtocols(x_disp, x_win, &aWMDelete, 1); - - /* Invisible cursor */ - CreateNullCursor(x_disp, x_win); - XDefineCursor(x_disp, x_win, nullcursor); - } - if (x_visinfo->depth == 8) { /* Create and upload the palette */ if (x_visinfo->class == PseudoColor) { @@ -695,12 +585,7 @@ void VID_Init (unsigned char *palette) // map the window XMapWindow(x_disp, x_win); XRaiseWindow(x_disp, x_win); -#ifdef HAVE_VIDMODE - if (hasvidmode && vid_fullscreen->value) { - XGrabKeyboard(x_disp, x_win, 1, GrabModeAsync, GrabModeAsync, - CurrentTime); - } -#endif + x11_grab_keyboard(); // wait for first exposure event { @@ -798,23 +683,7 @@ VID_Shutdown(void) { Sys_Printf("VID_Shutdown\n"); if (x_disp) { -#ifdef HAVE_VIDMODE - if (hasvidmode) { - int i; - - XF86VidModeSwitchToMode (x_disp, DefaultScreen (x_disp), - vidmodes[0]); - for (i = 0; i < nummodes; i++) { - if (vidmodes[i]->private) XFree(vidmodes[i]->private); - } - XFree(vidmodes); - } -#endif - if (nullcursor != None) { - XFreeCursor(x_disp, nullcursor); - nullcursor = None; - } - XAutoRepeatOn(x_disp); + x11_restore_vidmode(); x11_close_display(); x_disp = 0; }