diff options
Diffstat (limited to 'xorg-server/Xext')
-rw-r--r-- | xorg-server/Xext/panoramiX.c | 2598 | ||||
-rw-r--r-- | xorg-server/Xext/panoramiXsrv.h | 108 | ||||
-rw-r--r-- | xorg-server/Xext/xvdix.h | 550 | ||||
-rw-r--r-- | xorg-server/Xext/xvmain.c | 2368 | ||||
-rw-r--r-- | xorg-server/Xext/xvmc.c | 1578 |
5 files changed, 3600 insertions, 3602 deletions
diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c index 489224221..391346a6b 100644 --- a/xorg-server/Xext/panoramiX.c +++ b/xorg-server/Xext/panoramiX.c @@ -1,1299 +1,1299 @@ -/*****************************************************************
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xarch.h>
-#include "misc.h"
-#include "cursor.h"
-#include "cursorstr.h"
-#include "extnsionst.h"
-#include "dixstruct.h"
-#include "gc.h"
-#include "gcstruct.h"
-#include "scrnintstr.h"
-#include "window.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "panoramiX.h"
-#include <X11/extensions/panoramiXproto.h>
-#include "panoramiXsrv.h"
-#include "globals.h"
-#include "servermd.h"
-#include "resource.h"
-#include "picturestr.h"
-#ifdef XFIXES
-#include "xfixesint.h"
-#endif
-#ifdef COMPOSITE
-#include "compint.h"
-#endif
-#include "modinit.h"
-#include "protocol-versions.h"
-
-#ifdef GLXPROXY
-extern VisualPtr glxMatchVisual(ScreenPtr pScreen,
- VisualPtr pVisual,
- ScreenPtr pMatchScreen);
-#endif
-
-/*
- * PanoramiX data declarations
- */
-
-int PanoramiXPixWidth = 0;
-int PanoramiXPixHeight = 0;
-int PanoramiXNumScreens = 0;
-
-static RegionRec PanoramiXScreenRegion = {{0, 0, 0, 0}, NULL};
-
-static int PanoramiXNumDepths;
-static DepthPtr PanoramiXDepths;
-static int PanoramiXNumVisuals;
-static VisualPtr PanoramiXVisuals;
-
-unsigned long XRC_DRAWABLE;
-unsigned long XRT_WINDOW;
-unsigned long XRT_PIXMAP;
-unsigned long XRT_GC;
-unsigned long XRT_COLORMAP;
-
-static Bool VisualsEqual(VisualPtr, ScreenPtr, VisualPtr);
-XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr = &VisualsEqual;
-
-/*
- * Function prototypes
- */
-
-static int panoramiXGeneration;
-static int ProcPanoramiXDispatch(ClientPtr client);
-
-static void PanoramiXResetProc(ExtensionEntry*);
-
-/*
- * External references for functions and data variables
- */
-
-#include "panoramiXh.h"
-
-int (* SavedProcVector[256]) (ClientPtr client) = { NULL, };
-
-static DevPrivateKeyRec PanoramiXGCKeyRec;
-#define PanoramiXGCKey (&PanoramiXGCKeyRec)
-static DevPrivateKeyRec PanoramiXScreenKeyRec;
-#define PanoramiXScreenKey (&PanoramiXScreenKeyRec)
-
-typedef struct {
- DDXPointRec clipOrg;
- DDXPointRec patOrg;
- GCFuncs *wrapFuncs;
-} PanoramiXGCRec, *PanoramiXGCPtr;
-
-typedef struct {
- CreateGCProcPtr CreateGC;
- CloseScreenProcPtr CloseScreen;
-} PanoramiXScreenRec, *PanoramiXScreenPtr;
-
-static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr);
-static void XineramaChangeGC(GCPtr, unsigned long);
-static void XineramaCopyGC(GCPtr, unsigned long, GCPtr);
-static void XineramaDestroyGC(GCPtr);
-static void XineramaChangeClip(GCPtr, int, pointer, int);
-static void XineramaDestroyClip(GCPtr);
-static void XineramaCopyClip(GCPtr, GCPtr);
-
-static GCFuncs XineramaGCFuncs = {
- XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC,
- XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip
-};
-
-#define Xinerama_GC_FUNC_PROLOGUE(pGC)\
- PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) \
- dixLookupPrivate(&(pGC)->devPrivates, PanoramiXGCKey); \
- (pGC)->funcs = pGCPriv->wrapFuncs;
-
-#define Xinerama_GC_FUNC_EPILOGUE(pGC)\
- pGCPriv->wrapFuncs = (pGC)->funcs;\
- (pGC)->funcs = &XineramaGCFuncs;
-
-
-static Bool
-XineramaCloseScreen (int i, ScreenPtr pScreen)
-{
- PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr)
- dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->CreateGC = pScreenPriv->CreateGC;
-
- if (pScreen->myNum == 0)
- RegionUninit(&PanoramiXScreenRegion);
-
- free((pointer) pScreenPriv);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static Bool
-XineramaCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr)
- dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey);
- Bool ret;
-
- pScreen->CreateGC = pScreenPriv->CreateGC;
- if((ret = (*pScreen->CreateGC)(pGC))) {
- PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr)
- dixLookupPrivate(&pGC->devPrivates, PanoramiXGCKey);
-
- pGCPriv->wrapFuncs = pGC->funcs;
- pGC->funcs = &XineramaGCFuncs;
-
- pGCPriv->clipOrg.x = pGC->clipOrg.x;
- pGCPriv->clipOrg.y = pGC->clipOrg.y;
- pGCPriv->patOrg.x = pGC->patOrg.x;
- pGCPriv->patOrg.y = pGC->patOrg.y;
- }
- pScreen->CreateGC = XineramaCreateGC;
-
- return ret;
-}
-
-static void
-XineramaValidateGC(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-){
- Xinerama_GC_FUNC_PROLOGUE (pGC);
-
- if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) {
- /* the root window */
- int x_off = pGC->pScreen->x;
- int y_off = pGC->pScreen->y;
- int new_val;
-
- new_val = pGCPriv->clipOrg.x - x_off;
- if(pGC->clipOrg.x != new_val) {
- pGC->clipOrg.x = new_val;
- changes |= GCClipXOrigin;
- }
- new_val = pGCPriv->clipOrg.y - y_off;
- if(pGC->clipOrg.y != new_val) {
- pGC->clipOrg.y = new_val;
- changes |= GCClipYOrigin;
- }
- new_val = pGCPriv->patOrg.x - x_off;
- if(pGC->patOrg.x != new_val) {
- pGC->patOrg.x = new_val;
- changes |= GCTileStipXOrigin;
- }
- new_val = pGCPriv->patOrg.y - y_off;
- if(pGC->patOrg.y != new_val) {
- pGC->patOrg.y = new_val;
- changes |= GCTileStipYOrigin;
- }
- } else {
- if(pGC->clipOrg.x != pGCPriv->clipOrg.x) {
- pGC->clipOrg.x = pGCPriv->clipOrg.x;
- changes |= GCClipXOrigin;
- }
- if(pGC->clipOrg.y != pGCPriv->clipOrg.y) {
- pGC->clipOrg.y = pGCPriv->clipOrg.y;
- changes |= GCClipYOrigin;
- }
- if(pGC->patOrg.x != pGCPriv->patOrg.x) {
- pGC->patOrg.x = pGCPriv->patOrg.x;
- changes |= GCTileStipXOrigin;
- }
- if(pGC->patOrg.y != pGCPriv->patOrg.y) {
- pGC->patOrg.y = pGCPriv->patOrg.y;
- changes |= GCTileStipYOrigin;
- }
- }
-
- (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
- Xinerama_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XineramaDestroyGC(GCPtr pGC)
-{
- Xinerama_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->DestroyGC)(pGC);
- Xinerama_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XineramaChangeGC (
- GCPtr pGC,
- unsigned long mask
-){
- Xinerama_GC_FUNC_PROLOGUE (pGC);
-
- if(mask & GCTileStipXOrigin)
- pGCPriv->patOrg.x = pGC->patOrg.x;
- if(mask & GCTileStipYOrigin)
- pGCPriv->patOrg.y = pGC->patOrg.y;
- if(mask & GCClipXOrigin)
- pGCPriv->clipOrg.x = pGC->clipOrg.x;
- if(mask & GCClipYOrigin)
- pGCPriv->clipOrg.y = pGC->clipOrg.y;
-
- (*pGC->funcs->ChangeGC) (pGC, mask);
- Xinerama_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XineramaCopyGC (
- GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst
-){
- PanoramiXGCPtr pSrcPriv = (PanoramiXGCPtr)
- dixLookupPrivate(&pGCSrc->devPrivates, PanoramiXGCKey);
- Xinerama_GC_FUNC_PROLOGUE (pGCDst);
-
- if(mask & GCTileStipXOrigin)
- pGCPriv->patOrg.x = pSrcPriv->patOrg.x;
- if(mask & GCTileStipYOrigin)
- pGCPriv->patOrg.y = pSrcPriv->patOrg.y;
- if(mask & GCClipXOrigin)
- pGCPriv->clipOrg.x = pSrcPriv->clipOrg.x;
- if(mask & GCClipYOrigin)
- pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y;
-
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- Xinerama_GC_FUNC_EPILOGUE (pGCDst);
-}
-
-static void
-XineramaChangeClip (
- GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects
-){
- Xinerama_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- Xinerama_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XineramaCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- Xinerama_GC_FUNC_PROLOGUE (pgcDst);
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- Xinerama_GC_FUNC_EPILOGUE (pgcDst);
-}
-
-static void
-XineramaDestroyClip(GCPtr pGC)
-{
- Xinerama_GC_FUNC_PROLOGUE (pGC);
- (* pGC->funcs->DestroyClip)(pGC);
- Xinerama_GC_FUNC_EPILOGUE (pGC);
-}
-
-int
-XineramaDeleteResource(pointer data, XID id)
-{
- free(data);
- return 1;
-}
-
-typedef struct {
- int screen;
- int id;
-} PanoramiXSearchData;
-
-static Bool
-XineramaFindIDByScrnum(pointer resource, XID id, pointer privdata)
-{
- PanoramiXRes *res = (PanoramiXRes*)resource;
- PanoramiXSearchData *data = (PanoramiXSearchData*)privdata;
-
- return res->info[data->screen].id == data->id;
-}
-
-PanoramiXRes *
-PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen)
-{
- PanoramiXSearchData data;
- pointer val;
-
- if(!screen) {
- dixLookupResourceByType(&val, id, type, serverClient, DixReadAccess);
- return val;
- }
-
- data.screen = screen;
- data.id = id;
-
- return LookupClientResourceComplex(clients[CLIENT_ID(id)], type,
- XineramaFindIDByScrnum, &data);
-}
-
-typedef struct _connect_callback_list {
- void (*func)(void);
- struct _connect_callback_list *next;
-} XineramaConnectionCallbackList;
-
-static XineramaConnectionCallbackList *ConnectionCallbackList = NULL;
-
-Bool
-XineramaRegisterConnectionBlockCallback(void (*func)(void))
-{
- XineramaConnectionCallbackList *newlist;
-
- if(!(newlist = malloc(sizeof(XineramaConnectionCallbackList))))
- return FALSE;
-
- newlist->next = ConnectionCallbackList;
- newlist->func = func;
- ConnectionCallbackList = newlist;
-
- return TRUE;
-}
-
-static void XineramaInitData(ScreenPtr pScreen)
-{
- int i, w, h;
-
- RegionNull(&PanoramiXScreenRegion);
- for (i = 0; i < PanoramiXNumScreens; i++) {
- BoxRec TheBox;
- RegionRec ScreenRegion;
-
- pScreen = screenInfo.screens[i];
-
- TheBox.x1 = pScreen->x;
- TheBox.x2 = TheBox.x1 + pScreen->width;
- TheBox.y1 = pScreen->y;
- TheBox.y2 = TheBox.y1 + pScreen->height;
-
- RegionInit(&ScreenRegion, &TheBox, 1);
- RegionUnion(&PanoramiXScreenRegion, &PanoramiXScreenRegion,
- &ScreenRegion);
- RegionUninit(&ScreenRegion);
- }
-
- PanoramiXPixWidth = screenInfo.screens[0]->x + screenInfo.screens[0]->width;
- PanoramiXPixHeight = screenInfo.screens[0]->y + screenInfo.screens[0]->height;
-
- for (i = 1; i < PanoramiXNumScreens; i++) {
- pScreen = screenInfo.screens[i];
- w = pScreen->x + pScreen->width;
- h = pScreen->y + pScreen->height;
-
- if (PanoramiXPixWidth < w)
- PanoramiXPixWidth = w;
- if (PanoramiXPixHeight < h)
- PanoramiXPixHeight = h;
- }
-}
-
-void XineramaReinitData(ScreenPtr pScreen)
-{
- RegionUninit(&PanoramiXScreenRegion);
- XineramaInitData(pScreen);
-}
-
-/*
- * PanoramiXExtensionInit():
- * Called from InitExtensions in main().
- * Register PanoramiXeen Extension
- * Initialize global variables.
- */
-
-void PanoramiXExtensionInit(int argc, char *argv[])
-{
- int i;
- Bool success = FALSE;
- ExtensionEntry *extEntry;
- ScreenPtr pScreen = screenInfo.screens[0];
- PanoramiXScreenPtr pScreenPriv;
-
- if (noPanoramiXExtension)
- return;
-
- if (!dixRegisterPrivateKey(&PanoramiXScreenKeyRec, PRIVATE_SCREEN, 0)) {
- noPanoramiXExtension = TRUE;
- return;
- }
-
- if (!dixRegisterPrivateKey(&PanoramiXGCKeyRec, PRIVATE_GC, sizeof(PanoramiXGCRec))) {
- noPanoramiXExtension = TRUE;
- return;
- }
-
- PanoramiXNumScreens = screenInfo.numScreens;
- if (PanoramiXNumScreens == 1) { /* Only 1 screen */
- noPanoramiXExtension = TRUE;
- return;
- }
-
- while (panoramiXGeneration != serverGeneration) {
- extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
- ProcPanoramiXDispatch,
- SProcPanoramiXDispatch, PanoramiXResetProc,
- StandardMinorOpcode);
- if (!extEntry)
- break;
-
- /*
- * First make sure all the basic allocations succeed. If not,
- * run in non-PanoramiXeen mode.
- */
-
- for (i = 0; i < PanoramiXNumScreens; i++) {
- pScreen = screenInfo.screens[i];
- pScreenPriv = malloc(sizeof(PanoramiXScreenRec));
- dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey,
- pScreenPriv);
- if(!pScreenPriv) {
- noPanoramiXExtension = TRUE;
- return;
- }
-
- pScreenPriv->CreateGC = pScreen->CreateGC;
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
-
- pScreen->CreateGC = XineramaCreateGC;
- pScreen->CloseScreen = XineramaCloseScreen;
- }
-
- XRC_DRAWABLE = CreateNewResourceClass();
- XRT_WINDOW = CreateNewResourceType(XineramaDeleteResource,
- "XineramaWindow");
- if (XRT_WINDOW)
- XRT_WINDOW |= XRC_DRAWABLE;
- XRT_PIXMAP = CreateNewResourceType(XineramaDeleteResource,
- "XineramaPixmap");
- if (XRT_PIXMAP)
- XRT_PIXMAP |= XRC_DRAWABLE;
- XRT_GC = CreateNewResourceType(XineramaDeleteResource,
- "XineramaGC");
- XRT_COLORMAP = CreateNewResourceType(XineramaDeleteResource,
- "XineramaColormap");
-
- if (XRT_WINDOW && XRT_PIXMAP && XRT_GC && XRT_COLORMAP) {
- panoramiXGeneration = serverGeneration;
- success = TRUE;
- }
- SetResourceTypeErrorValue(XRT_WINDOW, BadWindow);
- SetResourceTypeErrorValue(XRT_PIXMAP, BadPixmap);
- SetResourceTypeErrorValue(XRT_GC, BadGC);
- SetResourceTypeErrorValue(XRT_COLORMAP, BadColor);
- }
-
- if (!success) {
- noPanoramiXExtension = TRUE;
- ErrorF(PANORAMIX_PROTOCOL_NAME " extension failed to initialize\n");
- return;
- }
-
- XineramaInitData(pScreen);
-
- /*
- * Put our processes into the ProcVector
- */
-
- for (i = 256; i--; )
- SavedProcVector[i] = ProcVector[i];
-
- ProcVector[X_CreateWindow] = PanoramiXCreateWindow;
- ProcVector[X_ChangeWindowAttributes] = PanoramiXChangeWindowAttributes;
- ProcVector[X_DestroyWindow] = PanoramiXDestroyWindow;
- ProcVector[X_DestroySubwindows] = PanoramiXDestroySubwindows;
- ProcVector[X_ChangeSaveSet] = PanoramiXChangeSaveSet;
- ProcVector[X_ReparentWindow] = PanoramiXReparentWindow;
- ProcVector[X_MapWindow] = PanoramiXMapWindow;
- ProcVector[X_MapSubwindows] = PanoramiXMapSubwindows;
- ProcVector[X_UnmapWindow] = PanoramiXUnmapWindow;
- ProcVector[X_UnmapSubwindows] = PanoramiXUnmapSubwindows;
- ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow;
- ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow;
- ProcVector[X_GetGeometry] = PanoramiXGetGeometry;
- ProcVector[X_TranslateCoords] = PanoramiXTranslateCoords;
- ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap;
- ProcVector[X_FreePixmap] = PanoramiXFreePixmap;
- ProcVector[X_CreateGC] = PanoramiXCreateGC;
- ProcVector[X_ChangeGC] = PanoramiXChangeGC;
- ProcVector[X_CopyGC] = PanoramiXCopyGC;
- ProcVector[X_SetDashes] = PanoramiXSetDashes;
- ProcVector[X_SetClipRectangles] = PanoramiXSetClipRectangles;
- ProcVector[X_FreeGC] = PanoramiXFreeGC;
- ProcVector[X_ClearArea] = PanoramiXClearToBackground;
- ProcVector[X_CopyArea] = PanoramiXCopyArea;
- ProcVector[X_CopyPlane] = PanoramiXCopyPlane;
- ProcVector[X_PolyPoint] = PanoramiXPolyPoint;
- ProcVector[X_PolyLine] = PanoramiXPolyLine;
- ProcVector[X_PolySegment] = PanoramiXPolySegment;
- ProcVector[X_PolyRectangle] = PanoramiXPolyRectangle;
- ProcVector[X_PolyArc] = PanoramiXPolyArc;
- ProcVector[X_FillPoly] = PanoramiXFillPoly;
- ProcVector[X_PolyFillRectangle] = PanoramiXPolyFillRectangle;
- ProcVector[X_PolyFillArc] = PanoramiXPolyFillArc;
- ProcVector[X_PutImage] = PanoramiXPutImage;
- ProcVector[X_GetImage] = PanoramiXGetImage;
- ProcVector[X_PolyText8] = PanoramiXPolyText8;
- ProcVector[X_PolyText16] = PanoramiXPolyText16;
- ProcVector[X_ImageText8] = PanoramiXImageText8;
- ProcVector[X_ImageText16] = PanoramiXImageText16;
- ProcVector[X_CreateColormap] = PanoramiXCreateColormap;
- ProcVector[X_FreeColormap] = PanoramiXFreeColormap;
- ProcVector[X_CopyColormapAndFree] = PanoramiXCopyColormapAndFree;
- ProcVector[X_InstallColormap] = PanoramiXInstallColormap;
- ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap;
- ProcVector[X_AllocColor] = PanoramiXAllocColor;
- ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor;
- ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells;
- ProcVector[X_AllocColorPlanes] = PanoramiXAllocColorPlanes;
- ProcVector[X_FreeColors] = PanoramiXFreeColors;
- ProcVector[X_StoreColors] = PanoramiXStoreColors;
- ProcVector[X_StoreNamedColor] = PanoramiXStoreNamedColor;
-
- PanoramiXRenderInit ();
-#ifdef XFIXES
- PanoramiXFixesInit ();
-#endif
-#ifdef COMPOSITE
- PanoramiXCompositeInit ();
-#endif
-
-}
-
-extern Bool CreateConnectionBlock(void);
-
-Bool PanoramiXCreateConnectionBlock(void)
-{
- int i, j, length;
- Bool disableBackingStore = FALSE;
- int old_width, old_height;
- float width_mult, height_mult;
- xWindowRoot *root;
- xVisualType *visual;
- xDepth *depth;
- VisualPtr pVisual;
- ScreenPtr pScreen;
-
- /*
- * Do normal CreateConnectionBlock but faking it for only one screen
- */
-
- if(!PanoramiXNumDepths) {
- ErrorF("Xinerama error: No common visuals\n");
- return FALSE;
- }
-
- for(i = 1; i < screenInfo.numScreens; i++) {
- pScreen = screenInfo.screens[i];
- if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) {
- ErrorF("Xinerama error: Root window depths differ\n");
- return FALSE;
- }
- if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport)
- disableBackingStore = TRUE;
- }
-
- if (disableBackingStore) {
- for (i = 0; i < screenInfo.numScreens; i++) {
- pScreen = screenInfo.screens[i];
- pScreen->backingStoreSupport = NotUseful;
- }
- }
-
- i = screenInfo.numScreens;
- screenInfo.numScreens = 1;
- if (!CreateConnectionBlock()) {
- screenInfo.numScreens = i;
- return FALSE;
- }
-
- screenInfo.numScreens = i;
-
- root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart);
- length = connBlockScreenStart + sizeof(xWindowRoot);
-
- /* overwrite the connection block */
- root->nDepths = PanoramiXNumDepths;
-
- for (i = 0; i < PanoramiXNumDepths; i++) {
- depth = (xDepth *) (ConnectionInfo + length);
- depth->depth = PanoramiXDepths[i].depth;
- depth->nVisuals = PanoramiXDepths[i].numVids;
- length += sizeof(xDepth);
- visual = (xVisualType *)(ConnectionInfo + length);
-
- for (j = 0; j < depth->nVisuals; j++, visual++) {
- visual->visualID = PanoramiXDepths[i].vids[j];
-
- for (pVisual = PanoramiXVisuals;
- pVisual->vid != visual->visualID;
- pVisual++)
- ;
-
- visual->class = pVisual->class;
- visual->bitsPerRGB = pVisual->bitsPerRGBValue;
- visual->colormapEntries = pVisual->ColormapEntries;
- visual->redMask = pVisual->redMask;
- visual->greenMask = pVisual->greenMask;
- visual->blueMask = pVisual->blueMask;
- }
-
- length += (depth->nVisuals * sizeof(xVisualType));
- }
-
- connSetupPrefix.length = bytes_to_int32(length);
-
- for (i = 0; i < PanoramiXNumDepths; i++)
- free(PanoramiXDepths[i].vids);
- free(PanoramiXDepths);
- PanoramiXDepths = NULL;
-
- /*
- * OK, change some dimensions so it looks as if it were one big screen
- */
-
- old_width = root->pixWidth;
- old_height = root->pixHeight;
-
- root->pixWidth = PanoramiXPixWidth;
- root->pixHeight = PanoramiXPixHeight;
- width_mult = (1.0 * root->pixWidth) / old_width;
- height_mult = (1.0 * root->pixHeight) / old_height;
- root->mmWidth *= width_mult;
- root->mmHeight *= height_mult;
-
- while(ConnectionCallbackList) {
- pointer tmp;
-
- tmp = (pointer)ConnectionCallbackList;
- (*ConnectionCallbackList->func)();
- ConnectionCallbackList = ConnectionCallbackList->next;
- free(tmp);
- }
-
- return TRUE;
-}
-
-/*
- * This isn't just memcmp(), bitsPerRGBValue is skipped. markv made that
- * change way back before xf86 4.0, but the comment for _why_ is a bit
- * opaque, so I'm not going to question it for now.
- *
- * This is probably better done as a screen hook so DBE/EVI/GLX can add
- * their own tests, and adding privates to VisualRec so they don't have to
- * do their own back-mapping.
- */
-static Bool
-VisualsEqual(VisualPtr a, ScreenPtr pScreenB, VisualPtr b)
-{
- return ((a->class == b->class) &&
- (a->ColormapEntries == b->ColormapEntries) &&
- (a->nplanes == b->nplanes) &&
- (a->redMask == b->redMask) &&
- (a->greenMask == b->greenMask) &&
- (a->blueMask == b->blueMask) &&
- (a->offsetRed == b->offsetRed) &&
- (a->offsetGreen == b->offsetGreen) &&
- (a->offsetBlue == b->offsetBlue));
-}
-
-static void
-PanoramiXMaybeAddDepth(DepthPtr pDepth)
-{
- ScreenPtr pScreen;
- int j, k;
- Bool found = FALSE;
-
- for (j = 1; j < PanoramiXNumScreens; j++) {
- pScreen = screenInfo.screens[j];
- for (k = 0; k < pScreen->numDepths; k++) {
- if (pScreen->allowedDepths[k].depth == pDepth->depth) {
- found = TRUE;
- break;
- }
- }
- }
-
- if (!found)
- return;
-
- j = PanoramiXNumDepths;
- PanoramiXNumDepths++;
- PanoramiXDepths = realloc(PanoramiXDepths,
- PanoramiXNumDepths * sizeof(DepthRec));
- PanoramiXDepths[j].depth = pDepth->depth;
- PanoramiXDepths[j].numVids = 0;
- /* XXX suboptimal, should grow these dynamically */
- if(pDepth->numVids)
- PanoramiXDepths[j].vids = malloc(sizeof(VisualID) * pDepth->numVids);
- else
- PanoramiXDepths[j].vids = NULL;
-}
-
-static void
-PanoramiXMaybeAddVisual(VisualPtr pVisual)
-{
- ScreenPtr pScreen;
- int j, k;
- Bool found = FALSE;
-
- for (j = 1; j < PanoramiXNumScreens; j++) {
- pScreen = screenInfo.screens[j];
- found = FALSE;
-
- for (k = 0; k < pScreen->numVisuals; k++) {
- VisualPtr candidate = &pScreen->visuals[k];
-
- if ((*XineramaVisualsEqualPtr)(pVisual, pScreen, candidate)
-#ifdef GLXPROXY
- && glxMatchVisual(screenInfo.screens[0], pVisual, pScreen)
-#endif
- ) {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- return;
- }
-
- /* found a matching visual on all screens, add it to the subset list */
- j = PanoramiXNumVisuals;
- PanoramiXNumVisuals++;
- PanoramiXVisuals = realloc(PanoramiXVisuals,
- PanoramiXNumVisuals * sizeof(VisualRec));
-
- memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec));
-
- for (k = 0; k < PanoramiXNumDepths; k++) {
- if (PanoramiXDepths[k].depth == pVisual->nplanes) {
- PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid;
- PanoramiXDepths[k].numVids++;
- break;
- }
- }
-}
-
-extern void
-PanoramiXConsolidate(void)
-{
- int i;
- PanoramiXRes *root, *defmap, *saver;
- ScreenPtr pScreen = screenInfo.screens[0];
- DepthPtr pDepth = pScreen->allowedDepths;
- VisualPtr pVisual = pScreen->visuals;
-
- PanoramiXNumDepths = 0;
- PanoramiXNumVisuals = 0;
-
- for (i = 0; i < pScreen->numDepths; i++)
- PanoramiXMaybeAddDepth(pDepth++);
-
- for (i = 0; i < pScreen->numVisuals; i++)
- PanoramiXMaybeAddVisual(pVisual++);
-
- root = malloc(sizeof(PanoramiXRes));
- root->type = XRT_WINDOW;
- defmap = malloc(sizeof(PanoramiXRes));
- defmap->type = XRT_COLORMAP;
- saver = malloc(sizeof(PanoramiXRes));
- saver->type = XRT_WINDOW;
-
- for (i = 0; i < PanoramiXNumScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- root->info[i].id = pScreen->root->drawable.id;
- root->u.win.class = InputOutput;
- root->u.win.root = TRUE;
- saver->info[i].id = pScreen->screensaver.wid;
- saver->u.win.class = InputOutput;
- saver->u.win.root = TRUE;
- defmap->info[i].id = pScreen->defColormap;
- }
-
- AddResource(root->info[0].id, XRT_WINDOW, root);
- AddResource(saver->info[0].id, XRT_WINDOW, saver);
- AddResource(defmap->info[0].id, XRT_COLORMAP, defmap);
-}
-
-VisualID
-PanoramiXTranslateVisualID(int screen, VisualID orig)
-{
- ScreenPtr pOtherScreen = screenInfo.screens[screen];
- VisualPtr pVisual = NULL;
- int i;
-
- for (i = 0; i < PanoramiXNumVisuals; i++) {
- if (orig == PanoramiXVisuals[i].vid) {
- pVisual = &PanoramiXVisuals[i];
- break;
- }
- }
-
- if (!pVisual)
- return 0;
-
- /* if screen is 0, orig is already the correct visual ID */
- if (screen == 0)
- return orig;
-
- /* found the original, now translate it relative to the backend screen */
- for (i = 0; i < pOtherScreen->numVisuals; i++) {
- VisualPtr pOtherVisual = &pOtherScreen->visuals[i];
-
- if ((*XineramaVisualsEqualPtr)(pVisual, pOtherScreen, pOtherVisual))
- return pOtherVisual->vid;
- }
-
- return 0;
-}
-
-
-/*
- * PanoramiXResetProc()
- * Exit, deallocating as needed.
- */
-
-static void PanoramiXResetProc(ExtensionEntry* extEntry)
-{
- int i;
-
- PanoramiXRenderReset ();
-#ifdef XFIXES
- PanoramiXFixesReset ();
-#endif
- screenInfo.numScreens = PanoramiXNumScreens;
- for (i = 256; i--; )
- ProcVector[i] = SavedProcVector[i];
-}
-
-
-int
-ProcPanoramiXQueryVersion (ClientPtr client)
-{
- /* REQUEST(xPanoramiXQueryVersionReq); */
- xPanoramiXQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION;
- rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- }
- WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-int
-ProcPanoramiXGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
- WindowPtr pWin;
- xPanoramiXGetStateReply rep;
- int n, rc;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !noPanoramiXExtension;
- rep.window = stuff->window;
- if (client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.window, n);
- }
- WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
- return Success;
-
-}
-
-int
-ProcPanoramiXGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
- WindowPtr pWin;
- xPanoramiXGetScreenCountReply rep;
- int n, rc;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.ScreenCount = PanoramiXNumScreens;
- rep.window = stuff->window;
- if (client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.window, n);
- }
- WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep);
- return Success;
-}
-
-int
-ProcPanoramiXGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
- WindowPtr pWin;
- xPanoramiXGetScreenSizeReply rep;
- int n, rc;
-
- if (stuff->screen >= PanoramiXNumScreens)
- return BadMatch;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- /* screen dimensions */
- rep.width = screenInfo.screens[stuff->screen]->width;
- rep.height = screenInfo.screens[stuff->screen]->height;
- rep.window = stuff->window;
- rep.screen = stuff->screen;
- if (client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.width, n);
- swapl (&rep.height, n);
- swapl (&rep.window, n);
- swapl (&rep.screen, n);
- }
- WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep);
- return Success;
-}
-
-
-int
-ProcXineramaIsActive(ClientPtr client)
-{
- /* REQUEST(xXineramaIsActiveReq); */
- xXineramaIsActiveReply rep;
-
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-#if 1
- {
- /* The following hack fools clients into thinking that Xinerama
- * is disabled even though it is not. */
- rep.state = !noPanoramiXExtension && !PanoramiXExtensionDisabledHack;
- }
-#else
- rep.state = !noPanoramiXExtension;
-#endif
- if (client->swapped) {
- int n;
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.state, n);
- }
- WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
- return Success;
-}
-
-
-int
-ProcXineramaQueryScreens(ClientPtr client)
-{
- /* REQUEST(xXineramaQueryScreensReq); */
- xXineramaQueryScreensReply rep;
-
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens;
- rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
- if (client->swapped) {
- int n;
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.number, n);
- }
- WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
-
- if(!noPanoramiXExtension) {
- xXineramaScreenInfo scratch;
- int i;
-
- for(i = 0; i < PanoramiXNumScreens; i++) {
- scratch.x_org = screenInfo.screens[i]->x;
- scratch.y_org = screenInfo.screens[i]->y;
- scratch.width = screenInfo.screens[i]->width;
- scratch.height = screenInfo.screens[i]->height;
-
- if(client->swapped) {
- int n;
- swaps (&scratch.x_org, n);
- swaps (&scratch.y_org, n);
- swaps (&scratch.width, n);
- swaps (&scratch.height, n);
- }
- WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
- }
- }
-
- return Success;
-}
-
-
-static int
-ProcPanoramiXDispatch (ClientPtr client)
-{ REQUEST(xReq);
- switch (stuff->data)
- {
- case X_PanoramiXQueryVersion:
- return ProcPanoramiXQueryVersion(client);
- case X_PanoramiXGetState:
- return ProcPanoramiXGetState(client);
- case X_PanoramiXGetScreenCount:
- return ProcPanoramiXGetScreenCount(client);
- case X_PanoramiXGetScreenSize:
- return ProcPanoramiXGetScreenSize(client);
- case X_XineramaIsActive:
- return ProcXineramaIsActive(client);
- case X_XineramaQueryScreens:
- return ProcXineramaQueryScreens(client);
- }
- return BadRequest;
-}
-
-
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
-#define SHIFT_L(v,s) (v) << (s)
-#define SHIFT_R(v,s) (v) >> (s)
-#else
-#define SHIFT_L(v,s) (v) >> (s)
-#define SHIFT_R(v,s) (v) << (s)
-#endif
-
-static void
-CopyBits(char *dst, int shiftL, char *src, int bytes)
-{
- /* Just get it to work. Worry about speed later */
- int shiftR = 8 - shiftL;
-
- while(bytes--) {
- *dst |= SHIFT_L(*src, shiftL);
- *(dst + 1) |= SHIFT_R(*src, shiftR);
- dst++; src++;
- }
-}
-
-
-/* Caution. This doesn't support 2 and 4 bpp formats. We expect
- 1 bpp and planar data to be already cleared when presented
- to this function */
-
-void
-XineramaGetImageData(
- DrawablePtr *pDrawables,
- int left,
- int top,
- int width,
- int height,
- unsigned int format,
- unsigned long planemask,
- char *data,
- int pitch,
- Bool isRoot
-){
- RegionRec SrcRegion, ScreenRegion, GrabRegion;
- BoxRec SrcBox, *pbox;
- int x, y, w, h, i, j, nbox, size, sizeNeeded, ScratchPitch, inOut, depth;
- DrawablePtr pDraw = pDrawables[0];
- char *ScratchMem = NULL;
-
- size = 0;
-
- /* find box in logical screen space */
- SrcBox.x1 = left;
- SrcBox.y1 = top;
- if(!isRoot) {
- SrcBox.x1 += pDraw->x + screenInfo.screens[0]->x;
- SrcBox.y1 += pDraw->y + screenInfo.screens[0]->y;
- }
- SrcBox.x2 = SrcBox.x1 + width;
- SrcBox.y2 = SrcBox.y1 + height;
-
- RegionInit(&SrcRegion, &SrcBox, 1);
- RegionNull(&GrabRegion);
-
- depth = (format == XYPixmap) ? 1 : pDraw->depth;
-
- for(i = 0; i < PanoramiXNumScreens; i++) {
- BoxRec TheBox;
- ScreenPtr pScreen;
- pDraw = pDrawables[i];
- pScreen = pDraw->pScreen;
-
- TheBox.x1 = pScreen->x;
- TheBox.x2 = TheBox.x1 + pScreen->width;
- TheBox.y1 = pScreen->y;
- TheBox.y2 = TheBox.y1 + pScreen->height;
-
- RegionInit(&ScreenRegion, &TheBox, 1);
- inOut = RegionContainsRect(&ScreenRegion, &SrcBox);
- if(inOut == rgnPART)
- RegionIntersect(&GrabRegion, &SrcRegion, &ScreenRegion);
- RegionUninit(&ScreenRegion);
-
- if(inOut == rgnIN) {
- (*pScreen->GetImage)(pDraw,
- SrcBox.x1 - pDraw->x - screenInfo.screens[i]->x,
- SrcBox.y1 - pDraw->y - screenInfo.screens[i]->y,
- width, height, format, planemask, data);
- break;
- } else if (inOut == rgnOUT)
- continue;
-
- nbox = RegionNumRects(&GrabRegion);
-
- if(nbox) {
- pbox = RegionRects(&GrabRegion);
-
- while(nbox--) {
- w = pbox->x2 - pbox->x1;
- h = pbox->y2 - pbox->y1;
- ScratchPitch = PixmapBytePad(w, depth);
- sizeNeeded = ScratchPitch * h;
-
- if(sizeNeeded > size) {
- char *tmpdata = ScratchMem;
- ScratchMem = realloc(ScratchMem, sizeNeeded);
- if(ScratchMem)
- size = sizeNeeded;
- else {
- ScratchMem = tmpdata;
- break;
- }
- }
-
- x = pbox->x1 - pDraw->x - screenInfo.screens[i]->x;
- y = pbox->y1 - pDraw->y - screenInfo.screens[i]->y;
-
- (*pScreen->GetImage)(pDraw, x, y, w, h,
- format, planemask, ScratchMem);
-
- /* copy the memory over */
-
- if(depth == 1) {
- int k, shift, leftover, index, index2;
-
- x = pbox->x1 - SrcBox.x1;
- y = pbox->y1 - SrcBox.y1;
- shift = x & 7;
- x >>= 3;
- leftover = w & 7;
- w >>= 3;
-
- /* clean up the edge */
- if(leftover) {
- int mask = (1 << leftover) - 1;
- for(j = h, k = w; j--; k += ScratchPitch)
- ScratchMem[k] &= mask;
- }
-
- for(j = 0, index = (pitch * y) + x, index2 = 0; j < h;
- j++, index += pitch, index2 += ScratchPitch)
- {
- if(w) {
- if(!shift)
- memcpy(data + index, ScratchMem + index2, w);
- else
- CopyBits(data + index, shift,
- ScratchMem + index2, w);
- }
-
- if(leftover) {
- data[index + w] |=
- SHIFT_L(ScratchMem[index2 + w], shift);
- if((shift + leftover) > 8)
- data[index + w + 1] |=
- SHIFT_R(ScratchMem[index2 + w],(8 - shift));
- }
- }
- } else {
- j = BitsPerPixel(depth) >> 3;
- x = (pbox->x1 - SrcBox.x1) * j;
- y = pbox->y1 - SrcBox.y1;
- w *= j;
-
- for(j = 0; j < h; j++) {
- memcpy(data + (pitch * (y + j)) + x,
- ScratchMem + (ScratchPitch * j), w);
- }
- }
- pbox++;
- }
-
- RegionSubtract(&SrcRegion, &SrcRegion, &GrabRegion);
- if(!RegionNotEmpty(&SrcRegion))
- break;
- }
-
- }
-
- free(ScratchMem);
-
- RegionUninit(&SrcRegion);
- RegionUninit(&GrabRegion);
-}
+/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include <stdio.h> +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/Xarch.h> +#include "misc.h" +#include "cursor.h" +#include "cursorstr.h" +#include "extnsionst.h" +#include "dixstruct.h" +#include "gc.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "window.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "panoramiX.h" +#include <X11/extensions/panoramiXproto.h> +#include "panoramiXsrv.h" +#include "globals.h" +#include "servermd.h" +#include "resource.h" +#include "picturestr.h" +#ifdef XFIXES +#include "xfixesint.h" +#endif +#ifdef COMPOSITE +#include "compint.h" +#endif +#include "modinit.h" +#include "protocol-versions.h" + +#ifdef GLXPROXY +extern VisualPtr glxMatchVisual(ScreenPtr pScreen, + VisualPtr pVisual, + ScreenPtr pMatchScreen); +#endif + +/* + * PanoramiX data declarations + */ + +int PanoramiXPixWidth = 0; +int PanoramiXPixHeight = 0; +int PanoramiXNumScreens = 0; + +static RegionRec PanoramiXScreenRegion = {{0, 0, 0, 0}, NULL}; + +static int PanoramiXNumDepths; +static DepthPtr PanoramiXDepths; +static int PanoramiXNumVisuals; +static VisualPtr PanoramiXVisuals; + +RESTYPE XRC_DRAWABLE; +RESTYPE XRT_WINDOW; +RESTYPE XRT_PIXMAP; +RESTYPE XRT_GC; +RESTYPE XRT_COLORMAP; + +static Bool VisualsEqual(VisualPtr, ScreenPtr, VisualPtr); +XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr = &VisualsEqual; + +/* + * Function prototypes + */ + +static int panoramiXGeneration; +static int ProcPanoramiXDispatch(ClientPtr client); + +static void PanoramiXResetProc(ExtensionEntry*); + +/* + * External references for functions and data variables + */ + +#include "panoramiXh.h" + +int (* SavedProcVector[256]) (ClientPtr client) = { NULL, }; + +static DevPrivateKeyRec PanoramiXGCKeyRec; +#define PanoramiXGCKey (&PanoramiXGCKeyRec) +static DevPrivateKeyRec PanoramiXScreenKeyRec; +#define PanoramiXScreenKey (&PanoramiXScreenKeyRec) + +typedef struct { + DDXPointRec clipOrg; + DDXPointRec patOrg; + GCFuncs *wrapFuncs; +} PanoramiXGCRec, *PanoramiXGCPtr; + +typedef struct { + CreateGCProcPtr CreateGC; + CloseScreenProcPtr CloseScreen; +} PanoramiXScreenRec, *PanoramiXScreenPtr; + +static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr); +static void XineramaChangeGC(GCPtr, unsigned long); +static void XineramaCopyGC(GCPtr, unsigned long, GCPtr); +static void XineramaDestroyGC(GCPtr); +static void XineramaChangeClip(GCPtr, int, pointer, int); +static void XineramaDestroyClip(GCPtr); +static void XineramaCopyClip(GCPtr, GCPtr); + +static GCFuncs XineramaGCFuncs = { + XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC, + XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip +}; + +#define Xinerama_GC_FUNC_PROLOGUE(pGC)\ + PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) \ + dixLookupPrivate(&(pGC)->devPrivates, PanoramiXGCKey); \ + (pGC)->funcs = pGCPriv->wrapFuncs; + +#define Xinerama_GC_FUNC_EPILOGUE(pGC)\ + pGCPriv->wrapFuncs = (pGC)->funcs;\ + (pGC)->funcs = &XineramaGCFuncs; + + +static Bool +XineramaCloseScreen (int i, ScreenPtr pScreen) +{ + PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) + dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->CreateGC = pScreenPriv->CreateGC; + + if (pScreen->myNum == 0) + RegionUninit(&PanoramiXScreenRegion); + + free((pointer) pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} + +static Bool +XineramaCreateGC(GCPtr pGC) +{ + ScreenPtr pScreen = pGC->pScreen; + PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) + dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey); + Bool ret; + + pScreen->CreateGC = pScreenPriv->CreateGC; + if((ret = (*pScreen->CreateGC)(pGC))) { + PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) + dixLookupPrivate(&pGC->devPrivates, PanoramiXGCKey); + + pGCPriv->wrapFuncs = pGC->funcs; + pGC->funcs = &XineramaGCFuncs; + + pGCPriv->clipOrg.x = pGC->clipOrg.x; + pGCPriv->clipOrg.y = pGC->clipOrg.y; + pGCPriv->patOrg.x = pGC->patOrg.x; + pGCPriv->patOrg.y = pGC->patOrg.y; + } + pScreen->CreateGC = XineramaCreateGC; + + return ret; +} + +static void +XineramaValidateGC( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw +){ + Xinerama_GC_FUNC_PROLOGUE (pGC); + + if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) { + /* the root window */ + int x_off = pGC->pScreen->x; + int y_off = pGC->pScreen->y; + int new_val; + + new_val = pGCPriv->clipOrg.x - x_off; + if(pGC->clipOrg.x != new_val) { + pGC->clipOrg.x = new_val; + changes |= GCClipXOrigin; + } + new_val = pGCPriv->clipOrg.y - y_off; + if(pGC->clipOrg.y != new_val) { + pGC->clipOrg.y = new_val; + changes |= GCClipYOrigin; + } + new_val = pGCPriv->patOrg.x - x_off; + if(pGC->patOrg.x != new_val) { + pGC->patOrg.x = new_val; + changes |= GCTileStipXOrigin; + } + new_val = pGCPriv->patOrg.y - y_off; + if(pGC->patOrg.y != new_val) { + pGC->patOrg.y = new_val; + changes |= GCTileStipYOrigin; + } + } else { + if(pGC->clipOrg.x != pGCPriv->clipOrg.x) { + pGC->clipOrg.x = pGCPriv->clipOrg.x; + changes |= GCClipXOrigin; + } + if(pGC->clipOrg.y != pGCPriv->clipOrg.y) { + pGC->clipOrg.y = pGCPriv->clipOrg.y; + changes |= GCClipYOrigin; + } + if(pGC->patOrg.x != pGCPriv->patOrg.x) { + pGC->patOrg.x = pGCPriv->patOrg.x; + changes |= GCTileStipXOrigin; + } + if(pGC->patOrg.y != pGCPriv->patOrg.y) { + pGC->patOrg.y = pGCPriv->patOrg.y; + changes |= GCTileStipYOrigin; + } + } + + (*pGC->funcs->ValidateGC)(pGC, changes, pDraw); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaDestroyGC(GCPtr pGC) +{ + Xinerama_GC_FUNC_PROLOGUE (pGC); + (*pGC->funcs->DestroyGC)(pGC); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaChangeGC ( + GCPtr pGC, + unsigned long mask +){ + Xinerama_GC_FUNC_PROLOGUE (pGC); + + if(mask & GCTileStipXOrigin) + pGCPriv->patOrg.x = pGC->patOrg.x; + if(mask & GCTileStipYOrigin) + pGCPriv->patOrg.y = pGC->patOrg.y; + if(mask & GCClipXOrigin) + pGCPriv->clipOrg.x = pGC->clipOrg.x; + if(mask & GCClipYOrigin) + pGCPriv->clipOrg.y = pGC->clipOrg.y; + + (*pGC->funcs->ChangeGC) (pGC, mask); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaCopyGC ( + GCPtr pGCSrc, + unsigned long mask, + GCPtr pGCDst +){ + PanoramiXGCPtr pSrcPriv = (PanoramiXGCPtr) + dixLookupPrivate(&pGCSrc->devPrivates, PanoramiXGCKey); + Xinerama_GC_FUNC_PROLOGUE (pGCDst); + + if(mask & GCTileStipXOrigin) + pGCPriv->patOrg.x = pSrcPriv->patOrg.x; + if(mask & GCTileStipYOrigin) + pGCPriv->patOrg.y = pSrcPriv->patOrg.y; + if(mask & GCClipXOrigin) + pGCPriv->clipOrg.x = pSrcPriv->clipOrg.x; + if(mask & GCClipYOrigin) + pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y; + + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); + Xinerama_GC_FUNC_EPILOGUE (pGCDst); +} + +static void +XineramaChangeClip ( + GCPtr pGC, + int type, + pointer pvalue, + int nrects +){ + Xinerama_GC_FUNC_PROLOGUE (pGC); + (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + Xinerama_GC_FUNC_PROLOGUE (pgcDst); + (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); + Xinerama_GC_FUNC_EPILOGUE (pgcDst); +} + +static void +XineramaDestroyClip(GCPtr pGC) +{ + Xinerama_GC_FUNC_PROLOGUE (pGC); + (* pGC->funcs->DestroyClip)(pGC); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +int +XineramaDeleteResource(pointer data, XID id) +{ + free(data); + return 1; +} + +typedef struct { + int screen; + int id; +} PanoramiXSearchData; + +static Bool +XineramaFindIDByScrnum(pointer resource, XID id, pointer privdata) +{ + PanoramiXRes *res = (PanoramiXRes*)resource; + PanoramiXSearchData *data = (PanoramiXSearchData*)privdata; + + return res->info[data->screen].id == data->id; +} + +PanoramiXRes * +PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen) +{ + PanoramiXSearchData data; + pointer val; + + if(!screen) { + dixLookupResourceByType(&val, id, type, serverClient, DixReadAccess); + return val; + } + + data.screen = screen; + data.id = id; + + return LookupClientResourceComplex(clients[CLIENT_ID(id)], type, + XineramaFindIDByScrnum, &data); +} + +typedef struct _connect_callback_list { + void (*func)(void); + struct _connect_callback_list *next; +} XineramaConnectionCallbackList; + +static XineramaConnectionCallbackList *ConnectionCallbackList = NULL; + +Bool +XineramaRegisterConnectionBlockCallback(void (*func)(void)) +{ + XineramaConnectionCallbackList *newlist; + + if(!(newlist = malloc(sizeof(XineramaConnectionCallbackList)))) + return FALSE; + + newlist->next = ConnectionCallbackList; + newlist->func = func; + ConnectionCallbackList = newlist; + + return TRUE; +} + +static void XineramaInitData(ScreenPtr pScreen) +{ + int i, w, h; + + RegionNull(&PanoramiXScreenRegion); + for (i = 0; i < PanoramiXNumScreens; i++) { + BoxRec TheBox; + RegionRec ScreenRegion; + + pScreen = screenInfo.screens[i]; + + TheBox.x1 = pScreen->x; + TheBox.x2 = TheBox.x1 + pScreen->width; + TheBox.y1 = pScreen->y; + TheBox.y2 = TheBox.y1 + pScreen->height; + + RegionInit(&ScreenRegion, &TheBox, 1); + RegionUnion(&PanoramiXScreenRegion, &PanoramiXScreenRegion, + &ScreenRegion); + RegionUninit(&ScreenRegion); + } + + PanoramiXPixWidth = screenInfo.screens[0]->x + screenInfo.screens[0]->width; + PanoramiXPixHeight = screenInfo.screens[0]->y + screenInfo.screens[0]->height; + + for (i = 1; i < PanoramiXNumScreens; i++) { + pScreen = screenInfo.screens[i]; + w = pScreen->x + pScreen->width; + h = pScreen->y + pScreen->height; + + if (PanoramiXPixWidth < w) + PanoramiXPixWidth = w; + if (PanoramiXPixHeight < h) + PanoramiXPixHeight = h; + } +} + +void XineramaReinitData(ScreenPtr pScreen) +{ + RegionUninit(&PanoramiXScreenRegion); + XineramaInitData(pScreen); +} + +/* + * PanoramiXExtensionInit(): + * Called from InitExtensions in main(). + * Register PanoramiXeen Extension + * Initialize global variables. + */ + +void PanoramiXExtensionInit(int argc, char *argv[]) +{ + int i; + Bool success = FALSE; + ExtensionEntry *extEntry; + ScreenPtr pScreen = screenInfo.screens[0]; + PanoramiXScreenPtr pScreenPriv; + + if (noPanoramiXExtension) + return; + + if (!dixRegisterPrivateKey(&PanoramiXScreenKeyRec, PRIVATE_SCREEN, 0)) { + noPanoramiXExtension = TRUE; + return; + } + + if (!dixRegisterPrivateKey(&PanoramiXGCKeyRec, PRIVATE_GC, sizeof(PanoramiXGCRec))) { + noPanoramiXExtension = TRUE; + return; + } + + PanoramiXNumScreens = screenInfo.numScreens; + if (PanoramiXNumScreens == 1) { /* Only 1 screen */ + noPanoramiXExtension = TRUE; + return; + } + + while (panoramiXGeneration != serverGeneration) { + extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcPanoramiXDispatch, + SProcPanoramiXDispatch, PanoramiXResetProc, + StandardMinorOpcode); + if (!extEntry) + break; + + /* + * First make sure all the basic allocations succeed. If not, + * run in non-PanoramiXeen mode. + */ + + for (i = 0; i < PanoramiXNumScreens; i++) { + pScreen = screenInfo.screens[i]; + pScreenPriv = malloc(sizeof(PanoramiXScreenRec)); + dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey, + pScreenPriv); + if(!pScreenPriv) { + noPanoramiXExtension = TRUE; + return; + } + + pScreenPriv->CreateGC = pScreen->CreateGC; + pScreenPriv->CloseScreen = pScreen->CloseScreen; + + pScreen->CreateGC = XineramaCreateGC; + pScreen->CloseScreen = XineramaCloseScreen; + } + + XRC_DRAWABLE = CreateNewResourceClass(); + XRT_WINDOW = CreateNewResourceType(XineramaDeleteResource, + "XineramaWindow"); + if (XRT_WINDOW) + XRT_WINDOW |= XRC_DRAWABLE; + XRT_PIXMAP = CreateNewResourceType(XineramaDeleteResource, + "XineramaPixmap"); + if (XRT_PIXMAP) + XRT_PIXMAP |= XRC_DRAWABLE; + XRT_GC = CreateNewResourceType(XineramaDeleteResource, + "XineramaGC"); + XRT_COLORMAP = CreateNewResourceType(XineramaDeleteResource, + "XineramaColormap"); + + if (XRT_WINDOW && XRT_PIXMAP && XRT_GC && XRT_COLORMAP) { + panoramiXGeneration = serverGeneration; + success = TRUE; + } + SetResourceTypeErrorValue(XRT_WINDOW, BadWindow); + SetResourceTypeErrorValue(XRT_PIXMAP, BadPixmap); + SetResourceTypeErrorValue(XRT_GC, BadGC); + SetResourceTypeErrorValue(XRT_COLORMAP, BadColor); + } + + if (!success) { + noPanoramiXExtension = TRUE; + ErrorF(PANORAMIX_PROTOCOL_NAME " extension failed to initialize\n"); + return; + } + + XineramaInitData(pScreen); + + /* + * Put our processes into the ProcVector + */ + + for (i = 256; i--; ) + SavedProcVector[i] = ProcVector[i]; + + ProcVector[X_CreateWindow] = PanoramiXCreateWindow; + ProcVector[X_ChangeWindowAttributes] = PanoramiXChangeWindowAttributes; + ProcVector[X_DestroyWindow] = PanoramiXDestroyWindow; + ProcVector[X_DestroySubwindows] = PanoramiXDestroySubwindows; + ProcVector[X_ChangeSaveSet] = PanoramiXChangeSaveSet; + ProcVector[X_ReparentWindow] = PanoramiXReparentWindow; + ProcVector[X_MapWindow] = PanoramiXMapWindow; + ProcVector[X_MapSubwindows] = PanoramiXMapSubwindows; + ProcVector[X_UnmapWindow] = PanoramiXUnmapWindow; + ProcVector[X_UnmapSubwindows] = PanoramiXUnmapSubwindows; + ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow; + ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow; + ProcVector[X_GetGeometry] = PanoramiXGetGeometry; + ProcVector[X_TranslateCoords] = PanoramiXTranslateCoords; + ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap; + ProcVector[X_FreePixmap] = PanoramiXFreePixmap; + ProcVector[X_CreateGC] = PanoramiXCreateGC; + ProcVector[X_ChangeGC] = PanoramiXChangeGC; + ProcVector[X_CopyGC] = PanoramiXCopyGC; + ProcVector[X_SetDashes] = PanoramiXSetDashes; + ProcVector[X_SetClipRectangles] = PanoramiXSetClipRectangles; + ProcVector[X_FreeGC] = PanoramiXFreeGC; + ProcVector[X_ClearArea] = PanoramiXClearToBackground; + ProcVector[X_CopyArea] = PanoramiXCopyArea; + ProcVector[X_CopyPlane] = PanoramiXCopyPlane; + ProcVector[X_PolyPoint] = PanoramiXPolyPoint; + ProcVector[X_PolyLine] = PanoramiXPolyLine; + ProcVector[X_PolySegment] = PanoramiXPolySegment; + ProcVector[X_PolyRectangle] = PanoramiXPolyRectangle; + ProcVector[X_PolyArc] = PanoramiXPolyArc; + ProcVector[X_FillPoly] = PanoramiXFillPoly; + ProcVector[X_PolyFillRectangle] = PanoramiXPolyFillRectangle; + ProcVector[X_PolyFillArc] = PanoramiXPolyFillArc; + ProcVector[X_PutImage] = PanoramiXPutImage; + ProcVector[X_GetImage] = PanoramiXGetImage; + ProcVector[X_PolyText8] = PanoramiXPolyText8; + ProcVector[X_PolyText16] = PanoramiXPolyText16; + ProcVector[X_ImageText8] = PanoramiXImageText8; + ProcVector[X_ImageText16] = PanoramiXImageText16; + ProcVector[X_CreateColormap] = PanoramiXCreateColormap; + ProcVector[X_FreeColormap] = PanoramiXFreeColormap; + ProcVector[X_CopyColormapAndFree] = PanoramiXCopyColormapAndFree; + ProcVector[X_InstallColormap] = PanoramiXInstallColormap; + ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap; + ProcVector[X_AllocColor] = PanoramiXAllocColor; + ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor; + ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells; + ProcVector[X_AllocColorPlanes] = PanoramiXAllocColorPlanes; + ProcVector[X_FreeColors] = PanoramiXFreeColors; + ProcVector[X_StoreColors] = PanoramiXStoreColors; + ProcVector[X_StoreNamedColor] = PanoramiXStoreNamedColor; + + PanoramiXRenderInit (); +#ifdef XFIXES + PanoramiXFixesInit (); +#endif +#ifdef COMPOSITE + PanoramiXCompositeInit (); +#endif + +} + +extern Bool CreateConnectionBlock(void); + +Bool PanoramiXCreateConnectionBlock(void) +{ + int i, j, length; + Bool disableBackingStore = FALSE; + int old_width, old_height; + float width_mult, height_mult; + xWindowRoot *root; + xVisualType *visual; + xDepth *depth; + VisualPtr pVisual; + ScreenPtr pScreen; + + /* + * Do normal CreateConnectionBlock but faking it for only one screen + */ + + if(!PanoramiXNumDepths) { + ErrorF("Xinerama error: No common visuals\n"); + return FALSE; + } + + for(i = 1; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) { + ErrorF("Xinerama error: Root window depths differ\n"); + return FALSE; + } + if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport) + disableBackingStore = TRUE; + } + + if (disableBackingStore) { + for (i = 0; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + pScreen->backingStoreSupport = NotUseful; + } + } + + i = screenInfo.numScreens; + screenInfo.numScreens = 1; + if (!CreateConnectionBlock()) { + screenInfo.numScreens = i; + return FALSE; + } + + screenInfo.numScreens = i; + + root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart); + length = connBlockScreenStart + sizeof(xWindowRoot); + + /* overwrite the connection block */ + root->nDepths = PanoramiXNumDepths; + + for (i = 0; i < PanoramiXNumDepths; i++) { + depth = (xDepth *) (ConnectionInfo + length); + depth->depth = PanoramiXDepths[i].depth; + depth->nVisuals = PanoramiXDepths[i].numVids; + length += sizeof(xDepth); + visual = (xVisualType *)(ConnectionInfo + length); + + for (j = 0; j < depth->nVisuals; j++, visual++) { + visual->visualID = PanoramiXDepths[i].vids[j]; + + for (pVisual = PanoramiXVisuals; + pVisual->vid != visual->visualID; + pVisual++) + ; + + visual->class = pVisual->class; + visual->bitsPerRGB = pVisual->bitsPerRGBValue; + visual->colormapEntries = pVisual->ColormapEntries; + visual->redMask = pVisual->redMask; + visual->greenMask = pVisual->greenMask; + visual->blueMask = pVisual->blueMask; + } + + length += (depth->nVisuals * sizeof(xVisualType)); + } + + connSetupPrefix.length = bytes_to_int32(length); + + for (i = 0; i < PanoramiXNumDepths; i++) + free(PanoramiXDepths[i].vids); + free(PanoramiXDepths); + PanoramiXDepths = NULL; + + /* + * OK, change some dimensions so it looks as if it were one big screen + */ + + old_width = root->pixWidth; + old_height = root->pixHeight; + + root->pixWidth = PanoramiXPixWidth; + root->pixHeight = PanoramiXPixHeight; + width_mult = (1.0 * root->pixWidth) / old_width; + height_mult = (1.0 * root->pixHeight) / old_height; + root->mmWidth *= width_mult; + root->mmHeight *= height_mult; + + while(ConnectionCallbackList) { + pointer tmp; + + tmp = (pointer)ConnectionCallbackList; + (*ConnectionCallbackList->func)(); + ConnectionCallbackList = ConnectionCallbackList->next; + free(tmp); + } + + return TRUE; +} + +/* + * This isn't just memcmp(), bitsPerRGBValue is skipped. markv made that + * change way back before xf86 4.0, but the comment for _why_ is a bit + * opaque, so I'm not going to question it for now. + * + * This is probably better done as a screen hook so DBE/EVI/GLX can add + * their own tests, and adding privates to VisualRec so they don't have to + * do their own back-mapping. + */ +static Bool +VisualsEqual(VisualPtr a, ScreenPtr pScreenB, VisualPtr b) +{ + return ((a->class == b->class) && + (a->ColormapEntries == b->ColormapEntries) && + (a->nplanes == b->nplanes) && + (a->redMask == b->redMask) && + (a->greenMask == b->greenMask) && + (a->blueMask == b->blueMask) && + (a->offsetRed == b->offsetRed) && + (a->offsetGreen == b->offsetGreen) && + (a->offsetBlue == b->offsetBlue)); +} + +static void +PanoramiXMaybeAddDepth(DepthPtr pDepth) +{ + ScreenPtr pScreen; + int j, k; + Bool found = FALSE; + + for (j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + for (k = 0; k < pScreen->numDepths; k++) { + if (pScreen->allowedDepths[k].depth == pDepth->depth) { + found = TRUE; + break; + } + } + } + + if (!found) + return; + + j = PanoramiXNumDepths; + PanoramiXNumDepths++; + PanoramiXDepths = realloc(PanoramiXDepths, + PanoramiXNumDepths * sizeof(DepthRec)); + PanoramiXDepths[j].depth = pDepth->depth; + PanoramiXDepths[j].numVids = 0; + /* XXX suboptimal, should grow these dynamically */ + if(pDepth->numVids) + PanoramiXDepths[j].vids = malloc(sizeof(VisualID) * pDepth->numVids); + else + PanoramiXDepths[j].vids = NULL; +} + +static void +PanoramiXMaybeAddVisual(VisualPtr pVisual) +{ + ScreenPtr pScreen; + int j, k; + Bool found = FALSE; + + for (j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + found = FALSE; + + for (k = 0; k < pScreen->numVisuals; k++) { + VisualPtr candidate = &pScreen->visuals[k]; + + if ((*XineramaVisualsEqualPtr)(pVisual, pScreen, candidate) +#ifdef GLXPROXY + && glxMatchVisual(screenInfo.screens[0], pVisual, pScreen) +#endif + ) { + found = TRUE; + break; + } + } + + if (!found) + return; + } + + /* found a matching visual on all screens, add it to the subset list */ + j = PanoramiXNumVisuals; + PanoramiXNumVisuals++; + PanoramiXVisuals = realloc(PanoramiXVisuals, + PanoramiXNumVisuals * sizeof(VisualRec)); + + memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec)); + + for (k = 0; k < PanoramiXNumDepths; k++) { + if (PanoramiXDepths[k].depth == pVisual->nplanes) { + PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; + PanoramiXDepths[k].numVids++; + break; + } + } +} + +extern void +PanoramiXConsolidate(void) +{ + int i; + PanoramiXRes *root, *defmap, *saver; + ScreenPtr pScreen = screenInfo.screens[0]; + DepthPtr pDepth = pScreen->allowedDepths; + VisualPtr pVisual = pScreen->visuals; + + PanoramiXNumDepths = 0; + PanoramiXNumVisuals = 0; + + for (i = 0; i < pScreen->numDepths; i++) + PanoramiXMaybeAddDepth(pDepth++); + + for (i = 0; i < pScreen->numVisuals; i++) + PanoramiXMaybeAddVisual(pVisual++); + + root = malloc(sizeof(PanoramiXRes)); + root->type = XRT_WINDOW; + defmap = malloc(sizeof(PanoramiXRes)); + defmap->type = XRT_COLORMAP; + saver = malloc(sizeof(PanoramiXRes)); + saver->type = XRT_WINDOW; + + for (i = 0; i < PanoramiXNumScreens; i++) { + ScreenPtr pScreen = screenInfo.screens[i]; + root->info[i].id = pScreen->root->drawable.id; + root->u.win.class = InputOutput; + root->u.win.root = TRUE; + saver->info[i].id = pScreen->screensaver.wid; + saver->u.win.class = InputOutput; + saver->u.win.root = TRUE; + defmap->info[i].id = pScreen->defColormap; + } + + AddResource(root->info[0].id, XRT_WINDOW, root); + AddResource(saver->info[0].id, XRT_WINDOW, saver); + AddResource(defmap->info[0].id, XRT_COLORMAP, defmap); +} + +VisualID +PanoramiXTranslateVisualID(int screen, VisualID orig) +{ + ScreenPtr pOtherScreen = screenInfo.screens[screen]; + VisualPtr pVisual = NULL; + int i; + + for (i = 0; i < PanoramiXNumVisuals; i++) { + if (orig == PanoramiXVisuals[i].vid) { + pVisual = &PanoramiXVisuals[i]; + break; + } + } + + if (!pVisual) + return 0; + + /* if screen is 0, orig is already the correct visual ID */ + if (screen == 0) + return orig; + + /* found the original, now translate it relative to the backend screen */ + for (i = 0; i < pOtherScreen->numVisuals; i++) { + VisualPtr pOtherVisual = &pOtherScreen->visuals[i]; + + if ((*XineramaVisualsEqualPtr)(pVisual, pOtherScreen, pOtherVisual)) + return pOtherVisual->vid; + } + + return 0; +} + + +/* + * PanoramiXResetProc() + * Exit, deallocating as needed. + */ + +static void PanoramiXResetProc(ExtensionEntry* extEntry) +{ + int i; + + PanoramiXRenderReset (); +#ifdef XFIXES + PanoramiXFixesReset (); +#endif + screenInfo.numScreens = PanoramiXNumScreens; + for (i = 256; i--; ) + ProcVector[i] = SavedProcVector[i]; +} + + +int +ProcPanoramiXQueryVersion (ClientPtr client) +{ + /* REQUEST(xPanoramiXQueryVersionReq); */ + xPanoramiXQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION; + rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), (char *)&rep); + return Success; +} + +int +ProcPanoramiXGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !noPanoramiXExtension; + rep.window = stuff->window; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.window, n); + } + WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep); + return Success; + +} + +int +ProcPanoramiXGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = PanoramiXNumScreens; + rep.window = stuff->window; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.window, n); + } + WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep); + return Success; +} + +int +ProcPanoramiXGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + int n, rc; + + if (stuff->screen >= PanoramiXNumScreens) + return BadMatch; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + /* screen dimensions */ + rep.width = screenInfo.screens[stuff->screen]->width; + rep.height = screenInfo.screens[stuff->screen]->height; + rep.window = stuff->window; + rep.screen = stuff->screen; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.width, n); + swapl (&rep.height, n); + swapl (&rep.window, n); + swapl (&rep.screen, n); + } + WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep); + return Success; +} + + +int +ProcXineramaIsActive(ClientPtr client) +{ + /* REQUEST(xXineramaIsActiveReq); */ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; +#if 1 + { + /* The following hack fools clients into thinking that Xinerama + * is disabled even though it is not. */ + rep.state = !noPanoramiXExtension && !PanoramiXExtensionDisabledHack; + } +#else + rep.state = !noPanoramiXExtension; +#endif + if (client->swapped) { + int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.state, n); + } + WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep); + return Success; +} + + +int +ProcXineramaQueryScreens(ClientPtr client) +{ + /* REQUEST(xXineramaQueryScreensReq); */ + xXineramaQueryScreensReply rep; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens; + rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo); + if (client->swapped) { + int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.number, n); + } + WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep); + + if(!noPanoramiXExtension) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < PanoramiXNumScreens; i++) { + scratch.x_org = screenInfo.screens[i]->x; + scratch.y_org = screenInfo.screens[i]->y; + scratch.width = screenInfo.screens[i]->width; + scratch.height = screenInfo.screens[i]->height; + + if(client->swapped) { + int n; + swaps (&scratch.x_org, n); + swaps (&scratch.y_org, n); + swaps (&scratch.width, n); + swaps (&scratch.height, n); + } + WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch); + } + } + + return Success; +} + + +static int +ProcPanoramiXDispatch (ClientPtr client) +{ REQUEST(xReq); + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return ProcPanoramiXQueryVersion(client); + case X_PanoramiXGetState: + return ProcPanoramiXGetState(client); + case X_PanoramiXGetScreenCount: + return ProcPanoramiXGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcPanoramiXGetScreenSize(client); + case X_XineramaIsActive: + return ProcXineramaIsActive(client); + case X_XineramaQueryScreens: + return ProcXineramaQueryScreens(client); + } + return BadRequest; +} + + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN +#define SHIFT_L(v,s) (v) << (s) +#define SHIFT_R(v,s) (v) >> (s) +#else +#define SHIFT_L(v,s) (v) >> (s) +#define SHIFT_R(v,s) (v) << (s) +#endif + +static void +CopyBits(char *dst, int shiftL, char *src, int bytes) +{ + /* Just get it to work. Worry about speed later */ + int shiftR = 8 - shiftL; + + while(bytes--) { + *dst |= SHIFT_L(*src, shiftL); + *(dst + 1) |= SHIFT_R(*src, shiftR); + dst++; src++; + } +} + + +/* Caution. This doesn't support 2 and 4 bpp formats. We expect + 1 bpp and planar data to be already cleared when presented + to this function */ + +void +XineramaGetImageData( + DrawablePtr *pDrawables, + int left, + int top, + int width, + int height, + unsigned int format, + unsigned long planemask, + char *data, + int pitch, + Bool isRoot +){ + RegionRec SrcRegion, ScreenRegion, GrabRegion; + BoxRec SrcBox, *pbox; + int x, y, w, h, i, j, nbox, size, sizeNeeded, ScratchPitch, inOut, depth; + DrawablePtr pDraw = pDrawables[0]; + char *ScratchMem = NULL; + + size = 0; + + /* find box in logical screen space */ + SrcBox.x1 = left; + SrcBox.y1 = top; + if(!isRoot) { + SrcBox.x1 += pDraw->x + screenInfo.screens[0]->x; + SrcBox.y1 += pDraw->y + screenInfo.screens[0]->y; + } + SrcBox.x2 = SrcBox.x1 + width; + SrcBox.y2 = SrcBox.y1 + height; + + RegionInit(&SrcRegion, &SrcBox, 1); + RegionNull(&GrabRegion); + + depth = (format == XYPixmap) ? 1 : pDraw->depth; + + for(i = 0; i < PanoramiXNumScreens; i++) { + BoxRec TheBox; + ScreenPtr pScreen; + pDraw = pDrawables[i]; + pScreen = pDraw->pScreen; + + TheBox.x1 = pScreen->x; + TheBox.x2 = TheBox.x1 + pScreen->width; + TheBox.y1 = pScreen->y; + TheBox.y2 = TheBox.y1 + pScreen->height; + + RegionInit(&ScreenRegion, &TheBox, 1); + inOut = RegionContainsRect(&ScreenRegion, &SrcBox); + if(inOut == rgnPART) + RegionIntersect(&GrabRegion, &SrcRegion, &ScreenRegion); + RegionUninit(&ScreenRegion); + + if(inOut == rgnIN) { + (*pScreen->GetImage)(pDraw, + SrcBox.x1 - pDraw->x - screenInfo.screens[i]->x, + SrcBox.y1 - pDraw->y - screenInfo.screens[i]->y, + width, height, format, planemask, data); + break; + } else if (inOut == rgnOUT) + continue; + + nbox = RegionNumRects(&GrabRegion); + + if(nbox) { + pbox = RegionRects(&GrabRegion); + + while(nbox--) { + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + ScratchPitch = PixmapBytePad(w, depth); + sizeNeeded = ScratchPitch * h; + + if(sizeNeeded > size) { + char *tmpdata = ScratchMem; + ScratchMem = realloc(ScratchMem, sizeNeeded); + if(ScratchMem) + size = sizeNeeded; + else { + ScratchMem = tmpdata; + break; + } + } + + x = pbox->x1 - pDraw->x - screenInfo.screens[i]->x; + y = pbox->y1 - pDraw->y - screenInfo.screens[i]->y; + + (*pScreen->GetImage)(pDraw, x, y, w, h, + format, planemask, ScratchMem); + + /* copy the memory over */ + + if(depth == 1) { + int k, shift, leftover, index, index2; + + x = pbox->x1 - SrcBox.x1; + y = pbox->y1 - SrcBox.y1; + shift = x & 7; + x >>= 3; + leftover = w & 7; + w >>= 3; + + /* clean up the edge */ + if(leftover) { + int mask = (1 << leftover) - 1; + for(j = h, k = w; j--; k += ScratchPitch) + ScratchMem[k] &= mask; + } + + for(j = 0, index = (pitch * y) + x, index2 = 0; j < h; + j++, index += pitch, index2 += ScratchPitch) + { + if(w) { + if(!shift) + memcpy(data + index, ScratchMem + index2, w); + else + CopyBits(data + index, shift, + ScratchMem + index2, w); + } + + if(leftover) { + data[index + w] |= + SHIFT_L(ScratchMem[index2 + w], shift); + if((shift + leftover) > 8) + data[index + w + 1] |= + SHIFT_R(ScratchMem[index2 + w],(8 - shift)); + } + } + } else { + j = BitsPerPixel(depth) >> 3; + x = (pbox->x1 - SrcBox.x1) * j; + y = pbox->y1 - SrcBox.y1; + w *= j; + + for(j = 0; j < h; j++) { + memcpy(data + (pitch * (y + j)) + x, + ScratchMem + (ScratchPitch * j), w); + } + } + pbox++; + } + + RegionSubtract(&SrcRegion, &SrcRegion, &GrabRegion); + if(!RegionNotEmpty(&SrcRegion)) + break; + } + + } + + free(ScratchMem); + + RegionUninit(&SrcRegion); + RegionUninit(&GrabRegion); +} diff --git a/xorg-server/Xext/panoramiXsrv.h b/xorg-server/Xext/panoramiXsrv.h index d177df28d..9751feb54 100644 --- a/xorg-server/Xext/panoramiXsrv.h +++ b/xorg-server/Xext/panoramiXsrv.h @@ -1,54 +1,54 @@ -
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _PANORAMIXSRV_H_
-#define _PANORAMIXSRV_H_
-
-#include "panoramiX.h"
-
-extern _X_EXPORT int PanoramiXNumScreens;
-extern _X_EXPORT int PanoramiXPixWidth;
-extern _X_EXPORT int PanoramiXPixHeight;
-
-extern _X_EXPORT VisualID PanoramiXTranslateVisualID(int screen, VisualID orig);
-extern _X_EXPORT void PanoramiXConsolidate(void);
-extern _X_EXPORT Bool PanoramiXCreateConnectionBlock(void);
-extern _X_EXPORT PanoramiXRes * PanoramiXFindIDByScrnum(RESTYPE, XID, int);
-extern _X_EXPORT Bool XineramaRegisterConnectionBlockCallback(void (*func)(void));
-extern _X_EXPORT int XineramaDeleteResource(pointer, XID);
-
-extern _X_EXPORT void XineramaReinitData(ScreenPtr);
-
-extern _X_EXPORT unsigned long XRC_DRAWABLE;
-extern _X_EXPORT unsigned long XRT_WINDOW;
-extern _X_EXPORT unsigned long XRT_PIXMAP;
-extern _X_EXPORT unsigned long XRT_GC;
-extern _X_EXPORT unsigned long XRT_COLORMAP;
-extern _X_EXPORT unsigned long XRT_PICTURE;
-
-/*
- * Drivers are allowed to wrap this function. Each wrapper can decide that the
- * two visuals are unequal, but if they are deemed equal, the wrapper must call
- * down and return FALSE if the wrapped function does. This ensures that all
- * layers agree that the visuals are equal. The first visual is always from
- * screen 0.
- */
-typedef Bool (*XineramaVisualsEqualProcPtr)(VisualPtr, ScreenPtr, VisualPtr);
-extern _X_EXPORT XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr;
-
-extern _X_EXPORT void XineramaGetImageData(
- DrawablePtr *pDrawables,
- int left,
- int top,
- int width,
- int height,
- unsigned int format,
- unsigned long planemask,
- char *data,
- int pitch,
- Bool isRoot
-);
-
-#endif /* _PANORAMIXSRV_H_ */
+ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _PANORAMIXSRV_H_ +#define _PANORAMIXSRV_H_ + +#include "panoramiX.h" + +extern _X_EXPORT int PanoramiXNumScreens; +extern _X_EXPORT int PanoramiXPixWidth; +extern _X_EXPORT int PanoramiXPixHeight; + +extern _X_EXPORT VisualID PanoramiXTranslateVisualID(int screen, VisualID orig); +extern _X_EXPORT void PanoramiXConsolidate(void); +extern _X_EXPORT Bool PanoramiXCreateConnectionBlock(void); +extern _X_EXPORT PanoramiXRes * PanoramiXFindIDByScrnum(RESTYPE, XID, int); +extern _X_EXPORT Bool XineramaRegisterConnectionBlockCallback(void (*func)(void)); +extern _X_EXPORT int XineramaDeleteResource(pointer, XID); + +extern _X_EXPORT void XineramaReinitData(ScreenPtr); + +extern _X_EXPORT RESTYPE XRC_DRAWABLE; +extern _X_EXPORT RESTYPE XRT_WINDOW; +extern _X_EXPORT RESTYPE XRT_PIXMAP; +extern _X_EXPORT RESTYPE XRT_GC; +extern _X_EXPORT RESTYPE XRT_COLORMAP; +extern _X_EXPORT RESTYPE XRT_PICTURE; + +/* + * Drivers are allowed to wrap this function. Each wrapper can decide that the + * two visuals are unequal, but if they are deemed equal, the wrapper must call + * down and return FALSE if the wrapped function does. This ensures that all + * layers agree that the visuals are equal. The first visual is always from + * screen 0. + */ +typedef Bool (*XineramaVisualsEqualProcPtr)(VisualPtr, ScreenPtr, VisualPtr); +extern _X_EXPORT XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr; + +extern _X_EXPORT void XineramaGetImageData( + DrawablePtr *pDrawables, + int left, + int top, + int width, + int height, + unsigned int format, + unsigned long planemask, + char *data, + int pitch, + Bool isRoot +); + +#endif /* _PANORAMIXSRV_H_ */ diff --git a/xorg-server/Xext/xvdix.h b/xorg-server/Xext/xvdix.h index 5104a4def..e9c22bf65 100644 --- a/xorg-server/Xext/xvdix.h +++ b/xorg-server/Xext/xvdix.h @@ -1,275 +1,275 @@ -/***********************************************************
-Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
-and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-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 names of Digital or MIT not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL 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.
-
-******************************************************************/
-
-#ifndef XVDIX_H
-#define XVDIX_H
-/*
-** File:
-**
-** xvdix.h --- Xv device independent header file
-**
-** Author:
-**
-** David Carver (Digital Workstation Engineering/Project Athena)
-**
-** Revisions:
-**
-** 29.08.91 Carver
-** - removed UnrealizeWindow wrapper unrealizing windows no longer
-** preempts video
-**
-** 11.06.91 Carver
-** - changed SetPortControl to SetPortAttribute
-** - changed GetPortControl to GetPortAttribute
-** - changed QueryBestSize
-**
-** 15.05.91 Carver
-** - version 2.0 upgrade
-**
-** 24.01.91 Carver
-** - version 1.4 upgrade
-**
-*/
-
-#include "scrnintstr.h"
-#include <X11/extensions/Xvproto.h>
-
-#ifndef XorgLoader
-extern _X_EXPORT unsigned long XvExtensionGeneration;
-extern _X_EXPORT unsigned long XvScreenGeneration;
-extern _X_EXPORT unsigned long XvResourceGeneration;
-
-extern _X_EXPORT int XvReqCode;
-extern _X_EXPORT int XvEventBase;
-extern _X_EXPORT int XvErrorBase;
-
-extern _X_EXPORT unsigned long XvRTPort;
-extern _X_EXPORT unsigned long XvRTEncoding;
-extern _X_EXPORT unsigned long XvRTGrab;
-extern _X_EXPORT unsigned long XvRTVideoNotify;
-extern _X_EXPORT unsigned long XvRTVideoNotifyList;
-extern _X_EXPORT unsigned long XvRTPortNotify;
-#endif
-
-typedef struct {
- int numerator;
- int denominator;
-} XvRationalRec, *XvRationalPtr;
-
-typedef struct {
- char depth;
- unsigned long visual;
-} XvFormatRec, *XvFormatPtr;
-
-typedef struct {
- unsigned long id;
- ClientPtr client;
-} XvGrabRec, *XvGrabPtr;
-
-typedef struct _XvVideoNotifyRec {
- struct _XvVideoNotifyRec *next;
- ClientPtr client;
- unsigned long id;
- unsigned long mask;
-} XvVideoNotifyRec, *XvVideoNotifyPtr;
-
-typedef struct _XvPortNotifyRec {
- struct _XvPortNotifyRec *next;
- ClientPtr client;
- unsigned long id;
-} XvPortNotifyRec, *XvPortNotifyPtr;
-
-typedef struct {
- int id;
- ScreenPtr pScreen;
- char *name;
- unsigned short width, height;
- XvRationalRec rate;
-} XvEncodingRec, *XvEncodingPtr;
-
-typedef struct _XvAttributeRec {
- int flags;
- int min_value;
- int max_value;
- char *name;
-} XvAttributeRec, *XvAttributePtr;
-
-typedef struct {
- int id;
- int type;
- int byte_order;
- char guid[16];
- int bits_per_pixel;
- int format;
- int num_planes;
-
- /* for RGB formats only */
- int depth;
- unsigned int red_mask;
- unsigned int green_mask;
- unsigned int blue_mask;
-
- /* for YUV formats only */
- unsigned int y_sample_bits;
- unsigned int u_sample_bits;
- unsigned int v_sample_bits;
- unsigned int horz_y_period;
- unsigned int horz_u_period;
- unsigned int horz_v_period;
- unsigned int vert_y_period;
- unsigned int vert_u_period;
- unsigned int vert_v_period;
- char component_order[32];
- int scanline_order;
-} XvImageRec, *XvImagePtr;
-
-typedef struct {
- unsigned long base_id;
- unsigned char type;
- char *name;
- int nEncodings;
- XvEncodingPtr pEncodings;
- int nFormats;
- XvFormatPtr pFormats;
- int nAttributes;
- XvAttributePtr pAttributes;
- int nImages;
- XvImagePtr pImages;
- int nPorts;
- struct _XvPortRec *pPorts;
- ScreenPtr pScreen;
- int (* ddAllocatePort)(unsigned long, struct _XvPortRec*,
- struct _XvPortRec**);
- int (* ddFreePort)(struct _XvPortRec*);
- int (* ddPutVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
- int (* ddPutStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
- int (* ddGetVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
- int (* ddGetStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
- int (* ddStopVideo)(ClientPtr, struct _XvPortRec*, DrawablePtr);
- int (* ddSetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32);
- int (* ddGetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32*);
- int (* ddQueryBestSize)(ClientPtr, struct _XvPortRec*, CARD8,
- CARD16, CARD16,CARD16, CARD16,
- unsigned int*, unsigned int*);
- int (* ddPutImage)(ClientPtr, DrawablePtr, struct _XvPortRec*, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16,
- XvImagePtr, unsigned char*, Bool,
- CARD16, CARD16);
- int (* ddQueryImageAttributes)(ClientPtr, struct _XvPortRec*, XvImagePtr,
- CARD16*, CARD16*, int*, int*);
- DevUnion devPriv;
-} XvAdaptorRec, *XvAdaptorPtr;
-
-typedef struct _XvPortRec {
- unsigned long id;
- XvAdaptorPtr pAdaptor;
- XvPortNotifyPtr pNotify;
- DrawablePtr pDraw;
- ClientPtr client;
- XvGrabRec grab;
- TimeStamp time;
- DevUnion devPriv;
-} XvPortRec, *XvPortPtr;
-
-#define VALIDATE_XV_PORT(portID, pPort, mode)\
- {\
- int rc = dixLookupResourceByType((pointer *)&(pPort), portID,\
- XvRTPort, client, mode);\
- if (rc != Success)\
- return rc;\
- }
-
-typedef struct {
- int version, revision;
- int nAdaptors;
- XvAdaptorPtr pAdaptors;
- DestroyWindowProcPtr DestroyWindow;
- DestroyPixmapProcPtr DestroyPixmap;
- CloseScreenProcPtr CloseScreen;
- Bool (* ddCloseScreen)(int, ScreenPtr);
- int (* ddQueryAdaptors)(ScreenPtr, XvAdaptorPtr*, int*);
- DevUnion devPriv;
-} XvScreenRec, *XvScreenPtr;
-
-#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = ((XvScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey))->field)
-
-#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
- ((pScreen)->field = wrapper)
-
-/* Errors */
-
-#define _XvBadPort (XvBadPort+XvErrorBase)
-#define _XvBadEncoding (XvBadEncoding+XvErrorBase)
-
-#ifndef XorgLoader
-extern _X_EXPORT int ProcXvDispatch(ClientPtr);
-extern _X_EXPORT int SProcXvDispatch(ClientPtr);
-
-extern _X_EXPORT void XvExtensionInit(void);
-extern _X_EXPORT int XvScreenInit(ScreenPtr);
-extern _X_EXPORT DevPrivateKey XvGetScreenKey(void);
-extern _X_EXPORT unsigned long XvGetRTPort(void);
-extern _X_EXPORT int XvdiSendPortNotify(XvPortPtr, Atom, INT32);
-extern _X_EXPORT int XvdiVideoStopped(XvPortPtr, int);
-
-extern _X_EXPORT int XvdiPutVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-extern _X_EXPORT int XvdiPutStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-extern _X_EXPORT int XvdiGetVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-extern _X_EXPORT int XvdiGetStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-extern _X_EXPORT int XvdiPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16,
- XvImagePtr, unsigned char*, Bool,
- CARD16, CARD16);
-extern _X_EXPORT int XvdiSelectVideoNotify(ClientPtr, DrawablePtr, BOOL);
-extern _X_EXPORT int XvdiSelectPortNotify(ClientPtr, XvPortPtr, BOOL);
-extern _X_EXPORT int XvdiSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
-extern _X_EXPORT int XvdiGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
-extern _X_EXPORT int XvdiStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
-extern _X_EXPORT int XvdiPreemptVideo(ClientPtr, XvPortPtr, DrawablePtr);
-extern _X_EXPORT int XvdiMatchPort(XvPortPtr, DrawablePtr);
-extern _X_EXPORT int XvdiGrabPort(ClientPtr, XvPortPtr, Time, int *);
-extern _X_EXPORT int XvdiUngrabPort( ClientPtr, XvPortPtr, Time);
-#endif /* XorgLoader */
-
-#endif /* XVDIX_H */
-
+/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +******************************************************************/ + +#ifndef XVDIX_H +#define XVDIX_H +/* +** File: +** +** xvdix.h --- Xv device independent header file +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 29.08.91 Carver +** - removed UnrealizeWindow wrapper unrealizing windows no longer +** preempts video +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 24.01.91 Carver +** - version 1.4 upgrade +** +*/ + +#include "scrnintstr.h" +#include <X11/extensions/Xvproto.h> + +#ifndef XorgLoader +extern _X_EXPORT unsigned long XvExtensionGeneration; +extern _X_EXPORT unsigned long XvScreenGeneration; +extern _X_EXPORT unsigned long XvResourceGeneration; + +extern _X_EXPORT int XvReqCode; +extern _X_EXPORT int XvEventBase; +extern _X_EXPORT int XvErrorBase; + +extern _X_EXPORT RESTYPE XvRTPort; +extern _X_EXPORT RESTYPE XvRTEncoding; +extern _X_EXPORT RESTYPE XvRTGrab; +extern _X_EXPORT RESTYPE XvRTVideoNotify; +extern _X_EXPORT RESTYPE XvRTVideoNotifyList; +extern _X_EXPORT RESTYPE XvRTPortNotify; +#endif + +typedef struct { + int numerator; + int denominator; +} XvRationalRec, *XvRationalPtr; + +typedef struct { + char depth; + unsigned long visual; +} XvFormatRec, *XvFormatPtr; + +typedef struct { + unsigned long id; + ClientPtr client; +} XvGrabRec, *XvGrabPtr; + +typedef struct _XvVideoNotifyRec { + struct _XvVideoNotifyRec *next; + ClientPtr client; + unsigned long id; + unsigned long mask; +} XvVideoNotifyRec, *XvVideoNotifyPtr; + +typedef struct _XvPortNotifyRec { + struct _XvPortNotifyRec *next; + ClientPtr client; + unsigned long id; +} XvPortNotifyRec, *XvPortNotifyPtr; + +typedef struct { + int id; + ScreenPtr pScreen; + char *name; + unsigned short width, height; + XvRationalRec rate; +} XvEncodingRec, *XvEncodingPtr; + +typedef struct _XvAttributeRec { + int flags; + int min_value; + int max_value; + char *name; +} XvAttributeRec, *XvAttributePtr; + +typedef struct { + int id; + int type; + int byte_order; + char guid[16]; + int bits_per_pixel; + int format; + int num_planes; + + /* for RGB formats only */ + int depth; + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + + /* for YUV formats only */ + unsigned int y_sample_bits; + unsigned int u_sample_bits; + unsigned int v_sample_bits; + unsigned int horz_y_period; + unsigned int horz_u_period; + unsigned int horz_v_period; + unsigned int vert_y_period; + unsigned int vert_u_period; + unsigned int vert_v_period; + char component_order[32]; + int scanline_order; +} XvImageRec, *XvImagePtr; + +typedef struct { + unsigned long base_id; + unsigned char type; + char *name; + int nEncodings; + XvEncodingPtr pEncodings; + int nFormats; + XvFormatPtr pFormats; + int nAttributes; + XvAttributePtr pAttributes; + int nImages; + XvImagePtr pImages; + int nPorts; + struct _XvPortRec *pPorts; + ScreenPtr pScreen; + int (* ddAllocatePort)(unsigned long, struct _XvPortRec*, + struct _XvPortRec**); + int (* ddFreePort)(struct _XvPortRec*); + int (* ddPutVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddPutStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddGetVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddGetStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddStopVideo)(ClientPtr, struct _XvPortRec*, DrawablePtr); + int (* ddSetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32); + int (* ddGetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32*); + int (* ddQueryBestSize)(ClientPtr, struct _XvPortRec*, CARD8, + CARD16, CARD16,CARD16, CARD16, + unsigned int*, unsigned int*); + int (* ddPutImage)(ClientPtr, DrawablePtr, struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16, + XvImagePtr, unsigned char*, Bool, + CARD16, CARD16); + int (* ddQueryImageAttributes)(ClientPtr, struct _XvPortRec*, XvImagePtr, + CARD16*, CARD16*, int*, int*); + DevUnion devPriv; +} XvAdaptorRec, *XvAdaptorPtr; + +typedef struct _XvPortRec { + unsigned long id; + XvAdaptorPtr pAdaptor; + XvPortNotifyPtr pNotify; + DrawablePtr pDraw; + ClientPtr client; + XvGrabRec grab; + TimeStamp time; + DevUnion devPriv; +} XvPortRec, *XvPortPtr; + +#define VALIDATE_XV_PORT(portID, pPort, mode)\ + {\ + int rc = dixLookupResourceByType((pointer *)&(pPort), portID,\ + XvRTPort, client, mode);\ + if (rc != Success)\ + return rc;\ + } + +typedef struct { + int version, revision; + int nAdaptors; + XvAdaptorPtr pAdaptors; + DestroyWindowProcPtr DestroyWindow; + DestroyPixmapProcPtr DestroyPixmap; + CloseScreenProcPtr CloseScreen; + Bool (* ddCloseScreen)(int, ScreenPtr); + int (* ddQueryAdaptors)(ScreenPtr, XvAdaptorPtr*, int*); + DevUnion devPriv; +} XvScreenRec, *XvScreenPtr; + +#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = ((XvScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey))->field) + +#define SCREEN_EPILOGUE(pScreen, field, wrapper)\ + ((pScreen)->field = wrapper) + +/* Errors */ + +#define _XvBadPort (XvBadPort+XvErrorBase) +#define _XvBadEncoding (XvBadEncoding+XvErrorBase) + +#ifndef XorgLoader +extern _X_EXPORT int ProcXvDispatch(ClientPtr); +extern _X_EXPORT int SProcXvDispatch(ClientPtr); + +extern _X_EXPORT void XvExtensionInit(void); +extern _X_EXPORT int XvScreenInit(ScreenPtr); +extern _X_EXPORT DevPrivateKey XvGetScreenKey(void); +extern _X_EXPORT unsigned long XvGetRTPort(void); +extern _X_EXPORT int XvdiSendPortNotify(XvPortPtr, Atom, INT32); +extern _X_EXPORT int XvdiVideoStopped(XvPortPtr, int); + +extern _X_EXPORT int XvdiPutVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiPutStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiGetVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiGetStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16, + XvImagePtr, unsigned char*, Bool, + CARD16, CARD16); +extern _X_EXPORT int XvdiSelectVideoNotify(ClientPtr, DrawablePtr, BOOL); +extern _X_EXPORT int XvdiSelectPortNotify(ClientPtr, XvPortPtr, BOOL); +extern _X_EXPORT int XvdiSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32); +extern _X_EXPORT int XvdiGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*); +extern _X_EXPORT int XvdiStopVideo(ClientPtr, XvPortPtr, DrawablePtr); +extern _X_EXPORT int XvdiPreemptVideo(ClientPtr, XvPortPtr, DrawablePtr); +extern _X_EXPORT int XvdiMatchPort(XvPortPtr, DrawablePtr); +extern _X_EXPORT int XvdiGrabPort(ClientPtr, XvPortPtr, Time, int *); +extern _X_EXPORT int XvdiUngrabPort( ClientPtr, XvPortPtr, Time); +#endif /* XorgLoader */ + +#endif /* XVDIX_H */ + diff --git a/xorg-server/Xext/xvmain.c b/xorg-server/Xext/xvmain.c index f3b6d84b9..cd6f0979c 100644 --- a/xorg-server/Xext/xvmain.c +++ b/xorg-server/Xext/xvmain.c @@ -1,1185 +1,1183 @@ -/***********************************************************
-Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
-and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-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 names of Digital or MIT not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL 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.
-
-******************************************************************/
-
-/*
-** File:
-**
-** xvmain.c --- Xv server extension main device independent module.
-**
-** Author:
-**
-** David Carver (Digital Workstation Engineering/Project Athena)
-**
-** Revisions:
-**
-** 04.09.91 Carver
-** - change: stop video always generates an event even when video
-** wasn't active
-**
-** 29.08.91 Carver
-** - change: unrealizing windows no longer preempts video
-**
-** 11.06.91 Carver
-** - changed SetPortControl to SetPortAttribute
-** - changed GetPortControl to GetPortAttribute
-** - changed QueryBestSize
-**
-** 28.05.91 Carver
-** - fixed Put and Get requests to not preempt operations to same drawable
-**
-** 15.05.91 Carver
-** - version 2.0 upgrade
-**
-** 19.03.91 Carver
-** - fixed Put and Get requests to honor grabbed ports.
-** - fixed Video requests to update di structure with new drawable, and
-** client after calling ddx.
-**
-** 24.01.91 Carver
-** - version 1.4 upgrade
-**
-** Notes:
-**
-** Port structures reference client structures in a two different
-** ways: when grabs, or video is active. Each reference is encoded
-** as fake client resources and thus when the client is goes away so
-** does the reference (it is zeroed). No other action is taken, so
-** video doesn't necessarily stop. It probably will as a result of
-** other resources going away, but if a client starts video using
-** none of its own resources, then the video will continue to play
-** after the client disappears.
-**
-**
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "gc.h"
-#include "extnsionst.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "opaque.h"
-#include "input.h"
-
-#define GLOBAL
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-#include "xvdix.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-#include "xvdisp.h"
-
-static DevPrivateKeyRec XvScreenKeyRec;
-#define XvScreenKey (&XvScreenKeyRec)
-unsigned long XvExtensionGeneration = 0;
-unsigned long XvScreenGeneration = 0;
-unsigned long XvResourceGeneration = 0;
-
-int XvReqCode;
-int XvEventBase;
-int XvErrorBase;
-
-unsigned long XvRTPort;
-unsigned long XvRTEncoding;
-unsigned long XvRTGrab;
-unsigned long XvRTVideoNotify;
-unsigned long XvRTVideoNotifyList;
-unsigned long XvRTPortNotify;
-
-
-
-/* EXTERNAL */
-
-static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *);
-static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *);
-static Bool CreateResourceTypes(void);
-
-static Bool XvCloseScreen(int, ScreenPtr);
-static Bool XvDestroyPixmap(PixmapPtr);
-static Bool XvDestroyWindow(WindowPtr);
-static void XvResetProc(ExtensionEntry*);
-static int XvdiDestroyGrab(pointer, XID);
-static int XvdiDestroyEncoding(pointer, XID);
-static int XvdiDestroyVideoNotify(pointer, XID);
-static int XvdiDestroyPortNotify(pointer, XID);
-static int XvdiDestroyVideoNotifyList(pointer, XID);
-static int XvdiDestroyPort(pointer, XID);
-static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int);
-
-
-
-
-/*
-** XvExtensionInit
-**
-**
-*/
-
-void
-XvExtensionInit(void)
-{
- ExtensionEntry *extEntry;
-
- if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0))
- return;
-
- /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN
- INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */
- if (XvScreenGeneration != serverGeneration)
- {
- if (!CreateResourceTypes())
- {
- ErrorF("XvExtensionInit: Unable to allocate resource types\n");
- return;
- }
-#ifdef PANORAMIX
- XineramaRegisterConnectionBlockCallback(XineramifyXv);
-#endif
- XvScreenGeneration = serverGeneration;
- }
-
- if (XvExtensionGeneration != serverGeneration)
- {
- XvExtensionGeneration = serverGeneration;
-
- extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors,
- ProcXvDispatch, SProcXvDispatch,
- XvResetProc, StandardMinorOpcode);
- if (!extEntry)
- {
- FatalError("XvExtensionInit: AddExtensions failed\n");
- }
-
- XvReqCode = extEntry->base;
- XvEventBase = extEntry->eventBase;
- XvErrorBase = extEntry->errorBase;
-
- EventSwapVector[XvEventBase+XvVideoNotify] =
- (EventSwapPtr)WriteSwappedVideoNotifyEvent;
- EventSwapVector[XvEventBase+XvPortNotify] =
- (EventSwapPtr)WriteSwappedPortNotifyEvent;
-
- SetResourceTypeErrorValue(XvRTPort, _XvBadPort);
- (void)MakeAtom(XvName, strlen(XvName), xTrue);
-
- }
-}
-
-static Bool
-CreateResourceTypes(void)
-
-{
-
- if (XvResourceGeneration == serverGeneration) return TRUE;
-
- XvResourceGeneration = serverGeneration;
-
- if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort, "XvRTPort")))
- {
- ErrorF("CreateResourceTypes: failed to allocate port resource.\n");
- return FALSE;
- }
-
- if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab, "XvRTGrab")))
- {
- ErrorF("CreateResourceTypes: failed to allocate grab resource.\n");
- return FALSE;
- }
-
- if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding,
- "XvRTEncoding")))
- {
- ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n");
- return FALSE;
- }
-
- if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify,
- "XvRTVideoNotify")))
- {
- ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n");
- return FALSE;
- }
-
- if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList,
- "XvRTVideoNotifyList")))
- {
- ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n");
- return FALSE;
- }
-
- if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify,
- "XvRTPortNotify")))
- {
- ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n");
- return FALSE;
- }
-
- return TRUE;
-
-}
-
-int
-XvScreenInit(ScreenPtr pScreen)
-{
- XvScreenPtr pxvs;
-
- if (XvScreenGeneration != serverGeneration)
- {
- if (!CreateResourceTypes())
- {
- ErrorF("XvScreenInit: Unable to allocate resource types\n");
- return BadAlloc;
- }
-#ifdef PANORAMIX
- XineramaRegisterConnectionBlockCallback(XineramifyXv);
-#endif
- XvScreenGeneration = serverGeneration;
- }
-
- if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0))
- return BadAlloc;
-
- if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey))
- {
- ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n");
- }
-
- /* ALLOCATE SCREEN PRIVATE RECORD */
-
- pxvs = malloc(sizeof (XvScreenRec));
- if (!pxvs)
- {
- ErrorF("XvScreenInit: Unable to allocate screen private structure\n");
- return BadAlloc;
- }
-
- dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs);
-
- pxvs->DestroyPixmap = pScreen->DestroyPixmap;
- pxvs->DestroyWindow = pScreen->DestroyWindow;
- pxvs->CloseScreen = pScreen->CloseScreen;
-
- pScreen->DestroyPixmap = XvDestroyPixmap;
- pScreen->DestroyWindow = XvDestroyWindow;
- pScreen->CloseScreen = XvCloseScreen;
-
- return Success;
-}
-
-static Bool
-XvCloseScreen(
- int ii,
- ScreenPtr pScreen
-){
-
- XvScreenPtr pxvs;
-
- pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey);
-
- pScreen->DestroyPixmap = pxvs->DestroyPixmap;
- pScreen->DestroyWindow = pxvs->DestroyWindow;
- pScreen->CloseScreen = pxvs->CloseScreen;
-
- (* pxvs->ddCloseScreen)(ii, pScreen);
-
- free(pxvs);
-
- dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL);
-
- return (*pScreen->CloseScreen)(ii, pScreen);
-}
-
-static void
-XvResetProc(ExtensionEntry* extEntry)
-{
- XvResetProcVector();
-}
-
-DevPrivateKey
-XvGetScreenKey(void)
-{
- return XvScreenKey;
-}
-
-unsigned long
-XvGetRTPort(void)
-{
- return XvRTPort;
-}
-
-static Bool
-XvDestroyPixmap(PixmapPtr pPix)
-{
- Bool status;
- ScreenPtr pScreen;
- XvScreenPtr pxvs;
- XvAdaptorPtr pa;
- int na;
- XvPortPtr pp;
- int np;
-
- pScreen = pPix->drawable.pScreen;
-
- SCREEN_PROLOGUE(pScreen, DestroyPixmap);
-
- pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey);
-
- /* CHECK TO SEE IF THIS PORT IS IN USE */
-
- pa = pxvs->pAdaptors;
- na = pxvs->nAdaptors;
- while (na--)
- {
- np = pa->nPorts;
- pp = pa->pPorts;
-
- while (np--)
- {
- if (pp->pDraw == (DrawablePtr)pPix)
- {
- XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
-
- (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw);
-
- pp->pDraw = NULL;
- pp->client = NULL;
- pp->time = currentTime;
- }
- pp++;
- }
- pa++;
- }
-
- status = (* pScreen->DestroyPixmap)(pPix);
-
- SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap);
-
- return status;
-
-}
-
-static Bool
-XvDestroyWindow(WindowPtr pWin)
-{
- Bool status;
- ScreenPtr pScreen;
- XvScreenPtr pxvs;
- XvAdaptorPtr pa;
- int na;
- XvPortPtr pp;
- int np;
-
- pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOGUE(pScreen, DestroyWindow);
-
- pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey);
-
- /* CHECK TO SEE IF THIS PORT IS IN USE */
-
- pa = pxvs->pAdaptors;
- na = pxvs->nAdaptors;
- while (na--)
- {
- np = pa->nPorts;
- pp = pa->pPorts;
-
- while (np--)
- {
- if (pp->pDraw == (DrawablePtr)pWin)
- {
- XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
-
- (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw);
-
- pp->pDraw = NULL;
- pp->client = NULL;
- pp->time = currentTime;
- }
- pp++;
- }
- pa++;
- }
-
-
- status = (* pScreen->DestroyWindow)(pWin);
-
- SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow);
-
- return status;
-
-}
-
-/* The XvdiVideoStopped procedure is a hook for the device dependent layer.
- It provides a way for the dd layer to inform the di layer that video has
- stopped in a port for reasons that the di layer had no control over; note
- that it doesn't call back into the dd layer */
-
-int
-XvdiVideoStopped(XvPortPtr pPort, int reason)
-{
-
- /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
-
- if (!pPort->pDraw) return Success;
-
- XvdiSendVideoNotify(pPort, pPort->pDraw, reason);
-
- pPort->pDraw = NULL;
- pPort->client = NULL;
- pPort->time = currentTime;
-
- return Success;
-
-}
-
-static int
-XvdiDestroyPort(pointer pPort, XID id)
-{
- return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort);
-}
-
-static int
-XvdiDestroyGrab(pointer pGrab, XID id)
-{
- ((XvGrabPtr)pGrab)->client = NULL;
- return Success;
-}
-
-static int
-XvdiDestroyVideoNotify(pointer pn, XID id)
-{
- /* JUST CLEAR OUT THE client POINTER FIELD */
-
- ((XvVideoNotifyPtr)pn)->client = NULL;
- return Success;
-}
-
-static int
-XvdiDestroyPortNotify(pointer pn, XID id)
-{
- /* JUST CLEAR OUT THE client POINTER FIELD */
-
- ((XvPortNotifyPtr)pn)->client = NULL;
- return Success;
-}
-
-static int
-XvdiDestroyVideoNotifyList(pointer pn, XID id)
-{
- XvVideoNotifyPtr npn,cpn;
-
- /* ACTUALLY DESTROY THE NOTITY LIST */
-
- cpn = (XvVideoNotifyPtr)pn;
-
- while (cpn)
- {
- npn = cpn->next;
- if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify);
- free(cpn);
- cpn = npn;
- }
- return Success;
-}
-
-static int
-XvdiDestroyEncoding(pointer value, XID id)
-{
- return Success;
-}
-
-static int
-XvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason)
-{
- xvEvent event;
- XvVideoNotifyPtr pn;
-
- dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList,
- serverClient, DixReadAccess);
-
- while (pn)
- {
- event.u.u.type = XvEventBase + XvVideoNotify;
- event.u.videoNotify.time = currentTime.milliseconds;
- event.u.videoNotify.drawable = pDraw->id;
- event.u.videoNotify.port = pPort->id;
- event.u.videoNotify.reason = reason;
- WriteEventsToClient(pn->client, 1, (xEventPtr)&event);
- pn = pn->next;
- }
-
- return Success;
-
-}
-
-
-int
-XvdiSendPortNotify(
- XvPortPtr pPort,
- Atom attribute,
- INT32 value
-){
- xvEvent event;
- XvPortNotifyPtr pn;
-
- pn = pPort->pNotify;
-
- while (pn)
- {
- event.u.u.type = XvEventBase + XvPortNotify;
- event.u.portNotify.time = currentTime.milliseconds;
- event.u.portNotify.port = pPort->id;
- event.u.portNotify.attribute = attribute;
- event.u.portNotify.value = value;
- WriteEventsToClient(pn->client, 1, (xEventPtr)&event);
- pn = pn->next;
- }
-
- return Success;
-
-}
-
-
-#define CHECK_SIZE(dw, dh, sw, sh) { \
- if(!dw || !dh || !sw || !sh) return Success; \
- /* The region code will break these if they are too large */ \
- if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \
- return BadValue; \
-}
-
-
-int
-XvdiPutVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- DrawablePtr pOldDraw;
-
- CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
-
- /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
-
- UpdateCurrentTime();
-
- /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
- INFORM CLIENT OF ITS FAILURE */
-
- if (pPort->grab.client && (pPort->grab.client != client))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvBusy);
- return Success;
- }
-
- /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
- EVENTS TO ANY CLIENTS WHO WANT THEM */
-
- pOldDraw = pPort->pDraw;
- if ((pOldDraw) && (pOldDraw != pDraw))
- {
- XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
- }
-
- (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC,
- vid_x, vid_y, vid_w, vid_h,
- drw_x, drw_y, drw_w, drw_h);
-
- if ((pPort->pDraw) && (pOldDraw != pDraw))
- {
- pPort->client = client;
- XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
- }
-
- pPort->time = currentTime;
-
- return Success;
-
-}
-
-int
-XvdiPutStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- int status;
-
- CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
-
- /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
-
- UpdateCurrentTime();
-
- /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
- INFORM CLIENT OF ITS FAILURE */
-
- if (pPort->grab.client && (pPort->grab.client != client))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvBusy);
- return Success;
- }
-
- pPort->time = currentTime;
-
- status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC,
- vid_x, vid_y, vid_w, vid_h,
- drw_x, drw_y, drw_w, drw_h);
-
- return status;
-
-}
-
-int
-XvdiPutImage(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 src_x, INT16 src_y,
- CARD16 src_w, CARD16 src_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h,
- XvImagePtr image,
- unsigned char* data,
- Bool sync,
- CARD16 width, CARD16 height
-){
- CHECK_SIZE(drw_w, drw_h, src_w, src_h);
-
- /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
-
- UpdateCurrentTime();
-
- /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
- INFORM CLIENT OF ITS FAILURE */
-
- if (pPort->grab.client && (pPort->grab.client != client))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvBusy);
- return Success;
- }
-
- pPort->time = currentTime;
-
- return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC,
- src_x, src_y, src_w, src_h,
- drw_x, drw_y, drw_w, drw_h,
- image, data, sync, width, height);
-}
-
-
-int
-XvdiGetVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- DrawablePtr pOldDraw;
-
- CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
-
- /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
-
- UpdateCurrentTime();
-
- /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
- INFORM CLIENT OF ITS FAILURE */
-
- if (pPort->grab.client && (pPort->grab.client != client))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvBusy);
- return Success;
- }
-
- /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
- EVENTS TO ANY CLIENTS WHO WANT THEM */
-
- pOldDraw = pPort->pDraw;
- if ((pOldDraw) && (pOldDraw != pDraw))
- {
- XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
- }
-
- (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC,
- vid_x, vid_y, vid_w, vid_h,
- drw_x, drw_y, drw_w, drw_h);
-
- if ((pPort->pDraw) && (pOldDraw != pDraw))
- {
- pPort->client = client;
- XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
- }
-
- pPort->time = currentTime;
-
- return Success;
-
-}
-
-int
-XvdiGetStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- int status;
-
- CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
-
- /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
-
- UpdateCurrentTime();
-
- /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
- INFORM CLIENT OF ITS FAILURE */
-
- if (pPort->grab.client && (pPort->grab.client != client))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvBusy);
- return Success;
- }
-
- status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC,
- vid_x, vid_y, vid_w, vid_h,
- drw_x, drw_y, drw_w, drw_h);
-
- pPort->time = currentTime;
-
- return status;
-
-}
-
-int
-XvdiGrabPort(
- ClientPtr client,
- XvPortPtr pPort,
- Time ctime,
- int *p_result
-){
- unsigned long id;
- TimeStamp time;
-
- UpdateCurrentTime();
- time = ClientTimeToServerTime(ctime);
-
- if (pPort->grab.client && (client != pPort->grab.client))
- {
- *p_result = XvAlreadyGrabbed;
- return Success;
- }
-
- if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, pPort->time) == EARLIER))
- {
- *p_result = XvInvalidTime;
- return Success;
- }
-
- if (client == pPort->grab.client)
- {
- *p_result = Success;
- return Success;
- }
-
- id = FakeClientID(client->index);
-
- if (!AddResource(id, XvRTGrab, &pPort->grab))
- {
- return BadAlloc;
- }
-
- /* IF THERE IS ACTIVE VIDEO THEN STOP IT */
-
- if ((pPort->pDraw) && (client != pPort->client))
- {
- XvdiStopVideo(NULL, pPort, pPort->pDraw);
- }
-
- pPort->grab.client = client;
- pPort->grab.id = id;
-
- pPort->time = currentTime;
-
- *p_result = Success;
-
- return Success;
-
-}
-
-int
-XvdiUngrabPort(
- ClientPtr client,
- XvPortPtr pPort,
- Time ctime
-){
- TimeStamp time;
-
- UpdateCurrentTime();
- time = ClientTimeToServerTime(ctime);
-
- if ((!pPort->grab.client) || (client != pPort->grab.client))
- {
- return Success;
- }
-
- if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, pPort->time) == EARLIER))
- {
- return Success;
- }
-
- /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */
-
- FreeResource(pPort->grab.id, XvRTGrab);
- pPort->grab.client = NULL;
-
- pPort->time = currentTime;
-
- return Success;
-
-}
-
-
-int
-XvdiSelectVideoNotify(
- ClientPtr client,
- DrawablePtr pDraw,
- BOOL onoff
-){
- XvVideoNotifyPtr pn,tpn,fpn;
- int rc;
-
- /* FIND VideoNotify LIST */
-
- rc = dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList,
- client, DixWriteAccess);
- if (rc != Success && rc != BadValue)
- return rc;
-
- /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */
-
- if (!onoff && !pn) return Success;
-
- /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST
- WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */
-
- if (!pn)
- {
- if (!(tpn = malloc(sizeof(XvVideoNotifyRec))))
- return BadAlloc;
- tpn->next = NULL;
- if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn))
- {
- free(tpn);
- return BadAlloc;
- }
- }
- else
- {
- /* LOOK TO SEE IF ENTRY ALREADY EXISTS */
-
- fpn = NULL;
- tpn = pn;
- while (tpn)
- {
- if (tpn->client == client)
- {
- if (!onoff) tpn->client = NULL;
- return Success;
- }
- if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */
- tpn = tpn->next;
- }
-
- /* IF TUNNING OFF, THEN JUST RETURN */
-
- if (!onoff) return Success;
-
- /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */
-
- if (fpn)
- {
- tpn = fpn;
- }
- else
- {
- if (!(tpn = malloc(sizeof(XvVideoNotifyRec))))
- return BadAlloc;
- tpn->next = pn->next;
- pn->next = tpn;
- }
- }
-
- /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */
- /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */
-
- tpn->client = NULL;
- tpn->id = FakeClientID(client->index);
- AddResource(tpn->id, XvRTVideoNotify, tpn);
-
- tpn->client = client;
- return Success;
-
-}
-
-int
-XvdiSelectPortNotify(
- ClientPtr client,
- XvPortPtr pPort,
- BOOL onoff
-){
- XvPortNotifyPtr pn,tpn;
-
- /* SEE IF CLIENT IS ALREADY IN LIST */
-
- tpn = NULL;
- pn = pPort->pNotify;
- while (pn)
- {
- if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */
- if (pn->client == client) break;
- pn = pn->next;
- }
-
- /* IS THE CLIENT ALREADY ON THE LIST? */
-
- if (pn)
- {
- /* REMOVE IT? */
-
- if (!onoff)
- {
- pn->client = NULL;
- FreeResource(pn->id, XvRTPortNotify);
- }
-
- return Success;
- }
-
- /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE
- CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */
-
- if (!tpn)
- {
- if (!(tpn = malloc(sizeof(XvPortNotifyRec))))
- return BadAlloc;
- tpn->next = pPort->pNotify;
- pPort->pNotify = tpn;
- }
-
- tpn->client = client;
- tpn->id = FakeClientID(client->index);
- AddResource(tpn->id, XvRTPortNotify, tpn);
-
- return Success;
-
-}
-
-int
-XvdiStopVideo(
- ClientPtr client,
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
- int status;
-
- /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
-
- if (!pPort->pDraw || (pPort->pDraw != pDraw))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvStopped);
- return Success;
- }
-
- /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
- INFORM CLIENT OF ITS FAILURE */
-
- if ((client) && (pPort->grab.client) && (pPort->grab.client != client))
- {
- XvdiSendVideoNotify(pPort, pDraw, XvBusy);
- return Success;
- }
-
- XvdiSendVideoNotify(pPort, pDraw, XvStopped);
-
- status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw);
-
- pPort->pDraw = NULL;
- pPort->client = (ClientPtr)client;
- pPort->time = currentTime;
-
- return status;
-
-}
-
-int
-XvdiPreemptVideo(
- ClientPtr client,
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
- int status;
-
- /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
-
- if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success;
-
- XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
-
- status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw);
-
- pPort->pDraw = NULL;
- pPort->client = (ClientPtr)client;
- pPort->time = currentTime;
-
- return status;
-
-}
-
-int
-XvdiMatchPort(
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
-
- XvAdaptorPtr pa;
- XvFormatPtr pf;
- int nf;
-
- pa = pPort->pAdaptor;
-
- if (pa->pScreen != pDraw->pScreen) return BadMatch;
-
- nf = pa->nFormats;
- pf = pa->pFormats;
-
- while (nf--)
- {
- if ((pf->depth == pDraw->depth)
-#if 0
- && ((pDraw->type == DRAWABLE_PIXMAP) ||
- (wVisual(((WindowPtr)pDraw)) == pf->visual))
-#endif
- )
- return Success;
- pf++;
- }
-
- return BadMatch;
-
-}
-
-int
-XvdiSetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 value
-){
- int status;
-
- status = (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value);
- if (status == Success)
- XvdiSendPortNotify(pPort, attribute, value);
-
- return status;
-}
-
-int
-XvdiGetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 *p_value
-){
-
- return
- (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value);
-
-}
-
-static void
-WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to)
-
-{
-
- to->u.u.type = from->u.u.type;
- to->u.u.detail = from->u.u.detail;
- cpswaps(from->u.videoNotify.sequenceNumber,
- to->u.videoNotify.sequenceNumber);
- cpswapl(from->u.videoNotify.time, to->u.videoNotify.time);
- cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable);
- cpswapl(from->u.videoNotify.port, to->u.videoNotify.port);
-
-}
-
-static void
-WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to)
-
-{
-
- to->u.u.type = from->u.u.type;
- to->u.u.detail = from->u.u.detail;
- cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber);
- cpswapl(from->u.portNotify.time, to->u.portNotify.time);
- cpswapl(from->u.portNotify.port, to->u.portNotify.port);
- cpswapl(from->u.portNotify.value, to->u.portNotify.value);
-
-}
+/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +******************************************************************/ + +/* +** File: +** +** xvmain.c --- Xv server extension main device independent module. +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 04.09.91 Carver +** - change: stop video always generates an event even when video +** wasn't active +** +** 29.08.91 Carver +** - change: unrealizing windows no longer preempts video +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 28.05.91 Carver +** - fixed Put and Get requests to not preempt operations to same drawable +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 19.03.91 Carver +** - fixed Put and Get requests to honor grabbed ports. +** - fixed Video requests to update di structure with new drawable, and +** client after calling ddx. +** +** 24.01.91 Carver +** - version 1.4 upgrade +** +** Notes: +** +** Port structures reference client structures in a two different +** ways: when grabs, or video is active. Each reference is encoded +** as fake client resources and thus when the client is goes away so +** does the reference (it is zeroed). No other action is taken, so +** video doesn't necessarily stop. It probably will as a result of +** other resources going away, but if a client starts video using +** none of its own resources, then the video will continue to play +** after the client disappears. +** +** +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "gc.h" +#include "extnsionst.h" +#include "dixstruct.h" +#include "resource.h" +#include "opaque.h" +#include "input.h" + +#define GLOBAL + +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> +#include "xvdix.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif +#include "xvdisp.h" + +static DevPrivateKeyRec XvScreenKeyRec; +#define XvScreenKey (&XvScreenKeyRec) +unsigned long XvExtensionGeneration = 0; +unsigned long XvScreenGeneration = 0; +unsigned long XvResourceGeneration = 0; + +int XvReqCode; +int XvEventBase; +int XvErrorBase; + +RESTYPE XvRTPort; +RESTYPE XvRTEncoding; +RESTYPE XvRTGrab; +RESTYPE XvRTVideoNotify; +RESTYPE XvRTVideoNotifyList; +RESTYPE XvRTPortNotify; + +/* EXTERNAL */ + +static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); +static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); +static Bool CreateResourceTypes(void); + +static Bool XvCloseScreen(int, ScreenPtr); +static Bool XvDestroyPixmap(PixmapPtr); +static Bool XvDestroyWindow(WindowPtr); +static void XvResetProc(ExtensionEntry*); +static int XvdiDestroyGrab(pointer, XID); +static int XvdiDestroyEncoding(pointer, XID); +static int XvdiDestroyVideoNotify(pointer, XID); +static int XvdiDestroyPortNotify(pointer, XID); +static int XvdiDestroyVideoNotifyList(pointer, XID); +static int XvdiDestroyPort(pointer, XID); +static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); + + + + +/* +** XvExtensionInit +** +** +*/ + +void +XvExtensionInit(void) +{ + ExtensionEntry *extEntry; + + if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) + return; + + /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN + INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */ + if (XvScreenGeneration != serverGeneration) + { + if (!CreateResourceTypes()) + { + ErrorF("XvExtensionInit: Unable to allocate resource types\n"); + return; + } +#ifdef PANORAMIX + XineramaRegisterConnectionBlockCallback(XineramifyXv); +#endif + XvScreenGeneration = serverGeneration; + } + + if (XvExtensionGeneration != serverGeneration) + { + XvExtensionGeneration = serverGeneration; + + extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, + ProcXvDispatch, SProcXvDispatch, + XvResetProc, StandardMinorOpcode); + if (!extEntry) + { + FatalError("XvExtensionInit: AddExtensions failed\n"); + } + + XvReqCode = extEntry->base; + XvEventBase = extEntry->eventBase; + XvErrorBase = extEntry->errorBase; + + EventSwapVector[XvEventBase+XvVideoNotify] = + (EventSwapPtr)WriteSwappedVideoNotifyEvent; + EventSwapVector[XvEventBase+XvPortNotify] = + (EventSwapPtr)WriteSwappedPortNotifyEvent; + + SetResourceTypeErrorValue(XvRTPort, _XvBadPort); + (void)MakeAtom(XvName, strlen(XvName), xTrue); + + } +} + +static Bool +CreateResourceTypes(void) + +{ + + if (XvResourceGeneration == serverGeneration) return TRUE; + + XvResourceGeneration = serverGeneration; + + if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort, "XvRTPort"))) + { + ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); + return FALSE; + } + + if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab, "XvRTGrab"))) + { + ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); + return FALSE; + } + + if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding, + "XvRTEncoding"))) + { + ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); + return FALSE; + } + + if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify, + "XvRTVideoNotify"))) + { + ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n"); + return FALSE; + } + + if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList, + "XvRTVideoNotifyList"))) + { + ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n"); + return FALSE; + } + + if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify, + "XvRTPortNotify"))) + { + ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n"); + return FALSE; + } + + return TRUE; + +} + +int +XvScreenInit(ScreenPtr pScreen) +{ + XvScreenPtr pxvs; + + if (XvScreenGeneration != serverGeneration) + { + if (!CreateResourceTypes()) + { + ErrorF("XvScreenInit: Unable to allocate resource types\n"); + return BadAlloc; + } +#ifdef PANORAMIX + XineramaRegisterConnectionBlockCallback(XineramifyXv); +#endif + XvScreenGeneration = serverGeneration; + } + + if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) + return BadAlloc; + + if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey)) + { + ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); + } + + /* ALLOCATE SCREEN PRIVATE RECORD */ + + pxvs = malloc(sizeof (XvScreenRec)); + if (!pxvs) + { + ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); + return BadAlloc; + } + + dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs); + + pxvs->DestroyPixmap = pScreen->DestroyPixmap; + pxvs->DestroyWindow = pScreen->DestroyWindow; + pxvs->CloseScreen = pScreen->CloseScreen; + + pScreen->DestroyPixmap = XvDestroyPixmap; + pScreen->DestroyWindow = XvDestroyWindow; + pScreen->CloseScreen = XvCloseScreen; + + return Success; +} + +static Bool +XvCloseScreen( + int ii, + ScreenPtr pScreen +){ + + XvScreenPtr pxvs; + + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); + + pScreen->DestroyPixmap = pxvs->DestroyPixmap; + pScreen->DestroyWindow = pxvs->DestroyWindow; + pScreen->CloseScreen = pxvs->CloseScreen; + + (* pxvs->ddCloseScreen)(ii, pScreen); + + free(pxvs); + + dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL); + + return (*pScreen->CloseScreen)(ii, pScreen); +} + +static void +XvResetProc(ExtensionEntry* extEntry) +{ + XvResetProcVector(); +} + +DevPrivateKey +XvGetScreenKey(void) +{ + return XvScreenKey; +} + +unsigned long +XvGetRTPort(void) +{ + return XvRTPort; +} + +static Bool +XvDestroyPixmap(PixmapPtr pPix) +{ + Bool status; + ScreenPtr pScreen; + XvScreenPtr pxvs; + XvAdaptorPtr pa; + int na; + XvPortPtr pp; + int np; + + pScreen = pPix->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, DestroyPixmap); + + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); + + /* CHECK TO SEE IF THIS PORT IS IN USE */ + + pa = pxvs->pAdaptors; + na = pxvs->nAdaptors; + while (na--) + { + np = pa->nPorts; + pp = pa->pPorts; + + while (np--) + { + if (pp->pDraw == (DrawablePtr)pPix) + { + XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); + + (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); + + pp->pDraw = NULL; + pp->client = NULL; + pp->time = currentTime; + } + pp++; + } + pa++; + } + + status = (* pScreen->DestroyPixmap)(pPix); + + SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); + + return status; + +} + +static Bool +XvDestroyWindow(WindowPtr pWin) +{ + Bool status; + ScreenPtr pScreen; + XvScreenPtr pxvs; + XvAdaptorPtr pa; + int na; + XvPortPtr pp; + int np; + + pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, DestroyWindow); + + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); + + /* CHECK TO SEE IF THIS PORT IS IN USE */ + + pa = pxvs->pAdaptors; + na = pxvs->nAdaptors; + while (na--) + { + np = pa->nPorts; + pp = pa->pPorts; + + while (np--) + { + if (pp->pDraw == (DrawablePtr)pWin) + { + XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); + + (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); + + pp->pDraw = NULL; + pp->client = NULL; + pp->time = currentTime; + } + pp++; + } + pa++; + } + + + status = (* pScreen->DestroyWindow)(pWin); + + SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); + + return status; + +} + +/* The XvdiVideoStopped procedure is a hook for the device dependent layer. + It provides a way for the dd layer to inform the di layer that video has + stopped in a port for reasons that the di layer had no control over; note + that it doesn't call back into the dd layer */ + +int +XvdiVideoStopped(XvPortPtr pPort, int reason) +{ + + /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ + + if (!pPort->pDraw) return Success; + + XvdiSendVideoNotify(pPort, pPort->pDraw, reason); + + pPort->pDraw = NULL; + pPort->client = NULL; + pPort->time = currentTime; + + return Success; + +} + +static int +XvdiDestroyPort(pointer pPort, XID id) +{ + return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort); +} + +static int +XvdiDestroyGrab(pointer pGrab, XID id) +{ + ((XvGrabPtr)pGrab)->client = NULL; + return Success; +} + +static int +XvdiDestroyVideoNotify(pointer pn, XID id) +{ + /* JUST CLEAR OUT THE client POINTER FIELD */ + + ((XvVideoNotifyPtr)pn)->client = NULL; + return Success; +} + +static int +XvdiDestroyPortNotify(pointer pn, XID id) +{ + /* JUST CLEAR OUT THE client POINTER FIELD */ + + ((XvPortNotifyPtr)pn)->client = NULL; + return Success; +} + +static int +XvdiDestroyVideoNotifyList(pointer pn, XID id) +{ + XvVideoNotifyPtr npn,cpn; + + /* ACTUALLY DESTROY THE NOTITY LIST */ + + cpn = (XvVideoNotifyPtr)pn; + + while (cpn) + { + npn = cpn->next; + if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify); + free(cpn); + cpn = npn; + } + return Success; +} + +static int +XvdiDestroyEncoding(pointer value, XID id) +{ + return Success; +} + +static int +XvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason) +{ + xvEvent event; + XvVideoNotifyPtr pn; + + dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, + serverClient, DixReadAccess); + + while (pn) + { + event.u.u.type = XvEventBase + XvVideoNotify; + event.u.videoNotify.time = currentTime.milliseconds; + event.u.videoNotify.drawable = pDraw->id; + event.u.videoNotify.port = pPort->id; + event.u.videoNotify.reason = reason; + WriteEventsToClient(pn->client, 1, (xEventPtr)&event); + pn = pn->next; + } + + return Success; + +} + + +int +XvdiSendPortNotify( + XvPortPtr pPort, + Atom attribute, + INT32 value +){ + xvEvent event; + XvPortNotifyPtr pn; + + pn = pPort->pNotify; + + while (pn) + { + event.u.u.type = XvEventBase + XvPortNotify; + event.u.portNotify.time = currentTime.milliseconds; + event.u.portNotify.port = pPort->id; + event.u.portNotify.attribute = attribute; + event.u.portNotify.value = value; + WriteEventsToClient(pn->client, 1, (xEventPtr)&event); + pn = pn->next; + } + + return Success; + +} + + +#define CHECK_SIZE(dw, dh, sw, sh) { \ + if(!dw || !dh || !sw || !sh) return Success; \ + /* The region code will break these if they are too large */ \ + if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ + return BadValue; \ +} + + +int +XvdiPutVideo( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + DrawablePtr pOldDraw; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED + EVENTS TO ANY CLIENTS WHO WANT THEM */ + + pOldDraw = pPort->pDraw; + if ((pOldDraw) && (pOldDraw != pDraw)) + { + XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); + } + + (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + if ((pPort->pDraw) && (pOldDraw != pDraw)) + { + pPort->client = client; + XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); + } + + pPort->time = currentTime; + + return Success; + +} + +int +XvdiPutStill( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + int status; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + pPort->time = currentTime; + + status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + return status; + +} + +int +XvdiPutImage( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 src_x, INT16 src_y, + CARD16 src_w, CARD16 src_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h, + XvImagePtr image, + unsigned char* data, + Bool sync, + CARD16 width, CARD16 height +){ + CHECK_SIZE(drw_w, drw_h, src_w, src_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + pPort->time = currentTime; + + return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, + src_x, src_y, src_w, src_h, + drw_x, drw_y, drw_w, drw_h, + image, data, sync, width, height); +} + + +int +XvdiGetVideo( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + DrawablePtr pOldDraw; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED + EVENTS TO ANY CLIENTS WHO WANT THEM */ + + pOldDraw = pPort->pDraw; + if ((pOldDraw) && (pOldDraw != pDraw)) + { + XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); + } + + (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + if ((pPort->pDraw) && (pOldDraw != pDraw)) + { + pPort->client = client; + XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); + } + + pPort->time = currentTime; + + return Success; + +} + +int +XvdiGetStill( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + int status; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + pPort->time = currentTime; + + return status; + +} + +int +XvdiGrabPort( + ClientPtr client, + XvPortPtr pPort, + Time ctime, + int *p_result +){ + unsigned long id; + TimeStamp time; + + UpdateCurrentTime(); + time = ClientTimeToServerTime(ctime); + + if (pPort->grab.client && (client != pPort->grab.client)) + { + *p_result = XvAlreadyGrabbed; + return Success; + } + + if ((CompareTimeStamps(time, currentTime) == LATER) || + (CompareTimeStamps(time, pPort->time) == EARLIER)) + { + *p_result = XvInvalidTime; + return Success; + } + + if (client == pPort->grab.client) + { + *p_result = Success; + return Success; + } + + id = FakeClientID(client->index); + + if (!AddResource(id, XvRTGrab, &pPort->grab)) + { + return BadAlloc; + } + + /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ + + if ((pPort->pDraw) && (client != pPort->client)) + { + XvdiStopVideo(NULL, pPort, pPort->pDraw); + } + + pPort->grab.client = client; + pPort->grab.id = id; + + pPort->time = currentTime; + + *p_result = Success; + + return Success; + +} + +int +XvdiUngrabPort( + ClientPtr client, + XvPortPtr pPort, + Time ctime +){ + TimeStamp time; + + UpdateCurrentTime(); + time = ClientTimeToServerTime(ctime); + + if ((!pPort->grab.client) || (client != pPort->grab.client)) + { + return Success; + } + + if ((CompareTimeStamps(time, currentTime) == LATER) || + (CompareTimeStamps(time, pPort->time) == EARLIER)) + { + return Success; + } + + /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ + + FreeResource(pPort->grab.id, XvRTGrab); + pPort->grab.client = NULL; + + pPort->time = currentTime; + + return Success; + +} + + +int +XvdiSelectVideoNotify( + ClientPtr client, + DrawablePtr pDraw, + BOOL onoff +){ + XvVideoNotifyPtr pn,tpn,fpn; + int rc; + + /* FIND VideoNotify LIST */ + + rc = dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, + client, DixWriteAccess); + if (rc != Success && rc != BadValue) + return rc; + + /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ + + if (!onoff && !pn) return Success; + + /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST + WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ + + if (!pn) + { + if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) + return BadAlloc; + tpn->next = NULL; + if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) + { + free(tpn); + return BadAlloc; + } + } + else + { + /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ + + fpn = NULL; + tpn = pn; + while (tpn) + { + if (tpn->client == client) + { + if (!onoff) tpn->client = NULL; + return Success; + } + if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ + tpn = tpn->next; + } + + /* IF TUNNING OFF, THEN JUST RETURN */ + + if (!onoff) return Success; + + /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ + + if (fpn) + { + tpn = fpn; + } + else + { + if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) + return BadAlloc; + tpn->next = pn->next; + pn->next = tpn; + } + } + + /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ + /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ + + tpn->client = NULL; + tpn->id = FakeClientID(client->index); + AddResource(tpn->id, XvRTVideoNotify, tpn); + + tpn->client = client; + return Success; + +} + +int +XvdiSelectPortNotify( + ClientPtr client, + XvPortPtr pPort, + BOOL onoff +){ + XvPortNotifyPtr pn,tpn; + + /* SEE IF CLIENT IS ALREADY IN LIST */ + + tpn = NULL; + pn = pPort->pNotify; + while (pn) + { + if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */ + if (pn->client == client) break; + pn = pn->next; + } + + /* IS THE CLIENT ALREADY ON THE LIST? */ + + if (pn) + { + /* REMOVE IT? */ + + if (!onoff) + { + pn->client = NULL; + FreeResource(pn->id, XvRTPortNotify); + } + + return Success; + } + + /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE + CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ + + if (!tpn) + { + if (!(tpn = malloc(sizeof(XvPortNotifyRec)))) + return BadAlloc; + tpn->next = pPort->pNotify; + pPort->pNotify = tpn; + } + + tpn->client = client; + tpn->id = FakeClientID(client->index); + AddResource(tpn->id, XvRTPortNotify, tpn); + + return Success; + +} + +int +XvdiStopVideo( + ClientPtr client, + XvPortPtr pPort, + DrawablePtr pDraw +){ + int status; + + /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ + + if (!pPort->pDraw || (pPort->pDraw != pDraw)) + { + XvdiSendVideoNotify(pPort, pDraw, XvStopped); + return Success; + } + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + XvdiSendVideoNotify(pPort, pDraw, XvStopped); + + status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw); + + pPort->pDraw = NULL; + pPort->client = (ClientPtr)client; + pPort->time = currentTime; + + return status; + +} + +int +XvdiPreemptVideo( + ClientPtr client, + XvPortPtr pPort, + DrawablePtr pDraw +){ + int status; + + /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ + + if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success; + + XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); + + status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw); + + pPort->pDraw = NULL; + pPort->client = (ClientPtr)client; + pPort->time = currentTime; + + return status; + +} + +int +XvdiMatchPort( + XvPortPtr pPort, + DrawablePtr pDraw +){ + + XvAdaptorPtr pa; + XvFormatPtr pf; + int nf; + + pa = pPort->pAdaptor; + + if (pa->pScreen != pDraw->pScreen) return BadMatch; + + nf = pa->nFormats; + pf = pa->pFormats; + + while (nf--) + { + if ((pf->depth == pDraw->depth) +#if 0 + && ((pDraw->type == DRAWABLE_PIXMAP) || + (wVisual(((WindowPtr)pDraw)) == pf->visual)) +#endif + ) + return Success; + pf++; + } + + return BadMatch; + +} + +int +XvdiSetPortAttribute( + ClientPtr client, + XvPortPtr pPort, + Atom attribute, + INT32 value +){ + int status; + + status = (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value); + if (status == Success) + XvdiSendPortNotify(pPort, attribute, value); + + return status; +} + +int +XvdiGetPortAttribute( + ClientPtr client, + XvPortPtr pPort, + Atom attribute, + INT32 *p_value +){ + + return + (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value); + +} + +static void +WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to) + +{ + + to->u.u.type = from->u.u.type; + to->u.u.detail = from->u.u.detail; + cpswaps(from->u.videoNotify.sequenceNumber, + to->u.videoNotify.sequenceNumber); + cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); + cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); + cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); + +} + +static void +WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to) + +{ + + to->u.u.type = from->u.u.type; + to->u.u.detail = from->u.u.detail; + cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); + cpswapl(from->u.portNotify.time, to->u.portNotify.time); + cpswapl(from->u.portNotify.port, to->u.portNotify.port); + cpswapl(from->u.portNotify.value, to->u.portNotify.value); + +} diff --git a/xorg-server/Xext/xvmc.c b/xorg-server/Xext/xvmc.c index 9b9dd0bc2..4d29941ee 100644 --- a/xorg-server/Xext/xvmc.c +++ b/xorg-server/Xext/xvmc.c @@ -1,789 +1,789 @@ -
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "scrnintstr.h"
-#include "extnsionst.h"
-#include "servermd.h"
-#include <X11/Xfuncproto.h>
-#include "xvdix.h"
-#include <X11/extensions/XvMC.h>
-#include <X11/extensions/Xvproto.h>
-#include <X11/extensions/XvMCproto.h>
-#include "xvmcext.h"
-#include "protocol-versions.h"
-
-#ifdef HAS_XVMCSHM
-#include <sys/ipc.h>
-#include <sys/types.h>
-#include <sys/shm.h>
-#endif /* HAS_XVMCSHM */
-
-
-
-#define DR_CLIENT_DRIVER_NAME_SIZE 48
-#define DR_BUSID_SIZE 48
-
-static DevPrivateKeyRec XvMCScreenKeyRec;
-#define XvMCScreenKey (&XvMCScreenKeyRec)
-static Bool XvMCInUse;
-
-unsigned long XvMCGeneration = 0;
-
-int XvMCReqCode;
-int XvMCEventBase;
-
-unsigned long XvMCRTContext;
-unsigned long XvMCRTSurface;
-unsigned long XvMCRTSubpicture;
-
-typedef struct {
- int num_adaptors;
- XvMCAdaptorPtr adaptors;
- CloseScreenProcPtr CloseScreen;
- char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE];
- char busID[DR_BUSID_SIZE];
- int major;
- int minor;
- int patchLevel;
-} XvMCScreenRec, *XvMCScreenPtr;
-
-#define XVMC_GET_PRIVATE(pScreen) \
- (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey))
-
-
-static int
-XvMCDestroyContextRes(pointer data, XID id)
-{
- XvMCContextPtr pContext = (XvMCContextPtr)data;
-
- pContext->refcnt--;
-
- if(!pContext->refcnt) {
- XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
- (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext);
- free(pContext);
- }
-
- return Success;
-}
-
-static int
-XvMCDestroySurfaceRes(pointer data, XID id)
-{
- XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data;
- XvMCContextPtr pContext = pSurface->context;
- XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
-
- (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface);
- free(pSurface);
-
- XvMCDestroyContextRes((pointer)pContext, pContext->context_id);
-
- return Success;
-}
-
-
-static int
-XvMCDestroySubpictureRes(pointer data, XID id)
-{
- XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data;
- XvMCContextPtr pContext = pSubpict->context;
- XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
-
- (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict);
- free(pSubpict);
-
- XvMCDestroyContextRes((pointer)pContext, pContext->context_id);
-
- return Success;
-}
-
-static int
-ProcXvMCQueryVersion(ClientPtr client)
-{
- xvmcQueryVersionReply rep;
- /* REQUEST(xvmcQueryVersionReq); */
- REQUEST_SIZE_MATCH(xvmcQueryVersionReq);
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.major = SERVER_XVMC_MAJOR_VERSION;
- rep.minor = SERVER_XVMC_MINOR_VERSION;
- WriteToClient(client, sizeof(xvmcQueryVersionReply), (char*)&rep);
- return Success;
-}
-
-
-static int
-ProcXvMCListSurfaceTypes(ClientPtr client)
-{
- XvPortPtr pPort;
- int i;
- XvMCScreenPtr pScreenPriv;
- xvmcListSurfaceTypesReply rep;
- xvmcSurfaceInfo info;
- XvMCAdaptorPtr adaptor = NULL;
- XvMCSurfaceInfoPtr surface;
- REQUEST(xvmcListSurfaceTypesReq);
- REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if(XvMCInUse) { /* any adaptors at all */
- ScreenPtr pScreen = pPort->pAdaptor->pScreen;
- if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */
- for(i = 0; i < pScreenPriv->num_adaptors; i++) {
- if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
- adaptor = &(pScreenPriv->adaptors[i]);
- break;
- }
- }
- }
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num = (adaptor) ? adaptor->num_surfaces : 0;
- rep.length = bytes_to_int32(rep.num * sizeof(xvmcSurfaceInfo));
-
- WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), (char*)&rep);
-
- for(i = 0; i < rep.num; i++) {
- surface = adaptor->surfaces[i];
- info.surface_type_id = surface->surface_type_id;
- info.chroma_format = surface->chroma_format;
- info.max_width = surface->max_width;
- info.max_height = surface->max_height;
- info.subpicture_max_width = surface->subpicture_max_width;
- info.subpicture_max_height = surface->subpicture_max_height;
- info.mc_type = surface->mc_type;
- info.flags = surface->flags;
- WriteToClient(client, sizeof(xvmcSurfaceInfo), (char*)&info);
- }
-
- return Success;
-}
-
-static int
-ProcXvMCCreateContext(ClientPtr client)
-{
- XvPortPtr pPort;
- CARD32 *data = NULL;
- int dwords = 0;
- int i, result, adapt_num = -1;
- ScreenPtr pScreen;
- XvMCContextPtr pContext;
- XvMCScreenPtr pScreenPriv;
- XvMCAdaptorPtr adaptor = NULL;
- XvMCSurfaceInfoPtr surface = NULL;
- xvmcCreateContextReply rep;
- REQUEST(xvmcCreateContextReq);
- REQUEST_SIZE_MATCH(xvmcCreateContextReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- pScreen = pPort->pAdaptor->pScreen;
-
- if(!XvMCInUse) /* no XvMC adaptors */
- return BadMatch;
-
- if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */
- return BadMatch;
-
- for(i = 0; i < pScreenPriv->num_adaptors; i++) {
- if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
- adaptor = &(pScreenPriv->adaptors[i]);
- adapt_num = i;
- break;
- }
- }
-
- if(adapt_num < 0) /* none this port */
- return BadMatch;
-
- for(i = 0; i < adaptor->num_surfaces; i++) {
- if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
- surface = adaptor->surfaces[i];
- break;
- }
- }
-
- /* adaptor doesn't support this suface_type_id */
- if(!surface) return BadMatch;
-
-
- if((stuff->width > surface->max_width) ||
- (stuff->height > surface->max_height))
- return BadValue;
-
- if(!(pContext = malloc(sizeof(XvMCContextRec)))) {
- return BadAlloc;
- }
-
-
- pContext->pScreen = pScreen;
- pContext->adapt_num = adapt_num;
- pContext->context_id = stuff->context_id;
- pContext->surface_type_id = stuff->surface_type_id;
- pContext->width = stuff->width;
- pContext->height = stuff->height;
- pContext->flags = stuff->flags;
- pContext->refcnt = 1;
-
- result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data);
-
- if(result != Success) {
- free(pContext);
- return result;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.width_actual = pContext->width;
- rep.height_actual = pContext->height;
- rep.flags_return = pContext->flags;
- rep.length = dwords;
-
- WriteToClient(client, sizeof(xvmcCreateContextReply), (char*)&rep);
- if(dwords)
- WriteToClient(client, dwords << 2, (char*)data);
- AddResource(pContext->context_id, XvMCRTContext, pContext);
-
- free(data);
-
- return Success;
-}
-
-static int
-ProcXvMCDestroyContext(ClientPtr client)
-{
- pointer val;
- int rc;
- REQUEST(xvmcDestroyContextReq);
- REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
-
- rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext,
- client, DixDestroyAccess);
- if (rc != Success)
- return rc;
-
- FreeResource(stuff->context_id, RT_NONE);
-
- return Success;
-}
-
-static int
-ProcXvMCCreateSurface(ClientPtr client)
-{
- CARD32 *data = NULL;
- int dwords = 0;
- int result;
- XvMCContextPtr pContext;
- XvMCSurfacePtr pSurface;
- XvMCScreenPtr pScreenPriv;
- xvmcCreateSurfaceReply rep;
- REQUEST(xvmcCreateSurfaceReq);
- REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
-
- result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id,
- XvMCRTContext, client, DixUseAccess);
- if (result != Success)
- return result;
-
- pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
-
- if(!(pSurface = malloc(sizeof(XvMCSurfaceRec))))
- return BadAlloc;
-
- pSurface->surface_id = stuff->surface_id;
- pSurface->surface_type_id = pContext->surface_type_id;
- pSurface->context = pContext;
-
- result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)(
- pSurface, &dwords, &data);
-
- if(result != Success) {
- free(pSurface);
- return result;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = dwords;
-
- WriteToClient(client, sizeof(xvmcCreateSurfaceReply), (char*)&rep);
- if(dwords)
- WriteToClient(client, dwords << 2, (char*)data);
- AddResource(pSurface->surface_id, XvMCRTSurface, pSurface);
-
- free(data);
-
- pContext->refcnt++;
-
- return Success;
-}
-
-static int
-ProcXvMCDestroySurface(ClientPtr client)
-{
- pointer val;
- int rc;
- REQUEST(xvmcDestroySurfaceReq);
- REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
-
- rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface,
- client, DixDestroyAccess);
- if (rc != Success)
- return rc;
-
- FreeResource(stuff->surface_id, RT_NONE);
-
- return Success;
-}
-
-static int
-ProcXvMCCreateSubpicture(ClientPtr client)
-{
- Bool image_supported = FALSE;
- CARD32 *data = NULL;
- int i, result, dwords = 0;
- XvMCContextPtr pContext;
- XvMCSubpicturePtr pSubpicture;
- XvMCScreenPtr pScreenPriv;
- xvmcCreateSubpictureReply rep;
- XvMCAdaptorPtr adaptor;
- XvMCSurfaceInfoPtr surface = NULL;
- REQUEST(xvmcCreateSubpictureReq);
- REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
-
- result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id,
- XvMCRTContext, client, DixUseAccess);
- if (result != Success)
- return result;
-
- pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
-
- adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
-
- /* find which surface this context supports */
- for(i = 0; i < adaptor->num_surfaces; i++) {
- if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){
- surface = adaptor->surfaces[i];
- break;
- }
- }
-
- if(!surface) return BadMatch;
-
- /* make sure this surface supports that xvimage format */
- if(!surface->compatible_subpictures) return BadMatch;
-
- for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
- if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) {
- image_supported = TRUE;
- break;
- }
- }
-
- if(!image_supported) return BadMatch;
-
- /* make sure the size is OK */
- if((stuff->width > surface->subpicture_max_width) ||
- (stuff->height > surface->subpicture_max_height))
- return BadValue;
-
- if(!(pSubpicture = malloc(sizeof(XvMCSubpictureRec))))
- return BadAlloc;
-
- pSubpicture->subpicture_id = stuff->subpicture_id;
- pSubpicture->xvimage_id = stuff->xvimage_id;
- pSubpicture->width = stuff->width;
- pSubpicture->height = stuff->height;
- pSubpicture->num_palette_entries = 0; /* overwritten by DDX */
- pSubpicture->entry_bytes = 0; /* overwritten by DDX */
- pSubpicture->component_order[0] = 0; /* overwritten by DDX */
- pSubpicture->component_order[1] = 0;
- pSubpicture->component_order[2] = 0;
- pSubpicture->component_order[3] = 0;
- pSubpicture->context = pContext;
-
- result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)(
- pSubpicture, &dwords, &data);
-
- if(result != Success) {
- free(pSubpicture);
- return result;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.width_actual = pSubpicture->width;
- rep.height_actual = pSubpicture->height;
- rep.num_palette_entries = pSubpicture->num_palette_entries;
- rep.entry_bytes = pSubpicture->entry_bytes;
- rep.component_order[0] = pSubpicture->component_order[0];
- rep.component_order[1] = pSubpicture->component_order[1];
- rep.component_order[2] = pSubpicture->component_order[2];
- rep.component_order[3] = pSubpicture->component_order[3];
- rep.length = dwords;
-
- WriteToClient(client, sizeof(xvmcCreateSubpictureReply), (char*)&rep);
- if(dwords)
- WriteToClient(client, dwords << 2, (char*)data);
- AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture);
-
- free(data);
-
- pContext->refcnt++;
-
- return Success;
-}
-
-static int
-ProcXvMCDestroySubpicture(ClientPtr client)
-{
- pointer val;
- int rc;
- REQUEST(xvmcDestroySubpictureReq);
- REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
-
- rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture,
- client, DixDestroyAccess);
- if (rc != Success)
- return rc;
-
- FreeResource(stuff->subpicture_id, RT_NONE);
-
- return Success;
-}
-
-
-static int
-ProcXvMCListSubpictureTypes(ClientPtr client)
-{
- XvPortPtr pPort;
- xvmcListSubpictureTypesReply rep;
- XvMCScreenPtr pScreenPriv;
- ScreenPtr pScreen;
- XvMCAdaptorPtr adaptor = NULL;
- XvMCSurfaceInfoPtr surface = NULL;
- xvImageFormatInfo info;
- XvImagePtr pImage;
- int i, j;
- REQUEST(xvmcListSubpictureTypesReq);
- REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- pScreen = pPort->pAdaptor->pScreen;
-
- if(XvMCScreenKey == NULL) /* No XvMC adaptors */
- return BadMatch;
-
- if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
- return BadMatch; /* None this screen */
-
- for(i = 0; i < pScreenPriv->num_adaptors; i++) {
- if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
- adaptor = &(pScreenPriv->adaptors[i]);
- break;
- }
- }
-
- if(!adaptor) return BadMatch;
-
- for(i = 0; i < adaptor->num_surfaces; i++) {
- if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
- surface = adaptor->surfaces[i];
- break;
- }
- }
-
- if(!surface) return BadMatch;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num = 0;
- if(surface->compatible_subpictures)
- rep.num = surface->compatible_subpictures->num_xvimages;
-
- rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo));
-
- WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), (char*)&rep);
-
- for(i = 0; i < rep.num; i++) {
- pImage = NULL;
- for(j = 0; j < adaptor->num_subpictures; j++) {
- if(surface->compatible_subpictures->xvimage_ids[i] ==
- adaptor->subpictures[j]->id)
- {
- pImage = adaptor->subpictures[j];
- break;
- }
- }
- if(!pImage) return BadImplementation;
-
- info.id = pImage->id;
- info.type = pImage->type;
- info.byte_order = pImage->byte_order;
- memcpy(&info.guid, pImage->guid, 16);
- info.bpp = pImage->bits_per_pixel;
- info.num_planes = pImage->num_planes;
- info.depth = pImage->depth;
- info.red_mask = pImage->red_mask;
- info.green_mask = pImage->green_mask;
- info.blue_mask = pImage->blue_mask;
- info.format = pImage->format;
- info.y_sample_bits = pImage->y_sample_bits;
- info.u_sample_bits = pImage->u_sample_bits;
- info.v_sample_bits = pImage->v_sample_bits;
- info.horz_y_period = pImage->horz_y_period;
- info.horz_u_period = pImage->horz_u_period;
- info.horz_v_period = pImage->horz_v_period;
- info.vert_y_period = pImage->vert_y_period;
- info.vert_u_period = pImage->vert_u_period;
- info.vert_v_period = pImage->vert_v_period;
- memcpy(&info.comp_order, pImage->component_order, 32);
- info.scanline_order = pImage->scanline_order;
- WriteToClient(client, sizeof(xvImageFormatInfo), (char*)&info);
- }
-
- return Success;
-}
-
-static int
-ProcXvMCGetDRInfo(ClientPtr client)
-{
- xvmcGetDRInfoReply rep;
- XvPortPtr pPort;
- ScreenPtr pScreen;
- XvMCScreenPtr pScreenPriv;
-
-#ifdef HAS_XVMCSHM
- volatile CARD32 *patternP;
-#endif
-
- REQUEST(xvmcGetDRInfoReq);
- REQUEST_SIZE_MATCH(xvmcGetDRInfoReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- pScreen = pPort->pAdaptor->pScreen;
- pScreenPriv = XVMC_GET_PRIVATE(pScreen);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.major = pScreenPriv->major;
- rep.minor = pScreenPriv->minor;
- rep.patchLevel = pScreenPriv->patchLevel;
- rep.nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1);
- rep.busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1);
-
- rep.length = rep.nameLen + rep.busIDLen;
- rep.nameLen <<=2;
- rep.busIDLen <<=2;
-
- /*
- * Read back to the client what she has put in the shared memory
- * segment she prepared for us.
- */
-
- rep.isLocal = 1;
-#ifdef HAS_XVMCSHM
- patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY );
- if ( -1 != (long) patternP) {
- volatile CARD32 *patternC = patternP;
- int i;
- CARD32 magic = stuff->magic;
-
- rep.isLocal = 1;
- i = 1024 / sizeof(CARD32);
-
- while ( i-- ) {
- if (*patternC++ != magic) {
- rep.isLocal = 0;
- break;
- }
- magic = ~magic;
- }
- shmdt( (char *)patternP );
- }
-#endif /* HAS_XVMCSHM */
-
- WriteToClient(client, sizeof(xvmcGetDRInfoReply),
- (char*)&rep);
- if (rep.length) {
- WriteToClient(client, rep.nameLen,
- pScreenPriv->clientDriverName);
- WriteToClient(client, rep.busIDLen,
- pScreenPriv->busID);
- }
- return Success;
-}
-
-
-int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = {
- ProcXvMCQueryVersion,
- ProcXvMCListSurfaceTypes,
- ProcXvMCCreateContext,
- ProcXvMCDestroyContext,
- ProcXvMCCreateSurface,
- ProcXvMCDestroySurface,
- ProcXvMCCreateSubpicture,
- ProcXvMCDestroySubpicture,
- ProcXvMCListSubpictureTypes,
- ProcXvMCGetDRInfo
-};
-
-static int
-ProcXvMCDispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if(stuff->data < xvmcNumRequest)
- return (*ProcXvMCVector[stuff->data])(client);
- else
- return BadRequest;
-}
-
-static int
-SProcXvMCDispatch (ClientPtr client)
-{
- /* We only support local */
- return BadImplementation;
-}
-
-void
-XvMCExtensionInit(void)
-{
- ExtensionEntry *extEntry;
-
- if(XvMCScreenKey == NULL) /* nobody supports it */
- return;
-
- if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes,
- "XvMCRTContext")))
- return;
-
- if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes,
- "XvMCRTSurface")))
- return;
-
- if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes,
- "XvMCRTSubpicture")))
- return;
-
- extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors,
- ProcXvMCDispatch, SProcXvMCDispatch,
- NULL, StandardMinorOpcode);
-
- if(!extEntry) return;
-
- XvMCReqCode = extEntry->base;
- XvMCEventBase = extEntry->eventBase;
- SetResourceTypeErrorValue(XvMCRTContext, extEntry->errorBase + XvMCBadContext);
- SetResourceTypeErrorValue(XvMCRTSurface, extEntry->errorBase + XvMCBadSurface);
- SetResourceTypeErrorValue(XvMCRTSubpicture, extEntry->errorBase + XvMCBadSubpicture);
-}
-
-static Bool
-XvMCCloseScreen (int i, ScreenPtr pScreen)
-{
- XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
-
- free(pScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
-
-
-int
-XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
-{
- XvMCScreenPtr pScreenPriv;
-
- if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0))
- return BadAlloc;
-
- if(!(pScreenPriv = malloc(sizeof(XvMCScreenRec))))
- return BadAlloc;
-
- dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv);
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = XvMCCloseScreen;
-
- pScreenPriv->num_adaptors = num;
- pScreenPriv->adaptors = pAdapt;
- pScreenPriv->clientDriverName[0] = 0;
- pScreenPriv->busID[0] = 0;
- pScreenPriv->major = 0;
- pScreenPriv->minor = 0;
- pScreenPriv->patchLevel = 0;
-
- XvMCInUse = TRUE;
-
- return Success;
-}
-
-XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
-{
- XvImagePtr pImage = NULL;
- ScreenPtr pScreen = pPort->pAdaptor->pScreen;
- XvMCScreenPtr pScreenPriv;
- XvMCAdaptorPtr adaptor = NULL;
- int i;
-
- if(XvMCScreenKey == NULL) return NULL;
-
- if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
- return NULL;
-
- for(i = 0; i < pScreenPriv->num_adaptors; i++) {
- if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
- adaptor = &(pScreenPriv->adaptors[i]);
- break;
- }
- }
-
- if(!adaptor) return NULL;
-
- for(i = 0; i < adaptor->num_subpictures; i++) {
- if(adaptor->subpictures[i]->id == id) {
- pImage = adaptor->subpictures[i];
- break;
- }
- }
-
- return pImage;
-}
-
-int
-xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
- char *busID, int major, int minor,
- int patchLevel)
-{
- XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
- strncpy(pScreenPriv->clientDriverName, name,
- DR_CLIENT_DRIVER_NAME_SIZE);
- strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
- pScreenPriv->major = major;
- pScreenPriv->minor = minor;
- pScreenPriv->patchLevel = patchLevel;
- pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0;
- pScreenPriv->busID[DR_BUSID_SIZE-1] = 0;
- return Success;
-}
-
+ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "extnsionst.h" +#include "servermd.h" +#include <X11/Xfuncproto.h> +#include "xvdix.h" +#include <X11/extensions/XvMC.h> +#include <X11/extensions/Xvproto.h> +#include <X11/extensions/XvMCproto.h> +#include "xvmcext.h" +#include "protocol-versions.h" + +#ifdef HAS_XVMCSHM +#include <sys/ipc.h> +#include <sys/types.h> +#include <sys/shm.h> +#endif /* HAS_XVMCSHM */ + + + +#define DR_CLIENT_DRIVER_NAME_SIZE 48 +#define DR_BUSID_SIZE 48 + +static DevPrivateKeyRec XvMCScreenKeyRec; +#define XvMCScreenKey (&XvMCScreenKeyRec) +static Bool XvMCInUse; + +unsigned long XvMCGeneration = 0; + +int XvMCReqCode; +int XvMCEventBase; + +static RESTYPE XvMCRTContext; +static RESTYPE XvMCRTSurface; +static RESTYPE XvMCRTSubpicture; + +typedef struct { + int num_adaptors; + XvMCAdaptorPtr adaptors; + CloseScreenProcPtr CloseScreen; + char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE]; + char busID[DR_BUSID_SIZE]; + int major; + int minor; + int patchLevel; +} XvMCScreenRec, *XvMCScreenPtr; + +#define XVMC_GET_PRIVATE(pScreen) \ + (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey)) + + +static int +XvMCDestroyContextRes(pointer data, XID id) +{ + XvMCContextPtr pContext = (XvMCContextPtr)data; + + pContext->refcnt--; + + if(!pContext->refcnt) { + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext); + free(pContext); + } + + return Success; +} + +static int +XvMCDestroySurfaceRes(pointer data, XID id) +{ + XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data; + XvMCContextPtr pContext = pSurface->context; + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface); + free(pSurface); + + XvMCDestroyContextRes((pointer)pContext, pContext->context_id); + + return Success; +} + + +static int +XvMCDestroySubpictureRes(pointer data, XID id) +{ + XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data; + XvMCContextPtr pContext = pSubpict->context; + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict); + free(pSubpict); + + XvMCDestroyContextRes((pointer)pContext, pContext->context_id); + + return Success; +} + +static int +ProcXvMCQueryVersion(ClientPtr client) +{ + xvmcQueryVersionReply rep; + /* REQUEST(xvmcQueryVersionReq); */ + REQUEST_SIZE_MATCH(xvmcQueryVersionReq); + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.major = SERVER_XVMC_MAJOR_VERSION; + rep.minor = SERVER_XVMC_MINOR_VERSION; + WriteToClient(client, sizeof(xvmcQueryVersionReply), (char*)&rep); + return Success; +} + + +static int +ProcXvMCListSurfaceTypes(ClientPtr client) +{ + XvPortPtr pPort; + int i; + XvMCScreenPtr pScreenPriv; + xvmcListSurfaceTypesReply rep; + xvmcSurfaceInfo info; + XvMCAdaptorPtr adaptor = NULL; + XvMCSurfaceInfoPtr surface; + REQUEST(xvmcListSurfaceTypesReq); + REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if(XvMCInUse) { /* any adaptors at all */ + ScreenPtr pScreen = pPort->pAdaptor->pScreen; + if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */ + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + break; + } + } + } + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num = (adaptor) ? adaptor->num_surfaces : 0; + rep.length = bytes_to_int32(rep.num * sizeof(xvmcSurfaceInfo)); + + WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), (char*)&rep); + + for(i = 0; i < rep.num; i++) { + surface = adaptor->surfaces[i]; + info.surface_type_id = surface->surface_type_id; + info.chroma_format = surface->chroma_format; + info.max_width = surface->max_width; + info.max_height = surface->max_height; + info.subpicture_max_width = surface->subpicture_max_width; + info.subpicture_max_height = surface->subpicture_max_height; + info.mc_type = surface->mc_type; + info.flags = surface->flags; + WriteToClient(client, sizeof(xvmcSurfaceInfo), (char*)&info); + } + + return Success; +} + +static int +ProcXvMCCreateContext(ClientPtr client) +{ + XvPortPtr pPort; + CARD32 *data = NULL; + int dwords = 0; + int i, result, adapt_num = -1; + ScreenPtr pScreen; + XvMCContextPtr pContext; + XvMCScreenPtr pScreenPriv; + XvMCAdaptorPtr adaptor = NULL; + XvMCSurfaceInfoPtr surface = NULL; + xvmcCreateContextReply rep; + REQUEST(xvmcCreateContextReq); + REQUEST_SIZE_MATCH(xvmcCreateContextReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + pScreen = pPort->pAdaptor->pScreen; + + if(!XvMCInUse) /* no XvMC adaptors */ + return BadMatch; + + if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */ + return BadMatch; + + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + adapt_num = i; + break; + } + } + + if(adapt_num < 0) /* none this port */ + return BadMatch; + + for(i = 0; i < adaptor->num_surfaces; i++) { + if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { + surface = adaptor->surfaces[i]; + break; + } + } + + /* adaptor doesn't support this suface_type_id */ + if(!surface) return BadMatch; + + + if((stuff->width > surface->max_width) || + (stuff->height > surface->max_height)) + return BadValue; + + if(!(pContext = malloc(sizeof(XvMCContextRec)))) { + return BadAlloc; + } + + + pContext->pScreen = pScreen; + pContext->adapt_num = adapt_num; + pContext->context_id = stuff->context_id; + pContext->surface_type_id = stuff->surface_type_id; + pContext->width = stuff->width; + pContext->height = stuff->height; + pContext->flags = stuff->flags; + pContext->refcnt = 1; + + result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data); + + if(result != Success) { + free(pContext); + return result; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.width_actual = pContext->width; + rep.height_actual = pContext->height; + rep.flags_return = pContext->flags; + rep.length = dwords; + + WriteToClient(client, sizeof(xvmcCreateContextReply), (char*)&rep); + if(dwords) + WriteToClient(client, dwords << 2, (char*)data); + AddResource(pContext->context_id, XvMCRTContext, pContext); + + free(data); + + return Success; +} + +static int +ProcXvMCDestroyContext(ClientPtr client) +{ + pointer val; + int rc; + REQUEST(xvmcDestroyContextReq); + REQUEST_SIZE_MATCH(xvmcDestroyContextReq); + + rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->context_id, RT_NONE); + + return Success; +} + +static int +ProcXvMCCreateSurface(ClientPtr client) +{ + CARD32 *data = NULL; + int dwords = 0; + int result; + XvMCContextPtr pContext; + XvMCSurfacePtr pSurface; + XvMCScreenPtr pScreenPriv; + xvmcCreateSurfaceReply rep; + REQUEST(xvmcCreateSurfaceReq); + REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq); + + result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id, + XvMCRTContext, client, DixUseAccess); + if (result != Success) + return result; + + pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + if(!(pSurface = malloc(sizeof(XvMCSurfaceRec)))) + return BadAlloc; + + pSurface->surface_id = stuff->surface_id; + pSurface->surface_type_id = pContext->surface_type_id; + pSurface->context = pContext; + + result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)( + pSurface, &dwords, &data); + + if(result != Success) { + free(pSurface); + return result; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = dwords; + + WriteToClient(client, sizeof(xvmcCreateSurfaceReply), (char*)&rep); + if(dwords) + WriteToClient(client, dwords << 2, (char*)data); + AddResource(pSurface->surface_id, XvMCRTSurface, pSurface); + + free(data); + + pContext->refcnt++; + + return Success; +} + +static int +ProcXvMCDestroySurface(ClientPtr client) +{ + pointer val; + int rc; + REQUEST(xvmcDestroySurfaceReq); + REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq); + + rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->surface_id, RT_NONE); + + return Success; +} + +static int +ProcXvMCCreateSubpicture(ClientPtr client) +{ + Bool image_supported = FALSE; + CARD32 *data = NULL; + int i, result, dwords = 0; + XvMCContextPtr pContext; + XvMCSubpicturePtr pSubpicture; + XvMCScreenPtr pScreenPriv; + xvmcCreateSubpictureReply rep; + XvMCAdaptorPtr adaptor; + XvMCSurfaceInfoPtr surface = NULL; + REQUEST(xvmcCreateSubpictureReq); + REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq); + + result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id, + XvMCRTContext, client, DixUseAccess); + if (result != Success) + return result; + + pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]); + + /* find which surface this context supports */ + for(i = 0; i < adaptor->num_surfaces; i++) { + if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){ + surface = adaptor->surfaces[i]; + break; + } + } + + if(!surface) return BadMatch; + + /* make sure this surface supports that xvimage format */ + if(!surface->compatible_subpictures) return BadMatch; + + for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) { + if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) { + image_supported = TRUE; + break; + } + } + + if(!image_supported) return BadMatch; + + /* make sure the size is OK */ + if((stuff->width > surface->subpicture_max_width) || + (stuff->height > surface->subpicture_max_height)) + return BadValue; + + if(!(pSubpicture = malloc(sizeof(XvMCSubpictureRec)))) + return BadAlloc; + + pSubpicture->subpicture_id = stuff->subpicture_id; + pSubpicture->xvimage_id = stuff->xvimage_id; + pSubpicture->width = stuff->width; + pSubpicture->height = stuff->height; + pSubpicture->num_palette_entries = 0; /* overwritten by DDX */ + pSubpicture->entry_bytes = 0; /* overwritten by DDX */ + pSubpicture->component_order[0] = 0; /* overwritten by DDX */ + pSubpicture->component_order[1] = 0; + pSubpicture->component_order[2] = 0; + pSubpicture->component_order[3] = 0; + pSubpicture->context = pContext; + + result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)( + pSubpicture, &dwords, &data); + + if(result != Success) { + free(pSubpicture); + return result; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.width_actual = pSubpicture->width; + rep.height_actual = pSubpicture->height; + rep.num_palette_entries = pSubpicture->num_palette_entries; + rep.entry_bytes = pSubpicture->entry_bytes; + rep.component_order[0] = pSubpicture->component_order[0]; + rep.component_order[1] = pSubpicture->component_order[1]; + rep.component_order[2] = pSubpicture->component_order[2]; + rep.component_order[3] = pSubpicture->component_order[3]; + rep.length = dwords; + + WriteToClient(client, sizeof(xvmcCreateSubpictureReply), (char*)&rep); + if(dwords) + WriteToClient(client, dwords << 2, (char*)data); + AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture); + + free(data); + + pContext->refcnt++; + + return Success; +} + +static int +ProcXvMCDestroySubpicture(ClientPtr client) +{ + pointer val; + int rc; + REQUEST(xvmcDestroySubpictureReq); + REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq); + + rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->subpicture_id, RT_NONE); + + return Success; +} + + +static int +ProcXvMCListSubpictureTypes(ClientPtr client) +{ + XvPortPtr pPort; + xvmcListSubpictureTypesReply rep; + XvMCScreenPtr pScreenPriv; + ScreenPtr pScreen; + XvMCAdaptorPtr adaptor = NULL; + XvMCSurfaceInfoPtr surface = NULL; + xvImageFormatInfo info; + XvImagePtr pImage; + int i, j; + REQUEST(xvmcListSubpictureTypesReq); + REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + pScreen = pPort->pAdaptor->pScreen; + + if(XvMCScreenKey == NULL) /* No XvMC adaptors */ + return BadMatch; + + if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) + return BadMatch; /* None this screen */ + + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + break; + } + } + + if(!adaptor) return BadMatch; + + for(i = 0; i < adaptor->num_surfaces; i++) { + if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { + surface = adaptor->surfaces[i]; + break; + } + } + + if(!surface) return BadMatch; + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num = 0; + if(surface->compatible_subpictures) + rep.num = surface->compatible_subpictures->num_xvimages; + + rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo)); + + WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), (char*)&rep); + + for(i = 0; i < rep.num; i++) { + pImage = NULL; + for(j = 0; j < adaptor->num_subpictures; j++) { + if(surface->compatible_subpictures->xvimage_ids[i] == + adaptor->subpictures[j]->id) + { + pImage = adaptor->subpictures[j]; + break; + } + } + if(!pImage) return BadImplementation; + + info.id = pImage->id; + info.type = pImage->type; + info.byte_order = pImage->byte_order; + memcpy(&info.guid, pImage->guid, 16); + info.bpp = pImage->bits_per_pixel; + info.num_planes = pImage->num_planes; + info.depth = pImage->depth; + info.red_mask = pImage->red_mask; + info.green_mask = pImage->green_mask; + info.blue_mask = pImage->blue_mask; + info.format = pImage->format; + info.y_sample_bits = pImage->y_sample_bits; + info.u_sample_bits = pImage->u_sample_bits; + info.v_sample_bits = pImage->v_sample_bits; + info.horz_y_period = pImage->horz_y_period; + info.horz_u_period = pImage->horz_u_period; + info.horz_v_period = pImage->horz_v_period; + info.vert_y_period = pImage->vert_y_period; + info.vert_u_period = pImage->vert_u_period; + info.vert_v_period = pImage->vert_v_period; + memcpy(&info.comp_order, pImage->component_order, 32); + info.scanline_order = pImage->scanline_order; + WriteToClient(client, sizeof(xvImageFormatInfo), (char*)&info); + } + + return Success; +} + +static int +ProcXvMCGetDRInfo(ClientPtr client) +{ + xvmcGetDRInfoReply rep; + XvPortPtr pPort; + ScreenPtr pScreen; + XvMCScreenPtr pScreenPriv; + +#ifdef HAS_XVMCSHM + volatile CARD32 *patternP; +#endif + + REQUEST(xvmcGetDRInfoReq); + REQUEST_SIZE_MATCH(xvmcGetDRInfoReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + pScreen = pPort->pAdaptor->pScreen; + pScreenPriv = XVMC_GET_PRIVATE(pScreen); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.major = pScreenPriv->major; + rep.minor = pScreenPriv->minor; + rep.patchLevel = pScreenPriv->patchLevel; + rep.nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1); + rep.busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1); + + rep.length = rep.nameLen + rep.busIDLen; + rep.nameLen <<=2; + rep.busIDLen <<=2; + + /* + * Read back to the client what she has put in the shared memory + * segment she prepared for us. + */ + + rep.isLocal = 1; +#ifdef HAS_XVMCSHM + patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY ); + if ( -1 != (long) patternP) { + volatile CARD32 *patternC = patternP; + int i; + CARD32 magic = stuff->magic; + + rep.isLocal = 1; + i = 1024 / sizeof(CARD32); + + while ( i-- ) { + if (*patternC++ != magic) { + rep.isLocal = 0; + break; + } + magic = ~magic; + } + shmdt( (char *)patternP ); + } +#endif /* HAS_XVMCSHM */ + + WriteToClient(client, sizeof(xvmcGetDRInfoReply), + (char*)&rep); + if (rep.length) { + WriteToClient(client, rep.nameLen, + pScreenPriv->clientDriverName); + WriteToClient(client, rep.busIDLen, + pScreenPriv->busID); + } + return Success; +} + + +int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = { + ProcXvMCQueryVersion, + ProcXvMCListSurfaceTypes, + ProcXvMCCreateContext, + ProcXvMCDestroyContext, + ProcXvMCCreateSurface, + ProcXvMCDestroySurface, + ProcXvMCCreateSubpicture, + ProcXvMCDestroySubpicture, + ProcXvMCListSubpictureTypes, + ProcXvMCGetDRInfo +}; + +static int +ProcXvMCDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if(stuff->data < xvmcNumRequest) + return (*ProcXvMCVector[stuff->data])(client); + else + return BadRequest; +} + +static int +SProcXvMCDispatch (ClientPtr client) +{ + /* We only support local */ + return BadImplementation; +} + +void +XvMCExtensionInit(void) +{ + ExtensionEntry *extEntry; + + if(XvMCScreenKey == NULL) /* nobody supports it */ + return; + + if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes, + "XvMCRTContext"))) + return; + + if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes, + "XvMCRTSurface"))) + return; + + if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes, + "XvMCRTSubpicture"))) + return; + + extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors, + ProcXvMCDispatch, SProcXvMCDispatch, + NULL, StandardMinorOpcode); + + if(!extEntry) return; + + XvMCReqCode = extEntry->base; + XvMCEventBase = extEntry->eventBase; + SetResourceTypeErrorValue(XvMCRTContext, extEntry->errorBase + XvMCBadContext); + SetResourceTypeErrorValue(XvMCRTSurface, extEntry->errorBase + XvMCBadSurface); + SetResourceTypeErrorValue(XvMCRTSubpicture, extEntry->errorBase + XvMCBadSubpicture); +} + +static Bool +XvMCCloseScreen (int i, ScreenPtr pScreen) +{ + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + + free(pScreenPriv); + + return (*pScreen->CloseScreen)(i, pScreen); +} + + +int +XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt) +{ + XvMCScreenPtr pScreenPriv; + + if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) + return BadAlloc; + + if(!(pScreenPriv = malloc(sizeof(XvMCScreenRec)))) + return BadAlloc; + + dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv); + + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = XvMCCloseScreen; + + pScreenPriv->num_adaptors = num; + pScreenPriv->adaptors = pAdapt; + pScreenPriv->clientDriverName[0] = 0; + pScreenPriv->busID[0] = 0; + pScreenPriv->major = 0; + pScreenPriv->minor = 0; + pScreenPriv->patchLevel = 0; + + XvMCInUse = TRUE; + + return Success; +} + +XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id) +{ + XvImagePtr pImage = NULL; + ScreenPtr pScreen = pPort->pAdaptor->pScreen; + XvMCScreenPtr pScreenPriv; + XvMCAdaptorPtr adaptor = NULL; + int i; + + if(XvMCScreenKey == NULL) return NULL; + + if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) + return NULL; + + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + break; + } + } + + if(!adaptor) return NULL; + + for(i = 0; i < adaptor->num_subpictures; i++) { + if(adaptor->subpictures[i]->id == id) { + pImage = adaptor->subpictures[i]; + break; + } + } + + return pImage; +} + +int +xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name, + char *busID, int major, int minor, + int patchLevel) +{ + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); + strncpy(pScreenPriv->clientDriverName, name, + DR_CLIENT_DRIVER_NAME_SIZE); + strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE); + pScreenPriv->major = major; + pScreenPriv->minor = minor; + pScreenPriv->patchLevel = patchLevel; + pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0; + pScreenPriv->busID[DR_BUSID_SIZE-1] = 0; + return Success; +} + |