Merge Xephyr-XV/GL stuff into master

This commit is contained in:
Dodji Seketeli 2007-10-03 16:13:16 +02:00
commit 604ebb5a6d
32 changed files with 8072 additions and 44 deletions

View File

@ -55,6 +55,7 @@
void GlxWrapInitVisuals(miInitVisualsProcPtr *);
extern Bool noGlxVisualInit;
#include "glcontextmodes.h"
struct ScreenVisualsRec {
@ -452,14 +453,15 @@ Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
/*
* Setup the visuals supported by this particular screen.
*/
init_visuals(nvisualp, visualp, defaultVisp,
*ndepthp, *depthp, *rootDepthp);
if (!noGlxVisualInit) {
init_visuals(nvisualp, visualp, defaultVisp,
*ndepthp, *depthp, *rootDepthp);
}
return True;
}
/************************************************************************/

View File

@ -723,6 +723,7 @@ if test "x$XV" = xyes; then
AC_DEFINE(XV, 1, [Support Xv extension])
AC_DEFINE(XvExtension, 1, [Build Xv extension])
REQUIRED_MODULES="$REQUIRED_MODULES videoproto"
PKG_CHECK_MODULES(XV, [xv >= 0.22])
else
XVMC=no
fi
@ -1842,6 +1843,13 @@ if test "$KDRIVE" = yes; then
if test "x$XEPHYR" = xauto; then
XEPHYR=$xephyr
fi
XEPHYR_DRI=no
if test x$XEPHYR = xyes -a x$DRI = xyes; then
XEPHYR_DRI=yes
fi
if test x$XEPHYR_DRI = xyes ; then
AC_DEFINE(XEPHYR_DRI,1,[enable DRI extension in xephyr])
fi
# Xephyr needs nanosleep() which is in librt on Solaris
AC_CHECK_FUNC([nanosleep], [],
@ -1861,9 +1869,9 @@ if test "$KDRIVE" = yes; then
KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS"
KDRIVE_PURE_LIBS="$FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB"
KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $XV_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
case $host_os in
*linux*)

View File

@ -184,6 +184,8 @@ _X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
char *name;
char **aliases;
if (!ext)
return FALSE ;
aliases = (char **)xrealloc(ext->aliases,
(ext->num_aliases + 1) * sizeof(char *));
if (!aliases)

View File

