Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | ||
47 | struct 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 | ||
68 | /** | |
69 | * List of known GLX Extensions. | |
70 | * The last Y/N switch informs whether the support of this extension is always enabled. | |
71 | */ | |
72 | static const struct extension_info known_glx_extensions[] = { | |
73 | /* GLX_ARB_get_proc_address is implemented on the client. */ | |
74 | /* *INDENT-OFF* */ | |
75 | { GLX(ARB_create_context), VER(0,0), N, }, | |
76 | { GLX(ARB_create_context_profile), VER(0,0), N, }, | |
77 | { GLX(ARB_create_context_robustness), VER(0,0), N, }, | |
78 | { GLX(ARB_fbconfig_float), VER(0,0), N, }, | |
79 | { GLX(ARB_framebuffer_sRGB), VER(0,0), N, }, | |
80 | { GLX(ARB_multisample), VER(1,4), Y, }, | |
81 | ||
82 | { GLX(EXT_create_context_es2_profile), VER(0,0), N, }, | |
83 | { GLX(EXT_framebuffer_sRGB), VER(0,0), N, }, | |
84 | { GLX(EXT_import_context), VER(0,0), Y, }, | |
85 | { GLX(EXT_texture_from_pixmap), VER(0,0), Y, }, | |
86 | { GLX(EXT_visual_info), VER(0,0), Y, }, | |
87 | { GLX(EXT_visual_rating), VER(0,0), Y, }, | |
88 | ||
89 | { GLX(MESA_copy_sub_buffer), VER(0,0), N, }, | |
90 | { GLX(OML_swap_method), VER(0,0), Y, }, | |
91 | { GLX(SGI_make_current_read), VER(1,3), N, }, | |
92 | { GLX(SGI_swap_control), VER(0,0), N, }, | |
93 | { GLX(SGIS_multisample), VER(0,0), Y, }, | |
94 | { GLX(SGIX_fbconfig), VER(1,3), Y, }, | |
95 | { GLX(SGIX_pbuffer), VER(1,3), Y, }, | |
96 | { GLX(SGIX_visual_select_group), VER(0,0), Y, }, | |
97 | { GLX(INTEL_swap_event), VER(0,0), N, }, | |
98 | { NULL } | |
99 | /* *INDENT-ON* */ | |
100 | }; | |
101 | ||
102 | /** | |
103 | * Create a GLX extension string for a set of enable bits. | |
104 | * | |
105 | * Creates a GLX extension string for the set of bit in \c enable_bits. This | |
106 | * string is then stored in \c buffer if buffer is not \c NULL. This allows | |
107 | * two-pass operation. On the first pass the caller passes \c NULL for | |
108 | * \c buffer, and the function determines how much space is required to store | |
109 | * the extension string. The caller allocates the buffer and calls the | |
110 | * function again. | |
111 | * | |
112 | * \param enable_bits Bits representing the enabled extensions. | |
113 | * \param buffer Buffer to store the extension string. May be \c NULL. | |
114 | * | |
115 | * \return | |
116 | * The number of characters in \c buffer that were written to. If \c buffer | |
117 | * is \c NULL, this is the size of buffer that must be allocated by the | |
118 | * caller. | |
119 | */ | |
120 | int | |
121 | __glXGetExtensionString(const unsigned char *enable_bits, char *buffer) | |
122 | { | |
123 | unsigned i; | |
124 | int length = 0; | |
125 | ||
126 | for (i = 0; known_glx_extensions[i].name != NULL; i++) { | |
127 | const unsigned bit = known_glx_extensions[i].bit; | |
128 | const size_t len = known_glx_extensions[i].name_len; | |
129 | ||
130 | if (EXT_ENABLED(bit, enable_bits)) { | |
131 | if (buffer != NULL) { | |
132 | (void) memcpy(&buffer[length], known_glx_extensions[i].name, | |
133 | len); | |
134 | ||
135 | buffer[length + len + 0] = ' '; | |
136 | buffer[length + len + 1] = '\0'; | |
137 | } | |
138 | ||
139 | length += len + 1; | |
140 | } | |
141 | } | |
142 | ||
143 | return length + 1; | |
144 | } | |
145 | ||
146 | void | |
147 | __glXEnableExtension(unsigned char *enable_bits, const char *ext) | |
148 | { | |
149 | const size_t ext_name_len = strlen(ext); | |
150 | unsigned i; | |
151 | ||
152 | for (i = 0; known_glx_extensions[i].name != NULL; i++) { | |
153 | if ((ext_name_len == known_glx_extensions[i].name_len) | |
154 | && (memcmp(ext, known_glx_extensions[i].name, ext_name_len) == 0)) { | |
155 | SET_BIT(enable_bits, known_glx_extensions[i].bit); | |
156 | break; | |
157 | } | |
158 | } | |
159 | } | |
160 | ||
161 | void | |
162 | __glXInitExtensionEnableBits(unsigned char *enable_bits) | |
163 | { | |
164 | unsigned i; | |
165 | ||
166 | (void) memset(enable_bits, 0, __GLX_EXT_BYTES); | |
167 | ||
168 | for (i = 0; known_glx_extensions[i].name != NULL; i++) { | |
169 | if (known_glx_extensions[i].driver_support) { | |
170 | SET_BIT(enable_bits, known_glx_extensions[i].bit); | |
171 | } | |
172 | } | |
173 | } |