/
HsOpenGLRaw.c
153 lines (123 loc) · 3.86 KB
/
HsOpenGLRaw.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* -----------------------------------------------------------------------------
*
* Module : C support for Graphics.Rendering.OpenGL.Raw.GetProcAddress.hs
* Copyright : (c) Sven Panne 2009-2019
* License : BSD3
*
* Maintainer : Sven Panne <svenpanne@gmail.com>
* Stability : stable
* Portability : portable
*
* -------------------------------------------------------------------------- */
#if defined(USE_WGLGETPROCADDRESS)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void*
getProcAddress(const char *name)
{
static int firstTime = 1;
static HMODULE handle = NULL;
if (firstTime) {
firstTime = 0;
handle = LoadLibrary(TEXT("opengl32"));
}
return handle ? GetProcAddress(handle, name) : NULL;
}
void*
hs_OpenGLRaw_getProcAddress(const char *name)
{
void *apiEntry = wglGetProcAddress(name);
/* Sometimes core API entries are not returned via wglGetProcAddress, so
we fall back to GetProcAddress in these cases. */
return (apiEntry == NULL) ? getProcAddress(name) : apiEntry;
}
/* -------------------------------------------------------------------------- */
#elif defined(USE_NSADDRESSOFSYMBOL)
#include <mach-o/dyld.h>
#include <stdlib.h>
#include <string.h>
void*
hs_OpenGLRaw_getProcAddress(const char *name)
{
NSSymbol symbol;
/* Prepend a '_' for the Unix C symbol mangling convention */
char* symbolName = (char*)malloc(strlen(name) + 2);
if (!symbolName) {
return NULL;
}
symbolName[0] = '_';
strcpy(symbolName + 1, name);
if (!NSIsSymbolNameDefined(symbolName)) {
free(symbolName);
return NULL;
}
symbol = NSLookupAndBindSymbol(symbolName);
free(symbolName);
if (!symbol) {
return NULL;
}
return NSAddressOfSymbol(symbol);
}
/* -------------------------------------------------------------------------- */
#elif defined(USE_DLSYM)
#include <stdlib.h>
#include <dlfcn.h>
/* Do not depend on <GL/gl.h> */
typedef unsigned char GLubyte;
/* Do not depend on <GL/glx.h> */
typedef void (*genericFunctionPointer)(void);
typedef genericFunctionPointer (*PFNGLXGETPROCADDRESSARB)(const GLubyte *);
static const char* gpaNames[] = {
"glXGetProcAddress", "glXGetProcAddressARB", "glXGetProcAddressEXT",
"_glXGetProcAddress", "_glXGetProcAddressARB", "_glXGetProcAddressEXT"
};
void*
hs_OpenGLRaw_getProcAddress(const char *name)
{
static int firstTime = 1;
static void *handle = NULL;
static void *gpa = NULL;
if (firstTime) {
firstTime = 0;
/* Get a handle for our executable. */
handle = dlopen(NULL, RTLD_LAZY);
/* If fail this early, there's not much we can do about it. */
if (!handle) {
return NULL;
}
{
/* Let's see if our platform supports a glXGetProcAddress() variant. */
int numNames = (int)(sizeof(gpaNames) / sizeof(gpaNames[0]));
int i;
for (i = 0; (!gpa) && (i < numNames); ++i) {
gpa = dlsym(handle, gpaNames[i]);
}
}
}
if (gpa) {
/* Fine, we seem to have some kind of glXGetProcAddress(), so use it. */
return ((PFNGLXGETPROCADDRESSARB)gpa)(name);
} else if (handle) {
/* Fallback to dlsym() if we have no glXGetProcAddress(), although we then
ignore the fact that OpenGL entry points could be context dependent. */
return dlsym(handle, name);
} else {
return NULL;
}
}
/* -------------------------------------------------------------------------- */
#elif defined(USE_GLXGETPROCADDRESS)
/* Do not depend on <GL/gl.h> */
typedef unsigned char GLubyte;
/* Do not depend on <GL/glx.h> */
typedef void (*genericFunctionPointer)(void);
extern genericFunctionPointer glXGetProcAddressARB(const GLubyte *);
void*
hs_OpenGLRaw_getProcAddress(const char *name)
{
return glXGetProcAddressARB((const GLubyte*)name);
}
/* -------------------------------------------------------------------------- */
#else
#error "Don't know how to retrieve OpenGL extension entries"
#endif