ephyrhostglx.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 * a lots of the content of this file has been adapted from the mesa source 26 * code. 27 * Authors: 28 * Dodji Seketeli <dodji@openedhand.com> 29 */ 30#ifdef HAVE_CONFIG_H 31#include <kdrive-config.h> 32#endif 33 34/* 35 * including some server headers (like kdrive-config.h) 36 * might define the macro _XSERVER64 37 * on 64 bits machines. That macro must _NOT_ be defined for Xlib 38 * client code, otherwise bad things happen. 39 * So let's undef that macro if necessary. 40 */ 41#ifdef _XSERVER64 42#undef _XSERVER64 43#endif 44 45#include <X11/Xlibint.h> 46#include <GL/glx.h> 47#include <GL/internal/glcore.h> 48#include <GL/glxproto.h> 49#include <GL/glxint.h> 50#include "ephyrhostglx.h" 51#define _HAVE_XALLOC_DECLS 52#include "ephyrlog.h" 53#include "hostx.h" 54 55enum VisualConfRequestType { 56 EPHYR_GET_FB_CONFIG, 57 EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX, 58 EPHYR_GET_VISUAL_CONFIGS 59 60}; 61 62static Bool ephyrHostGLXGetVisualConfigsInternal 63 (enum VisualConfRequestType a_type, 64 int32_t a_screen, 65 int32_t *a_num_visuals, 66 int32_t *a_num_props, 67 int32_t *a_props_buf_size, 68 int32_t **a_props_buf); 69Bool 70ephyrHostGLXGetMajorOpcode (int *a_opcode) 71{ 72 Bool is_ok=FALSE ; 73 Display *dpy=hostx_get_display () ; 74 static int opcode ; 75 int first_event_return=0, first_error_return=0; 76 77 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; 78 EPHYR_LOG ("enter\n") ; 79 if (!opcode) { 80 if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode, 81 &first_event_return, &first_error_return)) { 82 EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ; 83 goto out ; 84 } 85 } 86 *a_opcode = opcode ; 87 is_ok = TRUE ; 88out: 89 EPHYR_LOG ("release\n") ; 90 return is_ok ; 91} 92 93Bool 94ephyrHostGLXQueryVersion (int *a_major, int *a_minor) 95{ 96 Bool is_ok = FALSE ; 97 Display *dpy = hostx_get_display () ; 98 int major_opcode=0; 99 xGLXQueryVersionReq *req=NULL; 100 xGLXQueryVersionReply reply; 101 102 EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ; 103 EPHYR_LOG ("enter\n") ; 104 105 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 106 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 107 goto out ; 108 } 109 EPHYR_LOG ("major opcode: %d\n", major_opcode) ; 110 111 /* Send the glXQueryVersion request */ 112 memset (&reply, 0, sizeof (reply)) ; 113 LockDisplay (dpy); 114 GetReq (GLXQueryVersion, req); 115 req->reqType = major_opcode; 116 req->glxCode = X_GLXQueryVersion; 117 req->majorVersion = 2; 118 req->minorVersion = 1; 119 _XReply(dpy, (xReply*) &reply, 0, False); 120 UnlockDisplay (dpy); 121 SyncHandle (); 122 123 *a_major = reply.majorVersion ; 124 *a_minor = reply.minorVersion ; 125 126 EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ; 127 128 is_ok = TRUE ; 129out: 130 EPHYR_LOG ("leave\n") ; 131 return is_ok ; 132} 133 134/** 135 * GLX protocol structure for the ficticious "GXLGenericGetString" request. 136 * 137 * This is a non-existant protocol packet. It just so happens that all of 138 * the real protocol packets used to request a string from the server have 139 * an identical binary layout. The only difference between them is the 140 * meaning of the \c for_whom field and the value of the \c glxCode. 141 * (this has been copied from the mesa source code) 142 */ 143typedef struct GLXGenericGetString { 144 CARD8 reqType; 145 CARD8 glxCode; 146 CARD16 length B16; 147 CARD32 for_whom B32; 148 CARD32 name B32; 149} xGLXGenericGetStringReq; 150 151/* These defines are only needed to make the GetReq macro happy. 152 */ 153#define sz_xGLXGenericGetStringReq 12 154#define X_GLXGenericGetString 0 155 156Bool 157ephyrHostGLXGetStringFromServer (int a_screen_number, 158 int a_string_name, 159 enum EphyrHostGLXGetStringOps a_op, 160 char **a_string) 161{ 162 Bool is_ok=FALSE ; 163 Display *dpy = hostx_get_display () ; 164 int default_screen = DefaultScreen (dpy); 165 xGLXGenericGetStringReq *req=NULL; 166 xGLXSingleReply reply; 167 int length=0, numbytes=0, major_opcode=0, get_string_op=0; 168 169 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ; 170 171 EPHYR_LOG ("enter\n") ; 172 switch (a_op) { 173 case EPHYR_HOST_GLX_QueryServerString: 174 get_string_op = X_GLXQueryServerString; 175 break ; 176 case EPHYR_HOST_GLX_GetString: 177 get_string_op = X_GLsop_GetString; 178 EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n", 179 a_string_name, a_screen_number) ; 180 break ; 181 default: 182 EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ; 183 goto out ; 184 } 185 186 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 187 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 188 goto out ; 189 } 190 EPHYR_LOG ("major opcode: %d\n", major_opcode) ; 191 192 LockDisplay (dpy); 193 194 /* All of the GLX protocol requests for getting a string from the server 195 * look the same. The exact meaning of the a_for_whom field is usually 196 * either the screen number (for glXQueryServerString) or the context tag 197 * (for GLXSingle). 198 */ 199 GetReq (GLXGenericGetString, req); 200 req->reqType = major_opcode; 201 req->glxCode = get_string_op; 202 req->for_whom = default_screen; 203 req->name = a_string_name; 204 205 _XReply (dpy, (xReply *)&reply, 0, False); 206 207 length = reply.length * 4; 208 if (!length) { 209 numbytes = 0; 210 } else { 211 numbytes = reply.size; 212 } 213 EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ; 214 215 *a_string = (char *) Xmalloc (numbytes +1); 216 if (!a_string) { 217 EPHYR_LOG_ERROR ("allocation failed\n") ; 218 goto out; 219 } 220 221 memset (*a_string, 0, numbytes+1) ; 222 if (_XRead (dpy, *a_string, numbytes)) { 223 UnlockDisplay (dpy); 224 SyncHandle (); 225 EPHYR_LOG_ERROR ("read failed\n") ; 226 goto out ; 227 } 228 length -= numbytes; 229 _XEatData (dpy, length) ; 230 UnlockDisplay (dpy); 231 SyncHandle (); 232 EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n", 233 a_string_name, *a_string, numbytes) ; 234 235 is_ok = TRUE ; 236out: 237 EPHYR_LOG ("leave\n") ; 238 return is_ok ; 239} 240 241static Bool 242ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type, 243 int32_t a_screen, 244 int32_t *a_num_visuals, 245 int32_t *a_num_props, 246 int32_t *a_props_buf_size, 247 int32_t **a_props_buf) 248{ 249 Bool is_ok = FALSE ; 250 Display *dpy = hostx_get_display () ; 251 xGLXGetVisualConfigsReq *req; 252 xGLXGetFBConfigsReq *fb_req; 253 xGLXVendorPrivateWithReplyReq *vpreq; 254 xGLXGetFBConfigsSGIXReq *sgi_req; 255 xGLXGetVisualConfigsReply reply; 256 char *server_glx_version=NULL, 257 *server_glx_extensions=NULL ; 258 int j=0, 259 screens=0, 260 major_opcode=0, 261 num_props=0, 262 num_visuals=0, 263 props_buf_size=0, 264 props_per_visual_size=0; 265 int32_t *props_buf=NULL; 266 267 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; 268 269 screens = ScreenCount (dpy); 270 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 271 EPHYR_LOG_ERROR ("failed to get opcode\n") ; 272 goto out ; 273 } 274 275 LockDisplay(dpy); 276 switch (a_type) { 277 case EPHYR_GET_FB_CONFIG: 278 GetReq(GLXGetFBConfigs,fb_req); 279 fb_req->reqType = major_opcode; 280 fb_req->glxCode = X_GLXGetFBConfigs; 281 fb_req->screen = DefaultScreen (dpy); 282 break; 283 284 case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX: 285 GetReqExtra(GLXVendorPrivateWithReply, 286 sz_xGLXGetFBConfigsSGIXReq 287 - 288 sz_xGLXVendorPrivateWithReplyReq, 289 vpreq); 290 sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; 291 sgi_req->reqType = major_opcode; 292 sgi_req->glxCode = X_GLXVendorPrivateWithReply; 293 sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; 294 sgi_req->screen = DefaultScreen (dpy); 295 break; 296 297 case EPHYR_GET_VISUAL_CONFIGS: 298 GetReq(GLXGetVisualConfigs,req); 299 req->reqType = major_opcode; 300 req->glxCode = X_GLXGetVisualConfigs; 301 req->screen = DefaultScreen (dpy); 302 break; 303 } 304 305 if (!_XReply(dpy, (xReply*) &reply, 0, False)) { 306 EPHYR_LOG_ERROR ("unknown error\n") ; 307 UnlockDisplay(dpy); 308 goto out ; 309 } 310 if (!reply.numVisuals) { 311 EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ; 312 UnlockDisplay(dpy); 313 goto out ; 314 } 315 num_visuals = reply.numVisuals ; 316 317 /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for 318 * FIXME: FBconfigs? 319 */ 320 /* Check number of properties */ 321 num_props = reply.numProps; 322 if ((num_props < __GLX_MIN_CONFIG_PROPS) || 323 (num_props > __GLX_MAX_CONFIG_PROPS)) { 324 /* Huh? Not in protocol defined limits. Punt */ 325 EPHYR_LOG_ERROR ("got a bad reply to request\n") ; 326 UnlockDisplay(dpy); 327 goto out ; 328 } 329 330 if (a_type != EPHYR_GET_VISUAL_CONFIGS) { 331 num_props *= 2; 332 } 333 props_per_visual_size = num_props * __GLX_SIZE_INT32; 334 props_buf_size = props_per_visual_size * reply.numVisuals; 335 props_buf = malloc (props_buf_size) ; 336 for (j = 0; j < reply.numVisuals; j++) { 337 if (_XRead (dpy, 338 &((char*)props_buf)[j*props_per_visual_size], 339 props_per_visual_size) != Success) { 340 EPHYR_LOG_ERROR ("read failed\n") ; 341 } 342 } 343 UnlockDisplay(dpy); 344 345 *a_num_visuals = num_visuals ; 346 *a_num_props = reply.numProps ; 347 *a_props_buf_size = props_buf_size ; 348 *a_props_buf = props_buf ; 349 is_ok = TRUE ; 350 351out: 352 if (server_glx_version) { 353 XFree (server_glx_version) ; 354 server_glx_version = NULL ; 355 } 356 if (server_glx_extensions) { 357 XFree (server_glx_extensions) ; 358 server_glx_extensions = NULL ; 359 } 360 SyncHandle () ; 361 return is_ok; 362} 363 364Bool 365ephyrHostGLXGetVisualConfigs (int32_t a_screen, 366 int32_t *a_num_visuals, 367 int32_t *a_num_props, 368 int32_t *a_props_buf_size, 369 int32_t **a_props_buf) 370{ 371 Bool is_ok = FALSE; 372 373 EPHYR_LOG ("enter\n") ; 374 is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS, 375 a_screen, 376 a_num_visuals, 377 a_num_props, 378 a_props_buf_size, 379 a_props_buf) ; 380 381 EPHYR_LOG ("leave:%d\n", is_ok) ; 382 return is_ok; 383} 384 385Bool 386ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen, 387 int32_t *a_num_visuals, 388 int32_t *a_num_props, 389 int32_t *a_props_buf_size, 390 int32_t **a_props_buf) 391{ 392 Bool is_ok=FALSE ; 393 EPHYR_LOG ("enter\n") ; 394 is_ok = ephyrHostGLXGetVisualConfigsInternal 395 (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX, 396 a_screen, 397 a_num_visuals, 398 a_num_props, 399 a_props_buf_size, 400 a_props_buf) ; 401 EPHYR_LOG ("leave\n") ; 402 return is_ok ; 403} 404 405Bool 406ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor, 407 const char* a_extension_list) 408{ 409 Bool is_ok = FALSE ; 410 Display *dpy = hostx_get_display () ; 411 xGLXClientInfoReq *req; 412 int size; 413 int32_t major_opcode=0 ; 414 415 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ; 416 417 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 418 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 419 goto out ; 420 } 421 422 LockDisplay (dpy); 423 424 GetReq (GLXClientInfo,req); 425 req->reqType = major_opcode; 426 req->glxCode = X_GLXClientInfo; 427 req->major = a_major; 428 req->minor = a_minor; 429 430 size = strlen (a_extension_list) + 1; 431 req->length += bytes_to_int32(size); 432 req->numbytes = size; 433 Data (dpy, a_extension_list, size); 434 435 UnlockDisplay(dpy); 436 SyncHandle(); 437 438 is_ok=TRUE ; 439 440out: 441 return is_ok ; 442} 443 444Bool 445ephyrHostGLXCreateContext (int a_screen, 446 int a_visual_id, 447 int a_context_id, 448 int a_share_list_ctxt_id, 449 Bool a_direct) 450{ 451 Bool is_ok = FALSE; 452 Display *dpy = hostx_get_display (); 453 int major_opcode=0, remote_context_id=0; 454 xGLXCreateContextReq *req; 455 456 EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n", 457 a_screen, a_visual_id, a_context_id, a_direct) ; 458 459 if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) { 460 EPHYR_LOG_ERROR ("failed to peer the context id %d host X", 461 remote_context_id) ; 462 goto out ; 463 } 464 465 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 466 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 467 goto out ; 468 } 469 470 LockDisplay (dpy) ; 471 472 /* Send the glXCreateContext request */ 473 GetReq(GLXCreateContext,req); 474 req->reqType = major_opcode; 475 req->glxCode = X_GLXCreateContext; 476 req->context = remote_context_id; 477 req->visual = a_visual_id; 478 req->screen = DefaultScreen (dpy); 479 req->shareList = a_share_list_ctxt_id; 480 req->isDirect = a_direct; 481 482 UnlockDisplay (dpy); 483 SyncHandle (); 484 485 is_ok = TRUE ; 486 487out: 488 EPHYR_LOG ("leave\n") ; 489 return is_ok ; 490} 491 492Bool 493ephyrHostDestroyContext (int a_ctxt_id) 494{ 495 Bool is_ok=FALSE; 496 Display *dpy=hostx_get_display (); 497 int major_opcode=0, remote_ctxt_id=0 ; 498 xGLXDestroyContextReq *req=NULL; 499 500 EPHYR_LOG ("enter:%d\n", a_ctxt_id) ; 501 502 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 503 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 504 goto out ; 505 } 506 if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) { 507 EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ; 508 goto out ; 509 } 510 EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ; 511 512 LockDisplay (dpy); 513 GetReq (GLXDestroyContext,req); 514 req->reqType = major_opcode; 515 req->glxCode = X_GLXDestroyContext; 516 req->context = remote_ctxt_id; 517 UnlockDisplay (dpy); 518 SyncHandle (); 519 520 is_ok = TRUE ; 521 522out: 523 EPHYR_LOG ("leave\n") ; 524 return is_ok ; 525} 526 527Bool 528ephyrHostGLXMakeCurrent (int a_drawable, 529 int a_glx_ctxt_id, 530 int a_old_ctxt_tag, 531 int *a_ctxt_tag) 532{ 533 Bool is_ok=FALSE ; 534 Display *dpy = hostx_get_display () ; 535 int32_t major_opcode=0 ; 536 int remote_glx_ctxt_id=0 ; 537 xGLXMakeCurrentReq *req; 538 xGLXMakeCurrentReply reply; 539 540 EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ; 541 542 EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n", 543 a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ; 544 545 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 546 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 547 goto out ; 548 } 549 if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) { 550 EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ; 551 goto out ; 552 } 553 554 LockDisplay (dpy); 555 556 GetReq (GLXMakeCurrent,req); 557 req->reqType = major_opcode; 558 req->glxCode = X_GLXMakeCurrent; 559 req->drawable = a_drawable; 560 req->context = remote_glx_ctxt_id; 561 req->oldContextTag = a_old_ctxt_tag; 562 563 memset (&reply, 0, sizeof (reply)) ; 564 if (!_XReply (dpy, (xReply*)&reply, 0, False)) { 565 EPHYR_LOG_ERROR ("failed to get reply from host\n") ; 566 UnlockDisplay (dpy); 567 SyncHandle (); 568 goto out ; 569 } 570 UnlockDisplay (dpy); 571 SyncHandle (); 572 *a_ctxt_tag = reply.contextTag ; 573 EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ; 574 is_ok = TRUE ; 575 576out: 577 EPHYR_LOG ("leave\n") ; 578 return is_ok ; 579} 580 581#define X_GLXSingle 0 582 583#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \ 584 *((INT8 *) (pc + offset)) = a 585 586#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \ 587 *((INT16 *) (pc + offset)) = a 588 589#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \ 590 *((INT32 *) (pc + offset)) = a 591 592#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \ 593 *((FLOAT32 *) (pc + offset)) = a 594 595#define EPHYR_GLX_SINGLE_READ_XREPLY() \ 596 (void) _XReply(dpy, (xReply*) &reply, 0, False) 597 598#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \ 599 a = (cast) reply.retval 600 601#define EPHYR_GLX_SINGLE_GET_SIZE(a) \ 602 a = (GLint) reply.size 603 604#define EPHYR_GLX_SINGLE_GET_CHAR(p) \ 605 *p = *(GLbyte *)&reply.pad3; 606 607#define EPHYR_GLX_SINGLE_GET_SHORT(p) \ 608 *p = *(GLshort *)&reply.pad3; 609 610#define EPHYR_GLX_SINGLE_GET_LONG(p) \ 611 *p = *(GLint *)&reply.pad3; 612 613#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \ 614 *p = *(GLfloat *)&reply.pad3; 615 616Bool 617ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val) 618{ 619 Bool is_ok=FALSE; 620 Display *dpy = hostx_get_display () ; 621 int major_opcode=0, size=0; 622 xGLXSingleReq *req=NULL; 623 xGLXSingleReply reply; 624 unsigned char* pc=NULL ; 625 626 EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ; 627 628 EPHYR_LOG ("enter\n") ; 629 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 630 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 631 goto out ; 632 } 633 LockDisplay (dpy) ; 634 GetReqExtra (GLXSingle, 4, req) ; 635 req->reqType = major_opcode ; 636 req->glxCode = X_GLsop_GetIntegerv ; 637 req->contextTag = a_current_context_tag; 638 pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ; 639 EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ; 640 EPHYR_GLX_SINGLE_READ_XREPLY () ; 641 EPHYR_GLX_SINGLE_GET_SIZE (size) ; 642 if (!size) { 643 UnlockDisplay (dpy) ; 644 SyncHandle () ; 645 EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ; 646 goto out ; 647 } 648 EPHYR_GLX_SINGLE_GET_LONG (a_val) ; 649 UnlockDisplay (dpy) ; 650 SyncHandle () ; 651 is_ok = TRUE ; 652 653out: 654 EPHYR_LOG ("leave\n") ; 655 return is_ok ; 656} 657 658Bool 659ephyrHostIsContextDirect (int a_ctxt_id, 660 int *a_is_direct) 661{ 662 Bool is_ok=FALSE; 663 Display *dpy = hostx_get_display () ; 664 xGLXIsDirectReq *req=NULL; 665 xGLXIsDirectReply reply; 666 int major_opcode=0, remote_glx_ctxt_id=0; 667 668 EPHYR_LOG ("enter\n") ; 669 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 670 EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 671 goto out ; 672 } 673 if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) { 674 EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ; 675 goto out ; 676 } 677 memset (&reply, 0, sizeof (reply)) ; 678 679 /* Send the glXIsDirect request */ 680 LockDisplay (dpy); 681 GetReq (GLXIsDirect,req); 682 req->reqType = major_opcode; 683 req->glxCode = X_GLXIsDirect; 684 req->context = remote_glx_ctxt_id; 685 if (!_XReply (dpy, (xReply*) &reply, 0, False)) { 686 EPHYR_LOG_ERROR ("fail in reading reply from host\n") ; 687 UnlockDisplay (dpy); 688 SyncHandle (); 689 goto out ; 690 } 691 UnlockDisplay (dpy); 692 SyncHandle (); 693 *a_is_direct = reply.isDirect ; 694 is_ok = TRUE ; 695 696out: 697 EPHYR_LOG ("leave\n") ; 698 return is_ok ; 699} 700