]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/sys/linux/glimp_dlopen.cpp.m4
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / sys / linux / glimp_dlopen.cpp.m4
1 #include "idlib/precompiled.h"
2 #include "renderer/tr_local.h"
3 #include "sys/linux/local.h"
4 #include "glimp_local.h"
5
6 #include <dlfcn.h>
7
8 dnl =====================================================
9 dnl utils
10 dnl =====================================================
11
12 define(`forloop', 
13         `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
14 define(`_forloop',
15         `$4`'ifelse($1, `$3', ,
16         `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
17         
18 dnl =====================================================
19 dnl the gl wgl glX definitions
20 dnl =====================================================
21 include(../gllog/gl_def.m4)
22
23 dnl =====================================================
24 dnl qgl function ptrs
25 dnl =====================================================
26
27 define(`instance_funcptr', ``$1' ( APIENTRY * qgl`$2' )(`$3');')
28 forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
29 ')
30
31 dnl =====================================================
32 dnl glX function ptrs
33 dnl =====================================================
34
35 define(`instance_funcptr', ``$1' ( * qglX`$2' )(`$3');')
36 forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
37 ')
38
39 dnl =====================================================
40 dnl dll ptrs
41 dnl those are the actual dlsym'ed pointers
42 dnl logging configuration redirects qgl / qglX to either log or dll versions
43 dnl =====================================================
44
45 define(`instance_funcptr', ``$1' ( * dll`$2' )(`$3');')
46 forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
47 ')
48 forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
49 ')
50
51 dnl =====================================================
52 dnl code
53 dnl =====================================================
54
55 /*
56 ======================
57 GLimp_BindNative
58 ======================
59 */
60 void GLimp_BindNative() {
61 define(`assign_funcptr', `qgl`$1' = dll`$1';')
62 forloop(`i', gl_start, gl_end, `assign_funcptr(indir(`f'i`_name'))
63 ')
64
65 define(`assign_funcptr', `qglX`$1' = dll`$1';')
66 forloop(`i', glX_start, glX_end, `assign_funcptr(indir(`f'i`_name'))
67 ')
68 }
69
70 static void *glHandle = NULL;
71
72 /*
73 ======================
74 GLimp_dlsym_failed
75 ======================
76 */
77 void GLimp_dlsym_failed(const char *name) {
78         common->DPrintf("dlsym(%s) failed: %s\n", name, dlerror());
79 }
80
81 /*
82 ======================
83 GLimp_dlopen
84 ======================
85 */
86 bool GLimp_dlopen() {
87         const char *driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "libGL.so.1";
88         common->Printf("dlopen(%s)\n", driverName);
89         if ( !( glHandle = dlopen( driverName, RTLD_NOW | RTLD_GLOBAL ) ) ) {
90                 common->DPrintf("dlopen(%s) failed: %s\n", driverName, dlerror());
91                 return false;
92         }
93         
94         // dlsym the symbols
95         
96 define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "gl`$2'" );')
97 define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3')
98 if (!dll`$2') { GLimp_dlsym_failed("gl`$2'"); return false; }')
99 forloop(`i', gl_start, gl_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
100 ')
101
102 define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "glX`$2'" );')
103 define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3')
104 if (!dll`$2') { GLimp_dlsym_failed("glX`$2'"); return false; }')
105 forloop(`i', glX_start, glX_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
106 ')
107
108         // make the initial binding
109         GLimp_BindNative();
110
111         return true;
112 }
113
114 /*
115 ======================
116 GLimp_dlclose
117 ======================
118 */
119 void GLimp_dlclose() {
120         if ( !glHandle ) {
121                 common->DPrintf("dlclose: GL handle is NULL\n");
122         } else {        
123                 dlclose( glHandle );
124                 glHandle = NULL;
125         }
126         
127 define(`reset_funcptr', `qgl`$1' = NULL;')
128 forloop(`i', gl_start, gl_end, `reset_funcptr(indir(`f'i`_name'))
129 ')
130
131 define(`reset_funcptr', `qglX`$1' = NULL;')
132 forloop(`i', glX_start, glX_end, `reset_funcptr(indir(`f'i`_name'))
133 ')
134
135 }