extension_string.c revision 706f2543
1/* 2 * (C) Copyright IBM Corporation 2002-2006 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file extension_string.c 27 * Routines to manage the GLX extension string and GLX version for AIGLX 28 * drivers. This code is loosely based on src/glx/x11/glxextensions.c from 29 * Mesa. 30 * 31 * \author Ian Romanick <idr@us.ibm.com> 32 */ 33 34#include <string.h> 35#include "extension_string.h" 36 37#define SET_BIT(m,b) (m[ (b) / 8 ] |= (1U << ((b) % 8))) 38#define CLR_BIT(m,b) (m[ (b) / 8 ] &= ~(1U << ((b) % 8))) 39#define IS_SET(m,b) ((m[ (b) / 8 ] & (1U << ((b) % 8))) != 0) 40#define CONCAT(a,b) a ## b 41#define GLX(n) "GLX_" # n, 4 + sizeof( # n ) - 1, CONCAT(n,_bit) 42#define VER(a,b) a, b 43#define Y 1 44#define N 0 45#define EXT_ENABLED(bit,supported) (IS_SET(supported, bit)) 46 47struct extension_info { 48 const char * const name; 49 unsigned name_len; 50 51 unsigned char bit; 52 53 /** 54 * This is the lowest version of GLX that "requires" this extension. 55 * For example, GLX 1.3 requires SGIX_fbconfig, SGIX_pbuffer, and 56 * SGI_make_current_read. If the extension is not required by any known 57 * version of GLX, use 0, 0. 58 */ 59 unsigned char version_major; 60 unsigned char version_minor; 61 62 /** 63 * Is driver support forced by the ABI? 64 */ 65 unsigned char driver_support; 66}; 67 68static const struct extension_info known_glx_extensions[] = { 69/* GLX_ARB_get_proc_address is implemented on the client. */ 70 { GLX(ARB_multisample), VER(1,4), Y, }, 71 72 { GLX(EXT_import_context), VER(0,0), Y, }, 73 { GLX(EXT_texture_from_pixmap), VER(0,0), Y, }, 74 { GLX(EXT_visual_info), VER(0,0), Y, }, 75 { GLX(EXT_visual_rating), VER(0,0), Y, }, 76 77 { GLX(MESA_copy_sub_buffer), VER(0,0), N, }, 78 { GLX(OML_swap_method), VER(0,0), Y, }, 79 { GLX(SGI_make_current_read), VER(1,3), N, }, 80 { GLX(SGI_swap_control), VER(0,0), N, }, 81 { GLX(SGIS_multisample), VER(0,0), Y, }, 82 { GLX(SGIX_fbconfig), VER(1,3), Y, }, 83 { GLX(SGIX_pbuffer), VER(1,3), Y, }, 84 { GLX(SGIX_visual_select_group), VER(0,0), Y, }, 85 { GLX(INTEL_swap_event), VER(1,4), N, }, 86 { NULL } 87}; 88 89 90/** 91 * Create a GLX extension string for a set of enable bits. 92 * 93 * Creates a GLX extension string for the set of bit in \c enable_bits. This 94 * string is then stored in \c buffer if buffer is not \c NULL. This allows 95 * two-pass operation. On the first pass the caller passes \c NULL for 96 * \c buffer, and the function determines how much space is required to store 97 * the extension string. The caller allocates the buffer and calls the 98 * function again. 99 * 100 * \param enable_bits Bits representing the enabled extensions. 101 * \param buffer Buffer to store the extension string. May be \c NULL. 102 * 103 * \return 104 * The number of characters in \c buffer that were written to. If \c buffer 105 * is \c NULL, this is the size of buffer that must be allocated by the 106 * caller. 107 */ 108int 109__glXGetExtensionString(const unsigned char *enable_bits, char *buffer) 110{ 111 unsigned i; 112 int length = 0; 113 114 115 for (i = 0; known_glx_extensions[i].name != NULL; i++) { 116 const unsigned bit = known_glx_extensions[i].bit; 117 const size_t len = known_glx_extensions[i].name_len; 118 119 if (EXT_ENABLED(bit, enable_bits)) { 120 if (buffer != NULL) { 121 (void) memcpy(& buffer[length], known_glx_extensions[i].name, 122 len); 123 124 buffer[length + len + 0] = ' '; 125 buffer[length + len + 1] = '\0'; 126 } 127 128 length += len + 1; 129 } 130 } 131 132 return length + 1; 133} 134 135 136void 137__glXEnableExtension(unsigned char *enable_bits, const char *ext) 138{ 139 const size_t ext_name_len = strlen(ext); 140 unsigned i; 141 142 143 for (i = 0; known_glx_extensions[i].name != NULL; i++) { 144 if ((ext_name_len == known_glx_extensions[i].name_len) 145 && (memcmp(ext, known_glx_extensions[i].name, ext_name_len) == 0)) { 146 SET_BIT(enable_bits, known_glx_extensions[i].bit); 147 break; 148 } 149 } 150} 151 152 153void 154__glXInitExtensionEnableBits(unsigned char *enable_bits) 155{ 156 unsigned i; 157 158 159 (void) memset(enable_bits, 0, __GLX_EXT_BYTES); 160 161 for (i = 0; known_glx_extensions[i].name != NULL; i++) { 162 if (known_glx_extensions[i].driver_support) { 163 SET_BIT(enable_bits, known_glx_extensions[i].bit); 164 } 165 } 166} 167