122a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman#include <string.h>
2afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson#include <stdlib.h>
322a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman#include <X11/Xlib.h>
422a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
522a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman#include "glvnd/libglxabi.h"
622a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
722a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman#include "glxglvnd.h"
822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
922a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brennemanstatic Bool __glXGLVNDIsScreenSupported(Display *dpy, int screen)
1022a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman{
1122a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    /* TODO: Think of a better heuristic... */
1222a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    return True;
1322a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman}
1422a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
1522a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brennemanstatic void *__glXGLVNDGetProcAddress(const GLubyte *procName)
1622a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman{
1722a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    return glXGetProcAddressARB(procName);
1822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman}
1922a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
20afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jacksonstatic int
21afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jacksoncompare(const void *l, const void *r)
22afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson{
23afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson    const char *s = *(const char **)r;
24afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson    return strcmp(l, s);
25afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson}
26afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson
273bf00b6c6ac108f7d6cfc5c36401ccfd6a378469Emil Velikovstatic unsigned FindGLXFunction(const GLubyte *name)
2822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman{
29afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson    const char **match;
30afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson
31afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson    match = bsearch(name, __glXDispatchTableStrings, DI_FUNCTION_COUNT,
32afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson                    sizeof(const char *), compare);
33afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson
34afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson    if (match == NULL)
35afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson        return DI_FUNCTION_COUNT;
36afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson
37afaaf623d4d95b3ac736e72c744f683a2b804e1dAdam Jackson    return match - __glXDispatchTableStrings;
3822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman}
3922a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
4022a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brennemanstatic void *__glXGLVNDGetDispatchAddress(const GLubyte *procName)
4122a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman{
423bf00b6c6ac108f7d6cfc5c36401ccfd6a378469Emil Velikov    unsigned internalIndex = FindGLXFunction(procName);
4322a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
443bf00b6c6ac108f7d6cfc5c36401ccfd6a378469Emil Velikov    return __glXDispatchFunctions[internalIndex];
4522a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman}
4622a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
4722a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brennemanstatic void __glXGLVNDSetDispatchIndex(const GLubyte *procName, int index)
4822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman{
493bf00b6c6ac108f7d6cfc5c36401ccfd6a378469Emil Velikov    unsigned internalIndex = FindGLXFunction(procName);
5022a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
51deb0eb1660f612862c77d225582e102e7ab717eeAdam Jackson    if (internalIndex == DI_FUNCTION_COUNT)
52deb0eb1660f612862c77d225582e102e7ab717eeAdam Jackson        return; /* unknown or static dispatch */
53deb0eb1660f612862c77d225582e102e7ab717eeAdam Jackson
543bf00b6c6ac108f7d6cfc5c36401ccfd6a378469Emil Velikov    __glXDispatchTableIndices[internalIndex] = index;
5522a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman}
5622a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
5722a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman_X_EXPORT Bool __glx_Main(uint32_t version, const __GLXapiExports *exports,
5822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman                          __GLXvendorInfo *vendor, __GLXapiImports *imports)
5922a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman{
6022a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    static Bool initDone = False;
6122a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
6222a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    if (GLX_VENDOR_ABI_GET_MAJOR_VERSION(version) !=
6322a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        GLX_VENDOR_ABI_MAJOR_VERSION ||
6422a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        GLX_VENDOR_ABI_GET_MINOR_VERSION(version) <
6522a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        GLX_VENDOR_ABI_MINOR_VERSION)
6622a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        return False;
6722a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
6822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    if (!initDone) {
6922a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        initDone = True;
7022a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        __glXGLVNDAPIExports = exports;
7122a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
7222a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->isScreenSupported = __glXGLVNDIsScreenSupported;
7322a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->getProcAddress = __glXGLVNDGetProcAddress;
7422a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->getDispatchAddress = __glXGLVNDGetDispatchAddress;
7522a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->setDispatchIndex = __glXGLVNDSetDispatchIndex;
7622a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->notifyError = NULL;
7722a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->isPatchSupported = NULL;
7822a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman        imports->initiatePatch = NULL;
7922a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    }
8022a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman
8122a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman    return True;
8222a9e00aab66d3dd6890e9eaac3f429c0ddec17eKyle Brenneman}
83