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 * Authors: 26706f2543Smrg * Dodji Seketeli <dodji@openedhand.com> 27706f2543Smrg */ 28706f2543Smrg#ifdef HAVE_CONFIG_H 29706f2543Smrg#include <kdrive-config.h> 30706f2543Smrg#endif 31706f2543Smrg 32706f2543Smrg#include "extnsionst.h" 33706f2543Smrg#include "ephyrglxext.h" 34706f2543Smrg#include "ephyrhostglx.h" 35706f2543Smrg#define _HAVE_XALLOC_DECLS 36706f2543Smrg#include "ephyrlog.h" 37706f2543Smrg#include <GL/glxproto.h> 38706f2543Smrg#include "glx/glxserver.h" 39706f2543Smrg#include "glx/indirect_table.h" 40706f2543Smrg#include "glx/indirect_util.h" 41706f2543Smrg#include "glx/unpack.h" 42706f2543Smrg#include "hostx.h" 43706f2543Smrg 44706f2543Smrg 45706f2543Smrg#ifndef TRUE 46706f2543Smrg#define TRUE 1 47706f2543Smrg#endif 48706f2543Smrg 49706f2543Smrg#ifndef FALSE 50706f2543Smrg#define FALSE 0 51706f2543Smrg#endif 52706f2543Smrg 53706f2543Smrg 54706f2543Smrgint ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ; 55706f2543Smrgint ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ; 56706f2543Smrgint ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ; 57706f2543Smrgint ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ; 58706f2543Smrgint ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ; 59706f2543Smrgint ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ; 60706f2543Smrgint ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ; 61706f2543Smrgint ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ; 62706f2543Smrgint ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc); 63706f2543Smrgint ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc); 64706f2543Smrgint ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc); 65706f2543Smrgint ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc); 66706f2543Smrgint ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ; 67706f2543Smrgint ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 68706f2543Smrgint ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ; 69706f2543Smrgint ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 70706f2543Smrgint ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ; 71706f2543Smrgint ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 72706f2543Smrgint ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ; 73706f2543Smrgint ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 74706f2543Smrgint ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ; 75706f2543Smrgint ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; 76706f2543Smrg 77706f2543SmrgBool 78706f2543SmrgephyrHijackGLXExtension (void) 79706f2543Smrg{ 80706f2543Smrg const void *(*dispatch_functions)[2]; 81706f2543Smrg 82706f2543Smrg if (!hostx_has_glx ()) { 83706f2543Smrg EPHYR_LOG ("host X does not have GLX\n") ; 84706f2543Smrg return FALSE ; 85706f2543Smrg } 86706f2543Smrg EPHYR_LOG ("host X does have GLX\n") ; 87706f2543Smrg 88706f2543Smrg if (!Single_dispatch_info.dispatch_functions) { 89706f2543Smrg EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ; 90706f2543Smrg return FALSE ; 91706f2543Smrg } 92706f2543Smrg /* 93706f2543Smrg * hijack some single entry point dispatch functions 94706f2543Smrg */ 95706f2543Smrg dispatch_functions = Single_dispatch_info.dispatch_functions ; 96706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ; 97706f2543Smrg 98706f2543Smrg dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ; 99706f2543Smrg dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ; 100706f2543Smrg 101706f2543Smrg dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ; 102706f2543Smrg dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ; 103706f2543Smrg dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ; 104706f2543Smrg dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ; 105706f2543Smrg 106706f2543Smrg dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ; 107706f2543Smrg dispatch_functions[X_GLXQueryServerString][1] = 108706f2543Smrg ephyrGLXQueryServerStringSwap ; 109706f2543Smrg 110706f2543Smrg dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ; 111706f2543Smrg dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ; 112706f2543Smrg 113706f2543Smrg dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ; 114706f2543Smrg dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ; 115706f2543Smrg 116706f2543Smrg dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ; 117706f2543Smrg dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ; 118706f2543Smrg 119706f2543Smrg dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ; 120706f2543Smrg dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ; 121706f2543Smrg 122706f2543Smrg dispatch_functions[73][0] = ephyrGLXGetString ; 123706f2543Smrg dispatch_functions[73][1] = ephyrGLXGetStringSwap ; 124706f2543Smrg 125706f2543Smrg dispatch_functions[61][0] = ephyrGLXGetIntegerv ; 126706f2543Smrg dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ; 127706f2543Smrg 128706f2543Smrg /* 129706f2543Smrg * hijack some vendor priv entry point dispatch functions 130706f2543Smrg */ 131706f2543Smrg dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ; 132706f2543Smrg dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX; 133706f2543Smrg dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap; 134706f2543Smrg EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ; 135706f2543Smrg 136706f2543Smrg return TRUE ; 137706f2543Smrg} 138706f2543Smrg 139706f2543Smrg/********************* 140706f2543Smrg * implementation of 141706f2543Smrg * hijacked GLX entry 142706f2543Smrg * points 143706f2543Smrg ********************/ 144706f2543Smrg 145706f2543Smrgint 146706f2543SmrgephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc) 147706f2543Smrg{ 148706f2543Smrg ClientPtr client = a_cl->client; 149706f2543Smrg xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc; 150706f2543Smrg xGLXQueryVersionReply reply; 151706f2543Smrg int major, minor; 152706f2543Smrg int res = BadImplementation ; 153706f2543Smrg 154706f2543Smrg EPHYR_LOG ("enter\n") ; 155706f2543Smrg 156706f2543Smrg major = req->majorVersion ; 157706f2543Smrg minor = req->minorVersion ; 158706f2543Smrg 159706f2543Smrg if (!ephyrHostGLXQueryVersion (&major, &minor)) { 160706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ; 161706f2543Smrg goto out ; 162706f2543Smrg } 163706f2543Smrg EPHYR_LOG ("major:%d, minor:%d\n", 164706f2543Smrg major, minor); 165706f2543Smrg reply.majorVersion = major ; 166706f2543Smrg reply.minorVersion = minor ; 167706f2543Smrg reply.length = 0 ; 168706f2543Smrg reply.type = X_Reply ; 169706f2543Smrg reply.sequenceNumber = client->sequence ; 170706f2543Smrg 171706f2543Smrg if (client->swapped) { 172706f2543Smrg __glXSwapQueryVersionReply(client, &reply); 173706f2543Smrg } else { 174706f2543Smrg WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); 175706f2543Smrg } 176706f2543Smrg 177706f2543Smrg res = Success ; 178706f2543Smrgout: 179706f2543Smrg EPHYR_LOG ("leave\n") ; 180706f2543Smrg return res; 181706f2543Smrg} 182706f2543Smrg 183706f2543Smrgint 184706f2543SmrgephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc) 185706f2543Smrg{ 186706f2543Smrg xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc; 187706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 188706f2543Smrg 189706f2543Smrg __GLX_SWAP_SHORT (&req->length); 190706f2543Smrg __GLX_SWAP_INT (&req->majorVersion); 191706f2543Smrg __GLX_SWAP_INT (&req->minorVersion); 192706f2543Smrg return ephyrGLXQueryVersion (a_cl, a_pc) ; 193706f2543Smrg} 194706f2543Smrg 195706f2543Smrgstatic int 196706f2543SmrgephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl, 197706f2543Smrg GLbyte *a_pc, 198706f2543Smrg Bool a_do_swap) 199706f2543Smrg{ 200706f2543Smrg xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc; 201706f2543Smrg ClientPtr client = a_cl->client; 202706f2543Smrg xGLXGetVisualConfigsReply reply; 203706f2543Smrg int32_t *props_buf=NULL, num_visuals=0, 204706f2543Smrg num_props=0, res=BadImplementation, i=0, 205706f2543Smrg props_per_visual_size=0, 206706f2543Smrg props_buf_size=0; 207706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 208706f2543Smrg __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 209706f2543Smrg 210706f2543Smrg EPHYR_LOG ("enter\n") ; 211706f2543Smrg 212706f2543Smrg if (!ephyrHostGLXGetVisualConfigs (req->screen, 213706f2543Smrg &num_visuals, 214706f2543Smrg &num_props, 215706f2543Smrg &props_buf_size, 216706f2543Smrg &props_buf)) { 217706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ; 218706f2543Smrg goto out ; 219706f2543Smrg } 220706f2543Smrg EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ; 221706f2543Smrg 222706f2543Smrg reply.numVisuals = num_visuals; 223706f2543Smrg reply.numProps = num_props; 224706f2543Smrg reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2; 225706f2543Smrg reply.type = X_Reply; 226706f2543Smrg reply.sequenceNumber = client->sequence; 227706f2543Smrg 228706f2543Smrg if (a_do_swap) { 229706f2543Smrg __GLX_SWAP_SHORT(&reply.sequenceNumber); 230706f2543Smrg __GLX_SWAP_INT(&reply.length); 231706f2543Smrg __GLX_SWAP_INT(&reply.numVisuals); 232706f2543Smrg __GLX_SWAP_INT(&reply.numProps); 233706f2543Smrg __GLX_SWAP_INT_ARRAY (props_buf, num_props) ; 234706f2543Smrg } 235706f2543Smrg WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply); 236706f2543Smrg props_per_visual_size = props_buf_size/num_visuals ; 237706f2543Smrg for (i=0; i < num_visuals; i++) { 238706f2543Smrg WriteToClient (client, 239706f2543Smrg props_per_visual_size, 240706f2543Smrg (char*)props_buf +i*props_per_visual_size); 241706f2543Smrg } 242706f2543Smrg res = Success ; 243706f2543Smrg 244706f2543Smrgout: 245706f2543Smrg EPHYR_LOG ("leave\n") ; 246706f2543Smrg free(props_buf) ; 247706f2543Smrg props_buf = NULL ; 248706f2543Smrg 249706f2543Smrg return res ; 250706f2543Smrg} 251706f2543Smrg 252706f2543Smrgstatic int 253706f2543SmrgephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl, 254706f2543Smrg GLbyte *a_pc, 255706f2543Smrg Bool a_do_swap) 256706f2543Smrg{ 257706f2543Smrg xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc; 258706f2543Smrg ClientPtr client = a_cl->client; 259706f2543Smrg xGLXGetVisualConfigsReply reply; 260706f2543Smrg int32_t *props_buf=NULL, num_visuals=0, 261706f2543Smrg num_props=0, res=BadImplementation, i=0, 262706f2543Smrg props_per_visual_size=0, 263706f2543Smrg props_buf_size=0; 264706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 265706f2543Smrg __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 266706f2543Smrg 267706f2543Smrg EPHYR_LOG ("enter\n") ; 268706f2543Smrg 269706f2543Smrg if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen, 270706f2543Smrg &num_visuals, 271706f2543Smrg &num_props, 272706f2543Smrg &props_buf_size, 273706f2543Smrg &props_buf)) { 274706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ; 275706f2543Smrg goto out ; 276706f2543Smrg } 277706f2543Smrg EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ; 278706f2543Smrg 279706f2543Smrg reply.numVisuals = num_visuals; 280706f2543Smrg reply.numProps = num_props; 281706f2543Smrg reply.length = props_buf_size >> 2; 282706f2543Smrg reply.type = X_Reply; 283706f2543Smrg reply.sequenceNumber = client->sequence; 284706f2543Smrg 285706f2543Smrg if (a_do_swap) { 286706f2543Smrg __GLX_SWAP_SHORT(&reply.sequenceNumber); 287706f2543Smrg __GLX_SWAP_INT(&reply.length); 288706f2543Smrg __GLX_SWAP_INT(&reply.numVisuals); 289706f2543Smrg __GLX_SWAP_INT(&reply.numProps); 290706f2543Smrg __GLX_SWAP_INT_ARRAY (props_buf, num_props) ; 291706f2543Smrg } 292706f2543Smrg WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply); 293706f2543Smrg props_per_visual_size = props_buf_size/num_visuals ; 294706f2543Smrg for (i=0; i < num_visuals; i++) { 295706f2543Smrg WriteToClient (client, 296706f2543Smrg props_per_visual_size, 297706f2543Smrg &((char*)props_buf)[i*props_per_visual_size]); 298706f2543Smrg } 299706f2543Smrg res = Success ; 300706f2543Smrg 301706f2543Smrgout: 302706f2543Smrg EPHYR_LOG ("leave\n") ; 303706f2543Smrg free(props_buf) ; 304706f2543Smrg props_buf = NULL ; 305706f2543Smrg 306706f2543Smrg return res ; 307706f2543Smrg} 308706f2543Smrg 309706f2543Smrgint 310706f2543SmrgephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc) 311706f2543Smrg{ 312706f2543Smrg return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ; 313706f2543Smrg} 314706f2543Smrg 315706f2543Smrgint 316706f2543SmrgephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc) 317706f2543Smrg{ 318706f2543Smrg return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ; 319706f2543Smrg} 320706f2543Smrg 321706f2543Smrg 322706f2543Smrgint 323706f2543SmrgephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc) 324706f2543Smrg{ 325706f2543Smrg int res=BadImplementation ; 326706f2543Smrg xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc; 327706f2543Smrg 328706f2543Smrg EPHYR_LOG ("enter\n") ; 329706f2543Smrg if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) { 330706f2543Smrg EPHYR_LOG_ERROR ("failed to send client info to host\n") ; 331706f2543Smrg goto out ; 332706f2543Smrg } 333706f2543Smrg res = Success ; 334706f2543Smrg 335706f2543Smrgout: 336706f2543Smrg EPHYR_LOG ("leave\n") ; 337706f2543Smrg return res ; 338706f2543Smrg} 339706f2543Smrg 340706f2543Smrgint 341706f2543SmrgephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc) 342706f2543Smrg{ 343706f2543Smrg xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc; 344706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 345706f2543Smrg 346706f2543Smrg __GLX_SWAP_SHORT (&req->length); 347706f2543Smrg __GLX_SWAP_INT (&req->major); 348706f2543Smrg __GLX_SWAP_INT (&req->minor); 349706f2543Smrg __GLX_SWAP_INT (&req->numbytes); 350706f2543Smrg 351706f2543Smrg return ephyrGLXClientInfo (a_cl, a_pc) ; 352706f2543Smrg} 353706f2543Smrg 354706f2543Smrgint 355706f2543SmrgephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) 356706f2543Smrg{ 357706f2543Smrg int res = BadImplementation ; 358706f2543Smrg ClientPtr client = a_cl->client; 359706f2543Smrg xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc; 360706f2543Smrg xGLXQueryServerStringReply reply; 361706f2543Smrg char *server_string=NULL, *buf=NULL; 362706f2543Smrg int length=0 ; 363706f2543Smrg 364706f2543Smrg EPHYR_LOG ("enter\n") ; 365706f2543Smrg if (!ephyrHostGLXGetStringFromServer (req->screen, 366706f2543Smrg req->name, 367706f2543Smrg EPHYR_HOST_GLX_QueryServerString, 368706f2543Smrg &server_string)) { 369706f2543Smrg EPHYR_LOG_ERROR ("failed to query string from host\n") ; 370706f2543Smrg goto out ; 371706f2543Smrg } 372706f2543Smrg EPHYR_LOG ("string: %s\n", server_string) ; 373706f2543Smrg length= strlen (server_string) + 1; 374706f2543Smrg reply.type = X_Reply ; 375706f2543Smrg reply.sequenceNumber = client->sequence ; 376706f2543Smrg reply.length = __GLX_PAD (length) >> 2 ; 377706f2543Smrg reply.n = length ; 378706f2543Smrg buf = calloc(reply.length << 2, 1); 379706f2543Smrg if (!buf) { 380706f2543Smrg EPHYR_LOG_ERROR ("failed to allocate string\n;"); 381706f2543Smrg return BadAlloc; 382706f2543Smrg } 383706f2543Smrg memcpy (buf, server_string, length); 384706f2543Smrg 385706f2543Smrg WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply); 386706f2543Smrg WriteToClient(client, (int)(reply.length << 2), server_string); 387706f2543Smrg 388706f2543Smrg res = Success ; 389706f2543Smrg 390706f2543Smrgout: 391706f2543Smrg EPHYR_LOG ("leave\n") ; 392706f2543Smrg free(server_string) ; 393706f2543Smrg server_string = NULL; 394706f2543Smrg 395706f2543Smrg free(buf); 396706f2543Smrg buf = NULL; 397706f2543Smrg 398706f2543Smrg return res ; 399706f2543Smrg} 400706f2543Smrg 401706f2543Smrgint 402706f2543SmrgephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) 403706f2543Smrg{ 404706f2543Smrg EPHYR_LOG_ERROR ("not yet implemented\n") ; 405706f2543Smrg return BadImplementation ; 406706f2543Smrg} 407706f2543Smrg 408706f2543Smrg 409706f2543Smrgint 410706f2543SmrgephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc) 411706f2543Smrg{ 412706f2543Smrg return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ; 413706f2543Smrg} 414706f2543Smrg 415706f2543Smrgint 416706f2543SmrgephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc) 417706f2543Smrg{ 418706f2543Smrg return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ; 419706f2543Smrg} 420706f2543Smrg 421706f2543Smrgstatic int 422706f2543SmrgephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap) 423706f2543Smrg{ 424706f2543Smrg int res=BadImplementation; 425706f2543Smrg EphyrHostWindowAttributes host_w_attrs ; 426706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 427706f2543Smrg 428706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ; 429706f2543Smrg EPHYR_LOG ("enter\n") ; 430706f2543Smrg 431706f2543Smrg if (a_do_swap) { 432706f2543Smrg __GLX_SWAP_SHORT(&a_req->length); 433706f2543Smrg __GLX_SWAP_INT(&a_req->context); 434706f2543Smrg __GLX_SWAP_INT(&a_req->visual); 435706f2543Smrg __GLX_SWAP_INT(&a_req->screen); 436706f2543Smrg __GLX_SWAP_INT(&a_req->shareList); 437706f2543Smrg } 438706f2543Smrg 439706f2543Smrg EPHYR_LOG ("context creation requested. localid:%d, " 440706f2543Smrg "screen:%d, visual:%d, direct:%d\n", 441706f2543Smrg (int)a_req->context, (int)a_req->screen, 442706f2543Smrg (int)a_req->visual, (int)a_req->isDirect) ; 443706f2543Smrg 444706f2543Smrg memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ; 445706f2543Smrg if (!hostx_get_window_attributes (hostx_get_window (a_req->screen), 446706f2543Smrg &host_w_attrs)) { 447706f2543Smrg EPHYR_LOG_ERROR ("failed to get host window attrs\n") ; 448706f2543Smrg goto out ; 449706f2543Smrg } 450706f2543Smrg 451706f2543Smrg EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ; 452706f2543Smrg 453706f2543Smrg if (!ephyrHostGLXCreateContext (a_req->screen, 454706f2543Smrg host_w_attrs.visualid, 455706f2543Smrg a_req->context, 456706f2543Smrg a_req->shareList, 457706f2543Smrg a_req->isDirect)) { 458706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ; 459706f2543Smrg goto out ; 460706f2543Smrg } 461706f2543Smrg res = Success; 462706f2543Smrgout: 463706f2543Smrg EPHYR_LOG ("leave\n") ; 464706f2543Smrg return res ; 465706f2543Smrg} 466706f2543Smrg 467706f2543Smrgint 468706f2543SmrgephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc) 469706f2543Smrg{ 470706f2543Smrg xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; 471706f2543Smrg 472706f2543Smrg return ephyrGLXCreateContextReal (req, FALSE) ; 473706f2543Smrg} 474706f2543Smrg 475706f2543Smrgint ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc) 476706f2543Smrg{ 477706f2543Smrg xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; 478706f2543Smrg return ephyrGLXCreateContextReal (req, TRUE) ; 479706f2543Smrg} 480706f2543Smrg 481706f2543Smrgstatic int 482706f2543SmrgephyrGLXDestroyContextReal (__GLXclientState *a_cl, 483706f2543Smrg GLbyte *a_pc, 484706f2543Smrg Bool a_do_swap) 485706f2543Smrg{ 486706f2543Smrg int res=BadImplementation; 487706f2543Smrg ClientPtr client = a_cl->client; 488706f2543Smrg xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc; 489706f2543Smrg 490706f2543Smrg EPHYR_LOG ("enter. id:%d\n", (int)req->context) ; 491706f2543Smrg if (!ephyrHostDestroyContext (req->context)) { 492706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ; 493706f2543Smrg client->errorValue = req->context ; 494706f2543Smrg goto out ; 495706f2543Smrg } 496706f2543Smrg res = Success ; 497706f2543Smrg 498706f2543Smrgout: 499706f2543Smrg EPHYR_LOG ("leave\n") ; 500706f2543Smrg return res ; 501706f2543Smrg} 502706f2543Smrg 503706f2543Smrgint 504706f2543SmrgephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) 505706f2543Smrg{ 506706f2543Smrg return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ; 507706f2543Smrg} 508706f2543Smrg 509706f2543Smrgint 510706f2543SmrgephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) 511706f2543Smrg{ 512706f2543Smrg return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ; 513706f2543Smrg} 514706f2543Smrg 515706f2543Smrgstatic int 516706f2543SmrgephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 517706f2543Smrg{ 518706f2543Smrg int res=BadImplementation; 519706f2543Smrg xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc; 520706f2543Smrg xGLXMakeCurrentReply reply ; 521706f2543Smrg DrawablePtr drawable=NULL; 522706f2543Smrg int rc=0; 523706f2543Smrg 524706f2543Smrg EPHYR_LOG ("enter\n") ; 525706f2543Smrg rc = dixLookupDrawable (&drawable, 526706f2543Smrg req->drawable, 527706f2543Smrg a_cl->client, 528706f2543Smrg 0, 529706f2543Smrg DixReadAccess); 530706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ; 531706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ; 532706f2543Smrg EPHYR_LOG ("screen nummber requested:%d\n", 533706f2543Smrg drawable->pScreen->myNum) ; 534706f2543Smrg 535706f2543Smrg memset (&reply, 0, sizeof (reply)) ; 536706f2543Smrg if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum), 537706f2543Smrg req->context, 538706f2543Smrg req->oldContextTag, 539706f2543Smrg (int*)&reply.contextTag)) { 540706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ; 541706f2543Smrg goto out; 542706f2543Smrg } 543706f2543Smrg reply.length = 0; 544706f2543Smrg reply.type = X_Reply; 545706f2543Smrg reply.sequenceNumber = a_cl->client->sequence; 546706f2543Smrg if (a_do_swap) { 547706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 548706f2543Smrg __GLX_SWAP_SHORT(&reply.sequenceNumber); 549706f2543Smrg __GLX_SWAP_INT(&reply.length); 550706f2543Smrg __GLX_SWAP_INT(&reply.contextTag); 551706f2543Smrg } 552706f2543Smrg WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply); 553706f2543Smrg 554706f2543Smrg res = Success ; 555706f2543Smrgout: 556706f2543Smrg EPHYR_LOG ("leave\n") ; 557706f2543Smrg return res ; 558706f2543Smrg} 559706f2543Smrg 560706f2543Smrgint 561706f2543SmrgephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) 562706f2543Smrg{ 563706f2543Smrg return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ; 564706f2543Smrg} 565706f2543Smrg 566706f2543Smrgint 567706f2543SmrgephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) 568706f2543Smrg{ 569706f2543Smrg return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ; 570706f2543Smrg} 571706f2543Smrg 572706f2543Smrgstatic int 573706f2543SmrgephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 574706f2543Smrg{ 575706f2543Smrg ClientPtr client=NULL ; 576706f2543Smrg int context_tag=0, name=0, res=BadImplementation, length=0 ; 577706f2543Smrg char *string=NULL; 578706f2543Smrg __GLX_DECLARE_SWAP_VARIABLES; 579706f2543Smrg 580706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ; 581706f2543Smrg 582706f2543Smrg EPHYR_LOG ("enter\n") ; 583706f2543Smrg 584706f2543Smrg client = a_cl->client ; 585706f2543Smrg 586706f2543Smrg if (a_do_swap) { 587706f2543Smrg __GLX_SWAP_INT (a_pc + 4); 588706f2543Smrg __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE); 589706f2543Smrg } 590706f2543Smrg context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ; 591706f2543Smrg a_pc += __GLX_SINGLE_HDR_SIZE; 592706f2543Smrg name = *(GLenum*)(a_pc + 0); 593706f2543Smrg EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ; 594706f2543Smrg if (!ephyrHostGLXGetStringFromServer (context_tag, 595706f2543Smrg name, 596706f2543Smrg EPHYR_HOST_GLX_GetString, 597706f2543Smrg &string)) { 598706f2543Smrg EPHYR_LOG_ERROR ("failed to get string from server\n") ; 599706f2543Smrg goto out ; 600706f2543Smrg } 601706f2543Smrg if (string) { 602706f2543Smrg length = strlen (string) + 1; 603706f2543Smrg EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ; 604706f2543Smrg } else { 605706f2543Smrg EPHYR_LOG ("got string: string (null)\n") ; 606706f2543Smrg } 607706f2543Smrg __GLX_BEGIN_REPLY (length); 608706f2543Smrg __GLX_PUT_SIZE (length); 609706f2543Smrg __GLX_SEND_HEADER (); 610706f2543Smrg if (a_do_swap) { 611706f2543Smrg __GLX_SWAP_REPLY_SIZE (); 612706f2543Smrg __GLX_SWAP_REPLY_HEADER (); 613706f2543Smrg } 614706f2543Smrg WriteToClient (client, length, (char *)string); 615706f2543Smrg 616706f2543Smrg res = Success ; 617706f2543Smrgout: 618706f2543Smrg EPHYR_LOG ("leave\n") ; 619706f2543Smrg return res ; 620706f2543Smrg} 621706f2543Smrg 622706f2543Smrgint 623706f2543SmrgephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) 624706f2543Smrg{ 625706f2543Smrg return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ; 626706f2543Smrg} 627706f2543Smrg 628706f2543Smrgint 629706f2543SmrgephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) 630706f2543Smrg{ 631706f2543Smrg return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ; 632706f2543Smrg} 633706f2543Smrg 634706f2543Smrgstatic int 635706f2543SmrgephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 636706f2543Smrg{ 637706f2543Smrg int res=BadImplementation; 638706f2543Smrg xGLXSingleReq * const req = (xGLXSingleReq *) a_pc; 639706f2543Smrg GLenum int_name ; 640706f2543Smrg int value=0 ; 641706f2543Smrg GLint answer_buf_room[200]; 642706f2543Smrg GLint *buf=NULL ; 643706f2543Smrg 644706f2543Smrg EPHYR_LOG ("enter\n") ; 645706f2543Smrg 646706f2543Smrg a_pc += __GLX_SINGLE_HDR_SIZE; 647706f2543Smrg 648706f2543Smrg int_name = *(GLenum*) (a_pc+0) ; 649706f2543Smrg if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) { 650706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ; 651706f2543Smrg goto out ; 652706f2543Smrg } 653706f2543Smrg buf = __glXGetAnswerBuffer (a_cl, sizeof (value), 654706f2543Smrg answer_buf_room, 655706f2543Smrg sizeof (answer_buf_room), 656706f2543Smrg 4) ; 657706f2543Smrg 658706f2543Smrg if (!buf) { 659706f2543Smrg EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ; 660706f2543Smrg res = BadAlloc ; 661706f2543Smrg goto out ; 662706f2543Smrg } 663706f2543Smrg __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ; 664706f2543Smrg res = Success ; 665706f2543Smrg 666706f2543Smrgout: 667706f2543Smrg EPHYR_LOG ("leave\n") ; 668706f2543Smrg return res ; 669706f2543Smrg} 670706f2543Smrg 671706f2543Smrgint 672706f2543SmrgephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) 673706f2543Smrg{ 674706f2543Smrg return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ; 675706f2543Smrg} 676706f2543Smrg 677706f2543Smrgint 678706f2543SmrgephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) 679706f2543Smrg{ 680706f2543Smrg return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ; 681706f2543Smrg} 682706f2543Smrg 683706f2543Smrgstatic int 684706f2543SmrgephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) 685706f2543Smrg{ 686706f2543Smrg int res=BadImplementation; 687706f2543Smrg ClientPtr client = a_cl->client; 688706f2543Smrg xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc; 689706f2543Smrg xGLXIsDirectReply reply; 690706f2543Smrg int is_direct=0 ; 691706f2543Smrg 692706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ; 693706f2543Smrg 694706f2543Smrg EPHYR_LOG ("enter\n") ; 695706f2543Smrg 696706f2543Smrg memset (&reply, 0, sizeof (reply)) ; 697706f2543Smrg if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) { 698706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ; 699706f2543Smrg goto out ; 700706f2543Smrg } 701706f2543Smrg reply.isDirect = is_direct ; 702706f2543Smrg reply.length = 0; 703706f2543Smrg reply.type = X_Reply; 704706f2543Smrg reply.sequenceNumber = client->sequence; 705706f2543Smrg WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); 706706f2543Smrg res = Success ; 707706f2543Smrg 708706f2543Smrgout: 709706f2543Smrg EPHYR_LOG ("leave\n") ; 710706f2543Smrg return res ; 711706f2543Smrg} 712706f2543Smrg 713706f2543Smrgint 714706f2543SmrgephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) 715706f2543Smrg{ 716706f2543Smrg return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ; 717706f2543Smrg} 718706f2543Smrg 719706f2543Smrgint 720706f2543SmrgephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) 721706f2543Smrg{ 722706f2543Smrg return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ; 723706f2543Smrg} 724