| 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 | } |