Merge remote-tracking branch 'anholt/ephyr-fixes'

This commit is contained in:
Keith Packard 2013-10-04 14:04:48 -07:00
commit f3b529bf25
21 changed files with 1687 additions and 4164 deletions

View File

@ -2116,12 +2116,12 @@ if test "$KDRIVE" = yes; then
AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
fi
XEPHYR_REQUIRED_LIBS="x11 >= 1.6 $LIBXEXT xau xdmcp"
XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms"
if test "x$XV" = xyes; then
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv"
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xcb-xv"
fi
if test "x$DRI" = xyes && test "x$GLX" = xyes; then
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS libdrm xcb-glx xcb-xf86dri > 1.6"
fi
if test "x$XEPHYR" = xauto; then

View File

@ -1,3 +1,24 @@
# Copyright © 2013 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
SUBDIRS = man
AM_CPPFLAGS = \
@ -9,81 +30,45 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/exa
if XV
LIBXEPHYR_HOSTXV=libxephyr-hostxv.la
XV_SRCS = ephyrvideo.c
endif
if DRI
LIBXEPHYR_HOSTDRI=libxephyr-hostdri.la
endif
noinst_LTLIBRARIES = libxephyr-hostx.la $(LIBXEPHYR_HOSTXV) $(LIBXEPHYR_HOSTDRI) libxephyr.la
bin_PROGRAMS = Xephyr
HOSTX_SRCS = \
hostx.c \
hostx.h
HOSTVIDEO_SRCS = \
ephyrvideo.c \
ephyrhostvideo.c \
ephyrhostvideo.h
HOSTDRI_SRCS = \
DRI_SRCS = \
ephyrdriext.c \
ephyrdriext.h \
ephyrdri.c \
ephyrdri.h \
XF86dri.c \
xf86dri.h \
ephyrglxext.c \
ephyrglxext.h \
ephyrhostglx.c \
ephyrhostglx.h
XEPHYR_SRCS = \
ephyr.c \
ephyr.h \
ephyrlog.h \
ephyr_draw.c \
os.c
libxephyr_hostx_la_SOURCES = $(HOSTX_SRCS)
if XV
libxephyr_hostxv_la_SOURCES = $(HOSTVIDEO_SRCS)
ephyrhostglx.h \
$()
endif
if DRI
libxephyr_hostdri_la_SOURCES = $(HOSTDRI_SRCS)
endif
libxephyr_la_SOURCES = $(XEPHYR_SRCS)
bin_PROGRAMS = Xephyr
Xephyr_SOURCES = \
ephyrinit.c
ephyr.c \
ephyr.h \
ephyrlog.h \
ephyr_draw.c \
os.c \
ephyrinit.c \
hostx.c \
hostx.h \
$(XV_SRCS) \
$(DRI_SRCS) \
$()
Xephyr_LDADD = \
libxephyr.la \
libxephyr-hostx.la \
$(LIBXEPHYR_HOSTXV) \
$(LIBXEPHYR_HOSTDRI) \
$(top_builddir)/exa/libexa.la \
@KDRIVE_LIBS@ \
@XEPHYR_LIBS@
Xephyr_DEPENDENCIES = \
libxephyr.la \
libxephyr-hostx.la \
$(LIBXEPHYR_HOSTXV) \
$(LIBXEPHYR_HOSTDRI) \
@KDRIVE_LOCAL_LIBS@
Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@
Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
relink:
$(AM_V_at)rm -f $(bin_PROGRAMS) && $(MAKE) $(bin_PROGRAMS)
EXTRA_DIST = \
$(HOSTVIDEO_SRCS) \
$(HOSTDRI_SRCS)

View File

@ -1,654 +0,0 @@
/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Jens Owen <jens@tungstengraphics.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/
/*
* This file has been copied from the mesa source tree and a little bit
* modified by:
*
* Dodji Seketeli <dodji@openedhand.com>
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
/*
* including some server headers (like kdrive-config.h)
* might define the macro _XSERVER64
* on 64 bits machines. That macro must _NOT_ be defined for Xlib
* client code, otherwise bad things happen.
* So let's undef that macro if necessary.
*/
#ifdef _XSERVER64
#undef _XSERVER64
#endif
/* THIS IS NOT AN X CONSORTIUM STANDARD */
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <GL/glx.h>
#include "xf86dri.h"
#include <X11/dri/xf86driproto.h>
#include <limits.h>
static XExtensionInfo _xf86dri_info_data;
static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
static char xf86dri_extension_name[] = XF86DRINAME;
#define XF86DRICheckExtension(dpy,i,val) \
XextCheckExtension (dpy, i, xf86dri_extension_name, val)
/*****************************************************************************
* *
* private utility routines *
* *
*****************************************************************************/
static int close_display(Display * dpy, XExtCodes * extCodes);
static /* const */ XExtensionHooks xf86dri_extension_hooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
close_display, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
static
XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
xf86dri_extension_name,
&xf86dri_extension_hooks, 0, NULL)
static
XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
/*****************************************************************************
* *
* public XFree86-DRI Extension routines *
* *
*****************************************************************************/
#if 0
#include <stdio.h>
#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
#else
#define TRACE(msg)
#endif
Bool
XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable);
Bool
XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable);
Bool
XF86DRIQueryExtension(Display * dpy, int *event_basep, int *error_basep)
{
XExtDisplayInfo *info = find_display(dpy);
TRACE("QueryExtension...");
if (XextHasExtension(info)) {
*event_basep = info->codes->first_event;
*error_basep = info->codes->first_error;
TRACE("QueryExtension... return True");
return True;
}
else {
TRACE("QueryExtension... return False");
return False;
}
}
Bool
XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
int *patchVersion)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIQueryVersionReply rep;
xXF86DRIQueryVersionReq *req;
TRACE("QueryVersion...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIQueryVersion, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIQueryVersion;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryVersion... return False");
return False;
}
*majorVersion = rep.majorVersion;
*minorVersion = rep.minorVersion;
*patchVersion = rep.patchVersion;
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryVersion... return True");
return True;
}
Bool
XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen, Bool *isCapable)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIQueryDirectRenderingCapableReply rep;
xXF86DRIQueryDirectRenderingCapableReq *req;
TRACE("QueryDirectRenderingCapable...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIQueryDirectRenderingCapable, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
req->screen = screen;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryDirectRenderingCapable... return False");
return False;
}
*isCapable = rep.isCapable;
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryDirectRenderingCapable... return True");
return True;
}
Bool
XF86DRIOpenConnection(Display * dpy, int screen,
drm_handle_t * hSAREA, char **busIdString)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIOpenConnectionReply rep;
xXF86DRIOpenConnectionReq *req;
TRACE("OpenConnection...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIOpenConnection, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIOpenConnection;
req->screen = screen;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("OpenConnection... return False");
return False;
}
*hSAREA = rep.hSAREALow;
if (sizeof(drm_handle_t) == 8) {
int shift = 32; /* var to prevent warning on next line */
*hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
}
if (rep.length) {
if (rep.busIdStringLength < INT_MAX)
*busIdString = calloc(rep.busIdStringLength + 1, 1);
else
*busIdString = NULL;
if (*busIdString == NULL) {
_XEatDataWords(dpy, rep.length);
UnlockDisplay(dpy);
SyncHandle();
TRACE("OpenConnection... return False");
return False;
}
_XReadPad(dpy, *busIdString, rep.busIdStringLength);
}
else {
*busIdString = NULL;
}
UnlockDisplay(dpy);
SyncHandle();
TRACE("OpenConnection... return True");
return True;
}
Bool
XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIAuthConnectionReq *req;
xXF86DRIAuthConnectionReply rep;
TRACE("AuthConnection...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIAuthConnection, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIAuthConnection;
req->screen = screen;
req->magic = magic;
rep.authenticated = 0;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse) || !rep.authenticated) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("AuthConnection... return False");
return False;
}
UnlockDisplay(dpy);
SyncHandle();
TRACE("AuthConnection... return True");
return True;
}
Bool
XF86DRICloseConnection(Display * dpy, int screen)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRICloseConnectionReq *req;
TRACE("CloseConnection...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRICloseConnection, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRICloseConnection;
req->screen = screen;
UnlockDisplay(dpy);
SyncHandle();
TRACE("CloseConnection... return True");
return True;
}
Bool
XF86DRIGetClientDriverName(Display * dpy, int screen,
int *ddxDriverMajorVersion,
int *ddxDriverMinorVersion,
int *ddxDriverPatchVersion, char **clientDriverName)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIGetClientDriverNameReply rep;
xXF86DRIGetClientDriverNameReq *req;
TRACE("GetClientDriverName...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIGetClientDriverName, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIGetClientDriverName;
req->screen = screen;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetClientDriverName... return False");
return False;
}
*ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
*ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
*ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
if (rep.length) {
if (rep.clientDriverNameLength < INT_MAX)
*clientDriverName = calloc(rep.clientDriverNameLength + 1, 1);
else
*clientDriverName = NULL;
if (*clientDriverName == NULL) {
_XEatDataWords(dpy, rep.length);
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetClientDriverName... return False");
return False;
}
_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
}
else {
*clientDriverName = NULL;
}
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetClientDriverName... return True");
return True;
}
Bool
XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID,
XID *context, drm_context_t * hHWContext)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRICreateContextReply rep;
xXF86DRICreateContextReq *req;
TRACE("CreateContext...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRICreateContext, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRICreateContext;
req->visual = configID;
req->screen = screen;
*context = XAllocID(dpy);
req->context = *context;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("CreateContext... return False");
return False;
}
*hHWContext = rep.hHWContext;
UnlockDisplay(dpy);
SyncHandle();
TRACE("CreateContext... return True");
return True;
}
Bool
XF86DRICreateContext(Display * dpy, int screen, Visual * visual,
XID *context, drm_context_t * hHWContext)
{
return XF86DRICreateContextWithConfig(dpy, screen, visual->visualid,
context, hHWContext);
}
GLboolean
XF86DRIDestroyContext(Display * dpy, int screen, XID context)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIDestroyContextReq *req;
TRACE("DestroyContext...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIDestroyContext, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIDestroyContext;
req->screen = screen;
req->context = context;
UnlockDisplay(dpy);
SyncHandle();
TRACE("DestroyContext... return True");
return True;
}
GLboolean
XF86DRICreateDrawable(Display * dpy, int screen,
XID drawable, drm_drawable_t * hHWDrawable)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRICreateDrawableReply rep;
xXF86DRICreateDrawableReq *req;
TRACE("CreateDrawable...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRICreateDrawable, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRICreateDrawable;
req->screen = screen;
req->drawable = drawable;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("CreateDrawable... return False");
return False;
}
*hHWDrawable = rep.hHWDrawable;
UnlockDisplay(dpy);
SyncHandle();
TRACE("CreateDrawable... return True");
return True;
}
static int
noopErrorHandler(Display * dpy, XErrorEvent * xerr)
{
return 0;
}
GLboolean
XF86DRIDestroyDrawable(Display * dpy, int screen, XID drawable)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIDestroyDrawableReq *req;
int (*oldXErrorHandler) (Display *, XErrorEvent *);
TRACE("DestroyDrawable...");
XF86DRICheckExtension(dpy, info, False);
/* This is called from the DRI driver, which used call it like this
*
* if (windowExists(drawable))
* destroyDrawable(drawable);
*
* which is a textbook race condition - the window may disappear
* from the server between checking for its existance and
* destroying it. Instead we change the semantics of
* __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
* the windows is gone, by wrapping the destroy call in an error
* handler. */
XSync(dpy, GL_FALSE);
oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
LockDisplay(dpy);
GetReq(XF86DRIDestroyDrawable, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIDestroyDrawable;
req->screen = screen;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
XSetErrorHandler(oldXErrorHandler);
TRACE("DestroyDrawable... return True");
return True;
}
Bool
XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
unsigned int *index, unsigned int *stamp,
int *X, int *Y, int *W, int *H,
int *numClipRects, drm_clip_rect_t ** pClipRects,
int *backX, int *backY,
int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIGetDrawableInfoReply rep;
xXF86DRIGetDrawableInfoReq *req = NULL;
int total_rects;
TRACE("GetDrawableInfo...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIGetDrawableInfo, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIGetDrawableInfo;
req->screen = screen;
req->drawable = drawable;
if (!_XReply(dpy, (xReply *) &rep, 1, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetDrawableInfo... return False");
return False;
}
*index = rep.drawableTableIndex;
*stamp = rep.drawableTableStamp;
*X = (int) rep.drawableX;
*Y = (int) rep.drawableY;
*W = (int) rep.drawableWidth;
*H = (int) rep.drawableHeight;
*numClipRects = rep.numClipRects;
total_rects = *numClipRects;
*backX = rep.backX;
*backY = rep.backY;
*numBackClipRects = rep.numBackClipRects;
total_rects += *numBackClipRects;
#if 0
/* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
* backwards compatibility (Because of the >> 2 shift) but the fix
* enables multi-threaded apps to work.
*/
if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
SIZEOF(xGenericReply) +
total_rects * sizeof(drm_clip_rect_t)) +
3) & ~3) >> 2)) {
_XEatDataWords(dpy, rep.length);
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetDrawableInfo... return False");
return False;
}
#endif
if (*numClipRects) {
int len = sizeof(drm_clip_rect_t) * (*numClipRects);
*pClipRects = (drm_clip_rect_t *) calloc(len, 1);
if (*pClipRects)
_XRead(dpy, (char *) *pClipRects, len);
}
else {
*pClipRects = NULL;
}
if (*numBackClipRects) {
int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
*pBackClipRects = (drm_clip_rect_t *) calloc(len, 1);
if (*pBackClipRects)
_XRead(dpy, (char *) *pBackClipRects, len);
}
else {
*pBackClipRects = NULL;
}
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetDrawableInfo... return True");
return True;
}
Bool
XF86DRIGetDeviceInfo(Display * dpy, int screen, drm_handle_t * hFrameBuffer,
int *fbOrigin, int *fbSize, int *fbStride,
int *devPrivateSize, void **pDevPrivate)
{
XExtDisplayInfo *info = find_display(dpy);
xXF86DRIGetDeviceInfoReply rep;
xXF86DRIGetDeviceInfoReq *req;
TRACE("GetDeviceInfo...");
XF86DRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIGetDeviceInfo, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIGetDeviceInfo;
req->screen = screen;
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetDeviceInfo... return False");
return False;
}
*hFrameBuffer = rep.hFrameBufferLow;
if (sizeof(drm_handle_t) == 8) {
int shift = 32; /* var to prevent warning on next line */
*hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
}
*fbOrigin = rep.framebufferOrigin;
*fbSize = rep.framebufferSize;
*fbStride = rep.framebufferStride;
*devPrivateSize = rep.devPrivateSize;
if (rep.length) {
if (!(*pDevPrivate = (void *) calloc(rep.devPrivateSize, 1))) {
_XEatDataWords(dpy, rep.length);
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetDeviceInfo... return False");
return False;
}
_XRead(dpy, (char *) *pDevPrivate, rep.devPrivateSize);
}
else {
*pDevPrivate = NULL;
}
UnlockDisplay(dpy);
SyncHandle();
TRACE("GetDeviceInfo... return True");
return True;
}
Bool
XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable)
{
/* This function and the underlying X protocol are deprecated.
*/
(void) dpy;
(void) screen;
(void) drawable;
return False;
}
Bool
XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable)
{
/* This function and the underlying X protocol are deprecated.
*/
(void) dpy;
(void) screen;
(void) drawable;
return True;
}