@ -722,6 +722,48 @@ exaDriverAlloc(void)
return xcalloc(1, sizeof(ExaDriverRec));
}
static Bool
exaDriverValidateEntryPoints (ExaDriverPtr pExaDriver)
{
Bool res=TRUE ;
if (!pExaDriver)
return FALSE ;
if (!pExaDriver->memoryBase) {
LogMessage(X_ERROR,
"Exa: Exa::memoryBase member "
"must be assigned to a value different from zero\n") ;
res = FALSE ;
}
if (!pExaDriver->memorySize) {
LogMessage(X_ERROR,
"Exa: Exa::memorySize member must be different from zero\n") ;
res = FALSE ;
}
if (pExaDriver->offScreenBase > pExaDriver->memorySize) {
LogMessage(X_ERROR,
"Exa: Exa::ffscreenBase must be <= pExaDriver->memorySize member\n") ;
res = FALSE ;
}
if (!pExaDriver->PrepareSolid) {
LogMessage(X_ERROR,
"Exa: Exa::PrepareSolid member is required to be non NULL\n") ;
res = FALSE ;
}
if (!pExaDriver->PrepareCopy) {
LogMessage(X_ERROR,
"Exa: Exa::PrepareCopy member is required to be non NULL\n") ;
res = FALSE ;
}
if (!pExaDriver->WaitMarker) {
LogMessage(X_ERROR,
"Exa: Exa::WaitWarker member is required to be non NULL\n") ;
res = FALSE ;
}
return res ;
}
/**
* @param pScreen screen being initialized
* @param pScreenInfo EXA driver record
@ -806,6 +848,12 @@ exaDriverInit (ScreenPtr pScreen,
{
pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
}
if (!exaDriverValidateEntryPoints(pScreenInfo))
{
LogMessage(X_ERROR, "Exa(%d): EXA driver entry points validation failed\n",
pScreen->myNum) ;
return FALSE ;
}
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);

View File

@ -103,6 +103,14 @@ fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
}
Bool
fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
Pixel redMask, Pixel greenMask, Pixel blueMask)
{
return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, -1,
redMask, greenMask, blueMask);
}
/*
* Given a list of formats for a screen, create a list
* of visuals and depths for the screen which coorespond to

View File

@ -0,0 +1,517 @@
/*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* (C) Copyright IBM Corporation 2004
* 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
* on 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
* THE COPYRIGHT HOLDERS AND/OR THEIR 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 dri_interface.h
*
* This file contains all the types and functions that define the interface
* between a DRI driver and driver loader. Currently, the most common driver
* loader is the XFree86 libGL.so. However, other loaders do exist, and in
* the future the server-side libglx.a will also be a loader.
*
* \author Kevin E. Martin <kevin@precisioninsight.com>
* \author Ian Romanick <idr@us.ibm.com>
*/
#ifndef DRI_INTERFACE_H
#define DRI_INTERFACE_H
#include <GL/internal/glcore.h>
#include <drm.h>
/**
* \name DRI interface structures
*
* The following structures define the interface between the GLX client
* side library and the DRI (direct rendering infrastructure).
*/
/*@{*/
typedef struct __DRIdisplayRec __DRIdisplay;
typedef struct __DRIscreenRec __DRIscreen;
typedef struct __DRIcontextRec __DRIcontext;
typedef struct __DRIdrawableRec __DRIdrawable;
typedef struct __DRIdriverRec __DRIdriver;
typedef struct __DRIframebufferRec __DRIframebuffer;
typedef struct __DRIversionRec __DRIversion;
typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods;
typedef unsigned long __DRIid;
typedef void __DRInativeDisplay;
/*@}*/
/**
* \name Functions provided by the driver loader.
*/
/*@{*/
/**
* Type of a pointer to \c glXGetScreenDriver, as returned by
* \c glXGetProcAddress. This function is used to get the name of the DRI
* driver for the specified screen of the specified display. The driver
* name is typically used with \c glXGetDriverConfig.
*
* \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig
*/
typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum);
/**
* Type of a pointer to \c glXGetDriverConfig, as returned by
* \c glXGetProcAddress. This function is used to get the XML document
* describing the configuration options available for the specified driver.
*
* \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver
*/
typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName);
/**
* Type of a pointer to \c glxEnableExtension, as returned by
* \c __DRIinterfaceMethods::getProcAddress. This function is used to enable
* a GLX extension on the specified screen.
*/
typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
/*@}*/
/**
* \name Functions and data provided by the driver.
*/
/*@{*/
typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn,
__DRIscreen *psc, const __GLcontextModes * modes,
const __DRIversion * ddx_version, const __DRIversion * dri_version,
const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
void * pSAREA, int fd, int internal_api_version,
const __DRIinterfaceMethods * interface,
__GLcontextModes ** driver_modes);
typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
/**
* XML document describing the configuration options supported by the
* driver.
*/
extern const char __driConfigOptions[];
/*@}*/
/**
* Stored version of some component (i.e., server-side DRI module, kernel-side
* DRM, etc.).
*
* \todo
* There are several data structures that explicitly store a major version,
* minor version, and patch level. These structures should be modified to
* have a \c __DRIversionRec instead.
*/
struct __DRIversionRec {
int major; /**< Major version number. */
int minor; /**< Minor version number. */
int patch; /**< Patch-level. */
};
typedef void (*__DRIfuncPtr)(void);
struct __DRIinterfaceMethodsRec {
/**
* Get pointer to named function.
*/
__DRIfuncPtr (*getProcAddress)( const char * proc_name );
/**
* Create a list of \c __GLcontextModes structures.
*/
__GLcontextModes * (*createContextModes)(unsigned count,
size_t minimum_bytes_per_struct);
/**
* Destroy a list of \c __GLcontextModes structures.
*
* \todo
* Determine if the drivers actually need to call this.
*/
void (*destroyContextModes)( __GLcontextModes * modes );
/**
* Get the \c __DRIscreen for a given display and screen number.
*/
__DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum);
/**
* \name Client/server protocol functions.
*
* These functions implement the DRI client/server protocol for
* context and drawable operations. Platforms that do not implement
* the wire protocol (e.g., EGL) will implement glorified no-op functions.
*/
/*@{*/
/**
* Determine if the specified window ID still exists.
*
* \note
* Implementations may assume that the driver will only pass an ID into
* this function that actually corresponds to a window. On
* implementations where windows can only be destroyed by the DRI driver
* (e.g., EGL), this function is allowed to always return \c GL_TRUE.
*/
GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
/**
* Create the server-side portion of the GL context.
*/
GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum,
int configID, void * contextID, drm_context_t * hw_context );
/**
* Destroy the server-side portion of the GL context.
*/
GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum,
__DRIid context );
/**
* Create the server-side portion of the drawable.
*/
GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen,
__DRIid drawable, drm_drawable_t * hHWDrawable );
/**
* Destroy the server-side portion of the drawable.
*/
GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen,
__DRIid drawable );
/**
* This function is used to get information about the position, size, and
* clip rects of a drawable.
*/
GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn,
__DRIid draw, unsigned int * index, unsigned int * stamp,
int * x, int * y, int * width, int * height,
int * numClipRects, drm_clip_rect_t ** pClipRects,
int * backX, int * backY,
int * numBackClipRects, drm_clip_rect_t ** pBackClipRects );
/*@}*/
/**
* \name Timing related functions.
*/
/*@{*/
/**
* Get the 64-bit unadjusted system time (UST).
*/
int (*getUST)(int64_t * ust);
/**
* Get the media stream counter (MSC) rate.
*
* Matching the definition in GLX_OML_sync_control, this function returns
* the rate of the "media stream counter". In practical terms, this is
* the frame refresh rate of the display.
*/
GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable,
int32_t * numerator, int32_t * denominator);
/*@}*/
/**
* Reports areas of the given drawable which have been modified by the
* driver.
*
* \param drawable which the drawing was done to.
* \param rects rectangles affected, with the drawable origin as the
* origin.
* \param x X offset of the drawable within the screen (used in the
* front_buffer case)
* \param y Y offset of the drawable within the screen.
* \param front_buffer boolean flag for whether the drawing to the
* drawable was actually done directly to the front buffer (instead
* of backing storage, for example)
*/
void (*reportDamage)(__DRInativeDisplay * dpy, int screen,
__DRIid drawable,
int x, int y,
drm_clip_rect_t *rects, int num_rects,
int front_buffer);
};
/**
* Framebuffer information record. Used by libGL to communicate information
* about the framebuffer to the driver's \c __driCreateNewScreen function.
*
* In XFree86, most of this information is derrived from data returned by
* calling \c XF86DRIGetDeviceInfo.
*
* \sa XF86DRIGetDeviceInfo __DRIdisplayRec::createNewScreen
* __driUtilCreateNewScreen CallCreateNewScreen
*
* \bug This structure could be better named.
*/
struct __DRIframebufferRec {
unsigned char *base; /**< Framebuffer base address in the CPU's
* address space. This value is calculated by
* calling \c drmMap on the framebuffer handle
* returned by \c XF86DRIGetDeviceInfo (or a
* similar function).
*/
int size; /**< Framebuffer size, in bytes. */
int stride; /**< Number of bytes from one line to the next. */
int width; /**< Pixel width of the framebuffer. */
int height; /**< Pixel height of the framebuffer. */
int dev_priv_size; /**< Size of the driver's dev-priv structure. */
void *dev_priv; /**< Pointer to the driver's dev-priv structure. */
};
/**
* Screen dependent methods. This structure is initialized during the
* \c __DRIdisplayRec::createScreen call.
*/
struct __DRIscreenRec {
/**
* Method to destroy the private DRI screen data.
*/
void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate);
/**
* Method to create the private DRI drawable data and initialize the
* drawable dependent methods.
*/
void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
__DRIid draw, __DRIdrawable *pdraw,
int renderType, const int *attrs);
/**
* Method to return a pointer to the DRI drawable data.
*/
__DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
void *drawablePrivate);
/**
* Opaque pointer to private per screen direct rendering data. \c NULL
* if direct rendering is not supported on this screen. Never
* dereferenced in libGL.
*/
void *private;
/**
* Get the number of vertical refreshes since some point in time before
* this function was first called (i.e., system start up).
*
* \since Internal API version 20030317.
*/
int (*getMSC)( void *screenPrivate, int64_t *msc );
/**
* Opaque pointer that points back to the containing
* \c __GLXscreenConfigs. This data structure is shared with DRI drivers
* but \c __GLXscreenConfigs is not. However, they are needed by some GLX
* functions called by DRI drivers.
*
* \since Internal API version 20030813.
*/
void *screenConfigs;
/**
* Functions associated with MESA_allocate_memory.
*
* \since Internal API version 20030815.
*/
/*@{*/
void *(*allocateMemory)(__DRInativeDisplay *dpy, int scrn, GLsizei size,
GLfloat readfreq, GLfloat writefreq,
GLfloat priority);
void (*freeMemory)(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer);
GLuint (*memoryOffset)(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer);
/*@}*/
/**
* Method to create the private DRI context data and initialize the
* context dependent methods.
*
* \since Internal API version 20031201.
*/
void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
int render_type,
void *sharedPrivate, __DRIcontext *pctx);
/**
* Method to override base texture image with a driver specific 'offset'.
* The depth passed in allows e.g. to ignore the alpha channel of texture
* images where the non-alpha components don't occupy a whole texel.
*
* For GLX_EXT_texture_from_pixmap with AIGLX.
*
* \since Internal API version 20070121.
*/
void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
unsigned long long offset, GLint depth, GLuint pitch);
};
/**
* Context dependent methods. This structure is initialized during the
* \c __DRIscreenRec::createContext call.
*/
struct __DRIcontextRec {
/**
* Method to destroy the private DRI context data.
*/
void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate);
/**
* Opaque pointer to private per context direct rendering data.
* \c NULL if direct rendering is not supported on the display or
* screen used to create this context. Never dereferenced in libGL.
*/
void *private;
/**
* Pointer to the mode used to create this context.
*
* \since Internal API version 20040317.
*/
const __GLcontextModes * mode;
/**
* Method to bind a DRI drawable to a DRI graphics context.
*
* \since Internal API version 20050727.
*/
GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
__DRIid read, __DRIcontext *ctx);
/**
* Method to unbind a DRI drawable from a DRI graphics context.
*
* \since Internal API version 20050727.
*/
GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
__DRIid read, __DRIcontext *ctx);
};
/**
* Drawable dependent methods. This structure is initialized during the
* \c __DRIscreenRec::createDrawable call. \c createDrawable is not called
* by libGL at this time. It's currently used via the dri_util.c utility code
* instead.
*/
struct __DRIdrawableRec {
/**
* Method to destroy the private DRI drawable data.
*/
void (*destroyDrawable)(__DRInativeDisplay *dpy, void *drawablePrivate);
/**
* Method to swap the front and back buffers.
*/
void (*swapBuffers)(__DRInativeDisplay *dpy, void *drawablePrivate);
/**
* Opaque pointer to private per drawable direct rendering data.
* \c NULL if direct rendering is not supported on the display or
* screen used to create this drawable. Never dereferenced in libGL.
*/
void *private;
/**
* Get the number of completed swap buffers for this drawable.
*
* \since Internal API version 20030317.
*/
int (*getSBC)(__DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc );
/**
* Wait for the SBC to be greater than or equal target_sbc.
*
* \since Internal API version 20030317.
*/
int (*waitForSBC)( __DRInativeDisplay * dpy, void *drawablePriv,
int64_t target_sbc,
int64_t * msc, int64_t * sbc );
/**
* Wait for the MSC to equal target_msc, or, if that has already passed,
* the next time (MSC % divisor) is equal to remainder. If divisor is
* zero, the function will return as soon as MSC is greater than or equal
* to target_msc.
*
* \since Internal API version 20030317.
*/
int (*waitForMSC)( __DRInativeDisplay * dpy, void *drawablePriv,
int64_t target_msc, int64_t divisor, int64_t remainder,
int64_t * msc, int64_t * sbc );
/**
* Like \c swapBuffers, but does NOT have an implicit \c glFlush. Once
* rendering is complete, waits until MSC is equal to target_msc, or
* if that has already passed, waits until (MSC % divisor) is equal
* to remainder. If divisor is zero, the swap will happen as soon as
* MSC is greater than or equal to target_msc.
*
* \since Internal API version 20030317.
*/
int64_t (*swapBuffersMSC)(__DRInativeDisplay *dpy, void *drawablePrivate,
int64_t target_msc,
int64_t divisor, int64_t remainder);
/**
* Enable or disable frame usage tracking.
*
* \since Internal API version 20030317.
*/
int (*frameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, GLboolean enable);
/**
* Retrieve frame usage information.
*
* \since Internal API version 20030317.
*/
int (*queryFrameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate,
int64_t * sbc, int64_t * missedFrames,
float * lastMissedUsage, float * usage );
/**
* Used by drivers that implement the GLX_SGI_swap_control or
* GLX_MESA_swap_control extension.
*
* \since Internal API version 20030317.
*/
unsigned swap_interval;
/**
* Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
*
* \since Internal API version 20060314.
*/
void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate,
int x, int y, int w, int h);
};
#endif

