glx: Import glxvnd server module (v2)
This is based on an out-of-tree module written by Kyle: https://github.com/kbrenneman/libglvnd/tree/server-libglx I (ajax) did a bunch of cosmetic fixes, ported it off xfree86 API, added request length checks, and fixed a minor bug or two. v2: Use separate functions to set/get a context tag's private data, and call the backend's MakeCurrent when a client disconnects to unbind the context. (Kyle Brenneman) Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
		
							parent
							
								
									d1fdddeb76
								
							
						
					
					
						commit
						8753218bea
					
				| 
						 | 
					@ -2,7 +2,7 @@ if DRI2
 | 
				
			||||||
GLXDRI_LIBRARY = libglxdri.la
 | 
					GLXDRI_LIBRARY = libglxdri.la
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
noinst_LTLIBRARIES = libglx.la $(GLXDRI_LIBRARY)
 | 
					noinst_LTLIBRARIES = libglx.la $(GLXDRI_LIBRARY) libglxvnd.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_CFLAGS = \
 | 
					AM_CFLAGS = \
 | 
				
			||||||
	@DIX_CFLAGS@ \
 | 
						@DIX_CFLAGS@ \
 | 
				
			||||||
| 
						 | 
					@ -83,3 +83,9 @@ libglx_la_SOURCES = \
 | 
				
			||||||
        xfont.c
 | 
					        xfont.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libglx_la_LIBADD = $(DLOPEN_LIBS)
 | 
					libglx_la_LIBADD = $(DLOPEN_LIBS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libglxvnd_la_SOURCES = \
 | 
				
			||||||
 | 
						vndcmds.c \
 | 
				
			||||||
 | 
						vndext.c \
 | 
				
			||||||
 | 
						vndservermapping.c \
 | 
				
			||||||
 | 
						vndservervendor.c
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,3 +53,24 @@ srcs_glxdri2 = []
 | 
				
			||||||
if build_dri2 or build_dri3
 | 
					if build_dri2 or build_dri3
 | 
				
			||||||
    srcs_glxdri2 = files('glxdri2.c')
 | 
					    srcs_glxdri2 = files('glxdri2.c')
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					srcs_vnd = [
 | 
				
			||||||
 | 
					    'vndcmds.c',
 | 
				
			||||||
 | 
					    'vndext.c',
 | 
				
			||||||
 | 
					    'vndservermapping.c',
 | 
				
			||||||
 | 
					    'vndservervendor.c',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libglxvnd = ''
 | 
				
			||||||
 | 
					if build_glx
 | 
				
			||||||
 | 
					    libglxvnd = static_library('libglxvnd',
 | 
				
			||||||
 | 
						srcs_vnd,
 | 
				
			||||||
 | 
						include_directories: inc,
 | 
				
			||||||
 | 
					        dependencies: [
 | 
				
			||||||
 | 
					            common_dep,
 | 
				
			||||||
 | 
					            dl_dep,
 | 
				
			||||||
 | 
					            dependency('glproto', version: '>= 1.4.17'),
 | 
				
			||||||
 | 
					            dependency('gl', version: '>= 9.2.0'),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,525 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <dix-config.h>
 | 
				
			||||||
 | 
					#include <dix.h>
 | 
				
			||||||
 | 
					#include "vndserver.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HACK: The opcode in old glxproto.h has a typo in it.
 | 
				
			||||||
 | 
					#if !defined(X_GLXCreateContextAttribsARB)
 | 
				
			||||||
 | 
					#define X_GLXCreateContextAttribsARB X_GLXCreateContextAtrribsARB
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_Render(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXRenderReq);
 | 
				
			||||||
 | 
					    CARD32 contextTag;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    contextTag = GlxCheckSwap(client, stuff->contextTag);
 | 
				
			||||||
 | 
					    vendor = glxServer.getContextTag(client, contextTag);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = contextTag;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_RenderLarge(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXRenderLargeReq);
 | 
				
			||||||
 | 
					    CARD32 contextTag;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    contextTag = GlxCheckSwap(client, stuff->contextTag);
 | 
				
			||||||
 | 
					    vendor = glxServer.getContextTag(client, contextTag);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = contextTag;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreateContext(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreateContextReq);
 | 
				
			||||||
 | 
					    CARD32 screen, context;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, stuff->context);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(context, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(context, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(context);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_DestroyContext(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXDestroyContextReq);
 | 
				
			||||||
 | 
					    CARD32 context;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, stuff->context);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(context);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret == Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(context);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = context;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_WaitGL(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXWaitGLReq);
 | 
				
			||||||
 | 
					    CARD32 contextTag;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    contextTag = GlxCheckSwap(client, stuff->contextTag);
 | 
				
			||||||
 | 
					    vendor = glxServer.getContextTag(client, contextTag);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = contextTag;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_WaitX(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXWaitXReq);
 | 
				
			||||||
 | 
					    CARD32 contextTag;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    contextTag = GlxCheckSwap(client, stuff->contextTag);
 | 
				
			||||||
 | 
					    vendor = glxServer.getContextTag(client, contextTag);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = contextTag;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_UseXFont(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXUseXFontReq);
 | 
				
			||||||
 | 
					    CARD32 contextTag;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    contextTag = GlxCheckSwap(client, stuff->contextTag);
 | 
				
			||||||
 | 
					    vendor = glxServer.getContextTag(client, contextTag);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = contextTag;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreateGLXPixmap(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreateGLXPixmapReq);
 | 
				
			||||||
 | 
					    CARD32 screen, glxpixmap;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    glxpixmap = GlxCheckSwap(client, stuff->glxpixmap);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(glxpixmap, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(glxpixmap, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(glxpixmap);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_GetVisualConfigs(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXGetVisualConfigsReq);
 | 
				
			||||||
 | 
					    CARD32 screen;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_DestroyGLXPixmap(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXDestroyGLXPixmapReq);
 | 
				
			||||||
 | 
					    CARD32 glxpixmap;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    glxpixmap = GlxCheckSwap(client, stuff->glxpixmap);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(glxpixmap);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = glxpixmap;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadPixmap;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_QueryExtensionsString(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXQueryExtensionsStringReq);
 | 
				
			||||||
 | 
					    CARD32 screen;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_QueryServerString(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXQueryServerStringReq);
 | 
				
			||||||
 | 
					    CARD32 screen;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_ChangeDrawableAttributes(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXChangeDrawableAttributesReq);
 | 
				
			||||||
 | 
					    CARD32 drawable;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    drawable = GlxCheckSwap(client, stuff->drawable);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(drawable);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = drawable;
 | 
				
			||||||
 | 
					        return BadDrawable;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreateNewContext(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreateNewContextReq);
 | 
				
			||||||
 | 
					    CARD32 screen, context;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, stuff->context);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(context, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(context, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(context);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreatePbuffer(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreatePbufferReq);
 | 
				
			||||||
 | 
					    CARD32 screen, pbuffer;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    pbuffer = GlxCheckSwap(client, stuff->pbuffer);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(pbuffer, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(pbuffer, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(pbuffer);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreatePixmap(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreatePixmapReq);
 | 
				
			||||||
 | 
					    CARD32 screen, glxpixmap;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    glxpixmap = GlxCheckSwap(client, stuff->glxpixmap);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(glxpixmap, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(glxpixmap, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(glxpixmap);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreateWindow(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreateWindowReq);
 | 
				
			||||||
 | 
					    CARD32 screen, glxwindow;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    glxwindow = GlxCheckSwap(client, stuff->glxwindow);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(glxwindow, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(glxwindow, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(glxwindow);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_CreateContextAttribsARB(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCreateContextAttribsARBReq);
 | 
				
			||||||
 | 
					    CARD32 screen, context;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, stuff->context);
 | 
				
			||||||
 | 
					    LEGAL_NEW_RESOURCE(context, client);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        if (!glxServer.addXIDMap(context, vendor)) {
 | 
				
			||||||
 | 
					            return BadAlloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret != Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(context);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_DestroyPbuffer(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXDestroyPbufferReq);
 | 
				
			||||||
 | 
					    CARD32 pbuffer;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    pbuffer = GlxCheckSwap(client, stuff->pbuffer);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(pbuffer);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret == Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(pbuffer);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = pbuffer;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadPbuffer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_DestroyPixmap(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXDestroyPixmapReq);
 | 
				
			||||||
 | 
					    CARD32 glxpixmap;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    glxpixmap = GlxCheckSwap(client, stuff->glxpixmap);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(glxpixmap);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret == Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(glxpixmap);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = glxpixmap;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadPixmap;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_DestroyWindow(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXDestroyWindowReq);
 | 
				
			||||||
 | 
					    CARD32 glxwindow;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    glxwindow = GlxCheckSwap(client, stuff->glxwindow);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(glxwindow);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        if (ret == Success) {
 | 
				
			||||||
 | 
					            glxServer.removeXIDMap(glxwindow);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = glxwindow;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadWindow;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_GetDrawableAttributes(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXGetDrawableAttributesReq);
 | 
				
			||||||
 | 
					    CARD32 drawable;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    drawable = GlxCheckSwap(client, stuff->drawable);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(drawable);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = drawable;
 | 
				
			||||||
 | 
					        return BadDrawable;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_GetFBConfigs(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXGetFBConfigsReq);
 | 
				
			||||||
 | 
					    CARD32 screen;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    screen = GlxCheckSwap(client, stuff->screen);
 | 
				
			||||||
 | 
					    if (screen < screenInfo.numScreens) {
 | 
				
			||||||
 | 
					        vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = screen;
 | 
				
			||||||
 | 
					        return BadMatch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_QueryContext(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXQueryContextReq);
 | 
				
			||||||
 | 
					    CARD32 context;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, stuff->context);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(context);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = context;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static int dispatch_IsDirect(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXIsDirectReq);
 | 
				
			||||||
 | 
					    CARD32 context;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, stuff->context);
 | 
				
			||||||
 | 
					    vendor = glxServer.getXIDMap(context);
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        ret = glxServer.forwardRequest(vendor, client);
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        client->errorValue = context;
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,483 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <dix-config.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "hashtable.h"
 | 
				
			||||||
 | 
					#include "vndserver.h"
 | 
				
			||||||
 | 
					#include "vndservervendor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The length of the dispatchFuncs array. Every opcode above this is a
 | 
				
			||||||
 | 
					 * X_GLsop_* code, which all can use the same handler.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define OPCODE_ARRAY_LEN 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This hashtable is used to keep track of the dispatch stubs for
 | 
				
			||||||
 | 
					// GLXVendorPrivate and GLXVendorPrivateWithReply.
 | 
				
			||||||
 | 
					typedef struct GlxVendorPrivDispatchRec {
 | 
				
			||||||
 | 
					    CARD32 vendorCode;
 | 
				
			||||||
 | 
					    GlxServerDispatchProc proc;
 | 
				
			||||||
 | 
					    HashTable hh;
 | 
				
			||||||
 | 
					} GlxVendorPrivDispatch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxServerDispatchProc dispatchFuncs[OPCODE_ARRAY_LEN] = {};
 | 
				
			||||||
 | 
					static HashTable vendorPrivHash = NULL;
 | 
				
			||||||
 | 
					static HtGenericHashSetupRec vendorPrivSetup = {
 | 
				
			||||||
 | 
					    .keySize = sizeof(void*)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int DispatchBadRequest(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return BadRequest;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxVendorPrivDispatch *LookupVendorPrivDispatch(CARD32 vendorCode, Bool create)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxVendorPrivDispatch *disp = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    disp = ht_find(vendorPrivHash, &vendorCode);
 | 
				
			||||||
 | 
					    if (disp == NULL && create) {
 | 
				
			||||||
 | 
					        if ((disp = ht_add(vendorPrivHash, &vendorCode))) {
 | 
				
			||||||
 | 
					            disp->vendorCode = vendorCode;
 | 
				
			||||||
 | 
					            disp->proc = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return disp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxServerDispatchProc GetVendorDispatchFunc(CARD8 opcode, CARD32 vendorCode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xorg_list_for_each_entry(vendor, &GlxVendorList, entry) {
 | 
				
			||||||
 | 
					        GlxServerDispatchProc proc = vendor->glxvc.getDispatchAddress(opcode, vendorCode);
 | 
				
			||||||
 | 
					        if (proc != NULL) {
 | 
				
			||||||
 | 
					            return proc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return DispatchBadRequest;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void SetReplyHeader(ClientPtr client, void *replyPtr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    xGenericReply *rep = (xGenericReply *) replyPtr;
 | 
				
			||||||
 | 
					    rep->type = X_Reply;
 | 
				
			||||||
 | 
					    rep->sequenceNumber = client->sequence;
 | 
				
			||||||
 | 
					    rep->length = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Include the trivial dispatch handlers */
 | 
				
			||||||
 | 
					#include "vnd_dispatch_stubs.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXQueryVersion(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    xGLXQueryVersionReply reply;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(xGLXQueryVersionReq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SetReplyHeader(client, &reply);
 | 
				
			||||||
 | 
					    reply.majorVersion = GlxCheckSwap(client, 1);
 | 
				
			||||||
 | 
					    reply.minorVersion = GlxCheckSwap(client, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
 | 
				
			||||||
 | 
					    return Success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* broken header workaround */
 | 
				
			||||||
 | 
					#ifndef X_GLXSetClientInfo2ARB
 | 
				
			||||||
 | 
					#define X_GLXSetClientInfo2ARB X_GLXSetConfigInfo2ARB
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This function is used for X_GLXClientInfo, X_GLXSetClientInfoARB, and
 | 
				
			||||||
 | 
					 * X_GLXSetClientInfo2ARB.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int dispatch_GLXClientInfo(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor;
 | 
				
			||||||
 | 
					    void *requestCopy = NULL;
 | 
				
			||||||
 | 
					    size_t requestSize = client->req_len * 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (client->minorOp == X_GLXClientInfo) {
 | 
				
			||||||
 | 
					        REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq);
 | 
				
			||||||
 | 
					    } else if (client->minorOp == X_GLXSetClientInfoARB) {
 | 
				
			||||||
 | 
					        REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
 | 
				
			||||||
 | 
					    } else if (client->minorOp == X_GLXSetClientInfo2ARB) {
 | 
				
			||||||
 | 
					        REQUEST_AT_LEAST_SIZE(xGLXSetClientInfo2ARBReq);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return BadImplementation;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We'll forward this request to each vendor library. Since a vendor might
 | 
				
			||||||
 | 
					    // modify the request data in place (e.g., for byte swapping), make a copy
 | 
				
			||||||
 | 
					    // of the request first.
 | 
				
			||||||
 | 
					    requestCopy = malloc(requestSize);
 | 
				
			||||||
 | 
					    if (requestCopy == NULL) {
 | 
				
			||||||
 | 
					        return BadAlloc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    memcpy(requestCopy, client->requestBuffer, requestSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xorg_list_for_each_entry(vendor, &GlxVendorList, entry) {
 | 
				
			||||||
 | 
					        vendor->glxvc.handleRequest(client);
 | 
				
			||||||
 | 
					        // Revert the request buffer back to our copy.
 | 
				
			||||||
 | 
					        memcpy(client->requestBuffer, requestCopy, requestSize);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    free(requestCopy);
 | 
				
			||||||
 | 
					    return Success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int CommonLoseCurrent(ClientPtr client, GlxContextTagInfo *tagInfo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = tagInfo->vendor->glxvc.makeCurrent(client,
 | 
				
			||||||
 | 
					            tagInfo->tag, // No old context tag,
 | 
				
			||||||
 | 
					            None, None, None, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ret == Success) {
 | 
				
			||||||
 | 
					        GlxFreeContextTag(tagInfo);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int CommonMakeNewCurrent(ClientPtr client,
 | 
				
			||||||
 | 
					        GlxServerVendor *vendor,
 | 
				
			||||||
 | 
					        GLXDrawable drawable,
 | 
				
			||||||
 | 
					        GLXDrawable readdrawable,
 | 
				
			||||||
 | 
					        GLXContextID context,
 | 
				
			||||||
 | 
					        GLXContextTag *newContextTag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = BadAlloc;
 | 
				
			||||||
 | 
					    GlxContextTagInfo *tagInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tagInfo = GlxAllocContextTag(client, vendor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tagInfo) {
 | 
				
			||||||
 | 
					        ret = vendor->glxvc.makeCurrent(client,
 | 
				
			||||||
 | 
					                0, // No old context tag,
 | 
				
			||||||
 | 
					                drawable, readdrawable, context,
 | 
				
			||||||
 | 
					                tagInfo->tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ret == Success) {
 | 
				
			||||||
 | 
					            tagInfo->drawable = drawable;
 | 
				
			||||||
 | 
					            tagInfo->readdrawable = readdrawable;
 | 
				
			||||||
 | 
					            tagInfo->context = context;
 | 
				
			||||||
 | 
					            *newContextTag = tagInfo->tag;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            GlxFreeContextTag(tagInfo);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int CommonMakeCurrent(ClientPtr client,
 | 
				
			||||||
 | 
					        GLXContextTag oldContextTag,
 | 
				
			||||||
 | 
					        GLXDrawable drawable,
 | 
				
			||||||
 | 
					        GLXDrawable readdrawable,
 | 
				
			||||||
 | 
					        GLXContextID context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    xGLXMakeCurrentReply reply = {};
 | 
				
			||||||
 | 
					    GlxContextTagInfo *oldTag = NULL;
 | 
				
			||||||
 | 
					    GlxServerVendor *newVendor = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oldContextTag = GlxCheckSwap(client, oldContextTag);
 | 
				
			||||||
 | 
					    drawable = GlxCheckSwap(client, drawable);
 | 
				
			||||||
 | 
					    readdrawable = GlxCheckSwap(client, readdrawable);
 | 
				
			||||||
 | 
					    context = GlxCheckSwap(client, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SetReplyHeader(client, &reply);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (oldContextTag != 0) {
 | 
				
			||||||
 | 
					        oldTag = GlxLookupContextTag(client, oldContextTag);
 | 
				
			||||||
 | 
					        if (oldTag == NULL) {
 | 
				
			||||||
 | 
					            return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (context != 0) {
 | 
				
			||||||
 | 
					        newVendor = GlxGetXIDMap(context);
 | 
				
			||||||
 | 
					        if (newVendor == NULL) {
 | 
				
			||||||
 | 
					            return GlxErrorBase + GLXBadContext;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (oldTag == NULL && newVendor == NULL) {
 | 
				
			||||||
 | 
					        // Nothing to do here. Just send a successful reply.
 | 
				
			||||||
 | 
					        reply.contextTag = 0;
 | 
				
			||||||
 | 
					    } else if (oldTag != NULL && newVendor != NULL
 | 
				
			||||||
 | 
					            && oldTag->context == context
 | 
				
			||||||
 | 
					            && oldTag->drawable == drawable
 | 
				
			||||||
 | 
					            && oldTag->readdrawable == readdrawable)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // The old and new values are all the same, so send a successful reply.
 | 
				
			||||||
 | 
					        reply.contextTag = oldTag->tag;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // TODO: For switching contexts in a single vendor, just make one
 | 
				
			||||||
 | 
					        // makeCurrent call?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: When changing vendors, would it be better to do the
 | 
				
			||||||
 | 
					        // MakeCurrent(new) first, then the LoseCurrent(old)?
 | 
				
			||||||
 | 
					        // If the MakeCurrent(new) fails, then the old context will still be current.
 | 
				
			||||||
 | 
					        // If the LoseCurrent(old) fails, then we can (probably) undo the MakeCurrent(new) with
 | 
				
			||||||
 | 
					        // a LoseCurrent(old).
 | 
				
			||||||
 | 
					        // But, if the recovery LoseCurrent(old) fails, then we're really in a bad state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Clear the old context first.
 | 
				
			||||||
 | 
					        if (oldTag != NULL) {
 | 
				
			||||||
 | 
					            int ret = CommonLoseCurrent(client, oldTag);
 | 
				
			||||||
 | 
					            if (ret != Success) {
 | 
				
			||||||
 | 
					                return ret;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            oldTag = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (newVendor != NULL) {
 | 
				
			||||||
 | 
					            int ret = CommonMakeNewCurrent(client, newVendor, drawable, readdrawable, context, &reply.contextTag);
 | 
				
			||||||
 | 
					            if (ret != Success) {
 | 
				
			||||||
 | 
					                return ret;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            reply.contextTag = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reply.contextTag = GlxCheckSwap(client, reply.contextTag);
 | 
				
			||||||
 | 
					    WriteToClient(client, sz_xGLXMakeCurrentReply, &reply);
 | 
				
			||||||
 | 
					    return Success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXMakeCurrent(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXMakeCurrentReq);
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CommonMakeCurrent(client, stuff->oldContextTag,
 | 
				
			||||||
 | 
					            stuff->drawable, stuff->drawable, stuff->context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXMakeContextCurrent(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXMakeContextCurrentReq);
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CommonMakeCurrent(client, stuff->oldContextTag,
 | 
				
			||||||
 | 
					            stuff->drawable, stuff->readdrawable, stuff->context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXMakeCurrentReadSGI(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXMakeCurrentReadSGIReq);
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CommonMakeCurrent(client, stuff->oldContextTag,
 | 
				
			||||||
 | 
					            stuff->drawable, stuff->readable, stuff->context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXCopyContext(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXCopyContextReq);
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor;
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If we've got a context tag, then we'll use it to select a vendor. If we
 | 
				
			||||||
 | 
					    // don't have a tag, then we'll look up one of the contexts. In either
 | 
				
			||||||
 | 
					    // case, it's up to the vendor library to make sure that the context ID's
 | 
				
			||||||
 | 
					    // are valid.
 | 
				
			||||||
 | 
					    if (stuff->contextTag != 0) {
 | 
				
			||||||
 | 
					        GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, GlxCheckSwap(client, stuff->contextTag));
 | 
				
			||||||
 | 
					        if (tagInfo == NULL) {
 | 
				
			||||||
 | 
					            return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vendor = tagInfo->vendor;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        vendor = GlxGetXIDMap(GlxCheckSwap(client, stuff->source));
 | 
				
			||||||
 | 
					        if (vendor == NULL) {
 | 
				
			||||||
 | 
					            return GlxErrorBase + GLXBadContext;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return vendor->glxvc.handleRequest(client);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXSwapBuffers(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					    REQUEST(xGLXSwapBuffersReq);
 | 
				
			||||||
 | 
					    REQUEST_SIZE_MATCH(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (stuff->contextTag != 0) {
 | 
				
			||||||
 | 
					        // If the request has a context tag, then look up a vendor from that.
 | 
				
			||||||
 | 
					        // The vendor library is then responsible for validating the drawable.
 | 
				
			||||||
 | 
					        GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, GlxCheckSwap(client, stuff->contextTag));
 | 
				
			||||||
 | 
					        if (tagInfo == NULL) {
 | 
				
			||||||
 | 
					            return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vendor = tagInfo->vendor;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // We don't have a context tag, so look up the vendor from the
 | 
				
			||||||
 | 
					        // drawable.
 | 
				
			||||||
 | 
					        vendor = GlxGetXIDMap(GlxCheckSwap(client, stuff->drawable));
 | 
				
			||||||
 | 
					        if (vendor == NULL) {
 | 
				
			||||||
 | 
					            return GlxErrorBase + GLXBadDrawable;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return vendor->glxvc.handleRequest(client);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This is a generic handler for all of the X_GLXsop* requests.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int dispatch_GLXSingle(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xGLXSingleReq);
 | 
				
			||||||
 | 
					    GlxContextTagInfo *tagInfo;
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tagInfo = GlxLookupContextTag(client, GlxCheckSwap(client, stuff->contextTag));
 | 
				
			||||||
 | 
					    if (tagInfo != NULL) {
 | 
				
			||||||
 | 
					        return tagInfo->vendor->glxvc.handleRequest(client);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return GlxErrorBase + GLXBadContextTag;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dispatch_GLXVendorPriv(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxVendorPrivDispatch *disp;
 | 
				
			||||||
 | 
					    REQUEST(xGLXVendorPrivateReq);
 | 
				
			||||||
 | 
					    REQUEST_AT_LEAST_SIZE(*stuff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    disp = LookupVendorPrivDispatch(GlxCheckSwap(client, stuff->vendorCode), TRUE);
 | 
				
			||||||
 | 
					    if (disp == NULL) {
 | 
				
			||||||
 | 
					        return BadAlloc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (disp->proc == NULL) {
 | 
				
			||||||
 | 
					        // We don't have a dispatch function for this request yet. Check with
 | 
				
			||||||
 | 
					        // each vendor library to find one.
 | 
				
			||||||
 | 
					        // Note that even if none of the vendors provides a dispatch stub,
 | 
				
			||||||
 | 
					        // we'll still add an entry to the dispatch table, so that we don't
 | 
				
			||||||
 | 
					        // have to look it up again later.
 | 
				
			||||||
 | 
					        disp = (GlxVendorPrivDispatch *) malloc(sizeof(GlxVendorPrivDispatch));
 | 
				
			||||||
 | 
					        disp->proc = GetVendorDispatchFunc(stuff->glxCode,
 | 
				
			||||||
 | 
					                                           GlxCheckSwap(client,
 | 
				
			||||||
 | 
					                                                        stuff->vendorCode));
 | 
				
			||||||
 | 
					        if (disp->proc == NULL) {
 | 
				
			||||||
 | 
					            disp->proc = DispatchBadRequest;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return disp->proc(client);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bool GlxDispatchInit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxVendorPrivDispatch *disp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vendorPrivHash = ht_create(sizeof(CARD32), sizeof(GlxVendorPrivDispatch),
 | 
				
			||||||
 | 
					                               ht_generic_hash, ht_generic_compare,
 | 
				
			||||||
 | 
					                               (void *) &vendorPrivSetup);
 | 
				
			||||||
 | 
					    if (!vendorPrivHash) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Assign a custom dispatch stub GLXMakeCurrentReadSGI. This is the only
 | 
				
			||||||
 | 
					    // vendor private request that we need to deal with in libglvnd itself.
 | 
				
			||||||
 | 
					    disp = LookupVendorPrivDispatch(X_GLXvop_MakeCurrentReadSGI, TRUE);
 | 
				
			||||||
 | 
					    if (disp == NULL) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    disp->proc = dispatch_GLXMakeCurrentReadSGI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Assign the dispatch stubs for requests that need special handling.
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXQueryVersion] = dispatch_GLXQueryVersion;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXMakeCurrent] = dispatch_GLXMakeCurrent;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXMakeContextCurrent] = dispatch_GLXMakeContextCurrent;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCopyContext] = dispatch_GLXCopyContext;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXSwapBuffers] = dispatch_GLXSwapBuffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXClientInfo] = dispatch_GLXClientInfo;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXSetClientInfoARB] = dispatch_GLXClientInfo;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXSetClientInfo2ARB] = dispatch_GLXClientInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXVendorPrivate] = dispatch_GLXVendorPriv;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXVendorPrivateWithReply] = dispatch_GLXVendorPriv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Assign the trivial stubs
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXRender] = dispatch_Render;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXRenderLarge] = dispatch_RenderLarge;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreateContext] = dispatch_CreateContext;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXDestroyContext] = dispatch_DestroyContext;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXWaitGL] = dispatch_WaitGL;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXWaitX] = dispatch_WaitX;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXUseXFont] = dispatch_UseXFont;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreateGLXPixmap] = dispatch_CreateGLXPixmap;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXGetVisualConfigs] = dispatch_GetVisualConfigs;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXDestroyGLXPixmap] = dispatch_DestroyGLXPixmap;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXQueryExtensionsString] = dispatch_QueryExtensionsString;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXQueryServerString] = dispatch_QueryServerString;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXChangeDrawableAttributes] = dispatch_ChangeDrawableAttributes;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreateNewContext] = dispatch_CreateNewContext;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreatePbuffer] = dispatch_CreatePbuffer;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreatePixmap] = dispatch_CreatePixmap;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreateWindow] = dispatch_CreateWindow;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXCreateContextAttribsARB] = dispatch_CreateContextAttribsARB;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXDestroyPbuffer] = dispatch_DestroyPbuffer;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXDestroyPixmap] = dispatch_DestroyPixmap;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXDestroyWindow] = dispatch_DestroyWindow;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXGetDrawableAttributes] = dispatch_GetDrawableAttributes;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXGetFBConfigs] = dispatch_GetFBConfigs;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXQueryContext] = dispatch_QueryContext;
 | 
				
			||||||
 | 
					    dispatchFuncs[X_GLXIsDirect] = dispatch_IsDirect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GlxDispatchReset(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memset(dispatchFuncs, 0, sizeof(dispatchFuncs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ht_destroy(vendorPrivHash);
 | 
				
			||||||
 | 
					    vendorPrivHash = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int GlxDispatchRequest(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    REQUEST(xReq);
 | 
				
			||||||
 | 
					    if (stuff->data < OPCODE_ARRAY_LEN) {
 | 
				
			||||||
 | 
					        if (dispatchFuncs[stuff->data] == NULL) {
 | 
				
			||||||
 | 
					            // Try to find a dispatch stub.
 | 
				
			||||||
 | 
					            dispatchFuncs[stuff->data] = GetVendorDispatchFunc(stuff->data, 0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return dispatchFuncs[stuff->data](client);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return dispatch_GLXSingle(client);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,306 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "vndserver.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <scrnintstr.h>
 | 
				
			||||||
 | 
					#include <windowstr.h>
 | 
				
			||||||
 | 
					#include <dixstruct.h>
 | 
				
			||||||
 | 
					#include <extnsionst.h>
 | 
				
			||||||
 | 
					#include <glx_extinit.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <GL/glxproto.h>
 | 
				
			||||||
 | 
					#include "vndservervendor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int GlxErrorBase = 0;
 | 
				
			||||||
 | 
					static CallbackListPtr vndInitCallbackList;
 | 
				
			||||||
 | 
					static DevPrivateKeyRec glvXGLVScreenPrivKey;
 | 
				
			||||||
 | 
					static DevPrivateKeyRec glvXGLVClientPrivKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The resource type used to keep track of the vendor library for XID's.
 | 
				
			||||||
 | 
					RESTYPE idResource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					idResourceDeleteCallback(void *value, XID id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxScreenPriv *
 | 
				
			||||||
 | 
					xglvGetScreenPrivate(ScreenPtr pScreen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return dixLookupPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					xglvSetScreenPrivate(ScreenPtr pScreen, void *priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    dixSetPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey, priv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxScreenPriv *
 | 
				
			||||||
 | 
					GlxGetScreen(ScreenPtr pScreen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (pScreen != NULL) {
 | 
				
			||||||
 | 
					        GlxScreenPriv *priv = xglvGetScreenPrivate(pScreen);
 | 
				
			||||||
 | 
					        if (priv == NULL) {
 | 
				
			||||||
 | 
					            priv = calloc(1, sizeof(GlxScreenPriv));
 | 
				
			||||||
 | 
					            if (priv == NULL) {
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            xglvSetScreenPrivate(pScreen, priv);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return priv;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					GlxMappingReset(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i=0; i<screenInfo.numScreens; i++) {
 | 
				
			||||||
 | 
					        GlxScreenPriv *priv = xglvGetScreenPrivate(screenInfo.screens[i]);
 | 
				
			||||||
 | 
					        if (priv != NULL) {
 | 
				
			||||||
 | 
					            xglvSetScreenPrivate(screenInfo.screens[i], NULL);
 | 
				
			||||||
 | 
					            free(priv);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Bool
 | 
				
			||||||
 | 
					GlxMappingInit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i=0; i<screenInfo.numScreens; i++) {
 | 
				
			||||||
 | 
					        if (GlxGetScreen(screenInfo.screens[i]) == NULL) {
 | 
				
			||||||
 | 
					            GlxMappingReset();
 | 
				
			||||||
 | 
					            return FALSE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    idResource = CreateNewResourceType(idResourceDeleteCallback,
 | 
				
			||||||
 | 
					                                       "GLXServerIDRes");
 | 
				
			||||||
 | 
					    if (idResource == RT_NONE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        GlxMappingReset();
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxClientPriv *
 | 
				
			||||||
 | 
					xglvGetClientPrivate(ClientPtr pClient)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return dixLookupPrivate(&pClient->devPrivates, &glvXGLVClientPrivKey);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					xglvSetClientPrivate(ClientPtr pClient, void *priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    dixSetPrivate(&pClient->devPrivates, &glvXGLVClientPrivKey, priv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxClientPriv *
 | 
				
			||||||
 | 
					GlxGetClientData(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxClientPriv *cl = xglvGetClientPrivate(client);
 | 
				
			||||||
 | 
					    if (cl == NULL) {
 | 
				
			||||||
 | 
					        cl = calloc(1, sizeof(GlxClientPriv));
 | 
				
			||||||
 | 
					        if (cl != NULL) {
 | 
				
			||||||
 | 
					            xglvSetClientPrivate(client, cl);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return cl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					GlxFreeClientData(ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxClientPriv *cl = xglvGetClientPrivate(client);
 | 
				
			||||||
 | 
					    if (cl != NULL) {
 | 
				
			||||||
 | 
					        unsigned int i;
 | 
				
			||||||
 | 
					        for (i = 0; i < cl->contextTagCount; i++) {
 | 
				
			||||||
 | 
					            GlxContextTagInfo *tag = &cl->contextTags[i];
 | 
				
			||||||
 | 
					            if (tag->vendor != NULL) {
 | 
				
			||||||
 | 
					                tag->vendor->glxvc.makeCurrent(client, tag->tag,
 | 
				
			||||||
 | 
					                                               None, None, None, 0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        xglvSetClientPrivate(client, NULL);
 | 
				
			||||||
 | 
					        free(cl->contextTags);
 | 
				
			||||||
 | 
					        free(cl);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					GLXClientCallback(CallbackListPtr *list, void *closure, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
 | 
				
			||||||
 | 
					    ClientPtr client = clientinfo->client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (client->clientState)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case ClientStateRetained:
 | 
				
			||||||
 | 
					        case ClientStateGone:
 | 
				
			||||||
 | 
					            GlxFreeClientData(client);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					GLXReset(ExtensionEntry *extEntry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // xf86Msg(X_INFO, "GLX: GLXReset\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GlxVendorExtensionReset(extEntry);
 | 
				
			||||||
 | 
					    GlxDispatchReset();
 | 
				
			||||||
 | 
					    GlxMappingReset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					GlxExtensionInit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ExtensionEntry *extEntry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Init private keys, per-screen data
 | 
				
			||||||
 | 
					    if (!dixRegisterPrivateKey(&glvXGLVScreenPrivKey, PRIVATE_SCREEN, 0))
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    if (!dixRegisterPrivateKey(&glvXGLVClientPrivKey, PRIVATE_CLIENT, 0))
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!GlxMappingInit()) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!GlxDispatchInit()) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!AddCallback(&ClientStateCallback, GLXClientCallback, NULL)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
 | 
				
			||||||
 | 
					                            __GLX_NUMBER_ERRORS, GlxDispatchRequest,
 | 
				
			||||||
 | 
					                            GlxDispatchRequest, GLXReset, StandardMinorOpcode);
 | 
				
			||||||
 | 
					    if (!extEntry) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GlxErrorBase = extEntry->errorBase;
 | 
				
			||||||
 | 
					    CallCallbacks(&vndInitCallbackList, extEntry);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					GlxForwardRequest(GlxServerVendor *vendor, ClientPtr client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vendor->glxvc.handleRequest(client);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxServerVendor *
 | 
				
			||||||
 | 
					GlxGetContextTag(ClientPtr client, GLXContextTag tag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tagInfo != NULL) {
 | 
				
			||||||
 | 
					        return tagInfo->vendor;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Bool
 | 
				
			||||||
 | 
					GlxSetContextTagPrivate(ClientPtr client, GLXContextTag tag, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag);
 | 
				
			||||||
 | 
					    if (tagInfo != NULL) {
 | 
				
			||||||
 | 
					        tagInfo->data = data;
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *
 | 
				
			||||||
 | 
					GlxGetContextTagPrivate(ClientPtr client, GLXContextTag tag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag);
 | 
				
			||||||
 | 
					    if (tagInfo != NULL) {
 | 
				
			||||||
 | 
					        return tagInfo->data;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxServerImports *
 | 
				
			||||||
 | 
					GlxAllocateServerImports(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return calloc(1, sizeof(GlxServerImports));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					GlxFreeServerImports(GlxServerImports *imports)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    free(imports);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_X_EXPORT const GlxServerExports glxServer = {
 | 
				
			||||||
 | 
					    GLXSERVER_VENDOR_ABI_MAJOR_VERSION, // majorVersion
 | 
				
			||||||
 | 
					    GLXSERVER_VENDOR_ABI_MINOR_VERSION, // minorVersion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &vndInitCallbackList,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GlxAllocateServerImports, // allocateServerImports
 | 
				
			||||||
 | 
					    GlxFreeServerImports, // freeServerImports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GlxCreateVendor, // createVendor
 | 
				
			||||||
 | 
					    GlxDestroyVendor, // destroyVendor
 | 
				
			||||||
 | 
					    GlxSetScreenVendor, // setScreenVendor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GlxAddXIDMap, // addXIDMap
 | 
				
			||||||
 | 
					    GlxGetXIDMap, // getXIDMap
 | 
				
			||||||
 | 
					    GlxRemoveXIDMap, // removeXIDMap
 | 
				
			||||||
 | 
					    GlxGetContextTag, // getContextTag
 | 
				
			||||||
 | 
					    GlxSetContextTagPrivate, // setContextTagPrivate
 | 
				
			||||||
 | 
					    GlxGetContextTagPrivate, // getContextTagPrivate
 | 
				
			||||||
 | 
					    GlxGetVendorForScreen, // getVendorForScreen
 | 
				
			||||||
 | 
					    GlxForwardRequest, // forwardRequest
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const GlxServerExports *
 | 
				
			||||||
 | 
					glvndGetExports(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return &glxServer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,119 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef VNDSERVER_H
 | 
				
			||||||
 | 
					#define VNDSERVER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <dix-config.h>
 | 
				
			||||||
 | 
					#include "glxvndabi.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GLXContextID CARD32
 | 
				
			||||||
 | 
					#define GLXDrawable CARD32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct GlxScreenPrivRec {
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor;
 | 
				
			||||||
 | 
					} GlxScreenPriv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct GlxContextTagInfoRec {
 | 
				
			||||||
 | 
					    GLXContextTag tag;
 | 
				
			||||||
 | 
					    ClientPtr client;
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor;
 | 
				
			||||||
 | 
					    void *data;
 | 
				
			||||||
 | 
					    GLXContextID context;
 | 
				
			||||||
 | 
					    GLXDrawable drawable;
 | 
				
			||||||
 | 
					    GLXDrawable readdrawable;
 | 
				
			||||||
 | 
					} GlxContextTagInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct GlxClientPrivRec {
 | 
				
			||||||
 | 
					    GlxContextTagInfo *contextTags;
 | 
				
			||||||
 | 
					    unsigned int contextTagCount;
 | 
				
			||||||
 | 
					} GlxClientPriv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int GlxErrorBase;
 | 
				
			||||||
 | 
					extern RESTYPE idResource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Defined in glxext.c.
 | 
				
			||||||
 | 
					const ExtensionEntry *GlxGetExtensionEntry(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bool GlxDispatchInit(void);
 | 
				
			||||||
 | 
					void GlxDispatchReset(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Handles a request from the client.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function will look up the correct handler function and forward the
 | 
				
			||||||
 | 
					 * request to it.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int GlxDispatchRequest(ClientPtr client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Looks up the GlxClientPriv struct for a client. If we don't have a
 | 
				
			||||||
 | 
					 * GlxClientPriv struct yet, then allocate one.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					GlxClientPriv *GlxGetClientData(ClientPtr client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Frees any data that's specific to a client. This should be called when a
 | 
				
			||||||
 | 
					 * client disconnects.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void GlxFreeClientData(ClientPtr client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					GlxServerVendor * GlxGetXIDMap(XID id);
 | 
				
			||||||
 | 
					void GlxRemoveXIDMap(XID id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag);
 | 
				
			||||||
 | 
					void GlxFreeContextTag(GlxContextTagInfo *tagInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					GlxScreenPriv *GlxGetScreen(ScreenPtr pScreen);
 | 
				
			||||||
 | 
					GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline CARD32 GlxCheckSwap(ClientPtr client, CARD32 value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (client->swapped)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        value = ((value & 0XFF000000) >> 24) | ((value & 0X00FF0000) >>  8)
 | 
				
			||||||
 | 
					            | ((value & 0X0000FF00) <<  8) | ((value & 0X000000FF) << 24);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_X_EXPORT const GlxServerExports *glvndGetExports(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // VNDSERVER_H
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,196 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "vndserver.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pixmapstr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "vndservervendor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GlxServerVendor *LookupXIDMapResource(XID id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    void *ptr = NULL;
 | 
				
			||||||
 | 
					    int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rv = dixLookupResourceByType(&ptr, id, idResource, NULL, DixReadAccess);
 | 
				
			||||||
 | 
					    if (rv == Success) {
 | 
				
			||||||
 | 
					        return (GlxServerVendor *) ptr;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxServerVendor *GlxGetXIDMap(XID id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = LookupXIDMapResource(id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vendor == NULL) {
 | 
				
			||||||
 | 
					        // If we haven't seen this XID before, then it may be a drawable that
 | 
				
			||||||
 | 
					        // wasn't created through GLX, like a regular X window or pixmap. Try
 | 
				
			||||||
 | 
					        // to look up a matching drawable to find a screen number for it.
 | 
				
			||||||
 | 
					        void *ptr = NULL;
 | 
				
			||||||
 | 
					        int rv = dixLookupResourceByClass(&ptr, id, RC_DRAWABLE, NULL,
 | 
				
			||||||
 | 
					                                         DixGetAttrAccess);
 | 
				
			||||||
 | 
					        if (rv == Success && ptr != NULL) {
 | 
				
			||||||
 | 
					            DrawablePtr draw = (DrawablePtr) ptr;
 | 
				
			||||||
 | 
					            GlxScreenPriv *screenPriv = GlxGetScreen(draw->pScreen);
 | 
				
			||||||
 | 
					            if (screenPriv != NULL) {
 | 
				
			||||||
 | 
					                vendor = screenPriv->vendor;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return vendor;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (id == 0 || vendor == NULL) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (LookupXIDMapResource(id) != NULL) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return AddResource(id, idResource, vendor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GlxRemoveXIDMap(XID id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    FreeResourceByType(id, idResource, FALSE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxClientPriv *cl;
 | 
				
			||||||
 | 
					    unsigned int index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vendor == NULL) {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cl = GlxGetClientData(client);
 | 
				
			||||||
 | 
					    if (cl == NULL) {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Look for a free tag index.
 | 
				
			||||||
 | 
					    for (index=0; index<cl->contextTagCount; index++) {
 | 
				
			||||||
 | 
					        if (cl->contextTags[index].vendor == NULL) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (index >= cl->contextTagCount) {
 | 
				
			||||||
 | 
					        // We didn't find a free entry, so grow the array.
 | 
				
			||||||
 | 
					        GlxContextTagInfo *newTags;
 | 
				
			||||||
 | 
					        unsigned int newSize = cl->contextTagCount * 2;
 | 
				
			||||||
 | 
					        if (newSize == 0) {
 | 
				
			||||||
 | 
					            // TODO: What's a good starting size for this?
 | 
				
			||||||
 | 
					            newSize = 16;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        newTags = (GlxContextTagInfo *)
 | 
				
			||||||
 | 
					            realloc(cl->contextTags, newSize * sizeof(GlxContextTagInfo));
 | 
				
			||||||
 | 
					        if (newTags == NULL) {
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memset(&newTags[cl->contextTagCount], 0,
 | 
				
			||||||
 | 
					                (newSize - cl->contextTagCount) * sizeof(GlxContextTagInfo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        index = cl->contextTagCount;
 | 
				
			||||||
 | 
					        cl->contextTags = newTags;
 | 
				
			||||||
 | 
					        cl->contextTagCount = newSize;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(index >= 0);
 | 
				
			||||||
 | 
					    assert(index < cl->contextTagCount);
 | 
				
			||||||
 | 
					    memset(&cl->contextTags[index], 0, sizeof(GlxContextTagInfo));
 | 
				
			||||||
 | 
					    cl->contextTags[index].tag = (GLXContextTag) (index + 1);
 | 
				
			||||||
 | 
					    cl->contextTags[index].client = client;
 | 
				
			||||||
 | 
					    cl->contextTags[index].vendor = vendor;
 | 
				
			||||||
 | 
					    return &cl->contextTags[index];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxClientPriv *cl = GlxGetClientData(client);
 | 
				
			||||||
 | 
					    if (cl == NULL) {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tag > 0 && (tag - 1) < cl->contextTagCount) {
 | 
				
			||||||
 | 
					        if (cl->contextTags[tag - 1].vendor != NULL) {
 | 
				
			||||||
 | 
					            assert(cl->contextTags[tag - 1].client == client);
 | 
				
			||||||
 | 
					            return &cl->contextTags[tag - 1];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GlxFreeContextTag(GlxContextTagInfo *tagInfo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (tagInfo != NULL) {
 | 
				
			||||||
 | 
					        tagInfo->vendor = NULL;
 | 
				
			||||||
 | 
					        tagInfo->vendor = NULL;
 | 
				
			||||||
 | 
					        tagInfo->data = NULL;
 | 
				
			||||||
 | 
					        tagInfo->context = None;
 | 
				
			||||||
 | 
					        tagInfo->drawable = None;
 | 
				
			||||||
 | 
					        tagInfo->readdrawable = None;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxScreenPriv *priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vendor == NULL) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv = GlxGetScreen(screen);
 | 
				
			||||||
 | 
					    if (priv == NULL) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->vendor != NULL) {
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->vendor = vendor;
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxScreenPriv *priv = GlxGetScreen(screen);
 | 
				
			||||||
 | 
					    if (priv != NULL) {
 | 
				
			||||||
 | 
					        return priv->vendor;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,91 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "vndservervendor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct xorg_list GlxVendorList = { &GlxVendorList, &GlxVendorList };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxServerVendor *GlxCreateVendor(const GlxServerImports *imports)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (imports == NULL) {
 | 
				
			||||||
 | 
					        ErrorF("GLX: Vendor library did not provide an imports table\n");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (imports->extensionCloseDown == NULL
 | 
				
			||||||
 | 
					            || imports->handleRequest == NULL
 | 
				
			||||||
 | 
					            || imports->getDispatchAddress == NULL
 | 
				
			||||||
 | 
					            || imports->makeCurrent == NULL) {
 | 
				
			||||||
 | 
					        ErrorF("GLX: Vendor library is missing required callback functions.\n");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vendor = (GlxServerVendor *) calloc(1, sizeof(GlxServerVendor));
 | 
				
			||||||
 | 
					    if (vendor == NULL) {
 | 
				
			||||||
 | 
					        ErrorF("GLX: Can't allocate vendor library.\n");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    memcpy(&vendor->glxvc, imports, sizeof(GlxServerImports));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xorg_list_append(&vendor->entry, &GlxVendorList);
 | 
				
			||||||
 | 
					    return vendor;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GlxDestroyVendor(GlxServerVendor *vendor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (vendor != NULL) {
 | 
				
			||||||
 | 
					        xorg_list_del(&vendor->entry);
 | 
				
			||||||
 | 
					        free(vendor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GlxVendorExtensionReset(const ExtensionEntry *extEntry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GlxServerVendor *vendor, *tempVendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: Do we allow the driver to destroy a vendor library handle from
 | 
				
			||||||
 | 
					    // here?
 | 
				
			||||||
 | 
					    xorg_list_for_each_entry_safe(vendor, tempVendor, &GlxVendorList, entry) {
 | 
				
			||||||
 | 
					        if (vendor->glxvc.extensionCloseDown != NULL) {
 | 
				
			||||||
 | 
					            vendor->glxvc.extensionCloseDown(extEntry);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If the server is exiting instead of starting a new generation, then
 | 
				
			||||||
 | 
					    // free the remaining GlxServerVendor structs.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // XXX this used to be conditional on xf86ServerIsExiting, but it's
 | 
				
			||||||
 | 
					    // cleaner to just always create the vendor struct on every generation,
 | 
				
			||||||
 | 
					    // if nothing else so all ddxes get the same behavior.
 | 
				
			||||||
 | 
					    xorg_list_for_each_entry_safe(vendor, tempVendor, &GlxVendorList, entry) {
 | 
				
			||||||
 | 
					        GlxDestroyVendor(vendor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef VND_SERVER_VENDOR_H
 | 
				
			||||||
 | 
					#define VND_SERVER_VENDOR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <dix-config.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "glxvndabi.h"
 | 
				
			||||||
 | 
					#include "list.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Info related to a single vendor library.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct GlxServerVendorRec {
 | 
				
			||||||
 | 
					    GlxServerImports glxvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct xorg_list entry;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A linked list of vendor libraries.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that this list only includes vendor libraries that were successfully
 | 
				
			||||||
 | 
					 * initialized.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					extern struct xorg_list GlxVendorList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GlxServerVendor *GlxCreateVendor(const GlxServerImports *imports);
 | 
				
			||||||
 | 
					void GlxDestroyVendor(GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GlxVendorExtensionReset(const ExtensionEntry *extEntry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // VND_SERVER_VENDOR_H
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@ sdk_HEADERS =		\
 | 
				
			||||||
	gcstruct.h	\
 | 
						gcstruct.h	\
 | 
				
			||||||
	globals.h	\
 | 
						globals.h	\
 | 
				
			||||||
	glx_extinit.h	\
 | 
						glx_extinit.h	\
 | 
				
			||||||
 | 
						glxvndabi.h	\
 | 
				
			||||||
	input.h		\
 | 
						input.h		\
 | 
				
			||||||
	inputstr.h	\
 | 
						inputstr.h	\
 | 
				
			||||||
	list.h		\
 | 
						list.h		\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,307 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2016, NVIDIA CORPORATION.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and/or associated documentation files (the
 | 
				
			||||||
 | 
					 * "Materials"), to deal in the Materials without restriction, including
 | 
				
			||||||
 | 
					 * without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					 * distribute, sublicense, and/or sell copies of the Materials, and to
 | 
				
			||||||
 | 
					 * permit persons to whom the Materials are furnished to do so, subject to
 | 
				
			||||||
 | 
					 * the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					 * unaltered in all copies or substantial portions of the Materials.
 | 
				
			||||||
 | 
					 * Any additions, deletions, or changes to the original source files
 | 
				
			||||||
 | 
					 * must be clearly indicated in accompanying documentation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If only executable code is distributed, then the accompanying
 | 
				
			||||||
 | 
					 * documentation must state that "this software is based in part on the
 | 
				
			||||||
 | 
					 * work of the Khronos Group."
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \file
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Defines the interface between the libglvnd server module and a vendor
 | 
				
			||||||
 | 
					 * library.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Each screen may have one vendor library assigned to it. The GLVND module
 | 
				
			||||||
 | 
					 * will examine each GLX request to determine which screen it goes to, and then
 | 
				
			||||||
 | 
					 * it will forward that request to whichever vendor is assigned to that screen.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Each vendor library is represented by an opaque __GLXServerVendor handle.
 | 
				
			||||||
 | 
					 * Display drivers are responsible for creating handles for its GLX
 | 
				
			||||||
 | 
					 * implementations, and assigning those handles to each screen.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The GLVND module keeps a list of callbacks, which are called from
 | 
				
			||||||
 | 
					 * InitExtensions. Drivers should use that callback to assign a vendor
 | 
				
			||||||
 | 
					 * handle to whichever screens they support.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Additional notes about dispatching:
 | 
				
			||||||
 | 
					 * - If a request has one or more GLXContextTag values, then the dispatch stub
 | 
				
			||||||
 | 
					 *   must ensure that all of the tags belong to the vendor that it forwards the
 | 
				
			||||||
 | 
					 *   request to. Otherwise, if a vendor library tries to look up the private
 | 
				
			||||||
 | 
					 *   data for the tag, it could get the data from another vendor and crash.
 | 
				
			||||||
 | 
					 * - Following from the last point, if a request takes a GLXContextTag value,
 | 
				
			||||||
 | 
					 *   then the dispatch stub should use the tag to select a vendor. If the
 | 
				
			||||||
 | 
					 *   request takes two or more tags, then the vendor must ensure that they all
 | 
				
			||||||
 | 
					 *   map to the same vendor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef GLXVENDORABI_H
 | 
				
			||||||
 | 
					#define GLXVENDORABI_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <scrnintstr.h>
 | 
				
			||||||
 | 
					#include <extnsionst.h>
 | 
				
			||||||
 | 
					#include <GL/glxproto.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * Current version of the ABI.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This version number contains a major number in the high-order 16 bits, and
 | 
				
			||||||
 | 
					 * a minor version number in the low-order 16 bits.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The major version number is incremented when an interface change will break
 | 
				
			||||||
 | 
					 * backwards compatibility with existing vendor libraries. The minor version
 | 
				
			||||||
 | 
					 * number is incremented when there's a change but existing vendor libraries
 | 
				
			||||||
 | 
					 * will still work.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define GLXSERVER_VENDOR_ABI_MAJOR_VERSION 0
 | 
				
			||||||
 | 
					#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * An opaque pointer representing a vendor library.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct GlxServerVendorRec GlxServerVendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef int (* GlxServerDispatchProc) (ClientPtr client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct GlxServerImportsRec GlxServerImports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Functions exported by libglvnd to the vendor library.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct GlxServerExportsRec {
 | 
				
			||||||
 | 
					    int majorVersion;
 | 
				
			||||||
 | 
					    int minorVersion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This callback is called during each server generation when the GLX
 | 
				
			||||||
 | 
					     * extension is initialized.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Drivers may create a __GLXServerVendor handle at any time, but may only
 | 
				
			||||||
 | 
					     * assign a vendor to a screen from this callback.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The callback is called with the ExtensionEntry pointer for the GLX
 | 
				
			||||||
 | 
					     * extension.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    CallbackListPtr *extensionInitCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Allocates and zeroes a __GLXserverImports structure.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Future versions of the GLVND interface may add optional members to the
 | 
				
			||||||
 | 
					     * end of the __GLXserverImports struct. Letting the GLVND layer allocate
 | 
				
			||||||
 | 
					     * the __GLXserverImports struct allows backward compatibility with
 | 
				
			||||||
 | 
					     * existing drivers.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    GlxServerImports * (* allocateServerImports) (void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Frees a __GLXserverImports structure that was allocated with
 | 
				
			||||||
 | 
					     * \c allocateServerImports.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void (* freeServerImports) (GlxServerImports *imports);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Creates a new vendor library handle.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    GlxServerVendor * (* createVendor) (const GlxServerImports *imports);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Destroys a vendor library handle.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This function may not be called while the vendor handle is assigned to a
 | 
				
			||||||
 | 
					     * screen, but it may be called from the __GLXserverImports::extensionCloseDown
 | 
				
			||||||
 | 
					     * callback.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void (* destroyVendor) (GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Sets the vendor library to use for a screen.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This function should be called from the screen's CreateScreenResources
 | 
				
			||||||
 | 
					     * callback.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Bool (* setScreenVendor) (ScreenPtr screen, GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Adds an entry to the XID map.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This mapping is used to dispatch requests based on an XID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Client-generated XID's (contexts, drawables, etc) must be added to the
 | 
				
			||||||
 | 
					     * map by the dispatch stub.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * XID's that are generated in the server should be added by the vendor
 | 
				
			||||||
 | 
					     * library.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Vendor libraries are responsible for keeping track of any additional
 | 
				
			||||||
 | 
					     * data they need for the XID's.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Note that adding GLXFBConfig ID's appears to be unnecessary -- every GLX
 | 
				
			||||||
 | 
					     * request I can find that takes a GLXFBConfig also takes a screen number.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * \param id The XID to add to the map. The XID must not already be in the
 | 
				
			||||||
 | 
					     *      map.
 | 
				
			||||||
 | 
					     * \param vendor The vendor library to associate with \p id.
 | 
				
			||||||
 | 
					     * \return True on success, or False on failure.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Bool (* addXIDMap) (XID id, GlxServerVendor *vendor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the vendor and data for an XID, as added with \c addXIDMap.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * If \p id wasn't added with \c addXIDMap (for example, if it's a regular
 | 
				
			||||||
 | 
					     * X window), then libglvnd will try to look it up as a drawable and return
 | 
				
			||||||
 | 
					     * the vendor for whatever screen it's on.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * \param id The XID to look up.
 | 
				
			||||||
 | 
					     * \return The vendor that owns the XID, or \c NULL if no matching vendor
 | 
				
			||||||
 | 
					     * was found.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    GlxServerVendor * (* getXIDMap) (XID id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Removes an entry from the XID map.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void (* removeXIDMap) (XID id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Looks up a context tag.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Context tags are created and managed by libglvnd to ensure that they're
 | 
				
			||||||
 | 
					     * unique between vendors.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * \param client The client connection.
 | 
				
			||||||
 | 
					     * \param tag The context tag.
 | 
				
			||||||
 | 
					     * \return The vendor that owns the context tag, or \c NULL if the context
 | 
				
			||||||
 | 
					     * tag is invalid.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    GlxServerVendor * (* getContextTag)(ClientPtr client, GLXContextTag tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Assigns a pointer to vendor-private data for a context tag.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Since the tag values are assigned by GLVND, vendors can use this
 | 
				
			||||||
 | 
					     * function to store any private data they need for a context tag.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * \param client The client connection.
 | 
				
			||||||
 | 
					     * \param tag The context tag.
 | 
				
			||||||
 | 
					     * \param data An arbitrary pointer value.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Bool (* setContextTagPrivate)(ClientPtr client, GLXContextTag tag, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the private data pointer that was assigned from
 | 
				
			||||||
 | 
					     * setContextTagPrivate.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This function is safe to use in __GLXserverImports::makeCurrent to look
 | 
				
			||||||
 | 
					     * up the old context private pointer.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * However, this function is not safe to use from a ClientStateCallback,
 | 
				
			||||||
 | 
					     * because GLVND may have alraedy deleted the tag by that point.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void * (* getContextTagPrivate)(ClientPtr client, GLXContextTag tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GlxServerVendor * (* getVendorForScreen) (ClientPtr client, ScreenPtr screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Forwards a request to a vendor library.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * \param vendor The vendor to send the request to.
 | 
				
			||||||
 | 
					     * \param client The client.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int (* forwardRequest) (GlxServerVendor *vendor, ClientPtr client);
 | 
				
			||||||
 | 
					} GlxServerExports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern _X_EXPORT const GlxServerExports glxServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Functions exported by the vendor library to libglvnd.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct GlxServerImportsRec {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Called on a server reset.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This is called from the extension's CloseDown callback.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Note that this is called after freeing all of GLVND's per-screen data,
 | 
				
			||||||
 | 
					     * so the callback may destroy any vendor handles.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * If the server is exiting, then GLVND will free any remaining vendor
 | 
				
			||||||
 | 
					     * handles after calling the extensionCloseDown callbacks.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void (* extensionCloseDown) (const ExtensionEntry *extEntry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handles a GLX request.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int (* handleRequest) (ClientPtr client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns a dispatch function for a request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * \param minorOpcode The minor opcode of the request.
 | 
				
			||||||
 | 
					     * \param vendorCode The vendor opcode, if \p minorOpcode
 | 
				
			||||||
 | 
					     *      is \c X_GLXVendorPrivate or \c X_GLXVendorPrivateWithReply.
 | 
				
			||||||
 | 
					     * \return A dispatch function, or NULL if the vendor doesn't support this
 | 
				
			||||||
 | 
					     *      request.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    GlxServerDispatchProc (* getDispatchAddress) (CARD8 minorOpcode, CARD32 vendorCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handles a MakeCurrent request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This function is called to handle any MakeCurrent request. The vendor
 | 
				
			||||||
 | 
					     * library should deal with changing the current context. After the vendor
 | 
				
			||||||
 | 
					     * returns GLVND will send the reply.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * In addition, GLVND will call this function with any current contexts
 | 
				
			||||||
 | 
					     * when a client disconnects.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * To ensure that context tags are unique, libglvnd will select a context
 | 
				
			||||||
 | 
					     * tag and pass it to the vendor library.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The vendor can use \c __GLXserverExports::getContextTagPrivate to look
 | 
				
			||||||
 | 
					     * up the private data pointer for \p oldContextTag.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Likewise, the vendor can use \c __GLXserverExports::setContextTagPrivate
 | 
				
			||||||
 | 
					     * to assign a private data pointer to \p newContextTag.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int (* makeCurrent) (ClientPtr client,
 | 
				
			||||||
 | 
					        GLXContextTag oldContextTag,
 | 
				
			||||||
 | 
					        XID drawable,
 | 
				
			||||||
 | 
					        XID readdrawable,
 | 
				
			||||||
 | 
					        XID context,
 | 
				
			||||||
 | 
					        GLXContextTag newContextTag);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // GLXVENDORABI_H
 | 
				
			||||||
| 
						 | 
					@ -323,6 +323,7 @@ if build_xorg
 | 
				
			||||||
            'gcstruct.h',
 | 
					            'gcstruct.h',
 | 
				
			||||||
            'globals.h',
 | 
					            'globals.h',
 | 
				
			||||||
            'glx_extinit.h',
 | 
					            'glx_extinit.h',
 | 
				
			||||||
 | 
					            'glxvndabi.h',
 | 
				
			||||||
            'input.h',
 | 
					            'input.h',
 | 
				
			||||||
            'inputstr.h',
 | 
					            'inputstr.h',
 | 
				
			||||||
            'list.h',
 | 
					            'list.h',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue