Xephyr: Make glxinfo work on the ATI R200 free driver.

* hw/kdrive/ephyr/ephyr.c:
	  (EphyrDuplicateVisual): when duplicating the
	  visual, copy the color component masks and the class
	  from the hostX
	  (EphyrMirrorHostVisuals): don't mix blue and green mask.
	* hw/kdrive/ephyr/ephyrdri.c: add more logs.
	  (ephyrDRICreateDrawable): actually implement this.
	  for the moment it creates a DRI drawable for the hostX window,
	  no matter what drawable this call was issued for.
	  (ephyrDRIGetDrawableInfo): actually implemented this.
	  for the moment the drawable info queried for its attrs is the
	  Xephyr main main window.
	* hw/kdrive/ephyr/ephyrdriext.c:
	  (ProcXF86DRIGetDrawableInfo): properly hook this dispatch
	  function to the ephyrDRIGetDrawableInfo() function.
	* hw/kdrive/ephyr/ephyrglxext.c: add a bunch of GLX implementation hooks
	  here. Hijack some of the xserver GLX hooks with them. Still need to
	  properly support byteswapped clients though.
	* hw/kdrive/ephyr/ephyrhostglx.c,h: actually implemented the protocol
	  level forwarding functions used by the GLX entr points in
	  ephyrglxext.c. Here as well, there are a bunch of them, but we are
	  far from having implemented all the GLX calls.
	* hw/kdrive/ephyr/hostx.c,h:
	  (hostx_get_window_attributes): added this new entry point
	  (hostx_allocate_resource_id_peer): added this to keep track of
	   resource IDs peers: one member of the peer is in Xephyr, the other
	   is in host X.
	  (hostx_get_resource_id_peer): ditto.
This commit is contained in:
Dodji Seketeli 2007-08-30 23:54:49 +02:00 committed by Dodji Seketeli
parent 8c78df0ea3
commit 4dd4be99df
9 changed files with 801 additions and 40 deletions

View File

@ -1095,6 +1095,10 @@ EphyrDuplicateVisual (unsigned int a_screen,
/*copy the visual found*/
memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
new_visual.vid = a_new_id ;
new_visual.class = a_class ;
new_visual.redMask = a_red_mask ;
new_visual.greenMask = a_green_mask ;
new_visual.blueMask = a_blue_mask ;
found_visual = TRUE ;
EPHYR_LOG ("found a visual that matches visual id: %d\n",
a_new_id) ;
@ -1195,8 +1199,8 @@ EphyrMirrorHostVisuals (void)
visuals[i].bits_per_rgb,
visuals[i].colormap_size,
visuals[i].red_mask,
visuals[i].blue_mask,
visuals[i].green_mask,
visuals[i].blue_mask,
visuals[i].visualid)) {
EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
(int)visuals[i].visualid) ;

View File

