diff options
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr/ephyrdriext.c')
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrdriext.c | 2858 |
1 files changed, 1429 insertions, 1429 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c index 5f5fd3bff..3d3d18a39 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c @@ -1,1429 +1,1429 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.com> - * - * Copyright © 2007 OpenedHand Ltd - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of OpenedHand Ltd not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. OpenedHand Ltd makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - * This file is heavily copied from hw/xfree86/dri/xf86dri.c - * - * Authors: - * Dodji Seketeli <dodji@openedhand.com> - */ - -#ifdef HAVE_CONFIG_H -#include <kdrive-config.h> -#endif - -#include <string.h> - -#include <X11/X.h> -#include <X11/Xproto.h> -#define _XF86DRI_SERVER_ -#include <X11/dri/xf86dri.h> -#include <X11/dri/xf86driproto.h> -#include "misc.h" -#include "privates.h" -#include "dixstruct.h" -#include "extnsionst.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "servermd.h" -#include "swaprep.h" -#include "ephyrdri.h" -#include "ephyrdriext.h" -#include "hostx.h" -#define _HAVE_XALLOC_DECLS -#include "ephyrlog.h" -#include "protocol-versions.h" - -typedef struct { - int foo; -} EphyrDRIWindowPrivRec; -typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr; - -typedef struct { - CreateWindowProcPtr CreateWindow ; - DestroyWindowProcPtr DestroyWindow ; - MoveWindowProcPtr MoveWindow ; - PositionWindowProcPtr PositionWindow ; - ClipNotifyProcPtr ClipNotify ; -} EphyrDRIScreenPrivRec; -typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr; - -static int DRIErrorBase; - -static DISPATCH_PROC(ProcXF86DRIQueryVersion); -static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable); -static DISPATCH_PROC(ProcXF86DRIOpenConnection); -static DISPATCH_PROC(ProcXF86DRICloseConnection); -static DISPATCH_PROC(ProcXF86DRIGetClientDriverName); -static DISPATCH_PROC(ProcXF86DRICreateContext); -static DISPATCH_PROC(ProcXF86DRIDestroyContext); -static DISPATCH_PROC(ProcXF86DRICreateDrawable); -static DISPATCH_PROC(ProcXF86DRIDestroyDrawable); -static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo); -static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo); -static DISPATCH_PROC(ProcXF86DRIDispatch); -static DISPATCH_PROC(ProcXF86DRIAuthConnection); - -static DISPATCH_PROC(SProcXF86DRIQueryVersion); -static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable); -static DISPATCH_PROC(SProcXF86DRIDispatch); - -static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ; -static Bool ephyrDRICreateWindow (WindowPtr a_win) ; -static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ; -static void ephyrDRIMoveWindow (WindowPtr a_win, - int a_x, int a_y, - WindowPtr a_siblings, - VTKind a_kind); -static Bool ephyrDRIPositionWindow (WindowPtr a_win, - int x, int y) ; -static void ephyrDRIClipNotify (WindowPtr a_win, - int a_x, int a_y) ; - -static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ; -static Bool destroyHostPeerWindow (const WindowPtr a_win) ; -static Bool findWindowPairFromLocal (WindowPtr a_local, - EphyrWindowPair **a_pair); - -static unsigned char DRIReqCode = 0; - -static int ephyrDRIWindowKeyIndex; -static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKeyIndex; -static int ephyrDRIScreenKeyIndex; -static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKeyIndex; - -#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \ - dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey)) -#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \ - dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey)) - - -Bool -ephyrDRIExtensionInit (ScreenPtr a_screen) -{ - Bool is_ok=FALSE ; - ExtensionEntry* extEntry=NULL; - EphyrDRIScreenPrivPtr screen_priv=NULL ; - - EPHYR_LOG ("enter\n") ; - if (!hostx_has_dri ()) { - EPHYR_LOG ("host does not have DRI extension\n") ; - goto out ; - } - EPHYR_LOG ("host X does have DRI extension\n") ; - if (!hostx_has_xshape ()) { - EPHYR_LOG ("host does not have XShape extension\n") ; - goto out ; - } - EPHYR_LOG ("host X does have XShape extension\n") ; - -#ifdef XF86DRI_EVENTS - EventType = CreateNewResourceType (XF86DRIFreeEvents, "DRIEvents"); - if (!EventType) { - EPHYR_LOG_ERROR ("failed to register DRI event resource type\n") ; - goto out ; - } -#endif - - if ((extEntry = AddExtension(XF86DRINAME, - XF86DRINumberEvents, - XF86DRINumberErrors, - ProcXF86DRIDispatch, - SProcXF86DRIDispatch, - NULL, - StandardMinorOpcode))) { - DRIReqCode = (unsigned char)extEntry->base; - DRIErrorBase = extEntry->errorBase; - } else { - EPHYR_LOG_ERROR ("failed to register DRI extension\n") ; - goto out ; - } - screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ; - if (!screen_priv) { - EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ; - goto out ; - } - dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv); - - if (!ephyrDRIScreenInit (a_screen)) { - EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ; - goto out ; - } - EphyrMirrorHostVisuals (a_screen) ; - is_ok=TRUE ; -out: - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -static Bool -ephyrDRIScreenInit (ScreenPtr a_screen) -{ - Bool is_ok=FALSE ; - EphyrDRIScreenPrivPtr screen_priv=NULL ; - - EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ; - - screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ; - - screen_priv->CreateWindow = a_screen->CreateWindow ; - screen_priv->DestroyWindow = a_screen->DestroyWindow ; - screen_priv->MoveWindow = a_screen->MoveWindow ; - screen_priv->PositionWindow = a_screen->PositionWindow ; - screen_priv->ClipNotify = a_screen->ClipNotify ; - - a_screen->CreateWindow = ephyrDRICreateWindow ; - a_screen->DestroyWindow = ephyrDRIDestroyWindow ; - a_screen->MoveWindow = ephyrDRIMoveWindow ; - a_screen->PositionWindow = ephyrDRIPositionWindow ; - a_screen->ClipNotify = ephyrDRIClipNotify ; - - is_ok = TRUE ; - - return is_ok ; -} - -static Bool -ephyrDRICreateWindow (WindowPtr a_win) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv - && screen_priv->CreateWindow, - FALSE) ; - - EPHYR_LOG ("enter. win:%p\n", a_win) ; - - screen->CreateWindow = screen_priv->CreateWindow ; - is_ok = (*screen->CreateWindow) (a_win) ; - screen->CreateWindow = ephyrDRICreateWindow ; - - if (is_ok) { - dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL); - } - return is_ok ; -} - -static Bool -ephyrDRIDestroyWindow (WindowPtr a_win) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv - && screen_priv->DestroyWindow, - FALSE) ; - - screen->DestroyWindow = screen_priv->DestroyWindow ; - if (screen->DestroyWindow) { - is_ok = (*screen->DestroyWindow) (a_win) ; - } - screen->DestroyWindow = ephyrDRIDestroyWindow ; - - if (is_ok) { - EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (win_priv) { - destroyHostPeerWindow (a_win) ; - xfree (win_priv) ; - dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL); - EPHYR_LOG ("destroyed the remote peer window\n") ; - } - } - return is_ok ; -} - -static void -ephyrDRIMoveWindow (WindowPtr a_win, - int a_x, int a_y, - WindowPtr a_siblings, - VTKind a_kind) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - EphyrDRIWindowPrivPtr win_priv=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrBox geo; - int x=0,y=0;/*coords relative to parent window*/ - - EPHYR_RETURN_IF_FAIL (a_win) ; - - EPHYR_LOG ("enter\n") ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_IF_FAIL (screen) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_IF_FAIL (screen_priv - && screen_priv->MoveWindow) ; - - screen->MoveWindow = screen_priv->MoveWindow ; - if (screen->MoveWindow) { - (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ; - } - screen->MoveWindow = ephyrDRIMoveWindow ; - - EPHYR_LOG ("window: %p\n", a_win) ; - if (!a_win->parent) { - EPHYR_LOG ("cannot move root window\n") ; - is_ok = TRUE ; - goto out ; - } - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (!win_priv) { - EPHYR_LOG ("not a DRI peered window\n") ; - is_ok = TRUE ; - goto out ; - } - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to get window pair\n") ; - goto out ; - } - /*compute position relative to parent window*/ - x = a_win->drawable.x - a_win->parent->drawable.x ; - y = a_win->drawable.y - a_win->parent->drawable.y ; - /*set the geometry to pass to hostx_set_window_geometry*/ - memset (&geo, 0, sizeof (geo)) ; - geo.x = x ; - geo.y = y ; - geo.width = a_win->drawable.width ; - geo.height = a_win->drawable.height ; - hostx_set_window_geometry (pair->remote, &geo) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; - /*do cleanup here*/ -} - -static Bool -ephyrDRIPositionWindow (WindowPtr a_win, - int a_x, int a_y) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - EphyrDRIWindowPrivPtr win_priv=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrBox geo; - - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - - EPHYR_LOG ("enter\n") ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_VAL_IF_FAIL (screen_priv - && screen_priv->PositionWindow, - FALSE) ; - - screen->PositionWindow = screen_priv->PositionWindow ; - if (screen->PositionWindow) { - (*screen->PositionWindow) (a_win, a_x, a_y) ; - } - screen->PositionWindow = ephyrDRIPositionWindow ; - - EPHYR_LOG ("window: %p\n", a_win) ; - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (!win_priv) { - EPHYR_LOG ("not a DRI peered window\n") ; - is_ok = TRUE ; - goto out ; - } - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to get window pair\n") ; - goto out ; - } - /*set the geometry to pass to hostx_set_window_geometry*/ - memset (&geo, 0, sizeof (geo)) ; - geo.x = a_x ; - geo.y = a_y ; - geo.width = a_win->drawable.width ; - geo.height = a_win->drawable.height ; - hostx_set_window_geometry (pair->remote, &geo) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; - /*do cleanup here*/ - return is_ok ; -} - -static void -ephyrDRIClipNotify (WindowPtr a_win, - int a_x, int a_y) -{ - Bool is_ok=FALSE ; - ScreenPtr screen=NULL ; - EphyrDRIScreenPrivPtr screen_priv =NULL; - EphyrDRIWindowPrivPtr win_priv=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrRect *rects=NULL; - int i=0 ; - - EPHYR_RETURN_IF_FAIL (a_win) ; - - EPHYR_LOG ("enter\n") ; - screen = a_win->drawable.pScreen ; - EPHYR_RETURN_IF_FAIL (screen) ; - screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ; - EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ; - - screen->ClipNotify = screen_priv->ClipNotify ; - if (screen->ClipNotify) { - (*screen->ClipNotify) (a_win, a_x, a_y) ; - } - screen->ClipNotify = ephyrDRIClipNotify ; - - EPHYR_LOG ("window: %p\n", a_win) ; - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ; - if (!win_priv) { - EPHYR_LOG ("not a DRI peered window\n") ; - is_ok = TRUE ; - goto out ; - } - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to get window pair\n") ; - goto out ; - } - rects = xcalloc (REGION_NUM_RECTS (&a_win->clipList), - sizeof (EphyrRect)) ; - for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) { - memmove (&rects[i], - ®ION_RECTS (&a_win->clipList)[i], - sizeof (EphyrRect)) ; - rects[i].x1 -= a_win->drawable.x; - rects[i].x2 -= a_win->drawable.x; - rects[i].y1 -= a_win->drawable.y; - rects[i].y2 -= a_win->drawable.y; - } - /* - * push the clipping region of this window - * to the peer window in the host - */ - is_ok = hostx_set_window_bounding_rectangles - (pair->remote, - rects, - REGION_NUM_RECTS (&a_win->clipList)) ; - is_ok = TRUE ; - -out: - xfree (rects) ; - rects = NULL ; - - EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ; - /*do cleanup here*/ -} - -/** - * Duplicates a visual of a_screen - * In screen a_screen, for depth a_depth, find a visual which - * bitsPerRGBValue and colormap size equal - * a_bits_per_rgb_values and a_colormap_entries. - * The ID of that duplicated visual is set to a_new_id. - * That duplicated visual is then added to the list of visuals - * of the screen. - */ -static Bool -EphyrDuplicateVisual (unsigned int a_screen, - short a_depth, - short a_class, - short a_bits_per_rgb_values, - short a_colormap_entries, - unsigned int a_red_mask, - unsigned int a_green_mask, - unsigned int a_blue_mask, - unsigned int a_new_id) -{ - Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ; - ScreenPtr screen=NULL ; - VisualRec new_visual, *new_visuals=NULL ; - int i=0 ; - - EPHYR_LOG ("enter\n") ; - if (a_screen > screenInfo.numScreens) { - EPHYR_LOG_ERROR ("bad screen number\n") ; - goto out; - } - memset (&new_visual, 0, sizeof (VisualRec)) ; - - /*get the screen pointed to by a_screen*/ - screen = screenInfo.screens[a_screen] ; - EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ; - - /* - * In that screen, first look for an existing visual that has the - * same characteristics as those passed in parameter - * to this function and copy it. - */ - for (i=0; i < screen->numVisuals; i++) { - if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values && - screen->visuals[i].ColormapEntries == a_colormap_entries ) { - /*copy the visual found*/ - memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ; - new_visual.vid = a_new_id ; - new_visual.class = a_class ; - new_visual.redMask = a_red_mask ; - new_visual.greenMask = a_green_mask ; - new_visual.blueMask = a_blue_mask ; - found_visual = TRUE ; - EPHYR_LOG ("found a visual that matches visual id: %d\n", - a_new_id) ; - break; - } - } - if (!found_visual) { - EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ; - goto out ; - } - /* - * be prepare to extend screen->visuals to add new_visual to it - */ - new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ; - memmove (new_visuals, - screen->visuals, - screen->numVisuals*sizeof (VisualRec)) ; - memmove (&new_visuals[screen->numVisuals], - &new_visual, - sizeof (VisualRec)) ; - /* - * Now, in that same screen, update the screen->allowedDepths member. - * In that array, each element represents the visuals applicable to - * a given depth. So we need to add an entry matching the new visual - * that we are going to add to screen->visuals - */ - for (i=0; i<screen->numDepths; i++) { - VisualID *vids=NULL; - DepthPtr cur_depth=NULL ; - /*find the entry matching a_depth*/ - if (screen->allowedDepths[i].depth != a_depth) - continue ; - cur_depth = &screen->allowedDepths[i]; - /* - * extend the list of visual IDs in that entry, - * so to add a_new_id in there. - */ - vids = xrealloc (cur_depth->vids, - (cur_depth->numVids+1)*sizeof (VisualID)); - if (!vids) { - EPHYR_LOG_ERROR ("failed to realloc numids\n") ; - goto out ; - } - vids[cur_depth->numVids] = a_new_id ; - /* - * Okay now commit our change. - * Do really update screen->allowedDepths[i] - */ - cur_depth->numVids++ ; - cur_depth->vids = vids ; - found_depth=TRUE; - } - if (!found_depth) { - EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n", - a_screen) ; - goto out ; - } - /* - * Commit our change to screen->visuals - */ - xfree (screen->visuals) ; - screen->visuals = new_visuals ; - screen->numVisuals++ ; - new_visuals = NULL ; - - is_ok = TRUE ; -out: - xfree (new_visuals) ; - new_visuals = NULL ; - - EPHYR_LOG ("leave\n") ; - return is_ok ; -} - -/** - * Duplicates the visuals of the host X server. - * This is necessary to have visuals that have the same - * ID as those of the host X. It is important to have that for - * GLX. - */ -static Bool -EphyrMirrorHostVisuals (ScreenPtr a_screen) -{ - Bool is_ok=FALSE; - EphyrHostVisualInfo *visuals=NULL; - int nb_visuals=0, i=0; - - EPHYR_LOG ("enter\n") ; - if (!hostx_get_visuals_info (&visuals, &nb_visuals)) { - EPHYR_LOG_ERROR ("failed to get host visuals\n") ; - goto out ; - } - for (i=0; i<nb_visuals; i++) { - if (!EphyrDuplicateVisual (a_screen->myNum, - visuals[i].depth, - visuals[i].class, - visuals[i].bits_per_rgb, - visuals[i].colormap_size, - visuals[i].red_mask, - visuals[i].green_mask, - visuals[i].blue_mask, - visuals[i].visualid)) { - EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n", - (int)visuals[i].visualid) ; - } - } - - is_ok = TRUE ; -out: - EPHYR_LOG ("leave\n") ; - return is_ok; -} - - -static int -ProcXF86DRIQueryVersion (register ClientPtr client) -{ - xXF86DRIQueryVersionReply rep; - register int n; - REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq); - - EPHYR_LOG ("enter\n") ; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION; - rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION; - rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - swapl(&rep.patchVersion, n); - } - WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client) -{ - xXF86DRIQueryDirectRenderingCapableReply rep; - Bool isCapable; - register int n; - REQUEST(xXF86DRIQueryDirectRenderingCapableReq); - REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) { - return BadValue; - } - rep.isCapable = isCapable; - - if (!LocalClient(client) || client->swapped) - rep.isCapable = 0; - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - - WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - - return (client->noClientException); -} - -static int -ProcXF86DRIOpenConnection (register ClientPtr client) -{ - xXF86DRIOpenConnectionReply rep; - drm_handle_t hSAREA; - char* busIdString; - REQUEST(xXF86DRIOpenConnectionReq); - REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - if (!ephyrDRIOpenConnection(stuff->screen, - &hSAREA, - &busIdString)) { - return BadValue; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.busIdStringLength = 0; - if (busIdString) - rep.busIdStringLength = strlen(busIdString); - rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) + - pad_to_int32(rep.busIdStringLength)); - - rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff); -#if defined(LONG64) && !defined(__linux__) - rep.hSAREAHigh = (CARD32)(hSAREA >> 32); -#else - rep.hSAREAHigh = 0; -#endif - - WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep); - if (rep.busIdStringLength) - WriteToClient(client, rep.busIdStringLength, busIdString); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIAuthConnection (register ClientPtr client) -{ - xXF86DRIAuthConnectionReply rep; - REQUEST(xXF86DRIAuthConnectionReq); - REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.authenticated = 1; - - if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) { - ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic); - rep.authenticated = 0; - } - WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRICloseConnection (register ClientPtr client) -{ - REQUEST(xXF86DRICloseConnectionReq); - REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq); - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - /* - DRICloseConnection( screenInfo.screens[stuff->screen]); - */ - - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIGetClientDriverName (register ClientPtr client) -{ - xXF86DRIGetClientDriverNameReply rep; - char* clientDriverName; - REQUEST(xXF86DRIGetClientDriverNameReq); - REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - ephyrDRIGetClientDriverName (stuff->screen, - (int *)&rep.ddxDriverMajorVersion, - (int *)&rep.ddxDriverMinorVersion, - (int *)&rep.ddxDriverPatchVersion, - &clientDriverName); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.clientDriverNameLength = 0; - if (clientDriverName) - rep.clientDriverNameLength = strlen(clientDriverName); - rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) - - SIZEOF(xGenericReply) + - pad_to_int32(rep.clientDriverNameLength)); - - WriteToClient(client, - sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep); - if (rep.clientDriverNameLength) - WriteToClient(client, - rep.clientDriverNameLength, - clientDriverName); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRICreateContext (register ClientPtr client) -{ - xXF86DRICreateContextReply rep; - ScreenPtr pScreen; - VisualPtr visual; - int i=0; - unsigned long context_id=0; - REQUEST(xXF86DRICreateContextReq); - REQUEST_SIZE_MATCH(xXF86DRICreateContextReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - pScreen = screenInfo.screens[stuff->screen]; - visual = pScreen->visuals; - - /* Find the requested X visual */ - for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == stuff->visual) - break; - if (i == pScreen->numVisuals) { - /* No visual found */ - return BadValue; - } - - context_id = stuff->context ; - if (!ephyrDRICreateContext (stuff->screen, - stuff->visual, - &context_id, - (drm_context_t *)&rep.hHWContext)) { - return BadValue; - } - - WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIDestroyContext (register ClientPtr client) -{ - REQUEST(xXF86DRIDestroyContextReq); - REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq); - EPHYR_LOG ("enter\n") ; - - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) { - return BadValue; - } - - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static Bool -getWindowVisual (const WindowPtr a_win, - VisualPtr *a_visual) -{ - int i=0, visual_id=0 ; - EPHYR_RETURN_VAL_IF_FAIL (a_win - && a_win->drawable.pScreen - && a_win->drawable.pScreen->visuals, - FALSE) ; - - visual_id = wVisual (a_win) ; - for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) { - if (a_win->drawable.pScreen->visuals[i].vid == visual_id) { - *a_visual = &a_win->drawable.pScreen->visuals[i] ; - return TRUE ; - } - } - return FALSE ; -} - - -#define NUM_WINDOW_PAIRS 256 -static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ; - -static Bool -appendWindowPairToList (WindowPtr a_local, - int a_remote) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ; - - EPHYR_LOG ("(local,remote):(%p, %d)\n", a_local, a_remote) ; - - for (i=0; i < NUM_WINDOW_PAIRS; i++) { - if (window_pairs[i].local == NULL) { - window_pairs[i].local = a_local ; - window_pairs[i].remote = a_remote ; - return TRUE ; - } - } - return FALSE ; -} - -static Bool -findWindowPairFromLocal (WindowPtr a_local, - EphyrWindowPair **a_pair) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ; - - for (i=0; i < NUM_WINDOW_PAIRS; i++) { - if (window_pairs[i].local == a_local) { - *a_pair = &window_pairs[i] ; - EPHYR_LOG ("found (%p, %d)\n", - (*a_pair)->local, - (*a_pair)->remote) ; - return TRUE ; - } - } - return FALSE ; -} - -Bool -findWindowPairFromRemote (int a_remote, - EphyrWindowPair **a_pair) -{ - int i=0 ; - - EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ; - - for (i=0; i < NUM_WINDOW_PAIRS; i++) { - if (window_pairs[i].remote == a_remote) { - *a_pair = &window_pairs[i] ; - EPHYR_LOG ("found (%p, %d)\n", - (*a_pair)->local, - (*a_pair)->remote) ; - return TRUE ; - } - } - return FALSE ; -} - -static Bool -createHostPeerWindow (const WindowPtr a_win, - int *a_peer_win) -{ - Bool is_ok=FALSE ; - VisualPtr visual=NULL; - EphyrBox geo ; - - EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ; - EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen, - FALSE) ; - - EPHYR_LOG ("enter. a_win '%p'\n", a_win) ; - if (!getWindowVisual (a_win, &visual)) { - EPHYR_LOG_ERROR ("failed to get window visual\n") ; - goto out ; - } - if (!visual) { - EPHYR_LOG_ERROR ("failed to create visual\n") ; - goto out ; - } - memset (&geo, 0, sizeof (geo)) ; - geo.x = a_win->drawable.x ; - geo.y = a_win->drawable.y ; - geo.width = a_win->drawable.width ; - geo.height = a_win->drawable.height ; - if (!hostx_create_window (a_win->drawable.pScreen->myNum, - &geo, visual->vid, a_peer_win)) { - EPHYR_LOG_ERROR ("failed to create host peer window\n") ; - goto out ; - } - if (!appendWindowPairToList (a_win, *a_peer_win)) { - EPHYR_LOG_ERROR ("failed to append window to pair list\n") ; - goto out ; - } - is_ok = TRUE ; -out: - EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ; - return is_ok ; -} - -static Bool -destroyHostPeerWindow (const WindowPtr a_win) -{ - Bool is_ok = FALSE ; - EphyrWindowPair *pair=NULL ; - EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; - - EPHYR_LOG ("enter\n") ; - - if (!findWindowPairFromLocal (a_win, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to find peer to local window\n") ; - goto out; - } - hostx_destroy_window (pair->remote) ; - is_ok = TRUE ; - -out: - EPHYR_LOG ("leave\n") ; - return is_ok; -} - -static int -ProcXF86DRICreateDrawable (ClientPtr client) -{ - xXF86DRICreateDrawableReply rep; - DrawablePtr drawable=NULL; - WindowPtr window=NULL ; - EphyrWindowPair *pair=NULL ; - EphyrDRIWindowPrivPtr win_priv=NULL; - int rc=0, remote_win=0; - REQUEST(xXF86DRICreateDrawableReq); - REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - if (drawable->type != DRAWABLE_WINDOW) { - EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ; - return BadImplementation ; - } - EPHYR_LOG ("lookedup drawable %p\n", drawable) ; - window = (WindowPtr)drawable; - if (findWindowPairFromLocal (window, &pair) && pair) { - remote_win = pair->remote ; - EPHYR_LOG ("found window '%p' paire with remote '%d'\n", - window, remote_win) ; - } else if (!createHostPeerWindow (window, &remote_win)) { - EPHYR_LOG_ERROR ("failed to create host peer window\n") ; - return BadAlloc ; - } - - if (!ephyrDRICreateDrawable (stuff->screen, - remote_win, - (drm_drawable_t *)&rep.hHWDrawable)) { - EPHYR_LOG_ERROR ("failed to create dri drawable\n") ; - return BadValue; - } - - win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ; - if (!win_priv) { - win_priv = xcalloc (1, sizeof (EphyrDRIWindowPrivRec)) ; - if (!win_priv) { - EPHYR_LOG_ERROR ("failed to allocate window private\n") ; - return BadAlloc ; - } - dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv); - EPHYR_LOG ("paired window '%p' with remote '%d'\n", - window, remote_win) ; - } - - WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep); - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIDestroyDrawable (register ClientPtr client) -{ - DrawablePtr drawable=NULL; - WindowPtr window=NULL; - EphyrWindowPair *pair=NULL; - int rc=0; - REQUEST(xXF86DRIDestroyDrawableReq); - REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rc = dixLookupDrawable(&drawable, - stuff->drawable, - client, - 0, - DixReadAccess); - if (rc != Success) - return rc; - if (drawable->type != DRAWABLE_WINDOW) { - EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ; - return BadImplementation ; - } - window = (WindowPtr)drawable; - if (!findWindowPairFromLocal (window, &pair) && pair) { - EPHYR_LOG_ERROR ("failed to find pair window\n") ; - return BadImplementation; - } - if (!ephyrDRIDestroyDrawable(stuff->screen, - pair->remote/*drawable in host x*/)) { - EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ; - return BadImplementation; - } - pair->local=NULL ; - pair->remote=0; - - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIGetDrawableInfo (register ClientPtr client) -{ - xXF86DRIGetDrawableInfoReply rep; - DrawablePtr drawable; - WindowPtr window=NULL; - EphyrWindowPair *pair=NULL; - int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0; - drm_clip_rect_t *clipRects=NULL; - drm_clip_rect_t *backClipRects=NULL; - REQUEST(xXF86DRIGetDrawableInfoReq); - REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq); - - EPHYR_LOG ("enter\n") ; - memset (&rep, 0, sizeof (rep)) ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success || !drawable) { - EPHYR_LOG_ERROR ("could not get drawable\n") ; - return rc; - } - - if (drawable->type != DRAWABLE_WINDOW) { - EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ; - return BadImplementation ; - } - window = (WindowPtr)drawable ; - memset (&pair, 0, sizeof (pair)) ; - if (!findWindowPairFromLocal (window, &pair) || !pair) { - EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ; - return BadMatch ; - } - EPHYR_LOG ("clip list of xephyr gl drawable:\n") ; - for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) { - EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n", - REGION_RECTS (&window->clipList)[i].x1, - REGION_RECTS (&window->clipList)[i].y1, - REGION_RECTS (&window->clipList)[i].x2, - REGION_RECTS (&window->clipList)[i].y2) ; - } - - if (!ephyrDRIGetDrawableInfo (stuff->screen, - pair->remote/*the drawable in hostx*/, - (unsigned int*)&rep.drawableTableIndex, - (unsigned int*)&rep.drawableTableStamp, - (int*)&X, - (int*)&Y, - (int*)&W, - (int*)&H, - (int*)&rep.numClipRects, - &clipRects, - &backX, - &backY, - (int*)&rep.numBackClipRects, - &backClipRects)) { - return BadValue; - } - EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n", - (int)rep.numClipRects, (int)rep.numBackClipRects) ; - - rep.drawableX = X; - rep.drawableY = Y; - rep.drawableWidth = W; - rep.drawableHeight = H; - rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - - SIZEOF(xGenericReply)); - - rep.backX = backX; - rep.backY = backY; - - - if (rep.numClipRects) { - if (clipRects) { - ScreenPtr pScreen = screenInfo.screens[stuff->screen]; - int i=0; - EPHYR_LOG ("clip list of host gl drawable:\n") ; - for (i = 0; i < rep.numClipRects; i++) { - clipRects[i].x1 = max (clipRects[i].x1, 0); - clipRects[i].y1 = max (clipRects[i].y1, 0); - clipRects[i].x2 = min (clipRects[i].x2, - pScreen->width + clipRects[i].x1) ; - clipRects[i].y2 = min (clipRects[i].y2, - pScreen->width + clipRects[i].y1) ; - - EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n", - clipRects[i].x1, clipRects[i].y1, - clipRects[i].x2, clipRects[i].y2) ; - } - } else { - rep.numClipRects = 0; - } - } else { - EPHYR_LOG ("got zero host gl drawable clipping rects\n") ; - } - rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects; - backClipRects = clipRects ; - rep.numBackClipRects = rep.numClipRects ; - if (rep.numBackClipRects) - rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects; - EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ; - EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ; - - rep.length = bytes_to_int32(rep.length); - - WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep); - - if (rep.numClipRects) { - WriteToClient(client, - sizeof(drm_clip_rect_t) * rep.numClipRects, - (char *)clipRects); - } - - if (rep.numBackClipRects) { - WriteToClient(client, - sizeof(drm_clip_rect_t) * rep.numBackClipRects, - (char *)backClipRects); - } - xfree(clipRects); - clipRects = NULL ; - - EPHYR_LOG ("leave\n") ; - - return (client->noClientException); -} - -static int -ProcXF86DRIGetDeviceInfo (register ClientPtr client) -{ - xXF86DRIGetDeviceInfoReply rep; - drm_handle_t hFrameBuffer; - void *pDevPrivate; - REQUEST(xXF86DRIGetDeviceInfoReq); - REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq); - - EPHYR_LOG ("enter\n") ; - if (stuff->screen >= screenInfo.numScreens) { - client->errorValue = stuff->screen; - return BadValue; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if (!ephyrDRIGetDeviceInfo (stuff->screen, - &hFrameBuffer, - (int*)&rep.framebufferOrigin, - (int*)&rep.framebufferSize, - (int*)&rep.framebufferStride, - (int*)&rep.devPrivateSize, - &pDevPrivate)) { - return BadValue; - } - - rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff); -#if defined(LONG64) && !defined(__linux__) - rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32); -#else - rep.hFrameBufferHigh = 0; -#endif - - rep.length = 0; - if (rep.devPrivateSize) { - rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) - - SIZEOF(xGenericReply) + - pad_to_int32(rep.devPrivateSize)); - } - - WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep); - if (rep.length) { - WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate); - } - EPHYR_LOG ("leave\n") ; - return (client->noClientException); -} - -static int -ProcXF86DRIDispatch (register ClientPtr client) -{ - REQUEST(xReq); - EPHYR_LOG ("enter\n") ; - - switch (stuff->data) - { - case X_XF86DRIQueryVersion: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIQueryVersion(client); - } - case X_XF86DRIQueryDirectRenderingCapable: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIQueryDirectRenderingCapable(client); - } - } - - if (!LocalClient(client)) - return DRIErrorBase + XF86DRIClientNotLocal; - - switch (stuff->data) - { - case X_XF86DRIOpenConnection: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIOpenConnection(client); - } - case X_XF86DRICloseConnection: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRICloseConnection(client); - } - case X_XF86DRIGetClientDriverName: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIGetClientDriverName(client); - } - case X_XF86DRICreateContext: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRICreateContext(client); - } - case X_XF86DRIDestroyContext: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIDestroyContext(client); - } - case X_XF86DRICreateDrawable: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRICreateDrawable(client); - } - case X_XF86DRIDestroyDrawable: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIDestroyDrawable(client); - } - case X_XF86DRIGetDrawableInfo: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIGetDrawableInfo(client); - } - case X_XF86DRIGetDeviceInfo: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIGetDeviceInfo(client); - } - case X_XF86DRIAuthConnection: { - EPHYR_LOG ("leave\n") ; - return ProcXF86DRIAuthConnection(client); - } - /* {Open,Close}FullScreen are deprecated now */ - default: { - EPHYR_LOG ("leave\n") ; - return BadRequest; - } - } -} - -static int -SProcXF86DRIQueryVersion (register ClientPtr client) -{ - register int n; - REQUEST(xXF86DRIQueryVersionReq); - swaps(&stuff->length, n); - return ProcXF86DRIQueryVersion(client); -} - -static int -SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client) -{ - register int n; - REQUEST(xXF86DRIQueryDirectRenderingCapableReq); - swaps(&stuff->length, n); - swapl(&stuff->screen, n); - return ProcXF86DRIQueryDirectRenderingCapable(client); -} - -static int -SProcXF86DRIDispatch (register ClientPtr client) -{ - REQUEST(xReq); - - EPHYR_LOG ("enter\n") ; - /* - * Only local clients are allowed DRI access, but remote clients still need - * these requests to find out cleanly. - */ - switch (stuff->data) - { - case X_XF86DRIQueryVersion: { - EPHYR_LOG ("leave\n") ; - return SProcXF86DRIQueryVersion(client); - } - case X_XF86DRIQueryDirectRenderingCapable: { - EPHYR_LOG ("leave\n") ; - return SProcXF86DRIQueryDirectRenderingCapable(client); - } - default: { - EPHYR_LOG ("leave\n") ; - return DRIErrorBase + XF86DRIClientNotLocal; - } - } -} +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * This file is heavily copied from hw/xfree86/dri/xf86dri.c
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <string.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86driproto.h>
+#include "misc.h"
+#include "privates.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "hostx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "protocol-versions.h"
+
+typedef struct {
+ int foo;
+} EphyrDRIWindowPrivRec;
+typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
+
+typedef struct {
+ CreateWindowProcPtr CreateWindow ;
+ DestroyWindowProcPtr DestroyWindow ;
+ MoveWindowProcPtr MoveWindow ;
+ PositionWindowProcPtr PositionWindow ;
+ ClipNotifyProcPtr ClipNotify ;
+} EphyrDRIScreenPrivRec;
+typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
+
+static int DRIErrorBase;
+
+static DISPATCH_PROC(ProcXF86DRIQueryVersion);
+static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(ProcXF86DRIOpenConnection);
+static DISPATCH_PROC(ProcXF86DRICloseConnection);
+static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
+static DISPATCH_PROC(ProcXF86DRICreateContext);
+static DISPATCH_PROC(ProcXF86DRIDestroyContext);
+static DISPATCH_PROC(ProcXF86DRICreateDrawable);
+static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
+static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
+static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
+static DISPATCH_PROC(ProcXF86DRIDispatch);
+static DISPATCH_PROC(ProcXF86DRIAuthConnection);
+
+static DISPATCH_PROC(SProcXF86DRIQueryVersion);
+static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(SProcXF86DRIDispatch);
+
+static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
+static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
+static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
+static void ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind);
+static Bool ephyrDRIPositionWindow (WindowPtr a_win,
+ int x, int y) ;
+static void ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y) ;
+
+static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
+static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
+static Bool findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair);
+
+static unsigned char DRIReqCode = 0;
+
+static int ephyrDRIWindowKeyIndex;
+static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKeyIndex;
+static int ephyrDRIScreenKeyIndex;
+static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKeyIndex;
+
+#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \
+ dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey))
+#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \
+ dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey))
+
+
+Bool
+ephyrDRIExtensionInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ ExtensionEntry* extEntry=NULL;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_has_dri ()) {
+ EPHYR_LOG ("host does not have DRI extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have DRI extension\n") ;
+ if (!hostx_has_xshape ()) {
+ EPHYR_LOG ("host does not have XShape extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have XShape extension\n") ;
+
+#ifdef XF86DRI_EVENTS
+ EventType = CreateNewResourceType (XF86DRIFreeEvents, "DRIEvents");
+ if (!EventType) {
+ EPHYR_LOG_ERROR ("failed to register DRI event resource type\n") ;
+ goto out ;
+ }
+#endif
+
+ if ((extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ NULL,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ } else {
+ EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
+ goto out ;
+ }
+ screen_priv = calloc(1, sizeof (EphyrDRIScreenPrivRec)) ;
+ if (!screen_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
+ goto out ;
+ }
+ dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv);
+
+ if (!ephyrDRIScreenInit (a_screen)) {
+ EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
+ goto out ;
+ }
+ EphyrMirrorHostVisuals (a_screen) ;
+ is_ok=TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIScreenInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
+
+ screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
+
+ screen_priv->CreateWindow = a_screen->CreateWindow ;
+ screen_priv->DestroyWindow = a_screen->DestroyWindow ;
+ screen_priv->MoveWindow = a_screen->MoveWindow ;
+ screen_priv->PositionWindow = a_screen->PositionWindow ;
+ screen_priv->ClipNotify = a_screen->ClipNotify ;
+
+ a_screen->CreateWindow = ephyrDRICreateWindow ;
+ a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
+ a_screen->MoveWindow = ephyrDRIMoveWindow ;
+ a_screen->PositionWindow = ephyrDRIPositionWindow ;
+ a_screen->ClipNotify = ephyrDRIClipNotify ;
+
+ is_ok = TRUE ;
+
+ return is_ok ;
+}
+
+static Bool
+ephyrDRICreateWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->CreateWindow,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. win:%p\n", a_win) ;
+
+ screen->CreateWindow = screen_priv->CreateWindow ;
+ is_ok = (*screen->CreateWindow) (a_win) ;
+ screen->CreateWindow = ephyrDRICreateWindow ;
+
+ if (is_ok) {
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ }
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIDestroyWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->DestroyWindow,
+ FALSE) ;
+
+ screen->DestroyWindow = screen_priv->DestroyWindow ;
+ if (screen->DestroyWindow) {
+ is_ok = (*screen->DestroyWindow) (a_win) ;
+ }
+ screen->DestroyWindow = ephyrDRIDestroyWindow ;
+
+ if (is_ok) {
+ EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (win_priv) {
+ destroyHostPeerWindow (a_win) ;
+ free(win_priv) ;
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ EPHYR_LOG ("destroyed the remote peer window\n") ;
+ }
+ }
+ return is_ok ;
+}
+
+static void
+ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+ int x=0,y=0;/*coords relative to parent window*/
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv
+ && screen_priv->MoveWindow) ;
+
+ screen->MoveWindow = screen_priv->MoveWindow ;
+ if (screen->MoveWindow) {
+ (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+ }
+ screen->MoveWindow = ephyrDRIMoveWindow ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ if (!a_win->parent) {
+ EPHYR_LOG ("cannot move root window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*compute position relative to parent window*/
+ x = a_win->drawable.x - a_win->parent->drawable.x ;
+ y = a_win->drawable.y - a_win->parent->drawable.y ;
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = x ;
+ geo.y = y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+static Bool
+ephyrDRIPositionWindow (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->PositionWindow,
+ FALSE) ;
+
+ screen->PositionWindow = screen_priv->PositionWindow ;
+ if (screen->PositionWindow) {
+ (*screen->PositionWindow) (a_win, a_x, a_y) ;
+ }
+ screen->PositionWindow = ephyrDRIPositionWindow ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_x ;
+ geo.y = a_y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+ return is_ok ;
+}
+
+static void
+ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrRect *rects=NULL;
+ int i=0 ;
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
+
+ screen->ClipNotify = screen_priv->ClipNotify ;
+ if (screen->ClipNotify) {
+ (*screen->ClipNotify) (a_win, a_x, a_y) ;
+ }
+ screen->ClipNotify = ephyrDRIClipNotify ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ rects = calloc(REGION_NUM_RECTS (&a_win->clipList),
+ sizeof (EphyrRect)) ;
+ for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
+ memmove (&rects[i],
+ ®ION_RECTS (&a_win->clipList)[i],
+ sizeof (EphyrRect)) ;
+ rects[i].x1 -= a_win->drawable.x;
+ rects[i].x2 -= a_win->drawable.x;
+ rects[i].y1 -= a_win->drawable.y;
+ rects[i].y2 -= a_win->drawable.y;
+ }
+ /*
+ * push the clipping region of this window
+ * to the peer window in the host
+ */
+ is_ok = hostx_set_window_bounding_rectangles
+ (pair->remote,
+ rects,
+ REGION_NUM_RECTS (&a_win->clipList)) ;
+ is_ok = TRUE ;
+
+out:
+ free(rects) ;
+ rects = NULL ;
+
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+/**
+ * Duplicates a visual of a_screen
+ * In screen a_screen, for depth a_depth, find a visual which
+ * bitsPerRGBValue and colormap size equal
+ * a_bits_per_rgb_values and a_colormap_entries.
+ * The ID of that duplicated visual is set to a_new_id.
+ * That duplicated visual is then added to the list of visuals
+ * of the screen.
+ */
+static Bool
+EphyrDuplicateVisual (unsigned int a_screen,
+ short a_depth,
+ short a_class,
+ short a_bits_per_rgb_values,
+ short a_colormap_entries,
+ unsigned int a_red_mask,
+ unsigned int a_green_mask,
+ unsigned int a_blue_mask,
+ unsigned int a_new_id)
+{
+ Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
+ ScreenPtr screen=NULL ;
+ VisualRec new_visual, *new_visuals=NULL ;
+ int i=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (a_screen > screenInfo.numScreens) {
+ EPHYR_LOG_ERROR ("bad screen number\n") ;
+ goto out;
+ }
+ memset (&new_visual, 0, sizeof (VisualRec)) ;
+
+ /*get the screen pointed to by a_screen*/
+ screen = screenInfo.screens[a_screen] ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+
+ /*
+ * In that screen, first look for an existing visual that has the
+ * same characteristics as those passed in parameter
+ * to this function and copy it.
+ */
+ for (i=0; i < screen->numVisuals; i++) {
+ if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
+ screen->visuals[i].ColormapEntries == a_colormap_entries ) {
+ /*copy the visual found*/
+ memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
+ new_visual.vid = a_new_id ;
+ new_visual.class = a_class ;
+ new_visual.redMask = a_red_mask ;
+ new_visual.greenMask = a_green_mask ;
+ new_visual.blueMask = a_blue_mask ;
+ found_visual = TRUE ;
+ EPHYR_LOG ("found a visual that matches visual id: %d\n",
+ a_new_id) ;
+ break;
+ }
+ }
+ if (!found_visual) {
+ EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
+ goto out ;
+ }
+ /*
+ * be prepare to extend screen->visuals to add new_visual to it
+ */
+ new_visuals = calloc(screen->numVisuals+1, sizeof (VisualRec)) ;
+ memmove (new_visuals,
+ screen->visuals,
+ screen->numVisuals*sizeof (VisualRec)) ;
+ memmove (&new_visuals[screen->numVisuals],
+ &new_visual,
+ sizeof (VisualRec)) ;
+ /*
+ * Now, in that same screen, update the screen->allowedDepths member.
+ * In that array, each element represents the visuals applicable to
+ * a given depth. So we need to add an entry matching the new visual
+ * that we are going to add to screen->visuals
+ */
+ for (i=0; i<screen->numDepths; i++) {
+ VisualID *vids=NULL;
+ DepthPtr cur_depth=NULL ;
+ /*find the entry matching a_depth*/
+ if (screen->allowedDepths[i].depth != a_depth)
+ continue ;
+ cur_depth = &screen->allowedDepths[i];
+ /*
+ * extend the list of visual IDs in that entry,
+ * so to add a_new_id in there.
+ */
+ vids = realloc(cur_depth->vids,
+ (cur_depth->numVids+1)*sizeof (VisualID));
+ if (!vids) {
+ EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
+ goto out ;
+ }
+ vids[cur_depth->numVids] = a_new_id ;
+ /*
+ * Okay now commit our change.
+ * Do really update screen->allowedDepths[i]
+ */
+ cur_depth->numVids++ ;
+ cur_depth->vids = vids ;
+ found_depth=TRUE;
+ }
+ if (!found_depth) {
+ EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
+ a_screen) ;
+ goto out ;
+ }
+ /*
+ * Commit our change to screen->visuals
+ */
+ free(screen->visuals) ;
+ screen->visuals = new_visuals ;
+ screen->numVisuals++ ;
+ new_visuals = NULL ;
+
+ is_ok = TRUE ;
+out:
+ free(new_visuals) ;
+ new_visuals = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+/**
+ * Duplicates the visuals of the host X server.
+ * This is necessary to have visuals that have the same
+ * ID as those of the host X. It is important to have that for
+ * GLX.
+ */
+static Bool
+EphyrMirrorHostVisuals (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE;
+ EphyrHostVisualInfo *visuals=NULL;
+ int nb_visuals=0, i=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
+ EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
+ goto out ;
+ }
+ for (i=0; i<nb_visuals; i++) {
+ if (!EphyrDuplicateVisual (a_screen->myNum,
+ visuals[i].depth,
+ visuals[i].class,
+ visuals[i].bits_per_rgb,
+ visuals[i].colormap_size,
+ visuals[i].red_mask,
+ visuals[i].green_mask,
+ visuals[i].blue_mask,
+ visuals[i].visualid)) {
+ EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
+ (int)visuals[i].visualid) ;
+ }
+ }
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+
+static int
+ProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+
+ EPHYR_LOG ("enter\n") ;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client) || client->swapped)
+ rep.isCapable = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+
+ return Success;
+}
+
+static int
+ProcXF86DRIOpenConnection (register ClientPtr client)
+{
+ xXF86DRIOpenConnectionReply rep;
+ drm_handle_t hSAREA;
+ char* busIdString;
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIOpenConnection(stuff->screen,
+ &hSAREA,
+ &busIdString)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.busIdStringLength = 0;
+ if (busIdString)
+ rep.busIdStringLength = strlen(busIdString);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ pad_to_int32(rep.busIdStringLength));
+
+ rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+ rep.hSAREAHigh = 0;
+#endif
+
+ WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+ if (rep.busIdStringLength)
+ WriteToClient(client, rep.busIdStringLength, busIdString);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIAuthConnection (register ClientPtr client)
+{
+ xXF86DRIAuthConnectionReply rep;
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
+ ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRICloseConnection (register ClientPtr client)
+{
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ /*
+ DRICloseConnection( screenInfo.screens[stuff->screen]);
+ */
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIGetClientDriverName (register ClientPtr client)
+{
+ xXF86DRIGetClientDriverNameReply rep;
+ char* clientDriverName;
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ ephyrDRIGetClientDriverName (stuff->screen,
+ (int *)&rep.ddxDriverMajorVersion,
+ (int *)&rep.ddxDriverMinorVersion,
+ (int *)&rep.ddxDriverPatchVersion,
+ &clientDriverName);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.clientDriverNameLength = 0;
+ if (clientDriverName)
+ rep.clientDriverNameLength = strlen(clientDriverName);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.clientDriverNameLength));
+
+ WriteToClient(client,
+ sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+ if (rep.clientDriverNameLength)
+ WriteToClient(client,
+ rep.clientDriverNameLength,
+ clientDriverName);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRICreateContext (register ClientPtr client)
+{
+ xXF86DRICreateContextReply rep;
+ ScreenPtr pScreen;
+ VisualPtr visual;
+ int i=0;
+ unsigned long context_id=0;
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ pScreen = screenInfo.screens[stuff->screen];
+ visual = pScreen->visuals;
+
+ /* Find the requested X visual */
+ for (i = 0; i < pScreen->numVisuals; i++, visual++)
+ if (visual->vid == stuff->visual)
+ break;
+ if (i == pScreen->numVisuals) {
+ /* No visual found */
+ return BadValue;
+ }
+
+ context_id = stuff->context ;
+ if (!ephyrDRICreateContext (stuff->screen,
+ stuff->visual,
+ &context_id,
+ (drm_context_t *)&rep.hHWContext)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyContext (register ClientPtr client)
+{
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ EPHYR_LOG ("enter\n") ;
+
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
+ return BadValue;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static Bool
+getWindowVisual (const WindowPtr a_win,
+ VisualPtr *a_visual)
+{
+ int i=0, visual_id=0 ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win
+ && a_win->drawable.pScreen
+ && a_win->drawable.pScreen->visuals,
+ FALSE) ;
+
+ visual_id = wVisual (a_win) ;
+ for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
+ if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
+ *a_visual = &a_win->drawable.pScreen->visuals[i] ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+
+#define NUM_WINDOW_PAIRS 256
+static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
+
+static Bool
+appendWindowPairToList (WindowPtr a_local,
+ int a_remote)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
+
+ EPHYR_LOG ("(local,remote):(%p, %d)\n", a_local, a_remote) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == NULL) {
+ window_pairs[i].local = a_local ;
+ window_pairs[i].remote = a_remote ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == a_local) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+Bool
+findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].remote == a_remote) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+createHostPeerWindow (const WindowPtr a_win,
+ int *a_peer_win)
+{
+ Bool is_ok=FALSE ;
+ VisualPtr visual=NULL;
+ EphyrBox geo ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. a_win '%p'\n", a_win) ;
+ if (!getWindowVisual (a_win, &visual)) {
+ EPHYR_LOG_ERROR ("failed to get window visual\n") ;
+ goto out ;
+ }
+ if (!visual) {
+ EPHYR_LOG_ERROR ("failed to create visual\n") ;
+ goto out ;
+ }
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_win->drawable.x ;
+ geo.y = a_win->drawable.y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ if (!hostx_create_window (a_win->drawable.pScreen->myNum,
+ &geo, visual->vid, a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ goto out ;
+ }
+ if (!appendWindowPairToList (a_win, *a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
+ return is_ok ;
+}
+
+static Bool
+destroyHostPeerWindow (const WindowPtr a_win)
+{
+ Bool is_ok = FALSE ;
+ EphyrWindowPair *pair=NULL ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
+ goto out;
+ }
+ hostx_destroy_window (pair->remote) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+static int
+ProcXF86DRICreateDrawable (ClientPtr client)
+{
+ xXF86DRICreateDrawableReply rep;
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrDRIWindowPrivPtr win_priv=NULL;
+ int rc=0, remote_win=0;
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ EPHYR_LOG ("lookedup drawable %p\n", drawable) ;
+ window = (WindowPtr)drawable;
+ if (findWindowPairFromLocal (window, &pair) && pair) {
+ remote_win = pair->remote ;
+ EPHYR_LOG ("found window '%p' paire with remote '%d'\n",
+ window, remote_win) ;
+ } else if (!createHostPeerWindow (window, &remote_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ return BadAlloc ;
+ }
+
+ if (!ephyrDRICreateDrawable (stuff->screen,
+ remote_win,
+ (drm_drawable_t *)&rep.hHWDrawable)) {
+ EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
+ return BadValue;
+ }
+
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
+ if (!win_priv) {
+ win_priv = calloc(1, sizeof (EphyrDRIWindowPrivRec)) ;
+ if (!win_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
+ return BadAlloc ;
+ }
+ dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv);
+ EPHYR_LOG ("paired window '%p' with remote '%d'\n",
+ window, remote_win) ;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyDrawable (register ClientPtr client)
+{
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int rc=0;
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rc = dixLookupDrawable(&drawable,
+ stuff->drawable,
+ client,
+ 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable;
+ if (!findWindowPairFromLocal (window, &pair) && pair) {
+ EPHYR_LOG_ERROR ("failed to find pair window\n") ;
+ return BadImplementation;
+ }
+ if (!ephyrDRIDestroyDrawable(stuff->screen,
+ pair->remote/*drawable in host x*/)) {
+ EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
+ return BadImplementation;
+ }
+ pair->local=NULL ;
+ pair->remote=0;
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDrawableInfo (register ClientPtr client)
+{
+ xXF86DRIGetDrawableInfoReply rep;
+ DrawablePtr drawable;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
+ drm_clip_rect_t *clipRects=NULL;
+ drm_clip_rect_t *backClipRects=NULL;
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&rep, 0, sizeof (rep)) ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success || !drawable) {
+ EPHYR_LOG_ERROR ("could not get drawable\n") ;
+ return rc;
+ }
+
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable ;
+ memset (&pair, 0, sizeof (pair)) ;
+ if (!findWindowPairFromLocal (window, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
+ return BadMatch ;
+ }
+ EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
+ for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ REGION_RECTS (&window->clipList)[i].x1,
+ REGION_RECTS (&window->clipList)[i].y1,
+ REGION_RECTS (&window->clipList)[i].x2,
+ REGION_RECTS (&window->clipList)[i].y2) ;
+ }
+
+ if (!ephyrDRIGetDrawableInfo (stuff->screen,
+ pair->remote/*the drawable in hostx*/,
+ (unsigned int*)&rep.drawableTableIndex,
+ (unsigned int*)&rep.drawableTableStamp,
+ (int*)&X,
+ (int*)&Y,
+ (int*)&W,
+ (int*)&H,
+ (int*)&rep.numClipRects,
+ &clipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &backClipRects)) {
+ return BadValue;
+ }
+ EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
+ (int)rep.numClipRects, (int)rep.numBackClipRects) ;
+
+ rep.drawableX = X;
+ rep.drawableY = Y;
+ rep.drawableWidth = W;
+ rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+
+ if (rep.numClipRects) {
+ if (clipRects) {
+ ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+ int i=0;
+ EPHYR_LOG ("clip list of host gl drawable:\n") ;
+ for (i = 0; i < rep.numClipRects; i++) {
+ clipRects[i].x1 = max (clipRects[i].x1, 0);
+ clipRects[i].y1 = max (clipRects[i].y1, 0);
+ clipRects[i].x2 = min (clipRects[i].x2,
+ pScreen->width + clipRects[i].x1) ;
+ clipRects[i].y2 = min (clipRects[i].y2,
+ pScreen->width + clipRects[i].y1) ;
+
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ clipRects[i].x1, clipRects[i].y1,
+ clipRects[i].x2, clipRects[i].y2) ;
+ }
+ } else {
+ rep.numClipRects = 0;
+ }
+ } else {
+ EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
+ }
+ rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+ backClipRects = clipRects ;
+ rep.numBackClipRects = rep.numClipRects ;
+ if (rep.numBackClipRects)
+ rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+ EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
+ EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
+
+ rep.length = bytes_to_int32(rep.length);
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+ if (rep.numClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numClipRects,
+ (char *)clipRects);
+ }
+
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+ (char *)backClipRects);
+ }
+ free(clipRects);
+ clipRects = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDeviceInfo (register ClientPtr client)
+{
+ xXF86DRIGetDeviceInfoReply rep;
+ drm_handle_t hFrameBuffer;
+ void *pDevPrivate;
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIGetDeviceInfo (stuff->screen,
+ &hFrameBuffer,
+ (int*)&rep.framebufferOrigin,
+ (int*)&rep.framebufferSize,
+ (int*)&rep.framebufferStride,
+ (int*)&rep.devPrivateSize,
+ &pDevPrivate)) {
+ return BadValue;
+ }
+
+ rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+ rep.hFrameBufferHigh = 0;
+#endif
+
+ rep.length = 0;
+ if (rep.devPrivateSize) {
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.devPrivateSize));
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+ if (rep.length) {
+ WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+ }
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+ EPHYR_LOG ("enter\n") ;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + XF86DRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIOpenConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIOpenConnection(client);
+ }
+ case X_XF86DRICloseConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICloseConnection(client);
+ }
+ case X_XF86DRIGetClientDriverName: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetClientDriverName(client);
+ }
+ case X_XF86DRICreateContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateContext(client);
+ }
+ case X_XF86DRIDestroyContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyContext(client);
+ }
+ case X_XF86DRICreateDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateDrawable(client);
+ }
+ case X_XF86DRIDestroyDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyDrawable(client);
+ }
+ case X_XF86DRIGetDrawableInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDrawableInfo(client);
+ }
+ case X_XF86DRIGetDeviceInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDeviceInfo(client);
+ }
+ case X_XF86DRIAuthConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIAuthConnection(client);
+ }
+ /* {Open,Close}FullScreen are deprecated now */
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return BadRequest;
+ }
+ }
+}
+
+static int
+SProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+
+ EPHYR_LOG ("enter\n") ;
+ /*
+ * Only local clients are allowed DRI access, but remote clients still need
+ * these requests to find out cleanly.
+ */
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return DRIErrorBase + XF86DRIClientNotLocal;
+ }
+ }
+}
|