4ba76a7e2b
We can now launch GL or XV apps in any of the Xephyr screens we want. * hw/kdrive/ephyr/hostx.c,h: (hostx_get_window): (hostx_create_window): make these functions be screen number aware. * hw/kdrive/ephyr/XF86dri.c : fix some compiler warnings. * hw/kdrive/ephyr/ephyrdri.c: (ephyrDRIQueryDirectRenderingCapable), (ephyrDRIOpenConnection), (ephyrDRIAuthConnection), (ephyrDRICloseConnection), (ephyrDRIGetClientDriverName), (ephyrDRICreateContext), (ephyrDRIDestroyContext), (ephyrDRICreateDrawable), (ephyrDRIGetDrawableInfo), (ephyrDRIGetDeviceInfo): in all those functions, don't forward the screen number we receive - from the client - to the host X. We (Xephyr) are always targetting the same X display screen, which is the one Xephyr got launched against. So we enforce that in the code. * hw/kdrive/ephyr/ephyrdriext.c: (EphyrMirrorHostVisuals): make this duplicate the visuals of the host X default screen into a given Xephyr screen. This way we have a chance to update the visuals of all Xephyr screen to make them mirror those of the host X. (many other places): specify screen number where required by the api change in hostx.h. * hw/kdrive/ephyr/ephyrglxext.c: specify screen number where required by the api change in hostx.h * hw/kdrive/ephyr/ephyrhostglx.c: don't forward the screen number we receive - from the client - to the host X. We (Xephyr) are always targetting the same X display screen, which is the one Xephyr got launched against. So we enforce that in the code. * hw/kdrive/ephyr/ephyrhostvideo.c,h: take in account the screen number received from the client app. This is useful to know on which Xephyr screen we need to display video stuff. * hw/kdrive/ephyr/ephyrvideo.c: update this to reflect the API change in hw/kdrive/ephyr/ephyrhostvideo.h. (ephyrSetPortAttribute): when parameters are not valid - they exceed their validity range - send them to the host anyway and do not return an error to clients. Some host expose buggy validity range, so rejecting client for that is too harsh.
688 lines
20 KiB
C
688 lines
20 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.
|
|
*
|
|
* a lots of the content of this file has been adapted from the mesa source
|
|
* code.
|
|
* Authors:
|
|
* Dodji Seketeli <dodji@openedhand.com>
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <kdrive-config.h>
|
|
#endif
|
|
|
|
#include <X11/Xlibint.h>
|
|
#include <GL/glx.h>
|
|
#include <GL/internal/glcore.h>
|
|
#include <GL/glxproto.h>
|
|
#include <GL/glxint.h>
|
|
#include "ephyrhostglx.h"
|
|
#define _HAVE_XALLOC_DECLS
|
|
#include "ephyrlog.h"
|
|
#include "hostx.h"
|
|
|
|
#ifdef XEPHYR_DRI
|
|
enum VisualConfRequestType {
|
|
EPHYR_GET_FB_CONFIG,
|
|
EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
|
|
EPHYR_GET_VISUAL_CONFIGS
|
|
|
|
};
|
|
|
|
static Bool ephyrHostGLXGetVisualConfigsInternal
|
|
(enum VisualConfRequestType a_type,
|
|
int32_t a_screen,
|
|
int32_t *a_num_visuals,
|
|
int32_t *a_num_props,
|
|
int32_t *a_props_buf_size,
|
|
int32_t **a_props_buf);
|
|
Bool
|
|
ephyrHostGLXGetMajorOpcode (int *a_opcode)
|
|
{
|
|
Bool is_ok=FALSE ;
|
|
Display *dpy=hostx_get_display () ;
|
|
static int opcode ;
|
|
int first_event_return=0, first_error_return=0;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
|
|
EPHYR_LOG ("enter\n") ;
|
|
if (!opcode) {
|
|
if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
|
|
&first_event_return, &first_error_return)) {
|
|
EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
|
|
goto out ;
|
|
}
|
|
}
|
|
*a_opcode = opcode ;
|
|
is_ok = TRUE ;
|
|
out:
|
|
EPHYR_LOG ("release\n") ;
|
|
return is_ok ;
|
|
}
|
|
|
|
Bool
|
|
ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
|
|
{
|
|
Bool is_ok = FALSE ;
|
|
Display *dpy = hostx_get_display () ;
|
|
int major_opcode=0;
|
|
xGLXQueryVersionReq *req=NULL;
|
|
xGLXQueryVersionReply reply;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
|
|
EPHYR_LOG ("enter\n") ;
|
|
|
|
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
|
|
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
|
|
goto out ;
|
|
}
|
|
EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
|
|
|
|
/* Send the glXQueryVersion request */
|
|
memset (&reply, 0, sizeof (reply)) ;
|
|
LockDisplay (dpy);
|
|
GetReq (GLXQueryVersion, req);
|
|
req->reqType = major_opcode;
|
|
req->glxCode = X_GLXQueryVersion;
|
|
req->majorVersion = 2;
|
|
req->minorVersion = 1;
|
|
_XReply(dpy, (xReply*) &reply, 0, False);
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
*a_major = reply.majorVersion ;
|
|
*a_minor = reply.minorVersion ;
|
|
|
|
EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ;
|
|
|
|
is_ok = TRUE ;
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return is_ok ;
|
|
}
|
|
|
|
/**
|
|
* GLX protocol structure for the ficticious "GXLGenericGetString" request.
|
|
*
|
|
* This is a non-existant protocol packet. It just so happens that all of
|
|
* 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;
|
|
CARD8 glxCode;
|
|
CARD16 length B16;
|
|
CARD32 for_whom B32;
|
|
CARD32 name B32;
|
|
} xGLXGenericGetStringReq;
|
|
|
|
/* These defines are only needed to make the GetReq macro happy.
|
|
*/
|
|
#define sz_xGLXGenericGetStringReq 12
|
|
#define X_GLXGenericGetString 0
|
|
|
|
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, 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;
|
|
EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n",
|
|
a_string_name, a_screen_number) ;
|
|
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") ;
|
|
goto out ;
|
|
}
|
|
EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
|
|
|
|
LockDisplay (dpy);
|
|
|
|
/* All of the GLX protocol requests for getting a string from the server
|
|
* look the same. The exact meaning of the a_for_whom field is usually
|
|
* either the screen number (for glXQueryServerString) or the context tag
|
|
* (for GLXSingle).
|
|
*/
|
|
GetReq (GLXGenericGetString, req);
|
|
req->reqType = major_opcode;
|
|
req->glxCode = get_string_op;
|
|
req->for_whom = DefaultScreen (dpy);
|
|
req->name = a_string_name;
|
|
|
|
_XReply (dpy, (xReply *)&reply, 0, False);
|
|
|
|
length = reply.length * 4;
|
|
numbytes = reply.size;
|
|
EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
|
|
|
|
*a_string = (char *) Xmalloc (numbytes +1);
|
|
if (!a_string) {
|
|
EPHYR_LOG_ERROR ("allocation failed\n") ;
|
|
goto out;
|
|
}
|
|
|
|
memset (*a_string, 0, numbytes+1) ;
|
|
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 ();
|
|
EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n",
|
|
a_string_name, *a_string, numbytes) ;
|
|
|
|
is_ok = TRUE ;
|
|
out:
|
|
EPHYR_LOG ("leave\n") ;
|
|
return is_ok ;
|
|
}
|
|
|
|
static Bool
|
|
ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
|
|
int32_t a_screen,
|
|
int32_t *a_num_visuals,
|
|
int32_t *a_num_props,
|
|
int32_t *a_props_buf_size,
|
|
int32_t **a_props_buf)
|
|
{
|
|
Bool is_ok = FALSE ;
|
|
Display *dpy = hostx_get_display () ;
|
|
xGLXGetVisualConfigsReq *req;
|
|
xGLXGetFBConfigsReq *fb_req;
|
|
xGLXVendorPrivateWithReplyReq *vpreq;
|
|
xGLXGetFBConfigsSGIXReq *sgi_req;
|
|
xGLXGetVisualConfigsReply reply;
|
|
char *server_glx_version=NULL,
|
|
*server_glx_extensions=NULL ;
|
|
int j=0,
|
|
screens=0,
|
|
major_opcode=0,
|
|
num_props=0,
|
|
num_visuals=0,
|
|
props_buf_size=0,
|
|
props_per_visual_size=0;
|
|
int32_t *props_buf=NULL;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
|
|
|
|
screens = ScreenCount (dpy);
|
|
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
|
|
EPHYR_LOG_ERROR ("failed to get opcode\n") ;
|
|
goto out ;
|
|
}
|
|
|
|
LockDisplay(dpy);
|
|
switch (a_type) {
|
|
case EPHYR_GET_FB_CONFIG:
|
|
GetReq(GLXGetFBConfigs,fb_req);
|
|
fb_req->reqType = major_opcode;
|
|
fb_req->glxCode = X_GLXGetFBConfigs;
|
|
fb_req->screen = DefaultScreen (dpy);
|
|
break;
|
|
|
|
case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
|
|
GetReqExtra(GLXVendorPrivateWithReply,
|
|
sz_xGLXGetFBConfigsSGIXReq
|
|
-
|
|
sz_xGLXVendorPrivateWithReplyReq,
|
|
vpreq);
|
|
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
|
|
sgi_req->reqType = major_opcode;
|
|
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
|
|
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
|
|
sgi_req->screen = DefaultScreen (dpy);
|
|
break;
|
|
|
|
case EPHYR_GET_VISUAL_CONFIGS:
|
|
GetReq(GLXGetVisualConfigs,req);
|
|
req->reqType = major_opcode;
|
|
req->glxCode = X_GLXGetVisualConfigs;
|
|
req->screen = DefaultScreen (dpy);
|
|
break;
|
|
}
|
|
|
|
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
|
|
EPHYR_LOG_ERROR ("unknown error\n") ;
|
|
UnlockDisplay(dpy);
|
|
goto out ;
|
|
}
|
|
if (!reply.numVisuals) {
|
|
EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
|
|
UnlockDisplay(dpy);
|
|
goto out ;
|
|
}
|
|
num_visuals = reply.numVisuals ;
|
|
|
|
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
|
|
* FIXME: FBconfigs?
|
|
*/
|
|
/* Check number of properties */
|
|
num_props = reply.numProps;
|
|
if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
|
|
(num_props > __GLX_MAX_CONFIG_PROPS)) {
|
|
/* Huh? Not in protocol defined limits. Punt */
|
|
EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
|
|
UnlockDisplay(dpy);
|
|
goto out ;
|
|
}
|
|
|
|
if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
|
|
num_props *= 2;
|
|
}
|
|
props_per_visual_size = num_props * __GLX_SIZE_INT32;
|
|
props_buf_size = props_per_visual_size * reply.numVisuals;
|
|
props_buf = malloc (props_buf_size) ;
|
|
for (j = 0; j < reply.numVisuals; j++) {
|
|
if (_XRead (dpy,
|
|
&((char*)props_buf)[j*props_per_visual_size],
|
|
props_per_visual_size) != Success) {
|
|
EPHYR_LOG_ERROR ("read failed\n") ;
|
|
}
|
|
}
|
|
UnlockDisplay(dpy);
|
|
|
|
*a_num_visuals = num_visuals ;
|
|
*a_num_props = reply.numProps ;
|
|
*a_props_buf_size = props_buf_size ;
|
|
*a_props_buf = props_buf ;
|
|
is_ok = TRUE ;
|
|
|
|
out:
|
|
if (server_glx_version) {
|
|
XFree (server_glx_version) ;
|
|
server_glx_version = NULL ;
|
|
}
|
|
if (server_glx_extensions) {
|
|
XFree (server_glx_extensions) ;
|
|
server_glx_extensions = NULL ;
|
|
}
|
|
SyncHandle () ;
|
|
return is_ok;
|
|
}
|
|
|
|
Bool
|
|
ephyrHostGLXGetVisualConfigs (int32_t a_screen,
|
|
int32_t *a_num_visuals,
|
|
int32_t *a_num_props,
|
|
int32_t *a_props_buf_size,
|
|
int32_t **a_props_buf)
|
|
{
|
|
Bool is_ok = FALSE;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS,
|
|
a_screen,
|
|
a_num_visuals,
|
|
a_num_props,
|
|
a_props_buf_size,
|
|
a_props_buf) ;
|
|
|
|
EPHYR_LOG ("leave:%d\n", is_ok) ;
|
|
return is_ok;
|
|
}
|
|
|
|
Bool
|
|
ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
|
|
int32_t *a_num_visuals,
|
|
int32_t *a_num_props,
|
|
int32_t *a_props_buf_size,
|
|
int32_t **a_props_buf)
|
|
{
|
|
Bool is_ok=FALSE ;
|
|
EPHYR_LOG ("enter\n") ;
|
|
is_ok = ephyrHostGLXGetVisualConfigsInternal
|
|
(EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
|
|
a_screen,
|
|
a_num_visuals,
|
|
a_num_props,
|
|
a_props_buf_size,
|
|
a_props_buf) ;
|
|
EPHYR_LOG ("leave\n") ;
|
|
return is_ok ;
|
|
}
|
|
|
|
Bool
|
|
ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
|
|
const char* a_extension_list)
|
|
{
|
|
Bool is_ok = FALSE ;
|
|
Display *dpy = hostx_get_display () ;
|
|
xGLXClientInfoReq *req;
|
|
int size;
|
|
int32_t major_opcode=0 ;
|
|
|
|
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
|
|
|
|
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
|
|
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
|
|
goto out ;
|
|
}
|
|
|
|
LockDisplay (dpy);
|
|
|
|
GetReq (GLXClientInfo,req);
|
|
req->reqType = major_opcode;
|
|
req->glxCode = X_GLXClientInfo;
|
|
req->major = a_major;
|
|
req->minor = a_minor;
|
|
|
|
size = strlen (a_extension_list) + 1;
|
|
req->length += (size + 3) >> 2;
|
|
req->numbytes = size;
|
|
Data (dpy, a_extension_list, size);
|
|
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
|
|
is_ok=TRUE ;
|
|
|
|
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 = DefaultScreen (dpy);
|
|
req->shareList = a_share_list_ctxt_id;
|
|
req->isDirect = a_direct;
|
|
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
is_ok = TRUE ;
|
|
|
|
out:
|
|
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") ;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
goto out ;
|
|
}
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
*a_ctxt_tag = reply.contextTag ;
|
|
EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ;
|
|
is_ok = TRUE ;
|
|
|
|
out:
|
|
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*/
|
|
|