@ -40,6 +40,8 @@
#include "ephyrdri.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include "dixstruct.h"
#include "pixmapstr.h"
#ifndef TRUE
#define TRUE 1
@ -55,9 +57,10 @@ ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
Display *dpy=hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRIQueryDirectRenderingCapable (dpy, a_screen, a_is_capable) ;
EPHYR_LOG ("leave\n") ;
EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
return is_ok ;
}
@ -70,9 +73,16 @@ ephyrDRIOpenConnection (int a_screen,
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_LOG ("enter\n") ;
EPHYR_RETURN_VAL_IF_FAIL (a_bus_id_string, FALSE) ;
EPHYR_LOG ("enter. screen:%d\n", a_screen) ;
is_ok = XF86DRIOpenConnection (dpy, a_screen, a_sarea, a_bus_id_string) ;
EPHYR_LOG ("leave\n") ;
if (*a_bus_id_string) {
EPHYR_LOG ("leave. bus_id_string:%s, is_ok:%d\n",
*a_bus_id_string, is_ok) ;
} else {
EPHYR_LOG ("leave. bus_id_string:null, is_ok:%d\n",
is_ok) ;
}
return is_ok ;
}
@ -84,7 +94,7 @@ ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRIAuthConnection (dpy, a_screen, a_magic) ;
EPHYR_LOG ("leave\n") ;
EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
return is_ok ;
}
@ -140,7 +150,7 @@ ephyrDRICreateContext (int a_screen,
Bool is_ok=FALSE ;
Visual v;
EPHYR_LOG ("enter\n") ;
EPHYR_LOG ("enter. screen:%d, visual:%d\n", a_screen, a_visual_id) ;
memset (&v, 0, sizeof (v)) ;
v.visualid = a_visual_id ;
is_ok = XF86DRICreateContext (dpy,
@ -170,10 +180,14 @@ ephyrDRICreateDrawable (int a_screen,
int a_drawable,
drm_drawable_t *a_hw_drawable)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display () ;
int host_win=hostx_get_window () ;
EPHYR_LOG ("enter\n") ;
EPHYR_LOG_ERROR ("not implemented yet\n") ;
EPHYR_LOG ("leave\n") ;
return FALSE ;
is_ok = XF86DRICreateDrawable (dpy, a_screen, host_win, a_hw_drawable) ;
EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
return is_ok ;
}
Bool
@ -187,7 +201,7 @@ ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
Bool
ephyrDRIGetDrawableInfo (int a_screen,
int a_drawable,
void *a_drawable,
unsigned int *a_index,
unsigned int *a_stamp,
int *a_x,
@ -198,13 +212,38 @@ ephyrDRIGetDrawableInfo (int a_screen,
drm_clip_rect_t **a_clip_rects,
int *a_back_x,
int *a_back_y,
int *num_back_clip_rects,
int *a_num_back_clip_rects,
drm_clip_rect_t **a_back_clip_rects)
{
Bool is_ok=FALSE;
DrawablePtr drawable = a_drawable ;
EphyrHostWindowAttributes attrs ;
EPHYR_RETURN_VAL_IF_FAIL (drawable && a_x && a_y && a_w && a_h
&& a_num_clip_rects,
FALSE) ;
EPHYR_LOG ("enter\n") ;
EPHYR_LOG_ERROR ("not implemented yet\n") ;
memset (&attrs, 0, sizeof (attrs)) ;
if (!hostx_get_window_attributes (hostx_get_window (), &attrs)) {
EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
goto out;
}
*a_x = drawable->x + attrs.x;
*a_y = drawable->y + attrs.y;
*a_w = drawable->width + attrs.width ;
*a_h = drawable->height + attrs.height ;
*a_num_clip_rects = 0 ;
*a_clip_rects = NULL ;
*a_back_x = 0;
*a_back_y = 0 ;
*a_num_back_clip_rects = 0 ;
*a_back_clip_rects = NULL ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return FALSE ;
return is_ok ;
}
Bool

View File

@ -51,7 +51,7 @@ Bool ephyrDRICreateDrawable (int a_screen,
drm_drawable_t *a_hw_drawable) ;
Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
Bool ephyrDRIGetDrawableInfo (int a_screen,
int a_drawable,
void* /*DrawablePtr*/ a_drawable,
unsigned int *a_index,
unsigned int *a_stamp,
int *a_x,

View File

@ -447,11 +447,10 @@ static int
ProcXF86DRIGetDrawableInfo (register ClientPtr client)
{
xXF86DRIGetDrawableInfoReply rep;
DrawablePtr pDrawable;
int X, Y, W, H;
DrawablePtr drawable;
int X, Y, W, H, backX, backY, rc;
drm_clip_rect_t * pClipRects, *pClippedRects;
drm_clip_rect_t * pBackClipRects;
int backX, backY, rc;
EPHYR_LOG ("enter\n") ;
REQUEST(xXF86DRIGetDrawableInfoReq);
@ -469,25 +468,25 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
* We must properly do the mapping
* between xephyr drawable and the host drawable
*/
rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
DixReadAccess);
rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
DixReadAccess);
if (rc != Success)
return rc;
if (!ephyrDRIGetDrawableInfo (stuff->screen,
0 /*should be the drawable in hostx*/,
(unsigned int*)&rep.drawableTableIndex,
(unsigned int*)&rep.drawableTableStamp,
(int*)&X,
(int*)&Y,
(int*)&W,
(int*)&H,
(int*)&rep.numClipRects,
&pClipRects,
&backX,
&backY,
(int*)&rep.numBackClipRects,
&pBackClipRects)) {
drawable/*should be the drawable in hostx*/,
(unsigned int*)&rep.drawableTableIndex,
(unsigned int*)&rep.drawableTableStamp,
(int*)&X,
(int*)&Y,
(int*)&W,
(int*)&H,
(int*)&rep.numClipRects,
&pClipRects,
&backX,
&backY,
(int*)&rep.numBackClipRects,
&pBackClipRects)) {
return BadValue;
}

View File

@ -37,7 +37,9 @@
#include <GL/glxproto.h>
#include "GL/glx/glxserver.h"
#include "GL/glx/indirect_table.h"
#include "GL/glx/indirect_util.h"
#include "GL/glx/unpack.h"
#include "hostx.h"
#ifdef XEPHYR_DRI
@ -61,6 +63,18 @@ 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)
@ -83,7 +97,6 @@ ephyrHijackGLXExtension (void)
dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
@ -91,6 +104,24 @@ ephyrHijackGLXExtension (void)
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
*/
@ -332,6 +363,7 @@ ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
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 ;
@ -377,5 +409,288 @@ 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 (), &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 ;
EPHYR_LOG ("enter\n") ;
memset (&reply, 0, sizeof (reply)) ;
if (!ephyrHostGLXMakeCurrent (hostx_get_window (),
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) ;
EPHYR_LOG ("got string: string:%s\n", string) ;
} 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 ("enter\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 ;
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:
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) ;
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:
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) ;
}
#endif /*XEPHYR_DRI*/