View File

@ -3,22 +3,47 @@ INCLUDES = \
@KDRIVE_CFLAGS@ \
-I$(srcdir)/../../../exa
noinst_LIBRARIES = libxephyr.a libxephyr-hostx.a
noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a
bin_PROGRAMS = Xephyr
libxephyr_hostx_a_SOURCES = \
hostx.c \
hostx.h
libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@
libxephyr_hostxv_a_SOURCES= \
ephyrhostvideo.c \
ephyrhostvideo.h
libxephyr_a_SOURCES = \
ephyr.c \
ephyr_draw.c \
ephyrvideo.c \
XF86dri.c \
ephyrdriext.c \
ephyrdri.c \
ephyrdri.h \
ephyrglxext.c \
ephyrglxext.h \
ephyrhostglx.c \
ephyrhostglx.h \
ephyrhostproxy.c \
ephyrhostproxy.h \
ephyrhostproxy.c \
ephyrproxyext.c \
ephyrproxyext.h \
os.c \
hostx.h \
ephyr.h
hostx.h \
ephyr.h \
ephyrlog.h
libxephyr_hostx_a_SOURCES = \
hostx.c \
hostx.h
libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@
libxephyr_a_CFLAGS = \
@LIBDRM_CFLAGS@ \
-I$(top_srcdir) \
@DRIPROTO_CFLAGS@
Xephyr_SOURCES = \
ephyrinit.c
@ -26,13 +51,17 @@ Xephyr_SOURCES = \
Xephyr_LDADD = \
libxephyr.a \
libxephyr-hostx.a \
libxephyr-hostxv.a \
../../../exa/libexa.la \
@KDRIVE_LIBS@ \
@XEPHYR_LIBS@
@XEPHYR_LIBS@ \
@LIBDRM_LIBS@ \
-lGL
Xephyr_DEPENDENCIES = \
libxephyr.a \
libxephyr-hostx.a \
libxephyr-hostxv.a \
@KDRIVE_LOCAL_LIBS@
relink:

622
hw/kdrive/ephyr/XF86dri.c Normal file
View File

@ -0,0 +1,622 @@
/* $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
#ifdef XEPHYR_DRI
/* THIS IS NOT AN X CONSORTIUM STANDARD */
#define NEED_REPLIES
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <GL/glx.h>
#include <X11/dri/xf86dri.h>
#include <X11/dri/xf86dristr.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(dpy, majorVersion, minorVersion, patchVersion)
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 (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
_XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
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(dpy, screen, magic)
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(dpy, screen)
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(dpy, screen, ddxDriverMajorVersion,
ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
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 (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
_XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
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(dpy, screen, configID, context,
hHWContext)
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(dpy, screen, visual, context, hHWContext)
Display* dpy;
int screen;
Visual* visual;
XID* context;
drm_context_t * hHWContext;
{
return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
context, hHWContext );
}
GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
__DRIid context )
{
Display * const dpy = (Display *) ndpy;
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( __DRInativeDisplay * ndpy, int screen,
__DRIid drawable, drm_drawable_t * hHWDrawable )
{
Display * const dpy = (Display *) ndpy;
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;
}
GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
__DRIid drawable )
{
Display * const dpy = (Display *) ndpy;
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIDestroyDrawableReq *req;
TRACE("DestroyDrawable...");
XF86DRICheckExtension (dpy, info, False);
LockDisplay(dpy);
GetReq(XF86DRIDestroyDrawable, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_XF86DRIDestroyDrawable;
req->screen = screen;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
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)) {
_XEatData(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 *)Xcalloc(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 *)Xcalloc(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 *)Xcalloc(rep.devPrivateSize, 1))) {
_XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
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;
}
#endif /*EPHYR_DRI*/

View File

