1 #include <stdlib.h>
2 
3 #include "glxclient.h"
4 #include "glxglvnd.h"
5 #include "glxglvnddispatchfuncs.h"
6 #include "g_glxglvnddispatchindices.h"
7 
8 const int DI_FUNCTION_COUNT = DI_LAST_INDEX;
9 /* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */
10 int __glXDispatchTableIndices[DI_LAST_INDEX + 1];
11 const __GLXapiExports *__glXGLVNDAPIExports;
12 
13 const 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 
dispatch_BindTexImageEXT(Display * dpy,GLXDrawable drawable,int buffer,const int * attrib_list)108 static 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 
dispatch_ChooseFBConfigSGIX(Display * dpy,int screen,int * attrib_list,int * nelements)127 static 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 
dispatch_CreateContextAttribsARB(Display * dpy,GLXFBConfig config,GLXContext share_list,Bool direct,const int * attrib_list)154 static 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 
dispatch_CreateContextWithConfigSGIX(Display * dpy,GLXFBConfigSGIX config,int render_type,GLXContext share_list,Bool direct)197 static 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 
dispatch_CreateGLXPbufferSGIX(Display * dpy,GLXFBConfig config,unsigned int width,unsigned int height,int * attrib_list)228 static 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 
dispatch_CreateGLXPixmapWithConfigSGIX(Display * dpy,GLXFBConfigSGIX config,Pixmap pixmap)262 static 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 
dispatch_DestroyGLXPbufferSGIX(Display * dpy,GLXPbuffer pbuf)291 static 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 
dispatch_GetContextIDEXT(const GLXContext ctx)309 static 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 
dispatch_GetCurrentDisplayEXT(void)327 static 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 
dispatch_GetDriverConfig(const char * driverName)348 static 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 
dispatch_GetFBConfigAttribSGIX(Display * dpy,GLXFBConfigSGIX config,int attribute,int * value_return)363 static 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 
dispatch_GetFBConfigFromVisualSGIX(Display * dpy,XVisualInfo * vis)382 static 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 
dispatch_GetSelectedEventSGIX(Display * dpy,GLXDrawable drawable,unsigned long * mask)407 static 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 
dispatch_GetVideoSyncSGI(unsigned int * count)426 static 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 
dispatch_GetVisualFromFBConfigSGIX(Display * dpy,GLXFBConfigSGIX config)447 static 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 
dispatch_QueryContextInfoEXT(Display * dpy,GLXContext ctx,int attribute,int * value)466 static 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 
dispatch_QueryGLXPbufferSGIX(Display * dpy,GLXPbuffer pbuf,int attribute,unsigned int * value)485 static 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 
dispatch_ReleaseTexImageEXT(Display * dpy,GLXDrawable drawable,int buffer)504 static 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 
dispatch_SelectEventSGIX(Display * dpy,GLXDrawable drawable,unsigned long mask)523 static 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 
dispatch_SwapIntervalSGI(int interval)542 static 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 
dispatch_WaitVideoSyncSGI(int divisor,int remainder,unsigned int * count)563 static 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 
dispatch_BindSwapBarrierSGIX(Display * dpy,GLXDrawable drawable,int barrier)585 static 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 
dispatch_CopySubBufferMESA(Display * dpy,GLXDrawable drawable,int x,int y,int width,int height)604 static 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 
dispatch_CreateGLXPixmapMESA(Display * dpy,XVisualInfo * visinfo,Pixmap pixmap,Colormap cmap)623 static 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 
dispatch_GetMscRateOML(Display * dpy,GLXDrawable drawable,int32_t * numerator,int32_t * denominator)652 static 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 
dispatch_GetScreenDriver(Display * dpy,int scrNum)671 static 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 
dispatch_GetSwapIntervalMESA(void)690 static 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 
dispatch_GetSyncValuesOML(Display * dpy,GLXDrawable drawable,int64_t * ust,int64_t * msc,int64_t * sbc)711 static 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 
dispatch_JoinSwapGroupSGIX(Display * dpy,GLXDrawable drawable,GLXDrawable member)730 static 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 
dispatch_QueryCurrentRendererIntegerMESA(int attribute,unsigned int * value)749 static 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 
dispatch_QueryCurrentRendererStringMESA(int attribute)771 static 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 
dispatch_QueryMaxSwapBarriersSGIX(Display * dpy,int screen,int * max)792 static 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 
dispatch_QueryRendererIntegerMESA(Display * dpy,int screen,int renderer,int attribute,unsigned int * value)811 static 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 
dispatch_QueryRendererStringMESA(Display * dpy,int screen,int renderer,int attribute)831 static 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 
dispatch_ReleaseBuffersMESA(Display * dpy,GLXDrawable d)850 static 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 
dispatch_SwapBuffersMscOML(Display * dpy,GLXDrawable drawable,int64_t target_msc,int64_t divisor,int64_t remainder)868 static 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 
dispatch_SwapIntervalMESA(unsigned int interval)888 static 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 
dispatch_SwapIntervalEXT(Display * dpy,GLXDrawable drawable,int interval)909 static 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 
dispatch_WaitForMscOML(Display * dpy,GLXDrawable drawable,int64_t target_msc,int64_t divisor,int64_t remainder,int64_t * ust,int64_t * msc,int64_t * sbc)927 static 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 
dispatch_WaitForSbcOML(Display * dpy,GLXDrawable drawable,int64_t target_sbc,int64_t * ust,int64_t * msc,int64_t * sbc)948 static 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() */
970 const 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