View File

@ -36,10 +36,10 @@
#include <GL/internal/glcore.h>
#include <GL/glxproto.h>
#include <GL/glxint.h>
#include "hostx.h"
#include "ephyrhostglx.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include "hostx.h"
#ifdef XEPHYR_DRI
enum VisualConfRequestType {
@ -107,6 +107,7 @@ out:
* the real protocol packets used to request a string from the server have
* an identical binary layout. The only difference between them is the
* meaning of the \c for_whom field and the value of the \c glxCode.
* (this has been copied from the mesa source code)
*/
typedef struct GLXGenericGetString {
CARD8 reqType;
@ -124,20 +125,33 @@ typedef struct GLXGenericGetString {
Bool
ephyrHostGLXGetStringFromServer (int a_screen_number,
int a_string_name,
enum EphyrHostGLXGetStringOps a_op,
char **a_string)
{
Bool is_ok=FALSE ;
Display *dpy = hostx_get_display () ;
xGLXGenericGetStringReq *req=NULL;
xGLXSingleReply reply;
int length=0, numbytes=0, major_opcode=0;
int length=0, numbytes=0, major_opcode=0, get_string_op=0;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
EPHYR_LOG ("enter\n") ;
switch (a_op) {
case EPHYR_HOST_GLX_QueryServerString:
get_string_op = X_GLXQueryServerString;
break ;
case EPHYR_HOST_GLX_GetString:
get_string_op = X_GLsop_GetString;
break ;
default:
EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
goto out ;
}
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
return FALSE ;
goto out ;
}
EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
@ -150,7 +164,7 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
*/
GetReq (GLXGenericGetString, req);
req->reqType = major_opcode;
req->glxCode = X_GLXQueryServerString;
req->glxCode = get_string_op;
req->for_whom = a_screen_number;
req->name = a_string_name;
@ -162,18 +176,21 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
*a_string = (char *) Xmalloc( numbytes );
if (*a_string != NULL) {
if (_XRead (dpy, *a_string, numbytes)) {
UnlockDisplay (dpy);
SyncHandle ();
EPHYR_LOG_ERROR ("read failed\n") ;
goto out ;
}
length -= numbytes;
}
_XEatData (dpy, length) ;
UnlockDisplay (dpy);
SyncHandle ();
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return TRUE ;
return is_ok ;
}
static Bool
@ -378,5 +395,258 @@ out:
return is_ok ;
}
Bool
ephyrHostGLXCreateContext (int a_screen,
int a_visual_id,
int a_context_id,
int a_share_list_ctxt_id,
Bool a_direct)
{
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) ;
if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) {
EPHYR_LOG_ERROR ("failed to peer the context id %d host X",
remote_context_id) ;
goto out ;
}
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
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 = a_screen;
req->shareList = a_share_list_ctxt_id;
req->isDirect = a_direct;
is_ok = TRUE ;
out:
UnlockDisplay (dpy);
SyncHandle ();
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostDestroyContext (int a_ctxt_id)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display ();
int major_opcode=0, remote_ctxt_id=0 ;
xGLXDestroyContextReq *req=NULL;
EPHYR_LOG ("enter:%d\n", a_ctxt_id) ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) {
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
goto out ;
}
EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ;
LockDisplay (dpy);
GetReq (GLXDestroyContext,req);
req->reqType = major_opcode;
req->glxCode = X_GLXDestroyContext;
req->context = remote_ctxt_id;
UnlockDisplay (dpy);
SyncHandle ();
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostGLXMakeCurrent (int a_drawable,
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) ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) {
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
goto out ;
}
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;
memset (&reply, 0, sizeof (reply)) ;
if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
goto out ;
}
*a_ctxt_tag = reply.contextTag ;
is_ok = TRUE ;
out:
UnlockDisplay (dpy);
SyncHandle ();
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
#define X_GLXSingle 0
#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
*((INT8 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
*((INT16 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
*((INT32 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
*((FLOAT32 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_READ_XREPLY() \
(void) _XReply(dpy, (xReply*) &reply, 0, False)
#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
a = (cast) reply.retval
#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
a = (GLint) reply.size
#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
*p = *(GLbyte *)&reply.pad3;
#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
*p = *(GLshort *)&reply.pad3;
#define EPHYR_GLX_SINGLE_GET_LONG(p) \
*p = *(GLint *)&reply.pad3;
#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
*p = *(GLfloat *)&reply.pad3;
Bool
ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val)
{
Bool is_ok=FALSE;
Display *dpy = hostx_get_display () ;
int major_opcode=0, size=0;
xGLXSingleReq *req=NULL;
xGLXSingleReply reply;
unsigned char* pc=NULL ;
EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
LockDisplay (dpy) ;
GetReqExtra (GLXSingle, 4, req) ;
req->reqType = major_opcode ;
req->glxCode = X_GLsop_GetIntegerv ;
req->contextTag = a_current_context_tag;
pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ;
EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ;
EPHYR_GLX_SINGLE_READ_XREPLY () ;
EPHYR_GLX_SINGLE_GET_SIZE (size) ;
if (!size) {
UnlockDisplay (dpy) ;
SyncHandle () ;
EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ;
goto out ;
}
EPHYR_GLX_SINGLE_GET_LONG (a_val) ;
UnlockDisplay (dpy) ;
SyncHandle () ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostIsContextDirect (int a_ctxt_id,
int *a_is_direct)
{
Bool is_ok=FALSE;
Display *dpy = hostx_get_display () ;
xGLXIsDirectReq *req=NULL;
xGLXIsDirectReply reply;
int major_opcode=0, remote_glx_ctxt_id=0;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
goto out ;
}
memset (&reply, 0, sizeof (reply)) ;
/* Send the glXIsDirect request */
LockDisplay (dpy);
GetReq (GLXIsDirect,req);
req->reqType = major_opcode;
req->glxCode = X_GLXIsDirect;
req->context = remote_glx_ctxt_id;
if (!_XReply (dpy, (xReply*) &reply, 0, False)) {
EPHYR_LOG_ERROR ("fail in reading reply from host\n") ;
UnlockDisplay (dpy);
SyncHandle ();
goto out ;
}
UnlockDisplay (dpy);
SyncHandle ();
*a_is_direct = reply.isDirect ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
#endif /*XEPHYR_DRI*/

View File

@ -28,9 +28,16 @@
#ifndef __EPHYRHOSTGLX_H__
#define __EPHYRHOSTGLX_H__
enum EphyrHostGLXGetStringOps {
EPHYR_HOST_GLX_UNDEF,
EPHYR_HOST_GLX_QueryServerString,
EPHYR_HOST_GLX_GetString,
};
Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
int a_string_name,
enum EphyrHostGLXGetStringOps a_op,
char **a_string) ;
Bool ephyrHostGLXGetVisualConfigs (int a_screen,
int32_t *a_num_visuals,
@ -46,6 +53,24 @@ ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
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_context_id,
int a_shared_list_ctx_id,
Bool a_direct) ;
Bool ephyrHostDestroyContext (int a_ctxt_id) ;
Bool ephyrHostGLXMakeCurrent (int a_drawable, 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) ;
Bool ephyrHostIsContextDirect (int a_ctxt_id,
int *a_is_direct) ;
#endif /*__EPHYRHOSTGLX_H__*/

View File

@ -969,6 +969,27 @@ hostx_get_window(void)
return HostX.win ;
}
int
hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attrs)
{
XWindowAttributes attrs ;
memset (&attrs, 0, sizeof (attrs)) ;
if (!XGetWindowAttributes (hostx_get_display (),
a_window,
&attrs)) {
return FALSE ;
}
a_attrs->x = attrs.x ;
a_attrs->y = attrs.y ;
a_attrs->width = attrs.width ;
a_attrs->height = attrs.height ;
if (attrs.visual)
a_attrs->visualid = attrs.visual->visualid ;
return TRUE ;
}
int
hostx_get_extension_info (const char *a_ext_name,
int *a_major_opcode,
@ -1039,3 +1060,75 @@ out:
}
typedef struct {
int is_valid ;
int local_id ;
int remote_id ;
} ResourcePair ;
#define RESOURCE_PEERS_SIZE 1024*10
static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
int
hostx_allocate_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id)
{
int i=0 ;
ResourcePair *peer=NULL ;
Display *dpy=hostx_get_display ();
/*
* first make sure a resource peer
* does not exist already for
* a_local_resource_id
*/
for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
if (resource_peers[i].is_valid
&& resource_peers[i].local_id == a_local_resource_id) {
peer = &resource_peers[i] ;
break ;
}
}
/*
* find one free peer entry, an feed it with
*/
if (!peer) {
for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
if (!resource_peers[i].is_valid) {
peer = &resource_peers[i] ;
break ;
}
}
if (peer) {
peer->remote_id = XAllocID (dpy);
peer->local_id = a_local_resource_id ;
peer->is_valid = TRUE ;
}
}
if (peer) {
*a_remote_resource_id = peer->remote_id ;
return TRUE ;
}
return FALSE ;
}
int
hostx_get_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id)
{
int i=0 ;
ResourcePair *peer=NULL ;
for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
if (resource_peers[i].is_valid
&& resource_peers[i].local_id == a_local_resource_id) {
peer = &resource_peers[i] ;
break ;
}
}
if (peer) {
*a_remote_resource_id = peer->remote_id ;
return TRUE ;
}
return FALSE ;
}

View File

@ -104,6 +104,12 @@ typedef struct {
int bits_per_rgb;
} EphyrHostVisualInfo;
typedef struct {
int x, y;
int width, height ;
int visualid ;
} EphyrHostWindowAttributes;
int
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
@ -190,6 +196,9 @@ hostx_get_display(void) ;
int
hostx_get_window(void) ;
int
hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr) ;
int
hostx_get_extension_info (const char *a_ext_name,
int *a_major_opcode,
@ -198,4 +207,11 @@ hostx_get_extension_info (const char *a_ext_name,
int
hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
int *a_num_entries) ;
int
hostx_allocate_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id) ;
int
hostx_get_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id) ;
#endif