@ -23,11 +23,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* TODO:
*
* o Support multiple screens, shouldn't be hard just alot of rejigging.
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
@ -35,11 +30,21 @@
#include "inputstr.h"
#include "scrnintstr.h"
#include "ephyrlog.h"
#ifdef XEPHYR_DRI
#include "ephyrdri.h"
#include "ephyrdriext.h"
#include "ephyrglxext.h"
#include "ephyrproxyext.h"
#endif /*XEPHYR_DRI*/
extern int KdTsPhyScreen;
KdKeyboardInfo *ephyrKbd;
KdPointerInfo *ephyrMouse;
EphyrKeySyms ephyrKeySyms;
Bool ephyrNoDRI=FALSE ;
Bool ephyrNoXV=FALSE ;
static int mouseState = 0;
@ -49,6 +54,7 @@ typedef struct _EphyrInputPrivate {
Bool EphyrWantGrayScale = 0;
Bool
ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
{
@ -209,7 +215,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
KdPointerMatrix m;
int buffer_height;
EPHYR_DBG("screen->width: %d, screen->height: %d index=%d",
EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
screen->width, screen->height, screen->mynum);
KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
@ -245,7 +251,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
/* Rotated/Reflected so we need to use shadow fb */
scrpriv->shadow = TRUE;
EPHYR_DBG("allocing shadow");
EPHYR_LOG("allocing shadow");
KdShadowFbAlloc (screen, 0,
scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
@ -296,7 +302,7 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
EPHYR_DBG("slow paint");
EPHYR_LOG("slow paint");
/* FIXME: Slow Rotated/Reflected updates could be much
* much faster efficiently updating via tranforming
@ -410,7 +416,7 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
Rotation randr;
int n = 0;
EPHYR_DBG("mark");
EPHYR_LOG("mark");
struct { int width, height; } sizes[] =
{
@ -563,7 +569,7 @@ ephyrRandRSetConfig (ScreenPtr pScreen,
return TRUE;
bail4:
EPHYR_DBG("bailed");
EPHYR_LOG("bailed");
ephyrUnmapFramebuffer (screen);
*scrpriv = oldscr;
@ -606,10 +612,29 @@ ephyrInitScreen (ScreenPtr pScreen)
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
EPHYR_DBG ("pScreen->myNum:%d\n", pScreen->myNum) ;
EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
hostx_set_screen_number (screen, pScreen->myNum);
hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
pScreen->CreateColormap = ephyrCreateColormap;
#ifdef XV
if (!ephyrNoXV) {
if (!ephyrInitVideo (pScreen)) {
EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
} else {
EPHYR_LOG ("initialized xvideo okay\n") ;
}
}
#endif /*XV*/
#ifdef XEPHYR_DRI
if (!ephyrNoDRI) {
ephyrDRIExtensionInit (pScreen) ;
ephyrHijackGLXExtension () ;
ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
}
#endif
return TRUE;
}
@ -621,12 +646,12 @@ ephyrFinishInitScreen (ScreenPtr pScreen)
*/
if (!shadowSetup (pScreen))
return FALSE;
#ifdef RANDR
if (!ephyrRandRInit (pScreen))
return FALSE;
#endif
return TRUE;
}
@ -637,7 +662,7 @@ ephyrCreateResources (ScreenPtr pScreen)
KdScreenInfo *screen = pScreenPriv->screen;
EphyrScrPriv *scrpriv = screen->driver;
EPHYR_DBG("mark pScreen=%p mynum=%d shadow=%d",
EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
pScreen, pScreen->myNum, scrpriv->shadow);
if (scrpriv->shadow)
@ -809,20 +834,20 @@ ephyrPoll(void)
case EPHYR_EV_MOUSE_MOTION:
if (!ephyrMouse ||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
EPHYR_DBG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
continue;
}
{
if (ephyrCurScreen != ev.data.mouse_motion.screen)
{
EPHYR_DBG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
EPHYR_LOG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
ev.data.mouse_motion.x,
ev.data.mouse_motion.y );
}
else
{
EPHYR_DBG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
KdEnqueuePointerEvent(ephyrMouse, mouseState,
ev.data.mouse_motion.x,
ev.data.mouse_motion.y,
@ -834,10 +859,10 @@ ephyrPoll(void)
case EPHYR_EV_MOUSE_PRESS:
if (!ephyrMouse ||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
EPHYR_DBG ("skipping mouse press:%d\n", ephyrCurScreen) ;
EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
continue;
}
EPHYR_DBG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
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);
@ -849,7 +874,7 @@ ephyrPoll(void)
continue;
ephyrUpdateModifierState(ev.key_state);
mouseState &= ~ev.data.mouse_up.button_num;
EPHYR_DBG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
break;
@ -886,7 +911,7 @@ ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
/* XXX Not sure if this is right */
EPHYR_DBG("mark");
EPHYR_LOG("mark");
while (n--)
{
@ -1025,6 +1050,7 @@ EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
{
}
KdKeyboardDriver EphyrKeyboardDriver = {
"ephyr",
EphyrKeyboardInit,

View File

@ -194,4 +194,8 @@ ephyrDrawDisable(ScreenPtr pScreen);
void
ephyrDrawFini(ScreenPtr pScreen);
/*ephyvideo.c*/
Bool ephyrInitVideo(ScreenPtr pScreen) ;
#endif

291
hw/kdrive/ephyr/ephyrdri.c Normal file
View File

@ -0,0 +1,291 @@
/*
* 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
#ifdef XEPHYR_DRI
#include <X11/Xutil.h>
#include <X11/Xlibint.h>
/*#define _XF86DRI_SERVER_*/
#include <GL/glx.h>
#include <X11/dri/xf86dri.h>
#include "hostx.h"
#include "ephyrdri.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include "dixstruct.h"
#include "pixmapstr.h"
#ifndef TRUE
#define TRUE 1
#endif /*TRUE*/
#ifndef FALSE
#define FALSE 0
#endif /*FALSE*/
Bool
ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
{
Display *dpy=hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRIQueryDirectRenderingCapable (dpy, DefaultScreen (dpy),
a_is_capable) ;
EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
return is_ok ;
}
Bool
ephyrDRIOpenConnection (int a_screen,
drm_handle_t *a_sarea,
char **a_bus_id_string)
{
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
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) ;
}
return is_ok ;
}
Bool
ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
{
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRIAuthConnection (dpy, DefaultScreen (dpy), a_magic) ;
EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
return is_ok ;
}
Bool
ephyrDRICloseConnection (int a_screen)
{
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRICloseConnection (dpy, DefaultScreen (dpy)) ;
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrDRIGetClientDriverName (int a_screen,
int *a_ddx_driver_major_version,
int *a_ddx_driver_minor_version,
int *a_ddx_driver_patch_version,
char ** a_client_driver_name)
{
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_RETURN_VAL_IF_FAIL (a_ddx_driver_major_version
&& a_ddx_driver_minor_version
&& 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) ;
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) ;
EPHYR_LOG ("leave:%d\n", is_ok) ;
return is_ok ;
}
Bool
ephyrDRICreateContext (int a_screen,
int a_visual_id,
unsigned long int *a_returned_ctxt_id,
drm_context_t *a_hw_ctxt)
{
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
Visual v;
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,
a_returned_ctxt_id,
a_hw_ctxt) ;
EPHYR_LOG ("leave:%d\n", is_ok) ;
return is_ok ;
}
Bool
ephyrDRIDestroyContext (int a_screen,
int a_context_id)
{
Display *dpy = hostx_get_display () ;
Bool is_ok=FALSE ;
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRIDestroyContext (dpy, DefaultScreen (dpy), a_context_id) ;
EPHYR_LOG ("leave:%d\n", is_ok) ;
return is_ok ;
}
Bool
ephyrDRICreateDrawable (int a_screen,
int a_drawable,
drm_drawable_t *a_hw_drawable)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display () ;
EPHYR_LOG ("enter\n") ;
is_ok = XF86DRICreateDrawable (dpy, DefaultScreen (dpy),
a_drawable, a_hw_drawable) ;
EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
return is_ok ;
}
Bool
ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
{
EPHYR_LOG ("enter\n") ;
EPHYR_LOG_ERROR ("not implemented yet\n") ;
EPHYR_LOG ("leave\n") ;
return FALSE ;
}
Bool
ephyrDRIGetDrawableInfo (int a_screen,
int a_drawable,
unsigned int *a_index,
unsigned int *a_stamp,
int *a_x,
int *a_y,
int *a_w,
int *a_h,
int *a_num_clip_rects,
drm_clip_rect_t **a_clip_rects,
int *a_back_x,
int *a_back_y,
int *a_num_back_clip_rects,
drm_clip_rect_t **a_back_clip_rects)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display () ;
EphyrHostWindowAttributes attrs ;
EPHYR_RETURN_VAL_IF_FAIL (a_x && a_y && a_w && a_h
&& a_num_clip_rects,
FALSE) ;
EPHYR_LOG ("enter\n") ;
memset (&attrs, 0, sizeof (attrs)) ;
if (!hostx_get_window_attributes (a_drawable, &attrs)) {
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") ;
goto out ;
}
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) ;
*a_back_clip_rects = calloc (*a_num_clip_rects,
sizeof (drm_clip_rect_t)) ;
memmove (*a_back_clip_rects,
*a_clip_rects,
*a_num_clip_rects * sizeof (drm_clip_rect_t)) ;
*a_num_back_clip_rects = *a_num_clip_rects;
}
EPHYR_LOG ("num back clip rects:%d, num clip rects:%d\n",
*a_num_clip_rects, *a_num_back_clip_rects) ;
*a_back_x = *a_x ;
*a_back_y = *a_y ;
*a_w = attrs.width;
*a_h = attrs.height;
is_ok = TRUE ;
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) ;
return is_ok ;
}
Bool
ephyrDRIGetDeviceInfo (int a_screen,
drm_handle_t *a_frame_buffer,
int *a_fb_origin,
int *a_fb_size,
int *a_fb_stride,
int *a_dev_private_size,
void **a_dev_private)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
EPHYR_RETURN_VAL_IF_FAIL (dpy, 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) ;
EPHYR_LOG ("leave:%d\n", is_ok) ;
return is_ok ;
}
#endif /*EPHYR_DRI*/

View File

@ -0,0 +1,75 @@
/*
* 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 __EPHYRDRI_H__
#define __EPHYRDRI_H__
#include <xf86drm.h>
Bool ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable) ;
Bool ephyrDRIOpenConnection (int screen, drm_handle_t *a_sarea, char **a_bus_id_string) ;
Bool ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic) ;
Bool ephyrDRICloseConnection (int a_screen) ;
Bool ephyrDRIGetClientDriverName (int a_screen,
int *a_ddx_driver_major_version,
int *a_ddx_driver_minor_version,
int *a_ddx_driver_patch_version,
char ** a_client_driver_name) ;
Bool ephyrDRICreateContext (int a_screen,
int a_visual_id,
unsigned long int *a_returned_ctx_id,
drm_context_t *a_hw_ctx) ;
Bool ephyrDRIDestroyContext (int a_screen,
int a_context_id) ;
Bool ephyrDRICreateDrawable (int a_screen,
int a_drawable,
drm_drawable_t *a_hw_drawable) ;
Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
Bool ephyrDRIGetDrawableInfo (int a_screen,
int /*Drawable*/a_drawable,
unsigned int *a_index,
unsigned int *a_stamp,
int *a_x,
int *a_y,
int *a_w,
int *a_h,
int *a_num_clip_rects,
drm_clip_rect_t **a_clip_rects,
int *a_back_x,
int *a_back_y,
int *num_back_clip_rects,
drm_clip_rect_t **a_back_clip_rects) ;
Bool ephyrDRIGetDeviceInfo (int a_screen,
drm_handle_t *a_frame_buffer,
int *a_fb_origin,
int *a_fb_size,
int *a_fb_stride,
int *a_dev_private_size,
void **a_dev_private) ;
#endif /*__EPHYRDRI_H__*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/*
* 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 __EPHYRDRIEXT_H__
#define __EPHYRDRIEXT_H__
Bool ephyrDRIExtensionInit (ScreenPtr a_screen) ;
#endif /*__EPHYRDRIEXT_H__*/

