2011-11-22 21:28:15 +00:00
|
|
|
#include "idlib/precompiled.h"
|
|
|
|
#include "renderer/tr_local.h"
|
|
|
|
#include "sys/linux/local.h"
|
|
|
|
#include "glimp_local.h"
|
|
|
|
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
|
|
|
dnl =====================================================
|
|
|
|
dnl utils
|
|
|
|
dnl =====================================================
|
|
|
|
|
2011-12-06 18:20:15 +00:00
|
|
|
define(`forloop',
|
2011-11-22 21:28:15 +00:00
|
|
|
`pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
|
|
|
|
define(`_forloop',
|
|
|
|
`$4`'ifelse($1, `$3', ,
|
|
|
|
`define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
|
2011-12-06 18:20:15 +00:00
|
|
|
|
2011-11-22 21:28:15 +00:00
|
|
|
dnl =====================================================
|
|
|
|
dnl the gl wgl glX definitions
|
|
|
|
dnl =====================================================
|
|
|
|
include(../gllog/gl_def.m4)
|
|
|
|
|
|
|
|
dnl =====================================================
|
|
|
|
dnl qgl function ptrs
|
|
|
|
dnl =====================================================
|
|
|
|
|
|
|
|
define(`instance_funcptr', ``$1' ( APIENTRY * qgl`$2' )(`$3');')
|
|
|
|
forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
|
|
|
|
')
|
|
|
|
|
|
|
|
dnl =====================================================
|
|
|
|
dnl glX function ptrs
|
|
|
|
dnl =====================================================
|
|
|
|
|
|
|
|
define(`instance_funcptr', ``$1' ( * qglX`$2' )(`$3');')
|
|
|
|
forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
|
|
|
|
')
|
|
|
|
|
|
|
|
dnl =====================================================
|
|
|
|
dnl dll ptrs
|
|
|
|
dnl those are the actual dlsym'ed pointers
|
|
|
|
dnl logging configuration redirects qgl / qglX to either log or dll versions
|
|
|
|
dnl =====================================================
|
|
|
|
|
|
|
|
define(`instance_funcptr', ``$1' ( * dll`$2' )(`$3');')
|
|
|
|
forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
|
|
|
|
')
|
|
|
|
forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
|
|
|
|
')
|
|
|
|
|
|
|
|
dnl =====================================================
|
|
|
|
dnl code
|
|
|
|
dnl =====================================================
|
|
|
|
|
|
|
|
/*
|
|
|
|
======================
|
|
|
|
GLimp_BindNative
|
|
|
|
======================
|
|
|
|
*/
|
|
|
|
void GLimp_BindNative() {
|
|
|
|
define(`assign_funcptr', `qgl`$1' = dll`$1';')
|
|
|
|
forloop(`i', gl_start, gl_end, `assign_funcptr(indir(`f'i`_name'))
|
|
|
|
')
|
|
|
|
|
|
|
|
define(`assign_funcptr', `qglX`$1' = dll`$1';')
|
|
|
|
forloop(`i', glX_start, glX_end, `assign_funcptr(indir(`f'i`_name'))
|
|
|
|
')
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *glHandle = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
======================
|
|
|
|
GLimp_dlsym_failed
|
|
|
|
======================
|
|
|
|
*/
|
|
|
|
void GLimp_dlsym_failed(const char *name) {
|
|
|
|
common->DPrintf("dlsym(%s) failed: %s\n", name, dlerror());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
======================
|
|
|
|
GLimp_dlopen
|
|
|
|
======================
|
|
|
|
*/
|
|
|
|
bool GLimp_dlopen() {
|
|
|
|
const char *driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "libGL.so.1";
|
|
|
|
common->Printf("dlopen(%s)\n", driverName);
|
|
|
|
if ( !( glHandle = dlopen( driverName, RTLD_NOW | RTLD_GLOBAL ) ) ) {
|
|
|
|
common->DPrintf("dlopen(%s) failed: %s\n", driverName, dlerror());
|
|
|
|
return false;
|
|
|
|
}
|
2011-12-06 18:20:15 +00:00
|
|
|
|
2011-11-22 21:28:15 +00:00
|
|
|
// dlsym the symbols
|
2011-12-06 18:20:15 +00:00
|
|
|
|
2011-11-22 21:28:15 +00:00
|
|
|
define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "gl`$2'" );')
|
|
|
|
define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3')
|
|
|
|
if (!dll`$2') { GLimp_dlsym_failed("gl`$2'"); return false; }')
|
|
|
|
forloop(`i', gl_start, gl_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
|
|
|
|
')
|
|
|
|
|
|
|
|
define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "glX`$2'" );')
|
|
|
|
define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3')
|
|
|
|
if (!dll`$2') { GLimp_dlsym_failed("glX`$2'"); return false; }')
|
|
|
|
forloop(`i', glX_start, glX_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
|
|
|
|
')
|
|
|
|
|
|
|
|
// make the initial binding
|
|
|
|
GLimp_BindNative();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
======================
|
|
|
|
GLimp_dlclose
|
|
|
|
======================
|
|
|
|
*/
|
|
|
|
void GLimp_dlclose() {
|
|
|
|
if ( !glHandle ) {
|
|
|
|
common->DPrintf("dlclose: GL handle is NULL\n");
|
2011-12-06 18:20:15 +00:00
|
|
|
} else {
|
2011-11-22 21:28:15 +00:00
|
|
|
dlclose( glHandle );
|
|
|
|
glHandle = NULL;
|
|
|
|
}
|
2011-12-06 18:20:15 +00:00
|
|
|
|
2011-11-22 21:28:15 +00:00
|
|
|
define(`reset_funcptr', `qgl`$1' = NULL;')
|
|
|
|
forloop(`i', gl_start, gl_end, `reset_funcptr(indir(`f'i`_name'))
|
|
|
|
')
|
|
|
|
|
|
|
|
define(`reset_funcptr', `qglX`$1' = NULL;')
|
|
|
|
forloop(`i', glX_start, glX_end, `reset_funcptr(indir(`f'i`_name'))
|
|
|
|
')
|
|
|
|
|
|
|
|
}
|