View File

@ -26,6 +26,10 @@
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include <xcb/xcb_keysyms.h>
#include <X11/keysym.h>
#include "ephyr.h"
#include "inputstr.h"
@ -33,6 +37,7 @@
#include "ephyrlog.h"
#ifdef XF86DRI
#include <xcb/xf86dri.h>
#include "ephyrdri.h"
#include "ephyrdriext.h"
#include "ephyrglxext.h"
@ -58,6 +63,16 @@ typedef struct _EphyrInputPrivate {
Bool EphyrWantGrayScale = 0;
Bool EphyrWantResize = 0;
Bool
host_has_extension(xcb_extension_t *extension)
{
const xcb_query_extension_reply_t *rep;
rep = xcb_get_extension_data(hostx_get_xcbconn(), extension);
return rep && rep->present;
}
Bool
ephyrInitialize(KdCardInfo * card, EphyrPriv * priv)
{
@ -87,8 +102,9 @@ ephyrCardInit(KdCardInfo * card)
}
Bool
ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
ephyrScreenInitialize(KdScreenInfo *screen)
{
EphyrScrPriv *scrpriv = screen->driver;
int width = 640, height = 480;
CARD32 redMask, greenMask, blueMask;
@ -105,7 +121,7 @@ ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
if (screen->fb.depth < hostx_get_depth()
&& (screen->fb.depth == 24 || screen->fb.depth == 16
|| screen->fb.depth == 8)) {
hostx_set_server_depth(screen, screen->fb.depth);
scrpriv->server_depth = screen->fb.depth;
}
else
ErrorF
@ -168,27 +184,6 @@ ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
return ephyrMapFramebuffer(screen);
}
Bool
ephyrScreenInit(KdScreenInfo * screen)
{
EphyrScrPriv *scrpriv;
scrpriv = calloc(1, sizeof(EphyrScrPriv));
if (!scrpriv)
return FALSE;
screen->driver = scrpriv;
if (!ephyrScreenInitialize(screen, scrpriv)) {
screen->driver = 0;
free(scrpriv);
return FALSE;
}
return TRUE;
}
void *
ephyrWindowLinear(ScreenPtr pScreen,
CARD32 row,
@ -654,7 +649,7 @@ ephyrInitScreen(ScreenPtr pScreen)
}
#endif /*XV*/
#ifdef XF86DRI
if (!ephyrNoDRI && !hostx_has_dri()) {
if (!ephyrNoDRI && !host_has_extension(&xcb_xf86dri_id)) {
EPHYR_LOG("host x does not support DRI. Disabling DRI forwarding\n");
ephyrNoDRI = TRUE;
}
@ -804,13 +799,13 @@ ephyrCrossScreen(ScreenPtr pScreen, Bool entering)
{
}
int ephyrCurScreen; /*current event screen */
ScreenPtr ephyrCursorScreen; /* screen containing the cursor */
static void
ephyrWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
OsBlockSIGIO();
ephyrCurScreen = pScreen->myNum;
ephyrCursorScreen = pScreen;
miPointerWarpCursor(inputInfo.pointer, pScreen, x, y);
OsReleaseSIGIO();
@ -856,123 +851,327 @@ ephyrExposePairedWindow(int a_remote)
}
#endif /* XF86DRI */
static KdScreenInfo *
screen_from_window(Window w)
{
int i = 0;
for (i = 0; i < screenInfo.numScreens; i++) {
ScreenPtr pScreen = screenInfo.screens[i];
KdPrivScreenPtr kdscrpriv = KdGetScreenPriv(pScreen);
KdScreenInfo *screen = kdscrpriv->screen;
EphyrScrPriv *scrpriv = screen->driver;
if (scrpriv->win == w
|| scrpriv->peer_win == w
|| scrpriv->win_pre_existing == w) {
return screen;
}
}
return NULL;
}
static void
ephyrProcessErrorEvent(xcb_generic_event_t *xev)
{
xcb_generic_error_t *e = (xcb_generic_error_t *)xev;
FatalError("X11 error\n"
"Error code: %hhu\n"
"Sequence number: %hu\n"
"Major code: %hhu\tMinor code: %hu\n"
"Error value: %u\n",
e->error_code,
e->sequence,
e->major_code, e->minor_code,
e->resource_id);
}
static void
ephyrProcessExpose(xcb_generic_event_t *xev)
{
xcb_expose_event_t *expose = (xcb_expose_event_t *)xev;
KdScreenInfo *screen = screen_from_window(expose->window);
EphyrScrPriv *scrpriv = screen->driver;
/* Wait for the last expose event in a series of cliprects
* to actually paint our screen.
*/
if (expose->count != 0)
return;
if (scrpriv) {
hostx_paint_rect(scrpriv->screen, 0, 0, 0, 0,
scrpriv->win_width,
scrpriv->win_height);
} else {
EPHYR_LOG_ERROR("failed to get host screen\n");
#ifdef XF86DRI
/*
* We only receive expose events when the expose event
* have be generated for a drawable that is a host X
* window managed by Xephyr. Host X windows managed by
* Xephyr exists for instance when Xephyr is asked to
* create a GL drawable in a DRI environment.
*/
ephyrExposePairedWindow(expose->window);
#endif /* XF86DRI */
}
}
static void
ephyrProcessMouseMotion(xcb_generic_event_t *xev)
{
xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev;
KdScreenInfo *screen = screen_from_window(motion->event);
if (!ephyrMouse ||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
EPHYR_LOG("skipping mouse motion:%d\n", screen->pScreen->myNum);
return;
}
if (ephyrCursorScreen != screen->pScreen) {
EPHYR_LOG("warping mouse cursor. "
"cur_screen%d, motion_screen:%d\n",
ephyrCursorScreen, screen->pScreen->myNum);
ephyrWarpCursor(inputInfo.pointer, screen->pScreen,
motion->event_x, motion->event_y);
}
else {
int x = 0, y = 0;
#ifdef XF86DRI
EphyrWindowPair *pair = NULL;
#endif
EPHYR_LOG("enqueuing mouse motion:%d\n", ephyrCurScreen);
x = motion->event_x;
y = motion->event_y;
EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);
#ifdef XF86DRI
EPHYR_LOG("is this window peered by a gl drawable ?\n");
if (findWindowPairFromRemote(motion->event, &pair)) {
EPHYR_LOG("yes, it is peered\n");
x += pair->local->drawable.x;
y += pair->local->drawable.y;
}
else {
EPHYR_LOG("no, it is not peered\n");
}
EPHYR_LOG("final (x,y):(%d,%d)\n", x, y);
#endif
KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
}
}
static void
ephyrProcessButtonPress(xcb_generic_event_t *xev)
{
xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;
if (!ephyrMouse ||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
EPHYR_LOG("skipping mouse press:%d\n", ephyrCurScreen);
return;
}
ephyrUpdateModifierState(button->state);
/* This is a bit hacky. will break for button 5 ( defined as 0x10 )
* Check KD_BUTTON defines in kdrive.h
*/
mouseState |= 1 << (button->detail - 1);
EPHYR_LOG("enqueuing mouse press:%d\n", ephyrCurScreen);
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
}
static void
ephyrProcessButtonRelease(xcb_generic_event_t *xev)
{
xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;
if (!ephyrMouse ||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
return;
}
ephyrUpdateModifierState(button->state);
mouseState &= ~(1 << (button->detail - 1));
EPHYR_LOG("enqueuing mouse release:%d\n", ephyrCurScreen);
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
}
static void
ephyrProcessKeyPress(xcb_generic_event_t *xev)
{
xcb_key_press_event_t *key = (xcb_key_press_event_t *)xev;
if (!ephyrKbd ||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
return;
}
ephyrUpdateModifierState(key->state);
KdEnqueueKeyboardEvent(ephyrKbd, key->detail, FALSE);
}
static void
ephyrProcessKeyRelease(xcb_generic_event_t *xev)
{
xcb_connection_t *conn = hostx_get_xcbconn();
xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev;
static xcb_key_symbols_t *keysyms;
static int grabbed_screen = -1;
if (!keysyms)
keysyms = xcb_key_symbols_alloc(conn);
if (((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L
|| xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R)
&& (key->state & XCB_MOD_MASK_CONTROL)) ||
((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_L
|| xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_R)
&& (key->state & XCB_MOD_MASK_SHIFT))) {
KdScreenInfo *screen = screen_from_window(key->event);
EphyrScrPriv *scrpriv = screen->driver;
if (grabbed_screen != -1) {
xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME);
xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
grabbed_screen = -1;
hostx_set_win_title(screen,
"(ctrl+shift grabs mouse and keyboard)");
}
else {
/* Attempt grab */
xcb_grab_keyboard_cookie_t kbgrabc =
xcb_grab_keyboard(conn,
TRUE,
scrpriv->win,
XCB_TIME_CURRENT_TIME,
XCB_GRAB_MODE_ASYNC,
XCB_GRAB_MODE_ASYNC);
xcb_grab_keyboard_reply_t *kbgrabr;
xcb_grab_pointer_cookie_t pgrabc =
xcb_grab_pointer(conn,
TRUE,
scrpriv->win,
0,
XCB_GRAB_MODE_ASYNC,
XCB_GRAB_MODE_ASYNC,
scrpriv->win,
XCB_NONE,
XCB_TIME_CURRENT_TIME);
xcb_grab_pointer_reply_t *pgrabr;
kbgrabr = xcb_grab_keyboard_reply(conn, kbgrabc, NULL);
if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) {
xcb_discard_reply(conn, pgrabc.sequence);
xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
} else {
pgrabr = xcb_grab_pointer_reply(conn, pgrabc, NULL);
if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS)
{
xcb_ungrab_keyboard(conn,
XCB_TIME_CURRENT_TIME);
} else {
grabbed_screen = scrpriv->mynum;
hostx_set_win_title
(screen,
"(ctrl+shift releases mouse and keyboard)");
}
}
}
}
if (!ephyrKbd ||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
return;
}
/* Still send the release event even if above has happened server
* will get confused with just an up event. Maybe it would be
* better to just block shift+ctrls getting to kdrive all
* together.
*/
ephyrUpdateModifierState(key->state);
KdEnqueueKeyboardEvent(ephyrKbd, key->detail, TRUE);
}
static void
ephyrProcessConfigureNotify(xcb_generic_event_t *xev)
{
xcb_configure_notify_event_t *configure =
(xcb_configure_notify_event_t *)xev;
KdScreenInfo *screen = screen_from_window(configure->window);
EphyrScrPriv *scrpriv = screen->driver;
if (!scrpriv ||
(scrpriv->win_pre_existing == None && !EphyrWantResize)) {
return;
}
#ifdef RANDR
ephyrResizeScreen(screen->pScreen, configure->width, configure->height);
#endif /* RANDR */
}
void
ephyrPoll(void)
{
EphyrHostXEvent ev;
xcb_connection_t *conn = hostx_get_xcbconn();
while (hostx_get_event(&ev)) {
switch (ev.type) {
case EPHYR_EV_MOUSE_MOTION:
if (!ephyrMouse ||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
EPHYR_LOG("skipping mouse motion:%d\n", ephyrCurScreen);
continue;
}
{
if (ev.data.mouse_motion.screen >= 0
&& (ephyrCurScreen != ev.data.mouse_motion.screen)) {
EPHYR_LOG("warping mouse cursor. "
"cur_screen%d, motion_screen:%d\n",
ephyrCurScreen, ev.data.mouse_motion.screen);
if (ev.data.mouse_motion.screen >= 0) {
ephyrWarpCursor
(inputInfo.pointer,
screenInfo.screens[ev.data.mouse_motion.screen],
ev.data.mouse_motion.x, ev.data.mouse_motion.y);
}
}
else {
int x = 0, y = 0;
#ifdef XF86DRI
EphyrWindowPair *pair = NULL;
#endif
EPHYR_LOG("enqueuing mouse motion:%d\n", ephyrCurScreen);
x = ev.data.mouse_motion.x;
y = ev.data.mouse_motion.y;
EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);
#ifdef XF86DRI
EPHYR_LOG("is this window peered by a gl drawable ?\n");
if (findWindowPairFromRemote(ev.data.mouse_motion.window,
&pair)) {
EPHYR_LOG("yes, it is peered\n");
x += pair->local->drawable.x;
y += pair->local->drawable.y;
}
else {
EPHYR_LOG("no, it is not peered\n");
}
EPHYR_LOG("final (x,y):(%d,%d)\n", x, y);
#endif
KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
}
}
break;
case EPHYR_EV_MOUSE_PRESS:
if (!ephyrMouse ||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
EPHYR_LOG("skipping mouse press:%d\n", ephyrCurScreen);
continue;
}
EPHYR_LOG("enqueuing mouse press:%d\n", ephyrCurScreen);
ephyrUpdateModifierState(ev.key_state);
mouseState |= ev.data.mouse_down.button_num;
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0,
0);
break;
case EPHYR_EV_MOUSE_RELEASE:
if (!ephyrMouse ||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled)
continue;
ephyrUpdateModifierState(ev.key_state);
mouseState &= ~ev.data.mouse_up.button_num;
EPHYR_LOG("enqueuing mouse release:%d\n", ephyrCurScreen);
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0,
0);
break;
case EPHYR_EV_KEY_PRESS:
if (!ephyrKbd ||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled)
continue;
ephyrUpdateModifierState(ev.key_state);
KdEnqueueKeyboardEvent(ephyrKbd, ev.data.key_down.scancode, FALSE);
break;
case EPHYR_EV_KEY_RELEASE:
if (!ephyrKbd ||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled)
continue;
ephyrUpdateModifierState(ev.key_state);
KdEnqueueKeyboardEvent(ephyrKbd, ev.data.key_up.scancode, TRUE);
break;
#ifdef XF86DRI
case EPHYR_EV_EXPOSE:
/*
* We only receive expose events when the expose event have
* be generated for a drawable that is a host X window managed
* by Xephyr. Host X windows managed by Xephyr exists for instance
* when Xephyr is asked to create a GL drawable in a DRI environment.
while (TRUE) {
xcb_generic_event_t *xev = xcb_poll_for_event(conn);
if (!xev) {
/* If our XCB connection has died (for example, our window was
* closed), exit now.
*/
ephyrExposePairedWindow(ev.data.expose.window);
break;
#endif /* XF86DRI */
if (xcb_connection_has_error(conn)) {
CloseWellKnownConnections();
OsCleanup(1);
exit(1);
}
#ifdef RANDR
case EPHYR_EV_CONFIGURE:
ephyrResizeScreen(screenInfo.screens[ev.data.configure.screen],
ev.data.configure.width,
ev.data.configure.height);
break;
#endif /* RANDR */
default:
break;
}
switch (xev->response_type & 0x7f) {
case 0:
ephyrProcessErrorEvent(xev);
break;
case XCB_EXPOSE:
ephyrProcessExpose(xev);
break;
case XCB_MOTION_NOTIFY:
ephyrProcessMouseMotion(xev);
break;
case XCB_KEY_PRESS:
ephyrProcessKeyPress(xev);
break;
case XCB_KEY_RELEASE:
ephyrProcessKeyRelease(xev);
break;
case XCB_BUTTON_PRESS:
ephyrProcessButtonPress(xev);
break;
case XCB_BUTTON_RELEASE:
ephyrProcessButtonRelease(xev);
break;
case XCB_CONFIGURE_NOTIFY:
ephyrProcessConfigureNotify(xev);
break;
}
free(xev);
}
}
@ -1086,7 +1285,7 @@ EphyrKeyboardInit(KdKeyboardInfo * ki)
ki->driverPrivate = (EphyrKbdPrivate *)
calloc(sizeof(EphyrKbdPrivate), 1);
hostx_load_keymap();
if (!ephyrKeySyms.map) {
if (!ephyrKeySyms.minKeyCode) {
ErrorF("Couldn't load keymap from host\n");
return BadAlloc;
}

View File

@ -29,6 +29,7 @@
#include <unistd.h>
#include <signal.h>
#include <libgen.h>
#include <xcb/xcb_image.h>
#include "os.h" /* for OsSignal() */
#include "kdrive.h"
@ -61,10 +62,24 @@ typedef struct _ephyrFakexaPriv {
} EphyrFakexaPriv;
typedef struct _ephyrScrPriv {
/* ephyr server info */
Rotation randr;
Bool shadow;
DamagePtr pDamage;
EphyrFakexaPriv *fakexa;
/* Host X window info */
xcb_window_t win;
xcb_window_t win_pre_existing; /* Set via -parent option like xnest */
xcb_window_t peer_win; /* Used for GL; should be at most one */
xcb_image_t *ximg;
int win_width, win_height;
int server_depth;
unsigned char *fb_data; /* only used when host bpp != server bpp */
xcb_shm_segment_info_t shminfo;
KdScreenInfo *screen;
int mynum; /* Screen number */
} EphyrScrPriv;
extern KdCardFuncs ephyrFuncs;
@ -80,10 +95,7 @@ Bool
ephyrCardInit(KdCardInfo * card);
Bool
ephyrScreenInit(KdScreenInfo * screen);
Bool
ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv);
ephyrScreenInitialize(KdScreenInfo *screen);
Bool
ephyrInitScreen(ScreenPtr pScreen);