View File

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

View File

@ -0,0 +1,35 @@
/*
* 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 __EPHYR_GLXEXT_H__
#define __EPHYR_GLXEXT_H__
#include <X11/Xdefs.h>
Bool ephyrHijackGLXExtension (void) ;
#endif /*__EPHYR_GLXEXT_H__*/

View File

@ -0,0 +1,687 @@
/*
* Xephyr - A kdrive X server thats runs in a host X window.
* Authored by Matthew Allum <mallum@openedhand.com>
*
* Copyright © 2007 OpenedHand Ltd
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of OpenedHand Ltd not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. OpenedHand Ltd makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* a lots of the content of this file has been adapted from the mesa source
* code.
* Authors:
* Dodji Seketeli <dodji@openedhand.com>
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include <X11/Xlibint.h>
#include <GL/glx.h>
#include <GL/internal/glcore.h>
#include <GL/glxproto.h>
#include <GL/glxint.h>
#include "ephyrhostglx.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include "hostx.h"
#ifdef XEPHYR_DRI
enum VisualConfRequestType {
EPHYR_GET_FB_CONFIG,
EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
EPHYR_GET_VISUAL_CONFIGS
};
static Bool ephyrHostGLXGetVisualConfigsInternal
(enum VisualConfRequestType a_type,
int32_t a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf);
Bool
ephyrHostGLXGetMajorOpcode (int *a_opcode)
{
Bool is_ok=FALSE ;
Display *dpy=hostx_get_display () ;
static int opcode ;
int first_event_return=0, first_error_return=0;
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!opcode) {
if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
&first_event_return, &first_error_return)) {
EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
goto out ;
}
}
*a_opcode = opcode ;
is_ok = TRUE ;
out:
EPHYR_LOG ("release\n") ;
return is_ok ;
}
Bool
ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
int major_opcode=0;
xGLXQueryVersionReq *req=NULL;
xGLXQueryVersionReply reply;
EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
/* Send the glXQueryVersion request */
memset (&reply, 0, sizeof (reply)) ;
LockDisplay (dpy);
GetReq (GLXQueryVersion, req);
req->reqType = major_opcode;
req->glxCode = X_GLXQueryVersion;
req->majorVersion = 2;
req->minorVersion = 1;
_XReply(dpy, (xReply*) &reply, 0, False);
UnlockDisplay (dpy);
SyncHandle ();
*a_major = reply.majorVersion ;
*a_minor = reply.minorVersion ;
EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
/**
* GLX protocol structure for the ficticious "GXLGenericGetString" request.
*
* This is a non-existant protocol packet. It just so happens that all of
* the real protocol packets used to request a string from the server have
* an identical binary layout. The only difference between them is the
* meaning of the \c for_whom field and the value of the \c glxCode.
* (this has been copied from the mesa source code)
*/
typedef struct GLXGenericGetString {
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
} xGLXGenericGetStringReq;
/* These defines are only needed to make the GetReq macro happy.
*/
#define sz_xGLXGenericGetStringReq 12
#define X_GLXGenericGetString 0
Bool
ephyrHostGLXGetStringFromServer (int a_screen_number,
int a_string_name,
enum EphyrHostGLXGetStringOps a_op,
char **a_string)
{
Bool is_ok=FALSE ;
Display *dpy = hostx_get_display () ;
xGLXGenericGetStringReq *req=NULL;
xGLXSingleReply reply;
int length=0, numbytes=0, major_opcode=0, get_string_op=0;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
EPHYR_LOG ("enter\n") ;
switch (a_op) {
case EPHYR_HOST_GLX_QueryServerString:
get_string_op = X_GLXQueryServerString;
break ;
case EPHYR_HOST_GLX_GetString:
get_string_op = X_GLsop_GetString;
EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n",
a_string_name, a_screen_number) ;
break ;
default:
EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
goto out ;
}
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
LockDisplay (dpy);
/* All of the GLX protocol requests for getting a string from the server
* look the same. The exact meaning of the a_for_whom field is usually
* either the screen number (for glXQueryServerString) or the context tag
* (for GLXSingle).
*/
GetReq (GLXGenericGetString, req);
req->reqType = major_opcode;
req->glxCode = get_string_op;
req->for_whom = DefaultScreen (dpy);
req->name = a_string_name;
_XReply (dpy, (xReply *)&reply, 0, False);
length = reply.length * 4;
numbytes = reply.size;
EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
*a_string = (char *) Xmalloc (numbytes +1);
if (!a_string) {
EPHYR_LOG_ERROR ("allocation failed\n") ;
goto out;
}
memset (*a_string, 0, numbytes+1) ;
if (_XRead (dpy, *a_string, numbytes)) {
UnlockDisplay (dpy);
SyncHandle ();
EPHYR_LOG_ERROR ("read failed\n") ;
goto out ;
}
length -= numbytes;
_XEatData (dpy, length) ;
UnlockDisplay (dpy);
SyncHandle ();
EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n",
a_string_name, *a_string, numbytes) ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
static Bool
ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
int32_t a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
xGLXGetVisualConfigsReq *req;
xGLXGetFBConfigsReq *fb_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXGetFBConfigsSGIXReq *sgi_req;
xGLXGetVisualConfigsReply reply;
char *server_glx_version=NULL,
*server_glx_extensions=NULL ;
int j=0,
screens=0,
major_opcode=0,
num_props=0,
num_visuals=0,
props_buf_size=0,
props_per_visual_size=0;
int32_t *props_buf=NULL;
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
screens = ScreenCount (dpy);
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get opcode\n") ;
goto out ;
}
LockDisplay(dpy);
switch (a_type) {
case EPHYR_GET_FB_CONFIG:
GetReq(GLXGetFBConfigs,fb_req);
fb_req->reqType = major_opcode;
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = DefaultScreen (dpy);
break;
case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq
-
sz_xGLXVendorPrivateWithReplyReq,
vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = major_opcode;
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
sgi_req->screen = DefaultScreen (dpy);
break;
case EPHYR_GET_VISUAL_CONFIGS:
GetReq(GLXGetVisualConfigs,req);
req->reqType = major_opcode;
req->glxCode = X_GLXGetVisualConfigs;
req->screen = DefaultScreen (dpy);
break;
}
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
EPHYR_LOG_ERROR ("unknown error\n") ;
UnlockDisplay(dpy);
goto out ;
}
if (!reply.numVisuals) {
EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
UnlockDisplay(dpy);
goto out ;
}
num_visuals = reply.numVisuals ;
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
* FIXME: FBconfigs?
*/
/* Check number of properties */
num_props = reply.numProps;
if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
(num_props > __GLX_MAX_CONFIG_PROPS)) {
/* Huh? Not in protocol defined limits. Punt */
EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
UnlockDisplay(dpy);
goto out ;
}
if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
num_props *= 2;
}
props_per_visual_size = num_props * __GLX_SIZE_INT32;
props_buf_size = props_per_visual_size * reply.numVisuals;
props_buf = malloc (props_buf_size) ;
for (j = 0; j < reply.numVisuals; j++) {
if (_XRead (dpy,
&((char*)props_buf)[j*props_per_visual_size],
props_per_visual_size) != Success) {
EPHYR_LOG_ERROR ("read failed\n") ;
}
}
UnlockDisplay(dpy);
*a_num_visuals = num_visuals ;
*a_num_props = reply.numProps ;
*a_props_buf_size = props_buf_size ;
*a_props_buf = props_buf ;
is_ok = TRUE ;
out:
if (server_glx_version) {
XFree (server_glx_version) ;
server_glx_version = NULL ;
}
if (server_glx_extensions) {
XFree (server_glx_extensions) ;
server_glx_extensions = NULL ;
}
SyncHandle () ;
return is_ok;
}
Bool
ephyrHostGLXGetVisualConfigs (int32_t a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf)
{
Bool is_ok = FALSE;
EPHYR_LOG ("enter\n") ;
is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS,
a_screen,
a_num_visuals,
a_num_props,
a_props_buf_size,
a_props_buf) ;
EPHYR_LOG ("leave:%d\n", is_ok) ;
return is_ok;
}
Bool
ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf)
{
Bool is_ok=FALSE ;
EPHYR_LOG ("enter\n") ;
is_ok = ephyrHostGLXGetVisualConfigsInternal
(EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
a_screen,
a_num_visuals,
a_num_props,
a_props_buf_size,
a_props_buf) ;
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
const char* a_extension_list)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
xGLXClientInfoReq *req;
int size;
int32_t major_opcode=0 ;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
LockDisplay (dpy);
GetReq (GLXClientInfo,req);
req->reqType = major_opcode;
req->glxCode = X_GLXClientInfo;
req->major = a_major;
req->minor = a_minor;
size = strlen (a_extension_list) + 1;
req->length += (size + 3) >> 2;
req->numbytes = size;
Data (dpy, a_extension_list, size);
UnlockDisplay(dpy);
SyncHandle();
is_ok=TRUE ;
out:
return is_ok ;
}
Bool
ephyrHostGLXCreateContext (int a_screen,
int a_visual_id,
int a_context_id,
int a_share_list_ctxt_id,
Bool a_direct)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display ();
int major_opcode=0, remote_context_id=0;
xGLXCreateContextReq *req;
EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
a_screen, a_visual_id, a_context_id, a_direct) ;
if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) {
EPHYR_LOG_ERROR ("failed to peer the context id %d host X",
remote_context_id) ;
goto out ;
}
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
LockDisplay (dpy) ;
/* Send the glXCreateContext request */
GetReq(GLXCreateContext,req);
req->reqType = major_opcode;
req->glxCode = X_GLXCreateContext;
req->context = remote_context_id;
req->visual = a_visual_id;
req->screen = DefaultScreen (dpy);
req->shareList = a_share_list_ctxt_id;
req->isDirect = a_direct;
UnlockDisplay (dpy);
SyncHandle ();
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostDestroyContext (int a_ctxt_id)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display ();
int major_opcode=0, remote_ctxt_id=0 ;
xGLXDestroyContextReq *req=NULL;
EPHYR_LOG ("enter:%d\n", a_ctxt_id) ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) {
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
goto out ;
}
EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ;
LockDisplay (dpy);
GetReq (GLXDestroyContext,req);
req->reqType = major_opcode;
req->glxCode = X_GLXDestroyContext;
req->context = remote_ctxt_id;
UnlockDisplay (dpy);
SyncHandle ();
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostGLXMakeCurrent (int a_drawable,
int a_glx_ctxt_id,
int a_old_ctxt_tag,
int *a_ctxt_tag)
{
Bool is_ok=FALSE ;
Display *dpy = hostx_get_display () ;
int32_t major_opcode=0 ;
int remote_glx_ctxt_id=0 ;
xGLXMakeCurrentReq *req;
xGLXMakeCurrentReply reply;
EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ;
EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n",
a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) {
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
goto out ;
}
LockDisplay (dpy);
GetReq (GLXMakeCurrent,req);
req->reqType = major_opcode;
req->glxCode = X_GLXMakeCurrent;
req->drawable = a_drawable;
req->context = remote_glx_ctxt_id;
req->oldContextTag = a_old_ctxt_tag;
memset (&reply, 0, sizeof (reply)) ;
if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
UnlockDisplay (dpy);
SyncHandle ();
goto out ;
}
UnlockDisplay (dpy);
SyncHandle ();
*a_ctxt_tag = reply.contextTag ;
EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
#define X_GLXSingle 0
#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
*((INT8 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
*((INT16 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
*((INT32 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
*((FLOAT32 *) (pc + offset)) = a
#define EPHYR_GLX_SINGLE_READ_XREPLY() \
(void) _XReply(dpy, (xReply*) &reply, 0, False)
#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
a = (cast) reply.retval
#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
a = (GLint) reply.size
#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
*p = *(GLbyte *)&reply.pad3;
#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
*p = *(GLshort *)&reply.pad3;
#define EPHYR_GLX_SINGLE_GET_LONG(p) \
*p = *(GLint *)&reply.pad3;
#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
*p = *(GLfloat *)&reply.pad3;
Bool
ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val)
{
Bool is_ok=FALSE;
Display *dpy = hostx_get_display () ;
int major_opcode=0, size=0;
xGLXSingleReq *req=NULL;
xGLXSingleReply reply;
unsigned char* pc=NULL ;
EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
LockDisplay (dpy) ;
GetReqExtra (GLXSingle, 4, req) ;
req->reqType = major_opcode ;
req->glxCode = X_GLsop_GetIntegerv ;
req->contextTag = a_current_context_tag;
pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ;
EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ;
EPHYR_GLX_SINGLE_READ_XREPLY () ;
EPHYR_GLX_SINGLE_GET_SIZE (size) ;
if (!size) {
UnlockDisplay (dpy) ;
SyncHandle () ;
EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ;
goto out ;
}
EPHYR_GLX_SINGLE_GET_LONG (a_val) ;
UnlockDisplay (dpy) ;
SyncHandle () ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
Bool
ephyrHostIsContextDirect (int a_ctxt_id,
int *a_is_direct)
{
Bool is_ok=FALSE;
Display *dpy = hostx_get_display () ;
xGLXIsDirectReq *req=NULL;
xGLXIsDirectReply reply;
int major_opcode=0, remote_glx_ctxt_id=0;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
goto out ;
}
memset (&reply, 0, sizeof (reply)) ;
/* Send the glXIsDirect request */
LockDisplay (dpy);
GetReq (GLXIsDirect,req);
req->reqType = major_opcode;
req->glxCode = X_GLXIsDirect;
req->context = remote_glx_ctxt_id;
if (!_XReply (dpy, (xReply*) &reply, 0, False)) {
EPHYR_LOG_ERROR ("fail in reading reply from host\n") ;
UnlockDisplay (dpy);
SyncHandle ();
goto out ;
}
UnlockDisplay (dpy);
SyncHandle ();
*a_is_direct = reply.isDirect ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
#endif /*XEPHYR_DRI*/

View File

@ -0,0 +1,76 @@
/*
* 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 __EPHYRHOSTGLX_H__
#define __EPHYRHOSTGLX_H__
enum EphyrHostGLXGetStringOps {
EPHYR_HOST_GLX_UNDEF,
EPHYR_HOST_GLX_QueryServerString,
EPHYR_HOST_GLX_GetString,
};
Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
int a_string_name,
enum EphyrHostGLXGetStringOps a_op,
char **a_string) ;
Bool ephyrHostGLXGetVisualConfigs (int a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf) ;
Bool
ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf);
Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
const char* a_extension_list) ;
Bool ephyrHostGLXCreateContext (int a_screen,
int a_visual_id,
int a_context_id,
int a_shared_list_ctx_id,
Bool a_direct) ;
Bool ephyrHostDestroyContext (int a_ctxt_id) ;
Bool ephyrHostGLXMakeCurrent (int a_drawable, int a_glx_ctxt_id,
int a_olg_ctxt_tag, int *a_ctxt_tag) ;
Bool ephyrHostGetIntegerValue (int a_current_context_tag,
int a_int,
int *a_val) ;
Bool ephyrHostIsContextDirect (int a_ctxt_id,
int *a_is_direct) ;
#endif /*__EPHYRHOSTGLX_H__*/

View File

@ -0,0 +1,94 @@
/*
* 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, n) ;
}
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

@ -0,0 +1,51 @@
/*
* 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__*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,238 @@
/*
* 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

@ -27,11 +27,15 @@
#include <kdrive-config.h>
#endif
#include "ephyr.h"
#include "ephyrlog.h"
extern Window EphyrPreExistingHostWin;
extern Bool EphyrWantGrayScale;
extern Bool kdHasPointer;
extern Bool kdHasKbd;
extern Bool ephyrNoDRI;
extern Bool ephyrNoXV;
extern Bool noGlxVisualInit;
void processScreenArg (char *screen_size, char *parent_id) ;
@ -92,11 +96,14 @@ ddxUseMsg (void)
KdUseMsg();
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("-fullscreen Attempt to run Xephyr fullscreen\n");
ErrorF("-grayscale Simulate 8bit grayscale\n");
ErrorF("-fakexa Simulate acceleration using software rendering\n");
ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
ErrorF("-grayscale Simulate 8bit grayscale\n");
ErrorF("-fakexa Simulate acceleration using software rendering\n");
ErrorF("-verbosity <level> Set log verbosity level\n");
ErrorF("-nodri do not use DRI\n");
ErrorF("-noxv do not use XV\n");
ErrorF("\n");
exit(1);
@ -137,6 +144,8 @@ ddxProcessArgument (int argc, char **argv, int i)
{
EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
noGlxVisualInit = TRUE ;
if (!strcmp (argv[i], "-parent"))
{
if(i+1 < argc)
@ -182,6 +191,34 @@ ddxProcessArgument (int argc, char **argv, int i)
ephyrFuncs.finiAccel = ephyrDrawFini;
return 1;
}
else if (!strcmp (argv[i], "-verbosity"))
{
if(i+1 < argc && argv[i+1][0] != '-')
{
int verbosity=atoi (argv[i+1]) ;
LogSetParameter (XLOG_VERBOSITY, verbosity) ;
EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
return 2 ;
}
else
{
UseMsg() ;
exit(1) ;
}
}
else if (!strcmp (argv[i], "-nodri"))
{
noGlxVisualInit = FALSE ;
ephyrNoDRI = TRUE ;
EPHYR_LOG ("no direct rendering enabled\n") ;
return 1 ;
}
else if (!strcmp (argv[i], "-noxv"))
{
ephyrNoXV = TRUE ;
EPHYR_LOG ("no XVideo enabled\n") ;
return 1 ;
}
else if (argv[i][0] == ':')
{
hostx_set_display_name(argv[i]);

View File

@ -0,0 +1,67 @@
/*
* 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 __EPHYRLOG_H__
#define __EPHYRLOG_H__
#include <assert.h>
#include "os.h"
#ifdef NDEBUG
/*we are not in debug mode*/
#define EPHYR_LOG
#define EPHYR_LOG_ERROR
#endif /*NDEBUG*/
#define ERROR_LOG_LEVEL 3
#define INFO_LOG_LEVEL 4
#ifndef EPHYR_LOG
#define EPHYR_LOG(...) \
LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\
__FILE__, __LINE__, __func__) ; \
LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__)
#endif /*nomadik_log*/
#ifndef EPHYR_LOG_ERROR
#define EPHYR_LOG_ERROR(...) \
LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\
__FILE__, __LINE__, __func__) ; \
LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__)
#endif /*EPHYR_LOG_ERROR*/
#ifndef EPHYR_RETURN_IF_FAIL
#define EPHYR_RETURN_IF_FAIL(cond) \
if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return;}
#endif /*nomadik_return_if_fail*/
#ifndef EPHYR_RETURN_VAL_IF_FAIL
#define EPHYR_RETURN_VAL_IF_FAIL(cond,val) \
if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return val;}
#endif /*nomadik_return_val_if_fail*/
#endif /*__EPHYRLOG_H__*/

