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