724 lines
22 KiB
C
724 lines
22 KiB
C
/*
|
|
* Xephyr - A kdrive X server thats runs in a host X window.
|
|
* Authored by Matthew Allum <mallum@openedhand.com>
|
|
*
|
|
* Copyright © 2007 OpenedHand Ltd
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that
|
|
* copyright notice and this permission notice appear in supporting
|
|
* documentation, and that the name of OpenedHand Ltd not be used in
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
* specific, written prior permission. OpenedHand Ltd makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Authors:
|
|
* Dodji Seketeli <dodji@openedhand.com>
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <kdrive-config.h>
|
|
#endif
|
|
|
|
#include "extnsionst.h"
|
|
#include "ephyrglxext.h"
|
|
#include "ephyrhostglx.h"
|
|
#define _HAVE_XALLOC_DECLS
|
|
#include "ephyrlog.h"
|
|
#include <GL/glxproto.h>
|
|
#include "glx/glxserver.h"
|
|
#include "glx/indirect_table.h"
|
|
#include "glx/indirect_util.h"
|
|
#include "glx/unpack.h"
|
|
#include "hostx.h"
|
|
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#endif
|
|
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
|
|
int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
|
|
int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
|
|
int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
|
|
int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
|
|
int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
|
|
int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
|
|
int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
|
|
int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
|
|
int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
|
|
int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
|
|
int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
|
|
|
|
Bool
|
|
ephyrHijackGLXExtension (void)
|
|
{
|
|
const void *(*dispatch_functions)[2];
|
|
|
|
if (!hostx_has_glx ()) {
|
|
EPHYR_LOG ("host X does not have GLX\n") ;
|
|
return FALSE ;
|
|
}
|
|
EPHYR_LOG ("host X does have GLX\n") ;
|
|
|
|
if (!Single_dispatch_info.dispatch_functions) {
|
|
EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
|
|
return FALSE ;
|
|
}
|
|
/*
|
|
* hijack some single entry point dispatch functions
|
|
*/
|
|
dispatch_functions = Single_dispatch_info.dispatch_functions ;
|
|
EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
|
|
|
|
dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
|
|
dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
|
|
|
|
dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
|
|
dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
|
|
dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
|
|
dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
|
|
|
|
dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
|
|
dispatch_functions[X_GLXQueryServerString][1] =
|
|
ephyrGLXQueryServerStringSwap ;
|
|
|
|
dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
|
|
dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
|
|
|
|
dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
|
|
dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
|
|
|
|
dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
|
|
dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
|
|
|
|
dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
|
|
dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
|
|
|
|
dispatch_functions[73][0] = ephyrGLXGetString ;
|
|
dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
|
|
|
|
dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
|
|
dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
|
|
|
|
/*
|
|
* hijack some vendor priv entry point dispatch functions
|
|
*/
|
|
dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
|
|
dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
|
|
dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
|
|
EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
|
|
|
|
return TRUE ;
|
|
}
|
|
|
|
/*********************
|
|
* implementation of
|
|
* hijacked GLX entry
|
|
* points
|
|
********************/
|
|
|
|
int
|
|
ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
ClientPtr client = a_cl->client;
|
|
xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
|
|
xGLXQueryVersionReply reply;
|
|
int major, minor;
|
|
int res = BadImplementation ;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
major = req->majorVersion ;
|
|
minor = req->minorVersion ;
|
|
|
|
if (!ephyrHostGLXQueryVersion (&major, &minor)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
|
|
goto out ;
|
|
}
|
|
EPHYR_LOG ("major:%d, minor:%d\n",
|
|
major, minor);
|
|
reply.majorVersion = major ;
|
|
reply.minorVersion = minor ;
|
|
reply.length = 0 ;
|
|
reply.type = X_Reply ;
|
|
reply.sequenceNumber = client->sequence ;
|
|
|
|
if (client->swapped) {
|
|
__glXSwapQueryVersionReply(client, &reply);
|
|
} else {
|
|
WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
|
|
}
|
|
|
|
res = Success ;
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res;
|
|
}
|
|
|
|
int
|
|
ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT (&req->length);
|
|
__GLX_SWAP_INT (&req->majorVersion);
|
|
__GLX_SWAP_INT (&req->minorVersion);
|
|
return ephyrGLXQueryVersion (a_cl, a_pc) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
|
|
GLbyte *a_pc,
|
|
Bool a_do_swap)
|
|
{
|
|
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
|
|
ClientPtr client = a_cl->client;
|
|
xGLXGetVisualConfigsReply reply;
|
|
int32_t *props_buf=NULL, num_visuals=0,
|
|
num_props=0, res=BadImplementation, i=0,
|
|
props_per_visual_size=0,
|
|
props_buf_size=0;
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
if (!ephyrHostGLXGetVisualConfigs (req->screen,
|
|
&num_visuals,
|
|
&num_props,
|
|
&props_buf_size,
|
|
&props_buf)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
|
|
goto out ;
|
|
}
|
|
EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
|
|
|
|
reply.numVisuals = num_visuals;
|
|
reply.numProps = num_props;
|
|
reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
|
|
reply.type = X_Reply;
|
|
reply.sequenceNumber = client->sequence;
|
|
|
|
if (a_do_swap) {
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
__GLX_SWAP_INT(&reply.length);
|
|
__GLX_SWAP_INT(&reply.numVisuals);
|
|
__GLX_SWAP_INT(&reply.numProps);
|
|
__GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
|
|
}
|
|
WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
|
|
props_per_visual_size = props_buf_size/num_visuals ;
|
|
for (i=0; i < num_visuals; i++) {
|
|
WriteToClient (client,
|
|
props_per_visual_size,
|
|
(char*)props_buf +i*props_per_visual_size);
|
|
}
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
xfree (props_buf) ;
|
|
props_buf = NULL ;
|
|
|
|
return res ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
|
|
GLbyte *a_pc,
|
|
Bool a_do_swap)
|
|
{
|
|
xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
|
|
ClientPtr client = a_cl->client;
|
|
xGLXGetVisualConfigsReply reply;
|
|
int32_t *props_buf=NULL, num_visuals=0,
|
|
num_props=0, res=BadImplementation, i=0,
|
|
props_per_visual_size=0,
|
|
props_buf_size=0;
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
|
|
&num_visuals,
|
|
&num_props,
|
|
&props_buf_size,
|
|
&props_buf)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
|
|
goto out ;
|
|
}
|
|
EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
|
|
|
|
reply.numVisuals = num_visuals;
|
|
reply.numProps = num_props;
|
|
reply.length = props_buf_size >> 2;
|
|
reply.type = X_Reply;
|
|
reply.sequenceNumber = client->sequence;
|
|
|
|
if (a_do_swap) {
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
__GLX_SWAP_INT(&reply.length);
|
|
__GLX_SWAP_INT(&reply.numVisuals);
|
|
__GLX_SWAP_INT(&reply.numProps);
|
|
__GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
|
|
}
|
|
WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
|
|
props_per_visual_size = props_buf_size/num_visuals ;
|
|
for (i=0; i < num_visuals; i++) {
|
|
WriteToClient (client,
|
|
props_per_visual_size,
|
|
&((char*)props_buf)[i*props_per_visual_size]);
|
|
}
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
xfree (props_buf) ;
|
|
props_buf = NULL ;
|
|
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
|
|
}
|
|
|
|
|
|
int
|
|
ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
int res=BadImplementation ;
|
|
xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
|
|
EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
|
|
goto out ;
|
|
}
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT (&req->length);
|
|
__GLX_SWAP_INT (&req->major);
|
|
__GLX_SWAP_INT (&req->minor);
|
|
__GLX_SWAP_INT (&req->numbytes);
|
|
|
|
return ephyrGLXClientInfo (a_cl, a_pc) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
int res = BadImplementation ;
|
|
ClientPtr client = a_cl->client;
|
|
xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
|
|
xGLXQueryServerStringReply reply;
|
|
char *server_string=NULL, *buf=NULL;
|
|
int length=0 ;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
if (!ephyrHostGLXGetStringFromServer (req->screen,
|
|
req->name,
|
|
EPHYR_HOST_GLX_QueryServerString,
|
|
&server_string)) {
|
|
EPHYR_LOG_ERROR ("failed to query string from host\n") ;
|
|
goto out ;
|
|
}
|
|
EPHYR_LOG ("string: %s\n", server_string) ;
|
|
length= strlen (server_string) + 1;
|
|
reply.type = X_Reply ;
|
|
reply.sequenceNumber = client->sequence ;
|
|
reply.length = __GLX_PAD (length) >> 2 ;
|
|
reply.n = length ;
|
|
buf = xcalloc (reply.length << 2, 1);
|
|
if (!buf) {
|
|
EPHYR_LOG_ERROR ("failed to allocate string\n;");
|
|
return BadAlloc;
|
|
}
|
|
memcpy (buf, server_string, length);
|
|
|
|
WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
|
|
WriteToClient(client, (int)(reply.length << 2), server_string);
|
|
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
xfree (server_string) ;
|
|
server_string = NULL;
|
|
|
|
xfree (buf);
|
|
buf = NULL;
|
|
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
EPHYR_LOG_ERROR ("not yet implemented\n") ;
|
|
return BadImplementation ;
|
|
}
|
|
|
|
|
|
int
|
|
ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
|
|
{
|
|
int res=BadImplementation;
|
|
EphyrHostWindowAttributes host_w_attrs ;
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
if (a_do_swap) {
|
|
__GLX_SWAP_SHORT(&a_req->length);
|
|
__GLX_SWAP_INT(&a_req->context);
|
|
__GLX_SWAP_INT(&a_req->visual);
|
|
__GLX_SWAP_INT(&a_req->screen);
|
|
__GLX_SWAP_INT(&a_req->shareList);
|
|
}
|
|
|
|
EPHYR_LOG ("context creation requested. localid:%d, "
|
|
"screen:%d, visual:%d, direct:%d\n",
|
|
(int)a_req->context, (int)a_req->screen,
|
|
(int)a_req->visual, (int)a_req->isDirect) ;
|
|
|
|
memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
|
|
if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
|
|
&host_w_attrs)) {
|
|
EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
|
|
goto out ;
|
|
}
|
|
|
|
EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
|
|
|
|
if (!ephyrHostGLXCreateContext (a_req->screen,
|
|
host_w_attrs.visualid,
|
|
a_req->context,
|
|
a_req->shareList,
|
|
a_req->isDirect)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
|
|
goto out ;
|
|
}
|
|
res = Success;
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
|
|
{
|
|
xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
|
|
|
|
return ephyrGLXCreateContextReal (req, FALSE) ;
|
|
}
|
|
|
|
int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
|
|
{
|
|
xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
|
|
return ephyrGLXCreateContextReal (req, TRUE) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
|
|
GLbyte *a_pc,
|
|
Bool a_do_swap)
|
|
{
|
|
int res=BadImplementation;
|
|
ClientPtr client = a_cl->client;
|
|
xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
|
|
|
|
EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
|
|
if (!ephyrHostDestroyContext (req->context)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
|
|
client->errorValue = req->context ;
|
|
goto out ;
|
|
}
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
|
|
{
|
|
int res=BadImplementation;
|
|
xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
|
|
xGLXMakeCurrentReply reply ;
|
|
DrawablePtr drawable=NULL;
|
|
int rc=0;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
rc = dixLookupDrawable (&drawable,
|
|
req->drawable,
|
|
a_cl->client,
|
|
0,
|
|
DixReadAccess);
|
|
EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
|
|
EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
|
|
EPHYR_LOG ("screen nummber requested:%d\n",
|
|
drawable->pScreen->myNum) ;
|
|
|
|
memset (&reply, 0, sizeof (reply)) ;
|
|
if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
|
|
req->context,
|
|
req->oldContextTag,
|
|
(int*)&reply.contextTag)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
|
|
goto out;
|
|
}
|
|
reply.length = 0;
|
|
reply.type = X_Reply;
|
|
reply.sequenceNumber = a_cl->client->sequence;
|
|
if (a_do_swap) {
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
__GLX_SWAP_INT(&reply.length);
|
|
__GLX_SWAP_INT(&reply.contextTag);
|
|
}
|
|
WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
|
|
|
|
res = Success ;
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
|
|
{
|
|
ClientPtr client=NULL ;
|
|
int context_tag=0, name=0, res=BadImplementation, length=0 ;
|
|
char *string=NULL;
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
client = a_cl->client ;
|
|
|
|
if (a_do_swap) {
|
|
__GLX_SWAP_INT (a_pc + 4);
|
|
__GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
|
|
}
|
|
context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
|
|
a_pc += __GLX_SINGLE_HDR_SIZE;
|
|
name = *(GLenum*)(a_pc + 0);
|
|
EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
|
|
if (!ephyrHostGLXGetStringFromServer (context_tag,
|
|
name,
|
|
EPHYR_HOST_GLX_GetString,
|
|
&string)) {
|
|
EPHYR_LOG_ERROR ("failed to get string from server\n") ;
|
|
goto out ;
|
|
}
|
|
if (string) {
|
|
length = strlen (string) + 1;
|
|
EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
|
|
} else {
|
|
EPHYR_LOG ("got string: string (null)\n") ;
|
|
}
|
|
__GLX_BEGIN_REPLY (length);
|
|
__GLX_PUT_SIZE (length);
|
|
__GLX_SEND_HEADER ();
|
|
if (a_do_swap) {
|
|
__GLX_SWAP_REPLY_SIZE ();
|
|
__GLX_SWAP_REPLY_HEADER ();
|
|
}
|
|
WriteToClient (client, length, (char *)string);
|
|
|
|
res = Success ;
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
|
|
{
|
|
int res=BadImplementation;
|
|
xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
|
|
GLenum int_name ;
|
|
int value=0 ;
|
|
GLint answer_buf_room[200];
|
|
GLint *buf=NULL ;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
a_pc += __GLX_SINGLE_HDR_SIZE;
|
|
|
|
int_name = *(GLenum*) (a_pc+0) ;
|
|
if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
|
|
goto out ;
|
|
}
|
|
buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
|
|
answer_buf_room,
|
|
sizeof (answer_buf_room),
|
|
4) ;
|
|
|
|
if (!buf) {
|
|
EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
|
|
res = BadAlloc ;
|
|
goto out ;
|
|
}
|
|
__glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
|
|
}
|
|
|
|
static int
|
|
ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
|
|
{
|
|
int res=BadImplementation;
|
|
ClientPtr client = a_cl->client;
|
|
xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
|
|
xGLXIsDirectReply reply;
|
|
int is_direct=0 ;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
memset (&reply, 0, sizeof (reply)) ;
|
|
if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
|
|
EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
|
|
goto out ;
|
|
}
|
|
reply.isDirect = is_direct ;
|
|
reply.length = 0;
|
|
reply.type = X_Reply;
|
|
reply.sequenceNumber = client->sequence;
|
|
WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
|
|
res = Success ;
|
|
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return res ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
|
|
}
|
|
|
|
int
|
|
ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
|
|
{
|
|
return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
|
|
}
|