diff options
author | Dodji Seketeli <dodji@openedhand.com> | 2007-10-03 16:13:16 +0200 |
---|---|---|
committer | Dodji Seketeli <dodji@openedhand.com> | 2007-10-03 16:14:08 +0200 |
commit | 604ebb5a6de372e6a8a96e0ee997db7929126860 (patch) | |
tree | 72523d93657c444198a044282fe342edb9492d9e | |
parent | 1365aeff5499a051375e43a9fcbf54733ac93929 (diff) | |
parent | 4ba76a7e2b62d26f43c0e670de571afb75ec92f4 (diff) |
Merge Xephyr-XV/GL stuff into master
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 | ||
56 | void GlxWrapInitVisuals(miInitVisualsProcPtr *); | 56 | void GlxWrapInitVisuals(miInitVisualsProcPtr *); |
57 | 57 | ||
58 | extern Bool noGlxVisualInit; | ||
58 | #include "glcontextmodes.h" | 59 | #include "glcontextmodes.h" |
59 | 60 | ||
60 | struct ScreenVisualsRec { | 61 | struct 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]) | ||
726 | else | 727 | else |
727 | XVMC=no | 728 | XVMC=no |
728 | fi | 729 | fi |
@@ -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) |
@@ -722,6 +722,48 @@ exaDriverAlloc(void) | |||
722 | return xcalloc(1, sizeof(ExaDriverRec)); | 722 | return xcalloc(1, sizeof(ExaDriverRec)); |
723 | } | 723 | } |
724 | 724 | ||
725 | static Bool | ||
726 | exaDriverValidateEntryPoints (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 | ||
106 | Bool | ||
107 | fbSetVisualTypesAndMasks (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 | /*@{*/ | ||
51 | typedef struct __DRIdisplayRec __DRIdisplay; | ||
52 | typedef struct __DRIscreenRec __DRIscreen; | ||
53 | typedef struct __DRIcontextRec __DRIcontext; | ||
54 | typedef struct __DRIdrawableRec __DRIdrawable; | ||
55 | typedef struct __DRIdriverRec __DRIdriver; | ||
56 | typedef struct __DRIframebufferRec __DRIframebuffer; | ||
57 | typedef struct __DRIversionRec __DRIversion; | ||
58 | typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods; | ||
59 | typedef unsigned long __DRIid; | ||
60 | typedef 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 | */ | ||
76 | typedef 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 | */ | ||
85 | typedef 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 | */ | ||
92 | typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name ); | ||
93 | /*@}*/ | ||
94 | |||
95 | |||
96 | /** | ||
97 | * \name Functions and data provided by the driver. | ||
98 | */ | ||
99 | /*@{*/ | ||
100 | |||
101 | typedef 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); | ||
108 | typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC; | ||
109 | extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727; | ||
110 | |||
111 | |||
112 | /** | ||
113 | * XML document describing the configuration options supported by the | ||
114 | * driver. | ||
115 | */ | ||
116 | extern 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 | */ | ||
130 | struct __DRIversionRec { | ||
131 | int major; /**< Major version number. */ | ||
132 | int minor; /**< Minor version number. */ | ||
133 | int patch; /**< Patch-level. */ | ||
134 | }; | ||
135 | |||
136 | |||
137 | typedef void (*__DRIfuncPtr)(void); | ||
138 | |||
139 | struct __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 | */ | ||
275 | struct __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 | */ | ||
295 | struct __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 | */ | ||
382 | struct __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 | */ | ||
425 | struct __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 | ||
6 | noinst_LIBRARIES = libxephyr.a libxephyr-hostx.a | 6 | noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a |
7 | 7 | ||
8 | bin_PROGRAMS = Xephyr | 8 | bin_PROGRAMS = Xephyr |
9 | 9 | ||
10 | |||
11 | libxephyr_hostx_a_SOURCES = \ | ||
12 | hostx.c \ | ||
13 | hostx.h | ||
14 | |||
15 | libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@ | ||
16 | |||
17 | libxephyr_hostxv_a_SOURCES= \ | ||
18 | ephyrhostvideo.c \ | ||
19 | ephyrhostvideo.h | ||
20 | |||
10 | libxephyr_a_SOURCES = \ | 21 | libxephyr_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 | |
17 | libxephyr_hostx_a_SOURCES = \ | ||
18 | hostx.c \ | ||
19 | hostx.h | ||
20 | 42 | ||
21 | libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@ | 43 | libxephyr_a_CFLAGS = \ |
44 | @LIBDRM_CFLAGS@ \ | ||
45 | -I$(top_srcdir) \ | ||
46 | @DRIPROTO_CFLAGS@ | ||
22 | 47 | ||
23 | Xephyr_SOURCES = \ | 48 | Xephyr_SOURCES = \ |
24 | ephyrinit.c | 49 | ephyrinit.c |
@@ -26,13 +51,17 @@ Xephyr_SOURCES = \ | |||
26 | Xephyr_LDADD = \ | 51 | Xephyr_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 | ||
33 | Xephyr_DEPENDENCIES = \ | 61 | Xephyr_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 | ||
38 | relink: | 67 | relink: |
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 | |||
4 | Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. | ||
5 | Copyright 2000 VA Linux Systems, Inc. | ||
6 | All Rights Reserved. | ||
7 | |||
8 | Permission is hereby granted, free of charge, to any person obtaining a | ||
9 | copy of this software and associated documentation files (the | ||
10 | "Software"), to deal in the Software without restriction, including | ||
11 | without limitation the rights to use, copy, modify, merge, publish, | ||
12 | distribute, sub license, and/or sell copies of the Software, and to | ||
13 | permit persons to whom the Software is furnished to do so, subject to | ||
14 | the following conditions: | ||
15 | |||
16 | The above copyright notice and this permission notice (including the | ||
17 | next paragraph) shall be included in all copies or substantial portions | ||
18 | of the Software. | ||
19 | |||
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
21 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
23 | IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
24 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
26 | SOFTWARE 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 | |||
61 | static XExtensionInfo _xf86dri_info_data; | ||
62 | static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; | ||
63 | static 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 | |||
74 | static int close_display(Display *dpy, XExtCodes *extCodes); | ||
75 | static /* 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 | |||
89 | static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info, | ||
90 | xf86dri_extension_name, | ||
91 | &xf86dri_extension_hooks, | ||
92 | 0, NULL) | ||
93 | |||
94 | static 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 | |||
110 | Bool XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable); | ||
111 | Bool XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable); | ||
112 | |||
113 | Bool 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 | |||
129 | Bool 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 | |||
161 | Bool | ||
162 | XF86DRIQueryDirectRenderingCapable (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 | |||
189 | Bool | ||
190 | XF86DRIOpenConnection (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 | |||
237 | Bool 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 | |||
268 | Bool 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 | |||
290 | Bool 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 | |||
340 | Bool 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 | |||
376 | Bool 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 | |||
387 | GLboolean 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 | |||
409 | GLboolean 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 | |||
439 | GLboolean 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 | |||
461 | Bool 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 | |||
546 | Bool | ||
547 | XF86DRIGetDeviceInfo (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 | |||
600 | Bool | ||
601 | XF86DRIOpenFullScreen(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 | |||
611 | Bool | ||
612 | XF86DRICloseFullScreen(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 | ||
39 | extern int KdTsPhyScreen; | 42 | extern int KdTsPhyScreen; |
40 | KdKeyboardInfo *ephyrKbd; | 43 | KdKeyboardInfo *ephyrKbd; |
41 | KdPointerInfo *ephyrMouse; | 44 | KdPointerInfo *ephyrMouse; |
42 | EphyrKeySyms ephyrKeySyms; | 45 | EphyrKeySyms ephyrKeySyms; |
46 | Bool ephyrNoDRI=FALSE ; | ||
47 | Bool ephyrNoXV=FALSE ; | ||
43 | 48 | ||
44 | static int mouseState = 0; | 49 | static int mouseState = 0; |
45 | 50 | ||
@@ -49,6 +54,7 @@ typedef struct _EphyrInputPrivate { | |||
49 | 54 | ||
50 | Bool EphyrWantGrayScale = 0; | 55 | Bool EphyrWantGrayScale = 0; |
51 | 56 | ||
57 | |||
52 | Bool | 58 | Bool |
53 | ephyrInitialize (KdCardInfo *card, EphyrPriv *priv) | 59 | ephyrInitialize (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 | |||
1028 | KdKeyboardDriver EphyrKeyboardDriver = { | 1054 | KdKeyboardDriver 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); | |||
194 | void | 194 | void |
195 | ephyrDrawFini(ScreenPtr pScreen); | 195 | ephyrDrawFini(ScreenPtr pScreen); |
196 | 196 | ||
197 | /*ephyvideo.c*/ | ||
198 | |||
199 | Bool 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 | |||
54 | Bool | ||
55 | ephyrDRIQueryDirectRenderingCapable (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 | |||
69 | Bool | ||
70 | ephyrDRIOpenConnection (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 | |||
92 | Bool | ||
93 | ephyrDRIAuthConnection (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 | |||
104 | Bool | ||
105 | ephyrDRICloseConnection (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 | |||
116 | Bool | ||
117 | ephyrDRIGetClientDriverName (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 | |||
146 | Bool | ||
147 | ephyrDRICreateContext (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 | |||
168 | Bool | ||
169 | ephyrDRIDestroyContext (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 | |||
181 | Bool | ||
182 | ephyrDRICreateDrawable (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 | |||
196 | Bool | ||
197 | ephyrDRIDestroyDrawable (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 | |||
205 | Bool | ||
206 | ephyrDRIGetDrawableInfo (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 ; | ||
264 | out: | ||
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 | |||
270 | Bool | ||
271 | ephyrDRIGetDeviceInfo (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 | |||
34 | Bool ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable) ; | ||
35 | Bool ephyrDRIOpenConnection (int screen, drm_handle_t *a_sarea, char **a_bus_id_string) ; | ||
36 | Bool ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic) ; | ||
37 | Bool ephyrDRICloseConnection (int a_screen) ; | ||
38 | Bool 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) ; | ||
43 | Bool ephyrDRICreateContext (int a_screen, | ||
44 | int a_visual_id, | ||
45 | unsigned long int *a_returned_ctx_id, | ||
46 | drm_context_t *a_hw_ctx) ; | ||
47 | Bool ephyrDRIDestroyContext (int a_screen, | ||
48 | int a_context_id) ; | ||
49 | Bool ephyrDRICreateDrawable (int a_screen, | ||
50 | int a_drawable, | ||
51 | drm_drawable_t *a_hw_drawable) ; | ||
52 | Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ; | ||
53 | Bool 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) ; | ||
67 | Bool 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 | |||
61 | typedef struct { | ||
62 | WindowPtr local ; | ||
63 | int remote ; | ||
64 | } EphyrWindowPair; | ||
65 | |||
66 | typedef struct { | ||
67 | int foo; | ||
68 | } EphyrDRIWindowPrivRec; | ||
69 | typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr; | ||
70 | |||
71 | typedef struct { | ||
72 | CreateWindowProcPtr CreateWindow ; | ||
73 | DestroyWindowProcPtr DestroyWindow ; | ||
74 | MoveWindowProcPtr MoveWindow ; | ||
75 | PositionWindowProcPtr PositionWindow ; | ||
76 | ClipNotifyProcPtr ClipNotify ; | ||
77 | } EphyrDRIScreenPrivRec; | ||
78 | typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr; | ||
79 | |||
80 | static int DRIErrorBase; | ||
81 | |||
82 | static DISPATCH_PROC(ProcXF86DRIQueryVersion); | ||
83 | static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable); | ||
84 | static DISPATCH_PROC(ProcXF86DRIOpenConnection); | ||
85 | static DISPATCH_PROC(ProcXF86DRICloseConnection); | ||
86 | static DISPATCH_PROC(ProcXF86DRIGetClientDriverName); | ||
87 | static DISPATCH_PROC(ProcXF86DRICreateContext); | ||
88 | static DISPATCH_PROC(ProcXF86DRIDestroyContext); | ||
89 | static DISPATCH_PROC(ProcXF86DRICreateDrawable); | ||
90 | static DISPATCH_PROC(ProcXF86DRIDestroyDrawable); | ||
91 | static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo); | ||
92 | static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo); | ||
93 | static DISPATCH_PROC(ProcXF86DRIDispatch); | ||
94 | static DISPATCH_PROC(ProcXF86DRIAuthConnection); | ||
95 | |||
96 | static DISPATCH_PROC(SProcXF86DRIQueryVersion); | ||
97 | static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable); | ||
98 | static DISPATCH_PROC(SProcXF86DRIDispatch); | ||
99 | |||
100 | static void XF86DRIResetProc(ExtensionEntry* extEntry); | ||
101 | |||
102 | static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ; | ||
103 | static Bool ephyrDRICreateWindow (WindowPtr a_win) ; | ||
104 | static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ; | ||
105 | static void ephyrDRIMoveWindow (WindowPtr a_win, | ||
106 | int a_x, int a_y, | ||
107 | WindowPtr a_siblings, | ||
108 | VTKind a_kind); | ||
109 | static Bool ephyrDRIPositionWindow (WindowPtr a_win, | ||
110 | int x, int y) ; | ||
111 | static void ephyrDRIClipNotify (WindowPtr a_win, | ||
112 | int a_x, int a_y) ; | ||
113 | |||
114 | static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ; | ||
115 | static Bool destroyHostPeerWindow (const WindowPtr a_win) ; | ||
116 | static Bool findWindowPairFromLocal (WindowPtr a_local, | ||
117 | EphyrWindowPair **a_pair); | ||
118 | |||
119 | static unsigned char DRIReqCode = 0; | ||
120 | |||
121 | static int ephyrDRIGeneration=-1 ; | ||
122 | static int ephyrDRIWindowIndex=-1 ; | ||
123 | static 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 | |||
131 | Bool | ||
132 | ephyrDRIExtensionInit (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 ; | ||
190 | out: | ||
191 | EPHYR_LOG ("leave\n") ; | ||
192 | return is_ok ; | ||
193 | } | ||
194 | |||
195 | static Bool | ||
196 | ephyrDRIScreenInit (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 ; | ||
230 | out: | ||
231 | return is_ok ; | ||
232 | } | ||
233 | |||
234 | static Bool | ||
235 | ephyrDRICreateWindow (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 | |||
262 | static Bool | ||
263 | ephyrDRIDestroyWindow (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 | |||
295 | static void | ||
296 | ephyrDRIMoveWindow (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 | |||
352 | out: | ||
353 | EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; | ||
354 | /*do cleanup here*/ | ||
355 | } | ||
356 | |||
357 | static Bool | ||
358 | ephyrDRIPositionWindow (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 | |||
404 | out: | ||
405 | EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; | ||
406 | /*do cleanup here*/ | ||
407 | return is_ok ; | ||
408 | } | ||
409 | |||
410 | static void | ||
411 | ephyrDRIClipNotify (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 | ®ION_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 | |||
468 | out: | ||
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 | */ | ||
486 | static Bool | ||
487 | EphyrDuplicateVisual (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 ; | ||
594 | out: | ||
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 | */ | ||
609 | static Bool | ||
610 | EphyrMirrorHostVisuals (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 ; | ||
637 | out: | ||
638 | EPHYR_LOG ("leave\n") ; | ||
639 | return is_ok; | ||
640 | } | ||
641 | |||
642 | |||
643 | /*ARGSUSED*/ | ||
644 | static void | ||
645 | XF86DRIResetProc ( | ||
646 | ExtensionEntry* extEntry | ||
647 | ) | ||
648 | { | ||
649 | } | ||
650 | |||
651 | static int | ||
652 | ProcXF86DRIQueryVersion (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 | |||
678 | static int | ||
679 | ProcXF86DRIQueryDirectRenderingCapable (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 | |||
716 | static int | ||
717 | ProcXF86DRIOpenConnection (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 | |||
759 | static int | ||
760 | ProcXF86DRIAuthConnection (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 | |||
786 | static int | ||
787 | ProcXF86DRICloseConnection (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 | |||
805 | static int | ||
806 | ProcXF86DRIGetClientDriverName (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 | |||
844 | static int | ||
845 | ProcXF86DRICreateContext (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 | |||
890 | static int | ||
891 | ProcXF86DRIDestroyContext (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 | |||
910 | static Bool | ||
911 | getWindowVisual (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 | ||
932 | static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ; | ||
933 | |||
934 | static Bool | ||
935 | appendWindowPairToList (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 | |||
954 | static Bool | ||
955 | findWindowPairFromLocal (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 | |||
974 | static Bool | ||
975 | createHostPeerWindow (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 ; | ||
1010 | out: | ||
1011 | EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ; | ||
1012 | return is_ok ; | ||
1013 | } | ||
1014 | |||
1015 | static Bool | ||
1016 | destroyHostPeerWindow (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 | |||
1031 | out: | ||
1032 | EPHYR_LOG ("leave\n") ; | ||
1033 | return is_ok; | ||
1034 | } | ||
1035 | |||
1036 | static int | ||
1037 | ProcXF86DRICreateDrawable (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 | |||
1101 | static int | ||
1102 | ProcXF86DRIDestroyDrawable (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 | |||
1145 | static int | ||
1146 | ProcXF86DRIGetDrawableInfo (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 | |||
1280 | static int | ||
1281 | ProcXF86DRIGetDeviceInfo (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 | |||
1331 | static int | ||
1332 | ProcXF86DRIDispatch (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 | |||
1402 | static int | ||
1403 | SProcXF86DRIQueryVersion (register ClientPtr client) | ||
1404 | { | ||
1405 | register int n; | ||
1406 | REQUEST(xXF86DRIQueryVersionReq); | ||
1407 | swaps(&stuff->length, n); | ||
1408 | return ProcXF86DRIQueryVersion(client); | ||
1409 | } | ||
1410 | |||
1411 | static int | ||
1412 | SProcXF86DRIQueryDirectRenderingCapable (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 | |||
1421 | static int | ||
1422 | SProcXF86DRIDispatch (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__ | ||
30 | Bool 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 | |||
56 | int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ; | ||
57 | int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ; | ||
58 | int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ; | ||
59 | int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ; | ||
60 | int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ; | ||
61 | int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ; | ||
62 | int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
63 | int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
64 | int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc); | ||
65 | int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc); | ||
66 | int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc); | ||
67 | int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc); | ||
68 | int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
69 | int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
70 | int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
71 | int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
72 | int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
73 | int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
74 | int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
75 | int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
76 | int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
77 | int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ; | ||
78 | |||
79 | Bool | ||
80 | ephyrHijackGLXExtension (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 | |||
147 | int | ||
148 | ephyrGLXQueryVersion(__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 ; | ||
180 | out: | ||
181 | EPHYR_LOG ("leave\n") ; | ||
182 | return res; | ||
183 | } | ||
184 | |||
185 | int | ||
186 | ephyrGLXQueryVersionSwap (__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 | |||
197 | static int | ||
198 | ephyrGLXGetVisualConfigsReal (__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 | |||
246 | out: | ||
247 | EPHYR_LOG ("leave\n") ; | ||
248 | if (props_buf) { | ||
249 | xfree (props_buf) ; | ||
250 | props_buf = NULL ; | ||
251 | } | ||
252 | return res ; | ||
253 | } | ||
254 | |||
255 | static int | ||
256 | ephyrGLXGetFBConfigsSGIXReal (__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 | |||
304 | out: | ||
305 | EPHYR_LOG ("leave\n") ; | ||
306 | if (props_buf) { | ||
307 | xfree (props_buf) ; | ||
308 | props_buf = NULL ; | ||
309 | } | ||
310 | return res ; | ||
311 | } | ||
312 | |||
313 | int | ||
314 | ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc) | ||
315 | { | ||
316 | return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ; | ||
317 | } | ||
318 | |||
319 | int | ||
320 | ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc) | ||
321 | { | ||
322 | return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ; | ||
323 | } | ||
324 | |||
325 | |||
326 | int | ||
327 | ephyrGLXClientInfo(__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 | |||
339 | out: | ||
340 | EPHYR_LOG ("leave\n") ; | ||
341 | return res ; | ||
342 | } | ||
343 | |||
344 | int | ||
345 | ephyrGLXClientInfoSwap (__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 | |||
358 | int | ||
359 | ephyrGLXQueryServerString(__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 | |||
388 | out: | ||
389 | EPHYR_LOG ("leave\n") ; | ||
390 | if (server_string) { | ||
391 | xfree (server_string) ; | ||
392 | server_string = NULL; | ||
393 | } | ||
394 | return res ; | ||
395 | } | ||
396 | |||
397 | int | ||
398 | ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) | ||
399 | { | ||
400 | EPHYR_LOG_ERROR ("not yet implemented\n") ; | ||
401 | return BadImplementation ; | ||
402 | } | ||
403 | |||
404 | |||
405 | int | ||
406 | ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc) | ||
407 | { | ||
408 | return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ; | ||
409 | } | ||
410 | |||
411 | int | ||
412 | ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc) | ||
413 | { | ||
414 | return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ; | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | ephyrGLXCreateContextReal (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; | ||
458 | out: | ||
459 | EPHYR_LOG ("leave\n") ; | ||
460 | return res ; | ||
461 | } | ||
462 | |||
463 | int | ||
464 | ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc) | ||
465 | { | ||
466 | xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; | ||
467 | |||
468 | return ephyrGLXCreateContextReal (req, FALSE) ; | ||
469 | } | ||
470 | |||
471 | int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc) | ||
472 | { | ||
473 | xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; | ||
474 | return ephyrGLXCreateContextReal (req, TRUE) ; | ||
475 | } | ||
476 | |||
477 | static int | ||
478 | ephyrGLXDestroyContextReal (__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 | |||
494 | out: | ||
495 | EPHYR_LOG ("leave\n") ; | ||
496 | return res ; | ||
497 | } | ||
498 | |||
499 | int | ||
500 | ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) | ||
501 | { | ||
502 | return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ; | ||
503 | } | ||
504 | |||
505 | int | ||
506 | ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) | ||
507 | { | ||
508 | return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ; | ||
509 | } | ||
510 | |||
511 | static int | ||
512 | ephyrGLXMakeCurrentReal (__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 ; | ||
551 | out: | ||
552 | EPHYR_LOG ("leave\n") ; | ||
553 | return res ; | ||
554 | } | ||
555 | |||
556 | int | ||
557 | ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) | ||
558 | { | ||
559 | return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ; | ||
560 | } | ||
561 | |||
562 | int | ||
563 | ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) | ||
564 | { | ||
565 | return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ; | ||
566 | } | ||
567 | |||
568 | static int | ||
569 | ephyrGLXGetStringReal (__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 ; | ||
613 | out: | ||
614 | EPHYR_LOG ("leave\n") ; | ||
615 | return res ; | ||
616 | } | ||
617 | |||
618 | int | ||
619 | ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) | ||
620 | { | ||
621 | return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ; | ||
622 | } | ||
623 | |||
624 | int | ||
625 | ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) | ||
626 | { | ||
627 | return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ; | ||
628 | } | ||
629 | |||
630 | static int | ||
631 | ephyrGLXGetIntegervReal (__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 | |||
662 | out: | ||
663 | EPHYR_LOG ("leave\n") ; | ||
664 | return res ; | ||
665 | } | ||
666 | |||
667 | int | ||
668 | ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) | ||
669 | { | ||
670 | return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ; | ||
671 | } | ||
672 | |||
673 | int | ||
674 | ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) | ||
675 | { | ||
676 | return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ; | ||
677 | } | ||
678 | |||
679 | static int | ||
680 | ephyrGLXIsDirectReal (__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 | |||
704 | out: | ||
705 | EPHYR_LOG ("leave\n") ; | ||
706 | return res ; | ||
707 | } | ||
708 | |||
709 | int | ||
710 | ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) | ||
711 | { | ||
712 | return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ; | ||
713 | } | ||
714 | |||
715 | int | ||
716 | ephyrGLXIsDirectSwap (__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> | ||
32 | Bool 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 | ||
45 | enum VisualConfRequestType { | ||
46 | EPHYR_GET_FB_CONFIG, | ||
47 | EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX, | ||
48 | EPHYR_GET_VISUAL_CONFIGS | ||
49 | |||
50 | }; | ||
51 | |||
52 | static 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); | ||
59 | Bool | ||
60 | ephyrHostGLXGetMajorOpcode (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 ; | ||
78 | out: | ||
79 | EPHYR_LOG ("release\n") ; | ||
80 | return is_ok ; | ||
81 | } | ||
82 | |||
83 | Bool | ||
84 | ephyrHostGLXQueryVersion (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 ; | ||
119 | out: | ||
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 | */ | ||
133 | typedef 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 | |||
146 | Bool | ||
147 | ephyrHostGLXGetStringFromServer (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 ; | ||
221 | out: | ||
222 | EPHYR_LOG ("leave\n") ; | ||
223 | return is_ok ; | ||
224 | } | ||
225 | |||
226 | static Bool | ||
227 | ephyrHostGLXGetVisualConfigsInternal (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 | |||
336 | out: | ||
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 | |||
349 | Bool | ||
350 | ephyrHostGLXGetVisualConfigs (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 | |||
370 | Bool | ||
371 | ephyrHostGLXVendorPrivGetFBConfigsSGIX (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 | |||
390 | Bool | ||
391 | ephyrHostGLXSendClientInfo (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 | |||
425 | out: | ||
426 | return is_ok ; | ||
427 | } | ||
428 | |||
429 | Bool | ||
430 | ephyrHostGLXCreateContext (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 | |||
472 | out: | ||
473 | EPHYR_LOG ("leave\n") ; | ||
474 | return is_ok ; | ||
475 | } | ||
476 | |||
477 | Bool | ||
478 | ephyrHostDestroyContext (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 | |||
507 | out: | ||
508 | EPHYR_LOG ("leave\n") ; | ||
509 | return is_ok ; | ||
510 | } | ||
511 | |||
512 | Bool | ||
513 | ephyrHostGLXMakeCurrent (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 | |||
561 | out: | ||
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 | |||
601 | Bool | ||
602 | ephyrHostGetIntegerValue (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 | |||
638 | out: | ||
639 | EPHYR_LOG ("leave\n") ; | ||
640 | return is_ok ; | ||
641 | } | ||
642 | |||
643 | Bool | ||
644 | ephyrHostIsContextDirect (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 | |||
681 | out: | ||
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 | |||
31 | enum EphyrHostGLXGetStringOps { | ||
32 | EPHYR_HOST_GLX_UNDEF, | ||
33 | EPHYR_HOST_GLX_QueryServerString, | ||
34 | EPHYR_HOST_GLX_GetString, | ||
35 | }; | ||
36 | |||
37 | Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ; | ||
38 | Bool ephyrHostGLXGetStringFromServer (int a_screen_number, | ||
39 | int a_string_name, | ||
40 | enum EphyrHostGLXGetStringOps a_op, | ||
41 | char **a_string) ; | ||
42 | Bool 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) ; | ||
47 | Bool | ||
48 | ephyrHostGLXVendorPrivGetFBConfigsSGIX (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); | ||
53 | Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ; | ||
54 | Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor, | ||
55 | const char* a_extension_list) ; | ||
56 | Bool 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 | |||
62 | Bool ephyrHostDestroyContext (int a_ctxt_id) ; | ||
63 | |||
64 | Bool ephyrHostGLXMakeCurrent (int a_drawable, int a_glx_ctxt_id, | ||
65 | int a_olg_ctxt_tag, int *a_ctxt_tag) ; | ||
66 | |||
67 | Bool ephyrHostGetIntegerValue (int a_current_context_tag, | ||
68 | int a_int, | ||
69 | int *a_val) ; | ||
70 | |||
71 | Bool 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 | |||
54 | Bool | ||
55 | ephyrHostProxyDoForward (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 | |||
90 | out: | ||
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 | |||
32 | struct 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 | |||
46 | Bool | ||
47 | ephyrHostProxyDoForward (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 | |||
51 | static XExtensionInfo _xv_info_data; | ||
52 | static XExtensionInfo *xv_info = &_xv_info_data; | ||
53 | static char *xv_extension_name = XvName; | ||
54 | static char *xv_error_string(Display *dpy, int code, XExtCodes *codes, | ||
55 | char * buf, int n); | ||
56 | static int xv_close_display(Display *dpy, XExtCodes *codes); | ||
57 | static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire); | ||
58 | |||
59 | static 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 | |||
74 | static 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 | |||
95 | static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info) | ||
96 | |||
97 | |||
98 | static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info, | ||
99 | xv_extension_name, | ||
100 | &xv_extension_hooks, | ||
101 | XvNumEvents, NULL) | ||
102 | |||
103 | static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name, | ||
104 | XvNumErrors, xv_error_list) | ||
105 | |||
106 | struct _EphyrHostXVAdaptorArray { | ||
107 | XvAdaptorInfo *adaptors ; | ||
108 | unsigned int nb_adaptors ; | ||
109 | }; | ||
110 | |||
111 | /*heavily copied from libx11*/ | ||
112 | #define BUFSIZE 2048 | ||
113 | static void | ||
114 | ephyrHostXVLogXErrorEvent (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 | |||
224 | static int | ||
225 | ephyrHostXVErrorHandler (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 | |||
233 | void | ||
234 | ephyrHostXVInit (void) | ||
235 | { | ||
236 | static Bool s_initialized ; | ||
237 | |||
238 | if (s_initialized) | ||
239 | return ; | ||
240 | XSetErrorHandler (ephyrHostXVErrorHandler) ; | ||
241 | s_initialized = TRUE ; | ||
242 | } | ||
243 | |||
244 | Bool | ||
245 | ephyrHostXVQueryAdaptors (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 | |||
270 | out: | ||
271 | EPHYR_LOG ("leave\n") ; | ||
272 | return is_ok ; | ||
273 | } | ||
274 | |||
275 | void | ||
276 | ephyrHostXVAdaptorArrayDelete (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 | |||
288 | int | ||
289 | ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) | ||
290 | { | ||
291 | EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; | ||
292 | return a_this->nb_adaptors ; | ||
293 | } | ||
294 | |||
295 | EphyrHostXVAdaptor* | ||
296 | ephyrHostXVAdaptorArrayAt (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 | |||
306 | char | ||
307 | ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) | ||
308 | { | ||
309 | EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; | ||
310 | return ((XvAdaptorInfo*)a_this)->type ; | ||
311 | } | ||
312 | |||
313 | const char* | ||
314 | ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) | ||
315 | { | ||
316 | EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ; | ||
317 | |||
318 | return ((XvAdaptorInfo*)a_this)->name ; | ||
319 | } | ||
320 | |||
321 | EphyrHostVideoFormat* | ||
322 | ephyrHostXVAdaptorGetVideoFormats (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 | |||
351 | int | ||
352 | ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) | ||
353 | { | ||
354 | EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; | ||
355 | |||
356 | return ((XvAdaptorInfo*)a_this)->num_ports ; | ||
357 | } | ||
358 | |||
359 | int | ||
360 | ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) | ||
361 | { | ||
362 | EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ; | ||
363 | |||
364 | return ((XvAdaptorInfo*)a_this)->base_id ; | ||
365 | } | ||
366 | |||
367 | Bool | ||
368 | ephyrHostXVAdaptorHasPutVideo (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 | |||
380 | Bool | ||
381 | ephyrHostXVAdaptorHasGetVideo (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 | |||
391 | Bool | ||
392 | ephyrHostXVAdaptorHasPutStill (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 | |||
404 | Bool | ||
405 | ephyrHostXVAdaptorHasGetStill (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 | |||
417 | Bool | ||
418 | ephyrHostXVAdaptorHasPutImage (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 | |||
430 | Bool | ||
431 | ephyrHostXVQueryEncodings (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 | |||
469 | void | ||
470 | ephyrHostEncodingsDelete (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 | |||
486 | void | ||
487 | ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) | ||
488 | { | ||
489 | if (!a_attributes) | ||
490 | return ; | ||
491 | XFree (a_attributes) ; | ||
492 | } | ||
493 | |||
494 | Bool | ||
495 | ephyrHostXVQueryPortAttributes (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 | |||
509 | Bool | ||
510 | ephyrHostXVQueryImageFormats (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 | |||
526 | Bool | ||
527 | ephyrHostXVSetPortAttribute (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 | |||
552 | Bool | ||
553 | ephyrHostXVGetPortAttribute (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 | |||
577 | out: | ||
578 | EPHYR_LOG ("leave\n") ; | ||
579 | return ret ; | ||
580 | } | ||
581 | |||
582 | Bool | ||
583 | ephyrHostXVQueryBestSize (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 | |||
616 | out: | ||
617 | EPHYR_LOG ("leave\n") ; | ||
618 | return is_ok ; | ||
619 | } | ||
620 | |||
621 | static Bool | ||
622 | xv_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 | |||
660 | Bool | ||
661 | ephyrHostXVQueryImageAttributes (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 | |||
711 | out: | ||
712 | UnlockDisplay (dpy) ; | ||
713 | SyncHandle (); | ||
714 | return ret ; | ||
715 | } | ||
716 | |||
717 | Bool | ||
718 | ephyrHostGetAtom (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 | |||
734 | char* | ||
735 | ephyrHostGetAtomName (int a_atom) | ||
736 | { | ||
737 | return XGetAtomName (hostx_get_display (), a_atom) ; | ||
738 | } | ||
739 | |||
740 | void | ||
741 | ephyrHostFree (void *a_pointer) | ||
742 | { | ||
743 | if (a_pointer) | ||
744 | XFree (a_pointer) ; | ||
745 | } | ||
746 | |||
747 | Bool | ||
748 | ephyrHostXVPutImage (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 | |||
817 | out: | ||
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 | |||
834 | Bool | ||
835 | ephyrHostXVPutVideo (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 | |||
863 | out: | ||
864 | if (gc) { | ||
865 | XFreeGC (dpy, gc) ; | ||
866 | gc = NULL ; | ||
867 | } | ||
868 | return is_ok ; | ||
869 | } | ||
870 | |||
871 | Bool | ||
872 | ephyrHostXVGetVideo (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 | |||
900 | out: | ||
901 | if (gc) { | ||
902 | XFreeGC (dpy, gc) ; | ||
903 | gc = NULL ; | ||
904 | } | ||
905 | return is_ok ; | ||
906 | } | ||
907 | |||
908 | Bool | ||
909 | ephyrHostXVPutStill (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 | |||
937 | out: | ||
938 | if (gc) { | ||
939 | XFreeGC (dpy, gc) ; | ||
940 | gc = NULL ; | ||
941 | } | ||
942 | return is_ok ; | ||
943 | } | ||
944 | |||
945 | Bool | ||
946 | ephyrHostXVGetStill (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 | |||
974 | out: | ||
975 | if (gc) { | ||
976 | XFreeGC (dpy, gc) ; | ||
977 | gc = NULL ; | ||
978 | } | ||
979 | return is_ok ; | ||
980 | } | ||
981 | |||
982 | Bool | ||
983 | ephyrHostXVStopVideo (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 | |||
1000 | out: | ||
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 | |||
31 | typedef void* EphyrHostXVAdaptor ; | ||
32 | typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray ; | ||
33 | |||
34 | typedef struct _EphyrHostVideoFormat { | ||
35 | char depth ; | ||
36 | short visual_class; | ||
37 | } EphyrHostVideoFormat ; | ||
38 | |||
39 | typedef struct _EphyrHostRational { | ||
40 | int numerator ; | ||
41 | int denominator ; | ||
42 | } EphyrHostRational; | ||
43 | |||
44 | typedef struct _EphyrHostEncoding { | ||
45 | int id ; | ||
46 | char *name ; | ||
47 | unsigned short width, height ; | ||
48 | EphyrHostRational rate ; | ||
49 | } EphyrHostEncoding ; | ||
50 | |||
51 | typedef struct _EphyrHostAttribute { | ||
52 | int flags; | ||
53 | int min_value; | ||
54 | int max_value; | ||
55 | char *name; | ||
56 | } EphyrHostAttribute ; | ||
57 | |||
58 | typedef 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 | |||
87 | typedef struct { | ||
88 | unsigned short x1, y1, x2, y2 ; | ||
89 | } EphyrHostBox ; | ||
90 | |||
91 | void ephyrHostXVInit (void) ; | ||
92 | |||
93 | void ephyrHostFree (void *a_pointer) ; | ||
94 | |||
95 | /* | ||
96 | * host adaptor array | ||
97 | */ | ||
98 | Bool ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ; | ||
99 | void ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ; | ||
100 | int ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ; | ||
101 | EphyrHostXVAdaptor* ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this, | ||
102 | int a_index) ; | ||
103 | |||
104 | /* | ||
105 | * host adaptor | ||
106 | */ | ||
107 | |||
108 | char ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ; | ||
109 | const char* ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ; | ||
110 | EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats | ||
111 | (const EphyrHostXVAdaptor *a_this, | ||
112 | int *a_nb_formats) ; | ||
113 | int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ; | ||
114 | int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ; | ||
115 | |||
116 | Bool ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this, | ||
117 | Bool *a_result) ; | ||
118 | Bool ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this, | ||
119 | Bool *a_result) ; | ||
120 | Bool ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this, | ||
121 | Bool *a_result) ; | ||
122 | Bool ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this, | ||
123 | Bool *a_result) ; | ||
124 | Bool ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this, | ||
125 | Bool *a_result) ; | ||
126 | |||
127 | /* | ||
128 | * encoding | ||
129 | */ | ||
130 | Bool ephyrHostXVQueryEncodings (int a_port_id, | ||
131 | EphyrHostEncoding **a_encodings, | ||
132 | unsigned int *a_num_encodings) ; | ||
133 | |||
134 | void ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings, | ||
135 | int a_num_encodings) ; | ||
136 | |||
137 | /* | ||
138 | * attribute | ||
139 | */ | ||
140 | Bool ephyrHostXVQueryPortAttributes (int a_port_id, | ||
141 | EphyrHostAttribute **a_attributes, | ||
142 | int *a_num_attributes) ; | ||
143 | |||
144 | void ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ; | ||
145 | /* | ||
146 | * image format | ||
147 | */ | ||
148 | |||
149 | Bool ephyrHostXVQueryImageFormats (int a_port_id, | ||
150 | EphyrHostImageFormat **a_formats, | ||
151 | int *a_num_format) ; | ||
152 | /* | ||
153 | * Port Attribute Get/Set | ||
154 | */ | ||
155 | Bool ephyrHostXVSetPortAttribute (int a_port_id, | ||
156 | int a_atom, | ||
157 | int a_attr_value) ; | ||
158 | Bool ephyrHostXVGetPortAttribute (int a_port_id, | ||
159 | int a_atom, | ||
160 | int *a_attr_value) ; | ||
161 | /* | ||
162 | *size query | ||
163 | */ | ||
164 | Bool 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 | |||
173 | Bool 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 | */ | ||
183 | Bool ephyrHostGetAtom (const char* a_name, | ||
184 | Bool a_create_if_not_exists, | ||
185 | int *a_atom) ; | ||
186 | char* ephyrHostGetAtomName (int a_atom) ; | ||
187 | |||
188 | /* | ||
189 | *PutImage | ||
190 | * (ignore clipping for now) | ||
191 | */ | ||
192 | Bool 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 | */ | ||
212 | Bool 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 | |||
217 | Bool 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 | |||
222 | Bool 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 | |||
227 | Bool 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 | */ | ||
235 | Bool 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 | ||
31 | extern Window EphyrPreExistingHostWin; | 32 | extern Window EphyrPreExistingHostWin; |
32 | extern Bool EphyrWantGrayScale; | 33 | extern Bool EphyrWantGrayScale; |
33 | extern Bool kdHasPointer; | 34 | extern Bool kdHasPointer; |
34 | extern Bool kdHasKbd; | 35 | extern Bool kdHasKbd; |
36 | extern Bool ephyrNoDRI; | ||
37 | extern Bool ephyrNoXV; | ||
38 | extern Bool noGlxVisualInit; | ||
35 | 39 | ||
36 | void processScreenArg (char *screen_size, char *parent_id) ; | 40 | void 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(...) \ | ||
45 | LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\ | ||
46 | __FILE__, __LINE__, __func__) ; \ | ||
47 | LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__) | ||
48 | #endif /*nomadik_log*/ | ||
49 | |||
50 | #ifndef EPHYR_LOG_ERROR | ||
51 | #define EPHYR_LOG_ERROR(...) \ | ||
52 | LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\ | ||
53 | __FILE__, __LINE__, __func__) ; \ | ||
54 | LogMessageVerb(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) \ | ||
59 | if (!(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) \ | ||
64 | if (!(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 | |||
49 | static Bool ephyrProxyGetHostExtensionInfo (const char *a_ext_name, | ||
50 | int *a_major_opcode, | ||
51 | int *a_first_event, | ||
52 | int *a_first_error) ; | ||
53 | |||
54 | static int ephyrProxyProcDispatch (ClientPtr client) ; | ||
55 | |||
56 | static Bool | ||
57 | ephyrProxyGetHostExtensionInfo (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 | |||
66 | static int | ||
67 | ephyrProxyProcDispatch (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 | |||
81 | out: | ||
82 | return res ; | ||
83 | } | ||
84 | |||
85 | static void | ||
86 | ephyrProxyProcReset (ExtensionEntry *a_entry) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | Bool | ||
91 | ephyrProxyExtensionInit (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 | |||
115 | out: | ||
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 | |||
31 | Bool 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 | |||
41 | struct _EphyrXVPriv { | ||
42 | EphyrHostXVAdaptorArray *host_adaptors ; | ||
43 | KdVideoAdaptorPtr adaptors ; | ||
44 | int num_adaptors ; | ||
45 | }; | ||
46 | typedef struct _EphyrXVPriv EphyrXVPriv ; | ||
47 | |||
48 | struct _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 | }; | ||
59 | typedef struct _EphyrPortPriv EphyrPortPriv ; | ||
60 | |||
61 | static Bool DoSimpleClip (BoxPtr a_dst_drw, | ||
62 | BoxPtr a_clipper, | ||
63 | BoxPtr a_result) ; | ||
64 | |||
65 | static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ; | ||
66 | |||
67 | /* | ||
68 | static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ; | ||
69 | */ | ||
70 | |||
71 | static EphyrXVPriv* ephyrXVPrivNew (void) ; | ||
72 | static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ; | ||
73 | static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ; | ||
74 | static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ; | ||
75 | static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this, | ||
76 | ScreenPtr a_screen) ; | ||
77 | |||
78 | static 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 | |||
84 | static 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 | |||
90 | static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv, | ||
91 | const unsigned char *a_image, | ||
92 | int a_image_len) ; | ||
93 | |||
94 | static void ephyrStopVideo (KdScreenInfo *a_info, | ||
95 | pointer a_xv_priv, | ||
96 | Bool a_exit); | ||
97 | |||
98 | static int ephyrSetPortAttribute (KdScreenInfo *a_info, | ||
99 | Atom a_attr_name, | ||
100 | int a_attr_value, | ||
101 | pointer a_port_priv); | ||
102 | |||
103 | static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info, | ||
104 | Atom a_attr_name, | ||
105 | int *a_attr_value, | ||
106 | pointer a_port_priv); | ||
107 | |||
108 | static 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 | |||
118 | static 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 | |||
136 | static 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 | |||
143 | static 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 | |||
152 | static 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 | |||
161 | static 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 | |||
170 | static 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 | |||
179 | static 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); | ||
185 | static int s_base_port_id ; | ||
186 | |||
187 | /************** | ||
188 | * <helpers> | ||
189 | * ************/ | ||
190 | |||
191 | static Bool | ||
192 | DoSimpleClip (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 | |||
236 | static Bool | ||
237 | ephyrLocalAtomToHost (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. | ||
263 | static Bool | ||
264 | ephyrHostAtomToLocal (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 | |||
283 | out: | ||
284 | if (atom_name) { | ||
285 | ephyrHostFree (atom_name) ; | ||
286 | } | ||
287 | return is_ok ; | ||
288 | } | ||
289 | */ | ||
290 | |||
291 | /************** | ||
292 | *</helpers> | ||
293 | * ************/ | ||
294 | |||
295 | Bool | ||
296 | ephyrInitVideo (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 | |||
324 | out: | ||
325 | return is_ok ; | ||
326 | } | ||
327 | |||
328 | static EphyrXVPriv* | ||
329 | ephyrXVPrivNew (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 | |||
355 | error: | ||
356 | if (xv_priv) { | ||
357 | ephyrXVPrivDelete (xv_priv) ; | ||
358 | xv_priv = NULL ; | ||
359 | } | ||
360 | return NULL ; | ||
361 | } | ||
362 | |||
363 | static void | ||
364 | ephyrXVPrivDelete (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 | |||
382 | static KdVideoEncodingPtr | ||
383 | videoEncodingDup (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 | |||
403 | static KdAttributePtr | ||
404 | portAttributesDup (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 | |||
426 | static Bool | ||
427 | ephyrXVPrivQueryHostAdaptors (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 | |||
559 | out: | ||
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 | |||
572 | static Bool | ||
573 | ephyrXVPrivSetAdaptorsHooks (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 | |||
641 | static Bool | ||
642 | ephyrXVPrivRegisterAdaptors (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, ®istered_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 | |||
677 | out: | ||
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 | |||
690 | static Bool | ||
691 | ephyrXVPrivIsAttrValueValid (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 | |||
721 | static Bool | ||
722 | ephyrXVPrivGetImageBufSize (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 | |||
742 | out: | ||
743 | EPHYR_LOG ("leave\n") ; | ||
744 | return is_ok ; | ||
745 | } | ||
746 | |||
747 | static Bool | ||
748 | ephyrXVPrivSaveImageToPortPriv (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 | |||
769 | out: | ||
770 | return is_ok ; | ||
771 | EPHYR_LOG ("leave\n") ; | ||
772 | } | ||
773 | |||
774 | static void | ||
775 | ephyrStopVideo (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 | |||
790 | static int | ||
791 | ephyrSetPortAttribute (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 ; | ||
850 | out: | ||
851 | EPHYR_LOG ("leave\n") ; | ||
852 | return res ; | ||
853 | } | ||
854 | |||
855 | static int | ||
856 | ephyrGetPortAttribute (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 ; | ||
887 | out: | ||
888 | EPHYR_LOG ("leave\n") ; | ||
889 | return res ; | ||
890 | } | ||
891 | |||
892 | static void | ||
893 | ephyrQueryBestSize (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 | |||
920 | static int | ||
921 | ephyrPutImage (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 | |||
999 | out: | ||
1000 | EPHYR_LOG ("leave\n") ; | ||
1001 | return result ; | ||
1002 | } | ||
1003 | |||
1004 | static int | ||
1005 | ephyrReputImage (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 | |||
1041 | out: | ||
1042 | EPHYR_LOG ("leave\n") ; | ||
1043 | return result ; | ||
1044 | } | ||
1045 | |||
1046 | static int | ||
1047 | ephyrPutVideo (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 | |||
1092 | out: | ||
1093 | EPHYR_LOG ("leave\n") ; | ||
1094 | return result ; | ||
1095 | } | ||
1096 | |||
1097 | static int | ||
1098 | ephyrGetVideo (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 | |||
1143 | out: | ||
1144 | EPHYR_LOG ("leave\n") ; | ||
1145 | return result ; | ||
1146 | } | ||
1147 | |||
1148 | static int | ||
1149 | ephyrPutStill (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 | |||
1194 | out: | ||
1195 | EPHYR_LOG ("leave\n") ; | ||
1196 | return result ; | ||
1197 | } | ||
1198 | |||
1199 | static int | ||
1200 | ephyrGetStill (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 | |||
1245 | out: | ||
1246 | EPHYR_LOG ("leave\n") ; | ||
1247 | return result ; | ||
1248 | } | ||
1249 | |||
1250 | static int | ||
1251 | ephyrQueryImageAttributes (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 | |||
1275 | out: | ||
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 | ||
54 | extern 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 | ||
974 | void* | ||
975 | hostx_get_display(void) | ||
976 | { | ||
977 | return HostX.dpy ; | ||
978 | } | ||
979 | |||
980 | int | ||
981 | hostx_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 | |||
990 | int | ||
991 | hostx_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 | |||
1011 | int | ||
1012 | hostx_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 | |||
1030 | int | ||
1031 | hostx_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; | ||
1067 | out: | ||
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 | |||
1081 | typedef struct { | ||
1082 | int is_valid ; | ||
1083 | int local_id ; | ||
1084 | int remote_id ; | ||
1085 | } ResourcePair ; | ||
1086 | |||
1087 | #define RESOURCE_PEERS_SIZE 1024*10 | ||
1088 | static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ; | ||
1089 | |||
1090 | |||
1091 | int | ||
1092 | hostx_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 ; | ||
1141 | out: | ||
1142 | EPHYR_LOG ("leave\n") ; | ||
1143 | return is_ok ; | ||
1144 | } | ||
1145 | |||
1146 | int | ||
1147 | hostx_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 | |||
1157 | int | ||
1158 | hostx_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 | |||
1174 | int | ||
1175 | hostx_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 | |||
1211 | int | ||
1212 | hostx_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 | |||
1248 | int | ||
1249 | hostx_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 | ||
1262 | int | ||
1263 | hostx_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 | |||
1305 | int | ||
1306 | hostx_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 | |||
1325 | int | ||
1326 | hostx_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 | |||
1339 | int | ||
1340 | hostx_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 | ||
95 | typedef 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 | |||
107 | typedef struct { | ||
108 | int x, y; | ||
109 | int width, height ; | ||
110 | int visualid ; | ||
111 | } EphyrHostWindowAttributes; | ||
112 | |||
113 | typedef struct { | ||
114 | int x,y,width,height; | ||
115 | } EphyrBox; | ||
116 | |||
117 | typedef struct { | ||
118 | short x1,y1,x2,y2; | ||
119 | } EphyrRect; | ||
120 | |||
95 | int | 121 | int |
96 | hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height); | 122 | hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height); |
97 | 123 | ||
@@ -167,9 +193,60 @@ hostx_paint_rect(EphyrScreenInfo screen, | |||
167 | 193 | ||
168 | 194 | ||
169 | void | 195 | void |
170 | hostx_load_keymap(void); | 196 | hostx_load_keymap (void); |
171 | 197 | ||
172 | int | 198 | int |
173 | hostx_get_event(EphyrHostXEvent *ev); | 199 | hostx_get_event (EphyrHostXEvent *ev); |
174 | 200 | ||
175 | #endif | 201 | void* |
202 | hostx_get_display (void) ; | ||
203 | |||
204 | int | ||
205 | hostx_get_window (int a_screen_number) ; | ||
206 | |||
207 | int | ||
208 | hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr) ; | ||
209 | |||
210 | int | ||
211 | hostx_get_extension_info (const char *a_ext_name, | ||
212 | int *a_major_opcode, | ||
213 | int *a_first_even, | ||
214 | int *a_first_error) ; | ||
215 | int | ||
216 | hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals, | ||
217 | int *a_num_entries) ; | ||
218 | |||
219 | int hostx_create_window (int a_screen_number, | ||
220 | EphyrBox *a_geometry, | ||
221 | int a_visual_id, | ||
222 | int *a_host_win /*out parameter*/) ; | ||
223 | |||
224 | int hostx_destroy_window (int a_win) ; | ||
225 | |||
226 | int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ; | ||
227 | |||
228 | |||
229 | int hostx_set_window_bounding_rectangles (int a_window, | ||
230 | EphyrRect *a_rects, | ||
231 | int a_num_rects) ; | ||
232 | |||
233 | int hostx_set_window_clipping_rectangles (int a_window, | ||
234 | EphyrRect *a_rects, | ||
235 | int a_num_rects) ; | ||
236 | int hostx_has_xshape (void) ; | ||
237 | |||
238 | #ifdef XEPHYR_DRI | ||
239 | int hostx_lookup_peer_window (void *a_local_window, | ||
240 | int *a_host_peer /*out parameter*/) ; | ||
241 | int | ||
242 | hostx_allocate_resource_id_peer (int a_local_resource_id, | ||
243 | int *a_remote_resource_id) ; | ||
244 | int | ||
245 | hostx_get_resource_id_peer (int a_local_resource_id, | ||
246 | int *a_remote_resource_id) ; | ||
247 | int hostx_has_dri (void) ; | ||
248 | |||
249 | int 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 | ||
39 | libkdrivestubs_a_SOURCES = \ | 39 | libkdrivestubs_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; |