View File

@ -0,0 +1,119 @@
/*
* 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, (char *)&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

@ -0,0 +1,34 @@
/*
* 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__*/

1278
hw/kdrive/ephyr/ephyrvideo.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "hostx.h"
#include <stdlib.h>
@ -40,6 +44,17 @@
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/shape.h>
#ifdef XEPHYR_DRI
#include <GL/glx.h>
#endif /*XEPHYR_DRI*/
#include "ephyrlog.h"
#ifdef XEPHYR_DRI
extern Bool XF86DRIQueryExtension (Display *dpy,
int *event_basep,
int *error_basep);
#endif
/*
* All xlib calls go here, which gets built as its own .a .
@ -956,3 +971,382 @@ hostx_get_event(EphyrHostXEvent *ev)
return 0;
}
void*
hostx_get_display(void)
{
return HostX.dpy ;
}
int
hostx_get_window (int a_screen_number)
{
if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) {
EPHYR_LOG_ERROR ("bad screen number:%d\n", a_screen_number) ;
return 0;
}
return HostX.screens[a_screen_number].win ;
}
int
hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attrs)
{
XWindowAttributes attrs ;
memset (&attrs, 0, sizeof (attrs)) ;
if (!XGetWindowAttributes (hostx_get_display (),
a_window,
&attrs)) {
return FALSE ;
}
a_attrs->x = attrs.x ;
a_attrs->y = attrs.y ;
a_attrs->width = attrs.width ;
a_attrs->height = attrs.height ;
if (attrs.visual)
a_attrs->visualid = attrs.visual->visualid ;
return TRUE ;
}
int
hostx_get_extension_info (const char *a_ext_name,
int *a_major_opcode,
int *a_first_event,
int *a_first_error)
{
if (!a_ext_name || !a_major_opcode || !a_first_event || !a_first_error)
return 0 ;
if (!XQueryExtension (HostX.dpy,
a_ext_name,
a_major_opcode,
a_first_event,
a_first_error))
{
return 0 ;
}
return 1 ;
}
int
hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
int *a_num_entries)
{
Display *dpy=hostx_get_display () ;
Bool is_ok=False ;
XVisualInfo templ, *visuals=NULL;
EphyrHostVisualInfo *host_visuals=NULL ;
int nb_items=0, i=0;
EPHYR_RETURN_VAL_IF_FAIL (a_visuals && a_num_entries && dpy,
False) ;
EPHYR_LOG ("enter\n") ;
memset (&templ, 0, sizeof (templ)) ;
visuals = XGetVisualInfo (dpy, VisualNoMask, &templ, &nb_items) ;
if (!visuals) {
EPHYR_LOG_ERROR ("host does not advertise any visual\n") ;
goto out ;
}
EPHYR_LOG ("host advertises %d visuals\n", nb_items) ;
host_visuals = calloc (nb_items, sizeof (EphyrHostVisualInfo)) ;
for (i=0; i<nb_items; i++) {
host_visuals[i].visualid = visuals[i].visualid ;
host_visuals[i].screen = visuals[i].screen ;
host_visuals[i].depth = visuals[i].depth ;
host_visuals[i].class = visuals[i].class ;
host_visuals[i].red_mask = visuals[i].red_mask ;
host_visuals[i].green_mask = visuals[i].green_mask ;
host_visuals[i].blue_mask = visuals[i].blue_mask ;
host_visuals[i].colormap_size = visuals[i].colormap_size ;
host_visuals[i].bits_per_rgb = visuals[i].bits_per_rgb ;
}
*a_visuals = host_visuals ;
*a_num_entries = nb_items;
host_visuals=NULL;
is_ok = TRUE;
out:
if (visuals) {
XFree (visuals) ;
visuals = NULL;
}
if (host_visuals) {
free (host_visuals) ;
host_visuals = NULL;
}
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
typedef struct {
int is_valid ;
int local_id ;
int remote_id ;
} ResourcePair ;
#define RESOURCE_PEERS_SIZE 1024*10
static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
int
hostx_create_window (int a_screen_number,
EphyrBox *a_geometry,
int a_visual_id,
int *a_host_peer /*out parameter*/)
{
Bool is_ok=FALSE ;
Display *dpy=hostx_get_display () ;
XVisualInfo *visual_info=NULL, visual_info_templ;
int visual_mask=VisualIDMask ;
Window win=None ;
int nb_visuals=0, winmask=0;
XSetWindowAttributes attrs;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geometry, FALSE) ;
EPHYR_LOG ("enter\n") ;
/*get visual*/
memset (&visual_info, 0, sizeof (visual_info)) ;
visual_info_templ.visualid = a_visual_id ;
visual_info = XGetVisualInfo (dpy, visual_mask,
&visual_info_templ,
&nb_visuals) ;
if (!visual_info) {
EPHYR_LOG_ERROR ("argh, could not find a remote visual with id:%d\n",
a_visual_id) ;
goto out ;
}
memset (&attrs, 0, sizeof (attrs)) ;
attrs.colormap = XCreateColormap (dpy,
RootWindow (dpy,
visual_info->screen),
visual_info->visual,
AllocNone) ;
winmask = CWColormap;
win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
a_geometry->x, a_geometry->y,
a_geometry->width, a_geometry->height, 0,
visual_info->depth, InputOutput,
visual_info->visual, winmask, &attrs) ;
if (win == None) {
EPHYR_LOG_ERROR ("failed to create peer window\n") ;
goto out ;
}
XFlush (dpy) ;
XMapWindow (dpy, win) ;
*a_host_peer = win ;
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
int
hostx_destroy_window (int a_win)
{
Display *dpy=hostx_get_display () ;
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
XDestroyWindow (dpy, a_win) ;
XFlush (dpy) ;
return TRUE ;
}
int
hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
{
Display *dpy=hostx_get_display ();
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geo, FALSE) ;
EPHYR_LOG ("enter. x,y,w,h:(%d,%d,%d,%d)\n",
a_geo->x, a_geo->y,
a_geo->width, a_geo->height) ;
XMoveWindow (dpy, a_win, a_geo->x, a_geo->y) ;
XResizeWindow (dpy, a_win, a_geo->width, a_geo->height) ;
EPHYR_LOG ("leave\n") ;
return TRUE;
}
int
hostx_set_window_bounding_rectangles (int a_window,
EphyrRect *a_rects,
int a_num_rects)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display () ;
int i=0 ;
XRectangle *rects=NULL ;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
rects = calloc (a_num_rects, sizeof (XRectangle)) ;
for (i=0; i<a_num_rects; i++) {
rects[i].x = a_rects[i].x1 ;
rects[i].y = a_rects[i].y1 ;
rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
EPHYR_LOG ("borders clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
rects[i].x, rects[i].y,
rects[i].width, rects[i].height) ;
}
/*this aways returns 1*/
XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0,
rects, a_num_rects, ShapeSet, YXBanded) ;
is_ok = TRUE ;
if (rects) {
free (rects) ;
rects = NULL ;
}
EPHYR_LOG ("leave\n") ;
return is_ok;
}
int
hostx_set_window_clipping_rectangles (int a_window,
EphyrRect *a_rects,
int a_num_rects)
{
Bool is_ok=FALSE;
Display *dpy=hostx_get_display () ;
int i=0 ;
XRectangle *rects=NULL ;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
rects = calloc (a_num_rects, sizeof (XRectangle)) ;
for (i=0; i<a_num_rects; i++) {
rects[i].x = a_rects[i].x1 ;
rects[i].y = a_rects[i].y1 ;
rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
EPHYR_LOG ("clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
rects[i].x, rects[i].y,
rects[i].width, rects[i].height) ;
}
/*this aways returns 1*/
XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0,
rects, a_num_rects, ShapeSet, YXBanded) ;
is_ok = TRUE ;
if (rects) {
free (rects) ;
rects = NULL ;
}
EPHYR_LOG ("leave\n") ;
return is_ok;
}
int
hostx_has_xshape (void)
{
int event_base=0, error_base=0 ;
Display *dpy=hostx_get_display () ;
if (!XShapeQueryExtension (dpy,
&event_base,
&error_base)) {
return FALSE ;
}
return TRUE;
}
#ifdef XEPHYR_DRI
int
hostx_allocate_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id)
{
int i=0 ;
ResourcePair *peer=NULL ;
Display *dpy=hostx_get_display ();
/*
* first make sure a resource peer
* does not exist already for
* a_local_resource_id
*/
for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
if (resource_peers[i].is_valid
&& resource_peers[i].local_id == a_local_resource_id) {
peer = &resource_peers[i] ;
break ;
}
}
/*
* find one free peer entry, an feed it with
*/
if (!peer) {
for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
if (!resource_peers[i].is_valid) {
peer = &resource_peers[i] ;
break ;
}
}
if (peer) {
peer->remote_id = XAllocID (dpy);
peer->local_id = a_local_resource_id ;
peer->is_valid = TRUE ;
}
}
if (peer) {
*a_remote_resource_id = peer->remote_id ;
return TRUE ;
}
return FALSE ;
}
int
hostx_get_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id)
{
int i=0 ;
ResourcePair *peer=NULL ;
for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
if (resource_peers[i].is_valid
&& resource_peers[i].local_id == a_local_resource_id) {
peer = &resource_peers[i] ;
break ;
}
}
if (peer) {
*a_remote_resource_id = peer->remote_id ;
return TRUE ;
}
return FALSE ;
}
int
hostx_has_dri (void)
{
int event_base=0, error_base=0 ;
Display *dpy=hostx_get_display () ;
if (!XF86DRIQueryExtension (dpy,
&event_base,
&error_base)) {
return FALSE ;
}
return TRUE ;
}
int
hostx_has_glx (void)
{
Display *dpy=hostx_get_display () ;
int event_base=0, error_base=0 ;
if (!glXQueryExtension (dpy, &event_base, &error_base)) {
return FALSE ;
}
return TRUE ;
}
#endif /*XEPHYR_DRI*/

