diff options
Diffstat (limited to 'xorg-server/Xext')
-rw-r--r-- | xorg-server/Xext/panoramiX.c | 16 | ||||
-rw-r--r-- | xorg-server/Xext/panoramiX.h | 158 | ||||
-rw-r--r-- | xorg-server/Xext/panoramiXprocs.c | 4846 | ||||
-rw-r--r-- | xorg-server/Xext/panoramiXsrv.h | 11 | ||||
-rw-r--r-- | xorg-server/Xext/shm.c | 2652 | ||||
-rw-r--r-- | xorg-server/Xext/xvdisp.c | 3922 |
6 files changed, 5803 insertions, 5802 deletions
diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c index 391346a6b..00afe94f1 100644 --- a/xorg-server/Xext/panoramiX.c +++ b/xorg-server/Xext/panoramiX.c @@ -393,7 +393,7 @@ static void XineramaInitData(ScreenPtr pScreen) int i, w, h; RegionNull(&PanoramiXScreenRegion); - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { BoxRec TheBox; RegionRec ScreenRegion; @@ -413,7 +413,7 @@ static void XineramaInitData(ScreenPtr pScreen) PanoramiXPixWidth = screenInfo.screens[0]->x + screenInfo.screens[0]->width; PanoramiXPixHeight = screenInfo.screens[0]->y + screenInfo.screens[0]->height; - for (i = 1; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS_FORWARD_SKIP(i) { pScreen = screenInfo.screens[i]; w = pScreen->x + pScreen->width; h = pScreen->y + pScreen->height; @@ -478,7 +478,7 @@ void PanoramiXExtensionInit(int argc, char *argv[]) * run in non-PanoramiXeen mode. */ - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { pScreen = screenInfo.screens[i]; pScreenPriv = malloc(sizeof(PanoramiXScreenRec)); dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey, @@ -740,7 +740,7 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth) int j, k; Bool found = FALSE; - for (j = 1; j < PanoramiXNumScreens; j++) { + FOR_NSCREENS_FORWARD_SKIP(j) { pScreen = screenInfo.screens[j]; for (k = 0; k < pScreen->numDepths; k++) { if (pScreen->allowedDepths[k].depth == pDepth->depth) { @@ -773,7 +773,7 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual) int j, k; Bool found = FALSE; - for (j = 1; j < PanoramiXNumScreens; j++) { + FOR_NSCREENS_FORWARD_SKIP(j) { pScreen = screenInfo.screens[j]; found = FALSE; @@ -836,7 +836,7 @@ PanoramiXConsolidate(void) saver = malloc(sizeof(PanoramiXRes)); saver->type = XRT_WINDOW; - for (i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { ScreenPtr pScreen = screenInfo.screens[i]; root->info[i].id = pScreen->root->drawable.id; root->u.win.class = InputOutput; @@ -1074,7 +1074,7 @@ ProcXineramaQueryScreens(ClientPtr client) xXineramaScreenInfo scratch; int i; - for(i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { scratch.x_org = screenInfo.screens[i]->x; scratch.y_org = screenInfo.screens[i]->y; scratch.width = screenInfo.screens[i]->width; @@ -1179,7 +1179,7 @@ XineramaGetImageData( depth = (format == XYPixmap) ? 1 : pDraw->depth; - for(i = 0; i < PanoramiXNumScreens; i++) { + FOR_NSCREENS(i) { BoxRec TheBox; ScreenPtr pScreen; pDraw = pDrawables[i]; diff --git a/xorg-server/Xext/panoramiX.h b/xorg-server/Xext/panoramiX.h index 1bf6194c6..71651e558 100644 --- a/xorg-server/Xext/panoramiX.h +++ b/xorg-server/Xext/panoramiX.h @@ -1,78 +1,80 @@ -/*****************************************************************
-
-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.
-
-******************************************************************/
-
-
-/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
-
-/*
- * PanoramiX definitions
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _PANORAMIX_H_
-#define _PANORAMIX_H_
-
-#define _PANORAMIX_SERVER
-#include <X11/extensions/panoramiXproto.h>
-#undef _PANORAMIX_SERVER
-#include "gcstruct.h"
-
-
-typedef struct _PanoramiXInfo {
- XID id ;
-} PanoramiXInfo;
-
-typedef struct {
- PanoramiXInfo info[MAXSCREENS];
- RESTYPE type;
- union {
- struct {
- char visibility;
- char class;
- char root;
- } win;
- struct {
- Bool shared;
- } pix;
- struct {
- Bool root;
- } pict;
- char raw_data[4];
- } u;
-} PanoramiXRes;
-
-#define FOR_NSCREENS_FORWARD(j) for(j = 0; j < PanoramiXNumScreens; j++)
-#define FOR_NSCREENS_BACKWARD(j) for(j = PanoramiXNumScreens - 1; j >= 0; j--)
-#define FOR_NSCREENS(j) FOR_NSCREENS_FORWARD(j)
-
-#define IS_SHARED_PIXMAP(r) (((r)->type == XRT_PIXMAP) && (r)->u.pix.shared)
-
-#endif /* _PANORAMIX_H_ */
+/***************************************************************** + +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. + +******************************************************************/ + + +/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */ + +/* + * PanoramiX definitions + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _PANORAMIX_H_ +#define _PANORAMIX_H_ + +#define _PANORAMIX_SERVER +#include <X11/extensions/panoramiXproto.h> +#undef _PANORAMIX_SERVER +#include "gcstruct.h" +#include "dixstruct.h" + +typedef struct _PanoramiXInfo { + XID id ; +} PanoramiXInfo; + +typedef struct { + PanoramiXInfo info[MAXSCREENS]; + RESTYPE type; + union { + struct { + char visibility; + char class; + char root; + } win; + struct { + Bool shared; + } pix; + struct { + Bool root; + } pict; + char raw_data[4]; + } u; +} PanoramiXRes; + +#define FOR_NSCREENS_FORWARD(j) for(j = 0; j < PanoramiXNumScreens; j++) +#define FOR_NSCREENS_FORWARD_SKIP(j) for(j = 1; j < PanoramiXNumScreens; j++) +#define FOR_NSCREENS_BACKWARD(j) for(j = PanoramiXNumScreens - 1; j >= 0; j--) +#define FOR_NSCREENS(j) FOR_NSCREENS_FORWARD(j) + +#define IS_SHARED_PIXMAP(r) (((r)->type == XRT_PIXMAP) && (r)->u.pix.shared) + +#define IS_ROOT_DRAWABLE(d) (((d)->type == XRT_WINDOW) && (d)->u.win.root) +#endif /* _PANORAMIX_H_ */ diff --git a/xorg-server/Xext/panoramiXprocs.c b/xorg-server/Xext/panoramiXprocs.c index 615246bab..9ea461173 100644 --- a/xorg-server/Xext/panoramiXprocs.c +++ b/xorg-server/Xext/panoramiXprocs.c @@ -1,2428 +1,2418 @@ -/*****************************************************************
-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.
-******************************************************************/
-
-/* Massively rewritten by Mark Vojkovich <markv@valinux.com> */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "windowstr.h"
-#include "dixfontstr.h"
-#include "gcstruct.h"
-#include "colormapst.h"
-#include "scrnintstr.h"
-#include "opaque.h"
-#include "inputstr.h"
-#include "migc.h"
-#include "misc.h"
-#include "dixstruct.h"
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#include "resource.h"
-#include "panoramiXh.h"
-
-#define XINERAMA_IMAGE_BUFSIZE (256*1024)
-#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
- CWDontPropagate | CWOverrideRedirect | CWCursor )
-
-int PanoramiXCreateWindow(ClientPtr client)
-{
- PanoramiXRes *parent, *newWin;
- PanoramiXRes *backPix = NULL;
- PanoramiXRes *bordPix = NULL;
- PanoramiXRes *cmap = NULL;
- REQUEST(xCreateWindowReq);
- int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
- int result, len, j;
- int orig_x, orig_y;
- XID orig_visual, tmp;
- Bool parentIsRoot;
-
- REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- result = dixLookupResourceByType((pointer *)&parent, stuff->parent,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- if(stuff->class == CopyFromParent)
- stuff->class = parent->u.win.class;
-
- if((stuff->class == InputOnly) && (stuff->mask & (~INPUTONLY_LEGAL_MASK)))
- return BadMatch;
-
- if ((Mask)stuff->mask & CWBackPixmap) {
- pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pback_offset);
- if ((tmp != None) && (tmp != ParentRelative)) {
- result = dixLookupResourceByType((pointer *)&backPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & CWBorderPixmap) {
- pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pbord_offset);
- if (tmp != CopyFromParent) {
- result = dixLookupResourceByType((pointer *)&bordPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & CWColormap) {
- cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
- tmp = *((CARD32 *) &stuff[1] + cmap_offset);
- if ((tmp != CopyFromParent) && (tmp != None)) {
- result = dixLookupResourceByType((pointer *)&cmap, tmp,
- XRT_COLORMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- if(!(newWin = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newWin->type = XRT_WINDOW;
- newWin->u.win.visibility = VisibilityNotViewable;
- newWin->u.win.class = stuff->class;
- newWin->u.win.root = FALSE;
- newWin->info[0].id = stuff->wid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newWin->info[j].id = FakeClientID(client->index);
-
- if (stuff->class == InputOnly)
- stuff->visual = CopyFromParent;
- orig_visual = stuff->visual;
- orig_x = stuff->x;
- orig_y = stuff->y;
- parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
- (stuff->parent == screenInfo.screens[0]->screensaver.wid);
- FOR_NSCREENS_BACKWARD(j) {
- stuff->wid = newWin->info[j].id;
- stuff->parent = parent->info[j].id;
- if (parentIsRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- if (backPix)
- *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
- if (bordPix)
- *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
- if (cmap)
- *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
- if ( orig_visual != CopyFromParent )
- stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
- result = (*SavedProcVector[X_CreateWindow])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
- else
- free(newWin);
-
- return result;
-}
-
-
-int PanoramiXChangeWindowAttributes(ClientPtr client)
-{
- PanoramiXRes *win;
- PanoramiXRes *backPix = NULL;
- PanoramiXRes *bordPix = NULL;
- PanoramiXRes *cmap = NULL;
- REQUEST(xChangeWindowAttributesReq);
- int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
- int result, len, j;
- XID tmp;
-
- REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
- if (Ones(stuff->valueMask) != len)
- return BadLength;
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- if((win->u.win.class == InputOnly) &&
- (stuff->valueMask & (~INPUTONLY_LEGAL_MASK)))
- return BadMatch;
-
- if ((Mask)stuff->valueMask & CWBackPixmap) {
- pback_offset = Ones((Mask)stuff->valueMask & (CWBackPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pback_offset);
- if ((tmp != None) && (tmp != ParentRelative)) {
- result = dixLookupResourceByType((pointer *)&backPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->valueMask & CWBorderPixmap) {
- pbord_offset = Ones((Mask)stuff->valueMask & (CWBorderPixmap - 1));
- tmp = *((CARD32 *) &stuff[1] + pbord_offset);
- if (tmp != CopyFromParent) {
- result = dixLookupResourceByType((pointer *)&bordPix, tmp,
- XRT_PIXMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->valueMask & CWColormap) {
- cmap_offset = Ones((Mask)stuff->valueMask & (CWColormap - 1));
- tmp = *((CARD32 *) &stuff[1] + cmap_offset);
- if ((tmp != CopyFromParent) && (tmp != None)) {
- result = dixLookupResourceByType((pointer *)&cmap, tmp,
- XRT_COLORMAP, client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- if (backPix)
- *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
- if (bordPix)
- *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
- if (cmap)
- *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
- result = (*SavedProcVector[X_ChangeWindowAttributes])(client);
- }
-
- return result;
-}
-
-
-int PanoramiXDestroyWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_DestroyWindow])(client);
- if(result != Success) break;
- }
-
- /* Since ProcDestroyWindow is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXDestroySubwindows(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_DestroySubwindows])(client);
- if(result != Success) break;
- }
-
- /* DestroySubwindows is using FreeResource which will free
- our resources for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXChangeSaveSet(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xChangeSaveSetReq);
-
- REQUEST_SIZE_MATCH(xChangeSaveSetReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- result = (*SavedProcVector[X_ChangeSaveSet])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXReparentWindow(ClientPtr client)
-{
- PanoramiXRes *win, *parent;
- int result, j;
- int x, y;
- Bool parentIsRoot;
- REQUEST(xReparentWindowReq);
-
- REQUEST_SIZE_MATCH(xReparentWindowReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&parent, stuff->parent,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- x = stuff->x;
- y = stuff->y;
- parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
- (stuff->parent == screenInfo.screens[0]->screensaver.wid);
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- stuff->parent = parent->info[j].id;
- if(parentIsRoot) {
- stuff->x = x - screenInfo.screens[j]->x;
- stuff->y = y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ReparentWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXMapWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_MapWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXMapSubwindows(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_MapSubwindows])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXUnmapWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_UnmapWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXUnmapSubwindows(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->id,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->id = win->info[j].id;
- result = (*SavedProcVector[X_UnmapSubwindows])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXConfigureWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- PanoramiXRes *sib = NULL;
- WindowPtr pWin;
- int result, j, len, sib_offset = 0, x = 0, y = 0;
- int x_offset = -1;
- int y_offset = -1;
- REQUEST(xConfigureWindowReq);
-
- REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- /* because we need the parent */
- result = dixLookupResourceByType((pointer *)&pWin, stuff->window,
- RT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- if ((Mask)stuff->mask & CWSibling) {
- XID tmp;
- sib_offset = Ones((Mask)stuff->mask & (CWSibling - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) {
- result = dixLookupResourceByType((pointer *)&sib, tmp, XRT_WINDOW,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) ||
- (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid)))
- {
- if ((Mask)stuff->mask & CWX) {
- x_offset = 0;
- x = *((CARD32 *)&stuff[1]);
- }
- if ((Mask)stuff->mask & CWY) {
- y_offset = (x_offset == -1) ? 0 : 1;
- y = *((CARD32 *) &stuff[1] + y_offset);
- }
- }
-
- /* have to go forward or you get expose events before
- ConfigureNotify events */
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- if(sib)
- *((CARD32 *) &stuff[1] + sib_offset) = sib->info[j].id;
- if(x_offset >= 0)
- *((CARD32 *) &stuff[1] + x_offset) = x - screenInfo.screens[j]->x;
- if(y_offset >= 0)
- *((CARD32 *) &stuff[1] + y_offset) = y - screenInfo.screens[j]->y;
- result = (*SavedProcVector[X_ConfigureWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXCirculateWindow(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j;
- REQUEST(xCirculateWindowReq);
-
- REQUEST_SIZE_MATCH(xCirculateWindowReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->window = win->info[j].id;
- result = (*SavedProcVector[X_CirculateWindow])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXGetGeometry(ClientPtr client)
-{
- xGetGeometryReply rep;
- DrawablePtr pDraw;
- int rc;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.root = screenInfo.screens[0]->root->drawable.id;
- rep.depth = pDraw->depth;
- rep.width = pDraw->width;
- rep.height = pDraw->height;
- rep.x = rep.y = rep.borderWidth = 0;
-
- if (stuff->id == rep.root) {
- xWindowRoot *root = (xWindowRoot *)
- (ConnectionInfo + connBlockScreenStart);
-
- rep.width = root->pixWidth;
- rep.height = root->pixHeight;
- } else
- if (WindowDrawable(pDraw->type))
- {
- WindowPtr pWin = (WindowPtr)pDraw;
- rep.x = pWin->origin.x - wBorderWidth (pWin);
- rep.y = pWin->origin.y - wBorderWidth (pWin);
- if((pWin->parent == screenInfo.screens[0]->root) ||
- (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid))
- {
- rep.x += screenInfo.screens[0]->x;
- rep.y += screenInfo.screens[0]->y;
- }
- rep.borderWidth = pWin->borderWidth;
- }
-
- WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
- return Success;
-}
-
-int PanoramiXTranslateCoords(ClientPtr client)
-{
- INT16 x, y;
- REQUEST(xTranslateCoordsReq);
- int rc;
- WindowPtr pWin, pDst;
- xTranslateCoordsReply rep;
-
- REQUEST_SIZE_MATCH(xTranslateCoordsReq);
- rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess);
- if (rc != Success)
- return rc;
- rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess);
- if (rc != Success)
- return rc;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.sameScreen = xTrue;
- rep.child = None;
-
- if((pWin == screenInfo.screens[0]->root) ||
- (pWin->drawable.id == screenInfo.screens[0]->screensaver.wid))
- {
- x = stuff->srcX - screenInfo.screens[0]->x;
- y = stuff->srcY - screenInfo.screens[0]->y;
- } else {
- x = pWin->drawable.x + stuff->srcX;
- y = pWin->drawable.y + stuff->srcY;
- }
- pWin = pDst->firstChild;
- while (pWin) {
- BoxRec box;
- if ((pWin->mapped) &&
- (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
- (x < pWin->drawable.x + (int)pWin->drawable.width +
- wBorderWidth (pWin)) &&
- (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
- (y < pWin->drawable.y + (int)pWin->drawable.height +
- wBorderWidth (pWin))
- /* When a window is shaped, a further check
- * is made to see if the point is inside
- * borderSize
- */
- && (!wBoundingShape(pWin) ||
- RegionContainsPoint(wBoundingShape(pWin),
- x - pWin->drawable.x,
- y - pWin->drawable.y, &box))
- )
- {
- rep.child = pWin->drawable.id;
- pWin = (WindowPtr) NULL;
- }
- else
- pWin = pWin->nextSib;
- }
- rep.dstX = x - pDst->drawable.x;
- rep.dstY = y - pDst->drawable.y;
- if((pDst == screenInfo.screens[0]->root) ||
- (pDst->drawable.id == screenInfo.screens[0]->screensaver.wid))
- {
- rep.dstX += screenInfo.screens[0]->x;
- rep.dstY += screenInfo.screens[0]->y;
- }
-
- WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
- return Success;
-}
-
-int PanoramiXCreatePixmap(ClientPtr client)
-{
- PanoramiXRes *refDraw, *newPix;
- int result, j;
- REQUEST(xCreatePixmapReq);
-
- REQUEST_SIZE_MATCH(xCreatePixmapReq);
- client->errorValue = stuff->pid;
-
- result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(!(newPix = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPix->type = XRT_PIXMAP;
- newPix->u.pix.shared = FALSE;
- newPix->info[0].id = stuff->pid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newPix->info[j].id = FakeClientID(client->index);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPix->info[j].id;
- stuff->drawable = refDraw->info[j].id;
- result = (*SavedProcVector[X_CreatePixmap])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPix->info[0].id, XRT_PIXMAP, newPix);
- else
- free(newPix);
-
- return result;
-}
-
-
-int PanoramiXFreePixmap(ClientPtr client)
-{
- PanoramiXRes *pix;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&pix, stuff->id, XRT_PIXMAP,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = pix->info[j].id;
- result = (*SavedProcVector[X_FreePixmap])(client);
- if(result != Success) break;
- }
-
- /* Since ProcFreePixmap is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXCreateGC(ClientPtr client)
-{
- PanoramiXRes *refDraw;
- PanoramiXRes *newGC;
- PanoramiXRes *stip = NULL;
- PanoramiXRes *tile = NULL;
- PanoramiXRes *clip = NULL;
- REQUEST(xCreateGCReq);
- int tile_offset = 0, stip_offset = 0, clip_offset = 0;
- int result, len, j;
- XID tmp;
-
- REQUEST_AT_LEAST_SIZE(xCreateGCReq);
-
- client->errorValue = stuff->gc;
- len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if ((Mask)stuff->mask & GCTile) {
- tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
- result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCStipple) {
- stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
- result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCClipMask) {
- clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
- result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
- if(!(newGC = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newGC->type = XRT_GC;
- newGC->info[0].id = stuff->gc;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newGC->info[j].id = FakeClientID(client->index);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = newGC->info[j].id;
- stuff->drawable = refDraw->info[j].id;
- if (tile)
- *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
- if (stip)
- *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
- if (clip)
- *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
- result = (*SavedProcVector[X_CreateGC])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newGC->info[0].id, XRT_GC, newGC);
- else
- free(newGC);
-
- return result;
-}
-
-int PanoramiXChangeGC(ClientPtr client)
-{
- PanoramiXRes *gc;
- PanoramiXRes *stip = NULL;
- PanoramiXRes *tile = NULL;
- PanoramiXRes *clip = NULL;
- REQUEST(xChangeGCReq);
- int tile_offset = 0, stip_offset = 0, clip_offset = 0;
- int result, len, j;
- XID tmp;
-
- REQUEST_AT_LEAST_SIZE(xChangeGCReq);
-
- len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- if ((Mask)stuff->mask & GCTile) {
- tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
- result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCStipple) {
- stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
- result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
- if ((Mask)stuff->mask & GCClipMask) {
- clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
- if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
- result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
- }
- }
-
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- if (tile)
- *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
- if (stip)
- *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
- if (clip)
- *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
- result = (*SavedProcVector[X_ChangeGC])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXCopyGC(ClientPtr client)
-{
- PanoramiXRes *srcGC, *dstGC;
- int result, j;
- REQUEST(xCopyGCReq);
-
- REQUEST_SIZE_MATCH(xCopyGCReq);
-
- result = dixLookupResourceByType((pointer *)&srcGC, stuff->srcGC, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&dstGC, stuff->dstGC, XRT_GC,
- client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS(j) {
- stuff->srcGC = srcGC->info[j].id;
- stuff->dstGC = dstGC->info[j].id;
- result = (*SavedProcVector[X_CopyGC])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXSetDashes(ClientPtr client)
-{
- PanoramiXRes *gc;
- int result, j;
- REQUEST(xSetDashesReq);
-
- REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- result = (*SavedProcVector[X_SetDashes])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXSetClipRectangles(ClientPtr client)
-{
- PanoramiXRes *gc;
- int result, j;
- REQUEST(xSetClipRectanglesReq);
-
- REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- result = (*SavedProcVector[X_SetClipRectangles])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-int PanoramiXFreeGC(ClientPtr client)
-{
- PanoramiXRes *gc;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->id, XRT_GC,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = gc->info[j].id;
- result = (*SavedProcVector[X_FreeGC])(client);
- if(result != Success) break;
- }
-
- /* Since ProcFreeGC is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int PanoramiXClearToBackground(ClientPtr client)
-{
- PanoramiXRes *win;
- int result, j, x, y;
- Bool isRoot;
- REQUEST(xClearAreaReq);
-
- REQUEST_SIZE_MATCH(xClearAreaReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- x = stuff->x;
- y = stuff->y;
- isRoot = win->u.win.root;
- FOR_NSCREENS_BACKWARD(j) {
- stuff->window = win->info[j].id;
- if(isRoot) {
- stuff->x = x - screenInfo.screens[j]->x;
- stuff->y = y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ClearArea])(client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-
-/*
- For Window to Pixmap copies you're screwed since each screen's
- pixmap will look like what it sees on its screen. Unless the
- screens overlap and the window lies on each, the two copies
- will be out of sync. To remedy this we do a GetImage and PutImage
- in place of the copy. Doing this as a single Image isn't quite
- correct since it will include the obscured areas but we will
- have to fix this later. (MArk).
-*/
-
-int PanoramiXCopyArea(ClientPtr client)
-{
- int j, result, srcx, srcy, dstx, dsty;
- PanoramiXRes *gc, *src, *dst;
- Bool srcIsRoot = FALSE;
- Bool dstIsRoot = FALSE;
- Bool srcShared, dstShared;
- REQUEST(xCopyAreaReq);
-
- REQUEST_SIZE_MATCH(xCopyAreaReq);
-
- result = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- srcShared = IS_SHARED_PIXMAP(src);
-
- result = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- dstShared = IS_SHARED_PIXMAP(dst);
-
- if(dstShared && srcShared)
- return (* SavedProcVector[X_CopyArea])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- if((dst->type == XRT_WINDOW) && dst->u.win.root)
- dstIsRoot = TRUE;
- if((src->type == XRT_WINDOW) && src->u.win.root)
- srcIsRoot = TRUE;
-
- srcx = stuff->srcX; srcy = stuff->srcY;
- dstx = stuff->dstX; dsty = stuff->dstY;
- if((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
- DrawablePtr drawables[MAXSCREENS];
- DrawablePtr pDst;
- GCPtr pGC;
- char *data;
- int pitch, rc;
-
- FOR_NSCREENS(j) {
- rc = dixLookupDrawable(drawables+j, src->info[j].id, client, 0,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- }
-
- pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
- if(!(data = calloc(1, stuff->height * pitch)))
- return BadAlloc;
-
- XineramaGetImageData(drawables, srcx, srcy,
- stuff->width, stuff->height, ZPixmap, ~0, data, pitch,
- srcIsRoot);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->gc = gc->info[j].id;
- VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess);
- if(drawables[0]->depth != pDst->depth) {
- client->errorValue = stuff->dstDrawable;
- free(data);
- return BadMatch;
- }
-
- (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
- stuff->width, stuff->height,
- 0, ZPixmap, data);
-
- if(dstShared) break;
- }
-
- free(data);
- } else {
- DrawablePtr pDst = NULL, pSrc = NULL;
- GCPtr pGC = NULL;
- RegionRec totalReg;
- int rc;
-
- RegionNull(&totalReg);
- FOR_NSCREENS_BACKWARD(j) {
- RegionPtr pRgn;
- stuff->dstDrawable = dst->info[j].id;
- stuff->srcDrawable = src->info[j].id;
- stuff->gc = gc->info[j].id;
- if (srcIsRoot) {
- stuff->srcX = srcx - screenInfo.screens[j]->x;
- stuff->srcY = srcy - screenInfo.screens[j]->y;
- }
- if (dstIsRoot) {
- stuff->dstX = dstx - screenInfo.screens[j]->x;
- stuff->dstY = dsty - screenInfo.screens[j]->y;
- }
-
- VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
-
- if (stuff->dstDrawable != stuff->srcDrawable) {
- rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if ((pDst->pScreen != pSrc->pScreen) ||
- (pDst->depth != pSrc->depth)) {
- client->errorValue = stuff->dstDrawable;
- return BadMatch;
- }
- } else
- pSrc = pDst;
-
- pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
- stuff->srcX, stuff->srcY,
- stuff->width, stuff->height,
- stuff->dstX, stuff->dstY);
- if(pGC->graphicsExposures && pRgn) {
- if(srcIsRoot) {
- RegionTranslate(pRgn,
- screenInfo.screens[j]->x, screenInfo.screens[j]->y);
- }
- RegionAppend(&totalReg, pRgn);
- RegionDestroy(pRgn);
- }
-
- if(dstShared)
- break;
- }
-
- if(pGC->graphicsExposures) {
- Bool overlap;
- RegionValidate(&totalReg, &overlap);
- (*pDst->pScreen->SendGraphicsExpose)(
- client, &totalReg, stuff->dstDrawable, X_CopyArea, 0);
- RegionUninit(&totalReg);
- }
- }
-
- return Success;
-}
-
-
-int PanoramiXCopyPlane(ClientPtr client)
-{
- int j, srcx, srcy, dstx, dsty, rc;
- PanoramiXRes *gc, *src, *dst;
- Bool srcIsRoot = FALSE;
- Bool dstIsRoot = FALSE;
- Bool srcShared, dstShared;
- DrawablePtr psrcDraw, pdstDraw = NULL;
- GCPtr pGC = NULL;
- RegionRec totalReg;
- REQUEST(xCopyPlaneReq);
-
- REQUEST_SIZE_MATCH(xCopyPlaneReq);
-
- rc = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable,
- XRC_DRAWABLE, client, DixReadAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- srcShared = IS_SHARED_PIXMAP(src);
-
- rc = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- dstShared = IS_SHARED_PIXMAP(dst);
-
- if(dstShared && srcShared)
- return (* SavedProcVector[X_CopyPlane])(client);
-
- rc = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (rc != Success)
- return rc;
-
- if((dst->type == XRT_WINDOW) && dst->u.win.root)
- dstIsRoot = TRUE;
- if((src->type == XRT_WINDOW) && src->u.win.root)
- srcIsRoot = TRUE;
-
- srcx = stuff->srcX; srcy = stuff->srcY;
- dstx = stuff->dstX; dsty = stuff->dstY;
-
- RegionNull(&totalReg);
- FOR_NSCREENS_BACKWARD(j) {
- RegionPtr pRgn;
- stuff->dstDrawable = dst->info[j].id;
- stuff->srcDrawable = src->info[j].id;
- stuff->gc = gc->info[j].id;
- if (srcIsRoot) {
- stuff->srcX = srcx - screenInfo.screens[j]->x;
- stuff->srcY = srcy - screenInfo.screens[j]->y;
- }
- if (dstIsRoot) {
- stuff->dstX = dstx - screenInfo.screens[j]->x;
- stuff->dstY = dsty - screenInfo.screens[j]->y;
- }
-
- VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
- if (stuff->dstDrawable != stuff->srcDrawable) {
- rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (pdstDraw->pScreen != psrcDraw->pScreen) {
- client->errorValue = stuff->dstDrawable;
- return BadMatch;
- }
- } else
- psrcDraw = pdstDraw;
-
- if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
- (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
- client->errorValue = stuff->bitPlane;
- return BadValue;
- }
-
- pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC,
- stuff->srcX, stuff->srcY,
- stuff->width, stuff->height,
- stuff->dstX, stuff->dstY, stuff->bitPlane);
- if(pGC->graphicsExposures && pRgn) {
- RegionAppend(&totalReg, pRgn);
- RegionDestroy(pRgn);
- }
-
- if(dstShared)
- break;
- }
-
- if(pGC->graphicsExposures) {
- Bool overlap;
- RegionValidate(&totalReg, &overlap);
- (*pdstDraw->pScreen->SendGraphicsExpose)(
- client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0);
- RegionUninit(&totalReg);
- }
-
- return Success;
-}
-
-
-int PanoramiXPolyPoint(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- int result, npoint, j;
- xPoint *origPts;
- Bool isRoot;
- REQUEST(xPolyPointReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyPointReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyPoint])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
- npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
- if (npoint > 0) {
- origPts = malloc(npoint * sizeof(xPoint));
- memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xPoint *pnts = (xPoint*)&stuff[1];
- int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint;
-
- while(i--) {
- pnts->x -= x_off;
- pnts->y -= y_off;
- pnts++;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyPoint])(client);
- if(result != Success) break;
- }
- free(origPts);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyLine(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- int result, npoint, j;
- xPoint *origPts;
- Bool isRoot;
- REQUEST(xPolyLineReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyLineReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyLine])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
- npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
- if (npoint > 0){
- origPts = malloc(npoint * sizeof(xPoint));
- memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xPoint *pnts = (xPoint*)&stuff[1];
- int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint;
-
- while(i--) {
- pnts->x -= x_off;
- pnts->y -= y_off;
- pnts++;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyLine])(client);
- if(result != Success) break;
- }
- free(origPts);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolySegment(ClientPtr client)
-{
- int result, nsegs, i, j;
- PanoramiXRes *gc, *draw;
- xSegment *origSegs;
- Bool isRoot;
- REQUEST(xPolySegmentReq);
-
- REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolySegment])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
- if(nsegs & 4) return BadLength;
- nsegs >>= 3;
- if (nsegs > 0) {
- origSegs = malloc(nsegs * sizeof(xSegment));
- memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xSegment *segs = (xSegment*)&stuff[1];
-
- for (i = nsegs; i--; segs++) {
- segs->x1 -= x_off;
- segs->x2 -= x_off;
- segs->y1 -= y_off;
- segs->y2 -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolySegment])(client);
- if(result != Success) break;
- }
- free(origSegs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyRectangle(ClientPtr client)
-{
- int result, nrects, i, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- xRectangle *origRecs;
- REQUEST(xPolyRectangleReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyRectangle])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
- if(nrects & 4) return BadLength;
- nrects >>= 3;
- if (nrects > 0){
- origRecs = malloc(nrects * sizeof(xRectangle));
- memcpy((char *)origRecs,(char *)&stuff[1],nrects * sizeof(xRectangle));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
-
- if(x_off || y_off) {
- xRectangle *rects = (xRectangle *) &stuff[1];
-
- for (i = nrects; i--; rects++) {
- rects->x -= x_off;
- rects->y -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyRectangle])(client);
- if(result != Success) break;
- }
- free(origRecs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyArc(ClientPtr client)
-{
- int result, narcs, i, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- xArc *origArcs;
- REQUEST(xPolyArcReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyArcReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyArc])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
- if(narcs % sizeof(xArc)) return BadLength;
- narcs /= sizeof(xArc);
- if (narcs > 0){
- origArcs = malloc(narcs * sizeof(xArc));
- memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xArc *arcs = (xArc *) &stuff[1];
-
- for (i = narcs; i--; arcs++) {
- arcs->x -= x_off;
- arcs->y -= y_off;
- }
- }
- }
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyArc])(client);
- if(result != Success) break;
- }
- free(origArcs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXFillPoly(ClientPtr client)
-{
- int result, count, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- DDXPointPtr locPts;
- REQUEST(xFillPolyReq);
-
- REQUEST_AT_LEAST_SIZE(xFillPolyReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_FillPoly])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
- if (count > 0){
- locPts = malloc(count * sizeof(DDXPointRec));
- memcpy((char *)locPts, (char *)&stuff[1], count * sizeof(DDXPointRec));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- DDXPointPtr pnts = (DDXPointPtr)&stuff[1];
- int i = (stuff->coordMode==CoordModePrevious) ? 1 : count;
-
- while(i--) {
- pnts->x -= x_off;
- pnts->y -= y_off;
- pnts++;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_FillPoly])(client);
- if(result != Success) break;
- }
- free(locPts);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyFillRectangle(ClientPtr client)
-{
- int result, things, i, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- xRectangle *origRects;
- REQUEST(xPolyFillRectangleReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyFillRectangle])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
- if(things & 4) return BadLength;
- things >>= 3;
- if (things > 0){
- origRects = malloc(things * sizeof(xRectangle));
- memcpy((char*)origRects,(char*)&stuff[1], things * sizeof(xRectangle));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origRects, things * sizeof(xRectangle));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xRectangle *rects = (xRectangle *) &stuff[1];
-
- for (i = things; i--; rects++) {
- rects->x -= x_off;
- rects->y -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyFillRectangle])(client);
- if(result != Success) break;
- }
- free(origRects);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPolyFillArc(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int result, narcs, i, j;
- xArc *origArcs;
- REQUEST(xPolyFillArcReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyFillArc])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
- if (narcs % sizeof(xArc)) return BadLength;
- narcs /= sizeof(xArc);
- if (narcs > 0) {
- origArcs = malloc(narcs * sizeof(xArc));
- memcpy((char *) origArcs, (char *)&stuff[1], narcs * sizeof(xArc));
- FOR_NSCREENS_FORWARD(j){
-
- if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
-
- if (isRoot) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xArc *arcs = (xArc *) &stuff[1];
-
- for (i = narcs; i--; arcs++) {
- arcs->x -= x_off;
- arcs->y -= y_off;
- }
- }
- }
-
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PolyFillArc])(client);
- if(result != Success) break;
- }
- free(origArcs);
- return result;
- } else
- return Success;
-}
-
-
-int PanoramiXPutImage(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int j, result, orig_x, orig_y;
- REQUEST(xPutImageReq);
-
- REQUEST_AT_LEAST_SIZE(xPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PutImage])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->dstX;
- orig_y = stuff->dstY;
- FOR_NSCREENS_BACKWARD(j){
- if (isRoot) {
- stuff->dstX = orig_x - screenInfo.screens[j]->x;
- stuff->dstY = orig_y - screenInfo.screens[j]->y;
- }
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- result = (* SavedProcVector[X_PutImage])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXGetImage(ClientPtr client)
-{
- DrawablePtr drawables[MAXSCREENS];
- DrawablePtr pDraw;
- PanoramiXRes *draw;
- xGetImageReply xgi;
- Bool isRoot;
- char *pBuf;
- int i, x, y, w, h, format, rc;
- Mask plane = 0, planemask;
- int linesDone, nlines, linesPerBuf;
- long widthBytesLine, length;
-
- REQUEST(xGetImageReq);
-
- REQUEST_SIZE_MATCH(xGetImageReq);
-
- if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
- client->errorValue = stuff->format;
- return BadValue;
- }
-
- rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- if(draw->type == XRT_PIXMAP)
- return (*SavedProcVector[X_GetImage])(client);
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if(!((WindowPtr)pDraw)->realized)
- return BadMatch;
-
- x = stuff->x;
- y = stuff->y;
- w = stuff->width;
- h = stuff->height;
- format = stuff->format;
- planemask = stuff->planeMask;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- if(isRoot) {
- if( /* check for being onscreen */
- x < 0 || x + w > PanoramiXPixWidth ||
- y < 0 || y + h > PanoramiXPixHeight )
- return BadMatch;
- } else {
- if( /* check for being onscreen */
- screenInfo.screens[0]->x + pDraw->x + x < 0 ||
- screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
- screenInfo.screens[0]->y + pDraw->y + y < 0 ||
- screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
- /* check for being inside of border */
- x < - wBorderWidth((WindowPtr)pDraw) ||
- x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- y < -wBorderWidth((WindowPtr)pDraw) ||
- y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
- return BadMatch;
- }
-
- drawables[0] = pDraw;
- for(i = 1; i < PanoramiXNumScreens; i++) {
- rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
- }
-
- xgi.visual = wVisual (((WindowPtr) pDraw));
- xgi.type = X_Reply;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
- if(format == ZPixmap) {
- widthBytesLine = PixmapBytePad(w, pDraw->depth);
- length = widthBytesLine * h;
-
-
- } else {
- widthBytesLine = BitmapBytePad(w);
- plane = ((Mask)1) << (pDraw->depth - 1);
- /* only planes asked for */
- length = widthBytesLine * h *
- Ones(planemask & (plane | (plane - 1)));
-
- }
-
- xgi.length = bytes_to_int32(length);
-
- if (widthBytesLine == 0 || h == 0)
- linesPerBuf = 0;
- else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE)
- linesPerBuf = 1;
- else {
- linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine;
- if (linesPerBuf > h)
- linesPerBuf = h;
- }
- length = linesPerBuf * widthBytesLine;
- if(!(pBuf = malloc(length)))
- return BadAlloc;
-
- WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
-
- if (linesPerBuf == 0) {
- /* nothing to do */
- }
- else if (format == ZPixmap) {
- linesDone = 0;
- while (h - linesDone > 0) {
- nlines = min(linesPerBuf, h - linesDone);
-
- if(pDraw->depth == 1)
- memset(pBuf, 0, nlines * widthBytesLine);
-
- XineramaGetImageData(drawables, x, y + linesDone, w, nlines,
- format, planemask, pBuf, widthBytesLine, isRoot);
-
- (void)WriteToClient(client,
- (int)(nlines * widthBytesLine),
- pBuf);
- linesDone += nlines;
- }
- } else { /* XYPixmap */
- for (; plane; plane >>= 1) {
- if (planemask & plane) {
- linesDone = 0;
- while (h - linesDone > 0) {
- nlines = min(linesPerBuf, h - linesDone);
-
- memset(pBuf, 0, nlines * widthBytesLine);
-
- XineramaGetImageData(drawables, x, y + linesDone, w,
- nlines, format, plane, pBuf,
- widthBytesLine, isRoot);
-
- (void)WriteToClient(client,
- (int)(nlines * widthBytesLine),
- pBuf);
-
- linesDone += nlines;
- }
- }
- }
- }
- free(pBuf);
- return Success;
-}
-
-
-/* The text stuff should be rewritten so that duplication happens
- at the GlyphBlt level. That is, loading the font and getting
- the glyphs should only happen once */
-
-int
-PanoramiXPolyText8(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int result, j;
- int orig_x, orig_y;
- REQUEST(xPolyTextReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyTextReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyText8])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_PolyText8])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-int
-PanoramiXPolyText16(ClientPtr client)
-{
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int result, j;
- int orig_x, orig_y;
- REQUEST(xPolyTextReq);
-
- REQUEST_AT_LEAST_SIZE(xPolyTextReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_PolyText16])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_PolyText16])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXImageText8(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int orig_x, orig_y;
- REQUEST(xImageTextReq);
-
- REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_ImageText8])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ImageText8])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXImageText16(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *gc, *draw;
- Bool isRoot;
- int orig_x, orig_y;
- REQUEST(xImageTextReq);
-
- REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- if(IS_SHARED_PIXMAP(draw))
- return (*SavedProcVector[X_ImageText16])(client);
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->x;
- orig_y = stuff->y;
- FOR_NSCREENS_BACKWARD(j){
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->x = orig_x - screenInfo.screens[j]->x;
- stuff->y = orig_y - screenInfo.screens[j]->y;
- }
- result = (*SavedProcVector[X_ImageText16])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-
-int PanoramiXCreateColormap(ClientPtr client)
-{
- PanoramiXRes *win, *newCmap;
- int result, j, orig_visual;
- REQUEST(xCreateColormapReq);
-
- REQUEST_SIZE_MATCH(xCreateColormapReq);
-
- result = dixLookupResourceByType((pointer *)&win, stuff->window,
- XRT_WINDOW, client, DixReadAccess);
- if (result != Success)
- return result;
-
- if(!(newCmap = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newCmap->type = XRT_COLORMAP;
- newCmap->info[0].id = stuff->mid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newCmap->info[j].id = FakeClientID(client->index);
-
- orig_visual = stuff->visual;
- FOR_NSCREENS_BACKWARD(j){
- stuff->mid = newCmap->info[j].id;
- stuff->window = win->info[j].id;
- stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
- result = (* SavedProcVector[X_CreateColormap])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
- else
- free(newCmap);
-
- return result;
-}
-
-
-int PanoramiXFreeColormap(ClientPtr client)
-{
- PanoramiXRes *cmap;
- int result, j;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP,
- client, DixDestroyAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = cmap->info[j].id;
- result = (* SavedProcVector[X_FreeColormap])(client);
- if(result != Success) break;
- }
-
- /* Since ProcFreeColormap is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-
-int
-PanoramiXCopyColormapAndFree(ClientPtr client)
-{
- PanoramiXRes *cmap, *newCmap;
- int result, j;
- REQUEST(xCopyColormapAndFreeReq);
-
- REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
-
- client->errorValue = stuff->srcCmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->srcCmap,
- XRT_COLORMAP, client,
- DixReadAccess | DixWriteAccess);
- if (result != Success)
- return result;
-
- if(!(newCmap = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newCmap->type = XRT_COLORMAP;
- newCmap->info[0].id = stuff->mid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newCmap->info[j].id = FakeClientID(client->index);
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->srcCmap = cmap->info[j].id;
- stuff->mid = newCmap->info[j].id;
- result = (* SavedProcVector[X_CopyColormapAndFree])(client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
- else
- free(newCmap);
-
- return result;
-}
-
-
-int PanoramiXInstallColormap(ClientPtr client)
-{
- REQUEST(xResourceReq);
- int result, j;
- PanoramiXRes *cmap;
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->id = cmap->info[j].id;
- result = (* SavedProcVector[X_InstallColormap])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXUninstallColormap(ClientPtr client)
-{
- REQUEST(xResourceReq);
- int result, j;
- PanoramiXRes *cmap;
-
- REQUEST_SIZE_MATCH(xResourceReq);
-
- client->errorValue = stuff->id;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP,
- client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->id = cmap->info[j].id;
- result = (* SavedProcVector[X_UninstallColormap])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocColor(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocColorReq);
-
- REQUEST_SIZE_MATCH(xAllocColorReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocColor])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocNamedColor(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocNamedColorReq);
-
- REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocNamedColor])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocColorCells(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocColorCellsReq);
-
- REQUEST_SIZE_MATCH(xAllocColorCellsReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocColorCells])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXAllocColorPlanes(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xAllocColorPlanesReq);
-
- REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_AllocColorPlanes])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-
-int PanoramiXFreeColors(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xFreeColorsReq);
-
- REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_FreeColors])(client);
- }
- return result;
-}
-
-
-int PanoramiXStoreColors(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xStoreColorsReq);
-
- REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_StoreColors])(client);
- if(result != Success) break;
- }
- return result;
-}
-
-
-int PanoramiXStoreNamedColor(ClientPtr client)
-{
- int result, j;
- PanoramiXRes *cmap;
- REQUEST(xStoreNamedColorReq);
-
- REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
-
- client->errorValue = stuff->cmap;
-
- result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap,
- XRT_COLORMAP, client, DixWriteAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(j){
- stuff->cmap = cmap->info[j].id;
- result = (* SavedProcVector[X_StoreNamedColor])(client);
- if(result != Success) break;
- }
- return result;
-}
+/***************************************************************** +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. +******************************************************************/ + +/* Massively rewritten by Mark Vojkovich <markv@valinux.com> */ + + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <X11/X.h> +#include <X11/Xproto.h> +#include "windowstr.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "colormapst.h" +#include "scrnintstr.h" +#include "opaque.h" +#include "inputstr.h" +#include "migc.h" +#include "misc.h" +#include "dixstruct.h" +#include "panoramiX.h" +#include "panoramiXsrv.h" +#include "resource.h" +#include "panoramiXh.h" + +#define XINERAMA_IMAGE_BUFSIZE (256*1024) +#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ + CWDontPropagate | CWOverrideRedirect | CWCursor ) + +int PanoramiXCreateWindow(ClientPtr client) +{ + PanoramiXRes *parent, *newWin; + PanoramiXRes *backPix = NULL; + PanoramiXRes *bordPix = NULL; + PanoramiXRes *cmap = NULL; + REQUEST(xCreateWindowReq); + int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; + int result, len, j; + int orig_x, orig_y; + XID orig_visual, tmp; + Bool parentIsRoot; + + REQUEST_AT_LEAST_SIZE(xCreateWindowReq); + + len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + result = dixLookupResourceByType((pointer *)&parent, stuff->parent, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + if(stuff->class == CopyFromParent) + stuff->class = parent->u.win.class; + + if((stuff->class == InputOnly) && (stuff->mask & (~INPUTONLY_LEGAL_MASK))) + return BadMatch; + + if ((Mask)stuff->mask & CWBackPixmap) { + pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pback_offset); + if ((tmp != None) && (tmp != ParentRelative)) { + result = dixLookupResourceByType((pointer *)&backPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & CWBorderPixmap) { + pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pbord_offset); + if (tmp != CopyFromParent) { + result = dixLookupResourceByType((pointer *)&bordPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & CWColormap) { + cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); + tmp = *((CARD32 *) &stuff[1] + cmap_offset); + if ((tmp != CopyFromParent) && (tmp != None)) { + result = dixLookupResourceByType((pointer *)&cmap, tmp, + XRT_COLORMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + + if(!(newWin = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newWin->type = XRT_WINDOW; + newWin->u.win.visibility = VisibilityNotViewable; + newWin->u.win.class = stuff->class; + newWin->u.win.root = FALSE; + panoramix_setup_ids(newWin, client, stuff->wid); + + if (stuff->class == InputOnly) + stuff->visual = CopyFromParent; + orig_visual = stuff->visual; + orig_x = stuff->x; + orig_y = stuff->y; + parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) || + (stuff->parent == screenInfo.screens[0]->screensaver.wid); + FOR_NSCREENS_BACKWARD(j) { + stuff->wid = newWin->info[j].id; + stuff->parent = parent->info[j].id; + if (parentIsRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + if (backPix) + *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id; + if (bordPix) + *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id; + if (cmap) + *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id; + if ( orig_visual != CopyFromParent ) + stuff->visual = PanoramiXTranslateVisualID(j, orig_visual); + result = (*SavedProcVector[X_CreateWindow])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newWin->info[0].id, XRT_WINDOW, newWin); + else + free(newWin); + + return result; +} + + +int PanoramiXChangeWindowAttributes(ClientPtr client) +{ + PanoramiXRes *win; + PanoramiXRes *backPix = NULL; + PanoramiXRes *bordPix = NULL; + PanoramiXRes *cmap = NULL; + REQUEST(xChangeWindowAttributesReq); + int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; + int result, len, j; + XID tmp; + + REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); + + len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); + if (Ones(stuff->valueMask) != len) + return BadLength; + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + if((win->u.win.class == InputOnly) && + (stuff->valueMask & (~INPUTONLY_LEGAL_MASK))) + return BadMatch; + + if ((Mask)stuff->valueMask & CWBackPixmap) { + pback_offset = Ones((Mask)stuff->valueMask & (CWBackPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pback_offset); + if ((tmp != None) && (tmp != ParentRelative)) { + result = dixLookupResourceByType((pointer *)&backPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->valueMask & CWBorderPixmap) { + pbord_offset = Ones((Mask)stuff->valueMask & (CWBorderPixmap - 1)); + tmp = *((CARD32 *) &stuff[1] + pbord_offset); + if (tmp != CopyFromParent) { + result = dixLookupResourceByType((pointer *)&bordPix, tmp, + XRT_PIXMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->valueMask & CWColormap) { + cmap_offset = Ones((Mask)stuff->valueMask & (CWColormap - 1)); + tmp = *((CARD32 *) &stuff[1] + cmap_offset); + if ((tmp != CopyFromParent) && (tmp != None)) { + result = dixLookupResourceByType((pointer *)&cmap, tmp, + XRT_COLORMAP, client, DixReadAccess); + if (result != Success) + return result; + } + } + + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + if (backPix) + *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id; + if (bordPix) + *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id; + if (cmap) + *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id; + result = (*SavedProcVector[X_ChangeWindowAttributes])(client); + } + + return result; +} + + +int PanoramiXDestroyWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_DestroyWindow])(client); + if(result != Success) break; + } + + /* Since ProcDestroyWindow is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXDestroySubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, XRT_WINDOW, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_DestroySubwindows])(client); + if(result != Success) break; + } + + /* DestroySubwindows is using FreeResource which will free + our resources for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXChangeSaveSet(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xChangeSaveSetReq); + + REQUEST_SIZE_MATCH(xChangeSaveSetReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + result = (*SavedProcVector[X_ChangeSaveSet])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXReparentWindow(ClientPtr client) +{ + PanoramiXRes *win, *parent; + int result, j; + int x, y; + Bool parentIsRoot; + REQUEST(xReparentWindowReq); + + REQUEST_SIZE_MATCH(xReparentWindowReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&parent, stuff->parent, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + x = stuff->x; + y = stuff->y; + parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) || + (stuff->parent == screenInfo.screens[0]->screensaver.wid); + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + stuff->parent = parent->info[j].id; + if(parentIsRoot) { + stuff->x = x - screenInfo.screens[j]->x; + stuff->y = y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ReparentWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXMapWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_MapWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXMapSubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_MapSubwindows])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXUnmapWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_UnmapWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXUnmapSubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->id, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->id = win->info[j].id; + result = (*SavedProcVector[X_UnmapSubwindows])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXConfigureWindow(ClientPtr client) +{ + PanoramiXRes *win; + PanoramiXRes *sib = NULL; + WindowPtr pWin; + int result, j, len, sib_offset = 0, x = 0, y = 0; + int x_offset = -1; + int y_offset = -1; + REQUEST(xConfigureWindowReq); + + REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); + + len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + /* because we need the parent */ + result = dixLookupResourceByType((pointer *)&pWin, stuff->window, + RT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + if ((Mask)stuff->mask & CWSibling) { + XID tmp; + sib_offset = Ones((Mask)stuff->mask & (CWSibling - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) { + result = dixLookupResourceByType((pointer *)&sib, tmp, XRT_WINDOW, + client, DixReadAccess); + if (result != Success) + return result; + } + } + + if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) || + (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid))) + { + if ((Mask)stuff->mask & CWX) { + x_offset = 0; + x = *((CARD32 *)&stuff[1]); + } + if ((Mask)stuff->mask & CWY) { + y_offset = (x_offset == -1) ? 0 : 1; + y = *((CARD32 *) &stuff[1] + y_offset); + } + } + + /* have to go forward or you get expose events before + ConfigureNotify events */ + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + if(sib) + *((CARD32 *) &stuff[1] + sib_offset) = sib->info[j].id; + if(x_offset >= 0) + *((CARD32 *) &stuff[1] + x_offset) = x - screenInfo.screens[j]->x; + if(y_offset >= 0) + *((CARD32 *) &stuff[1] + y_offset) = y - screenInfo.screens[j]->y; + result = (*SavedProcVector[X_ConfigureWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXCirculateWindow(ClientPtr client) +{ + PanoramiXRes *win; + int result, j; + REQUEST(xCirculateWindowReq); + + REQUEST_SIZE_MATCH(xCirculateWindowReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + result = (*SavedProcVector[X_CirculateWindow])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXGetGeometry(ClientPtr client) +{ + xGetGeometryReply rep; + DrawablePtr pDraw; + int rc; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.root = screenInfo.screens[0]->root->drawable.id; + rep.depth = pDraw->depth; + rep.width = pDraw->width; + rep.height = pDraw->height; + rep.x = rep.y = rep.borderWidth = 0; + + if (stuff->id == rep.root) { + xWindowRoot *root = (xWindowRoot *) + (ConnectionInfo + connBlockScreenStart); + + rep.width = root->pixWidth; + rep.height = root->pixHeight; + } else + if (WindowDrawable(pDraw->type)) + { + WindowPtr pWin = (WindowPtr)pDraw; + rep.x = pWin->origin.x - wBorderWidth (pWin); + rep.y = pWin->origin.y - wBorderWidth (pWin); + if((pWin->parent == screenInfo.screens[0]->root) || + (pWin->parent->drawable.id == screenInfo.screens[0]->screensaver.wid)) + { + rep.x += screenInfo.screens[0]->x; + rep.y += screenInfo.screens[0]->y; + } + rep.borderWidth = pWin->borderWidth; + } + + WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); + return Success; +} + +int PanoramiXTranslateCoords(ClientPtr client) +{ + INT16 x, y; + REQUEST(xTranslateCoordsReq); + int rc; + WindowPtr pWin, pDst; + xTranslateCoordsReply rep; + + REQUEST_SIZE_MATCH(xTranslateCoordsReq); + rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess); + if (rc != Success) + return rc; + rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess); + if (rc != Success) + return rc; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.sameScreen = xTrue; + rep.child = None; + + if((pWin == screenInfo.screens[0]->root) || + (pWin->drawable.id == screenInfo.screens[0]->screensaver.wid)) + { + x = stuff->srcX - screenInfo.screens[0]->x; + y = stuff->srcY - screenInfo.screens[0]->y; + } else { + x = pWin->drawable.x + stuff->srcX; + y = pWin->drawable.y + stuff->srcY; + } + pWin = pDst->firstChild; + while (pWin) { + BoxRec box; + if ((pWin->mapped) && + (x >= pWin->drawable.x - wBorderWidth (pWin)) && + (x < pWin->drawable.x + (int)pWin->drawable.width + + wBorderWidth (pWin)) && + (y >= pWin->drawable.y - wBorderWidth (pWin)) && + (y < pWin->drawable.y + (int)pWin->drawable.height + + wBorderWidth (pWin)) + /* When a window is shaped, a further check + * is made to see if the point is inside + * borderSize + */ + && (!wBoundingShape(pWin) || + RegionContainsPoint(wBoundingShape(pWin), + x - pWin->drawable.x, + y - pWin->drawable.y, &box)) + ) + { + rep.child = pWin->drawable.id; + pWin = (WindowPtr) NULL; + } + else + pWin = pWin->nextSib; + } + rep.dstX = x - pDst->drawable.x; + rep.dstY = y - pDst->drawable.y; + if((pDst == screenInfo.screens[0]->root) || + (pDst->drawable.id == screenInfo.screens[0]->screensaver.wid)) + { + rep.dstX += screenInfo.screens[0]->x; + rep.dstY += screenInfo.screens[0]->y; + } + + WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); + return Success; +} + +int PanoramiXCreatePixmap(ClientPtr client) +{ + PanoramiXRes *refDraw, *newPix; + int result, j; + REQUEST(xCreatePixmapReq); + + REQUEST_SIZE_MATCH(xCreatePixmapReq); + client->errorValue = stuff->pid; + + result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, + XRC_DRAWABLE, client, DixReadAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(!(newPix = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPix->type = XRT_PIXMAP; + newPix->u.pix.shared = FALSE; + panoramix_setup_ids(newPix, client, stuff->pid); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPix->info[j].id; + stuff->drawable = refDraw->info[j].id; + result = (*SavedProcVector[X_CreatePixmap])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPix->info[0].id, XRT_PIXMAP, newPix); + else + free(newPix); + + return result; +} + + +int PanoramiXFreePixmap(ClientPtr client) +{ + PanoramiXRes *pix; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&pix, stuff->id, XRT_PIXMAP, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = pix->info[j].id; + result = (*SavedProcVector[X_FreePixmap])(client); + if(result != Success) break; + } + + /* Since ProcFreePixmap is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXCreateGC(ClientPtr client) +{ + PanoramiXRes *refDraw; + PanoramiXRes *newGC; + PanoramiXRes *stip = NULL; + PanoramiXRes *tile = NULL; + PanoramiXRes *clip = NULL; + REQUEST(xCreateGCReq); + int tile_offset = 0, stip_offset = 0, clip_offset = 0; + int result, len, j; + XID tmp; + + REQUEST_AT_LEAST_SIZE(xCreateGCReq); + + client->errorValue = stuff->gc; + len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, + XRC_DRAWABLE, client, DixReadAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if ((Mask)stuff->mask & GCTile) { + tile_offset = Ones((Mask)stuff->mask & (GCTile - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) { + result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCStipple) { + stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) { + result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCClipMask) { + clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) { + result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + + if(!(newGC = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newGC->type = XRT_GC; + panoramix_setup_ids(newGC, client, stuff->gc); + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = newGC->info[j].id; + stuff->drawable = refDraw->info[j].id; + if (tile) + *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id; + if (stip) + *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id; + if (clip) + *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id; + result = (*SavedProcVector[X_CreateGC])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newGC->info[0].id, XRT_GC, newGC); + else + free(newGC); + + return result; +} + +int PanoramiXChangeGC(ClientPtr client) +{ + PanoramiXRes *gc; + PanoramiXRes *stip = NULL; + PanoramiXRes *tile = NULL; + PanoramiXRes *clip = NULL; + REQUEST(xChangeGCReq); + int tile_offset = 0, stip_offset = 0, clip_offset = 0; + int result, len, j; + XID tmp; + + REQUEST_AT_LEAST_SIZE(xChangeGCReq); + + len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + if ((Mask)stuff->mask & GCTile) { + tile_offset = Ones((Mask)stuff->mask & (GCTile - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) { + result = dixLookupResourceByType((pointer *)&tile, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCStipple) { + stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) { + result = dixLookupResourceByType((pointer *)&stip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + if ((Mask)stuff->mask & GCClipMask) { + clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1)); + if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) { + result = dixLookupResourceByType((pointer *)&clip, tmp, XRT_PIXMAP, + client, DixReadAccess); + if (result != Success) + return result; + } + } + + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + if (tile) + *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id; + if (stip) + *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id; + if (clip) + *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id; + result = (*SavedProcVector[X_ChangeGC])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXCopyGC(ClientPtr client) +{ + PanoramiXRes *srcGC, *dstGC; + int result, j; + REQUEST(xCopyGCReq); + + REQUEST_SIZE_MATCH(xCopyGCReq); + + result = dixLookupResourceByType((pointer *)&srcGC, stuff->srcGC, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&dstGC, stuff->dstGC, XRT_GC, + client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS(j) { + stuff->srcGC = srcGC->info[j].id; + stuff->dstGC = dstGC->info[j].id; + result = (*SavedProcVector[X_CopyGC])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXSetDashes(ClientPtr client) +{ + PanoramiXRes *gc; + int result, j; + REQUEST(xSetDashesReq); + + REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + result = (*SavedProcVector[X_SetDashes])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXSetClipRectangles(ClientPtr client) +{ + PanoramiXRes *gc; + int result, j; + REQUEST(xSetClipRectanglesReq); + + REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + result = (*SavedProcVector[X_SetClipRectangles])(client); + if(result != Success) break; + } + + return result; +} + + +int PanoramiXFreeGC(ClientPtr client) +{ + PanoramiXRes *gc; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + result = dixLookupResourceByType((pointer *)&gc, stuff->id, XRT_GC, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = gc->info[j].id; + result = (*SavedProcVector[X_FreeGC])(client); + if(result != Success) break; + } + + /* Since ProcFreeGC is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int PanoramiXClearToBackground(ClientPtr client) +{ + PanoramiXRes *win; + int result, j, x, y; + Bool isRoot; + REQUEST(xClearAreaReq); + + REQUEST_SIZE_MATCH(xClearAreaReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixWriteAccess); + if (result != Success) + return result; + + x = stuff->x; + y = stuff->y; + isRoot = win->u.win.root; + FOR_NSCREENS_BACKWARD(j) { + stuff->window = win->info[j].id; + if(isRoot) { + stuff->x = x - screenInfo.screens[j]->x; + stuff->y = y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ClearArea])(client); + if(result != Success) break; + } + + return result; +} + + +/* + For Window to Pixmap copies you're screwed since each screen's + pixmap will look like what it sees on its screen. Unless the + screens overlap and the window lies on each, the two copies + will be out of sync. To remedy this we do a GetImage and PutImage + in place of the copy. Doing this as a single Image isn't quite + correct since it will include the obscured areas but we will + have to fix this later. (MArk). +*/ + +int PanoramiXCopyArea(ClientPtr client) +{ + int j, result, srcx, srcy, dstx, dsty; + PanoramiXRes *gc, *src, *dst; + Bool srcIsRoot = FALSE; + Bool dstIsRoot = FALSE; + Bool srcShared, dstShared; + REQUEST(xCopyAreaReq); + + REQUEST_SIZE_MATCH(xCopyAreaReq); + + result = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable, + XRC_DRAWABLE, client, DixReadAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + srcShared = IS_SHARED_PIXMAP(src); + + result = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + dstShared = IS_SHARED_PIXMAP(dst); + + if(dstShared && srcShared) + return (* SavedProcVector[X_CopyArea])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + if((dst->type == XRT_WINDOW) && dst->u.win.root) + dstIsRoot = TRUE; + if((src->type == XRT_WINDOW) && src->u.win.root) + srcIsRoot = TRUE; + + srcx = stuff->srcX; srcy = stuff->srcY; + dstx = stuff->dstX; dsty = stuff->dstY; + if((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) { + DrawablePtr drawables[MAXSCREENS]; + DrawablePtr pDst; + GCPtr pGC; + char *data; + int pitch, rc; + + FOR_NSCREENS(j) { + rc = dixLookupDrawable(drawables+j, src->info[j].id, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + } + + pitch = PixmapBytePad(stuff->width, drawables[0]->depth); + if(!(data = calloc(1, stuff->height * pitch))) + return BadAlloc; + + XineramaGetImageData(drawables, srcx, srcy, + stuff->width, stuff->height, ZPixmap, ~0, data, pitch, + srcIsRoot); + + FOR_NSCREENS_BACKWARD(j) { + stuff->gc = gc->info[j].id; + VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess); + if(drawables[0]->depth != pDst->depth) { + client->errorValue = stuff->dstDrawable; + free(data); + return BadMatch; + } + + (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty, + stuff->width, stuff->height, + 0, ZPixmap, data); + + if(dstShared) break; + } + + free(data); + } else { + DrawablePtr pDst = NULL, pSrc = NULL; + GCPtr pGC = NULL; + RegionRec totalReg; + int rc; + + RegionNull(&totalReg); + FOR_NSCREENS_BACKWARD(j) { + RegionPtr pRgn; + stuff->dstDrawable = dst->info[j].id; + stuff->srcDrawable = src->info[j].id; + stuff->gc = gc->info[j].id; + if (srcIsRoot) { + stuff->srcX = srcx - screenInfo.screens[j]->x; + stuff->srcY = srcy - screenInfo.screens[j]->y; + } + if (dstIsRoot) { + stuff->dstX = dstx - screenInfo.screens[j]->x; + stuff->dstY = dsty - screenInfo.screens[j]->y; + } + + VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); + + if (stuff->dstDrawable != stuff->srcDrawable) { + rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if ((pDst->pScreen != pSrc->pScreen) || + (pDst->depth != pSrc->depth)) { + client->errorValue = stuff->dstDrawable; + return BadMatch; + } + } else + pSrc = pDst; + + pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, + stuff->srcX, stuff->srcY, + stuff->width, stuff->height, + stuff->dstX, stuff->dstY); + if(pGC->graphicsExposures && pRgn) { + if(srcIsRoot) { + RegionTranslate(pRgn, + screenInfo.screens[j]->x, screenInfo.screens[j]->y); + } + RegionAppend(&totalReg, pRgn); + RegionDestroy(pRgn); + } + + if(dstShared) + break; + } + + if(pGC->graphicsExposures) { + Bool overlap; + RegionValidate(&totalReg, &overlap); + (*pDst->pScreen->SendGraphicsExpose)( + client, &totalReg, stuff->dstDrawable, X_CopyArea, 0); + RegionUninit(&totalReg); + } + } + + return Success; +} + + +int PanoramiXCopyPlane(ClientPtr client) +{ + int j, srcx, srcy, dstx, dsty, rc; + PanoramiXRes *gc, *src, *dst; + Bool srcIsRoot = FALSE; + Bool dstIsRoot = FALSE; + Bool srcShared, dstShared; + DrawablePtr psrcDraw, pdstDraw = NULL; + GCPtr pGC = NULL; + RegionRec totalReg; + REQUEST(xCopyPlaneReq); + + REQUEST_SIZE_MATCH(xCopyPlaneReq); + + rc = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable, + XRC_DRAWABLE, client, DixReadAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + srcShared = IS_SHARED_PIXMAP(src); + + rc = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + dstShared = IS_SHARED_PIXMAP(dst); + + if(dstShared && srcShared) + return (* SavedProcVector[X_CopyPlane])(client); + + rc = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (rc != Success) + return rc; + + if((dst->type == XRT_WINDOW) && dst->u.win.root) + dstIsRoot = TRUE; + if((src->type == XRT_WINDOW) && src->u.win.root) + srcIsRoot = TRUE; + + srcx = stuff->srcX; srcy = stuff->srcY; + dstx = stuff->dstX; dsty = stuff->dstY; + + RegionNull(&totalReg); + FOR_NSCREENS_BACKWARD(j) { + RegionPtr pRgn; + stuff->dstDrawable = dst->info[j].id; + stuff->srcDrawable = src->info[j].id; + stuff->gc = gc->info[j].id; + if (srcIsRoot) { + stuff->srcX = srcx - screenInfo.screens[j]->x; + stuff->srcY = srcy - screenInfo.screens[j]->y; + } + if (dstIsRoot) { + stuff->dstX = dstx - screenInfo.screens[j]->x; + stuff->dstY = dsty - screenInfo.screens[j]->y; + } + + VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); + if (stuff->dstDrawable != stuff->srcDrawable) { + rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if (pdstDraw->pScreen != psrcDraw->pScreen) { + client->errorValue = stuff->dstDrawable; + return BadMatch; + } + } else + psrcDraw = pdstDraw; + + if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || + (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) { + client->errorValue = stuff->bitPlane; + return BadValue; + } + + pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, + stuff->srcX, stuff->srcY, + stuff->width, stuff->height, + stuff->dstX, stuff->dstY, stuff->bitPlane); + if(pGC->graphicsExposures && pRgn) { + RegionAppend(&totalReg, pRgn); + RegionDestroy(pRgn); + } + + if(dstShared) + break; + } + + if(pGC->graphicsExposures) { + Bool overlap; + RegionValidate(&totalReg, &overlap); + (*pdstDraw->pScreen->SendGraphicsExpose)( + client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0); + RegionUninit(&totalReg); + } + + return Success; +} + + +int PanoramiXPolyPoint(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + int result, npoint, j; + xPoint *origPts; + Bool isRoot; + REQUEST(xPolyPointReq); + + REQUEST_AT_LEAST_SIZE(xPolyPointReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyPoint])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); + if (npoint > 0) { + origPts = malloc(npoint * sizeof(xPoint)); + memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPoint *pnts = (xPoint*)&stuff[1]; + int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint; + + while(i--) { + pnts->x -= x_off; + pnts->y -= y_off; + pnts++; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyPoint])(client); + if(result != Success) break; + } + free(origPts); + return result; + } else + return Success; +} + + +int PanoramiXPolyLine(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + int result, npoint, j; + xPoint *origPts; + Bool isRoot; + REQUEST(xPolyLineReq); + + REQUEST_AT_LEAST_SIZE(xPolyLineReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyLine])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); + if (npoint > 0){ + origPts = malloc(npoint * sizeof(xPoint)); + memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPoint *pnts = (xPoint*)&stuff[1]; + int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint; + + while(i--) { + pnts->x -= x_off; + pnts->y -= y_off; + pnts++; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyLine])(client); + if(result != Success) break; + } + free(origPts); + return result; + } else + return Success; +} + + +int PanoramiXPolySegment(ClientPtr client) +{ + int result, nsegs, i, j; + PanoramiXRes *gc, *draw; + xSegment *origSegs; + Bool isRoot; + REQUEST(xPolySegmentReq); + + REQUEST_AT_LEAST_SIZE(xPolySegmentReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolySegment])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); + if(nsegs & 4) return BadLength; + nsegs >>= 3; + if (nsegs > 0) { + origSegs = malloc(nsegs * sizeof(xSegment)); + memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xSegment *segs = (xSegment*)&stuff[1]; + + for (i = nsegs; i--; segs++) { + segs->x1 -= x_off; + segs->x2 -= x_off; + segs->y1 -= y_off; + segs->y2 -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolySegment])(client); + if(result != Success) break; + } + free(origSegs); + return result; + } else + return Success; +} + + +int PanoramiXPolyRectangle(ClientPtr client) +{ + int result, nrects, i, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + xRectangle *origRecs; + REQUEST(xPolyRectangleReq); + + REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyRectangle])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); + if(nrects & 4) return BadLength; + nrects >>= 3; + if (nrects > 0){ + origRecs = malloc(nrects * sizeof(xRectangle)); + memcpy((char *)origRecs,(char *)&stuff[1],nrects * sizeof(xRectangle)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) &stuff[1]; + + for (i = nrects; i--; rects++) { + rects->x -= x_off; + rects->y -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyRectangle])(client); + if(result != Success) break; + } + free(origRecs); + return result; + } else + return Success; +} + + +int PanoramiXPolyArc(ClientPtr client) +{ + int result, narcs, i, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + xArc *origArcs; + REQUEST(xPolyArcReq); + + REQUEST_AT_LEAST_SIZE(xPolyArcReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyArc])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + narcs = (client->req_len << 2) - sizeof(xPolyArcReq); + if(narcs % sizeof(xArc)) return BadLength; + narcs /= sizeof(xArc); + if (narcs > 0){ + origArcs = malloc(narcs * sizeof(xArc)); + memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xArc *arcs = (xArc *) &stuff[1]; + + for (i = narcs; i--; arcs++) { + arcs->x -= x_off; + arcs->y -= y_off; + } + } + } + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyArc])(client); + if(result != Success) break; + } + free(origArcs); + return result; + } else + return Success; +} + + +int PanoramiXFillPoly(ClientPtr client) +{ + int result, count, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + DDXPointPtr locPts; + REQUEST(xFillPolyReq); + + REQUEST_AT_LEAST_SIZE(xFillPolyReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_FillPoly])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); + if (count > 0){ + locPts = malloc(count * sizeof(DDXPointRec)); + memcpy((char *)locPts, (char *)&stuff[1], count * sizeof(DDXPointRec)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + DDXPointPtr pnts = (DDXPointPtr)&stuff[1]; + int i = (stuff->coordMode==CoordModePrevious) ? 1 : count; + + while(i--) { + pnts->x -= x_off; + pnts->y -= y_off; + pnts++; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_FillPoly])(client); + if(result != Success) break; + } + free(locPts); + return result; + } else + return Success; +} + + +int PanoramiXPolyFillRectangle(ClientPtr client) +{ + int result, things, i, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + xRectangle *origRects; + REQUEST(xPolyFillRectangleReq); + + REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyFillRectangle])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); + if(things & 4) return BadLength; + things >>= 3; + if (things > 0){ + origRects = malloc(things * sizeof(xRectangle)); + memcpy((char*)origRects,(char*)&stuff[1], things * sizeof(xRectangle)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origRects, things * sizeof(xRectangle)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) &stuff[1]; + + for (i = things; i--; rects++) { + rects->x -= x_off; + rects->y -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyFillRectangle])(client); + if(result != Success) break; + } + free(origRects); + return result; + } else + return Success; +} + + +int PanoramiXPolyFillArc(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int result, narcs, i, j; + xArc *origArcs; + REQUEST(xPolyFillArcReq); + + REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyFillArc])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); + if (narcs % sizeof(xArc)) return BadLength; + narcs /= sizeof(xArc); + if (narcs > 0) { + origArcs = malloc(narcs * sizeof(xArc)); + memcpy((char *) origArcs, (char *)&stuff[1], narcs * sizeof(xArc)); + FOR_NSCREENS_FORWARD(j){ + + if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc)); + + if (isRoot) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xArc *arcs = (xArc *) &stuff[1]; + + for (i = narcs; i--; arcs++) { + arcs->x -= x_off; + arcs->y -= y_off; + } + } + } + + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PolyFillArc])(client); + if(result != Success) break; + } + free(origArcs); + return result; + } else + return Success; +} + + +int PanoramiXPutImage(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int j, result, orig_x, orig_y; + REQUEST(xPutImageReq); + + REQUEST_AT_LEAST_SIZE(xPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PutImage])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->dstX; + orig_y = stuff->dstY; + FOR_NSCREENS_BACKWARD(j){ + if (isRoot) { + stuff->dstX = orig_x - screenInfo.screens[j]->x; + stuff->dstY = orig_y - screenInfo.screens[j]->y; + } + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + result = (* SavedProcVector[X_PutImage])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXGetImage(ClientPtr client) +{ + DrawablePtr drawables[MAXSCREENS]; + DrawablePtr pDraw; + PanoramiXRes *draw; + xGetImageReply xgi; + Bool isRoot; + char *pBuf; + int i, x, y, w, h, format, rc; + Mask plane = 0, planemask; + int linesDone, nlines, linesPerBuf; + long widthBytesLine, length; + + REQUEST(xGetImageReq); + + REQUEST_SIZE_MATCH(xGetImageReq); + + if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { + client->errorValue = stuff->format; + return BadValue; + } + + rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + if(draw->type == XRT_PIXMAP) + return (*SavedProcVector[X_GetImage])(client); + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if(!((WindowPtr)pDraw)->realized) + return BadMatch; + + x = stuff->x; + y = stuff->y; + w = stuff->width; + h = stuff->height; + format = stuff->format; + planemask = stuff->planeMask; + + isRoot = IS_ROOT_DRAWABLE(draw); + + if(isRoot) { + if( /* check for being onscreen */ + x < 0 || x + w > PanoramiXPixWidth || + y < 0 || y + h > PanoramiXPixHeight ) + return BadMatch; + } else { + if( /* check for being onscreen */ + screenInfo.screens[0]->x + pDraw->x + x < 0 || + screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || + screenInfo.screens[0]->y + pDraw->y + y < 0 || + screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || + /* check for being inside of border */ + x < - wBorderWidth((WindowPtr)pDraw) || + x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || + y < -wBorderWidth((WindowPtr)pDraw) || + y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) + return BadMatch; + } + + drawables[0] = pDraw; + FOR_NSCREENS_FORWARD_SKIP(i) { + rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + } + + xgi.visual = wVisual (((WindowPtr) pDraw)); + xgi.type = X_Reply; + xgi.sequenceNumber = client->sequence; + xgi.depth = pDraw->depth; + if(format == ZPixmap) { + widthBytesLine = PixmapBytePad(w, pDraw->depth); + length = widthBytesLine * h; + + + } else { + widthBytesLine = BitmapBytePad(w); + plane = ((Mask)1) << (pDraw->depth - 1); + /* only planes asked for */ + length = widthBytesLine * h * + Ones(planemask & (plane | (plane - 1))); + + } + + xgi.length = bytes_to_int32(length); + + if (widthBytesLine == 0 || h == 0) + linesPerBuf = 0; + else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE) + linesPerBuf = 1; + else { + linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine; + if (linesPerBuf > h) + linesPerBuf = h; + } + length = linesPerBuf * widthBytesLine; + if(!(pBuf = malloc(length))) + return BadAlloc; + + WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); + + if (linesPerBuf == 0) { + /* nothing to do */ + } + else if (format == ZPixmap) { + linesDone = 0; + while (h - linesDone > 0) { + nlines = min(linesPerBuf, h - linesDone); + + if(pDraw->depth == 1) + memset(pBuf, 0, nlines * widthBytesLine); + + XineramaGetImageData(drawables, x, y + linesDone, w, nlines, + format, planemask, pBuf, widthBytesLine, isRoot); + + (void)WriteToClient(client, + (int)(nlines * widthBytesLine), + pBuf); + linesDone += nlines; + } + } else { /* XYPixmap */ + for (; plane; plane >>= 1) { + if (planemask & plane) { + linesDone = 0; + while (h - linesDone > 0) { + nlines = min(linesPerBuf, h - linesDone); + + memset(pBuf, 0, nlines * widthBytesLine); + + XineramaGetImageData(drawables, x, y + linesDone, w, + nlines, format, plane, pBuf, + widthBytesLine, isRoot); + + (void)WriteToClient(client, + (int)(nlines * widthBytesLine), + pBuf); + + linesDone += nlines; + } + } + } + } + free(pBuf); + return Success; +} + + +/* The text stuff should be rewritten so that duplication happens + at the GlyphBlt level. That is, loading the font and getting + the glyphs should only happen once */ + +int +PanoramiXPolyText8(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int result, j; + int orig_x, orig_y; + REQUEST(xPolyTextReq); + + REQUEST_AT_LEAST_SIZE(xPolyTextReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyText8])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_PolyText8])(client); + if(result != Success) break; + } + return result; +} + +int +PanoramiXPolyText16(ClientPtr client) +{ + PanoramiXRes *gc, *draw; + Bool isRoot; + int result, j; + int orig_x, orig_y; + REQUEST(xPolyTextReq); + + REQUEST_AT_LEAST_SIZE(xPolyTextReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_PolyText16])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_PolyText16])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXImageText8(ClientPtr client) +{ + int result, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + int orig_x, orig_y; + REQUEST(xImageTextReq); + + REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_ImageText8])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ImageText8])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXImageText16(ClientPtr client) +{ + int result, j; + PanoramiXRes *gc, *draw; + Bool isRoot; + int orig_x, orig_y; + REQUEST(xImageTextReq); + + REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + if(IS_SHARED_PIXMAP(draw)) + return (*SavedProcVector[X_ImageText16])(client); + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC, + client, DixReadAccess); + if (result != Success) + return result; + + isRoot = IS_ROOT_DRAWABLE(draw); + + orig_x = stuff->x; + orig_y = stuff->y; + FOR_NSCREENS_BACKWARD(j){ + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->x = orig_x - screenInfo.screens[j]->x; + stuff->y = orig_y - screenInfo.screens[j]->y; + } + result = (*SavedProcVector[X_ImageText16])(client); + if(result != Success) break; + } + return result; +} + + + +int PanoramiXCreateColormap(ClientPtr client) +{ + PanoramiXRes *win, *newCmap; + int result, j, orig_visual; + REQUEST(xCreateColormapReq); + + REQUEST_SIZE_MATCH(xCreateColormapReq); + + result = dixLookupResourceByType((pointer *)&win, stuff->window, + XRT_WINDOW, client, DixReadAccess); + if (result != Success) + return result; + + if(!(newCmap = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newCmap->type = XRT_COLORMAP; + panoramix_setup_ids(newCmap, client, stuff->mid); + + orig_visual = stuff->visual; + FOR_NSCREENS_BACKWARD(j){ + stuff->mid = newCmap->info[j].id; + stuff->window = win->info[j].id; + stuff->visual = PanoramiXTranslateVisualID(j, orig_visual); + result = (* SavedProcVector[X_CreateColormap])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap); + else + free(newCmap); + + return result; +} + + +int PanoramiXFreeColormap(ClientPtr client) +{ + PanoramiXRes *cmap; + int result, j; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP, + client, DixDestroyAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = cmap->info[j].id; + result = (* SavedProcVector[X_FreeColormap])(client); + if(result != Success) break; + } + + /* Since ProcFreeColormap is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + + +int +PanoramiXCopyColormapAndFree(ClientPtr client) +{ + PanoramiXRes *cmap, *newCmap; + int result, j; + REQUEST(xCopyColormapAndFreeReq); + + REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); + + client->errorValue = stuff->srcCmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->srcCmap, + XRT_COLORMAP, client, + DixReadAccess | DixWriteAccess); + if (result != Success) + return result; + + if(!(newCmap = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newCmap->type = XRT_COLORMAP; + panoramix_setup_ids(newCmap, client, stuff->mid); + + FOR_NSCREENS_BACKWARD(j) { + stuff->srcCmap = cmap->info[j].id; + stuff->mid = newCmap->info[j].id; + result = (* SavedProcVector[X_CopyColormapAndFree])(client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap); + else + free(newCmap); + + return result; +} + + +int PanoramiXInstallColormap(ClientPtr client) +{ + REQUEST(xResourceReq); + int result, j; + PanoramiXRes *cmap; + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP, + client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->id = cmap->info[j].id; + result = (* SavedProcVector[X_InstallColormap])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXUninstallColormap(ClientPtr client) +{ + REQUEST(xResourceReq); + int result, j; + PanoramiXRes *cmap; + + REQUEST_SIZE_MATCH(xResourceReq); + + client->errorValue = stuff->id; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->id, XRT_COLORMAP, + client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->id = cmap->info[j].id; + result = (* SavedProcVector[X_UninstallColormap])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocColor(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocColorReq); + + REQUEST_SIZE_MATCH(xAllocColorReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocColor])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocNamedColor(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocNamedColorReq); + + REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocNamedColor])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocColorCells(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocColorCellsReq); + + REQUEST_SIZE_MATCH(xAllocColorCellsReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocColorCells])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXAllocColorPlanes(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xAllocColorPlanesReq); + + REQUEST_SIZE_MATCH(xAllocColorPlanesReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_AllocColorPlanes])(client); + if(result != Success) break; + } + return result; +} + + + +int PanoramiXFreeColors(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xFreeColorsReq); + + REQUEST_AT_LEAST_SIZE(xFreeColorsReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j) { + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_FreeColors])(client); + } + return result; +} + + +int PanoramiXStoreColors(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xStoreColorsReq); + + REQUEST_AT_LEAST_SIZE(xStoreColorsReq); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_StoreColors])(client); + if(result != Success) break; + } + return result; +} + + +int PanoramiXStoreNamedColor(ClientPtr client) +{ + int result, j; + PanoramiXRes *cmap; + REQUEST(xStoreNamedColorReq); + + REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); + + client->errorValue = stuff->cmap; + + result = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, + XRT_COLORMAP, client, DixWriteAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(j){ + stuff->cmap = cmap->info[j].id; + result = (* SavedProcVector[X_StoreNamedColor])(client); + if(result != Success) break; + } + return result; +} diff --git a/xorg-server/Xext/panoramiXsrv.h b/xorg-server/Xext/panoramiXsrv.h index 9751feb54..6fc903b88 100644 --- a/xorg-server/Xext/panoramiXsrv.h +++ b/xorg-server/Xext/panoramiXsrv.h @@ -51,4 +51,15 @@ extern _X_EXPORT void XineramaGetImageData( Bool isRoot ); +static inline void panoramix_setup_ids(PanoramiXRes *resource, + ClientPtr client, XID base_id) +{ + int j; + + resource->info[0].id = base_id; + FOR_NSCREENS_FORWARD_SKIP(j) { + resource->info[j].id = FakeClientID(client->index); + } +} + #endif /* _PANORAMIXSRV_H_ */ diff --git a/xorg-server/Xext/shm.c b/xorg-server/Xext/shm.c index 8a048deb0..b08af821b 100644 --- a/xorg-server/Xext/shm.c +++ b/xorg-server/Xext/shm.c @@ -1,1327 +1,1325 @@ -/************************************************************
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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 THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-********************************************************/
-
-/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
-
-
-#define SHM
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <unistd.h>
-#include <sys/stat.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 "windowstr.h"
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "extnsionst.h"
-#include "servermd.h"
-#include "shmint.h"
-#include "xace.h"
-#include <X11/extensions/shmproto.h>
-#include <X11/Xfuncproto.h>
-#include "protocol-versions.h"
-
-/* Needed for Solaris cross-zone shared memory extension */
-#ifdef HAVE_SHMCTL64
-#include <sys/ipc_impl.h>
-#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf)
-#define SHMSTAT_TYPE struct shmid_ds64
-#define SHMPERM_TYPE struct ipc_perm64
-#define SHM_PERM(buf) buf.shmx_perm
-#define SHM_SEGSZ(buf) buf.shmx_segsz
-#define SHMPERM_UID(p) p->ipcx_uid
-#define SHMPERM_CUID(p) p->ipcx_cuid
-#define SHMPERM_GID(p) p->ipcx_gid
-#define SHMPERM_CGID(p) p->ipcx_cgid
-#define SHMPERM_MODE(p) p->ipcx_mode
-#define SHMPERM_ZONEID(p) p->ipcx_zoneid
-#else
-#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf)
-#define SHMSTAT_TYPE struct shmid_ds
-#define SHMPERM_TYPE struct ipc_perm
-#define SHM_PERM(buf) buf.shm_perm
-#define SHM_SEGSZ(buf) buf.shm_segsz
-#define SHMPERM_UID(p) p->uid
-#define SHMPERM_CUID(p) p->cuid
-#define SHMPERM_GID(p) p->gid
-#define SHMPERM_CGID(p) p->cgid
-#define SHMPERM_MODE(p) p->mode
-#endif
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-#include "modinit.h"
-
-typedef struct _ShmDesc {
- struct _ShmDesc *next;
- int shmid;
- int refcnt;
- char *addr;
- Bool writable;
- unsigned long size;
-} ShmDescRec, *ShmDescPtr;
-
-typedef struct _ShmScrPrivateRec {
- CloseScreenProcPtr CloseScreen;
- ShmFuncsPtr shmFuncs;
- DestroyPixmapProcPtr destroyPixmap;
-} ShmScrPrivateRec;
-
-static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
-static int ShmDetachSegment(
- pointer /* value */,
- XID /* shmseg */
- );
-static void ShmResetProc(
- ExtensionEntry * /* extEntry */
- );
-static void SShmCompletionEvent(
- xShmCompletionEvent * /* from */,
- xShmCompletionEvent * /* to */
- );
-
-static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
-
-
-static unsigned char ShmReqCode;
-int ShmCompletionCode;
-int BadShmSegCode;
-RESTYPE ShmSegType;
-static ShmDescPtr Shmsegs;
-static Bool sharedPixmaps;
-static DevPrivateKeyRec shmScrPrivateKeyRec;
-#define shmScrPrivateKey (&shmScrPrivateKeyRec)
-static DevPrivateKeyRec shmPixmapPrivateKeyRec;
-#define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec)
-static ShmFuncs miFuncs = {NULL, NULL};
-static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL};
-
-#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey))
-
-#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
-{ \
- int rc; \
- rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \
- client, DixReadAccess); \
- if (rc != Success) \
- return rc; \
-}
-
-#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
-{ \
- VERIFY_SHMSEG(shmseg, shmdesc, client); \
- if ((offset & 3) || (offset > shmdesc->size)) \
- { \
- client->errorValue = offset; \
- return BadValue; \
- } \
- if (needwrite && !shmdesc->writable) \
- return BadAccess; \
-}
-
-#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
-{ \
- if ((offset + len) > shmdesc->size) \
- { \
- return BadAccess; \
- } \
-}
-
-
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
-#include <sys/signal.h>
-
-static Bool badSysCall = FALSE;
-
-static void
-SigSysHandler(int signo)
-{
- badSysCall = TRUE;
-}
-
-static Bool CheckForShmSyscall(void)
-{
- void (*oldHandler)();
- int shmid = -1;
-
- /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
- oldHandler = signal(SIGSYS, SigSysHandler);
-
- badSysCall = FALSE;
- shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
-
- if (shmid != -1)
- {
- /* Successful allocation - clean up */
- shmctl(shmid, IPC_RMID, NULL);
- }
- else
- {
- /* Allocation failed */
- badSysCall = TRUE;
- }
- signal(SIGSYS, oldHandler);
- return !badSysCall;
-}
-
-#define MUST_CHECK_FOR_SHM_SYSCALL
-
-#endif
-
-static Bool
-ShmCloseScreen(int i, ScreenPtr pScreen)
-{
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
- pScreen->CloseScreen = screen_priv->CloseScreen;
- dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL);
- free(screen_priv);
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static ShmScrPrivateRec *
-ShmInitScreenPriv(ScreenPtr pScreen)
-{
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
- if (!screen_priv)
- {
- screen_priv = calloc(1, sizeof (ShmScrPrivateRec));
- screen_priv->CloseScreen = pScreen->CloseScreen;
- dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv);
- pScreen->CloseScreen = ShmCloseScreen;
- }
- return screen_priv;
-}
-
-static Bool
-ShmRegisterPrivates(void)
-{
- if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
- return FALSE;
- return TRUE;
-}
-
-/*ARGSUSED*/
-static void
-ShmResetProc(ExtensionEntry *extEntry)
-{
- int i;
- for (i = 0; i < screenInfo.numScreens; i++)
- ShmRegisterFuncs(screenInfo.screens[i], NULL);
-}
-
-void
-ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
-{
- if (!ShmRegisterPrivates())
- return;
- ShmInitScreenPriv(pScreen)->shmFuncs = funcs;
-}
-
-static Bool
-ShmDestroyPixmap (PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
- Bool ret;
- if (pPixmap->refcnt == 1)
- {
- ShmDescPtr shmdesc;
- shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates,
- shmPixmapPrivateKey);
- if (shmdesc)
- ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
- }
-
- pScreen->DestroyPixmap = screen_priv->destroyPixmap;
- ret = (*pScreen->DestroyPixmap) (pPixmap);
- screen_priv->destroyPixmap = pScreen->DestroyPixmap;
- pScreen->DestroyPixmap = ShmDestroyPixmap;
- return ret;
-}
-
-void
-ShmRegisterFbFuncs(ScreenPtr pScreen)
-{
- ShmRegisterFuncs(pScreen, &fbFuncs);
-}
-
-static int
-ProcShmQueryVersion(ClientPtr client)
-{
- xShmQueryVersionReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xShmQueryVersionReq);
- memset(&rep, 0, sizeof(xShmQueryVersionReply));
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.sharedPixmaps = sharedPixmaps;
- rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0;
- rep.majorVersion = SERVER_SHM_MAJOR_VERSION;
- rep.minorVersion = SERVER_SHM_MINOR_VERSION;
- rep.uid = geteuid();
- rep.gid = getegid();
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- swaps(&rep.uid, n);
- swaps(&rep.gid, n);
- }
- WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-/*
- * Simulate the access() system call for a shared memory segement,
- * using the credentials from the client if available
- */
-static int
-shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
-{
- int uid, gid;
- mode_t mask;
- int uidset = 0, gidset = 0;
- LocalClientCredRec *lcc;
-
- if (GetLocalClientCreds(client, &lcc) != -1) {
-
- if (lcc->fieldsSet & LCC_UID_SET) {
- uid = lcc->euid;
- uidset = 1;
- }
- if (lcc->fieldsSet & LCC_GID_SET) {
- gid = lcc->egid;
- gidset = 1;
- }
-
-#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
- if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1)
- || (lcc->zoneid != SHMPERM_ZONEID(perm))) {
- uidset = 0;
- gidset = 0;
- }
-#endif
- FreeLocalClientCreds(lcc);
-
- if (uidset) {
- /* User id 0 always gets access */
- if (uid == 0) {
- return 0;
- }
- /* Check the owner */
- if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
- mask = S_IRUSR;
- if (!readonly) {
- mask |= S_IWUSR;
- }
- return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
- }
- }
-
- if (gidset) {
- /* Check the group */
- if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
- mask = S_IRGRP;
- if (!readonly) {
- mask |= S_IWGRP;
- }
- return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
- }
- }
- }
- /* Otherwise, check everyone else */
- mask = S_IROTH;
- if (!readonly) {
- mask |= S_IWOTH;
- }
- return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
-}
-
-static int
-ProcShmAttach(ClientPtr client)
-{
- SHMSTAT_TYPE buf;
- ShmDescPtr shmdesc;
- REQUEST(xShmAttachReq);
-
- REQUEST_SIZE_MATCH(xShmAttachReq);
- LEGAL_NEW_RESOURCE(stuff->shmseg, client);
- if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
- {
- client->errorValue = stuff->readOnly;
- return BadValue;
- }
- for (shmdesc = Shmsegs;
- shmdesc && (shmdesc->shmid != stuff->shmid);
- shmdesc = shmdesc->next)
- ;
- if (shmdesc)
- {
- if (!stuff->readOnly && !shmdesc->writable)
- return BadAccess;
- shmdesc->refcnt++;
- }
- else
- {
- shmdesc = malloc(sizeof(ShmDescRec));
- if (!shmdesc)
- return BadAlloc;
- shmdesc->addr = shmat(stuff->shmid, 0,
- stuff->readOnly ? SHM_RDONLY : 0);
- if ((shmdesc->addr == ((char *)-1)) ||
- SHMSTAT(stuff->shmid, &buf))
- {
- free(shmdesc);
- return BadAccess;
- }
-
- /* The attach was performed with root privs. We must
- * do manual checking of access rights for the credentials
- * of the client */
-
- if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) {
- shmdt(shmdesc->addr);
- free(shmdesc);
- return BadAccess;
- }
-
- shmdesc->shmid = stuff->shmid;
- shmdesc->refcnt = 1;
- shmdesc->writable = !stuff->readOnly;
- shmdesc->size = SHM_SEGSZ(buf);
- shmdesc->next = Shmsegs;
- Shmsegs = shmdesc;
- }
- if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
- return BadAlloc;
- return Success;
-}
-
-/*ARGSUSED*/
-static int
-ShmDetachSegment(pointer value, /* must conform to DeleteType */
- XID shmseg)
-{
- ShmDescPtr shmdesc = (ShmDescPtr)value;
- ShmDescPtr *prev;
-
- if (--shmdesc->refcnt)
- return TRUE;
- shmdt(shmdesc->addr);
- for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
- ;
- *prev = shmdesc->next;
- free(shmdesc);
- return Success;
-}
-
-static int
-ProcShmDetach(ClientPtr client)
-{
- ShmDescPtr shmdesc;
- REQUEST(xShmDetachReq);
-
- REQUEST_SIZE_MATCH(xShmDetachReq);
- VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
- FreeResource(stuff->shmseg, RT_NONE);
- return Success;
-}
-
-/*
- * If the given request doesn't exactly match PutImage's constraints,
- * wrap the image in a scratch pixmap header and let CopyArea sort it out.
- */
-static void
-doShmPutImage(DrawablePtr dst, GCPtr pGC,
- int depth, unsigned int format,
- int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
- char *data)
-{
- PixmapPtr pPixmap;
-
- if (format == ZPixmap || depth == 1) {
- pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
- BitsPerPixel(depth),
- PixmapBytePad(w, depth),
- data);
- if (!pPixmap)
- return;
- pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy);
- FreeScratchPixmapHeader(pPixmap);
- } else {
- GCPtr putGC = GetScratchGC(depth, dst->pScreen);
-
- if (!putGC)
- return;
-
- pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pPixmap) {
- FreeScratchGC(putGC);
- return;
- }
- ValidateGC(&pPixmap->drawable, putGC);
- (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0,
- (format == XYPixmap) ? XYPixmap : ZPixmap, data);
- FreeScratchGC(putGC);
- if (format == XYBitmap)
- (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
- dx, dy, 1L);
- else
- (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
- dx, dy);
- (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
- }
-}
-
-static int
-ProcShmPutImage(ClientPtr client)
-{
- GCPtr pGC;
- DrawablePtr pDraw;
- long length;
- ShmDescPtr shmdesc;
- REQUEST(xShmPutImageReq);
-
- REQUEST_SIZE_MATCH(xShmPutImageReq);
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
- if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
- return BadValue;
- if (stuff->format == XYBitmap)
- {
- if (stuff->depth != 1)
- return BadMatch;
- length = PixmapBytePad(stuff->totalWidth, 1);
- }
- else if (stuff->format == XYPixmap)
- {
- if (pDraw->depth != stuff->depth)
- return BadMatch;
- length = PixmapBytePad(stuff->totalWidth, 1);
- length *= stuff->depth;
- }
- else if (stuff->format == ZPixmap)
- {
- if (pDraw->depth != stuff->depth)
- return BadMatch;
- length = PixmapBytePad(stuff->totalWidth, stuff->depth);
- }
- else
- {
- client->errorValue = stuff->format;
- return BadValue;
- }
-
- /*
- * There's a potential integer overflow in this check:
- * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
- * client);
- * the version below ought to avoid it
- */
- if (stuff->totalHeight != 0 &&
- length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
- client->errorValue = stuff->totalWidth;
- return BadValue;
- }
- if (stuff->srcX > stuff->totalWidth)
- {
- client->errorValue = stuff->srcX;
- return BadValue;
- }
- if (stuff->srcY > stuff->totalHeight)
- {
- client->errorValue = stuff->srcY;
- return BadValue;
- }
- if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
- {
- client->errorValue = stuff->srcWidth;
- return BadValue;
- }
- if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
- {
- client->errorValue = stuff->srcHeight;
- return BadValue;
- }
-
- if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
- ((stuff->format != ZPixmap) &&
- (stuff->srcX < screenInfo.bitmapScanlinePad) &&
- ((stuff->format == XYBitmap) ||
- ((stuff->srcY == 0) &&
- (stuff->srcHeight == stuff->totalHeight))))) &&
- ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
- (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
- stuff->dstX, stuff->dstY,
- stuff->totalWidth, stuff->srcHeight,
- stuff->srcX, stuff->format,
- shmdesc->addr + stuff->offset +
- (stuff->srcY * length));
- else
- doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
- stuff->totalWidth, stuff->totalHeight,
- stuff->srcX, stuff->srcY,
- stuff->srcWidth, stuff->srcHeight,
- stuff->dstX, stuff->dstY,
- shmdesc->addr + stuff->offset);
-
- if (stuff->sendEvent)
- {
- xShmCompletionEvent ev;
-
- ev.type = ShmCompletionCode;
- ev.drawable = stuff->drawable;
- ev.minorEvent = X_ShmPutImage;
- ev.majorEvent = ShmReqCode;
- ev.shmseg = stuff->shmseg;
- ev.offset = stuff->offset;
- WriteEventsToClient(client, 1, (xEvent *) &ev);
- }
-
- return Success;
-}
-
-static int
-ProcShmGetImage(ClientPtr client)
-{
- DrawablePtr pDraw;
- long lenPer = 0, length;
- Mask plane = 0;
- xShmGetImageReply xgi;
- ShmDescPtr shmdesc;
- int n, rc;
-
- REQUEST(xShmGetImageReq);
-
- REQUEST_SIZE_MATCH(xShmGetImageReq);
- if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
- {
- client->errorValue = stuff->format;
- return BadValue;
- }
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
- if (pDraw->type == DRAWABLE_WINDOW)
- {
- if( /* check for being viewable */
- !((WindowPtr) pDraw)->realized ||
- /* check for being on screen */
- pDraw->x + stuff->x < 0 ||
- pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
- pDraw->y + stuff->y < 0 ||
- pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
- /* check for being inside of border */
- stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
- stuff->x + (int)stuff->width >
- wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
- stuff->y + (int)stuff->height >
- wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
- )
- return BadMatch;
- xgi.visual = wVisual(((WindowPtr)pDraw));
- }
- else
- {
- if (stuff->x < 0 ||
- stuff->x+(int)stuff->width > pDraw->width ||
- stuff->y < 0 ||
- stuff->y+(int)stuff->height > pDraw->height
- )
- return BadMatch;
- xgi.visual = None;
- }
- xgi.type = X_Reply;
- xgi.length = 0;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
- if(stuff->format == ZPixmap)
- {
- length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
- }
- else
- {
- lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
- plane = ((Mask)1) << (pDraw->depth - 1);
- /* only planes asked for */
- length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
- }
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
- xgi.size = length;
-
- if (length == 0)
- {
- /* nothing to do */
- }
- else if (stuff->format == ZPixmap)
- {
- (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
- stuff->width, stuff->height,
- stuff->format, stuff->planeMask,
- shmdesc->addr + stuff->offset);
- }
- else
- {
-
- length = stuff->offset;
- for (; plane; plane >>= 1)
- {
- if (stuff->planeMask & plane)
- {
- (*pDraw->pScreen->GetImage)(pDraw,
- stuff->x, stuff->y,
- stuff->width, stuff->height,
- stuff->format, plane,
- shmdesc->addr + length);
- length += lenPer;
- }
- }
- }
-
- if (client->swapped) {
- swaps(&xgi.sequenceNumber, n);
- swapl(&xgi.length, n);
- swapl(&xgi.visual, n);
- swapl(&xgi.size, n);
- }
- WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
-
- return Success;
-}
-
-#ifdef PANORAMIX
-static int
-ProcPanoramiXShmPutImage(ClientPtr client)
-{
- int j, result, orig_x, orig_y;
- PanoramiXRes *draw, *gc;
- Bool sendEvent, isRoot;
-
- REQUEST(xShmPutImageReq);
- REQUEST_SIZE_MATCH(xShmPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- orig_x = stuff->dstX;
- orig_y = stuff->dstY;
- sendEvent = stuff->sendEvent;
- stuff->sendEvent = 0;
- FOR_NSCREENS(j) {
- if(!j) stuff->sendEvent = sendEvent;
- stuff->drawable = draw->info[j].id;
- stuff->gc = gc->info[j].id;
- if (isRoot) {
- stuff->dstX = orig_x - screenInfo.screens[j]->x;
- stuff->dstY = orig_y - screenInfo.screens[j]->y;
- }
- result = ProcShmPutImage(client);
- if(result != Success) break;
- }
- return result;
-}
-
-static int
-ProcPanoramiXShmGetImage(ClientPtr client)
-{
- PanoramiXRes *draw;
- DrawablePtr *drawables;
- DrawablePtr pDraw;
- xShmGetImageReply xgi;
- ShmDescPtr shmdesc;
- int i, x, y, w, h, format, rc;
- Mask plane = 0, planemask;
- long lenPer = 0, length, widthBytesLine;
- Bool isRoot;
-
- REQUEST(xShmGetImageReq);
-
- REQUEST_SIZE_MATCH(xShmGetImageReq);
-
- if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
- client->errorValue = stuff->format;
- return BadValue;
- }
-
- rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (rc != Success)
- return (rc == BadValue) ? BadDrawable : rc;
-
- if (draw->type == XRT_PIXMAP)
- return ProcShmGetImage(client);
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-
- x = stuff->x;
- y = stuff->y;
- w = stuff->width;
- h = stuff->height;
- format = stuff->format;
- planemask = stuff->planeMask;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- if(isRoot) {
- if( /* check for being onscreen */
- x < 0 || x + w > PanoramiXPixWidth ||
- y < 0 || y + h > PanoramiXPixHeight )
- return BadMatch;
- } else {
- if( /* check for being onscreen */
- screenInfo.screens[0]->x + pDraw->x + x < 0 ||
- screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
- screenInfo.screens[0]->y + pDraw->y + y < 0 ||
- screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
- /* check for being inside of border */
- x < - wBorderWidth((WindowPtr)pDraw) ||
- x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- y < -wBorderWidth((WindowPtr)pDraw) ||
- y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
- return BadMatch;
- }
-
- drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr));
- if(!drawables)
- return BadAlloc;
-
- drawables[0] = pDraw;
- for(i = 1; i < PanoramiXNumScreens; i++) {
- rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0,
- DixReadAccess);
- if (rc != Success)
- {
- free(drawables);
- return rc;
- }
- }
-
- xgi.visual = wVisual(((WindowPtr)pDraw));
- xgi.type = X_Reply;
- xgi.length = 0;
- xgi.sequenceNumber = client->sequence;
- xgi.depth = pDraw->depth;
-
- if(format == ZPixmap) {
- widthBytesLine = PixmapBytePad(w, pDraw->depth);
- length = widthBytesLine * h;
- } else {
- widthBytesLine = PixmapBytePad(w, 1);
- lenPer = widthBytesLine * h;
- plane = ((Mask)1) << (pDraw->depth - 1);
- length = lenPer * Ones(planemask & (plane | (plane - 1)));
- }
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
- xgi.size = length;
-
- if (length == 0) {/* nothing to do */ }
- else if (format == ZPixmap) {
- XineramaGetImageData(drawables, x, y, w, h, format, planemask,
- shmdesc->addr + stuff->offset,
- widthBytesLine, isRoot);
- } else {
-
- length = stuff->offset;
- for (; plane; plane >>= 1) {
- if (planemask & plane) {
- XineramaGetImageData(drawables, x, y, w, h,
- format, plane, shmdesc->addr + length,
- widthBytesLine, isRoot);
- length += lenPer;
- }
- }
- }
- free(drawables);
-
- if (client->swapped) {
- int n;
- swaps(&xgi.sequenceNumber, n);
- swapl(&xgi.length, n);
- swapl(&xgi.visual, n);
- swapl(&xgi.size, n);
- }
- WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
-
- return Success;
-}
-
-static int
-ProcPanoramiXShmCreatePixmap(ClientPtr client)
-{
- ScreenPtr pScreen = NULL;
- PixmapPtr pMap = NULL;
- DrawablePtr pDraw;
- DepthPtr pDepth;
- int i, j, result, rc;
- ShmDescPtr shmdesc;
- REQUEST(xShmCreatePixmapReq);
- unsigned int width, height, depth;
- unsigned long size;
- PanoramiXRes *newPix;
-
- REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
- client->errorValue = stuff->pid;
- if (!sharedPixmaps)
- return BadImplementation;
- LEGAL_NEW_RESOURCE(stuff->pid, client);
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-
- width = stuff->width;
- height = stuff->height;
- depth = stuff->depth;
- if (!width || !height || !depth)
- {
- client->errorValue = 0;
- return BadValue;
- }
- if (width > 32767 || height > 32767)
- return BadAlloc;
-
- if (stuff->depth != 1)
- {
- pDepth = pDraw->pScreen->allowedDepths;
- for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
- if (pDepth->depth == stuff->depth)
- goto CreatePmap;
- client->errorValue = stuff->depth;
- return BadValue;
- }
-
-CreatePmap:
- size = PixmapBytePad(width, depth) * height;
- if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
- if (size < width * height)
- return BadAlloc;
- }
- /* thankfully, offset is unsigned */
- if (stuff->offset + size < size)
- return BadAlloc;
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
-
- if(!(newPix = malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPix->type = XRT_PIXMAP;
- newPix->u.pix.shared = TRUE;
- newPix->info[0].id = stuff->pid;
- for(j = 1; j < PanoramiXNumScreens; j++)
- newPix->info[j].id = FakeClientID(client->index);
-
- result = Success;
-
- FOR_NSCREENS(j) {
- ShmScrPrivateRec *screen_priv;
- pScreen = screenInfo.screens[j];
-
- screen_priv = ShmGetScreenPriv(pScreen);
- pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen,
- stuff->width, stuff->height, stuff->depth,
- shmdesc->addr + stuff->offset);
-
- if (pMap) {
- dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
- shmdesc->refcnt++;
- pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pMap->drawable.id = newPix->info[j].id;
- if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
- (*pScreen->DestroyPixmap)(pMap);
- result = BadAlloc;
- break;
- }
- } else {
- result = BadAlloc;
- break;
- }
- }
-
- if(result == BadAlloc) {
- while(j--) {
- (*pScreen->DestroyPixmap)(pMap);
- FreeResource(newPix->info[j].id, RT_NONE);
- }
- free(newPix);
- } else
- AddResource(stuff->pid, XRT_PIXMAP, newPix);
-
- return result;
-}
-#endif
-
-static PixmapPtr
-fbShmCreatePixmap (ScreenPtr pScreen,
- int width, int height, int depth, char *addr)
-{
- PixmapPtr pPixmap;
-
- pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
- if (!pPixmap)
- return NullPixmap;
-
- if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
- BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
- (*pScreen->DestroyPixmap)(pPixmap);
- return NullPixmap;
- }
- return pPixmap;
-}
-
-static int
-ProcShmCreatePixmap(ClientPtr client)
-{
- PixmapPtr pMap;
- DrawablePtr pDraw;
- DepthPtr pDepth;
- int i, rc;
- ShmDescPtr shmdesc;
- ShmScrPrivateRec *screen_priv;
- REQUEST(xShmCreatePixmapReq);
- unsigned int width, height, depth;
- unsigned long size;
-
- REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
- client->errorValue = stuff->pid;
- if (!sharedPixmaps)
- return BadImplementation;
- LEGAL_NEW_RESOURCE(stuff->pid, client);
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-
- width = stuff->width;
- height = stuff->height;
- depth = stuff->depth;
- if (!width || !height || !depth)
- {
- client->errorValue = 0;
- return BadValue;
- }
- if (width > 32767 || height > 32767)
- return BadAlloc;
-
- if (stuff->depth != 1)
- {
- pDepth = pDraw->pScreen->allowedDepths;
- for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
- if (pDepth->depth == stuff->depth)
- goto CreatePmap;
- client->errorValue = stuff->depth;
- return BadValue;
- }
-
-CreatePmap:
- size = PixmapBytePad(width, depth) * height;
- if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
- if (size < width * height)
- return BadAlloc;
- }
- /* thankfully, offset is unsigned */
- if (stuff->offset + size < size)
- return BadAlloc;
-
- VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
- screen_priv = ShmGetScreenPriv(pDraw->pScreen);
- pMap = (*screen_priv->shmFuncs->CreatePixmap)(
- pDraw->pScreen, stuff->width,
- stuff->height, stuff->depth,
- shmdesc->addr + stuff->offset);
- if (pMap)
- {
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
- pMap, RT_NONE, NULL, DixCreateAccess);
- if (rc != Success) {
- pDraw->pScreen->DestroyPixmap(pMap);
- return rc;
- }
- dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
- shmdesc->refcnt++;
- pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pMap->drawable.id = stuff->pid;
- if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
- {
- return Success;
- }
- pDraw->pScreen->DestroyPixmap(pMap);
- }
- return BadAlloc;
-}
-
-static int
-ProcShmDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_ShmQueryVersion:
- return ProcShmQueryVersion(client);
- case X_ShmAttach:
- return ProcShmAttach(client);
- case X_ShmDetach:
- return ProcShmDetach(client);
- case X_ShmPutImage:
-#ifdef PANORAMIX
- if ( !noPanoramiXExtension )
- return ProcPanoramiXShmPutImage(client);
-#endif
- return ProcShmPutImage(client);
- case X_ShmGetImage:
-#ifdef PANORAMIX
- if ( !noPanoramiXExtension )
- return ProcPanoramiXShmGetImage(client);
-#endif
- return ProcShmGetImage(client);
- case X_ShmCreatePixmap:
-#ifdef PANORAMIX
- if ( !noPanoramiXExtension )
- return ProcPanoramiXShmCreatePixmap(client);
-#endif
- return ProcShmCreatePixmap(client);
- default:
- return BadRequest;
- }
-}
-
-static void
-SShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to)
-{
- to->type = from->type;
- cpswaps(from->sequenceNumber, to->sequenceNumber);
- cpswapl(from->drawable, to->drawable);
- cpswaps(from->minorEvent, to->minorEvent);
- to->majorEvent = from->majorEvent;
- cpswapl(from->shmseg, to->shmseg);
- cpswapl(from->offset, to->offset);
-}
-
-static int
-SProcShmQueryVersion(ClientPtr client)
-{
- int n;
- REQUEST(xShmQueryVersionReq);
-
- swaps(&stuff->length, n);
- return ProcShmQueryVersion(client);
-}
-
-static int
-SProcShmAttach(ClientPtr client)
-{
- int n;
- REQUEST(xShmAttachReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmAttachReq);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->shmid, n);
- return ProcShmAttach(client);
-}
-
-static int
-SProcShmDetach(ClientPtr client)
-{
- int n;
- REQUEST(xShmDetachReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmDetachReq);
- swapl(&stuff->shmseg, n);
- return ProcShmDetach(client);
-}
-
-static int
-SProcShmPutImage(ClientPtr client)
-{
- int n;
- REQUEST(xShmPutImageReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmPutImageReq);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->totalWidth, n);
- swaps(&stuff->totalHeight, n);
- swaps(&stuff->srcX, n);
- swaps(&stuff->srcY, n);
- swaps(&stuff->srcWidth, n);
- swaps(&stuff->srcHeight, n);
- swaps(&stuff->dstX, n);
- swaps(&stuff->dstY, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->offset, n);
- return ProcShmPutImage(client);
-}
-
-static int
-SProcShmGetImage(ClientPtr client)
-{
- int n;
- REQUEST(xShmGetImageReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmGetImageReq);
- swapl(&stuff->drawable, n);
- swaps(&stuff->x, n);
- swaps(&stuff->y, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- swapl(&stuff->planeMask, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->offset, n);
- return ProcShmGetImage(client);
-}
-
-static int
-SProcShmCreatePixmap(ClientPtr client)
-{
- int n;
- REQUEST(xShmCreatePixmapReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
- swapl(&stuff->pid, n);
- swapl(&stuff->drawable, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->offset, n);
- return ProcShmCreatePixmap(client);
-}
-
-static int
-SProcShmDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_ShmQueryVersion:
- return SProcShmQueryVersion(client);
- case X_ShmAttach:
- return SProcShmAttach(client);
- case X_ShmDetach:
- return SProcShmDetach(client);
- case X_ShmPutImage:
- return SProcShmPutImage(client);
- case X_ShmGetImage:
- return SProcShmGetImage(client);
- case X_ShmCreatePixmap:
- return SProcShmCreatePixmap(client);
- default:
- return BadRequest;
- }
-}
-
-void
-ShmExtensionInit(INITARGS)
-{
- ExtensionEntry *extEntry;
- int i;
-
-#ifdef MUST_CHECK_FOR_SHM_SYSCALL
- if (!CheckForShmSyscall())
- {
- ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
- return;
- }
-#endif
-
- if (!ShmRegisterPrivates())
- return;
-
- sharedPixmaps = xFalse;
- {
- sharedPixmaps = xTrue;
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]);
- if (!screen_priv->shmFuncs)
- screen_priv->shmFuncs = &miFuncs;
- if (!screen_priv->shmFuncs->CreatePixmap)
- sharedPixmaps = xFalse;
- }
- if (sharedPixmaps)
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]);
- screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
- screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
- }
- }
- ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg");
- if (ShmSegType &&
- (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
- ProcShmDispatch, SProcShmDispatch,
- ShmResetProc, StandardMinorOpcode)))
- {
- ShmReqCode = (unsigned char)extEntry->base;
- ShmCompletionCode = extEntry->eventBase;
- BadShmSegCode = extEntry->errorBase;
- SetResourceTypeErrorValue(ShmSegType, BadShmSegCode);
- EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
- }
-}
+/************************************************************ + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +********************************************************/ + +/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ + + +#define SHM + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <unistd.h> +#include <sys/stat.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 "windowstr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "extnsionst.h" +#include "servermd.h" +#include "shmint.h" +#include "xace.h" +#include <X11/extensions/shmproto.h> +#include <X11/Xfuncproto.h> +#include "protocol-versions.h" + +/* Needed for Solaris cross-zone shared memory extension */ +#ifdef HAVE_SHMCTL64 +#include <sys/ipc_impl.h> +#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf) +#define SHMSTAT_TYPE struct shmid_ds64 +#define SHMPERM_TYPE struct ipc_perm64 +#define SHM_PERM(buf) buf.shmx_perm +#define SHM_SEGSZ(buf) buf.shmx_segsz +#define SHMPERM_UID(p) p->ipcx_uid +#define SHMPERM_CUID(p) p->ipcx_cuid +#define SHMPERM_GID(p) p->ipcx_gid +#define SHMPERM_CGID(p) p->ipcx_cgid +#define SHMPERM_MODE(p) p->ipcx_mode +#define SHMPERM_ZONEID(p) p->ipcx_zoneid +#else +#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf) +#define SHMSTAT_TYPE struct shmid_ds +#define SHMPERM_TYPE struct ipc_perm +#define SHM_PERM(buf) buf.shm_perm +#define SHM_SEGSZ(buf) buf.shm_segsz +#define SHMPERM_UID(p) p->uid +#define SHMPERM_CUID(p) p->cuid +#define SHMPERM_GID(p) p->gid +#define SHMPERM_CGID(p) p->cgid +#define SHMPERM_MODE(p) p->mode +#endif + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +#include "modinit.h" + +typedef struct _ShmDesc { + struct _ShmDesc *next; + int shmid; + int refcnt; + char *addr; + Bool writable; + unsigned long size; +} ShmDescRec, *ShmDescPtr; + +typedef struct _ShmScrPrivateRec { + CloseScreenProcPtr CloseScreen; + ShmFuncsPtr shmFuncs; + DestroyPixmapProcPtr destroyPixmap; +} ShmScrPrivateRec; + +static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS); +static int ShmDetachSegment( + pointer /* value */, + XID /* shmseg */ + ); +static void ShmResetProc( + ExtensionEntry * /* extEntry */ + ); +static void SShmCompletionEvent( + xShmCompletionEvent * /* from */, + xShmCompletionEvent * /* to */ + ); + +static Bool ShmDestroyPixmap (PixmapPtr pPixmap); + + +static unsigned char ShmReqCode; +int ShmCompletionCode; +int BadShmSegCode; +RESTYPE ShmSegType; +static ShmDescPtr Shmsegs; +static Bool sharedPixmaps; +static DevPrivateKeyRec shmScrPrivateKeyRec; +#define shmScrPrivateKey (&shmScrPrivateKeyRec) +static DevPrivateKeyRec shmPixmapPrivateKeyRec; +#define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec) +static ShmFuncs miFuncs = {NULL, NULL}; +static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL}; + +#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey)) + +#define VERIFY_SHMSEG(shmseg,shmdesc,client) \ +{ \ + int rc; \ + rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \ + client, DixReadAccess); \ + if (rc != Success) \ + return rc; \ +} + +#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \ +{ \ + VERIFY_SHMSEG(shmseg, shmdesc, client); \ + if ((offset & 3) || (offset > shmdesc->size)) \ + { \ + client->errorValue = offset; \ + return BadValue; \ + } \ + if (needwrite && !shmdesc->writable) \ + return BadAccess; \ +} + +#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \ +{ \ + if ((offset + len) > shmdesc->size) \ + { \ + return BadAccess; \ + } \ +} + + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__) +#include <sys/signal.h> + +static Bool badSysCall = FALSE; + +static void +SigSysHandler(int signo) +{ + badSysCall = TRUE; +} + +static Bool CheckForShmSyscall(void) +{ + void (*oldHandler)(); + int shmid = -1; + + /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ + oldHandler = signal(SIGSYS, SigSysHandler); + + badSysCall = FALSE; + shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); + + if (shmid != -1) + { + /* Successful allocation - clean up */ + shmctl(shmid, IPC_RMID, NULL); + } + else + { + /* Allocation failed */ + badSysCall = TRUE; + } + signal(SIGSYS, oldHandler); + return !badSysCall; +} + +#define MUST_CHECK_FOR_SHM_SYSCALL + +#endif + +static Bool +ShmCloseScreen(int i, ScreenPtr pScreen) +{ + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); + pScreen->CloseScreen = screen_priv->CloseScreen; + dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL); + free(screen_priv); + return (*pScreen->CloseScreen) (i, pScreen); +} + +static ShmScrPrivateRec * +ShmInitScreenPriv(ScreenPtr pScreen) +{ + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); + if (!screen_priv) + { + screen_priv = calloc(1, sizeof (ShmScrPrivateRec)); + screen_priv->CloseScreen = pScreen->CloseScreen; + dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv); + pScreen->CloseScreen = ShmCloseScreen; + } + return screen_priv; +} + +static Bool +ShmRegisterPrivates(void) +{ + if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0)) + return FALSE; + return TRUE; +} + +/*ARGSUSED*/ +static void +ShmResetProc(ExtensionEntry *extEntry) +{ + int i; + for (i = 0; i < screenInfo.numScreens; i++) + ShmRegisterFuncs(screenInfo.screens[i], NULL); +} + +void +ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) +{ + if (!ShmRegisterPrivates()) + return; + ShmInitScreenPriv(pScreen)->shmFuncs = funcs; +} + +static Bool +ShmDestroyPixmap (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); + Bool ret; + if (pPixmap->refcnt == 1) + { + ShmDescPtr shmdesc; + shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates, + shmPixmapPrivateKey); + if (shmdesc) + ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id); + } + + pScreen->DestroyPixmap = screen_priv->destroyPixmap; + ret = (*pScreen->DestroyPixmap) (pPixmap); + screen_priv->destroyPixmap = pScreen->DestroyPixmap; + pScreen->DestroyPixmap = ShmDestroyPixmap; + return ret; +} + +void +ShmRegisterFbFuncs(ScreenPtr pScreen) +{ + ShmRegisterFuncs(pScreen, &fbFuncs); +} + +static int +ProcShmQueryVersion(ClientPtr client) +{ + xShmQueryVersionReply rep; + int n; + + REQUEST_SIZE_MATCH(xShmQueryVersionReq); + memset(&rep, 0, sizeof(xShmQueryVersionReply)); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.sharedPixmaps = sharedPixmaps; + rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0; + rep.majorVersion = SERVER_SHM_MAJOR_VERSION; + rep.minorVersion = SERVER_SHM_MINOR_VERSION; + rep.uid = geteuid(); + rep.gid = getegid(); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + swaps(&rep.uid, n); + swaps(&rep.gid, n); + } + WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep); + return Success; +} + +/* + * Simulate the access() system call for a shared memory segement, + * using the credentials from the client if available + */ +static int +shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly) +{ + int uid, gid; + mode_t mask; + int uidset = 0, gidset = 0; + LocalClientCredRec *lcc; + + if (GetLocalClientCreds(client, &lcc) != -1) { + + if (lcc->fieldsSet & LCC_UID_SET) { + uid = lcc->euid; + uidset = 1; + } + if (lcc->fieldsSet & LCC_GID_SET) { + gid = lcc->egid; + gidset = 1; + } + +#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID) + if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1) + || (lcc->zoneid != SHMPERM_ZONEID(perm))) { + uidset = 0; + gidset = 0; + } +#endif + FreeLocalClientCreds(lcc); + + if (uidset) { + /* User id 0 always gets access */ + if (uid == 0) { + return 0; + } + /* Check the owner */ + if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) { + mask = S_IRUSR; + if (!readonly) { + mask |= S_IWUSR; + } + return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; + } + } + + if (gidset) { + /* Check the group */ + if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) { + mask = S_IRGRP; + if (!readonly) { + mask |= S_IWGRP; + } + return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; + } + } + } + /* Otherwise, check everyone else */ + mask = S_IROTH; + if (!readonly) { + mask |= S_IWOTH; + } + return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; +} + +static int +ProcShmAttach(ClientPtr client) +{ + SHMSTAT_TYPE buf; + ShmDescPtr shmdesc; + REQUEST(xShmAttachReq); + + REQUEST_SIZE_MATCH(xShmAttachReq); + LEGAL_NEW_RESOURCE(stuff->shmseg, client); + if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) + { + client->errorValue = stuff->readOnly; + return BadValue; + } + for (shmdesc = Shmsegs; + shmdesc && (shmdesc->shmid != stuff->shmid); + shmdesc = shmdesc->next) + ; + if (shmdesc) + { + if (!stuff->readOnly && !shmdesc->writable) + return BadAccess; + shmdesc->refcnt++; + } + else + { + shmdesc = malloc(sizeof(ShmDescRec)); + if (!shmdesc) + return BadAlloc; + shmdesc->addr = shmat(stuff->shmid, 0, + stuff->readOnly ? SHM_RDONLY : 0); + if ((shmdesc->addr == ((char *)-1)) || + SHMSTAT(stuff->shmid, &buf)) + { + free(shmdesc); + return BadAccess; + } + + /* The attach was performed with root privs. We must + * do manual checking of access rights for the credentials + * of the client */ + + if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) { + shmdt(shmdesc->addr); + free(shmdesc); + return BadAccess; + } + + shmdesc->shmid = stuff->shmid; + shmdesc->refcnt = 1; + shmdesc->writable = !stuff->readOnly; + shmdesc->size = SHM_SEGSZ(buf); + shmdesc->next = Shmsegs; + Shmsegs = shmdesc; + } + if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc)) + return BadAlloc; + return Success; +} + +/*ARGSUSED*/ +static int +ShmDetachSegment(pointer value, /* must conform to DeleteType */ + XID shmseg) +{ + ShmDescPtr shmdesc = (ShmDescPtr)value; + ShmDescPtr *prev; + + if (--shmdesc->refcnt) + return TRUE; + shmdt(shmdesc->addr); + for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next) + ; + *prev = shmdesc->next; + free(shmdesc); + return Success; +} + +static int +ProcShmDetach(ClientPtr client) +{ + ShmDescPtr shmdesc; + REQUEST(xShmDetachReq); + + REQUEST_SIZE_MATCH(xShmDetachReq); + VERIFY_SHMSEG(stuff->shmseg, shmdesc, client); + FreeResource(stuff->shmseg, RT_NONE); + return Success; +} + +/* + * If the given request doesn't exactly match PutImage's constraints, + * wrap the image in a scratch pixmap header and let CopyArea sort it out. + */ +static void +doShmPutImage(DrawablePtr dst, GCPtr pGC, + int depth, unsigned int format, + int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, + char *data) +{ + PixmapPtr pPixmap; + + if (format == ZPixmap || depth == 1) { + pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, + BitsPerPixel(depth), + PixmapBytePad(w, depth), + data); + if (!pPixmap) + return; + pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy); + FreeScratchPixmapHeader(pPixmap); + } else { + GCPtr putGC = GetScratchGC(depth, dst->pScreen); + + if (!putGC) + return; + + pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) { + FreeScratchGC(putGC); + return; + } + ValidateGC(&pPixmap->drawable, putGC); + (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0, + (format == XYPixmap) ? XYPixmap : ZPixmap, data); + FreeScratchGC(putGC); + if (format == XYBitmap) + (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, + dx, dy, 1L); + else + (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, + dx, dy); + (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); + } +} + +static int +ProcShmPutImage(ClientPtr client) +{ + GCPtr pGC; + DrawablePtr pDraw; + long length; + ShmDescPtr shmdesc; + REQUEST(xShmPutImageReq); + + REQUEST_SIZE_MATCH(xShmPutImageReq); + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client); + if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse)) + return BadValue; + if (stuff->format == XYBitmap) + { + if (stuff->depth != 1) + return BadMatch; + length = PixmapBytePad(stuff->totalWidth, 1); + } + else if (stuff->format == XYPixmap) + { + if (pDraw->depth != stuff->depth) + return BadMatch; + length = PixmapBytePad(stuff->totalWidth, 1); + length *= stuff->depth; + } + else if (stuff->format == ZPixmap) + { + if (pDraw->depth != stuff->depth) + return BadMatch; + length = PixmapBytePad(stuff->totalWidth, stuff->depth); + } + else + { + client->errorValue = stuff->format; + return BadValue; + } + + /* + * There's a potential integer overflow in this check: + * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, + * client); + * the version below ought to avoid it + */ + if (stuff->totalHeight != 0 && + length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { + client->errorValue = stuff->totalWidth; + return BadValue; + } + if (stuff->srcX > stuff->totalWidth) + { + client->errorValue = stuff->srcX; + return BadValue; + } + if (stuff->srcY > stuff->totalHeight) + { + client->errorValue = stuff->srcY; + return BadValue; + } + if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) + { + client->errorValue = stuff->srcWidth; + return BadValue; + } + if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) + { + client->errorValue = stuff->srcHeight; + return BadValue; + } + + if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) || + ((stuff->format != ZPixmap) && + (stuff->srcX < screenInfo.bitmapScanlinePad) && + ((stuff->format == XYBitmap) || + ((stuff->srcY == 0) && + (stuff->srcHeight == stuff->totalHeight))))) && + ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) + (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, + stuff->dstX, stuff->dstY, + stuff->totalWidth, stuff->srcHeight, + stuff->srcX, stuff->format, + shmdesc->addr + stuff->offset + + (stuff->srcY * length)); + else + doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, + stuff->totalWidth, stuff->totalHeight, + stuff->srcX, stuff->srcY, + stuff->srcWidth, stuff->srcHeight, + stuff->dstX, stuff->dstY, + shmdesc->addr + stuff->offset); + + if (stuff->sendEvent) + { + xShmCompletionEvent ev; + + ev.type = ShmCompletionCode; + ev.drawable = stuff->drawable; + ev.minorEvent = X_ShmPutImage; + ev.majorEvent = ShmReqCode; + ev.shmseg = stuff->shmseg; + ev.offset = stuff->offset; + WriteEventsToClient(client, 1, (xEvent *) &ev); + } + + return Success; +} + +static int +ProcShmGetImage(ClientPtr client) +{ + DrawablePtr pDraw; + long lenPer = 0, length; + Mask plane = 0; + xShmGetImageReply xgi; + ShmDescPtr shmdesc; + int n, rc; + + REQUEST(xShmGetImageReq); + + REQUEST_SIZE_MATCH(xShmGetImageReq); + if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) + { + client->errorValue = stuff->format; + return BadValue; + } + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + if (pDraw->type == DRAWABLE_WINDOW) + { + if( /* check for being viewable */ + !((WindowPtr) pDraw)->realized || + /* check for being on screen */ + pDraw->x + stuff->x < 0 || + pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width || + pDraw->y + stuff->y < 0 || + pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height || + /* check for being inside of border */ + stuff->x < - wBorderWidth((WindowPtr)pDraw) || + stuff->x + (int)stuff->width > + wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || + stuff->y < -wBorderWidth((WindowPtr)pDraw) || + stuff->y + (int)stuff->height > + wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height + ) + return BadMatch; + xgi.visual = wVisual(((WindowPtr)pDraw)); + } + else + { + if (stuff->x < 0 || + stuff->x+(int)stuff->width > pDraw->width || + stuff->y < 0 || + stuff->y+(int)stuff->height > pDraw->height + ) + return BadMatch; + xgi.visual = None; + } + xgi.type = X_Reply; + xgi.length = 0; + xgi.sequenceNumber = client->sequence; + xgi.depth = pDraw->depth; + if(stuff->format == ZPixmap) + { + length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height; + } + else + { + lenPer = PixmapBytePad(stuff->width, 1) * stuff->height; + plane = ((Mask)1) << (pDraw->depth - 1); + /* only planes asked for */ + length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); + xgi.size = length; + + if (length == 0) + { + /* nothing to do */ + } + else if (stuff->format == ZPixmap) + { + (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, + stuff->width, stuff->height, + stuff->format, stuff->planeMask, + shmdesc->addr + stuff->offset); + } + else + { + + length = stuff->offset; + for (; plane; plane >>= 1) + { + if (stuff->planeMask & plane) + { + (*pDraw->pScreen->GetImage)(pDraw, + stuff->x, stuff->y, + stuff->width, stuff->height, + stuff->format, plane, + shmdesc->addr + length); + length += lenPer; + } + } + } + + if (client->swapped) { + swaps(&xgi.sequenceNumber, n); + swapl(&xgi.length, n); + swapl(&xgi.visual, n); + swapl(&xgi.size, n); + } + WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); + + return Success; +} + +#ifdef PANORAMIX +static int +ProcPanoramiXShmPutImage(ClientPtr client) +{ + int j, result, orig_x, orig_y; + PanoramiXRes *draw, *gc; + Bool sendEvent, isRoot; + + REQUEST(xShmPutImageReq); + REQUEST_SIZE_MATCH(xShmPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + orig_x = stuff->dstX; + orig_y = stuff->dstY; + sendEvent = stuff->sendEvent; + stuff->sendEvent = 0; + FOR_NSCREENS(j) { + if(!j) stuff->sendEvent = sendEvent; + stuff->drawable = draw->info[j].id; + stuff->gc = gc->info[j].id; + if (isRoot) { + stuff->dstX = orig_x - screenInfo.screens[j]->x; + stuff->dstY = orig_y - screenInfo.screens[j]->y; + } + result = ProcShmPutImage(client); + if(result != Success) break; + } + return result; +} + +static int +ProcPanoramiXShmGetImage(ClientPtr client) +{ + PanoramiXRes *draw; + DrawablePtr *drawables; + DrawablePtr pDraw; + xShmGetImageReply xgi; + ShmDescPtr shmdesc; + int i, x, y, w, h, format, rc; + Mask plane = 0, planemask; + long lenPer = 0, length, widthBytesLine; + Bool isRoot; + + REQUEST(xShmGetImageReq); + + REQUEST_SIZE_MATCH(xShmGetImageReq); + + if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { + client->errorValue = stuff->format; + return BadValue; + } + + rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (rc != Success) + return (rc == BadValue) ? BadDrawable : rc; + + if (draw->type == XRT_PIXMAP) + return ProcShmGetImage(client); + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + + x = stuff->x; + y = stuff->y; + w = stuff->width; + h = stuff->height; + format = stuff->format; + planemask = stuff->planeMask; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + if(isRoot) { + if( /* check for being onscreen */ + x < 0 || x + w > PanoramiXPixWidth || + y < 0 || y + h > PanoramiXPixHeight ) + return BadMatch; + } else { + if( /* check for being onscreen */ + screenInfo.screens[0]->x + pDraw->x + x < 0 || + screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || + screenInfo.screens[0]->y + pDraw->y + y < 0 || + screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || + /* check for being inside of border */ + x < - wBorderWidth((WindowPtr)pDraw) || + x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || + y < -wBorderWidth((WindowPtr)pDraw) || + y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) + return BadMatch; + } + + drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); + if(!drawables) + return BadAlloc; + + drawables[0] = pDraw; + FOR_NSCREENS_FORWARD_SKIP(i) { + rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, + DixReadAccess); + if (rc != Success) + { + free(drawables); + return rc; + } + } + + xgi.visual = wVisual(((WindowPtr)pDraw)); + xgi.type = X_Reply; + xgi.length = 0; + xgi.sequenceNumber = client->sequence; + xgi.depth = pDraw->depth; + + if(format == ZPixmap) { + widthBytesLine = PixmapBytePad(w, pDraw->depth); + length = widthBytesLine * h; + } else { + widthBytesLine = PixmapBytePad(w, 1); + lenPer = widthBytesLine * h; + plane = ((Mask)1) << (pDraw->depth - 1); + length = lenPer * Ones(planemask & (plane | (plane - 1))); + } + + VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); + xgi.size = length; + + if (length == 0) {/* nothing to do */ } + else if (format == ZPixmap) { + XineramaGetImageData(drawables, x, y, w, h, format, planemask, + shmdesc->addr + stuff->offset, + widthBytesLine, isRoot); + } else { + + length = stuff->offset; + for (; plane; plane >>= 1) { + if (planemask & plane) { + XineramaGetImageData(drawables, x, y, w, h, + format, plane, shmdesc->addr + length, + widthBytesLine, isRoot); + length += lenPer; + } + } + } + free(drawables); + + if (client->swapped) { + int n; + swaps(&xgi.sequenceNumber, n); + swapl(&xgi.length, n); + swapl(&xgi.visual, n); + swapl(&xgi.size, n); + } + WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); + + return Success; +} + +static int +ProcPanoramiXShmCreatePixmap(ClientPtr client) +{ + ScreenPtr pScreen = NULL; + PixmapPtr pMap = NULL; + DrawablePtr pDraw; + DepthPtr pDepth; + int i, j, result, rc; + ShmDescPtr shmdesc; + REQUEST(xShmCreatePixmapReq); + unsigned int width, height, depth; + unsigned long size; + PanoramiXRes *newPix; + + REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + client->errorValue = stuff->pid; + if (!sharedPixmaps) + return BadImplementation; + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, + DixGetAttrAccess); + if (rc != Success) + return rc; + + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + + width = stuff->width; + height = stuff->height; + depth = stuff->depth; + if (!width || !height || !depth) + { + client->errorValue = 0; + return BadValue; + } + if (width > 32767 || height > 32767) + return BadAlloc; + + if (stuff->depth != 1) + { + pDepth = pDraw->pScreen->allowedDepths; + for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) + if (pDepth->depth == stuff->depth) + goto CreatePmap; + client->errorValue = stuff->depth; + return BadValue; + } + +CreatePmap: + size = PixmapBytePad(width, depth) * height; + if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { + if (size < width * height) + return BadAlloc; + } + /* thankfully, offset is unsigned */ + if (stuff->offset + size < size) + return BadAlloc; + + VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); + + if(!(newPix = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPix->type = XRT_PIXMAP; + newPix->u.pix.shared = TRUE; + panoramix_setup_ids(newPix, client, stuff->pid); + + result = Success; + + FOR_NSCREENS(j) { + ShmScrPrivateRec *screen_priv; + pScreen = screenInfo.screens[j]; + + screen_priv = ShmGetScreenPriv(pScreen); + pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen, + stuff->width, stuff->height, stuff->depth, + shmdesc->addr + stuff->offset); + + if (pMap) { + dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); + shmdesc->refcnt++; + pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pMap->drawable.id = newPix->info[j].id; + if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) { + (*pScreen->DestroyPixmap)(pMap); + result = BadAlloc; + break; + } + } else { + result = BadAlloc; + break; + } + } + + if(result == BadAlloc) { + while(j--) { + (*pScreen->DestroyPixmap)(pMap); + FreeResource(newPix->info[j].id, RT_NONE); + } + free(newPix); + } else + AddResource(stuff->pid, XRT_PIXMAP, newPix); + + return result; +} +#endif + +static PixmapPtr +fbShmCreatePixmap (ScreenPtr pScreen, + int width, int height, int depth, char *addr) +{ + PixmapPtr pPixmap; + + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); + if (!pPixmap) + return NullPixmap; + + if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, + BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) { + (*pScreen->DestroyPixmap)(pPixmap); + return NullPixmap; + } + return pPixmap; +} + +static int +ProcShmCreatePixmap(ClientPtr client) +{ + PixmapPtr pMap; + DrawablePtr pDraw; + DepthPtr pDepth; + int i, rc; + ShmDescPtr shmdesc; + ShmScrPrivateRec *screen_priv; + REQUEST(xShmCreatePixmapReq); + unsigned int width, height, depth; + unsigned long size; + + REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + client->errorValue = stuff->pid; + if (!sharedPixmaps) + return BadImplementation; + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, + DixGetAttrAccess); + if (rc != Success) + return rc; + + VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); + + width = stuff->width; + height = stuff->height; + depth = stuff->depth; + if (!width || !height || !depth) + { + client->errorValue = 0; + return BadValue; + } + if (width > 32767 || height > 32767) + return BadAlloc; + + if (stuff->depth != 1) + { + pDepth = pDraw->pScreen->allowedDepths; + for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) + if (pDepth->depth == stuff->depth) + goto CreatePmap; + client->errorValue = stuff->depth; + return BadValue; + } + +CreatePmap: + size = PixmapBytePad(width, depth) * height; + if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { + if (size < width * height) + return BadAlloc; + } + /* thankfully, offset is unsigned */ + if (stuff->offset + size < size) + return BadAlloc; + + VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); + screen_priv = ShmGetScreenPriv(pDraw->pScreen); + pMap = (*screen_priv->shmFuncs->CreatePixmap)( + pDraw->pScreen, stuff->width, + stuff->height, stuff->depth, + shmdesc->addr + stuff->offset); + if (pMap) + { + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, + pMap, RT_NONE, NULL, DixCreateAccess); + if (rc != Success) { + pDraw->pScreen->DestroyPixmap(pMap); + return rc; + } + dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); + shmdesc->refcnt++; + pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pMap->drawable.id = stuff->pid; + if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) + { + return Success; + } + pDraw->pScreen->DestroyPixmap(pMap); + } + return BadAlloc; +} + +static int +ProcShmDispatch (ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) + { + case X_ShmQueryVersion: + return ProcShmQueryVersion(client); + case X_ShmAttach: + return ProcShmAttach(client); + case X_ShmDetach: + return ProcShmDetach(client); + case X_ShmPutImage: +#ifdef PANORAMIX + if ( !noPanoramiXExtension ) + return ProcPanoramiXShmPutImage(client); +#endif + return ProcShmPutImage(client); + case X_ShmGetImage: +#ifdef PANORAMIX + if ( !noPanoramiXExtension ) + return ProcPanoramiXShmGetImage(client); +#endif + return ProcShmGetImage(client); + case X_ShmCreatePixmap: +#ifdef PANORAMIX + if ( !noPanoramiXExtension ) + return ProcPanoramiXShmCreatePixmap(client); +#endif + return ProcShmCreatePixmap(client); + default: + return BadRequest; + } +} + +static void +SShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to) +{ + to->type = from->type; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->drawable, to->drawable); + cpswaps(from->minorEvent, to->minorEvent); + to->majorEvent = from->majorEvent; + cpswapl(from->shmseg, to->shmseg); + cpswapl(from->offset, to->offset); +} + +static int +SProcShmQueryVersion(ClientPtr client) +{ + int n; + REQUEST(xShmQueryVersionReq); + + swaps(&stuff->length, n); + return ProcShmQueryVersion(client); +} + +static int +SProcShmAttach(ClientPtr client) +{ + int n; + REQUEST(xShmAttachReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmAttachReq); + swapl(&stuff->shmseg, n); + swapl(&stuff->shmid, n); + return ProcShmAttach(client); +} + +static int +SProcShmDetach(ClientPtr client) +{ + int n; + REQUEST(xShmDetachReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmDetachReq); + swapl(&stuff->shmseg, n); + return ProcShmDetach(client); +} + +static int +SProcShmPutImage(ClientPtr client) +{ + int n; + REQUEST(xShmPutImageReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmPutImageReq); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->totalWidth, n); + swaps(&stuff->totalHeight, n); + swaps(&stuff->srcX, n); + swaps(&stuff->srcY, n); + swaps(&stuff->srcWidth, n); + swaps(&stuff->srcHeight, n); + swaps(&stuff->dstX, n); + swaps(&stuff->dstY, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->offset, n); + return ProcShmPutImage(client); +} + +static int +SProcShmGetImage(ClientPtr client) +{ + int n; + REQUEST(xShmGetImageReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmGetImageReq); + swapl(&stuff->drawable, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->planeMask, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->offset, n); + return ProcShmGetImage(client); +} + +static int +SProcShmCreatePixmap(ClientPtr client) +{ + int n; + REQUEST(xShmCreatePixmapReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xShmCreatePixmapReq); + swapl(&stuff->pid, n); + swapl(&stuff->drawable, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->offset, n); + return ProcShmCreatePixmap(client); +} + +static int +SProcShmDispatch (ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) + { + case X_ShmQueryVersion: + return SProcShmQueryVersion(client); + case X_ShmAttach: + return SProcShmAttach(client); + case X_ShmDetach: + return SProcShmDetach(client); + case X_ShmPutImage: + return SProcShmPutImage(client); + case X_ShmGetImage: + return SProcShmGetImage(client); + case X_ShmCreatePixmap: + return SProcShmCreatePixmap(client); + default: + return BadRequest; + } +} + +void +ShmExtensionInit(INITARGS) +{ + ExtensionEntry *extEntry; + int i; + +#ifdef MUST_CHECK_FOR_SHM_SYSCALL + if (!CheckForShmSyscall()) + { + ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); + return; + } +#endif + + if (!ShmRegisterPrivates()) + return; + + sharedPixmaps = xFalse; + { + sharedPixmaps = xTrue; + for (i = 0; i < screenInfo.numScreens; i++) + { + ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]); + if (!screen_priv->shmFuncs) + screen_priv->shmFuncs = &miFuncs; + if (!screen_priv->shmFuncs->CreatePixmap) + sharedPixmaps = xFalse; + } + if (sharedPixmaps) + for (i = 0; i < screenInfo.numScreens; i++) + { + ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]); + screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap; + screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; + } + } + ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg"); + if (ShmSegType && + (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors, + ProcShmDispatch, SProcShmDispatch, + ShmResetProc, StandardMinorOpcode))) + { + ShmReqCode = (unsigned char)extEntry->base; + ShmCompletionCode = extEntry->eventBase; + BadShmSegCode = extEntry->errorBase; + SetResourceTypeErrorValue(ShmSegType, BadShmSegCode); + EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent; + } +} diff --git a/xorg-server/Xext/xvdisp.c b/xorg-server/Xext/xvdisp.c index e723fd84b..b96843159 100644 --- a/xorg-server/Xext/xvdisp.c +++ b/xorg-server/Xext/xvdisp.c @@ -1,1961 +1,1961 @@ -/***********************************************************
-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.
-******************************************************************/
-
-#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 "scrnintstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "opaque.h"
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-#include "xvdix.h"
-#ifdef MITSHM
-#include <X11/extensions/shmproto.h>
-#endif
-
-#include "xvdisp.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-
-unsigned long XvXRTPort;
-#endif
-
-static int
-SWriteQueryExtensionReply(
- ClientPtr client,
- xvQueryExtensionReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->version, n);
- swaps(&rep->revision, n);
-
- (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryAdaptorsReply(
- ClientPtr client,
- xvQueryAdaptorsReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->num_adaptors, n);
-
- (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryEncodingsReply(
- ClientPtr client,
- xvQueryEncodingsReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->num_encodings, n);
-
- (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteAdaptorInfo(
- ClientPtr client,
- xvAdaptorInfo *pAdaptor
-){
- char n;
-
- swapl(&pAdaptor->base_id, n);
- swaps(&pAdaptor->name_size, n);
- swaps(&pAdaptor->num_ports, n);
- swaps(&pAdaptor->num_formats, n);
-
- (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
-
- return Success;
-}
-
-static int
-SWriteEncodingInfo(
- ClientPtr client,
- xvEncodingInfo *pEncoding
-){
- char n;
-
- swapl(&pEncoding->encoding, n);
- swaps(&pEncoding->name_size, n);
- swaps(&pEncoding->width, n);
- swaps(&pEncoding->height, n);
- swapl(&pEncoding->rate.numerator, n);
- swapl(&pEncoding->rate.denominator, n);
- (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
-
- return Success;
-}
-
-static int
-SWriteFormat(
- ClientPtr client,
- xvFormat *pFormat
-){
- char n;
-
- swapl(&pFormat->visual, n);
- (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
-
- return Success;
-}
-
-static int
-SWriteAttributeInfo(
- ClientPtr client,
- xvAttributeInfo *pAtt
-){
- char n;
-
- swapl(&pAtt->flags, n);
- swapl(&pAtt->size, n);
- swapl(&pAtt->min, n);
- swapl(&pAtt->max, n);
- (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
-
- return Success;
-}
-
-static int
-SWriteImageFormatInfo(
- ClientPtr client,
- xvImageFormatInfo *pImage
-){
- char n;
-
- swapl(&pImage->id, n);
- swapl(&pImage->red_mask, n);
- swapl(&pImage->green_mask, n);
- swapl(&pImage->blue_mask, n);
- swapl(&pImage->y_sample_bits, n);
- swapl(&pImage->u_sample_bits, n);
- swapl(&pImage->v_sample_bits, n);
- swapl(&pImage->horz_y_period, n);
- swapl(&pImage->horz_u_period, n);
- swapl(&pImage->horz_v_period, n);
- swapl(&pImage->vert_y_period, n);
- swapl(&pImage->vert_u_period, n);
- swapl(&pImage->vert_v_period, n);
-
- (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
-
- return Success;
-}
-
-static int
-SWriteGrabPortReply(
- ClientPtr client,
- xvGrabPortReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
-
- (void)WriteToClient(client, sz_xvGrabPortReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteGetPortAttributeReply(
- ClientPtr client,
- xvGetPortAttributeReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->value, n);
-
- (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryBestSizeReply(
- ClientPtr client,
- xvQueryBestSizeReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swaps(&rep->actual_width, n);
- swaps(&rep->actual_height, n);
-
- (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryPortAttributesReply(
- ClientPtr client,
- xvQueryPortAttributesReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->num_attributes, n);
- swapl(&rep->text_size, n);
-
- (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteQueryImageAttributesReply(
- ClientPtr client,
- xvQueryImageAttributesReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->num_planes, n);
- swapl(&rep->data_size, n);
- swaps(&rep->width, n);
- swaps(&rep->height, n);
-
- (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)rep);
-
- return Success;
-}
-
-static int
-SWriteListImageFormatsReply(
- ClientPtr client,
- xvListImageFormatsReply *rep
-){
- char n;
-
- swaps(&rep->sequenceNumber, n);
- swapl(&rep->length, n);
- swapl(&rep->num_formats, n);
-
- (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)rep);
-
- return Success;
-}
-
-#define _WriteQueryAdaptorsReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
-
-#define _WriteQueryExtensionReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
-
-#define _WriteQueryEncodingsReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
-
-#define _WriteAdaptorInfo(_c,_d) \
- if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
- else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
-
-#define _WriteAttributeInfo(_c,_d) \
- if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
- else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
-
-#define _WriteEncodingInfo(_c,_d) \
- if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
- else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
-
-#define _WriteFormat(_c,_d) \
- if ((_c)->swapped) SWriteFormat(_c, _d); \
- else WriteToClient(_c, sz_xvFormat, (char*)_d)
-
-#define _WriteGrabPortReply(_c,_d) \
- if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
- else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
-
-#define _WriteGetPortAttributeReply(_c,_d) \
- if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
- else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
-
-#define _WriteQueryBestSizeReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
-
-#define _WriteQueryPortAttributesReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
-
-#define _WriteQueryImageAttributesReply(_c,_d) \
- if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
- else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
-
-#define _WriteListImageFormatsReply(_c,_d) \
- if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
- else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
-
-#define _WriteImageFormatInfo(_c,_d) \
- if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
- else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
-
-#define _AllocatePort(_i,_p) \
- ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
-
-static int
-ProcXvQueryExtension(ClientPtr client)
-{
- xvQueryExtensionReply rep;
- /* REQUEST(xvQueryExtensionReq); */
- REQUEST_SIZE_MATCH(xvQueryExtensionReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.version = XvVersion;
- rep.revision = XvRevision;
-
- _WriteQueryExtensionReply(client, &rep);
-
- return Success;
-}
-
-static int
-ProcXvQueryAdaptors(ClientPtr client)
-{
- xvFormat format;
- xvAdaptorInfo ainfo;
- xvQueryAdaptorsReply rep;
- int totalSize, na, nf, rc;
- int nameSize;
- XvAdaptorPtr pa;
- XvFormatPtr pf;
- WindowPtr pWin;
- ScreenPtr pScreen;
- XvScreenPtr pxvs;
-
- REQUEST(xvQueryAdaptorsReq);
- REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
-
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- pScreen = pWin->drawable.pScreen;
- pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- XvGetScreenKey());
- if (!pxvs)
- {
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_adaptors = 0;
- rep.length = 0;
-
- _WriteQueryAdaptorsReply(client, &rep);
-
- return Success;
- }
-
- (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_adaptors = pxvs->nAdaptors;
-
- /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
-
- totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
-
- /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
-
- na = pxvs->nAdaptors;
- pa = pxvs->pAdaptors;
- while (na--)
- {
- totalSize += pad_to_int32(strlen(pa->name));
- totalSize += pa->nFormats * sz_xvFormat;
- pa++;
- }
-
- rep.length = bytes_to_int32(totalSize);
-
- _WriteQueryAdaptorsReply(client, &rep);
-
- na = pxvs->nAdaptors;
- pa = pxvs->pAdaptors;
- while (na--)
- {
-
- ainfo.base_id = pa->base_id;
- ainfo.num_ports = pa->nPorts;
- ainfo.type = pa->type;
- ainfo.name_size = nameSize = strlen(pa->name);
- ainfo.num_formats = pa->nFormats;
-
- _WriteAdaptorInfo(client, &ainfo);
-
- WriteToClient(client, nameSize, pa->name);
-
- nf = pa->nFormats;
- pf = pa->pFormats;
- while (nf--)
- {
- format.depth = pf->depth;
- format.visual = pf->visual;
- _WriteFormat(client, &format);
- pf++;
- }
-
- pa++;
-
- }
-
- return Success;
-}
-
-static int
-ProcXvQueryEncodings(ClientPtr client)
-{
- xvEncodingInfo einfo;
- xvQueryEncodingsReply rep;
- int totalSize;
- int nameSize;
- XvPortPtr pPort;
- int ne;
- XvEncodingPtr pe;
- int status;
-
- REQUEST(xvQueryEncodingsReq);
- REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_encodings = pPort->pAdaptor->nEncodings;
-
- /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
-
- ne = pPort->pAdaptor->nEncodings;
- pe = pPort->pAdaptor->pEncodings;
- totalSize = ne * sz_xvEncodingInfo;
- while (ne--)
- {
- totalSize += pad_to_int32(strlen(pe->name));
- pe++;
- }
-
- rep.length = bytes_to_int32(totalSize);
-
- _WriteQueryEncodingsReply(client, &rep);
-
- ne = pPort->pAdaptor->nEncodings;
- pe = pPort->pAdaptor->pEncodings;
- while (ne--)
- {
- einfo.encoding = pe->id;
- einfo.name_size = nameSize = strlen(pe->name);
- einfo.width = pe->width;
- einfo.height = pe->height;
- einfo.rate.numerator = pe->rate.numerator;
- einfo.rate.denominator = pe->rate.denominator;
- _WriteEncodingInfo(client, &einfo);
- WriteToClient(client, nameSize, pe->name);
- pe++;
- }
-
- return Success;
-}
-
-static int
-ProcXvPutVideo(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvPutVideoReq);
- REQUEST_SIZE_MATCH(xvPutVideoReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvInputMask) ||
- !(pPort->pAdaptor->type & XvVideoMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvPutStill(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvPutStillReq);
- REQUEST_SIZE_MATCH(xvPutStillReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvInputMask) ||
- !(pPort->pAdaptor->type & XvStillMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvGetVideo(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvGetVideoReq);
- REQUEST_SIZE_MATCH(xvGetVideoReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvOutputMask) ||
- !(pPort->pAdaptor->type & XvVideoMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvGetStill(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- GCPtr pGC;
- int status;
-
- REQUEST(xvGetStillReq);
- REQUEST_SIZE_MATCH(xvGetStillReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvOutputMask) ||
- !(pPort->pAdaptor->type & XvStillMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
- stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h);
-}
-
-static int
-ProcXvSelectVideoNotify(ClientPtr client)
-{
- DrawablePtr pDraw;
- int rc;
- REQUEST(xvSelectVideoNotifyReq);
- REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReceiveAccess);
- if (rc != Success)
- return rc;
-
- return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
-}
-
-static int
-ProcXvSelectPortNotify(ClientPtr client)
-{
- int status;
- XvPortPtr pPort;
- REQUEST(xvSelectPortNotifyReq);
- REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- return XvdiSelectPortNotify(client, pPort, stuff->onoff);
-}
-
-static int
-ProcXvGrabPort(ClientPtr client)
-{
- int result, status;
- XvPortPtr pPort;
- xvGrabPortReply rep;
- REQUEST(xvGrabPortReq);
- REQUEST_SIZE_MATCH(xvGrabPortReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- status = XvdiGrabPort(client, pPort, stuff->time, &result);
-
- if (status != Success)
- {
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.result = result;
-
- _WriteGrabPortReply(client, &rep);
-
- return Success;
-}
-
-static int
-ProcXvUngrabPort(ClientPtr client)
-{
- int status;
- XvPortPtr pPort;
- REQUEST(xvGrabPortReq);
- REQUEST_SIZE_MATCH(xvGrabPortReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- return XvdiUngrabPort(client, pPort, stuff->time);
-}
-
-static int
-ProcXvStopVideo(ClientPtr client)
-{
- int status, rc;
- DrawablePtr pDraw;
- XvPortPtr pPort;
- REQUEST(xvStopVideoReq);
- REQUEST_SIZE_MATCH(xvStopVideoReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
- if (rc != Success)
- return rc;
-
- return XvdiStopVideo(client, pPort, pDraw);
-}
-
-static int
-ProcXvSetPortAttribute(ClientPtr client)
-{
- int status;
- XvPortPtr pPort;
- REQUEST(xvSetPortAttributeReq);
- REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!ValidAtom(stuff->attribute))
- {
- client->errorValue = stuff->attribute;
- return BadAtom;
- }
-
- status = XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value);
-
- if (status == BadMatch)
- client->errorValue = stuff->attribute;
- else
- client->errorValue = stuff->value;
-
- return status;
-}
-
-static int
-ProcXvGetPortAttribute(ClientPtr client)
-{
- INT32 value;
- int status;
- XvPortPtr pPort;
- xvGetPortAttributeReply rep;
- REQUEST(xvGetPortAttributeReq);
- REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!ValidAtom(stuff->attribute))
- {
- client->errorValue = stuff->attribute;
- return BadAtom;
- }
-
- status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value);
- if (status != Success)
- {
- client->errorValue = stuff->attribute;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.value = value;
-
- _WriteGetPortAttributeReply(client, &rep);
-
- return Success;
-}
-
-static int
-ProcXvQueryBestSize(ClientPtr client)
-{
- int status;
- unsigned int actual_width, actual_height;
- XvPortPtr pPort;
- xvQueryBestSizeReply rep;
- REQUEST(xvQueryBestSizeReq);
- REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
-
- (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
- stuff->vid_w, stuff->vid_h,
- stuff->drw_w, stuff->drw_h,
- &actual_width, &actual_height);
-
- rep.actual_width = actual_width;
- rep.actual_height = actual_height;
-
- _WriteQueryBestSizeReply(client, &rep);
-
- return Success;
-}
-
-
-static int
-ProcXvQueryPortAttributes(ClientPtr client)
-{
- int status, size, i;
- XvPortPtr pPort;
- XvAttributePtr pAtt;
- xvQueryPortAttributesReply rep;
- xvAttributeInfo Info;
- REQUEST(xvQueryPortAttributesReq);
- REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_attributes = pPort->pAdaptor->nAttributes;
- rep.text_size = 0;
-
- for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
- i < pPort->pAdaptor->nAttributes; i++, pAtt++)
- {
- rep.text_size += pad_to_int32(strlen(pAtt->name) + 1);
- }
-
- rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo)
- + rep.text_size;
- rep.length >>= 2;
-
- _WriteQueryPortAttributesReply(client, &rep);
-
- for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
- i < pPort->pAdaptor->nAttributes; i++, pAtt++)
- {
- size = strlen(pAtt->name) + 1; /* pass the NULL */
- Info.flags = pAtt->flags;
- Info.min = pAtt->min_value;
- Info.max = pAtt->max_value;
- Info.size = pad_to_int32(size);
-
- _WriteAttributeInfo(client, &Info);
-
- WriteToClient(client, size, pAtt->name);
- }
-
- return Success;
-}
-
-static int
-ProcXvPutImage(ClientPtr client)
-{
- DrawablePtr pDraw;
- XvPortPtr pPort;
- XvImagePtr pImage = NULL;
- GCPtr pGC;
- int status, i, size;
- CARD16 width, height;
-
- REQUEST(xvPutImageReq);
- REQUEST_AT_LEAST_SIZE(xvPutImageReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvImageMask) ||
- !(pPort->pAdaptor->type & XvInputMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++) {
- if(pPort->pAdaptor->pImages[i].id == stuff->id) {
- pImage = &(pPort->pAdaptor->pImages[i]);
- break;
- }
- }
-
- if(!pImage)
- return BadMatch;
-
- width = stuff->width;
- height = stuff->height;
- size = (*pPort->pAdaptor->ddQueryImageAttributes)(client,
- pPort, pImage, &width, &height, NULL, NULL);
- size += sizeof(xvPutImageReq);
- size = bytes_to_int32(size);
-
- if((width < stuff->width) || (height < stuff->height))
- return BadValue;
-
- if(client->req_len < size)
- return BadLength;
-
- return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
- stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h, pImage,
- (unsigned char*)(&stuff[1]), FALSE,
- stuff->width, stuff->height);
-}
-
-#ifdef MITSHM
-/* redefined here since it's not in any header file */
-typedef struct _ShmDesc {
- struct _ShmDesc *next;
- int shmid;
- int refcnt;
- char *addr;
- Bool writable;
- unsigned long size;
-} ShmDescRec, *ShmDescPtr;
-
-extern RESTYPE ShmSegType;
-extern int ShmCompletionCode;
-
-static int
-ProcXvShmPutImage(ClientPtr client)
-{
- ShmDescPtr shmdesc;
- DrawablePtr pDraw;
- XvPortPtr pPort;
- XvImagePtr pImage = NULL;
- GCPtr pGC;
- int status, size_needed, i;
- CARD16 width, height;
-
- REQUEST(xvShmPutImageReq);
- REQUEST_SIZE_MATCH(xvShmPutImageReq);
-
- VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- if ((status = _AllocatePort(stuff->port, pPort)) != Success)
- {
- client->errorValue = stuff->port;
- return status;
- }
-
- if (!(pPort->pAdaptor->type & XvImageMask) ||
- !(pPort->pAdaptor->type & XvInputMask))
- {
- client->errorValue = stuff->port;
- return BadMatch;
- }
-
- status = XvdiMatchPort(pPort, pDraw);
- if (status != Success)
- {
- return status;
- }
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++) {
- if(pPort->pAdaptor->pImages[i].id == stuff->id) {
- pImage = &(pPort->pAdaptor->pImages[i]);
- break;
- }
- }
-
- if(!pImage)
- return BadMatch;
-
- status = dixLookupResourceByType((pointer *)&shmdesc, stuff->shmseg,
- ShmSegType, serverClient, DixReadAccess);
- if (status != Success)
- return status;
-
- width = stuff->width;
- height = stuff->height;
- size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client,
- pPort, pImage, &width, &height, NULL, NULL);
- if((size_needed + stuff->offset) > shmdesc->size)
- return BadAccess;
-
- if((width < stuff->width) || (height < stuff->height))
- return BadValue;
-
- status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
- stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
- stuff->drw_w, stuff->drw_h, pImage,
- (unsigned char *)shmdesc->addr + stuff->offset,
- stuff->send_event, stuff->width, stuff->height);
-
- if((status == Success) && stuff->send_event) {
- xShmCompletionEvent ev;
-
- ev.type = ShmCompletionCode;
- ev.drawable = stuff->drawable;
- ev.minorEvent = xv_ShmPutImage;
- ev.majorEvent = XvReqCode;
- ev.shmseg = stuff->shmseg;
- ev.offset = stuff->offset;
- WriteEventsToClient(client, 1, (xEvent *) &ev);
- }
-
- return status;
-}
-#else /* !MITSHM */
-static int
-ProcXvShmPutImage(ClientPtr client)
-{
- SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation);
- return BadImplementation;
-}
-#endif
-
-#ifdef XvMCExtension
-#include "xvmcext.h"
-#endif
-
-static int
-ProcXvQueryImageAttributes(ClientPtr client)
-{
- xvQueryImageAttributesReply rep;
- int size, num_planes, i;
- CARD16 width, height;
- XvImagePtr pImage = NULL;
- XvPortPtr pPort;
- int *offsets;
- int *pitches;
- int planeLength;
- REQUEST(xvQueryImageAttributesReq);
-
- REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++) {
- if(pPort->pAdaptor->pImages[i].id == stuff->id) {
- pImage = &(pPort->pAdaptor->pImages[i]);
- break;
- }
- }
-
-#ifdef XvMCExtension
- if(!pImage)
- pImage = XvMCFindXvImage(pPort, stuff->id);
-#endif
-
- if(!pImage)
- return BadMatch;
-
- num_planes = pImage->num_planes;
-
- if(!(offsets = malloc(num_planes << 3)))
- return BadAlloc;
- pitches = offsets + num_planes;
-
- width = stuff->width;
- height = stuff->height;
-
- size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
- &width, &height, offsets, pitches);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = planeLength = num_planes << 1;
- rep.num_planes = num_planes;
- rep.width = width;
- rep.height = height;
- rep.data_size = size;
-
- _WriteQueryImageAttributesReply(client, &rep);
- if(client->swapped)
- SwapLongs((CARD32*)offsets, planeLength);
- WriteToClient(client, planeLength << 2, (char*)offsets);
-
- free(offsets);
-
- return Success;
-}
-
-static int
-ProcXvListImageFormats(ClientPtr client)
-{
- XvPortPtr pPort;
- XvImagePtr pImage;
- int i;
- xvListImageFormatsReply rep;
- xvImageFormatInfo info;
- REQUEST(xvListImageFormatsReq);
-
- REQUEST_SIZE_MATCH(xvListImageFormatsReq);
-
- VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.num_formats = pPort->pAdaptor->nImages;
- rep.length = bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo);
-
- _WriteListImageFormatsReply(client, &rep);
-
- pImage = pPort->pAdaptor->pImages;
-
- for(i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) {
- 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;
- _WriteImageFormatInfo(client, &info);
- }
-
- return Success;
-}
-
-static int (*XvProcVector[xvNumRequests])(ClientPtr) = {
- ProcXvQueryExtension,
- ProcXvQueryAdaptors,
- ProcXvQueryEncodings,
- ProcXvGrabPort,
- ProcXvUngrabPort,
- ProcXvPutVideo,
- ProcXvPutStill,
- ProcXvGetVideo,
- ProcXvGetStill,
- ProcXvStopVideo,
- ProcXvSelectVideoNotify,
- ProcXvSelectPortNotify,
- ProcXvQueryBestSize,
- ProcXvSetPortAttribute,
- ProcXvGetPortAttribute,
- ProcXvQueryPortAttributes,
- ProcXvListImageFormats,
- ProcXvQueryImageAttributes,
- ProcXvPutImage,
- ProcXvShmPutImage,
-};
-
-int
-ProcXvDispatch(ClientPtr client)
-{
- REQUEST(xReq);
-
- UpdateCurrentTime();
-
- if (stuff->data > xvNumRequests) {
- SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
- return BadRequest;
- }
-
- return XvProcVector[stuff->data](client);
-}
-
-/* Swapped Procs */
-
-static int
-SProcXvQueryExtension(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryExtensionReq);
- swaps(&stuff->length, n);
- return XvProcVector[xv_QueryExtension](client);
-}
-
-static int
-SProcXvQueryAdaptors(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryAdaptorsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->window, n);
- return XvProcVector[xv_QueryAdaptors](client);
-}
-
-static int
-SProcXvQueryEncodings(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryEncodingsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_QueryEncodings](client);
-}
-
-static int
-SProcXvGrabPort(ClientPtr client)
-{
- char n;
- REQUEST(xvGrabPortReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->time, n);
- return XvProcVector[xv_GrabPort](client);
-}
-
-static int
-SProcXvUngrabPort(ClientPtr client)
-{
- char n;
- REQUEST(xvUngrabPortReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->time, n);
- return XvProcVector[xv_UngrabPort](client);
-}
-
-static int
-SProcXvPutVideo(ClientPtr client)
-{
- char n;
- REQUEST(xvPutVideoReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_PutVideo](client);
-}
-
-static int
-SProcXvPutStill(ClientPtr client)
-{
- char n;
- REQUEST(xvPutStillReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_PutStill](client);
-}
-
-static int
-SProcXvGetVideo(ClientPtr client)
-{
- char n;
- REQUEST(xvGetVideoReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_GetVideo](client);
-}
-
-static int
-SProcXvGetStill(ClientPtr client)
-{
- char n;
- REQUEST(xvGetStillReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swaps(&stuff->vid_x, n);
- swaps(&stuff->vid_y, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_GetStill](client);
-}
-
-static int
-SProcXvPutImage(ClientPtr client)
-{
- char n;
- REQUEST(xvPutImageReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swapl(&stuff->id, n);
- swaps(&stuff->src_x, n);
- swaps(&stuff->src_y, n);
- swaps(&stuff->src_w, n);
- swaps(&stuff->src_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return XvProcVector[xv_PutImage](client);
-}
-
-#ifdef MITSHM
-static int
-SProcXvShmPutImage(ClientPtr client)
-{
- char n;
- REQUEST(xvShmPutImageReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->gc, n);
- swapl(&stuff->shmseg, n);
- swapl(&stuff->id, n);
- swapl(&stuff->offset, n);
- swaps(&stuff->src_x, n);
- swaps(&stuff->src_y, n);
- swaps(&stuff->src_w, n);
- swaps(&stuff->src_h, n);
- swaps(&stuff->drw_x, n);
- swaps(&stuff->drw_y, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return XvProcVector[xv_ShmPutImage](client);
-}
-#else /* MITSHM */
-#define SProcXvShmPutImage ProcXvShmPutImage
-#endif
-
-static int
-SProcXvSelectVideoNotify(ClientPtr client)
-{
- char n;
- REQUEST(xvSelectVideoNotifyReq);
- swaps(&stuff->length, n);
- swapl(&stuff->drawable, n);
- return XvProcVector[xv_SelectVideoNotify](client);
-}
-
-static int
-SProcXvSelectPortNotify(ClientPtr client)
-{
- char n;
- REQUEST(xvSelectPortNotifyReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_SelectPortNotify](client);
-}
-
-static int
-SProcXvStopVideo(ClientPtr client)
-{
- char n;
- REQUEST(xvStopVideoReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->drawable, n);
- return XvProcVector[xv_StopVideo](client);
-}
-
-static int
-SProcXvSetPortAttribute(ClientPtr client)
-{
- char n;
- REQUEST(xvSetPortAttributeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->attribute, n);
- swapl(&stuff->value, n);
- return XvProcVector[xv_SetPortAttribute](client);
-}
-
-static int
-SProcXvGetPortAttribute(ClientPtr client)
-{
- char n;
- REQUEST(xvGetPortAttributeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->attribute, n);
- return XvProcVector[xv_GetPortAttribute](client);
-}
-
-static int
-SProcXvQueryBestSize(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryBestSizeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swaps(&stuff->vid_w, n);
- swaps(&stuff->vid_h, n);
- swaps(&stuff->drw_w, n);
- swaps(&stuff->drw_h, n);
- return XvProcVector[xv_QueryBestSize](client);
-}
-
-static int
-SProcXvQueryPortAttributes(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryPortAttributesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_QueryPortAttributes](client);
-}
-
-static int
-SProcXvQueryImageAttributes(ClientPtr client)
-{
- char n;
- REQUEST(xvQueryImageAttributesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- swapl(&stuff->id, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return XvProcVector[xv_QueryImageAttributes](client);
-}
-
-static int
-SProcXvListImageFormats(ClientPtr client)
-{
- char n;
- REQUEST(xvListImageFormatsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->port, n);
- return XvProcVector[xv_ListImageFormats](client);
-}
-
-static int (*SXvProcVector[xvNumRequests])(ClientPtr) = {
- SProcXvQueryExtension,
- SProcXvQueryAdaptors,
- SProcXvQueryEncodings,
- SProcXvGrabPort,
- SProcXvUngrabPort,
- SProcXvPutVideo,
- SProcXvPutStill,
- SProcXvGetVideo,
- SProcXvGetStill,
- SProcXvStopVideo,
- SProcXvSelectVideoNotify,
- SProcXvSelectPortNotify,
- SProcXvQueryBestSize,
- SProcXvSetPortAttribute,
- SProcXvGetPortAttribute,
- SProcXvQueryPortAttributes,
- SProcXvListImageFormats,
- SProcXvQueryImageAttributes,
- SProcXvPutImage,
- SProcXvShmPutImage,
-};
-
-int
-SProcXvDispatch(ClientPtr client)
-{
- REQUEST(xReq);
-
- UpdateCurrentTime();
-
- if (stuff->data > xvNumRequests) {
- SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
- return BadRequest;
- }
-
- return SXvProcVector[stuff->data](client);
-}
-
-#ifdef PANORAMIX
-static int
-XineramaXvStopVideo(ClientPtr client)
-{
- int result, i;
- PanoramiXRes *draw, *port;
- REQUEST(xvStopVideoReq);
- REQUEST_SIZE_MATCH(xvStopVideoReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- result = ProcXvStopVideo(client);
- }
- }
-
- return result;
-}
-
-static int
-XineramaXvSetPortAttribute(ClientPtr client)
-{
- REQUEST(xvSetPortAttributeReq);
- PanoramiXRes *port;
- int result, i;
-
- REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->port = port->info[i].id;
- result = ProcXvSetPortAttribute(client);
- }
- }
- return result;
-}
-
-#ifdef MITSHM
-static int
-XineramaXvShmPutImage(ClientPtr client)
-{
- REQUEST(xvShmPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool send_event = stuff->send_event;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_SIZE_MATCH(xvShmPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
- stuff->send_event = (send_event && !i) ? 1 : 0;
-
- result = ProcXvShmPutImage(client);
- }
- }
- return result;
-}
-#else
-#define XineramaXvShmPutImage ProcXvShmPutImage
-#endif
-
-static int
-XineramaXvPutImage(ClientPtr client)
-{
- REQUEST(xvPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_AT_LEAST_SIZE(xvPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
-
- result = ProcXvPutImage(client);
- }
- }
- return result;
-}
-
-static int
-XineramaXvPutVideo(ClientPtr client)
-{
- REQUEST(xvPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
-
- result = ProcXvPutVideo(client);
- }
- }
- return result;
-}
-
-static int
-XineramaXvPutStill(ClientPtr client)
-{
- REQUEST(xvPutImageReq);
- PanoramiXRes *draw, *gc, *port;
- Bool isRoot;
- int result, i, x, y;
-
- REQUEST_AT_LEAST_SIZE(xvPutImageReq);
-
- result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
-
- result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
- XRT_GC, client, DixReadAccess);
- if (result != Success)
- return result;
-
- result = dixLookupResourceByType((pointer *)&port, stuff->port,
- XvXRTPort, client, DixReadAccess);
- if (result != Success)
- return result;
-
- isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
-
- x = stuff->drw_x;
- y = stuff->drw_y;
-
- FOR_NSCREENS_BACKWARD(i) {
- if(port->info[i].id) {
- stuff->drawable = draw->info[i].id;
- stuff->port = port->info[i].id;
- stuff->gc = gc->info[i].id;
- stuff->drw_x = x;
- stuff->drw_y = y;
- if(isRoot) {
- stuff->drw_x -= screenInfo.screens[i]->x;
- stuff->drw_y -= screenInfo.screens[i]->y;
- }
-
- result = ProcXvPutStill(client);
- }
- }
- return result;
-}
-
-static Bool
-isImageAdaptor(XvAdaptorPtr pAdapt)
-{
- return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
-}
-
-static Bool
-hasOverlay(XvAdaptorPtr pAdapt)
-{
- int i;
- for(i = 0; i < pAdapt->nAttributes; i++)
- if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
- return TRUE;
- return FALSE;
-}
-
-static XvAdaptorPtr
-matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
-{
- int i;
- XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
- /* Do not try to go on if xv is not supported on this screen */
- if(xvsp == NULL)
- return NULL;
-
- /* if the adaptor has the same name it's a perfect match */
- for(i = 0; i < xvsp->nAdaptors; i++) {
- XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
- if(!strcmp(refAdapt->name, pAdapt->name))
- return pAdapt;
- }
-
- /* otherwise we only look for XvImage adaptors */
- if(!isImageAdaptor(refAdapt))
- return NULL;
-
- /* prefer overlay/overlay non-overlay/non-overlay pairing */
- for(i = 0; i < xvsp->nAdaptors; i++) {
- XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
- if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
- return pAdapt;
- }
-
- /* but we'll take any XvImage pairing if we can get it */
- for(i = 0; i < xvsp->nAdaptors; i++) {
- XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
- if(isImageAdaptor(pAdapt))
- return pAdapt;
- }
- return NULL;
-}
-
-void XineramifyXv(void)
-{
- XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
- XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
- int i, j, k;
-
- XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
-
- if (!xvsp0 || !XvXRTPort) return;
- SetResourceTypeErrorValue(XvXRTPort, _XvBadPort);
-
- for(i = 0; i < xvsp0->nAdaptors; i++) {
- Bool isOverlay;
- XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
- if(!(refAdapt->type & XvInputMask)) continue;
-
- MatchingAdaptors[0] = refAdapt;
- isOverlay = hasOverlay(refAdapt);
- for(j = 1; j < PanoramiXNumScreens; j++)
- MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
-
- /* now create a resource for each port */
- for(j = 0; j < refAdapt->nPorts; j++) {
- PanoramiXRes *port = malloc(sizeof(PanoramiXRes));
- if(!port)
- break;
-
- for(k = 0; k < PanoramiXNumScreens; k++) {
- if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
- port->info[k].id = MatchingAdaptors[k]->base_id + j;
- else
- port->info[k].id = 0;
- }
- AddResource(port->info[0].id, XvXRTPort, port);
- }
- }
-
- /* munge the dispatch vector */
- XvProcVector[xv_PutVideo] = XineramaXvPutVideo;
- XvProcVector[xv_PutStill] = XineramaXvPutStill;
- XvProcVector[xv_StopVideo] = XineramaXvStopVideo;
- XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute;
- XvProcVector[xv_PutImage] = XineramaXvPutImage;
- XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage;
-}
-#endif /* PANORAMIX */
-
-void
-XvResetProcVector(void)
-{
-#ifdef PANORAMIX
- XvProcVector[xv_PutVideo] = ProcXvPutVideo;
- XvProcVector[xv_PutStill] = ProcXvPutStill;
- XvProcVector[xv_StopVideo] = ProcXvStopVideo;
- XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute;
- XvProcVector[xv_PutImage] = ProcXvPutImage;
- XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage;
-#endif
-}
+/*********************************************************** +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. +******************************************************************/ + +#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 "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "dixstruct.h" +#include "resource.h" +#include "opaque.h" + +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> +#include "xvdix.h" +#ifdef MITSHM +#include <X11/extensions/shmproto.h> +#endif + +#include "xvdisp.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" + +unsigned long XvXRTPort; +#endif + +static int +SWriteQueryExtensionReply( + ClientPtr client, + xvQueryExtensionReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->version, n); + swaps(&rep->revision, n); + + (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryAdaptorsReply( + ClientPtr client, + xvQueryAdaptorsReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_adaptors, n); + + (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryEncodingsReply( + ClientPtr client, + xvQueryEncodingsReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_encodings, n); + + (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)rep); + + return Success; +} + +static int +SWriteAdaptorInfo( + ClientPtr client, + xvAdaptorInfo *pAdaptor +){ + char n; + + swapl(&pAdaptor->base_id, n); + swaps(&pAdaptor->name_size, n); + swaps(&pAdaptor->num_ports, n); + swaps(&pAdaptor->num_formats, n); + + (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor); + + return Success; +} + +static int +SWriteEncodingInfo( + ClientPtr client, + xvEncodingInfo *pEncoding +){ + char n; + + swapl(&pEncoding->encoding, n); + swaps(&pEncoding->name_size, n); + swaps(&pEncoding->width, n); + swaps(&pEncoding->height, n); + swapl(&pEncoding->rate.numerator, n); + swapl(&pEncoding->rate.denominator, n); + (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding); + + return Success; +} + +static int +SWriteFormat( + ClientPtr client, + xvFormat *pFormat +){ + char n; + + swapl(&pFormat->visual, n); + (void)WriteToClient(client, sz_xvFormat, (char *)pFormat); + + return Success; +} + +static int +SWriteAttributeInfo( + ClientPtr client, + xvAttributeInfo *pAtt +){ + char n; + + swapl(&pAtt->flags, n); + swapl(&pAtt->size, n); + swapl(&pAtt->min, n); + swapl(&pAtt->max, n); + (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt); + + return Success; +} + +static int +SWriteImageFormatInfo( + ClientPtr client, + xvImageFormatInfo *pImage +){ + char n; + + swapl(&pImage->id, n); + swapl(&pImage->red_mask, n); + swapl(&pImage->green_mask, n); + swapl(&pImage->blue_mask, n); + swapl(&pImage->y_sample_bits, n); + swapl(&pImage->u_sample_bits, n); + swapl(&pImage->v_sample_bits, n); + swapl(&pImage->horz_y_period, n); + swapl(&pImage->horz_u_period, n); + swapl(&pImage->horz_v_period, n); + swapl(&pImage->vert_y_period, n); + swapl(&pImage->vert_u_period, n); + swapl(&pImage->vert_v_period, n); + + (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage); + + return Success; +} + +static int +SWriteGrabPortReply( + ClientPtr client, + xvGrabPortReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + + (void)WriteToClient(client, sz_xvGrabPortReply, (char *)rep); + + return Success; +} + +static int +SWriteGetPortAttributeReply( + ClientPtr client, + xvGetPortAttributeReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->value, n); + + (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryBestSizeReply( + ClientPtr client, + xvQueryBestSizeReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->actual_width, n); + swaps(&rep->actual_height, n); + + (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryPortAttributesReply( + ClientPtr client, + xvQueryPortAttributesReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_attributes, n); + swapl(&rep->text_size, n); + + (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)rep); + + return Success; +} + +static int +SWriteQueryImageAttributesReply( + ClientPtr client, + xvQueryImageAttributesReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_planes, n); + swapl(&rep->data_size, n); + swaps(&rep->width, n); + swaps(&rep->height, n); + + (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)rep); + + return Success; +} + +static int +SWriteListImageFormatsReply( + ClientPtr client, + xvListImageFormatsReply *rep +){ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->num_formats, n); + + (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)rep); + + return Success; +} + +#define _WriteQueryAdaptorsReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d) + +#define _WriteQueryExtensionReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d) + +#define _WriteQueryEncodingsReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d) + +#define _WriteAdaptorInfo(_c,_d) \ + if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \ + else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d) + +#define _WriteAttributeInfo(_c,_d) \ + if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \ + else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d) + +#define _WriteEncodingInfo(_c,_d) \ + if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \ + else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d) + +#define _WriteFormat(_c,_d) \ + if ((_c)->swapped) SWriteFormat(_c, _d); \ + else WriteToClient(_c, sz_xvFormat, (char*)_d) + +#define _WriteGrabPortReply(_c,_d) \ + if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \ + else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d) + +#define _WriteGetPortAttributeReply(_c,_d) \ + if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \ + else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d) + +#define _WriteQueryBestSizeReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d) + +#define _WriteQueryPortAttributesReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d) + +#define _WriteQueryImageAttributesReply(_c,_d) \ + if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \ + else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d) + +#define _WriteListImageFormatsReply(_c,_d) \ + if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \ + else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d) + +#define _WriteImageFormatInfo(_c,_d) \ + if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \ + else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d) + +#define _AllocatePort(_i,_p) \ + ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success + +static int +ProcXvQueryExtension(ClientPtr client) +{ + xvQueryExtensionReply rep; + /* REQUEST(xvQueryExtensionReq); */ + REQUEST_SIZE_MATCH(xvQueryExtensionReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.version = XvVersion; + rep.revision = XvRevision; + + _WriteQueryExtensionReply(client, &rep); + + return Success; +} + +static int +ProcXvQueryAdaptors(ClientPtr client) +{ + xvFormat format; + xvAdaptorInfo ainfo; + xvQueryAdaptorsReply rep; + int totalSize, na, nf, rc; + int nameSize; + XvAdaptorPtr pa; + XvFormatPtr pf; + WindowPtr pWin; + ScreenPtr pScreen; + XvScreenPtr pxvs; + + REQUEST(xvQueryAdaptorsReq); + REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); + + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, + XvGetScreenKey()); + if (!pxvs) + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_adaptors = 0; + rep.length = 0; + + _WriteQueryAdaptorsReply(client, &rep); + + return Success; + } + + (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_adaptors = pxvs->nAdaptors; + + /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */ + + totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo; + + /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */ + + na = pxvs->nAdaptors; + pa = pxvs->pAdaptors; + while (na--) + { + totalSize += pad_to_int32(strlen(pa->name)); + totalSize += pa->nFormats * sz_xvFormat; + pa++; + } + + rep.length = bytes_to_int32(totalSize); + + _WriteQueryAdaptorsReply(client, &rep); + + na = pxvs->nAdaptors; + pa = pxvs->pAdaptors; + while (na--) + { + + ainfo.base_id = pa->base_id; + ainfo.num_ports = pa->nPorts; + ainfo.type = pa->type; + ainfo.name_size = nameSize = strlen(pa->name); + ainfo.num_formats = pa->nFormats; + + _WriteAdaptorInfo(client, &ainfo); + + WriteToClient(client, nameSize, pa->name); + + nf = pa->nFormats; + pf = pa->pFormats; + while (nf--) + { + format.depth = pf->depth; + format.visual = pf->visual; + _WriteFormat(client, &format); + pf++; + } + + pa++; + + } + + return Success; +} + +static int +ProcXvQueryEncodings(ClientPtr client) +{ + xvEncodingInfo einfo; + xvQueryEncodingsReply rep; + int totalSize; + int nameSize; + XvPortPtr pPort; + int ne; + XvEncodingPtr pe; + int status; + + REQUEST(xvQueryEncodingsReq); + REQUEST_SIZE_MATCH(xvQueryEncodingsReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_encodings = pPort->pAdaptor->nEncodings; + + /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */ + + ne = pPort->pAdaptor->nEncodings; + pe = pPort->pAdaptor->pEncodings; + totalSize = ne * sz_xvEncodingInfo; + while (ne--) + { + totalSize += pad_to_int32(strlen(pe->name)); + pe++; + } + + rep.length = bytes_to_int32(totalSize); + + _WriteQueryEncodingsReply(client, &rep); + + ne = pPort->pAdaptor->nEncodings; + pe = pPort->pAdaptor->pEncodings; + while (ne--) + { + einfo.encoding = pe->id; + einfo.name_size = nameSize = strlen(pe->name); + einfo.width = pe->width; + einfo.height = pe->height; + einfo.rate.numerator = pe->rate.numerator; + einfo.rate.denominator = pe->rate.denominator; + _WriteEncodingInfo(client, &einfo); + WriteToClient(client, nameSize, pe->name); + pe++; + } + + return Success; +} + +static int +ProcXvPutVideo(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvPutVideoReq); + REQUEST_SIZE_MATCH(xvPutVideoReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvInputMask) || + !(pPort->pAdaptor->type & XvVideoMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvPutStill(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvPutStillReq); + REQUEST_SIZE_MATCH(xvPutStillReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvInputMask) || + !(pPort->pAdaptor->type & XvStillMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvGetVideo(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvGetVideoReq); + REQUEST_SIZE_MATCH(xvGetVideoReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvOutputMask) || + !(pPort->pAdaptor->type & XvVideoMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvGetStill(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + GCPtr pGC; + int status; + + REQUEST(xvGetStillReq); + REQUEST_SIZE_MATCH(xvGetStillReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvOutputMask) || + !(pPort->pAdaptor->type & XvStillMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, + stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h); +} + +static int +ProcXvSelectVideoNotify(ClientPtr client) +{ + DrawablePtr pDraw; + int rc; + REQUEST(xvSelectVideoNotifyReq); + REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReceiveAccess); + if (rc != Success) + return rc; + + return XvdiSelectVideoNotify(client, pDraw, stuff->onoff); +} + +static int +ProcXvSelectPortNotify(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvSelectPortNotifyReq); + REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + return XvdiSelectPortNotify(client, pPort, stuff->onoff); +} + +static int +ProcXvGrabPort(ClientPtr client) +{ + int result, status; + XvPortPtr pPort; + xvGrabPortReply rep; + REQUEST(xvGrabPortReq); + REQUEST_SIZE_MATCH(xvGrabPortReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + status = XvdiGrabPort(client, pPort, stuff->time, &result); + + if (status != Success) + { + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.result = result; + + _WriteGrabPortReply(client, &rep); + + return Success; +} + +static int +ProcXvUngrabPort(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvGrabPortReq); + REQUEST_SIZE_MATCH(xvGrabPortReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + return XvdiUngrabPort(client, pPort, stuff->time); +} + +static int +ProcXvStopVideo(ClientPtr client) +{ + int status, rc; + DrawablePtr pDraw; + XvPortPtr pPort; + REQUEST(xvStopVideoReq); + REQUEST_SIZE_MATCH(xvStopVideoReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); + if (rc != Success) + return rc; + + return XvdiStopVideo(client, pPort, pDraw); +} + +static int +ProcXvSetPortAttribute(ClientPtr client) +{ + int status; + XvPortPtr pPort; + REQUEST(xvSetPortAttributeReq); + REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!ValidAtom(stuff->attribute)) + { + client->errorValue = stuff->attribute; + return BadAtom; + } + + status = XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value); + + if (status == BadMatch) + client->errorValue = stuff->attribute; + else + client->errorValue = stuff->value; + + return status; +} + +static int +ProcXvGetPortAttribute(ClientPtr client) +{ + INT32 value; + int status; + XvPortPtr pPort; + xvGetPortAttributeReply rep; + REQUEST(xvGetPortAttributeReq); + REQUEST_SIZE_MATCH(xvGetPortAttributeReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!ValidAtom(stuff->attribute)) + { + client->errorValue = stuff->attribute; + return BadAtom; + } + + status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value); + if (status != Success) + { + client->errorValue = stuff->attribute; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.value = value; + + _WriteGetPortAttributeReply(client, &rep); + + return Success; +} + +static int +ProcXvQueryBestSize(ClientPtr client) +{ + int status; + unsigned int actual_width, actual_height; + XvPortPtr pPort; + xvQueryBestSizeReply rep; + REQUEST(xvQueryBestSizeReq); + REQUEST_SIZE_MATCH(xvQueryBestSizeReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion, + stuff->vid_w, stuff->vid_h, + stuff->drw_w, stuff->drw_h, + &actual_width, &actual_height); + + rep.actual_width = actual_width; + rep.actual_height = actual_height; + + _WriteQueryBestSizeReply(client, &rep); + + return Success; +} + + +static int +ProcXvQueryPortAttributes(ClientPtr client) +{ + int status, size, i; + XvPortPtr pPort; + XvAttributePtr pAtt; + xvQueryPortAttributesReply rep; + xvAttributeInfo Info; + REQUEST(xvQueryPortAttributesReq); + REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_attributes = pPort->pAdaptor->nAttributes; + rep.text_size = 0; + + for(i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < pPort->pAdaptor->nAttributes; i++, pAtt++) + { + rep.text_size += pad_to_int32(strlen(pAtt->name) + 1); + } + + rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo) + + rep.text_size; + rep.length >>= 2; + + _WriteQueryPortAttributesReply(client, &rep); + + for(i = 0, pAtt = pPort->pAdaptor->pAttributes; + i < pPort->pAdaptor->nAttributes; i++, pAtt++) + { + size = strlen(pAtt->name) + 1; /* pass the NULL */ + Info.flags = pAtt->flags; + Info.min = pAtt->min_value; + Info.max = pAtt->max_value; + Info.size = pad_to_int32(size); + + _WriteAttributeInfo(client, &Info); + + WriteToClient(client, size, pAtt->name); + } + + return Success; +} + +static int +ProcXvPutImage(ClientPtr client) +{ + DrawablePtr pDraw; + XvPortPtr pPort; + XvImagePtr pImage = NULL; + GCPtr pGC; + int status, i, size; + CARD16 width, height; + + REQUEST(xvPutImageReq); + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvImageMask) || + !(pPort->pAdaptor->type & XvInputMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + + if(!pImage) + return BadMatch; + + width = stuff->width; + height = stuff->height; + size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, + pPort, pImage, &width, &height, NULL, NULL); + size += sizeof(xvPutImageReq); + size = bytes_to_int32(size); + + if((width < stuff->width) || (height < stuff->height)) + return BadValue; + + if(client->req_len < size) + return BadLength; + + return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y, + stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h, pImage, + (unsigned char*)(&stuff[1]), FALSE, + stuff->width, stuff->height); +} + +#ifdef MITSHM +/* redefined here since it's not in any header file */ +typedef struct _ShmDesc { + struct _ShmDesc *next; + int shmid; + int refcnt; + char *addr; + Bool writable; + unsigned long size; +} ShmDescRec, *ShmDescPtr; + +extern RESTYPE ShmSegType; +extern int ShmCompletionCode; + +static int +ProcXvShmPutImage(ClientPtr client) +{ + ShmDescPtr shmdesc; + DrawablePtr pDraw; + XvPortPtr pPort; + XvImagePtr pImage = NULL; + GCPtr pGC; + int status, size_needed, i; + CARD16 width, height; + + REQUEST(xvShmPutImageReq); + REQUEST_SIZE_MATCH(xvShmPutImageReq); + + VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if ((status = _AllocatePort(stuff->port, pPort)) != Success) + { + client->errorValue = stuff->port; + return status; + } + + if (!(pPort->pAdaptor->type & XvImageMask) || + !(pPort->pAdaptor->type & XvInputMask)) + { + client->errorValue = stuff->port; + return BadMatch; + } + + status = XvdiMatchPort(pPort, pDraw); + if (status != Success) + { + return status; + } + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + + if(!pImage) + return BadMatch; + + status = dixLookupResourceByType((pointer *)&shmdesc, stuff->shmseg, + ShmSegType, serverClient, DixReadAccess); + if (status != Success) + return status; + + width = stuff->width; + height = stuff->height; + size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, + pPort, pImage, &width, &height, NULL, NULL); + if((size_needed + stuff->offset) > shmdesc->size) + return BadAccess; + + if((width < stuff->width) || (height < stuff->height)) + return BadValue; + + status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y, + stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y, + stuff->drw_w, stuff->drw_h, pImage, + (unsigned char *)shmdesc->addr + stuff->offset, + stuff->send_event, stuff->width, stuff->height); + + if((status == Success) && stuff->send_event) { + xShmCompletionEvent ev; + + ev.type = ShmCompletionCode; + ev.drawable = stuff->drawable; + ev.minorEvent = xv_ShmPutImage; + ev.majorEvent = XvReqCode; + ev.shmseg = stuff->shmseg; + ev.offset = stuff->offset; + WriteEventsToClient(client, 1, (xEvent *) &ev); + } + + return status; +} +#else /* !MITSHM */ +static int +ProcXvShmPutImage(ClientPtr client) +{ + SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation); + return BadImplementation; +} +#endif + +#ifdef XvMCExtension +#include "xvmcext.h" +#endif + +static int +ProcXvQueryImageAttributes(ClientPtr client) +{ + xvQueryImageAttributesReply rep; + int size, num_planes, i; + CARD16 width, height; + XvImagePtr pImage = NULL; + XvPortPtr pPort; + int *offsets; + int *pitches; + int planeLength; + REQUEST(xvQueryImageAttributesReq); + + REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + for(i = 0; i < pPort->pAdaptor->nImages; i++) { + if(pPort->pAdaptor->pImages[i].id == stuff->id) { + pImage = &(pPort->pAdaptor->pImages[i]); + break; + } + } + +#ifdef XvMCExtension + if(!pImage) + pImage = XvMCFindXvImage(pPort, stuff->id); +#endif + + if(!pImage) + return BadMatch; + + num_planes = pImage->num_planes; + + if(!(offsets = malloc(num_planes << 3))) + return BadAlloc; + pitches = offsets + num_planes; + + width = stuff->width; + height = stuff->height; + + size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage, + &width, &height, offsets, pitches); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = planeLength = num_planes << 1; + rep.num_planes = num_planes; + rep.width = width; + rep.height = height; + rep.data_size = size; + + _WriteQueryImageAttributesReply(client, &rep); + if(client->swapped) + SwapLongs((CARD32*)offsets, planeLength); + WriteToClient(client, planeLength << 2, (char*)offsets); + + free(offsets); + + return Success; +} + +static int +ProcXvListImageFormats(ClientPtr client) +{ + XvPortPtr pPort; + XvImagePtr pImage; + int i; + xvListImageFormatsReply rep; + xvImageFormatInfo info; + REQUEST(xvListImageFormatsReq); + + REQUEST_SIZE_MATCH(xvListImageFormatsReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num_formats = pPort->pAdaptor->nImages; + rep.length = bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo); + + _WriteListImageFormatsReply(client, &rep); + + pImage = pPort->pAdaptor->pImages; + + for(i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) { + 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; + _WriteImageFormatInfo(client, &info); + } + + return Success; +} + +static int (*XvProcVector[xvNumRequests])(ClientPtr) = { + ProcXvQueryExtension, + ProcXvQueryAdaptors, + ProcXvQueryEncodings, + ProcXvGrabPort, + ProcXvUngrabPort, + ProcXvPutVideo, + ProcXvPutStill, + ProcXvGetVideo, + ProcXvGetStill, + ProcXvStopVideo, + ProcXvSelectVideoNotify, + ProcXvSelectPortNotify, + ProcXvQueryBestSize, + ProcXvSetPortAttribute, + ProcXvGetPortAttribute, + ProcXvQueryPortAttributes, + ProcXvListImageFormats, + ProcXvQueryImageAttributes, + ProcXvPutImage, + ProcXvShmPutImage, +}; + +int +ProcXvDispatch(ClientPtr client) +{ + REQUEST(xReq); + + UpdateCurrentTime(); + + if (stuff->data > xvNumRequests) { + SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); + return BadRequest; + } + + return XvProcVector[stuff->data](client); +} + +/* Swapped Procs */ + +static int +SProcXvQueryExtension(ClientPtr client) +{ + char n; + REQUEST(xvQueryExtensionReq); + swaps(&stuff->length, n); + return XvProcVector[xv_QueryExtension](client); +} + +static int +SProcXvQueryAdaptors(ClientPtr client) +{ + char n; + REQUEST(xvQueryAdaptorsReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return XvProcVector[xv_QueryAdaptors](client); +} + +static int +SProcXvQueryEncodings(ClientPtr client) +{ + char n; + REQUEST(xvQueryEncodingsReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_QueryEncodings](client); +} + +static int +SProcXvGrabPort(ClientPtr client) +{ + char n; + REQUEST(xvGrabPortReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->time, n); + return XvProcVector[xv_GrabPort](client); +} + +static int +SProcXvUngrabPort(ClientPtr client) +{ + char n; + REQUEST(xvUngrabPortReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->time, n); + return XvProcVector[xv_UngrabPort](client); +} + +static int +SProcXvPutVideo(ClientPtr client) +{ + char n; + REQUEST(xvPutVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_PutVideo](client); +} + +static int +SProcXvPutStill(ClientPtr client) +{ + char n; + REQUEST(xvPutStillReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_PutStill](client); +} + +static int +SProcXvGetVideo(ClientPtr client) +{ + char n; + REQUEST(xvGetVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_GetVideo](client); +} + +static int +SProcXvGetStill(ClientPtr client) +{ + char n; + REQUEST(xvGetStillReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swaps(&stuff->vid_x, n); + swaps(&stuff->vid_y, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_GetStill](client); +} + +static int +SProcXvPutImage(ClientPtr client) +{ + char n; + REQUEST(xvPutImageReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swapl(&stuff->id, n); + swaps(&stuff->src_x, n); + swaps(&stuff->src_y, n); + swaps(&stuff->src_w, n); + swaps(&stuff->src_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return XvProcVector[xv_PutImage](client); +} + +#ifdef MITSHM +static int +SProcXvShmPutImage(ClientPtr client) +{ + char n; + REQUEST(xvShmPutImageReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + swapl(&stuff->gc, n); + swapl(&stuff->shmseg, n); + swapl(&stuff->id, n); + swapl(&stuff->offset, n); + swaps(&stuff->src_x, n); + swaps(&stuff->src_y, n); + swaps(&stuff->src_w, n); + swaps(&stuff->src_h, n); + swaps(&stuff->drw_x, n); + swaps(&stuff->drw_y, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return XvProcVector[xv_ShmPutImage](client); +} +#else /* MITSHM */ +#define SProcXvShmPutImage ProcXvShmPutImage +#endif + +static int +SProcXvSelectVideoNotify(ClientPtr client) +{ + char n; + REQUEST(xvSelectVideoNotifyReq); + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return XvProcVector[xv_SelectVideoNotify](client); +} + +static int +SProcXvSelectPortNotify(ClientPtr client) +{ + char n; + REQUEST(xvSelectPortNotifyReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_SelectPortNotify](client); +} + +static int +SProcXvStopVideo(ClientPtr client) +{ + char n; + REQUEST(xvStopVideoReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->drawable, n); + return XvProcVector[xv_StopVideo](client); +} + +static int +SProcXvSetPortAttribute(ClientPtr client) +{ + char n; + REQUEST(xvSetPortAttributeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->attribute, n); + swapl(&stuff->value, n); + return XvProcVector[xv_SetPortAttribute](client); +} + +static int +SProcXvGetPortAttribute(ClientPtr client) +{ + char n; + REQUEST(xvGetPortAttributeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->attribute, n); + return XvProcVector[xv_GetPortAttribute](client); +} + +static int +SProcXvQueryBestSize(ClientPtr client) +{ + char n; + REQUEST(xvQueryBestSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swaps(&stuff->vid_w, n); + swaps(&stuff->vid_h, n); + swaps(&stuff->drw_w, n); + swaps(&stuff->drw_h, n); + return XvProcVector[xv_QueryBestSize](client); +} + +static int +SProcXvQueryPortAttributes(ClientPtr client) +{ + char n; + REQUEST(xvQueryPortAttributesReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_QueryPortAttributes](client); +} + +static int +SProcXvQueryImageAttributes(ClientPtr client) +{ + char n; + REQUEST(xvQueryImageAttributesReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + swapl(&stuff->id, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return XvProcVector[xv_QueryImageAttributes](client); +} + +static int +SProcXvListImageFormats(ClientPtr client) +{ + char n; + REQUEST(xvListImageFormatsReq); + swaps(&stuff->length, n); + swapl(&stuff->port, n); + return XvProcVector[xv_ListImageFormats](client); +} + +static int (*SXvProcVector[xvNumRequests])(ClientPtr) = { + SProcXvQueryExtension, + SProcXvQueryAdaptors, + SProcXvQueryEncodings, + SProcXvGrabPort, + SProcXvUngrabPort, + SProcXvPutVideo, + SProcXvPutStill, + SProcXvGetVideo, + SProcXvGetStill, + SProcXvStopVideo, + SProcXvSelectVideoNotify, + SProcXvSelectPortNotify, + SProcXvQueryBestSize, + SProcXvSetPortAttribute, + SProcXvGetPortAttribute, + SProcXvQueryPortAttributes, + SProcXvListImageFormats, + SProcXvQueryImageAttributes, + SProcXvPutImage, + SProcXvShmPutImage, +}; + +int +SProcXvDispatch(ClientPtr client) +{ + REQUEST(xReq); + + UpdateCurrentTime(); + + if (stuff->data > xvNumRequests) { + SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest); + return BadRequest; + } + + return SXvProcVector[stuff->data](client); +} + +#ifdef PANORAMIX +static int +XineramaXvStopVideo(ClientPtr client) +{ + int result, i; + PanoramiXRes *draw, *port; + REQUEST(xvStopVideoReq); + REQUEST_SIZE_MATCH(xvStopVideoReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + result = ProcXvStopVideo(client); + } + } + + return result; +} + +static int +XineramaXvSetPortAttribute(ClientPtr client) +{ + REQUEST(xvSetPortAttributeReq); + PanoramiXRes *port; + int result, i; + + REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->port = port->info[i].id; + result = ProcXvSetPortAttribute(client); + } + } + return result; +} + +#ifdef MITSHM +static int +XineramaXvShmPutImage(ClientPtr client) +{ + REQUEST(xvShmPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool send_event = stuff->send_event; + Bool isRoot; + int result, i, x, y; + + REQUEST_SIZE_MATCH(xvShmPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + stuff->send_event = (send_event && !i) ? 1 : 0; + + result = ProcXvShmPutImage(client); + } + } + return result; +} +#else +#define XineramaXvShmPutImage ProcXvShmPutImage +#endif + +static int +XineramaXvPutImage(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + + result = ProcXvPutImage(client); + } + } + return result; +} + +static int +XineramaXvPutVideo(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutVideoReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + + result = ProcXvPutVideo(client); + } + } + return result; +} + +static int +XineramaXvPutStill(ClientPtr client) +{ + REQUEST(xvPutImageReq); + PanoramiXRes *draw, *gc, *port; + Bool isRoot; + int result, i, x, y; + + REQUEST_AT_LEAST_SIZE(xvPutImageReq); + + result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + + result = dixLookupResourceByType((pointer *)&gc, stuff->gc, + XRT_GC, client, DixReadAccess); + if (result != Success) + return result; + + result = dixLookupResourceByType((pointer *)&port, stuff->port, + XvXRTPort, client, DixReadAccess); + if (result != Success) + return result; + + isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; + + x = stuff->drw_x; + y = stuff->drw_y; + + FOR_NSCREENS_BACKWARD(i) { + if(port->info[i].id) { + stuff->drawable = draw->info[i].id; + stuff->port = port->info[i].id; + stuff->gc = gc->info[i].id; + stuff->drw_x = x; + stuff->drw_y = y; + if(isRoot) { + stuff->drw_x -= screenInfo.screens[i]->x; + stuff->drw_y -= screenInfo.screens[i]->y; + } + + result = ProcXvPutStill(client); + } + } + return result; +} + +static Bool +isImageAdaptor(XvAdaptorPtr pAdapt) +{ + return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0); +} + +static Bool +hasOverlay(XvAdaptorPtr pAdapt) +{ + int i; + for(i = 0; i < pAdapt->nAttributes; i++) + if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY")) + return TRUE; + return FALSE; +} + +static XvAdaptorPtr +matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay) +{ + int i; + XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey()); + /* Do not try to go on if xv is not supported on this screen */ + if(xvsp == NULL) + return NULL; + + /* if the adaptor has the same name it's a perfect match */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(!strcmp(refAdapt->name, pAdapt->name)) + return pAdapt; + } + + /* otherwise we only look for XvImage adaptors */ + if(!isImageAdaptor(refAdapt)) + return NULL; + + /* prefer overlay/overlay non-overlay/non-overlay pairing */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt)) + return pAdapt; + } + + /* but we'll take any XvImage pairing if we can get it */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(isImageAdaptor(pAdapt)) + return pAdapt; + } + return NULL; +} + +void XineramifyXv(void) +{ + XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey()); + XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; + int i, j, k; + + XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort"); + + if (!xvsp0 || !XvXRTPort) return; + SetResourceTypeErrorValue(XvXRTPort, _XvBadPort); + + for(i = 0; i < xvsp0->nAdaptors; i++) { + Bool isOverlay; + XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i; + if(!(refAdapt->type & XvInputMask)) continue; + + MatchingAdaptors[0] = refAdapt; + isOverlay = hasOverlay(refAdapt); + FOR_NSCREENS_FORWARD_SKIP(j) + MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay); + + /* now create a resource for each port */ + for(j = 0; j < refAdapt->nPorts; j++) { + PanoramiXRes *port = malloc(sizeof(PanoramiXRes)); + if(!port) + break; + + FOR_NSCREENS(k) { + if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) + port->info[k].id = MatchingAdaptors[k]->base_id + j; + else + port->info[k].id = 0; + } + AddResource(port->info[0].id, XvXRTPort, port); + } + } + + /* munge the dispatch vector */ + XvProcVector[xv_PutVideo] = XineramaXvPutVideo; + XvProcVector[xv_PutStill] = XineramaXvPutStill; + XvProcVector[xv_StopVideo] = XineramaXvStopVideo; + XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute; + XvProcVector[xv_PutImage] = XineramaXvPutImage; + XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage; +} +#endif /* PANORAMIX */ + +void +XvResetProcVector(void) +{ +#ifdef PANORAMIX + XvProcVector[xv_PutVideo] = ProcXvPutVideo; + XvProcVector[xv_PutStill] = ProcXvPutStill; + XvProcVector[xv_StopVideo] = ProcXvStopVideo; + XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute; + XvProcVector[xv_PutImage] = ProcXvPutImage; + XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage; +#endif +} |