summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@openedhand.com>2007-10-03 16:13:16 +0200
committerDodji Seketeli <dodji@openedhand.com>2007-10-03 16:14:08 +0200
commit604ebb5a6de372e6a8a96e0ee997db7929126860 (patch)
tree72523d93657c444198a044282fe342edb9492d9e
parent1365aeff5499a051375e43a9fcbf54733ac93929 (diff)
parent4ba76a7e2b62d26f43c0e670de571afb75ec92f4 (diff)
Merge Xephyr-XV/GL stuff into master
-rw-r--r--GL/glx/glxvisuals.c8
-rw-r--r--configure.ac12
-rw-r--r--dix/extension.c2
-rw-r--r--exa/exa.c48
-rw-r--r--fb/fbcmap_mi.c8
-rw-r--r--hw/kdrive/ephyr/GL/internal/dri_interface.h517
-rw-r--r--hw/kdrive/ephyr/Makefile.am47
-rw-r--r--hw/kdrive/ephyr/XF86dri.c622
-rw-r--r--hw/kdrive/ephyr/ephyr.c68
-rw-r--r--hw/kdrive/ephyr/ephyr.h4
-rw-r--r--hw/kdrive/ephyr/ephyrdri.c291
-rw-r--r--hw/kdrive/ephyr/ephyrdri.h75
-rw-r--r--hw/kdrive/ephyr/ephyrdriext.c1448
-rw-r--r--hw/kdrive/ephyr/ephyrdriext.h32
-rw-r--r--hw/kdrive/ephyr/ephyrglxext.c722
-rw-r--r--hw/kdrive/ephyr/ephyrglxext.h35
-rw-r--r--hw/kdrive/ephyr/ephyrhostglx.c687
-rw-r--r--hw/kdrive/ephyr/ephyrhostglx.h76
-rw-r--r--hw/kdrive/ephyr/ephyrhostproxy.c94
-rw-r--r--hw/kdrive/ephyr/ephyrhostproxy.h51
-rw-r--r--hw/kdrive/ephyr/ephyrhostvideo.c1004
-rw-r--r--hw/kdrive/ephyr/ephyrhostvideo.h238
-rw-r--r--hw/kdrive/ephyr/ephyrinit.c47
-rw-r--r--hw/kdrive/ephyr/ephyrlog.h67
-rw-r--r--hw/kdrive/ephyr/ephyrproxyext.c119
-rw-r--r--hw/kdrive/ephyr/ephyrproxyext.h34
-rw-r--r--hw/kdrive/ephyr/ephyrvideo.c1278
-rw-r--r--hw/kdrive/ephyr/hostx.c394
-rw-r--r--hw/kdrive/ephyr/hostx.h83
-rw-r--r--hw/kdrive/src/Makefile.am2
-rw-r--r--include/dix-config.h.in2
-rw-r--r--os/utils.c1
32 files changed, 8072 insertions, 44 deletions
diff --git a/GL/glx/glxvisuals.c b/GL/glx/glxvisuals.c
index 0e9bdedec..46b380b3d 100644
--- a/GL/glx/glxvisuals.c
+++ b/GL/glx/glxvisuals.c
@@ -55,6 +55,7 @@
55 55
56void GlxWrapInitVisuals(miInitVisualsProcPtr *); 56void GlxWrapInitVisuals(miInitVisualsProcPtr *);
57 57
58extern Bool noGlxVisualInit;
58#include "glcontextmodes.h" 59#include "glcontextmodes.h"
59 60
60struct ScreenVisualsRec { 61struct ScreenVisualsRec {
@@ -452,14 +453,15 @@ Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
452 /* 453 /*
453 * Setup the visuals supported by this particular screen. 454 * Setup the visuals supported by this particular screen.
454 */ 455 */
455 init_visuals(nvisualp, visualp, defaultVisp, 456 if (!noGlxVisualInit) {
456 *ndepthp, *depthp, *rootDepthp); 457 init_visuals(nvisualp, visualp, defaultVisp,
458 *ndepthp, *depthp, *rootDepthp);
459 }
457 460
458 461
459 return True; 462 return True;
460} 463}
461 464
462
463/************************************************************************/ 465/************************************************************************/
464 466
465 467
diff --git a/configure.ac b/configure.ac
index a5f18668f..ae1170a78 100644
--- a/configure.ac
+++ b/configure.ac
@@ -723,6 +723,7 @@ if test "x$XV" = xyes; then
723 AC_DEFINE(XV, 1, [Support Xv extension]) 723 AC_DEFINE(XV, 1, [Support Xv extension])
724 AC_DEFINE(XvExtension, 1, [Build Xv extension]) 724 AC_DEFINE(XvExtension, 1, [Build Xv extension])
725 REQUIRED_MODULES="$REQUIRED_MODULES videoproto" 725 REQUIRED_MODULES="$REQUIRED_MODULES videoproto"
726 PKG_CHECK_MODULES(XV, [xv >= 0.22])
726else 727else
727 XVMC=no 728 XVMC=no
728fi 729fi
@@ -1842,6 +1843,13 @@ if test "$KDRIVE" = yes; then
1842 if test "x$XEPHYR" = xauto; then 1843 if test "x$XEPHYR" = xauto; then
1843 XEPHYR=$xephyr 1844 XEPHYR=$xephyr
1844 fi 1845 fi
1846 XEPHYR_DRI=no
1847 if test x$XEPHYR = xyes -a x$DRI = xyes; then
1848 XEPHYR_DRI=yes
1849 fi
1850 if test x$XEPHYR_DRI = xyes ; then
1851 AC_DEFINE(XEPHYR_DRI,1,[enable DRI extension in xephyr])
1852 fi
1845 1853
1846 # Xephyr needs nanosleep() which is in librt on Solaris 1854 # Xephyr needs nanosleep() which is in librt on Solaris
1847 AC_CHECK_FUNC([nanosleep], [], 1855 AC_CHECK_FUNC([nanosleep], [],
@@ -1861,9 +1869,9 @@ if test "$KDRIVE" = yes; then
1861 KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux' 1869 KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
1862 KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC" 1870 KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
1863 1871
1864 KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS" 1872 KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS"
1865 1873
1866 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" 1874 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"
1867 KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a' 1875 KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
1868 case $host_os in 1876 case $host_os in
1869 *linux*) 1877 *linux*)
diff --git a/dix/extension.c b/dix/extension.c
index 186574d76..4c0c3d236 100644
--- a/dix/extension.c
+++ b/dix/extension.c
@@ -184,6 +184,8 @@ _X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
184 char *name; 184 char *name;
185 char **aliases; 185 char **aliases;
186 186
187 if (!ext)
188 return FALSE ;
187 aliases = (char **)xrealloc(ext->aliases, 189 aliases = (char **)xrealloc(ext->aliases,
188 (ext->num_aliases + 1) * sizeof(char *)); 190 (ext->num_aliases + 1) * sizeof(char *));
189 if (!aliases) 191 if (!aliases)
diff --git a/exa/exa.c b/exa/exa.c
index 7ad226fba..1403d4fa3 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -722,6 +722,48 @@ exaDriverAlloc(void)
722 return xcalloc(1, sizeof(ExaDriverRec)); 722 return xcalloc(1, sizeof(ExaDriverRec));
723} 723}
724 724
725static Bool
726exaDriverValidateEntryPoints (ExaDriverPtr pExaDriver)
727{
728 Bool res=TRUE ;
729
730 if (!pExaDriver)
731 return FALSE ;
732
733 if (!pExaDriver->memoryBase) {
734 LogMessage(X_ERROR,
735 "Exa: Exa::memoryBase member "
736 "must be assigned to a value different from zero\n") ;
737 res = FALSE ;
738 }
739 if (!pExaDriver->memorySize) {
740 LogMessage(X_ERROR,
741 "Exa: Exa::memorySize member must be different from zero\n") ;
742 res = FALSE ;
743 }
744 if (pExaDriver->offScreenBase > pExaDriver->memorySize) {
745 LogMessage(X_ERROR,
746 "Exa: Exa::ffscreenBase must be <= pExaDriver->memorySize member\n") ;
747 res = FALSE ;
748 }
749 if (!pExaDriver->PrepareSolid) {
750 LogMessage(X_ERROR,
751 "Exa: Exa::PrepareSolid member is required to be non NULL\n") ;
752 res = FALSE ;
753 }
754 if (!pExaDriver->PrepareCopy) {
755 LogMessage(X_ERROR,
756 "Exa: Exa::PrepareCopy member is required to be non NULL\n") ;
757 res = FALSE ;
758 }
759 if (!pExaDriver->WaitMarker) {
760 LogMessage(X_ERROR,
761 "Exa: Exa::WaitWarker member is required to be non NULL\n") ;
762 res = FALSE ;
763 }
764 return res ;
765}
766
725/** 767/**
726 * @param pScreen screen being initialized 768 * @param pScreen screen being initialized
727 * @param pScreenInfo EXA driver record 769 * @param pScreenInfo EXA driver record
@@ -806,6 +848,12 @@ exaDriverInit (ScreenPtr pScreen,
806 { 848 {
807 pScreenInfo->maxPitchPixels = pScreenInfo->maxX; 849 pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
808 } 850 }
851 if (!exaDriverValidateEntryPoints(pScreenInfo))
852 {
853 LogMessage(X_ERROR, "Exa(%d): EXA driver entry points validation failed\n",
854 pScreen->myNum) ;
855 return FALSE ;
856 }
809 857
810#ifdef RENDER 858#ifdef RENDER
811 ps = GetPictureScreenIfSet(pScreen); 859 ps = GetPictureScreenIfSet(pScreen);
diff --git a/fb/fbcmap_mi.c b/fb/fbcmap_mi.c
index 58bcae3aa..188decd4c 100644
--- a/fb/fbcmap_mi.c
+++ b/fb/fbcmap_mi.c
@@ -103,6 +103,14 @@ fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
103 return miSetVisualTypes(depth, visuals, bitsPerRGB, -1); 103 return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
104} 104}
105 105
106Bool
107fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
108 Pixel redMask, Pixel greenMask, Pixel blueMask)
109{
110 return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, -1,
111 redMask, greenMask, blueMask);
112}
113
106/* 114/*
107 * Given a list of formats for a screen, create a list 115 * Given a list of formats for a screen, create a list
108 * of visuals and depths for the screen which coorespond to 116 * of visuals and depths for the screen which coorespond to
diff --git a/hw/kdrive/ephyr/GL/internal/dri_interface.h b/hw/kdrive/ephyr/GL/internal/dri_interface.h
new file mode 100644
index 000000000..8d24e311f
--- /dev/null
+++ b/hw/kdrive/ephyr/GL/internal/dri_interface.h
@@ -0,0 +1,517 @@
1/*
2 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3 * (C) Copyright IBM Corporation 2004
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * \file dri_interface.h
28 *
29 * This file contains all the types and functions that define the interface
30 * between a DRI driver and driver loader. Currently, the most common driver
31 * loader is the XFree86 libGL.so. However, other loaders do exist, and in
32 * the future the server-side libglx.a will also be a loader.
33 *
34 * \author Kevin E. Martin <kevin@precisioninsight.com>
35 * \author Ian Romanick <idr@us.ibm.com>
36 */
37
38#ifndef DRI_INTERFACE_H
39#define DRI_INTERFACE_H
40
41#include <GL/internal/glcore.h>
42#include <drm.h>
43
44/**
45 * \name DRI interface structures
46 *
47 * The following structures define the interface between the GLX client
48 * side library and the DRI (direct rendering infrastructure).
49 */
50/*@{*/
51typedef struct __DRIdisplayRec __DRIdisplay;
52typedef struct __DRIscreenRec __DRIscreen;
53typedef struct __DRIcontextRec __DRIcontext;
54typedef struct __DRIdrawableRec __DRIdrawable;
55typedef struct __DRIdriverRec __DRIdriver;
56typedef struct __DRIframebufferRec __DRIframebuffer;
57typedef struct __DRIversionRec __DRIversion;
58typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods;
59typedef unsigned long __DRIid;
60typedef void __DRInativeDisplay;
61/*@}*/
62
63
64/**
65 * \name Functions provided by the driver loader.
66 */
67/*@{*/
68/**
69 * Type of a pointer to \c glXGetScreenDriver, as returned by
70 * \c glXGetProcAddress. This function is used to get the name of the DRI
71 * driver for the specified screen of the specified display. The driver
72 * name is typically used with \c glXGetDriverConfig.
73 *
74 * \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig
75 */
76typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum);
77
78/**
79 * Type of a pointer to \c glXGetDriverConfig, as returned by
80 * \c glXGetProcAddress. This function is used to get the XML document
81 * describing the configuration options available for the specified driver.
82 *
83 * \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver
84 */
85typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName);
86
87/**
88 * Type of a pointer to \c glxEnableExtension, as returned by
89 * \c __DRIinterfaceMethods::getProcAddress. This function is used to enable
90 * a GLX extension on the specified screen.
91 */
92typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
93/*@}*/
94
95
96/**
97 * \name Functions and data provided by the driver.
98 */
99/*@{*/
100
101typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn,
102 __DRIscreen *psc, const __GLcontextModes * modes,
103 const __DRIversion * ddx_version, const __DRIversion * dri_version,
104 const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
105 void * pSAREA, int fd, int internal_api_version,
106 const __DRIinterfaceMethods * interface,
107 __GLcontextModes ** driver_modes);
108typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
109extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
110
111
112/**
113 * XML document describing the configuration options supported by the
114 * driver.
115 */
116extern const char __driConfigOptions[];
117
118/*@}*/
119
120
121/**
122 * Stored version of some component (i.e., server-side DRI module, kernel-side
123 * DRM, etc.).
124 *
125 * \todo
126 * There are several data structures that explicitly store a major version,
127 * minor version, and patch level. These structures should be modified to
128 * have a \c __DRIversionRec instead.
129 */
130struct __DRIversionRec {
131 int major; /**< Major version number. */
132 int minor; /**< Minor version number. */
133 int patch; /**< Patch-level. */
134};
135
136
137typedef void (*__DRIfuncPtr)(void);
138
139struct __DRIinterfaceMethodsRec {
140 /**
141 * Get pointer to named function.
142 */
143 __DRIfuncPtr (*getProcAddress)( const char * proc_name );
144
145 /**
146 * Create a list of \c __GLcontextModes structures.
147 */
148 __GLcontextModes * (*createContextModes)(unsigned count,
149 size_t minimum_bytes_per_struct);
150
151 /**
152 * Destroy a list of \c __GLcontextModes structures.
153 *
154 * \todo
155 * Determine if the drivers actually need to call this.
156 */
157 void (*destroyContextModes)( __GLcontextModes * modes );
158
159 /**
160 * Get the \c __DRIscreen for a given display and screen number.
161 */
162 __DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum);
163
164
165 /**
166 * \name Client/server protocol functions.
167 *
168 * These functions implement the DRI client/server protocol for
169 * context and drawable operations. Platforms that do not implement
170 * the wire protocol (e.g., EGL) will implement glorified no-op functions.
171 */
172 /*@{*/
173 /**
174 * Determine if the specified window ID still exists.
175 *
176 * \note
177 * Implementations may assume that the driver will only pass an ID into
178 * this function that actually corresponds to a window. On
179 * implementations where windows can only be destroyed by the DRI driver
180 * (e.g., EGL), this function is allowed to always return \c GL_TRUE.
181 */
182 GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
183
184 /**
185 * Create the server-side portion of the GL context.
186 */
187 GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum,
188 int configID, void * contextID, drm_context_t * hw_context );
189
190 /**
191 * Destroy the server-side portion of the GL context.
192 */
193 GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum,
194 __DRIid context );
195
196 /**
197 * Create the server-side portion of the drawable.
198 */
199 GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen,
200 __DRIid drawable, drm_drawable_t * hHWDrawable );
201
202 /**
203 * Destroy the server-side portion of the drawable.
204 */
205 GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen,
206 __DRIid drawable );
207
208 /**
209 * This function is used to get information about the position, size, and
210 * clip rects of a drawable.
211 */
212 GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn,
213 __DRIid draw, unsigned int * index, unsigned int * stamp,
214 int * x, int * y, int * width, int * height,
215 int * numClipRects, drm_clip_rect_t ** pClipRects,
216 int * backX, int * backY,
217 int * numBackClipRects, drm_clip_rect_t ** pBackClipRects );
218 /*@}*/
219
220
221 /**
222 * \name Timing related functions.
223 */
224 /*@{*/
225 /**
226 * Get the 64-bit unadjusted system time (UST).
227 */
228 int (*getUST)(int64_t * ust);
229
230 /**
231 * Get the media stream counter (MSC) rate.
232 *
233 * Matching the definition in GLX_OML_sync_control, this function returns
234 * the rate of the "media stream counter". In practical terms, this is
235 * the frame refresh rate of the display.
236 */
237 GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable,
238 int32_t * numerator, int32_t * denominator);
239 /*@}*/
240
241 /**
242 * Reports areas of the given drawable which have been modified by the
243 * driver.
244 *
245 * \param drawable which the drawing was done to.
246 * \param rects rectangles affected, with the drawable origin as the
247 * origin.
248 * \param x X offset of the drawable within the screen (used in the
249 * front_buffer case)
250 * \param y Y offset of the drawable within the screen.
251 * \param front_buffer boolean flag for whether the drawing to the
252 * drawable was actually done directly to the front buffer (instead
253 * of backing storage, for example)
254 */
255 void (*reportDamage)(__DRInativeDisplay * dpy, int screen,
256 __DRIid drawable,
257 int x, int y,
258 drm_clip_rect_t *rects, int num_rects,
259 int front_buffer);
260};
261
262
263/**
264 * Framebuffer information record. Used by libGL to communicate information
265 * about the framebuffer to the driver's \c __driCreateNewScreen function.
266 *
267 * In XFree86, most of this information is derrived from data returned by
268 * calling \c XF86DRIGetDeviceInfo.
269 *
270 * \sa XF86DRIGetDeviceInfo __DRIdisplayRec::createNewScreen
271 * __driUtilCreateNewScreen CallCreateNewScreen
272 *
273 * \bug This structure could be better named.
274 */
275struct __DRIframebufferRec {
276 unsigned char *base; /**< Framebuffer base address in the CPU's
277 * address space. This value is calculated by
278 * calling \c drmMap on the framebuffer handle
279 * returned by \c XF86DRIGetDeviceInfo (or a
280 * similar function).
281 */
282 int size; /**< Framebuffer size, in bytes. */
283 int stride; /**< Number of bytes from one line to the next. */
284 int width; /**< Pixel width of the framebuffer. */
285 int height; /**< Pixel height of the framebuffer. */
286 int dev_priv_size; /**< Size of the driver's dev-priv structure. */
287 void *dev_priv; /**< Pointer to the driver's dev-priv structure. */
288};
289
290
291/**
292 * Screen dependent methods. This structure is initialized during the
293 * \c __DRIdisplayRec::createScreen call.
294 */
295struct __DRIscreenRec {
296 /**
297 * Method to destroy the private DRI screen data.
298 */
299 void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate);
300
301 /**
302 * Method to create the private DRI drawable data and initialize the
303 * drawable dependent methods.
304 */
305 void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
306 __DRIid draw, __DRIdrawable *pdraw,
307 int renderType, const int *attrs);
308
309 /**
310 * Method to return a pointer to the DRI drawable data.
311 */
312 __DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
313 void *drawablePrivate);
314
315 /**
316 * Opaque pointer to private per screen direct rendering data. \c NULL
317 * if direct rendering is not supported on this screen. Never
318 * dereferenced in libGL.
319 */
320 void *private;
321
322 /**
323 * Get the number of vertical refreshes since some point in time before
324 * this function was first called (i.e., system start up).
325 *
326 * \since Internal API version 20030317.
327 */
328 int (*getMSC)( void *screenPrivate, int64_t *msc );
329
330 /**
331 * Opaque pointer that points back to the containing
332 * \c __GLXscreenConfigs. This data structure is shared with DRI drivers
333 * but \c __GLXscreenConfigs is not. However, they are needed by some GLX
334 * functions called by DRI drivers.
335 *
336 * \since Internal API version 20030813.
337 */
338 void *screenConfigs;
339
340 /**
341 * Functions associated with MESA_allocate_memory.
342 *
343 * \since Internal API version 20030815.
344 */
345 /*@{*/
346 void *(*allocateMemory)(__DRInativeDisplay *dpy, int scrn, GLsizei size,
347 GLfloat readfreq, GLfloat writefreq,
348 GLfloat priority);
349
350 void (*freeMemory)(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer);
351
352 GLuint (*memoryOffset)(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer);
353 /*@}*/
354
355 /**
356 * Method to create the private DRI context data and initialize the
357 * context dependent methods.
358 *
359 * \since Internal API version 20031201.
360 */
361 void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
362 int render_type,
363 void *sharedPrivate, __DRIcontext *pctx);
364
365 /**
366 * Method to override base texture image with a driver specific 'offset'.
367 * The depth passed in allows e.g. to ignore the alpha channel of texture
368 * images where the non-alpha components don't occupy a whole texel.
369 *
370 * For GLX_EXT_texture_from_pixmap with AIGLX.
371 *
372 * \since Internal API version 20070121.
373 */
374 void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
375 unsigned long long offset, GLint depth, GLuint pitch);
376};
377
378/**
379 * Context dependent methods. This structure is initialized during the
380 * \c __DRIscreenRec::createContext call.
381 */
382struct __DRIcontextRec {
383 /**
384 * Method to destroy the private DRI context data.
385 */
386 void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate);
387
388 /**
389 * Opaque pointer to private per context direct rendering data.
390 * \c NULL if direct rendering is not supported on the display or
391 * screen used to create this context. Never dereferenced in libGL.
392 */
393 void *private;
394
395 /**
396 * Pointer to the mode used to create this context.
397 *
398 * \since Internal API version 20040317.
399 */
400 const __GLcontextModes * mode;
401
402 /**
403 * Method to bind a DRI drawable to a DRI graphics context.
404 *
405 * \since Internal API version 20050727.
406 */
407 GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
408 __DRIid read, __DRIcontext *ctx);
409
410 /**
411 * Method to unbind a DRI drawable from a DRI graphics context.
412 *
413 * \since Internal API version 20050727.
414 */
415 GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
416 __DRIid read, __DRIcontext *ctx);
417};
418
419/**
420 * Drawable dependent methods. This structure is initialized during the
421 * \c __DRIscreenRec::createDrawable call. \c createDrawable is not called
422 * by libGL at this time. It's currently used via the dri_util.c utility code
423 * instead.
424 */
425struct __DRIdrawableRec {
426 /**
427 * Method to destroy the private DRI drawable data.
428 */
429 void (*destroyDrawable)(__DRInativeDisplay *dpy, void *drawablePrivate);
430
431 /**
432 * Method to swap the front and back buffers.
433 */
434 void (*swapBuffers)(__DRInativeDisplay *dpy, void *drawablePrivate);
435
436 /**
437 * Opaque pointer to private per drawable direct rendering data.
438 * \c NULL if direct rendering is not supported on the display or
439 * screen used to create this drawable. Never dereferenced in libGL.
440 */
441 void *private;
442
443 /**
444 * Get the number of completed swap buffers for this drawable.
445 *
446 * \since Internal API version 20030317.
447 */
448 int (*getSBC)(__DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc );
449
450 /**
451 * Wait for the SBC to be greater than or equal target_sbc.
452 *
453 * \since Internal API version 20030317.
454 */
455 int (*waitForSBC)( __DRInativeDisplay * dpy, void *drawablePriv,
456 int64_t target_sbc,
457 int64_t * msc, int64_t * sbc );
458
459 /**
460 * Wait for the MSC to equal target_msc, or, if that has already passed,
461 * the next time (MSC % divisor) is equal to remainder. If divisor is
462 * zero, the function will return as soon as MSC is greater than or equal
463 * to target_msc.
464 *
465 * \since Internal API version 20030317.
466 */
467 int (*waitForMSC)( __DRInativeDisplay * dpy, void *drawablePriv,
468 int64_t target_msc, int64_t divisor, int64_t remainder,
469 int64_t * msc, int64_t * sbc );
470
471 /**
472 * Like \c swapBuffers, but does NOT have an implicit \c glFlush. Once
473 * rendering is complete, waits until MSC is equal to target_msc, or
474 * if that has already passed, waits until (MSC % divisor) is equal
475 * to remainder. If divisor is zero, the swap will happen as soon as
476 * MSC is greater than or equal to target_msc.
477 *
478 * \since Internal API version 20030317.
479 */
480 int64_t (*swapBuffersMSC)(__DRInativeDisplay *dpy, void *drawablePrivate,
481 int64_t target_msc,
482 int64_t divisor, int64_t remainder);
483
484 /**
485 * Enable or disable frame usage tracking.
486 *
487 * \since Internal API version 20030317.
488 */
489 int (*frameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, GLboolean enable);
490
491 /**
492 * Retrieve frame usage information.
493 *
494 * \since Internal API version 20030317.
495 */
496 int (*queryFrameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate,
497 int64_t * sbc, int64_t * missedFrames,
498 float * lastMissedUsage, float * usage );
499
500 /**
501 * Used by drivers that implement the GLX_SGI_swap_control or
502 * GLX_MESA_swap_control extension.
503 *
504 * \since Internal API version 20030317.
505 */
506 unsigned swap_interval;
507
508 /**
509 * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
510 *
511 * \since Internal API version 20060314.
512 */
513 void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate,
514 int x, int y, int w, int h);
515};
516
517#endif
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index cc3019fc7..604e22eaa 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -3,22 +3,47 @@ INCLUDES = \
3 @KDRIVE_CFLAGS@ \ 3 @KDRIVE_CFLAGS@ \
4 -I$(srcdir)/../../../exa 4 -I$(srcdir)/../../../exa
5 5
6noinst_LIBRARIES = libxephyr.a libxephyr-hostx.a 6noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a
7 7
8bin_PROGRAMS = Xephyr 8bin_PROGRAMS = Xephyr
9 9
10
11libxephyr_hostx_a_SOURCES = \
12 hostx.c \
13 hostx.h
14
15libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@
16
17libxephyr_hostxv_a_SOURCES= \
18 ephyrhostvideo.c \
19 ephyrhostvideo.h
20
10libxephyr_a_SOURCES = \ 21libxephyr_a_SOURCES = \
11 ephyr.c \ 22 ephyr.c \
12 ephyr_draw.c \ 23 ephyr_draw.c \
24 ephyrvideo.c \
25 XF86dri.c \
26 ephyrdriext.c \
27 ephyrdri.c \
28 ephyrdri.h \
29 ephyrglxext.c \
30 ephyrglxext.h \
31 ephyrhostglx.c \
32 ephyrhostglx.h \
33 ephyrhostproxy.c \
34 ephyrhostproxy.h \
35 ephyrhostproxy.c \
36 ephyrproxyext.c \
37 ephyrproxyext.h \
13 os.c \ 38 os.c \
14 hostx.h \ 39 hostx.h \
15 ephyr.h 40 ephyr.h \
16 41 ephyrlog.h
17libxephyr_hostx_a_SOURCES = \
18 hostx.c \
19 hostx.h
20 42
21libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@ 43libxephyr_a_CFLAGS = \
44@LIBDRM_CFLAGS@ \
45-I$(top_srcdir) \
46@DRIPROTO_CFLAGS@
22 47
23Xephyr_SOURCES = \ 48Xephyr_SOURCES = \
24 ephyrinit.c 49 ephyrinit.c
@@ -26,13 +51,17 @@ Xephyr_SOURCES = \
26Xephyr_LDADD = \ 51Xephyr_LDADD = \
27 libxephyr.a \ 52 libxephyr.a \
28 libxephyr-hostx.a \ 53 libxephyr-hostx.a \
54 libxephyr-hostxv.a \
29 ../../../exa/libexa.la \ 55 ../../../exa/libexa.la \
30 @KDRIVE_LIBS@ \ 56 @KDRIVE_LIBS@ \
31 @XEPHYR_LIBS@ 57 @XEPHYR_LIBS@ \
58 @LIBDRM_LIBS@ \
59 -lGL
32 60
33Xephyr_DEPENDENCIES = \ 61Xephyr_DEPENDENCIES = \
34 libxephyr.a \ 62 libxephyr.a \
35 libxephyr-hostx.a \ 63 libxephyr-hostx.a \
64 libxephyr-hostxv.a \
36 @KDRIVE_LOCAL_LIBS@ 65 @KDRIVE_LOCAL_LIBS@
37 66
38relink: 67relink:
diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
new file mode 100644
index 000000000..ae2ec890f
--- /dev/null
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -0,0 +1,622 @@
1/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
2/**************************************************************************
3
4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5Copyright 2000 VA Linux Systems, Inc.
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a
9copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sub license, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial portions
18of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 * Kevin E. Martin <martin@valinux.com>
33 * Jens Owen <jens@tungstengraphics.com>
34 * Rickard E. (Rik) Faith <faith@valinux.com>
35 *
36 */
37
38/*
39 * This file has been copied from the mesa source tree and a little bit
40 * modified by:
41 *
42 * Dodji Seketeli <dodji@openedhand.com>
43 */
44
45#ifdef HAVE_CONFIG_H
46#include <kdrive-config.h>
47#endif
48
49#ifdef XEPHYR_DRI
50
51/* THIS IS NOT AN X CONSORTIUM STANDARD */
52
53#define NEED_REPLIES
54#include <X11/Xlibint.h>
55#include <X11/extensions/Xext.h>
56#include <X11/extensions/extutil.h>
57#include <GL/glx.h>
58#include <X11/dri/xf86dri.h>
59#include <X11/dri/xf86dristr.h>
60
61static XExtensionInfo _xf86dri_info_data;
62static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
63static char xf86dri_extension_name[] = XF86DRINAME;
64
65#define XF86DRICheckExtension(dpy,i,val) \
66 XextCheckExtension (dpy, i, xf86dri_extension_name, val)
67
68/*****************************************************************************
69 * *
70 * private utility routines *
71 * *
72 *****************************************************************************/
73
74static int close_display(Display *dpy, XExtCodes *extCodes);
75static /* const */ XExtensionHooks xf86dri_extension_hooks = {
76 NULL, /* create_gc */
77 NULL, /* copy_gc */
78 NULL, /* flush_gc */
79 NULL, /* free_gc */
80 NULL, /* create_font */
81 NULL, /* free_font */
82 close_display, /* close_display */
83 NULL, /* wire_to_event */
84 NULL, /* event_to_wire */
85 NULL, /* error */
86 NULL, /* error_string */
87};
88
89static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
90 xf86dri_extension_name,
91 &xf86dri_extension_hooks,
92 0, NULL)
93
94static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
95
96
97/*****************************************************************************
98 * *
99 * public XFree86-DRI Extension routines *
100 * *
101 *****************************************************************************/
102
103#if 0
104#include <stdio.h>
105#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
106#else
107#define TRACE(msg)
108#endif
109
110Bool XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable);
111Bool XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable);
112
113Bool XF86DRIQueryExtension (Display *dpy, int *event_basep, int *error_basep)
114{
115 XExtDisplayInfo *info = find_display (dpy);
116
117 TRACE("QueryExtension...");
118 if (XextHasExtension(info)) {
119 *event_basep = info->codes->first_event;
120 *error_basep = info->codes->first_error;
121 TRACE("QueryExtension... return True");
122 return True;
123 } else {
124 TRACE("QueryExtension... return False");
125 return False;
126 }
127}
128
129Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
130 Display* dpy;
131 int* majorVersion;
132 int* minorVersion;
133 int* patchVersion;
134{
135 XExtDisplayInfo *info = find_display (dpy);
136 xXF86DRIQueryVersionReply rep;
137 xXF86DRIQueryVersionReq *req;
138
139 TRACE("QueryVersion...");
140 XF86DRICheckExtension (dpy, info, False);
141
142 LockDisplay(dpy);
143 GetReq(XF86DRIQueryVersion, req);
144 req->reqType = info->codes->major_opcode;
145 req->driReqType = X_XF86DRIQueryVersion;
146 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
147 UnlockDisplay(dpy);
148 SyncHandle();
149 TRACE("QueryVersion... return False");
150 return False;
151 }
152 *majorVersion = rep.majorVersion;
153 *minorVersion = rep.minorVersion;
154 *patchVersion = rep.patchVersion;
155 UnlockDisplay(dpy);
156 SyncHandle();
157 TRACE("QueryVersion... return True");
158 return True;
159}
160
161Bool
162XF86DRIQueryDirectRenderingCapable (Display *dpy, int screen, Bool *isCapable)
163{
164 XExtDisplayInfo *info = find_display (dpy);
165 xXF86DRIQueryDirectRenderingCapableReply rep;
166 xXF86DRIQueryDirectRenderingCapableReq *req;
167
168 TRACE("QueryDirectRenderingCapable...");
169 XF86DRICheckExtension (dpy, info, False);
170
171 LockDisplay(dpy);
172 GetReq(XF86DRIQueryDirectRenderingCapable, req);
173 req->reqType = info->codes->major_opcode;
174 req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
175 req->screen = screen;
176 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
177 UnlockDisplay(dpy);
178 SyncHandle();
179 TRACE("QueryDirectRenderingCapable... return False");
180 return False;
181 }
182 *isCapable = rep.isCapable;
183 UnlockDisplay(dpy);
184 SyncHandle();
185 TRACE("QueryDirectRenderingCapable... return True");
186 return True;
187}
188
189Bool
190XF86DRIOpenConnection (Display *dpy, int screen,
191 drm_handle_t *hSAREA,
192 char **busIdString)
193{
194 XExtDisplayInfo *info = find_display (dpy);
195 xXF86DRIOpenConnectionReply rep;
196 xXF86DRIOpenConnectionReq *req;
197
198 TRACE("OpenConnection...");
199 XF86DRICheckExtension (dpy, info, False);
200
201 LockDisplay(dpy);
202 GetReq(XF86DRIOpenConnection, req);
203 req->reqType = info->codes->major_opcode;
204 req->driReqType = X_XF86DRIOpenConnection;
205 req->screen = screen;
206 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
207 UnlockDisplay(dpy);
208 SyncHandle();
209 TRACE("OpenConnection... return False");
210 return False;
211 }
212
213 *hSAREA = rep.hSAREALow;
214 if (sizeof(drm_handle_t) == 8) {
215 int shift = 32; /* var to prevent warning on next line */
216 *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
217 }
218
219 if (rep.length) {
220 if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
221 _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
222 UnlockDisplay(dpy);
223 SyncHandle();
224 TRACE("OpenConnection... return False");
225 return False;
226 }
227 _XReadPad(dpy, *busIdString, rep.busIdStringLength);
228 } else {
229 *busIdString = NULL;
230 }
231 UnlockDisplay(dpy);
232 SyncHandle();
233 TRACE("OpenConnection... return True");
234 return True;
235}
236
237Bool XF86DRIAuthConnection(dpy, screen, magic)
238 Display* dpy;
239 int screen;
240 drm_magic_t magic;
241{
242 XExtDisplayInfo *info = find_display (dpy);
243 xXF86DRIAuthConnectionReq *req;
244 xXF86DRIAuthConnectionReply rep;
245
246 TRACE("AuthConnection...");
247 XF86DRICheckExtension (dpy, info, False);
248
249 LockDisplay(dpy);
250 GetReq(XF86DRIAuthConnection, req);
251 req->reqType = info->codes->major_opcode;
252 req->driReqType = X_XF86DRIAuthConnection;
253 req->screen = screen;
254 req->magic = magic;
255 rep.authenticated = 0;
256 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
257 UnlockDisplay(dpy);
258 SyncHandle();
259 TRACE("AuthConnection... return False");
260 return False;
261 }
262 UnlockDisplay(dpy);
263 SyncHandle();
264 TRACE("AuthConnection... return True");
265 return True;
266}
267
268Bool XF86DRICloseConnection(dpy, screen)
269 Display* dpy;
270 int screen;
271{
272 XExtDisplayInfo *info = find_display (dpy);
273 xXF86DRICloseConnectionReq *req;
274
275 TRACE("CloseConnection...");
276
277 XF86DRICheckExtension (dpy, info, False);
278
279 LockDisplay(dpy);
280 GetReq(XF86DRICloseConnection, req);
281 req->reqType = info->codes->major_opcode;
282 req->driReqType = X_XF86DRICloseConnection;
283 req->screen = screen;
284 UnlockDisplay(dpy);
285 SyncHandle();
286 TRACE("CloseConnection... return True");
287 return True;
288}
289
290Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
291 ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
292 Display* dpy;
293 int screen;
294 int* ddxDriverMajorVersion;
295 int* ddxDriverMinorVersion;
296 int* ddxDriverPatchVersion;
297 char** clientDriverName;
298{
299 XExtDisplayInfo *info = find_display (dpy);
300 xXF86DRIGetClientDriverNameReply rep;
301 xXF86DRIGetClientDriverNameReq *req;
302
303 TRACE("GetClientDriverName...");
304 XF86DRICheckExtension (dpy, info, False);
305
306 LockDisplay(dpy);
307 GetReq(XF86DRIGetClientDriverName, req);
308 req->reqType = info->codes->major_opcode;
309 req->driReqType = X_XF86DRIGetClientDriverName;
310 req->screen = screen;
311 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
312 UnlockDisplay(dpy);
313 SyncHandle();
314 TRACE("GetClientDriverName... return False");
315 return False;
316 }
317
318 *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
319 *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
320 *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
321
322 if (rep.length) {
323 if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
324 _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
325 UnlockDisplay(dpy);
326 SyncHandle();
327 TRACE("GetClientDriverName... return False");
328 return False;
329 }
330 _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
331 } else {
332 *clientDriverName = NULL;
333 }
334 UnlockDisplay(dpy);
335 SyncHandle();
336 TRACE("GetClientDriverName... return True");
337 return True;
338}
339
340Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
341 hHWContext)
342 Display* dpy;
343 int screen;
344 int configID;
345 XID* context;
346 drm_context_t * hHWContext;
347{
348 XExtDisplayInfo *info = find_display (dpy);
349 xXF86DRICreateContextReply rep;
350 xXF86DRICreateContextReq *req;
351
352 TRACE("CreateContext...");
353 XF86DRICheckExtension (dpy, info, False);
354
355 LockDisplay(dpy);
356 GetReq(XF86DRICreateContext, req);
357 req->reqType = info->codes->major_opcode;
358 req->driReqType = X_XF86DRICreateContext;
359 req->visual = configID;
360 req->screen = screen;
361 *context = XAllocID(dpy);
362 req->context = *context;
363 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
364 UnlockDisplay(dpy);
365 SyncHandle();
366 TRACE("CreateContext... return False");
367 return False;
368 }
369 *hHWContext = rep.hHWContext;
370 UnlockDisplay(dpy);
371 SyncHandle();
372 TRACE("CreateContext... return True");
373 return True;
374}
375
376Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
377 Display* dpy;
378 int screen;
379 Visual* visual;
380 XID* context;
381 drm_context_t * hHWContext;
382{
383 return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
384 context, hHWContext );
385}
386
387GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
388 __DRIid context )
389{
390 Display * const dpy = (Display *) ndpy;
391 XExtDisplayInfo *info = find_display (dpy);
392 xXF86DRIDestroyContextReq *req;
393
394 TRACE("DestroyContext...");
395 XF86DRICheckExtension (dpy, info, False);
396
397 LockDisplay(dpy);
398 GetReq(XF86DRIDestroyContext, req);
399 req->reqType = info->codes->major_opcode;
400 req->driReqType = X_XF86DRIDestroyContext;
401 req->screen = screen;
402 req->context = context;
403 UnlockDisplay(dpy);
404 SyncHandle();
405 TRACE("DestroyContext... return True");
406 return True;
407}
408
409GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
410 __DRIid drawable, drm_drawable_t * hHWDrawable )
411{
412 Display * const dpy = (Display *) ndpy;
413 XExtDisplayInfo *info = find_display (dpy);
414 xXF86DRICreateDrawableReply rep;
415 xXF86DRICreateDrawableReq *req;
416
417 TRACE("CreateDrawable...");
418 XF86DRICheckExtension (dpy, info, False);
419
420 LockDisplay(dpy);
421 GetReq(XF86DRICreateDrawable, req);
422 req->reqType = info->codes->major_opcode;
423 req->driReqType = X_XF86DRICreateDrawable;
424 req->screen = screen;
425 req->drawable = drawable;
426 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
427 UnlockDisplay(dpy);
428 SyncHandle();
429 TRACE("CreateDrawable... return False");
430 return False;
431 }
432 *hHWDrawable = rep.hHWDrawable;
433 UnlockDisplay(dpy);
434 SyncHandle();
435 TRACE("CreateDrawable... return True");
436 return True;
437}
438
439GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
440 __DRIid drawable )
441{
442 Display * const dpy = (Display *) ndpy;
443 XExtDisplayInfo *info = find_display (dpy);
444 xXF86DRIDestroyDrawableReq *req;
445
446 TRACE("DestroyDrawable...");
447 XF86DRICheckExtension (dpy, info, False);
448
449 LockDisplay(dpy);
450 GetReq(XF86DRIDestroyDrawable, req);
451 req->reqType = info->codes->major_opcode;
452 req->driReqType = X_XF86DRIDestroyDrawable;
453 req->screen = screen;
454 req->drawable = drawable;
455 UnlockDisplay(dpy);
456 SyncHandle();
457 TRACE("DestroyDrawable... return True");
458 return True;
459}
460
461Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
462 unsigned int* index, unsigned int* stamp,
463 int* X, int* Y, int* W, int* H,
464 int* numClipRects, drm_clip_rect_t ** pClipRects,
465 int* backX, int* backY,
466 int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
467{
468 XExtDisplayInfo *info = find_display (dpy);
469 xXF86DRIGetDrawableInfoReply rep;
470 xXF86DRIGetDrawableInfoReq *req=NULL;
471 int total_rects;
472
473 TRACE("GetDrawableInfo...");
474 XF86DRICheckExtension (dpy, info, False);
475
476 LockDisplay(dpy);
477 GetReq(XF86DRIGetDrawableInfo, req);
478 req->reqType = info->codes->major_opcode;
479 req->driReqType = X_XF86DRIGetDrawableInfo;
480 req->screen = screen;
481 req->drawable = drawable;
482
483 if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
484 {
485 UnlockDisplay(dpy);
486 SyncHandle();
487 TRACE("GetDrawableInfo... return False");
488 return False;
489 }
490 *index = rep.drawableTableIndex;
491 *stamp = rep.drawableTableStamp;
492 *X = (int)rep.drawableX;
493 *Y = (int)rep.drawableY;
494 *W = (int)rep.drawableWidth;
495 *H = (int)rep.drawableHeight;
496 *numClipRects = rep.numClipRects;
497 total_rects = *numClipRects;
498
499 *backX = rep.backX;
500 *backY = rep.backY;
501 *numBackClipRects = rep.numBackClipRects;
502 total_rects += *numBackClipRects;
503
504#if 0
505 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
506 * backwards compatibility (Because of the >> 2 shift) but the fix
507 * enables multi-threaded apps to work.
508 */
509 if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
510 SIZEOF(xGenericReply) +
511 total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
512 _XEatData(dpy, rep.length);
513 UnlockDisplay(dpy);
514 SyncHandle();
515 TRACE("GetDrawableInfo... return False");
516 return False;
517 }
518#endif
519
520 if (*numClipRects) {
521 int len = sizeof(drm_clip_rect_t) * (*numClipRects);
522
523 *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
524 if (*pClipRects)
525 _XRead(dpy, (char*)*pClipRects, len);
526 } else {
527 *pClipRects = NULL;
528 }
529
530 if (*numBackClipRects) {
531 int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
532
533 *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
534 if (*pBackClipRects)
535 _XRead(dpy, (char*)*pBackClipRects, len);
536 } else {
537 *pBackClipRects = NULL;
538 }
539
540 UnlockDisplay(dpy);
541 SyncHandle();
542 TRACE("GetDrawableInfo... return True");
543 return True;
544}
545
546Bool
547XF86DRIGetDeviceInfo (Display *dpy, int screen, drm_handle_t *hFrameBuffer,
548 int *fbOrigin, int *fbSize, int *fbStride,
549 int *devPrivateSize, void **pDevPrivate)
550{
551 XExtDisplayInfo *info = find_display (dpy);
552 xXF86DRIGetDeviceInfoReply rep;
553 xXF86DRIGetDeviceInfoReq *req;
554
555 TRACE("GetDeviceInfo...");
556 XF86DRICheckExtension (dpy, info, False);
557
558 LockDisplay(dpy);
559 GetReq(XF86DRIGetDeviceInfo, req);
560 req->reqType = info->codes->major_opcode;
561 req->driReqType = X_XF86DRIGetDeviceInfo;
562 req->screen = screen;
563 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
564 UnlockDisplay(dpy);
565 SyncHandle();
566 TRACE("GetDeviceInfo... return False");
567 return False;
568 }
569
570 *hFrameBuffer = rep.hFrameBufferLow;
571 if (sizeof(drm_handle_t) == 8) {
572 int shift = 32; /* var to prevent warning on next line */
573 *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
574 }
575
576 *fbOrigin = rep.framebufferOrigin;
577 *fbSize = rep.framebufferSize;
578 *fbStride = rep.framebufferStride;
579 *devPrivateSize = rep.devPrivateSize;
580
581 if (rep.length) {
582 if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
583 _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
584 UnlockDisplay(dpy);
585 SyncHandle();
586 TRACE("GetDeviceInfo... return False");
587 return False;
588 }
589 _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
590 } else {
591 *pDevPrivate = NULL;
592 }
593
594 UnlockDisplay(dpy);
595 SyncHandle();
596 TRACE("GetDeviceInfo... return True");
597 return True;
598}
599
600Bool
601XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable)
602{
603 /* This function and the underlying X protocol are deprecated.
604 */
605 (void) dpy;
606 (void) screen;
607 (void) drawable;
608 return False;
609}
610
611Bool
612XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable)
613{
614 /* This function and the underlying X protocol are deprecated.
615 */
616 (void) dpy;
617 (void) screen;
618 (void) drawable;
619 return True;
620}
621#endif /*EPHYR_DRI*/
622
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index c5cb21a64..85aab280f 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -23,11 +23,6 @@
23 * PERFORMANCE OF THIS SOFTWARE. 23 * PERFORMANCE OF THIS SOFTWARE.
24 */ 24 */
25 25
26/* TODO:
27 *
28 * o Support multiple screens, shouldn't be hard just alot of rejigging.
29 */
30
31#ifdef HAVE_CONFIG_H 26#ifdef HAVE_CONFIG_H
32#include <kdrive-config.h> 27#include <kdrive-config.h>
33#endif 28#endif
@@ -35,11 +30,21 @@
35 30
36#include "inputstr.h" 31#include "inputstr.h"
37#include "scrnintstr.h" 32#include "scrnintstr.h"
33#include "ephyrlog.h"
34
35#ifdef XEPHYR_DRI
36#include "ephyrdri.h"
37#include "ephyrdriext.h"
38#include "ephyrglxext.h"
39#include "ephyrproxyext.h"
40#endif /*XEPHYR_DRI*/
38 41
39extern int KdTsPhyScreen; 42extern int KdTsPhyScreen;
40KdKeyboardInfo *ephyrKbd; 43KdKeyboardInfo *ephyrKbd;
41KdPointerInfo *ephyrMouse; 44KdPointerInfo *ephyrMouse;
42EphyrKeySyms ephyrKeySyms; 45EphyrKeySyms ephyrKeySyms;
46Bool ephyrNoDRI=FALSE ;
47Bool ephyrNoXV=FALSE ;
43 48
44static int mouseState = 0; 49static int mouseState = 0;
45 50
@@ -49,6 +54,7 @@ typedef struct _EphyrInputPrivate {
49 54
50Bool EphyrWantGrayScale = 0; 55Bool EphyrWantGrayScale = 0;
51 56
57
52Bool 58Bool
53ephyrInitialize (KdCardInfo *card, EphyrPriv *priv) 59ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
54{ 60{
@@ -209,7 +215,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
209 KdPointerMatrix m; 215 KdPointerMatrix m;
210 int buffer_height; 216 int buffer_height;
211 217
212 EPHYR_DBG("screen->width: %d, screen->height: %d index=%d", 218 EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
213 screen->width, screen->height, screen->mynum); 219 screen->width, screen->height, screen->mynum);
214 220
215 KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); 221 KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
@@ -245,7 +251,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
245 /* Rotated/Reflected so we need to use shadow fb */ 251 /* Rotated/Reflected so we need to use shadow fb */
246 scrpriv->shadow = TRUE; 252 scrpriv->shadow = TRUE;
247 253
248 EPHYR_DBG("allocing shadow"); 254 EPHYR_LOG("allocing shadow");
249 255
250 KdShadowFbAlloc (screen, 0, 256 KdShadowFbAlloc (screen, 0,
251 scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)); 257 scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
@@ -296,7 +302,7 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
296 KdScreenPriv(pScreen); 302 KdScreenPriv(pScreen);
297 KdScreenInfo *screen = pScreenPriv->screen; 303 KdScreenInfo *screen = pScreenPriv->screen;
298 304
299 EPHYR_DBG("slow paint"); 305 EPHYR_LOG("slow paint");
300 306
301 /* FIXME: Slow Rotated/Reflected updates could be much 307 /* FIXME: Slow Rotated/Reflected updates could be much
302 * much faster efficiently updating via tranforming 308 * much faster efficiently updating via tranforming
@@ -410,7 +416,7 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
410 Rotation randr; 416 Rotation randr;
411 int n = 0; 417 int n = 0;
412 418
413 EPHYR_DBG("mark"); 419 EPHYR_LOG("mark");
414 420
415 struct { int width, height; } sizes[] = 421 struct { int width, height; } sizes[] =
416 { 422 {
@@ -563,7 +569,7 @@ ephyrRandRSetConfig (ScreenPtr pScreen,
563 return TRUE; 569 return TRUE;
564 570
565 bail4: 571 bail4:
566 EPHYR_DBG("bailed"); 572 EPHYR_LOG("bailed");
567 573
568 ephyrUnmapFramebuffer (screen); 574 ephyrUnmapFramebuffer (screen);
569 *scrpriv = oldscr; 575 *scrpriv = oldscr;
@@ -606,10 +612,29 @@ ephyrInitScreen (ScreenPtr pScreen)
606 KdScreenPriv(pScreen); 612 KdScreenPriv(pScreen);
607 KdScreenInfo *screen = pScreenPriv->screen; 613 KdScreenInfo *screen = pScreenPriv->screen;
608 614
609 EPHYR_DBG ("pScreen->myNum:%d\n", pScreen->myNum) ; 615 EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
610 hostx_set_screen_number (screen, pScreen->myNum); 616 hostx_set_screen_number (screen, pScreen->myNum);
611 hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ; 617 hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
612 pScreen->CreateColormap = ephyrCreateColormap; 618 pScreen->CreateColormap = ephyrCreateColormap;
619
620#ifdef XV
621 if (!ephyrNoXV) {
622 if (!ephyrInitVideo (pScreen)) {
623 EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
624 } else {
625 EPHYR_LOG ("initialized xvideo okay\n") ;
626 }
627 }
628#endif /*XV*/
629
630#ifdef XEPHYR_DRI
631 if (!ephyrNoDRI) {
632 ephyrDRIExtensionInit (pScreen) ;
633 ephyrHijackGLXExtension () ;
634 ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
635 }
636#endif
637
613 return TRUE; 638 return TRUE;
614} 639}
615 640
@@ -621,12 +646,12 @@ ephyrFinishInitScreen (ScreenPtr pScreen)
621 */ 646 */
622 if (!shadowSetup (pScreen)) 647 if (!shadowSetup (pScreen))
623 return FALSE; 648 return FALSE;
624 649
625#ifdef RANDR 650#ifdef RANDR
626 if (!ephyrRandRInit (pScreen)) 651 if (!ephyrRandRInit (pScreen))
627 return FALSE; 652 return FALSE;
628#endif 653#endif
629 654
630 return TRUE; 655 return TRUE;
631} 656}
632 657
@@ -637,7 +662,7 @@ ephyrCreateResources (ScreenPtr pScreen)
637 KdScreenInfo *screen = pScreenPriv->screen; 662 KdScreenInfo *screen = pScreenPriv->screen;
638 EphyrScrPriv *scrpriv = screen->driver; 663 EphyrScrPriv *scrpriv = screen->driver;
639 664
640 EPHYR_DBG("mark pScreen=%p mynum=%d shadow=%d", 665 EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
641 pScreen, pScreen->myNum, scrpriv->shadow); 666 pScreen, pScreen->myNum, scrpriv->shadow);
642 667
643 if (scrpriv->shadow) 668 if (scrpriv->shadow)
@@ -809,20 +834,20 @@ ephyrPoll(void)
809 case EPHYR_EV_MOUSE_MOTION: 834 case EPHYR_EV_MOUSE_MOTION:
810 if (!ephyrMouse || 835 if (!ephyrMouse ||
811 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { 836 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
812 EPHYR_DBG ("skipping mouse motion:%d\n", ephyrCurScreen) ; 837 EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
813 continue; 838 continue;
814 } 839 }
815 { 840 {
816 if (ephyrCurScreen != ev.data.mouse_motion.screen) 841 if (ephyrCurScreen != ev.data.mouse_motion.screen)
817 { 842 {
818 EPHYR_DBG ("warping mouse cursor:%d\n", ephyrCurScreen) ; 843 EPHYR_LOG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
819 ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen], 844 ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
820 ev.data.mouse_motion.x, 845 ev.data.mouse_motion.x,
821 ev.data.mouse_motion.y ); 846 ev.data.mouse_motion.y );
822 } 847 }
823 else 848 else
824 { 849 {
825 EPHYR_DBG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ; 850 EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
826 KdEnqueuePointerEvent(ephyrMouse, mouseState, 851 KdEnqueuePointerEvent(ephyrMouse, mouseState,
827 ev.data.mouse_motion.x, 852 ev.data.mouse_motion.x,
828 ev.data.mouse_motion.y, 853 ev.data.mouse_motion.y,
@@ -834,10 +859,10 @@ ephyrPoll(void)
834 case EPHYR_EV_MOUSE_PRESS: 859 case EPHYR_EV_MOUSE_PRESS:
835 if (!ephyrMouse || 860 if (!ephyrMouse ||
836 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { 861 !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
837 EPHYR_DBG ("skipping mouse press:%d\n", ephyrCurScreen) ; 862 EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
838 continue; 863 continue;
839 } 864 }
840 EPHYR_DBG ("enqueuing mouse press:%d\n", ephyrCurScreen) ; 865 EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
841 ephyrUpdateModifierState(ev.key_state); 866 ephyrUpdateModifierState(ev.key_state);
842 mouseState |= ev.data.mouse_down.button_num; 867 mouseState |= ev.data.mouse_down.button_num;
843 KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); 868 KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
@@ -849,7 +874,7 @@ ephyrPoll(void)
849 continue; 874 continue;
850 ephyrUpdateModifierState(ev.key_state); 875 ephyrUpdateModifierState(ev.key_state);
851 mouseState &= ~ev.data.mouse_up.button_num; 876 mouseState &= ~ev.data.mouse_up.button_num;
852 EPHYR_DBG ("enqueuing mouse release:%d\n", ephyrCurScreen) ; 877 EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
853 KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); 878 KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
854 break; 879 break;
855 880
@@ -886,7 +911,7 @@ ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
886{ 911{
887 /* XXX Not sure if this is right */ 912 /* XXX Not sure if this is right */
888 913
889 EPHYR_DBG("mark"); 914 EPHYR_LOG("mark");
890 915
891 while (n--) 916 while (n--)
892 { 917 {
@@ -1025,6 +1050,7 @@ EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
1025{ 1050{
1026} 1051}
1027 1052
1053
1028KdKeyboardDriver EphyrKeyboardDriver = { 1054KdKeyboardDriver EphyrKeyboardDriver = {
1029 "ephyr", 1055 "ephyr",
1030 EphyrKeyboardInit, 1056 EphyrKeyboardInit,
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 1c9b4f859..8ed7e23dd 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -194,4 +194,8 @@ ephyrDrawDisable(ScreenPtr pScreen);
194void 194void
195ephyrDrawFini(ScreenPtr pScreen); 195ephyrDrawFini(ScreenPtr pScreen);
196 196
197/*ephyvideo.c*/
198
199Bool ephyrInitVideo(ScreenPtr pScreen) ;
200
197#endif 201#endif
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
new file mode 100644
index 000000000..53a96ba11
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -0,0 +1,291 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifdef HAVE_CONFIG_H
29#include <kdrive-config.h>
30#endif
31
32#ifdef XEPHYR_DRI
33
34#include <X11/Xutil.h>
35#include <X11/Xlibint.h>
36/*#define _XF86DRI_SERVER_*/
37#include <GL/glx.h>
38#include <X11/dri/xf86dri.h>
39#include "hostx.h"
40#include "ephyrdri.h"
41#define _HAVE_XALLOC_DECLS
42#include "ephyrlog.h"
43#include "dixstruct.h"
44#include "pixmapstr.h"
45
46#ifndef TRUE
47#define TRUE 1
48#endif /*TRUE*/
49
50#ifndef FALSE
51#define FALSE 0
52#endif /*FALSE*/
53
54Bool
55ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
56{
57 Display *dpy=hostx_get_display () ;
58 Bool is_ok=FALSE ;
59
60 EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
61 EPHYR_LOG ("enter\n") ;
62 is_ok = XF86DRIQueryDirectRenderingCapable (dpy, DefaultScreen (dpy),
63 a_is_capable) ;
64 EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
65
66 return is_ok ;
67}
68
69Bool
70ephyrDRIOpenConnection (int a_screen,
71 drm_handle_t *a_sarea,
72 char **a_bus_id_string)
73{
74 Display *dpy = hostx_get_display () ;
75 Bool is_ok=FALSE ;
76
77 EPHYR_RETURN_VAL_IF_FAIL (a_bus_id_string, FALSE) ;
78 EPHYR_LOG ("enter. screen:%d\n", a_screen) ;
79 is_ok = XF86DRIOpenConnection (dpy, DefaultScreen (dpy),
80 a_sarea,
81 a_bus_id_string) ;
82 if (*a_bus_id_string) {
83 EPHYR_LOG ("leave. bus_id_string:%s, is_ok:%d\n",
84 *a_bus_id_string, is_ok) ;
85 } else {
86 EPHYR_LOG ("leave. bus_id_string:null, is_ok:%d\n",
87 is_ok) ;
88 }
89 return is_ok ;
90}
91
92Bool
93ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
94{
95 Display *dpy = hostx_get_display () ;
96 Bool is_ok=FALSE ;
97
98 EPHYR_LOG ("enter\n") ;
99 is_ok = XF86DRIAuthConnection (dpy, DefaultScreen (dpy), a_magic) ;
100 EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
101 return is_ok ;
102}
103
104Bool
105ephyrDRICloseConnection (int a_screen)
106{
107 Display *dpy = hostx_get_display () ;
108 Bool is_ok=FALSE ;
109
110 EPHYR_LOG ("enter\n") ;
111 is_ok = XF86DRICloseConnection (dpy, DefaultScreen (dpy)) ;
112 EPHYR_LOG ("leave\n") ;
113 return is_ok ;
114}
115
116Bool
117ephyrDRIGetClientDriverName (int a_screen,
118 int *a_ddx_driver_major_version,
119 int *a_ddx_driver_minor_version,
120 int *a_ddx_driver_patch_version,
121 char ** a_client_driver_name)
122{
123 Display *dpy = hostx_get_display () ;
124 Bool is_ok=FALSE ;
125
126 EPHYR_RETURN_VAL_IF_FAIL (a_ddx_driver_major_version
127 && a_ddx_driver_minor_version
128 && a_ddx_driver_patch_version
129 && a_client_driver_name,
130 FALSE);
131 EPHYR_LOG ("enter\n") ;
132 is_ok = XF86DRIGetClientDriverName (dpy, DefaultScreen (dpy),
133 a_ddx_driver_major_version,
134 a_ddx_driver_minor_version,
135 a_ddx_driver_patch_version,
136 a_client_driver_name) ;
137 EPHYR_LOG ("major:%d, minor:%d, patch:%d, name:%s\n",
138 *a_ddx_driver_major_version,
139 *a_ddx_driver_minor_version,
140 *a_ddx_driver_patch_version,
141 *a_client_driver_name) ;
142 EPHYR_LOG ("leave:%d\n", is_ok) ;
143 return is_ok ;
144}
145
146Bool
147ephyrDRICreateContext (int a_screen,
148 int a_visual_id,
149 unsigned long int *a_returned_ctxt_id,
150 drm_context_t *a_hw_ctxt)
151{
152 Display *dpy = hostx_get_display () ;
153 Bool is_ok=FALSE ;
154 Visual v;
155
156 EPHYR_LOG ("enter. screen:%d, visual:%d\n", a_screen, a_visual_id) ;
157 memset (&v, 0, sizeof (v)) ;
158 v.visualid = a_visual_id ;
159 is_ok = XF86DRICreateContext (dpy,
160 DefaultScreen (dpy),
161 &v,
162 a_returned_ctxt_id,
163 a_hw_ctxt) ;
164 EPHYR_LOG ("leave:%d\n", is_ok) ;
165 return is_ok ;
166}
167
168Bool
169ephyrDRIDestroyContext (int a_screen,
170 int a_context_id)
171{
172 Display *dpy = hostx_get_display () ;
173 Bool is_ok=FALSE ;
174
175 EPHYR_LOG ("enter\n") ;
176 is_ok = XF86DRIDestroyContext (dpy, DefaultScreen (dpy), a_context_id) ;
177 EPHYR_LOG ("leave:%d\n", is_ok) ;
178 return is_ok ;
179}
180
181Bool
182ephyrDRICreateDrawable (int a_screen,
183 int a_drawable,
184 drm_drawable_t *a_hw_drawable)
185{
186 Bool is_ok=FALSE;
187 Display *dpy=hostx_get_display () ;
188
189 EPHYR_LOG ("enter\n") ;
190 is_ok = XF86DRICreateDrawable (dpy, DefaultScreen (dpy),
191 a_drawable, a_hw_drawable) ;
192 EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
193 return is_ok ;
194}
195
196Bool
197ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
198{
199 EPHYR_LOG ("enter\n") ;
200 EPHYR_LOG_ERROR ("not implemented yet\n") ;
201 EPHYR_LOG ("leave\n") ;
202 return FALSE ;
203}
204
205Bool
206ephyrDRIGetDrawableInfo (int a_screen,
207 int a_drawable,
208 unsigned int *a_index,
209 unsigned int *a_stamp,
210 int *a_x,
211 int *a_y,
212 int *a_w,
213 int *a_h,
214 int *a_num_clip_rects,
215 drm_clip_rect_t **a_clip_rects,
216 int *a_back_x,
217 int *a_back_y,
218 int *a_num_back_clip_rects,
219 drm_clip_rect_t **a_back_clip_rects)
220{
221 Bool is_ok=FALSE;
222 Display *dpy=hostx_get_display () ;
223 EphyrHostWindowAttributes attrs ;
224
225 EPHYR_RETURN_VAL_IF_FAIL (a_x && a_y && a_w && a_h
226 && a_num_clip_rects,
227 FALSE) ;
228
229 EPHYR_LOG ("enter\n") ;
230 memset (&attrs, 0, sizeof (attrs)) ;
231 if (!hostx_get_window_attributes (a_drawable, &attrs)) {
232 EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
233 goto out;
234 }
235 if (!XF86DRIGetDrawableInfo (dpy, DefaultScreen (dpy), a_drawable,
236 a_index, a_stamp,
237 a_x, a_y,
238 a_w, a_h,
239 a_num_clip_rects, a_clip_rects,
240 a_back_x, a_back_y,
241 a_num_back_clip_rects,
242 a_back_clip_rects)) {
243 EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n") ;
244 goto out ;
245 }
246 EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
247 if (*a_num_clip_rects) {
248 free (*a_back_clip_rects) ;
249 *a_back_clip_rects = calloc (*a_num_clip_rects,
250 sizeof (drm_clip_rect_t)) ;
251 memmove (*a_back_clip_rects,
252 *a_clip_rects,
253 *a_num_clip_rects * sizeof (drm_clip_rect_t)) ;
254 *a_num_back_clip_rects = *a_num_clip_rects;
255 }
256 EPHYR_LOG ("num back clip rects:%d, num clip rects:%d\n",
257 *a_num_clip_rects, *a_num_back_clip_rects) ;
258 *a_back_x = *a_x ;
259 *a_back_y = *a_y ;
260 *a_w = attrs.width;
261 *a_h = attrs.height;
262
263 is_ok = TRUE ;
264out:
265 EPHYR_LOG ("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
266 *a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h) ;
267 return is_ok ;
268}
269
270Bool
271ephyrDRIGetDeviceInfo (int a_screen,
272 drm_handle_t *a_frame_buffer,
273 int *a_fb_origin,
274 int *a_fb_size,
275 int *a_fb_stride,
276 int *a_dev_private_size,
277 void **a_dev_private)
278{
279 Bool is_ok = FALSE ;
280 Display *dpy = hostx_get_display () ;
281
282 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
283 EPHYR_LOG ("enter\n") ;
284 is_ok = XF86DRIGetDeviceInfo (dpy, DefaultScreen (dpy), a_frame_buffer,
285 a_fb_origin, a_fb_size, a_fb_stride,
286 a_dev_private_size, a_dev_private) ;
287 EPHYR_LOG ("leave:%d\n", is_ok) ;
288 return is_ok ;
289}
290#endif /*EPHYR_DRI*/
291
diff --git a/hw/kdrive/ephyr/ephyrdri.h b/hw/kdrive/ephyr/ephyrdri.h
new file mode 100644
index 000000000..af8bb11fd
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdri.h
@@ -0,0 +1,75 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28
29#ifndef __EPHYRDRI_H__
30#define __EPHYRDRI_H__
31
32#include <xf86drm.h>
33
34Bool ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable) ;
35Bool ephyrDRIOpenConnection (int screen, drm_handle_t *a_sarea, char **a_bus_id_string) ;
36Bool ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic) ;
37Bool ephyrDRICloseConnection (int a_screen) ;
38Bool ephyrDRIGetClientDriverName (int a_screen,
39 int *a_ddx_driver_major_version,
40 int *a_ddx_driver_minor_version,
41 int *a_ddx_driver_patch_version,
42 char ** a_client_driver_name) ;
43Bool ephyrDRICreateContext (int a_screen,
44 int a_visual_id,
45 unsigned long int *a_returned_ctx_id,
46 drm_context_t *a_hw_ctx) ;
47Bool ephyrDRIDestroyContext (int a_screen,
48 int a_context_id) ;
49Bool ephyrDRICreateDrawable (int a_screen,
50 int a_drawable,
51 drm_drawable_t *a_hw_drawable) ;
52Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
53Bool ephyrDRIGetDrawableInfo (int a_screen,
54 int /*Drawable*/a_drawable,
55 unsigned int *a_index,
56 unsigned int *a_stamp,
57 int *a_x,
58 int *a_y,
59 int *a_w,
60 int *a_h,
61 int *a_num_clip_rects,
62 drm_clip_rect_t **a_clip_rects,
63 int *a_back_x,
64 int *a_back_y,
65 int *num_back_clip_rects,
66 drm_clip_rect_t **a_back_clip_rects) ;
67Bool ephyrDRIGetDeviceInfo (int a_screen,
68 drm_handle_t *a_frame_buffer,
69 int *a_fb_origin,
70 int *a_fb_size,
71 int *a_fb_stride,
72 int *a_dev_private_size,
73 void **a_dev_private) ;
74#endif /*__EPHYRDRI_H__*/
75
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
new file mode 100644
index 000000000..e3d0cfbb4
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -0,0 +1,1448 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * This file is heavily copied from hw/xfree86/dri/xf86dri.c
26 *
27 * Authors:
28 * Dodji Seketeli <dodji@openedhand.com>
29 */
30
31#ifdef HAVE_CONFIG_H
32#include <kdrive-config.h>
33#endif
34
35#ifdef XEPHYR_DRI
36
37#include <string.h>
38
39#define NEED_REPLIES
40#define NEED_EVENTS
41#include <X11/X.h>
42#include <X11/Xproto.h>
43#define _XF86DRI_SERVER_
44#include <X11/dri/xf86dri.h>
45#include <X11/dri/xf86dristr.h>
46#include "misc.h"
47#include "dixstruct.h"
48#include "extnsionst.h"
49#include "colormapst.h"
50#include "cursorstr.h"
51#include "scrnintstr.h"
52#include "windowstr.h"
53#include "servermd.h"
54#include "swaprep.h"
55#include "ephyrdri.h"
56#include "ephyrdriext.h"
57#include "hostx.h"
58#define _HAVE_XALLOC_DECLS
59#include "ephyrlog.h"
60
61typedef struct {
62 WindowPtr local ;
63 int remote ;
64} EphyrWindowPair;
65
66typedef struct {
67 int foo;
68} EphyrDRIWindowPrivRec;
69typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
70
71typedef struct {
72 CreateWindowProcPtr CreateWindow ;
73 DestroyWindowProcPtr DestroyWindow ;
74 MoveWindowProcPtr MoveWindow ;
75 PositionWindowProcPtr PositionWindow ;
76 ClipNotifyProcPtr ClipNotify ;
77} EphyrDRIScreenPrivRec;
78typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
79
80static int DRIErrorBase;
81
82static DISPATCH_PROC(ProcXF86DRIQueryVersion);
83static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
84static DISPATCH_PROC(ProcXF86DRIOpenConnection);
85static DISPATCH_PROC(ProcXF86DRICloseConnection);
86static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
87static DISPATCH_PROC(ProcXF86DRICreateContext);
88static DISPATCH_PROC(ProcXF86DRIDestroyContext);
89static DISPATCH_PROC(ProcXF86DRICreateDrawable);
90static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
91static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
92static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
93static DISPATCH_PROC(ProcXF86DRIDispatch);
94static DISPATCH_PROC(ProcXF86DRIAuthConnection);
95
96static DISPATCH_PROC(SProcXF86DRIQueryVersion);
97static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
98static DISPATCH_PROC(SProcXF86DRIDispatch);
99
100static void XF86DRIResetProc(ExtensionEntry* extEntry);
101
102static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
103static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
104static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
105static void ephyrDRIMoveWindow (WindowPtr a_win,
106 int a_x, int a_y,
107 WindowPtr a_siblings,
108 VTKind a_kind);
109static Bool ephyrDRIPositionWindow (WindowPtr a_win,
110 int x, int y) ;
111static void ephyrDRIClipNotify (WindowPtr a_win,
112 int a_x, int a_y) ;
113
114static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
115static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
116static Bool findWindowPairFromLocal (WindowPtr a_local,
117 EphyrWindowPair **a_pair);
118
119static unsigned char DRIReqCode = 0;
120
121static int ephyrDRIGeneration=-1 ;
122static int ephyrDRIWindowIndex=-1 ;
123static int ephyrDRIScreenIndex=-1 ;
124
125#define GET_EPHYR_DRI_WINDOW_PRIV(win) \
126 ((EphyrDRIWindowPrivPtr)((win)->devPrivates[ephyrDRIWindowIndex].ptr))
127#define GET_EPHYR_DRI_SCREEN_PRIV(screen) \
128 ((EphyrDRIScreenPrivPtr)((screen)->devPrivates[ephyrDRIScreenIndex].ptr))
129
130
131Bool
132ephyrDRIExtensionInit (ScreenPtr a_screen)
133{
134 Bool is_ok=FALSE ;
135 ExtensionEntry* extEntry=NULL;
136 EphyrDRIScreenPrivPtr screen_priv=NULL ;
137
138 EPHYR_LOG ("enter\n") ;
139 if (!hostx_has_dri ()) {
140 EPHYR_LOG ("host does not have DRI extension\n") ;
141 goto out ;
142 }
143 EPHYR_LOG ("host X does have DRI extension\n") ;
144 if (!hostx_has_xshape ()) {
145 EPHYR_LOG ("host does not have XShape extension\n") ;
146 goto out ;
147 }
148 EPHYR_LOG ("host X does have XShape extension\n") ;
149
150#ifdef XF86DRI_EVENTS
151 EventType = CreateNewResourceType (XF86DRIFreeEvents);
152#endif
153
154 if ((extEntry = AddExtension(XF86DRINAME,
155 XF86DRINumberEvents,
156 XF86DRINumberErrors,
157 ProcXF86DRIDispatch,
158 SProcXF86DRIDispatch,
159 XF86DRIResetProc,
160 StandardMinorOpcode))) {
161 DRIReqCode = (unsigned char)extEntry->base;
162 DRIErrorBase = extEntry->errorBase;
163 } else {
164 EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
165 goto out ;
166 }
167 if (ephyrDRIGeneration != serverGeneration) {
168 ephyrDRIScreenIndex = AllocateScreenPrivateIndex () ;
169 if (ephyrDRIScreenIndex < 0) {
170 EPHYR_LOG_ERROR ("failed to allocate screen priv index\n") ;
171 goto out ;
172 }
173 }
174 screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ;
175 if (!screen_priv) {
176 EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
177 goto out ;
178 }
179 a_screen->devPrivates[ephyrDRIScreenIndex].ptr = screen_priv;
180
181 if (!ephyrDRIScreenInit (a_screen)) {
182 EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
183 goto out ;
184 }
185 EphyrMirrorHostVisuals (a_screen) ;
186 if (ephyrDRIGeneration != serverGeneration) {
187 ephyrDRIGeneration = serverGeneration ;
188 }
189 is_ok=TRUE ;
190out:
191 EPHYR_LOG ("leave\n") ;
192 return is_ok ;
193}
194
195static Bool
196ephyrDRIScreenInit (ScreenPtr a_screen)
197{
198 Bool is_ok=FALSE ;
199 EphyrDRIScreenPrivPtr screen_priv=NULL ;
200
201 EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
202
203 screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
204 EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
205
206 if (ephyrDRIGeneration != serverGeneration) {
207 ephyrDRIWindowIndex = AllocateWindowPrivateIndex () ;
208 if (ephyrDRIWindowIndex < 0) {
209 EPHYR_LOG_ERROR ("failed to allocate window priv index\n") ;
210 goto out ;
211 }
212 }
213 if (!AllocateWindowPrivate (a_screen, ephyrDRIWindowIndex, 0)) {
214 EPHYR_LOG_ERROR ("failed to allocate window privates\n") ;
215 goto out ;
216 }
217 screen_priv->CreateWindow = a_screen->CreateWindow ;
218 screen_priv->DestroyWindow = a_screen->DestroyWindow ;
219 screen_priv->MoveWindow = a_screen->MoveWindow ;
220 screen_priv->PositionWindow = a_screen->PositionWindow ;
221 screen_priv->ClipNotify = a_screen->ClipNotify ;
222
223 a_screen->CreateWindow = ephyrDRICreateWindow ;
224 a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
225 a_screen->MoveWindow = ephyrDRIMoveWindow ;
226 a_screen->PositionWindow = ephyrDRIPositionWindow ;
227 a_screen->ClipNotify = ephyrDRIClipNotify ;
228
229 is_ok = TRUE ;
230out:
231 return is_ok ;
232}
233
234static Bool
235ephyrDRICreateWindow (WindowPtr a_win)
236{
237 Bool is_ok=FALSE ;
238 ScreenPtr screen=NULL ;
239 EphyrDRIScreenPrivPtr screen_priv =NULL;
240
241 EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
242 screen = a_win->drawable.pScreen ;
243 EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
244 screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
245 EPHYR_RETURN_VAL_IF_FAIL (screen_priv
246 && screen_priv->CreateWindow,
247 FALSE) ;
248
249 EPHYR_LOG ("enter. win:%#x\n",
250 (unsigned int)a_win) ;
251
252 screen->CreateWindow = screen_priv->CreateWindow ;
253 is_ok = (*screen->CreateWindow) (a_win) ;
254 screen->CreateWindow = ephyrDRICreateWindow ;
255
256 if (is_ok) {
257 a_win->devPrivates[ephyrDRIWindowIndex].ptr = NULL ;
258 }
259 return is_ok ;
260}
261
262static Bool
263ephyrDRIDestroyWindow (WindowPtr a_win)
264{
265 Bool is_ok=FALSE ;
266 ScreenPtr screen=NULL ;
267 EphyrDRIScreenPrivPtr screen_priv =NULL;
268
269 EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
270 screen = a_win->drawable.pScreen ;
271 EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
272 screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
273 EPHYR_RETURN_VAL_IF_FAIL (screen_priv
274 && screen_priv->DestroyWindow,
275 FALSE) ;
276
277 screen->DestroyWindow = screen_priv->DestroyWindow ;
278 if (screen->DestroyWindow) {
279 is_ok = (*screen->DestroyWindow) (a_win) ;
280 }
281 screen->DestroyWindow = ephyrDRIDestroyWindow ;
282
283 if (is_ok) {
284 EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
285 if (win_priv) {
286 destroyHostPeerWindow (a_win) ;
287 xfree (win_priv) ;
288 a_win->devPrivates[ephyrDRIWindowIndex].ptr = NULL ;
289 EPHYR_LOG ("destroyed the remote peer window\n") ;
290 }
291 }
292 return is_ok ;
293}
294
295static void
296ephyrDRIMoveWindow (WindowPtr a_win,
297 int a_x, int a_y,
298 WindowPtr a_siblings,
299 VTKind a_kind)
300{
301 Bool is_ok=FALSE ;
302 ScreenPtr screen=NULL ;
303 EphyrDRIScreenPrivPtr screen_priv =NULL;
304 EphyrDRIWindowPrivPtr win_priv=NULL ;
305 EphyrWindowPair *pair=NULL ;
306 EphyrBox geo;
307 int x=0,y=0;/*coords relative to parent window*/
308
309 EPHYR_RETURN_IF_FAIL (a_win) ;
310
311 EPHYR_LOG ("enter\n") ;
312 screen = a_win->drawable.pScreen ;
313 EPHYR_RETURN_IF_FAIL (screen) ;
314 screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
315 EPHYR_RETURN_IF_FAIL (screen_priv
316 && screen_priv->MoveWindow) ;
317
318 screen->MoveWindow = screen_priv->MoveWindow ;
319 if (screen->MoveWindow) {
320 (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
321 }
322 screen->MoveWindow = ephyrDRIMoveWindow ;
323
324 EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
325 if (!a_win->parent) {
326 EPHYR_LOG ("cannot move root window\n") ;
327 is_ok = TRUE ;
328 goto out ;
329 }
330 win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
331 if (!win_priv) {
332 EPHYR_LOG ("not a DRI peered window\n") ;
333 is_ok = TRUE ;
334 goto out ;
335 }
336 if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
337 EPHYR_LOG_ERROR ("failed to get window pair\n") ;
338 goto out ;
339 }
340 /*compute position relative to parent window*/
341 x = a_win->drawable.x - a_win->parent->drawable.x ;
342 y = a_win->drawable.y - a_win->parent->drawable.y ;
343 /*set the geometry to pass to hostx_set_window_geometry*/
344 memset (&geo, 0, sizeof (geo)) ;
345 geo.x = x ;
346 geo.y = y ;
347 geo.width = a_win->drawable.width ;
348 geo.height = a_win->drawable.height ;
349 hostx_set_window_geometry (pair->remote, &geo) ;
350 is_ok = TRUE ;
351
352out:
353 EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
354 /*do cleanup here*/
355}
356
357static Bool
358ephyrDRIPositionWindow (WindowPtr a_win,
359 int a_x, int a_y)
360{
361 Bool is_ok=FALSE ;
362 ScreenPtr screen=NULL ;
363 EphyrDRIScreenPrivPtr screen_priv =NULL;
364 EphyrDRIWindowPrivPtr win_priv=NULL ;
365 EphyrWindowPair *pair=NULL ;
366 EphyrBox geo;
367
368 EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
369
370 EPHYR_LOG ("enter\n") ;
371 screen = a_win->drawable.pScreen ;
372 EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
373 screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
374 EPHYR_RETURN_VAL_IF_FAIL (screen_priv
375 && screen_priv->PositionWindow,
376 FALSE) ;
377
378 screen->PositionWindow = screen_priv->PositionWindow ;
379 if (screen->PositionWindow) {
380 (*screen->PositionWindow) (a_win, a_x, a_y) ;
381 }
382 screen->PositionWindow = ephyrDRIPositionWindow ;
383
384 EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
385 win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
386 if (!win_priv) {
387 EPHYR_LOG ("not a DRI peered window\n") ;
388 is_ok = TRUE ;
389 goto out ;
390 }
391 if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
392 EPHYR_LOG_ERROR ("failed to get window pair\n") ;
393 goto out ;
394 }
395 /*set the geometry to pass to hostx_set_window_geometry*/
396 memset (&geo, 0, sizeof (geo)) ;
397 geo.x = a_x ;
398 geo.y = a_y ;
399 geo.width = a_win->drawable.width ;
400 geo.height = a_win->drawable.height ;
401 hostx_set_window_geometry (pair->remote, &geo) ;
402 is_ok = TRUE ;
403
404out:
405 EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
406 /*do cleanup here*/
407 return is_ok ;
408}
409
410static void
411ephyrDRIClipNotify (WindowPtr a_win,
412 int a_x, int a_y)
413{
414 Bool is_ok=FALSE ;
415 ScreenPtr screen=NULL ;
416 EphyrDRIScreenPrivPtr screen_priv =NULL;
417 EphyrDRIWindowPrivPtr win_priv=NULL ;
418 EphyrWindowPair *pair=NULL ;
419 EphyrRect *rects=NULL;
420 int i=0 ;
421
422 EPHYR_RETURN_IF_FAIL (a_win) ;
423
424 EPHYR_LOG ("enter\n") ;
425 screen = a_win->drawable.pScreen ;
426 EPHYR_RETURN_IF_FAIL (screen) ;
427 screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
428 EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
429
430 screen->ClipNotify = screen_priv->ClipNotify ;
431 if (screen->ClipNotify) {
432 (*screen->ClipNotify) (a_win, a_x, a_y) ;
433 }
434 screen->ClipNotify = ephyrDRIClipNotify ;
435
436 EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
437 win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
438 if (!win_priv) {
439 EPHYR_LOG ("not a DRI peered window\n") ;
440 is_ok = TRUE ;
441 goto out ;
442 }
443 if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
444 EPHYR_LOG_ERROR ("failed to get window pair\n") ;
445 goto out ;
446 }
447 rects = xcalloc (REGION_NUM_RECTS (&a_win->clipList),
448 sizeof (EphyrRect)) ;
449 for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
450 memmove (&rects[i],
451 &REGION_RECTS (&a_win->clipList)[i],
452 sizeof (EphyrRect)) ;
453 rects[i].x1 -= a_win->drawable.x;
454 rects[i].x2 -= a_win->drawable.x;
455 rects[i].y1 -= a_win->drawable.y;
456 rects[i].y2 -= a_win->drawable.y;
457 }
458 /*
459 * push the clipping region of this window
460 * to the peer window in the host
461 */
462 is_ok = hostx_set_window_bounding_rectangles
463 (pair->remote,
464 rects,
465 REGION_NUM_RECTS (&a_win->clipList)) ;
466 is_ok = TRUE ;
467
468out:
469 if (rects) {
470 xfree (rects) ;
471 rects = NULL ;
472 }
473 EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
474 /*do cleanup here*/
475}
476
477/**
478 * Duplicates a visual of a_screen
479 * In screen a_screen, for depth a_depth, find a visual which
480 * bitsPerRGBValue and colormap size equal
481 * a_bits_per_rgb_values and a_colormap_entries.
482 * The ID of that duplicated visual is set to a_new_id.
483 * That duplicated visual is then added to the list of visuals
484 * of the screen.
485 */
486static Bool
487EphyrDuplicateVisual (unsigned int a_screen,
488 short a_depth,
489 short a_class,
490 short a_bits_per_rgb_values,
491 short a_colormap_entries,
492 unsigned int a_red_mask,
493 unsigned int a_green_mask,
494 unsigned int a_blue_mask,
495 unsigned int a_new_id)
496{
497 Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
498 ScreenPtr screen=NULL ;
499 VisualRec new_visual, *new_visuals=NULL ;
500 int i=0 ;
501
502 EPHYR_LOG ("enter\n") ;
503 if (a_screen > screenInfo.numScreens) {
504 EPHYR_LOG_ERROR ("bad screen number\n") ;
505 goto out;
506 }
507 memset (&new_visual, 0, sizeof (VisualRec)) ;
508
509 /*get the screen pointed to by a_screen*/
510 screen = screenInfo.screens[a_screen] ;
511 EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
512
513 /*
514 * In that screen, first look for an existing visual that has the
515 * same characteristics as those passed in parameter
516 * to this function and copy it.
517 */
518 for (i=0; i < screen->numVisuals; i++) {
519 if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
520 screen->visuals[i].ColormapEntries == a_colormap_entries ) {
521 /*copy the visual found*/
522 memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
523 new_visual.vid = a_new_id ;
524 new_visual.class = a_class ;
525 new_visual.redMask = a_red_mask ;
526 new_visual.greenMask = a_green_mask ;
527 new_visual.blueMask = a_blue_mask ;
528 found_visual = TRUE ;
529 EPHYR_LOG ("found a visual that matches visual id: %d\n",
530 a_new_id) ;
531 break;
532 }
533 }
534 if (!found_visual) {
535 EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
536 goto out ;
537 }
538 /*
539 * be prepare to extend screen->visuals to add new_visual to it
540 */
541 new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
542 memmove (new_visuals,
543 screen->visuals,
544 screen->numVisuals*sizeof (VisualRec)) ;
545 memmove (&new_visuals[screen->numVisuals],
546 &new_visual,
547 sizeof (VisualRec)) ;
548 /*
549 * Now, in that same screen, update the screen->allowedDepths member.
550 * In that array, each element represents the visuals applicable to
551 * a given depth. So we need to add an entry matching the new visual
552 * that we are going to add to screen->visuals
553 */
554 for (i=0; i<screen->numDepths; i++) {
555 VisualID *vids=NULL;
556 DepthPtr cur_depth=NULL ;
557 /*find the entry matching a_depth*/
558 if (screen->allowedDepths[i].depth != a_depth)
559 continue ;
560 cur_depth = &screen->allowedDepths[i];
561 /*
562 * extend the list of visual IDs in that entry,
563 * so to add a_new_id in there.
564 */
565 vids = xrealloc (cur_depth->vids,
566 (cur_depth->numVids+1)*sizeof (VisualID));
567 if (!vids) {
568 EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
569 goto out ;
570 }
571 vids[cur_depth->numVids] = a_new_id ;
572 /*
573 * Okay now commit our change.
574 * Do really update screen->allowedDepths[i]
575 */
576 cur_depth->numVids++ ;
577 cur_depth->vids = vids ;
578 found_depth=TRUE;
579 }
580 if (!found_depth) {
581 EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
582 a_screen) ;
583 goto out ;
584 }
585 /*
586 * Commit our change to screen->visuals
587 */
588 xfree (screen->visuals) ;
589 screen->visuals = new_visuals ;
590 screen->numVisuals++ ;
591 new_visuals = NULL ;
592
593 is_ok = TRUE ;
594out:
595 if (new_visuals) {
596 xfree (new_visuals) ;
597 new_visuals = NULL ;
598 }
599 EPHYR_LOG ("leave\n") ;
600 return is_ok ;
601}
602
603/**
604 * Duplicates the visuals of the host X server.
605 * This is necessary to have visuals that have the same
606 * ID as those of the host X. It is important to have that for
607 * GLX.
608 */
609static Bool
610EphyrMirrorHostVisuals (ScreenPtr a_screen)
611{
612 Bool is_ok=FALSE;
613 EphyrHostVisualInfo *visuals=NULL;
614 int nb_visuals=0, i=0;
615
616 EPHYR_LOG ("enter\n") ;
617 if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
618 EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
619 goto out ;
620 }
621 for (i=0; i<nb_visuals; i++) {
622 if (!EphyrDuplicateVisual (a_screen->myNum,
623 visuals[i].depth,
624 visuals[i].class,
625 visuals[i].bits_per_rgb,
626 visuals[i].colormap_size,
627 visuals[i].red_mask,
628 visuals[i].green_mask,
629 visuals[i].blue_mask,
630 visuals[i].visualid)) {
631 EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
632 (int)visuals[i].visualid) ;
633 }
634 }
635
636 is_ok = TRUE ;
637out:
638 EPHYR_LOG ("leave\n") ;
639 return is_ok;
640}
641
642
643/*ARGSUSED*/
644static void
645XF86DRIResetProc (
646 ExtensionEntry* extEntry
647)
648{
649}
650
651static int
652ProcXF86DRIQueryVersion (register ClientPtr client)
653{
654 xXF86DRIQueryVersionReply rep;
655 register int n;
656
657 EPHYR_LOG ("enter\n") ;
658
659 REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
660 rep.type = X_Reply;
661 rep.length = 0;
662 rep.sequenceNumber = client->sequence;
663 rep.majorVersion = XF86DRI_MAJOR_VERSION;
664 rep.minorVersion = XF86DRI_MINOR_VERSION;
665 rep.patchVersion = XF86DRI_PATCH_VERSION;
666 if (client->swapped) {
667 swaps(&rep.sequenceNumber, n);
668 swapl(&rep.length, n);
669 swaps(&rep.majorVersion, n);
670 swaps(&rep.minorVersion, n);
671 swapl(&rep.patchVersion, n);
672 }
673 WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
674 EPHYR_LOG ("leave\n") ;
675 return (client->noClientException);
676}
677
678static int
679ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
680{
681 xXF86DRIQueryDirectRenderingCapableReply rep;
682 Bool isCapable;
683 register int n;
684
685 EPHYR_LOG ("enter\n") ;
686 REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
687 REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
688 if (stuff->screen >= screenInfo.numScreens) {
689 client->errorValue = stuff->screen;
690 return BadValue;
691 }
692
693 rep.type = X_Reply;
694 rep.length = 0;
695 rep.sequenceNumber = client->sequence;
696
697 if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
698 return BadValue;
699 }
700 rep.isCapable = isCapable;
701
702 if (!LocalClient(client) || client->swapped)
703 rep.isCapable = 0;
704
705 if (client->swapped) {
706 swaps(&rep.sequenceNumber, n);
707 swapl(&rep.length, n);
708 }
709
710 WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
711 EPHYR_LOG ("leave\n") ;
712
713 return (client->noClientException);
714}
715
716static int
717ProcXF86DRIOpenConnection (register ClientPtr client)
718{
719 xXF86DRIOpenConnectionReply rep;
720 drm_handle_t hSAREA;
721 char* busIdString;
722
723 EPHYR_LOG ("enter\n") ;
724 REQUEST(xXF86DRIOpenConnectionReq);
725 REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
726 if (stuff->screen >= screenInfo.numScreens) {
727 client->errorValue = stuff->screen;
728 return BadValue;
729 }
730
731 if (!ephyrDRIOpenConnection(stuff->screen,
732 &hSAREA,
733 &busIdString)) {
734 return BadValue;
735 }
736
737 rep.type = X_Reply;
738 rep.sequenceNumber = client->sequence;
739 rep.busIdStringLength = 0;
740 if (busIdString)
741 rep.busIdStringLength = strlen(busIdString);
742 rep.length = (SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
743 ((rep.busIdStringLength + 3) & ~3)) >> 2;
744
745 rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
746#if defined(LONG64) && !defined(__linux__)
747 rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
748#else
749 rep.hSAREAHigh = 0;
750#endif
751
752 WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
753 if (rep.busIdStringLength)
754 WriteToClient(client, rep.busIdStringLength, busIdString);
755 EPHYR_LOG ("leave\n") ;
756 return (client->noClientException);
757}
758
759static int
760ProcXF86DRIAuthConnection (register ClientPtr client)
761{
762 xXF86DRIAuthConnectionReply rep;
763
764 EPHYR_LOG ("enter\n") ;
765 REQUEST(xXF86DRIAuthConnectionReq);
766 REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
767 if (stuff->screen >= screenInfo.numScreens) {
768 client->errorValue = stuff->screen;
769 return BadValue;
770 }
771
772 rep.type = X_Reply;
773 rep.length = 0;
774 rep.sequenceNumber = client->sequence;
775 rep.authenticated = 1;
776
777 if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
778 ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
779 rep.authenticated = 0;
780 }
781 WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
782 EPHYR_LOG ("leave\n") ;
783 return (client->noClientException);
784}
785
786static int
787ProcXF86DRICloseConnection (register ClientPtr client)
788{
789 EPHYR_LOG ("enter\n") ;
790 REQUEST(xXF86DRICloseConnectionReq);
791 REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
792 if (stuff->screen >= screenInfo.numScreens) {
793 client->errorValue = stuff->screen;
794 return BadValue;
795 }
796
797 /*
798 DRICloseConnection( screenInfo.screens[stuff->screen]);
799 */
800
801 EPHYR_LOG ("leave\n") ;
802 return (client->noClientException);
803}
804
805static int
806ProcXF86DRIGetClientDriverName (register ClientPtr client)
807{
808 xXF86DRIGetClientDriverNameReply rep;
809 char* clientDriverName;
810
811 EPHYR_LOG ("enter\n") ;
812 REQUEST(xXF86DRIGetClientDriverNameReq);
813 REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
814 if (stuff->screen >= screenInfo.numScreens) {
815 client->errorValue = stuff->screen;
816 return BadValue;
817 }
818
819 ephyrDRIGetClientDriverName (stuff->screen,
820 (int *)&rep.ddxDriverMajorVersion,
821 (int *)&rep.ddxDriverMinorVersion,
822 (int *)&rep.ddxDriverPatchVersion,
823 &clientDriverName);
824
825 rep.type = X_Reply;
826 rep.sequenceNumber = client->sequence;
827 rep.clientDriverNameLength = 0;
828 if (clientDriverName)
829 rep.clientDriverNameLength = strlen(clientDriverName);
830 rep.length = (SIZEOF(xXF86DRIGetClientDriverNameReply) -
831 SIZEOF(xGenericReply) +
832 ((rep.clientDriverNameLength + 3) & ~3)) >> 2;
833
834 WriteToClient(client,
835 sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
836 if (rep.clientDriverNameLength)
837 WriteToClient(client,
838 rep.clientDriverNameLength,
839 clientDriverName);
840 EPHYR_LOG ("leave\n") ;
841 return (client->noClientException);
842}
843
844static int
845ProcXF86DRICreateContext (register ClientPtr client)
846{
847 xXF86DRICreateContextReply rep;
848 ScreenPtr pScreen;
849 VisualPtr visual;
850 int i=0;
851 unsigned long context_id=0;
852
853 EPHYR_LOG ("enter\n") ;
854 REQUEST(xXF86DRICreateContextReq);
855 REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
856 if (stuff->screen >= screenInfo.numScreens) {
857 client->errorValue = stuff->screen;
858 return BadValue;
859 }
860
861 rep.type = X_Reply;
862 rep.length = 0;
863 rep.sequenceNumber = client->sequence;
864
865 pScreen = screenInfo.screens[stuff->screen];
866 visual = pScreen->visuals;
867
868 /* Find the requested X visual */
869 for (i = 0; i < pScreen->numVisuals; i++, visual++)
870 if (visual->vid == stuff->visual)
871 break;
872 if (i == pScreen->numVisuals) {
873 /* No visual found */
874 return BadValue;
875 }
876
877 context_id = stuff->context ;
878 if (!ephyrDRICreateContext (stuff->screen,
879 stuff->visual,
880 &context_id,
881 (drm_context_t *)&rep.hHWContext)) {
882 return BadValue;
883 }
884
885 WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
886 EPHYR_LOG ("leave\n") ;
887 return (client->noClientException);
888}
889
890static int
891ProcXF86DRIDestroyContext (register ClientPtr client)
892{
893 EPHYR_LOG ("enter\n") ;
894
895 REQUEST(xXF86DRIDestroyContextReq);
896 REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
897 if (stuff->screen >= screenInfo.numScreens) {
898 client->errorValue = stuff->screen;
899 return BadValue;
900 }
901
902 if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
903 return BadValue;
904 }
905
906 EPHYR_LOG ("leave\n") ;
907 return (client->noClientException);
908}
909
910static Bool
911getWindowVisual (const WindowPtr a_win,
912 VisualPtr *a_visual)
913{
914 int i=0, visual_id=0 ;
915 EPHYR_RETURN_VAL_IF_FAIL (a_win
916 && a_win->drawable.pScreen
917 && a_win->drawable.pScreen->visuals,
918 FALSE) ;
919
920 visual_id = wVisual (a_win) ;
921 for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
922 if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
923 *a_visual = &a_win->drawable.pScreen->visuals[i] ;
924 return TRUE ;
925 }
926 }
927 return FALSE ;
928}
929
930
931#define NUM_WINDOW_PAIRS 256
932static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
933
934static Bool
935appendWindowPairToList (WindowPtr a_local,
936 int a_remote)
937{
938 int i=0 ;
939
940 EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
941
942 EPHYR_LOG ("(local,remote):(%#x, %d)\n", (unsigned int)a_local, a_remote) ;
943
944 for (i=0; i < NUM_WINDOW_PAIRS; i++) {
945 if (window_pairs[i].local == NULL) {
946 window_pairs[i].local = a_local ;
947 window_pairs[i].remote = a_remote ;
948 return TRUE ;
949 }
950 }
951 return FALSE ;
952}
953
954static Bool
955findWindowPairFromLocal (WindowPtr a_local,
956 EphyrWindowPair **a_pair)
957{
958 int i=0 ;
959
960 EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
961
962 for (i=0; i < NUM_WINDOW_PAIRS; i++) {
963 if (window_pairs[i].local == a_local) {
964 *a_pair = &window_pairs[i] ;
965 EPHYR_LOG ("found (%#x, %d)\n",
966 (unsigned int)(*a_pair)->local,
967 (*a_pair)->remote) ;
968 return TRUE ;
969 }
970 }
971 return FALSE ;
972}
973
974static Bool
975createHostPeerWindow (const WindowPtr a_win,
976 int *a_peer_win)
977{
978 Bool is_ok=FALSE ;
979 VisualPtr visual=NULL;
980 EphyrBox geo ;
981
982 EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
983 EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
984 FALSE) ;
985
986 EPHYR_LOG ("enter. a_win '%#x'\n", (unsigned int)a_win) ;
987 if (!getWindowVisual (a_win, &visual)) {
988 EPHYR_LOG_ERROR ("failed to get window visual\n") ;
989 goto out ;
990 }
991 if (!visual) {
992 EPHYR_LOG_ERROR ("failed to create visual\n") ;
993 goto out ;
994 }
995 memset (&geo, 0, sizeof (geo)) ;
996 geo.x = a_win->drawable.x ;
997 geo.y = a_win->drawable.y ;
998 geo.width = a_win->drawable.width ;
999 geo.height = a_win->drawable.height ;
1000 if (!hostx_create_window (a_win->drawable.pScreen->myNum,
1001 &geo, visual->vid, a_peer_win)) {
1002 EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
1003 goto out ;
1004 }
1005 if (!appendWindowPairToList (a_win, *a_peer_win)) {
1006 EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
1007 goto out ;
1008 }
1009 is_ok = TRUE ;
1010out:
1011 EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
1012 return is_ok ;
1013}
1014
1015static Bool
1016destroyHostPeerWindow (const WindowPtr a_win)
1017{
1018 Bool is_ok = FALSE ;
1019 EphyrWindowPair *pair=NULL ;
1020 EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
1021
1022 EPHYR_LOG ("enter\n") ;
1023
1024 if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
1025 EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
1026 goto out;
1027 }
1028 hostx_destroy_window (pair->remote) ;
1029 is_ok = TRUE ;
1030
1031out:
1032 EPHYR_LOG ("leave\n") ;
1033 return is_ok;
1034}
1035
1036static int
1037ProcXF86DRICreateDrawable (ClientPtr client)
1038{
1039 xXF86DRICreateDrawableReply rep;
1040 DrawablePtr drawable=NULL;
1041 WindowPtr window=NULL ;
1042 EphyrWindowPair *pair=NULL ;
1043 EphyrDRIWindowPrivPtr win_priv=NULL;
1044 int rc=0, remote_win=0;
1045
1046 EPHYR_LOG ("enter\n") ;
1047 REQUEST(xXF86DRICreateDrawableReq);
1048 REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
1049 if (stuff->screen >= screenInfo.numScreens) {
1050 client->errorValue = stuff->screen;
1051 return BadValue;
1052 }
1053
1054 rep.type = X_Reply;
1055 rep.length = 0;
1056 rep.sequenceNumber = client->sequence;
1057
1058 rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
1059 DixReadAccess);
1060 if (rc != Success)
1061 return rc;
1062 if (drawable->type != DRAWABLE_WINDOW) {
1063 EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
1064 return BadImplementation ;
1065 }
1066 EPHYR_LOG ("lookedup drawable %#x\n", (unsigned int)drawable) ;
1067 window = (WindowPtr)drawable;
1068 if (findWindowPairFromLocal (window, &pair) && pair) {
1069 remote_win = pair->remote ;
1070 EPHYR_LOG ("found window '%#x' paire with remote '%d'\n",
1071 (unsigned int)window, remote_win) ;
1072 } else if (!createHostPeerWindow (window, &remote_win)) {
1073 EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
1074 return BadAlloc ;
1075 }
1076
1077 if (!ephyrDRICreateDrawable (stuff->screen,
1078 remote_win,
1079 (drm_drawable_t *)&rep.hHWDrawable)) {
1080 EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
1081 return BadValue;
1082 }
1083
1084 win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
1085 if (!win_priv) {
1086 win_priv = xcalloc (1, sizeof (EphyrDRIWindowPrivRec)) ;
1087 if (!win_priv) {
1088 EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
1089 return BadAlloc ;
1090 }
1091 window->devPrivates[ephyrDRIWindowIndex].ptr = win_priv ;
1092 EPHYR_LOG ("paired window '%#x' with remote '%d'\n",
1093 (unsigned int)window, remote_win) ;
1094 }
1095
1096 WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
1097 EPHYR_LOG ("leave\n") ;
1098 return (client->noClientException);
1099}
1100
1101static int
1102ProcXF86DRIDestroyDrawable (register ClientPtr client)
1103{
1104 REQUEST(xXF86DRIDestroyDrawableReq);
1105 DrawablePtr drawable=NULL;
1106 WindowPtr window=NULL;
1107 EphyrWindowPair *pair=NULL;
1108 REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
1109 int rc=0;
1110
1111 EPHYR_LOG ("enter\n") ;
1112 if (stuff->screen >= screenInfo.numScreens) {
1113 client->errorValue = stuff->screen;
1114 return BadValue;
1115 }
1116
1117 rc = dixLookupDrawable(&drawable,
1118 stuff->drawable,
1119 client,
1120 0,
1121 DixReadAccess);
1122 if (rc != Success)
1123 return rc;
1124 if (drawable->type != DRAWABLE_WINDOW) {
1125 EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
1126 return BadImplementation ;
1127 }
1128 window = (WindowPtr)drawable;
1129 if (!findWindowPairFromLocal (window, &pair) && pair) {
1130 EPHYR_LOG_ERROR ("failed to find pair window\n") ;
1131 return BadImplementation;
1132 }
1133 if (!ephyrDRIDestroyDrawable(stuff->screen,
1134 pair->remote/*drawable in host x*/)) {
1135 EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
1136 return BadImplementation;
1137 }
1138 pair->local=NULL ;
1139 pair->remote=0;
1140
1141 EPHYR_LOG ("leave\n") ;
1142 return (client->noClientException);
1143}
1144
1145static int
1146ProcXF86DRIGetDrawableInfo (register ClientPtr client)
1147{
1148 xXF86DRIGetDrawableInfoReply rep;
1149 DrawablePtr drawable;
1150 WindowPtr window=NULL;
1151 EphyrWindowPair *pair=NULL;
1152 int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
1153 drm_clip_rect_t *clipRects=NULL;
1154 drm_clip_rect_t *backClipRects=NULL;
1155
1156 EPHYR_LOG ("enter\n") ;
1157 memset (&rep, 0, sizeof (rep)) ;
1158 REQUEST(xXF86DRIGetDrawableInfoReq);
1159 REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
1160 if (stuff->screen >= screenInfo.numScreens) {
1161 client->errorValue = stuff->screen;
1162 return BadValue;
1163 }
1164
1165 rep.type = X_Reply;
1166 rep.length = 0;
1167 rep.sequenceNumber = client->sequence;
1168
1169 rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
1170 DixReadAccess);
1171 if (rc != Success || !drawable) {
1172 EPHYR_LOG_ERROR ("could not get drawable\n") ;
1173 return rc;
1174 }
1175
1176 if (drawable->type != DRAWABLE_WINDOW) {
1177 EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
1178 return BadImplementation ;
1179 }
1180 window = (WindowPtr)drawable ;
1181 memset (&pair, 0, sizeof (pair)) ;
1182 if (!findWindowPairFromLocal (window, &pair) || !pair) {
1183 EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
1184 return BadMatch ;
1185 }
1186 EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
1187 for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
1188 EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
1189 REGION_RECTS (&window->clipList)[i].x1,
1190 REGION_RECTS (&window->clipList)[i].y1,
1191 REGION_RECTS (&window->clipList)[i].x2,
1192 REGION_RECTS (&window->clipList)[i].y2) ;
1193 }
1194
1195 if (!ephyrDRIGetDrawableInfo (stuff->screen,
1196 pair->remote/*the drawable in hostx*/,
1197 (unsigned int*)&rep.drawableTableIndex,
1198 (unsigned int*)&rep.drawableTableStamp,
1199 (int*)&X,
1200 (int*)&Y,
1201 (int*)&W,
1202 (int*)&H,
1203 (int*)&rep.numClipRects,
1204 &clipRects,
1205 &backX,
1206 &backY,
1207 (int*)&rep.numBackClipRects,
1208 &backClipRects)) {
1209 return BadValue;
1210 }
1211 EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
1212 (int)rep.numClipRects, (int)rep.numBackClipRects) ;
1213
1214 rep.drawableX = X;
1215 rep.drawableY = Y;
1216 rep.drawableWidth = W;
1217 rep.drawableHeight = H;
1218 rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
1219 SIZEOF(xGenericReply));
1220
1221 rep.backX = backX;
1222 rep.backY = backY;
1223
1224
1225 if (rep.numClipRects) {
1226 if (clipRects) {
1227 ScreenPtr pScreen = screenInfo.screens[stuff->screen];
1228 int i=0;
1229 EPHYR_LOG ("clip list of host gl drawable:\n") ;
1230 for (i = 0; i < rep.numClipRects; i++) {
1231 clipRects[i].x1 = max (clipRects[i].x1, 0);
1232 clipRects[i].y1 = max (clipRects[i].y1, 0);
1233 clipRects[i].x2 = min (clipRects[i].x2,
1234 pScreen->width + clipRects[i].x1) ;
1235 clipRects[i].y2 = min (clipRects[i].y2,
1236 pScreen->width + clipRects[i].y1) ;
1237
1238 EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
1239 clipRects[i].x1, clipRects[i].y1,
1240 clipRects[i].x2, clipRects[i].y2) ;
1241 }
1242 } else {
1243 rep.numClipRects = 0;
1244 }
1245 } else {
1246 EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
1247 }
1248 rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
1249 backClipRects = clipRects ;
1250 rep.numBackClipRects = rep.numClipRects ;
1251 if (rep.numBackClipRects)
1252 rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
1253 EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
1254 EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
1255
1256 rep.length = ((rep.length + 3) & ~3) >> 2;
1257
1258 WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
1259
1260 if (rep.numClipRects) {
1261 WriteToClient(client,
1262 sizeof(drm_clip_rect_t) * rep.numClipRects,
1263 (char *)clipRects);
1264 }
1265
1266 if (rep.numBackClipRects) {
1267 WriteToClient(client,
1268 sizeof(drm_clip_rect_t) * rep.numBackClipRects,
1269 (char *)backClipRects);
1270 }
1271 if (clipRects) {
1272 xfree(clipRects);
1273 clipRects = NULL ;
1274 }
1275 EPHYR_LOG ("leave\n") ;
1276
1277 return (client->noClientException);
1278}
1279
1280static int
1281ProcXF86DRIGetDeviceInfo (register ClientPtr client)
1282{
1283 xXF86DRIGetDeviceInfoReply rep;
1284 drm_handle_t hFrameBuffer;
1285 void *pDevPrivate;
1286
1287 EPHYR_LOG ("enter\n") ;
1288 REQUEST(xXF86DRIGetDeviceInfoReq);
1289 REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
1290 if (stuff->screen >= screenInfo.numScreens) {
1291 client->errorValue = stuff->screen;
1292 return BadValue;
1293 }
1294
1295 rep.type = X_Reply;
1296 rep.length = 0;
1297 rep.sequenceNumber = client->sequence;
1298
1299 if (!ephyrDRIGetDeviceInfo (stuff->screen,
1300 &hFrameBuffer,
1301 (int*)&rep.framebufferOrigin,
1302 (int*)&rep.framebufferSize,
1303 (int*)&rep.framebufferStride,
1304 (int*)&rep.devPrivateSize,
1305 &pDevPrivate)) {
1306 return BadValue;
1307 }
1308
1309 rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
1310#if defined(LONG64) && !defined(__linux__)
1311 rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
1312#else
1313 rep.hFrameBufferHigh = 0;
1314#endif
1315
1316 rep.length = 0;
1317 if (rep.devPrivateSize) {
1318 rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) -
1319 SIZEOF(xGenericReply) +
1320 ((rep.devPrivateSize + 3) & ~3)) >> 2;
1321 }
1322
1323 WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
1324 if (rep.length) {
1325 WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
1326 }
1327 EPHYR_LOG ("leave\n") ;
1328 return (client->noClientException);
1329}
1330
1331static int
1332ProcXF86DRIDispatch (register ClientPtr client)
1333{
1334 REQUEST(xReq);
1335 EPHYR_LOG ("enter\n") ;
1336
1337 switch (stuff->data)
1338 {
1339 case X_XF86DRIQueryVersion: {
1340 EPHYR_LOG ("leave\n") ;
1341 return ProcXF86DRIQueryVersion(client);
1342 }
1343 case X_XF86DRIQueryDirectRenderingCapable: {
1344 EPHYR_LOG ("leave\n") ;
1345 return ProcXF86DRIQueryDirectRenderingCapable(client);
1346 }
1347 }
1348
1349 if (!LocalClient(client))
1350 return DRIErrorBase + XF86DRIClientNotLocal;
1351
1352 switch (stuff->data)
1353 {
1354 case X_XF86DRIOpenConnection: {
1355 EPHYR_LOG ("leave\n") ;
1356 return ProcXF86DRIOpenConnection(client);
1357 }
1358 case X_XF86DRICloseConnection: {
1359 EPHYR_LOG ("leave\n") ;
1360 return ProcXF86DRICloseConnection(client);
1361 }
1362 case X_XF86DRIGetClientDriverName: {
1363 EPHYR_LOG ("leave\n") ;
1364 return ProcXF86DRIGetClientDriverName(client);
1365 }
1366 case X_XF86DRICreateContext: {
1367 EPHYR_LOG ("leave\n") ;
1368 return ProcXF86DRICreateContext(client);
1369 }
1370 case X_XF86DRIDestroyContext: {
1371 EPHYR_LOG ("leave\n") ;
1372 return ProcXF86DRIDestroyContext(client);
1373 }
1374 case X_XF86DRICreateDrawable: {
1375 EPHYR_LOG ("leave\n") ;
1376 return ProcXF86DRICreateDrawable(client);
1377 }
1378 case X_XF86DRIDestroyDrawable: {
1379 EPHYR_LOG ("leave\n") ;
1380 return ProcXF86DRIDestroyDrawable(client);
1381 }
1382 case X_XF86DRIGetDrawableInfo: {
1383 EPHYR_LOG ("leave\n") ;
1384 return ProcXF86DRIGetDrawableInfo(client);
1385 }
1386 case X_XF86DRIGetDeviceInfo: {
1387 EPHYR_LOG ("leave\n") ;
1388 return ProcXF86DRIGetDeviceInfo(client);
1389 }
1390 case X_XF86DRIAuthConnection: {
1391 EPHYR_LOG ("leave\n") ;
1392 return ProcXF86DRIAuthConnection(client);
1393 }
1394 /* {Open,Close}FullScreen are deprecated now */
1395 default: {
1396 EPHYR_LOG ("leave\n") ;
1397 return BadRequest;
1398 }
1399 }
1400}
1401
1402static int
1403SProcXF86DRIQueryVersion (register ClientPtr client)
1404{
1405 register int n;
1406 REQUEST(xXF86DRIQueryVersionReq);
1407 swaps(&stuff->length, n);
1408 return ProcXF86DRIQueryVersion(client);
1409}
1410
1411static int
1412SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
1413{
1414 register int n;
1415 REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
1416 swaps(&stuff->length, n);
1417 swapl(&stuff->screen, n);
1418 return ProcXF86DRIQueryDirectRenderingCapable(client);
1419}
1420
1421static int
1422SProcXF86DRIDispatch (register ClientPtr client)
1423{
1424 REQUEST(xReq);
1425
1426 EPHYR_LOG ("enter\n") ;
1427 /*
1428 * Only local clients are allowed DRI access, but remote clients still need
1429 * these requests to find out cleanly.
1430 */
1431 switch (stuff->data)
1432 {
1433 case X_XF86DRIQueryVersion: {
1434 EPHYR_LOG ("leave\n") ;
1435 return SProcXF86DRIQueryVersion(client);
1436 }
1437 case X_XF86DRIQueryDirectRenderingCapable: {
1438 EPHYR_LOG ("leave\n") ;
1439 return SProcXF86DRIQueryDirectRenderingCapable(client);
1440 }
1441 default: {
1442 EPHYR_LOG ("leave\n") ;
1443 return DRIErrorBase + XF86DRIClientNotLocal;
1444 }
1445 }
1446}
1447
1448#endif /*XEPHYR_DRI*/
diff --git a/hw/kdrive/ephyr/ephyrdriext.h b/hw/kdrive/ephyr/ephyrdriext.h
new file mode 100644
index 000000000..66af833b9
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdriext.h
@@ -0,0 +1,32 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifndef __EPHYRDRIEXT_H__
29#define __EPHYRDRIEXT_H__
30Bool ephyrDRIExtensionInit (ScreenPtr a_screen) ;
31#endif /*__EPHYRDRIEXT_H__*/
32
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
new file mode 100644
index 000000000..381c9d7ed
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -0,0 +1,722 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifdef HAVE_CONFIG_H
29#include <kdrive-config.h>
30#endif
31
32#include "extnsionst.h"
33#include "ephyrglxext.h"
34#include "ephyrhostglx.h"
35#define _HAVE_XALLOC_DECLS
36#include "ephyrlog.h"
37#include <GL/glxproto.h>
38#include "GL/glx/glxserver.h"
39#include "GL/glx/indirect_table.h"
40#include "GL/glx/indirect_util.h"
41#include "GL/glx/unpack.h"
42#include "hostx.h"
43
44
45#ifdef XEPHYR_DRI
46
47#ifndef TRUE
48#define TRUE 1
49#endif
50
51#ifndef FALSE
52#define FALSE 0
53#endif
54
55
56int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
57int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
58int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
59int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
60int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
61int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
62int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
63int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
64int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
65int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
66int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
67int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
68int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
69int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
70int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
71int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
72int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
73int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
74int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
75int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
76int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
77int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
78
79Bool
80ephyrHijackGLXExtension (void)
81{
82 const void *(*dispatch_functions)[2];
83
84 if (!hostx_has_glx ()) {
85 EPHYR_LOG ("host X does not have GLX\n") ;
86 return FALSE ;
87 }
88 EPHYR_LOG ("host X does have GLX\n") ;
89
90 if (!Single_dispatch_info.dispatch_functions) {
91 EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
92 return FALSE ;
93 }
94 /*
95 * hijack some single entry point dispatch functions
96 */
97 dispatch_functions = Single_dispatch_info.dispatch_functions ;
98 EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
99
100 dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
101 dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
102
103 dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
104 dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
105 dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
106 dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
107
108 dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
109 dispatch_functions[X_GLXQueryServerString][1] =
110 ephyrGLXQueryServerStringSwap ;
111
112 dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
113 dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
114
115 dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
116 dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
117
118 dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
119 dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
120
121 dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
122 dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
123
124 dispatch_functions[73][0] = ephyrGLXGetString ;
125 dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
126
127 dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
128 dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
129
130 /*
131 * hijack some vendor priv entry point dispatch functions
132 */
133 dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
134 dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
135 dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
136 EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
137
138 return TRUE ;
139}
140
141/*********************
142 * implementation of
143 * hijacked GLX entry
144 * points
145 ********************/
146
147int
148ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
149{
150 ClientPtr client = a_cl->client;
151 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
152 xGLXQueryVersionReply reply;
153 int major, minor;
154 int res = BadImplementation ;
155
156 EPHYR_LOG ("enter\n") ;
157
158 major = req->majorVersion ;
159 minor = req->minorVersion ;
160
161 if (!ephyrHostGLXQueryVersion (&major, &minor)) {
162 EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
163 goto out ;
164 }
165 EPHYR_LOG ("major:%d, minor:%d\n",
166 major, minor);
167 reply.majorVersion = major ;
168 reply.minorVersion = minor ;
169 reply.length = 0 ;
170 reply.type = X_Reply ;
171 reply.sequenceNumber = client->sequence ;
172
173 if (client->swapped) {
174 __glXSwapQueryVersionReply(client, &reply);
175 } else {
176 WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
177 }
178
179 res = Success ;
180out:
181 EPHYR_LOG ("leave\n") ;
182 return res;
183}
184
185int
186ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
187{
188 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
189 __GLX_DECLARE_SWAP_VARIABLES;
190
191 __GLX_SWAP_SHORT (&req->length);
192 __GLX_SWAP_INT (&req->majorVersion);
193 __GLX_SWAP_INT (&req->minorVersion);
194 return ephyrGLXQueryVersion (a_cl, a_pc) ;
195}
196
197static int
198ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
199 GLbyte *a_pc,
200 Bool a_do_swap)
201{
202 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
203 ClientPtr client = a_cl->client;
204 xGLXGetVisualConfigsReply reply;
205 int32_t *props_buf=NULL, num_visuals=0,
206 num_props=0, res=BadImplementation, i=0,
207 props_per_visual_size=0,
208 props_buf_size=0;
209 __GLX_DECLARE_SWAP_VARIABLES;
210 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
211
212 EPHYR_LOG ("enter\n") ;
213
214 if (!ephyrHostGLXGetVisualConfigs (req->screen,
215 &num_visuals,
216 &num_props,
217 &props_buf_size,
218 &props_buf)) {
219 EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
220 goto out ;
221 }
222 EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
223
224 reply.numVisuals = num_visuals;
225 reply.numProps = num_props;
226 reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
227 reply.type = X_Reply;
228 reply.sequenceNumber = client->sequence;
229
230 if (a_do_swap) {
231 __GLX_SWAP_SHORT(&reply.sequenceNumber);
232 __GLX_SWAP_INT(&reply.length);
233 __GLX_SWAP_INT(&reply.numVisuals);
234 __GLX_SWAP_INT(&reply.numProps);
235 __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
236 }
237 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
238 props_per_visual_size = props_buf_size/num_visuals ;
239 for (i=0; i < num_visuals; i++) {
240 WriteToClient (client,
241 props_per_visual_size,
242 (char*)props_buf +i*props_per_visual_size);
243 }
244 res = Success ;
245
246out:
247 EPHYR_LOG ("leave\n") ;
248 if (props_buf) {
249 xfree (props_buf) ;
250 props_buf = NULL ;
251 }
252 return res ;
253}
254
255static int
256ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
257 GLbyte *a_pc,
258 Bool a_do_swap)
259{
260 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
261 ClientPtr client = a_cl->client;
262 xGLXGetVisualConfigsReply reply;
263 int32_t *props_buf=NULL, num_visuals=0,
264 num_props=0, res=BadImplementation, i=0,
265 props_per_visual_size=0,
266 props_buf_size=0;
267 __GLX_DECLARE_SWAP_VARIABLES;
268 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
269
270 EPHYR_LOG ("enter\n") ;
271
272 if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
273 &num_visuals,
274 &num_props,
275 &props_buf_size,
276 &props_buf)) {
277 EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
278 goto out ;
279 }
280 EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
281
282 reply.numVisuals = num_visuals;
283 reply.numProps = num_props;
284 reply.length = props_buf_size >> 2;
285 reply.type = X_Reply;
286 reply.sequenceNumber = client->sequence;
287
288 if (a_do_swap) {
289 __GLX_SWAP_SHORT(&reply.sequenceNumber);
290 __GLX_SWAP_INT(&reply.length);
291 __GLX_SWAP_INT(&reply.numVisuals);
292 __GLX_SWAP_INT(&reply.numProps);
293 __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
294 }
295 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
296 props_per_visual_size = props_buf_size/num_visuals ;
297 for (i=0; i < num_visuals; i++) {
298 WriteToClient (client,
299 props_per_visual_size,
300 &((char*)props_buf)[i*props_per_visual_size]);
301 }
302 res = Success ;
303
304out:
305 EPHYR_LOG ("leave\n") ;
306 if (props_buf) {
307 xfree (props_buf) ;
308 props_buf = NULL ;
309 }
310 return res ;
311}
312
313int
314ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
315{
316 return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
317}
318
319int
320ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
321{
322 return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
323}
324
325
326int
327ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
328{
329 int res=BadImplementation ;
330 xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
331
332 EPHYR_LOG ("enter\n") ;
333 if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
334 EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
335 goto out ;
336 }
337 res = Success ;
338
339out:
340 EPHYR_LOG ("leave\n") ;
341 return res ;
342}
343
344int
345ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
346{
347 xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
348 __GLX_DECLARE_SWAP_VARIABLES;
349
350 __GLX_SWAP_SHORT (&req->length);
351 __GLX_SWAP_INT (&req->major);
352 __GLX_SWAP_INT (&req->minor);
353 __GLX_SWAP_INT (&req->numbytes);
354
355 return ephyrGLXClientInfo (a_cl, a_pc) ;
356}
357
358int
359ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
360{
361 int res = BadImplementation ;
362 ClientPtr client = a_cl->client;
363 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
364 xGLXQueryServerStringReply reply;
365 char *server_string=NULL ;
366 int length=0 ;
367
368 EPHYR_LOG ("enter\n") ;
369 if (!ephyrHostGLXGetStringFromServer (req->screen,
370 req->name,
371 EPHYR_HOST_GLX_QueryServerString,
372 &server_string)) {
373 EPHYR_LOG_ERROR ("failed to query string from host\n") ;
374 goto out ;
375 }
376 EPHYR_LOG ("string: %s\n", server_string) ;
377 length= strlen (server_string) + 1;
378 reply.type = X_Reply ;
379 reply.sequenceNumber = client->sequence ;
380 reply.length = __GLX_PAD (length) >> 2 ;
381 reply.n = length ;
382
383 WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
384 WriteToClient(client, (int)length, server_string);
385
386 res = Success ;
387
388out:
389 EPHYR_LOG ("leave\n") ;
390 if (server_string) {
391 xfree (server_string) ;
392 server_string = NULL;
393 }
394 return res ;
395}
396
397int
398ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
399{
400 EPHYR_LOG_ERROR ("not yet implemented\n") ;
401 return BadImplementation ;
402}
403
404
405int
406ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
407{
408 return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
409}
410
411int
412ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
413{
414 return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
415}
416
417static int
418ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
419{
420 int res=BadImplementation;
421 EphyrHostWindowAttributes host_w_attrs ;
422 __GLX_DECLARE_SWAP_VARIABLES;
423
424 EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
425 EPHYR_LOG ("enter\n") ;
426
427 if (a_do_swap) {
428 __GLX_SWAP_SHORT(&a_req->length);
429 __GLX_SWAP_INT(&a_req->context);
430 __GLX_SWAP_INT(&a_req->visual);
431 __GLX_SWAP_INT(&a_req->screen);
432 __GLX_SWAP_INT(&a_req->shareList);
433 }
434
435 EPHYR_LOG ("context creation requested. localid:%d, "
436 "screen:%d, visual:%d, direct:%d\n",
437 (int)a_req->context, (int)a_req->screen,
438 (int)a_req->visual, (int)a_req->isDirect) ;
439
440 memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
441 if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
442 &host_w_attrs)) {
443 EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
444 goto out ;
445 }
446
447 EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
448
449 if (!ephyrHostGLXCreateContext (a_req->screen,
450 host_w_attrs.visualid,
451 a_req->context,
452 a_req->shareList,
453 a_req->isDirect)) {
454 EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
455 goto out ;
456 }
457 res = Success;
458out:
459 EPHYR_LOG ("leave\n") ;
460 return res ;
461}
462
463int
464ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
465{
466 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
467
468 return ephyrGLXCreateContextReal (req, FALSE) ;
469}
470
471int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
472{
473 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
474 return ephyrGLXCreateContextReal (req, TRUE) ;
475}
476
477static int
478ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
479 GLbyte *a_pc,
480 Bool a_do_swap)
481{
482 int res=BadImplementation;
483 ClientPtr client = a_cl->client;
484 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
485
486 EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
487 if (!ephyrHostDestroyContext (req->context)) {
488 EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
489 client->errorValue = req->context ;
490 goto out ;
491 }
492 res = Success ;
493
494out:
495 EPHYR_LOG ("leave\n") ;
496 return res ;
497}
498
499int
500ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
501{
502 return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
503}
504
505int
506ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
507{
508 return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
509}
510
511static int
512ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
513{
514 int res=BadImplementation;
515 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
516 xGLXMakeCurrentReply reply ;
517 DrawablePtr drawable=NULL;
518 int rc=0;
519
520 EPHYR_LOG ("enter\n") ;
521 rc = dixLookupDrawable (&drawable,
522 req->drawable,
523 a_cl->client,
524 0,
525 DixReadAccess);
526 EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
527 EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
528 EPHYR_LOG ("screen nummber requested:%d\n",
529 drawable->pScreen->myNum) ;
530
531 memset (&reply, 0, sizeof (reply)) ;
532 if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
533 req->context,
534 req->oldContextTag,
535 (int*)&reply.contextTag)) {
536 EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
537 goto out;
538 }
539 reply.length = 0;
540 reply.type = X_Reply;
541 reply.sequenceNumber = a_cl->client->sequence;
542 if (a_do_swap) {
543 __GLX_DECLARE_SWAP_VARIABLES;
544 __GLX_SWAP_SHORT(&reply.sequenceNumber);
545 __GLX_SWAP_INT(&reply.length);
546 __GLX_SWAP_INT(&reply.contextTag);
547 }
548 WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
549
550 res = Success ;
551out:
552 EPHYR_LOG ("leave\n") ;
553 return res ;
554}
555
556int
557ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
558{
559 return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
560}
561
562int
563ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
564{
565 return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
566}
567
568static int
569ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
570{
571 ClientPtr client=NULL ;
572 int context_tag=0, name=0, res=BadImplementation, length=0 ;
573 char *string=NULL;
574 __GLX_DECLARE_SWAP_VARIABLES;
575
576 EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
577
578 EPHYR_LOG ("enter\n") ;
579
580 client = a_cl->client ;
581
582 if (a_do_swap) {
583 __GLX_SWAP_INT (a_pc + 4);
584 __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
585 }
586 context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
587 a_pc += __GLX_SINGLE_HDR_SIZE;
588 name = *(GLenum*)(a_pc + 0);
589 EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
590 if (!ephyrHostGLXGetStringFromServer (context_tag,
591 name,
592 EPHYR_HOST_GLX_GetString,
593 &string)) {
594 EPHYR_LOG_ERROR ("failed to get string from server\n") ;
595 goto out ;
596 }
597 if (string) {
598 length = strlen (string) + 1;
599 EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
600 } else {
601 EPHYR_LOG ("got string: string (null)\n") ;
602 }
603 __GLX_BEGIN_REPLY (length);
604 __GLX_PUT_SIZE (length);
605 __GLX_SEND_HEADER ();
606 if (a_do_swap) {
607 __GLX_SWAP_REPLY_SIZE ();
608 __GLX_SWAP_REPLY_HEADER ();
609 }
610 WriteToClient (client, length, (char *)string);
611
612 res = Success ;
613out:
614 EPHYR_LOG ("leave\n") ;
615 return res ;
616}
617
618int
619ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
620{
621 return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
622}
623
624int
625ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
626{
627 return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
628}
629
630static int
631ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
632{
633 int res=BadImplementation;
634 xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
635 GLenum int_name ;
636 int value=0 ;
637 GLint answer_buf_room[200];
638 GLint *buf=NULL ;
639
640 EPHYR_LOG ("enter\n") ;
641
642 a_pc += __GLX_SINGLE_HDR_SIZE;
643
644 int_name = *(GLenum*) (a_pc+0) ;
645 if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
646 EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
647 goto out ;
648 }
649 buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
650 answer_buf_room,
651 sizeof (answer_buf_room),
652 4) ;
653
654 if (!buf) {
655 EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
656 res = BadAlloc ;
657 goto out ;
658 }
659 __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
660 res = Success ;
661
662out:
663 EPHYR_LOG ("leave\n") ;
664 return res ;
665}
666
667int
668ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
669{
670 return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
671}
672
673int
674ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
675{
676 return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
677}
678
679static int
680ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
681{
682 int res=BadImplementation;
683 ClientPtr client = a_cl->client;
684 xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
685 xGLXIsDirectReply reply;
686 int is_direct=0 ;
687
688 EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
689
690 EPHYR_LOG ("enter\n") ;
691
692 memset (&reply, 0, sizeof (reply)) ;
693 if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
694 EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
695 goto out ;
696 }
697 reply.isDirect = is_direct ;
698 reply.length = 0;
699 reply.type = X_Reply;
700 reply.sequenceNumber = client->sequence;
701 WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
702 res = Success ;
703
704out:
705 EPHYR_LOG ("leave\n") ;
706 return res ;
707}
708
709int
710ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
711{
712 return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
713}
714
715int
716ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
717{
718 return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
719}
720
721#endif /*XEPHYR_DRI*/
722
diff --git a/hw/kdrive/ephyr/ephyrglxext.h b/hw/kdrive/ephyr/ephyrglxext.h
new file mode 100644
index 000000000..22ea605d7
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrglxext.h
@@ -0,0 +1,35 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifndef __EPHYR_GLXEXT_H__
29#define __EPHYR_GLXEXT_H__
30
31#include <X11/Xdefs.h>
32Bool ephyrHijackGLXExtension (void) ;
33
34#endif /*__EPHYR_GLXEXT_H__*/
35
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
new file mode 100644
index 000000000..5d9a482e8
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -0,0 +1,687 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * a lots of the content of this file has been adapted from the mesa source
26 * code.
27 * Authors:
28 * Dodji Seketeli <dodji@openedhand.com>
29 */
30#ifdef HAVE_CONFIG_H
31#include <kdrive-config.h>
32#endif
33
34#include <X11/Xlibint.h>
35#include <GL/glx.h>
36#include <GL/internal/glcore.h>
37#include <GL/glxproto.h>
38#include <GL/glxint.h>
39#include "ephyrhostglx.h"
40#define _HAVE_XALLOC_DECLS
41#include "ephyrlog.h"
42#include "hostx.h"
43
44#ifdef XEPHYR_DRI
45enum VisualConfRequestType {
46 EPHYR_GET_FB_CONFIG,
47 EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
48 EPHYR_GET_VISUAL_CONFIGS
49
50};
51
52static Bool ephyrHostGLXGetVisualConfigsInternal
53 (enum VisualConfRequestType a_type,
54 int32_t a_screen,
55 int32_t *a_num_visuals,
56 int32_t *a_num_props,
57 int32_t *a_props_buf_size,
58 int32_t **a_props_buf);
59Bool
60ephyrHostGLXGetMajorOpcode (int *a_opcode)
61{
62 Bool is_ok=FALSE ;
63 Display *dpy=hostx_get_display () ;
64 static int opcode ;
65 int first_event_return=0, first_error_return=0;
66
67 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
68 EPHYR_LOG ("enter\n") ;
69 if (!opcode) {
70 if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
71 &first_event_return, &first_error_return)) {
72 EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
73 goto out ;
74 }
75 }
76 *a_opcode = opcode ;
77 is_ok = TRUE ;
78out:
79 EPHYR_LOG ("release\n") ;
80 return is_ok ;
81}
82
83Bool
84ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
85{
86 Bool is_ok = FALSE ;
87 Display *dpy = hostx_get_display () ;
88 int major_opcode=0;
89 xGLXQueryVersionReq *req=NULL;
90 xGLXQueryVersionReply reply;
91
92 EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
93 EPHYR_LOG ("enter\n") ;
94
95 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
96 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
97 goto out ;
98 }
99 EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
100
101 /* Send the glXQueryVersion request */
102 memset (&reply, 0, sizeof (reply)) ;
103 LockDisplay (dpy);
104 GetReq (GLXQueryVersion, req);
105 req->reqType = major_opcode;
106 req->glxCode = X_GLXQueryVersion;
107 req->majorVersion = 2;
108 req->minorVersion = 1;
109 _XReply(dpy, (xReply*) &reply, 0, False);
110 UnlockDisplay (dpy);
111 SyncHandle ();
112
113 *a_major = reply.majorVersion ;
114 *a_minor = reply.minorVersion ;
115
116 EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ;
117
118 is_ok = TRUE ;
119out:
120 EPHYR_LOG ("leave\n") ;
121 return is_ok ;
122}
123
124/**
125 * GLX protocol structure for the ficticious "GXLGenericGetString" request.
126 *
127 * This is a non-existant protocol packet. It just so happens that all of
128 * the real protocol packets used to request a string from the server have
129 * an identical binary layout. The only difference between them is the
130 * meaning of the \c for_whom field and the value of the \c glxCode.
131 * (this has been copied from the mesa source code)
132 */
133typedef struct GLXGenericGetString {
134 CARD8 reqType;
135 CARD8 glxCode;
136 CARD16 length B16;
137 CARD32 for_whom B32;
138 CARD32 name B32;
139} xGLXGenericGetStringReq;
140
141/* These defines are only needed to make the GetReq macro happy.
142 */
143#define sz_xGLXGenericGetStringReq 12
144#define X_GLXGenericGetString 0
145
146Bool
147ephyrHostGLXGetStringFromServer (int a_screen_number,
148 int a_string_name,
149 enum EphyrHostGLXGetStringOps a_op,
150 char **a_string)
151{
152 Bool is_ok=FALSE ;
153 Display *dpy = hostx_get_display () ;
154 xGLXGenericGetStringReq *req=NULL;
155 xGLXSingleReply reply;
156 int length=0, numbytes=0, major_opcode=0, get_string_op=0;
157
158 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
159
160 EPHYR_LOG ("enter\n") ;
161 switch (a_op) {
162 case EPHYR_HOST_GLX_QueryServerString:
163 get_string_op = X_GLXQueryServerString;
164 break ;
165 case EPHYR_HOST_GLX_GetString:
166 get_string_op = X_GLsop_GetString;
167 EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n",
168 a_string_name, a_screen_number) ;
169 break ;
170 default:
171 EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
172 goto out ;
173 }
174
175 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
176 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
177 goto out ;
178 }
179 EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
180
181 LockDisplay (dpy);
182
183 /* All of the GLX protocol requests for getting a string from the server
184 * look the same. The exact meaning of the a_for_whom field is usually
185 * either the screen number (for glXQueryServerString) or the context tag
186 * (for GLXSingle).
187 */
188 GetReq (GLXGenericGetString, req);
189 req->reqType = major_opcode;
190 req->glxCode = get_string_op;
191 req->for_whom = DefaultScreen (dpy);
192 req->name = a_string_name;
193
194 _XReply (dpy, (xReply *)&reply, 0, False);
195
196 length = reply.length * 4;
197 numbytes = reply.size;
198 EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
199
200 *a_string = (char *) Xmalloc (numbytes +1);
201 if (!a_string) {
202 EPHYR_LOG_ERROR ("allocation failed\n") ;
203 goto out;
204 }
205
206 memset (*a_string, 0, numbytes+1) ;
207 if (_XRead (dpy, *a_string, numbytes)) {
208 UnlockDisplay (dpy);
209 SyncHandle ();
210 EPHYR_LOG_ERROR ("read failed\n") ;
211 goto out ;
212 }
213 length -= numbytes;
214 _XEatData (dpy, length) ;
215 UnlockDisplay (dpy);
216 SyncHandle ();
217 EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n",
218 a_string_name, *a_string, numbytes) ;
219
220 is_ok = TRUE ;
221out:
222 EPHYR_LOG ("leave\n") ;
223 return is_ok ;
224}
225
226static Bool
227ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
228 int32_t a_screen,
229 int32_t *a_num_visuals,
230 int32_t *a_num_props,
231 int32_t *a_props_buf_size,
232 int32_t **a_props_buf)
233{
234 Bool is_ok = FALSE ;
235 Display *dpy = hostx_get_display () ;
236 xGLXGetVisualConfigsReq *req;
237 xGLXGetFBConfigsReq *fb_req;
238 xGLXVendorPrivateWithReplyReq *vpreq;
239 xGLXGetFBConfigsSGIXReq *sgi_req;
240 xGLXGetVisualConfigsReply reply;
241 char *server_glx_version=NULL,
242 *server_glx_extensions=NULL ;
243 int j=0,
244 screens=0,
245 major_opcode=0,
246 num_props=0,
247 num_visuals=0,
248 props_buf_size=0,
249 props_per_visual_size=0;
250 int32_t *props_buf=NULL;
251
252 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
253
254 screens = ScreenCount (dpy);
255 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
256 EPHYR_LOG_ERROR ("failed to get opcode\n") ;
257 goto out ;
258 }
259
260 LockDisplay(dpy);
261 switch (a_type) {
262 case EPHYR_GET_FB_CONFIG:
263 GetReq(GLXGetFBConfigs,fb_req);
264 fb_req->reqType = major_opcode;
265 fb_req->glxCode = X_GLXGetFBConfigs;
266 fb_req->screen = DefaultScreen (dpy);
267 break;
268
269 case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
270 GetReqExtra(GLXVendorPrivateWithReply,
271 sz_xGLXGetFBConfigsSGIXReq
272 -
273 sz_xGLXVendorPrivateWithReplyReq,
274 vpreq);
275 sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
276 sgi_req->reqType = major_opcode;
277 sgi_req->glxCode = X_GLXVendorPrivateWithReply;
278 sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
279 sgi_req->screen = DefaultScreen (dpy);
280 break;
281
282 case EPHYR_GET_VISUAL_CONFIGS:
283 GetReq(GLXGetVisualConfigs,req);
284 req->reqType = major_opcode;
285 req->glxCode = X_GLXGetVisualConfigs;
286 req->screen = DefaultScreen (dpy);
287 break;
288 }
289
290 if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
291 EPHYR_LOG_ERROR ("unknown error\n") ;
292 UnlockDisplay(dpy);
293 goto out ;
294 }
295 if (!reply.numVisuals) {
296 EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
297 UnlockDisplay(dpy);
298 goto out ;
299 }
300 num_visuals = reply.numVisuals ;
301
302 /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
303 * FIXME: FBconfigs?
304 */
305 /* Check number of properties */
306 num_props = reply.numProps;
307 if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
308 (num_props > __GLX_MAX_CONFIG_PROPS)) {
309 /* Huh? Not in protocol defined limits. Punt */
310 EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
311 UnlockDisplay(dpy);
312 goto out ;
313 }
314
315 if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
316 num_props *= 2;
317 }
318 props_per_visual_size = num_props * __GLX_SIZE_INT32;
319 props_buf_size = props_per_visual_size * reply.numVisuals;
320 props_buf = malloc (props_buf_size) ;
321 for (j = 0; j < reply.numVisuals; j++) {
322 if (_XRead (dpy,
323 &((char*)props_buf)[j*props_per_visual_size],
324 props_per_visual_size) != Success) {
325 EPHYR_LOG_ERROR ("read failed\n") ;
326 }
327 }
328 UnlockDisplay(dpy);
329
330 *a_num_visuals = num_visuals ;
331 *a_num_props = reply.numProps ;
332 *a_props_buf_size = props_buf_size ;
333 *a_props_buf = props_buf ;
334 is_ok = TRUE ;
335
336out:
337 if (server_glx_version) {
338 XFree (server_glx_version) ;
339 server_glx_version = NULL ;
340 }
341 if (server_glx_extensions) {
342 XFree (server_glx_extensions) ;
343 server_glx_extensions = NULL ;
344 }
345 SyncHandle () ;
346 return is_ok;
347}
348
349Bool
350ephyrHostGLXGetVisualConfigs (int32_t a_screen,
351 int32_t *a_num_visuals,
352 int32_t *a_num_props,
353 int32_t *a_props_buf_size,
354 int32_t **a_props_buf)
355{
356 Bool is_ok = FALSE;
357
358 EPHYR_LOG ("enter\n") ;
359 is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS,
360 a_screen,
361 a_num_visuals,
362 a_num_props,
363 a_props_buf_size,
364 a_props_buf) ;
365
366 EPHYR_LOG ("leave:%d\n", is_ok) ;
367 return is_ok;
368}
369
370Bool
371ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
372 int32_t *a_num_visuals,
373 int32_t *a_num_props,
374 int32_t *a_props_buf_size,
375 int32_t **a_props_buf)
376{
377 Bool is_ok=FALSE ;
378 EPHYR_LOG ("enter\n") ;
379 is_ok = ephyrHostGLXGetVisualConfigsInternal
380 (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
381 a_screen,
382 a_num_visuals,
383 a_num_props,
384 a_props_buf_size,
385 a_props_buf) ;
386 EPHYR_LOG ("leave\n") ;
387 return is_ok ;
388}
389
390Bool
391ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
392 const char* a_extension_list)
393{
394 Bool is_ok = FALSE ;
395 Display *dpy = hostx_get_display () ;
396 xGLXClientInfoReq *req;
397 int size;
398 int32_t major_opcode=0 ;
399
400 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
401
402 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
403 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
404 goto out ;
405 }
406
407 LockDisplay (dpy);
408
409 GetReq (GLXClientInfo,req);
410 req->reqType = major_opcode;
411 req->glxCode = X_GLXClientInfo;
412 req->major = a_major;
413 req->minor = a_minor;
414
415 size = strlen (a_extension_list) + 1;
416 req->length += (size + 3) >> 2;
417 req->numbytes = size;
418 Data (dpy, a_extension_list, size);
419
420 UnlockDisplay(dpy);
421 SyncHandle();
422
423 is_ok=TRUE ;
424
425out:
426 return is_ok ;
427}
428
429Bool
430ephyrHostGLXCreateContext (int a_screen,
431 int a_visual_id,
432 int a_context_id,
433 int a_share_list_ctxt_id,
434 Bool a_direct)
435{
436 Bool is_ok = FALSE;
437 Display *dpy = hostx_get_display ();
438 int major_opcode=0, remote_context_id=0;
439 xGLXCreateContextReq *req;
440
441 EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
442 a_screen, a_visual_id, a_context_id, a_direct) ;
443
444 if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) {
445 EPHYR_LOG_ERROR ("failed to peer the context id %d host X",
446 remote_context_id) ;
447 goto out ;
448 }
449
450 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
451 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
452 goto out ;
453 }
454
455 LockDisplay (dpy) ;
456
457 /* Send the glXCreateContext request */
458 GetReq(GLXCreateContext,req);
459 req->reqType = major_opcode;
460 req->glxCode = X_GLXCreateContext;
461 req->context = remote_context_id;
462 req->visual = a_visual_id;
463 req->screen = DefaultScreen (dpy);
464 req->shareList = a_share_list_ctxt_id;
465 req->isDirect = a_direct;
466
467 UnlockDisplay (dpy);
468 SyncHandle ();
469
470 is_ok = TRUE ;
471
472out:
473 EPHYR_LOG ("leave\n") ;
474 return is_ok ;
475}
476
477Bool
478ephyrHostDestroyContext (int a_ctxt_id)
479{
480 Bool is_ok=FALSE;
481 Display *dpy=hostx_get_display ();
482 int major_opcode=0, remote_ctxt_id=0 ;
483 xGLXDestroyContextReq *req=NULL;
484
485 EPHYR_LOG ("enter:%d\n", a_ctxt_id) ;
486
487 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
488 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
489 goto out ;
490 }
491 if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) {
492 EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
493 goto out ;
494 }
495 EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ;
496
497 LockDisplay (dpy);
498 GetReq (GLXDestroyContext,req);
499 req->reqType = major_opcode;
500 req->glxCode = X_GLXDestroyContext;
501 req->context = remote_ctxt_id;
502 UnlockDisplay (dpy);
503 SyncHandle ();
504
505 is_ok = TRUE ;
506
507out:
508 EPHYR_LOG ("leave\n") ;
509 return is_ok ;
510}
511
512Bool
513ephyrHostGLXMakeCurrent (int a_drawable,
514 int a_glx_ctxt_id,
515 int a_old_ctxt_tag,
516 int *a_ctxt_tag)
517{
518 Bool is_ok=FALSE ;
519 Display *dpy = hostx_get_display () ;
520 int32_t major_opcode=0 ;
521 int remote_glx_ctxt_id=0 ;
522 xGLXMakeCurrentReq *req;
523 xGLXMakeCurrentReply reply;
524
525 EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ;
526
527 EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n",
528 a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ;
529
530 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
531 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
532 goto out ;
533 }
534 if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) {
535 EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
536 goto out ;
537 }
538
539 LockDisplay (dpy);
540
541 GetReq (GLXMakeCurrent,req);
542 req->reqType = major_opcode;
543 req->glxCode = X_GLXMakeCurrent;
544 req->drawable = a_drawable;
545 req->context = remote_glx_ctxt_id;
546 req->oldContextTag = a_old_ctxt_tag;
547
548 memset (&reply, 0, sizeof (reply)) ;
549 if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
550 EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
551 UnlockDisplay (dpy);
552 SyncHandle ();
553 goto out ;
554 }
555 UnlockDisplay (dpy);
556 SyncHandle ();
557 *a_ctxt_tag = reply.contextTag ;
558 EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ;
559 is_ok = TRUE ;
560
561out:
562 EPHYR_LOG ("leave\n") ;
563 return is_ok ;
564}
565
566#define X_GLXSingle 0
567
568#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
569 *((INT8 *) (pc + offset)) = a
570
571#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
572 *((INT16 *) (pc + offset)) = a
573
574#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
575 *((INT32 *) (pc + offset)) = a
576
577#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
578 *((FLOAT32 *) (pc + offset)) = a
579
580#define EPHYR_GLX_SINGLE_READ_XREPLY() \
581 (void) _XReply(dpy, (xReply*) &reply, 0, False)
582
583#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
584 a = (cast) reply.retval
585
586#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
587 a = (GLint) reply.size
588
589#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
590 *p = *(GLbyte *)&reply.pad3;
591
592#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
593 *p = *(GLshort *)&reply.pad3;
594
595#define EPHYR_GLX_SINGLE_GET_LONG(p) \
596 *p = *(GLint *)&reply.pad3;
597
598#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
599 *p = *(GLfloat *)&reply.pad3;
600
601Bool
602ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val)
603{
604 Bool is_ok=FALSE;
605 Display *dpy = hostx_get_display () ;
606 int major_opcode=0, size=0;
607 xGLXSingleReq *req=NULL;
608 xGLXSingleReply reply;
609 unsigned char* pc=NULL ;
610
611 EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ;
612
613 EPHYR_LOG ("enter\n") ;
614 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
615 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
616 goto out ;
617 }
618 LockDisplay (dpy) ;
619 GetReqExtra (GLXSingle, 4, req) ;
620 req->reqType = major_opcode ;
621 req->glxCode = X_GLsop_GetIntegerv ;
622 req->contextTag = a_current_context_tag;
623 pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ;
624 EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ;
625 EPHYR_GLX_SINGLE_READ_XREPLY () ;
626 EPHYR_GLX_SINGLE_GET_SIZE (size) ;
627 if (!size) {
628 UnlockDisplay (dpy) ;
629 SyncHandle () ;
630 EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ;
631 goto out ;
632 }
633 EPHYR_GLX_SINGLE_GET_LONG (a_val) ;
634 UnlockDisplay (dpy) ;
635 SyncHandle () ;
636 is_ok = TRUE ;
637
638out:
639 EPHYR_LOG ("leave\n") ;
640 return is_ok ;
641}
642
643Bool
644ephyrHostIsContextDirect (int a_ctxt_id,
645 int *a_is_direct)
646{
647 Bool is_ok=FALSE;
648 Display *dpy = hostx_get_display () ;
649 xGLXIsDirectReq *req=NULL;
650 xGLXIsDirectReply reply;
651 int major_opcode=0, remote_glx_ctxt_id=0;
652
653 EPHYR_LOG ("enter\n") ;
654 if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
655 EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
656 goto out ;
657 }
658 if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
659 EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
660 goto out ;
661 }
662 memset (&reply, 0, sizeof (reply)) ;
663
664 /* Send the glXIsDirect request */
665 LockDisplay (dpy);
666 GetReq (GLXIsDirect,req);
667 req->reqType = major_opcode;
668 req->glxCode = X_GLXIsDirect;
669 req->context = remote_glx_ctxt_id;
670 if (!_XReply (dpy, (xReply*) &reply, 0, False)) {
671 EPHYR_LOG_ERROR ("fail in reading reply from host\n") ;
672 UnlockDisplay (dpy);
673 SyncHandle ();
674 goto out ;
675 }
676 UnlockDisplay (dpy);
677 SyncHandle ();
678 *a_is_direct = reply.isDirect ;
679 is_ok = TRUE ;
680
681out:
682 EPHYR_LOG ("leave\n") ;
683 return is_ok ;
684}
685
686#endif /*XEPHYR_DRI*/
687
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
new file mode 100644
index 000000000..6db362f30
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostglx.h
@@ -0,0 +1,76 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifndef __EPHYRHOSTGLX_H__
29#define __EPHYRHOSTGLX_H__
30
31enum EphyrHostGLXGetStringOps {
32 EPHYR_HOST_GLX_UNDEF,
33 EPHYR_HOST_GLX_QueryServerString,
34 EPHYR_HOST_GLX_GetString,
35};
36
37Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
38Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
39 int a_string_name,
40 enum EphyrHostGLXGetStringOps a_op,
41 char **a_string) ;
42Bool ephyrHostGLXGetVisualConfigs (int a_screen,
43 int32_t *a_num_visuals,
44 int32_t *a_num_props,
45 int32_t *a_props_buf_size,
46 int32_t **a_props_buf) ;
47Bool
48ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
49 int32_t *a_num_visuals,
50 int32_t *a_num_props,
51 int32_t *a_props_buf_size,
52 int32_t **a_props_buf);
53Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
54Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
55 const char* a_extension_list) ;
56Bool ephyrHostGLXCreateContext (int a_screen,
57 int a_visual_id,
58 int a_context_id,
59 int a_shared_list_ctx_id,
60 Bool a_direct) ;
61
62Bool ephyrHostDestroyContext (int a_ctxt_id) ;
63
64Bool ephyrHostGLXMakeCurrent (int a_drawable, int a_glx_ctxt_id,
65 int a_olg_ctxt_tag, int *a_ctxt_tag) ;
66
67Bool ephyrHostGetIntegerValue (int a_current_context_tag,
68 int a_int,
69 int *a_val) ;
70
71Bool ephyrHostIsContextDirect (int a_ctxt_id,
72 int *a_is_direct) ;
73
74
75#endif /*__EPHYRHOSTGLX_H__*/
76
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.c b/hw/kdrive/ephyr/ephyrhostproxy.c
new file mode 100644
index 000000000..ce3f01852
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostproxy.c
@@ -0,0 +1,94 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28
29#ifdef HAVE_CONFIG_H
30#include <kdrive-config.h>
31#endif
32
33#include <X11/Xlibint.h>
34#define _HAVE_XALLOC_DECLS
35#include "ephyrlog.h"
36#include "ephyrhostproxy.h"
37#include "hostx.h"
38
39/* byte swap a short */
40#define swaps(x, n) { \
41 n = ((char *) (x))[0];\
42 ((char *) (x))[0] = ((char *) (x))[1];\
43 ((char *) (x))[1] = n; }
44
45#define GetXReq(req) \
46 WORD64ALIGN ;\
47 if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
48 _XFlush(dpy);\
49 req = (xReq *)(dpy->last_req = dpy->bufptr);\
50 dpy->bufptr += SIZEOF(xReq);\
51 dpy->request++
52
53
54Bool
55ephyrHostProxyDoForward (pointer a_request_buffer,
56 struct XReply *a_reply,
57 Bool a_do_swap)
58{
59 Bool is_ok = FALSE ;
60 int n=0 ;
61 Display *dpy=hostx_get_display () ;
62 xReq *in_req = (xReq*) a_request_buffer ;
63 xReq *forward_req=NULL ;
64 struct XReply reply ;
65
66 EPHYR_RETURN_VAL_IF_FAIL (in_req && dpy, FALSE) ;
67
68 EPHYR_LOG ("enter\n") ;
69
70 if (a_do_swap) {
71 swaps (&in_req->length, n) ;
72 }
73 EPHYR_LOG ("Req {type:%d, data:%d, length:%d}\n",
74 in_req->reqType, in_req->data, in_req->length) ;
75 GetXReq (forward_req) ;
76 memmove (forward_req, in_req, 4) ;
77
78 if (!_XReply (dpy, (xReply*) &reply, 0, FALSE)) {
79 EPHYR_LOG_ERROR ("failed to get reply\n") ;
80 goto out;
81 }
82 EPHYR_LOG ("XReply{type:%d, foo:%d, seqnum:%d, length:%d}\n",
83 reply.type, reply.foo, reply.sequence_number, reply.length) ;
84
85 if (a_reply) {
86 memmove (a_reply, &reply, sizeof (reply)) ;
87 }
88 is_ok = TRUE ;
89
90out:
91 EPHYR_LOG ("leave\n") ;
92 return is_ok ;
93}
94
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.h b/hw/kdrive/ephyr/ephyrhostproxy.h
new file mode 100644
index 000000000..720c986ff
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostproxy.h
@@ -0,0 +1,51 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28
29#ifndef __EPHYRHOSTPROXY_H__
30#define __EPHYRHOSTPROXY_H__
31
32struct XReply {
33 int8_t type ;/*X_Reply*/
34 int8_t foo;
35 int16_t sequence_number ;
36 int32_t length ;
37 /*following is some data up to 32 bytes lenght*/
38 int32_t pad0 ;
39 int32_t pad1 ;
40 int32_t pad2 ;
41 int32_t pad3 ;
42 int32_t pad4 ;
43 int32_t pad5 ;
44};
45
46Bool
47ephyrHostProxyDoForward (pointer a_request_buffer,
48 struct XReply *a_reply,
49 Bool a_do_swap) ;
50
51#endif /*__EPHYRHOSTPROXY_H__*/
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
new file mode 100644
index 000000000..562c2a4e8
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -0,0 +1,1004 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifdef HAVE_CONFIG_H
29#include <kdrive-config.h>
30#endif
31#include <X11/Xutil.h>
32#include <X11/Xlibint.h>
33#include <X11/extensions/Xvlib.h>
34#include <X11/extensions/Xvproto.h>
35#include <X11/extensions/Xext.h>
36#include <X11/extensions/extutil.h>
37#define _HAVE_XALLOC_DECLS
38
39#include "hostx.h"
40#include "ephyrhostvideo.h"
41#include "ephyrlog.h"
42
43#ifndef TRUE
44#define TRUE 1
45#endif /*TRUE*/
46
47#ifndef FALSE
48#define FALSE 0
49#endif /*FALSE*/
50
51static XExtensionInfo _xv_info_data;
52static XExtensionInfo *xv_info = &_xv_info_data;
53static char *xv_extension_name = XvName;
54static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
55 char * buf, int n);
56static int xv_close_display(Display *dpy, XExtCodes *codes);
57static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
58
59static XExtensionHooks xv_extension_hooks = {
60 NULL, /* create_gc */
61 NULL, /* copy_gc */
62 NULL, /* flush_gc */
63 NULL, /* free_gc */
64 NULL, /* create_font */
65 NULL, /* free_font */
66 xv_close_display, /* close_display */
67 xv_wire_to_event, /* wire_to_event */
68 NULL, /* event_to_wire */
69 NULL, /* error */
70 xv_error_string /* error_string */
71};
72
73
74static char *xv_error_list[] =
75{
76 "BadPort", /* XvBadPort */
77 "BadEncoding", /* XvBadEncoding */
78 "BadControl" /* XvBadControl */
79};
80
81
82#define XvCheckExtension(dpy, i, val) \
83 XextCheckExtension(dpy, i, xv_extension_name, val)
84#define XvGetReq(name, req) \
85 WORD64ALIGN\
86 if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
87 _XFlush(dpy);\
88 req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
89 req->reqType = info->codes->major_opcode;\
90 req->xvReqType = xv_##name; \
91 req->length = (SIZEOF(xv##name##Req))>>2;\
92 dpy->bufptr += SIZEOF(xv##name##Req);\
93 dpy->request++
94
95static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
96
97
98static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
99 xv_extension_name,
100 &xv_extension_hooks,
101 XvNumEvents, NULL)
102
103static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
104 XvNumErrors, xv_error_list)
105
106struct _EphyrHostXVAdaptorArray {
107 XvAdaptorInfo *adaptors ;
108 unsigned int nb_adaptors ;
109};
110
111/*heavily copied from libx11*/
112#define BUFSIZE 2048
113static void
114ephyrHostXVLogXErrorEvent (Display *a_display,
115 XErrorEvent *a_err_event,
116 FILE *a_fp)
117{
118 char buffer[BUFSIZ];
119 char mesg[BUFSIZ];
120 char number[32];
121 const char *mtype = "XlibMessage";
122 register _XExtension *ext = (_XExtension *)NULL;
123 _XExtension *bext = (_XExtension *)NULL;
124 Display *dpy = a_display ;
125
126 XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
127 XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
128 (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
129 XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
130 mesg, BUFSIZ);
131 (void) fprintf(a_fp, mesg, a_err_event->request_code);
132 if (a_err_event->request_code < 128) {
133 sprintf(number, "%d", a_err_event->request_code);
134 XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
135 } else {
136 for (ext = dpy->ext_procs;
137 ext && (ext->codes.major_opcode != a_err_event->request_code);
138 ext = ext->next)
139 ;
140 if (ext)
141 strcpy(buffer, ext->name);
142 else
143 buffer[0] = '\0';
144 }
145 (void) fprintf(a_fp, " (%s)\n", buffer);
146 if (a_err_event->request_code >= 128) {
147 XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
148 mesg, BUFSIZ);
149 fputs(" ", a_fp);
150 (void) fprintf(a_fp, mesg, a_err_event->minor_code);
151 if (ext) {
152 sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
153 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
154 (void) fprintf(a_fp, " (%s)", buffer);
155 }
156 fputs("\n", a_fp);
157 }
158 if (a_err_event->error_code >= 128) {
159 /* kludge, try to find the extension that caused it */
160 buffer[0] = '\0';
161 for (ext = dpy->ext_procs; ext; ext = ext->next) {
162 if (ext->error_string)
163 (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
164 buffer, BUFSIZ);
165 if (buffer[0]) {
166 bext = ext;
167 break;
168 }
169 if (ext->codes.first_error &&
170 ext->codes.first_error < (int)a_err_event->error_code &&
171 (!bext || ext->codes.first_error > bext->codes.first_error))
172 bext = ext;
173 }
174 if (bext)
175 sprintf(buffer, "%s.%d", bext->name,
176 a_err_event->error_code - bext->codes.first_error);
177 else
178 strcpy(buffer, "Value");
179 XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
180 if (mesg[0]) {
181 fputs(" ", a_fp);
182 (void) fprintf(a_fp, mesg, a_err_event->resourceid);
183 fputs("\n", a_fp);
184 }
185 /* let extensions try to print the values */
186 for (ext = dpy->ext_procs; ext; ext = ext->next) {
187 if (ext->error_values)
188 (*ext->error_values)(dpy, a_err_event, a_fp);
189 }
190 } else if ((a_err_event->error_code == BadWindow) ||
191 (a_err_event->error_code == BadPixmap) ||
192 (a_err_event->error_code == BadCursor) ||
193 (a_err_event->error_code == BadFont) ||
194 (a_err_event->error_code == BadDrawable) ||
195 (a_err_event->error_code == BadColor) ||
196 (a_err_event->error_code == BadGC) ||
197 (a_err_event->error_code == BadIDChoice) ||
198 (a_err_event->error_code == BadValue) ||
199 (a_err_event->error_code == BadAtom)) {
200 if (a_err_event->error_code == BadValue)
201 XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
202 mesg, BUFSIZ);
203 else if (a_err_event->error_code == BadAtom)
204 XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
205 mesg, BUFSIZ);
206 else
207 XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
208 mesg, BUFSIZ);
209 fputs(" ", a_fp);
210 (void) fprintf(a_fp, mesg, a_err_event->resourceid);
211 fputs("\n", a_fp);
212 }
213 XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
214 mesg, BUFSIZ);
215 fputs(" ", a_fp);
216 (void) fprintf(a_fp, mesg, a_err_event->serial);
217 XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
218 mesg, BUFSIZ);
219 fputs("\n ", a_fp);
220 (void) fprintf(a_fp, mesg, dpy->request);
221 fputs("\n", a_fp);
222}
223
224static int
225ephyrHostXVErrorHandler (Display *a_display,
226 XErrorEvent *a_error_event)
227{
228 EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
229 ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
230 return Success ;
231}
232
233void
234ephyrHostXVInit (void)
235{
236 static Bool s_initialized ;
237
238 if (s_initialized)
239 return ;
240 XSetErrorHandler (ephyrHostXVErrorHandler) ;
241 s_initialized = TRUE ;
242}
243
244Bool
245ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
246{
247 EphyrHostXVAdaptorArray *result=NULL ;
248 int ret=0 ;
249 Bool is_ok=FALSE ;
250
251 EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
252
253 EPHYR_LOG ("enter\n") ;
254
255 result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
256 if (!result)
257 goto out ;
258
259 ret = XvQueryAdaptors (hostx_get_display (),
260 DefaultRootWindow (hostx_get_display ()),
261 &result->nb_adaptors,
262 &result->adaptors) ;
263 if (ret != Success) {
264 EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
265 goto out ;
266 }
267 *a_adaptors = result ;
268 is_ok = TRUE ;
269
270out:
271 EPHYR_LOG ("leave\n") ;
272 return is_ok ;
273}
274
275void
276ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
277{
278 if (!a_adaptors)
279 return ;
280 if (a_adaptors->adaptors) {
281 XvFreeAdaptorInfo (a_adaptors->adaptors) ;
282 a_adaptors->adaptors = NULL ;
283 a_adaptors->nb_adaptors = 0 ;
284 }
285 XFree (a_adaptors) ;
286}
287
288int
289ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
290{
291 EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
292 return a_this->nb_adaptors ;
293}
294
295EphyrHostXVAdaptor*
296ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
297 int a_index)
298{
299 EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
300
301 if (a_index >= a_this->nb_adaptors)
302 return NULL ;
303 return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
304}
305
306char
307ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
308{
309 EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
310 return ((XvAdaptorInfo*)a_this)->type ;
311}
312
313const char*
314ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
315{
316 EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
317
318 return ((XvAdaptorInfo*)a_this)->name ;
319}
320
321EphyrHostVideoFormat*
322ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
323 int *a_nb_formats)
324{
325 EphyrHostVideoFormat *formats=NULL ;
326 int nb_formats=0, i=0 ;
327 XVisualInfo *visual_info, visual_info_template ;
328 int nb_visual_info ;
329
330 EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
331
332 nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
333 formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
334 for (i=0; i < nb_formats; i++) {
335 memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
336 visual_info_template.visualid =
337 ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
338 visual_info = XGetVisualInfo (hostx_get_display (),
339 VisualIDMask,
340 &visual_info_template,
341 &nb_visual_info) ;
342 formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
343 formats[i].visual_class = visual_info->class ;
344 XFree (visual_info) ;
345 }
346 if (a_nb_formats)
347 *a_nb_formats = nb_formats ;
348 return formats ;
349}
350
351int
352ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
353{
354 EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
355
356 return ((XvAdaptorInfo*)a_this)->num_ports ;
357}
358
359int
360ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
361{
362 EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
363
364 return ((XvAdaptorInfo*)a_this)->base_id ;
365}
366
367Bool
368ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
369 Bool *a_result)
370{
371 EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
372
373 if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
374 *a_result = TRUE ;
375 else
376 *a_result = FALSE ;
377 return TRUE ;
378}
379
380Bool
381ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
382 Bool *a_result)
383{
384 if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
385 *a_result = TRUE ;
386 else
387 *a_result = FALSE ;
388 return TRUE ;
389}
390
391Bool
392ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
393 Bool *a_result)
394{
395 EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
396
397 if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
398 *a_result = TRUE ;
399 else
400 *a_result = FALSE ;
401 return TRUE ;
402}
403
404Bool
405ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
406 Bool *a_result)
407{
408 EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
409
410 if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
411 *a_result = TRUE ;
412 else
413 *a_result = FALSE ;
414 return TRUE ;
415}
416
417Bool
418ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
419 Bool *a_result)
420{
421 EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
422
423 if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
424 *a_result = TRUE ;
425 else
426 *a_result = FALSE ;
427 return TRUE ;
428}
429
430Bool
431ephyrHostXVQueryEncodings (int a_port_id,
432 EphyrHostEncoding **a_encodings,
433 unsigned int *a_num_encodings)
434{
435 EphyrHostEncoding *encodings=NULL ;
436 XvEncodingInfo *encoding_info=NULL ;
437 unsigned int num_encodings=0, i;
438 int ret=0 ;
439
440 EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
441
442 ret = XvQueryEncodings (hostx_get_display (),
443 a_port_id,
444 &num_encodings,
445 &encoding_info) ;
446 if (num_encodings && encoding_info) {
447 encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
448 for (i=0; i<num_encodings; i++) {
449 encodings[i].id = encoding_info[i].encoding_id ;
450 encodings[i].name = strdup (encoding_info[i].name) ;
451 encodings[i].width = encoding_info[i].width ;
452 encodings[i].height = encoding_info[i].height ;
453 encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
454 encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
455 }
456 }
457 if (encoding_info) {
458 XvFreeEncodingInfo (encoding_info) ;
459 encoding_info = NULL ;
460 }
461 *a_encodings = encodings ;
462 *a_num_encodings = num_encodings ;
463
464 if (ret != Success)
465 return FALSE ;
466 return TRUE ;
467}
468
469void
470ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
471 int a_num_encodings)
472{
473 int i=0 ;
474
475 if (!a_encodings)
476 return ;
477 for (i=0; i < a_num_encodings; i++) {
478 if (a_encodings[i].name) {
479 xfree (a_encodings[i].name) ;
480 a_encodings[i].name = NULL ;
481 }
482 }
483 xfree (a_encodings) ;
484}
485
486void
487ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
488{
489 if (!a_attributes)
490 return ;
491 XFree (a_attributes) ;
492}
493
494Bool
495ephyrHostXVQueryPortAttributes (int a_port_id,
496 EphyrHostAttribute **a_attributes,
497 int *a_num_attributes)
498{
499 EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
500
501 *a_attributes =
502 (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
503 a_port_id,
504 a_num_attributes);
505
506 return TRUE ;
507}
508
509Bool
510ephyrHostXVQueryImageFormats (int a_port_id,
511 EphyrHostImageFormat **a_formats,
512 int *a_num_format)
513{
514 XvImageFormatValues *result=NULL ;
515
516 EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
517
518 result = XvListImageFormats (hostx_get_display (),
519 a_port_id,
520 a_num_format) ;
521 *a_formats = (EphyrHostImageFormat*) result ;
522 return TRUE ;
523
524}
525
526Bool
527ephyrHostXVSetPortAttribute (int a_port_id,
528 int a_atom,
529 int a_attr_value)
530{
531 int res=Success ;
532
533 EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
534 a_atom,
535 XGetAtomName (hostx_get_display (), a_atom),
536 a_attr_value) ;
537
538 res = XvSetPortAttribute (hostx_get_display (),
539 a_port_id,
540 a_atom,
541 a_attr_value) ;
542 if (res != Success) {
543 EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
544 return FALSE ;
545 }
546 XFlush (hostx_get_display ()) ;
547 EPHYR_LOG ("leave\n") ;
548
549 return TRUE ;
550}
551
552Bool
553ephyrHostXVGetPortAttribute (int a_port_id,
554 int a_atom,
555 int *a_attr_value)
556{
557 int res=Success ;
558 Bool ret=FALSE ;
559
560 EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
561
562 EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
563 a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
564
565 res = XvGetPortAttribute (hostx_get_display (),
566 a_port_id,
567 a_atom,
568 a_attr_value) ;
569 if (res != Success) {
570 EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
571 goto out ;
572 }
573 EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
574
575 ret = TRUE ;
576
577out:
578 EPHYR_LOG ("leave\n") ;
579 return ret ;
580}
581
582Bool
583ephyrHostXVQueryBestSize (int a_port_id,
584 Bool a_motion,
585 unsigned int a_frame_w,
586 unsigned int a_frame_h,
587 unsigned int a_drw_w,
588 unsigned int a_drw_h,
589 unsigned int *a_actual_w,
590 unsigned int *a_actual_h)
591{
592 int res=0 ;
593 Bool is_ok=FALSE ;
594
595 EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
596
597 EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
598 a_frame_w, a_frame_h,
599 a_drw_w, a_drw_h) ;
600
601 res = XvQueryBestSize (hostx_get_display (),
602 a_port_id,
603 a_motion,
604 a_frame_w, a_frame_h,
605 a_drw_w, a_drw_h,
606 a_actual_w, a_actual_h) ;
607 if (res != Success) {
608 EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
609 goto out ;
610 }
611 XSync (hostx_get_display (), FALSE) ;
612
613 EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
614 is_ok = TRUE ;
615
616out:
617 EPHYR_LOG ("leave\n") ;
618 return is_ok ;
619}
620
621static Bool
622xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
623{
624 XExtDisplayInfo *info = xv_find_display (dpy);
625 XvEvent *re = (XvEvent *)host;
626 xvEvent *event = (xvEvent *)wire;
627
628 XvCheckExtension(dpy, info, False);
629
630 switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
631 case XvVideoNotify:
632 re->xvvideo.type = event->u.u.type & 0x7f;
633 re->xvvideo.serial =
634 _XSetLastRequestRead(dpy, (xGenericReply *)event);
635 re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
636 re->xvvideo.display = dpy;
637 re->xvvideo.time = event->u.videoNotify.time;
638 re->xvvideo.reason = event->u.videoNotify.reason;
639 re->xvvideo.drawable = event->u.videoNotify.drawable;
640 re->xvvideo.port_id = event->u.videoNotify.port;
641 break;
642 case XvPortNotify:
643 re->xvport.type = event->u.u.type & 0x7f;
644 re->xvport.serial =
645 _XSetLastRequestRead(dpy, (xGenericReply *)event);
646 re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
647 re->xvport.display = dpy;
648 re->xvport.time = event->u.portNotify.time;
649 re->xvport.port_id = event->u.portNotify.port;
650 re->xvport.attribute = event->u.portNotify.attribute;
651 re->xvport.value = event->u.portNotify.value;
652 break;
653 default:
654 return False;
655 }
656
657 return True ;
658}
659
660Bool
661ephyrHostXVQueryImageAttributes (int a_port_id,
662 int a_image_id /*image fourcc code*/,
663 unsigned short *a_width,
664 unsigned short *a_height,
665 int *a_image_size,
666 int *a_pitches,
667 int *a_offsets)
668{
669 Display *dpy = hostx_get_display () ;
670 Bool ret=FALSE ;
671 XExtDisplayInfo *info = xv_find_display (dpy);
672 xvQueryImageAttributesReq *req=NULL;
673 xvQueryImageAttributesReply rep;
674
675 EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
676 EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
677 EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
678
679 XvCheckExtension (dpy, info, FALSE);
680
681 LockDisplay (dpy);
682
683 XvGetReq (QueryImageAttributes, req);
684 req->id = a_image_id;
685 req->port = a_port_id;
686 req->width = *a_width;
687 req->height = *a_height;
688 /*
689 * read the reply
690 */
691 if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
692 EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
693 goto out ;
694 }
695 if (a_pitches && a_offsets) {
696 _XRead (dpy,
697 (char*)a_pitches,
698 rep.num_planes << 2);
699 _XRead (dpy,
700 (char*)a_offsets,
701 rep.num_planes << 2);
702 } else {
703 _XEatData(dpy, rep.length << 2);
704 }
705 *a_width = rep.width ;
706 *a_height = rep.height ;
707 *a_image_size = rep.data_size ;
708
709 ret = TRUE ;
710
711out:
712 UnlockDisplay (dpy) ;
713 SyncHandle ();
714 return ret ;
715}
716
717Bool
718ephyrHostGetAtom (const char* a_name,
719 Bool a_create_if_not_exists,
720 int *a_atom)
721{
722 int atom=None ;
723
724 EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
725
726 atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
727 if (atom == None) {
728 return FALSE ;
729 }
730 *a_atom = atom ;
731 return TRUE ;
732}
733
734char*
735ephyrHostGetAtomName (int a_atom)
736{
737 return XGetAtomName (hostx_get_display (), a_atom) ;
738}
739
740void
741ephyrHostFree (void *a_pointer)
742{
743 if (a_pointer)
744 XFree (a_pointer) ;
745}
746
747Bool
748ephyrHostXVPutImage (int a_screen_num,
749 int a_port_id,
750 int a_image_id,
751 int a_drw_x,
752 int a_drw_y,
753 int a_drw_w,
754 int a_drw_h,
755 int a_src_x,
756 int a_src_y,
757 int a_src_w,
758 int a_src_h,
759 int a_image_width,
760 int a_image_height,
761 unsigned char *a_buf,
762 EphyrHostBox *a_clip_rects,
763 int a_clip_rect_nums )
764{
765 Bool is_ok=TRUE ;
766 XvImage *xv_image=NULL ;
767 GC gc=0 ;
768 XGCValues gc_values;
769 Display *dpy = hostx_get_display () ;
770 XRectangle *rects=NULL ;
771 int res = 0 ;
772
773 EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
774
775 EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
776
777 memset (&gc_values, 0, sizeof (gc_values)) ;
778 gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
779 if (!gc) {
780 EPHYR_LOG_ERROR ("failed to create gc \n") ;
781 goto out ;
782 }
783 xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
784 a_port_id, a_image_id,
785 NULL, a_image_width, a_image_height) ;
786 if (!xv_image) {
787 EPHYR_LOG_ERROR ("failed to create image\n") ;
788 goto out ;
789 }
790 xv_image->data = (char*)a_buf ;
791 if (a_clip_rect_nums) {
792 int i=0 ;
793 rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
794 for (i=0; i < a_clip_rect_nums; i++) {
795 rects[i].x = a_clip_rects[i].x1 ;
796 rects[i].y = a_clip_rects[i].y1 ;
797 rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
798 rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
799 EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
800 rects[i].x, rects[i].y,
801 rects[i].width, rects[i].height) ;
802 }
803 XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
804 /*this always returns 1*/
805 }
806 res = XvPutImage (dpy, a_port_id,
807 hostx_get_window (a_screen_num),
808 gc, xv_image,
809 a_src_x, a_src_y, a_src_w, a_src_h,
810 a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
811 if (res != Success) {
812 EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
813 goto out ;
814 }
815 is_ok = TRUE ;
816
817out:
818 if (xv_image) {
819 XFree (xv_image) ;
820 xv_image = NULL ;
821 }
822 if (gc) {
823 XFreeGC (dpy, gc) ;
824 gc = NULL ;
825 }
826 if (rects) {
827 free (rects) ;
828 rects = NULL ;
829 }
830 EPHYR_LOG ("leave\n") ;
831 return is_ok ;
832}
833
834Bool
835ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
836 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
837 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
838{
839 Bool is_ok=FALSE ;
840 int res=FALSE ;
841 GC gc=0 ;
842 XGCValues gc_values;
843 Display *dpy=hostx_get_display () ;
844
845 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
846
847 gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
848 if (!gc) {
849 EPHYR_LOG_ERROR ("failed to create gc \n") ;
850 goto out ;
851 }
852 res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
853 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
854 a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
855
856 if (res != Success) {
857 EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
858 goto out ;
859 }
860
861 is_ok = TRUE ;
862
863out:
864 if (gc) {
865 XFreeGC (dpy, gc) ;
866 gc = NULL ;
867 }
868 return is_ok ;
869}
870
871Bool
872ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
873 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
874 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
875{
876 Bool is_ok=FALSE ;
877 int res=FALSE ;
878 GC gc=0 ;
879 XGCValues gc_values;
880 Display *dpy=hostx_get_display () ;
881
882 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
883
884 gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
885 if (!gc) {
886 EPHYR_LOG_ERROR ("failed to create gc \n") ;
887 goto out ;
888 }
889 res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
890 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
891 a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
892
893 if (res != Success) {
894 EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
895 goto out ;
896 }
897
898 is_ok = TRUE ;
899
900out:
901 if (gc) {
902 XFreeGC (dpy, gc) ;
903 gc = NULL ;
904 }
905 return is_ok ;
906}
907
908Bool
909ephyrHostXVPutStill (int a_screen_num, int a_port_id,
910 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
911 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
912{
913 Bool is_ok=FALSE ;
914 int res=FALSE ;
915 GC gc=0 ;
916 XGCValues gc_values;
917 Display *dpy=hostx_get_display () ;
918
919 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
920
921 gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
922 if (!gc) {
923 EPHYR_LOG_ERROR ("failed to create gc \n") ;
924 goto out ;
925 }
926 res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
927 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
928 a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
929
930 if (res != Success) {
931 EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
932 goto out ;
933 }
934
935 is_ok = TRUE ;
936
937out:
938 if (gc) {
939 XFreeGC (dpy, gc) ;
940 gc = NULL ;
941 }
942 return is_ok ;
943}
944
945Bool
946ephyrHostXVGetStill (int a_screen_num, int a_port_id,
947 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
948 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
949{
950 Bool is_ok=FALSE ;
951 int res=FALSE ;
952 GC gc=0 ;
953 XGCValues gc_values;
954 Display *dpy=hostx_get_display () ;
955
956 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
957
958 gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
959 if (!gc) {
960 EPHYR_LOG_ERROR ("failed to create gc \n") ;
961 goto out ;
962 }
963 res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
964 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
965 a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
966
967 if (res != Success) {
968 EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
969 goto out ;
970 }
971
972 is_ok = TRUE ;
973
974out:
975 if (gc) {
976 XFreeGC (dpy, gc) ;
977 gc = NULL ;
978 }
979 return is_ok ;
980}
981
982Bool
983ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
984{
985 int ret=0 ;
986 Bool is_ok=FALSE ;
987 Display *dpy = hostx_get_display () ;
988
989 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
990
991 EPHYR_LOG ("enter\n") ;
992
993 ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
994 if (ret != Success) {
995 EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
996 goto out ;
997 }
998 is_ok = TRUE ;
999
1000out:
1001 EPHYR_LOG ("leave\n") ;
1002 return is_ok ;
1003}
1004
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
new file mode 100644
index 000000000..05ee38a03
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -0,0 +1,238 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifndef __EPHYRHOSTVIDEO_H__
29#define __EPHYRHOSTVIDEO_H__
30
31typedef void* EphyrHostXVAdaptor ;
32typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray ;
33
34typedef struct _EphyrHostVideoFormat {
35 char depth ;
36 short visual_class;
37} EphyrHostVideoFormat ;
38
39typedef struct _EphyrHostRational {
40 int numerator ;
41 int denominator ;
42} EphyrHostRational;
43
44typedef struct _EphyrHostEncoding {
45 int id ;
46 char *name ;
47 unsigned short width, height ;
48 EphyrHostRational rate ;
49} EphyrHostEncoding ;
50
51typedef struct _EphyrHostAttribute {
52 int flags;
53 int min_value;
54 int max_value;
55 char *name;
56} EphyrHostAttribute ;
57
58typedef struct _EphyrHostImageFormat {
59 int id; /* Unique descriptor for the format */
60 int type; /* XvRGB, XvYUV */
61 int byte_order; /* LSBFirst, MSBFirst */
62 char guid[16]; /* Globally Unique IDentifier */
63 int bits_per_pixel;
64 int format; /* XvPacked, XvPlanar */
65 int num_planes;
66
67 /* for RGB formats only */
68 int depth;
69 unsigned int red_mask;
70 unsigned int green_mask;
71 unsigned int blue_mask;
72
73 /* for YUV formats only */
74 unsigned int y_sample_bits;
75 unsigned int u_sample_bits;
76 unsigned int v_sample_bits;
77 unsigned int horz_y_period;
78 unsigned int horz_u_period;
79 unsigned int horz_v_period;
80 unsigned int vert_y_period;
81 unsigned int vert_u_period;
82 unsigned int vert_v_period;
83 char component_order[32]; /* eg. UYVY */
84 int scanline_order; /* XvTopToBottom, XvBottomToTop */
85} EphyrHostImageFormat ;
86
87typedef struct {
88 unsigned short x1, y1, x2, y2 ;
89} EphyrHostBox ;
90
91void ephyrHostXVInit (void) ;
92
93void ephyrHostFree (void *a_pointer) ;
94
95/*
96 * host adaptor array
97 */
98Bool ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
99void ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
100int ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
101EphyrHostXVAdaptor* ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
102 int a_index) ;
103
104/*
105 * host adaptor
106 */
107
108char ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
109const char* ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
110EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats
111 (const EphyrHostXVAdaptor *a_this,
112 int *a_nb_formats) ;
113int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
114int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
115
116Bool ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
117 Bool *a_result) ;
118Bool ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
119 Bool *a_result) ;
120Bool ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
121 Bool *a_result) ;
122Bool ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
123 Bool *a_result) ;
124Bool ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
125 Bool *a_result) ;
126
127/*
128 * encoding
129 */
130Bool ephyrHostXVQueryEncodings (int a_port_id,
131 EphyrHostEncoding **a_encodings,
132 unsigned int *a_num_encodings) ;
133
134void ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
135 int a_num_encodings) ;
136
137/*
138 * attribute
139 */
140Bool ephyrHostXVQueryPortAttributes (int a_port_id,
141 EphyrHostAttribute **a_attributes,
142 int *a_num_attributes) ;
143
144void ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
145/*
146 * image format
147 */
148
149Bool ephyrHostXVQueryImageFormats (int a_port_id,
150 EphyrHostImageFormat **a_formats,
151 int *a_num_format) ;
152/*
153 * Port Attribute Get/Set
154 */
155Bool ephyrHostXVSetPortAttribute (int a_port_id,
156 int a_atom,
157 int a_attr_value) ;
158Bool ephyrHostXVGetPortAttribute (int a_port_id,
159 int a_atom,
160 int *a_attr_value) ;
161/*
162 *size query
163 */
164Bool ephyrHostXVQueryBestSize (int a_port_id,
165 Bool a_motion,
166 unsigned int a_frame_w,
167 unsigned int a_frame_h,
168 unsigned int a_drw_w,
169 unsigned int a_drw_h,
170 unsigned int *a_actual_w,
171 unsigned int *a_actual_h) ;
172
173Bool ephyrHostXVQueryImageAttributes (int a_port_id,
174 int a_image_id /*image fourcc code*/,
175 unsigned short *a_width,
176 unsigned short *a_height,
177 int *a_image_size,
178 int *a_pitches,
179 int *a_offsets) ;
180/*
181 * atom
182 */
183Bool ephyrHostGetAtom (const char* a_name,
184 Bool a_create_if_not_exists,
185 int *a_atom) ;
186char* ephyrHostGetAtomName (int a_atom) ;
187
188/*
189 *PutImage
190 * (ignore clipping for now)
191 */
192Bool ephyrHostXVPutImage (int a_screen_num,
193 int a_port_id,
194 int a_image_id,
195 int a_drw_x,
196 int a_drw_y,
197 int a_drw_w,
198 int a_drw_h,
199 int a_src_x,
200 int a_src_y,
201 int a_src_w,
202 int a_src_h,
203 int a_image_width,
204 int a_image_height,
205 unsigned char *a_buf,
206 EphyrHostBox *a_clip_rects,
207 int a_clip_rect_nums) ;
208
209/*
210 * Putvideo/PutStill/GetVideo
211 */
212Bool ephyrHostXVPutVideo (int a_screen_num,
213 int a_port_id,
214 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
215 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
216
217Bool ephyrHostXVGetVideo (int a_screen_num,
218 int a_port_id,
219 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
220 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
221
222Bool ephyrHostXVPutStill (int a_screen_num,
223 int a_port_id,
224 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
225 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
226
227Bool ephyrHostXVGetStill (int a_screen_num,
228 int a_port_id,
229 int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
230 int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
231
232/*
233 * StopVideo
234 */
235Bool ephyrHostXVStopVideo (int a_screen_num, int a_port_id) ;
236
237#endif /*__EPHYRHOSTVIDEO_H__*/
238
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 687460952..cc7a36700 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -27,11 +27,15 @@
27#include <kdrive-config.h> 27#include <kdrive-config.h>
28#endif 28#endif
29#include "ephyr.h" 29#include "ephyr.h"
30#include "ephyrlog.h"
30 31
31extern Window EphyrPreExistingHostWin; 32extern Window EphyrPreExistingHostWin;
32extern Bool EphyrWantGrayScale; 33extern Bool EphyrWantGrayScale;
33extern Bool kdHasPointer; 34extern Bool kdHasPointer;
34extern Bool kdHasKbd; 35extern Bool kdHasKbd;
36extern Bool ephyrNoDRI;
37extern Bool ephyrNoXV;
38extern Bool noGlxVisualInit;
35 39
36void processScreenArg (char *screen_size, char *parent_id) ; 40void processScreenArg (char *screen_size, char *parent_id) ;
37 41
@@ -92,11 +96,14 @@ ddxUseMsg (void)
92 KdUseMsg(); 96 KdUseMsg();
93 97
94 ErrorF("\nXephyr Option Usage:\n"); 98 ErrorF("\nXephyr Option Usage:\n");
95 ErrorF("-parent XID Use existing window as Xephyr root win\n"); 99 ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
96 ErrorF("-host-cursor Re-use exisiting X host server cursor\n"); 100 ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
97 ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); 101 ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
98 ErrorF("-grayscale Simulate 8bit grayscale\n"); 102 ErrorF("-grayscale Simulate 8bit grayscale\n");
99 ErrorF("-fakexa Simulate acceleration using software rendering\n"); 103 ErrorF("-fakexa Simulate acceleration using software rendering\n");
104 ErrorF("-verbosity <level> Set log verbosity level\n");
105 ErrorF("-nodri do not use DRI\n");
106 ErrorF("-noxv do not use XV\n");
100 ErrorF("\n"); 107 ErrorF("\n");
101 108
102 exit(1); 109 exit(1);
@@ -137,6 +144,8 @@ ddxProcessArgument (int argc, char **argv, int i)
137{ 144{
138 EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] ); 145 EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
139 146
147 noGlxVisualInit = TRUE ;
148
140 if (!strcmp (argv[i], "-parent")) 149 if (!strcmp (argv[i], "-parent"))
141 { 150 {
142 if(i+1 < argc) 151 if(i+1 < argc)
@@ -182,6 +191,34 @@ ddxProcessArgument (int argc, char **argv, int i)
182 ephyrFuncs.finiAccel = ephyrDrawFini; 191 ephyrFuncs.finiAccel = ephyrDrawFini;
183 return 1; 192 return 1;
184 } 193 }
194 else if (!strcmp (argv[i], "-verbosity"))
195 {
196 if(i+1 < argc && argv[i+1][0] != '-')
197 {
198 int verbosity=atoi (argv[i+1]) ;
199 LogSetParameter (XLOG_VERBOSITY, verbosity) ;
200 EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
201 return 2 ;
202 }
203 else
204 {
205 UseMsg() ;
206 exit(1) ;
207 }
208 }
209 else if (!strcmp (argv[i], "-nodri"))
210 {
211 noGlxVisualInit = FALSE ;
212 ephyrNoDRI = TRUE ;
213 EPHYR_LOG ("no direct rendering enabled\n") ;
214 return 1 ;
215 }
216 else if (!strcmp (argv[i], "-noxv"))
217 {
218 ephyrNoXV = TRUE ;
219 EPHYR_LOG ("no XVideo enabled\n") ;
220 return 1 ;
221 }
185 else if (argv[i][0] == ':') 222 else if (argv[i][0] == ':')
186 { 223 {
187 hostx_set_display_name(argv[i]); 224 hostx_set_display_name(argv[i]);
diff --git a/hw/kdrive/ephyr/ephyrlog.h b/hw/kdrive/ephyr/ephyrlog.h
new file mode 100644
index 000000000..4c6435edd
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrlog.h
@@ -0,0 +1,67 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifndef __EPHYRLOG_H__
29#define __EPHYRLOG_H__
30
31#include <assert.h>
32#include "os.h"
33
34#ifdef NDEBUG
35/*we are not in debug mode*/
36#define EPHYR_LOG
37#define EPHYR_LOG_ERROR
38#endif /*NDEBUG*/
39
40#define ERROR_LOG_LEVEL 3
41#define INFO_LOG_LEVEL 4
42
43#ifndef EPHYR_LOG
44#define EPHYR_LOG(...) \
45LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\
46 __FILE__, __LINE__, __func__) ; \
47LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__)
48#endif /*nomadik_log*/
49
50#ifndef EPHYR_LOG_ERROR
51#define EPHYR_LOG_ERROR(...) \
52LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\
53 __FILE__, __LINE__, __func__) ; \
54LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__)
55#endif /*EPHYR_LOG_ERROR*/
56
57#ifndef EPHYR_RETURN_IF_FAIL
58#define EPHYR_RETURN_IF_FAIL(cond) \
59if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return;}
60#endif /*nomadik_return_if_fail*/
61
62#ifndef EPHYR_RETURN_VAL_IF_FAIL
63#define EPHYR_RETURN_VAL_IF_FAIL(cond,val) \
64if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return val;}
65#endif /*nomadik_return_val_if_fail*/
66
67#endif /*__EPHYRLOG_H__*/
diff --git a/hw/kdrive/ephyr/ephyrproxyext.c b/hw/kdrive/ephyr/ephyrproxyext.c
new file mode 100644
index 000000000..0c070f4c7
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrproxyext.c
@@ -0,0 +1,119 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28
29/*
30 * \file
31 * This file defines a proxy extension that forwards requests.
32 * When a request to extension FOO is sent to Xephyr, that request is forwared
33 * to the host X, without even trying to know what the request means.
34 */
35
36#ifdef HAVE_CONFIG_H
37#include <kdrive-config.h>
38#endif
39
40#include "misc.h"
41#include "dixstruct.h"
42#include "extnsionst.h"
43#include "ephyrproxyext.h"
44#define _HAVE_XALLOC_DECLS
45#include "ephyrlog.h"
46#include "ephyrhostproxy.h"
47#include "hostx.h"
48
49static Bool ephyrProxyGetHostExtensionInfo (const char *a_ext_name,
50 int *a_major_opcode,
51 int *a_first_event,
52 int *a_first_error) ;
53
54static int ephyrProxyProcDispatch (ClientPtr client) ;
55
56static Bool
57ephyrProxyGetHostExtensionInfo (const char *a_ext_name,
58 int *a_major_opcode,
59 int *a_first_event,
60 int *a_first_error)
61{
62 return hostx_get_extension_info (a_ext_name, a_major_opcode,
63 a_first_event, a_first_error) ;
64}
65
66static int
67ephyrProxyProcDispatch (ClientPtr a_client)
68{
69 int res=BadImplementation ;
70 struct XReply reply ;
71
72 if (!ephyrHostProxyDoForward (a_client->requestBuffer, &reply, FALSE)) {
73 EPHYR_LOG_ERROR ("forwarding failed\n") ;
74 goto out ;
75 }
76 reply.sequence_number = a_client->sequence;
77 res = Success ;
78
79 WriteToClient(a_client, 32, (char *)&reply);
80
81out:
82 return res ;
83}
84
85static void
86ephyrProxyProcReset (ExtensionEntry *a_entry)
87{
88}
89
90Bool
91ephyrProxyExtensionInit (const char *a_extension_name)
92{
93 Bool is_ok = FALSE ;
94 int major_opcode=0, first_event=0, first_error=0;
95 ExtensionEntry *ext=NULL ;
96
97 if (!ephyrProxyGetHostExtensionInfo (a_extension_name,
98 &major_opcode,
99 &first_event,
100 &first_error)) {
101 EPHYR_LOG ("failed to query extension %s from host\n", a_extension_name) ;
102 goto out;
103 }
104 ext = AddExtension ((char*)a_extension_name, 0, 0,
105 ephyrProxyProcDispatch,
106 ephyrProxyProcDispatch,
107 ephyrProxyProcReset,
108 StandardMinorOpcode) ;
109 if (!ext) {
110 EPHYR_LOG_ERROR ("failed to add the extension\n") ;
111 goto out ;
112 }
113 is_ok = TRUE ;
114
115out:
116 EPHYR_LOG ("leave\n") ;
117 return is_ok ;
118}
119
diff --git a/hw/kdrive/ephyr/ephyrproxyext.h b/hw/kdrive/ephyr/ephyrproxyext.h
new file mode 100644
index 000000000..e52f8d887
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrproxyext.h
@@ -0,0 +1,34 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifndef __EPHYRPROXYEXT_H__
29#define __EPHYRPROXYEXT_H__
30
31Bool ephyrProxyExtensionInit (const char *a_extension_name) ;
32
33#endif /*__EPHYRPROXYEXT_H__*/
34
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
new file mode 100644
index 000000000..bfe4d7223
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -0,0 +1,1278 @@
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28
29#ifdef HAVE_CONFIG_H
30#include <kdrive-config.h>
31#endif
32#include <string.h>
33#include <X11/extensions/Xv.h>
34#include "ephyrlog.h"
35#include "kdrive.h"
36#include "kxv.h"
37#include "ephyr.h"
38#include "hostx.h"
39#include "ephyrhostvideo.h"
40
41struct _EphyrXVPriv {
42 EphyrHostXVAdaptorArray *host_adaptors ;
43 KdVideoAdaptorPtr adaptors ;
44 int num_adaptors ;
45};
46typedef struct _EphyrXVPriv EphyrXVPriv ;
47
48struct _EphyrPortPriv {
49 int port_number ;
50 KdVideoAdaptorPtr current_adaptor ;
51 EphyrXVPriv *xv_priv;
52 unsigned char *image_buf ;
53 int image_buf_size ;
54 int image_id ;
55 int drw_x, drw_y, drw_w, drw_h ;
56 int src_x, src_y, src_w, src_h ;
57 int image_width, image_height ;
58};
59typedef struct _EphyrPortPriv EphyrPortPriv ;
60
61static Bool DoSimpleClip (BoxPtr a_dst_drw,
62 BoxPtr a_clipper,
63 BoxPtr a_result) ;
64
65static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
66
67/*
68static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
69*/
70
71static EphyrXVPriv* ephyrXVPrivNew (void) ;
72static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
73static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
74static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
75static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
76 ScreenPtr a_screen) ;
77
78static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
79 int a_attrs_len,
80 const char *a_attr_name,
81 int a_attr_value,
82 Bool *a_is_valid) ;
83
84static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
85 int a_image_id,
86 unsigned short a_width,
87 unsigned short a_height,
88 int *a_size) ;
89
90static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
91 const unsigned char *a_image,
92 int a_image_len) ;
93
94static void ephyrStopVideo (KdScreenInfo *a_info,
95 pointer a_xv_priv,
96 Bool a_exit);
97
98static int ephyrSetPortAttribute (KdScreenInfo *a_info,
99 Atom a_attr_name,
100 int a_attr_value,
101 pointer a_port_priv);
102
103static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
104 Atom a_attr_name,
105 int *a_attr_value,
106 pointer a_port_priv);
107
108static void ephyrQueryBestSize (KdScreenInfo *a_info,
109 Bool a_motion,
110 short a_src_w,
111 short a_src_h,
112 short a_drw_w,
113 short a_drw_h,
114 unsigned int *a_prefered_w,
115 unsigned int *a_prefered_h,
116 pointer a_port_priv);
117
118static int ephyrPutImage (KdScreenInfo *a_info,
119 DrawablePtr a_drawable,
120 short a_src_x,
121 short a_src_y,
122 short a_drw_x,
123 short a_drw_y,
124 short a_src_w,
125 short a_src_h,
126 short a_drw_w,
127 short a_drw_h,
128 int a_id,
129 unsigned char *a_buf,
130 short a_width,
131 short a_height,
132 Bool a_sync,
133 RegionPtr a_clipping_region,
134 pointer a_port_priv);
135
136static int ephyrReputImage (KdScreenInfo *a_info,
137 DrawablePtr a_drawable,
138 short a_drw_x,
139 short a_drw_y,
140 RegionPtr a_clipping_region,
141 pointer a_port_priv) ;
142
143static int ephyrPutVideo (KdScreenInfo *a_info,
144 DrawablePtr a_drawable,
145 short a_vid_x, short a_vid_y,
146 short a_drw_x, short a_drw_y,
147 short a_vid_w, short a_vid_h,
148 short a_drw_w, short a_drw_h,
149 RegionPtr a_clip_region,
150 pointer a_port_priv) ;
151
152static int ephyrGetVideo (KdScreenInfo *a_info,
153 DrawablePtr a_drawable,
154 short a_vid_x, short a_vid_y,
155 short a_drw_x, short a_drw_y,
156 short a_vid_w, short a_vid_h,
157 short a_drw_w, short a_drw_h,
158 RegionPtr a_clip_region,
159 pointer a_port_priv) ;
160
161static int ephyrPutStill (KdScreenInfo *a_info,
162 DrawablePtr a_drawable,
163 short a_vid_x, short a_vid_y,
164 short a_drw_x, short a_drw_y,
165 short a_vid_w, short a_vid_h,
166 short a_drw_w, short a_drw_h,
167 RegionPtr a_clip_region,
168 pointer a_port_priv) ;
169
170static int ephyrGetStill (KdScreenInfo *a_info,
171 DrawablePtr a_drawable,
172 short a_vid_x, short a_vid_y,
173 short a_drw_x, short a_drw_y,
174 short a_vid_w, short a_vid_h,
175 short a_drw_w, short a_drw_h,
176 RegionPtr a_clip_region,
177 pointer a_port_priv) ;
178
179static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
180 int a_id,
181 unsigned short *a_w,
182 unsigned short *a_h,
183 int *a_pitches,
184 int *a_offsets);
185static int s_base_port_id ;
186
187/**************
188 * <helpers>
189 * ************/
190
191static Bool
192DoSimpleClip (BoxPtr a_dst_box,
193 BoxPtr a_clipper,
194 BoxPtr a_result)
195{
196 BoxRec dstClippedBox ;
197
198 EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
199
200 /*
201 * setup the clipbox inside the destination.
202 */
203 dstClippedBox.x1 = a_dst_box->x1 ;
204 dstClippedBox.x2 = a_dst_box->x2 ;
205 dstClippedBox.y1 = a_dst_box->y1 ;
206 dstClippedBox.y2 = a_dst_box->y2 ;
207
208 /*
209 * if the cliper leftmost edge is inside
210 * the destination area then the leftmost edge of the resulting
211 * clipped box is the leftmost edge of the cliper.
212 */
213 if (a_clipper->x1 > dstClippedBox.x1)
214 dstClippedBox.x1 = a_clipper->x1 ;
215
216 /*
217 * if the cliper top edge is inside the destination area
218 * then the bottom horizontal edge of the resulting clipped box
219 * is the bottom edge of the cliper
220 */
221 if (a_clipper->y1 > dstClippedBox.y1)
222 dstClippedBox.y1 = a_clipper->y1 ;
223
224 /*ditto for right edge*/
225 if (a_clipper->x2 < dstClippedBox.x2)
226 dstClippedBox.x2 = a_clipper->x2 ;
227
228 /*ditto for bottom edge*/
229 if (a_clipper->y2 < dstClippedBox.y2)
230 dstClippedBox.y2 = a_clipper->y2 ;
231
232 memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
233 return TRUE ;
234}
235
236static Bool
237ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
238{
239 char *atom_name=NULL;
240 int host_atom=None ;
241
242 EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
243
244 if (!ValidAtom (a_local_atom))
245 return FALSE ;
246
247 atom_name = NameForAtom (a_local_atom) ;
248
249 if (!atom_name)
250 return FALSE ;
251
252 if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
253 EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
254 atom_name) ;
255 return FALSE ;
256 }
257 *a_host_atom = host_atom ;
258 return TRUE ;
259}
260
261/*
262 Not used yed.
263static Bool
264ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
265{
266 Bool is_ok=FALSE ;
267 char *atom_name=NULL ;
268 int atom=None ;
269
270 EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
271
272 atom_name = ephyrHostGetAtomName (a_host_atom) ;
273 if (!atom_name)
274 goto out ;
275
276 atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
277 if (atom == None)
278 goto out ;
279
280 *a_local_atom = atom ;
281 is_ok = TRUE ;
282
283out:
284 if (atom_name) {
285 ephyrHostFree (atom_name) ;
286 }
287 return is_ok ;
288}
289*/
290
291/**************
292 *</helpers>
293 * ************/
294
295Bool
296ephyrInitVideo (ScreenPtr pScreen)
297{
298 Bool is_ok = FALSE ;
299 KdScreenPriv(pScreen);
300 KdScreenInfo *screen = pScreenPriv->screen;
301 static EphyrXVPriv *xv_priv;
302
303 EPHYR_LOG ("enter\n") ;
304
305 if (screen->fb[0].bitsPerPixel == 8) {
306 EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
307 return FALSE ;
308 }
309
310 if (!xv_priv) {
311 xv_priv = ephyrXVPrivNew () ;
312 }
313 if (!xv_priv) {
314 EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
315 goto out ;
316 }
317
318 if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
319 EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
320 goto out ;
321 }
322 is_ok = TRUE ;
323
324out:
325 return is_ok ;
326}
327
328static EphyrXVPriv*
329ephyrXVPrivNew (void)
330{
331 EphyrXVPriv *xv_priv=NULL ;
332
333 EPHYR_LOG ("enter\n") ;
334
335 xv_priv = xcalloc (1, sizeof (EphyrXVPriv)) ;
336 if (!xv_priv) {
337 EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
338 goto error ;
339 }
340
341 ephyrHostXVInit () ;
342
343 if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
344 EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
345 goto error ;
346 }
347 if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
348 EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
349 goto error ;
350 }
351
352 EPHYR_LOG ("leave\n") ;
353 return xv_priv ;
354
355error:
356 if (xv_priv) {
357 ephyrXVPrivDelete (xv_priv) ;
358 xv_priv = NULL ;
359 }
360 return NULL ;
361}
362
363static void
364ephyrXVPrivDelete (EphyrXVPriv *a_this)
365{
366 EPHYR_LOG ("enter\n") ;
367
368 if (!a_this)
369 return ;
370 if (a_this->host_adaptors) {
371 ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
372 a_this->host_adaptors = NULL ;
373 }
374 if (a_this->adaptors) {
375 xfree (a_this->adaptors) ;
376 a_this->adaptors = NULL ;
377 }
378 xfree (a_this) ;
379 EPHYR_LOG ("leave\n") ;
380}
381
382static KdVideoEncodingPtr
383videoEncodingDup (EphyrHostEncoding *a_encodings,
384 int a_num_encodings)
385{
386 KdVideoEncodingPtr result = NULL ;
387 int i=0 ;
388
389 EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
390
391 result = xcalloc (a_num_encodings, sizeof (KdVideoEncodingRec)) ;
392 for (i=0 ; i < a_num_encodings; i++) {
393 result[i].id = a_encodings[i].id ;
394 result[i].name = strdup (a_encodings[i].name) ;
395 result[i].width = a_encodings[i].width ;
396 result[i].height = a_encodings[i].height ;
397 result[i].rate.numerator = a_encodings[i].rate.numerator ;
398 result[i].rate.denominator = a_encodings[i].rate.denominator ;
399 }
400 return result ;
401}
402
403static KdAttributePtr
404portAttributesDup (EphyrHostAttribute *a_encodings,
405 int a_num_encodings)
406{
407 int i=0 ;
408 KdAttributePtr result=NULL ;
409
410 EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
411
412 result = xcalloc (a_num_encodings, sizeof (KdAttributeRec)) ;
413 if (!result) {
414 EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
415 return NULL ;
416 }
417 for (i=0; i < a_num_encodings; i++) {
418 result[i].flags = a_encodings[i].flags ;
419 result[i].min_value = a_encodings[i].min_value ;
420 result[i].max_value = a_encodings[i].max_value ;
421 result[i].name = strdup (a_encodings[i].name) ;
422 }
423 return result ;
424}
425
426static Bool
427ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
428{
429 EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
430 EphyrHostVideoFormat *video_formats=NULL ;
431 EphyrHostEncoding *encodings=NULL ;
432 EphyrHostAttribute *attributes=NULL ;
433 EphyrHostImageFormat *image_formats=NULL ;
434 int num_video_formats=0, base_port_id=0,
435 num_attributes=0, num_formats=0, i=0,
436 port_priv_offset=0;
437 unsigned num_encodings=0 ;
438 Bool is_ok = FALSE ;
439
440 EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
441
442 EPHYR_LOG ("enter\n") ;
443
444 if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
445 EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
446 goto out ;
447 }
448 if (a_this->host_adaptors)
449 a_this->num_adaptors =
450 ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
451 if (a_this->num_adaptors < 0) {
452 EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
453 goto out ;
454 }
455 EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
456 /*
457 * copy what we can from adaptors into a_this->adaptors
458 */
459 if (a_this->num_adaptors) {
460 a_this->adaptors = xcalloc (a_this->num_adaptors,
461 sizeof (KdVideoAdaptorRec)) ;
462 if (!a_this->adaptors) {
463 EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
464 goto out ;
465 }
466 }
467 for (i=0; i < a_this->num_adaptors; i++) {
468 int j=0 ;
469 cur_host_adaptor =
470 ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
471 if (!cur_host_adaptor)
472 continue ;
473 a_this->adaptors[i].nPorts =
474 ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
475 if (a_this->adaptors[i].nPorts <=0) {
476 EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
477 continue ;
478 }
479 a_this->adaptors[i].type =
480 ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
481 a_this->adaptors[i].type |= XvWindowMask ;
482 a_this->adaptors[i].flags =
483 VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
484 if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
485 a_this->adaptors[i].name =
486 strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
487 else
488 a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
489 base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
490 if (base_port_id < 0) {
491 EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
492 continue ;
493 }
494 if (!s_base_port_id)
495 s_base_port_id = base_port_id ;
496
497 if (!ephyrHostXVQueryEncodings (base_port_id,
498 &encodings,
499 &num_encodings)) {
500 EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
501 " adaptors %d\n",
502 base_port_id, i) ;
503 continue ;
504 }
505 a_this->adaptors[i].nEncodings = num_encodings ;
506 a_this->adaptors[i].pEncodings =
507 videoEncodingDup (encodings, num_encodings) ;
508 video_formats = (EphyrHostVideoFormat*)
509 ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
510 &num_video_formats);
511 a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
512 a_this->adaptors[i].nFormats = num_video_formats ;
513 /* got a_this->adaptors[i].nPorts already
514 a_this->adaptors[i].nPorts =
515 ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
516 */
517 a_this->adaptors[i].pPortPrivates =
518 xcalloc (a_this->adaptors[i].nPorts,
519 sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
520 port_priv_offset = a_this->adaptors[i].nPorts;
521 for (j=0; j < a_this->adaptors[i].nPorts; j++) {
522 EphyrPortPriv *port_privs_base =
523 (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
524 EphyrPortPriv *port_priv = &port_privs_base[j] ;
525 port_priv->port_number = base_port_id + j;
526 port_priv->current_adaptor = &a_this->adaptors[i] ;
527 port_priv->xv_priv = a_this ;
528 a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
529 }
530 if (!ephyrHostXVQueryPortAttributes (base_port_id,
531 &attributes,
532 &num_attributes)) {
533 EPHYR_LOG_ERROR ("failed to get port attribute "
534 "for adaptor %d\n", i) ;
535 continue ;
536 }
537 a_this->adaptors[i].pAttributes =
538 portAttributesDup (attributes, num_attributes);
539 a_this->adaptors[i].nAttributes = num_attributes ;
540 /*make sure atoms of attrs names are created in xephyr*/
541 for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
542 if (a_this->adaptors[i].pAttributes[j].name)
543 MakeAtom (a_this->adaptors[i].pAttributes[j].name,
544 strlen (a_this->adaptors[i].pAttributes[j].name),
545 TRUE) ;
546 }
547 if (!ephyrHostXVQueryImageFormats (base_port_id,
548 &image_formats,
549 &num_formats)) {
550 EPHYR_LOG_ERROR ("failed to get image formats "
551 "for adaptor %d\n", i) ;
552 continue ;
553 }
554 a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
555 a_this->adaptors[i].nImages = num_formats ;
556 }
557 is_ok = TRUE ;
558
559out:
560 if (encodings) {
561 ephyrHostEncodingsDelete (encodings, num_encodings) ;
562 encodings = NULL ;
563 }
564 if (attributes) {
565 ephyrHostAttributesDelete (attributes) ;
566 attributes = NULL ;
567 }
568 EPHYR_LOG ("leave\n") ;
569 return is_ok ;
570}
571
572static Bool
573ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
574{
575 int i=0 ;
576 Bool has_it=FALSE ;
577 EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
578
579 EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
580
581 EPHYR_LOG ("enter\n") ;
582
583 for (i=0; i < a_this->num_adaptors; i++) {
584 a_this->adaptors[i].ReputImage = ephyrReputImage ;
585 a_this->adaptors[i].StopVideo = ephyrStopVideo ;
586 a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
587 a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
588 a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
589 a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
590
591 cur_host_adaptor =
592 ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
593 if (!cur_host_adaptor) {
594 EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
595 continue ;
596 }
597 has_it = FALSE ;
598 if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
599 EPHYR_LOG_ERROR ("error\n") ;
600 }
601 if (has_it) {
602 a_this->adaptors[i].PutImage = ephyrPutImage;
603 }
604
605 has_it = FALSE ;
606 if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
607 EPHYR_LOG_ERROR ("error\n") ;
608 }
609 if (has_it) {
610 a_this->adaptors[i].PutVideo = ephyrPutVideo;
611 }
612
613 has_it = FALSE ;
614 if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
615 EPHYR_LOG_ERROR ("error\n") ;
616 }
617 if (has_it) {
618 a_this->adaptors[i].GetVideo = ephyrGetVideo;
619 }
620
621 has_it = FALSE ;
622 if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
623 EPHYR_LOG_ERROR ("error\n") ;
624 }
625 if (has_it) {
626 a_this->adaptors[i].PutStill = ephyrPutStill;
627 }
628
629 has_it = FALSE ;
630 if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
631 EPHYR_LOG_ERROR ("error\n") ;
632 }
633 if (has_it) {
634 a_this->adaptors[i].GetStill = ephyrGetStill;
635 }
636 }
637 EPHYR_LOG ("leave\n") ;
638 return TRUE ;
639}
640
641static Bool
642ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
643 ScreenPtr a_screen)
644{
645 KdScreenPriv(a_screen);
646 KdScreenInfo *screen = pScreenPriv->screen;
647 Bool is_ok = FALSE ;
648 KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
649 int num_registered_adaptors=0, i=0, num_adaptors=0 ;
650
651 EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
652
653 EPHYR_LOG ("enter\n") ;
654
655 if (!a_this->num_adaptors)
656 goto out ;
657 num_registered_adaptors =
658 KdXVListGenericAdaptors (screen, &registered_adaptors);
659
660 num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
661 adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
662 if (!adaptors) {
663 EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
664 goto out ;
665 }
666 memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
667 for (i=0 ; i < a_this->num_adaptors; i++) {
668 *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
669 }
670 if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
671 EPHYR_LOG_ERROR ("failed to register adaptors\n");
672 goto out ;
673 }
674 EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
675 is_ok = TRUE ;
676
677out:
678 if (registered_adaptors) {
679 xfree (registered_adaptors) ;
680 registered_adaptors = NULL ;
681 }
682 if (adaptors) {
683 xfree (adaptors) ;
684 adaptors=NULL ;
685 }
686 EPHYR_LOG ("leave\n") ;
687 return is_ok ;
688}
689
690static Bool
691ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
692 int a_attrs_len,
693 const char *a_attr_name,
694 int a_attr_value,
695 Bool *a_is_valid)
696{
697 int i=0 ;
698
699 EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
700 FALSE) ;
701
702 for (i=0; i < a_attrs_len; i++) {
703 if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
704 continue ;
705 if (a_attrs[i].min_value > a_attr_value ||
706 a_attrs[i].max_value < a_attr_value) {
707 *a_is_valid = FALSE ;
708 EPHYR_LOG_ERROR ("attribute was not valid\n"
709 "value:%d. min:%d. max:%d\n",
710 a_attr_value,
711 a_attrs[i].min_value,
712 a_attrs[i].max_value) ;
713 } else {
714 *a_is_valid = TRUE ;
715 }
716 return TRUE ;
717 }
718 return FALSE ;
719}
720
721static Bool
722ephyrXVPrivGetImageBufSize (int a_port_id,
723 int a_image_id,
724 unsigned short a_width,
725 unsigned short a_height,
726 int *a_size)
727{
728 Bool is_ok=FALSE ;
729 unsigned short width=a_width, height=a_height ;
730
731 EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
732
733 EPHYR_LOG ("enter\n") ;
734
735 if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
736 &width, &height, a_size, NULL, NULL)) {
737 EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
738 goto out ;
739 }
740 is_ok = TRUE ;
741
742out:
743 EPHYR_LOG ("leave\n") ;
744 return is_ok ;
745}
746
747static Bool
748ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
749 const unsigned char *a_image_buf,
750 int a_image_len)
751{
752 Bool is_ok=FALSE ;
753
754 EPHYR_LOG ("enter\n") ;
755
756 if (a_port_priv->image_buf_size < a_image_len) {
757 unsigned char *buf=NULL ;
758 buf = realloc (a_port_priv->image_buf, a_image_len) ;
759 if (!buf) {
760 EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
761 goto out ;
762 }
763 a_port_priv->image_buf = buf ;
764 a_port_priv->image_buf_size = a_image_len;
765 }
766 memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
767 is_ok = TRUE ;
768
769out:
770 return is_ok ;
771 EPHYR_LOG ("leave\n") ;
772}
773
774static void
775ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
776{
777 EphyrPortPriv *port_priv = a_port_priv ;
778
779 EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
780 EPHYR_RETURN_IF_FAIL (port_priv) ;
781
782 EPHYR_LOG ("enter\n") ;
783 if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
784 port_priv->port_number)) {
785 EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
786 }
787 EPHYR_LOG ("leave\n") ;
788}
789
790static int
791ephyrSetPortAttribute (KdScreenInfo *a_info,
792 Atom a_attr_name,
793 int a_attr_value,
794 pointer a_port_priv)
795{
796 int res=Success, host_atom=0 ;
797 EphyrPortPriv *port_priv = a_port_priv ;
798 Bool is_attr_valid=FALSE ;
799
800 EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
801 EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
802 EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
803 BadMatch) ;
804 EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
805 BadMatch) ;
806 EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
807
808 EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
809 port_priv->port_number,
810 (int)a_attr_name,
811 NameForAtom (a_attr_name),
812 a_attr_value) ;
813
814 if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
815 EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
816 res = BadMatch ;
817 goto out ;
818 }
819
820 if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
821 port_priv->current_adaptor->nAttributes,
822 NameForAtom (a_attr_name),
823 a_attr_value,
824 &is_attr_valid)) {
825 EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
826 NameForAtom (a_attr_name)) ;
827 /*
828 res = BadMatch ;
829 goto out ;
830 */
831 }
832 if (!is_attr_valid) {
833 EPHYR_LOG_ERROR ("attribute %s is not valid\n",
834 NameForAtom (a_attr_name)) ;
835 /*
836 res = BadMatch ;
837 goto out ;
838 */
839 }
840
841 if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
842 host_atom,
843 a_attr_value)) {
844 EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
845 res = BadMatch ;
846 goto out ;
847 }
848
849 res = Success ;
850out:
851 EPHYR_LOG ("leave\n") ;
852 return res ;
853}
854
855static int
856ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
857 Atom a_attr_name,
858 int *a_attr_value,
859 pointer a_port_priv)
860{
861 int res=Success, host_atom=0 ;
862 EphyrPortPriv *port_priv = a_port_priv ;
863
864 EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
865 EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
866
867 EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
868 port_priv->port_number,
869 (int)a_attr_name,
870 NameForAtom (a_attr_name)) ;
871
872 if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
873 EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
874 res = BadMatch ;
875 goto out ;
876 }
877
878 if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
879 host_atom,
880 a_attr_value)) {
881 EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
882 res = BadMatch ;
883 goto out ;
884 }
885
886 res = Success ;
887out:
888 EPHYR_LOG ("leave\n") ;
889 return res ;
890}
891
892static void
893ephyrQueryBestSize (KdScreenInfo *a_info,
894 Bool a_motion,
895 short a_src_w,
896 short a_src_h,
897 short a_drw_w,
898 short a_drw_h,
899 unsigned int *a_prefered_w,
900 unsigned int *a_prefered_h,
901 pointer a_port_priv)
902{
903 int res=0 ;
904 EphyrPortPriv *port_priv = a_port_priv ;
905
906 EPHYR_RETURN_IF_FAIL (port_priv) ;
907
908 EPHYR_LOG ("enter\n") ;
909 res = ephyrHostXVQueryBestSize (port_priv->port_number,
910 a_motion,
911 a_src_w, a_src_h,
912 a_drw_w, a_drw_h,
913 a_prefered_w, a_prefered_h) ;
914 if (!res) {
915 EPHYR_LOG_ERROR ("Failed to query best size\n") ;
916 }
917 EPHYR_LOG ("leave\n") ;
918}
919
920static int
921ephyrPutImage (KdScreenInfo *a_info,
922 DrawablePtr a_drawable,
923 short a_src_x,
924 short a_src_y,
925 short a_drw_x,
926 short a_drw_y,
927 short a_src_w,
928 short a_src_h,
929 short a_drw_w,
930 short a_drw_h,
931 int a_id,
932 unsigned char *a_buf,
933 short a_width,
934 short a_height,
935 Bool a_sync,
936 RegionPtr a_clipping_region,
937 pointer a_port_priv)
938{
939 EphyrPortPriv *port_priv = a_port_priv ;
940 Bool is_ok=FALSE ;
941 int result=BadImplementation, image_size=0 ;
942
943 EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
944 EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
945
946 EPHYR_LOG ("enter\n") ;
947
948 if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
949 port_priv->port_number,
950 a_id,
951 a_drw_x, a_drw_y, a_drw_w, a_drw_h,
952 a_src_x, a_src_y, a_src_w, a_src_h,
953 a_width, a_height, a_buf,
954 (EphyrHostBox*)REGION_RECTS (a_clipping_region),
955 REGION_NUM_RECTS (a_clipping_region))) {
956 EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
957 goto out ;
958 }
959
960 /*
961 * Now save the image so that we can resend it to host it
962 * later, in ReputImage.
963 */
964 if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
965 a_id, a_width, a_height, &image_size)) {
966 EPHYR_LOG_ERROR ("failed to get image size\n") ;
967 /*this is a minor error so we won't get bail out abruptly*/
968 is_ok = FALSE ;
969 } else {
970 is_ok = TRUE ;
971 }
972 if (is_ok) {
973 if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
974 is_ok=FALSE ;
975 } else {
976 port_priv->image_id = a_id;
977 port_priv->drw_x = a_drw_x;
978 port_priv->drw_y = a_drw_y;
979 port_priv->drw_w = a_drw_w ;
980 port_priv->drw_h = a_drw_h ;
981 port_priv->src_x = a_src_x;
982 port_priv->src_y = a_src_y ;
983 port_priv->src_w = a_src_w ;
984 port_priv->src_h = a_src_h ;
985 port_priv->image_width = a_width ;
986 port_priv->image_height = a_height ;
987 }
988 }
989 if (!is_ok) {
990 if (port_priv->image_buf) {
991 free (port_priv->image_buf) ;
992 port_priv->image_buf = NULL ;
993 port_priv->image_buf_size = 0 ;
994 }
995 }
996
997 result = Success ;
998
999out:
1000 EPHYR_LOG ("leave\n") ;
1001 return result ;
1002}
1003
1004static int
1005ephyrReputImage (KdScreenInfo *a_info,
1006 DrawablePtr a_drawable,
1007 short a_drw_x,
1008 short a_drw_y,
1009 RegionPtr a_clipping_region,
1010 pointer a_port_priv)
1011{
1012 EphyrPortPriv *port_priv = a_port_priv ;
1013 int result=BadImplementation ;
1014
1015 EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
1016 EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
1017
1018 EPHYR_LOG ("enter\n") ;
1019
1020 if (!port_priv->image_buf_size || !port_priv->image_buf) {
1021 EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
1022 goto out ;
1023 }
1024 if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
1025 port_priv->port_number,
1026 port_priv->image_id,
1027 a_drw_x, a_drw_y,
1028 port_priv->drw_w, port_priv->drw_h,
1029 port_priv->src_x, port_priv->src_y,
1030 port_priv->src_w, port_priv->src_h,
1031 port_priv->image_width, port_priv->image_height,
1032 port_priv->image_buf,
1033 (EphyrHostBox*)REGION_RECTS (a_clipping_region),
1034 REGION_NUM_RECTS (a_clipping_region))) {
1035 EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
1036 goto out ;
1037 }
1038
1039 result = Success ;
1040
1041out:
1042 EPHYR_LOG ("leave\n") ;
1043 return result ;
1044}
1045
1046static int
1047ephyrPutVideo (KdScreenInfo *a_info,
1048 DrawablePtr a_drawable,
1049 short a_vid_x, short a_vid_y,
1050 short a_drw_x, short a_drw_y,
1051 short a_vid_w, short a_vid_h,
1052 short a_drw_w, short a_drw_h,
1053 RegionPtr a_clipping_region,
1054 pointer a_port_priv)
1055{
1056 EphyrPortPriv *port_priv = a_port_priv ;
1057 BoxRec clipped_area, dst_box ;
1058 int result=BadImplementation ;
1059 int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
1060
1061 EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
1062 EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
1063
1064 EPHYR_LOG ("enter\n") ;
1065
1066 dst_box.x1 = a_drw_x ;
1067 dst_box.x2 = a_drw_x + a_drw_w;
1068 dst_box.y1 = a_drw_y ;
1069 dst_box.y2 = a_drw_y + a_drw_h;
1070
1071 if (!DoSimpleClip (&dst_box,
1072 REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
1073 &clipped_area)) {
1074 EPHYR_LOG_ERROR ("failed to simple clip\n") ;
1075 goto out ;
1076 }
1077
1078 drw_x = clipped_area.x1 ;
1079 drw_y = clipped_area.y1 ;
1080 drw_w = clipped_area.x2 - clipped_area.x1 ;
1081 drw_h = clipped_area.y2 - clipped_area.y1 ;
1082
1083 if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
1084 port_priv->port_number,
1085 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
1086 a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
1087 EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
1088 goto out ;
1089 }
1090 result = Success ;
1091
1092out:
1093 EPHYR_LOG ("leave\n") ;
1094 return result ;
1095}
1096
1097static int
1098ephyrGetVideo (KdScreenInfo *a_info,
1099 DrawablePtr a_drawable,
1100 short a_vid_x, short a_vid_y,
1101 short a_drw_x, short a_drw_y,
1102 short a_vid_w, short a_vid_h,
1103 short a_drw_w, short a_drw_h,
1104 RegionPtr a_clipping_region,
1105 pointer a_port_priv)
1106{
1107 EphyrPortPriv *port_priv = a_port_priv ;
1108 BoxRec clipped_area, dst_box ;
1109 int result=BadImplementation ;
1110 int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
1111
1112 EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
1113 EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
1114
1115 EPHYR_LOG ("enter\n") ;
1116
1117 dst_box.x1 = a_drw_x ;
1118 dst_box.x2 = a_drw_x + a_drw_w;
1119 dst_box.y1 = a_drw_y ;
1120 dst_box.y2 = a_drw_y + a_drw_h;
1121
1122 if (!DoSimpleClip (&dst_box,
1123 REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
1124 &clipped_area)) {
1125 EPHYR_LOG_ERROR ("failed to simple clip\n") ;
1126 goto out ;
1127 }
1128
1129 drw_x = clipped_area.x1 ;
1130 drw_y = clipped_area.y1 ;
1131 drw_w = clipped_area.x2 - clipped_area.x1 ;
1132 drw_h = clipped_area.y2 - clipped_area.y1 ;
1133
1134 if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
1135 port_priv->port_number,
1136 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
1137 a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
1138 EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
1139 goto out ;
1140 }
1141 result = Success ;
1142
1143out:
1144 EPHYR_LOG ("leave\n") ;
1145 return result ;
1146}
1147
1148static int
1149ephyrPutStill (KdScreenInfo *a_info,
1150 DrawablePtr a_drawable,
1151 short a_vid_x, short a_vid_y,
1152 short a_drw_x, short a_drw_y,
1153 short a_vid_w, short a_vid_h,
1154 short a_drw_w, short a_drw_h,
1155 RegionPtr a_clipping_region,
1156 pointer a_port_priv)
1157{
1158 EphyrPortPriv *port_priv = a_port_priv ;
1159 BoxRec clipped_area, dst_box ;
1160 int result=BadImplementation ;
1161 int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
1162
1163 EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
1164 EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
1165
1166 EPHYR_LOG ("enter\n") ;
1167
1168 dst_box.x1 = a_drw_x ;
1169 dst_box.x2 = a_drw_x + a_drw_w;
1170 dst_box.y1 = a_drw_y ;
1171 dst_box.y2 = a_drw_y + a_drw_h;
1172
1173 if (!DoSimpleClip (&dst_box,
1174 REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
1175 &clipped_area)) {
1176 EPHYR_LOG_ERROR ("failed to simple clip\n") ;
1177 goto out ;
1178 }
1179
1180 drw_x = clipped_area.x1 ;
1181 drw_y = clipped_area.y1 ;
1182 drw_w = clipped_area.x2 - clipped_area.x1 ;
1183 drw_h = clipped_area.y2 - clipped_area.y1 ;
1184
1185 if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
1186 port_priv->port_number,
1187 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
1188 a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
1189 EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
1190 goto out ;
1191 }
1192 result = Success ;
1193
1194out:
1195 EPHYR_LOG ("leave\n") ;
1196 return result ;
1197}
1198
1199static int
1200ephyrGetStill (KdScreenInfo *a_info,
1201 DrawablePtr a_drawable,
1202 short a_vid_x, short a_vid_y,
1203 short a_drw_x, short a_drw_y,
1204 short a_vid_w, short a_vid_h,
1205 short a_drw_w, short a_drw_h,
1206 RegionPtr a_clipping_region,
1207 pointer a_port_priv)
1208{
1209 EphyrPortPriv *port_priv = a_port_priv ;
1210 BoxRec clipped_area, dst_box ;
1211 int result=BadImplementation ;
1212 int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
1213
1214 EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
1215 EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
1216
1217 EPHYR_LOG ("enter\n") ;
1218
1219 dst_box.x1 = a_drw_x ;
1220 dst_box.x2 = a_drw_x + a_drw_w;
1221 dst_box.y1 = a_drw_y ;
1222 dst_box.y2 = a_drw_y + a_drw_h;
1223
1224 if (!DoSimpleClip (&dst_box,
1225 REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
1226 &clipped_area)) {
1227 EPHYR_LOG_ERROR ("failed to simple clip\n") ;
1228 goto out ;
1229 }
1230
1231 drw_x = clipped_area.x1 ;
1232 drw_y = clipped_area.y1 ;
1233 drw_w = clipped_area.x2 - clipped_area.x1 ;
1234 drw_h = clipped_area.y2 - clipped_area.y1 ;
1235
1236 if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
1237 port_priv->port_number,
1238 a_vid_x, a_vid_y, a_vid_w, a_vid_h,
1239 a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
1240 EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
1241 goto out ;
1242 }
1243 result = Success ;
1244
1245out:
1246 EPHYR_LOG ("leave\n") ;
1247 return result ;
1248}
1249
1250static int
1251ephyrQueryImageAttributes (KdScreenInfo *a_info,
1252 int a_id,
1253 unsigned short *a_w,
1254 unsigned short *a_h,
1255 int *a_pitches,
1256 int *a_offsets)
1257{
1258 int image_size=0 ;
1259
1260 EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
1261
1262 EPHYR_LOG ("enter: dim (%dx%d), pitches: %#x, offsets: %#x\n",
1263 *a_w, *a_h, (unsigned int)a_pitches, (unsigned int)a_offsets) ;
1264
1265 if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
1266 a_id,
1267 a_w, a_h,
1268 &image_size,
1269 a_pitches, a_offsets)) {
1270 EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
1271 goto out ;
1272 }
1273 EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
1274
1275out:
1276 EPHYR_LOG ("leave\n") ;
1277 return image_size ;
1278}
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 81678d927..181edd226 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -23,6 +23,10 @@
23 * PERFORMANCE OF THIS SOFTWARE. 23 * PERFORMANCE OF THIS SOFTWARE.
24 */ 24 */
25 25
26#ifdef HAVE_CONFIG_H
27#include <kdrive-config.h>
28#endif
29
26#include "hostx.h" 30#include "hostx.h"
27 31
28#include <stdlib.h> 32#include <stdlib.h>
@@ -40,6 +44,17 @@
40#include <X11/Xatom.h> 44#include <X11/Xatom.h>
41#include <X11/keysym.h> 45#include <X11/keysym.h>
42#include <X11/extensions/XShm.h> 46#include <X11/extensions/XShm.h>
47#include <X11/extensions/shape.h>
48#ifdef XEPHYR_DRI
49#include <GL/glx.h>
50#endif /*XEPHYR_DRI*/
51#include "ephyrlog.h"
52
53#ifdef XEPHYR_DRI
54extern Bool XF86DRIQueryExtension (Display *dpy,
55 int *event_basep,
56 int *error_basep);
57#endif
43 58
44/* 59/*
45 * All xlib calls go here, which gets built as its own .a . 60 * All xlib calls go here, which gets built as its own .a .
@@ -956,3 +971,382 @@ hostx_get_event(EphyrHostXEvent *ev)
956 return 0; 971 return 0;
957} 972}
958 973
974void*
975hostx_get_display(void)
976{
977 return HostX.dpy ;
978}
979
980int
981hostx_get_window (int a_screen_number)
982{
983 if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) {
984 EPHYR_LOG_ERROR ("bad screen number:%d\n", a_screen_number) ;
985 return 0;
986 }
987 return HostX.screens[a_screen_number].win ;
988}
989
990int
991hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attrs)
992{
993 XWindowAttributes attrs ;
994
995 memset (&attrs, 0, sizeof (attrs)) ;
996
997 if (!XGetWindowAttributes (hostx_get_display (),
998 a_window,
999 &attrs)) {
1000 return FALSE ;
1001 }
1002 a_attrs->x = attrs.x ;
1003 a_attrs->y = attrs.y ;
1004 a_attrs->width = attrs.width ;
1005 a_attrs->height = attrs.height ;
1006 if (attrs.visual)
1007 a_attrs->visualid = attrs.visual->visualid ;
1008 return TRUE ;
1009}
1010
1011int
1012hostx_get_extension_info (const char *a_ext_name,
1013 int *a_major_opcode,
1014 int *a_first_event,
1015 int *a_first_error)
1016{
1017 if (!a_ext_name || !a_major_opcode || !a_first_event || !a_first_error)
1018 return 0 ;
1019 if (!XQueryExtension (HostX.dpy,
1020 a_ext_name,
1021 a_major_opcode,
1022 a_first_event,
1023 a_first_error))
1024 {
1025 return 0 ;
1026 }
1027 return 1 ;
1028}
1029
1030int
1031hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
1032 int *a_num_entries)
1033{
1034 Display *dpy=hostx_get_display () ;
1035 Bool is_ok=False ;
1036 XVisualInfo templ, *visuals=NULL;
1037 EphyrHostVisualInfo *host_visuals=NULL ;
1038 int nb_items=0, i=0;
1039
1040 EPHYR_RETURN_VAL_IF_FAIL (a_visuals && a_num_entries && dpy,
1041 False) ;
1042 EPHYR_LOG ("enter\n") ;
1043 memset (&templ, 0, sizeof (templ)) ;
1044 visuals = XGetVisualInfo (dpy, VisualNoMask, &templ, &nb_items) ;
1045 if (!visuals) {
1046 EPHYR_LOG_ERROR ("host does not advertise any visual\n") ;
1047 goto out ;
1048 }
1049 EPHYR_LOG ("host advertises %d visuals\n", nb_items) ;
1050 host_visuals = calloc (nb_items, sizeof (EphyrHostVisualInfo)) ;
1051 for (i=0; i<nb_items; i++) {
1052 host_visuals[i].visualid = visuals[i].visualid ;
1053 host_visuals[i].screen = visuals[i].screen ;
1054 host_visuals[i].depth = visuals[i].depth ;
1055 host_visuals[i].class = visuals[i].class ;
1056 host_visuals[i].red_mask = visuals[i].red_mask ;
1057 host_visuals[i].green_mask = visuals[i].green_mask ;
1058 host_visuals[i].blue_mask = visuals[i].blue_mask ;
1059 host_visuals[i].colormap_size = visuals[i].colormap_size ;
1060 host_visuals[i].bits_per_rgb = visuals[i].bits_per_rgb ;
1061 }
1062 *a_visuals = host_visuals ;
1063 *a_num_entries = nb_items;
1064 host_visuals=NULL;
1065
1066 is_ok = TRUE;
1067out:
1068 if (visuals) {
1069 XFree (visuals) ;
1070 visuals = NULL;
1071 }
1072 if (host_visuals) {
1073 free (host_visuals) ;
1074 host_visuals = NULL;
1075 }
1076 EPHYR_LOG ("leave\n") ;
1077 return is_ok ;
1078
1079}
1080
1081typedef struct {
1082 int is_valid ;
1083 int local_id ;
1084 int remote_id ;
1085} ResourcePair ;
1086
1087#define RESOURCE_PEERS_SIZE 1024*10
1088static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
1089
1090
1091int
1092hostx_create_window (int a_screen_number,
1093 EphyrBox *a_geometry,
1094 int a_visual_id,
1095 int *a_host_peer /*out parameter*/)
1096{
1097 Bool is_ok=FALSE ;
1098 Display *dpy=hostx_get_display () ;
1099 XVisualInfo *visual_info=NULL, visual_info_templ;
1100 int visual_mask=VisualIDMask ;
1101 Window win=None ;
1102 int nb_visuals=0, winmask=0;
1103 XSetWindowAttributes attrs;
1104
1105 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geometry, FALSE) ;
1106
1107 EPHYR_LOG ("enter\n") ;
1108
1109 /*get visual*/
1110 memset (&visual_info, 0, sizeof (visual_info)) ;
1111 visual_info_templ.visualid = a_visual_id ;
1112 visual_info = XGetVisualInfo (dpy, visual_mask,
1113 &visual_info_templ,
1114 &nb_visuals) ;
1115 if (!visual_info) {
1116 EPHYR_LOG_ERROR ("argh, could not find a remote visual with id:%d\n",
1117 a_visual_id) ;
1118 goto out ;
1119 }
1120 memset (&attrs, 0, sizeof (attrs)) ;
1121 attrs.colormap = XCreateColormap (dpy,
1122 RootWindow (dpy,
1123 visual_info->screen),
1124 visual_info->visual,
1125 AllocNone) ;
1126 winmask = CWColormap;
1127
1128 win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
1129 a_geometry->x, a_geometry->y,
1130 a_geometry->width, a_geometry->height, 0,
1131 visual_info->depth, InputOutput,
1132 visual_info->visual, winmask, &attrs) ;
1133 if (win == None) {
1134 EPHYR_LOG_ERROR ("failed to create peer window\n") ;
1135 goto out ;
1136 }
1137 XFlush (dpy) ;
1138 XMapWindow (dpy, win) ;
1139 *a_host_peer = win ;
1140 is_ok = TRUE ;
1141out:
1142 EPHYR_LOG ("leave\n") ;
1143 return is_ok ;
1144}
1145
1146int
1147hostx_destroy_window (int a_win)
1148{
1149 Display *dpy=hostx_get_display () ;
1150
1151 EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
1152 XDestroyWindow (dpy, a_win) ;
1153 XFlush (dpy) ;
1154 return TRUE ;
1155}
1156
1157int
1158hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
1159{
1160 Display *dpy=hostx_get_display ();
1161
1162 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geo, FALSE) ;
1163
1164 EPHYR_LOG ("enter. x,y,w,h:(%d,%d,%d,%d)\n",
1165 a_geo->x, a_geo->y,
1166 a_geo->width, a_geo->height) ;
1167
1168 XMoveWindow (dpy, a_win, a_geo->x, a_geo->y) ;
1169 XResizeWindow (dpy, a_win, a_geo->width, a_geo->height) ;
1170 EPHYR_LOG ("leave\n") ;
1171 return TRUE;
1172}
1173
1174int
1175hostx_set_window_bounding_rectangles (int a_window,
1176 EphyrRect *a_rects,
1177 int a_num_rects)
1178{
1179 Bool is_ok=FALSE;
1180 Display *dpy=hostx_get_display () ;
1181 int i=0 ;
1182 XRectangle *rects=NULL ;
1183
1184 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
1185
1186 EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
1187
1188 rects = calloc (a_num_rects, sizeof (XRectangle)) ;
1189 for (i=0; i<a_num_rects; i++) {
1190 rects[i].x = a_rects[i].x1 ;
1191 rects[i].y = a_rects[i].y1 ;
1192 rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
1193 rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
1194 EPHYR_LOG ("borders clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
1195 rects[i].x, rects[i].y,
1196 rects[i].width, rects[i].height) ;
1197 }
1198 /*this aways returns 1*/
1199 XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0,
1200 rects, a_num_rects, ShapeSet, YXBanded) ;
1201 is_ok = TRUE ;
1202
1203 if (rects) {
1204 free (rects) ;
1205 rects = NULL ;
1206 }
1207 EPHYR_LOG ("leave\n") ;
1208 return is_ok;
1209}
1210
1211int
1212hostx_set_window_clipping_rectangles (int a_window,
1213 EphyrRect *a_rects,
1214 int a_num_rects)
1215{
1216 Bool is_ok=FALSE;
1217 Display *dpy=hostx_get_display () ;
1218 int i=0 ;
1219 XRectangle *rects=NULL ;
1220
1221 EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
1222
1223 EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
1224
1225 rects = calloc (a_num_rects, sizeof (XRectangle)) ;
1226 for (i=0; i<a_num_rects; i++) {
1227 rects[i].x = a_rects[i].x1 ;
1228 rects[i].y = a_rects[i].y1 ;
1229 rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
1230 rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
1231 EPHYR_LOG ("clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
1232 rects[i].x, rects[i].y,
1233 rects[i].width, rects[i].height) ;
1234 }
1235 /*this aways returns 1*/
1236 XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0,
1237 rects, a_num_rects, ShapeSet, YXBanded) ;
1238 is_ok = TRUE ;
1239
1240 if (rects) {
1241 free (rects) ;
1242 rects = NULL ;
1243 }
1244 EPHYR_LOG ("leave\n") ;
1245 return is_ok;
1246}
1247
1248int
1249hostx_has_xshape (void)
1250{
1251 int event_base=0, error_base=0 ;
1252 Display *dpy=hostx_get_display () ;
1253 if (!XShapeQueryExtension (dpy,
1254 &event_base,
1255 &error_base)) {
1256 return FALSE ;
1257 }
1258 return TRUE;
1259}
1260
1261#ifdef XEPHYR_DRI
1262int
1263hostx_allocate_resource_id_peer (int a_local_resource_id,
1264 int *a_remote_resource_id)
1265{
1266 int i=0 ;
1267 ResourcePair *peer=NULL ;
1268 Display *dpy=hostx_get_display ();
1269
1270 /*
1271 * first make sure a resource peer
1272 * does not exist already for
1273 * a_local_resource_id
1274 */
1275 for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
1276 if (resource_peers[i].is_valid
1277 && resource_peers[i].local_id == a_local_resource_id) {
1278 peer = &resource_peers[i] ;
1279 break ;
1280 }
1281 }
1282 /*
1283 * find one free peer entry, an feed it with
1284 */
1285 if (!peer) {
1286 for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
1287 if (!resource_peers[i].is_valid) {
1288 peer = &resource_peers[i] ;
1289 break ;
1290 }
1291 }
1292 if (peer) {
1293 peer->remote_id = XAllocID (dpy);
1294 peer->local_id = a_local_resource_id ;
1295 peer->is_valid = TRUE ;
1296 }
1297 }
1298 if (peer) {
1299 *a_remote_resource_id = peer->remote_id ;
1300 return TRUE ;
1301 }
1302 return FALSE ;
1303}
1304
1305int
1306hostx_get_resource_id_peer (int a_local_resource_id,
1307 int *a_remote_resource_id)
1308{
1309 int i=0 ;
1310 ResourcePair *peer=NULL ;
1311 for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
1312 if (resource_peers[i].is_valid
1313 && resource_peers[i].local_id == a_local_resource_id) {
1314 peer = &resource_peers[i] ;
1315 break ;
1316 }
1317 }
1318 if (peer) {
1319 *a_remote_resource_id = peer->remote_id ;
1320 return TRUE ;
1321 }
1322 return FALSE ;
1323}
1324
1325int
1326hostx_has_dri (void)
1327{
1328 int event_base=0, error_base=0 ;
1329 Display *dpy=hostx_get_display () ;
1330
1331 if (!XF86DRIQueryExtension (dpy,
1332 &event_base,
1333 &error_base)) {
1334 return FALSE ;
1335 }
1336 return TRUE ;
1337}
1338
1339int
1340hostx_has_glx (void)
1341{
1342 Display *dpy=hostx_get_display () ;
1343 int event_base=0, error_base=0 ;
1344
1345 if (!glXQueryExtension (dpy, &event_base, &error_base)) {
1346 return FALSE ;
1347 }
1348 return TRUE ;
1349}
1350
1351#endif /*XEPHYR_DRI*/
1352
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 93765d096..3caa466a7 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -92,6 +92,32 @@ struct EphyrHostXEvent
92 int key_state; 92 int key_state;
93}; 93};
94 94
95typedef struct {
96 VisualID visualid;
97 int screen;
98 int depth;
99 int class;
100 unsigned long red_mask;
101 unsigned long green_mask;
102 unsigned long blue_mask;
103 int colormap_size;
104 int bits_per_rgb;
105} EphyrHostVisualInfo;
106
107typedef struct {
108 int x, y;
109 int width, height ;
110 int visualid ;
111} EphyrHostWindowAttributes;
112
113typedef struct {
114 int x,y,width,height;
115} EphyrBox;
116
117typedef struct {
118 short x1,y1,x2,y2;
119} EphyrRect;
120
95int 121int
96hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height); 122hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
97 123
@@ -167,9 +193,60 @@ hostx_paint_rect(EphyrScreenInfo screen,
167 193
168 194
169void 195void
170hostx_load_keymap(void); 196hostx_load_keymap (void);
171 197
172int 198int
173hostx_get_event(EphyrHostXEvent *ev); 199hostx_get_event (EphyrHostXEvent *ev);
174 200
175#endif 201void*
202hostx_get_display (void) ;
203
204int
205hostx_get_window (int a_screen_number) ;
206
207int
208hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr) ;
209
210int
211hostx_get_extension_info (const char *a_ext_name,
212 int *a_major_opcode,
213 int *a_first_even,
214 int *a_first_error) ;
215int
216hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
217 int *a_num_entries) ;
218
219int hostx_create_window (int a_screen_number,
220 EphyrBox *a_geometry,
221 int a_visual_id,
222 int *a_host_win /*out parameter*/) ;
223
224int hostx_destroy_window (int a_win) ;
225
226int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
227
228
229int hostx_set_window_bounding_rectangles (int a_window,
230 EphyrRect *a_rects,
231 int a_num_rects) ;
232
233int hostx_set_window_clipping_rectangles (int a_window,
234 EphyrRect *a_rects,
235 int a_num_rects) ;
236int hostx_has_xshape (void) ;
237
238#ifdef XEPHYR_DRI
239int hostx_lookup_peer_window (void *a_local_window,
240 int *a_host_peer /*out parameter*/) ;
241int
242hostx_allocate_resource_id_peer (int a_local_resource_id,
243 int *a_remote_resource_id) ;
244int
245hostx_get_resource_id_peer (int a_local_resource_id,
246 int *a_remote_resource_id) ;
247int hostx_has_dri (void) ;
248
249int hostx_has_glx (void) ;
250#endif /*XEPHYR_DRI*/
251
252#endif /*_XLIBS_STUFF_H_*/
diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
index 20fae554a..07ab8c859 100644
--- a/hw/kdrive/src/Makefile.am
+++ b/hw/kdrive/src/Makefile.am
@@ -37,4 +37,4 @@ libkdrive_a_SOURCES = \
37 $(top_srcdir)/mi/miinitext.c 37 $(top_srcdir)/mi/miinitext.c
38 38
39libkdrivestubs_a_SOURCES = \ 39libkdrivestubs_a_SOURCES = \
40 $(top_srcdir)/fb/fbcmap.c 40 $(top_srcdir)/fb/fbcmap_mi.c
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 563d3439f..3b9f15c28 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -425,6 +425,8 @@
425/* Support DRI extension */ 425/* Support DRI extension */
426#undef XF86DRI 426#undef XF86DRI
427 427
428#undef XEPHYR_DRI
429
428/* Build DBE support */ 430/* Build DBE support */
429#undef DBE 431#undef DBE
430 432
diff --git a/os/utils.c b/os/utils.c
index 36c8dfeb3..31cb0af92 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -160,6 +160,7 @@ _X_EXPORT Bool noFontCacheExtension = FALSE;
160#endif 160#endif
161#ifdef GLXEXT 161#ifdef GLXEXT
162_X_EXPORT Bool noGlxExtension = FALSE; 162_X_EXPORT Bool noGlxExtension = FALSE;
163_X_EXPORT Bool noGlxVisualInit = FALSE;
163#endif 164#endif
164#ifdef SCREENSAVER 165#ifdef SCREENSAVER
165_X_EXPORT Bool noScreenSaverExtension = FALSE; 166_X_EXPORT Bool noScreenSaverExtension = FALSE;