singlepix.c revision 7e31ba66
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_H 32#include <dix-config.h> 33#endif 34 35#include "glxserver.h" 36#include "glxext.h" 37#include "singlesize.h" 38#include "unpack.h" 39#include "indirect_size_get.h" 40#include "indirect_dispatch.h" 41 42int 43__glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc) 44{ 45 GLsizei width, height; 46 GLenum format, type; 47 GLboolean swapBytes, lsbFirst; 48 GLint compsize; 49 __GLXcontext *cx; 50 ClientPtr client = cl->client; 51 int error; 52 char *answer, answerBuffer[200]; 53 xGLXSingleReply reply = { 0, }; 54 55 REQUEST_FIXED_SIZE(xGLXSingleReq, 28); 56 57 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 58 if (!cx) { 59 return error; 60 } 61 62 pc += __GLX_SINGLE_HDR_SIZE; 63 width = *(GLsizei *) (pc + 8); 64 height = *(GLsizei *) (pc + 12); 65 format = *(GLenum *) (pc + 16); 66 type = *(GLenum *) (pc + 20); 67 swapBytes = *(GLboolean *) (pc + 24); 68 lsbFirst = *(GLboolean *) (pc + 25); 69 compsize = __glReadPixels_size(format, type, width, height); 70 if (compsize < 0) 71 return BadLength; 72 73 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 74 glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); 75 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); 76 __glXClearErrorOccured(); 77 glReadPixels(*(GLint *) (pc + 0), *(GLint *) (pc + 4), 78 *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12), 79 *(GLenum *) (pc + 16), *(GLenum *) (pc + 20), answer); 80 81 if (__glXErrorOccured()) { 82 __GLX_BEGIN_REPLY(0); 83 __GLX_SEND_HEADER(); 84 } 85 else { 86 __GLX_BEGIN_REPLY(compsize); 87 __GLX_SEND_HEADER(); 88 __GLX_SEND_VOID_ARRAY(compsize); 89 } 90 return Success; 91} 92 93int 94__glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc) 95{ 96 GLint level, compsize; 97 GLenum format, type, target; 98 GLboolean swapBytes; 99 __GLXcontext *cx; 100 ClientPtr client = cl->client; 101 int error; 102 char *answer, answerBuffer[200]; 103 GLint width = 0, height = 0, depth = 1; 104 xGLXSingleReply reply = { 0, }; 105 106 REQUEST_FIXED_SIZE(xGLXSingleReq, 20); 107 108 REQUEST_FIXED_SIZE(xGLXSingleReq, 20); 109 110 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 111 if (!cx) { 112 return error; 113 } 114 115 pc += __GLX_SINGLE_HDR_SIZE; 116 level = *(GLint *) (pc + 4); 117 format = *(GLenum *) (pc + 8); 118 type = *(GLenum *) (pc + 12); 119 target = *(GLenum *) (pc + 0); 120 swapBytes = *(GLboolean *) (pc + 16); 121 122 glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); 123 glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); 124 if (target == GL_TEXTURE_3D) { 125 glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth); 126 } 127 /* 128 * The three queries above might fail if we're in a state where queries 129 * are illegal, but then width, height, and depth would still be zero anyway. 130 */ 131 compsize = 132 __glGetTexImage_size(target, level, format, type, width, height, depth); 133 if (compsize < 0) 134 return BadLength; 135 136 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 137 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); 138 __glXClearErrorOccured(); 139 glGetTexImage(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), 140 *(GLenum *) (pc + 8), *(GLenum *) (pc + 12), answer); 141 142 if (__glXErrorOccured()) { 143 __GLX_BEGIN_REPLY(0); 144 __GLX_SEND_HEADER(); 145 } 146 else { 147 __GLX_BEGIN_REPLY(compsize); 148 ((xGLXGetTexImageReply *) &reply)->width = width; 149 ((xGLXGetTexImageReply *) &reply)->height = height; 150 ((xGLXGetTexImageReply *) &reply)->depth = depth; 151 __GLX_SEND_HEADER(); 152 __GLX_SEND_VOID_ARRAY(compsize); 153 } 154 return Success; 155} 156 157int 158__glXDisp_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc) 159{ 160 GLboolean lsbFirst; 161 __GLXcontext *cx; 162 ClientPtr client = cl->client; 163 int error; 164 GLubyte answerBuffer[200]; 165 char *answer; 166 xGLXSingleReply reply = { 0, }; 167 168 REQUEST_FIXED_SIZE(xGLXSingleReq, 4); 169 170 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); 171 if (!cx) { 172 return error; 173 } 174 175 pc += __GLX_SINGLE_HDR_SIZE; 176 lsbFirst = *(GLboolean *) (pc + 0); 177 178 glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); 179 __GLX_GET_ANSWER_BUFFER(answer, cl, 128, 1); 180 181 __glXClearErrorOccured(); 182 glGetPolygonStipple((GLubyte *) answer); 183 184 if (__glXErrorOccured()) { 185 __GLX_BEGIN_REPLY(0); 186 __GLX_SEND_HEADER(); 187 } 188 else { 189 __GLX_BEGIN_REPLY(128); 190 __GLX_SEND_HEADER(); 191 __GLX_SEND_BYTE_ARRAY(128); 192 } 193 return Success; 194} 195 196static int 197GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) 198{ 199 GLint compsize, compsize2; 200 GLenum format, type, target; 201 GLboolean swapBytes; 202 __GLXcontext *cx; 203 ClientPtr client = cl->client; 204 int error; 205 char *answer, answerBuffer[200]; 206 GLint width = 0, height = 0; 207 xGLXSingleReply reply = { 0, }; 208 209 cx = __glXForceCurrent(cl, tag, &error); 210 if (!cx) { 211 return error; 212 } 213 214 format = *(GLenum *) (pc + 4); 215 type = *(GLenum *) (pc + 8); 216 target = *(GLenum *) (pc + 0); 217 swapBytes = *(GLboolean *) (pc + 12); 218 219 /* target must be SEPARABLE_2D, however I guess we can let the GL 220 barf on this one.... */ 221 222 glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); 223 glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); 224 /* 225 * The two queries above might fail if we're in a state where queries 226 * are illegal, but then width and height would still be zero anyway. 227 */ 228 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); 229 compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); 230 231 if ((compsize = safe_pad(compsize)) < 0) 232 return BadLength; 233 if ((compsize2 = safe_pad(compsize2)) < 0) 234 return BadLength; 235 236 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 237 __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); 238 __glXClearErrorOccured(); 239 glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), 240 *(GLenum *) (pc + 8), answer, answer + compsize, NULL); 241 242 if (__glXErrorOccured()) { 243 __GLX_BEGIN_REPLY(0); 244 __GLX_SEND_HEADER(); 245 } 246 else { 247 __GLX_BEGIN_REPLY(compsize + compsize2); 248 ((xGLXGetSeparableFilterReply *) &reply)->width = width; 249 ((xGLXGetSeparableFilterReply *) &reply)->height = height; 250 __GLX_SEND_HEADER(); 251 __GLX_SEND_VOID_ARRAY(compsize + compsize2); 252 } 253 254 return Success; 255} 256 257int 258__glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) 259{ 260 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); 261 ClientPtr client = cl->client; 262 REQUEST_FIXED_SIZE(xGLXSingleReq, 16); 263 return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); 264} 265 266int 267__glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) 268{ 269 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); 270 ClientPtr client = cl->client; 271 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); 272 return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); 273} 274 275static int 276GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) 277{ 278 GLint compsize; 279 GLenum format, type, target; 280 GLboolean swapBytes; 281 __GLXcontext *cx; 282 ClientPtr client = cl->client; 283 int error; 284 char *answer, answerBuffer[200]; 285 GLint width = 0, height = 0; 286 xGLXSingleReply reply = { 0, }; 287 288 cx = __glXForceCurrent(cl, tag, &error); 289 if (!cx) { 290 return error; 291 } 292 293 format = *(GLenum *) (pc + 4); 294 type = *(GLenum *) (pc + 8); 295 target = *(GLenum *) (pc + 0); 296 swapBytes = *(GLboolean *) (pc + 12); 297 298 glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); 299 if (target == GL_CONVOLUTION_1D) { 300 height = 1; 301 } 302 else { 303 glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); 304 } 305 /* 306 * The two queries above might fail if we're in a state where queries 307 * are illegal, but then width and height would still be zero anyway. 308 */ 309 compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); 310 if (compsize < 0) 311 return BadLength; 312 313 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 314 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); 315 __glXClearErrorOccured(); 316 glGetConvolutionFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), 317 *(GLenum *) (pc + 8), answer); 318 319 if (__glXErrorOccured()) { 320 __GLX_BEGIN_REPLY(0); 321 __GLX_SEND_HEADER(); 322 } 323 else { 324 __GLX_BEGIN_REPLY(compsize); 325 ((xGLXGetConvolutionFilterReply *) &reply)->width = width; 326 ((xGLXGetConvolutionFilterReply *) &reply)->height = height; 327 __GLX_SEND_HEADER(); 328 __GLX_SEND_VOID_ARRAY(compsize); 329 } 330 331 return Success; 332} 333 334int 335__glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) 336{ 337 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); 338 ClientPtr client = cl->client; 339 REQUEST_FIXED_SIZE(xGLXSingleReq, 16); 340 return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); 341} 342 343int 344__glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) 345{ 346 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); 347 ClientPtr client = cl->client; 348 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); 349 return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); 350} 351 352static int 353GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) 354{ 355 GLint compsize; 356 GLenum format, type, target; 357 GLboolean swapBytes, reset; 358 __GLXcontext *cx; 359 ClientPtr client = cl->client; 360 int error; 361 char *answer, answerBuffer[200]; 362 GLint width = 0; 363 xGLXSingleReply reply = { 0, }; 364 365 cx = __glXForceCurrent(cl, tag, &error); 366 if (!cx) { 367 return error; 368 } 369 370 format = *(GLenum *) (pc + 4); 371 type = *(GLenum *) (pc + 8); 372 target = *(GLenum *) (pc + 0); 373 swapBytes = *(GLboolean *) (pc + 12); 374 reset = *(GLboolean *) (pc + 13); 375 376 glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width); 377 /* 378 * The one query above might fail if we're in a state where queries 379 * are illegal, but then width would still be zero anyway. 380 */ 381 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); 382 if (compsize < 0) 383 return BadLength; 384 385 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 386 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); 387 __glXClearErrorOccured(); 388 glGetHistogram(target, reset, format, type, answer); 389 390 if (__glXErrorOccured()) { 391 __GLX_BEGIN_REPLY(0); 392 __GLX_SEND_HEADER(); 393 } 394 else { 395 __GLX_BEGIN_REPLY(compsize); 396 ((xGLXGetHistogramReply *) &reply)->width = width; 397 __GLX_SEND_HEADER(); 398 __GLX_SEND_VOID_ARRAY(compsize); 399 } 400 401 return Success; 402} 403 404int 405__glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc) 406{ 407 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); 408 ClientPtr client = cl->client; 409 REQUEST_FIXED_SIZE(xGLXSingleReq, 16); 410 return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); 411} 412 413int 414__glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) 415{ 416 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); 417 ClientPtr client = cl->client; 418 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); 419 return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); 420} 421 422static int 423GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) 424{ 425 GLint compsize; 426 GLenum format, type, target; 427 GLboolean swapBytes, reset; 428 __GLXcontext *cx; 429 ClientPtr client = cl->client; 430 int error; 431 char *answer, answerBuffer[200]; 432 xGLXSingleReply reply = { 0, }; 433 434 cx = __glXForceCurrent(cl, tag, &error); 435 if (!cx) { 436 return error; 437 } 438 439 format = *(GLenum *) (pc + 4); 440 type = *(GLenum *) (pc + 8); 441 target = *(GLenum *) (pc + 0); 442 swapBytes = *(GLboolean *) (pc + 12); 443 reset = *(GLboolean *) (pc + 13); 444 445 compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); 446 if (compsize < 0) 447 return BadLength; 448 449 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 450 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); 451 __glXClearErrorOccured(); 452 glGetMinmax(target, reset, format, type, answer); 453 454 if (__glXErrorOccured()) { 455 __GLX_BEGIN_REPLY(0); 456 __GLX_SEND_HEADER(); 457 } 458 else { 459 __GLX_BEGIN_REPLY(compsize); 460 __GLX_SEND_HEADER(); 461 __GLX_SEND_VOID_ARRAY(compsize); 462 } 463 464 return Success; 465} 466 467int 468__glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc) 469{ 470 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); 471 ClientPtr client = cl->client; 472 REQUEST_FIXED_SIZE(xGLXSingleReq, 16); 473 return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); 474} 475 476int 477__glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) 478{ 479 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); 480 ClientPtr client = cl->client; 481 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); 482 return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); 483} 484 485static int 486GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) 487{ 488 GLint compsize; 489 GLenum format, type, target; 490 GLboolean swapBytes; 491 __GLXcontext *cx; 492 ClientPtr client = cl->client; 493 int error; 494 char *answer, answerBuffer[200]; 495 GLint width = 0; 496 xGLXSingleReply reply = { 0, }; 497 498 cx = __glXForceCurrent(cl, tag, &error); 499 if (!cx) { 500 return error; 501 } 502 503 target = *(GLenum *) (pc + 0); 504 format = *(GLenum *) (pc + 4); 505 type = *(GLenum *) (pc + 8); 506 swapBytes = *(GLboolean *) (pc + 12); 507 508 glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width); 509 /* 510 * The one query above might fail if we're in a state where queries 511 * are illegal, but then width would still be zero anyway. 512 */ 513 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); 514 if (compsize < 0) 515 return BadLength; 516 517 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); 518 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); 519 __glXClearErrorOccured(); 520 glGetColorTable(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), 521 *(GLenum *) (pc + 8), answer); 522 523 if (__glXErrorOccured()) { 524 __GLX_BEGIN_REPLY(0); 525 __GLX_SEND_HEADER(); 526 } 527 else { 528 __GLX_BEGIN_REPLY(compsize); 529 ((xGLXGetColorTableReply *) &reply)->width = width; 530 __GLX_SEND_HEADER(); 531 __GLX_SEND_VOID_ARRAY(compsize); 532 } 533 534 return Success; 535} 536 537int 538__glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc) 539{ 540 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); 541 ClientPtr client = cl->client; 542 REQUEST_FIXED_SIZE(xGLXSingleReq, 16); 543 return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); 544} 545 546int 547__glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) 548{ 549 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); 550 ClientPtr client = cl->client; 551 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); 552 return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); 553} 554