diff options
-rw-r--r-- | src/GLX/Makefile.am | 4 | ||||
-rw-r--r-- | src/GLX/libglxproto.c | 173 | ||||
-rw-r--r-- | src/GLX/libglxproto.h | 71 |
3 files changed, 247 insertions, 1 deletions
diff --git a/src/GLX/Makefile.am b/src/GLX/Makefile.am index 6905cc1..156b3b5 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 @@ -79,6 +80,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/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/GLX/libglxproto.h b/src/GLX/libglxproto.h new file mode 100644 index 0000000..2e82f8d --- /dev/null +++ b/src/GLX/libglxproto.h @@ -0,0 +1,71 @@ +/* + * 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 LIBGLXPROTO_H +#define LIBGLXPROTO_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" + +/*! + * Sends a glXQueryServerString request. If an error occurs, then it will + * return \c NULL, but won't call the X error handler. + * + * \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); + +/*! + * 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 // LIBGLXPROTO_H |