put in reference counting for the x_disp pointer and make openneing and closing

of the display centralised. This will eventually lead to a much improved X init
and shutdown code.

Unfortunatly, X still crashes for me after running uquake-glx (haven't tested
for qw-client-glx, but I imagine it's no different), but I've found it's after
running uquake-glx the /second/ time, so I suspect it's a utah-glx(mga)/mesa
bug. It could also be an X server bug. I'll see if I can upgrade my X and then
report to the utah-glx team.
This commit is contained in:
Bill Currie 2000-03-14 10:25:46 +00:00
parent 7f8dbfdebc
commit c3d782a688
5 changed files with 71 additions and 61 deletions

View file

@ -45,12 +45,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <context_x11.h> #include <context_x11.h>
#include <qtypes.h> #include <qtypes.h>
#include <vid.h>
#include <sys.h>
static void (*event_handlers[LASTEvent])(XEvent *); static void (*event_handlers[LASTEvent])(XEvent *);
qboolean oktodraw = false; qboolean oktodraw = false;
int x_shmeventtype; int x_shmeventtype;
Display *x_disp = NULL;
static int x_disp_ref_count = 0;
qboolean x11_add_event(int event, void (*event_handler)(XEvent *)) qboolean
x11_add_event(int event, void (*event_handler)(XEvent *))
{ {
if (event >= LASTEvent) { if (event >= LASTEvent) {
printf("event: %d, LASTEvent: %d\n", event, LASTEvent); printf("event: %d, LASTEvent: %d\n", event, LASTEvent);
@ -63,7 +68,8 @@ qboolean x11_add_event(int event, void (*event_handler)(XEvent *))
return true; return true;
} }
qboolean x11_del_event(int event, void (*event_handler)(XEvent *)) qboolean
x11_del_event(int event, void (*event_handler)(XEvent *))
{ {
if (event >= LASTEvent) if (event >= LASTEvent)
return false; return false;
@ -74,7 +80,8 @@ qboolean x11_del_event(int event, void (*event_handler)(XEvent *))
return true; return true;
} }
void x11_process_event(void) void
x11_process_event(void)
{ {
XEvent x_event; XEvent x_event;
@ -89,10 +96,55 @@ void x11_process_event(void)
event_handlers[x_event.type](&x_event); event_handlers[x_event.type](&x_event);
} }
void x11_process_events(void) void
x11_process_events(void)
{ {
/* Get events from X server. */ /* Get events from X server. */
while (XPending(x_disp)) { while (XPending(x_disp)) {
x11_process_event(); x11_process_event();
} }
} }
// ========================================================================
// Tragic death handler
// ========================================================================
static void TragicDeath(int signal_num)
{
//XCloseDisplay(x_disp);
VID_Shutdown();
Sys_Error("This death brought to you by the number %d\n", signal_num);
}
void
x11_open_display(void)
{
struct sigaction sa;
if (!x_disp) {
x_disp = XOpenDisplay(0);
if (!x_disp) {
Sys_Error("VID: Could not open display [%s]\n", XDisplayName(0));
}
// catch signals
sigaction(SIGINT, 0, &sa);
sa.sa_handler = TragicDeath;
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
// for debugging only
XSynchronize(x_disp, True);
} else {
x_disp_ref_count++;
}
}
void
x11_close_display(void)
{
if (!--x_disp_ref_count) {
XCloseDisplay(x_disp);
x_disp = NULL;
}
}

View file

@ -35,9 +35,11 @@ extern qboolean doShm;
extern int x_shmeventtype; extern int x_shmeventtype;
extern qboolean oktodraw; extern qboolean oktodraw;
extern qboolean x11_add_event(int event, void (*event_handler)(XEvent *)); qboolean x11_add_event(int event, void (*event_handler)(XEvent *));
extern qboolean x11_del_event(int event, void (*event_handler)(XEvent *)); qboolean x11_del_event(int event, void (*event_handler)(XEvent *));
extern void x11_process_event(void); void x11_process_event(void);
extern void x11_process_events(void); void x11_process_events(void);
void x11_open_display(void);
void x11_close_display(void);
#endif // __CONTEXT_X11_H__ #endif // __CONTEXT_X11_H__

View file

@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <sys.h> #include <sys.h>
#include <lib_replace.h> #include <lib_replace.h>
#include <draw.h> #include <draw.h>
#include <context_x11.h>
#ifndef _EXPERIMENTAL_ #ifndef _EXPERIMENTAL_
# undef HAS_DGA # undef HAS_DGA
@ -70,7 +71,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define WARP_WIDTH 320 #define WARP_WIDTH 320
#define WARP_HEIGHT 200 #define WARP_HEIGHT 200
Display *x_disp = NULL;
static int screen; static int screen;
Window x_win; Window x_win;
static GLXContext ctx = NULL; static GLXContext ctx = NULL;
@ -145,10 +145,7 @@ VID_Shutdown(void)
{ {
Con_Printf("VID_Shutdown\n"); Con_Printf("VID_Shutdown\n");
if (x_disp && ctx) {
glXDestroyContext(x_disp, ctx); glXDestroyContext(x_disp, ctx);
ctx = NULL;
}
#ifdef HAS_DGA #ifdef HAS_DGA
if (hasvidmode) { if (hasvidmode) {
int i; int i;
@ -165,11 +162,7 @@ VID_Shutdown(void)
dlhand = NULL; dlhand = NULL;
} }
#endif #endif
x11_close_display();
if (x_disp) {
XCloseDisplay(x_disp);
x_disp = NULL;
}
} }
@ -450,11 +443,7 @@ void VID_Init(unsigned char *palette)
if (vid.conheight < 200) if (vid.conheight < 200)
vid.conheight = 200; vid.conheight = 200;
x_disp = XOpenDisplay(NULL); x11_open_display();
if ( !x_disp ) {
fprintf(stderr, "Error couldn't open the X display\n");
exit(1);
}
screen = DefaultScreen(x_disp); screen = DefaultScreen(x_disp);
root = RootWindow(x_disp, screen); root = RootWindow(x_disp, screen);

View file

@ -94,11 +94,8 @@ void IN_Shutdown(void)
{ {
Con_Printf("IN_Shutdown\n"); Con_Printf("IN_Shutdown\n");
mouse_avail = 0; mouse_avail = 0;
if (x_disp) {
XAutoRepeatOn(x_disp); XAutoRepeatOn(x_disp);
XCloseDisplay(x_disp); x11_close_display();
x_disp = 0;
}
} }
@ -378,6 +375,7 @@ int IN_Init ()
if (!x_win) if (!x_win)
Sys_Error("IN: No window!!\n"); Sys_Error("IN: No window!!\n");
x11_open_display(); // call to increment the reference counter
{ {
int attribmask = CWEventMask; int attribmask = CWEventMask;
XWindowAttributes attribs_1; XWindowAttributes attribs_1;

View file

@ -65,7 +65,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
viddef_t vid; // global video state viddef_t vid; // global video state
unsigned short d_8to16table[256]; unsigned short d_8to16table[256];
Display *x_disp = NULL;
Window x_win; Window x_win;
static Colormap x_cmap; static Colormap x_cmap;
static GC x_gc; static GC x_gc;
@ -287,16 +286,6 @@ void VID_Gamma_f (void)
} }
} }
// ========================================================================
// Tragic death handler
// ========================================================================
static void TragicDeath(int signal_num)
{
XCloseDisplay(x_disp);
Sys_Error("This death brought to you by the number %d\n", signal_num);
}
// ======================================================================== // ========================================================================
// makes a null cursor // makes a null cursor
// ======================================================================== // ========================================================================
@ -503,27 +492,7 @@ void VID_Init (unsigned char *palette)
verbose=COM_CheckParm("-verbose"); verbose=COM_CheckParm("-verbose");
// open the display // open the display
x_disp = XOpenDisplay(0); x11_open_display();
if (!x_disp)
{
if (getenv("DISPLAY"))
Sys_Error("VID: Could not open display [%s]\n",
getenv("DISPLAY"));
else
Sys_Error("VID: Could not open local display\n");
}
// catch signals
{
struct sigaction sa;
sigaction(SIGINT, 0, &sa);
sa.sa_handler = TragicDeath;
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
}
// for debugging only
XSynchronize(x_disp, True);
// check for command-line window size // check for command-line window size
if ((pnum=COM_CheckParm("-winsize"))) if ((pnum=COM_CheckParm("-winsize")))
@ -746,7 +715,7 @@ VID_Shutdown(void)
Sys_Printf("VID_Shutdown\n"); Sys_Printf("VID_Shutdown\n");
if (x_disp) { if (x_disp) {
XAutoRepeatOn(x_disp); XAutoRepeatOn(x_disp);
XCloseDisplay(x_disp); x11_close_display();
x_disp = 0; x_disp = 0;
} }
} }