- Removed libltdl from the code. Not only does this make

the code make more sense, it also means that the dynamic
  loading of game and video refreshers (especially video
  refreshers) is consistent -- which means that you can now
  change video modes FROM WITHIN QUAKE2 as Carmack intended,
  and quake2 no longer dies with an Xlib error on exit, so
  your resolutions and gamma are restored!  (Closes: #34)
This commit is contained in:
Jamie Wilkinson 2002-12-06 14:49:11 +00:00
parent 6320e8e0a4
commit 3de95855fe
7 changed files with 56 additions and 69 deletions

View file

@ -1,6 +1,6 @@
# $Id$ # $Id$
SUBDIRS = libltdl src data SUBDIRS = src data
EXTRA_DIST = quake2.dsp quake2.dsw quake2.mak \ EXTRA_DIST = quake2.dsp quake2.dsw quake2.mak \
HACKING NEWS THANKS TODO \ HACKING NEWS THANKS TODO \

View file

@ -22,6 +22,6 @@ fi
# when one can just read the README # when one can just read the README
aclocal && \ aclocal && \
autoheader && \ autoheader && \
libtoolize --copy --ltdl --automake && \ libtoolize --copy --automake && \
automake --foreign --add-missing --copy && \ automake --foreign --add-missing --copy && \
autoconf autoconf

View file

@ -30,12 +30,7 @@ dnl -------------------
AC_PROG_CC AC_PROG_CC
dnl libtool is evil dnl libtool is evil
AC_LIBTOOL_DLOPEN
AC_LIBLTDL_CONVENIENCE
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_CONFIG_SUBDIRS(libltdl)
AC_SUBST(INCLTDL)
AC_SUBST(LIBLTDL)
HAVE_MASM="" HAVE_MASM=""
AC_SUBST(HAVE_MASM) AC_SUBST(HAVE_MASM)

View file

@ -2,7 +2,7 @@
SUBDIRS = . baseq2 ctf xatrix rogue SUBDIRS = . baseq2 ctf xatrix rogue
std_cflags = -Wall -pipe @OPT_CFLAGS@ std_cflags = -Wall -Werror -pipe @OPT_CFLAGS@
module_ldflags = -module -avoid-version -rpath $(pkglibdir) module_ldflags = -module -avoid-version -rpath $(pkglibdir)
bin_PROGRAMS = quake2 bin_PROGRAMS = quake2
@ -69,26 +69,24 @@ quake2_SOURCES = main.c q_sh.c vid_menu.c vid_so.c q_glob.c net_udp.c \
$(QUAKE2_ASM) $(SOUND) $(QUAKE2_ASM) $(SOUND)
if BUILD_SDLQUAKE2 if BUILD_SDLQUAKE2
quake2_CFLAGS = $(std_cflags) @INCLTDL@ @PTHREAD_CFLAGS@ @SDL_CFLAGS@ quake2_CFLAGS = $(std_cflags) @PTHREAD_CFLAGS@ @SDL_CFLAGS@
else else
quake2_CFLAGS = $(std_cflags) @INCLTDL@ @PTHREAD_CFLAGS@ quake2_CFLAGS = $(std_cflags) @PTHREAD_CFLAGS@
endif endif
# the macro puts -pthread into cflags, but we want to link # the macro puts -pthread into cflags, but we want to link
# with this flag too, so stick it into the ldflags if it's there... # with this flag too, so stick it into the ldflags if it's there...
# extra cflags at link time can't hurt # extra cflags at link time can't hurt
quake2_LDFLAGS = @PTHREAD_CFLAGS@ quake2_LDFLAGS = @PTHREAD_CFLAGS@
if BUILD_SDLQUAKE2 if BUILD_SDLQUAKE2
quake2_LDADD = @PTHREAD_LIBS@ @LIBLTDL@ @OSS_LIBS@ @SDL_LIBS@ @SYSTEM_LIBS@ -lm quake2_LDADD = @PTHREAD_LIBS@ @DL_LIBS@ @OSS_LIBS@ @SDL_LIBS@ @SYSTEM_LIBS@ -lm
else else
quake2_LDADD = @PTHREAD_LIBS@ @LIBLTDL@ @OSS_LIBS@ @SYSTEM_LIBS@ -lm quake2_LDADD = @PTHREAD_LIBS@ @DL_LIBS@ @OSS_LIBS@ @SYSTEM_LIBS@ -lm
endif endif
# ref_glx # ref_glx
if BUILD_GLX if BUILD_GLX
ref_glx_la_SOURCES = $(REF_GL_COMMON) gl_glx.c ref_glx_la_SOURCES = $(REF_GL_COMMON) gl_glx.c
#ref_glx_la_CFLAGS = $(std_cflags) -fPIC @X_CFLAGS@ @OPENGL_CFLAGS@
ref_glx_la_CFLAGS = $(std_cflags) -fPIC @X_CFLAGS@ ref_glx_la_CFLAGS = $(std_cflags) -fPIC @X_CFLAGS@
#ref_glx_la_LIBADD = @X_PRE_LIBS@ @X_LIBS@ @XTRA_LIBS@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ @DL_LIBS@
ref_glx_la_LIBADD = @X_PRE_LIBS@ @X_LIBS@ @XTRA_LIBS@ @X_EXTRA_LIBS@ @DL_LIBS@ ref_glx_la_LIBADD = @X_PRE_LIBS@ @X_LIBS@ @XTRA_LIBS@ @X_EXTRA_LIBS@ @DL_LIBS@
ref_glx_la_LDFLAGS = $(module_ldflags) ref_glx_la_LDFLAGS = $(module_ldflags)
endif endif

View file

@ -53,8 +53,9 @@
#include <sys/file.h> #include <sys/file.h>
#endif #endif
/* libtool dynamic loader */ #ifdef HAVE_DLOPEN
#include <ltdl.h> # include <dlfcn.h>
#endif
#include "qcommon.h" #include "qcommon.h"
#include "game.h" #include "game.h"
@ -107,7 +108,7 @@ void Sys_Printf (char *fmt, ...) {
void Sys_Quit (void) { void Sys_Quit (void) {
CL_Shutdown(); CL_Shutdown();
Qcommon_Shutdown(); Qcommon_Shutdown();
lt_dlexit();
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
_exit(0); _exit(0);
} }
@ -208,22 +209,20 @@ char *Sys_ConsoleInput(void)
/*****************************************************************************/ /*****************************************************************************/
static lt_dlhandle game_library = NULL; static void * game_library = NULL;
typedef game_export_t * gameapi_t(game_import_t *); typedef game_export_t * gameapi_t(game_import_t *);
void Sys_UnloadGame(void) { void Sys_UnloadGame(void) {
if (game_library) if (game_library)
lt_dlclose(game_library); dlclose(game_library);
game_library = NULL; game_library = NULL;
} }
/* Loads the game dll */ /* Loads the game dll */
void *Sys_GetGameAPI (void *parms) { void *Sys_GetGameAPI (void *parms) {
gameapi_t * GetGameAPI; gameapi_t * GetGameAPI;
cvar_t * game;
char path[MAX_OSPATH]; char path[MAX_OSPATH];
char name[MAX_OSPATH]; cvar_t * gamename;
char * str_p;
setreuid(getuid(), getuid()); setreuid(getuid(), getuid());
setegid(getgid()); setegid(getgid());
@ -231,34 +230,21 @@ void *Sys_GetGameAPI (void *parms) {
if (game_library) if (game_library)
Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
game = Cvar_Get("game", "", CVAR_LATCH|CVAR_SERVERINFO); /* now run through the search paths */
gamename = Cvar_Get("gamedir", BASEDIRNAME, CVAR_LATCH|CVAR_SERVERINFO);
Com_Printf("------- Loading %s -------\n", game->string); Com_Printf("------- Loading %s -------\n", gamename->string);
/* set the module search path */ /* set the module search path */
snprintf(name, MAX_OSPATH, "%s", snprintf(path, MAX_OSPATH, PKGLIBDIR"/%s/game.so", gamename->string);
game->string[0]?game->string:BASEDIRNAME); game_library = dlopen(path, RTLD_NOW);
snprintf(path, MAX_OSPATH, "./%s:"PKGLIBDIR"/%s", name, name);
lt_dlsetsearchpath(path);
/* load the module */
game_library = lt_dlopenext("game");
if (game_library) { if (game_library) {
Com_MDPrintf("LoadLibrary (%s)\n", name); Com_MDPrintf("LoadLibrary (%s)\n", gamename->string);
} else { } else {
Com_MDPrintf("LoadLibrary (%s)\n", name); Com_MDPrintf("LoadLibrary (%s)\n", gamename->string);
//str_p = strchr(lt_dlerror(), ':'); // skip the path (already shown) Com_MDPrintf("%s\n", dlerror());
str_p = (char *) lt_dlerror();
if (str_p != NULL) {
Com_MDPrintf (" **");
while (*str_p)
Com_MDPrintf ("%c", *(++str_p));
Com_MDPrintf ("\n");
}
} }
GetGameAPI = (gameapi_t *) lt_dlsym(game_library, "GetGameAPI"); GetGameAPI = (gameapi_t *) dlsym(game_library, "GetGameAPI");
if (!GetGameAPI) { if (!GetGameAPI) {
Sys_UnloadGame (); Sys_UnloadGame ();
@ -296,9 +282,6 @@ int main (int argc, char **argv) {
printf("QuakeIIForge %s\n", VERSION); printf("QuakeIIForge %s\n", VERSION);
/* initialiase libltdl */
lt_dlinit();
Qcommon_Init(argc, argv); Qcommon_Init(argc, argv);
/* sys_irix.c had this and the fcntl line 3 lines down commented out */ /* sys_irix.c had this and the fcntl line 3 lines down commented out */

View file

@ -3081,8 +3081,7 @@ qboolean QGL_Init( const char *dllname )
if (glw_state.OpenGLLib) if (glw_state.OpenGLLib)
QGL_Shutdown(); QGL_Shutdown();
if ( ( glw_state.OpenGLLib = dlopen( dllname, RTLD_LAZY | RTLD_GLOBAL ) ) == 0 ) if ((glw_state.OpenGLLib = dlopen(dllname, RTLD_LAZY)) == 0) {
{
char fn[MAX_OSPATH]; char fn[MAX_OSPATH];
char *path; char *path;

View file

@ -40,8 +40,9 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
/* libtool dynamic loader */ #ifdef HAVE_DLOPEN
#include <ltdl.h> # include <dlfcn.h>
#endif
#include "client.h" #include "client.h"
#include "rw.h" #include "rw.h"
@ -60,7 +61,7 @@ cvar_t * vid_fullscreen; /* fullscreen on or off */
viddef_t viddef; viddef_t viddef;
/* Handle to refresh DLL */ /* Handle to refresh DLL */
lt_dlhandle reflib_library = NULL; static void * reflib_library = NULL;
qboolean reflib_active = 0; qboolean reflib_active = 0;
@ -193,7 +194,7 @@ void VID_FreeReflib(void) {
KBD_Close_fp(); KBD_Close_fp();
if (RW_IN_Shutdown_fp) if (RW_IN_Shutdown_fp)
RW_IN_Shutdown_fp(); RW_IN_Shutdown_fp();
lt_dlclose(reflib_library); dlclose(reflib_library);
} }
KBD_Init_fp = NULL; KBD_Init_fp = NULL;
@ -220,6 +221,9 @@ VID_LoadRefresh
qboolean VID_LoadRefresh(char * name) { qboolean VID_LoadRefresh(char * name) {
refimport_t ri; refimport_t ri;
GetRefAPI_t GetRefAPI; GetRefAPI_t GetRefAPI;
char fn[MAX_OSPATH];
/* char * path; */
struct stat st;
extern uid_t saved_euid; extern uid_t saved_euid;
/* clean up a previous reflib */ /* clean up a previous reflib */
@ -239,7 +243,15 @@ qboolean VID_LoadRefresh(char * name) {
//regain root //regain root
seteuid(saved_euid); seteuid(saved_euid);
lt_dlsetsearchpath(".:"PKGLIBDIR); /*
path = Cvar_Get("basedir", ".", CVAR_NOSET)->string;
snprintf(fn, MAX_OSPATH, "%s/%s", path, name);
*/
snprintf(fn, MAX_OSPATH, PKGLIBDIR"/%s", name);
if (stat(fn, &st) == -1) {
Com_Printf("LoadLibrary(\"%s\") failed: %s\n", name, strerror(errno));
return false;
}
// permission checking // permission checking
if (strstr(name, "softx") == NULL && if (strstr(name, "softx") == NULL &&
@ -263,8 +275,8 @@ qboolean VID_LoadRefresh(char * name) {
setegid(getgid()); setegid(getgid());
} }
if ((reflib_library = lt_dlopenext(name)) == 0) { if ((reflib_library = dlopen(fn, RTLD_LAZY)) == 0) {
Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name , lt_dlerror()); Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name , dlerror());
return false; return false;
} }
@ -287,7 +299,7 @@ qboolean VID_LoadRefresh(char * name) {
ri.Vid_MenuInit = VID_MenuInit; ri.Vid_MenuInit = VID_MenuInit;
ri.Vid_NewWindow = VID_NewWindow; ri.Vid_NewWindow = VID_NewWindow;
if ((GetRefAPI = (GetRefAPI_t) lt_dlsym(reflib_library, "GetRefAPI")) == 0) if ((GetRefAPI = (GetRefAPI_t) dlsym(reflib_library, "GetRefAPI")) == 0)
Com_Error(ERR_FATAL, "dlsym failed on %s", name); Com_Error(ERR_FATAL, "dlsym failed on %s", name);
re = GetRefAPI( ri ); re = GetRefAPI( ri );
@ -303,16 +315,16 @@ qboolean VID_LoadRefresh(char * name) {
in_state.viewangles = cl.viewangles; in_state.viewangles = cl.viewangles;
in_state.in_strafe_state = &in_strafe.state; in_state.in_strafe_state = &in_strafe.state;
if ((RW_IN_Init_fp = (void (*)(in_state_t *)) lt_dlsym(reflib_library, "RW_IN_Init")) == NULL || if ((RW_IN_Init_fp = (void (*)(in_state_t *)) dlsym(reflib_library, "RW_IN_Init")) == NULL ||
(RW_IN_Shutdown_fp = (void(*)(void)) lt_dlsym(reflib_library, "RW_IN_Shutdown")) == NULL || (RW_IN_Shutdown_fp = (void(*)(void)) dlsym(reflib_library, "RW_IN_Shutdown")) == NULL ||
(RW_IN_Activate_fp = (void(*)(qboolean)) lt_dlsym(reflib_library, "RW_IN_Activate")) == NULL || (RW_IN_Activate_fp = (void(*)(qboolean)) dlsym(reflib_library, "RW_IN_Activate")) == NULL ||
(RW_IN_Commands_fp = (void(*)(void)) lt_dlsym(reflib_library, "RW_IN_Commands")) == NULL || (RW_IN_Commands_fp = (void(*)(void)) dlsym(reflib_library, "RW_IN_Commands")) == NULL ||
(RW_IN_Move_fp = (void(*)(usercmd_t *)) lt_dlsym(reflib_library, "RW_IN_Move")) == NULL || (RW_IN_Move_fp = (void(*)(usercmd_t *)) dlsym(reflib_library, "RW_IN_Move")) == NULL ||
(RW_IN_Frame_fp = (void(*)(void)) lt_dlsym(reflib_library, "RW_IN_Frame")) == NULL) (RW_IN_Frame_fp = (void(*)(void)) dlsym(reflib_library, "RW_IN_Frame")) == NULL)
Sys_Error("No RW_IN functions in REF.\n"); Sys_Error("No RW_IN functions in REF.\n");
/* this one is optional */ /* this one is optional */
RW_Sys_GetClipboardData_fp = (char*(*)(void)) lt_dlsym(reflib_library, "RW_Sys_GetClipboardData"); RW_Sys_GetClipboardData_fp = (char*(*)(void)) dlsym(reflib_library, "RW_Sys_GetClipboardData");
Real_IN_Init(); Real_IN_Init();
@ -332,9 +344,9 @@ qboolean VID_LoadRefresh(char * name) {
*/ */
/* Init KBD */ /* Init KBD */
if ((KBD_Init_fp = (void(*)(Key_Event_fp_t)) lt_dlsym(reflib_library, "KBD_Init")) == NULL || if ((KBD_Init_fp = (void(*)(Key_Event_fp_t)) dlsym(reflib_library, "KBD_Init")) == NULL ||
(KBD_Update_fp = (void(*)(void)) lt_dlsym(reflib_library, "KBD_Update")) == NULL || (KBD_Update_fp = (void(*)(void)) dlsym(reflib_library, "KBD_Update")) == NULL ||
(KBD_Close_fp = (void(*)(void)) lt_dlsym(reflib_library, "KBD_Close")) == NULL) (KBD_Close_fp = (void(*)(void)) dlsym(reflib_library, "KBD_Close")) == NULL)
Sys_Error("No KBD functions in REF.\n"); Sys_Error("No KBD functions in REF.\n");
KBD_Init_fp(Do_Key_Event); KBD_Init_fp(Do_Key_Event);
@ -374,7 +386,7 @@ void VID_CheckChanges(void) {
cl.refresh_prepped = false; cl.refresh_prepped = false;
cls.disable_screen = true; cls.disable_screen = true;
sprintf(name, "ref_%s", vid_ref->string); sprintf(name, "ref_%s.so", vid_ref->string);
if (!VID_LoadRefresh(name)) { if (!VID_LoadRefresh(name)) {
if (strcmp(vid_ref->string, "soft") == 0 || if (strcmp(vid_ref->string, "soft") == 0 ||
strcmp(vid_ref->string, "softx") == 0) { strcmp(vid_ref->string, "softx") == 0) {