1706f2543Smrg/* 2706f2543Smrg * Xephyr - A kdrive X server thats runs in a host X window. 3706f2543Smrg * Authored by Matthew Allum <mallum@openedhand.com> 4706f2543Smrg * 5706f2543Smrg * Copyright © 2007 OpenedHand Ltd 6706f2543Smrg * 7706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 8706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 9706f2543Smrg * the above copyright notice appear in all copies and that both that 10706f2543Smrg * copyright notice and this permission notice appear in supporting 11706f2543Smrg * documentation, and that the name of OpenedHand Ltd not be used in 12706f2543Smrg * advertising or publicity pertaining to distribution of the software without 13706f2543Smrg * specific, written prior permission. OpenedHand Ltd makes no 14706f2543Smrg * representations about the suitability of this software for any purpose. It 15706f2543Smrg * is provided "as is" without express or implied warranty. 16706f2543Smrg * 17706f2543Smrg * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19706f2543Smrg * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg * 25706f2543Smrg * a lots of the content of this file has been adapted from the mesa source 26706f2543Smrg * code. 27706f2543Smrg * Authors: 28706f2543Smrg * Dodji Seketeli <dodji@openedhand.com> 29706f2543Smrg */ 30706f2543Smrg#ifdef HAVE_CONFIG_H 31706f2543Smrg#include <kdrive-config.h> 32706f2543Smrg#endif 33706f2543Smrg 34706f2543Smrg/* 35706f2543Smrg * including some server headers (like kdrive-config.h) 36706f2543Smrg * might define the macro _XSERVER64 37706f2543Smrg * on 64 bits machines. That macro must _NOT_ be defined for Xlib 38706f2543Smrg * client code, otherwise bad things happen. 39706f2543Smrg * So let's undef that macro if necessary. 40706f2543Smrg */ 41706f2543Smrg#ifdef _XSERVER64 42706f2543Smrg#undef _XSERVER64 43706f2543Smrg#endif 44706f2543Smrg 45706f2543Smrg#include <X11/Xlibint.h> 46706f2543Smrg#include <GL/glx.h> 47706f2543Smrg#include <GL/internal/glcore.h> 48706f2543Smrg#include <GL/glxproto.h> 49706f2543Smrg#include <GL/glxint.h> 50706f2543Smrg#include "ephyrhostglx.h" 51706f2543Smrg#define _HAVE_XALLOC_DECLS 52706f2543Smrg#include "ephyrlog.h" 53706f2543Smrg#include "hostx.h" 54706f2543Smrg 55706f2543Smrgenum VisualConfRequestType { 56706f2543Smrg EPHYR_GET_FB_CONFIG, 57706f2543Smrg EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX, 58706f2543Smrg EPHYR_GET_VISUAL_CONFIGS 59706f2543Smrg 60706f2543Smrg}; 61706f2543Smrg 62706f2543Smrgstatic Bool ephyrHostGLXGetVisualConfigsInternal 63706f2543Smrg (enum VisualConfRequestType a_type, 64706f2543Smrg int32_t a_screen, 65706f2543Smrg int32_t *a_num_visuals, 66706f2543Smrg int32_t *a_num_props, 67706f2543Smrg int32_t *a_props_buf_size, 68706f2543Smrg int32_t **a_props_buf); 69706f2543SmrgBool 70706f2543SmrgephyrHostGLXGetMajorOpcode (int *a_opcode) 71706f2543Smrg{ 72706f2543Smrg Bool is_ok=FALSE ; 73706f2543Smrg Display *dpy=hostx_get_display () ; 74706f2543Smrg static int opcode ; 75706f2543Smrg int first_event_return=0, first_error_return=0; 76706f2543Smrg 77706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; 78706f2543Smrg EPHYR_LOG ("enter\n") ; 79706f2543Smrg if (!opcode) { 80706f2543Smrg if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode, 81706f2543Smrg &first_event_return, &first_error_return)) { 82706f2543Smrg EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ; 83706f2543Smrg goto out ; 84706f2543Smrg } 85706f2543Smrg } 86706f2543Smrg *a_opcode = opcode ; 87706f2543Smrg is_ok = TRUE ; 88706f2543Smrgout: 89706f2543Smrg EPHYR_LOG ("release\n") ; 90706f2543Smrg return is_ok ; 91706f2543Smrg} 92706f2543Smrg 93706f2543SmrgBool 94706f2543SmrgephyrHostGLXQueryVersion (int *a_major, int *a_minor) 95706f2543Smrg{ 96706f2543Smrg Bool is_ok = FALSE ; 97706f2543Smrg Display *dpy = hostx_get_display () ; 98706f2543Smrg int major_opcode=0; 99706f2543Smrg xGLXQueryVersionReq *req=NULL; 100706f2543Smrg xGLXQueryVersionReply reply; 101706f2543Smrg 102706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ; 103706f2543Smrg EPHYR_LOG ("enter\n") ; 104706f2543Smrg 105706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 106706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 107706f2543Smrg goto out ; 108706f2543Smrg } 109706f2543Smrg EPHYR_LOG ("major opcode: %d\n", major_opcode) ; 110706f2543Smrg 111706f2543Smrg /* Send the glXQueryVersion request */ 112706f2543Smrg memset (&reply, 0, sizeof (reply)) ; 113706f2543Smrg LockDisplay (dpy); 114706f2543Smrg GetReq (GLXQueryVersion, req); 115706f2543Smrg req->reqType = major_opcode; 116706f2543Smrg req->glxCode = X_GLXQueryVersion; 117706f2543Smrg req->majorVersion = 2; 118706f2543Smrg req->minorVersion = 1; 119706f2543Smrg _XReply(dpy, (xReply*) &reply, 0, False); 120706f2543Smrg UnlockDisplay (dpy); 121706f2543Smrg SyncHandle (); 122706f2543Smrg 123706f2543Smrg *a_major = reply.majorVersion ; 124706f2543Smrg *a_minor = reply.minorVersion ; 125706f2543Smrg 126706f2543Smrg EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ; 127706f2543Smrg 128706f2543Smrg is_ok = TRUE ; 129706f2543Smrgout: 130706f2543Smrg EPHYR_LOG ("leave\n") ; 131706f2543Smrg return is_ok ; 132706f2543Smrg} 133706f2543Smrg 134706f2543Smrg/** 135706f2543Smrg * GLX protocol structure for the ficticious "GXLGenericGetString" request. 136706f2543Smrg * 137706f2543Smrg * This is a non-existant protocol packet. It just so happens that all of 138706f2543Smrg * the real protocol packets used to request a string from the server have 139706f2543Smrg * an identical binary layout. The only difference between them is the 140706f2543Smrg * meaning of the \c for_whom field and the value of the \c glxCode. 141706f2543Smrg * (this has been copied from the mesa source code) 142706f2543Smrg */ 143706f2543Smrgtypedef struct GLXGenericGetString { 144706f2543Smrg CARD8 reqType; 145706f2543Smrg CARD8 glxCode; 146706f2543Smrg CARD16 length B16; 147706f2543Smrg CARD32 for_whom B32; 148706f2543Smrg CARD32 name B32; 149706f2543Smrg} xGLXGenericGetStringReq; 150706f2543Smrg 151706f2543Smrg/* These defines are only needed to make the GetReq macro happy. 152706f2543Smrg */ 153706f2543Smrg#define sz_xGLXGenericGetStringReq 12 154706f2543Smrg#define X_GLXGenericGetString 0 155706f2543Smrg 156706f2543SmrgBool 157706f2543SmrgephyrHostGLXGetStringFromServer (int a_screen_number, 158706f2543Smrg int a_string_name, 159706f2543Smrg enum EphyrHostGLXGetStringOps a_op, 160706f2543Smrg char **a_string) 161706f2543Smrg{ 162706f2543Smrg Bool is_ok=FALSE ; 163706f2543Smrg Display *dpy = hostx_get_display () ; 164706f2543Smrg int default_screen = DefaultScreen (dpy); 165706f2543Smrg xGLXGenericGetStringReq *req=NULL; 166706f2543Smrg xGLXSingleReply reply; 167706f2543Smrg int length=0, numbytes=0, major_opcode=0, get_string_op=0; 168706f2543Smrg 169706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ; 170706f2543Smrg 171706f2543Smrg EPHYR_LOG ("enter\n") ; 172706f2543Smrg switch (a_op) { 173706f2543Smrg case EPHYR_HOST_GLX_QueryServerString: 174706f2543Smrg get_string_op = X_GLXQueryServerString; 175706f2543Smrg break ; 176706f2543Smrg case EPHYR_HOST_GLX_GetString: 177706f2543Smrg get_string_op = X_GLsop_GetString; 178706f2543Smrg EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n", 179706f2543Smrg a_string_name, a_screen_number) ; 180706f2543Smrg break ; 181706f2543Smrg default: 182706f2543Smrg EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ; 183706f2543Smrg goto out ; 184706f2543Smrg } 185706f2543Smrg 186706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 187706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 188706f2543Smrg goto out ; 189706f2543Smrg } 190706f2543Smrg EPHYR_LOG ("major opcode: %d\n", major_opcode) ; 191706f2543Smrg 192706f2543Smrg LockDisplay (dpy); 193706f2543Smrg 194706f2543Smrg /* All of the GLX protocol requests for getting a string from the server 195706f2543Smrg * look the same. The exact meaning of the a_for_whom field is usually 196706f2543Smrg * either the screen number (for glXQueryServerString) or the context tag 197706f2543Smrg * (for GLXSingle). 198706f2543Smrg */ 199706f2543Smrg GetReq (GLXGenericGetString, req); 200706f2543Smrg req->reqType = major_opcode; 201706f2543Smrg req->glxCode = get_string_op; 202706f2543Smrg req->for_whom = default_screen; 203706f2543Smrg req->name = a_string_name; 204706f2543Smrg 205706f2543Smrg _XReply (dpy, (xReply *)&reply, 0, False); 206706f2543Smrg 207706f2543Smrg length = reply.length * 4; 208706f2543Smrg if (!length) { 209706f2543Smrg numbytes = 0; 210706f2543Smrg } else { 211706f2543Smrg numbytes = reply.size; 212706f2543Smrg } 213706f2543Smrg EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ; 214706f2543Smrg 215706f2543Smrg *a_string = (char *) Xmalloc (numbytes +1); 216706f2543Smrg if (!a_string) { 217706f2543Smrg EPHYR_LOG_ERROR ("allocation failed\n") ; 218706f2543Smrg goto out; 219706f2543Smrg } 220706f2543Smrg 221706f2543Smrg memset (*a_string, 0, numbytes+1) ; 222706f2543Smrg if (_XRead (dpy, *a_string, numbytes)) { 223706f2543Smrg UnlockDisplay (dpy); 224706f2543Smrg SyncHandle (); 225706f2543Smrg EPHYR_LOG_ERROR ("read failed\n") ; 226706f2543Smrg goto out ; 227706f2543Smrg } 228706f2543Smrg length -= numbytes; 229706f2543Smrg _XEatData (dpy, length) ; 230706f2543Smrg UnlockDisplay (dpy); 231706f2543Smrg SyncHandle (); 232706f2543Smrg EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n", 233706f2543Smrg a_string_name, *a_string, numbytes) ; 234706f2543Smrg 235706f2543Smrg is_ok = TRUE ; 236706f2543Smrgout: 237706f2543Smrg EPHYR_LOG ("leave\n") ; 238706f2543Smrg return is_ok ; 239706f2543Smrg} 240706f2543Smrg 241706f2543Smrgstatic Bool 242706f2543SmrgephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type, 243706f2543Smrg int32_t a_screen, 244706f2543Smrg int32_t *a_num_visuals, 245706f2543Smrg int32_t *a_num_props, 246706f2543Smrg int32_t *a_props_buf_size, 247706f2543Smrg int32_t **a_props_buf) 248706f2543Smrg{ 249706f2543Smrg Bool is_ok = FALSE ; 250706f2543Smrg Display *dpy = hostx_get_display () ; 251706f2543Smrg xGLXGetVisualConfigsReq *req; 252706f2543Smrg xGLXGetFBConfigsReq *fb_req; 253706f2543Smrg xGLXVendorPrivateWithReplyReq *vpreq; 254706f2543Smrg xGLXGetFBConfigsSGIXReq *sgi_req; 255706f2543Smrg xGLXGetVisualConfigsReply reply; 256706f2543Smrg char *server_glx_version=NULL, 257706f2543Smrg *server_glx_extensions=NULL ; 258706f2543Smrg int j=0, 259706f2543Smrg screens=0, 260706f2543Smrg major_opcode=0, 261706f2543Smrg num_props=0, 262706f2543Smrg num_visuals=0, 263706f2543Smrg props_buf_size=0, 264706f2543Smrg props_per_visual_size=0; 265706f2543Smrg int32_t *props_buf=NULL; 266706f2543Smrg 267706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ; 268706f2543Smrg 269706f2543Smrg screens = ScreenCount (dpy); 270706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 271706f2543Smrg EPHYR_LOG_ERROR ("failed to get opcode\n") ; 272706f2543Smrg goto out ; 273706f2543Smrg } 274706f2543Smrg 275706f2543Smrg LockDisplay(dpy); 276706f2543Smrg switch (a_type) { 277706f2543Smrg case EPHYR_GET_FB_CONFIG: 278706f2543Smrg GetReq(GLXGetFBConfigs,fb_req); 279706f2543Smrg fb_req->reqType = major_opcode; 280706f2543Smrg fb_req->glxCode = X_GLXGetFBConfigs; 281706f2543Smrg fb_req->screen = DefaultScreen (dpy); 282706f2543Smrg break; 283706f2543Smrg 284706f2543Smrg case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX: 285706f2543Smrg GetReqExtra(GLXVendorPrivateWithReply, 286706f2543Smrg sz_xGLXGetFBConfigsSGIXReq 287706f2543Smrg - 288706f2543Smrg sz_xGLXVendorPrivateWithReplyReq, 289706f2543Smrg vpreq); 290706f2543Smrg sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; 291706f2543Smrg sgi_req->reqType = major_opcode; 292706f2543Smrg sgi_req->glxCode = X_GLXVendorPrivateWithReply; 293706f2543Smrg sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; 294706f2543Smrg sgi_req->screen = DefaultScreen (dpy); 295706f2543Smrg break; 296706f2543Smrg 297706f2543Smrg case EPHYR_GET_VISUAL_CONFIGS: 298706f2543Smrg GetReq(GLXGetVisualConfigs,req); 299706f2543Smrg req->reqType = major_opcode; 300706f2543Smrg req->glxCode = X_GLXGetVisualConfigs; 301706f2543Smrg req->screen = DefaultScreen (dpy); 302706f2543Smrg break; 303706f2543Smrg } 304706f2543Smrg 305706f2543Smrg if (!_XReply(dpy, (xReply*) &reply, 0, False)) { 306706f2543Smrg EPHYR_LOG_ERROR ("unknown error\n") ; 307706f2543Smrg UnlockDisplay(dpy); 308706f2543Smrg goto out ; 309706f2543Smrg } 310706f2543Smrg if (!reply.numVisuals) { 311706f2543Smrg EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ; 312706f2543Smrg UnlockDisplay(dpy); 313706f2543Smrg goto out ; 314706f2543Smrg } 315706f2543Smrg num_visuals = reply.numVisuals ; 316706f2543Smrg 317706f2543Smrg /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for 318706f2543Smrg * FIXME: FBconfigs? 319706f2543Smrg */ 320706f2543Smrg /* Check number of properties */ 321706f2543Smrg num_props = reply.numProps; 322706f2543Smrg if ((num_props < __GLX_MIN_CONFIG_PROPS) || 323706f2543Smrg (num_props > __GLX_MAX_CONFIG_PROPS)) { 324706f2543Smrg /* Huh? Not in protocol defined limits. Punt */ 325706f2543Smrg EPHYR_LOG_ERROR ("got a bad reply to request\n") ; 326706f2543Smrg UnlockDisplay(dpy); 327706f2543Smrg goto out ; 328706f2543Smrg } 329706f2543Smrg 330706f2543Smrg if (a_type != EPHYR_GET_VISUAL_CONFIGS) { 331706f2543Smrg num_props *= 2; 332706f2543Smrg } 333706f2543Smrg props_per_visual_size = num_props * __GLX_SIZE_INT32; 334706f2543Smrg props_buf_size = props_per_visual_size * reply.numVisuals; 335706f2543Smrg props_buf = malloc (props_buf_size) ; 336706f2543Smrg for (j = 0; j < reply.numVisuals; j++) { 337706f2543Smrg if (_XRead (dpy, 338706f2543Smrg &((char*)props_buf)[j*props_per_visual_size], 339706f2543Smrg props_per_visual_size) != Success) { 340706f2543Smrg EPHYR_LOG_ERROR ("read failed\n") ; 341706f2543Smrg } 342706f2543Smrg } 343706f2543Smrg UnlockDisplay(dpy); 344706f2543Smrg 345706f2543Smrg *a_num_visuals = num_visuals ; 346706f2543Smrg *a_num_props = reply.numProps ; 347706f2543Smrg *a_props_buf_size = props_buf_size ; 348706f2543Smrg *a_props_buf = props_buf ; 349706f2543Smrg is_ok = TRUE ; 350706f2543Smrg 351706f2543Smrgout: 352706f2543Smrg if (server_glx_version) { 353706f2543Smrg XFree (server_glx_version) ; 354706f2543Smrg server_glx_version = NULL ; 355706f2543Smrg } 356706f2543Smrg if (server_glx_extensions) { 357706f2543Smrg XFree (server_glx_extensions) ; 358706f2543Smrg server_glx_extensions = NULL ; 359706f2543Smrg } 360706f2543Smrg SyncHandle () ; 361706f2543Smrg return is_ok; 362706f2543Smrg} 363706f2543Smrg 364706f2543SmrgBool 365706f2543SmrgephyrHostGLXGetVisualConfigs (int32_t a_screen, 366706f2543Smrg int32_t *a_num_visuals, 367706f2543Smrg int32_t *a_num_props, 368706f2543Smrg int32_t *a_props_buf_size, 369706f2543Smrg int32_t **a_props_buf) 370706f2543Smrg{ 371706f2543Smrg Bool is_ok = FALSE; 372706f2543Smrg 373706f2543Smrg EPHYR_LOG ("enter\n") ; 374706f2543Smrg is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS, 375706f2543Smrg a_screen, 376706f2543Smrg a_num_visuals, 377706f2543Smrg a_num_props, 378706f2543Smrg a_props_buf_size, 379706f2543Smrg a_props_buf) ; 380706f2543Smrg 381706f2543Smrg EPHYR_LOG ("leave:%d\n", is_ok) ; 382706f2543Smrg return is_ok; 383706f2543Smrg} 384706f2543Smrg 385706f2543SmrgBool 386706f2543SmrgephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen, 387706f2543Smrg int32_t *a_num_visuals, 388706f2543Smrg int32_t *a_num_props, 389706f2543Smrg int32_t *a_props_buf_size, 390706f2543Smrg int32_t **a_props_buf) 391706f2543Smrg{ 392706f2543Smrg Bool is_ok=FALSE ; 393706f2543Smrg EPHYR_LOG ("enter\n") ; 394706f2543Smrg is_ok = ephyrHostGLXGetVisualConfigsInternal 395706f2543Smrg (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX, 396706f2543Smrg a_screen, 397706f2543Smrg a_num_visuals, 398706f2543Smrg a_num_props, 399706f2543Smrg a_props_buf_size, 400706f2543Smrg a_props_buf) ; 401706f2543Smrg EPHYR_LOG ("leave\n") ; 402706f2543Smrg return is_ok ; 403706f2543Smrg} 404706f2543Smrg 405706f2543SmrgBool 406706f2543SmrgephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor, 407706f2543Smrg const char* a_extension_list) 408706f2543Smrg{ 409706f2543Smrg Bool is_ok = FALSE ; 410706f2543Smrg Display *dpy = hostx_get_display () ; 411706f2543Smrg xGLXClientInfoReq *req; 412706f2543Smrg int size; 413706f2543Smrg int32_t major_opcode=0 ; 414706f2543Smrg 415706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ; 416706f2543Smrg 417706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 418706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 419706f2543Smrg goto out ; 420706f2543Smrg } 421706f2543Smrg 422706f2543Smrg LockDisplay (dpy); 423706f2543Smrg 424706f2543Smrg GetReq (GLXClientInfo,req); 425706f2543Smrg req->reqType = major_opcode; 426706f2543Smrg req->glxCode = X_GLXClientInfo; 427706f2543Smrg req->major = a_major; 428706f2543Smrg req->minor = a_minor; 429706f2543Smrg 430706f2543Smrg size = strlen (a_extension_list) + 1; 431706f2543Smrg req->length += bytes_to_int32(size); 432706f2543Smrg req->numbytes = size; 433706f2543Smrg Data (dpy, a_extension_list, size); 434706f2543Smrg 435706f2543Smrg UnlockDisplay(dpy); 436706f2543Smrg SyncHandle(); 437706f2543Smrg 438706f2543Smrg is_ok=TRUE ; 439706f2543Smrg 440706f2543Smrgout: 441706f2543Smrg return is_ok ; 442706f2543Smrg} 443706f2543Smrg 444706f2543SmrgBool 445706f2543SmrgephyrHostGLXCreateContext (int a_screen, 446706f2543Smrg int a_visual_id, 447706f2543Smrg int a_context_id, 448706f2543Smrg int a_share_list_ctxt_id, 449706f2543Smrg Bool a_direct) 450706f2543Smrg{ 451706f2543Smrg Bool is_ok = FALSE; 452706f2543Smrg Display *dpy = hostx_get_display (); 453706f2543Smrg int major_opcode=0, remote_context_id=0; 454706f2543Smrg xGLXCreateContextReq *req; 455706f2543Smrg 456706f2543Smrg EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n", 457706f2543Smrg a_screen, a_visual_id, a_context_id, a_direct) ; 458706f2543Smrg 459706f2543Smrg if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) { 460706f2543Smrg EPHYR_LOG_ERROR ("failed to peer the context id %d host X", 461706f2543Smrg remote_context_id) ; 462706f2543Smrg goto out ; 463706f2543Smrg } 464706f2543Smrg 465706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 466706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 467706f2543Smrg goto out ; 468706f2543Smrg } 469706f2543Smrg 470706f2543Smrg LockDisplay (dpy) ; 471706f2543Smrg 472706f2543Smrg /* Send the glXCreateContext request */ 473706f2543Smrg GetReq(GLXCreateContext,req); 474706f2543Smrg req->reqType = major_opcode; 475706f2543Smrg req->glxCode = X_GLXCreateContext; 476706f2543Smrg req->context = remote_context_id; 477706f2543Smrg req->visual = a_visual_id; 478706f2543Smrg req->screen = DefaultScreen (dpy); 479706f2543Smrg req->shareList = a_share_list_ctxt_id; 480706f2543Smrg req->isDirect = a_direct; 481706f2543Smrg 482706f2543Smrg UnlockDisplay (dpy); 483706f2543Smrg SyncHandle (); 484706f2543Smrg 485706f2543Smrg is_ok = TRUE ; 486706f2543Smrg 487706f2543Smrgout: 488706f2543Smrg EPHYR_LOG ("leave\n") ; 489706f2543Smrg return is_ok ; 490706f2543Smrg} 491706f2543Smrg 492706f2543SmrgBool 493706f2543SmrgephyrHostDestroyContext (int a_ctxt_id) 494706f2543Smrg{ 495706f2543Smrg Bool is_ok=FALSE; 496706f2543Smrg Display *dpy=hostx_get_display (); 497706f2543Smrg int major_opcode=0, remote_ctxt_id=0 ; 498706f2543Smrg xGLXDestroyContextReq *req=NULL; 499706f2543Smrg 500706f2543Smrg EPHYR_LOG ("enter:%d\n", a_ctxt_id) ; 501706f2543Smrg 502706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 503706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 504706f2543Smrg goto out ; 505706f2543Smrg } 506706f2543Smrg if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) { 507706f2543Smrg EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ; 508706f2543Smrg goto out ; 509706f2543Smrg } 510706f2543Smrg EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ; 511706f2543Smrg 512706f2543Smrg LockDisplay (dpy); 513706f2543Smrg GetReq (GLXDestroyContext,req); 514706f2543Smrg req->reqType = major_opcode; 515706f2543Smrg req->glxCode = X_GLXDestroyContext; 516706f2543Smrg req->context = remote_ctxt_id; 517706f2543Smrg UnlockDisplay (dpy); 518706f2543Smrg SyncHandle (); 519706f2543Smrg 520706f2543Smrg is_ok = TRUE ; 521706f2543Smrg 522706f2543Smrgout: 523706f2543Smrg EPHYR_LOG ("leave\n") ; 524706f2543Smrg return is_ok ; 525706f2543Smrg} 526706f2543Smrg 527706f2543SmrgBool 528706f2543SmrgephyrHostGLXMakeCurrent (int a_drawable, 529706f2543Smrg int a_glx_ctxt_id, 530706f2543Smrg int a_old_ctxt_tag, 531706f2543Smrg int *a_ctxt_tag) 532706f2543Smrg{ 533706f2543Smrg Bool is_ok=FALSE ; 534706f2543Smrg Display *dpy = hostx_get_display () ; 535706f2543Smrg int32_t major_opcode=0 ; 536706f2543Smrg int remote_glx_ctxt_id=0 ; 537706f2543Smrg xGLXMakeCurrentReq *req; 538706f2543Smrg xGLXMakeCurrentReply reply; 539706f2543Smrg 540706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ; 541706f2543Smrg 542706f2543Smrg EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n", 543706f2543Smrg a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ; 544706f2543Smrg 545706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 546706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 547706f2543Smrg goto out ; 548706f2543Smrg } 549706f2543Smrg if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) { 550706f2543Smrg EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ; 551706f2543Smrg goto out ; 552706f2543Smrg } 553706f2543Smrg 554706f2543Smrg LockDisplay (dpy); 555706f2543Smrg 556706f2543Smrg GetReq (GLXMakeCurrent,req); 557706f2543Smrg req->reqType = major_opcode; 558706f2543Smrg req->glxCode = X_GLXMakeCurrent; 559706f2543Smrg req->drawable = a_drawable; 560706f2543Smrg req->context = remote_glx_ctxt_id; 561706f2543Smrg req->oldContextTag = a_old_ctxt_tag; 562706f2543Smrg 563706f2543Smrg memset (&reply, 0, sizeof (reply)) ; 564706f2543Smrg if (!_XReply (dpy, (xReply*)&reply, 0, False)) { 565706f2543Smrg EPHYR_LOG_ERROR ("failed to get reply from host\n") ; 566706f2543Smrg UnlockDisplay (dpy); 567706f2543Smrg SyncHandle (); 568706f2543Smrg goto out ; 569706f2543Smrg } 570706f2543Smrg UnlockDisplay (dpy); 571706f2543Smrg SyncHandle (); 572706f2543Smrg *a_ctxt_tag = reply.contextTag ; 573706f2543Smrg EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ; 574706f2543Smrg is_ok = TRUE ; 575706f2543Smrg 576706f2543Smrgout: 577706f2543Smrg EPHYR_LOG ("leave\n") ; 578706f2543Smrg return is_ok ; 579706f2543Smrg} 580706f2543Smrg 581706f2543Smrg#define X_GLXSingle 0 582706f2543Smrg 583706f2543Smrg#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \ 584706f2543Smrg *((INT8 *) (pc + offset)) = a 585706f2543Smrg 586706f2543Smrg#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \ 587706f2543Smrg *((INT16 *) (pc + offset)) = a 588706f2543Smrg 589706f2543Smrg#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \ 590706f2543Smrg *((INT32 *) (pc + offset)) = a 591706f2543Smrg 592706f2543Smrg#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \ 593706f2543Smrg *((FLOAT32 *) (pc + offset)) = a 594706f2543Smrg 595706f2543Smrg#define EPHYR_GLX_SINGLE_READ_XREPLY() \ 596706f2543Smrg (void) _XReply(dpy, (xReply*) &reply, 0, False) 597706f2543Smrg 598706f2543Smrg#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \ 599706f2543Smrg a = (cast) reply.retval 600706f2543Smrg 601706f2543Smrg#define EPHYR_GLX_SINGLE_GET_SIZE(a) \ 602706f2543Smrg a = (GLint) reply.size 603706f2543Smrg 604706f2543Smrg#define EPHYR_GLX_SINGLE_GET_CHAR(p) \ 605706f2543Smrg *p = *(GLbyte *)&reply.pad3; 606706f2543Smrg 607706f2543Smrg#define EPHYR_GLX_SINGLE_GET_SHORT(p) \ 608706f2543Smrg *p = *(GLshort *)&reply.pad3; 609706f2543Smrg 610706f2543Smrg#define EPHYR_GLX_SINGLE_GET_LONG(p) \ 611706f2543Smrg *p = *(GLint *)&reply.pad3; 612706f2543Smrg 613706f2543Smrg#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \ 614706f2543Smrg *p = *(GLfloat *)&reply.pad3; 615706f2543Smrg 616706f2543SmrgBool 617706f2543SmrgephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val) 618706f2543Smrg{ 619706f2543Smrg Bool is_ok=FALSE; 620706f2543Smrg Display *dpy = hostx_get_display () ; 621706f2543Smrg int major_opcode=0, size=0; 622706f2543Smrg xGLXSingleReq *req=NULL; 623706f2543Smrg xGLXSingleReply reply; 624706f2543Smrg unsigned char* pc=NULL ; 625706f2543Smrg 626706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ; 627706f2543Smrg 628706f2543Smrg EPHYR_LOG ("enter\n") ; 629706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 630706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 631706f2543Smrg goto out ; 632706f2543Smrg } 633706f2543Smrg LockDisplay (dpy) ; 634706f2543Smrg GetReqExtra (GLXSingle, 4, req) ; 635706f2543Smrg req->reqType = major_opcode ; 636706f2543Smrg req->glxCode = X_GLsop_GetIntegerv ; 637706f2543Smrg req->contextTag = a_current_context_tag; 638706f2543Smrg pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ; 639706f2543Smrg EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ; 640706f2543Smrg EPHYR_GLX_SINGLE_READ_XREPLY () ; 641706f2543Smrg EPHYR_GLX_SINGLE_GET_SIZE (size) ; 642706f2543Smrg if (!size) { 643706f2543Smrg UnlockDisplay (dpy) ; 644706f2543Smrg SyncHandle () ; 645706f2543Smrg EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ; 646706f2543Smrg goto out ; 647706f2543Smrg } 648706f2543Smrg EPHYR_GLX_SINGLE_GET_LONG (a_val) ; 649706f2543Smrg UnlockDisplay (dpy) ; 650706f2543Smrg SyncHandle () ; 651706f2543Smrg is_ok = TRUE ; 652706f2543Smrg 653706f2543Smrgout: 654706f2543Smrg EPHYR_LOG ("leave\n") ; 655706f2543Smrg return is_ok ; 656706f2543Smrg} 657706f2543Smrg 658706f2543SmrgBool 659706f2543SmrgephyrHostIsContextDirect (int a_ctxt_id, 660706f2543Smrg int *a_is_direct) 661706f2543Smrg{ 662706f2543Smrg Bool is_ok=FALSE; 663706f2543Smrg Display *dpy = hostx_get_display () ; 664706f2543Smrg xGLXIsDirectReq *req=NULL; 665706f2543Smrg xGLXIsDirectReply reply; 666706f2543Smrg int major_opcode=0, remote_glx_ctxt_id=0; 667706f2543Smrg 668706f2543Smrg EPHYR_LOG ("enter\n") ; 669706f2543Smrg if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) { 670706f2543Smrg EPHYR_LOG_ERROR ("failed to get major opcode\n") ; 671706f2543Smrg goto out ; 672706f2543Smrg } 673706f2543Smrg if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) { 674706f2543Smrg EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ; 675706f2543Smrg goto out ; 676706f2543Smrg } 677706f2543Smrg memset (&reply, 0, sizeof (reply)) ; 678706f2543Smrg 679706f2543Smrg /* Send the glXIsDirect request */ 680706f2543Smrg LockDisplay (dpy); 681706f2543Smrg GetReq (GLXIsDirect,req); 682706f2543Smrg req->reqType = major_opcode; 683706f2543Smrg req->glxCode = X_GLXIsDirect; 684706f2543Smrg req->context = remote_glx_ctxt_id; 685706f2543Smrg if (!_XReply (dpy, (xReply*) &reply, 0, False)) { 686706f2543Smrg EPHYR_LOG_ERROR ("fail in reading reply from host\n") ; 687706f2543Smrg UnlockDisplay (dpy); 688706f2543Smrg SyncHandle (); 689706f2543Smrg goto out ; 690706f2543Smrg } 691706f2543Smrg UnlockDisplay (dpy); 692706f2543Smrg SyncHandle (); 693706f2543Smrg *a_is_direct = reply.isDirect ; 694706f2543Smrg is_ok = TRUE ; 695706f2543Smrg 696706f2543Smrgout: 697706f2543Smrg EPHYR_LOG ("leave\n") ; 698706f2543Smrg return is_ok ; 699706f2543Smrg} 700