Merge remote-tracking branch 'daniels/master'

This commit is contained in:
Keith Packard 2012-10-04 11:39:46 -07:00
commit f179b13b91
4 changed files with 267 additions and 49 deletions

View File

@ -180,8 +180,13 @@ ProcXISelectEvents(ClientPtr client)
if (CLIENT_ID(iclient->resource) == client->index)
continue;
dixLookupDevice(&tmp, evmask->deviceid, serverClient,
DixReadAccess);
if (evmask->deviceid == XIAllDevices)
tmp = inputInfo.all_devices;
else if (evmask->deviceid == XIAllMasterDevices)
tmp = inputInfo.all_master_devices;
else
dixLookupDevice(&tmp, evmask->deviceid, serverClient,
DixReadAccess);
if (!tmp)
return BadImplementation; /* this shouldn't happen */

View File

@ -61,10 +61,16 @@ 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 ephyrGLXCreateNewContext(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXCreateNewContextSwap(__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 ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXMakeContextCurrentSwap(__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);
@ -108,6 +114,9 @@ ephyrHijackGLXExtension(void)
dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext;
dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap;
dispatch_functions[X_GLXCreateNewContext][0] = ephyrGLXCreateNewContext;
dispatch_functions[X_GLXCreateNewContext][1] = ephyrGLXCreateNewContextSwap;
dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext;
dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap;
@ -123,14 +132,24 @@ ephyrHijackGLXExtension(void)
dispatch_functions[61][0] = ephyrGLXGetIntegerv;
dispatch_functions[61][1] = ephyrGLXGetIntegervSwap;
dispatch_functions[X_GLXMakeContextCurrent][0] =
ephyrGLXMakeContextCurrent;
dispatch_functions[X_GLXMakeContextCurrent][1] =
ephyrGLXMakeContextCurrentSwap;
/*
* 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;
dispatch_functions[89][0] = ephyrGLXMakeCurrentReadSGI;
dispatch_functions[89][1] = ephyrGLXMakeCurrentReadSGISwap;
EPHYR_LOG("hijacked glx entry points to forward requests to host X\n");
return TRUE;
}
@ -445,7 +464,8 @@ ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap)
if (!ephyrHostGLXCreateContext(a_req->screen,
host_w_attrs.visualid,
a_req->context,
a_req->shareList, a_req->isDirect)) {
a_req->shareList, 0,
a_req->isDirect, X_GLXCreateContext)) {
EPHYR_LOG_ERROR("ephyrHostGLXCreateContext() failed\n");
goto out;
}
@ -455,6 +475,45 @@ ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap)
return res;
}
static int
ephyrGLXCreateNewContextReal(xGLXCreateNewContextReq * a_req, Bool a_do_swap)
{
int res = BadImplementation;
__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->fbconfig);
__GLX_SWAP_INT(&a_req->screen);
__GLX_SWAP_INT(&a_req->renderType);
__GLX_SWAP_INT(&a_req->shareList);
}
EPHYR_LOG("context creation requested. localid:%d, "
"screen:%d, fbconfig:%d, renderType:%d, direct:%d\n",
(int) a_req->context, (int) a_req->screen,
(int) a_req->fbconfig, (int) a_req->renderType,
(int) a_req->isDirect);
if (!ephyrHostGLXCreateContext(a_req->screen,
a_req->fbconfig,
a_req->context,
a_req->shareList, a_req->renderType,
a_req->isDirect, X_GLXCreateNewContext)) {
EPHYR_LOG_ERROR("ephyrHostGLXCreateNewContext() failed\n");
goto out;
}
res = Success;
out:
EPHYR_LOG("leave\n");
return res;
}
int
ephyrGLXCreateContext(__GLXclientState * cl, GLbyte * pc)
{
@ -471,6 +530,22 @@ ephyrGLXCreateContextSwap(__GLXclientState * cl, GLbyte * pc)
return ephyrGLXCreateContextReal(req, TRUE);
}
int
ephyrGLXCreateNewContext(__GLXclientState * cl, GLbyte * pc)
{
xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
return ephyrGLXCreateNewContextReal(req, FALSE);
}
int
ephyrGLXCreateNewContextSwap(__GLXclientState * cl, GLbyte * pc)
{
xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
return ephyrGLXCreateNewContextReal(req, TRUE);
}
static int
ephyrGLXDestroyContextReal(__GLXclientState * a_cl,
GLbyte * a_pc, Bool a_do_swap)
@ -505,26 +580,34 @@ ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc)
}
static int
ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLXDrawable write,
GLXDrawable read, GLXContextTag ctx,
GLXContextTag old_ctx, Bool a_do_swap)
{
int res = BadImplementation;
xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
xGLXMakeCurrentReply reply;
DrawablePtr drawable = NULL;
GLXContextTag contextTag = 0;
int rc = 0;
DrawablePtr drawableR = NULL, drawableW = NULL;
GLXContextTag new_ctx = 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);
res = dixLookupDrawable(&drawableW, write, a_cl->client, 0, DixReadAccess);
EPHYR_RETURN_VAL_IF_FAIL(drawableW, BadValue);
EPHYR_RETURN_VAL_IF_FAIL(drawableW->pScreen, BadValue);
EPHYR_LOG("screen nummber requested:%d\n", drawableW->pScreen->myNum);
if (!ephyrHostGLXMakeCurrent(hostx_get_window(drawable->pScreen->myNum),
req->context,
req->oldContextTag,
(int *) &contextTag)) {
if (read != write) {
res = dixLookupDrawable(&drawableR, read, a_cl->client, 0,
DixReadAccess);
EPHYR_RETURN_VAL_IF_FAIL(drawableR, BadValue);
EPHYR_RETURN_VAL_IF_FAIL(drawableR->pScreen, BadValue);
}
else {
drawableR = drawableW;
}
if (!ephyrHostGLXMakeCurrent(hostx_get_window(drawableW->pScreen->myNum),
hostx_get_window(drawableR->pScreen->myNum),
ctx, old_ctx, (int *) &new_ctx)) {
EPHYR_LOG_ERROR("ephyrHostGLXMakeCurrent() failed\n");
goto out;
}
@ -532,7 +615,7 @@ ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
.type = X_Reply,
.sequenceNumber = a_cl->client->sequence,
.length = 0,
.contextTag = contextTag
.contextTag = new_ctx
};
if (a_do_swap) {
__GLX_DECLARE_SWAP_VARIABLES;
@ -551,13 +634,71 @@ ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
int
ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
{
return ephyrGLXMakeCurrentReal(a_cl, a_pc, FALSE);
xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
req->context, req->oldContextTag, FALSE);
}
int
ephyrGLXMakeCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc)
{
return ephyrGLXMakeCurrentReal(a_cl, a_pc, TRUE);
xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT(&req->drawable);
__GLX_SWAP_INT(&req->context);
__GLX_SWAP_INT(&req->oldContextTag);
return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
req->context, req->oldContextTag, TRUE);
}
int
ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc)
{
xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) a_pc;
return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readable,
req->context, req->oldContextTag, FALSE);
}
int
ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc)
{
xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) a_pc;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT(&req->drawable);
__GLX_SWAP_INT(&req->readable);
__GLX_SWAP_INT(&req->context);
__GLX_SWAP_INT(&req->oldContextTag);
return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readable,
req->context, req->oldContextTag, TRUE);
}
int
ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
{
xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) a_pc;
return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readdrawable,
req->context, req->oldContextTag, FALSE);
}
int
ephyrGLXMakeContextCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc)
{
xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) a_pc;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT(&req->drawable);
__GLX_SWAP_INT(&req->readdrawable);
__GLX_SWAP_INT(&req->context);
__GLX_SWAP_INT(&req->oldContextTag);
return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readdrawable,
req->context, req->oldContextTag, TRUE);
}
static int

View File

@ -52,6 +52,8 @@
#include "ephyrlog.h"
#include "hostx.h"
static int glx_major, glx_minor;
enum VisualConfRequestType {
EPHYR_GET_FB_CONFIG,
EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
@ -99,6 +101,12 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
EPHYR_RETURN_VAL_IF_FAIL(a_major && a_minor, FALSE);
EPHYR_LOG("enter\n");
if (glx_major) {
*a_major = glx_major;
*a_minor = glx_minor;
return TRUE;
}
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
EPHYR_LOG_ERROR("failed to get major opcode\n");
goto out;
@ -117,8 +125,8 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
UnlockDisplay(dpy);
SyncHandle();
*a_major = reply.majorVersion;
*a_minor = reply.minorVersion;
*a_major = glx_major = reply.majorVersion;
*a_minor = glx_minor = reply.minorVersion;
EPHYR_LOG("major:%d, minor:%d\n", *a_major, *a_minor);
@ -431,17 +439,20 @@ ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
Bool
ephyrHostGLXCreateContext(int a_screen,
int a_visual_id,
int a_generic_id,
int a_context_id,
int a_share_list_ctxt_id, Bool a_direct)
int a_share_list_ctxt_id,
int a_render_type,
Bool a_direct,
int code)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int major_opcode = 0, remote_context_id = 0;
xGLXCreateContextReq *req;
EPHYR_LOG("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
a_screen, a_visual_id, a_context_id, a_direct);
EPHYR_LOG("enter. screen:%d, generic_id:%d, contextid:%d, rendertype:%d, "
"direct:%d\n", a_screen, a_generic_id, a_context_id,
a_render_type, a_direct);
if (!hostx_allocate_resource_id_peer(a_context_id, &remote_context_id)) {
EPHYR_LOG_ERROR("failed to peer the context id %d host X",
@ -456,15 +467,38 @@ ephyrHostGLXCreateContext(int a_screen,
LockDisplay(dpy);
/* Send the glXCreateContext request */
GetReq(GLXCreateContext, req);
req->reqType = major_opcode;
req->glxCode = X_GLXCreateContext;
req->context = remote_context_id;
req->visual = a_visual_id;
req->screen = DefaultScreen(dpy);
req->shareList = a_share_list_ctxt_id;
req->isDirect = a_direct;
switch (code) {
case X_GLXCreateContext: {
/* Send the glXCreateContext request */
xGLXCreateContextReq *req;
GetReq(GLXCreateContext, req);
req->reqType = major_opcode;
req->glxCode = X_GLXCreateContext;
req->context = remote_context_id;
req->visual = a_generic_id;
req->screen = DefaultScreen(dpy);
req->shareList = a_share_list_ctxt_id;
req->isDirect = a_direct;
}
case X_GLXCreateNewContext: {
/* Send the glXCreateNewContext request */
xGLXCreateNewContextReq *req;
GetReq(GLXCreateNewContext, req);
req->reqType = major_opcode;
req->glxCode = X_GLXCreateNewContext;
req->context = remote_context_id;
req->fbconfig = a_generic_id;
req->screen = DefaultScreen(dpy);
req->renderType = a_render_type;
req->shareList = a_share_list_ctxt_id;
req->isDirect = a_direct;
}
default:
/* This should never be reached !*/
EPHYR_LOG("Internal error! Invalid CreateContext code!\n");
}
UnlockDisplay(dpy);
SyncHandle();
@ -512,20 +546,19 @@ ephyrHostDestroyContext(int a_ctxt_id)
}
Bool
ephyrHostGLXMakeCurrent(int a_drawable,
ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
int a_glx_ctxt_id, int a_old_ctxt_tag, int *a_ctxt_tag)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int32_t major_opcode = 0;
int remote_glx_ctxt_id = 0;
xGLXMakeCurrentReq *req;
xGLXMakeCurrentReply reply;
EPHYR_RETURN_VAL_IF_FAIL(a_ctxt_tag, FALSE);
EPHYR_LOG("enter. drawable:%d, context:%d, oldtag:%d\n",
a_drawable, a_glx_ctxt_id, a_old_ctxt_tag);
EPHYR_LOG("enter. drawable:%d, read:%d, context:%d, oldtag:%d\n",
a_drawable, a_readable, a_glx_ctxt_id, a_old_ctxt_tag);
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
EPHYR_LOG_ERROR("failed to get major opcode\n");
@ -538,12 +571,48 @@ ephyrHostGLXMakeCurrent(int a_drawable,
LockDisplay(dpy);
GetReq(GLXMakeCurrent, req);
req->reqType = major_opcode;
req->glxCode = X_GLXMakeCurrent;
req->drawable = a_drawable;
req->context = remote_glx_ctxt_id;
req->oldContextTag = a_old_ctxt_tag;
/* If both drawables are the same, use the old MakeCurrent request.
* Otherwise, if we have GLX 1.3 or higher, use the MakeContextCurrent
* request which supports separate read and draw targets. Failing that,
* try the SGI MakeCurrentRead extension. Logic cribbed from Mesa. */
if (a_drawable == a_readable) {
xGLXMakeCurrentReq *req;
GetReq(GLXMakeCurrent, req);
req->reqType = major_opcode;
req->glxCode = X_GLXMakeCurrent;
req->drawable = a_drawable;
req->context = remote_glx_ctxt_id;
req->oldContextTag = a_old_ctxt_tag;
}
else if (glx_major > 1 || glx_minor >= 3) {
xGLXMakeContextCurrentReq *req;
GetReq(GLXMakeContextCurrent, req);
req->reqType = major_opcode;
req->glxCode = X_GLXMakeContextCurrent;
req->drawable = a_drawable;
req->readdrawable = a_readable;
req->context = remote_glx_ctxt_id;
req->oldContextTag = a_old_ctxt_tag;
}
else {
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXMakeCurrentReadSGIReq *req;
GetReqExtra(GLXVendorPrivateWithReply,
(sz_xGLXMakeCurrentReadSGIReq -
sz_xGLXVendorPrivateWithReplyReq),
vpreq);
req = (xGLXMakeCurrentReadSGIReq *) vpreq;
req->reqType = major_opcode;
req->glxCode = X_GLXVendorPrivateWithReply;
req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
req->drawable = a_drawable;
req->readable = a_readable;
req->context = remote_glx_ctxt_id;
req->oldContextTag = a_old_ctxt_tag;
}
memset(&reply, 0, sizeof(reply));
if (!_XReply(dpy, (xReply *) & reply, 0, False)) {

View File

@ -55,13 +55,16 @@ Bool ephyrHostGLXGetMajorOpcode(int32_t * a_opcode);
Bool ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
const char *a_extension_list);
Bool ephyrHostGLXCreateContext(int a_screen,
int a_visual_id,
int a_generic_id,
int a_context_id,
int a_shared_list_ctx_id, Bool a_direct);
int a_share_list_ctxt_id,
int a_render_type,
Bool a_direct,
int code);
Bool ephyrHostDestroyContext(int a_ctxt_id);
Bool ephyrHostGLXMakeCurrent(int a_drawable, int a_glx_ctxt_id,
Bool ephyrHostGLXMakeCurrent(int a_drawable, int a_readable, int a_glx_ctxt_id,
int a_olg_ctxt_tag, int *a_ctxt_tag);
Bool ephyrHostGetIntegerValue(int a_current_context_tag, int a_int, int *a_val);