1#include <stdlib.h>
2
3#include "glxclient.h"
4#include "glxglvnd.h"
5#include "glxglvnddispatchfuncs.h"
6#include "g_glxglvnddispatchindices.h"
7
8const int DI_FUNCTION_COUNT = DI_LAST_INDEX;
9/* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */
10int __glXDispatchTableIndices[DI_LAST_INDEX + 1];
11const __GLXapiExports *__glXGLVNDAPIExports;
12
13const char * const __glXDispatchTableStrings[DI_LAST_INDEX] = {
14#define __ATTRIB(field) \
15    [DI_##field] = "glX"#field
16
17    __ATTRIB(BindSwapBarrierSGIX),
18    __ATTRIB(BindTexImageEXT),
19    // glXChooseFBConfig implemented by libglvnd
20    __ATTRIB(ChooseFBConfigSGIX),
21    // glXChooseVisual implemented by libglvnd
22    // glXCopyContext implemented by libglvnd
23    __ATTRIB(CopySubBufferMESA),
24    // glXCreateContext implemented by libglvnd
25    __ATTRIB(CreateContextAttribsARB),
26    __ATTRIB(CreateContextWithConfigSGIX),
27    __ATTRIB(CreateGLXPbufferSGIX),
28    // glXCreateGLXPixmap implemented by libglvnd
29    __ATTRIB(CreateGLXPixmapMESA),
30    __ATTRIB(CreateGLXPixmapWithConfigSGIX),
31    // glXCreateNewContext implemented by libglvnd
32    // glXCreatePbuffer implemented by libglvnd
33    // glXCreatePixmap implemented by libglvnd
34    // glXCreateWindow implemented by libglvnd
35    // glXDestroyContext implemented by libglvnd
36    __ATTRIB(DestroyGLXPbufferSGIX),
37    // glXDestroyGLXPixmap implemented by libglvnd
38    // glXDestroyPbuffer implemented by libglvnd
39    // glXDestroyPixmap implemented by libglvnd
40    // glXDestroyWindow implemented by libglvnd
41    // glXFreeContextEXT implemented by libglvnd
42    // glXGetClientString implemented by libglvnd
43    // glXGetConfig implemented by libglvnd
44    __ATTRIB(GetContextIDEXT),
45    // glXGetCurrentContext implemented by libglvnd
46    // glXGetCurrentDisplay implemented by libglvnd
47    __ATTRIB(GetCurrentDisplayEXT),
48    // glXGetCurrentDrawable implemented by libglvnd
49    // glXGetCurrentReadDrawable implemented by libglvnd
50    __ATTRIB(GetDriverConfig),
51    // glXGetFBConfigAttrib implemented by libglvnd
52    __ATTRIB(GetFBConfigAttribSGIX),
53    __ATTRIB(GetFBConfigFromVisualSGIX),
54    // glXGetFBConfigs implemented by libglvnd
55    __ATTRIB(GetMscRateOML),
56    // glXGetProcAddress implemented by libglvnd
57    // glXGetProcAddressARB implemented by libglvnd
58    __ATTRIB(GetScreenDriver),
59    // glXGetSelectedEvent implemented by libglvnd
60    __ATTRIB(GetSelectedEventSGIX),
61    __ATTRIB(GetSwapIntervalMESA),
62    __ATTRIB(GetSyncValuesOML),
63    __ATTRIB(GetVideoSyncSGI),
64    // glXGetVisualFromFBConfig implemented by libglvnd
65    __ATTRIB(GetVisualFromFBConfigSGIX),
66    // glXImportContextEXT implemented by libglvnd
67    // glXIsDirect implemented by libglvnd
68    __ATTRIB(JoinSwapGroupSGIX),
69    // glXMakeContextCurrent implemented by libglvnd
70    // glXMakeCurrent implemented by libglvnd
71    // glXQueryContext implemented by libglvnd
72    __ATTRIB(QueryContextInfoEXT),
73    __ATTRIB(QueryCurrentRendererIntegerMESA),
74    __ATTRIB(QueryCurrentRendererStringMESA),
75    // glXQueryDrawable implemented by libglvnd
76    // glXQueryExtension implemented by libglvnd
77    // glXQueryExtensionsString implemented by libglvnd
78    __ATTRIB(QueryGLXPbufferSGIX),
79    __ATTRIB(QueryMaxSwapBarriersSGIX),
80    __ATTRIB(QueryRendererIntegerMESA),
81    __ATTRIB(QueryRendererStringMESA),
82    // glXQueryServerString implemented by libglvnd
83    // glXQueryVersion implemented by libglvnd
84    __ATTRIB(ReleaseBuffersMESA),
85    __ATTRIB(ReleaseTexImageEXT),
86    // glXSelectEvent implemented by libglvnd
87    __ATTRIB(SelectEventSGIX),
88    // glXSwapBuffers implemented by libglvnd
89    __ATTRIB(SwapBuffersMscOML),
90    __ATTRIB(SwapIntervalEXT),
91    __ATTRIB(SwapIntervalMESA),
92    __ATTRIB(SwapIntervalSGI),
93    // glXUseXFont implemented by libglvnd
94    __ATTRIB(WaitForMscOML),
95    __ATTRIB(WaitForSbcOML),
96    // glXWaitGL implemented by libglvnd
97    __ATTRIB(WaitVideoSyncSGI),
98    // glXWaitX implemented by libglvnd
99
100#undef __ATTRIB
101};
102
103#define __FETCH_FUNCTION_PTR(func_name) \
104    p##func_name = (void *) \
105        __VND->fetchDispatchEntry(dd, __glXDispatchTableIndices[DI_##func_name])
106
107
108static void dispatch_BindTexImageEXT(Display *dpy, GLXDrawable drawable,
109                                     int buffer, const int *attrib_list)
110{
111    PFNGLXBINDTEXIMAGEEXTPROC pBindTexImageEXT;
112    __GLXvendorInfo *dd;
113
114    dd = GetDispatchFromDrawable(dpy, drawable);
115    if (dd == NULL)
116        return;
117
118    __FETCH_FUNCTION_PTR(BindTexImageEXT);
119    if (pBindTexImageEXT == NULL)
120        return;
121
122    pBindTexImageEXT(dpy, drawable, buffer, attrib_list);
123}
124
125
126
127static GLXFBConfigSGIX *dispatch_ChooseFBConfigSGIX(Display *dpy, int screen,
128                                                    int *attrib_list,
129                                                    int *nelements)
130{
131    PFNGLXCHOOSEFBCONFIGSGIXPROC pChooseFBConfigSGIX;
132    __GLXvendorInfo *dd;
133    GLXFBConfigSGIX *ret;
134
135    dd = __VND->getDynDispatch(dpy, screen);
136    if (dd == NULL)
137        return NULL;
138
139    __FETCH_FUNCTION_PTR(ChooseFBConfigSGIX);
140    if (pChooseFBConfigSGIX == NULL)
141        return NULL;
142
143    ret = pChooseFBConfigSGIX(dpy, screen, attrib_list, nelements);
144    if (AddFBConfigsMapping(dpy, ret, nelements, dd)) {
145        free(ret);
146        return NULL;
147    }
148
149    return ret;
150}
151
152
153
154static GLXContext dispatch_CreateContextAttribsARB(Display *dpy,
155                                                   GLXFBConfig config,
156                                                   GLXContext share_list,
157                                                   Bool direct,
158                                                   const int *attrib_list)
159{
160    PFNGLXCREATECONTEXTATTRIBSARBPROC pCreateContextAttribsARB;
161    __GLXvendorInfo *dd = NULL;
162    GLXContext ret;
163
164    if (config) {
165       dd = GetDispatchFromFBConfig(dpy, config);
166    } else if (attrib_list) {
167       int i, screen;
168
169       for (i = 0; attrib_list[i * 2] != None; i++) {
170          if (attrib_list[i * 2] == GLX_SCREEN) {
171             screen = attrib_list[i * 2 + 1];
172             dd = GetDispatchFromDrawable(dpy, RootWindow(dpy, screen));
173             break;
174          }
175       }
176    }
177    if (dd == NULL)
178        return None;
179
180    __FETCH_FUNCTION_PTR(CreateContextAttribsARB);
181    if (pCreateContextAttribsARB == NULL)
182        return None;
183
184    ret = pCreateContextAttribsARB(dpy, config, share_list, direct, attrib_list);
185    if (AddContextMapping(dpy, ret, dd)) {
186        /* XXX: Call glXDestroyContext which lives in libglvnd. If we're not
187         * allowed to call it from here, should we extend __glXDispatchTableIndices ?
188         */
189        return None;
190    }
191
192    return ret;
193}
194
195
196
197static GLXContext dispatch_CreateContextWithConfigSGIX(Display *dpy,
198                                                       GLXFBConfigSGIX config,
199                                                       int render_type,
200                                                       GLXContext share_list,
201                                                       Bool direct)
202{
203    PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC pCreateContextWithConfigSGIX;
204    __GLXvendorInfo *dd;
205    GLXContext ret;
206
207    dd = GetDispatchFromFBConfig(dpy, config);
208    if (dd == NULL)
209        return None;
210
211    __FETCH_FUNCTION_PTR(CreateContextWithConfigSGIX);
212    if (pCreateContextWithConfigSGIX == NULL)
213        return None;
214
215    ret = pCreateContextWithConfigSGIX(dpy, config, render_type, share_list, direct);
216    if (AddContextMapping(dpy, ret, dd)) {
217        /* XXX: Call glXDestroyContext which lives in libglvnd. If we're not
218         * allowed to call it from here, should we extend __glXDispatchTableIndices ?
219         */
220        return None;
221    }
222
223    return ret;
224}
225
226
227
228static GLXPbuffer dispatch_CreateGLXPbufferSGIX(Display *dpy,
229                                                GLXFBConfig config,
230                                                unsigned int width,
231                                                unsigned int height,
232                                                int *attrib_list)
233{
234    PFNGLXCREATEGLXPBUFFERSGIXPROC pCreateGLXPbufferSGIX;
235    __GLXvendorInfo *dd;
236    GLXPbuffer ret;
237
238    dd = GetDispatchFromFBConfig(dpy, config);
239    if (dd == NULL)
240        return None;
241
242    __FETCH_FUNCTION_PTR(CreateGLXPbufferSGIX);
243    if (pCreateGLXPbufferSGIX == NULL)
244        return None;
245
246    ret = pCreateGLXPbufferSGIX(dpy, config, width, height, attrib_list);
247    if (AddDrawableMapping(dpy, ret, dd)) {
248        PFNGLXDESTROYGLXPBUFFERSGIXPROC pDestroyGLXPbufferSGIX;
249
250        __FETCH_FUNCTION_PTR(DestroyGLXPbufferSGIX);
251        if (pDestroyGLXPbufferSGIX)
252            pDestroyGLXPbufferSGIX(dpy, ret);
253
254        return None;
255    }
256
257    return ret;
258}
259
260
261
262static GLXPixmap dispatch_CreateGLXPixmapWithConfigSGIX(Display *dpy,
263                                                        GLXFBConfigSGIX config,
264                                                        Pixmap pixmap)
265{
266    PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC pCreateGLXPixmapWithConfigSGIX;
267    __GLXvendorInfo *dd;
268    GLXPixmap ret;
269
270    dd = GetDispatchFromFBConfig(dpy, config);
271    if (dd == NULL)
272        return None;
273
274    __FETCH_FUNCTION_PTR(CreateGLXPixmapWithConfigSGIX);
275    if (pCreateGLXPixmapWithConfigSGIX == NULL)
276        return None;
277
278    ret = pCreateGLXPixmapWithConfigSGIX(dpy, config, pixmap);
279    if (AddDrawableMapping(dpy, ret, dd)) {
280        /* XXX: Call glXDestroyGLXPixmap which lives in libglvnd. If we're not
281         * allowed to call it from here, should we extend __glXDispatchTableIndices ?
282         */
283        return None;
284    }
285
286    return ret;
287}
288
289
290
291static void dispatch_DestroyGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf)
292{
293    PFNGLXDESTROYGLXPBUFFERSGIXPROC pDestroyGLXPbufferSGIX;
294    __GLXvendorInfo *dd;
295
296    dd = GetDispatchFromDrawable(dpy, pbuf);
297    if (dd == NULL)
298        return;
299
300    __FETCH_FUNCTION_PTR(DestroyGLXPbufferSGIX);
301    if (pDestroyGLXPbufferSGIX == NULL)
302        return;
303
304    pDestroyGLXPbufferSGIX(dpy, pbuf);
305}
306
307
308
309static GLXContextID dispatch_GetContextIDEXT(const GLXContext ctx)
310{
311    PFNGLXGETCONTEXTIDEXTPROC pGetContextIDEXT;
312    __GLXvendorInfo *dd;
313
314    dd = GetDispatchFromContext(ctx);
315    if (dd == NULL)
316        return None;
317
318    __FETCH_FUNCTION_PTR(GetContextIDEXT);
319    if (pGetContextIDEXT == NULL)
320        return None;
321
322    return pGetContextIDEXT(ctx);
323}
324
325
326
327static Display *dispatch_GetCurrentDisplayEXT(void)
328{
329    PFNGLXGETCURRENTDISPLAYEXTPROC pGetCurrentDisplayEXT;
330    __GLXvendorInfo *dd;
331
332    if (!__VND->getCurrentContext())
333        return NULL;
334
335    dd = __VND->getCurrentDynDispatch();
336    if (dd == NULL)
337        return NULL;
338
339    __FETCH_FUNCTION_PTR(GetCurrentDisplayEXT);
340    if (pGetCurrentDisplayEXT == NULL)
341        return NULL;
342
343    return pGetCurrentDisplayEXT();
344}
345
346
347
348static const char *dispatch_GetDriverConfig(const char *driverName)
349{
350#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
351    /*
352     * The options are constant for a given driverName, so we do not need
353     * a context (and apps expect to be able to call this without one).
354     */
355    return glXGetDriverConfig(driverName);
356#else
357    return NULL;
358#endif
359}
360
361
362
363static int dispatch_GetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
364                                          int attribute, int *value_return)
365{
366    PFNGLXGETFBCONFIGATTRIBSGIXPROC pGetFBConfigAttribSGIX;
367    __GLXvendorInfo *dd;
368
369    dd = GetDispatchFromFBConfig(dpy, config);
370    if (dd == NULL)
371        return GLX_NO_EXTENSION;
372
373    __FETCH_FUNCTION_PTR(GetFBConfigAttribSGIX);
374    if (pGetFBConfigAttribSGIX == NULL)
375        return GLX_NO_EXTENSION;
376
377    return pGetFBConfigAttribSGIX(dpy, config, attribute, value_return);
378}
379
380
381
382static GLXFBConfigSGIX dispatch_GetFBConfigFromVisualSGIX(Display *dpy,
383                                                          XVisualInfo *vis)
384{
385    PFNGLXGETFBCONFIGFROMVISUALSGIXPROC pGetFBConfigFromVisualSGIX;
386    __GLXvendorInfo *dd;
387    GLXFBConfigSGIX ret = NULL;
388
389    dd = GetDispatchFromVisual(dpy, vis);
390    if (dd == NULL)
391        return NULL;
392
393    __FETCH_FUNCTION_PTR(GetFBConfigFromVisualSGIX);
394    if (pGetFBConfigFromVisualSGIX == NULL)
395        return NULL;
396
397    ret = pGetFBConfigFromVisualSGIX(dpy, vis);
398    if (AddFBConfigMapping(dpy, ret, dd))
399        /* XXX: dealloc ret ? */
400        return NULL;
401
402    return ret;
403}
404
405
406
407static void dispatch_GetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
408                                          unsigned long *mask)
409{
410    PFNGLXGETSELECTEDEVENTSGIXPROC pGetSelectedEventSGIX;
411    __GLXvendorInfo *dd;
412
413    dd = GetDispatchFromDrawable(dpy, drawable);
414    if (dd == NULL)
415        return;
416
417    __FETCH_FUNCTION_PTR(GetSelectedEventSGIX);
418    if (pGetSelectedEventSGIX == NULL)
419        return;
420
421    pGetSelectedEventSGIX(dpy, drawable, mask);
422}
423
424
425
426static int dispatch_GetVideoSyncSGI(unsigned int *count)
427{
428    PFNGLXGETVIDEOSYNCSGIPROC pGetVideoSyncSGI;
429    __GLXvendorInfo *dd;
430
431    if (!__VND->getCurrentContext())
432        return GLX_BAD_CONTEXT;
433
434    dd = __VND->getCurrentDynDispatch();
435    if (dd == NULL)
436        return GLX_NO_EXTENSION;
437
438    __FETCH_FUNCTION_PTR(GetVideoSyncSGI);
439    if (pGetVideoSyncSGI == NULL)
440        return GLX_NO_EXTENSION;
441
442    return pGetVideoSyncSGI(count);
443}
444
445
446
447static XVisualInfo *dispatch_GetVisualFromFBConfigSGIX(Display *dpy,
448                                                       GLXFBConfigSGIX config)
449{
450    PFNGLXGETVISUALFROMFBCONFIGSGIXPROC pGetVisualFromFBConfigSGIX;
451    __GLXvendorInfo *dd;
452
453    dd = GetDispatchFromFBConfig(dpy, config);
454    if (dd == NULL)
455        return NULL;
456
457    __FETCH_FUNCTION_PTR(GetVisualFromFBConfigSGIX);
458    if (pGetVisualFromFBConfigSGIX == NULL)
459        return NULL;
460
461    return pGetVisualFromFBConfigSGIX(dpy, config);
462}
463
464
465
466static int dispatch_QueryContextInfoEXT(Display *dpy, GLXContext ctx,
467                                        int attribute, int *value)
468{
469    PFNGLXQUERYCONTEXTINFOEXTPROC pQueryContextInfoEXT;
470    __GLXvendorInfo *dd;
471
472    dd = GetDispatchFromContext(ctx);
473    if (dd == NULL)
474        return GLX_NO_EXTENSION;
475
476    __FETCH_FUNCTION_PTR(QueryContextInfoEXT);
477    if (pQueryContextInfoEXT == NULL)
478        return GLX_NO_EXTENSION;
479
480    return pQueryContextInfoEXT(dpy, ctx, attribute, value);
481}
482
483
484
485static void dispatch_QueryGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf,
486                                         int attribute, unsigned int *value)
487{
488    PFNGLXQUERYGLXPBUFFERSGIXPROC pQueryGLXPbufferSGIX;
489    __GLXvendorInfo *dd;
490
491    dd = GetDispatchFromDrawable(dpy, pbuf);
492    if (dd == NULL)
493        return;
494
495    __FETCH_FUNCTION_PTR(QueryGLXPbufferSGIX);
496    if (pQueryGLXPbufferSGIX == NULL)
497        return;
498
499    pQueryGLXPbufferSGIX(dpy, pbuf, attribute, value);
500}
501
502
503
504static void dispatch_ReleaseTexImageEXT(Display *dpy, GLXDrawable drawable,
505                                        int buffer)
506{
507    PFNGLXRELEASETEXIMAGEEXTPROC pReleaseTexImageEXT;
508    __GLXvendorInfo *dd;
509
510    dd = GetDispatchFromDrawable(dpy, drawable);
511    if (dd == NULL)
512        return;
513
514    __FETCH_FUNCTION_PTR(ReleaseTexImageEXT);
515    if (pReleaseTexImageEXT == NULL)
516        return;
517
518    pReleaseTexImageEXT(dpy, drawable, buffer);
519}
520
521
522
523static void dispatch_SelectEventSGIX(Display *dpy, GLXDrawable drawable,
524                                     unsigned long mask)
525{
526    PFNGLXSELECTEVENTSGIXPROC pSelectEventSGIX;
527    __GLXvendorInfo *dd;
528
529    dd = GetDispatchFromDrawable(dpy, drawable);
530    if (dd == NULL)
531        return;
532
533    __FETCH_FUNCTION_PTR(SelectEventSGIX);
534    if (pSelectEventSGIX == NULL)
535        return;
536
537    pSelectEventSGIX(dpy, drawable, mask);
538}
539
540
541
542static int dispatch_SwapIntervalSGI(int interval)
543{
544    PFNGLXSWAPINTERVALSGIPROC pSwapIntervalSGI;
545    __GLXvendorInfo *dd;
546
547    if (!__VND->getCurrentContext())
548        return GLX_BAD_CONTEXT;
549
550    dd = __VND->getCurrentDynDispatch();
551    if (dd == NULL)
552        return GLX_NO_EXTENSION;
553
554    __FETCH_FUNCTION_PTR(SwapIntervalSGI);
555    if (pSwapIntervalSGI == NULL)
556        return GLX_NO_EXTENSION;
557
558    return pSwapIntervalSGI(interval);
559}
560
561
562
563static int dispatch_WaitVideoSyncSGI(int divisor, int remainder,
564                                     unsigned int *count)
565{
566    PFNGLXWAITVIDEOSYNCSGIPROC pWaitVideoSyncSGI;
567    __GLXvendorInfo *dd;
568
569    if (!__VND->getCurrentContext())
570        return GLX_BAD_CONTEXT;
571
572    dd = __VND->getCurrentDynDispatch();
573    if (dd == NULL)
574        return GLX_NO_EXTENSION;
575
576    __FETCH_FUNCTION_PTR(WaitVideoSyncSGI);
577    if (pWaitVideoSyncSGI == NULL)
578        return GLX_NO_EXTENSION;
579
580    return pWaitVideoSyncSGI(divisor, remainder, count);
581}
582
583
584
585static void dispatch_BindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable,
586                                            int barrier)
587{
588    PFNGLXBINDSWAPBARRIERSGIXPROC pBindSwapBarrierSGIX;
589    __GLXvendorInfo *dd;
590
591    dd = GetDispatchFromDrawable(dpy, drawable);
592    if (dd == NULL)
593        return;
594
595    __FETCH_FUNCTION_PTR(BindSwapBarrierSGIX);
596    if (pBindSwapBarrierSGIX == NULL)
597        return;
598
599    pBindSwapBarrierSGIX(dpy, drawable, barrier);
600}
601
602
603
604static void dispatch_CopySubBufferMESA(Display *dpy, GLXDrawable drawable,
605                                          int x, int y, int width, int height)
606{
607    PFNGLXCOPYSUBBUFFERMESAPROC pCopySubBufferMESA;
608    __GLXvendorInfo *dd;
609
610    dd = GetDispatchFromDrawable(dpy, drawable);
611    if (dd == NULL)
612        return;
613
614    __FETCH_FUNCTION_PTR(CopySubBufferMESA);
615    if (pCopySubBufferMESA == NULL)
616        return;
617
618    pCopySubBufferMESA(dpy, drawable, x, y, width, height);
619}
620
621
622
623static GLXPixmap dispatch_CreateGLXPixmapMESA(Display *dpy,
624                                                 XVisualInfo *visinfo,
625                                                 Pixmap pixmap, Colormap cmap)
626{
627    PFNGLXCREATEGLXPIXMAPMESAPROC pCreateGLXPixmapMESA;
628    __GLXvendorInfo *dd;
629    GLXPixmap ret;
630
631    dd = GetDispatchFromVisual(dpy, visinfo);
632    if (dd == NULL)
633        return None;
634
635    __FETCH_FUNCTION_PTR(CreateGLXPixmapMESA);
636    if (pCreateGLXPixmapMESA == NULL)
637        return None;
638
639    ret = pCreateGLXPixmapMESA(dpy, visinfo, pixmap, cmap);
640    if (AddDrawableMapping(dpy, ret, dd)) {
641        /* XXX: Call glXDestroyGLXPixmap which lives in libglvnd. If we're not
642         * allowed to call it from here, should we extend __glXDispatchTableIndices ?
643         */
644        return None;
645    }
646
647    return ret;
648}
649
650
651
652static GLboolean dispatch_GetMscRateOML(Display *dpy, GLXDrawable drawable,
653                                           int32_t *numerator, int32_t *denominator)
654{
655    PFNGLXGETMSCRATEOMLPROC pGetMscRateOML;
656    __GLXvendorInfo *dd;
657
658    dd = GetDispatchFromDrawable(dpy, drawable);
659    if (dd == NULL)
660        return GL_FALSE;
661
662    __FETCH_FUNCTION_PTR(GetMscRateOML);
663    if (pGetMscRateOML == NULL)
664        return GL_FALSE;
665
666    return pGetMscRateOML(dpy, drawable, numerator, denominator);
667}
668
669
670
671static const char *dispatch_GetScreenDriver(Display *dpy, int scrNum)
672{
673    typedef const char *(*fn_glXGetScreenDriver_ptr)(Display *dpy, int scrNum);
674    fn_glXGetScreenDriver_ptr pGetScreenDriver;
675    __GLXvendorInfo *dd;
676
677    dd = __VND->getDynDispatch(dpy, scrNum);
678    if (dd == NULL)
679        return NULL;
680
681    __FETCH_FUNCTION_PTR(GetScreenDriver);
682    if (pGetScreenDriver == NULL)
683        return NULL;
684
685    return pGetScreenDriver(dpy, scrNum);
686}
687
688
689
690static int dispatch_GetSwapIntervalMESA(void)
691{
692    PFNGLXGETSWAPINTERVALMESAPROC pGetSwapIntervalMESA;
693    __GLXvendorInfo *dd;
694
695    if (!__VND->getCurrentContext())
696        return GLX_BAD_CONTEXT;
697
698    dd = __VND->getCurrentDynDispatch();
699    if (dd == NULL)
700        return 0;
701
702    __FETCH_FUNCTION_PTR(GetSwapIntervalMESA);
703    if (pGetSwapIntervalMESA == NULL)
704        return 0;
705
706    return pGetSwapIntervalMESA();
707}
708
709
710
711static Bool dispatch_GetSyncValuesOML(Display *dpy, GLXDrawable drawable,
712                                         int64_t *ust, int64_t *msc, int64_t *sbc)
713{
714    PFNGLXGETSYNCVALUESOMLPROC pGetSyncValuesOML;
715    __GLXvendorInfo *dd;
716
717    dd = GetDispatchFromDrawable(dpy, drawable);
718    if (dd == NULL)
719        return False;
720
721    __FETCH_FUNCTION_PTR(GetSyncValuesOML);
722    if (pGetSyncValuesOML == NULL)
723        return False;
724
725    return pGetSyncValuesOML(dpy, drawable, ust, msc, sbc);
726}
727
728
729
730static void dispatch_JoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
731                                          GLXDrawable member)
732{
733    PFNGLXJOINSWAPGROUPSGIXPROC pJoinSwapGroupSGIX;
734    __GLXvendorInfo *dd;
735
736    dd = GetDispatchFromDrawable(dpy, drawable);
737    if (dd == NULL)
738        return;
739
740    __FETCH_FUNCTION_PTR(JoinSwapGroupSGIX);
741    if (pJoinSwapGroupSGIX == NULL)
742        return;
743
744    pJoinSwapGroupSGIX(dpy, drawable, member);
745}
746
747
748
749static Bool dispatch_QueryCurrentRendererIntegerMESA(int attribute,
750                                                        unsigned int *value)
751{
752    PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC pQueryCurrentRendererIntegerMESA;
753    __GLXvendorInfo *dd;
754
755    if (!__VND->getCurrentContext())
756        return False;
757
758    dd = __VND->getCurrentDynDispatch();
759    if (dd == NULL)
760        return False;
761
762    __FETCH_FUNCTION_PTR(QueryCurrentRendererIntegerMESA);
763    if (pQueryCurrentRendererIntegerMESA == NULL)
764        return False;
765
766    return pQueryCurrentRendererIntegerMESA(attribute, value);
767}
768
769
770
771static const char *dispatch_QueryCurrentRendererStringMESA(int attribute)
772{
773    PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC pQueryCurrentRendererStringMESA;
774    __GLXvendorInfo *dd;
775
776    if (!__VND->getCurrentContext())
777        return NULL;
778
779    dd = __VND->getCurrentDynDispatch();
780    if (dd == NULL)
781        return NULL;
782
783    __FETCH_FUNCTION_PTR(QueryCurrentRendererStringMESA);
784    if (pQueryCurrentRendererStringMESA == NULL)
785        return NULL;
786
787    return pQueryCurrentRendererStringMESA(attribute);
788}
789
790
791
792static Bool dispatch_QueryMaxSwapBarriersSGIX(Display *dpy, int screen,
793                                                 int *max)
794{
795    PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC pQueryMaxSwapBarriersSGIX;
796    __GLXvendorInfo *dd;
797
798    dd = __VND->getDynDispatch(dpy, screen);
799    if (dd == NULL)
800        return False;
801
802    __FETCH_FUNCTION_PTR(QueryMaxSwapBarriersSGIX);
803    if (pQueryMaxSwapBarriersSGIX == NULL)
804        return False;
805
806    return pQueryMaxSwapBarriersSGIX(dpy, screen, max);
807}
808
809
810
811static Bool dispatch_QueryRendererIntegerMESA(Display *dpy, int screen,
812                                                 int renderer, int attribute,
813                                                 unsigned int *value)
814{
815    PFNGLXQUERYRENDERERINTEGERMESAPROC pQueryRendererIntegerMESA;
816    __GLXvendorInfo *dd;
817
818    dd = __VND->getDynDispatch(dpy, screen);
819    if (dd == NULL)
820        return False;
821
822    __FETCH_FUNCTION_PTR(QueryRendererIntegerMESA);
823    if (pQueryRendererIntegerMESA == NULL)
824        return False;
825
826    return pQueryRendererIntegerMESA(dpy, screen, renderer, attribute, value);
827}
828
829
830
831static const char *dispatch_QueryRendererStringMESA(Display *dpy, int screen,
832                                                       int renderer, int attribute)
833{
834    PFNGLXQUERYRENDERERSTRINGMESAPROC pQueryRendererStringMESA;
835    __GLXvendorInfo *dd = NULL;
836
837    dd = __VND->getDynDispatch(dpy, screen);
838    if (dd == NULL)
839        return NULL;
840
841    __FETCH_FUNCTION_PTR(QueryRendererStringMESA);
842    if (pQueryRendererStringMESA == NULL)
843        return NULL;
844
845    return pQueryRendererStringMESA(dpy, screen, renderer, attribute);
846}
847
848
849
850static Bool dispatch_ReleaseBuffersMESA(Display *dpy, GLXDrawable d)
851{
852    PFNGLXRELEASEBUFFERSMESAPROC pReleaseBuffersMESA;
853    __GLXvendorInfo *dd;
854
855    dd = GetDispatchFromDrawable(dpy, d);
856    if (dd == NULL)
857        return False;
858
859    __FETCH_FUNCTION_PTR(ReleaseBuffersMESA);
860    if (pReleaseBuffersMESA == NULL)
861        return False;
862
863    return pReleaseBuffersMESA(dpy, d);
864}
865
866
867
868static int64_t dispatch_SwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
869                                             int64_t target_msc, int64_t divisor,
870                                             int64_t remainder)
871{
872    PFNGLXSWAPBUFFERSMSCOMLPROC pSwapBuffersMscOML;
873    __GLXvendorInfo *dd;
874
875    dd = GetDispatchFromDrawable(dpy, drawable);
876    if (dd == NULL)
877        return 0;
878
879    __FETCH_FUNCTION_PTR(SwapBuffersMscOML);
880    if (pSwapBuffersMscOML == NULL)
881        return 0;
882
883    return pSwapBuffersMscOML(dpy, drawable, target_msc, divisor, remainder);
884}
885
886
887
888static int dispatch_SwapIntervalMESA(unsigned int interval)
889{
890    PFNGLXSWAPINTERVALMESAPROC pSwapIntervalMESA;
891    __GLXvendorInfo *dd;
892
893    if (!__VND->getCurrentContext())
894        return GLX_BAD_CONTEXT;
895
896    dd = __VND->getCurrentDynDispatch();
897    if (dd == NULL)
898        return 0;
899
900    __FETCH_FUNCTION_PTR(SwapIntervalMESA);
901    if (pSwapIntervalMESA == NULL)
902        return 0;
903
904    return pSwapIntervalMESA(interval);
905}
906
907
908
909static void dispatch_SwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval)
910{
911    PFNGLXSWAPINTERVALEXTPROC pSwapIntervalEXT;
912    __GLXvendorInfo *dd;
913
914    dd = GetDispatchFromDrawable(dpy, drawable);
915    if (dd == NULL)
916        return;
917
918    __FETCH_FUNCTION_PTR(SwapIntervalEXT);
919    if (pSwapIntervalEXT == NULL)
920        return;
921
922    pSwapIntervalEXT(dpy, drawable, interval);
923}
924
925
926
927static Bool dispatch_WaitForMscOML(Display *dpy, GLXDrawable drawable,
928                                      int64_t target_msc, int64_t divisor,
929                                      int64_t remainder, int64_t *ust,
930                                      int64_t *msc, int64_t *sbc)
931{
932    PFNGLXWAITFORMSCOMLPROC pWaitForMscOML;
933    __GLXvendorInfo *dd;
934
935    dd = GetDispatchFromDrawable(dpy, drawable);
936    if (dd == NULL)
937        return False;
938
939    __FETCH_FUNCTION_PTR(WaitForMscOML);
940    if (pWaitForMscOML == NULL)
941        return False;
942
943    return pWaitForMscOML(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc);
944}
945
946
947
948static Bool dispatch_WaitForSbcOML(Display *dpy, GLXDrawable drawable,
949                                      int64_t target_sbc, int64_t *ust,
950                                      int64_t *msc, int64_t *sbc)
951{
952    PFNGLXWAITFORSBCOMLPROC pWaitForSbcOML;
953    __GLXvendorInfo *dd;
954
955    dd = GetDispatchFromDrawable(dpy, drawable);
956    if (dd == NULL)
957        return False;
958
959    __FETCH_FUNCTION_PTR(WaitForSbcOML);
960    if (pWaitForSbcOML == NULL)
961        return False;
962
963    return pWaitForSbcOML(dpy, drawable, target_sbc, ust, msc, sbc);
964}
965
966#undef __FETCH_FUNCTION_PTR
967
968
969/* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */
970const void * const __glXDispatchFunctions[DI_LAST_INDEX + 1] = {
971#define __ATTRIB(field) \
972    [DI_##field] = (void *)dispatch_##field
973
974    __ATTRIB(BindSwapBarrierSGIX),
975    __ATTRIB(BindTexImageEXT),
976    __ATTRIB(ChooseFBConfigSGIX),
977    __ATTRIB(CopySubBufferMESA),
978    __ATTRIB(CreateContextAttribsARB),
979    __ATTRIB(CreateContextWithConfigSGIX),
980    __ATTRIB(CreateGLXPbufferSGIX),
981    __ATTRIB(CreateGLXPixmapMESA),
982    __ATTRIB(CreateGLXPixmapWithConfigSGIX),
983    __ATTRIB(DestroyGLXPbufferSGIX),
984    __ATTRIB(GetContextIDEXT),
985    __ATTRIB(GetCurrentDisplayEXT),
986    __ATTRIB(GetDriverConfig),
987    __ATTRIB(GetFBConfigAttribSGIX),
988    __ATTRIB(GetFBConfigFromVisualSGIX),
989    __ATTRIB(GetMscRateOML),
990    __ATTRIB(GetScreenDriver),
991    __ATTRIB(GetSelectedEventSGIX),
992    __ATTRIB(GetSwapIntervalMESA),
993    __ATTRIB(GetSyncValuesOML),
994    __ATTRIB(GetVideoSyncSGI),
995    __ATTRIB(GetVisualFromFBConfigSGIX),
996    __ATTRIB(JoinSwapGroupSGIX),
997    __ATTRIB(QueryContextInfoEXT),
998    __ATTRIB(QueryCurrentRendererIntegerMESA),
999    __ATTRIB(QueryCurrentRendererStringMESA),
1000    __ATTRIB(QueryGLXPbufferSGIX),
1001    __ATTRIB(QueryMaxSwapBarriersSGIX),
1002    __ATTRIB(QueryRendererIntegerMESA),
1003    __ATTRIB(QueryRendererStringMESA),
1004    __ATTRIB(ReleaseBuffersMESA),
1005    __ATTRIB(ReleaseTexImageEXT),
1006    __ATTRIB(SelectEventSGIX),
1007    __ATTRIB(SwapBuffersMscOML),
1008    __ATTRIB(SwapIntervalEXT),
1009    __ATTRIB(SwapIntervalMESA),
1010    __ATTRIB(SwapIntervalSGI),
1011    __ATTRIB(WaitForMscOML),
1012    __ATTRIB(WaitForSbcOML),
1013    __ATTRIB(WaitVideoSyncSGI),
1014
1015    [DI_LAST_INDEX] = NULL,
1016#undef __ATTRIB
1017};
1018