View File

@ -92,6 +92,32 @@ struct EphyrHostXEvent
int key_state;
};
typedef struct {
VisualID visualid;
int screen;
int depth;
int class;
unsigned long red_mask;
unsigned long green_mask;
unsigned long blue_mask;
int colormap_size;
int bits_per_rgb;
} EphyrHostVisualInfo;
typedef struct {
int x, y;
int width, height ;
int visualid ;
} EphyrHostWindowAttributes;
typedef struct {
int x,y,width,height;
} EphyrBox;
typedef struct {
short x1,y1,x2,y2;
} EphyrRect;
int
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
@ -167,9 +193,60 @@ hostx_paint_rect(EphyrScreenInfo screen,
void
hostx_load_keymap(void);
hostx_load_keymap (void);
int
hostx_get_event(EphyrHostXEvent *ev);
hostx_get_event (EphyrHostXEvent *ev);
#endif
void*
hostx_get_display (void) ;
int
hostx_get_window (int a_screen_number) ;
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) ;
int hostx_create_window (int a_screen_number,
EphyrBox *a_geometry,
int a_visual_id,
int *a_host_win /*out parameter*/) ;
int hostx_destroy_window (int a_win) ;
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) ;
#ifdef XEPHYR_DRI
int hostx_lookup_peer_window (void *a_local_window,
int *a_host_peer /*out parameter*/) ;
int
hostx_allocate_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id) ;
int
hostx_get_resource_id_peer (int a_local_resource_id,
int *a_remote_resource_id) ;
int hostx_has_dri (void) ;
int hostx_has_glx (void) ;
#endif /*XEPHYR_DRI*/
#endif /*_XLIBS_STUFF_H_*/

View File

@ -37,4 +37,4 @@ libkdrive_a_SOURCES = \
$(top_srcdir)/mi/miinitext.c
libkdrivestubs_a_SOURCES = \
$(top_srcdir)/fb/fbcmap.c
$(top_srcdir)/fb/fbcmap_mi.c

View File

@ -425,6 +425,8 @@
/* Support DRI extension */
#undef XF86DRI
#undef XEPHYR_DRI
/* Build DBE support */
#undef DBE

View File

@ -160,6 +160,7 @@ _X_EXPORT Bool noFontCacheExtension = FALSE;
#endif
#ifdef GLXEXT
_X_EXPORT Bool noGlxExtension = FALSE;
_X_EXPORT Bool noGlxVisualInit = FALSE;
#endif
#ifdef SCREENSAVER
_X_EXPORT Bool noScreenSaverExtension = FALSE;