View File

@ -29,10 +29,8 @@
#include <kdrive-config.h>
#endif
#include <X11/Xutil.h>
#include <X11/Xlibint.h>
#include <GL/glx.h>
#include "xf86dri.h"
#include <X11/Xdefs.h>
#include <xcb/xf86dri.h>
#include "hostx.h"
#include "ephyrdri.h"
#define _HAVE_XALLOC_DECLS
@ -49,13 +47,21 @@
Bool
ephyrDRIQueryDirectRenderingCapable(int a_screen, Bool *a_is_capable)
{
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
Bool is_ok = FALSE;
xcb_xf86dri_query_direct_rendering_capable_cookie_t cookie;
xcb_xf86dri_query_direct_rendering_capable_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(a_is_capable, FALSE);
EPHYR_LOG("enter\n");
is_ok = XF86DRIQueryDirectRenderingCapable(dpy, DefaultScreen(dpy),
a_is_capable);
cookie = xcb_xf86dri_query_direct_rendering_capable(conn,
hostx_get_screen());
reply = xcb_xf86dri_query_direct_rendering_capable_reply(conn, cookie, NULL);
if (reply) {
is_ok = TRUE;
*a_is_capable = reply->is_capable;
free(reply);
}
EPHYR_LOG("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok);
return is_ok;
@ -65,31 +71,48 @@ Bool
ephyrDRIOpenConnection(int a_screen,
drm_handle_t * a_sarea, char **a_bus_id_string)
{
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
Bool is_ok = FALSE;
xcb_xf86dri_open_connection_cookie_t cookie;
xcb_xf86dri_open_connection_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(a_bus_id_string, FALSE);
EPHYR_LOG("enter. screen:%d\n", a_screen);
is_ok = XF86DRIOpenConnection(dpy, DefaultScreen(dpy),
a_sarea, a_bus_id_string);
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);
cookie = xcb_xf86dri_open_connection(conn, hostx_get_screen());
reply = xcb_xf86dri_open_connection_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_sarea = reply->sarea_handle_low;
if (sizeof(drm_handle_t) == 8) {
int shift = 32;
*a_sarea |= ((drm_handle_t) reply->sarea_handle_high) << shift;
}
*a_bus_id_string = malloc(reply->bus_id_len + 1);
if (!*a_bus_id_string)
goto out;
memcpy(*a_bus_id_string, xcb_xf86dri_open_connection_bus_id(reply), reply->bus_id_len);
*a_bus_id_string[reply->bus_id_len] = '\0';
is_ok = TRUE;
out:
free(reply);
EPHYR_LOG("leave. bus_id_string:%s, is_ok:%d\n", *a_bus_id_string, is_ok);
return is_ok;
}
Bool
ephyrDRIAuthConnection(int a_screen, drm_magic_t a_magic)
{
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
xcb_xf86dri_auth_connection_cookie_t cookie;
xcb_xf86dri_auth_connection_reply_t *reply;
Bool is_ok = FALSE;
EPHYR_LOG("enter\n");
is_ok = XF86DRIAuthConnection(dpy, DefaultScreen(dpy), a_magic);
cookie = xcb_xf86dri_auth_connection(conn, screen, a_magic);
reply = xcb_xf86dri_auth_connection_reply(conn, cookie, NULL);
is_ok = reply->authenticated;
free(reply);
EPHYR_LOG("leave. is_ok:%d\n", is_ok);
return is_ok;
}
@ -97,13 +120,13 @@ ephyrDRIAuthConnection(int a_screen, drm_magic_t a_magic)
Bool
ephyrDRICloseConnection(int a_screen)
{
Display *dpy = hostx_get_display();
Bool is_ok = FALSE;
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
EPHYR_LOG("enter\n");
is_ok = XF86DRICloseConnection(dpy, DefaultScreen(dpy));
xcb_xf86dri_close_connection(conn, screen);
EPHYR_LOG("leave\n");
return is_ok;
return TRUE;
}
Bool
@ -113,7 +136,10 @@ ephyrDRIGetClientDriverName(int a_screen,
int *a_ddx_driver_patch_version,
char **a_client_driver_name)
{
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
xcb_xf86dri_get_client_driver_name_cookie_t cookie;
xcb_xf86dri_get_client_driver_name_reply_t *reply;
Bool is_ok = FALSE;
EPHYR_RETURN_VAL_IF_FAIL(a_ddx_driver_major_version
@ -121,15 +147,27 @@ ephyrDRIGetClientDriverName(int a_screen,
&& a_ddx_driver_patch_version
&& a_client_driver_name, FALSE);
EPHYR_LOG("enter\n");
is_ok = XF86DRIGetClientDriverName(dpy, DefaultScreen(dpy),
a_ddx_driver_major_version,
a_ddx_driver_minor_version,
a_ddx_driver_patch_version,
a_client_driver_name);
cookie = xcb_xf86dri_get_client_driver_name(conn, screen);
reply = xcb_xf86dri_get_client_driver_name_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_ddx_driver_major_version = reply->client_driver_major_version;
*a_ddx_driver_minor_version = reply->client_driver_minor_version;
*a_ddx_driver_patch_version = reply->client_driver_patch_version;
*a_client_driver_name = malloc(reply->client_driver_name_len + 1);
if (!*a_client_driver_name)
goto out;
memcpy(*a_client_driver_name,
xcb_xf86dri_get_client_driver_name_client_driver_name(reply),
reply->client_driver_name_len);
(*a_client_driver_name)[reply->client_driver_name_len] = '\0';
is_ok = TRUE;
EPHYR_LOG("major:%d, minor:%d, patch:%d, name:%s\n",
*a_ddx_driver_major_version,
*a_ddx_driver_minor_version,
*a_ddx_driver_patch_version, *a_client_driver_name);
out:
free(reply);
EPHYR_LOG("leave:%d\n", is_ok);
return is_ok;
}
@ -139,17 +177,23 @@ ephyrDRICreateContext(int a_screen,
int a_visual_id,
CARD32 ctxt_id, drm_context_t * a_hw_ctxt)
{
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
Bool is_ok = FALSE;
Visual v;
XID returned_ctxt_id = ctxt_id;
xcb_xf86dri_create_context_cookie_t cookie;
xcb_xf86dri_create_context_reply_t *reply;
ctxt_id = xcb_generate_id(conn);
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,
DefaultScreen(dpy),
&v, &returned_ctxt_id, a_hw_ctxt);
cookie = xcb_xf86dri_create_context(conn, screen, a_visual_id, ctxt_id);
reply = xcb_xf86dri_create_context_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_hw_ctxt = reply->hw_context;
is_ok = TRUE;
out:
free(reply);
EPHYR_LOG("leave:%d\n", is_ok);
return is_ok;
}
@ -157,13 +201,13 @@ ephyrDRICreateContext(int a_screen,
Bool
ephyrDRIDestroyContext(int a_screen, int a_context_id)
{
Display *dpy = hostx_get_display();
Bool is_ok = FALSE;
xcb_connection_t *conn = hostx_get_xcbconn ();
int screen = hostx_get_screen();
EPHYR_LOG("enter\n");
is_ok = XF86DRIDestroyContext(dpy, DefaultScreen(dpy), a_context_id);
EPHYR_LOG("leave:%d\n", is_ok);
return is_ok;
xcb_xf86dri_destroy_context(conn, screen, a_context_id);
EPHYR_LOG("leave\n");
return TRUE;
}
Bool
@ -171,11 +215,20 @@ ephyrDRICreateDrawable(int a_screen,
int a_drawable, drm_drawable_t * a_hw_drawable)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
xcb_xf86dri_create_drawable_cookie_t cookie;
xcb_xf86dri_create_drawable_reply_t *reply;
EPHYR_LOG("enter\n");
is_ok = XF86DRICreateDrawable(dpy, DefaultScreen(dpy),
a_drawable, a_hw_drawable);
cookie = xcb_xf86dri_create_drawable(conn, screen, a_drawable);
reply = xcb_xf86dri_create_drawable_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_hw_drawable = reply->hw_drawable_handle;
is_ok = TRUE;
out:
free(reply);
EPHYR_LOG("leave. is_ok:%d\n", is_ok);
return is_ok;
}
@ -206,7 +259,10 @@ ephyrDRIGetDrawableInfo(int a_screen,
drm_clip_rect_t ** a_back_clip_rects)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
xcb_xf86dri_get_drawable_info_cookie_t cookie;
xcb_xf86dri_get_drawable_info_reply_t *reply = NULL;
EphyrHostWindowAttributes attrs;
EPHYR_RETURN_VAL_IF_FAIL(a_x && a_y && a_w && a_h
@ -218,16 +274,22 @@ ephyrDRIGetDrawableInfo(int a_screen,
EPHYR_LOG_ERROR("failed to query host window attributes\n");
goto out;
}
if (!XF86DRIGetDrawableInfo(dpy, DefaultScreen(dpy), a_drawable,
a_index, a_stamp,
a_x, a_y,
a_w, a_h,
a_num_clip_rects, a_clip_rects,
a_back_x, a_back_y,
a_num_back_clip_rects, a_back_clip_rects)) {
EPHYR_LOG_ERROR("XF86DRIGetDrawableInfo ()\n");
cookie = xcb_xf86dri_get_drawable_info(conn, screen, a_drawable);
reply = xcb_xf86dri_get_drawable_info_reply(conn, cookie, NULL);
if (!reply) {
EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n");
goto out;
}
*a_index = reply->drawable_table_index;
*a_stamp = reply->drawable_table_stamp;
*a_x = reply->drawable_origin_X;
*a_y = reply->drawable_origin_Y;
*a_w = reply->drawable_size_W;
*a_h = reply->drawable_size_H;
*a_num_clip_rects = reply->num_clip_rects;
*a_clip_rects = calloc(*a_num_clip_rects, sizeof(drm_clip_rect_t));
memcpy(*a_clip_rects, xcb_xf86dri_get_drawable_info_clip_rects(reply),
*a_num_clip_rects * sizeof(drm_clip_rect_t));
EPHYR_LOG("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h);
if (*a_num_clip_rects) {
free(*a_back_clip_rects);
@ -247,6 +309,7 @@ ephyrDRIGetDrawableInfo(int a_screen,
out:
EPHYR_LOG("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
*a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h);
free(reply);
return is_ok;
}
@ -259,13 +322,35 @@ ephyrDRIGetDeviceInfo(int a_screen,
int *a_dev_private_size, void **a_dev_private)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
xcb_connection_t *conn = hostx_get_xcbconn ();
int screen = hostx_get_screen();
xcb_xf86dri_get_device_info_cookie_t cookie;
xcb_xf86dri_get_device_info_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
EPHYR_RETURN_VAL_IF_FAIL(conn, FALSE);
EPHYR_LOG("enter\n");
is_ok = XF86DRIGetDeviceInfo(dpy, DefaultScreen(dpy), a_frame_buffer,
a_fb_origin, a_fb_size, a_fb_stride,
a_dev_private_size, a_dev_private);
cookie = xcb_xf86dri_get_device_info(conn, screen);
reply = xcb_xf86dri_get_device_info_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_frame_buffer = reply->framebuffer_handle_low;
if (sizeof(drm_handle_t) == 8) {
int shift = 32;
*a_frame_buffer |= ((drm_handle_t)reply->framebuffer_handle_high) << shift;
}
*a_fb_origin = reply->framebuffer_origin_offset;
*a_fb_size = reply->framebuffer_size;
*a_fb_stride = reply->framebuffer_stride;
*a_dev_private_size = reply->device_private_size;
*a_dev_private = calloc(reply->device_private_size, 1);
if (!*a_dev_private)
goto out;
memcpy(*a_dev_private,
xcb_xf86dri_get_device_info_device_private(reply),
reply->device_private_size);
is_ok = TRUE;
out:
free(reply);
EPHYR_LOG("leave:%d\n", is_ok);
return is_ok;
}

View File

@ -39,6 +39,9 @@
#define _XF86DRI_SERVER_
#include <X11/dri/xf86dri.h>
#include <X11/dri/xf86driproto.h>
#include <xcb/xcb.h>
#include <xcb/shape.h>
#include <xcb/xf86dri.h>
#include "misc.h"
#include "privates.h"
#include "dixstruct.h"
@ -1319,12 +1322,12 @@ ephyrDRIExtensionInit(ScreenPtr a_screen)
EphyrDRIScreenPrivPtr screen_priv = NULL;
EPHYR_LOG("enter\n");
if (!hostx_has_dri()) {
if (!host_has_extension(&xcb_xf86dri_id)) {
EPHYR_LOG("host does not have DRI extension\n");
goto out;
}
EPHYR_LOG("host X does have DRI extension\n");
if (!hostx_has_xshape()) {
if (!host_has_extension(&xcb_shape_id)) {
EPHYR_LOG("host does not have XShape extension\n");
goto out;
}

View File

@ -29,6 +29,7 @@
#include <kdrive-config.h>
#endif
#include <xcb/glx.h>
#include "extnsionst.h"
#include "ephyrglxext.h"
#include "ephyrhostglx.h"
@ -83,7 +84,7 @@ ephyrHijackGLXExtension(void)
{
const void *(*dispatch_functions)[2];
if (!hostx_has_glx()) {
if (!host_has_extension(&xcb_glx_id)) {
EPHYR_LOG("host X does not have GLX\n");
return FALSE;
}
@ -380,10 +381,9 @@ ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc)
int length = 0;
EPHYR_LOG("enter\n");
if (!ephyrHostGLXGetStringFromServer(req->screen,
req->name,
EPHYR_HOST_GLX_QueryServerString,
&server_string)) {
if (!ephyrHostGLXQueryServerString(req->screen,
req->name,
&server_string)) {
EPHYR_LOG_ERROR("failed to query string from host\n");
goto out;
}
@ -724,9 +724,7 @@ ephyrGLXGetStringReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
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)) {
if (!ephyrHostGLXGetString(context_tag, name, &string)) {
EPHYR_LOG_ERROR("failed to get string from server\n");
goto out;
}

View File

@ -31,22 +31,10 @@
#include <kdrive-config.h>
#endif
/*
* including some server headers (like kdrive-config.h)
* might define the macro _XSERVER64
* on 64 bits machines. That macro must _NOT_ be defined for Xlib
* client code, otherwise bad things happen.
* So let's undef that macro if necessary.
*/
#ifdef _XSERVER64
#undef _XSERVER64
#endif
#include <X11/Xlibint.h>
#include <GL/glx.h>
#include <GL/internal/glcore.h>
#include <X11/Xdefs.h>
#include <X11/Xmd.h>
#include <GL/glxproto.h>
#include <GL/glxint.h>
#include <xcb/glx.h>
#include "ephyrhostglx.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
@ -62,41 +50,20 @@ enum VisualConfRequestType {
static Bool ephyrHostGLXGetVisualConfigsInternal
(enum VisualConfRequestType a_type,
xcb_glx_get_visual_configs_reply_t *reply,
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;
}
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf);
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;
xcb_connection_t *conn = hostx_get_xcbconn();
xcb_glx_query_version_cookie_t cookie;
xcb_glx_query_version_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(a_major && a_minor, FALSE);
EPHYR_LOG("enter\n");
@ -107,26 +74,14 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
return TRUE;
}
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 = glx_major = reply.majorVersion;
*a_minor = glx_minor = reply.minorVersion;
cookie = xcb_glx_query_version(conn, 2, 1);
reply = xcb_glx_query_version_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_major = reply->major_version;
*a_minor = reply->minor_version;
free(reply);
EPHYR_LOG("major:%d, minor:%d\n", *a_major, *a_minor);
@ -136,129 +91,63 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
return is_ok;
}
/**
* GLX protocol structure for the ficticious "GLXGenericGetString" 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)
ephyrHostGLXGetString(int a_context_tag,
int a_string_name,
char **a_string)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int default_screen = DefaultScreen(dpy);
xGLXGenericGetStringReq *req = NULL;
xGLXSingleReply reply;
unsigned long length = 0, numbytes = 0;
int major_opcode = 0, get_string_op = 0;
xcb_connection_t *conn = hostx_get_xcbconn();
xcb_glx_get_string_cookie_t cookie;
xcb_glx_get_string_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(dpy && a_string, FALSE);
EPHYR_RETURN_VAL_IF_FAIL(conn && 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);
cookie = xcb_glx_get_string(conn, a_context_tag, a_string_name);
reply = xcb_glx_get_string_reply(conn, cookie, NULL);
if (!reply)
goto out;
}
*a_string = malloc(reply->n + 1);
memcpy(*a_string, xcb_glx_get_string_string(reply), reply->n);
(*a_string)[reply->n] = '\0';
free(reply);
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
EPHYR_LOG_ERROR("failed to get major opcode\n");
Bool ephyrHostGLXQueryServerString(int a_screen_number,
int a_string_name,
char **a_string)
{
Bool is_ok = FALSE;
xcb_connection_t *conn = hostx_get_xcbconn();
int default_screen = hostx_get_screen();
xcb_glx_query_server_string_cookie_t cookie;
xcb_glx_query_server_string_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(conn && a_string, FALSE);
EPHYR_LOG("enter\n");
cookie = xcb_glx_query_server_string(conn, default_screen, a_string_name);
reply = xcb_glx_query_server_string_reply(conn, cookie, NULL);
if (!reply)
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 = default_screen;
req->name = a_string_name;
_XReply(dpy, (xReply *) &reply, 0, False);
#if UINT32_MAX >= (ULONG_MAX / 4)
if (reply.length >= (ULONG_MAX / 4)) {
_XEatDataWords(dpy, reply.length);
goto eat_out;
}
#endif
if (reply.length > 0) {
length = (unsigned long) reply.length * 4;
numbytes = reply.size;
if (numbytes > length) {
EPHYR_LOG_ERROR("string length %d longer than reply length %d\n",
numbytes, length);
goto eat_out;
}
}
EPHYR_LOG("going to get a string of size:%d\n", numbytes);
if (numbytes < INT_MAX)
*a_string = Xcalloc(numbytes + 1, 1);
else
*a_string = NULL;
if (*a_string == NULL) {
EPHYR_LOG_ERROR("allocation failed\n");
goto eat_out;
}
if (_XRead(dpy, *a_string, numbytes)) {
EPHYR_LOG_ERROR("read failed\n");
length = 0; /* if read failed, no idea how much to eat */
}
else {
length -= numbytes;
EPHYR_LOG("strname:%#x, strvalue:'%s', strlen:%d\n",
a_string_name, *a_string, numbytes);
is_ok = TRUE;
}
eat_out:
_XEatData(dpy, length);
UnlockDisplay(dpy);
SyncHandle();
out:
*a_string = malloc(reply->str_len + 1);
memcpy(*a_string, xcb_glx_query_server_string_string(reply), reply->str_len);
(*a_string)[reply->str_len] = '\0';
free(reply);
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}
static Bool
ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type,
xcb_glx_get_visual_configs_reply_t *reply,
int32_t a_screen,
int32_t * a_num_visuals,
int32_t * a_num_props,
@ -266,110 +155,36 @@ ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type,
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,
major_opcode = 0,
num_props = 0,
num_visuals = 0, props_buf_size = 0, props_per_visual_size = 0;
int num_props = 0, num_visuals = 0, props_buf_size = 0;
int props_per_visual_size = 0;
int32_t *props_buf = NULL;
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
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) {
if (!reply->num_visuals) {
EPHYR_LOG_ERROR("screen does not support GL rendering\n");
UnlockDisplay(dpy);
goto out;
}
num_visuals = reply.numVisuals;
num_visuals = reply->num_visuals;
/* 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;
}
num_props = reply->num_properties;
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_per_visual_size = num_props * sizeof(uint32_t);
props_buf_size = props_per_visual_size * reply->num_visuals;
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);
if (!props_buf)
goto out;
memcpy(props_buf, xcb_glx_get_visual_configs_property_list(reply),
props_buf_size);
*a_num_visuals = num_visuals;
*a_num_props = reply.numProps;
*a_num_props = reply->num_properties;
*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();
out:
return is_ok;
}
@ -380,14 +195,27 @@ ephyrHostGLXGetVisualConfigs(int32_t a_screen,
int32_t * a_props_buf_size, int32_t ** a_props_buf)
{
Bool is_ok = FALSE;
xcb_glx_get_visual_configs_cookie_t cookie;
xcb_glx_get_visual_configs_reply_t *reply;
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
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);
cookie = xcb_glx_get_visual_configs(conn, screen);
reply = xcb_glx_get_visual_configs_reply(conn, cookie, NULL);
if (!reply)
goto out;
is_ok = ephyrHostGLXGetVisualConfigsInternal
(EPHYR_GET_VISUAL_CONFIGS,
reply,
a_screen,
a_num_visuals,
a_num_props,
a_props_buf_size,
a_props_buf);
out:
free(reply);
EPHYR_LOG("leave:%d\n", is_ok);
return is_ok;
}
@ -399,12 +227,32 @@ ephyrHostGLXVendorPrivGetFBConfigsSGIX(int a_screen,
int32_t * a_props_buf_size,
int32_t ** a_props_buf)
{
Bool is_ok = FALSE;
Bool is_ok=FALSE;
xcb_connection_t *conn = hostx_get_xcbconn();
int screen = hostx_get_screen();
xcb_glx_vendor_private_with_reply_cookie_t cookie;
union {
xcb_glx_vendor_private_with_reply_reply_t *vprep;
xcb_glx_get_visual_configs_reply_t *rep;
} reply;
EPHYR_LOG("enter\n");
cookie = xcb_glx_vendor_private_with_reply(conn,
X_GLXvop_GetFBConfigsSGIX,
0, 4, (uint8_t *)&screen);
reply.vprep = xcb_glx_vendor_private_with_reply_reply(conn, cookie, NULL);
if (!reply.vprep)
goto out;
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);
reply.rep,
a_screen,
a_num_visuals,
a_num_props,
a_props_buf_size,
a_props_buf);
out:
free(reply.vprep);
EPHYR_LOG("leave\n");
return is_ok;
}
@ -413,39 +261,15 @@ 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;
xcb_connection_t *conn = hostx_get_xcbconn();
int size;
int32_t major_opcode = 0;
EPHYR_RETURN_VAL_IF_FAIL(dpy && a_extension_list, FALSE);
EPHYR_RETURN_VAL_IF_FAIL(conn && a_extension_list, FALSE);
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
EPHYR_LOG_ERROR("failed to get major opcode\n");
goto out;
}
size = strlen (a_extension_list) + 1;
xcb_glx_client_info(conn, a_major, a_minor, size, a_extension_list);
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 += bytes_to_int32(size);
req->numbytes = size;
Data(dpy, a_extension_list, size);
UnlockDisplay(dpy);
SyncHandle();
is_ok = TRUE;
out:
return is_ok;
return TRUE;
}
Bool
@ -457,9 +281,9 @@ ephyrHostGLXCreateContext(int a_screen,
Bool a_direct,
int code)
{
xcb_connection_t *conn = hostx_get_xcbconn();
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int major_opcode = 0, remote_context_id = 0;
int remote_context_id = 0;
EPHYR_LOG("enter. screen:%d, generic_id:%d, contextid:%d, rendertype:%d, "
"direct:%d\n", a_screen, a_generic_id, a_context_id,
@ -471,39 +295,24 @@ ephyrHostGLXCreateContext(int a_screen,
goto out;
}
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
EPHYR_LOG_ERROR("failed to get major opcode\n");
goto out;
}
LockDisplay(dpy);
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;
}
xcb_glx_create_context(conn,
remote_context_id,
a_generic_id,
hostx_get_screen(),
a_share_list_ctxt_id,
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;
xcb_glx_create_new_context(conn,
remote_context_id,
a_generic_id,
hostx_get_screen(),
a_render_type,
a_share_list_ctxt_id,
a_direct);
}
default:
@ -511,9 +320,6 @@ ephyrHostGLXCreateContext(int a_screen,
EPHYR_LOG("Internal error! Invalid CreateContext code!\n");
}
UnlockDisplay(dpy);
SyncHandle();
is_ok = TRUE;
out:
@ -524,30 +330,19 @@ ephyrHostGLXCreateContext(int a_screen,
Bool
ephyrHostDestroyContext(int a_ctxt_id)
{
xcb_connection_t *conn = hostx_get_xcbconn();
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int major_opcode = 0, remote_ctxt_id = 0;
xGLXDestroyContextReq *req = NULL;
int remote_ctxt_id = 0;
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();
xcb_glx_destroy_context(conn, remote_ctxt_id);
is_ok = TRUE;
@ -560,81 +355,71 @@ Bool
ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
int a_glx_ctxt_id, int a_old_ctxt_tag, int *a_ctxt_tag)
{
xcb_connection_t *conn = hostx_get_xcbconn();
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int32_t major_opcode = 0;
int remote_glx_ctxt_id = 0;
xGLXMakeCurrentReply reply;
EPHYR_RETURN_VAL_IF_FAIL(a_ctxt_tag, FALSE);
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");
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);
/* 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;
xcb_glx_make_current_cookie_t cookie;
xcb_glx_make_current_reply_t *reply;
cookie = xcb_glx_make_current(conn,
a_drawable,
remote_glx_ctxt_id,
a_old_ctxt_tag);
reply = xcb_glx_make_current_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_ctxt_tag = reply->context_tag;
free(reply);
}
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;
xcb_glx_make_context_current_cookie_t cookie;
xcb_glx_make_context_current_reply_t *reply;
cookie = xcb_glx_make_context_current(conn,
a_old_ctxt_tag,
a_drawable,
a_readable,
remote_glx_ctxt_id);
reply = xcb_glx_make_context_current_reply(conn, cookie, NULL);
if (!reply)
goto out;
*a_ctxt_tag = reply->context_tag;
free(reply);
}
else {
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXMakeCurrentReadSGIReq *req;
xcb_glx_vendor_private_with_reply_cookie_t cookie;
xcb_glx_vendor_private_with_reply_reply_t *reply;
uint32_t data[3] = {
a_drawable, a_readable, remote_glx_ctxt_id,
};
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;
EPHYR_LOG("enter\n");
cookie = xcb_glx_vendor_private_with_reply(conn,
X_GLXvop_MakeCurrentReadSGI,
a_old_ctxt_tag,
sizeof(data),
(uint8_t *)data);
reply = xcb_glx_vendor_private_with_reply_reply(conn, cookie, NULL);
*a_ctxt_tag = reply->retval;
free(reply);
}
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;
@ -643,79 +428,32 @@ ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
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)
{
xcb_connection_t *conn = hostx_get_xcbconn();
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int major_opcode = 0, size = 0;
xGLXSingleReq *req = NULL;
xGLXSingleReply reply;
unsigned char *pc = NULL;
int size = 0;
xcb_glx_get_integerv_cookie_t cookie;
xcb_glx_get_integerv_reply_t *reply;
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");
cookie = xcb_glx_get_integerv(conn, a_current_context_tag, a_int);
reply = xcb_glx_get_integerv_reply(conn, cookie, NULL);
if (!reply)
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);
size = reply->n;
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();
*a_val = reply->datum;
is_ok = TRUE;
out:
out:
free(reply);
EPHYR_LOG("leave\n");
return is_ok;
}
@ -724,40 +462,29 @@ 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;
xcb_connection_t *conn = hostx_get_xcbconn();
xcb_glx_is_direct_cookie_t cookie;
xcb_glx_is_direct_reply_t *reply = NULL;
int remote_glx_ctxt_id = 0;
EPHYR_LOG("enter\n");
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
EPHYR_LOG_ERROR("failed to get major opcode\n");
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;
}
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)) {
cookie = xcb_glx_is_direct(conn, remote_glx_ctxt_id);
reply = xcb_glx_is_direct_reply(conn, cookie, NULL);
if (!reply) {
EPHYR_LOG_ERROR("fail in reading reply from host\n");
UnlockDisplay(dpy);
SyncHandle();
goto out;
}
UnlockDisplay(dpy);
SyncHandle();
*a_is_direct = reply.isDirect;
*a_is_direct = reply->is_direct;
is_ok = TRUE;
out:
out:
free(reply);
EPHYR_LOG("leave\n");
return is_ok;
}

View File

@ -35,10 +35,12 @@ enum EphyrHostGLXGetStringOps {
};
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 ephyrHostGLXGetString(int a_context_tag,
int a_string_name,
char **a_string);
Bool ephyrHostGLXQueryServerString(int a_screen_number,
int a_string_name,
char **a_string);
Bool ephyrHostGLXGetVisualConfigs(int a_screen,
int32_t * a_num_visuals,
int32_t * a_num_props,
@ -51,7 +53,6 @@ ephyrHostGLXVendorPrivGetFBConfigsSGIX(int a_screen,
int32_t * a_num_props,
int32_t * a_props_buf_size,
int32_t ** a_props_buf);
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,

View File

@ -1,91 +0,0 @@
/*
* 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 <X11/Xlibint.h>
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include "ephyrhostproxy.h"
#include "hostx.h"
/* byte swap a short */
#define swaps(x, n) { \
n = ((char *) (x))[0];\
((char *) (x))[0] = ((char *) (x))[1];\
((char *) (x))[1] = n; }
#define GetXReq(req) \
WORD64ALIGN ;\
if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
_XFlush(dpy);\
req = (xReq *)(dpy->last_req = dpy->bufptr);\
dpy->bufptr += SIZEOF(xReq);\
dpy->request++
Bool
ephyrHostProxyDoForward(pointer a_request_buffer,
struct XReply *a_reply, Bool a_do_swap)
{
Bool is_ok = FALSE;
int n = 0;
Display *dpy = hostx_get_display();
xReq *in_req = (xReq *) a_request_buffer;
xReq *forward_req = NULL;
struct XReply reply;
EPHYR_RETURN_VAL_IF_FAIL(in_req && dpy, FALSE);
EPHYR_LOG("enter\n");
if (a_do_swap) {
swaps(&in_req->length);
}
EPHYR_LOG("Req {type:%d, data:%d, length:%d}\n",
in_req->reqType, in_req->data, in_req->length);
GetXReq(forward_req);
memmove(forward_req, in_req, 4);
if (!_XReply(dpy, (xReply *) &reply, 0, FALSE)) {
EPHYR_LOG_ERROR("failed to get reply\n");
goto out;
}
EPHYR_LOG("XReply{type:%d, foo:%d, seqnum:%d, length:%d}\n",
reply.type, reply.foo, reply.sequence_number, reply.length);
if (a_reply) {
memmove(a_reply, &reply, sizeof(reply));
}
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}

View File

@ -1,51 +0,0 @@
/*
* 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>
*/
#ifndef __EPHYRHOSTPROXY_H__
#define __EPHYRHOSTPROXY_H__
struct XReply {
int8_t type; /*X_Reply */
int8_t foo;
int16_t sequence_number;
int32_t length;
/*following is some data up to 32 bytes lenght */
int32_t pad0;
int32_t pad1;
int32_t pad2;
int32_t pad3;
int32_t pad4;
int32_t pad5;
};
Bool
ephyrHostProxyDoForward(pointer a_request_buffer,
struct XReply *a_reply, Bool a_do_swap);
#endif /*__EPHYRHOSTPROXY_H__*/

View File

@ -1,975 +0,0 @@
/*
* 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
/*
* including some server headers (like kdrive-config.h)
* might define the macro _XSERVER64
* on 64 bits machines. That macro must _NOT_ be defined for Xlib
* client code, otherwise bad things happen.
* So let's undef that macro if necessary.
*/
#ifdef _XSERVER64
#undef _XSERVER64
#endif
#include <X11/Xutil.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xvlib.h>
#include <X11/extensions/Xvproto.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#define _HAVE_XALLOC_DECLS
#include "hostx.h"
#include "ephyrhostvideo.h"
#include "ephyrlog.h"
#ifndef TRUE
#define TRUE 1
#endif /*TRUE*/
#ifndef FALSE
#define FALSE 0
#endif /*FALSE*/
static XExtensionInfo _xv_info_data;
static XExtensionInfo *xv_info = &_xv_info_data;
static const char *xv_extension_name = XvName;
static char *xv_error_string(Display * dpy, int code, XExtCodes * codes,
char *buf, int n);
static int xv_close_display(Display * dpy, XExtCodes * codes);
static Bool xv_wire_to_event(Display * dpy, XEvent * host, xEvent *wire);
static XExtensionHooks xv_extension_hooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
xv_close_display, /* close_display */
xv_wire_to_event, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
xv_error_string /* error_string */
};
static const char *xv_error_list[] = {
"BadPort", /* XvBadPort */
"BadEncoding", /* XvBadEncoding */
"BadControl" /* XvBadControl */
};
#define XvCheckExtension(dpy, i, val) \
XextCheckExtension(dpy, i, xv_extension_name, val)
#define XvGetReq(name, req) \
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
_XFlush(dpy);\
req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
req->reqType = info->codes->major_opcode;\
req->xvReqType = xv_##name; \
req->length = (SIZEOF(xv##name##Req))>>2;\
dpy->bufptr += SIZEOF(xv##name##Req);\
dpy->request++
static
XEXT_GENERATE_CLOSE_DISPLAY(xv_close_display, xv_info)
static
XEXT_GENERATE_FIND_DISPLAY(xv_find_display, xv_info,
xv_extension_name,
&xv_extension_hooks, XvNumEvents, NULL)
static
XEXT_GENERATE_ERROR_STRING(xv_error_string, xv_extension_name,
XvNumErrors, xv_error_list)
struct _EphyrHostXVAdaptorArray {
XvAdaptorInfo *adaptors;
unsigned int nb_adaptors;
};
/*heavily copied from libx11*/
#define BUFSIZE 2048
static void
ephyrHostXVLogXErrorEvent(Display * a_display,
XErrorEvent * a_err_event, FILE * a_fp)
{
char buffer[BUFSIZ];
char mesg[BUFSIZ];
char number[32];
const char *mtype = "XlibMessage";
register _XExtension *ext = (_XExtension *) NULL;
_XExtension *bext = (_XExtension *) NULL;
Display *dpy = a_display;
XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
(void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
mesg, BUFSIZ);
(void) fprintf(a_fp, mesg, a_err_event->request_code);
if (a_err_event->request_code < 128) {
snprintf(number, sizeof(number), "%d", a_err_event->request_code);
XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
}
else {
for (ext = dpy->ext_procs;
ext && (ext->codes.major_opcode != a_err_event->request_code);
ext = ext->next);
if (ext)
strcpy(buffer, ext->name);
else
buffer[0] = '\0';
}
(void) fprintf(a_fp, " (%s)\n", buffer);
if (a_err_event->request_code >= 128) {
XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
mesg, BUFSIZ);
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->minor_code);
if (ext) {
snprintf(mesg, sizeof(mesg), "%s.%d",
ext->name, a_err_event->minor_code);
XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
(void) fprintf(a_fp, " (%s)", buffer);
}
fputs("\n", a_fp);
}
if (a_err_event->error_code >= 128) {
/* kludge, try to find the extension that caused it */
buffer[0] = '\0';
for (ext = dpy->ext_procs; ext; ext = ext->next) {
if (ext->error_string)
(*ext->error_string) (dpy, a_err_event->error_code, &ext->codes,
buffer, BUFSIZ);
if (buffer[0]) {
bext = ext;
break;
}
if (ext->codes.first_error &&
ext->codes.first_error < (int) a_err_event->error_code &&
(!bext || ext->codes.first_error > bext->codes.first_error))
bext = ext;
}
if (bext)
snprintf(buffer, sizeof(buffer), "%s.%d", bext->name,
a_err_event->error_code - bext->codes.first_error);
else
strcpy(buffer, "Value");
XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
if (mesg[0]) {
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->resourceid);
fputs("\n", a_fp);
}
/* let extensions try to print the values */
for (ext = dpy->ext_procs; ext; ext = ext->next) {
if (ext->error_values)
(*ext->error_values) (dpy, a_err_event, a_fp);
}
}
else if ((a_err_event->error_code == BadWindow) ||
(a_err_event->error_code == BadPixmap) ||
(a_err_event->error_code == BadCursor) ||
(a_err_event->error_code == BadFont) ||
(a_err_event->error_code == BadDrawable) ||
(a_err_event->error_code == BadColor) ||
(a_err_event->error_code == BadGC) ||
(a_err_event->error_code == BadIDChoice) ||
(a_err_event->error_code == BadValue) ||
(a_err_event->error_code == BadAtom)) {
if (a_err_event->error_code == BadValue)
XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
mesg, BUFSIZ);
else if (a_err_event->error_code == BadAtom)
XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
mesg, BUFSIZ);
else
XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
mesg, BUFSIZ);
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->resourceid);
fputs("\n", a_fp);
}
XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
mesg, BUFSIZ);
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->serial);
XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
mesg, BUFSIZ);
fputs("\n ", a_fp);
(void) fprintf(a_fp, mesg, dpy->request);
fputs("\n", a_fp);
}
static int
ephyrHostXVErrorHandler(Display * a_display, XErrorEvent * a_error_event)
{
EPHYR_LOG_ERROR("got an error from the host xserver:\n");
ephyrHostXVLogXErrorEvent(a_display, a_error_event, stderr);
return Success;
}
void
ephyrHostXVInit(void)
{
static Bool s_initialized;
if (s_initialized)
return;
XSetErrorHandler(ephyrHostXVErrorHandler);
s_initialized = TRUE;
}
Bool
ephyrHostXVQueryAdaptors(EphyrHostXVAdaptorArray ** a_adaptors)
{
EphyrHostXVAdaptorArray *result = NULL;
int ret = 0;
Bool is_ok = FALSE;
EPHYR_RETURN_VAL_IF_FAIL(a_adaptors, FALSE);
EPHYR_LOG("enter\n");
result = calloc(1, sizeof(EphyrHostXVAdaptorArray));
if (!result)
goto out;
ret = XvQueryAdaptors(hostx_get_display(),
DefaultRootWindow(hostx_get_display()),
&result->nb_adaptors, &result->adaptors);
if (ret != Success) {
EPHYR_LOG_ERROR("failed to query host adaptors: %d\n", ret);
goto out;
}
*a_adaptors = result;
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}
void
ephyrHostXVAdaptorArrayDelete(EphyrHostXVAdaptorArray * a_adaptors)
{
if (!a_adaptors)
return;
if (a_adaptors->adaptors) {
XvFreeAdaptorInfo(a_adaptors->adaptors);
a_adaptors->adaptors = NULL;
a_adaptors->nb_adaptors = 0;
}
XFree(a_adaptors);
}
int
ephyrHostXVAdaptorArrayGetSize(const EphyrHostXVAdaptorArray * a_this)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
return a_this->nb_adaptors;
}
EphyrHostXVAdaptor *
ephyrHostXVAdaptorArrayAt(const EphyrHostXVAdaptorArray * a_this, int a_index)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this, NULL);
if (a_index >= a_this->nb_adaptors)
return NULL;
return (EphyrHostXVAdaptor *) &a_this->adaptors[a_index];
}
char
ephyrHostXVAdaptorGetType(const EphyrHostXVAdaptor * a_this)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
return ((const XvAdaptorInfo *) a_this)->type;
}
const char *
ephyrHostXVAdaptorGetName(const EphyrHostXVAdaptor * a_this)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this, NULL);
return ((const XvAdaptorInfo *) a_this)->name;
}
EphyrHostVideoFormat *
ephyrHostXVAdaptorGetVideoFormats(const EphyrHostXVAdaptor * a_this,
int *a_nb_formats)
{
EphyrHostVideoFormat *formats = NULL;
int nb_formats = 0, i = 0;
XVisualInfo *visual_info, visual_info_template;
int nb_visual_info;
EPHYR_RETURN_VAL_IF_FAIL(a_this, NULL);
nb_formats = ((const XvAdaptorInfo *) a_this)->num_formats;
formats = calloc(nb_formats, sizeof(EphyrHostVideoFormat));
for (i = 0; i < nb_formats; i++) {
memset(&visual_info_template, 0, sizeof(visual_info_template));
visual_info_template.visualid =
((const XvAdaptorInfo *) a_this)->formats[i].visual_id;
visual_info = XGetVisualInfo(hostx_get_display(),
VisualIDMask,
&visual_info_template, &nb_visual_info);
formats[i].depth = ((const XvAdaptorInfo *) a_this)->formats[i].depth;
formats[i].visual_class = visual_info->class;
XFree(visual_info);
}
if (a_nb_formats)
*a_nb_formats = nb_formats;
return formats;
}
int
ephyrHostXVAdaptorGetNbPorts(const EphyrHostXVAdaptor * a_this)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
return ((const XvAdaptorInfo *) a_this)->num_ports;
}
int
ephyrHostXVAdaptorGetFirstPortID(const EphyrHostXVAdaptor * a_this)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
return ((const XvAdaptorInfo *) a_this)->base_id;
}
Bool
ephyrHostXVAdaptorHasPutVideo(const EphyrHostXVAdaptor * a_this, Bool *a_result)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
if ((((const XvAdaptorInfo *) a_this)->type &
(XvVideoMask | XvInputMask)) == (XvVideoMask | XvInputMask))
*a_result = TRUE;
else
*a_result = FALSE;
return TRUE;
}
Bool
ephyrHostXVAdaptorHasGetVideo(const EphyrHostXVAdaptor * a_this, Bool *a_result)
{
if ((((const XvAdaptorInfo *) a_this)->type &
(XvVideoMask | XvOutputMask)) == (XvVideoMask | XvOutputMask))
*a_result = TRUE;
else
*a_result = FALSE;
return TRUE;
}
Bool
ephyrHostXVAdaptorHasPutStill(const EphyrHostXVAdaptor * a_this, Bool *a_result)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
if ((((const XvAdaptorInfo *) a_this)->type &
(XvStillMask | XvInputMask)) == (XvStillMask | XvInputMask))
*a_result = TRUE;
else
*a_result = FALSE;
return TRUE;
}
Bool
ephyrHostXVAdaptorHasGetStill(const EphyrHostXVAdaptor * a_this, Bool *a_result)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
if ((((const XvAdaptorInfo *) a_this)->type &
(XvStillMask | XvOutputMask)) == (XvStillMask | XvOutputMask))
*a_result = TRUE;
else
*a_result = FALSE;
return TRUE;
}
Bool
ephyrHostXVAdaptorHasPutImage(const EphyrHostXVAdaptor * a_this, Bool *a_result)
{
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
if ((((const XvAdaptorInfo *) a_this)->type &
(XvImageMask | XvInputMask)) == (XvImageMask | XvInputMask))
*a_result = TRUE;
else
*a_result = FALSE;
return TRUE;
}
Bool
ephyrHostXVQueryEncodings(int a_port_id,
EphyrHostEncoding ** a_encodings,
unsigned int *a_num_encodings)
{
EphyrHostEncoding *encodings = NULL;
XvEncodingInfo *encoding_info = NULL;
unsigned int num_encodings = 0, i;
int ret = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_encodings && a_num_encodings, FALSE);
ret = XvQueryEncodings(hostx_get_display(),
a_port_id, &num_encodings, &encoding_info);
if (num_encodings && encoding_info) {
encodings = calloc(num_encodings, sizeof(EphyrHostEncoding));
for (i = 0; i < num_encodings; i++) {
encodings[i].id = encoding_info[i].encoding_id;
encodings[i].name = strdup(encoding_info[i].name);
encodings[i].width = encoding_info[i].width;
encodings[i].height = encoding_info[i].height;
encodings[i].rate.numerator = encoding_info[i].rate.numerator;
encodings[i].rate.denominator = encoding_info[i].rate.denominator;
}
}
if (encoding_info) {
XvFreeEncodingInfo(encoding_info);
encoding_info = NULL;
}
*a_encodings = encodings;
*a_num_encodings = num_encodings;
if (ret != Success)
return FALSE;
return TRUE;
}
void
ephyrHostEncodingsDelete(EphyrHostEncoding * a_encodings, int a_num_encodings)
{
int i = 0;
if (!a_encodings)
return;
for (i = 0; i < a_num_encodings; i++) {
free(a_encodings[i].name);
a_encodings[i].name = NULL;
}
free(a_encodings);
}
void
ephyrHostAttributesDelete(EphyrHostAttribute * a_attributes)
{
if (!a_attributes)
return;
XFree(a_attributes);
}
Bool
ephyrHostXVQueryPortAttributes(int a_port_id,
EphyrHostAttribute ** a_attributes,
int *a_num_attributes)
{
EPHYR_RETURN_VAL_IF_FAIL(a_attributes && a_num_attributes, FALSE);
*a_attributes =
(EphyrHostAttribute *) XvQueryPortAttributes(hostx_get_display(),
a_port_id,
a_num_attributes);
return TRUE;
}
Bool
ephyrHostXVQueryImageFormats(int a_port_id,
EphyrHostImageFormat ** a_formats,
int *a_num_format)
{
XvImageFormatValues *result = NULL;
EPHYR_RETURN_VAL_IF_FAIL(a_formats && a_num_format, FALSE);
result = XvListImageFormats(hostx_get_display(), a_port_id, a_num_format);
*a_formats = (EphyrHostImageFormat *) result;
return TRUE;
}
Bool
ephyrHostXVSetPortAttribute(int a_port_id, int a_atom, int a_attr_value)
{
int res = Success;
EPHYR_LOG("atom,name,value: (%d,%s,%d)\n",
a_atom, XGetAtomName(hostx_get_display(), a_atom), a_attr_value);
res = XvSetPortAttribute(hostx_get_display(),
a_port_id, a_atom, a_attr_value);
if (res != Success) {
EPHYR_LOG_ERROR("XvSetPortAttribute() failed: %d\n", res);
return FALSE;
}
XFlush(hostx_get_display());
EPHYR_LOG("leave\n");
return TRUE;
}
Bool
ephyrHostXVGetPortAttribute(int a_port_id, int a_atom, int *a_attr_value)
{
int res = Success;
Bool ret = FALSE;
EPHYR_RETURN_VAL_IF_FAIL(a_attr_value, FALSE);
EPHYR_LOG("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
a_port_id, a_atom, XGetAtomName(hostx_get_display(), a_atom));
res = XvGetPortAttribute(hostx_get_display(),
a_port_id, a_atom, a_attr_value);
if (res != Success) {
EPHYR_LOG_ERROR("XvGetPortAttribute() failed: %d \n", res);
goto out;
}
EPHYR_LOG("atom,value: (%d, %d)\n", a_atom, *a_attr_value);
ret = TRUE;
out:
EPHYR_LOG("leave\n");
return ret;
}
Bool
ephyrHostXVQueryBestSize(int a_port_id,
Bool a_motion,
unsigned int a_frame_w,
unsigned int a_frame_h,
unsigned int a_drw_w,
unsigned int a_drw_h,
unsigned int *a_actual_w, unsigned int *a_actual_h)
{
int res = 0;
Bool is_ok = FALSE;
EPHYR_RETURN_VAL_IF_FAIL(a_actual_w && a_actual_h, FALSE);
EPHYR_LOG("enter: frame (%dx%d), drw (%dx%d)\n",
a_frame_w, a_frame_h, a_drw_w, a_drw_h);
res = XvQueryBestSize(hostx_get_display(),
a_port_id,
a_motion,
a_frame_w, a_frame_h,
a_drw_w, a_drw_h, a_actual_w, a_actual_h);
if (res != Success) {
EPHYR_LOG_ERROR("XvQueryBestSize() failed: %d\n", res);
goto out;
}
XSync(hostx_get_display(), FALSE);
EPHYR_LOG("actual (%dx%d)\n", *a_actual_w, *a_actual_h);
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}
static Bool
xv_wire_to_event(Display * dpy, XEvent * host, xEvent *wire)
{
XExtDisplayInfo *info = xv_find_display(dpy);
XvEvent *re = (XvEvent *) host;
xvEvent *event = (xvEvent *) wire;
XvCheckExtension(dpy, info, False);
switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
case XvVideoNotify:
re->xvvideo.type = event->u.u.type & 0x7f;
re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
re->xvvideo.display = dpy;
re->xvvideo.time = event->u.videoNotify.time;
re->xvvideo.reason = event->u.videoNotify.reason;
re->xvvideo.drawable = event->u.videoNotify.drawable;
re->xvvideo.port_id = event->u.videoNotify.port;
break;
case XvPortNotify:
re->xvport.type = event->u.u.type & 0x7f;
re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
re->xvport.display = dpy;
re->xvport.time = event->u.portNotify.time;
re->xvport.port_id = event->u.portNotify.port;
re->xvport.attribute = event->u.portNotify.attribute;
re->xvport.value = event->u.portNotify.value;
break;
default:
return False;
}
return True;
}
Bool
ephyrHostXVQueryImageAttributes(int a_port_id,
int a_image_id /*image fourcc code */ ,
unsigned short *a_width,
unsigned short *a_height,
int *a_image_size,
int *a_pitches, int *a_offsets)
{
Display *dpy = hostx_get_display();
Bool ret = FALSE;
XExtDisplayInfo *info = xv_find_display(dpy);
xvQueryImageAttributesReq *req = NULL;
xvQueryImageAttributesReply rep;
EPHYR_RETURN_VAL_IF_FAIL(a_width, FALSE);
EPHYR_RETURN_VAL_IF_FAIL(a_height, FALSE);
EPHYR_RETURN_VAL_IF_FAIL(a_image_size, FALSE);
XvCheckExtension(dpy, info, FALSE);
LockDisplay(dpy);
XvGetReq(QueryImageAttributes, req);
req->id = a_image_id;
req->port = a_port_id;
req->width = *a_width;
req->height = *a_height;
/*
* read the reply
*/
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
EPHYR_LOG_ERROR("QeryImageAttribute req failed\n");
goto out;
}
if (a_pitches && a_offsets) {
_XRead(dpy, (char *) a_pitches, rep.num_planes << 2);
_XRead(dpy, (char *) a_offsets, rep.num_planes << 2);
}
else {
_XEatDataWords(dpy, rep.length);
}
*a_width = rep.width;
*a_height = rep.height;
*a_image_size = rep.data_size;
ret = TRUE;
out:
UnlockDisplay(dpy);
SyncHandle();
return ret;
}
Bool
ephyrHostGetAtom(const char *a_name, Bool a_create_if_not_exists, int *a_atom)
{
int atom = None;
EPHYR_RETURN_VAL_IF_FAIL(a_atom, FALSE);
atom = XInternAtom(hostx_get_display(), a_name, a_create_if_not_exists);
if (atom == None) {
return FALSE;
}
*a_atom = atom;
return TRUE;
}
char *
ephyrHostGetAtomName(int a_atom)
{
return XGetAtomName(hostx_get_display(), a_atom);
}
void
ephyrHostFree(void *a_pointer)
{
if (a_pointer)
XFree(a_pointer);
}
Bool
ephyrHostXVPutImage(int a_screen_num,
int a_port_id,
int a_image_id,
int a_drw_x,
int a_drw_y,
int a_drw_w,
int a_drw_h,
int a_src_x,
int a_src_y,
int a_src_w,
int a_src_h,
int a_image_width,
int a_image_height,
unsigned char *a_buf,
EphyrHostBox * a_clip_rects, int a_clip_rect_nums)
{
Bool is_ok = TRUE;
XvImage *xv_image = NULL;
GC gc = 0;
XGCValues gc_values;
Display *dpy = hostx_get_display();
XRectangle *rects = NULL;
int res = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_buf, FALSE);
EPHYR_LOG("enter, num_clip_rects: %d\n", a_clip_rect_nums);
memset(&gc_values, 0, sizeof(gc_values));
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
if (!gc) {
EPHYR_LOG_ERROR("failed to create gc \n");
goto out;
}
xv_image = (XvImage *) XvCreateImage(hostx_get_display(),
a_port_id, a_image_id,
NULL, a_image_width, a_image_height);
if (!xv_image) {
EPHYR_LOG_ERROR("failed to create image\n");
goto out;
}
xv_image->data = (char *) a_buf;
if (a_clip_rect_nums) {
int i = 0;
rects = calloc(a_clip_rect_nums, sizeof(XRectangle));
for (i = 0; i < a_clip_rect_nums; i++) {
rects[i].x = a_clip_rects[i].x1;
rects[i].y = a_clip_rects[i].y1;
rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
EPHYR_LOG("(x,y,w,h): (%d,%d,%d,%d)\n",
rects[i].x, rects[i].y, rects[i].width, rects[i].height);
}
XSetClipRectangles(dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded);
/*this always returns 1 */
}
res = XvPutImage(dpy, a_port_id,
hostx_get_window(a_screen_num),
gc, xv_image,
a_src_x, a_src_y, a_src_w, a_src_h,
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
if (res != Success) {
EPHYR_LOG_ERROR("XvPutImage() failed: %d\n", res);
goto out;
}
is_ok = TRUE;
out:
if (xv_image) {
XFree(xv_image);
xv_image = NULL;
}
if (gc) {
XFreeGC(dpy, gc);
gc = NULL;
}
free(rects);
rects = NULL;
EPHYR_LOG("leave\n");
return is_ok;
}
Bool
ephyrHostXVPutVideo(int a_screen_num, int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
{
Bool is_ok = FALSE;
int res = FALSE;
GC gc = 0;
XGCValues gc_values;
Display *dpy = hostx_get_display();
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
if (!gc) {
EPHYR_LOG_ERROR("failed to create gc \n");
goto out;
}
res = XvPutVideo(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
if (res != Success) {
EPHYR_LOG_ERROR("XvPutVideo() failed: %d\n", res);
goto out;
}
is_ok = TRUE;
out:
if (gc) {
XFreeGC(dpy, gc);
gc = NULL;
}
return is_ok;
}
Bool
ephyrHostXVGetVideo(int a_screen_num, int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
{
Bool is_ok = FALSE;
int res = FALSE;
GC gc = 0;
XGCValues gc_values;
Display *dpy = hostx_get_display();
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
if (!gc) {
EPHYR_LOG_ERROR("failed to create gc \n");
goto out;
}
res = XvGetVideo(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
if (res != Success) {
EPHYR_LOG_ERROR("XvGetVideo() failed: %d\n", res);
goto out;
}
is_ok = TRUE;
out:
if (gc) {
XFreeGC(dpy, gc);
gc = NULL;
}
return is_ok;
}
Bool
ephyrHostXVPutStill(int a_screen_num, int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
{
Bool is_ok = FALSE;
int res = FALSE;
GC gc = 0;
XGCValues gc_values;
Display *dpy = hostx_get_display();
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
if (!gc) {
EPHYR_LOG_ERROR("failed to create gc \n");
goto out;
}
res = XvPutStill(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
if (res != Success) {
EPHYR_LOG_ERROR("XvPutStill() failed: %d\n", res);
goto out;
}
is_ok = TRUE;
out:
if (gc) {
XFreeGC(dpy, gc);
gc = NULL;
}
return is_ok;
}
Bool
ephyrHostXVGetStill(int a_screen_num, int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
{
Bool is_ok = FALSE;
int res = FALSE;
GC gc = 0;
XGCValues gc_values;
Display *dpy = hostx_get_display();
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
if (!gc) {
EPHYR_LOG_ERROR("failed to create gc \n");
goto out;
}
res = XvGetStill(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
if (res != Success) {
EPHYR_LOG_ERROR("XvGetStill() failed: %d\n", res);
goto out;
}
is_ok = TRUE;
out:
if (gc) {
XFreeGC(dpy, gc);
gc = NULL;
}
return is_ok;
}
Bool
ephyrHostXVStopVideo(int a_screen_num, int a_port_id)
{
int ret = 0;
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
EPHYR_LOG("enter\n");
ret = XvStopVideo(dpy, a_port_id, hostx_get_window(a_screen_num));
if (ret != Success) {
EPHYR_LOG_ERROR("XvStopVideo() failed: %d \n", ret);
goto out;
}
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}

View File

@ -1,231 +0,0 @@
/*
* 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>
*/
#ifndef __EPHYRHOSTVIDEO_H__
#define __EPHYRHOSTVIDEO_H__
typedef void *EphyrHostXVAdaptor;
typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray;
typedef struct _EphyrHostVideoFormat {
char depth;
short visual_class;
} EphyrHostVideoFormat;
typedef struct _EphyrHostRational {
int numerator;
int denominator;
} EphyrHostRational;
typedef struct _EphyrHostEncoding {
int id;
char *name;
unsigned short width, height;
EphyrHostRational rate;
} EphyrHostEncoding;
typedef struct _EphyrHostAttribute {
int flags;
int min_value;
int max_value;
char *name;
} EphyrHostAttribute;
typedef struct _EphyrHostImageFormat {
int id; /* Unique descriptor for the format */
int type; /* XvRGB, XvYUV */
int byte_order; /* LSBFirst, MSBFirst */
char guid[16]; /* Globally Unique IDentifier */
int bits_per_pixel;
int format; /* XvPacked, XvPlanar */
int num_planes;
/* for RGB formats only */
int depth;
unsigned int red_mask;
unsigned int green_mask;
unsigned int blue_mask;
/* for YUV formats only */
unsigned int y_sample_bits;
unsigned int u_sample_bits;
unsigned int v_sample_bits;
unsigned int horz_y_period;
unsigned int horz_u_period;
unsigned int horz_v_period;
unsigned int vert_y_period;
unsigned int vert_u_period;
unsigned int vert_v_period;
char component_order[32]; /* eg. UYVY */
int scanline_order; /* XvTopToBottom, XvBottomToTop */
} EphyrHostImageFormat;
typedef struct {
unsigned short x1, y1, x2, y2;
} EphyrHostBox;
void ephyrHostXVInit(void);
void ephyrHostFree(void *a_pointer);
/*
* host adaptor array
*/
Bool ephyrHostXVQueryAdaptors(EphyrHostXVAdaptorArray ** a_adaptors);
void ephyrHostXVAdaptorArrayDelete(EphyrHostXVAdaptorArray * a_adaptors);
int ephyrHostXVAdaptorArrayGetSize(const EphyrHostXVAdaptorArray * a_this);
EphyrHostXVAdaptor *ephyrHostXVAdaptorArrayAt(const EphyrHostXVAdaptorArray *
a_this, int a_index);
/*
* host adaptor
*/
char ephyrHostXVAdaptorGetType(const EphyrHostXVAdaptor * a_this);
const char *ephyrHostXVAdaptorGetName(const EphyrHostXVAdaptor * a_this);
EphyrHostVideoFormat *ephyrHostXVAdaptorGetVideoFormats
(const EphyrHostXVAdaptor * a_this, int *a_nb_formats);
int ephyrHostXVAdaptorGetNbPorts(const EphyrHostXVAdaptor * a_this);
int ephyrHostXVAdaptorGetFirstPortID(const EphyrHostXVAdaptor * a_this);
Bool ephyrHostXVAdaptorHasPutVideo(const EphyrHostXVAdaptor * a_this,
Bool *a_result);
Bool ephyrHostXVAdaptorHasGetVideo(const EphyrHostXVAdaptor * a_this,
Bool *a_result);
Bool ephyrHostXVAdaptorHasPutStill(const EphyrHostXVAdaptor * a_this,
Bool *a_result);
Bool ephyrHostXVAdaptorHasGetStill(const EphyrHostXVAdaptor * a_this,
Bool *a_result);
Bool ephyrHostXVAdaptorHasPutImage(const EphyrHostXVAdaptor * a_this,
Bool *a_result);
/*
* encoding
*/
Bool ephyrHostXVQueryEncodings(int a_port_id,
EphyrHostEncoding ** a_encodings,
unsigned int *a_num_encodings);
void ephyrHostEncodingsDelete(EphyrHostEncoding * a_encodings,
int a_num_encodings);
/*
* attribute
*/
Bool ephyrHostXVQueryPortAttributes(int a_port_id,
EphyrHostAttribute ** a_attributes,
int *a_num_attributes);
void ephyrHostAttributesDelete(EphyrHostAttribute * a_attributes);
/*
* image format
*/
Bool ephyrHostXVQueryImageFormats(int a_port_id,
EphyrHostImageFormat ** a_formats,
int *a_num_format);
/*
* Port Attribute Get/Set
*/
Bool ephyrHostXVSetPortAttribute(int a_port_id, int a_atom, int a_attr_value);
Bool ephyrHostXVGetPortAttribute(int a_port_id, int a_atom, int *a_attr_value);
/*
*size query
*/
Bool ephyrHostXVQueryBestSize(int a_port_id,
Bool a_motion,
unsigned int a_frame_w,
unsigned int a_frame_h,
unsigned int a_drw_w,
unsigned int a_drw_h,
unsigned int *a_actual_w,
unsigned int *a_actual_h);
Bool ephyrHostXVQueryImageAttributes(int a_port_id,
int a_image_id /*image fourcc code */ ,
unsigned short *a_width,
unsigned short *a_height,
int *a_image_size,
int *a_pitches, int *a_offsets);
/*
* atom
*/
Bool ephyrHostGetAtom(const char *a_name,
Bool a_create_if_not_exists, int *a_atom);
char *ephyrHostGetAtomName(int a_atom);
/*
*PutImage
* (ignore clipping for now)
*/
Bool ephyrHostXVPutImage(int a_screen_num,
int a_port_id,
int a_image_id,
int a_drw_x,
int a_drw_y,
int a_drw_w,
int a_drw_h,
int a_src_x,
int a_src_y,
int a_src_w,
int a_src_h,
int a_image_width,
int a_image_height,
unsigned char *a_buf,
EphyrHostBox * a_clip_rects, int a_clip_rect_nums);
/*
* Putvideo/PutStill/GetVideo
*/
Bool ephyrHostXVPutVideo(int a_screen_num,
int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
Bool ephyrHostXVGetVideo(int a_screen_num,
int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
Bool ephyrHostXVPutStill(int a_screen_num,
int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
Bool ephyrHostXVGetStill(int a_screen_num,
int a_port_id,
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
/*
* StopVideo
*/
Bool ephyrHostXVStopVideo(int a_screen_num, int a_port_id);
#endif /*__EPHYRHOSTVIDEO_H__*/

View File

@ -71,6 +71,22 @@ InitCard(char *name)
KdCardInfoAdd(&ephyrFuncs, 0);
}
static const ExtensionModule ephyrExtensions[] = {
#ifdef GLXEXT
{ GlxExtensionInit, "GLX", &noGlxExtension },
#endif
};
static
void ephyrExtensionInit(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(ephyrExtensions); i++)
LoadExtension(&ephyrExtensions[i], TRUE);
}
void
InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
{
@ -134,7 +150,7 @@ ddxUseMsg(void)
ErrorF("\nXephyr Option Usage:\n");
ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
ErrorF("-sw-cursor Render cursors in software in Xephyr\n");
ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
ErrorF("-grayscale Simulate 8bit grayscale\n");
ErrorF("-resizeable Make Xephyr windows resizeable\n");
@ -167,6 +183,9 @@ processScreenArg(const char *screen_size, char *parent_id)
screen = KdScreenInfoAdd(card);
KdParseScreen(screen, screen_size);
screen->driver = calloc(1, sizeof(EphyrScrPriv));
if (!screen->driver)
FatalError("Couldn't alloc screen private\n");
if (parent_id) {
p_id = strtol(parent_id, NULL, 0);
@ -220,8 +239,12 @@ ddxProcessArgument(int argc, char **argv, int i)
UseMsg();
exit(1);
}
else if (!strcmp(argv[i], "-sw-cursor")) {
hostx_use_sw_cursor();
return 1;
}
else if (!strcmp(argv[i], "-host-cursor")) {
hostx_use_host_cursor();
/* Compatibility with the old command line argument, now the default. */
return 1;
}
else if (!strcmp(argv[i], "-fullscreen")) {
@ -389,7 +412,7 @@ ephyrCursorEnable(ScreenPtr pScreen)
KdCardFuncs ephyrFuncs = {
ephyrCardInit, /* cardinit */
ephyrScreenInit, /* scrinit */
ephyrScreenInitialize, /* scrinit */
ephyrInitScreen, /* initScreen */
ephyrFinishInitScreen, /* finishInitScreen */
ephyrCreateResources, /* createRes */

View File

@ -1,115 +0,0 @@
/*
* 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>
*/
/*
* \file
* This file defines a proxy extension that forwards requests.
* When a request to extension FOO is sent to Xephyr, that request is forwared
* to the host X, without even trying to know what the request means.
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "misc.h"
#include "dixstruct.h"
#include "extnsionst.h"
#include "ephyrproxyext.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include "ephyrhostproxy.h"
#include "hostx.h"
static Bool ephyrProxyGetHostExtensionInfo(const char *a_ext_name,
int *a_major_opcode,
int *a_first_event,
int *a_first_error);
static int ephyrProxyProcDispatch(ClientPtr client);
static Bool
ephyrProxyGetHostExtensionInfo(const char *a_ext_name,
int *a_major_opcode,
int *a_first_event, int *a_first_error)
{
return hostx_get_extension_info(a_ext_name, a_major_opcode,
a_first_event, a_first_error);
}
static int
ephyrProxyProcDispatch(ClientPtr a_client)
{
int res = BadImplementation;
struct XReply reply;
if (!ephyrHostProxyDoForward(a_client->requestBuffer, &reply, FALSE)) {
EPHYR_LOG_ERROR("forwarding failed\n");
goto out;
}
reply.sequence_number = a_client->sequence;
res = Success;
WriteToClient(a_client, 32, &reply);
out:
return res;
}
static void
ephyrProxyProcReset(ExtensionEntry * a_entry)
{
}
Bool
ephyrProxyExtensionInit(const char *a_extension_name)
{
Bool is_ok = FALSE;
int major_opcode = 0, first_event = 0, first_error = 0;
ExtensionEntry *ext = NULL;
if (!ephyrProxyGetHostExtensionInfo(a_extension_name,
&major_opcode,
&first_event, &first_error)) {
EPHYR_LOG("failed to query extension %s from host\n", a_extension_name);
goto out;
}
ext = AddExtension((char *) a_extension_name, 0, 0,
ephyrProxyProcDispatch,
ephyrProxyProcDispatch,
ephyrProxyProcReset, StandardMinorOpcode);
if (!ext) {
EPHYR_LOG_ERROR("failed to add the extension\n");
goto out;
}
is_ok = TRUE;
out:
EPHYR_LOG("leave\n");
return is_ok;
}

View File

@ -1,33 +0,0 @@
/*
* 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>
*/
#ifndef __EPHYRPROXYEXT_H__
#define __EPHYRPROXYEXT_H__
Bool ephyrProxyExtensionInit(const char *a_extension_name);
#endif /*__EPHYRPROXYEXT_H__*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,8 @@
#include <X11/X.h>
#include <X11/Xmd.h>
#include <xcb/xcb.h>
#include "ephyr.h"
#define EPHYR_WANT_DEBUG 0
@ -39,69 +41,12 @@
#endif
typedef struct EphyrHostXVars EphyrHostXVars;
typedef struct EphyrHostXEvent EphyrHostXEvent;
typedef void *EphyrScreenInfo;
typedef enum EphyrHostXEventType {
EPHYR_EV_MOUSE_MOTION,
EPHYR_EV_MOUSE_PRESS,
EPHYR_EV_MOUSE_RELEASE,
EPHYR_EV_KEY_PRESS,
EPHYR_EV_KEY_RELEASE,
EPHYR_EV_EXPOSE,
EPHYR_EV_CONFIGURE,
} EphyrHostXEventType;
/* I can't believe it's not a KeySymsRec. */
typedef struct {
int minKeyCode;
int maxKeyCode;
int mapWidth;
CARD32 *map;
} EphyrKeySyms;
struct EphyrHostXEvent {
EphyrHostXEventType type;
union {
struct mouse_motion {
int x;
int y;
int screen;
int window;
} mouse_motion;
struct mouse_down {
int button_num;
} mouse_down;
struct mouse_up {
int button_num;
} mouse_up;
struct key_up {
int scancode;
} key_up;
struct key_down {
int scancode;
} key_down;
struct expose {
int window;
} expose;
struct configure {
int width;
int height;
int screen;
int window;
} configure;
} data;
int key_state;
};
typedef struct {
VisualID visualid;
int screen;
@ -129,13 +74,13 @@ typedef struct {
} EphyrRect;
int
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height);
int
hostx_want_host_cursor(void);
void
hostx_use_host_cursor(void);
hostx_use_sw_cursor(void);
void
hostx_use_fullscreen(void);
@ -144,7 +89,7 @@ int
hostx_want_fullscreen(void);
int
hostx_want_preexisting_window(EphyrScreenInfo screen);
hostx_want_preexisting_window(KdScreenInfo *screen);
void
hostx_use_preexisting_window(unsigned long win_id);
@ -162,52 +107,50 @@ int
hostx_init(void);
void
hostx_add_screen(EphyrScreenInfo screen, unsigned long win_id, int screen_num);
hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num);
void
hostx_set_display_name(char *name);
void
hostx_set_screen_number(EphyrScreenInfo screen, int number);
hostx_set_screen_number(KdScreenInfo *screen, int number);
void
hostx_set_win_title(EphyrScreenInfo screen, const char *extra_text);
hostx_set_win_title(KdScreenInfo *screen, const char *extra_text);
int
hostx_get_depth(void);
int
hostx_get_server_depth(EphyrScreenInfo screen);
void
hostx_set_server_depth(EphyrScreenInfo screen, int depth);
hostx_get_server_depth(KdScreenInfo *screen);
int
hostx_get_bpp(void *info);
hostx_get_bpp(KdScreenInfo *screen);
void
hostx_get_visual_masks(void *info, CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
hostx_get_visual_masks(KdScreenInfo *screen,
CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
void
hostx_set_cmap_entry(unsigned char idx,
unsigned char r, unsigned char g, unsigned char b);
void *hostx_screen_init(EphyrScreenInfo screen,
void *hostx_screen_init(KdScreenInfo *screen,
int width, int height, int buffer_height,
int *bytes_per_line, int *bits_per_pixel);
void
hostx_paint_rect(EphyrScreenInfo screen,
hostx_paint_rect(KdScreenInfo *screen,
int sx, int sy, int dx, int dy, int width, int height);
void
hostx_load_keymap(void);
int
hostx_get_event(EphyrHostXEvent * ev);
xcb_connection_t *
hostx_get_xcbconn(void);
void *hostx_get_display(void);
int
hostx_get_screen(void);
int
hostx_get_window(int a_screen_number);
@ -215,11 +158,6 @@ int
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,
int *a_first_even, int *a_first_error);
int
hostx_get_visuals_info(EphyrHostVisualInfo ** a_visuals, int *a_num_entries);
@ -234,9 +172,7 @@ int hostx_set_window_geometry(int a_win, EphyrBox * a_geo);
int hostx_set_window_bounding_rectangles(int a_window,
EphyrRect * a_rects, int a_num_rects);
int hostx_set_window_clipping_rectangles(int a_window,
EphyrRect * a_rects, int a_num_rects);
int hostx_has_xshape(void);
int host_has_extension(xcb_extension_t *extension);
#ifdef XF86DRI
int hostx_lookup_peer_window(void *a_local_window,

View File

@ -1,124 +0,0 @@
/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/**
* \file xf86dri.h
* Protocol numbers and function prototypes for DRI X protocol.
*
* \author Kevin E. Martin <martin@valinux.com>
* \author Jens Owen <jens@tungstengraphics.com>
* \author Rickard E. (Rik) Faith <faith@valinux.com>
*/
#ifndef _XF86DRI_H_
#define _XF86DRI_H_
#include <X11/Xfuncproto.h>
#include <xf86drm.h>
#define X_XF86DRIQueryVersion 0
#define X_XF86DRIQueryDirectRenderingCapable 1
#define X_XF86DRIOpenConnection 2
#define X_XF86DRICloseConnection 3
#define X_XF86DRIGetClientDriverName 4
#define X_XF86DRICreateContext 5
#define X_XF86DRIDestroyContext 6
#define X_XF86DRICreateDrawable 7
#define X_XF86DRIDestroyDrawable 8
#define X_XF86DRIGetDrawableInfo 9
#define X_XF86DRIGetDeviceInfo 10
#define X_XF86DRIAuthConnection 11
#define X_XF86DRIOpenFullScreen 12 /* Deprecated */
#define X_XF86DRICloseFullScreen 13 /* Deprecated */
#define XF86DRINumberEvents 0
#define XF86DRIClientNotLocal 0
#define XF86DRIOperationNotSupported 1
#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
#ifndef _XF86DRI_SERVER_
_XFUNCPROTOBEGIN
Bool XF86DRIQueryExtension(Display * dpy, int *event_base, int *error_base);
Bool XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
int *patchVersion);
Bool XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen,
Bool *isCapable);
Bool XF86DRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
char **busIDString);
Bool XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
Bool XF86DRICloseConnection(Display * dpy, int screen);
Bool XF86DRIGetClientDriverName(Display * dpy, int screen,
int *ddxDriverMajorVersion,
int *ddxDriverMinorVersion,
int *ddxDriverPatchVersion,
char **clientDriverName);
Bool XF86DRICreateContext(Display * dpy, int screen, Visual * visual,
XID *ptr_to_returned_context_id,
drm_context_t * hHWContext);
Bool XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID,
XID *ptr_to_returned_context_id,
drm_context_t * hHWContext);
extern GLboolean XF86DRIDestroyContext(Display * dpy, int screen,
XID context_id);
extern GLboolean XF86DRICreateDrawable(Display * dpy, int screen,
XID drawable,
drm_drawable_t * hHWDrawable);
extern GLboolean XF86DRIDestroyDrawable(Display * dpy, int screen,
XID drawable);
Bool XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
unsigned int *index, unsigned int *stamp,
int *X, int *Y, int *W, int *H,
int *numClipRects, drm_clip_rect_t ** pClipRects,
int *backX, int *backY,
int *numBackClipRects,
drm_clip_rect_t ** pBackClipRects);
Bool XF86DRIGetDeviceInfo(Display * dpy, int screen,
drm_handle_t * hFrameBuffer, int *fbOrigin,
int *fbSize, int *fbStride, int *devPrivateSize,
void **pDevPrivate);
_XFUNCPROTOEND
#endif /* _XF86DRI_SERVER_ */
#endif /* _XF86DRI_H_ */