diff options
author | Kyle Brenneman <kbrenneman@nvidia.com> | 2016-03-28 17:44:05 -0600 |
---|---|---|
committer | Kyle Brenneman <kbrenneman@nvidia.com> | 2016-03-28 17:44:05 -0600 |
commit | d7f4370dde9b67c8b5a8a4fd3a3df4507ba7f879 (patch) | |
tree | e62e3cfbe6a874181785847b79ae7e5d666f860c | |
parent | 95a5bfcdfbc3c38e201e81d6497efe6c7b97f72b (diff) | |
parent | 1d7ab91b76d0fbefaff4f4b8c7d019cbd18c9ff9 (diff) |
Merge pull request #79 from kbrenneman/replace-x11glvnd-v2.
Replace x11glvnd with GLX_EXT_libglvnd extension.
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/GLX/Makefile.am | 7 | ||||
-rw-r--r-- | src/GLX/libglx.c | 17 | ||||
-rw-r--r-- | src/GLX/libglxmapping.c | 116 | ||||
-rw-r--r-- | src/GLX/libglxmapping.h | 11 | ||||
-rw-r--r-- | src/GLX/libglxproto.c | 173 | ||||
-rw-r--r-- | src/GLX/libglxproto.h (renamed from src/x11glvnd/x11glvndserver.h) | 56 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/x11glvnd/Makefile.am | 59 | ||||
-rw-r--r-- | src/x11glvnd/x11glvnd.h | 95 | ||||
-rw-r--r-- | src/x11glvnd/x11glvndclient.c | 263 | ||||
-rw-r--r-- | src/x11glvnd/x11glvndproto.h | 136 | ||||
-rw-r--r-- | src/x11glvnd/x11glvndserver.c | 552 | ||||
-rw-r--r-- | tests/Makefile.am | 35 |
14 files changed, 317 insertions, 1205 deletions
diff --git a/configure.ac b/configure.ac index 8d00683..fab86f3 100644 --- a/configure.ac +++ b/configure.ac @@ -240,7 +240,6 @@ AC_CONFIG_FILES([Makefile src/GLESv1/Makefile src/GLESv2/Makefile src/GLX/Makefile - src/x11glvnd/Makefile src/GLdispatch/Makefile src/GLdispatch/vnd-glapi/Makefile src/util/Makefile diff --git a/src/GLX/Makefile.am b/src/GLX/Makefile.am index 6905cc1..1e865b2 100644 --- a/src/GLX/Makefile.am +++ b/src/GLX/Makefile.am @@ -32,7 +32,8 @@ noinst_HEADERS = \ libglxnoop.h \ libglxgl.h \ libglxstring.h \ - libglxthread.h + libglxthread.h \ + libglxproto.h lib_LTLIBRARIES = libGLX.la @@ -40,7 +41,6 @@ UTIL_DIR = ../util TRACE_DIR = ../util/trace UTHASH_DIR = ../util/uthash/src GL_DISPATCH_DIR = ../GLdispatch -X11GLVND_DIR = ../x11glvnd # Warning settings # Include paths @@ -49,7 +49,6 @@ libGLX_la_CFLAGS += -I$(srcdir)/$(UTIL_DIR) libGLX_la_CFLAGS += -I$(srcdir)/$(TRACE_DIR) libGLX_la_CFLAGS += -I$(srcdir)/$(GL_DISPATCH_DIR) libGLX_la_CFLAGS += -I$(top_srcdir)/include -libGLX_la_CFLAGS += -I$(srcdir)/$(X11GLVND_DIR) libGLX_la_CFLAGS += $(GLPROTO_CFLAGS) # Required library flags @@ -60,7 +59,6 @@ libGLX_la_LIBADD = -ldl libGLX_la_LIBADD += $(X11_LIBS) libGLX_la_LIBADD += $(XEXT_LIBS) libGLX_la_LIBADD += $(GL_DISPATCH_DIR)/libGLdispatch.la -libGLX_la_LIBADD += $(X11GLVND_DIR)/libx11glvnd_client.la libGLX_la_LIBADD += $(TRACE_DIR)/libtrace.la libGLX_la_LDFLAGS = -shared -Wl,-Bsymbolic -version-info 0 $(LINKER_FLAG_NO_UNDEFINED) @@ -79,6 +77,7 @@ libGLX_la_SOURCES = \ libglx.c \ libglxmapping.c \ libglxstring.c \ + libglxproto.c \ $(UTIL_DIR)/glvnd_genentry.c \ $(UTIL_DIR)/utils_misc.c \ g_libglxnoop.c diff --git a/src/GLX/libglx.c b/src/GLX/libglx.c index f3a408a..840edc1 100644 --- a/src/GLX/libglx.c +++ b/src/GLX/libglx.c @@ -43,7 +43,6 @@ #include "utils_misc.h" #include "trace.h" #include "GL/glxproto.h" -#include "x11glvnd.h" #include "libglxgl.h" #include "glvnd_list.h" @@ -562,13 +561,12 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext context) } } -void DisplayClosed(Display *dpy) +void __glXDisplayClosed(__GLXdisplayInfo *dpyInfo) { __GLXThreadState *threadState; - __glXFreeDisplay(dpy); threadState = __glXGetCurrentThreadState(); - if (threadState != NULL && threadState->currentDisplay == dpy) { + if (threadState != NULL && threadState->currentDisplay == dpyInfo->dpy) { // Clear out the current context, but don't call into the vendor // library or do anything that might require a valid display. __glDispatchLoseCurrent(); @@ -583,7 +581,7 @@ void DisplayClosed(Display *dpy) /* * Stub out any references to this display in any other thread states. */ - if (threadState->currentDisplay == dpy) { + if (threadState->currentDisplay == dpyInfo->dpy) { threadState->currentDisplay = NULL; } } @@ -2070,9 +2068,6 @@ void _init(void) /* TODO install fork handlers using __register_atfork */ - /* Register our XCloseDisplay() callback */ - XGLVRegisterCloseDisplayCallback(DisplayClosed); - DBG_PRINTF(0, "Loading GLX...\n"); } @@ -2097,11 +2092,7 @@ void _fini(void) __glDispatchLoseCurrent(); } - - /* Unregister all XCloseDisplay() callbacks */ - XGLVUnregisterCloseDisplayCallbacks(); - - /* Tear down all GLX thread state */ + /* Tear down all GLX API state */ __glXAPITeardown(False); /* Tear down all mapping state */ diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c index 506cb06..36f3159 100644 --- a/src/GLX/libglxmapping.c +++ b/src/GLX/libglxmapping.c @@ -42,12 +42,12 @@ #include "libglxnoop.h" #include "libglxthread.h" #include "libglxstring.h" +#include "libglxproto.h" #include "utils_misc.h" #include "glvnd_genentry.h" #include "trace.h" #include "lkdhash.h" -#include "x11glvnd.h" #define _GNU_SOURCE 1 @@ -119,7 +119,6 @@ typedef struct __GLXvendorNameHashRec { static DEFINE_INITIALIZED_LKDHASH(__GLXvendorNameHash, __glXVendorNameHash); typedef struct __GLXdisplayInfoHashRec { - Display *dpy; __GLXdisplayInfo info; UT_hash_handle hh; } __GLXdisplayInfoHash; @@ -622,16 +621,26 @@ __GLXvendorInfo *__glXLookupVendorByScreen(Display *dpy, const int screen) } if (!vendor) { - if (dpyInfo->x11glvndSupported) { - char *queriedVendorName = XGLVQueryScreenVendorMapping(dpy, screen); - vendor = __glXLookupVendorByName(queriedVendorName); - Xfree(queriedVendorName); - - // Make sure that the vendor library can support this screen. - // If it can't, then we'll fall back to the indirect rendering - // library. - if (vendor != NULL && !vendor->glxvc->isScreenSupported(dpy, screen)) { - vendor = NULL; + if (dpyInfo->libglvndExtensionSupported) { + char *queriedVendorNames = + __glXQueryServerString(dpyInfo, screen, GLX_VENDOR_NAMES_EXT); + if (queriedVendorNames != NULL) { + char *name, *saveptr; + for (name = strtok_r(queriedVendorNames, " ", &saveptr); + name != NULL; + name = strtok_r(NULL, " ", &saveptr)) { + vendor = __glXLookupVendorByName(name); + + // Make sure that the vendor library can support this screen. + if (vendor != NULL && !vendor->glxvc->isScreenSupported(dpy, screen)) { + vendor = NULL; + } + + if (vendor != NULL) { + break; + } + } + free(queriedVendorNames); } } } @@ -693,7 +702,7 @@ static __GLXdisplayInfoHash *InitDisplayInfoEntry(Display *dpy) { __GLXdisplayInfoHash *pEntry; size_t size; - int eventBase, errorBase; + int eventBase; size = sizeof(*pEntry) + ScreenCount(dpy) * sizeof(__GLXvendorInfo *); pEntry = (__GLXdisplayInfoHash *) malloc(size); @@ -702,7 +711,7 @@ static __GLXdisplayInfoHash *InitDisplayInfoEntry(Display *dpy) } memset(pEntry, 0, size); - pEntry->dpy = dpy; + pEntry->info.dpy = dpy; pEntry->info.vendors = (__GLXvendorInfo **) (pEntry + 1); LKDHASH_INIT(pEntry->info.xidVendorHash); @@ -714,11 +723,26 @@ static __GLXdisplayInfoHash *InitDisplayInfoEntry(Display *dpy) &pEntry->info.glxMajorOpcode, &eventBase, &pEntry->info.glxFirstError); - // Check whether the server supports the x11glvnd extension. - if (XGLVQueryExtension(dpy, &eventBase, &errorBase)) { - pEntry->info.x11glvndSupported = True; - XGLVQueryVersion(dpy, &pEntry->info.x11glvndMajor, - &pEntry->info.x11glvndMinor); + if (pEntry->info.glxSupported) { + int screen; + + // Check to see if the server supports the GLX_EXT_libglvnd extension. + // Note that it has to be supported on every screen to use it. + pEntry->info.libglvndExtensionSupported = True; + for (screen = 0; + screen < ScreenCount(dpy) && pEntry->info.libglvndExtensionSupported; + screen++) { + char *extensions = __glXQueryServerString(&pEntry->info, screen, GLX_EXTENSIONS); + if (extensions != NULL) { + if (!IsExtensionInString(extensions, GLX_EXT_LIBGLVND_NAME, + strlen(GLX_EXT_LIBGLVND_NAME))) { + pEntry->info.libglvndExtensionSupported = False; + } + free(extensions); + } else { + pEntry->info.libglvndExtensionSupported = False; + } + } } return pEntry; @@ -748,6 +772,25 @@ static void CleanupDisplayInfoEntry(void *unused, __GLXdisplayInfoHash *pEntry) pEntry->info.xidVendorHash, NULL, NULL, False); } +static int OnDisplayClosed(Display *dpy, XExtCodes *codes) +{ + __GLXdisplayInfoHash *pEntry = NULL; + + LKDHASH_WRLOCK(__glXDisplayInfoHash); + + HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, pEntry); + if (pEntry != NULL) { + __glXDisplayClosed(&pEntry->info); + HASH_DEL(_LH(__glXDisplayInfoHash), pEntry); + } + LKDHASH_UNLOCK(__glXDisplayInfoHash); + + CleanupDisplayInfoEntry(NULL, pEntry); + free(pEntry); + + return 0; +} + __GLXdisplayInfo *__glXLookupDisplay(Display *dpy) { __GLXdisplayInfoHash *pEntry = NULL; @@ -776,9 +819,19 @@ __GLXdisplayInfo *__glXLookupDisplay(Display *dpy) LKDHASH_WRLOCK(__glXDisplayInfoHash); HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, foundEntry); if (foundEntry == NULL) { - HASH_ADD_PTR(_LH(__glXDisplayInfoHash), dpy, pEntry); + XExtCodes *extCodes = XAddExtension(dpy); + if (extCodes == NULL) { + CleanupDisplayInfoEntry(NULL, pEntry); + free(pEntry); + LKDHASH_UNLOCK(__glXDisplayInfoHash); + return NULL; + } + + XESetCloseDisplay(dpy, extCodes->extension, OnDisplayClosed); + HASH_ADD_PTR(_LH(__glXDisplayInfoHash), info.dpy, pEntry); } else { // Another thread already created the hashtable entry. + CleanupDisplayInfoEntry(NULL, pEntry); free(pEntry); pEntry = foundEntry; } @@ -787,23 +840,6 @@ __GLXdisplayInfo *__glXLookupDisplay(Display *dpy) return &pEntry->info; } -void __glXFreeDisplay(Display *dpy) -{ - __GLXdisplayInfoHash *pEntry = NULL; - - LKDHASH_WRLOCK(__glXDisplayInfoHash); - HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, pEntry); - if (pEntry != NULL) { - HASH_DEL(_LH(__glXDisplayInfoHash), pEntry); - } - LKDHASH_UNLOCK(__glXDisplayInfoHash); - - if (pEntry != NULL) { - CleanupDisplayInfoEntry(NULL, pEntry); - free(pEntry); - } -} - /****************************************************************************/ /* * Define two hashtables to store the mappings for GLXFBConfig and GLXContext @@ -983,8 +1019,8 @@ static void VendorFromXID(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid, } else { LKDHASH_UNLOCK(dpyInfo->xidVendorHash); - if (dpyInfo->x11glvndSupported) { - int screen = XGLVQueryXIDScreenMapping(dpy, xid); + if (dpyInfo->libglvndExtensionSupported) { + int screen = __glXGetDrawableScreen(dpyInfo, xid); if (screen >= 0 && screen < ScreenCount(dpy)) { vendor = __glXLookupVendorByScreen(dpy, screen); if (vendor != NULL) { @@ -1029,7 +1065,7 @@ __GLXvendorInfo *__glXVendorFromDrawable(Display *dpy, GLXDrawable drawable) __GLXdisplayInfo *dpyInfo = __glXLookupDisplay(dpy); __GLXvendorInfo *vendor = NULL; if (dpyInfo != NULL) { - if (dpyInfo->x11glvndSupported) { + if (dpyInfo->libglvndExtensionSupported) { VendorFromXID(dpy, dpyInfo, drawable, &vendor); } else { // We'll use the same vendor for every screen in this case. diff --git a/src/GLX/libglxmapping.h b/src/GLX/libglxmapping.h index 2c377e7..365a95c 100644 --- a/src/GLX/libglxmapping.h +++ b/src/GLX/libglxmapping.h @@ -60,6 +60,8 @@ typedef struct __GLXvendorXIDMappingHashRec __GLXvendorXIDMappingHash; * Structure containing per-display information. */ typedef struct __GLXdisplayInfoRec { + Display *dpy; + char *clientStrings[GLX_CLIENT_STRING_LAST_ATTRIB]; /** @@ -79,9 +81,7 @@ typedef struct __GLXdisplayInfoRec { int glxMajorOpcode; int glxFirstError; - Bool x11glvndSupported; - int x11glvndMajor; - int x11glvndMinor; + Bool libglvndExtensionSupported; } __GLXdisplayInfo; /*! @@ -128,9 +128,10 @@ __GLXvendorInfo *__glXLookupVendorByScreen(Display *dpy, const int screen); __GLXdisplayInfo *__glXLookupDisplay(Display *dpy); /*! - * Frees the __GLXdisplayInfo structure for a display, if one exists. + * This is called to perform any context-related cleanup when a display is + * closed. */ -void __glXFreeDisplay(Display *dpy); +void __glXDisplayClosed(__GLXdisplayInfo *dpyInfo); /* * Close the vendor library and perform any relevant teardown. This should diff --git a/src/GLX/libglxproto.c b/src/GLX/libglxproto.c new file mode 100644 index 0000000..98bf71a --- /dev/null +++ b/src/GLX/libglxproto.c @@ -0,0 +1,173 @@ +/* + * 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 <X11/Xlibint.h> + +#include "libglxproto.h" + +#include <GL/glx.h> +#include <GL/glxproto.h> + +/*! + * Reads a reply from the server, including any additional data. + * + * This function will read a reply from the server, and it will optionally + * allocate a buffer and read any variable-length data in the reply. + * + * If \c replyData is not \c NULL and the reply contains additional data, then + * this function will allocate a buffer and read the data into it. + * + * If \c replyData is \c NULL, then the caller must read any data in the reply. + * + * If the last request generates an error, then it will return the error code, + * but it will not call the normal X error handler. + * + * \param dpyInfo The display connection. + * \param[out] reply Returns the reply structure. + * \param[out] replyData If not \c NULL, returns any additional reply data. + * \return \c Success on a successful reply. If the server sent back an error, + * then the error code is returned. If something else fails, then -1 is + * returned. + */ +static Status ReadReply(__GLXdisplayInfo *dpyInfo, xReply *reply, void **replyData) +{ + Display *dpy = dpyInfo->dpy; + _XAsyncHandler async; + _XAsyncErrorState state = {}; + Status error = Success; + + state.min_sequence_number = state.max_sequence_number = dpy->request; + state.major_opcode = dpyInfo->glxMajorOpcode; + async.next = dpy->async_handlers; + async.handler = _XAsyncErrorHandler; + async.data = (XPointer) &state; + dpy->async_handlers = &async; + + if (!_XReply(dpy, reply, 0, False)) { + error = -1; + } + DeqAsyncHandler(dpy, &async); + + if (state.error_count) { + error = state.last_error_received; + if (error == Success) { + assert(error != Success); + error = -1; + } + } + + if (replyData != NULL) { + void *data = NULL; + if (error == Success && reply->generic.length > 0) { + int length = reply->generic.length * 4; + data = malloc(length); + if (data != NULL) { + _XRead(dpyInfo->dpy, (char *) data, length); + } else { + _XEatData(dpyInfo->dpy, length); + error = -1; + } + } + *replyData = data;; + } + + return error; +} + +char *__glXQueryServerString(__GLXdisplayInfo *dpyInfo, int screen, int name) +{ + Display *dpy = dpyInfo->dpy; + xGLXQueryServerStringReq *req; + xGLXSingleReply rep; + char *ret = NULL; + + if (!dpyInfo->glxSupported) { + return NULL; + } + + LockDisplay(dpy); + + GetReq(GLXQueryServerString, req); + req->reqType = dpyInfo->glxMajorOpcode; + req->glxCode = X_GLXQueryServerString; + req->screen = screen; + req->name = name; + + ReadReply(dpyInfo, (xReply *) &rep, (void **) &ret); + + UnlockDisplay(dpy); + SyncHandle(); + + return ret; +} +int __glXGetDrawableScreen(__GLXdisplayInfo *dpyInfo, GLXDrawable drawable) +{ + Display *dpy = dpyInfo->dpy; + xGLXGetDrawableAttributesReq *req; + xGLXGetDrawableAttributesReply rep; + int *attribs = NULL; + Status st; + + if (drawable == None) { + return -1; + } + if (!dpyInfo->glxSupported) { + return 0; + } + + LockDisplay(dpy); + + GetReq(GLXGetDrawableAttributes, req); + req->reqType = dpyInfo->glxMajorOpcode; + req->glxCode = X_GLXGetDrawableAttributes; + req->drawable = drawable; + + st = ReadReply(dpyInfo, (xReply *) &rep, (void **) &attribs); + + UnlockDisplay(dpy); + SyncHandle(); + + if (st == Success) { + int screen = 0; + unsigned int i; + + if (attribs != NULL) { + for (i=0; i<rep.numAttribs; i++) { + if (attribs[i * 2] == GLX_SCREEN) { + screen = attribs[i * 2 + 1]; + break; + } + } + free(attribs); + } + return screen; + } else { + return -1; + } +} + diff --git a/src/x11glvnd/x11glvndserver.h b/src/GLX/libglxproto.h index 5bb0556..2e82f8d 100644 --- a/src/x11glvnd/x11glvndserver.h +++ b/src/GLX/libglxproto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, NVIDIA CORPORATION. + * 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 @@ -27,29 +27,45 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ -#ifndef __X11GLVNDSERVER_H__ -#define __X11GLVNDSERVER_H__ +#ifndef LIBGLXPROTO_H +#define LIBGLXPROTO_H -#include <X11/Xdefs.h> -#include "compiler.h" +/*! + * Functions to handle various GLX protocol requests. + */ + +#include "libglxmapping.h" + +#ifndef GLX_VENDOR_NAMES_EXT +#define GLX_VENDOR_NAMES_EXT 0x20F6 +#endif + +#define GLX_EXT_LIBGLVND_NAME "GLX_EXT_libglvnd" /*! - * Public symbols exported by the x11glvnd X server module. Server-side GLX can - * hook into these symbols in order to implement tracking of GLX drawables and - * potentially implement active notification of clients when XID -> screen - * mappings change (this could be done via shared memory in the direct rendering - * case). The latter will allow clients to cache XID -> screen values, saving a - * round trip in the common case. + * Sends a glXQueryServerString request. If an error occurs, then it will + * return \c NULL, but won't call the X error handler. * - * XXX: Currently there is a race between the XID -> screen lookup and potential - * destruction of a GLX drawable and recycling of its XID. Will we need to - * somehow lock drawables on the server to prevent them from going away until we - * have dispatched to the vendor? Or should it be safe to dispatch even if the - * drawable disappears? + * \param dpyInfo The display connection. + * \param screen The screen number. + * \param name The name enum to request. + * \return The string, or \c NULL on error. The caller must free the string + * using \c free. */ +char *__glXQueryServerString(__GLXdisplayInfo *dpyInfo, int screen, int name); -#define XGLV_X_CONFIG_OPTION_NAME "GLVendor" - -PUBLIC void _XGLVRegisterGLXDrawableType(RESTYPE rtype); +/*! + * Looks up the screen number for a drawable. + * + * Note that if the drawable is valid, but server doesn't send a screen number, + * then that means the server doesn't support the GLX_EXT_libglvnd extension. + * In that case, this function will return zero, since we'll be using the same + * screen for every drawable anyway. + * + * \param dpyInfo The display connection. + * \param drawable The drawable to query. + * \return The screen number for the drawable, or -1 on error. + */ +int __glXGetDrawableScreen(__GLXdisplayInfo *dpyInfo, GLXDrawable drawable); -#endif +#endif // LIBGLXPROTO_H diff --git a/src/Makefile.am b/src/Makefile.am index 01c6e4c..b57606a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,5 @@ SUBDIRS = util \ GLdispatch \ - x11glvnd \ GLX \ OpenGL \ GLESv1 \ diff --git a/src/x11glvnd/Makefile.am b/src/x11glvnd/Makefile.am deleted file mode 100644 index a907718..0000000 --- a/src/x11glvnd/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2013, 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. - -noinst_HEADERS = \ - x11glvnd.h \ - x11glvndproto.h \ - x11glvndserver.h - -noinst_LTLIBRARIES = libx11glvnd_client.la - -INCLUDES = \ - -I$(top_srcdir)/include \ - -I$(srcdir)/../util/uthash/src - -libx11glvnd_client_la_CFLAGS = $(X11_CFLAGS) $(INCLUDES) - -libx11glvnd_client_la_LIBADD = $(XEXT_LIBS) - -libx11glvnd_client_la_SOURCES = \ - x11glvndclient.c - -x11glvnd_LTLIBRARIES = x11glvnd.la - -x11glvnddir = $(libdir)/xorg/modules/extensions - -x11glvnd_la_CFLAGS = \ - $(XORG_CFLAGS) \ - $(X11_CFLAGS) \ - $(INCLUDES) - -x11glvnd_la_LDFLAGS = \ - -module -avoid-version - -x11glvnd_la_SOURCES = \ - x11glvndserver.c diff --git a/src/x11glvnd/x11glvnd.h b/src/x11glvnd/x11glvnd.h deleted file mode 100644 index 6b9f3c7..0000000 --- a/src/x11glvnd/x11glvnd.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2013, 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 __X11GLVND_H__ -#define __X11GLVND_H__ - -#include <X11/Xlib.h> - -/* - * Describes the client-side functions implemented by the x11glvnd extension. - * This is a simple extension to query the X server for XID -> screen and screen - * -> vendor mappings, used by libGLX. This may eventually be replaced by a - * server-side GLX extension which does the same thing. - */ - -#define XGLV_EXTENSION_NAME "x11glvnd" - -/*! - * Determines if the x11glvnd extension is supported. - * - * \param[out] event_base_return Returns the base event code. - * \param[out] error_base_return Returns the base error code. - * \return True if the extension is available, or False if it is not. - */ -Bool XGLVQueryExtension(Display *dpy, int *event_base_return, int *error_base_return); - -/*! - * Returns the version of the x11glvnd extension supported by the server. - * - * \param[out] major Returns the major version number. - * \param[out] minor Returns the minor version number. - * \return nonzero if the server supports a compatible version of x11glvnd. - */ -Bool XGLVQueryVersion(Display *dpy, int *major, int *minor); - -/*! - * Returns the screen associated with this XID, or -1 if there was an error. - */ -int XGLVQueryXIDScreenMapping( - Display *dpy, - XID xid -); - -/*! - * Returns the vendor associated with this screen, or NULL if there was an - * error. - * - * The caller must free the string with XFree. - */ -char *XGLVQueryScreenVendorMapping( - Display *dpy, - int screen -); - -/* - * Registers a callback with x11glvnd which is fired whenever XCloseDisplay() - * is called. This gives x11glvnd clients a lightweight alternative to - * declaring themselves an X11 extension and using XESetCloseDisplay(). - * - * This is NOT a thread-safe operation. - */ -void XGLVRegisterCloseDisplayCallback(void (*callback)(Display *)); - -/* - * Unregisters all registered callbacks. - */ -void XGLVUnregisterCloseDisplayCallbacks(void); - -#endif // __X11GLVND_H__ diff --git a/src/x11glvnd/x11glvndclient.c b/src/x11glvnd/x11glvndclient.c deleted file mode 100644 index acbb182..0000000 --- a/src/x11glvnd/x11glvndclient.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2013, 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 <X11/Xlib.h> -#include <X11/Xlibint.h> -#include <X11/Xproto.h> -#include <X11/extensions/Xext.h> -#include <X11/extensions/extutil.h> -#include <assert.h> - -#include "glvnd_list.h" -#include "x11glvnd.h" -#include "x11glvndproto.h" - -const char *xglv_ext_name = XGLV_EXTENSION_NAME; -static XExtensionInfo *xglv_ext_info = NULL; - -static int close_display(Display *dpy, XExtCodes *codes); - -static /* const */ XExtensionHooks xglv_ext_hooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - close_display, /* close_display */ - NULL, /* wire_to_event */ - NULL, /* event_to_wire */ - NULL, /* error */ - NULL, /* error_string */ -}; - - -static XEXT_GENERATE_FIND_DISPLAY(find_display, xglv_ext_info, - (char *)xglv_ext_name, - &xglv_ext_hooks, - XGLV_NUM_EVENTS, NULL); - -typedef struct CloseDisplayHookRec { - /* - * Callback function - */ - void (*callback)(Display *); - - /* - * List entry - */ - struct glvnd_list entry; -} CloseDisplayHook; - -static int closeDisplayHookListInitialized; -static struct glvnd_list closeDisplayHookList; - -void XGLVRegisterCloseDisplayCallback(void (*callback)(Display *)) -{ - CloseDisplayHook *hook = malloc(sizeof(*hook)); - hook->callback = callback; - - if (!closeDisplayHookListInitialized) { - glvnd_list_init(&closeDisplayHookList); - } - - glvnd_list_add(&hook->entry, &closeDisplayHookList); -} - -void XGLVUnregisterCloseDisplayCallbacks(void) -{ - CloseDisplayHook *curHook, *tmpHook; - glvnd_list_for_each_entry_safe(curHook, tmpHook, &closeDisplayHookList, entry) { - glvnd_list_del(&curHook->entry); - free(curHook); - } - assert(glvnd_list_is_empty(&closeDisplayHookList)); - closeDisplayHookListInitialized = False; -} - -static XEXT_GENERATE_CLOSE_DISPLAY(close_display_internal, xglv_ext_info); - -static XEXT_CLOSE_DISPLAY_PROTO(close_display) -{ - CloseDisplayHook *curHook; - - /* - * Call any registered hooks before calling into the - * generated close_display() hook. - */ - glvnd_list_for_each_entry(curHook, &closeDisplayHookList, entry) { - curHook->callback(dpy); - } - - return close_display_internal(dpy, codes); -} - -#define CHECK_EXTENSION(dpy, i, val) \ - do { \ - if (!XextHasExtension(i)) { \ - XMissingExtension(dpy, xglv_ext_name); \ - UnlockDisplay(dpy); \ - SyncHandle(); \ - return val; \ - } \ - } while (0) - - -Bool XGLVQueryExtension(Display *dpy, int *event_base_return, int *error_base_return) -{ - XExtDisplayInfo *info = find_display(dpy); - if (XextHasExtension(info)) { - *event_base_return = info->codes->first_event; - *error_base_return = info->codes->first_error; - return True; - } else { - return False; - } -} - -Bool XGLVQueryVersion(Display *dpy, int *major, int *minor) -{ - XExtDisplayInfo *info = find_display(dpy); - xglvQueryVersionReq *req; - xglvQueryVersionReply rep; - - LockDisplay(dpy); - - CHECK_EXTENSION(dpy, info, False); - - GetReq(glvQueryVersion, req); - - req->reqType = info->codes->major_opcode; - req->glvndReqType = X_glvQueryVersion; - req->majorVersion = XGLV_EXT_MAJOR; - req->minorVersion = XGLV_EXT_MINOR; - - if (!_XReply(dpy, (xReply*)&rep, 0, xTrue)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *major = rep.majorVersion; - *minor = rep.minorVersion; - UnlockDisplay(dpy); - SyncHandle(); - return True; -} - -/* - * Returns the screen associated with this XID, or -1 if there was an error. - */ -int XGLVQueryXIDScreenMapping( - Display *dpy, - XID xid -) -{ - XExtDisplayInfo *info = find_display(dpy); - xglvQueryXIDScreenMappingReq *req; - xglvQueryXIDScreenMappingReply rep; - - LockDisplay(dpy); - - CHECK_EXTENSION(dpy, info, -1); - - GetReq(glvQueryXIDScreenMapping, req); - - req->reqType = info->codes->major_opcode; - req->glvndReqType = X_glvQueryXIDScreenMapping; - req->xid = xid; - - if (!_XReply(dpy, (xReply*)&rep, 0, xTrue)) { - UnlockDisplay(dpy); - SyncHandle(); - return -1; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return rep.screen; -} - -/* - * Returns the vendor associated with this screen, or NULL if there was an - * error. - */ -char *XGLVQueryScreenVendorMapping( - Display *dpy, - int screen -) -{ - XExtDisplayInfo *info = find_display(dpy); - xglvQueryScreenVendorMappingReq *req; - xglvQueryScreenVendorMappingReply rep; - size_t length, nbytes, slop; - char *buf; - - LockDisplay(dpy); - - CHECK_EXTENSION(dpy, info, NULL); - - GetReq(glvQueryScreenVendorMapping, req); - req->reqType = info->codes->major_opcode; - req->glvndReqType = X_glvQueryScreenVendorMapping; - req->screen = screen; - - if (!_XReply(dpy, (xReply*)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - - length = rep.length; - nbytes = rep.n; - - if (!nbytes) { - buf = NULL; - assert(!length); - } else { - slop = nbytes & 3; - buf = (char *)Xmalloc(nbytes); - if (!buf) { - _XEatData(dpy, length); - } else { - _XRead(dpy, (char *)buf, nbytes); - if (slop) { - _XEatData(dpy, 4-slop); - } - } - } - - UnlockDisplay(dpy); - SyncHandle(); - - return buf; -} - diff --git a/src/x11glvnd/x11glvndproto.h b/src/x11glvnd/x11glvndproto.h deleted file mode 100644 index eb1a534..0000000 --- a/src/x11glvnd/x11glvndproto.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2013, 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 __X11GLVND_PROTO_H__ -#define __X11GLVND_PROTO_H__ - -/*! - * File describing protocol for the x11glvnd extension. - */ - -#include "X11/Xmd.h" - -#define XGLV_NUM_EVENTS 0 -#define XGLV_NUM_ERRORS 0 - -#define XGLV_EXT_MAJOR 1 -#define XGLV_EXT_MINOR 0 - -// TODO: X_glvQueryXIDVendorMapping? -#define X_glvQueryVersion 0 -#define X_glvQueryXIDScreenMapping 1 -#define X_glvQueryScreenVendorMapping 2 -#define X_glvLastRequest (X_glvQueryScreenVendorMapping+1) - -#define GLVND_PAD(x) (((x)+3) & ~3) - -#define GLVND_REPLY_HEADER(reply, len) \ - (reply).type = X_Reply; \ - (reply).unused = 0; \ - (reply).sequenceNumber = client->sequence; \ - (reply).length = len - -/* - * Following convenience macros are temporary and will be #undef'ed - * after the protocol definitions. - */ - -#define __GLV_REQ_PREAMBLE \ - CARD8 reqType; \ - CARD8 glvndReqType; \ - CARD16 length B16 - -#define __GLV_REPLY_PREAMBLE \ - BYTE type; \ - BYTE unused; \ - CARD16 sequenceNumber B16; \ - CARD32 length B32 - -#define __GLV_DEFINE_REQ(name, layout) \ - typedef struct xglv ## name ## ReqRec { \ - __GLV_REQ_PREAMBLE; \ - layout \ - } xglv ## name ## Req; \ -static const size_t sz_xglv ## name ## Req = \ - GLVND_PAD(sizeof(xglv ## name ## Req)) - -#define __GLV_DEFINE_REPLY(name, layout) \ - typedef struct xglv ## name ## ReplyRec { \ - __GLV_REPLY_PREAMBLE; \ - layout \ - } xglv ## name ## Reply; \ -static const size_t sz_xglv ## name ## Reply = \ - 32 // sizeof(xReply) - -__GLV_DEFINE_REQ(QueryVersion, - CARD32 majorVersion B32; - CARD32 minorVersion B32; -); - -__GLV_DEFINE_REPLY(QueryVersion, - CARD32 majorVersion B32; - CARD32 minorVersion B32; - CARD32 padl4 B32; - CARD32 padl5 B32; - CARD32 padl6 B32; - CARD32 padl7 B32; -); - -__GLV_DEFINE_REQ(QueryXIDScreenMapping, - CARD32 xid B32; -); - -__GLV_DEFINE_REPLY(QueryXIDScreenMapping, - INT32 screen B32; - CARD32 padl3 B32; - CARD32 padl4 B32; - CARD32 padl5 B32; - CARD32 padl6 B32; - CARD32 padl7 B32; -); - -__GLV_DEFINE_REQ(QueryScreenVendorMapping, - INT32 screen B32; -); - -__GLV_DEFINE_REPLY(QueryScreenVendorMapping, - CARD32 n B32; - CARD32 padl3 B32; - CARD32 padl4 B32; - CARD32 padl5 B32; - CARD32 padl6 B32; - CARD32 padl7 B32; -); - -#undef __GLV_DEFINE_REQ -#undef __GLV_DEFINE_REPLY -#undef __GLV_REPLY_PREAMBLE -#undef __GLV_REQ_PREAMBLE - -#endif diff --git a/src/x11glvnd/x11glvndserver.c b/src/x11glvnd/x11glvndserver.c deleted file mode 100644 index 61db9da..0000000 --- a/src/x11glvnd/x11glvndserver.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2013, 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 "include/scrnintstr.h" - -#include <xorg-server.h> -#include <xorgVersion.h> -#include <string.h> -#include <xf86Module.h> -#include <scrnintstr.h> -#include <windowstr.h> -#include <dixstruct.h> -#include <extnsionst.h> -#include <xf86.h> - -#include "x11glvnd.h" -#include "x11glvndproto.h" -#include "x11glvndserver.h" -#include "glvnd_list.h" - -#define XGLV_ABI_HAS_DIX_REGISTER_PRIVATE_KEY (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 8) -#define XGLV_ABI_HAS_DEV_PRIVATE_REWORK (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 4) -#define XGLV_ABI_HAS_DIX_LOOKUP_RES_BY (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 6) -#define XGLV_ABI_EXTENSION_MODULE_HAS_SETUP_FUNC_AND_INIT_DEPS \ - (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) <= 12) -#define XGLV_ABI_HAS_LOAD_EXTENSION_LIST (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 17) -#define XGLV_ABI_SWAP_MACROS_HAVE_N_ARG (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) <= 11) - -/* - * Screen-private structure - */ -typedef struct XGLVScreenPrivRec { - char *vendorLib; -} XGLVScreenPriv; - -static inline Bool xglvInitPrivateSpace(void); -static inline XGLVScreenPriv *xglvGetScreenPrivate(ScreenPtr pScreen); -static inline void xglvSetScreenPrivate(ScreenPtr pScreen, XGLVScreenPriv *priv); -static inline int xglvLookupResource(pointer *result, XID id, RESTYPE rtype, - ClientPtr client, Mask access_mode); - -#if XGLV_ABI_HAS_DIX_REGISTER_PRIVATE_KEY -// ABI >= 8 -static DevPrivateKeyRec glvXGLVScreenPrivKey; -#elif XGLV_ABI_HAS_DEV_PRIVATE_REWORK // XGLV_ABI_HAS_DIX_REGISTER_PRIVATE_KEY -// ABI 4 - 7 -// In ABI 5, DevPrivateKey is int* and needs to point to a unique int. -// In ABI 4, DevPrivateKey is void* and just needs to be unique. -// We just use the ABI 5 behavior for both for consistency. -static int glvXGLVScreenPrivKey; -#else -// ABI <= 3 -static int glvXGLVScreenPrivKey = -1; -#endif - -#if XGLV_ABI_SWAP_MACROS_HAVE_N_ARG - -#define XGLV_SWAPS(x) \ -do { \ - int _XGLV_SWAPN; \ - swaps(x, _XGLV_SWAPN);\ -} while(0) - -#define XGLV_SWAPL(x) \ -do { \ - int _XGLV_SWAPN; \ - swapl(x, _XGLV_SWAPN);\ -} while(0) - -#else - -#define XGLV_SWAPS(x) swaps(x) -#define XGLV_SWAPL(x) swapl(x) - -#endif // XGLV_ABI_SWAP_FUNCS_TAKE_N_ARG - -/* Dispatch information */ -typedef int ProcVectorFunc(ClientPtr); -typedef ProcVectorFunc *ProcVectorFuncPtr; - -#define PROC_VECTOR_ENTRY(foo) [X_glv ## foo] = ProcGLV ## foo -#define PROC_PROTO(foo) static int ProcGLV ## foo (ClientPtr client) - -PROC_PROTO(QueryVersion); -PROC_PROTO(QueryXIDScreenMapping); -PROC_PROTO(QueryScreenVendorMapping); - -static ProcVectorFuncPtr glvProcVector[X_glvLastRequest] = { - PROC_VECTOR_ENTRY(QueryVersion), - PROC_VECTOR_ENTRY(QueryXIDScreenMapping), - PROC_VECTOR_ENTRY(QueryScreenVendorMapping), -}; - -#undef PROC_VECTOR_ENTRY - -static void GLVExtensionInit(void); - -/* Module information */ -static ExtensionModule glvExtensionModule = { - GLVExtensionInit, - XGLV_EXTENSION_NAME, - NULL, -#if XGLV_ABI_EXTENSION_MODULE_HAS_SETUP_FUNC_AND_INIT_DEPS - NULL, - NULL -#endif -}; - -static XF86ModuleVersionInfo x11glvndVersionInfo = -{ - "x11glvnd", - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XORG_VERSION_NUMERIC(4,0,2,0,0), - 1, 0, 0, - NULL, // ABI_CLASS_EXTENSION, - ABI_EXTENSION_VERSION, - MOD_CLASS_EXTENSION, - {0, 0, 0, 0} -}; - -static void *glvSetup(void *module, void *opts, int *errmaj, int *errmin); - -/* - * x11glvndModuleData is a magic symbol needed to load the x11glvnd module in - * the X server. - */ -PUBLIC const XF86ModuleData x11glvndModuleData = { &x11glvndVersionInfo, - glvSetup, NULL }; - -static void *glvSetup(void *module, void *opts, int *errmaj, int *errmin) -{ - static Bool x11glvndSetupDone = FALSE; - typedef int (*LoaderGetABIVersionProc)(const char *abiclass); - LoaderGetABIVersionProc pLoaderGetABIVersion; - int videoMajor = 0; - - if (x11glvndSetupDone) { - if (errmaj) { - *errmaj = LDR_ONCEONLY; - } - return NULL; - } - x11glvndSetupDone = TRUE; - - xf86Msg(X_INFO, "x11glvnd Loading\n"); - - // All of the ABI checks use the video driver ABI version number, so that's - // what we'll check here. - if ((pLoaderGetABIVersion = (LoaderGetABIVersionProc)LoaderSymbol("LoaderGetABIVersion"))) { - videoMajor = GET_ABI_MAJOR(pLoaderGetABIVersion(ABI_CLASS_VIDEODRV)); - } - - if (videoMajor != GET_ABI_MAJOR(ABI_VIDEODRV_VERSION)) { - xf86Msg(X_INFO, "x11glvnd: X server major video driver ABI mismatch: expected %d but saw %d\n", - GET_ABI_MAJOR(ABI_VIDEODRV_VERSION), videoMajor); - return NULL; - } - -#if XGLV_ABI_HAS_LOAD_EXTENSION_LIST - LoadExtensionList(&glvExtensionModule, 1, False); -#else - LoadExtension(&glvExtensionModule, False); -#endif - - return (pointer)1; -} - -typedef struct DrawableTypeRec { - RESTYPE rtype; - struct glvnd_list entry; -} XGLVDrawableType; - -struct glvnd_list xglvDrawableTypes; - -int LookupXIDScreenMapping(ClientPtr client, XID xid); - -int LookupXIDScreenMapping(ClientPtr client, XID xid) -{ - DrawablePtr pDraw; - Status status; - XGLVDrawableType *drawType; - - glvnd_list_for_each_entry(drawType, &xglvDrawableTypes, entry) { - pDraw = NULL; - status = xglvLookupResource((void **)&pDraw, xid, - RT_WINDOW, client, - BadDrawable); - if (status == Success) { - break; - } - } - - if (pDraw) { - return pDraw->pScreen->myNum; - } else { - return -1; - } -} - -/* - * Hook for GLX drivers to register their GLX drawable types. - */ -void _XGLVRegisterGLXDrawableType(RESTYPE rtype) -{ - XGLVDrawableType *drawType = malloc(sizeof(*drawType)); - - drawType->rtype = rtype; - glvnd_list_add(&drawType->entry, &xglvDrawableTypes); -} - -enum { - OPTION_GL_VENDOR, -}; - -static char *GetVendorForThisScreen(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum]; - const char *str; - char *processedStr; - OptionInfoRec options[2]; - - options[0].token = OPTION_GL_VENDOR; - options[0].name = XGLV_X_CONFIG_OPTION_NAME; - options[0].type = OPTV_STRING; - memset(&options[0].value, 0, sizeof(options[0].value)); - options[0].found = False; - - /* Fill a blank entry to the table */ - options[1].token = -1; - options[1].name = NULL; - options[1].type = OPTV_NONE; - memset(&options[1].value, 0, sizeof(options[1].value)); - options[1].found = False; - - if (!pScrnInfo->options) { - xf86CollectOptions(pScrnInfo, NULL); - } - - xf86ProcessOptions(pScreen->myNum, - pScrnInfo->options, - options); - - str = xf86GetOptValString(options, OPTION_GL_VENDOR); - if (!str) { - // Fall back to the driver name if no explicit option specified - str = pScrnInfo->name; - } - if (!str) { - str = "unknown"; - } - - processedStr = strdup(str); - if (processedStr) { - size_t i; - size_t len = strlen(processedStr); - for (i = 0; i < len; i++) { - processedStr[i] = tolower(processedStr[i]); - } - } - - return processedStr; -} - -static Bool xglvScreenInit(ScreenPtr pScreen) -{ - XGLVScreenPriv *pScreenPriv; - - pScreenPriv = malloc(sizeof(XGLVScreenPriv)); - - if (!pScreenPriv) { - return False; - } - - // Get the vendor library for this screen - pScreenPriv->vendorLib = GetVendorForThisScreen(pScreen); - - if (!pScreenPriv->vendorLib) { - free(pScreenPriv); - return False; - } - - xglvSetScreenPrivate(pScreen, pScreenPriv); - - return True; -} - -static int ProcGLVQueryVersion(ClientPtr client) -{ - xglvQueryVersionReply rep; - REQUEST(xglvQueryVersionReq); - - REQUEST_SIZE_MATCH(*stuff); - - // Write the reply - GLVND_REPLY_HEADER(rep, 0); - rep.majorVersion = XGLV_EXT_MAJOR; - rep.minorVersion = XGLV_EXT_MINOR; - - if (client->swapped) { - XGLV_SWAPS(&rep.sequenceNumber); - XGLV_SWAPL(&rep.length); - XGLV_SWAPL(&rep.majorVersion); - XGLV_SWAPL(&rep.minorVersion); - } - - WriteToClient(client, sz_xglvQueryVersionReply, (char *)&rep); - return client->noClientException; -} - -// TODO: make sense to do this instead? -// -//static int ProcGLVQueryXIDVendorMapping(ClientPtr client) -//{ -// // TODO: char *XGLVQueryXIDVendorMapping(XID xid) -// // Returns the name of the vendor library for this XID -//} - -static int ProcGLVQueryXIDScreenMapping(ClientPtr client) -{ - xglvQueryXIDScreenMappingReply rep; - REQUEST(xglvQueryXIDScreenMappingReq); - int scrnum; - - REQUEST_SIZE_MATCH(*stuff); - - scrnum = LookupXIDScreenMapping(client, stuff->xid); - - // Write the reply - GLVND_REPLY_HEADER(rep, 0); - rep.screen = scrnum; - - if (client->swapped) { - XGLV_SWAPS(&rep.sequenceNumber); - XGLV_SWAPL(&rep.length); - XGLV_SWAPL(&rep.screen); - } - - WriteToClient(client, sz_xglvQueryXIDScreenMappingReply, (char *)&rep); - return client->noClientException; -} - -static int ProcGLVQueryScreenVendorMapping(ClientPtr client) -{ - xglvQueryScreenVendorMappingReply rep; - REQUEST(xglvQueryScreenVendorMappingReq); - const char *vendor; - size_t n, length; - char *buf; - ScreenPtr pScreen; - XGLVScreenPriv *pScreenPriv; - - REQUEST_SIZE_MATCH(*stuff); - - if ((stuff->screen >= screenInfo.numScreens) || - (stuff->screen < 0)) { - vendor = NULL; - } else { - pScreen = screenInfo.screens[stuff->screen]; - pScreenPriv = xglvGetScreenPrivate(pScreen); - vendor = pScreenPriv->vendorLib; - } - - if (vendor) { - n = strlen(vendor) + 1; - length = GLVND_PAD(n) >> 2; - buf = malloc(length << 2); - if (!buf) { - return BadAlloc; - } - strncpy(buf, vendor, n); - - // Write the reply - GLVND_REPLY_HEADER(rep, length); - rep.n = n; - - if (client->swapped) { - XGLV_SWAPS(&rep.sequenceNumber); - XGLV_SWAPL(&rep.length); - XGLV_SWAPL(&rep.n); - } - - WriteToClient(client, sz_xglvQueryScreenVendorMappingReply, (char *)&rep); - WriteToClient(client, (int)(length << 2), buf); - - free(buf); - } else { - GLVND_REPLY_HEADER(rep, 0); - rep.n = 0; - if (client->swapped) { - XGLV_SWAPS(&rep.sequenceNumber); - XGLV_SWAPL(&rep.length); - XGLV_SWAPL(&rep.n); - } - WriteToClient(client, sz_xglvQueryScreenVendorMappingReply, (char *)&rep); - } - - return client->noClientException; -} - -static int ProcGLVDispatch(ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data >= X_glvLastRequest) { - return BadRequest; - } - - if (!glvProcVector[stuff->data]) { - return BadImplementation; - } - - return glvProcVector[stuff->data](client); -} - -static int SProcGLVDispatch(ClientPtr client) -{ - return BadImplementation; -} - -static void GLVReset(ExtensionEntry *extEntry) -{ - // nop -} - -static void GLVExtensionInit(void) -{ - ExtensionEntry *extEntry; - char ext_name[] = XGLV_EXTENSION_NAME; - size_t i; - XGLVDrawableType *drawType; - - if ((extEntry = AddExtension(ext_name, - XGLV_NUM_EVENTS, - XGLV_NUM_ERRORS, - ProcGLVDispatch, - SProcGLVDispatch, - GLVReset, - StandardMinorOpcode))) - { - // do stuff with extEntry? - } - - xglvInitPrivateSpace(); - - for (i = 0; i < screenInfo.numScreens; i++) { - xglvScreenInit(screenInfo.screens[i]); - } - - glvnd_list_init(&xglvDrawableTypes); - drawType = malloc(sizeof(*drawType)); - drawType->rtype = RT_WINDOW; - glvnd_list_add(&drawType->entry, &xglvDrawableTypes); -} - -#if XGLV_ABI_HAS_DIX_REGISTER_PRIVATE_KEY -// ABI >= 8 - -Bool xglvInitPrivateSpace(void) -{ - return dixRegisterPrivateKey(&glvXGLVScreenPrivKey, PRIVATE_SCREEN, 0); -} - -XGLVScreenPriv *xglvGetScreenPrivate(ScreenPtr pScreen) -{ - return (XGLVScreenPriv *) dixLookupPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey); -} - -void xglvSetScreenPrivate(ScreenPtr pScreen, XGLVScreenPriv *priv) -{ - dixSetPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey, priv); -} - -#elif XGLV_ABI_HAS_DEV_PRIVATE_REWORK // XGLV_ABI_HAS_DIX_REGISTER_PRIVATE_KEY -// ABI 4 - 7 - -Bool xglvInitPrivateSpace(void) -{ - return dixRequestPrivate(&glvXGLVScreenPrivKey, 0); -} - -XGLVScreenPriv *xglvGetScreenPrivate(ScreenPtr pScreen) -{ - return (XGLVScreenPriv *) dixLookupPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey); -} - -void xglvSetScreenPrivate(ScreenPtr pScreen, XGLVScreenPriv *priv) -{ - dixSetPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey, priv); -} - -#else -// ABI <= 3 - -Bool xglvInitPrivateSpace(void) -{ - glvXGLVScreenPrivKey = AllocateScreenPrivateIndex(); - return (glvXGLVScreenPrivKey >= 0); -} - -XGLVScreenPriv *xglvGetScreenPrivate(ScreenPtr pScreen) -{ - return (XGLVScreenPriv *) (pScreen->devPrivates[glvXGLVScreenPrivKey].ptr); -} - -void xglvSetScreenPrivate(ScreenPtr pScreen, XGLVScreenPriv *priv) -{ - pScreen->devPrivates[glvXGLVScreenPrivKey].ptr = priv; -} - -#endif - -int xglvLookupResource(pointer *result, XID id, RESTYPE rtype, - ClientPtr client, Mask access_mode) -{ -#if XGLV_ABI_HAS_DIX_LOOKUP_RES_BY - return dixLookupResourceByType(result, id, rtype, client, access_mode); -#elif XGLV_ABI_HAS_DEV_PRIVATE_REWORK - return dixLookupResource(result, id, rtype, client, access_mode); -#else - *result = SecurityLookupIDByType(client, id, rtype, access_mode); - return (*result ? Success : BadValue); -#endif -} - diff --git a/tests/Makefile.am b/tests/Makefile.am index 5d2ab01..2703656 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,41 +41,44 @@ TESTS = \ testglxmcloop.sh \ testglxmcthreads.sh \ testglxmclate.sh \ - testx11glvndproto.sh \ testglxmcoldlink.sh \ testglxgetclientstr.sh \ testglxqueryversion.sh \ - testglxnscreens.sh \ testglxnscrthreads.sh \ testpatchentrypoints.sh \ fini_test_env.sh +# TODO: These tests depend on the x11glvnd server extension, which isn't used +# anymore. They need to be rewritten to use the GLX_EXT_libglvnd extension +# instead. +#TESTS += testx11glvndproto.sh +#TESTS += testglxnscreens.sh + EXTRA_DIST = $(TESTS) check_PROGRAMS = \ testglxgetprocaddress \ testglxmakecurrent \ testglxmakecurrent_oldlink \ - testx11glvndproto \ testglxgetclientstr \ testglxqueryversion \ - testpatchentrypoints \ - testglxnscreens + testpatchentrypoints + +#check_PROGRAMS += testx11glvndproto +#check_PROGRAMS += testglxnscreens testglxnscreens_SOURCES = \ $(top_srcdir)/src/util/glvnd_pthread.c \ testglxnscreens.c \ test_utils.c -X11GLVND_DIR = src/x11glvnd - -testglxnscreens_CFLAGS = -I$(top_srcdir)/$(X11GLVND_DIR) $(AM_CFLAGS) - -testglxnscreens_LDADD = -lX11 -testglxnscreens_LDADD += $(top_builddir)/src/GLX/libGLX.la -testglxnscreens_LDADD += $(top_builddir)/src/OpenGL/libOpenGL.la -testglxnscreens_LDADD += $(top_builddir)/src/util/trace/libtrace.la -testglxnscreens_LDADD += -lX11 -ldl $(top_builddir)/$(X11GLVND_DIR)/libx11glvnd_client.la +#testglxnscreens_CFLAGS = -I$(top_srcdir)/$(X11GLVND_DIR) $(AM_CFLAGS) +# +#testglxnscreens_LDADD = -lX11 +#testglxnscreens_LDADD += $(top_builddir)/src/GLX/libGLX.la +#testglxnscreens_LDADD += $(top_builddir)/src/OpenGL/libOpenGL.la +#testglxnscreens_LDADD += $(top_builddir)/src/util/trace/libtrace.la +#testglxnscreens_LDADD += -lX11 -ldl $(top_builddir)/$(X11GLVND_DIR)/libx11glvnd_client.la # The *_oldlink variant tests that linking against legacy libGL.so works @@ -94,8 +97,8 @@ testglxmakecurrent_oldlink_LDADD = -lX11 -ldl testglxmakecurrent_oldlink_LDADD += $(top_builddir)/src/GL/libGL.la testglxmakecurrent_oldlink_LDADD += $(top_builddir)/src/util/trace/libtrace.la -testx11glvndproto_CFLAGS = -I$(top_srcdir)/$(X11GLVND_DIR) -testx11glvndproto_LDADD = -lX11 $(top_builddir)/$(X11GLVND_DIR)/libx11glvnd_client.la +#testx11glvndproto_CFLAGS = -I$(top_srcdir)/$(X11GLVND_DIR) +#testx11glvndproto_LDADD = -lX11 $(top_builddir)/$(X11GLVND_DIR)/libx11glvnd_client.la # Disable annoying "unused" errors AM_CFLAGS = \ |