File: | glx/glxscreens.c |
Location: | line 325, column 9 |
Description: | Call to 'calloc' has an allocation size of 0 bytes |
1 | /* | |||
2 | * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) | |||
3 | * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
9 | * and/or sell copies of the Software, and to permit persons to whom the | |||
10 | * Software is furnished to do so, subject to the following conditions: | |||
11 | * | |||
12 | * The above copyright notice including the dates of first publication and | |||
13 | * either this permission notice or a reference to | |||
14 | * http://oss.sgi.com/projects/FreeB/ | |||
15 | * shall be included in all copies or substantial portions of the Software. | |||
16 | * | |||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
20 | * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF | |||
22 | * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
23 | * SOFTWARE. | |||
24 | * | |||
25 | * Except as contained in this notice, the name of Silicon Graphics, Inc. | |||
26 | * shall not be used in advertising or otherwise to promote the sale, use or | |||
27 | * other dealings in this Software without prior written authorization from | |||
28 | * Silicon Graphics, Inc. | |||
29 | */ | |||
30 | ||||
31 | #ifdef HAVE_DIX_CONFIG_H1 | |||
32 | #include <dix-config.h> | |||
33 | #endif | |||
34 | ||||
35 | #include <GL/glxtokens.h> | |||
36 | #include <string.h> | |||
37 | #include <windowstr.h> | |||
38 | #include <os.h> | |||
39 | #include <colormapst.h> | |||
40 | ||||
41 | #include "privates.h" | |||
42 | #include "glxserver.h" | |||
43 | #include "glxutil.h" | |||
44 | #include "glxext.h" | |||
45 | #include "protocol-versions.h" | |||
46 | ||||
47 | static DevPrivateKeyRec glxScreenPrivateKeyRec; | |||
48 | ||||
49 | #define glxScreenPrivateKey(&glxScreenPrivateKeyRec) (&glxScreenPrivateKeyRec) | |||
50 | ||||
51 | const char GLServerVersion[] = "1.4"; | |||
52 | static const char GLServerExtensions[] = | |||
53 | "GL_ARB_depth_texture " | |||
54 | "GL_ARB_draw_buffers " | |||
55 | "GL_ARB_fragment_program " | |||
56 | "GL_ARB_fragment_program_shadow " | |||
57 | "GL_ARB_imaging " | |||
58 | "GL_ARB_multisample " | |||
59 | "GL_ARB_multitexture " | |||
60 | "GL_ARB_occlusion_query " | |||
61 | "GL_ARB_point_parameters " | |||
62 | "GL_ARB_point_sprite " | |||
63 | "GL_ARB_shadow " | |||
64 | "GL_ARB_shadow_ambient " | |||
65 | "GL_ARB_texture_border_clamp " | |||
66 | "GL_ARB_texture_compression " | |||
67 | "GL_ARB_texture_cube_map " | |||
68 | "GL_ARB_texture_env_add " | |||
69 | "GL_ARB_texture_env_combine " | |||
70 | "GL_ARB_texture_env_crossbar " | |||
71 | "GL_ARB_texture_env_dot3 " | |||
72 | "GL_ARB_texture_mirrored_repeat " | |||
73 | "GL_ARB_texture_non_power_of_two " | |||
74 | "GL_ARB_transpose_matrix " | |||
75 | "GL_ARB_vertex_program " | |||
76 | "GL_ARB_window_pos " | |||
77 | "GL_EXT_abgr " | |||
78 | "GL_EXT_bgra " | |||
79 | "GL_EXT_blend_color " | |||
80 | "GL_EXT_blend_equation_separate " | |||
81 | "GL_EXT_blend_func_separate " | |||
82 | "GL_EXT_blend_logic_op " | |||
83 | "GL_EXT_blend_minmax " | |||
84 | "GL_EXT_blend_subtract " | |||
85 | "GL_EXT_clip_volume_hint " | |||
86 | "GL_EXT_copy_texture " | |||
87 | "GL_EXT_draw_range_elements " | |||
88 | "GL_EXT_fog_coord " | |||
89 | "GL_EXT_framebuffer_object " | |||
90 | "GL_EXT_multi_draw_arrays " | |||
91 | "GL_EXT_packed_pixels " | |||
92 | "GL_EXT_paletted_texture " | |||
93 | "GL_EXT_point_parameters " | |||
94 | "GL_EXT_polygon_offset " | |||
95 | "GL_EXT_rescale_normal " | |||
96 | "GL_EXT_secondary_color " | |||
97 | "GL_EXT_separate_specular_color " | |||
98 | "GL_EXT_shadow_funcs " | |||
99 | "GL_EXT_shared_texture_palette " | |||
100 | "GL_EXT_stencil_two_side " | |||
101 | "GL_EXT_stencil_wrap " | |||
102 | "GL_EXT_subtexture " | |||
103 | "GL_EXT_texture " | |||
104 | "GL_EXT_texture3D " | |||
105 | "GL_EXT_texture_compression_dxt1 " | |||
106 | "GL_EXT_texture_compression_s3tc " | |||
107 | "GL_EXT_texture_edge_clamp " | |||
108 | "GL_EXT_texture_env_add " | |||
109 | "GL_EXT_texture_env_combine " | |||
110 | "GL_EXT_texture_env_dot3 " | |||
111 | "GL_EXT_texture_filter_anisotropic " | |||
112 | "GL_EXT_texture_lod " | |||
113 | "GL_EXT_texture_lod_bias " | |||
114 | "GL_EXT_texture_mirror_clamp " | |||
115 | "GL_EXT_texture_object " | |||
116 | "GL_EXT_texture_rectangle " | |||
117 | "GL_EXT_vertex_array " | |||
118 | "GL_3DFX_texture_compression_FXT1 " | |||
119 | "GL_APPLE_packed_pixels " | |||
120 | "GL_ATI_draw_buffers " | |||
121 | "GL_ATI_texture_env_combine3 " | |||
122 | "GL_ATI_texture_mirror_once " | |||
123 | "GL_HP_occlusion_test " | |||
124 | "GL_IBM_texture_mirrored_repeat " | |||
125 | "GL_INGR_blend_func_separate " | |||
126 | "GL_MESA_pack_invert " | |||
127 | "GL_MESA_ycbcr_texture " | |||
128 | "GL_NV_blend_square " | |||
129 | "GL_NV_depth_clamp " | |||
130 | "GL_NV_fog_distance " | |||
131 | "GL_NV_fragment_program_option " | |||
132 | "GL_NV_fragment_program2 " | |||
133 | "GL_NV_light_max_exponent " | |||
134 | "GL_NV_multisample_filter_hint " | |||
135 | "GL_NV_point_sprite " | |||
136 | "GL_NV_texgen_reflection " | |||
137 | "GL_NV_texture_compression_vtc " | |||
138 | "GL_NV_texture_env_combine4 " | |||
139 | "GL_NV_texture_expand_normal " | |||
140 | "GL_NV_texture_rectangle " | |||
141 | "GL_NV_vertex_program2_option " | |||
142 | "GL_NV_vertex_program3 " | |||
143 | "GL_OES_compressed_paletted_texture " | |||
144 | "GL_SGI_color_matrix " | |||
145 | "GL_SGI_color_table " | |||
146 | "GL_SGIS_generate_mipmap " | |||
147 | "GL_SGIS_multisample " | |||
148 | "GL_SGIS_point_parameters " | |||
149 | "GL_SGIS_texture_border_clamp " | |||
150 | "GL_SGIS_texture_edge_clamp " | |||
151 | "GL_SGIS_texture_lod " | |||
152 | "GL_SGIX_depth_texture " | |||
153 | "GL_SGIX_shadow " | |||
154 | "GL_SGIX_shadow_ambient " | |||
155 | "GL_SUN_slice_accum "; | |||
156 | ||||
157 | static Bool | |||
158 | glxCloseScreen(ScreenPtr pScreen) | |||
159 | { | |||
160 | __GLXscreen *pGlxScreen = glxGetScreen(pScreen); | |||
161 | ||||
162 | pScreen->CloseScreen = pGlxScreen->CloseScreen; | |||
163 | ||||
164 | pGlxScreen->destroy(pGlxScreen); | |||
165 | ||||
166 | return pScreen->CloseScreen(pScreen); | |||
167 | } | |||
168 | ||||
169 | __GLXscreen * | |||
170 | glxGetScreen(ScreenPtr pScreen) | |||
171 | { | |||
172 | return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey(&glxScreenPrivateKeyRec)); | |||
173 | } | |||
174 | ||||
175 | _X_EXPORT__attribute__((visibility("default"))) void | |||
176 | GlxSetVisualConfigs(int nconfigs, void *configs, void **privates) | |||
177 | { | |||
178 | /* We keep this stub around for the DDX drivers that still | |||
179 | * call it. */ | |||
180 | } | |||
181 | ||||
182 | GLint | |||
183 | glxConvertToXVisualType(int visualType) | |||
184 | { | |||
185 | static const int x_visual_types[] = { | |||
186 | TrueColor4, DirectColor5, | |||
187 | PseudoColor3, StaticColor2, | |||
188 | GrayScale1, StaticGray0 | |||
189 | }; | |||
190 | ||||
191 | return ((unsigned) (visualType - GLX_TRUE_COLOR0x8002) < 6) | |||
192 | ? x_visual_types[visualType - GLX_TRUE_COLOR0x8002] : -1; | |||
193 | } | |||
194 | ||||
195 | /* This code inspired by composite/compinit.c. We could move this to | |||
196 | * mi/ and share it with composite.*/ | |||
197 | ||||
198 | static VisualPtr | |||
199 | AddScreenVisuals(ScreenPtr pScreen, int count, int d) | |||
200 | { | |||
201 | int i; | |||
202 | DepthPtr depth; | |||
203 | ||||
204 | depth = NULL((void*)0); | |||
205 | for (i = 0; i < pScreen->numDepths; i++) { | |||
206 | if (pScreen->allowedDepths[i].depth == d) { | |||
207 | depth = &pScreen->allowedDepths[i]; | |||
208 | break; | |||
209 | } | |||
210 | } | |||
211 | if (depth == NULL((void*)0)) | |||
212 | return NULL((void*)0); | |||
213 | ||||
214 | if (ResizeVisualArray(pScreen, count, depth) == FALSE0) | |||
215 | return NULL((void*)0); | |||
216 | ||||
217 | /* Return a pointer to the first of the added visuals. */ | |||
218 | return pScreen->visuals + pScreen->numVisuals - count; | |||
219 | } | |||
220 | ||||
221 | static int | |||
222 | findFirstSet(unsigned int v) | |||
223 | { | |||
224 | int i; | |||
225 | ||||
226 | for (i = 0; i < 32; i++) | |||
227 | if (v & (1 << i)) | |||
228 | return i; | |||
229 | ||||
230 | return -1; | |||
231 | } | |||
232 | ||||
233 | static void | |||
234 | initGlxVisual(VisualPtr visual, __GLXconfig * config) | |||
235 | { | |||
236 | int maxBits; | |||
237 | ||||
238 | maxBits = max(config->redBits, max(config->greenBits, config->blueBits))(((config->redBits) > ((((config->greenBits) > (config ->blueBits)) ? (config->greenBits) : (config->blueBits )))) ? (config->redBits) : ((((config->greenBits) > ( config->blueBits)) ? (config->greenBits) : (config-> blueBits)))); | |||
239 | ||||
240 | config->visualID = visual->vid; | |||
241 | visual->class = glxConvertToXVisualType(config->visualType); | |||
242 | visual->bitsPerRGBValue = maxBits; | |||
243 | visual->ColormapEntries = 1 << maxBits; | |||
244 | visual->nplanes = config->redBits + config->greenBits + config->blueBits; | |||
245 | ||||
246 | visual->redMask = config->redMask; | |||
247 | visual->greenMask = config->greenMask; | |||
248 | visual->blueMask = config->blueMask; | |||
249 | visual->offsetRed = findFirstSet(config->redMask); | |||
250 | visual->offsetGreen = findFirstSet(config->greenMask); | |||
251 | visual->offsetBlue = findFirstSet(config->blueMask); | |||
252 | } | |||
253 | ||||
254 | static __GLXconfig * | |||
255 | pickFBConfig(__GLXscreen * pGlxScreen, VisualPtr visual) | |||
256 | { | |||
257 | __GLXconfig *best = NULL((void*)0), *config; | |||
258 | int best_score = 0; | |||
259 | ||||
260 | for (config = pGlxScreen->fbconfigs; config != NULL((void*)0); config = config->next) { | |||
261 | int score = 0; | |||
262 | ||||
263 | if (config->redMask != visual->redMask || | |||
264 | config->greenMask != visual->greenMask || | |||
265 | config->blueMask != visual->blueMask) | |||
266 | continue; | |||
267 | if (config->visualRating != GLX_NONE0x8000) | |||
268 | continue; | |||
269 | /* Ignore multisampled configs */ | |||
270 | if (config->sampleBuffers) | |||
271 | continue; | |||
272 | if (glxConvertToXVisualType(config->visualType) != visual->class) | |||
273 | continue; | |||
274 | /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */ | |||
275 | if (visual->nplanes == 32 && config->rgbBits != 32) | |||
276 | continue; | |||
277 | /* Can't use the same FBconfig for multiple X visuals. I think. */ | |||
278 | if (config->visualID != 0) | |||
279 | continue; | |||
280 | ||||
281 | if (config->doubleBufferMode > 0) | |||
282 | score += 8; | |||
283 | if (config->depthBits > 0) | |||
284 | score += 4; | |||
285 | if (config->stencilBits > 0) | |||
286 | score += 2; | |||
287 | if (config->alphaBits > 0) | |||
288 | score++; | |||
289 | ||||
290 | if (score > best_score) { | |||
291 | best = config; | |||
292 | best_score = score; | |||
293 | } | |||
294 | } | |||
295 | ||||
296 | return best; | |||
297 | } | |||
298 | ||||
299 | void | |||
300 | __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen) | |||
301 | { | |||
302 | __GLXconfig *m; | |||
303 | __GLXconfig *config; | |||
304 | int i; | |||
305 | ||||
306 | if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) | |||
| ||||
307 | return; | |||
308 | ||||
309 | pGlxScreen->pScreen = pScreen; | |||
310 | pGlxScreen->GLextensions = strdup(GLServerExtensions); | |||
311 | pGlxScreen->GLXextensions = NULL((void*)0); | |||
312 | ||||
313 | pGlxScreen->CloseScreen = pScreen->CloseScreen; | |||
314 | pScreen->CloseScreen = glxCloseScreen; | |||
315 | ||||
316 | i = 0; | |||
317 | for (m = pGlxScreen->fbconfigs; m != NULL((void*)0); m = m->next) { | |||
318 | m->fbconfigID = FakeClientID(0); | |||
319 | m->visualID = 0; | |||
320 | i++; | |||
321 | } | |||
322 | pGlxScreen->numFBConfigs = i; | |||
323 | ||||
324 | pGlxScreen->visuals = | |||
325 | calloc(pGlxScreen->numFBConfigs, sizeof(__GLXconfig *)); | |||
| ||||
326 | ||||
327 | /* First, try to choose featureful FBconfigs for the existing X visuals. | |||
328 | * Note that if multiple X visuals end up with the same FBconfig being | |||
329 | * chosen, the later X visuals don't get GLX visuals (because we want to | |||
330 | * prioritize the root visual being GLX). | |||
331 | */ | |||
332 | for (i = 0; i < pScreen->numVisuals; i++) { | |||
333 | VisualPtr visual = &pScreen->visuals[i]; | |||
334 | ||||
335 | config = pickFBConfig(pGlxScreen, visual); | |||
336 | if (config) { | |||
337 | pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; | |||
338 | config->visualID = visual->vid; | |||
339 | } | |||
340 | } | |||
341 | ||||
342 | /* Then, add new visuals corresponding to all FBconfigs that didn't have | |||
343 | * an existing, appropriate visual. | |||
344 | */ | |||
345 | for (config = pGlxScreen->fbconfigs; config != NULL((void*)0); config = config->next) { | |||
346 | int depth; | |||
347 | ||||
348 | VisualPtr visual; | |||
349 | ||||
350 | if (config->visualID != 0) | |||
351 | continue; | |||
352 | ||||
353 | /* Only count RGB bits and not alpha, as we're not trying to create | |||
354 | * visuals for compositing (that's what the 32-bit composite visual | |||
355 | * set up above is for. | |||
356 | */ | |||
357 | depth = config->redBits + config->greenBits + config->blueBits; | |||
358 | ||||
359 | /* Make sure that our FBconfig's depth can actually be displayed | |||
360 | * (corresponds to an existing visual). | |||
361 | */ | |||
362 | for (i = 0; i < pScreen->numVisuals; i++) { | |||
363 | if (depth == pScreen->visuals[i].nplanes) | |||
364 | break; | |||
365 | } | |||
366 | /* if it can't, fix up the fbconfig to not advertise window support */ | |||
367 | if (i == pScreen->numVisuals) | |||
368 | config->drawableType &= ~(GLX_WINDOW_BIT0x00000001); | |||
369 | ||||
370 | /* fbconfig must support window drawables */ | |||
371 | if (!(config->drawableType & GLX_WINDOW_BIT0x00000001)) { | |||
372 | config->visualID = 0; | |||
373 | continue; | |||
374 | } | |||
375 | ||||
376 | /* Create a new X visual for our FBconfig. */ | |||
377 | visual = AddScreenVisuals(pScreen, 1, depth); | |||
378 | if (visual == NULL((void*)0)) | |||
379 | continue; | |||
380 | ||||
381 | pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; | |||
382 | initGlxVisual(visual, config); | |||
383 | } | |||
384 | ||||
385 | dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey(&glxScreenPrivateKeyRec), pGlxScreen); | |||
386 | ||||
387 | if (pGlxScreen->glvnd) | |||
388 | __glXEnableExtension(pGlxScreen->glx_enable_bits, "GLX_EXT_libglvnd"); | |||
389 | ||||
390 | i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL((void*)0)); | |||
391 | if (i > 0) { | |||
392 | pGlxScreen->GLXextensions = xnfalloc(i)XNFalloc((unsigned long)(i)); | |||
393 | (void) __glXGetExtensionString(pGlxScreen->glx_enable_bits, | |||
394 | pGlxScreen->GLXextensions); | |||
395 | } | |||
396 | ||||
397 | } | |||
398 | ||||
399 | void | |||
400 | __glXScreenDestroy(__GLXscreen * screen) | |||
401 | { | |||
402 | free(screen->glvnd); | |||
403 | free(screen->GLXextensions); | |||
404 | free(screen->GLextensions); | |||
405 | free(screen->visuals); | |||
406 | } |