ephyrglxext.c revision 706f2543
1/* 2 * Xephyr - A kdrive X server thats runs in a host X window. 3 * Authored by Matthew Allum <mallum@openedhand.com> 4 * 5 * Copyright © 2007 OpenedHand Ltd 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and its 8 * documentation for any purpose is hereby granted without fee, provided that 9 * the above copyright notice appear in all copies and that both that 10 * copyright notice and this permission notice appear in supporting 11 * documentation, and that the name of OpenedHand Ltd not be used in 12 * advertising or publicity pertaining to distribution of the software without 13 * specific, written prior permission. OpenedHand Ltd makes no 14 * representations about the suitability of this software for any purpose. It 15 * is provided "as is" without express or implied warranty. 16 * 17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23 * PERFORMANCE OF THIS SOFTWARE. 24 * 25 * Authors: 26 * Dodji Seketeli <dodji@openedhand.com> 27 */ 28#ifdef HAVE_CONFIG_H 29#include <kdrive-config.h> 30#endif 31 32#include "extnsionst.h" 33#include "ephyrglxext.h" 34#include "ephyrhostglx.h" 35#define _HAVE_XALLOC_DECLS 36#include "ephyrlog.h" 37#include <GL/glxproto.h> 38#include "glx/glxserver.h" 39#include "glx/indirect_table.h" 40#include "glx/indirect_util.h" 41#include "glx/unpack.h" 42#include "hostx.h" 43 44 45#ifndef TRUE 46#define TRUE 1 47#endif 48 49#ifndef FALSE 50#define FALSE 0 51#endif 52 53 54int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ; 55int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ; 56int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ; 57int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ; 58int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ; 59int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ; 60int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ; 61int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ; 62int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc); 63int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc); 64int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc); 65int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc); 66int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ; 67int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 68int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ; 69int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 70int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ; 71int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 72int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ; 73int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 74int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ; 75int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 76 77Bool 78ephyrHijackGLXExtension (void) 79{ 80 const void *(*dispatch_functions)[2]; 81 82 if (!hostx_has_glx ()) { 83 EPHYR_LOG ("host X does not have GLX\n") ; 84 return FALSE ; 85 } 86 EPHYR_LOG ("host X does have GLX\n") ; 87 88 if (!Single_dispatch_info.dispatch_functions) { 89 EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ; 90 return FALSE ; 91 } 92 /* 93 * hijack some single entry point dispatch functions 94 */ 95 dispatch_functions = Single_dispatch_info.dispatch_functions ; 96 EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ; 97 98 dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ; 99 dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ; 100 101 dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ; 102 dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ; 103 dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ; 104 dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ; 105 106 dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ; 107 dispatch_functions[X_GLXQueryServerString][1] = 108 ephyrGLXQueryServerStringSwap ; 109 110 dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ; 111 dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ; 112 113 dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ; 114 dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ; 115 116 dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ; 117 dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ; 118 119 dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ; 120 dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ; 121 122 dispatch_functions[73][0] = ephyrGLXGetString ; 123 dispatch_functions[73][1] = ephyrGLXGetStringSwap ; 124 125 dispatch_functions[61][0] = ephyrGLXGetIntegerv ; 126 dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ; 127 128 /* 129 * hijack some vendor priv entry point dispatch functions 130 */ 131 dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ; 132 dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX; 133 dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap; 134 EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ; 135 136 return TRUE ; 137} 138 139/********************* 140 * implementation of 141 * hijacked GLX entry 142 * points 143 ********************/ 144 145int 146ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc) 147{ 148 ClientPtr client = a_cl->client; 149 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc; 150 xGLXQueryVersionReply reply; 151 int major, minor; 152 int res = BadImplementation ; 153 154 EPHYR_LOG ("enter\n") ; 155 156 major = req->majorVersion ; 157 minor = req->minorVersion ; 158 159 if (!ephyrHostGLXQueryVersion (&major, &minor)) { 160 EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ; 161 goto out ; 162 } 163 EPHYR_LOG ("major:%d, minor:%d\n", 164 major, minor); 165 reply.majorVersion = major ; 166 reply.minorVersion = minor ; 167 reply.length = 0 ; 168 reply.type = X_Reply ; 169 reply.sequenceNumber = client->sequence ; 170 171 if (client->swapped) { 172 __glXSwapQueryVersionReply(client, &reply); 173 } else { 174 WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); 175 } 176 177 res = Success ; 178out: 179 EPHYR_LOG ("leave\n") ; 180 return res; 181} 182 183int 184ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc) 185{ 186 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc; 187 __GLX_DECLARE_SWAP_VARIABLES; 188 189 __GLX_SWAP_SHORT (&req->length); 190 __GLX_SWAP_INT (&req->majorVersion); 191 __GLX_SWAP_INT (&req->minorVersion); 192 return ephyrGLXQueryVersion (a_cl, a_pc) ; 193} 194 195static int 196ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl, 197 GLbyte *a_pc, 198 Bool a_do_swap) 199{ 200 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc; 201 ClientPtr client = a_cl->client; 202 xGLXGetVisualConfigsReply reply; 203 int32_t *props_buf=NULL, num_visuals=0, 204 num_props=0, res=BadImplementation, i=0, 205 props_per_visual_size=0, 206 props_buf_size=0; 207 __GLX_DECLARE_SWAP_VARIABLES; 208 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 209 210 EPHYR_LOG ("enter\n") ; 211 212 if (!ephyrHostGLXGetVisualConfigs (req->screen, 213 &num_visuals, 214 &num_props, 215 &props_buf_size, 216 &props_buf)) { 217 EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ; 218 goto out ; 219 } 220 EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ; 221 222 reply.numVisuals = num_visuals; 223 reply.numProps = num_props; 224 reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2; 225 reply.type = X_Reply; 226 reply.sequenceNumber = client->sequence; 227 228 if (a_do_swap) { 229 __GLX_SWAP_SHORT(&reply.sequenceNumber); 230 __GLX_SWAP_INT(&reply.length); 231 __GLX_SWAP_INT(&reply.numVisuals); 232 __GLX_SWAP_INT(&reply.numProps); 233 __GLX_SWAP_INT_ARRAY (props_buf, num_props) ; 234 } 235 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply); 236 props_per_visual_size = props_buf_size/num_visuals ; 237 for (i=0; i < num_visuals; i++) { 238 WriteToClient (client, 239 props_per_visual_size, 240 (char*)props_buf +i*props_per_visual_size); 241 } 242 res = Success ; 243 244out: 245 EPHYR_LOG ("leave\n") ; 246 free(props_buf) ; 247 props_buf = NULL ; 248 249 return res ; 250} 251 252static int 253ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl, 254 GLbyte *a_pc, 255 Bool a_do_swap) 256{ 257 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc; 258 ClientPtr client = a_cl->client; 259 xGLXGetVisualConfigsReply reply; 260 int32_t *props_buf=NULL, num_visuals=0, 261 num_props=0, res=BadImplementation, i=0, 262 props_per_visual_size=0, 263 props_buf_size=0; 264 __GLX_DECLARE_SWAP_VARIABLES; 265 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 266 267 EPHYR_LOG ("enter\n") ; 268 269 if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen, 270 &num_visuals, 271 &num_props, 272 &props_buf_size, 273 &props_buf)) { 274 EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ; 275 goto out ; 276 } 277 EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ; 278 279 reply.numVisuals = num_visuals; 280 reply.numProps = num_props; 281 reply.length = props_buf_size >> 2; 282 reply.type = X_Reply; 283 reply.sequenceNumber = client->sequence; 284 285 if (a_do_swap) { 286 __GLX_SWAP_SHORT(&reply.sequenceNumber); 287 __GLX_SWAP_INT(&reply.length); 288 __GLX_SWAP_INT(&reply.numVisuals); 289 __GLX_SWAP_INT(&reply.numProps); 290 __GLX_SWAP_INT_ARRAY (props_buf, num_props) ; 291 } 292 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply); 293 props_per_visual_size = props_buf_size/num_visuals ; 294 for (i=0; i < num_visuals; i++) { 295 WriteToClient (client, 296 props_per_visual_size, 297 &((char*)props_buf)[i*props_per_visual_size]); 298 } 299 res = Success ; 300 301out: 302 EPHYR_LOG ("leave\n") ; 303 free(props_buf) ; 304 props_buf = NULL ; 305 306 return res ; 307} 308 309int 310ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc) 311{ 312 return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ; 313} 314 315int 316ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc) 317{ 318 return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ; 319} 320 321 322int 323ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc) 324{ 325 int res=BadImplementation ; 326 xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc; 327 328 EPHYR_LOG ("enter\n") ; 329 if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) { 330 EPHYR_LOG_ERROR ("failed to send client info to host\n") ; 331 goto out ; 332 } 333 res = Success ; 334 335out: 336 EPHYR_LOG ("leave\n") ; 337 return res ; 338} 339 340int 341ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc) 342{ 343 xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc; 344 __GLX_DECLARE_SWAP_VARIABLES; 345 346 __GLX_SWAP_SHORT (&req->length); 347 __GLX_SWAP_INT (&req->major); 348 __GLX_SWAP_INT (&req->minor); 349 __GLX_SWAP_INT (&req->numbytes); 350 351 return ephyrGLXClientInfo (a_cl, a_pc) ; 352} 353 354int 355ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) 356{ 357 int res = BadImplementation ; 358 ClientPtr client = a_cl->client; 359 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc; 360 xGLXQueryServerStringReply reply; 361 char *server_string=NULL, *buf=NULL; 362 int length=0 ; 363 364 EPHYR_LOG ("enter\n") ; 365 if (!ephyrHostGLXGetStringFromServer (req->screen, 366 req->name, 367 EPHYR_HOST_GLX_QueryServerString, 368 &server_string)) { 369 EPHYR_LOG_ERROR ("failed to query string from host\n") ; 370 goto out ; 371 } 372 EPHYR_LOG ("string: %s\n", server_string) ; 373 length= strlen (server_string) + 1; 374 reply.type = X_Reply ; 375 reply.sequenceNumber = client->sequence ; 376 reply.length = __GLX_PAD (length) >> 2 ; 377 reply.n = length ; 378 buf = calloc(reply.length << 2, 1); 379 if (!buf) { 380 EPHYR_LOG_ERROR ("failed to allocate string\n;"); 381 return BadAlloc; 382 } 383 memcpy (buf, server_string, length); 384 385 WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply); 386 WriteToClient(client, (int)(reply.length << 2), server_string); 387 388 res = Success ; 389 390out: 391 EPHYR_LOG ("leave\n") ; 392 free(server_string) ; 393 server_string = NULL; 394 395 free(buf); 396 buf = NULL; 397 398 return res ; 399} 400 401int 402ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) 403{ 404 EPHYR_LOG_ERROR ("not yet implemented\n") ; 405 return BadImplementation ; 406} 407 408 409int 410ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc) 411{ 412 return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ; 413} 414 415int 416ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc) 417{ 418 return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ; 419} 420 421static int 422ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap) 423{ 424 int res=BadImplementation; 425 EphyrHostWindowAttributes host_w_attrs ; 426 __GLX_DECLARE_SWAP_VARIABLES; 427 428 EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ; 429 EPHYR_LOG ("enter\n") ; 430 431 if (a_do_swap) { 432 __GLX_SWAP_SHORT(&a_req->length); 433 __GLX_SWAP_INT(&a_req->context); 434 __GLX_SWAP_INT(&a_req->visual); 435 __GLX_SWAP_INT(&a_req->screen); 436 __GLX_SWAP_INT(&a_req->shareList); 437 } 438 439 EPHYR_LOG ("context creation requested. localid:%d, " 440 "screen:%d, visual:%d, direct:%d\n", 441 (int)a_req->context, (int)a_req->screen, 442 (int)a_req->visual, (int)a_req->isDirect) ; 443 444 memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ; 445 if (!hostx_get_window_attributes (hostx_get_window (a_req->screen), 446 &host_w_attrs)) { 447 EPHYR_LOG_ERROR ("failed to get host window attrs\n") ; 448 goto out ; 449 } 450 451 EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ; 452 453 if (!ephyrHostGLXCreateContext (a_req->screen, 454 host_w_attrs.visualid, 455 a_req->context, 456 a_req->shareList, 457 a_req->isDirect)) { 458 EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ; 459 goto out ; 460 } 461 res = Success; 462out: 463 EPHYR_LOG ("leave\n") ; 464 return res ; 465} 466 467int 468ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc) 469{ 470 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; 471 472 return ephyrGLXCreateContextReal (req, FALSE) ; 473} 474 475int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc) 476{ 477 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; 478 return ephyrGLXCreateContextReal (req, TRUE) ; 479} 480 481static int 482ephyrGLXDestroyContextReal (__GLXclientState *a_cl, 483 GLbyte *a_pc, 484 Bool a_do_swap) 485{ 486 int res=BadImplementation; 487 ClientPtr client = a_cl->client; 488 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc; 489 490 EPHYR_LOG ("enter. id:%d\n", (int)req->context) ; 491 if (!ephyrHostDestroyContext (req->context)) { 492 EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ; 493 client->errorValue = req->context ; 494 goto out ; 495 } 496 res = Success ; 497 498out: 499 EPHYR_LOG ("leave\n") ; 500 return res ; 501} 502 503int 504ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) 505{ 506 return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ; 507} 508 509int 510ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) 511{ 512 return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ; 513} 514 515static int 516ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 517{ 518 int res=BadImplementation; 519 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc; 520 xGLXMakeCurrentReply reply ; 521 DrawablePtr drawable=NULL; 522 int rc=0; 523 524 EPHYR_LOG ("enter\n") ; 525 rc = dixLookupDrawable (&drawable, 526 req->drawable, 527 a_cl->client, 528 0, 529 DixReadAccess); 530 EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ; 531 EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ; 532 EPHYR_LOG ("screen nummber requested:%d\n", 533 drawable->pScreen->myNum) ; 534 535 memset (&reply, 0, sizeof (reply)) ; 536 if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum), 537 req->context, 538 req->oldContextTag, 539 (int*)&reply.contextTag)) { 540 EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ; 541 goto out; 542 } 543 reply.length = 0; 544 reply.type = X_Reply; 545 reply.sequenceNumber = a_cl->client->sequence; 546 if (a_do_swap) { 547 __GLX_DECLARE_SWAP_VARIABLES; 548 __GLX_SWAP_SHORT(&reply.sequenceNumber); 549 __GLX_SWAP_INT(&reply.length); 550 __GLX_SWAP_INT(&reply.contextTag); 551 } 552 WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply); 553 554 res = Success ; 555out: 556 EPHYR_LOG ("leave\n") ; 557 return res ; 558} 559 560int 561ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) 562{ 563 return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ; 564} 565 566int 567ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) 568{ 569 return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ; 570} 571 572static int 573ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 574{ 575 ClientPtr client=NULL ; 576 int context_tag=0, name=0, res=BadImplementation, length=0 ; 577 char *string=NULL; 578 __GLX_DECLARE_SWAP_VARIABLES; 579 580 EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ; 581 582 EPHYR_LOG ("enter\n") ; 583 584 client = a_cl->client ; 585 586 if (a_do_swap) { 587 __GLX_SWAP_INT (a_pc + 4); 588 __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE); 589 } 590 context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ; 591 a_pc += __GLX_SINGLE_HDR_SIZE; 592 name = *(GLenum*)(a_pc + 0); 593 EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ; 594 if (!ephyrHostGLXGetStringFromServer (context_tag, 595 name, 596 EPHYR_HOST_GLX_GetString, 597 &string)) { 598 EPHYR_LOG_ERROR ("failed to get string from server\n") ; 599 goto out ; 600 } 601 if (string) { 602 length = strlen (string) + 1; 603 EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ; 604 } else { 605 EPHYR_LOG ("got string: string (null)\n") ; 606 } 607 __GLX_BEGIN_REPLY (length); 608 __GLX_PUT_SIZE (length); 609 __GLX_SEND_HEADER (); 610 if (a_do_swap) { 611 __GLX_SWAP_REPLY_SIZE (); 612 __GLX_SWAP_REPLY_HEADER (); 613 } 614 WriteToClient (client, length, (char *)string); 615 616 res = Success ; 617out: 618 EPHYR_LOG ("leave\n") ; 619 return res ; 620} 621 622int 623ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) 624{ 625 return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ; 626} 627 628int 629ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) 630{ 631 return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ; 632} 633 634static int 635ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 636{ 637 int res=BadImplementation; 638 xGLXSingleReq * const req = (xGLXSingleReq *) a_pc; 639 GLenum int_name ; 640 int value=0 ; 641 GLint answer_buf_room[200]; 642 GLint *buf=NULL ; 643 644 EPHYR_LOG ("enter\n") ; 645 646 a_pc += __GLX_SINGLE_HDR_SIZE; 647 648 int_name = *(GLenum*) (a_pc+0) ; 649 if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) { 650 EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ; 651 goto out ; 652 } 653 buf = __glXGetAnswerBuffer (a_cl, sizeof (value), 654 answer_buf_room, 655 sizeof (answer_buf_room), 656 4) ; 657 658 if (!buf) { 659 EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ; 660 res = BadAlloc ; 661 goto out ; 662 } 663 __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ; 664 res = Success ; 665 666out: 667 EPHYR_LOG ("leave\n") ; 668 return res ; 669} 670 671int 672ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) 673{ 674 return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ; 675} 676 677int 678ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) 679{ 680 return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ; 681} 682 683static int 684ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 685{ 686 int res=BadImplementation; 687 ClientPtr client = a_cl->client; 688 xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc; 689 xGLXIsDirectReply reply; 690 int is_direct=0 ; 691 692 EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ; 693 694 EPHYR_LOG ("enter\n") ; 695 696 memset (&reply, 0, sizeof (reply)) ; 697 if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) { 698 EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ; 699 goto out ; 700 } 701 reply.isDirect = is_direct ; 702 reply.length = 0; 703 reply.type = X_Reply; 704 reply.sequenceNumber = client->sequence; 705 WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); 706 res = Success ; 707 708out: 709 EPHYR_LOG ("leave\n") ; 710 return res ; 711} 712 713int 714ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) 715{ 716 return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ; 717} 718 719int 720ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) 721{ 722 return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ; 723} 724